18.11.2012 Views

ASE Manual Release 3.6.1.2825 CAMd - CampOS Wiki

ASE Manual Release 3.6.1.2825 CAMd - CampOS Wiki

ASE Manual Release 3.6.1.2825 CAMd - CampOS Wiki

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

<strong>ASE</strong> <strong>Manual</strong><br />

<strong>Release</strong> 3.6.1.2828<br />

<strong>CAMd</strong><br />

November 17, 2012


CONTENTS<br />

1 Atomic Simulation Environment 3<br />

1.1 News . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3<br />

2 Overview 5<br />

3 Installation requirements 7<br />

4 Download 9<br />

4.1 Latest stable release . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9<br />

4.2 Latest development release . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9<br />

5 Installation 11<br />

5.1 Installation with package manager on Linux . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11<br />

5.2 OSX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12<br />

5.3 Windows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12<br />

5.4 <strong>Manual</strong> installation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13<br />

5.5 Run the tests . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14<br />

5.6 Video tutorial . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14<br />

6 Tutorials 15<br />

6.1 Python . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15<br />

6.2 <strong>ASE</strong> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18<br />

6.3 NumPy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45<br />

6.4 Further reading . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46<br />

6.5 Videos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51<br />

7 Documentation for modules in <strong>ASE</strong> 53<br />

7.1 The Atoms object . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53<br />

7.2 The Atom object . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65<br />

7.3 Units . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67<br />

7.4 The ase.data module . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67<br />

7.5 File input and output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67<br />

7.6 Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70<br />

7.7 <strong>ASE</strong>-GUI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72<br />

7.8 Command line tools . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79<br />

7.9 Creating atomic structures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83<br />

7.10 Structure optimization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97<br />

7.11 Parallel calculations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102<br />

7.12 Visualization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103<br />

7.13 <strong>ASE</strong>-VTK . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107<br />

7.14 Calculators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110<br />

7.15 Constraints . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139<br />

7.16 Nudged elastic band . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143<br />

7.17 Vibration analysis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145<br />

i


7.18 Phonon calculations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147<br />

7.19 Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147<br />

7.20 Infrared intensities . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150<br />

7.21 Molecular dynamics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152<br />

7.22 Density Functional Theory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 156<br />

7.23 Electron transport . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165<br />

7.24 The data module . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 166<br />

7.25 Trajectory files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 169<br />

7.26 Utillity functions and classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172<br />

7.27 Thermochemistry . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 173<br />

8 Frequently Asked Questions 179<br />

8.1 <strong>ASE</strong>-GUI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179<br />

8.2 General . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179<br />

8.3 Download . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 180<br />

9 Glossary 181<br />

10 Mailing Lists 183<br />

10.1 Internet Relay Chat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183<br />

11 <strong>ASE</strong> development 185<br />

11.1 Development topics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 185<br />

11.2 Creating an encrypted password for SVN access . . . . . . . . . . . . . . . . . . . . . . . . . . 197<br />

12 Bugs! 199<br />

12.1 Bug report . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 199<br />

12.2 Known bugs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 199<br />

13 Porting old <strong>ASE</strong>-2 code to version 3 201<br />

13.1 The <strong>ASE</strong>2ase tool . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 201<br />

Bibliography 203<br />

Python Module Index 205<br />

Index 207<br />

ii


• Introduction to <strong>ASE</strong> - what is it?<br />

• Download and installation instructions<br />

• Tutorials<br />

• Documentation for modules in <strong>ASE</strong><br />

• Frequently Asked Questions<br />

• Mailing Lists<br />

• Glossary<br />

• <strong>ASE</strong> development<br />

• Bugs!<br />

• Porting old <strong>ASE</strong>-2 code to version 3<br />

The complete table of contents:<br />

<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

CONTENTS 1


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

2 CONTENTS


CHAPTER<br />

ONE<br />

ATOMIC SIMULATION ENVIRONMENT<br />

The Atomic Simulation Environment (<strong>ASE</strong>) is the common part of the simulation tools developed at <strong>CAMd</strong>. <strong>ASE</strong><br />

provides Python modules for manipulating atoms, analyzing simulations, visualization etc.<br />

Note: The old <strong>ASE</strong>-2 webpage has moved to http://wiki.fysik.dtu.dk/ase2.<br />

Supported calculators:<br />

1.1 News<br />

• <strong>ASE</strong> version 3.6.0 released (24 February 2012).<br />

• Bugfix release: <strong>ASE</strong> version 3.5.1 (24 May 2011).<br />

• <strong>ASE</strong> version 3.5.0 released (13 April 2011).<br />

• <strong>ASE</strong> version 3.4.1 released (11 August 2010).<br />

• <strong>ASE</strong> version 3.4 released (23 April 2010).<br />

• <strong>ASE</strong> version 3.3 released (11 January 2010).<br />

Gaussian<br />

Mopac<br />

3


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

• <strong>ASE</strong> version 3.2 released (4 September 2009).<br />

• <strong>ASE</strong> has reached revision 1000 (16 July 2009).<br />

• <strong>ASE</strong> version 3.1.0 released (27 March 2009).<br />

• Improved vibrations module: More accurate and possibility to calculate infrared intensities<br />

(13 March 2009).<br />

• <strong>ASE</strong> version 3.0.0 released (13 November 2008).<br />

• Asap version 3.0.2 released (15 October 2008).<br />

• An experimental abinit interface released (9 June 2008).<br />

• Thursday April 24 will be <strong>ASE</strong> documentation-day. Ten people from <strong>CAMd</strong>/Cinf will do a “doc-sprint”<br />

from 9 to 16. (17 Apr 2008)<br />

• The new <strong>ASE</strong>-3.0 Sphinx page is now up and running! (2 Apr 2008)<br />

• A beta version of the new <strong>ASE</strong>-3.0 will be used for the electronic structure course at <strong>CAMd</strong>. (10 Jan 2008)<br />

4 Chapter 1. Atomic Simulation Environment


CHAPTER<br />

TWO<br />

OVERVIEW<br />

<strong>ASE</strong> is an Atomistic Simulation Environment written in the Python programming language with the aim of setting<br />

up, stearing, and analyzing atomistic simulations. The <strong>ASE</strong> has been constructed with a number of “design goals”<br />

that make it:<br />

• Easy to use:<br />

Setting up an atomistic total energy calculation or molecular dynamics simulation with <strong>ASE</strong> is simple and<br />

straightforward. <strong>ASE</strong> can be used via a graphical user interface, Command line tools and the<br />

Python language. Python scripts are easy to follow (see What is Python? for a short introduction). It is<br />

simple for new users to get access to all of the functionality of <strong>ASE</strong>.<br />

• Flexible:<br />

Since <strong>ASE</strong> is based on the Python scripting language it is possible to perform very complicated simulation<br />

tasks without any code modifications. For example, a sequence of calculations may be performed with the<br />

use of simple “for-loop” constructions. There exist <strong>ASE</strong> modules for performing many standard simulation<br />

tasks.<br />

• Customizable:<br />

The Python code in <strong>ASE</strong> is structured in modules intended for different purposes. There are calculators<br />

for calculating energies, forces and stresses, md and optimize modules for controlling the motion of<br />

atoms, constraint objects and filters for performing nudged-elastic-band calculations etc. The<br />

modularity of the object-oriented code make it simple to contribute new functionality to <strong>ASE</strong>.<br />

• Pythonic:<br />

It fits nicely into the rest of the Python world with use of the popular NumPy package for numerical work<br />

(see Numeric arrays in Python for a short introduction). The use of the Python language allows <strong>ASE</strong> to be<br />

used both interactively as well as in scripts.<br />

• Open to participation:<br />

The CAMPOS Atomic Simulation Environment is released under the GNU Lesser General Public License<br />

version 2.1 or any later version. See the files COPYING and COPYING.LESSER which accompany the<br />

downloaded files, or see the license at GNU’s web server at http://www.gnu.org/licenses/. Everybody is<br />

invited to participate in using and developing the code.<br />

5


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

6 Chapter 2. Overview


CHAPTER<br />

THREE<br />

INSTALLATION REQUIREMENTS<br />

The following packages are required for basic <strong>ASE</strong> functionality:<br />

1. Python 2.4 - 2.7.<br />

2. NumPy.<br />

It is highly recommended (but not required) to install also these two:<br />

3. matplotlib.<br />

4. pygtk.<br />

Matplotlib is needed for writing png and eps files, and both packages are needed for <strong>ASE</strong>’s simple<br />

GUI (called ag, see gui). Some of these packages may already be installed on your system.<br />

Specific information for different operating systems is provided at Installation.<br />

7


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

8 Chapter 3. Installation requirements


4.1 Latest stable release<br />

The latest stable release can be obtained from svn or as a tarball.<br />

Note: The recommended installation path is $HOME.<br />

When using svn please set the following variable:<br />

• bash:<br />

export <strong>ASE</strong>_TAGS=https://svn.fysik.dtu.dk/projects/ase/tags/<br />

• csh/tcsh:<br />

setenv <strong>ASE</strong>_TAGS https://svn.fysik.dtu.dk/projects/ase/tags/<br />

CHAPTER<br />

FOUR<br />

DOWNLOAD<br />

<strong>Release</strong> Date Retrieve as svn checkout Retrieve as tarball<br />

3.6.0 Feb 24 2012 svn co -r 2515 $<strong>ASE</strong>_TAGS/3.6.0 ase-3.6.0 python-ase-3.6.0.2515.tar.gz<br />

3.5.1 May 24 2011 svn co -r 2175 $<strong>ASE</strong>_TAGS/3.5.1 ase-3.5.1 python-ase-3.5.1.2175.tar.gz<br />

3.4.1 Aug 11 2010 svn co -r 1765 $<strong>ASE</strong>_TAGS/3.4.1 ase-3.4.1 python-ase-3.4.1.1765.tar.gz<br />

3.4.0 Apr 23 2010 svn co -r 1574 $<strong>ASE</strong>_TAGS/3.4.0 ase-3.4.0 python-ase-3.4.0.1574.tar.gz<br />

3.3.1 Jan 20 2010 svn co -r 1390 $<strong>ASE</strong>_TAGS/3.3.1 ase-3.3.1 python-ase-3.3.1.1390.tar.gz<br />

3.2.0 Sep 4 2009 svn co -r 1121 $<strong>ASE</strong>_TAGS/3.2.0 ase-3.2.0 python-ase-3.2.0.1121.tar.gz<br />

3.1.0 Mar 27 2009 svn co -r 846 $<strong>ASE</strong>_TAGS/3.1.0 ase-3.1.0 python-ase-3.1.0.846.tar.gz<br />

3.0.0 Nov 13 2008 svn co -r 657 $<strong>ASE</strong>_TAGS/3.0.0 ase-3.0.0 python-ase-3.0.0.657.tar.gz<br />

4.2 Latest development release<br />

The latest revision can be obtained like this:<br />

$ svn checkout https://svn.fysik.dtu.dk/projects/ase/trunk ase<br />

or from the daily snapshot: python-ase-snapshot.tar.gz.<br />

Note: The recommended checkout path is $HOME.<br />

9


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

10 Chapter 4. Download


After performing the installation do not forget to Run the tests!<br />

5.1 Installation with package manager on Linux<br />

Install the binaries with the software package manager of your Linux distribution.<br />

This is the preferred way to install on a Linux system.<br />

If you prefer to install from sources follow <strong>Manual</strong> installation.<br />

The currently supported systems include (issue the commands below as root):<br />

• RHEL/CentOS 6:<br />

CHAPTER<br />

FIVE<br />

INSTALLATION<br />

yum install wget<br />

cd /etc/yum.repos.d/<br />

wget http://download.opensuse.org/repositories/home:/dtufys/CentOS_CentOS-6/home:dtufys.repo<br />

yum install python-ase<br />

yum install python-matplotlib # optionally<br />

• Fedora 17:<br />

yum install wget<br />

cd /etc/yum.repos.d/<br />

wget http://download.opensuse.org/repositories/home:/dtufys/Fedora_17/home:dtufys.repo<br />

yum install python-ase<br />

yum install python-matplotlib # optionally<br />

• openSUSE 12.2:<br />

zypper ar -f http://download.opensuse.org/repositories/home:/dtufys/openSUSE_12.2/home:dtufys<br />

yast -i python-ase<br />

yast -i python-matplotlib # optionally<br />

• Debian 6.0:<br />

sudo bash -c ’echo "deb http://widehat.opensuse.org/repositories/home:/dtufys/Debian_6.0 /" ><br />

wget http://widehat.opensuse.org/repositories/home:/dtufys/Debian_6.0/<strong>Release</strong>.key && sudo apt<br />

sudo apt-get update<br />

sudo apt-get install python-ase<br />

sudo apt-get install python-matplotlib # optionally<br />

• Ubuntu 12.04:<br />

sudo bash -c ’echo "deb http://widehat.opensuse.org/repositories/home:/dtufys/xUbuntu_12.04 /<br />

wget http://widehat.opensuse.org/repositories/home:/dtufys/xUbuntu_12.04/<strong>Release</strong>.key && sudo<br />

sudo apt-get update<br />

sudo apt-get install python-ase<br />

sudo apt-get install python-matplotlib # optionally<br />

11


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

Note: Alternative packages for ubuntu are provided at Ubuntu package.<br />

For the full list of supported distributions check https://build.opensuse.org/package/show?package=pythonase&project=home%3Adtufys<br />

Note: Explore the repositories - more software packages are available!<br />

Note: If you prefer to install manually, proceed to <strong>Manual</strong> installation, or alternatively, manually unpack the<br />

RPMS, e.g.:<br />

# download the packages + dependencies (you can do that also manually!)<br />

$ yumdownloader --resolve python-ase<br />

# unpack into the current directory<br />

$ find . -name "*.rpm" | xargs -t -I file sh -c "rpm2cpio file | cpio -idm"<br />

# modify profile.d environment scripts<br />

$ find . -name "*.*sh" | xargs -t -I file sh -c ’sed -i "s#PA=/usr#PA=$PWD/usr#" file’<br />

# modify environment modules scripts<br />

$ find . -name "*.modules" | xargs -t -I file sh -c ’sed -i "s# /usr# $PWD/usr#" file’<br />

# make scripts executable<br />

$ find . -name "*.*sh" | xargs -t -I file sh -c "chmod u+x file"<br />

# source the scripts (example for bash)<br />

$ for f in ‘find . -name "*.sh"‘; do source $f; done<br />

# verify the desired installation location is used<br />

$ python -c "import ase; print ase.__file__"<br />

This method works for all the RPM packages from the repository (like gpaw), however not for the external,<br />

distribution provided packages, which may require manually creating the environment scripts.<br />

5.2 OSX<br />

For Apple users, the MacPorts Project provides a straight-forward route to obtain all necessary requirements.<br />

Unfortunately, MacPorts does not install the gtk bindings to matplotlib by default, which are required to open the<br />

GUI. To get all the <strong>ASE</strong> prerequisites for python 2.7 in one single command anyway, install MacPorts and then<br />

run:<br />

$ port install py27-matplotlib +gtk2<br />

Use the sudo command if you have root access and if you require a system-wide install. Once finished, please<br />

follow <strong>Manual</strong> installation.<br />

5.3 Windows<br />

Note: <strong>ASE</strong> is not yet fully functional on Windows! https://trac.fysik.dtu.dk/projects/ase/ticket/62<br />

On Windows the following packages need to installed. On the command prompt:<br />

Note: installation assumes the python TARGETDIR C:\Python27 , leave also the default C:\Program<br />

Files\pythonxy .<br />

• pythonxy. Download the exe installer and install with:<br />

12 Chapter 5. Installation


Python(x,y)-2.7.2.2.exe /Log="%TMP%\pythonxy_install.log" /S<br />

Note: Open Task Manager and control when the process in finished.<br />

<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

• pygtk_win32. Download the msi pygtk-all-in-one installer. Specify the correct TARGETDIR and install:<br />

pygtk-all-in-one-2.24.2.win32-py2.7.msi TARGETDIR="%HOMEDRIVE%\Python27" ALLUSERS=1 /l*vx "%T<br />

Note: If performing clicking-installation make sure that the default python Windows TARGETDIR is selected.<br />

• Download the python-ase-win32.msi installer and install with:<br />

python-ase-X.X.X.win32.msi /l*vx "%TMP%\python-ase_install.log" /passive<br />

Note: You can build the msi <strong>ASE</strong> package on Windows with:<br />

python setup.py bdist_msi<br />

The msi package will be created under the dist directory.<br />

5.4 <strong>Manual</strong> installation<br />

After the Download of <strong>ASE</strong> source create the link to the requested version, e.g.:<br />

• if retrieved from svn:<br />

$ cd $HOME<br />

$ ln -s ase-3.5.1 ase<br />

• if retrieved as tarball:<br />

$ cd $HOME<br />

$ tar zxf python-ase-3.5.1.2175.tar.gz<br />

$ ln -s python-ase-3.5.1.2175 ase<br />

It is sufficient to put the directory $HOME/ase in your PYTHONPATH environment variable, and the directory<br />

$HOME/ase/tools in your PATH environment variable. Do this permanently in your ~/.bashrc file:<br />

export PYTHONPATH=$HOME/ase:$PYTHONPATH<br />

export PATH=$HOME/ase/tools:$PATH<br />

or your ~/.cshrc file:<br />

setenv PYTHONPATH ${HOME}/ase:${PYTHONPATH}<br />

setenv PATH ${HOME}/ase/tools:${PATH}<br />

Instead of HOME, you may use any other directory.<br />

Optional, NOT recommended way of installing <strong>ASE</strong> system-wide is:<br />

$ cd ase<br />

$ sudo python setup.py install<br />

This is one of the best ways to ruin a Linux system.<br />

5.4. <strong>Manual</strong> installation 13


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

5.5 Run the tests<br />

Make sure that everything works by running the test suite. This will create many files, so run the tests in a<br />

new directory (preferably using bash):<br />

$ bash<br />

$ mkdir /tmp/testase.$$; cd /tmp/testase.*<br />

$ testase.py 2>&1 | tee testase.log<br />

Note: In the development version of <strong>ASE</strong>, and in future stable versions, the test script is just named testase.<br />

Note: The last test ase/test/COCu111.py requires closing the graphics windows to terminate the whole test-suite.<br />

If any of the tests fail, then please send us testase.log (see Bugs!).<br />

Note: If matplotlib or pygtk is not installed, one of the tests will fail - avoid this with:<br />

$ testase.py --no-display<br />

5.6 Video tutorial<br />

In the video: Overview of the features of <strong>ASE</strong>, followed by a <strong>Manual</strong> installation of <strong>ASE</strong> on a Linux system.<br />

Note: Use “Right Click -> Play” to play.<br />

14 Chapter 5. Installation


6.1 Python<br />

If you are not familiar with Python please read What is Python?.<br />

6.1.1 What is Python?<br />

This section will give a very brief introduction to the Python language.<br />

See Also:<br />

• The Python home page.<br />

• Python Recipes.<br />

• Try a Python quick reference card or a different reference card.<br />

Executing Python code<br />

You can execute Python code interactively by starting the interpreter like this:<br />

$ python<br />

Python 2.5.1 (r251:54863, Mar 7 2008, 04:10:12)<br />

[GCC 4.1.3 20070929 (prerelease) (Ubuntu 4.1.2-16ubuntu2)] on linux2<br />

Type "help", "copyright", "credits" or "license" for more information.<br />

>>> print ’hello’<br />

hello<br />

CHAPTER<br />

SIX<br />

TUTORIALS<br />

You can also put the print ’hello’ line in a file (hello.py) and execute it as a Python script:<br />

$ python hello.py<br />

hello<br />

Or like this:<br />

$ python -i hello.py<br />

hello<br />

>>> print ’hi!’<br />

hi!<br />

Finally, you can put #!/usr/bin/env python in the first line of the hello.py file, make it executable<br />

(chmod +x hello.py) and execute it like any other executable.<br />

Tip: For interactive Python sessions, it is very convenient to have a personal .pythonrc file:<br />

15


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

import rlcompleter<br />

import readline<br />

readline.parse_and_bind("tab: complete")<br />

from ase import *<br />

and point the PYTHONSTARTUP environment variable at it (see here for details).<br />

Tip: For an even better interactive experience, use ipython.<br />

Types<br />

Python has the following predefined types:<br />

type description example<br />

bool boolean False<br />

int integer 117<br />

float floating point number 1.78<br />

complex complex number 0.5 + 2.0j<br />

str string ’abc’<br />

tuple tuple (1, ’hmm’, 2.0)<br />

list list [1, ’hmm’, 2.0]<br />

dict dictionary {’a’: 7.0, 23: True}<br />

file file open(’stuff.dat’, ’w’)<br />

A dict object is mapping from keys to values:<br />

>>> d = {’s’: 0, ’p’: 1}<br />

>>> d[’d’] = 2<br />

>>> d<br />

{’p’: 1, ’s’: 0, ’d’: 2}<br />

>>> d[’p’]<br />

1<br />

A list object is an ordered collection of arbitrary objects:<br />

>>> l = [1, (’gg’, 7), ’hmm’]<br />

>>> l[1]<br />

(’gg’, 7)<br />

>>> l.append(1.2)<br />

>>> l[-2]<br />

’hmm’<br />

A tuple behaves like a list - except that it can’t be modified inplace. Objects of types list and dict are<br />

mutable - all the other types listed in the table are immutable, which means that once an object has been created,<br />

it can not change.<br />

Note: List and dictionary objects can change. Variables in Python are references to objects. This is demonstrated<br />

here:<br />

>>> a = [’q’, ’w’]<br />

>>> b = a<br />

>>> a.append(’e’)<br />

>>> a<br />

[’q’, ’w’, ’e’]<br />

>>> b<br />

[’q’, ’w’, ’e’]<br />

Note: Another very important type is the ndarray type described here: Numeric arrays in Python.<br />

16 Chapter 6. Tutorials


Loops<br />

A loop in Python can be done like this:<br />

>>> things = [’a’, 7]<br />

>>> for x in things:<br />

... print x<br />

...<br />

a<br />

7<br />

<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

The things object could be any sequence. Strings, tuples, lists, dictionaries, ndarrays and files are sequences.<br />

Functions and classes<br />

A function is defined like this:<br />

>>> def f(x, m=2, n=1):<br />

... y = x + n<br />

... return y**m<br />

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.<br />

A class is defined like this:<br />

>>> class A:<br />

... def __init__(self, b):<br />

... self.c = b<br />

... def m(self):<br />

... return f(self.c, n=0)<br />

The __init__() function is called a constructor. You can think of a class as a template for creating user defined<br />

objects.<br />

In the class A __init__ is a constructor, c is an attribute and m is a method.<br />

>>> a = A(7)<br />

>>> a.c<br />

7<br />

>>> a.m()<br />

49<br />

>>> g = a.m<br />

>>> g()<br />

49<br />

Here we make an instance/object a of type A and g is a method bound to a.<br />

Importing modules<br />

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<br />

another piece of code:<br />

from stuff import f, C<br />

print f(1, 2)<br />

print C(1).m(2)<br />

or:<br />

import stuff<br />

print stuff.f(1, 2)<br />

print stuff.C(1).m(2)<br />

6.1. Python 17


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

or:<br />

import stuff as st<br />

print st.f(1, 2)<br />

print st.C(1).m(2)<br />

Python will look for stuff.py in these directories:<br />

1. current working directory<br />

2. directories listed in your PYTHONPATH<br />

3. Python’s own system directory (typically /usr/lib/python2.5)<br />

and import the first one found.<br />

6.2 <strong>ASE</strong><br />

Most of the tutorials will use the EMT potential, but any other Calculator could be plugged in instead.<br />

6.2.1 Introduction: Nitrogen on copper<br />

This section gives a quick (and incomplete) overview of what <strong>ASE</strong> can do.<br />

We will calculate the adsorption energy of a nitrogen molecule on a copper surface. This is done by calculating<br />

the total energy for the isolated slab and for the isolated molecule. The adsorbate is then added to the slab and<br />

relaxed, and the total energy for this composite system is calculated. The adsorption energy is obtained as the sum<br />

of the isolated energies minus the energy of the composite system.<br />

Here is a picture of the system after the relaxation:<br />

Please have a look at the following script doc/tutorials/N2Cu.py:<br />

from ase import Atoms<br />

from ase.visualize import view<br />

from ase.calculators.emt import EMT<br />

from ase.constraints import FixAtoms<br />

from ase.optimize import QuasiNewton<br />

from ase.lattice.surface import fcc111,add_adsorbate<br />

h = 1.85<br />

d = 1.10<br />

slab = fcc111(’Cu’, size=(4,4,2), vacuum=10.0)<br />

slab.set_calculator(EMT())<br />

18 Chapter 6. Tutorials


e_slab = slab.get_potential_energy()<br />

molecule = Atoms(’2N’, positions=[(0., 0., 0.), (0., 0., d)])<br />

molecule.set_calculator(EMT())<br />

e_N2 = molecule.get_potential_energy()<br />

add_adsorbate(slab, molecule, h, ’ontop’)<br />

constraint = FixAtoms(mask=[a.symbol != ’N’ for a in slab])<br />

slab.set_constraint(constraint)<br />

dyn = QuasiNewton(slab, trajectory=’N2Cu.traj’)<br />

dyn.run(fmax=0.05)<br />

<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

print ’Adsorption energy:’, e_slab + e_N2 - slab.get_potential_energy()<br />

#view(slab)<br />

Assuming you have <strong>ASE</strong> setup correctly (Installation requirements) run the script:<br />

python N2Cu.py<br />

Please read below what the script does.<br />

Atoms<br />

The Atoms object is a collection of atoms. Here is how to define a N2 molecule by directly specifying the position<br />

of two nitrogen atoms:<br />

from ase import Atoms<br />

d = 1.10<br />

molecule = Atoms(’2N’, positions=[(0., 0., 0.), (0., 0., d)])<br />

You can also build crystals using, for example, the lattice module which returns Atoms objects corresponding to<br />

common crystal structures. Let us make a Cu (111) surface:<br />

from ase.lattice.surface import fcc111<br />

slab = fcc111(’Cu’, size=(4,4,2), vacuum=10.0)<br />

Calculators<br />

Many calculators can be used with <strong>ASE</strong>, including emt, Asap, Dacapo, GPAW, Abinit, Vasp. See the <strong>ASE</strong><br />

home page for the full list.<br />

In this overview we use the effective medium theory (EMT) calculator, as it is very fast and hence useful for<br />

getting started.<br />

We can attach a calculator to the previously created Atoms objects:<br />

from ase import EMT<br />

slab.set_calculator(EMT())<br />

molecule.set_calculator(EMT())<br />

and use it to calculate the total energies for the systems by using the get_potential_energy() method<br />

from the Atoms class:<br />

e_slab = slab.get_potential_energy()<br />

e_N2 = molecule.get_potential_energy()<br />

Structure relaxation<br />

Let’s use the QuasiNewton minimizer to optimize the structure of the N2 molecule adsorbed on the Cu surface.<br />

First add the adsorbate to the Cu slab, for example in the on-top position:<br />

6.2. <strong>ASE</strong> 19


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

h = 1.85<br />

add_adsorbate(slab, molecule, h, ’ontop’)<br />

In order to speed up the relaxation, let us keep the Cu atoms fixed in the slab by using FixAtoms from the<br />

constraints module. Only the N2 molecule is then allowed to relax to the equilibrium structure:<br />

from ase.constraints import FixAtoms<br />

constraint = FixAtoms(mask=[a.symbol != ’N’ for a in slab])<br />

slab.set_constraint(constraint)<br />

Now attach the QuasiNewton minimizer to the system and save the trajectory file. Run the minimizer with the<br />

convergence criteria that the force on all atoms should be less than some fmax:<br />

from ase.optimize import QuasiNewton<br />

dyn = QuasiNewton(slab, trajectory=’N2Cu.traj’)<br />

dyn.run(fmax=0.05)<br />

Note: The general documentation on structure optimizations contains information about different algorithms,<br />

saving the state of an optimizer and other functionality which should be considered when performing expensive<br />

relaxations.<br />

Input-output<br />

Writing the atomic positions to a file is done with the write() function:<br />

from ase.io import write<br />

write(’slab.xyz’, slab)<br />

This will write a file in the xyz-format. Possible formats are:<br />

format description<br />

xyz Simple xyz-format<br />

cube Gaussian cube file<br />

pdb Protein data bank file<br />

traj <strong>ASE</strong>’s own trajectory format<br />

py Python script<br />

Reading from a file is done like this:<br />

from ase.io import read<br />

slab_from_file = read(’slab.xyz’)<br />

If the file contains several configurations, the default behavior of the write() function is to return the last<br />

configuration. However, we can load a specific configuration by doing:<br />

read(’slab.traj’) # last configuration<br />

read(’slab.traj’, -1) # same as above<br />

read(’slab.traj’, 0) # first configuration<br />

Visualization<br />

The simplest way to visualize the atoms is the view() function:<br />

from ase.visualize import view<br />

view(slab)<br />

This will pop up a gui window. Alternative viewers can be used by specifying the optional keyword<br />

viewer=... - use one of ‘ase.gui’, ‘gopenmol’, ‘vmd’, or ‘rasmol’. (Note that these alternative viewers are not<br />

a part of <strong>ASE</strong> and will need to be installed by the user separately.) The VMD viewer can take an optional data<br />

argument to show 3D data:<br />

20 Chapter 6. Tutorials


view(slab, viewer=’VMD’, data=array)<br />

Molecular dynamics<br />

<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

Let us look at the nitrogen molecule as an example of molecular dynamics with the VelocityVerlet algorithm.<br />

We first create the VelocityVerlet object giving it the molecule and the time step for the integration<br />

of Newton’s law. We then perform the dynamics by calling its run() method and giving it the number of steps<br />

to take:<br />

from ase.md.verlet import VelocityVerlet<br />

from ase import units<br />

dyn = VelocityVerlet(molecule, dt=1.0 * units.fs)<br />

for i in range(10):<br />

pot = molecule.get_potential_energy()<br />

kin = molecule.get_kinetic_energy()<br />

print ’%2d: %.5f eV, %.5f eV, %.5f eV’ % (i, pot + kin, pot, kin)<br />

dyn.run(steps=20)<br />

6.2.2 Manipulating atoms<br />

XXX rewrite this: use fcc111() function and do some relaxation ...<br />

We will set up a one layer slab of Ni atoms with one Ag adatom.<br />

Define the slab atoms:<br />

>>> from ase import Atoms<br />

>>> atoms = Atoms(’Ni4’, [(0, 0, 0),<br />

... (0.45, 0, 0),<br />

... (0, 0.5, 0),<br />

... (0.5, 0.5, 0)])<br />

Have a look at the individual atoms:<br />

>>> atoms[0]<br />

Atom(’Ni’, [0.0, 0.0, 0.0], atoms=..., index=0)<br />

>>> atoms[1]<br />

Atom(’Ni’, [0.45, 0.0, 0.0], atoms=..., index=1)<br />

>>> atoms[2]<br />

Atom(’Ni’, [0.0, 0.5, 0.0], atoms=..., index=2)<br />

>>> atoms[3]<br />

Atom(’Ni’, [0.5, 0.5, 0.0], atoms=..., index=3)<br />

Let us assume we forgot how many atoms we set up:<br />

>>> atoms[4]<br />

Traceback (most recent call last):<br />

File "", line 1, in ?<br />

IndexError: list index out of range<br />

Wrong because we only have four atoms<br />

>>> len(atoms)<br />

4<br />

Change the position of the 2nd atom in the list<br />

>>> atoms[1].x = 0.5<br />

>>> atoms.get_positions()<br />

array([[ 0. , 0. , 0. ],<br />

[ 0.5, 0. , 0. ],<br />

6.2. <strong>ASE</strong> 21


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

[ 0. , 0.5, 0. ],<br />

[ 0.5, 0.5, 0. ]])<br />

What is the unit cell so far?<br />

>>> atoms.get_cell()<br />

array([[ 1., 0., 0.],<br />

[ 0., 1., 0.],<br />

[ 0., 0., 1.]])<br />

Now, setup a p(2x2) cell in a hexagonal surface. Here, a is the fcc lattice constant, the cell is 10 layers high:<br />

>>> from numpy import sqrt<br />

>>> a = 3.55<br />

>>> cell = [(2/sqrt(2.)*a, 0, 0),<br />

... (1/sqrt(2.)*a, sqrt(3./2.)*a, 0),<br />

... (0, 0, 10*sqrt(3.)/3.*a)]<br />

>>> cell<br />

[(5.0204581464244864, 0, 0),<br />

(2.5102290732122432, 4.3478442934401409, 0),<br />

(0, 0, 20.495934556231713)]<br />

>>> atoms.set_cell(cell, scale_atoms=True)<br />

The argument scale_atoms=True indicates that the atomic positions should be scaled with the unit cell. The<br />

default is scale_atoms=False indicating that the cartesian coordinates remain the same when the cell is changed.<br />

>>> atoms.get_positions()<br />

array([[ 0. , 0. , 0. ],<br />

[ 2.51022907, 0. , 0. ],<br />

[ 1.25511454, 2.17392215, 0. ],<br />

[ 3.76534361, 2.17392215, 0. ]])<br />

Plot the whole system by bringing up the gui:<br />

>>> from ase.visualize import view<br />

>>> view(atoms)<br />

Within the viewer (called ag or ase.gui) it is possible to repeat the unit cell in all three directions (using the<br />

Repeat → View window).<br />

22 Chapter 6. Tutorials


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

We now add an adatom. Since the supercell is now declared as the unit cell for our atoms we can either add the<br />

atom using its cartesian coordinates in Angstrom or rescale the unit cell and use scaled coordinates. We try the<br />

latter:<br />

>>> from numpy import identity<br />

>>> from ase import Atom<br />

>>> xyzcell = identity(3) # The 3x3 unit matrix<br />

>>> atoms.set_cell(xyzcell, scale_atoms=True) # Set the unit cell and rescale<br />

>>> atoms.append(Atom(’Ni’, (1/6., 1/6., .1)))<br />

>>> atoms.set_cell(cell, scale_atoms=True) # Set the unit cell and scale back<br />

The structure now looks like this:<br />

>>> view(atoms)<br />

6.2.3 Using the spacegroup subpackage<br />

The most evident usage of the spacegroup subpackage is to set up an initial unit of a bulk structure. For this you<br />

only need to supply the unique atoms and their scaled positions, space group and lattice parameters.<br />

Examples of setting up bulk structures<br />

We start by showing some examples of how to set up some common or interesting bulk structures using<br />

ase.lattice.spacegroup.crystal(). This function takes a lot of arguments, of which the most important are:<br />

symbols [string | sequence of strings] Either a string formula or sequence of element symbols. E.g.<br />

‘NaCl’ and (‘Na’, ‘Cl’) are equivalent.<br />

basis [list of scaled coordinates] Coordinates of the non-equivalent sites in units of the lattice vectors.<br />

spacegroup [int | string | Spacegroup instance] Space group given either as its number in International<br />

Tables or as its Hermann-Mauguin (or international) symbol.<br />

setting [1 | 2] Space group setting.<br />

6.2. <strong>ASE</strong> 23


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

cellpar [[a, b, c, alpha, beta, gamma]] Cell parameters with angles in degree. Is not used when cell<br />

is given.<br />

Aluminium (fcc)<br />

from ase.lattice.spacegroup import crystal<br />

a = 4.05<br />

al = crystal(’Al’, [(0,0,0)], spacegroup=225, cellpar=[a, a, a, 90, 90, 90])<br />

The spacegroup argument can also be entered with its Hermann-Mauguin symbol, e.g. spacegroup=225 is equivalent<br />

to spacegroup=’F m -3 m’.<br />

Iron (bcc)<br />

from ase.lattice.spacegroup import crystal<br />

a = 2.87<br />

fe = crystal(’Fe’, [(0,0,0)], spacegroup=229, cellpar=[a, a, a, 90, 90, 90])<br />

Magnesium (hcp)<br />

from ase.lattice.spacegroup import crystal<br />

a = 3.21<br />

c = 5.21<br />

mg = crystal(’Mg’, [(1./3., 2./3., 3./4.)], spacegroup=194,<br />

cellpar=[a, a, c, 90, 90, 120])<br />

24 Chapter 6. Tutorials


Diamond<br />

from ase.lattice.spacegroup import crystal<br />

<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

a = 3.57<br />

diamond = crystal(’C’, [(0,0,0)], spacegroup=227, cellpar=[a, a, a, 90, 90, 90])<br />

Sodium chloride<br />

from ase.lattice.spacegroup import crystal<br />

a = 5.64<br />

nacl = crystal([’Na’, ’Cl’], [(0, 0, 0), (0.5, 0.5, 0.5)], spacegroup=225,<br />

cellpar=[a, a, a, 90, 90, 90])<br />

Rutile<br />

from ase.lattice.spacegroup import crystal<br />

a = 4.6<br />

c = 2.95<br />

rutile =crystal([’Ti’, ’O’], basis=[(0, 0, 0), (0.3, 0.3, 0.0)],<br />

spacegroup=136, cellpar=[a, a, c, 90, 90, 90])<br />

6.2. <strong>ASE</strong> 25


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

CoSb3 skutterudite<br />

Skutterudites are quite interesting structures with 32 atoms in the unit cell.<br />

from ase.lattice.spacegroup import crystal<br />

a = 9.04<br />

skutterudite = crystal((’Co’, ’Sb’),<br />

basis=[(0.25,0.25,0.25), (0.0, 0.335, 0.158)],<br />

spacegroup=204,<br />

cellpar=[a, a, a, 90, 90, 90])<br />

#ase.view(skutterudite)<br />

Often this structure is visualised with the Cobalt atoms on the corners. This can easily be accomplished with<br />

<strong>ASE</strong> using ase.utils.geomegry.cut(). Below is the origo argument used to put the Cobalt atom on the corners and<br />

extend to include all corner and edge atoms, even those belonging to neighbouring unit cells.<br />

26 Chapter 6. Tutorials


import numpy as np<br />

import ase.utils.geometry as geometry<br />

import ase.io as io<br />

<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

# Create a new atoms instance with Co at origo including all atoms on the<br />

# surface of the unit cell<br />

cosb3 = geometry.cut(skutterudite, origo=(0.25, 0.25, 0.25), extend=1.01)<br />

# Define the atomic bonds to show<br />

bondatoms = []<br />

symbols = cosb3.get_chemical_symbols()<br />

for i in xrange(len(cosb3)):<br />

for j in xrange(i):<br />

if (symbols[i] == symbols[j] == ’Co’ and<br />

cosb3.get_distance(i, j) < 4.53):<br />

bondatoms.append((i, j))<br />

elif (symbols[i] == symbols[j] == ’Sb’ and<br />

cosb3.get_distance(i, j) < 2.99):<br />

bondatoms.append((i, j))<br />

# Create nice-looking image using povray<br />

io.write(’spacegroup-cosb3.pov’, cosb3,<br />

transparent=False,<br />

display=False,<br />

run_povray=True,<br />

camera_type=’perspective’,<br />

canvas_width=320,<br />

radii=0.4,<br />

rotation=’90y’,<br />

bondlinewidth=0.07,<br />

bondatoms=bondatoms,<br />

)<br />

6.2. <strong>ASE</strong> 27


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

The Spacegroup class<br />

The Spacegroup class is used internally by the ase.lattice.spacegroup.crystal() function, but might sometimes<br />

also be useful if you want to know e.g. the symmetry operations of a given space group. Instances of the Spacegroup<br />

class are immutable objects holding space group information, such as symmetry operations.<br />

Let us e.g. consider the fcc structure. To print information about the space group, do<br />

from ase.lattice.spacegroup import Spacegroup<br />

sg = Spacegroup(225)<br />

print ’Space group:’, sg.no, sg.symbol<br />

print ’Primitive cell:\n’, sg.scaled_primitive_cell<br />

print ’Reciprocal cell:\n’, sg.scaled_reciprocal_cell<br />

print ’Lattice type:’, sg.lattice<br />

print ’Lattice sub-translations’, sg.subtrans<br />

print ’Centerosymmetric’, sg.centerosymmetric<br />

print ’Rotation matrices (not including inversions)\n’, sg.rotations<br />

print ’Translation vectors (not including inversions)\n’, sg.translations<br />

or simply<br />

print sg<br />

Or, if you want to figure out what sites in the unit cell are equivalent to (0, 0, 0.5), simply do<br />

sites,kinds = sg.equivalent_sites([(0, 0, 0.5)])<br />

where sites will be an array containing the scaled positions of the four symmetry-equivalent sites.<br />

6.2.4 Atomization energy<br />

The following script will calculate the atomization energy of a nitrogen molecule:<br />

from ase import Atoms<br />

from ase.calculators.emt import EMT<br />

atom = Atoms(’N’, calculator=EMT())<br />

e_atom = atom.get_potential_energy()<br />

d = 1.1<br />

molecule = Atoms(’2N’, [(0., 0., 0.), (0., 0., d)])<br />

molecule.set_calculator(EMT())<br />

e_molecule = molecule.get_potential_energy()<br />

e_atomization = e_molecule - 2 * e_atom<br />

print ’Nitrogen atom energy: %5.2f eV’ %e_atom<br />

print ’Nitrogen molecule energy: %5.2f eV’ %e_molecule<br />

print ’Atomization energy: %5.2f eV’ %-e_atomization<br />

First, an Atoms object containing one nitrogen is created and a fast EMT calculator is attached to it simply as an<br />

argument. The total energy for the isolated atom is then calculated and stored in the e_atom variable.<br />

The molecule object is defined, holding the nitrogen molecule at the experimental bond length. The EMT<br />

calculator is then attached to the molecule and the total energy is extracted into the e_molecule variable.<br />

Running the script will produce the output:<br />

Nitrogen atom energy: 4.97 eV<br />

Nitrogen molecule energy: 0.04 eV<br />

Atomization energy: 9.90 eV<br />

28 Chapter 6. Tutorials


6.2.5 Finding lattice constants<br />

See Also:<br />

Equation of state.<br />

HCP<br />

Let’s try to find the a and c lattice constants for HCP nickel using the EMT potential.<br />

<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

First, we make a good intial guess for a and c using the FCC nearest neighbor distance and the ideal c/a ratio:<br />

import numpy as np<br />

a0 = 3.52 / np.sqrt(2)<br />

c0 = np.sqrt(8 / 3.0) * a0<br />

and create a trajectory for the results:<br />

from ase.io import PickleTrajectory<br />

traj = PickleTrajectory(’Ni.traj’, ’w’)<br />

Finally, we do the 9 calculations (three values for a and three for c):<br />

from ase.lattice import bulk<br />

from ase.calculators.emt import EMT<br />

eps = 0.01<br />

for a in a0 * np.linspace(1 - eps, 1 + eps, 3):<br />

for c in c0 * np.linspace(1 - eps, 1 + eps, 3):<br />

ni = bulk(’Ni’, ’hcp’, a=a, c=c)<br />

ni.set_calculator(EMT())<br />

ni.get_potential_energy()<br />

traj.write(ni)<br />

Analysis<br />

Now, we need to extract the data from the trajectory. Try this:<br />

>>> from ase.lattice import bulk<br />

>>> ni = bulk(’Ni’, ’hcp’, a=2.5, c=4.0)<br />

>>> ni.cell<br />

array([[ 2.5 , 0. , 0. ],<br />

[-1.25 , 2.16506351, 0. ],<br />

[ 0. , 0. , 4. ]])<br />

So, we can get a and c from ni.cell[0, 0] and ni.cell[2, 2]:<br />

from ase.io import read<br />

configs = read(’Ni.traj@:’)<br />

energies = [config.get_potential_energy() for config in configs]<br />

a = np.array([config.cell[0, 0] for config in configs])<br />

c = np.array([config.cell[2, 2] for config in configs])<br />

We fit the energy to this expression:<br />

The best fit is found like this:<br />

p0 + p1a + p2c + p3a 2 + p4ac + p5c 2<br />

functions = np.array([a**0, a, c, a**2, a * c, c**2])<br />

p = np.linalg.lstsq(functions.T, energies)[0]<br />

6.2. <strong>ASE</strong> 29


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

and we can find the minimum like this:<br />

p0 = p[0]<br />

p1 = p[1:3]<br />

p2 = np.array([(2 * p[3], p[4]),<br />

(p[4], 2 * p[5])])<br />

a0, c0 = np.linalg.solve(p2.T, -p1)<br />

Results:<br />

a c<br />

2.466 4.023<br />

Using the stress tensor<br />

One can also use the stress tensor to optimize the unit cell:<br />

from ase.optimize import BFGS<br />

from ase.constraints import StrainFilter<br />

sf = StrainFilter(ni)<br />

opt = BFGS(sf)<br />

opt.run(0.005)<br />

If you want the optimization path in a trajectory, add these lines before calling the run() method:<br />

traj = PickleTrajectory(’path.traj’, ’w’, ni)<br />

opt.attach(traj)<br />

6.2.6 Equation of state<br />

First, do a bulk calculation for different lattice constants:<br />

import numpy as np<br />

from ase import Atoms<br />

from ase.io.trajectory import PickleTrajectory<br />

from ase.calculators.emt import EMT<br />

a = 4.0 # approximate lattice constant<br />

b = a / 2<br />

ag = Atoms(’Ag’,<br />

cell=[(0,b,b), (b,0,b), (b,b,0)],<br />

pbc=1,<br />

calculator=EMT()) # use EMT potential<br />

cell = ag.get_cell()<br />

traj = PickleTrajectory(’Ag.traj’, ’w’)<br />

for x in np.linspace(0.95, 1.05, 5):<br />

ag.set_cell(cell * x, scale_atoms=True)<br />

traj.write(ag)<br />

This will write a trajectory file containing five configurations of FCC silver for five different lattice constans. Now,<br />

analyse the result with the EquationOfState class and this script:<br />

from ase.io import read<br />

from ase.units import kJ<br />

from ase.utils.eos import EquationOfState<br />

configs = read(’Ag.traj@0:5’) # read 5 configurations<br />

# Extract volumes and energies:<br />

volumes = [ag.get_volume() for ag in configs]<br />

energies = [ag.get_potential_energy() for ag in configs]<br />

eos = EquationOfState(volumes, energies)<br />

v0, e0, B = eos.fit()<br />

30 Chapter 6. Tutorials


print B / kJ * 1.0e24, ’GPa’<br />

eos.plot(’Ag-eos.png’)<br />

A quicker way to do this analysis, is to use the gui tool:<br />

$ ag Ag.traj<br />

And then choose Tools → Bulk modulus.<br />

6.2.7 Dissociation<br />

from ase import Atoms<br />

from ase.calculators.emt import EMT<br />

from ase.constraints import FixAtoms<br />

from ase.optimize import QuasiNewton<br />

from ase.io import write<br />

# Find the initial and final states for the reaction.<br />

# Set up a (3 x 3) two layer slab of Ru:<br />

a = 2.70<br />

c = 1.59 * a<br />

sqrt3 = 3. ** .5<br />

bulk = Atoms(’2Cu’, [(0., 0., 0.), (1./3, 1./3, -0.5*c)],<br />

tags=(1, 1),<br />

pbc=(1, 1, 0))<br />

bulk.set_cell([(a, 0, 0),<br />

(a / 2, sqrt3 * a / 2, 0),<br />

(0, 0, 1)])<br />

slab = bulk.repeat((4, 4, 1))<br />

# Initial state.<br />

# Add the molecule:<br />

x = a / 2.<br />

y = a * 3. ** .5 / 6.<br />

<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

6.2. <strong>ASE</strong> 31


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

z = 1.8<br />

d = 1.10 # N2 bond length<br />

# Molecular state parallel to the surface:<br />

slab += Atoms(’2N’, [(x, y, z), (x + sqrt3 * d / 2, y + d / 2, z)])<br />

# Use the EMT calculator for the forces and energies:<br />

slab.set_calculator(EMT())<br />

# We don’t want to worry about the Cu degrees of freedom:<br />

mask = [atom.symbol == ’Cu’ for atom in slab]<br />

slab.set_constraint(FixAtoms(mask=mask))<br />

relax = QuasiNewton(slab)<br />

relax.run(fmax=0.05)<br />

print ’initial state:’, slab.get_potential_energy()<br />

write(’N2.traj’, slab)<br />

# Now the final state.<br />

# Move the second N atom to a neighboring hollow site:<br />

slab[-1].set_position((x + a, y, z))<br />

relax.run()<br />

print ’final state: ’, slab.get_potential_energy()<br />

write(’2N.traj’, slab)<br />

import numpy as np<br />

from ase.io import read<br />

from ase.constraints import FixAtoms<br />

from ase.calculators.emt import EMT<br />

from ase.neb import NEB<br />

from ase.optimize import QuasiNewton<br />

initial = read(’N2.traj’)<br />

final = read(’2N.traj’)<br />

configs = [initial.copy() for i in range(8)] + [final]<br />

constraint = FixAtoms(mask=[atom.symbol != ’N’ for atom in initial])<br />

for config in configs:<br />

config.set_calculator(EMT())<br />

config.set_constraint(constraint)<br />

band = NEB(configs)<br />

band.interpolate()<br />

# Create a quickmin object:<br />

relax = QuasiNewton(band)<br />

relax.run(steps=20)<br />

e0 = initial.get_potential_energy()<br />

for config in configs:<br />

d = config[-2].position - config[-1].position<br />

print np.linalg.norm(d), config.get_potential_energy() - e0<br />

6.2.8 Dissociation using ANEB<br />

from ase import *<br />

# XXX This cannot be converted to ase 3, since we lack ANEB<br />

raise NotImplementedError<br />

32 Chapter 6. Tutorials


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

#from <strong>ASE</strong>.Calculators.PairPotential import PairPotential<br />

#from <strong>ASE</strong>.Filters.Subset import Subset<br />

#from <strong>ASE</strong>.Dynamics.AdaptiveNudgedElasticBand import AdaptiveNudgedElasticBand<br />

#from <strong>ASE</strong>.IO.NetCDF import ReadNetCDF<br />

import os<br />

# check that N2.nc and 2N.nc exists otherwise run<br />

# N2Ru-Dissociation1.py<br />

if not (os.path.exists(’N2.nc’) and os.path.exists(’N2.nc’)):<br />

os.system(’python N2Ru-Dissociation1.py’)<br />

initial = read(’N2.traj’)<br />

final = read(’2N.traj’)<br />

configs = [initial.copy() for i in range(4)] + [final]<br />

constraint = FixAtoms(mask=[atom.symbol != ’N’ for atom in initial])<br />

for config in configs:<br />

config.set_calculator(EMT())<br />

config.set_constraint(constraint)<br />

band = NEB(configs)<br />

band.interpolate()<br />

# Create a quickmin object:<br />

relax = QuasiNewton(band)<br />

#configs0 = [initial]<br />

#for i in range(3):<br />

# configs0.append(initial.Copy())<br />

#configs0.append(final)<br />

#<br />

#configs = []<br />

#for config in configs0:<br />

# config.SetCalculator(PairPotential())<br />

# configs.append(Subset(config, indices=[-2, -1]))<br />

# setup the Adaptive Nudged Elastic Band dynamics<br />

aneb = AdaptiveNudgedElasticBand(configs,prefix=’aneb’,linear_interpolation=True,maxlevels=1)<br />

aneb.Converge()<br />

# test the anebfit tool<br />

os.system(’anebfit aneb’)<br />

os.system(’xmgrace aneb_-1.agr&’)<br />

# clean up<br />

# os.system(’rm aneb*conf*’)<br />

6.2.9 Association<br />

from ase import *<br />

#from math import sqrt<br />

#from <strong>ASE</strong>.Calculators.PairPotential import PairPotential<br />

#from <strong>ASE</strong>.Filters.Subset import Subset<br />

#from <strong>ASE</strong>.Filters.FixBondLength import FixBondLength<br />

6.2. <strong>ASE</strong> 33


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

#from <strong>ASE</strong>.Dynamics.MDMin import MDMin<br />

#from <strong>ASE</strong>.Trajectories.NetCDFTrajectory import NetCDFTrajectory<br />

#from <strong>ASE</strong>.IO.NetCDF import ReadNetCDF<br />

slab = read(’2N.traj’)<br />

slab.set_calculator(EMT())<br />

constraint = FixBondLength(-2, -1)<br />

#mask=[atom.symbol != ’N’ for atom in slab])<br />

#molecule = Subset(slab, indices=[-2, -1])<br />

# Create a trajectory for the dissociation path:<br />

path = PickleTrajectory(’association.traj’, slab)<br />

# Put the initial state in the trajectory:<br />

path.write()<br />

# From now on, we relax the molecule under the constraint of fixed<br />

# bond length:<br />

#fixed = FixBondLength(molecule, 0, 1)<br />

#relax = MDMin(fixed, dt=0.08, fmax=0.05)<br />

relax = QuasiNewton(slab)<br />

d = linalg.norm(slab[-2].position - slab[-1].position)<br />

#d = fixed.GetBondLength()<br />

delta = 0.1<br />

e0 = slab.get_potential_energy()<br />

print d, 0.0<br />

while d > 1.10:<br />

d -= delta<br />

fixed.SetBondLength(d, fix=’first’)<br />

# XXX<br />

raise NotImplementedError<br />

relax.run(fmax=.05)<br />

path.write()<br />

print d, slab.GetPotentialEnergy() - e0<br />

6.2.10 Diffusion of gold atom on Al(100) surface (NEB)<br />

First, set up the initial and final states:<br />

34 Chapter 6. Tutorials


from ase.lattice.surface import fcc100, add_adsorbate<br />

from ase.constraints import FixAtoms<br />

from ase.calculators.emt import EMT<br />

from ase.optimize import QuasiNewton<br />

# 2x2-Al(001) surface with 3 layers and an<br />

# Au atom adsorbed in a hollow site:<br />

slab = fcc100(’Al’, size=(2, 2, 3))<br />

add_adsorbate(slab, ’Au’, 1.7, ’hollow’)<br />

slab.center(axis=2, vacuum=4.0)<br />

# Make sure the structure is correct:<br />

#view(slab)<br />

# Fix second and third layers:<br />

mask = [atom.tag > 1 for atom in slab]<br />

#print mask<br />

slab.set_constraint(FixAtoms(mask=mask))<br />

# Use EMT potential:<br />

slab.set_calculator(EMT())<br />

# Initial state:<br />

qn = QuasiNewton(slab, trajectory=’initial.traj’)<br />

qn.run(fmax=0.05)<br />

# Final state:<br />

slab[-1].x += slab.get_cell()[0, 0] / 2<br />

qn = QuasiNewton(slab, trajectory=’final.traj’)<br />

qn.run(fmax=0.05)<br />

Note: Notice how the tags are used to select the constrained atoms<br />

Now, do the NEB calculation:<br />

from ase.io import read<br />

from ase.constraints import FixAtoms<br />

from ase.calculators.emt import EMT<br />

from ase.neb import NEB<br />

from ase.optimize import BFGS<br />

initial = read(’initial.traj’)<br />

final = read(’final.traj’)<br />

constraint = FixAtoms(mask=[atom.tag > 1 for atom in initial])<br />

images = [initial]<br />

for i in range(3):<br />

image = initial.copy()<br />

image.set_calculator(EMT())<br />

image.set_constraint(constraint)<br />

images.append(image)<br />

images.append(final)<br />

neb = NEB(images)<br />

neb.interpolate()<br />

qn = BFGS(neb, trajectory=’neb.traj’)<br />

qn.run(fmax=0.05)<br />

<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

6.2. <strong>ASE</strong> 35


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

Note: For this reaction, the reaction coordinate is very simple: The x-coordinate of the Au atom. In such cases,<br />

the NEB method is overkill, and a simple constraint method should be used like in this tutorial: Diffusion of gold<br />

atom on Al(100) surface (constraint).<br />

See Also:<br />

• neb<br />

• constraints<br />

• Diffusion of gold atom on Al(100) surface (constraint)<br />

• fcc100()<br />

Parallelizing over images<br />

Instead of having one process do the calculations for all three internal images in turn, it will be faster to have three<br />

processes do one image each. This can be done like this:<br />

from ase.io import read<br />

from ase.constraints import FixAtoms<br />

from ase.calculators.emt import EMT<br />

from ase.neb import NEB<br />

from ase.optimize import BFGS<br />

from ase.io.trajectory import PickleTrajectory<br />

from ase.parallel import rank, size<br />

initial = read(’initial.traj’)<br />

final = read(’final.traj’)<br />

constraint = FixAtoms(mask=[atom.tag > 1 for atom in initial])<br />

images = [initial]<br />

j = rank * 3 // size # my image number<br />

for i in range(3):<br />

image = initial.copy()<br />

if i == j:<br />

image.set_calculator(EMT())<br />

image.set_constraint(constraint)<br />

images.append(image)<br />

images.append(final)<br />

36 Chapter 6. Tutorials


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

neb = NEB(images, parallel=True)<br />

neb.interpolate()<br />

qn = BFGS(neb)<br />

if rank % (size // 3) == 0:<br />

traj = PickleTrajectory(’neb%d.traj’ % j, ’w’, images[1 + j], master=True)<br />

qn.attach(traj)<br />

qn.run(fmax=0.05)<br />

6.2.11 Diffusion of gold atom on Al(100) surface (constraint)<br />

In this tutorial, we will calculate the energy barrier that was found using the NEB method in the Diffusion of gold<br />

atom on Al(100) surface (NEB) tutorial. Here, we use a siple FixedPlane constraint that forces the Au atom to<br />

relax in the yz-plane only:<br />

from ase.lattice.surface import fcc100, add_adsorbate<br />

from ase.constraints import FixAtoms, FixedPlane<br />

from ase.calculators.emt import EMT<br />

from ase.optimize import QuasiNewton<br />

# 2x2-Al(001) surface with 3 layers and an<br />

# Au atom adsorbed in a hollow site:<br />

slab = fcc100(’Al’, size=(2, 2, 3))<br />

add_adsorbate(slab, ’Au’, 1.7, ’hollow’)<br />

slab.center(axis=2, vacuum=4.0)<br />

# Make sure the structure is correct:<br />

#view(slab)<br />

# Fix second and third layers:<br />

mask = [atom.tag > 1 for atom in slab]<br />

#print mask<br />

fixlayers = FixAtoms(mask=mask)<br />

# Constrain the last atom (Au atom) to move only in the yz-plane:<br />

plane = FixedPlane(-1, (1, 0, 0))<br />

slab.set_constraint([fixlayers, plane])<br />

# Use EMT potential:<br />

slab.set_calculator(EMT())<br />

# Initial state:<br />

for i in range(5):<br />

qn = QuasiNewton(slab, trajectory=’mep%d.traj’ % i)<br />

qn.run(fmax=0.05)<br />

slab[-1].x += slab.get_cell()[0, 0] / 8<br />

The result can be analysed with the command ag mep?.traj -n -1 (choose Tools → NEB). The barrier is found to<br />

be 0.35 eV - exactly as in the NEB tutorial.<br />

Here is a side-view of the path (unit cell repeated twice):<br />

6.2. <strong>ASE</strong> 37


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

See Also:<br />

• neb<br />

• constraints<br />

• Diffusion of gold atom on Al(100) surface (NEB)<br />

• fcc100()<br />

6.2.12 Molecular dynamics<br />

Note: These examples can be used without Asap installed, then the ase.EMT calculator (implemented in Python)<br />

is used, but nearly superhuman patience is required.<br />

Here we demonstrate now simple molecular dynamics is performed. A crystal is set up, the atoms are given<br />

momenta corresponding to a temperature of 300K, then Newtons second law is integrated numerically with a time<br />

step of 5 fs (a good choice for copper).<br />

"Demonstrates molecular dynamics with constant energy."<br />

from ase.calculators.emt import EMT<br />

from ase.lattice.cubic import FaceCenteredCubic<br />

from ase.md.velocitydistribution import MaxwellBoltzmannDistribution<br />

from ase.md.verlet import VelocityVerlet<br />

from ase import units<br />

# Use Asap for a huge performance increase if it is installed<br />

useAsap = False<br />

if useAsap:<br />

from asap3 import EMT<br />

size = 10<br />

else:<br />

size = 3<br />

# Set up a crystal<br />

atoms = FaceCenteredCubic(directions=[[1,0,0],[0,1,0],[0,0,1]], symbol="Cu",<br />

size=(size,size,size), pbc=True)<br />

# Describe the interatomic interactions with the Effective Medium Theory<br />

38 Chapter 6. Tutorials


atoms.set_calculator(EMT())<br />

# Set the momenta corresponding to T=300K<br />

MaxwellBoltzmannDistribution(atoms, 300*units.kB)<br />

<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

# We want to run MD with constant energy using the VelocityVerlet algorithm.<br />

dyn = VelocityVerlet(atoms, 5*units.fs) # 5 fs time step.<br />

#Function to print the potential, kinetic and total energy<br />

def printenergy(a):<br />

epot = a.get_potential_energy() / len(a)<br />

ekin = a.get_kinetic_energy() / len(a)<br />

print ("Energy per atom: Epot = %.3feV Ekin = %.3feV (T=%3.0fK) Etot = %.3feV" %<br />

(epot, ekin, ekin/(1.5*units.kB), epot+ekin))<br />

# Now run the dynamics<br />

printenergy(atoms)<br />

for i in range(20):<br />

dyn.run(10)<br />

printenergy(atoms)<br />

Note how the total energy is conserved, but the kinetic energy quickly drops to half the expected value. Why?<br />

Instead of printing within a loop, it is possible to use an “observer” to observe the atoms and do the printing (or<br />

more sophisticated analysis).<br />

"Demonstrates molecular dynamics with constant energy."<br />

from ase.calculators.emt import EMT<br />

from ase.lattice.cubic import FaceCenteredCubic<br />

from ase.md.velocitydistribution import MaxwellBoltzmannDistribution<br />

from ase.md.verlet import VelocityVerlet<br />

from ase import units<br />

# Use Asap for a huge performance increase if it is installed<br />

useAsap = True<br />

if useAsap:<br />

from asap3 import EMT<br />

size = 10<br />

else:<br />

size = 3<br />

# Set up a crystal<br />

atoms = FaceCenteredCubic(directions=[[1,0,0],[0,1,0],[0,0,1]], symbol="Cu",<br />

size=(size,size,size), pbc=True)<br />

# Describe the interatomic interactions with the Effective Medium Theory<br />

atoms.set_calculator(EMT())<br />

# Set the momenta corresponding to T=300K<br />

MaxwellBoltzmannDistribution(atoms, 300*units.kB)<br />

# We want to run MD with constant energy using the VelocityVerlet algorithm.<br />

dyn = VelocityVerlet(atoms, 5*units.fs) # 5 fs time step.<br />

#Function to print the potential, kinetic and total energy.<br />

def printenergy(a=atoms): #store a reference to atoms in the definition.<br />

epot = a.get_potential_energy() / len(a)<br />

ekin = a.get_kinetic_energy() / len(a)<br />

print ("Energy per atom: Epot = %.3feV Ekin = %.3feV (T=%3.0fK) Etot = %.3feV" %<br />

(epot, ekin, ekin/(1.5*units.kB), epot+ekin))<br />

6.2. <strong>ASE</strong> 39


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

# Now run the dynamics<br />

dyn.attach(printenergy, interval=10)<br />

printenergy()<br />

dyn.run(200)<br />

Constant temperature MD<br />

Often, you want to control the temperature of an MD simulation. This can be done with the Langevin dynamics<br />

module. In the previous examples, replace the line dyn = VelocityVerlet(...) with:<br />

dyn = Langevin(atoms, 5*units.fs, T*units.kB, 0.002)<br />

where T is the desired temperature in Kelvin. You also need to import Langevin, see the class below.<br />

The Langevin dynamics will then slowly adjust the total energy of the system so the temperature approaches the<br />

desired one.<br />

As a slightly less boring example, let us use this to melt a chunck of copper by starting the simulation without any<br />

momentum of the atoms (no kinetic energy), and with a desired temperature above the melting point. We will also<br />

save information about the atoms in a trajectory file called moldyn3.traj.<br />

"Demonstrates molecular dynamics with constant energy."<br />

from ase.calculators.emt import EMT<br />

from ase.lattice.cubic import FaceCenteredCubic<br />

from ase.md.langevin import Langevin<br />

from ase.io.trajectory import PickleTrajectory<br />

from ase import units<br />

from asap3 import EMT # Way too slow with ase.EMT !<br />

size = 10<br />

T = 1500 # Kelvin<br />

# Set up a crystal<br />

atoms = FaceCenteredCubic(directions=[[1,0,0],[0,1,0],[0,0,1]], symbol="Cu",<br />

size=(size,size,size), pbc=False)<br />

# Describe the interatomic interactions with the Effective Medium Theory<br />

atoms.set_calculator(EMT())<br />

# We want to run MD with constant energy using the Langevin algorithm<br />

# with a time step of 5 fs, the temperature T and the friction<br />

# coefficient to 0.02 atomic units.<br />

dyn = Langevin(atoms, 5*units.fs, T*units.kB, 0.002)<br />

#Function to print the potential, kinetic and total energy.<br />

def printenergy(a=atoms): #store a reference to atoms in the definition.<br />

epot = a.get_potential_energy() / len(a)<br />

ekin = a.get_kinetic_energy() / len(a)<br />

print ("Energy per atom: Epot = %.3feV Ekin = %.3feV (T=%3.0fK) Etot = %.3feV" %<br />

(epot, ekin, ekin/(1.5*units.kB), epot+ekin))<br />

dyn.attach(printenergy, interval=50)<br />

#We also want to save the positions of all atoms after every 100th time step.<br />

traj = PickleTrajectory("moldyn3.traj", ’w’, atoms)<br />

dyn.attach(traj.write, interval=50)<br />

# Now run the dynamics<br />

printenergy()<br />

dyn.run(5000)<br />

After running the simulation, you can study the result with the command<br />

40 Chapter 6. Tutorials


ag moldyn3.traj<br />

<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

Try plotting the kinetic energy. You will not see a well-defined melting point due to finite size effects (including<br />

surface melting), but you will probably see an almost flat region where the inside of the system melts. The<br />

outermost layers melt at a lower temperature.<br />

Note: The Langevin dynamics will by default keep the position and momentum of the center of mass unperturbed.<br />

This is another improvement over just setting momenta corresponding to a temperature, as we did before.<br />

Isolated particle MD<br />

When simulating isolated particles with MD, it is sometimes preferable to set random momenta corresponding to<br />

a spefic temperature and let the system evolve freely. With a relatively high temperature, the is however a risk that<br />

the collection of atoms will drift out of the simulation box because the randomized momenta gave the center of<br />

mass a small but non-zero velocity too.<br />

Let us see what happens when we propagate a nanoparticle for a long time:<br />

"Demonstrates molecular dynamics for isolated particles."<br />

from ase.calculators.emt import EMT<br />

from ase.cluster.cubic import FaceCenteredCubic<br />

from ase.optimize import QuasiNewton<br />

from ase.md.velocitydistribution import MaxwellBoltzmannDistribution, \<br />

Stationary, ZeroRotation<br />

from ase.md.verlet import VelocityVerlet<br />

from ase import units<br />

# Use Asap for a huge performance increase if it is installed<br />

useAsap = True<br />

if useAsap:<br />

from asap3 import EMT<br />

size = 4<br />

else:<br />

size = 2<br />

# Set up a nanoparticle<br />

atoms = FaceCenteredCubic(’Cu’, surfaces=[[1,0,0],[1,1,0],[1,1,1]],<br />

layers=(size,size,size), vacuum=4)<br />

# Describe the interatomic interactions with the Effective Medium Theory<br />

atoms.set_calculator(EMT())<br />

# Do a quick relaxation of the cluster<br />

qn = QuasiNewton(atoms)<br />

qn.run(0.001, 10)<br />

# Set the momenta corresponding to T=1200K<br />

MaxwellBoltzmannDistribution(atoms, 1200*units.kB)<br />

Stationary(atoms) # zero linear momentum<br />

ZeroRotation(atoms) # zero angular momentum<br />

# We want to run MD using the VelocityVerlet algorithm.<br />

dyn = VelocityVerlet(atoms, 5*units.fs, trajectory=’moldyn4.traj’) # save trajectory.<br />

#Function to print the potential, kinetic and total energy.<br />

def printenergy(a=atoms): #store a reference to atoms in the definition.<br />

epot = a.get_potential_energy() / len(a)<br />

ekin = a.get_kinetic_energy() / len(a)<br />

6.2. <strong>ASE</strong> 41


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

print ("Energy per atom: Epot = %.3feV Ekin = %.3feV (T=%3.0fK) Etot = %.3feV" %<br />

(epot, ekin, ekin/(1.5*units.kB), epot+ekin))<br />

dyn.attach(printenergy, interval=10)<br />

# Now run the dynamics<br />

printenergy()<br />

dyn.run(2000)<br />

After running the simulation, use ag to compare the results with how it looks if you comment out either the line<br />

that says Stationary (atoms), ZeroRotation (atoms) or both.<br />

ag moldyn4.traj<br />

Try playing the movie with a high frame rate and set frame skipping to a low number. Can you spot the subtle<br />

difference?<br />

6.2.13 Tutorial: STM images - Al(100)<br />

The STM is a revolutionary experimental surface probe that has provided direct local insight into the surface<br />

electronic structure. Sometimes the interpretation of STM topographs are not straightforward and therefore theoretically<br />

modeled STM images may resolve conflicting possibilities and point to an underlying atomistic model.<br />

The CAMPOS code includes python modules for generating Tersoff-Hamann STM topographs. The STM code is<br />

illustrated here for a Al(100) in a 2x2 unit cell.<br />

Let’s make the Al(100) fcc surface by using the lattice module:<br />

from ase.lattice.surface import *<br />

atoms = fcc100(’Al’, size=(2,2,2))<br />

Now a calculator must be defined, in this tutorial we will make a STM image from the GPAW calculator.<br />

For the GPAW code the calculator for the Al(100) surface can be defined like this:<br />

from gpaw import GPAW<br />

calc = GPAW(gpts=(28,28,20),nbands=28,<br />

kpts=(4,4,1),txt=’Al100.out’)<br />

atoms.set_calculator(calc)<br />

energy = atoms.get_potential_energy()<br />

calc.write(’Al100.gpw’, ’all’)<br />

Linescans<br />

In this section we will make simulated STM linescans and contour plot using matplotlib. First initialize the STM<br />

object and get the averaged current along the z-direction:<br />

from ase import STM<br />

stm = STM(atoms, symmetries=[0, 1, 2])<br />

z = 2.5<br />

c = stm.get_averaged_current(z)<br />

From the current we make a scan to get a 2D array of constant current heights:<br />

h = stm.scan(c)<br />

Finally we make a contour plot:<br />

import pylab as p<br />

p.contourf(h, 40)<br />

p.hot()<br />

p.colorbar()<br />

p.show()<br />

42 Chapter 6. Tutorials


6.2.14 Partly occupied Wannier Functions<br />

from ase.data.molecules import molecule<br />

from gpaw import GPAW<br />

atoms = molecule(’C6H6’)<br />

atoms.center(vacuum=3.5)<br />

calc = GPAW(h=.21, xc=’PBE’, txt=’benzene.txt’, nbands=18)<br />

atoms.set_calculator(calc)<br />

atoms.get_potential_energy()<br />

calc.set(fixdensity=True, txt=’benzene-harris.txt’,<br />

nbands=40, eigensolver=’cg’, convergence={’bands’: 35})<br />

atoms.get_potential_energy()<br />

calc.write(’benzene.gpw’, mode=’all’)<br />

from gpaw import restart<br />

from ase.dft import Wannier<br />

atoms, calc = restart(’benzene.gpw’, txt=None)<br />

# Make wannier functions of occupied space only<br />

wan = Wannier(nwannier=15, calc=calc)<br />

wan.localize()<br />

for i in range(wan.nwannier):<br />

wan.write_cube(i, ’benzene15_%i.cube’ % i)<br />

# Make wannier functions using (three) extra degrees of freedom.<br />

wan = Wannier(nwannier=18, calc=calc, fixedstates=15)<br />

wan.localize()<br />

wan.save(’wan18.pickle’)<br />

for i in range(wan.nwannier):<br />

wan.write_cube(i, ’benzene18_%i.cube’ % i)<br />

from ase.dft import Wannier<br />

from gpaw import restart<br />

<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

atoms, calc = restart(’benzene.gpw’, txt=None)<br />

wan = Wannier(nwannier=18, calc=calc, fixedstates=15, file=’wan18.pickle’)<br />

import pylab as pl<br />

weight_n = pl.sum(abs(wan.V_knw[0])**2, 1)<br />

N = len(weight_n)<br />

F = wan.fixedstates_k[0]<br />

pl.figure(1, figsize=(12, 4))<br />

pl.bar(range(1, N+1), weight_n, width=0.65, bottom=0,<br />

color=’k’, edgecolor=’k’, linewidth=None,<br />

align=’center’, orientation=’vertical’)<br />

pl.plot([F+.5, F+.5], [0, 1], ’k--’)<br />

pl.axis(xmin=.32, xmax=N+1.33, ymin=0, ymax=1)<br />

pl.xlabel(’Eigenstate’)<br />

pl.ylabel(’Projection of wannier functions’)<br />

pl.savefig(’spectral_weight.png’)<br />

pl.show()<br />

import numpy as np<br />

from ase import Atoms<br />

from ase.dft.kpoints import monkhorst_pack<br />

from gpaw import GPAW<br />

6.2. <strong>ASE</strong> 43


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

kpts = monkhorst_pack((13, 1, 1)) + [1e-5, 0, 0]<br />

calc = GPAW(h=.21, xc=’PBE’, kpts=kpts, nbands=12, txt=’poly.txt’,<br />

eigensolver=’cg’, convergence={’bands’: 9})<br />

CC = 1.38<br />

CH = 1.094<br />

a = 2.45<br />

x = a / 2.<br />

y = np.sqrt(CC**2 - x**2)<br />

atoms = Atoms(’C2H2’, pbc=(True, False, False), cell=(a, 8., 6.),<br />

calculator=calc, positions=[[0, 0, 0],<br />

[x, y, 0],<br />

[x, y+CH, 0],<br />

[0, -CH, 0]])<br />

atoms.center()<br />

atoms.get_potential_energy()<br />

calc.write(’poly.gpw’, mode=’all’)<br />

import numpy as np<br />

from ase.dft import Wannier<br />

from gpaw import restart<br />

atoms, calc = restart(’poly.gpw’, txt=None)<br />

# Make wannier functions using (one) extra degree of freedom<br />

wan = Wannier(nwannier=6, calc=calc, fixedenergy=1.5)<br />

wan.localize()<br />

wan.save(’poly.pickle’)<br />

wan.translate_all_to_cell((2, 0, 0))<br />

for i in range(wan.nwannier):<br />

wan.write_cube(i, ’polyacetylene_%i.cube’ % i)<br />

# Print Kohn-Sham bandstructure<br />

ef = calc.get_fermi_level()<br />

f = open(’KSbands.txt’, ’w’)<br />

for k, kpt_c in enumerate(calc.get_ibz_k_points()):<br />

for eps in calc.get_eigenvalues(kpt=k):<br />

print >> f, kpt_c[0], eps - ef<br />

# Print Wannier bandstructure<br />

f = open(’WANbands.txt’, ’w’)<br />

for k in np.linspace(-.5, .5, 100):<br />

for eps in np.linalg.eigvalsh(wan.get_hamiltonian_kpoint([k, 0, 0])).real:<br />

print >> f, k, eps - ef<br />

import pylab as pl<br />

fig = pl.figure(1, dpi=80, figsize=(4.2, 6))<br />

fig.subplots_adjust(left=.16, right=.97, top=.97, bottom=.05)<br />

# Plot KS bands<br />

k, eps = pl.load(’KSbands.txt’, unpack=True)<br />

pl.plot(k, eps, ’ro’, label=’DFT’, ms=9)<br />

# Plot Wannier bands<br />

k, eps = pl.load(’WANbands.txt’, unpack=True)<br />

pl.plot(k, eps, ’k.’, label=’Wannier’)<br />

pl.plot([-.5, .5], [1, 1], ’k:’, label=’_nolegend_’)<br />

pl.text(-.5, 1, ’fixedenergy’, ha=’left’, va=’bottom’)<br />

pl.axis(’tight’)<br />

pl.xticks([-.5, -.25, 0, .25, .5],<br />

44 Chapter 6. Tutorials


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

[ r’$X$’, r’$\Delta$’, r’$\Gamma$’, r’$\Delta$’, r’$X$’], size=16)<br />

pl.ylabel(r’$E - E_F\ \rm{(eV)}$’, size=16)<br />

pl.legend()<br />

pl.savefig(’bands.png’, dpi=80)<br />

pl.show()<br />

6.3 NumPy<br />

If your <strong>ASE</strong> scripts make extensive use of matrices you may want to familiarize yourself with Numeric arrays in<br />

Python.<br />

6.3.1 Numeric arrays in Python<br />

Links to NumPy’s webpage:<br />

• Numpy and Scipy Documentation<br />

• Numpy guide book<br />

• Numpy example list<br />

• Numpy functions by category<br />

<strong>ASE</strong> makes heavy use of an extension to Python called NumPy. The NumPy module defines an ndarray type that<br />

can hold large arrays of uniform multidimensional numeric data. An array is similar to a list or a tuple, but<br />

it is a lot more powerful and efficient.<br />

XXX More examples from everyday <strong>ASE</strong>-life here ...<br />

>>> import numpy as np<br />

>>> a = np.zeros((3, 2))<br />

>>> a[:, 1] = 1.0<br />

>>> a[1] = 2.0<br />

>>> a<br />

array([[ 0., 1.],<br />

[ 2., 2.],<br />

[ 0., 1.]])<br />

>>> a.shape<br />

(3, 2)<br />

>>> a.ndim<br />

2<br />

The conventions of numpy’s linear algebra package:<br />

>>> import numpy as np<br />

>>><br />

>>> # Make a random hermitian matrix, H<br />

>>> H = np.random.rand(6, 6) + 1.j * np.random.rand(6, 6)<br />

>>> H = H + H.T.conj()<br />

>>><br />

>>> # Determine eigenvalues and rotation matrix<br />

>>> eps, U = np.linalg.eigh(H)<br />

>>><br />

>>> # Sort eigenvalues<br />

>>> sorted_indices = eps.real.argsort()<br />

>>> eps = eps[sorted_indices]<br />

>>> U = U[:, sorted_indices]<br />

>>><br />

>>> # Make print of numpy arrays less messy:<br />

>>> np.set_printoptions(precision=3, suppress=True)<br />

>>><br />

6.3. NumPy 45


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

>>> # Check that U diagonalizes H:<br />

>>> print np.dot(np.dot(U.T.conj(), H), U) - np.diag(eps)<br />

>>> print np.allclose(np.dot(np.dot(U.T.conj(), H), U), np.diag(eps))<br />

>>><br />

>>> # The eigenvectors of H are the *coloumns* of U:<br />

>>> np.allclose(np.dot(H, U[:, 3]), eps[3] * U[:, 3])<br />

>>> np.allclose(np.dot(H, U), eps * U)<br />

The rules for multiplying 1D arrays with 2D arrays:<br />

• 1D arrays and treated like shape (1, N) arrays (row vectors).<br />

• left and right multiplications are treated identically.<br />

• A length m row vector can be multiplied with an n x m matrix, producing the same result as if replaced by a<br />

matrix with n copies of the vector as rows.<br />

• A length n column vector can be multiplied with an n x m matrix, producing the same result as if replaced<br />

by a matrix with m copies of the vector as columns.<br />

Thus, for the arrays below:<br />

>>> M = np.arange(5 * 6).reshape(5, 6) # A matrix af shape (5, 6)<br />

>>> v5 = np.arange(5) + 10 # A vector of length 5<br />

>>> v51 = v5[:, None] # A length 5 coulomn vector<br />

>>> v6 = np.arange(6) - 12 # A vector of length 6<br />

>>> v16 = v6[None, :] # A length 6 row vector<br />

The following identities hold:<br />

v6 * M == v16 * M == M * v6 == M * v16 == M * v16.repeat(5, 0)<br />

v51 * M == M * v51 == M * v51.repeat(6, 1)<br />

The exact same rules apply for adding and subtracting 1D arrays to / from 2D arrays.<br />

6.4 Further reading<br />

For more details:<br />

• Look at the documentation for the individual modules.<br />

• See the automatically generated documentation Epydoc: ase.<br />

• Browse the source code online.<br />

• Have a look at siesta exercises:<br />

6.4.1 Exercises<br />

Note: <strong>CAMd</strong> summer school participants should read this page before doing the SIESTA exercises.<br />

Exercise 2 contains a script which takes somewhat long time. For this reason you may want to submit the script<br />

to Niflheim in advance, before analyzing the results in Exercise 1.<br />

Siesta 1: Basis Sets<br />

This exercise is intended to illustrate the definition of basis sets with different numbers of orbitals and localization<br />

radii in SIESTA. It is based on the H2O molecule. You will first use standard basis sets generated by SIESTA,<br />

and then a basis set specifically optimized for the H2O molecule. The tips at the end of this page will help you in<br />

analyzing the results of the calculations.<br />

46 Chapter 6. Tutorials


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

We are going to use the <strong>ASE</strong> interface to the siesta calculator, for the official SIESTA documentation see here.<br />

Part 1: Standard basis sets<br />

In the following script you will relax the structure of the H2O molecule to find its equilibrium structure.<br />

import time<br />

import numpy as np<br />

from ase import Atoms, units<br />

from ase.optimize import QuasiNewton<br />

from ase.calculators.siesta import Siesta<br />

# Set up a H2O molecule by specifying atomic positions<br />

h2o = Atoms(symbols=’H2O’,<br />

positions=[( 0.776070, 0.590459, 0.00000),<br />

(-0.776070, 0.590459, 0.00000),<br />

(0.000000, -0.007702, -0.000001)],<br />

pbc=(1,1,1))<br />

# Center the molecule in the cell with some vacuum around<br />

h2o.center(vacuum=6.0)<br />

# Select some energy-shifts for the basis orbitals<br />

e_shifts = [0.01,0.1,0.2,0.3,0.4,0.5]<br />

# Run the relaxation for each energy shift, and print out the<br />

# corresponding total energy, bond length and angle<br />

for e_s in e_shifts:<br />

starttime = time.time()<br />

calc = Siesta(’h2o’,meshcutoff=200.0 * units.Ry, mix=0.5, pulay=4)<br />

calc.set_fdf(’PAO.EnergyShift’, e_s * units.eV)<br />

calc.set_fdf(’PAO.SplitNorm’, 0.15)<br />

calc.set_fdf(’PAO.BasisSize’, ’SZ’)<br />

h2o.set_calculator(calc)<br />

# Make a -traj file named h2o_current_shift.traj:<br />

dyn = QuasiNewton(h2o, trajectory=’h2o_%s.traj’ % e_s)<br />

dyn.run(fmax=0.02) # Perform the relaxation<br />

E = h2o.get_potential_energy()<br />

print # Make the output more readable<br />

print "E_shift: %.2f" %e_s<br />

print "----------------"<br />

print "Total Energy: %.4f" % E # Print total energy<br />

d = h2o.get_distance(0,2)<br />

print "Bond length: %.4f" % d # Print bond length<br />

p = h2o.positions<br />

d1 = p[0] - p[2]<br />

d2 = p[1] - p[2]<br />

r = np.dot(d1, d2) / (np.linalg.norm(d1) * np.linalg.norm(d2))<br />

angle = np.arccos(r) / pi * 180<br />

print "Bond angle: %.4f" % angle # Print bond angle<br />

endtime = time.time()<br />

walltime = endtime - starttime<br />

print ’Wall time: %.5f’ % walltime<br />

print # Make the output more readable<br />

Run the script using three different basis sets: single-Z (SZ), double-Z (DZ) and double-Z plus polarization (DZP).<br />

Run it in different directories for each basis set, since the run will produce a large amount of output files. The<br />

bases are defined in the script through these three lines:<br />

6.4. Further reading 47


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

calc.set_fdf(’PAO.BasisSize’,’SZ’)<br />

calc.set_fdf(’PAO.EnergyShift’,e_s * eV)<br />

calc.set_fdf(’PAO.SplitNorm’,0.15)<br />

For each of the basis sets the script will run the relaxation for different EnergyShift parameters. Look at the<br />

results as a function of basis size and localization radius (or energy shift).<br />

In particular, you should look at:<br />

• Total energy<br />

• Bond lenghts at the relaxed structure<br />

• Bond angles at the relaxed structure<br />

• Execution time<br />

• Radius of each of the orbitals<br />

• Shape of the orbitals<br />

The script will print bond lengths and angles, total energy plus the wall time for each energy shift. The radii of the<br />

orbitals from the last run can be found in the file h2o.txt along with miscellaneous other informations. Orbital<br />

shapes from the last run are stored in the ORB.* files, which contain the value of the orbitals versus radius. (Note<br />

that the standard way to plot the orbitals is to multiply the orbital by r l ).<br />

You can visualize both the static atoms and the relaxation trajectory using the the <strong>ASE</strong> gui. For example you can<br />

visualize the relaxation trajectory from the command line by doing:<br />

$ ag h2o_0.1.traj<br />

Note that you will get a trajectory file .traj for each energy shift in the loop.<br />

Try to get plots like the following, obtained for a SZ basis:<br />

48 Chapter 6. Tutorials


Try to answer these questions:<br />

1. What is the best basis set that you have found? Why?<br />

2. How do the results compare with experiment?<br />

<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

3. What do you consider a reasonable basis for the molecule, if you need an accuracy in the geometry of about<br />

1%?<br />

4. In order to assess convergence with respect to basis set size, should you compare the results with the experimental<br />

ones, or with those of a converged basis set calculation?<br />

Part 2: Optimized basis sets<br />

You will now do the same calculations as in Part 1, but now using a basis set specifically optimized for the H2O<br />

molecule. Use the following optimized block instead of the basis-definition lines in Part1:<br />

calc.set_fdf(’PAO.Basis’,<br />

["""H 2 0.22<br />

n=1 0 2 E 2.07 0.00<br />

4.971 1.771<br />

1.000 1.000<br />

n=2 1 1 E 0.89 0.01<br />

4.988<br />

1.000<br />

O 3 -0.20<br />

n=2 0 2 E 0.00 1.31<br />

5.000 2.581<br />

1.000 1.000<br />

n=2 1 2 E 0.00 5.28<br />

6.500 2.487<br />

1.000 1.000<br />

n=3 2 1 E 104.31 0.00<br />

3.923<br />

1.000"""])<br />

Compare the parameters with those of the calculations in Part 1.<br />

Do the runs with this basis set, and compare the results with the previous ones.<br />

Tips<br />

Tip 1: You can see the radii of the orbitals in the output file, just after the line reading:<br />

6.4. Further reading 49


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

printput: Basis input ----------------------------------------------<br />

Tip 2: You can look at the shape of the orbitals by plotting the contents of the ORB* files generated by SIESTA.<br />

Tip 3: You will find a lot of information on the run in the .txt output file<br />

Tip 4: In ag you can select View → VMD to start the VMD viewer. There you can change the atom representation<br />

to what you feel is more convenient. Do that by selecting Graphics → Representations in the top bar.<br />

Tip 5: SIESTA will store basis functions in ORB.* files. These files can be plotted using the xmgrace command<br />

on the GBAR like this:<br />

$ xmgrace ORB.S1.1.O ORB.S2.1.O<br />

Siesta 2: Molecular Dynamics<br />

This exercise is intended to illustrate a Molecular Dynamics run with the SIESTA calculator. The system is a<br />

Si(001) surface, in the 2x1 reconstruction with asymmetric dimers. The simulation cell contains two dimers. An<br />

H2 molecule approaches the surface, above one of the dimers, and dissociates, ending up with a H atom bonded<br />

to each of the Si atoms in the dimer (and thus leading to a symmetric dimer). You can get the xyz file with the<br />

initial geometry doc/exercises/siesta2/geom.xyz.<br />

#!/usr/bin/env python<br />

from ase.io import read<br />

from ase.constraints import FixAtoms<br />

from ase.calculators.siesta import Siesta<br />

from ase.md import VelocityVerlet<br />

from ase import units<br />

# Read in the geometry from a xyz file, set the cell, boundary conditions and center<br />

atoms = read(’geom.xyz’)<br />

atoms.set_cell([7.66348,7.66348,7.66348*2])<br />

atoms.set_pbc((1,1,1))<br />

atoms.center()<br />

# Set initial velocities for hydrogen atoms along the z-direction<br />

p = atoms.get_momenta()<br />

p[0,2]= -1.5<br />

p[1,2]= -1.5<br />

atoms.set_momenta(p)<br />

# Keep some atoms fixed during the simulation<br />

atoms.set_constraint(FixAtoms(indices=range(18,38)))<br />

# Set the calculator and attach it to the system<br />

calc = Siesta(’si001+h2’,basis=’SZ’,xc=’PBE’,meshcutoff=50*units.Ry)<br />

calc.set_fdf(’PAO.EnergyShift’, 0.25 * units.eV)<br />

calc.set_fdf(’PAO.SplitNorm’, 0.15)<br />

atoms.set_calculator(calc)<br />

# Set the VelocityVerlet algorithm and run it<br />

dyn = VelocityVerlet(atoms,dt=1.0 * units.fs,trajectory=’si001+h2.traj’)<br />

dyn.run(steps=100)<br />

Note that both H atoms are given an initial velocity towards the surface through the lines:<br />

p = atoms.get_momenta()<br />

p[0,2]= -1.5<br />

p[1,2]= -1.5<br />

atoms.set_momenta(p)<br />

Run the program, and check the results. You can visualize the dynamics using the trajectory file with the help of<br />

the <strong>ASE</strong> gui. For example you can visualize the behaviour of the potential and total energies during the dynamics<br />

50 Chapter 6. Tutorials


y doing:<br />

$ ag -b si001+h2.traj -g i,e,e+ekin<br />

<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

The -b option turns on plotting of bonds between the atoms. Check that the total energy is a conserved quantity<br />

in this microcanonical simulation.<br />

You can also use VMD to visualize the trajectory. To do this, you need a .xyz file that you can write using ag:<br />

$ ag si001+h2.traj -o si.xyz -r 2,2,1<br />

Then simply open the file using VMD:<br />

$ vmd si.xyz<br />

and set Graphics/Representations from the main menu in order to get a nice picture.<br />

You can also try to repeat the simulation with a different dynamics. For instance you can model a canonical<br />

ensemble with the Langevin dynamics, which couples the system to a heat bath:<br />

dyn = Langevin(atoms, 1 * fs, kB * 300, 0.002, trajectory=traj)<br />

6.5 Videos<br />

The following video tutorials are available:<br />

• Overview and installation of <strong>ASE</strong>, by Anthony Goodrow (duration: ~5min 30sec; size: 26 MB) - en:<br />

6.5. Videos 51


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

52 Chapter 6. Tutorials


CHAPTER<br />

SEVEN<br />

DOCUMENTATION FOR MODULES IN<br />

<strong>ASE</strong><br />

Quick links:<br />

atom atoms calculators constraints dft<br />

data gui infrared io lattice<br />

md neb optimize parallel phonons<br />

spacegroup structure surface transport thermochemistry<br />

units utils vibrations visualize vtk<br />

See Also:<br />

• Tutorials<br />

• Automatically generated documentation (API)<br />

• Source code<br />

List of all modules:<br />

7.1 The Atoms object<br />

The Atoms object is a collection of atoms. Here is how to define a CO molecule:<br />

from ase import Atoms<br />

d = 1.1<br />

co = Atoms(’CO’, positions=[(0, 0, 0), (0, 0, d)])<br />

Here, the first argument specifies the type of the atoms and we used the positions keywords to specify their<br />

positions. Other possible keywords are: numbers, tags, momenta, masses, magmoms and charges.<br />

Here is how you could make an infinite gold wire with a bond length of 2.9 Å:<br />

from ase import Atoms<br />

d = 2.9<br />

L = 10.0<br />

wire = Atoms(’Au’,<br />

positions=[(0, L / 2, L / 2)],<br />

cell=(d, L, L),<br />

pbc=(1, 0, 0))<br />

53


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

Here, two more optional keyword arguments were used:<br />

cell: Unit cell size This can be a sequence of three numbers for an orthorhombic unit cell or three by three<br />

numbers for a general unit cell (a sequence of three sequences of three numbers). The default value is [1.0,<br />

1.0, 1.0].<br />

pbc: Periodic boundary conditions The default value is False - a value of True would give periodic boundary<br />

conditions along all three axes. It is possible to give a sequence of three booleans to specify periodicity<br />

along specific axes.<br />

You can also use the following methods to work with the unit cell and the boundary conditions: set_pbc(),<br />

set_cell(), get_cell(), and get_pbc().<br />

7.1.1 Working with the array methods of Atoms objects<br />

Like with a single Atom the properties of a collection of atoms can be accessed and changed with get- and setmethods.<br />

For example the positions of the atoms can be addressed as<br />

>>> a = Atoms(’N3’, [(0, 0, 0), (1, 0, 0), (0, 0, 1)])<br />

>>> a.get_positions()<br />

array([[ 0., 0., 0.],<br />

[ 1., 0., 0.],<br />

[ 0., 0., 1.]])<br />

>>> a.set_positions([(2, 0, 0), (0, 2, 2), (2, 2, 0)])<br />

>>> a.get_positions()<br />

array([[ 2., 0., 0.],<br />

[ 0., 2., 2.],<br />

[ 2., 2., 0.]])<br />

Here is the full list of the get/set methods operating on all the atoms at once. The get methods return an array<br />

of quantities, one for each atom; the set methods take similar arrays. E.g. get_positions() return N * 3<br />

numbers, get_atomic_numbers() return N integers.<br />

These methods return copies of the internal arrays, it is thus safe to modify the returned arrays.<br />

54 Chapter 7. Documentation for modules in <strong>ASE</strong>


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

get_atomic_numbers() set_atomic_numbers()<br />

get_charges() set_charges()<br />

get_chemical_symbols() set_chemical_symbols()<br />

get_initial_magnetic_moments() set_initial_magnetic_moments()<br />

get_magnetic_moments()<br />

get_masses() set_masses()<br />

get_momenta() set_momenta()<br />

get_forces()<br />

get_positions() set_positions()<br />

get_potential_energies()<br />

get_scaled_positions() set_scaled_positions()<br />

get_stresses()<br />

get_tags() set_tags()<br />

get_velocities() set_velocities()<br />

There are also a number of get/set methods that operate on quantities common to all the atoms or defined for the<br />

collection of atoms:<br />

get_calculator() set_calculator()<br />

get_cell() set_cell()<br />

get_center_of_mass()<br />

get_kinetic_energy()<br />

get_magnetic_moment()<br />

get_name()<br />

get_number_of_atoms()<br />

get_pbc() set_pbc()<br />

get_potential_energy()<br />

get_stress()<br />

get_total_energy()<br />

get_volume()<br />

7.1.2 Unit cell and boundary conditions<br />

The Atoms object holds a unit cell which by default is the 3x3 unit matrix as can be seen from<br />

>>> a.get_cell()<br />

array([[ 1., 0., 0.],<br />

[ 0., 1., 0.],<br />

[ 0., 0., 1.]])<br />

The cell can be defined or changed using the set_cell() method. Changing the unit cell does per default not<br />

move the atoms:<br />

>>> a.set_cell(2 * identity(3))<br />

>>> a.get_cell()<br />

array([[ 2., 0., 0.],<br />

[ 0., 2., 0.],<br />

[ 0., 0., 2.]])<br />

>>> a.get_positions()<br />

array([[ 2., 0., 0.],<br />

[ 1., 1., 0.],<br />

[ 2., 2., 0.]])<br />

However if we set scale_atoms=True the atomic positions are scaled with the unit cell:<br />

>>> a.set_cell(identity(3), scale_atoms=True)<br />

>>> a.get_positions()<br />

array([[ 1. , 0. , 0. ],<br />

[ 0.5, 0.5, 0. ],<br />

[ 1. , 1. , 0. ]])<br />

7.1. The Atoms object 55


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

The set_pbc() method specifies whether periodic boundary conditions are to be used in the directions of the<br />

three vectors of the unit cell. A slab calculation with periodic boundary conditions in x and y directions and free<br />

boundary conditions in the z direction is obtained through<br />

>>> a.set_pbc((True, True, False))<br />

7.1.3 Special attributes<br />

It is also possible to work directly with the attributes positions, numbers, pbc and cell. Here we change<br />

the position of the 2nd atom (which has count number 1 because Python starts counting at zero) and the type of<br />

the first atom:<br />

>>> a.positions[1] = (1, 1, 0)<br />

>>> a.get_positions()<br />

array([[2., 0., 0.],<br />

[1., 1., 0.],<br />

[2., 2., 0.]])<br />

>>> a.positions<br />

array([[2., 0., 0.],<br />

[1., 1., 0.],<br />

[2., 2., 0.]])<br />

>>> a.numbers<br />

array([7, 7, 7])<br />

>>> a.numbers[0] = 13<br />

>>> a.get_chemical_symbols()<br />

[’Al’, ’N’, ’N’]<br />

Check for periodic boundary conditions:<br />

>>> a.pbc # equivalent to a.get_pbc()<br />

array([False, False, False], dtype=bool)<br />

>>> a.pbc.any()<br />

False<br />

>>> a.pbc[2] = 1<br />

>>> a.pbc<br />

array([False, False, True], dtype=bool)<br />

7.1.4 Adding a calculator<br />

A calculator can be attached to the atoms with the purpose of calculating energies and forces on the atoms. <strong>ASE</strong><br />

works with many different calculators.<br />

A calculator object calc is attached to the atoms like this:<br />

>>> a.set_calculator(calc)<br />

After the calculator has been appropriately setup the energy of the atoms can be obtained through<br />

>>> a.get_potential_energy()<br />

The term “potential energy” here means for example the total energy of a DFT calculation, which includes both<br />

kinetic, electrostatic, and exchange-correlation energy for the electrons. The reason it is called potential energy is<br />

that the atoms might also have a kinetic energy (from the moving nuclei) and that is obtained with<br />

>>> a.get_kinetic_energy()<br />

In case of a DFT calculator, it is up to the user to check exactly what the get_potential_energy() method<br />

returns. For example it may be the result of a calculation with a finite temperature smearing of the occupation<br />

numbers extrapolated to zero temperature. More about this can be found for the different calculators.<br />

The following methods can only be called if a calculator is present:<br />

56 Chapter 7. Documentation for modules in <strong>ASE</strong>


• get_potential_energy()<br />

• get_potential_energies()<br />

• get_forces()<br />

• get_stress()<br />

• get_stresses()<br />

• get_total_energy()<br />

• get_magnetic_moments()<br />

• get_magnetic_moment()<br />

Not all of these methods are supported by all calculators.<br />

7.1.5 List-methods<br />

method example<br />

+ wire2 = wire + co<br />

+=, extend() wire += co<br />

wire.extend(co)<br />

append() wire.append(Atom(’H’))<br />

*<br />

wire3 = wire * (3, 1, 1)<br />

*=, repeat() wire *= (3, 1, 1)<br />

wire.repeat((3, 1, 1))<br />

len len(co)<br />

del del wire3[0]<br />

del wire3[[1,3]]<br />

pop() oxygen = wire2.pop()<br />

<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

Note that the del method can be used with the more powerful numpy-style indexing, as in the second example<br />

above. This can be combined with python list comprehension in order to selectively delete atoms within an <strong>ASE</strong><br />

Atoms object. For example, the below code creates an ethanol molecule and subsequently strips all the hydrogen<br />

atoms from it:<br />

from ase.data.molecules import molecule<br />

atoms = molecule(’CH3CH2OH’)<br />

del atoms[[atom.index for atom in atoms if atom.symbol==’H’]]<br />

7.1.6 Other methods<br />

• center()<br />

• translate()<br />

• rotate()<br />

• rotate_euler()<br />

• get_dihedral()<br />

• set_dihedral()<br />

• rotate_dihedral()<br />

• rattle()<br />

• set_constraint()<br />

• set_distance()<br />

• copy()<br />

7.1. The Atoms object 57


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

• get_center_of_mass()<br />

• get_distance()<br />

• get_volume()<br />

• has()<br />

• edit()<br />

• identical_to()<br />

7.1.7 List of all Methods<br />

class ase.atoms.Atoms(symbols=None, positions=None, numbers=None, tags=None, momenta=None,<br />

masses=None, magmoms=None, charges=None,<br />

scaled_positions=None, cell=None, pbc=None, celldisp=None, constraint=None,<br />

calculator=None, info=None)<br />

Atoms object.<br />

The Atoms object can represent an isolated molecule, or a periodically repeated structure. It has a unit cell<br />

and there may be periodic boundary conditions along any of the three unit cell axes.<br />

Information about the atoms (atomic numbers and position) is stored in ndarrays. Optionally, there can be<br />

information about tags, momenta, masses, magnetic moments and charges.<br />

In order to calculate energies, forces and stresses, a calculator object has to attached to the atoms object.<br />

Parameters:<br />

symbols: str (formula) or list of str Can be a string formula, a list of symbols or a list of Atom objects.<br />

Examples: ‘H2O’, ‘COPt12’, [’H’, ‘H’, ‘O’], [Atom(‘Ne’, (x, y, z)), ...].<br />

positions: list of xyz-positions Atomic positions. Anything that can be converted to an ndarray of shape<br />

(n, 3) will do: [(x1,y1,z1), (x2,y2,z2), ...].<br />

scaled_positions: list of scaled-positions Like positions, but given in units of the unit cell. Can not be set<br />

at the same time as positions.<br />

numbers: list of int Atomic numbers (use only one of symbols/numbers).<br />

tags: list of int Special purpose tags.<br />

momenta: list of xyz-momenta Momenta for all atoms.<br />

masses: list of float Atomic masses in atomic units.<br />

magmoms: list of float or list of xyz-values Magnetic moments. Can be either a single value for each<br />

atom for collinear calculations or three numbers for each atom for non-collinear calculations.<br />

charges: list of float Atomic charges.<br />

cell: 3x3 matrix Unit cell vectors. Can also be given as just three numbers for orthorhombic cells. Default<br />

value: [1, 1, 1].<br />

celldisp: Vector Unit cell displacement vector. To visualize a displaced cell around the center of mass of a<br />

Systems of atoms. Default value = (0,0,0)<br />

pbc: one or three bool Periodic boundary conditions flags. Examples: True, False, 0, 1, (1, 1, 0), (True,<br />

False, False). Default value: False.<br />

constraint: constraint object(s) Used for applying one or more constraints during structure optimization.<br />

calculator: calculator object Used to attach a calculator for calculating energies and atomic forces.<br />

info: dict of key-value pairs Dictionary of key-value pairs with additional information about the system.<br />

The following keys may be used by ase:<br />

• spacegroup: Spacegroup instance<br />

58 Chapter 7. Documentation for modules in <strong>ASE</strong>


• unit_cell: ‘conventional’ | ‘primitive’ | int | 3 ints<br />

• adsorbate_info:<br />

<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

Items in the info attribute survives copy and slicing and can be store to and retrieved from trajectory<br />

files given that the key is a string, the value is picklable and, if the value is a user-defined object, its<br />

base class is importable. One should not make any assumptions about the existence of keys.<br />

Examples:<br />

These three are equivalent:<br />

>>> d = 1.104 # N2 bondlength<br />

>>> a = Atoms(’N2’, [(0, 0, 0), (0, 0, d)])<br />

>>> a = Atoms(numbers=[7, 7], positions=[(0, 0, 0), (0, 0, d)])<br />

>>> a = Atoms([Atom(’N’, (0, 0, 0)), Atom(’N’, (0, 0, d)])<br />

FCC gold:<br />

>>> a = 4.05 # Gold lattice constant<br />

>>> b = a / 2<br />

>>> fcc = Atoms(’Au’,<br />

... cell=[(0, b, b), (b, 0, b), (b, b, 0)],<br />

... pbc=True)<br />

Hydrogen wire:<br />

>>> d = 0.9 # H-H distance<br />

>>> L = 7.0<br />

>>> h = Atoms(’H’, positions=[(0, L / 2, L / 2)],<br />

... cell=(d, L, L),<br />

... pbc=(1, 0, 0))<br />

append(atom)<br />

Append atom to end.<br />

calc<br />

Calculator object.<br />

cell<br />

Attribute for direct manipulation of the unit cell.<br />

center(vacuum=None, axis=None)<br />

Center atoms in unit cell.<br />

Centers the atoms in the unit cell, so there is the same amount of vacuum on all sides.<br />

Parameters:<br />

vacuum (default: None): If specified adjust the amount of vacuum when centering. If vacuum=10.0<br />

there will thus be 10 Angstrom of vacuum on each side.<br />

axis (default: None): If specified, only act on the specified axis. Default: Act on all axes.<br />

constraints<br />

Constraints of the atoms.<br />

copy()<br />

Return a copy.<br />

edit()<br />

Modify atoms interactively through ag viewer.<br />

Conflicts leading to undesirable behaviour might arise when matplotlib has been pre-imported with<br />

certain incompatible backends and while trying to use the plot feature inside the interactive ag. To<br />

circumvent, please set matplotlib.use(‘gtk’) before calling this method.<br />

extend(other)<br />

Extend atoms object by appending atoms from other.<br />

7.1. The Atoms object 59


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

get_angle(list)<br />

Get angle formed by three atoms.<br />

calculate angle between the vectors list[0]->list[1] and list[1]->list[2], where list contains the atomic<br />

indexes in question.<br />

get_angular_momentum()<br />

Get total angular momentum with respect to the center of mass.<br />

get_array(name, copy=True)<br />

Get an array.<br />

Returns a copy unless the optional argument copy is false.<br />

get_atomic_numbers()<br />

Get integer array of atomic numbers.<br />

get_calculation_done()<br />

Let the calculator calculate its thing, using the current input.<br />

get_calculator()<br />

Get currently attached calculator object.<br />

get_cell()<br />

Get the three unit cell vectors as a 3x3 ndarray.<br />

get_celldisp()<br />

Get the unit cell displacement vectors .<br />

get_center_of_mass(scaled=False)<br />

Get the center of mass.<br />

If scaled=True the center of mass in scaled coordinates is returned.<br />

get_charges()<br />

Get array of charges.<br />

get_chemical_formula(mode=’hill’)<br />

Get the chemial formula as a string based on the chemical symbols.<br />

Parameters:<br />

mode: There are three different modes available:<br />

‘all’: The list of chemical symbols are contracted to at string, e.g. [’C’, ‘H’, ‘H’, ‘H’, ‘O’, ‘H’]<br />

becomes ‘CHHHOH’.<br />

‘reduce’: The same as ‘all’ where repeated elements are contracted to a single symbol and a<br />

number, e.g. ‘CHHHOCHHH’ is reduced to ‘CH3OCH3’.<br />

‘hill’: The list of chemical symbols are contracted to a string following the Hill notation (alphabetical<br />

order with C and H first), e.g. ‘CHHHOCHHH’ is reduced to ‘C2H6O’ and ‘SOOHOHO’<br />

to ‘H2O4S’. This is default.<br />

get_chemical_symbols(reduce=False)<br />

Get list of chemical symbol strings.<br />

get_dihedral(list)<br />

Calculate dihedral angle.<br />

Calculate dihedral angle between the vectors list[0]->list[1] and list[2]->list[3], where list contains the<br />

atomic indexes in question.<br />

get_dipole_moment()<br />

Calculate the electric dipole moment for the atoms object.<br />

Only available for calculators which has a get_dipole_moment() method.<br />

60 Chapter 7. Documentation for modules in <strong>ASE</strong>


get_distance(a0, a1, mic=False)<br />

Return distance between two atoms.<br />

Use mic=True to use the Minimum Image Convention.<br />

get_forces(apply_constraint=True)<br />

Calculate atomic forces.<br />

<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

Ask the attached calculator to calculate the forces and apply constraints. Use apply_constraint=False<br />

to get the raw forces.<br />

get_initial_magnetic_moments()<br />

Get array of initial magnetic moments.<br />

get_isotropic_pressure(stress)<br />

Get the current calculated pressure, assume isotropic medium. in Bar<br />

get_kinetic_energy()<br />

Get the kinetic energy.<br />

get_magnetic_moment()<br />

Get calculated total magnetic moment.<br />

get_magnetic_moments()<br />

Get calculated local magnetic moments.<br />

get_masses()<br />

Get array of masses.<br />

get_momenta()<br />

Get array of momenta.<br />

get_moments_of_inertia(vectors=False)<br />

Get the moments of inertia along the principal axes.<br />

The three principal moments of inertia are computed from the eigenvalues of the symmetric inertial<br />

tensor. Periodic boundary conditions are ignored. Units of the moments of inertia are<br />

amu*angstrom**2.<br />

get_number_of_atoms()<br />

Returns the number of atoms.<br />

Equivalent to len(atoms) in the standard <strong>ASE</strong> Atoms class.<br />

get_pbc()<br />

Get periodic boundary condition flags.<br />

get_positions(wrap=False)<br />

Get array of positions. If wrap==True, wraps atoms back into unit cell.<br />

get_potential_energies()<br />

Calculate the potential energies of all the atoms.<br />

Only available with calculators supporting per-atom energies (e.g. classical potentials).<br />

get_potential_energy()<br />

Calculate potential energy.<br />

get_reciprocal_cell()<br />

Get the three reciprocal lattice vectors as a 3x3 ndarray.<br />

Note that the commonly used factor of 2 pi for Fourier transforms is not included here.<br />

get_scaled_positions()<br />

Get positions relative to unit cell.<br />

Atoms outside the unit cell will be wrapped into the cell in those directions with periodic boundary<br />

conditions so that the scaled coordinates are between zero and one.<br />

7.1. The Atoms object 61


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

get_stress(voigt=True)<br />

Calculate stress tensor.<br />

Returns an array of the six independent components of the symmetric stress tensor, in the traditional<br />

Voigt order (xx, yy, zz, yz, xz, xy) or as a 3x3 matrix. Default is Voigt order.<br />

get_stresses()<br />

Calculate the stress-tensor of all the atoms.<br />

Only available with calculators supporting per-atom energies and stresses (e.g. classical potentials).<br />

Even for such calculators there is a certain arbitrariness in defining per-atom stresses.<br />

get_tags()<br />

Get integer array of tags.<br />

get_temperature()<br />

Get the temperature. in Kelvin<br />

get_total_energy()<br />

Get the total energy - potential plus kinetic energy.<br />

get_velocities()<br />

Get array of velocities.<br />

get_volume()<br />

Get volume of unit cell.<br />

has(name)<br />

Check for existence of array.<br />

name must be one of: ‘tags’, ‘momenta’, ‘masses’, ‘magmoms’, ‘charges’.<br />

new_array(name, a, dtype=None, shape=None)<br />

Add new array.<br />

If shape is not None, the shape of a will be checked.<br />

numbers<br />

Attribute for direct manipulation of the atomic numbers.<br />

pbc<br />

Attribute for direct manipulation of the periodic boundary condition flags.<br />

pop(i=-1)<br />

Remove and return atom at index i (default last).<br />

positions<br />

Attribute for direct manipulation of the positions.<br />

rattle(stdev=0.001, seed=42)<br />

Randomly displace atoms.<br />

This method adds random displacements to the atomic positions, taking a possible constraint into<br />

account. The random numbers are drawn from a normal distribution of standard deviation stdev.<br />

For a parallel calculation, it is important to use the same seed on all processors!<br />

repeat(rep)<br />

Create new repeated atoms object.<br />

The rep argument should be a sequence of three positive integers like (2,3,1) or a single integer (r)<br />

equivalent to (r,r,r).<br />

rotate(v, a=None, center=(0, 0, 0), rotate_cell=False)<br />

Rotate atoms based on a vector and an angle, or two vectors.<br />

Parameters:<br />

v: Vector to rotate the atoms around. Vectors can be given as strings: ‘x’, ‘-x’, ‘y’, ... .<br />

62 Chapter 7. Documentation for modules in <strong>ASE</strong>


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

a = None: Angle that the atoms is rotated around the vecor ‘v’. If an angle is not specified, the length<br />

of ‘v’ is used as the angle (default). The angle can also be a vector and then ‘v’ is rotated into ‘a’.<br />

center = (0, 0, 0): The center is kept fixed under the rotation. Use ‘COM’ to fix the center of mass,<br />

‘COP’ to fix the center of positions or ‘COU’ to fix the center of cell.<br />

rotate_cell = False: If true the cell is also rotated.<br />

Examples:<br />

Rotate 90 degrees around the z-axis, so that the x-axis is rotated into the y-axis:<br />

>>> a = pi / 2<br />

>>> atoms.rotate(’z’, a)<br />

>>> atoms.rotate((0, 0, 1), a)<br />

>>> atoms.rotate(’-z’, -a)<br />

>>> atoms.rotate((0, 0, a))<br />

>>> atoms.rotate(’x’, ’y’)<br />

rotate_dihedral(list, angle, mask=None)<br />

Rotate dihedral angle.<br />

Complementing the two routines above: rotate a group by a predefined dihedral angle, starting from<br />

its current configuration<br />

rotate_euler(center=(0, 0, 0), phi=0.0, theta=0.0, psi=0.0)<br />

Rotate atoms via Euler angles.<br />

See e.g http://mathworld.wolfram.com/EulerAngles.html for explanation.<br />

Parameters:<br />

center : The point to rotate about. A sequence of length 3 with the coordinates, or ‘COM’ to select<br />

the center of mass, ‘COP’ to select center of positions or ‘COU’ to select center of cell.<br />

phi : The 1st rotation angle around the z axis.<br />

theta : Rotation around the x axis.<br />

psi : 2nd rotation around the z axis.<br />

set_angle(list, angle, mask=None)<br />

Set angle formed by three atoms.<br />

Sets the angle between vectors list[1]->list[0] and list[1]->list[2].<br />

Same usage as in set_dihedral.<br />

set_array(name, a, dtype=None, shape=None)<br />

Update array.<br />

If shape is not None, the shape of a will be checked. If a is None, then the array is deleted.<br />

set_atomic_numbers(numbers)<br />

Set atomic numbers.<br />

set_calculator(calc=None)<br />

Attach calculator object.<br />

set_cell(cell, scale_atoms=False, fix=None)<br />

Set unit cell vectors.<br />

Parameters:<br />

cell [] Unit cell. A 3x3 matrix (the three unit cell vectors) or just three numbers for an orthorhombic<br />

cell.<br />

scale_atoms [bool] Fix atomic positions or move atoms with the unit cell? Default behavior is to not<br />

move the atoms (scale_atoms=False).<br />

7.1. The Atoms object 63


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

Examples:<br />

Two equivalent ways to define an orthorhombic cell:<br />

>>> a.set_cell([a, b, c])<br />

>>> a.set_cell([(a, 0, 0), (0, b, 0), (0, 0, c)])<br />

FCC unit cell:<br />

>>> a.set_cell([(0, b, b), (b, 0, b), (b, b, 0)])<br />

set_charges(charges)<br />

Set charges.<br />

set_chemical_symbols(symbols)<br />

Set chemical symbols.<br />

set_constraint(constraint=None)<br />

Apply one or more constrains.<br />

The constraint argument must be one constraint object or a list of constraint objects.<br />

set_dihedral(list, angle, mask=None)<br />

set the dihedral angle between vectors list[0]->list[1] and list[2]->list[3] by changing the atom indexed<br />

by list[3] if mask is not None, all the atoms described in mask (read: the entire subgroup) are moved<br />

example: the following defines a very crude ethane-like molecule and twists one half of it by 30<br />

degrees.<br />

>>> atoms = Atoms(’HHCCHH’, [[-1, 1, 0], [-1, -1, 0], [0, 0, 0],<br />

[1, 0, 0], [2, 1, 0], [2, -1, 0]])<br />

>>> atoms.set_dihedral([1,2,3,4],7*pi/6,mask=[0,0,0,1,1,1])<br />

set_distance(a0, a1, distance, fix=0.5)<br />

Set the distance between two atoms.<br />

Set the distance between atoms a0 and a1 to distance. By default, the center of the two atoms will be<br />

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<br />

of the bond.<br />

set_initial_magnetic_moments(magmoms=None)<br />

Set the initial magnetic moments.<br />

Use either one or three numbers for every atom (collinear or non-collinear spins).<br />

set_masses(masses=’defaults’)<br />

Set atomic masses.<br />

The array masses should contain a list of masses. In case the masses argument is not given or for those<br />

elements of the masses list that are None, standard values are set.<br />

set_momenta(momenta)<br />

Set momenta.<br />

set_pbc(pbc)<br />

Set periodic boundary condition flags.<br />

set_positions(newpositions)<br />

Set positions, honoring any constraints.<br />

set_scaled_positions(scaled)<br />

Set positions relative to unit cell.<br />

set_tags(tags)<br />

Set tags for all atoms.<br />

set_velocities(velocities)<br />

Set the momenta by specifying the velocities.<br />

64 Chapter 7. Documentation for modules in <strong>ASE</strong>


translate(displacement)<br />

Translate atomic positions.<br />

<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

The displacement argument can be a float an xyz vector or an nx3 array (where n is the number of<br />

atoms).<br />

write(filename, format=None, **kwargs)<br />

Write yourself to a file.<br />

7.2 The Atom object<br />

<strong>ASE</strong> defines a python class called Atom to setup and handle atoms in electronic structure and molecular simulations.<br />

From a python script, atoms can be created like this:<br />

>>> from ase import Atom<br />

>>> a1 = Atom(’Si’, (0, 0, 0))<br />

>>> a2 = Atom(’H’, (1.3, 0, 0), mass=2)<br />

>>> a3 = Atom(position=(0, 0, 0), Z=14) # same is a1<br />

class ase.atom.Atom(symbol=’X’, position=(0, 0, 0), tag=None, momentum=None, mass=None, magmom=None,<br />

charge=None, atoms=None, index=None)<br />

Class for representing a single atom.<br />

Parameters:<br />

symbol: str or int Can be a chemical symbol (str) or an atomic number (int).<br />

position: sequence of 3 floats Atomi position.<br />

tag: int Special purpose tag.<br />

momentum: sequence of 3 floats Momentum for atom.<br />

mass: float Atomic mass in atomic units.<br />

magmom: float or 3 floats Magnetic moment.<br />

charge: float Atomic charge.<br />

The first argument to the constructor of an Atom object is the chemical symbol, and the second argument is the<br />

position in Å units (see units). The position can be any numerical sequence of length three. The properties of<br />

an atom can also be set using keywords like it is done in the a2 and a3 examples above.<br />

More examples:<br />

>>> a = Atom(’O’, charge=-2)<br />

>>> b = Atom(8, charge=-2)<br />

>>> c = Atom(’H’, (1, 2, 3), magmom=1)<br />

>>> print a.charge, a.position<br />

-2 [ 0. 0. 0.]<br />

>>> c.x = 0.0<br />

>>> c.position<br />

array([ 0., 2., 3.])<br />

>>> b.symbol<br />

’O’<br />

>>> c.tag = 42<br />

>>> c.number<br />

1<br />

>>> c.symbol = ’Li’<br />

>>> c.number<br />

3<br />

If the atom object belongs to an Atoms object, then assigning values to the atom attributes will change the corresponding<br />

arrays of the atoms object:<br />

7.2. The Atom object 65


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

>>> OH = Atoms(’OH’)<br />

>>> OH[0].charge = -1<br />

>>> OH.get_charges()<br />

array([-1., 0.])<br />

Another example:<br />

>>> for atom in bulk:<br />

... if atom.symbol = ’Ni’:<br />

... atom.magmom = 0.7 # set initial magnetic moment<br />

The different properties of an atom can be obtained and changed via attributes (position, number, tag,<br />

momentum, mass, magmom, charge, x, y, z):<br />

>>> a1.position = [1, 0, 0]<br />

>>> a1.position<br />

array([ 1., 0., 0.])<br />

>>> a1.z = 2.5<br />

>>> a1.position<br />

array([ 1. , 0. , 2.5])<br />

>>> a2.magmom = 1.0<br />

That last line will set the initial magnetic moment that some calulators use (similar to the<br />

set_initial_magnetic_moments() method).<br />

Note: The position and momentum attributes refer to mutable objects, so in some cases, you may want to<br />

use a1.position.copy() in order to avoid changing the position of a1 by accident.<br />

7.2.1 Getting an Atom from an Atoms object<br />

Indexing an Atoms object returns an Atom object still remembering that it belongs to the collective Atoms:<br />

Modifying it will also change the atoms object:<br />

>>> atoms = ase.data.molecules.molecule(’CH4’)<br />

>>> atoms.get_positions()<br />

array([[ 0. , 0. , 0. ],<br />

[ 0.629118, 0.629118, 0.629118],<br />

[-0.629118, -0.629118, 0.629118],<br />

[ 0.629118, -0.629118, -0.629118],<br />

[-0.629118, 0.629118, -0.629118]])<br />

>>> a = atoms[2]<br />

>>> a<br />

Atom(’H’, [-0.62911799999999996, -0.62911799999999996, 0.62911799999999996], index=2)<br />

>>> a.x = 0<br />

>>> atoms.get_positions()<br />

array([[ 0. , 0. , 0. ],<br />

[ 0.629118, 0.629118, 0.629118],<br />

[ 0. , -0.629118, 0.629118],<br />

[ 0.629118, -0.629118, -0.629118],<br />

[-0.629118, 0.629118, -0.629118]])<br />

See Also:<br />

Atom: All the details!<br />

atoms: More information about how to use collections of atoms.<br />

calculators: Information about how to calculate forces and energies of atoms.<br />

66 Chapter 7. Documentation for modules in <strong>ASE</strong>


7.3 Units<br />

<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

Physical units are defined in the ase/units.py module. Electron volts (eV) and angstroms (Ang) are defined as 1.0.<br />

Other units are nm, Bohr, Hartree or Ha, kJ, kcal, mol, Rydberg or Ry, second, fs and kB.<br />

Note: All constants are taken from the 1986 CODATA.<br />

Examples:<br />

>>> from ase import *<br />

>>> 2 * Bohr<br />

1.0583545150138329<br />

>>> 25 * Rydberg<br />

340.14244569396635<br />

>>> 100 * kJ/mol<br />

1.0364272141304978<br />

>>> 300 * kB<br />

0.025852157076770025<br />

>>> 0.1 * fs<br />

0.009822693531550318<br />

>>> print ’1 Hartree = ’+str(Hartree*mol/kcal)+’ kcal/mol’<br />

7.4 The ase.data module<br />

This module defines the following variables: atomic_masses, atomic_names, chemical_symbols,<br />

covalent_radii, cpk_colors and reference_states. All of these are lists that should be indexed<br />

with an atomic number:<br />

>>> atomic_names[92]<br />

’Uranium’<br />

>>> atomic_masses[2]<br />

4.0026000000000002<br />

If you don’t know the atomic number of some element, then you can look it up in the atomic_numbers<br />

dictionary:<br />

>>> atomic_numbers[’Cu’]<br />

29<br />

>>> covalent_radii[29]<br />

1.1699999999999999<br />

7.5 File input and output<br />

The io module has two basic functions: read() and write(). The two methods are described here:<br />

ase.io.read(filename, index=-1, format=None)<br />

Read Atoms object(s) from file.<br />

filename: str Name of the file to read from.<br />

index: int or slice If the file contains several configurations, the last configuration will be returned by<br />

default. Use index=n to get configuration number n (counting from zero).<br />

format: str Used to specify the file-format. If not given, the file-format will be guessed by the filetype<br />

function.<br />

Known formats:<br />

7.3. Units 67


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

format short name<br />

GPAW restart-file gpw<br />

Dacapo netCDF output file dacapo<br />

Old <strong>ASE</strong> netCDF trajectory nc<br />

Virtual Nano Lab file vnl<br />

<strong>ASE</strong> pickle trajectory traj<br />

<strong>ASE</strong> bundle trajectory bundle<br />

GPAW text output gpaw-text<br />

CUBE file cube<br />

XCrySDen Structure File xsf<br />

Dacapo text output dacapo-text<br />

XYZ-file xyz<br />

VASP POSCAR/CONTCAR file vasp<br />

VASP OUTCAR file vasp_out<br />

SIESTA STRUCT file struct_out<br />

ABINIT input file abinit<br />

V_Sim ascii file v_sim<br />

Protein Data Bank pdb<br />

CIF-file cif<br />

FHI-aims geometry file aims<br />

FHI-aims output file aims_out<br />

VTK XML Image Data vti<br />

VTK XML Structured Grid vts<br />

VTK XML Unstructured Grid vtu<br />

TURBOMOLE coord file tmol<br />

TURBOMOLE gradient file tmol-gradient<br />

exciting input exi<br />

AtomEye configuration cfg<br />

WIEN2k structure file struct<br />

DftbPlus input file dftb<br />

CASTEP geom file cell<br />

CASTEP output file castep<br />

CASTEP trajectory file geom<br />

ETSF format etsf.nc<br />

DFTBPlus GEN format gen<br />

CMR db/cmr-file db<br />

CMR db/cmr-file cmr<br />

LAMMPS dump file lammps<br />

EON reactant.con file eon<br />

Gromacs coordinates gro<br />

Gaussian com (input) file gaussian<br />

Gaussian output file gaussian_out<br />

ase.io.write(filename, images, format=None, **kwargs)<br />

Write Atoms object(s) to file.<br />

filename: str Name of the file to write to.<br />

images: Atoms object or list of Atoms objects A single Atoms object or a list of Atoms objects.<br />

format: str Used to specify the file-format. If not given, the file-format will be taken from suffix of the<br />

filename.<br />

The accepted output formats:<br />

format short name<br />

<strong>ASE</strong> pickle trajectory traj<br />

Continued on next page<br />

68 Chapter 7. Documentation for modules in <strong>ASE</strong>


The use of additional keywords is format specific.<br />

Table 7.2 – continued from previous page<br />

format short name<br />

<strong>ASE</strong> bundle trajectory bundle<br />

CUBE file cube<br />

XYZ-file xyz<br />

VASP POSCAR/CONTCAR file vasp<br />

ABINIT input file abinit<br />

Protein Data Bank pdb<br />

CIF-file cif<br />

XCrySDen Structure File xsf<br />

FHI-aims geometry file aims<br />

gOpenMol .plt file plt<br />

Python script py<br />

Encapsulated Postscript eps<br />

Portable Network Graphics png<br />

Persistance of Vision pov<br />

VTK XML Image Data vti<br />

VTK XML Structured Grid vts<br />

VTK XML Unstructured Grid vtu<br />

TURBOMOLE coord file tmol<br />

exciting exi<br />

AtomEye configuration cfg<br />

WIEN2k structure file struct<br />

CASTEP cell file cell<br />

DftbPlus input file dftb<br />

ETSF etsf.nc<br />

DFTBPlus GEN format gen<br />

CMR db/cmr-file db<br />

CMR db/cmr-file cmr<br />

EON reactant.con file eon<br />

Gromacs coordinates gro<br />

GROMOS96 (only positions) g96<br />

<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

The cube and plt formats accept (plt requires it) a data keyword, which can be used to write a 3D array<br />

to the file along with the nuclei coordinates.<br />

The vti, vts and vtu formats are all specifically directed for use with MayaVi, and the latter is designated<br />

for visualization of the atoms whereas the two others are intended for volume data. Further, it should be<br />

noted that the vti format is intended for orthogonal unit cells as only the grid-spacing is stored, whereas<br />

the vts format additionally stores the coordinates of each grid point, thus making it useful for volume date<br />

in more general unit cells.<br />

The eps, png, and pov formats are all graphics formats, and accept the additional keywords:<br />

rotation: str (default ‘’) The rotation angles, e.g. ‘45x,70y,90z’.<br />

show_unit_cell: int (default 0) Can be 0, 1, 2 to either not show, show, or show all of the unit cell.<br />

radii: array or float (default 1.0) An array of same length as the list of atoms indicating the sphere radii.<br />

A single float specifies a uniform scaling of the default covalent radii.<br />

bbox: 4 floats (default None) Set the bounding box to (xll, yll, xur, yur) (lower left, upper right).<br />

colors: array (default None) An array of same length as the list of atoms, indicating the rgb color code<br />

for each atom. Default is the jmol_colors of ase/data/colors.<br />

scale: int (default 20) Number of pixels per Angstrom.<br />

7.5. File input and output 69


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

For the pov graphics format, scale should not be specified. The elements of the color array can additionally<br />

be strings, or 4 and 5 vectors for named colors, rgb + filter, and rgb + filter + transmit specification.<br />

This format accepts the additional keywords:<br />

run_povray, display, pause, transparent, canvas_width, canvas_height,<br />

camera_dist, image_plane, camera_type, point_lights, area_light, background,<br />

textures, celllinewidth, bondlinewidth, bondatoms<br />

The read() function is only designed to retrive the atomic configuration from a file, but for the CUBE format<br />

you can import the function:<br />

io.read_cube_data()<br />

which will return a (data, atoms) tuple:<br />

from ase.io.cube import read_cube_data<br />

data, atoms = read_cube_data(’abc.cube’)<br />

7.6 Examples<br />

from ase.lattice.surface import *<br />

adsorbate = Atoms(’CO’)<br />

adsorbate[1].z = 1.1<br />

a = 3.61<br />

slab = fcc111(’Cu’, (2, 2, 3), a=a, vacuum=7.0)<br />

add_adsorbate(slab, adsorbate, 1.8, ’ontop’)<br />

Write PNG image:<br />

write(’slab.png’, slab * (3, 3, 1), rotation=’10z,-80x’)<br />

Write POVRAY file:<br />

write(’slab.pov’, slab * (3, 3, 1), rotation=’10z,-80x’)<br />

This will write both a slab.pov and a slab.ini file. Convert to PNG with the command povray<br />

slab.ini or use the run_povray=True option:<br />

70 Chapter 7. Documentation for modules in <strong>ASE</strong>


Here is an example using bbox:<br />

d = a / 2**0.5<br />

write(’slab.pov’, slab * (2, 2, 1),<br />

bbox=(d, 0, 3 * d, d * 3**0.5))<br />

Note that the XYZ-format does not contain information about the unic cell:<br />

>>> write(’slab.xyz’, slab)<br />

>>> a = read(’slab.xyz’)<br />

>>> a.get_cell()<br />

array([[ 1., 0., 0.],<br />

[ 0., 1., 0.],<br />

[ 0., 0., 1.]])<br />

>>> a.get_pbc()<br />

array([False, False, False], dtype=bool)<br />

Use <strong>ASE</strong>’s native format for writing all information:<br />

>>> write(’slab.traj’, slab)<br />

>>> b = read(’slab.traj’)<br />

>>> b.get_cell()<br />

array([[ 5.10531096e+00, -4.11836034e-16, 1.99569088e-16],<br />

[ 2.55265548e+00, 4.42132899e+00, 7.11236625e-17],<br />

[ 8.11559027e+00, 4.68553823e+00, 1.32527034e+01]])<br />

>>> b.get_pbc()<br />

array([ True, True, True], dtype=bool)<br />

<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

A script showing all of the povray parameters, and generating the image below, can be found here:<br />

doc/ase/save_pov.py<br />

7.6. Examples 71


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

An other example showing how to change colors and textures in pov can be found here:<br />

doc/tutorials/saving_graphics.py<br />

7.7 <strong>ASE</strong>-GUI<br />

The graphical user-interface allows users to visualize, manipulate, and render molecular systems and atoms objects.<br />

It also allows to setup and run a number of calculations and can be used to transfer between different file<br />

formats.<br />

72 Chapter 7. Documentation for modules in <strong>ASE</strong>


7.7.1 ag basics and command line options<br />

General use<br />

<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

Visualizing a system with ag is straight-forward using a regular mouse. The scroll function allows to change the<br />

magnification, the left mouse button selects atoms, the right mouse button allows to rotate, and the middle button<br />

allows to translate the system on the screen.<br />

Depending on the number of selected atoms, ag automatically measures different quantities:<br />

Selection measurement<br />

single atom xyz position and atomic symbol<br />

two atoms interatomic distance and symbols<br />

three atoms all three internal angles and symbols<br />

four atoms, selected sequentially Measures the dihedral angle, e.g. the angle between bonds 12 and 34<br />

more than four atoms chemical composition of selection.<br />

ag can save the following file formats:<br />

File format Comment<br />

xyz XYZ file<br />

traj <strong>ASE</strong> trajectory<br />

pdb PDB file<br />

cube Gaussian cube file<br />

py Python script<br />

vnl VNL file<br />

png Portable Network Graphics<br />

pov Persistance of Vision<br />

eps Encapsulated PostScript<br />

in FHI-aims geometry input<br />

POSCAR VASP geometry input<br />

bundle <strong>ASE</strong> bundle trajectory<br />

cif Crystallographic Information File<br />

Files<br />

The ag program can read all the file formats the <strong>ASE</strong>’s read() function can understand.<br />

$ ag N2Fe110-path.traj<br />

Selecting part of a trajectory<br />

A Python-like syntax for selecting a subset of configurations can be used. Instead of the Python syntax<br />

list[start:stop:step], you use filaname@start:stop:step:<br />

$ ag x.traj@0:10:1 # first 10 images<br />

$ ag x.traj@0:10 # first 10 images<br />

$ ag x.traj@:10 # first 10 images<br />

$ ag x.traj@-10: # last 10 images<br />

$ ag x.traj@0 # first image<br />

$ ag x.traj@-1 # last image<br />

$ ag x.traj@::2 # every second image<br />

If you want to select the same range from many files, the you can use the -n or --image-number option:<br />

$ ag -n -1 *.traj # last image from all files<br />

$ ag -n 0 *.traj # first image from all files<br />

Tip: Type ag -h for a description of all command line options.<br />

7.7. <strong>ASE</strong>-GUI 73


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

Writing files<br />

$ ag -n -1 a*.traj -o new.traj<br />

Possible formats are: traj, xyz, cube, pdb, eps, png, and pov. For details, see the io module documentation.<br />

Interactive use<br />

The ag program can also be launched directly from a Python script or interactive session:<br />

>>> from ase import *<br />

>>> atoms = ...<br />

>>> view(atoms)<br />

or<br />

>>> view(atoms, repeat=(3, 3, 2))<br />

or, to keep changes to your atoms:<br />

>>> atoms.edit()<br />

NEB calculations<br />

Use Tools → NEB to plot energy barrier.<br />

$ ag --interpolate 3 initial.xyz final.xyz -o interpolated_path.traj<br />

Plotting data from the command line<br />

Plot the energy relative to the energy of the first image as a function of the distance between atom 0 and 5:<br />

$ ag -g "d(0,5),e-E[0]" x.traj<br />

$ ag -t -g "d(0,5),e-E[0]" x.traj > x.dat # No GUI, write data to stdout<br />

The symbols are the same as used in the plotting data function.<br />

Defaults for ag<br />

Using a file ~/.ase/gui.py, certain defaults can be set. If it exists, this file is executed after initializing the<br />

variables and colours normally used in ag. One can change the default graphs that are plotted, and the default radii<br />

for displaying specific atoms. This example will display the energy evolution and the maximal force in a graph<br />

and also display Cu atoms (Z=29) with a radius of 1.6 Angstrom.<br />

gui_default_settings[’gui_graphs_string’] = "i, e - min(E), fmax"<br />

gui_default_settings[’covalent_radii’] = [[29,1.6]]<br />

High contrast settings for ag<br />

In revision 2600 or later, it is possible to change the foreground and background colors used to draw the atoms,<br />

for instance to draw white graphics on a black background. This can be done in ~/.ase/gui.py.<br />

gui_default_settings[’gui_foreground_color’] = ’#ffffff’ #white<br />

gui_default_settings[’gui_background_color’] = ’#000000’ #black<br />

74 Chapter 7. Documentation for modules in <strong>ASE</strong>


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

To change the color scheme of graphs it is necessary to change the default behaviour of Matplotlib in a similar<br />

way by using a file ~/.matplotlib/matplotlibrc.<br />

patch.edgecolor : white<br />

text.color : white<br />

axes.facecolor : black<br />

axes.edgecolor : white<br />

axes.labelcolor : white<br />

axes.color_cycle : b, g, r, c, m, y, w<br />

xtick.color : white<br />

ytick.color : white<br />

grid.color : white<br />

figure.facecolor : 0.1<br />

figure.edgecolor : black<br />

Finally, the color scheme of the windows themselves (i.e. menus, buttons and text etc.) can be changed by<br />

choosing a different desktop theme. In Ubuntu it is possible to get white on a dark background by selecting the<br />

theme HighContrastInverse under Appearances in the system settings dialog.<br />

7.7.2 Edit<br />

Add atoms<br />

Allows to add single atoms or a group of atoms to an existing atoms object. If the description is an atom or a<br />

known molecule from the g1, g2, or g3 set (e.g. CH4), then the structure from the data molecule is used. In<br />

addition, a molecule can also be imported from file via the load molecule button.<br />

The specified position can either be absolute, or determined automatically via<br />

auto+<br />

where auto is the centre of mass of the currently selected atoms, and is the distance toward the viewing<br />

plane.<br />

The molecule-to-be is rotated into the current viewing plane before addition into the system. Two options exist for<br />

chosing the origin within the new atoms, it can be either the centre of mass or the origin of the loaded geometry.<br />

Modify<br />

Menu to allow modification of the atomic symbol, an attached tag, or its magnetic moment.<br />

Copy/Paste<br />

Allows to copy parts of an existing system to a clipboard, and pastes via the same infrastructure as the Add<br />

atoms functionality. Note that the on-screen orientation of the pasted atoms will be the same as at the time of<br />

copying. Note also that, by default, the origin of the pasted system is taken to be the atom furthest away from the<br />

viewing point.<br />

7.7.3 View<br />

Repeat<br />

Menu to allow repition of periodic unit cells. Use the ‘Set unit cell’ button to set the overall unit cell to the current<br />

one.<br />

7.7. <strong>ASE</strong>-GUI 75


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

Rotate<br />

Menu to manually fine tune the viewing angle. Use ‘Update’ button to set the menu to the current angle.<br />

Colors<br />

The colors menu allows numerous ways to change the color scheme and to encode additional information into<br />

the display colors. This includes automatic coloring by atomic numbers (default), user-specified atomic number<br />

scheme, coloring by tags, forces, or completely manually specified colors. In addition, several standard color<br />

scales are available.<br />

Settings<br />

Basic viewing settings. Also allows to constrain/unconstrain atoms and to mark selected atoms as invisible.<br />

7.7.4 Tools<br />

Graphs<br />

Allows to graph different quantities for a given trajectory. A ‘save’ button also gives the opportunity to save the<br />

data to file.<br />

This example plots the maximal force for each image i and could help in investigating the convergence properties<br />

for relaxations:<br />

i, e-min(E), fmax<br />

These are the symbols that can be used:<br />

Symbol Interpretation<br />

e total energy<br />

epot potential energy<br />

ekin kinetic energy<br />

fmax maximum force<br />

fave average force<br />

d(n1,n2) distance between two atoms<br />

R[n,0-2] position of atom number n<br />

i current image number<br />

E[i] energy of image number i<br />

F[n,0-2] force on atom number n<br />

M[n] magnetic moment of atom number n<br />

A[0-2,0-2] unit-cell basis vectors<br />

s path length<br />

a(n1,n2,n3) tangle between atoms n1, n2 and n3, centered on n2<br />

dih(n1,n2,n3,n4) dihedral angle between n1, n2, n3, and n4<br />

T temperature (requires velocity)<br />

Movie<br />

Allows to play the current trajectory as a movie using a number of different settings. Default duration is 5 s.<br />

Expert mode<br />

Python interface to all ag functions, with numerous extra commands defined that help to modify and visualize a<br />

system. The commands come in two flavors, the first is interpreted on an atom-by-atom basis (e.g. operates on<br />

76 Chapter 7. Documentation for modules in <strong>ASE</strong>


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

position, color, etc) and the second is based on the entire frame. The flavor of a given line is determined from the<br />

first command. Note that the frame-based commands can be used in atom-based operations, but not vice versa.<br />

See below for some examples.<br />

Regular python syntax applies to the commands and numpy has been imported as np.<br />

Two buttons allow to reduce the operation to a given frame:<br />

Only selected<br />

atoms (sa)<br />

Only current<br />

frame (cf)<br />

Restricts operation only to the selected atoms. The text command sa activates or<br />

deactivates this button.<br />

Restricts operation only to the current frame, useful for long trajectories. The text<br />

command cf activates or deactivates this button.<br />

List of atom-based commands with a few examples:<br />

Com- Interpretation<br />

mand<br />

x,y,z Cartesian coordinates. Example: x += A[0][0]<br />

r,g,b Color components, invoking the expert mode changes the color mode to manual and allows to<br />

address all colors individually. Example: r =<br />

(z-min(R[:,2]))/(max(R[:,2])-min(R[:,2]))<br />

rad atomic display radius<br />

s Boolean to control the selection of an atom. Example: s = Z == 6 and x > 5 or s = d<br />

== False<br />

f force on an atom<br />

Z atomic number<br />

m magnetic moment<br />

d dynamic, e.g. d = False fixes an atom<br />

List of frame-based and global commands and global objects with examples:<br />

Command Interpretation<br />

e total energy<br />

fmax maximal force<br />

A unit cell<br />

E total energy array of all frames. Example: e-min(E)<br />

F all forces in one frame<br />

M all magnetic moments<br />

R all atomic positions<br />

S boolean array of the entire selection<br />

D boolean array of dynamic atoms (False = atom is fixed)<br />

del S deletes current selection<br />

sa,cf toggles the selected-atoms-only or the current-frame-only buttons<br />

frame provides and edits the frame number in a trajectory<br />

center centers system in its unit cell<br />

cov array of original covalent radii<br />

self expert mode window<br />

gui ag GUI object, this controls the entire ag session<br />

img ag images object, all physical data is stored here<br />

To save data between commands, one has to assign variables to parent objects in the gui, e.g. via<br />

self.temp_var = R-img.P[0,:]. DISCLAIMER: Doing so might risk the functionality ofthe entire ag<br />

session if you accidentally overwrite basic functionality of the gui or the image objects stored within.<br />

Finally, recurring selections of commands collected as scripts can be executed as<br />

exec <br />

If the file in question is saved in the directory ~/.ase/ then just the filename will also do.<br />

7.7. <strong>ASE</strong>-GUI 77


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

Constraints<br />

Allows to set (or remove) constraints based on the currently selected atoms.<br />

Render scene<br />

Graphical interface to the <strong>ASE</strong> povray interface, ideally it requires that povray is installed on your computer to<br />

function, but it also can be used just to export the complete set of povray files.<br />

The texture of each atom is adjustable: The default texture is applied to all atoms, but then additional textures<br />

can be defined based on selections (Create new texture from current selection). These can be<br />

obtained either from selecting atoms by hand or by defining a selection with a boolean expression, for example<br />

Z==6 and x>5 and y5 and y


7.7.5 Setup<br />

<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

The setup menus allow for the intuitive creation of numerous standard surfaces, nanoparticles, graphene and<br />

graphene nanoribbons, as well as nanotubes.<br />

Along with creating the geometry within ag, a button provides the necessary python code allowing one to recreate<br />

the exact same geometry in <strong>ASE</strong> scripts.<br />

7.7.6 Calculate<br />

Set calculator<br />

Allows ag to choose a calculator for internal computations (see below). Different density functional codes and<br />

force fields, as well as the EMT calculator are available. For the FHI-aims and VASP calculators, it is also possible<br />

to export an entire set of input files.<br />

Energy and forces<br />

Invokes the currently set calculator and provides energies and optional forces for all atoms.<br />

Energy minimization<br />

Runs an <strong>ASE</strong> relaxation using the currently selected calculator with a choice of relaxation algorithm and convergence<br />

criteria. Great for quickly (pre-)relaxing a molecule before placing it into a bigger system.<br />

Scale system<br />

Stub<br />

7.8 Command line tools<br />

The ase program can be used to do calculations with <strong>ASE</strong> supported calculators on the command line without<br />

having to write a Python script. The syntax is:<br />

$ ase [calculator] [task] [options] system(s)<br />

The name of the calculator must be lower case and will default to EMT. The task must be molecule or bulk.<br />

There are several ways to specify the system or systems to perform the calculations on:<br />

• Chemical names: H2O or Fe. Default molecule definitions are used.<br />

• Range of chemical symbols: Sc-Zn (3d-metals)<br />

• Special names: G2, G2_1 or S22<br />

• File names: benzene.xyz or slab.traj<br />

The exact meaning of these names will depend on the task.<br />

Simple examples:<br />

$ ase emt H2 --relax=0.01<br />

$ ase abinit bulk Si -a 5.5 -p ecut=150 -k 4,4,4<br />

7.8. Command line tools 79


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

7.8.1 Command line options<br />

General options:<br />

-h, --help Show help message and exit.<br />

-t TAG, --tag=TAG String tag added to filenames.<br />

-M , --magnetic-moment= Magnetic moment(s). Use “-M 1” or “-M<br />

2.3,-2.3”.<br />

-G, --gui Pop up <strong>ASE</strong>’s GUI.<br />

-s, --write-summary Write summary.<br />

--slice= Select subset of calculations using Python slice syntax. Use ”::2” to do<br />

every second calculation and ”:-5” to do the last five.<br />

-w FILENAME, --write-to-file=FILENAME Write configuration to file.<br />

-i, --interactive-python-session Run calculation inside interactive Python session. A possible<br />

$PYTHONSTARTUP script will be imported and the “atoms” variable refers<br />

to the Atoms object.<br />

-l, --use-lock-files Skip calculations where the json lock-file or result file already exists.<br />

-R FMAX, --relax=FMAX Relax internal coordinates using L-BFGS algorithm.<br />

-F , --fit= Find optimal bondlength and vibration frequency for dimer molecules or<br />

optimal volume and bulk modulus for bulk systems using N points and a<br />

variation from -x % to +x % for the bondlength or lattice constants.<br />

--constrain-tags= Constrain atoms with tags T1, T2, ...<br />

-k , --monkhorst-pack= Monkhorst-Pack sampling of BZ. Example:<br />

“4,4,4”: 4x4x4 k-points, “4,4,4g”: same set of k-points shifted to include the<br />

Gamma point.<br />

--k-point-density=K_POINT_DENSITY Density of k-points in Å.<br />

-p , --parameters= Comma-separated key=value pairs of calculator<br />

specific parameters.<br />

Options specific to the molecule task:<br />

-v VACUUM, --vacuum=VACUUM Amount of vacuum to add around isolated systems (in<br />

Angstrom).<br />

--unit-cell=CELL Unit cell. Examples: “10.0” or “9,10,11” (in Angstrom).<br />

--bond-length=BOND_LENGTH Bond length of dimer in Angstrom.<br />

--atomize Calculate Atomization energies.<br />

Options specific to the bulk task:<br />

-x CRYSTAL_STRUCTURE, --crystal-structure=CRYSTAL_STRUCTURE Crystal structure.<br />

-a LATTICE_CONSTANT, --lattice-constant=LATTICE_CONSTANT Lattice constant in Å.<br />

--c-over-a=C_OVER_A c/a ratio.<br />

-O, --orthorhombic Use orthorhombic unit cell.<br />

-C, --cubic Use cubic unit cell.<br />

-r REPEAT, --repeat=REPEAT Repeat unit cell. Use “-r 2” or “-r 2,3,1”.<br />

80 Chapter 7. Documentation for modules in <strong>ASE</strong>


7.8.2 Molecules<br />

Example:<br />

$ ase abinit H2 -p ecut=200,xc=LDA -F 5,1 --atomize<br />

<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

This will calculate the energy of a H2 molecule using Abinit with a planewave cutoff of 200 eV and the LDA<br />

XC-functional. A fit using 5 points and a variation of the bond length from -1 % to +1 % is made and in addition<br />

the energy of a single hydrogen atom is also calculated.<br />

Results are written to json files and can be analysed with:<br />

$ ase abinit H H2 -s<br />

name E E-E0 d0 hnu Ea Ea0<br />

eV eV Ang meV eV eV<br />

H2 -29.703 0.022 0.770 556.096 4.852 4.873<br />

H -12.426<br />

Note: The json files are simple text files that can be more or less’ed or pretty printed with python -m<br />

json.tool H2-molecule-abinit.jon.<br />

7.8.3 Bulk systems<br />

Example:<br />

$ ase bulk Ni Cu Pd Ag Pt Au -F 5,1<br />

Here we used the default EMT potential and the result is:<br />

$ ase bulk Ni Cu Pd Ag Pt Au -s<br />

name E E-E0 V0 B<br />

eV eV Ang^3 GPa<br />

Ni -0.009 0.005 10.600 175.978<br />

Ag 0.002 0.002 16.775 100.151<br />

Pt -0.000 0.000 15.080 278.087<br />

Au 0.003 0.003 16.684 173.868<br />

Pd 0.000 0.001 14.588 179.105<br />

Cu -0.006 0.001 11.565 134.439<br />

More examples<br />

Anti-ferromagnetic bcc iron:<br />

$ ase vasp bulk -x bcc Fe -C -M 2.3,-2.3 -p xc=PBE -k 8,8,8<br />

Bulk silicon (128 atoms, Gamma point only):<br />

$ ase abinit bulk Si -r 4,4,4 -k 1,1,1 -a 5.46<br />

Bulk aluminum in orthorhombic cell with LDA and fixed rmt:<br />

$ ase elk bulk --orthorhombic Al -k 4,4,4 -a 4.05 -p "swidth=0.1,rmt={’Al’: 1.9}"<br />

7.8.4 Batch jobs<br />

Suppose you want to run a large number of similar calculations like relaxing the structure of all the molecules in<br />

the G2-1 database. You could do that by submitting this job to your compute cluster:<br />

7.8. Command line tools 81


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

$ ase gpaw G2_1 -v 6.0 -p xc=vdW-DF,h=0.18 -R 0.02<br />

The molecule task will expand G2_1 to a lot of molecules, so it makes sense to use -l option<br />

(--use-lock-files) and submit the same job many times. A lock file will be created for each started calculation<br />

and calculations with existing lock file skipped. Moreover the calculations can be run in parallel (if parallel<br />

version of GPAW is installed):<br />

$ mpiexec gpaw-python ‘which ase‘ gpaw G2_1 -v 6.0 -p xc=vdW-DF,h=0.18 -R 0.02 -l<br />

7.8.5 Making your own tasks<br />

FCC clusters with 13 atoms<br />

Put this in m13.py:<br />

from math import sqrt<br />

from ase.cluster.cubic import FaceCenteredCubic<br />

from ase.tasks.molecule import MoleculeTask<br />

from ase.data import covalent_radii, atomic_numbers<br />

class M13Task(MoleculeTask):<br />

taskname = ’m13’<br />

def build_system(self, name):<br />

if self.bond_length is None:<br />

b = 2 * covalent_radii[atomic_numbers[name]]<br />

else:<br />

b = self.bond_length<br />

task = M13Task()<br />

Then do this:<br />

return FaceCenteredCubic(name, [(1, 0, 0)], [1],<br />

latticeconstant=b * sqrt(2))<br />

$ ase m13.py Pt -R 0.01<br />

The relaxed EMT bondlength of 2.62 Å can be extracted from the created trajectory like this:<br />

$ ag -tg "e,fmax,d(0,9)" Pt-m13-emt.traj<br />

10.9824302706 2.27575724833 2.72<br />

10.0805658256 1.45353946744 2.68<br />

9.61654400875 0.447140179352 2.64<br />

9.57510700742 0.0656434401881 2.6222281202<br />

9.57424531861 0.00239771758341 2.62450316817<br />

or like this:<br />

>>> from ase.io import read<br />

>>> pt = read(’Pt-m13-emt.traj’)<br />

>>> pt.get_distance(0, 9)<br />

2.6245031681662452<br />

Convergence test<br />

See convergence.py.<br />

7.8.6 To be done<br />

• Optimize c/a ratio.<br />

82 Chapter 7. Documentation for modules in <strong>ASE</strong>


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

• Implement different way of cell sampling for eos: [a0 + s for s in [x * np.array(range(- N/2 + 1, N/2 +<br />

1))]] where x is sampling step length, N number of steps. Current way of sampling gives different length of<br />

sampling interval depending on the lattice constant guess a0. DONE<br />

• Write results to file (pickel, csv, cmr (db), traj, ...) per system, together with json file!<br />

• Split off EnergyTask from Task.<br />

• Set correct magnetic moments for atoms. DONE<br />

• Allow setting charges in ase.tasks.task<br />

• Check occupation numbers and requested total magnetic moments for molecules/atoms. DONE<br />

• Add –exclude option.<br />

• Relax cell. DONE<br />

• Optimize first then fit. DONE<br />

• Behavior of -w option?<br />

• Reaction task?<br />

• Rethink analysis and summary stuff:<br />

– it would be nice to calculate for example cohesive energies on the command line, i.e. using<br />

species belonging to different tasks<br />

– analysis should be more modular: one may want for example to calculate zpe energies for adsorption<br />

systems including molecules and surfaces and print the zpe correction for a given reaction.<br />

• ase.tasks.main - print complete architecture string in case of error (like in ase/test/__init__.py)<br />

7.9 Creating atomic structures<br />

See Also:<br />

• The lattice module<br />

• The spacegroup module<br />

• The surface module<br />

7.9.1 Common bulk crystals<br />

ase.structure.bulk(name, crystalstructure, a=None, c=None, covera=None, orthorhombic=False,<br />

cubic=False)<br />

Helper function for creating bulk systems.<br />

examples:<br />

name: str Chemical symbol or symbols as in ‘MgO’ or ‘NaCl’.<br />

crystalstructure: str Must be one of sc, fcc, bcc, hcp, diamond, zincblende or rocksalt.<br />

a: float Lattice constant.<br />

c: float Lattice constant.<br />

covera: float c/a raitio used for hcp. Defaults to ideal ratio.<br />

orthorhombic: bool Construct orthorhombic unit cell instead of primitive cell which is the default.<br />

cubic: bool Construct cubic unit cell.<br />

7.9. Creating atomic structures 83


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

>>> from ase.structure import bulk<br />

>>> a1 = bulk(’Cu’, ’fcc’, a=3.6)<br />

>>> a2 = bulk(’Cu’, ’fcc’, a=3.6, orthorhombic=True)<br />

>>> a3 = bulk(’Cu’, ’fcc’, a=3.6, cubic=True)<br />

>>> a1.cell<br />

array([[ 0. , 1.8, 1.8],<br />

[ 1.8, 0. , 1.8],<br />

[ 1.8, 1.8, 0. ]])<br />

>>> a2.cell<br />

array([[ 2.54558441, 0. , 0. ],<br />

[ 0. , 2.54558441, 0. ],<br />

[ 0. , 0. , 3.6 ]])<br />

>>> a3.cell<br />

array([[ 3.6, 0. , 0. ],<br />

[ 0. , 3.6, 0. ],<br />

[ 0. , 0. , 3.6]])<br />

7.9.2 Nanotubes<br />

ase.structure.nanotube(n, m, length=1, bond=1.42, symbol=’C’, verbose=False)<br />

examples:<br />

>>> from ase.structure import nanotube<br />

>>> cnt1 = nanotube(6, 0, length=4)<br />

>>> cnt2 = nanotube(3, 3, length=6, bond=1.4, symbol=’Si’)<br />

7.9.3 Graphene nanoribbons<br />

ase.structure.graphene_nanoribbon(n, m, type=’zigzag’, saturated=False, C_H=1.09,<br />

C_C=1.42, vacuum=2.5, magnetic=None, initial_mag=1.12,<br />

sheet=False, main_element=’C’,<br />

saturate_element=’H’, vacc=None)<br />

Create a graphene nanoribbon.<br />

Creates a graphene nanoribbon in the x-z plane, with the nanoribbon running along the z axis.<br />

Parameters:<br />

n: int The width of the nanoribbon.<br />

84 Chapter 7. Documentation for modules in <strong>ASE</strong>


examples:<br />

m: int The length of the nanoribbon.<br />

type: str The orientation of the ribbon. Must be either ‘zigzag’ or ‘armchair’.<br />

saturated: bool If true, hydrogen atoms are placed along the edge.<br />

C_H: float Carbon-hydrogen bond length. Default: 1.09 Angstrom.<br />

C_C: float Carbon-carbon bond length. Default: 1.42 Angstrom.<br />

vacuum: float Amount of vacuum added to both sides. Default 2.5 Angstrom.<br />

magnetic: bool Make the edges magnetic.<br />

initial_mag: float Magnitude of magnetic moment if magnetic=True.<br />

sheet: bool If true, make an infinite sheet instead of a ribbon.<br />

>>> from ase.structure import graphene_nanoribbon<br />

>>> gnr1 = graphene_nanoribbon(3, 4, type=’armchair’, saturated=True)<br />

>>> gnr2 = graphene_nanoribbon(2, 6, type=’zigzag’, saturated=True,<br />

>>> C_H=1.1, C_C=1.4, vacuum=6.0,<br />

>>> magnetic=True, initial_mag=1.12)<br />

7.9.4 Special points in the Brillouin zone<br />

You can find the psecial points in the Brillouin zone:<br />

>>> from ase.structure import bulk<br />

>>> from ase.dft.kpoints import ibz_points, get_bandpath<br />

>>> si = bulk(’Si’, ’diamond’, a=5.459)<br />

>>> points = ibz_points[’fcc’]<br />

>>> G = points[’Gamma’]<br />

>>> X = points[’X’]<br />

>>> W = points[’W’]<br />

>>> K = points[’K’]<br />

>>> L = points[’L’]<br />

>>> kpts, x, X = get_bandpath([W, L, G, X, W, K], si.cell)<br />

>>> print len(kpts), len(x), len(X)<br />

50 50 6<br />

<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

7.9. Creating atomic structures 85


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

7.9.5 Surfaces<br />

Common surfaces<br />

A number of utility functions are provided to set up the most common surfaces, to add vacuum layers, and to add<br />

adsorbates to a surface. In general, all surfaces can be set up with the modules described in the section General<br />

crystal structures and surfaces, but these utility functions make common tasks easier.<br />

Example<br />

To setup an Al(111) surface with a hydrogen atom adsorbed in an on-top position:<br />

from ase.lattice.surface import *<br />

slab = fcc111(’Al’, size=(2,2,3), vacuum=10.0)<br />

This will produce a slab 2x2x3 times the minimal possible size, with a (111) surface in the z direction. A 10 Å<br />

vacuum layer is added on each side.<br />

To set up the same surface with with a hydrogen atom adsorbed in an on-top position 1.5 Å above the top layer:<br />

from ase.lattice.surface import *<br />

slab = fcc111(’Al’, size=(2,2,3))<br />

add_adsorbate(slab, ’H’, 1.5, ’ontop’)<br />

slab.center(vacuum=10.0, axis=2)<br />

Note that in this case is is probably not meaningful to use the vacuum keyword to fcc111, as we want to leave 10<br />

Å of vacuum after the adsorbate has been added. Instead, the center() method of the Atoms is used to add<br />

the vacuum and center the system.<br />

The atoms in the slab will have tags set to the layer number: First layer atoms will have tag=1, second layer atoms<br />

will have tag=2, and so on. Addsorbates get tag=0:<br />

>>> print atoms.get_tags()<br />

[3 3 3 3 2 2 2 2 1 1 1 1 0]<br />

This can be useful for setting up constraints (see Diffusion of gold atom on Al(100) surface (NEB)).<br />

Utility functions for setting up surfaces<br />

All the functions setting up surfaces take the same arguments.<br />

symbol: The chemical symbol of the element to use.<br />

size: A tuple giving the system size in units of the minimal unit cell.<br />

a: (optional) The lattice constant. If specified, it overrides the expermental lattice constant of the element. Must<br />

be specified if setting up a crystal structure different from the one found in nature.<br />

c: (optional) Extra HCP lattice constant. If specified, it overrides the expermental lattice constant of the element.<br />

Can be specified if setting up a crystal structure different from the one found in nature and an ideal c/a ratio<br />

is not wanted (c/a = (8/3) 1/3 ).<br />

vacuum: The thickness of the vacuum layer. The specified amount of vacuum appears on both sides of the slab.<br />

Default value is None, meaning not to add any vacuum. In that case a “vacuum” layer equal to the interlayer<br />

spacing will be present on the upper surface of the slab. Specify vacuum=0.0 to remove it.<br />

orthogonal: (optional, not supported by all functions). If specified and true, forces the creation of a unit cell with<br />

orthogonal basis vectors. If the default is such a unit cell, this argument is not supported.<br />

Each function defines a number of standard adsorbtion sites that can later be used when adding an adsorbate with<br />

lattice.surface.add_adsorbate().<br />

86 Chapter 7. Documentation for modules in <strong>ASE</strong>


The following functions are provided<br />

ase.lattice.surface.fcc100(symbol, size, a=None, vacuum=0.0)<br />

ase.lattice.surface.fcc110(symbol, size, a=None, vacuum=0.0)<br />

ase.lattice.surface.bcc100(symbol, size, a=None, vacuum=0.0)<br />

ase.lattice.surface.hcp10m10(symbol, size, a=None, c=None, vacuum=0.0)<br />

ase.lattice.surface.diamond100(symbol, size, a=None, vacuum=0.0)<br />

These allways give orthorhombic cells:<br />

<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

7.9. Creating atomic structures 87


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

fcc100<br />

fcc110<br />

bcc100<br />

hcp10m10<br />

diamond100<br />

ase.lattice.surface.fcc111(symbol, size, a=None, vacuum=0.0, orthogonal=False)<br />

ase.lattice.surface.bcc110(symbol, size, a=None, vacuum=0.0, orthogonal=False)<br />

ase.lattice.surface.bcc111(symbol, size, a=None, vacuum=0.0, orthogonal=False)<br />

ase.lattice.surface.hcp0001(symbol, size, a=None, c=None, vacuum=0.0, orthogonal=False)<br />

88 Chapter 7. Documentation for modules in <strong>ASE</strong>


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

ase.lattice.surface.diamond111(symbol, size, a=None, vacuum=0.0, orthogonal=False)<br />

These can give both non-orthorhombic and orthorhombic cells:<br />

fcc111<br />

bcc110<br />

bcc111<br />

hcp0001<br />

diamond111 not implemented<br />

The adsorption sites are marked with:<br />

7.9. Creating atomic structures 89


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

ontop hollow fcc hcp bridge shortbridge longbridge<br />

Adding new utility functions If you need other surfaces than the ones above, the easiest is to look in the source<br />

file surface.py, and adapt one of the existing functions. Please contribute any such function that you make either<br />

by cheking it into SVN or by mailing it to the developers.<br />

Adding adsorbates<br />

After a slab has been created, a vacuum layer can be added. It is also possible to add one or more adsorbates.<br />

ase.lattice.surface.add_adsorbate(slab, adsorbate, height, position=(0, 0), offset=None,<br />

mol_index=0)<br />

Add an adsorbate to a surface.<br />

This function adds an adsorbate to a slab. If the slab is produced by one of the utility functions in<br />

ase.lattice.surface, it is possible to specify the position of the adsorbate by a keyword (the supported keywords<br />

depend on which function was used to create the slab).<br />

If the adsorbate is a molecule, the atom indexed by the mol_index optional argument is positioned on top<br />

of the adsorption position on the surface, and it is the responsibility of the user to orient the adsorbate in a<br />

sensible way.<br />

This function can be called multiple times to add more than one adsorbate.<br />

Parameters:<br />

slab: The surface onto which the adsorbate should be added.<br />

adsorbate: The adsorbate. Must be one of the following three types: A string containing the chemical<br />

symbol for a single atom. An atom object. An atoms object (for a molecular adsorbate).<br />

height: Height above the surface.<br />

position: The x-y position of the adsorbate, either as a tuple of two numbers or as a keyword (if the surface<br />

is produced by one of the functions in ase.lattice.surfaces).<br />

offset (default: None): Offsets the adsorbate by a number of unit cells. Mostly useful when adding<br />

more than one adsorbate.<br />

mol_index (default: 0): If the adsorbate is a molecule, index of the atom to be positioned above the location<br />

specified by the position argument.<br />

Note position is given in absolute xy coordinates (or as a keyword), whereas offset is specified in unit cells.<br />

This can be used to give the positions in units of the unit cell by using offset instead.<br />

Create specific non-common surfaces<br />

New in version 3.5.2. In addition to the most normal surfaces, a function has been constructed to create more<br />

uncommon surfaces that one could be interested in. It is constructed upon the Miller Indices defining the surface<br />

and can be used for both fcc, bcc and hcp structures. The theory behind the implementation can be found here:<br />

general_surface.pdf.<br />

Example<br />

To setup a Au(211) surface with 9 layers and 10 Å of vacuum:<br />

from ase.lattice.surface import surface<br />

s1 = surface(’Au’, (2, 1, 1), 9)<br />

s1.center(vacuum=10, axis=2)<br />

90 Chapter 7. Documentation for modules in <strong>ASE</strong>


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

This is the easy way, where you use the experimental lattice constant for gold bulk structure. You can write:<br />

from ase.visualize import view<br />

view(s1)<br />

or simply s1.edit() if you want to see and rotate the structure.<br />

Next example is a molybdenum bcc(321) surface where we decide what lattice constant to use:<br />

from ase.lattice import bulk<br />

Mobulk = bulk(’Mo’, ’bcc’, a=3.16, cubic=True)<br />

s2 = surface(Mobulk, (3, 2, 1), 9)<br />

s2.center(vacuum=10, axis=2)<br />

7.9. Creating atomic structures 91


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

As the last example, creation of alloy surfaces is also very easily carried out with this module. In this example,<br />

two Pt3Rh fcc(211) surfaces will be created:<br />

a = 4.0<br />

from ase import Atoms<br />

Pt3Rh = Atoms(’Pt3Rh’,<br />

scaled_positions=[(0, 0, 0),<br />

(0.5, 0.5, 0),<br />

(0.5, 0, 0.5),<br />

(0, 0.5, 0.5)],<br />

cell=[a, a, a],<br />

pbc=True)<br />

s3 = surface(Pt3Rh, (2, 1, 1), 9)<br />

s3.center(vacuum=10, axis=2)<br />

Pt3Rh.set_chemical_symbols(’PtRhPt2’)<br />

s4 = surface(Pt3Rh , (2, 1, 1), 9)<br />

s4.center(vacuum=10, axis=2)<br />

92 Chapter 7. Documentation for modules in <strong>ASE</strong>


7.9.6 General crystal structures and surfaces<br />

<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

Modules for creating crystal structures are found in the module lattice. Most Bravais lattices are implemented,<br />

as are a few important lattices with a basis. The modules can create lattices with any orientation (see below). These<br />

modules can be used to create surfaces with any crystal structure and any orientation by later adding a vacuum<br />

layer with lattice.surface.add_vacuum().<br />

Example<br />

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]<br />

along the z-axis, use:<br />

7.9. Creating atomic structures 93


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

from ase.lattice.cubic import FaceCenteredCubic<br />

atoms = FaceCenteredCubic(directions=[[1,-1,0], [1,1,-2], [1,1,1]],<br />

size=(2,2,3), symbol=’Cu’, pbc=(1,1,0))<br />

The minimal unit cell is repeated 2*2*3 times. The lattice constant is taken from the database of lattice constants<br />

in data module. There are periodic boundary conditions along the x and y axis, but free boundary conditions<br />

along the z axis. Since the three directions are perpendicular, a (111) surface is created.<br />

To set up a slab of BCC copper with [100] along the first axis, [010] along the second axis, and [111] along the<br />

third axis use:<br />

from ase.lattice.cubic import BodyCenteredCubic<br />

atoms = BodyCenteredCubic(directions=[[1,0,0], [0,1,0], [1,1,1]],<br />

size=(2,2,3), symbol=’Cu’, pbc=(1,1,0),<br />

latticeconstant=4.0)<br />

Since BCC is not the natural crystal structure for Cu, a lattice constant has to be specified. Note that since the<br />

repeat directions of the unit cell are not orthogonal, the Miller indices of the surfaces will not be the same as the<br />

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).<br />

Available crystal lattices<br />

The following modules are currently available (the * mark lattices with a basis):<br />

• lattice.cubic<br />

– SimpleCubic<br />

– FaceCenteredCubic<br />

– BodyCenteredCubic<br />

– Diamond (*)<br />

• lattice.tetragonal<br />

– SimpleTetragonal<br />

– CenteredTetragonal<br />

• lattice.orthorhombic<br />

– SimpleOrthorhombic<br />

– BaseCenteredOrthorhombic<br />

– FaceCenteredOrthorhombic<br />

– BodyCenteredOrthorhombic<br />

• lattice.monoclinic<br />

– SimpleMonoclinic<br />

– BaseCenteredMonoclinic<br />

• lattice.triclinic<br />

– Triclinic<br />

• lattice.hexagonal<br />

– Hexagonal<br />

– HexagonalClosedPacked (*)<br />

– Graphite (*)<br />

94 Chapter 7. Documentation for modules in <strong>ASE</strong>


Usage<br />

<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

• The rhombohedral (or trigonal) lattices are not implemented. They will be implemented when the need<br />

arises (and if somebody can tell me the precise definition of the 4-number Miller indices - I only know that<br />

they are “almost the same as in hexagonal lattices”).<br />

• lattice.compounds<br />

Lattices with more than one element. These are mainly intended as examples allowing you to define new<br />

such lattices. Currenly, the following are defined<br />

– B1 = NaCl = Rocksalt<br />

– B2 = CsCl<br />

– B3 = ZnS = Zincblende<br />

– L1_2 = AuCu3<br />

– L1_0 = AuCu<br />

The lattice objects are called with a number of arguments specifying e.g. the size and orientation of the lattice.<br />

All arguments should be given as named arguments. At a minimum the symbol argument must be specified.<br />

symbol The element, specified by the atomic number (an integer) or by the atomic symbol (i.e. ‘Au’). For<br />

compounds, a tuple or list of elements should be given. This argument is mandatory.<br />

directions and/or miller: Specifies the orientation of the lattice as the Miller indices of the three basis<br />

vectors of the supercell (directions=...) and/or as the Miller indices of the three surfaces<br />

(miller=...). Normally, one will specify either three directions or three surfaces, but any combination<br />

that is both complete and consistent is allowed, e.g. two directions and two surface miller indices (this<br />

example is slightly redundant, and consistency will be checked). If only some directions/miller indices are<br />

specified, the remaining should be given as None. If you intend to generate a specific surface, and prefer to<br />

specify the miller indices of the unit cell basis (directions=...), it is a good idea to give the desired<br />

Miller index of the surface as well to allow the module to test for consistency. Example:<br />

>>> atoms = BodyCenteredCubic(directions=[[1,-1,0],[1,1,-1],[0,0,1]],<br />

... miller=[None, None, [1,1,2]], ...)<br />

If neither directions nor miller are specified, the default is directions=[[1,0,0],<br />

[0,1,0], [0,0,1]].<br />

size: A tuple of three numbers, defining how many times the fundamental repeat unit is repeated. Default:<br />

(1,1,1). Be aware that if high-index directions are specified, the fundamental repeat unit may be large.<br />

latticeconstant: The lattice constant. If no lattice constant is specified, one is extracted from<br />

<strong>ASE</strong>.ChemicalElements provided that the element actually has the crystal structure you are creating. Depending<br />

on the crystal structure, there will be more than one lattice constant, and they are specified by giving<br />

a dictionary or a tuple (a scalar for cubic lattices). Distances are given in Angstrom, angles in degrees.<br />

Structure Lattice constants Dictionary-keys<br />

Cubic a ‘a’<br />

Tetragonal (a, c) ‘a’, ‘c’ or ‘c/a’<br />

Orthorhombic (a, b, c) ‘a’, ‘b’ or ‘b/a’, ‘c’ or ‘c/a’<br />

Triclinic (a, b, c, α, β, γ) ‘a’, ‘b’ or ‘b/a’, ‘c’ or ‘c/a’, ‘alpha’, ‘beta’, ‘gamma’<br />

Monoclinic (a, b, c, alpha) ‘a’, ‘b’ or ‘b/a’, ‘c’ or ‘c/a’, ‘alpha’<br />

Hexagonal (a, c) ‘a’, ‘c’ or ‘c/a’<br />

Example:<br />

>>> atoms = Monoclinic( ... , latticeconstant={’a’: 3.06,<br />

... ’b/a’: 0.95, ’c/a’: 1.07, ’alpha’: 74})<br />

debug: Controls the amount of information printed. 0: no info is printed. 1 (the default): The indices of surfaces<br />

and unit cell vectors are printed. 2: Debugging info is printed.<br />

7.9. Creating atomic structures 95


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

Defining new lattices<br />

Often, there is a need for new lattices - either because an element crystallizes in a lattice that is not a simple<br />

Bravais lattice, or because you need to work with a compound or an ordered alloy.<br />

All the lattice generating objects are instances of a class, you generate new lattices by deriving a new class and<br />

instantiating it. This is best explained by an example. The diamond lattice is two interlacing FCC lattices, so it<br />

can be seen as a face-centered cubic lattice with a two-atom basis. The Diamond object could be defined like this:<br />

from ase.lattice.cubic import FaceCenteredCubicFactory<br />

class DiamondFactory(FaceCenteredCubicFactory):<br />

"""A factory for creating diamond lattices."""<br />

xtal_name = ’diamond’<br />

bravais_basis = [[0, 0, 0], [0.25, 0.25, 0.25]]<br />

Diamond = DiamondFactory()<br />

Lattices with more than one element<br />

Lattices with more than one element is made in the same way. A new attribute, element_basis, is added,<br />

giving which atoms in the basis are which element. If there are four atoms in the basis, and element_basis is<br />

(0,0,1,0), then the first, second and fourth atoms are one element, and the third is the other element. As an<br />

example, the AuCu3 structure (also known as L12) is defined as:<br />

# The L1_2 structure is "based on FCC", but is really simple cubic<br />

# with a basis.<br />

class AuCu3Factory(SimpleCubicFactory):<br />

"A factory for creating AuCu3 (L1_2) lattices."<br />

bravais_basis = [[0, 0, 0], [0, 0.5, 0.5], [0.5, 0, 0.5], [0.5, 0.5, 0]]<br />

element_basis = (0, 1, 1, 1)<br />

AuCu3 = L1_2 = AuCu3Factory()<br />

Sometimes, more than one crystal structure can be used to define the crystal structure, for example the Rocksalt<br />

structure is two interpenetrating FCC lattices, one with one kind of atoms and one with another. It would be<br />

tempting to define it as<br />

class NaClFactory(FaceCenteredCubicFactory):<br />

"A factory for creating NaCl (B1, Rocksalt) lattices."<br />

bravais_basis = [[0, 0, 0], [0.5, 0.5, 0.5]]<br />

element_basis = (0, 1)<br />

B1 = NaCl = Rocksalt = NaClFactory()<br />

but if this is used to define a finite system, one surface would be covered with one type of atoms, and the opposite<br />

surface with the other. To maintain the stochiometry of the surfaces, it is better to use the simple cubic lattice with<br />

a larger basis:<br />

# To prevent a layer of element one on one side, and a layer of<br />

# element two on the other side, NaCl is based on SimpleCubic instead<br />

# of on FaceCenteredCubic<br />

class NaClFactory(SimpleCubicFactory):<br />

"A factory for creating NaCl (B1, Rocksalt) lattices."<br />

bravais_basis = [[0, 0, 0], [0, 0, 0.5], [0, 0.5, 0], [0, 0.5, 0.5],<br />

[0.5, 0, 0], [0.5, 0, 0.5], [0.5, 0.5, 0],<br />

[0.5, 0.5, 0.5]]<br />

element_basis = (0, 1, 1, 0, 1, 0, 0, 1)<br />

96 Chapter 7. Documentation for modules in <strong>ASE</strong>


B1 = NaCl = Rocksalt = NaClFactory()<br />

More examples can be found in the file ase/lattice/compounds.py.<br />

7.9.7 Molecules<br />

The G2-database of common molecules is available in the data.molecules module.<br />

ase.data.molecules.molecule(name, **kwargs)<br />

Deprecated.<br />

Example:<br />

>>> from ase.data.molecules import molecule<br />

>>> atoms = molecule(’H2O’)<br />

<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

<strong>ASE</strong> contains a number of modules for setting up atomic structures, mainly molecules, bulk crystals and surfaces.<br />

Some of these modules have overlapping functionality, but strike a different balance between flexibility and easeof-use.<br />

Common bulk crystals<br />

The ase.structure.bulk() function can be used to create the most common bulk crystal structures. The<br />

function creates a single unit cell oriented such that the number of atoms in the cell is minimal.<br />

Read more: Common bulk crystals.<br />

Common surfaces<br />

The lattice.surface module contains a number of functions for creating the most common surfaces in a<br />

minimal unit cell, and for adding adsorbates to these surfaces.<br />

Read more: Surfaces.<br />

Nanotubes and nanoribbons<br />

The functions ase.structure.nanotube() and ase.structure.graphene_nanoribbon() can<br />

be used to create Carbon nanotubes and graphene sheets or nanoribbons. Per default, they create Carbon nanotubes<br />

and sheets, but other elements can be used.<br />

Read more: Nanotubes and Graphene nanoribbons.<br />

Generally oriented bulk crystals and surfaces<br />

The lattice module contains functions for creating most common crystal structures with arbitrary orientation.<br />

The user can specify the desired Miller index along the three axes of the simulation, and the smallest periodic<br />

structure fulfilling this specification is created. Thirteen of the 14 Bravais lattices are supported by the module, as<br />

are a few lattices with a basis, and lattices for some of the most common compounds/alloys. The modules makes<br />

it possible to define further lattices based on the supported Bravais lattices.<br />

Both bulk crystals and surfaces can be created.<br />

Read more: General crystal structures and surfaces.<br />

Molecules<br />

Some common molecules are available in the molecules module.<br />

Read more: Molecules.<br />

7.10 Structure optimization<br />

The optimization algorithms can be roughly divided into local optimization algorithms which find a nearby local<br />

minimum and global optimization algorithms that try to find the global minimum (a much harder task).<br />

7.10. Structure optimization 97


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

7.10.1 Local optimization<br />

The local optimization algorithms available in <strong>ASE</strong> are: BFGS, LBFGS, BFGSLineSearch,<br />

LBFGSLineSearch, MDMin, and FIRE.<br />

See Also:<br />

Performance test for all <strong>ASE</strong> local optimizers.<br />

MDMin and FIRE both use Newtonian dynamics with added friction, to converge to an energy minimum, whereas<br />

the others are of the quasi-Newton type, where the forces of consecutive steps are used to dynamically update a<br />

Hessian describing the curvature of the potential energy landscape. You can use the QuasiNewton synonym for<br />

BFGSLineSearch because this algorithm is in many cases the optimal of the quasi-Newton algorithms.<br />

All of the local optimizer classes have the following structure:<br />

class Optimizer:<br />

def __init__(self, atoms, restart=None, logfile=None):<br />

def run(self, fmax=0.05, steps=100000000):<br />

def get_number_of_steps():<br />

The convergence criterion is that the force on all individual atoms should be less than fmax:<br />

BFGS<br />

max |<br />

a<br />

� Fa| < fmax<br />

The BFGS object is one of the minimizers in the <strong>ASE</strong> package. The below script uses BFGS to optimize the<br />

structure of a water molecule, starting with the experimental geometry:<br />

from ase import Atoms<br />

from ase.optimize import BFGS<br />

from ase.calculators.emt import EMT<br />

import numpy as np<br />

d = 0.9575<br />

t = np.pi / 180 * 104.51<br />

water = Atoms(’H2O’,<br />

positions=[(d, 0, 0),<br />

(d * np.cos(t), d * np.sin(t), 0),<br />

(0, 0, 0)],<br />

calculator=EMT())<br />

dyn = BFGS(water)<br />

dyn.run(fmax=0.05)<br />

which produces the following output. The columns are the solver name, step number, clock time, potential energy<br />

(eV), and maximum force.:<br />

BFGS: 0 19:45:25 2.769633 8.6091<br />

BFGS: 1 19:45:25 2.154560 4.4644<br />

BFGS: 2 19:45:25 1.906812 1.3097<br />

BFGS: 3 19:45:25 1.880255 0.2056<br />

BFGS: 4 19:45:25 1.879488 0.0205<br />

When doing structure optimization, it is useful to write the trajectory to a file, so that the progress of the optimization<br />

run can be followed during or after the run:<br />

dyn = BFGS(water, trajectory=’H2O.traj’)<br />

dyn.run(fmax=0.05)<br />

Use the command ag H2O.traj to see what is going on (more here: gui). The trajectory file can also be<br />

accessed using the module ase.io.trajectory.<br />

98 Chapter 7. Documentation for modules in <strong>ASE</strong>


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

The attach method takes an optional argument interval=n that can be used to tell the structure optimizer<br />

object to write the configuration to the trajectory file only every n steps.<br />

During a structure optimization, the BFGS and LBFGS optimizers use two quantities to decide where to move the<br />

atoms on each step:<br />

• the forces on each atom, as returned by the associated Calculator object<br />

∂ • the Hessian matrix, i.e. the matrix of second derivatives 2 E<br />

∂xi∂xj<br />

coordinates.<br />

of the total energy with respect to nuclear<br />

If the atoms are close to the minimum, such that the potential energy surface is locally quadratic, the Hessian<br />

and forces accurately determine the required step to reach the optimal structure. The Hessian is very expensive to<br />

calculate a priori, so instead the algorithm estimates it by means of an initial guess which is adjusted along the<br />

way depending on the information obtained on each step of the structure optimization.<br />

It is frequently practical to restart or continue a structure optimization with a geometry obtained from a previous<br />

relaxation. Aside from the geometry, the Hessian of the previous run can and should be retained for the second<br />

run. Use the restart keyword to specify a file in which to save the Hessian:<br />

dyn = BFGS(atoms=system, trajectory=’qn.traj’, restart=’qn.pckl’)<br />

This will create an optimizer which saves the Hessian to qn.pckl (using the Python pickle module) on each<br />

step. If the file already exists, the Hessian will also be initialized from that file.<br />

The trajectory file can also be used to restart a structure optimization, since it contains the history of all forces and<br />

positions, and thus whichever information about the Hessian was assembled so far:<br />

dyn = BFGS(atoms=system, trajectory=’qn.traj’)<br />

dyn.replay_trajectory(’history.traj’)<br />

This will read through each iteration stored in history.traj, performing adjustments to the Hessian as appropriate.<br />

Note that these steps will not be written to qn.traj. If restarting with more than one previous trajectory<br />

file, use ag to concatenate them into a single trajectory file first:<br />

$ ag part1.traj part2.traj -o history.traj<br />

The file history.traj will then contain all necessary information.<br />

When switching between different types of optimizers, e.g. between BFGS and LBFGS, the pickle-files specified<br />

by the restart keyword are not compatible, but the Hessian can still be retained by replaying the trajectory as<br />

above.<br />

LBFGS<br />

LBFGS is the limited memory version of the BFGS algorithm, where the inverse of Hessian matrix is updated<br />

instead of the Hessian itself. Two ways exist for determining the atomic step: Standard LBFGS and<br />

LBFGSLineSearch. For the first one, both the directions and lengths of the atomic steps are determined by the<br />

approximated Hessian matrix. While for the latter one, the approximated Hessian matrix is only used to find out<br />

the directions of the line searches and atomic steps, the step lengths are determined by the forces.<br />

To start a structure optimization with LBFGS algorithm is similar to BFGS. A typical optimization should look<br />

like:<br />

dyn = LBFGS(atoms=system, trajectory=’lbfgs.traj’, restart=’lbfgs.pckl’)<br />

where the trajectory and the restart save the trajectory of the optimization and the vectors needed to generate the<br />

Hessian Matrix.<br />

FIRE<br />

Read about this algorithm here:<br />

Erik Bitzek, Pekka Koskinen, Franz Gähler, Michael Moseler, and Peter Gumbsch<br />

7.10. Structure optimization 99


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

MDMin<br />

Structural Relaxation Made Simple<br />

Physical Review Letters, Vol. 97, 170201 (2006)<br />

The MDmin algorithm is a modification of the usual velocity-Verlet molecular dynamics algorithm. Newtons<br />

second law is solved numerically, but after each time step the dot product between the forces and the momenta is<br />

checked. If it is zero, the system has just passed through a (local) minimum in the potential energy, the kinetic<br />

energy is large and about to decrease again. At this point, the momentum is set to zero. Unlike a “real” molecular<br />

dynamics, the masses of the atoms are not used, instead all masses are set to one.<br />

The MDmin algorithm exists in two flavors, one where each atom is tested and stopped individually, and one<br />

where all coordinates are treated as one long vector, and all momenta are set to zero if the dotproduct between the<br />

momentum vector and force vector (both of length 3N) is zero. This module implements the latter version.<br />

Although the algorithm is primitive, it performs very well because it takes advantage of the physics of the problem.<br />

Once the system is so near the minimum that the potential energy surface is approximately quadratic it becomes<br />

advantageous to switch to a minimization method with quadratic convergence, such as Conjugate Gradient or<br />

Quasi Newton.<br />

SciPy optimizers<br />

SciPy provides a number of optimizers. An interface module for a couple of these have been written for <strong>ASE</strong>.<br />

Most notable are the optimizers SciPyFminBFGS and SciPyFminCG. These are called with the regular syntax and<br />

can be imported as:<br />

from ase.optimize.sciopt import SciPyFminBFGS, SciPyFminCG<br />

class ase.optimize.sciopt.SciPyFminBFGS(atoms, logfile=’-‘, trajectory=None, callback_always=False,<br />

alpha=70.0)<br />

Quasi-Newton method (Broydon-Fletcher-Goldfarb-Shanno)<br />

Initialize object<br />

Parameters:<br />

callback_always: book Should the callback be run after each force call (also in the linesearch)<br />

alpha: float Initial guess for the Hessian (curvature of energy surface). A conservative value of 70.0 is the<br />

default, but number of needed steps to converge might be less if a lower value is used. However, a<br />

lower value also means risk of instability.<br />

class ase.optimize.sciopt.SciPyFminCG(atoms, logfile=’-‘, trajectory=None, callback_always=False,<br />

alpha=70.0)<br />

Non-linear (Polak-Ribiere) conjugate gradient algorithm<br />

See Also:<br />

Initialize object<br />

Parameters:<br />

callback_always: book Should the callback be run after each force call (also in the linesearch)<br />

alpha: float Initial guess for the Hessian (curvature of energy surface). A conservative value of 70.0 is the<br />

default, but number of needed steps to converge might be less if a lower value is used. However, a<br />

lower value also means risk of instability.<br />

SciPyFminBFGS, SciPyFminCG<br />

100 Chapter 7. Documentation for modules in <strong>ASE</strong>


BFGSLineSearch<br />

<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

BFGSLineSearch is the BFGS algorithm with an line search mechanism that enforces the step taken fulfills the<br />

Wolfe conditions, so that the energy and absolute value of the force decrease monotonically. Like the lbfgs<br />

algorithm the inverse of the Hessian Matrix is updated.<br />

The usage of BFGSLineSearch algorithm is similar to other BFGS type algorithms. A typical optimization should<br />

look like:<br />

from ase.optimize.bfgslinesearch import BFGSLineSearch<br />

dyn = BFGSLineSearch(atoms=system, trajectory=’bfgs_ls.traj’, restart=’bfgs_ls.pckl’)<br />

where the trajectory and the restart save the trajectory of the optimization and the information needed to generate<br />

the Hessian Matrix.<br />

Note: In many of the examples, tests, exercises and tutorials, QuasiNewton is used – it is a synonym for<br />

BFGSLineSearch.<br />

7.10.2 Global optimization<br />

There are currently two global optimisation algorithms available.<br />

Basin hopping<br />

The global optimization algorithm can be used quite similar as a local optimization algorithm:<br />

from ase import *<br />

from ase.optimize.basin import BasinHopping<br />

bh = BasinHopping(atoms=system, # the system to optimize<br />

temperature=100 * kB, # ’temperature’ to overcome barriers<br />

dr=0.5, # maximal stepwidth<br />

optimizer=LBFGS, # optimizer to find local minima<br />

fmax=0.1, # maximal force for the optimizer<br />

)<br />

Read more about this algorithm here:<br />

and here:<br />

David J. Wales and Jonathan P. K. Doye<br />

Global Optimization by Basin-Hopping and the Lowest Energy Structures of Lennard-Jones Clusters<br />

Containing up to 110 Atoms<br />

J. Phys. Chem. A, Vol. 101, 5111-5116 (1997)<br />

David J. Wales and Harold A. Scheraga<br />

Global Optimization of Clusters, Crystals, and Biomolecules<br />

Science, Vol. 285, 1368 (1999)<br />

Minima hopping<br />

The minima hopping algorithm was developed and described by Goedecker:<br />

Stefan Goedecker<br />

Minima hopping: An efficient search method for the global minimum of the potential energy surface<br />

of complex molecular systems<br />

J. Chem. Phys., Vol. 120, 9911 (2004)<br />

7.10. Structure optimization 101


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

This algorithm utilizes a series of alternating steps of NVE molecular dynamics and local optimizations, and has<br />

two parameters that the code dynamically adjusts in response to the progress of the search. The first parameter<br />

is the initial temperature of the NVE simulation. Whenever a step finds a new minimum this temperature is<br />

decreased; if the step finds a previously found minimum the temperature is increased. The second dynamically<br />

adjusted parameter is Ediff, which is an energy threshold for accepting a newly found minimum. If the new<br />

minimum is no more than Ediff eV higher than the previous minimum, it is acccepted and Ediff is decreased; if it<br />

is more than Ediff eV higher it is rejected and Ediff is increased. The method is used as:<br />

from ase.optimize.minimahopping import MinimaHopping<br />

opt = MinimaHopping(atoms=system)<br />

opt(totalsteps=10)<br />

This will run the algorithm until 10 steps are taken; alternatively, if totalsteps is not specified the algorithm will<br />

run indefinitely (or until stopped by a batch system). A number of optional arguments can be fed when initializing<br />

the algorithm as keyword pairs. The keywords and default values are:<br />

T0: 1000., # K, initial MD ‘temperature’<br />

beta1: 1.1, # temperature adjustment parameter<br />

beta2: 1.1, # temperature adjustment parameter<br />

beta3: 1. / 1.1, # temperature adjustment parameter<br />

Ediff0: 0.5, # eV, initial energy acceptance threshold<br />

alpha1 : 0.98, # energy threshold adjustment parameter<br />

alpha2 : 1. / 0.98, # energy threshold adjustment parameter<br />

mdmin : 2, # criteria to stop MD simulation (no. of minima)<br />

logfile: ‘hop.log’, # text log<br />

minima_threshold : 0.5, # A, threshold for identical configs<br />

timestep : 1.0, # fs, timestep for MD simulations<br />

optimizer : QuasiNewton, # local optimizer to use<br />

minima_traj : ‘minima.traj’, # storage file for minima list<br />

Specific definitions of the alpha, beta, and mdmin parameters can be found in the publication by Goedecker.<br />

minima_threshold is used to determine if two atomic configurations are identical; if any atom has moved by<br />

more than this amount it is considered a new configuration. Note that the code tries to do this in an intelligent<br />

manner: atoms are considered to be indistinguishable, and translations are allowed in the directions of the periodic<br />

boundary conditions. Therefore, if a CO is adsorbed in an ontop site on a (211) surface it will be considered<br />

identical no matter which ontop site it occupies.<br />

The trajectory file minima_traj will be populated with the accepted minima as they are found. A log of the<br />

progress is kept in logfile.<br />

The code is written such that a stopped simulation (e.g., killed by the batching system when the maximum wall<br />

time was exceeded) can usually be restarted without too much effort by the user. In most cases, the script can be<br />

resubmitted without any modification – if the logfile and minima_traj are found, the script will attempt<br />

to use these to resume. (Note that you may need to clean up files left in the directory by the calculator, however,<br />

such as the .nc file produced by Jacapo.)<br />

Note that these searches can be quite slow, so it can pay to have multiple searches running at a time. Multiple<br />

searches can run in parallel and share one list of minima. (Run each script from a separate directory but specify<br />

the location to the same absolute location for minima_traj). Each search will use the global information of the<br />

list of minima, but will keep its own local information of the initial temperature and Ediff.<br />

7.11 Parallel calculations<br />

ase.parallel.paropen(name, mode=’r’, buffering=0)<br />

MPI-safe version of open function.<br />

In read mode, the file is opened on all nodes. In write and append mode, the file is opened on the master<br />

only, and /dev/null is opened on all other nodes.<br />

102 Chapter 7. Documentation for modules in <strong>ASE</strong>


ase.parallel.parprint(*args, **kwargs)<br />

MPI-safe print - prints only from master.<br />

Tries to adopt python 3 behaviour.<br />

7.12 Visualization<br />

visualize.view(atoms, data=None, viewer=None, repeat=None)<br />

<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

This provides an interface to various visualization tools, such as ase.gui, ase.visualize.vtk, RasMol,<br />

VMD, VTK, gOpenMol, or Avogadro. The default viewer is the ase.gui, described in the gui module. The<br />

simplest invocation is:<br />

>>> from ase import view<br />

>>> view(atoms)<br />

where atoms is any Atoms object. Alternative viewers can be used by specifying the optional keyword<br />

viewer=... - use one of ‘ase.gui’, ‘gopenmol’, ‘vmd’, or ‘rasmol’. The VMD and Avogadro viewers can<br />

take an optional data argument to show 3D data, such as charge density:<br />

>>> view(atoms, viewer=’VMD’, data=array)<br />

If you do not wish to open an interactive gui, but rather visualize your structure by dumping directly to a graphics<br />

file; you can use the write command of the io module, which can write ‘eps’, ‘png’, and ‘pov’ files directly,<br />

like this:<br />

>>> write(’image.png’, atoms)<br />

7.12.1 VTK<br />

The Visualization Toolkit (VTK) is a powerful platform-independent graphics engine, which comes as an open<br />

source graphics toolkit licensed under the BSD license. It is available for a wide range of programming languages,<br />

including easily scriptable interfaces in Python and Tcl.<br />

In the scientific community, VTK is used by thousands of researchers and developers for 3D computer graphics,<br />

image processing, and visualization. VTK includes a suite of 3D interaction widgets within the development<br />

framework for information visualization, integrating GUI toolkits such as Qt and Tk into a highly flexible design<br />

platform.<br />

For visualization purposes within <strong>ASE</strong>, two different VTK-approaches are supported, namely:<br />

Scripted on-the-fly rendering <strong>ASE</strong> includes VTK-scripting for easy data visualization using the<br />

vtk module. Development is in progress, so you might want to check out the latest development<br />

release from SVN (see Latest development release).<br />

Interactive rendering MayaVi is an easy-to-use GUI for VTK. With Enthought’s traits-based VTKwrapper<br />

(TVTK), constructing VTK pipelines has been simplified greatly by introducing three<br />

basic concepts: data sources, filters and visualization modules. MayaVi also supports the VTK<br />

file formats, including the flexible VTK XML, which in <strong>ASE</strong> can be used to export atomic<br />

positions, forces and volume data using the write command in the io module.<br />

A key feature of VTK is the inherent ability to use MPI for parallel rending, which is provided with built-in<br />

parallel composite rendering objects to handle domain decomposition and subsequent recombination of the raster<br />

information. This is particularly useful for non-interactive ray tracing, batch isosurface generation and in-situ<br />

visualization of simulation data in cluster computing.<br />

See Also:<br />

ParaView is a VTK-based open-source, multi-platform data analysis and visualization application for extremely<br />

large data-sets using distributed memory computing resources and parallel rendering through MPI.<br />

7.12. Visualization 103


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

7.12.2 PrimiPlotter<br />

The PrimiPlotter is intended to do on-the-fly plotting of the positions of the atoms during long molecular dynamics<br />

simulations. The module ase.visualize.primiplotter contains the PrimiPlotter and the various output<br />

modules, see below.<br />

class ase.visualize.primiplotter.PrimiPlotter(atoms, verbose=0, timing=0, interval=1,<br />

initframe=0)<br />

Primitive PostScript-based plots during a simulation.<br />

The PrimiPlotter plots atoms during simulations, extracting the relevant information from the list of atoms.<br />

It is created using the list of atoms as an argument to the constructor. Then one or more output devices must<br />

be attached using set_output(device). The list of supported output devices is at the end.<br />

The atoms are plotted as circles. The system is first rotated using the angles specified by set_rotation([vx,<br />

vy, vz]). The rotation is vx degrees around the x axis (positive from the y toward the z axis), then vy degrees<br />

around the y axis (from x toward z), then vz degrees around the z axis (from x toward y). The rotation<br />

matrix is the same as the one used by RasMol.<br />

Per default, the system is scaled so it fits within the canvas (autoscale mode). Autoscale mode is enabled and<br />

disables using autoscale(“on”) or autoscale(“off”). A manual scale factor can be set with set_scale(scale),<br />

this implies autoscale(“off”). The scale factor (from the last autoscale event or from set_scale) can be<br />

obtained with get_scale(). Finally, an explicit autoscaling can be triggered with autoscale(“now”), this is<br />

mainly useful before calling get_scale or before disabling further autoscaling. Finally, a relative scaling<br />

factor can be set with SetRelativeScaling(), it is multiplied to the usual scale factor (from autoscale or from<br />

set_scale). This is probably only useful in connection with autoscaling.<br />

The radii of the atoms are obtained from the first of the following methods which work:<br />

1.If the radii are specified using PrimiPlotter.set_radii(r), they are used. Must be an array, or a single<br />

number.<br />

2.If the atoms has a get_atomic_radii() method, it is used. This is unlikely.<br />

3.If the atoms has a get_atomic_numbers() method, the corresponding covalent radii are extracted from<br />

the <strong>ASE</strong>.ChemicalElements module.<br />

4.If all else fails, the radius is set to 1.0 Angstrom.<br />

The atoms are colored using the first of the following methods which work.<br />

1.If colors are explicitly set using PrimiPlotter.set_colors(), they are used.<br />

2.If these colors are specified as a dictionary, the tags (from atoms.get_tags()) are used as an index into<br />

the dictionary to get the actual colors of the atoms.<br />

3.If a color function has been set using PrimiPlotter.set_color_function(), it is called with the atoms as<br />

an argument, and is expected to return an array of colors.<br />

4.If the atoms have a get_colors() method, it is used to get the colors.<br />

5.If these colors are specified as a dictionary, the tags (from atoms.get_tags()) are used as an index into<br />

the dictionary to get the actual colors of the atoms.<br />

6.If all else fails, the atoms will be white.<br />

The colors are specified as an array of colors, one color per atom. Each color is either a real number from<br />

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,<br />

specifying RGB values. The colors of all atoms are thus a Numerical Python N-vector or a 3xN matrix.<br />

In cases 1a and 3a above, the keys of the dictionary are integers, and the values are either numbers<br />

(grayscales) or 3-vectors (RGB values), or strings with X11 color names, which are then translated to RGB<br />

values. Only in case 1a and 3a are strings recognized as colors.<br />

Some atoms may be invisible, and thus left out of the plot. Invisible atoms are determined from the following<br />

algorithm. Unlike the radius or the coloring, all points below are tried and if an atom is invisible by any<br />

criterion, it is left out of the plot.<br />

104 Chapter 7. Documentation for modules in <strong>ASE</strong>


1.All atoms are visible.<br />

<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

2.If PrimiPlotter.set_invisible() has be used to specify invisible atoms, any atoms for which the value is<br />

non-zero becomes invisible.<br />

3.If an invisiblility function has been set with PrimiPlotter.set_invisibility_function(), it is called with<br />

the atoms as argument. It is expected to return an integer per atom, any non-zero value makes that<br />

atom invisible.<br />

4.If a cut has been specified using set_cut, any atom outside the cut is made invisible.<br />

Note that invisible atoms are still included in the algorithm for positioning and scaling the plot.<br />

The following output devices are implemented.<br />

PostScriptFile(prefix): Create PS files names prefix0000.ps etc.<br />

PnmFile(prefix): Similar, but makes PNM files.<br />

GifFile(prefix): Similar, but makes GIF files.<br />

JpegFile(prefix): Similar, but makes JPEG files.<br />

X11Window(): Show the plot in an X11 window using ghostscript.<br />

Output devices writing to files take an extra optional argument to the constructor, compress, specifying if<br />

the output file should be gzipped. This is not allowed for some (already compressed) file formats.<br />

Instead of a filename prefix, a filename containing a % can be used. In that case the filename is expected to<br />

expand to a real filename when used with the Python string formatting operator (%) with the frame number<br />

as argument. Avoid generating spaces in the file names: use e.g. %03d instead of %3d.<br />

Parameters to the constructor:<br />

atoms: The atoms to be plottet.<br />

verbose = 0: Write progress information to stderr.<br />

timing = 0: Collect timing information.<br />

interval = 1: If specified, a plot is only made every interval’th time update() is called. Deprecated, normally<br />

you should use the interval argument when attaching the plotter to e.g. the dynamics.<br />

initframe = 0: Initial frame number, i.e. the number of the first plot.<br />

log(message)<br />

logs a message to the file set by set_log.<br />

plot()<br />

Create a plot now. Does not respect the interval timer.<br />

This method makes a plot unconditionally. It does not look at the interval variable, nor is this plot<br />

taken into account in the counting done by the update() method if an interval variable was specified.<br />

set_color_function(colors)<br />

Set a color function, to be used to color the atoms.<br />

set_colors(colors)<br />

Explicitly set the colors of the atoms.<br />

set_dimensions(dims)<br />

Set the size of the canvas (a 2-tuple).<br />

set_invisibility_function(invfunc)<br />

Set an invisibility function.<br />

set_invisible(inv)<br />

Choose invisible atoms.<br />

set_log(log)<br />

Sets a file for logging.<br />

7.12. Visualization 105


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

log may be an open file or a filename.<br />

set_radii(radii)<br />

Set the atomic radii. Give an array or a single number.<br />

set_rotation(rotation)<br />

Set the rotation angles (in degrees).<br />

update(newatoms=None)<br />

Cause a plot (respecting the interval setting).<br />

update causes a plot to be made. If the interval variable was specified when the plotter was create, it<br />

will only produce a plot with that interval. update takes an optional argument, newatoms, which can<br />

be used to replace the list of atoms with a new one.<br />

7.12.3 FieldPlotter<br />

The FieldPlotter is intended to plot fields defined on the atoms in large-scale simulations. The fields could be e.g.<br />

pressure, stress or temperature (kinetic energy), i.e. any quantity that in a given simulation is best defined on a<br />

per-atom basis, but is best interpreted as a continuum field.<br />

The current version of FieldPlotter only works if the number of atoms is at least 5-10 times larger than the number<br />

of pixels in the plot.<br />

class ase.visualize.fieldplotter.FieldPlotter(atoms, datasource=None, verbose=0,<br />

timing=0, interval=1, initframe=0)<br />

log(message)<br />

logs a message to the file set by set_log.<br />

plot(data=None)<br />

Create a plot now. Does not respect the interval timer.<br />

This method makes a plot unconditionally. It does not look at the interval variable, nor is this plot<br />

taken into account in the counting done by the update() method if an interval variable was specified.<br />

If data is specified, it must be an array of numbers with the same length as the atoms. That data will<br />

then be plotted. If no data is given, the data source specified when creating the plotter is used.<br />

set_background(value)<br />

Set the data value of the background. See also set_background_color<br />

Set the value of the background (parts of the plot without atoms) to a specific value, or to ‘min’ or<br />

‘max’ representing the minimal or maximal data values on the atoms.<br />

Calling set_background cancels previous calls to set_background_color.<br />

set_background_color(color)<br />

Set the background color. See also set_background.<br />

Set the background color. Use a single value in the range [0, 1[ for gray values, or a tuple of three such<br />

values as an RGB color.<br />

Calling set_background_color cancels previous calls to set_background.<br />

set_black_white_colors(reverse=False)<br />

Set the color to Black-White (greyscale)<br />

set_color_function(colors)<br />

Set a color function, to be used to color the atoms.<br />

set_data_range(range1, range2=None)<br />

Set the range of the data used when coloring.<br />

This function sets the range of data values mapped unto colors in the final plot.<br />

Three possibilities:<br />

106 Chapter 7. Documentation for modules in <strong>ASE</strong>


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

‘data’: Autoscale using the data on visible atoms. The range goes from the lowest to the highest<br />

value present on the atoms. If only a few atoms have extreme values, the entire color range may<br />

not be used on the plot, as many values may be averaged on each point in the plot.<br />

‘plot’: Autoscale using the data on the plot. Unlike ‘data’ this guarantees that the entire color<br />

range is used.<br />

min, max: Use the range [min, max]<br />

set_dimensions(dims)<br />

Set the size of the canvas (a 2-tuple).<br />

set_invisibility_function(invfunc)<br />

Set an invisibility function.<br />

set_invisible(inv)<br />

Choose invisible atoms.<br />

set_log(log)<br />

Sets a file for logging.<br />

log may be an open file or a filename.<br />

set_plot_plane(plane)<br />

Set the plotting plane to xy, xz or yz (default: xy)<br />

set_radii(radii)<br />

Set the atomic radii. Give an array or a single number.<br />

set_red_yellow_colors(reverse=False)<br />

Set colors to Black-Red-Yellow-White (a.k.a. STM colors)<br />

set_rotation(rotation)<br />

Set the rotation angles (in degrees).<br />

update(newatoms=None)<br />

Cause a plot (respecting the interval setting).<br />

update causes a plot to be made. If the interval variable was specified when the plotter was create, it<br />

will only produce a plot with that interval. update takes an optional argument, newatoms, which can<br />

be used to replace the list of atoms with a new one.<br />

7.13 <strong>ASE</strong>-VTK<br />

For <strong>ASE</strong>, the vtk interface consists of Python modules for automatic visualization of positions, bonds, forces and<br />

volume data (e.g. wave functions) from an Atoms object, provided such data is made available by the calculator.<br />

Note: The Python modules in <strong>ASE</strong> are intended to wrap lower-level functionality of the VTK object models<br />

in small and easy-to-comprehend classes. To be able to distinguish between build-in VTK objects and their<br />

wrappers, and because VTK uses the CamelCase naming convention whereas <strong>ASE</strong> uses lower-case cf. our coding<br />

conventions, all variables referring to VTK built-in types are prefixed by vtk_. However, both VTK and wrapper<br />

classes are named according to the standard vtkFooBar.<br />

7.13.1 Representing atoms<br />

class ase.visualize.vtk.atoms.vtkAtoms(atoms, scale=1)<br />

Bases: ase.visualize.vtk.module.vtkModuleAnchor, ase.visualize.vtk.grid.vtkAtomicPositi<br />

Provides fundamental representation for Atoms-specific data in VTK.<br />

7.13. <strong>ASE</strong>-VTK 107


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

The vtkAtoms class plots atoms during simulations, extracting the relevant information from the list of<br />

atoms. It is created using the list of atoms as an argument to the constructor. Then one or more visualization<br />

modules can be attached using add_module(name, module).<br />

Example:<br />

>>> va = vtkAtoms(atoms)<br />

>>> va.add_forces()<br />

>>> va.add_axes()<br />

>>> XXX va.add_to_renderer(vtk_ren)<br />

Construct a fundamental VTK-representation of atoms.<br />

atoms: Atoms object or list of Atoms objects The atoms to be plotted.<br />

scale = 1: float or int Relative scaling of all Atoms-specific visualization.<br />

add_axes()<br />

Add an orientation indicator for the cartesian axes. An appropriate vtkAxesModule is added to the<br />

module anchor under axes.<br />

add_cell()<br />

Add a box outline of the cell using atoms.get_cell(). The existing vtkUnitCellModule is added<br />

to the module anchor under cell.<br />

add_forces()<br />

Add force vectors for the atoms using atoms.get_forces(). A vtkGlyphModule is added to the<br />

module anchor under force.<br />

add_velocities()<br />

Add velocity vectors for the atoms using atoms.get_velocities(). A vtkGlyphModule is added to<br />

the module anchor under velocity.<br />

Atom-centered data<br />

The superclass vtkAtomicPositions implements the basic concepts for representing atomic-centered data<br />

in VTK.<br />

class ase.visualize.vtk.grid.vtkAtomicPositions(pos, cell)<br />

Provides an interface for adding Atoms-centered data to VTK modules. Atomic positions, e.g. obtained<br />

using atoms.get_positions(), constitute an unstructured grid in VTK, to which scalar and vector can be added<br />

as point data sets.<br />

Just like Atoms, instances of vtkAtomicPositions can be divided into subsets, which makes it easy<br />

to select atoms and add properties.<br />

Example:<br />

>>> cell = vtkUnitCellModule(atoms)<br />

>>> apos = vtkAtomicPositions(atoms.get_positions(), cell)<br />

>>> apos.add_scalar_property(atoms.get_charges(), ’charges’)<br />

>>> apos.add_vector_property(atoms.get_forces(), ’forces’)<br />

Construct basic VTK-representation of a set of atomic positions.<br />

pos: NumPy array of dtype float and shape (n,3) Cartesian positions of the atoms.<br />

cell: Instance of vtkUnitCellModule of subclass thereof Holds information equivalent to that of<br />

atoms.get_cell().<br />

add_scalar_property(data, name=None, active=True)<br />

Add VTK-representation of scalar data at the atomic positions.<br />

data: NumPy array of dtype float and shape (n,) Scalar values corresponding to the atomic positions.<br />

name=None: str Unique identifier for the scalar data.<br />

108 Chapter 7. Documentation for modules in <strong>ASE</strong>


active=True: bool Flag indicating whether to use as active scalar data.<br />

add_vector_property(data, name=None, active=True)<br />

Add VTK-representation of vector data at the atomic positions.<br />

<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

data: NumPy array of dtype float and shape (n,3) Vector components corresponding to the<br />

atomic positions.<br />

name=None: str Unique identifier for the vector data.<br />

active=True: bool Flag indicating whether to use as active vector data.<br />

get_points(subset=None)<br />

Return (subset of) vtkPoints containing atomic positions.<br />

subset=None: list of int A list of indices into the atomic positions; ignored if None.<br />

get_unstructured_grid(subset=None)<br />

Return (subset of) an unstructured grid of the atomic positions.<br />

Predefined shapes<br />

subset=None: list of int A list of indices into the atomic positions; ignored if None.<br />

The class vtkGlyphModule implements the lower-level objects for representing predefined shapes (glyphs) in<br />

VTK.<br />

class ase.visualize.vtk.module.vtkGlyphModule(vtk_pointset, glyph_source, scalemode=None,<br />

colormode=None)<br />

Modules represent a unified collection of VTK objects needed for introducing basic visualization concepts<br />

such as surfaces or shapes.<br />

A common trait of all modules is the need for an actor representation and corresponding generic properties<br />

such as lighting, color and transparency.<br />

Poly data modules are based on polygonal data sets, which can be mapped into graphics primitives suitable<br />

for rendering within the VTK framework.<br />

Glyph modules construct these polygonal data sets by replicating a glyph source across a specific set of<br />

points, using available scalar or vector point data to scale and orientate the glyph source if desired.<br />

Example:<br />

>>> atoms = molecule(’C60’)<br />

>>> cell = vtkUnitCellModule(atoms)<br />

>>> apos = vtkAtomicPositions(atoms.get_positions(), cell)<br />

>>> vtk_ugd = apos.get_unstructured_grid()<br />

>>> glyph_source = vtkAtomSource(’C’)<br />

>>> glyph_module = vtkGlyphModule(vtk_ugd, glyph_source)<br />

Construct VTK-representation of a module containing glyphs. These glyphs share a common source, defining<br />

their geometrical shape, which is cloned and oriented according to the input data.<br />

vtk_pointset: Instance of vtkPointSet or subclass thereof A vtkPointSet defines a set of positions,<br />

which may then be assigned specific scalar of vector data across the entire set.<br />

glyph_source: Instance of ~vtk.vtkCustomGlyphSource or subclass thereof Provides the basic shape<br />

to distribute over the point set.<br />

get_actor()<br />

Return the actor representing this module in a rendering scene.<br />

set_actor(vtk_act)<br />

Set the actor representing this module in a rendering scene.<br />

set_property(vtk_property)<br />

Set the property of the actor representing this module.<br />

7.13. <strong>ASE</strong>-VTK 109


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

7.14 Calculators<br />

For <strong>ASE</strong>, a calculator is a black box that can take atomic numbers and atomic positions from an Atoms object<br />

and calculate the energy and forces and sometimes also stresses.<br />

In order to calculate forces and energies, you need to attach a calculator object to your atoms object:<br />

>>> a = read(’molecule.xyz’)<br />

>>> e = a.get_potential_energy()<br />

Traceback (most recent call last):<br />

File "", line 1, in <br />

File "/home/jjmo/ase/ase/atoms.py", line 399, in get_potential_energy<br />

raise RuntimeError(’Atoms object has no calculator.’)<br />

RuntimeError: Atoms object has no calculator.<br />

>>> from ase.calculators import Abinit<br />

>>> calc = Abinit(...)<br />

>>> a.set_calculator(calc)<br />

>>> e = a.get_potential_energy()<br />

>>> print e<br />

-42.0<br />

Here, we used the set_calculator() method to attach an instance of the Abinit class and then we asked<br />

for the energy.<br />

Alternatively, a calculator can be attached like this:<br />

atoms = Atoms(..., calculator=Siesta())<br />

7.14.1 Supported calculators<br />

Code Description Type<br />

GPAW Grid-based real-space PAW code DFT, HF<br />

Asap Highly efficient EMT code (written in C++) EMT<br />

jacapo <strong>ASE</strong> interface to Dacapo, a planewave ultra-soft pseudopotential code DFT<br />

Dacapo Old interface to Dacapo. Requires Numeric python and <strong>ASE</strong>2. DFT<br />

emt Effective Medium Theory calculator EMT<br />

abinit A planewave pseudopotential code DFT<br />

siesta LCAO pseudopotential code DFT<br />

dftb DftbPlus DFT based tight binding DFT<br />

turbomole Fast atom orbital code Turbomole, DFT, HF<br />

castep Planewave pseodopotential code DFT, HF<br />

vasp Planewave PAW code DFT<br />

FHI-aims Numeric Atomic Orbital, full potential code DFT, HF<br />

exciting Full Potential LAPW code DFT, LAPW<br />

fleur Full Potential LAPW code DFT, LAPW<br />

lammps Classical molecular dynamics code<br />

gromacs Classical molecular dynamics code<br />

mmtk XXX Library for molecular simulations<br />

The calculators can be divided in three groups:<br />

1. GPAW, Asap, Dacapo have their own native <strong>ASE</strong> interfaces.<br />

2. Jacapo, ABINIT, SIESTA, DftbPlus, TURBOMOLE, VASP, FLEUR, FHI-aims, LAMMPS, MMTK and<br />

Gromacs have Python wrappers in the <strong>ASE</strong> package, but the actual codes are not part of <strong>ASE</strong>.<br />

3. EMT is a pure python implementation of the Effective Medium Theory potential and it is included in the<br />

<strong>ASE</strong> package.<br />

110 Chapter 7. Documentation for modules in <strong>ASE</strong>


7.14.2 Documentation for group 2 and 3 calculators<br />

Pure Python EMT calculator<br />

<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

The EMT potential is included in the <strong>ASE</strong> package in order to have a simple calculator that can be used for quick<br />

demonstrations and tests.<br />

Warning: If you want to do a real application using EMT, you should used the much more efficient implementation<br />

in the ASAP calculator.<br />

class emt.EMT<br />

Right now, the only supported elements are: H, C, N, O, Al, Ni, Cu, Pd, Ag, Pt and Au. The EMT parameters for<br />

the metals are quite realistic for many purposes, whereas the H, C, N and O parameters are just for fun!<br />

Jacapo - <strong>ASE</strong> python interface for Dacapo<br />

Introduction<br />

Jacapo is an <strong>ASE</strong> interface for Dacapo and fully compatible with <strong>ASE</strong>. It replaces the old Dacapo interface using<br />

Numeric python and <strong>ASE</strong>2. The code was originally developed by John Kitchin and detailed documentation as<br />

well as many examples are available online:<br />

http://gilgamesh.cheme.cmu.edu/doc/software/jacapo/index.html<br />

Jacapo is included as an optional calculator in <strong>ASE</strong> and small differences to the above documentation may occur.<br />

Jacapo Calculator<br />

The Jacapo calculator is automatically installed with ase and can be imported using:<br />

from ase.calculators.jacapo import *<br />

class jacapo.Jacapo<br />

Here is a list of available keywords to initialize the calculator:<br />

keyword type description<br />

nc str Output NetCDF file, or input file if nc already exists.<br />

outnc str Output file. By default equal to nc.<br />

atoms object ase atoms object<br />

pw float Planewave cutoff in eV<br />

dw float Density cutoff in eV<br />

xc str Exchange-correlation functional. One of<br />

[’PZ’,’VWN’,’PW91’,’PBE’,’RPBE’,’revPBE’]<br />

nbands int Number of bands<br />

ft float Fermi temperature<br />

kpts list K-point grid, e.g. kpts = (2,2,1)<br />

spinpol boolean Turn on/off spin-polarization<br />

fixmagmom str Magnetic moment of the unit cell<br />

symmetry boolean Turn on/off symmetry reduction<br />

stress boolean Turn on/off stress calculation<br />

dipole boolean Turn on/off dipole correction<br />

stay_alive boolean Turn on/off stay alive<br />

debug int Set debug level (0=off, 10=extreme)<br />

deletenc boolean If the nc file exists, delete it (to ensure a fresh run). Default is False.<br />

7.14. Calculators 111


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

Example<br />

Here is an example of how to calculate the total energy of a CO molecule:<br />

#!/usr/bin/env python<br />

from ase import *<br />

from ase.calculators.jacapo import *<br />

CO = data.molecules.molecule(’CO’)<br />

CO.set_cell([6,6,6])<br />

CO.center()<br />

calc = Jacapo(nc=’CO.nc’,<br />

atoms=CO,<br />

pw=300,<br />

nbands=8)<br />

print CO.get_potential_energy()<br />

Restarting from an old Calculation<br />

With Jacapo it is very easy to restart an old calculation. All necessary information (including the constraints) is<br />

stored in the out.nc file. To continue for example a geometry optimization do something like this:<br />

calc = Jacapo(’old.nc’,stay_alive=True)<br />

atoms = calc.get_atoms()<br />

dyn = QuasiNewton(atoms,logfile=’qn.log’)<br />

dyn.run(fmax=0.05)<br />

Note, that the stay_alive flag is not stored in the .nc file and must be set when the calculator instance is created.<br />

ABINIT<br />

Introduction<br />

ABINIT is a density-functional theory code based on pseudopotentials and a planewave basis.<br />

Environment variables<br />

Note: setting environment variables is necessary only if you configure your ABINIT/<strong>ASE</strong> environment from<br />

scratch.<br />

You need to write a script called abinit.py containing something like this:<br />

import os<br />

abinit = ’/usr/bin/abinis’ # full path to the abinit executable<br />

exitcode = os.system(’%s < %s.files > %s.log’ % (abinit, label, label))<br />

The environment variable ABINIT_SCRIPT must point to that file.<br />

A directory containing the pseudopotential files (at least of .fhi type) is also needed, and it is to be put in the<br />

environment variable ABINIT_PP_PATH. Abinit does not provide tarballs of pseduopotentials so the easiest way<br />

is to download and unpack http://wiki.fysik.dtu.dk/abinit-files/abinit-pseudopotentials-2.tar.gz<br />

Set the environment variables in your in your shell configuration file:<br />

$ export ABINIT_SCRIPT=$HOME/bin/abinit.py<br />

$ export ABINIT_PP_PATH=${HOME}/abinit-pseudopotentials-2/LDA_FHI<br />

$ export ABINIT_PP_PATH=${HOME}/abinit-pseudopotentials-2/GGA_FHI:$ABINIT_PP_PATH<br />

$ export ABINIT_PP_PATH=${HOME}/abinit-pseudopotentials-2/LDA_HGH:$ABINIT_PP_PATH<br />

112 Chapter 7. Documentation for modules in <strong>ASE</strong>


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

$ export ABINIT_PP_PATH=${HOME}/abinit-pseudopotentials-2/LDA_PAW:$ABINIT_PP_PATH<br />

$ export ABINIT_PP_PATH=${HOME}/abinit-pseudopotentials-2/LDA_TM:$ABINIT_PP_PATH<br />

$ export ABINIT_PP_PATH=${HOME}/abinit-pseudopotentials-2/GGA_FHI:$ABINIT_PP_PATH<br />

$ export ABINIT_PP_PATH=${HOME}/abinit-pseudopotentials-2/GGA_HGHK:$ABINIT_PP_PATH<br />

$ export ABINIT_PP_PATH=${HOME}/abinit-pseudopotentials-2/GGA_PAW:$ABINIT_PP_PATH<br />

$ export ABINIT_PP_PATH=$HOME/mypps:$ABINIT_PP_PATH<br />

ABINIT Calculator<br />

The default parameters are very close to those that the ABINIT Fortran code uses. These are the exceptions:<br />

class abinit.Abinit(label=’abinit’, xc=’LDA’, mix=0.1)<br />

Here is a detailed list of all the keywords for the calculator:<br />

keyword type default value description<br />

kpts list [1,1,1] Monkhorst-Pack k-point sampling<br />

nbands int None Number of band. May be omitted.<br />

nstep int None Number of self-consistent field STEPS.<br />

ecut float None Planewave cutoff energy in eV (default: None)<br />

xc str ’LDA’ Exchange-correlation functional.<br />

npulayit int 7 Number of old densities to use for Pulay mixing<br />

diemix float 0.1 Pulay mixing weight<br />

diemac float 1e6 Model DIElectric MACroscopic constant<br />

width float 0.04 Ha Fermi-distribution width in eV (default: 0.04 Ha)<br />

charge float 0 Total charge of the system (default: 0)<br />

label str ’abinit’ Name of the output file<br />

pps str ’fhi’ Pseudopotentials used ‘fhi’, ‘hgh’, ‘hgh.sc’, ‘hgh.k’, ‘tm’, ‘paw’<br />

toldfe float 1.0e-6 TOLerance on the DiFference of total Energy<br />

A value of None means that ABINIT’s default value is used.<br />

Warning: abinit does not specify a default value for Planewave cutoff energy in eV - you need to set<br />

them as in the example at thei bottom of the page, otherwise calculation will fail. Calculations wihout k-points<br />

are not parallelized by default and will fail! To enable band paralellization specify Number of BanDs in a<br />

BLOCK (nbdblock) as Extra parameters - see http://www.abinit.org/Infos_v5.2/tutorial/lesson_parallelism.html.<br />

Extra parameters<br />

The ABINIT code reads the input parameters for any calculation from a .in file and .files file. This means<br />

that you can set parameters by manually setting entries in this input .in file. This is done by the syntax:<br />

>>> calc.set_inp(’name_of_the_entry’, value)<br />

For example, the ndtset can be set using<br />

>>> calc.set_inp(’ndtset’, 2)<br />

The complete list of keywords can be found in the official ABINIT manual.<br />

Pseudopotentials<br />

Pseudopotentials in the ABINIT format are available on the pseudopotentials website. A database of user contributed<br />

pseudopotentials is also available there.<br />

7.14. Calculators 113


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

Example 1<br />

Here is an example of how to calculate the total energy for bulk Silicon:<br />

from ase import *<br />

from ase.calculators.abinit import Abinit<br />

a0 = 5.43<br />

bulk = Atoms(’Si2’, [(0, 0, 0),<br />

(0.25, 0.25, 0.25)],<br />

pbc=True)<br />

b = a0 / 2<br />

bulk.set_cell([(0, b, b),<br />

(b, 0, b),<br />

(b, b, 0)], scale_atoms=True)<br />

calc = Abinit(label=’Si’,<br />

nbands=8,<br />

xc=’PBE’,<br />

ecut=50 * Ry,<br />

mix=0.01,<br />

kpts=[10, 10, 10])<br />

bulk.set_calculator(calc)<br />

e = bulk.get_potential_energy()<br />

SIESTA<br />

Introduction<br />

SIESTA is a density-functional theory code for very large systems based on atomic orbital (LCAO) basis sets.<br />

Environment variables<br />

You need to write a script called run_siesta.py containing something like this:<br />

import os<br />

siesta = ’siesta_2.0’<br />

exitcode = os.system(’%s < %s.fdf > %s.txt’ % (siesta, label, label))<br />

The environment variable SIESTA_SCRIPT must point to that file.<br />

A directory containing the pseudopotential files .vps is also needed, and it is to be put in the environment variable<br />

SIESTA_PP_PATH.<br />

Set both environment variables in your shell configuration file:<br />

$ export SIESTA_SCRIPT=$HOME/siesta/run_siesta.py<br />

$ export SIESTA_PP_PATH=$HOME/mypps<br />

SIESTA Calculator<br />

The default parameters are very close to those that the SIESTA Fortran code uses. These are the exceptions:<br />

class siesta.Siesta(label=’siesta’, xc=’LDA’, pulay=5, mix=0.1)<br />

Here is a detailed list of all the keywords for the calculator:<br />

114 Chapter 7. Documentation for modules in <strong>ASE</strong>


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

keyword type default value description<br />

kpts list [1,1,1] Monkhorst-Pack k-point sampling<br />

nbands int None Number of bands<br />

meshcutoff float None Mesh cut-off energy in eV<br />

basis str None Type of basis set (‘sz’, ‘dz’, ‘szp’, ‘dzp’)<br />

xc str ’LDA’ Exchange-correlation functional.<br />

pulay int 5 Number of old densities to use for Pulay mixing<br />

mix float 0.1 Pulay mixing weight<br />

width float None Fermi-distribution width in eV<br />

charge float None Total charge of the system<br />

label str ’siesta’ Name of the output file<br />

A value of None means that SIESTA’s default value is used.<br />

Extra FDF parameters<br />

The SIESTA code reads the input parameters for any calculation from a .fdf file. This means that you can set<br />

parameters by manually setting entries in this input .fdf file. This is done by the syntax:<br />

>>> calc.set_fdf(’name_of_the_entry’, value)<br />

For example, the EnergyShift can be set using<br />

>>> calc.set_fdf(’PAO.EnergyShift’, 0.01 * Rydberg)<br />

The complete list of the FDF entries can be found in the official SIESTA manual.<br />

Customized basis-set<br />

Standard basis sets can be set by the keyword basis directly in the Siesta calculator object. If a customized basis<br />

is needed, it can be set as an FDF entry, as explained in the previous section.<br />

As an example, we generate a triple-zeta triple-polarized (TZTP) basis for Au. Since the valence states are 6s and<br />

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<br />

by<br />

>>> value = ["""Au 2 split 0.00 #label, num. of l-shells,type,charge<br />

>>> 0 3 P 3 #l,nzeta,’P’(opt):pol.functions,npolzeta<br />

>>> 0.00 0.00 0.00 #rc of basis functions for each zeta function<br />

>>> #0.00 => rc determined by PAO.EnergyShift<br />

>>> 2 3 #l,nzeta<br />

>>> 0.00 0.00 0.00"""] #rc<br />

>>> calc.set_fdf(’PAO.Basis’,value=value)<br />

The default basis set generation fails for Pt for some versions of Siesta. If this happens, you should specify the<br />

basis set manually. This is exemplified below.<br />

For Pt, using calc.set_fdf(’PAO.EnergyShift’, 0.1 * eV) is usually resonable, and a single-zeta<br />

polarized basis set can be specified by writing:<br />

# Define SZP basis set for Pt<br />

calc.set_fdf(’PAO.Basis’,<br />

["""\<br />

Pt 2 # Species label, number of l-shells<br />

n=6 0 1 P # n, l, Nzeta, Polarization, NzetaPol<br />

0. # 0.0 => default [6.982 \n 1.000]<br />

n=5 2 1 # n, l, zeta<br />

0."""]) # 0.0 => default [5.172 \n 1.000]<br />

A double-zeta polarized basis set for Pt may be specified by:<br />

7.14. Calculators 115


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

# Define DZP basis set for Pt<br />

calc.set_fdf(’PAO.Basis’,<br />

["""\<br />

Pt 2 split 0.00 # Species label, number of l-shells<br />

n=6 0 2 P 1 # n, l, Nzeta, Polarization, NzetaPol<br />

0.00 0.00 # 0.0 => default [6.982 5.935 \n 1.000 1.000]<br />

n=5 2 2 # n, l, zeta<br />

0.00 0.00"""]) # 0.0 => default [5.172 3.060 \n 1.000 1.000]<br />

You can also reuse the basis set of a previous calculation, by copying the .ion files to the new location, and set the<br />

User.Basis tag to True:<br />

# Load basis from previous calc (*.ion files)<br />

calc.set_fdf(’User.Basis’, True)<br />

Warning: Specifying a basis set manually in any way will, for some obscure reason, make Siesta crash if you have<br />

ghost atoms!<br />

Pseudopotentials<br />

Pseudopotential files in the .psf or .vps formats are needed. Pseudopotentials generated from the ABINIT<br />

code and converted to the SIESTA format are available in the SIESTA website . A database of user contributed<br />

pseudopotentials is also available there.<br />

You can also find an on-line pseudopotential generator from the OCTOPUS code.<br />

Example<br />

Here is an example of how to calculate the total energy for bulk Silicon, using a double-zeta basis generated by<br />

specifying a given energy-shift:<br />

#!/usr/bin/env python<br />

from ase import *<br />

a0 = 5.43<br />

bulk = Atoms(’Si2’, [(0, 0, 0),<br />

(0.25, 0.25, 0.25)],<br />

pbc=True)<br />

b = a0 / 2<br />

bulk.set_cell([(0, b, b),<br />

(b, 0, b),<br />

(b, b, 0)], scale_atoms=True)<br />

calc = Siesta(label=’Si’,<br />

xc=’PBE’,<br />

meshcutoff=200 * Ry,<br />

basis=’dz’,<br />

mix=0.01,<br />

kpts=[10, 10, 10])<br />

calc.set_fdf(’PAO.EnergyShift’, 0.01 * Ry)<br />

bulk.set_calculator(calc)<br />

e = bulk.get_potential_energy()<br />

Here, the only input information on the basis set is, that it should be double-zeta (basis=’dz’) and that the confinement<br />

potential should result in an energy shift of 0.01 Rydberg (the PAO.EnergyShift fdf tag). Sometimes<br />

it can be necessary to specify more information on the basis set. For example, the default basis set generation fails<br />

for Pt for some versions of Siesta. To fix this, you must specify the basis set manually. <strong>Manual</strong> basis set specifications<br />

are described in Customized basis-set.<br />

116 Chapter 7. Documentation for modules in <strong>ASE</strong>


Restarting from an old Calculation<br />

<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

If you want to rerun an old SIESTA calculation, made using the <strong>ASE</strong> interface or not, you can set the fdf tag<br />

UseSaveData to True. This is equivalent to setting both DM.UseSaveDM and MD.UseSaveXV to True, i.e.<br />

it will reuse the the density matrix, and the atomic coordinates (and unit cell) of the previous calculation. Note<br />

that the Siesta jobname (the label keyword in the <strong>ASE</strong> interface) must be identical to the jobname of the old<br />

calculation.<br />

DftbPlus<br />

Introduction<br />

DftbPlus is a density-functional based tight-binding code using atom centered orbitals. This interface makes it<br />

possible to use DftbPlus as a calculator in <strong>ASE</strong>. You need to register at DftbPlus site to download the code.<br />

Additionally you need Slater-coster files for the combination of atom types of your system. These can be obtained<br />

at dftb.org.<br />

Environment variables<br />

Set environment variables in your configuration file (what is the directory for the Slater-Koster files and what is<br />

the name of the executable):<br />

• bash:<br />

$ DFTB_PREFIX=/my_disk/my_name/lib/Dftb+sk/mio-0-1/ (an example)<br />

$ DFTB_COMMAND=~/bin/DFTB+/dftb+_s081217.i686-linux (an example)<br />

• csh/tcsh:<br />

$ setenv DFTB_PREFIX /my_disk/my_name/lib/Dftb+sk/mio-0-1/ (an example)<br />

$ setenv DFTB_COMMAND ~/bin/DFTB+/dftb+_s081217.i686-linux (an example)<br />

DftbPlus Calculator<br />

This is a preliminary version of the DftbPlus calculator, so all the DftbPlus features are unfortunately not there.<br />

Use write_dftb=False to use your own ‘dftb_in.hsd’-file with all the flavours you need. In that case ase only<br />

updates the coordinates of the system, otherwise file ‘dftb_in.hsd’ remains intact (see example 2 below). However,<br />

in case of own ‘dftb_in.hsd’ file you need first read in atom position and atom type information of your system for<br />

ase (for instance a xyz-file), see example 2 below.<br />

The atom positions in file ‘dftb_in.hsd’ are updated during <strong>ASE</strong> geometry optimization.<br />

For the spin polarised calculations this <strong>ASE</strong>-interface generates parameters with GGA-PBE-spin parameters. If<br />

you need LDA use your own ‘dftb_in.hsd’-file.<br />

Information of periodicity is taken from ase (see example1 below).<br />

For example:<br />

calc = Dftb(label=’o2’,<br />

write_dftb=True,<br />

do_spin_polarized=True,<br />

unpaired_electrons=2.0,<br />

fermi_temperature=100.0,<br />

scc=True)<br />

7.14. Calculators 117


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

Parameters<br />

label: str Prefix to use for filenames (label.txt, ...). Default is ‘dftb’.<br />

write_dftb: boolean True: a minimal input file (name of which is always ‘dftb_in.hsd’) is written based on<br />

values given here. False: input file for dftb+ is not written. User must have generated file ‘dftb_in.hsd’ in<br />

the working directory. Use write_dftb=False to use your own ‘dftb_in.hsd’-file.<br />

charge: float Total charge of the system.<br />

include_dispersion: boolean True: Default dispersion parameters are written in the file ‘dftb_in.hsd’ (requires<br />

that also write_dftb_input_file==True) False: dispersion parameters are not written here.<br />

do_spin_polarized: boolean True: Spin polarized calculation False: Spin unpolarized calculation<br />

unpaired_electrons: float Number of spin unpaired electrons in the system. Relevant only if<br />

do_spin_polarized==True<br />

fermi_temperature: float Fermi temperature for electrons.<br />

scc: boolean True: Do charge self consistent dftb+ False: No SCC, charges on atoms are not iterated<br />

Example1: Geometry Optimization<br />

#!/usr/bin/env python<br />

import os<br />

from ase import Atoms<br />

from ase.calculators.dftb import Dftb<br />

from ase.optimize import QuasiNewton<br />

from ase.io import write<br />

d = 1.10<br />

test = Atoms(’2O’, positions=[(0., 0., 0.), (0., 0., d)])<br />

test.set_pbc([False, False, False])<br />

test.set_calculator(Dftb(label=’o2’,write_dftb=True,do_spin_polarized=True,unpaired_electrons=2.0,<br />

dyn = QuasiNewton(test, trajectory=’test.traj’)<br />

dyn.run(fmax=0.01)<br />

write(’test.final.xyz’, test)<br />

Example2: Geometry Optimization using your own ‘dftb_in.hsd’ file<br />

#!/usr/bin/python<br />

from ase.io import read, write<br />

from ase.calculators.dftb import Dftb<br />

from ase.optimize import QuasiNewton<br />

system = read(’h2o_1.xyz’)<br />

system.set_calculator(Dftb(label=’dftb’,write_dftb=False))<br />

qn = QuasiNewton(system)<br />

qn.run(fmax=0.005)<br />

write(’final.xyz’, system)<br />

write(’final.traj’, system)<br />

Input file for example 2 (h2o_1.xyz)<br />

118 Chapter 7. Documentation for modules in <strong>ASE</strong>


3<br />

H2O<br />

O 0.00000 0.00000 0.00000<br />

H 0.00000 0.00000 1.00000<br />

H 1.00000 0.00000 0.00000<br />

<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

You also need to have generated the file ‘dftb_in.hsd’, here is and example: change the variable ‘Prefix’ below<br />

Geometry = {<br />

TypeNames = { "O" }<br />

TypesAndCoordinates [Angstrom] = {<br />

1 0.00000000000000 0.00000000000000 0.00000000000000<br />

1 0.00000000000000 0.00000000000000 1.10000000000000<br />

}<br />

Periodic = No<br />

}<br />

Driver = ConjugateGradient {<br />

MovedAtoms = Range { 1 -1 }<br />

MaxForceComponent = 1.0e-4<br />

MaxSteps = 0<br />

OutputPrefix = o2<br />

}<br />

Hamiltonian = DFTB { # DFTB Hamiltonian<br />

SCC = Yes # Use self consistent charges<br />

SCCTolerance = 1.0e-5 # Tolerance for charge consistence<br />

MaxSCCIterations = 1000 # Nr. of maximal SCC iterations<br />

Mixer = Broyden { # Broyden mixer for charge mixing<br />

MixingParameter = 0.2 # Mixing parameter<br />

}<br />

SlaterKosterFiles = Type2FileNames { # File names from two atom type names<br />

TURBOMOLE<br />

Introduction<br />

TURBOMOLE is a density-functional or Hartree Fock code using atom centered orbitals. This interface makes it<br />

possible to use TURBOMOLE as a calculator in <strong>ASE</strong>.<br />

Environment variables<br />

Set environment variables in your configuration file:<br />

• bash:<br />

$ TURBODIR=/my_disk/my_name/TURBOMOLE<br />

$ PATH=$PATH:$TURBODIR/scripts<br />

$ PATH=$PATH:$TURBODIR/bin/‘sysname‘<br />

• csh/tcsh:<br />

$ setenv TURBODIR /my_disk/my_name/TURBOMOLE<br />

$ set path=($path ${TURBODIR}/scripts)<br />

$ set path=($path ${TURBODIR}/bin/‘sysname‘)<br />

7.14. Calculators 119


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

Turbomole Calculator<br />

All usual turbomole input files generated by Turbomole’s define [coord, control, basis, (auxbasis),<br />

mos/alpha+beta] must be present in the current working directory.<br />

Turbomole files are updated during the <strong>ASE</strong>-run.<br />

Do not use internal coordinates, only cartesians are allowed.<br />

In the coord file one can fix atoms the turbomole way (writing a ‘f’ in the end of the line in the coord file).<br />

Ase-Turbomole uses turbomole programs ‘ridft’ and ‘rdgrad’ if keyword ‘$ricore’ is present in the Turbomole’s<br />

control file. Otherwise programs ‘dscf’ and ‘grad’ are used.<br />

Example1: Geometry Optimization<br />

#!/usr/bin/env python<br />

import os<br />

from ase.io import read,write<br />

from ase.optimize import QuasiNewton<br />

# Turbomole input coordinates must be in the file ’coord’.<br />

# The coordinates are updated to the file ’coord’ during the minimization.<br />

test = read(’coord’)<br />

test.set_calculator(Turbomole())<br />

dyn = QuasiNewton(test, trajectory=’test.traj’)<br />

dyn.run(fmax=0.01)<br />

write(’coord.final.tmol’, test)<br />

Example2: Diffusion run using NEB<br />

#!/usr/bin/env python<br />

import os<br />

from ase.io import read<br />

from ase.neb import NEB<br />

from ase.calculators.turbomole import Turbomole<br />

from ase.optimize import BFGS<br />

initial = read(’initial.coord’)<br />

final = read(’final.coord’)<br />

os.system(’rm -f coord; cp initial.coord coord’)<br />

# Make a band consisting of 5 configs:<br />

configs = [initial]<br />

configs += [initial.copy() for i in range(3)]<br />

configs += [final]<br />

band = NEB(configs, climb=True)<br />

# Interpolate linearly the positions of the not-endpoint-configs:<br />

band.interpolate()<br />

#Set calculators<br />

for config in configs:<br />

config.set_calculator(Turbomole())<br />

120 Chapter 7. Documentation for modules in <strong>ASE</strong>


# Optimize the Path:<br />

relax = BFGS(band, trajectory=’neb.traj’)<br />

relax.run(fmax=0.05)<br />

Example3: Diffusion run using NEB, Restart old calculation<br />

#!/usr/bin/env python<br />

import os<br />

from ase.io import read<br />

from ase.neb import NEB<br />

from ase.calculators.turbomole import Turbomole<br />

from ase.optimize import BFGS<br />

initial = read(’initial.coord’)<br />

final = read(’final.coord’)<br />

os.system(’rm -f coord; cp initial.coord coord’)<br />

#restart<br />

configs = read(’neb.traj@-5:’)<br />

band = NEB(configs, climb=True)<br />

#Set calculators<br />

for config in configs:<br />

config.set_calculator(Turbomole())<br />

# Optimize:<br />

relax = BFGS(band, trajectory=’neb.traj’)<br />

relax.run(fmax=0.05)<br />

For developers: python files affected by the turbomole interface<br />

ase:<br />

__init__.py<br />

new lines 17from<br />

ase.calculators import LennardJones, \<br />

EMT, ASAP, Siesta, Dacapo, Vasp, Turbomole<br />

ase/io:<br />

__init__.py<br />

new line 44<br />

TURBOMOLE coord file (filename===’coord’)<br />

new lines 145if<br />

format == ’turbomole’:<br />

from ase.io.turbomole import read_turbomole<br />

return read_turbomole(filename)<br />

new line 184<br />

TURBOMOLE coord file turbomole<br />

new lines 267elif<br />

format == ’tmol’:<br />

from ase.io.turbomole import write_turbomole<br />

write_turbomole(filename, images)<br />

return<br />

new lines 349if<br />

lines[0].startswith(’$coord’):<br />

return ’turbomole’<br />

<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

7.14. Calculators 121


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

NEW FILE:<br />

ase/io/turbomole.py<br />

ase/calculators:<br />

__init__.py<br />

new line 10<br />

from ase.calculators.turbomole import Turbomole<br />

NEW FILE:<br />

ase/calculators/turbomole.py<br />

VASP<br />

Introduction<br />

VASP is a density-functional theory code using pseudopotentials or the projector-augmented wave method and a<br />

plane wave basis set. This interface makes it possible to use VASP as a calculator in <strong>ASE</strong>, and also to use <strong>ASE</strong> as<br />

a post-processor for an already performed VASP calculation.<br />

Environment variables<br />

You need to write a script called run_vasp.py containing something like this:<br />

import os<br />

exitcode = os.system(’vasp’)<br />

The environment variable VASP_SCRIPT must point to that file.<br />

A directory containing the pseudopotential directories potpaw (LDA XC) potpaw_GGA (PW91 XC) and<br />

potpaw_PBE (PBE XC) is also needed, and it is to be put in the environment variable VASP_PP_PATH.<br />

Set both environment variables in your shell configuration file:<br />

$ export VASP_SCRIPT=$HOME/vasp/run_vasp.py<br />

$ export VASP_PP_PATH=$HOME/vasp/mypps<br />

VASP Calculator<br />

The default setting used by the VASP interface is<br />

class vasp.Vasp(restart=None, xc=’PW91’, setups=None, kpts=(1, 1, 1), gamma=None)<br />

Below follows a list with a selection of parameters<br />

keyword type default value description<br />

restart bool None Restart old calculation or use <strong>ASE</strong> for post-processing<br />

xc str ’PW91’ XC-functional<br />

setups str None Additional setup option<br />

kpts seq Gamma-point k-point sampling<br />

gamma bool None Gamma-point centered k-point sampling<br />

reciprocal bool None Use reciprocal units if k-points are specified explicitly<br />

prec str Accuracy of calculation<br />

encut float Kinetic energy cutoff<br />

ediff float Convergence break condition for SC-loop.<br />

nbands int Number of bands<br />

algo str Electronic minimization algorithm<br />

ismear int Type of smearing<br />

sigma float Width of smearing<br />

nelm int Maximum number of SC-iterations<br />

122 Chapter 7. Documentation for modules in <strong>ASE</strong>


seq: A sequence of three int‘s.<br />

<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

For parameters in the list without default value given, VASP will set the default value. Most of the parameters<br />

used in the VASP INCAR file are allowed keywords. See the official VASP manual for more details.<br />

Note: Parameters can be changed after the calculator has been constructed by using the set() method:<br />

>>> calc.set(prec=’Accurate’, ediff=1E-5)<br />

This would set the precision to Accurate and the break condition for the electronic SC-loop to 1E-5 eV.<br />

Spin-polarized calculation<br />

If the atoms object has non-zero magnetic moments, a spin-polarized calculation will be performed by default.<br />

Here follows an example how to calculate the total magnetic moment of a sodium chloride molecule.<br />

from ase import Atoms, Atom<br />

from ase.calculators.vasp import Vasp<br />

a = [6.5, 6.5, 7.7]<br />

d = 2.3608<br />

NaCl = Atoms([Atom(’Na’, [0, 0, 0], magmom=1.928),<br />

Atom(’Cl’, [0, 0, d], magmom=0.75)],<br />

cell=a)<br />

calc = Vasp(prec = ’Accurate’,<br />

xc = ’PBE’,<br />

lreal = False)<br />

NaCl.set_calculator(calc)<br />

print NaCl.get_magnetic_moment()<br />

In this example the initial magnetic moments are assigned to the atoms when defining the Atoms object. The calculator<br />

will detect that at least one of the atoms has a non-zero magnetic moment and a spin-polarized calculation<br />

will automatically be performed. The <strong>ASE</strong> generated INCAR file will look like:<br />

INCAR created by Atomic Simulation Environment<br />

PREC = Accurate<br />

LREAL = .FALSE.<br />

ISPIN = 2<br />

MAGMOM = 1*1.9280 1*0.7500<br />

Note: It is also possible to manually tell the calculator to perform a spin-polarized calculation:<br />

>>> calc.set(ispin=2)<br />

This can be useful for continuation jobs, where the initial magnetic moment is read from the WAVECAR file.<br />

Restart old calculation<br />

To continue an old calculation which has been performed without the interface use the restart parameter when<br />

constructing the calculator<br />

>>> calc = Vasp(restart=True)<br />

Then the calculator will read atomic positions from the CONTCAR file, physical quantities from the OUTCAR file,<br />

k-points from the KPOINTS file and parameters from the INCAR file.<br />

7.14. Calculators 123


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

Note: Only Monkhorst-Pack and Gamma-centered k-point sampling are supported for restart at the moment.<br />

Some INCAR parameters may not be implemented for restart yet. Please report any problems to the <strong>ASE</strong> mailing<br />

list.<br />

The restart parameter can be used , as the name suggest to continue a job from where a previous calculation<br />

finished. Furthermore, it can be used to extract data from an already performed calculation. For example, to get the<br />

total potential energy of the sodium chloride molecule in the previous section, without performing any additional<br />

calculations, in the directory of the previous calculation do:<br />

>>> calc = Vasp(restart=True)<br />

>>> atoms = calc.get_atoms()<br />

>>> atoms.get_potential_energy()<br />

-4.7386889999999999<br />

FHI-aims<br />

Introduction<br />

FHI-aims is a all-electron full-potential density functional theory code using a numeric local orbital basis set. This<br />

interface provides all that should be required to run FHI-aims from within <strong>ASE</strong>.<br />

Running the Calculator<br />

The default initialization command for the FHI-aims calculator is<br />

class FHI-aims.Aims(output_template = ‘aims’, track_output = False)<br />

In order to run a calculation, you have to ensure that at least the following str variables are specified, either in<br />

the initialization or as shell variables:<br />

key- description<br />

word<br />

run_command The full command required to run FHI-aims from a shell, including anything to do with an MPI<br />

wrapper script and the number of tasks. An alternative way to set this command is via the shell<br />

variable AIMS_COMMAND, which is checked upon initialization and when starting a run.<br />

species_dir Directory where the species defaults are located that should be used. Can also be specified with<br />

the system variable AIMS_SPECIES_DIR.<br />

xc The minimal physical specification: what kind of calculation should be done.<br />

In addition, you might want to specify at least one of self-consistency accuracy commands (see below) in order to<br />

avoid an excessively long calculation.<br />

Two general options might come in useful to postprocess the output:<br />

keyword description<br />

output_template Base name for the output, in case the calculator is called multiple times within a single<br />

script.<br />

track_output True/False - if True all the output files will be kept, while the number of calls to the<br />

calculator is encoded in the output file name.<br />

List of keywords<br />

This is a non-exclusive list of keywords for the control.in file that can be addresses from within <strong>ASE</strong>. The<br />

meaning for these keywords is exactly the same as in FHI-aims, please refer to its manual for help on their use.<br />

One thing that should be mentioned is that keywords with more than one option have been implemented as lists, eg.<br />

k_grid=(12,12,12) or relativistic=(’atomic_zora’,’scalar’). In those cases, specifying a<br />

single string containing all the options is also possible.<br />

124 Chapter 7. Documentation for modules in <strong>ASE</strong>


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

None of the keywords have any default within <strong>ASE</strong>,but do check the defaults set by FHI-aims. If there is a keyword<br />

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<br />

calculator in the file <strong>ASE</strong>/ase/calculators/aims.py .<br />

Describing the basic physics of the system:<br />

keyword type<br />

xc str<br />

charge float<br />

spin str<br />

relativistic list<br />

use_dipole_correction bool<br />

vdw_correction_hirshfeld str<br />

k_grid list<br />

Driving relaxations and molecular dynamics:<br />

keyword type<br />

relax_geometry list<br />

max_relaxation_steps int<br />

n_max_pulay int<br />

sc_iter_limit int<br />

restart_relaxations bool<br />

MD_run list<br />

MD_schedule list<br />

MD_segment list<br />

Output options:<br />

keyword type<br />

output_level str<br />

output list<br />

cubes AimsCube<br />

See below for a description of the volumetric cube file output interface AimsCube<br />

Keywords for accuracy settings:<br />

keyword type<br />

sc_accuracy_eev exp<br />

sc_accuracy_etot exp<br />

sc_accuracy_forces exp<br />

sc_accuracy_rho exp<br />

compute_forces bool<br />

Keywords to adjust the SCF-cycle<br />

keyword type<br />

charge_mix_param float<br />

prec_mix_param float<br />

spin_mix_param float<br />

KS_method str<br />

restart str<br />

restart_read_only str<br />

restart_write_only srt<br />

preconditioner list<br />

mixer str<br />

empty_states int<br />

ini_linear_mixing int<br />

mixer_threshold list<br />

occupation_type list<br />

Note:<br />

7.14. Calculators 125


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

Any argument can be changed after the initial construction of the<br />

calculator, simply by setting it with the method<br />

>>> calc.set( keyword=value )<br />

Volumetric Data Output<br />

The class<br />

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)<br />

describes an object that takes care of the volumetric output requests within FHI-aims. An object of this type can<br />

be attached to the main Aims() object as an option.<br />

The possible arguments for AimsCube are:<br />

keyword type<br />

origin list<br />

edges 3x3-array<br />

points list<br />

plots list<br />

The possible values for the entry of plots are discussed in detail in the FHI-aims manual, see below for an example.<br />

Example<br />

As an example, here is a possible setup to obtain the geometry of a water molecule:<br />

from ase import Atoms<br />

from ase.visualize import view<br />

from ase.calculators.aims import Aims, AimsCube<br />

from ase.optimize import QuasiNewton<br />

water = Atoms(’HOH’, [(1,0,0), (0,0,0), (0,1,0)])<br />

water_cube = AimsCube(points=(29,29,29),<br />

plots=(’total_density’,’delta_density’,<br />

’eigenstate 5’,’eigenstate 6’))<br />

calc=Aims(xc=’pbe’,<br />

sc_accuracy_etot=1e-6,<br />

sc_accuracy_eev=1e-3,<br />

sc_accuracy_rho=1e-6,<br />

sc_accuracy_forces=1e-4,<br />

species_dir=’/home/hanke/codes/fhi-aims/fhi-aims.workshop/species_defaults/light/’,<br />

run_command=’aims.workshop.serial.x’,<br />

cubes=water_cube)<br />

water.set_calculator(calc)<br />

dynamics = QuasiNewton(water,trajectory=’square_water.traj’)<br />

dynamics.run(fmax=0.01)<br />

view(water)<br />

LAMMPS<br />

Introduction<br />

LAMMPS (Large-scale Atomic/Molecular Massively Parallel Simulator) is a classical molecular dynamics code.<br />

126 Chapter 7. Documentation for modules in <strong>ASE</strong>


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

“LAMMPS has potentials for soft materials (biomolecules, polymers) and solid-state materials (metals,<br />

semiconductors) and coarse-grained or mesoscopic systems. It can be used to model atoms or,<br />

more generically, as a parallel particle simulator at the atomic, meso, or continuum scale.”<br />

Environment variables<br />

The environment variable LAMMPS_COMMAND should contain the path to the lammps binary, or more generally,<br />

a command line possibly also including an MPI-launcher command. For example (in a Bourne-shell compatible<br />

environment):<br />

$ export LAMMPS_COMMAND=/path/to/lmp_binary<br />

or possibly something similar to<br />

$ export LAMMPS_COMMAND="/path/to/mpirun --np 4 lmp_binary"<br />

LAMMPS Calculator<br />

The LAMMPS calculator first appeared in <strong>ASE</strong> version 3.5.0. At the time of the release of <strong>ASE</strong> 3.5.0, the<br />

LAMMPS calculator is still in a fairly early stage of development (if you are missing some feature, consider<br />

checking out the source code development tree or some more recent version of <strong>ASE</strong>).<br />

class lammps.LAMMPS(..., parameters={}, files=[], ...)<br />

Below follows a list with a selection of parameters<br />

keyword<br />

type default<br />

value<br />

description<br />

files list[] List of files needed by LAMMPS. Typically a list of potential files.<br />

parameters dict{} Dictionary with key-value pairs corresponding to commands and arguments.<br />

Command-argument pairs provided here will be used for overriding the the<br />

calculator defaults.<br />

Example<br />

A simple example.<br />

from ase import Atoms, Atom<br />

from ase.calculators.lammps import LAMMPS<br />

a = [6.5, 6.5, 7.7]<br />

d = 2.3608<br />

NaCl = Atoms([Atom(’Na’, [0, 0, 0]),<br />

Atom(’Cl’, [0, 0, d])],<br />

cell=a, pbc=True)<br />

calc = LAMMPS()<br />

NaCl.set_calculator(calc)<br />

print NaCl.get_stress()<br />

Molecular Modelling Toolkit<br />

class mmtk.MMTK<br />

7.14. Calculators 127


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

Warning: <strong>ASE</strong>2 has an interface to MMTK, but <strong>ASE</strong>3 has not. There may be a problem with MMTK and<br />

numpy?<br />

Let us know if you need MMTK, and we will take a look at it.<br />

exciting<br />

Introduction<br />

exciting is a full-potential all-electron density-functional-theory (DFT) package based on the linearized augmented<br />

planewave (LAPW) method. It can be applied to all kinds of materials, irrespective of the atomic species<br />

involved, and also allows for the investigation of the core region. The website is http://exciting-code.org/<br />

The module depends on lxml http://codespeak.net/lxml/<br />

Exciting Calculator Class<br />

class ase.calculators.exciting.Exciting(dir=’calc’, template=None,<br />

speciespath=’http://xml.excitingcode.org/species/’,<br />

bin=’excitingser’, kpts=(1, 1,<br />

1), **kwargs)<br />

Exciting calculator object constructor<br />

dir: string directory in which to execute exciting<br />

template: string Path to XSLT template if it should be used default: none<br />

speciespath: string Directory or URL to look up species files<br />

bin: string Path or executable name of exciting default: excitingser<br />

kpts: integer list length 3 Number of k-points<br />

kwargs: dictionary like list of key value pairs to be converted into groundstate attributes<br />

There are two ways to construct the exciting calculator.<br />

Constructor Keywords One is by giving parameters of the ground state in the constructor. The possible attributes<br />

can be found at http://exciting-code.org/input-reference#groundstate.<br />

class exciting.Exciting(bin=’excitingser’, kpts=(4, 4, 4), xctype=’GGArevPBE’)<br />

XSLT Template The other way is to use an XSLT template<br />

class exciting.Exciting(template=’template.xsl’, bin=’excitingser’)<br />

The template may look like:<br />

<br />

<br />

<br />

<br />

<br />

created from template<br />

<br />

128 Chapter 7. Documentation for modules in <strong>ASE</strong>


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

Current Limitations<br />

The calculator supports only total energy and forces no stress strain implemented in exciting yet. However it is<br />

planned to be implemented soon. http://exciting-code.org/current-developments.<br />

The keywords on the constructor are converted into attributes of the groundstate element. No check is done<br />

there and not all options are accessible in that way. By using the template one can exceed this limitation.<br />

FLEUR<br />

Introduction<br />

FLEUR is a density-functional theory code which uses the full potential linearized augmented plane-wave<br />

(FLAPW) method. FLEUR can be applied to any element in the periodic table, and the code is well suited<br />

especially to surfaces and magnetic materials.<br />

Environment variables<br />

In order to use FLEUR through <strong>ASE</strong>, two environment variables have to be set. FLEUR_INPGEN should point to<br />

the simple input generator of FLEUR, and FLEUR to the actual executable. Note that FLEUR has different executables<br />

e.g. for cases with and without inversion symmetry, so the environment variable has to be set accordingly.<br />

As an example, the variables could be set like:<br />

$ export FLEUR_INPGEN=$HOME/fleur/v25/inpgen.x<br />

$ export FLEUR=$HOME/fleur/v25/fleur.x<br />

or:<br />

$ export FLEUR="mpirun -np 32 $HOME/fleur/v25/fleur.x"<br />

for parallel calculations.<br />

FLEUR Calculator<br />

Currently, limited number of FLEUR parameters can be set via the <strong>ASE</strong> interface Below follows a list of supported<br />

parameters<br />

7.14. Calculators 129


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

keyword type default value description<br />

xc str ’LDA’ XC-functional. Must be one of ‘LDA’, ‘PBE’, ‘RPBE’<br />

kpts seq Gamma-point k-point sampling<br />

convergence dict {’energy’: 0.0001} Convergence criteria (meV)<br />

width float Width of Fermi smearing (eV)<br />

kmax float Plane-wave cut-off (a.u.)<br />

mixer dict Mixing parameters ‘imix’, ‘alpha’, and ‘spinf’<br />

maxiter int 40 Maximum number of SCF steps<br />

maxrelax int 20 Maximum number of relaxation steps<br />

workdir str Current dir Working directory for the calculation<br />

seq: A sequence of three int‘s. dict: A dictionary<br />

Spin-polarized calculation<br />

If the atoms object has non-zero magnetic moments, a spin-polarized calculation will be performed by default.<br />

Utility functions<br />

As only a subset of FLEUR parameters can currently be specified through <strong>ASE</strong> interface, the interface defines<br />

some utility functions for cases where manual editing of the FLEUR input file inp is necessary.<br />

FLEUR.write_inp(atoms)<br />

Write the inp input file of FLEUR.<br />

First, the information from Atoms is written to the simple input file and the actual input file inp is then<br />

generated with the FLEUR input generator. The location of input generator is specified in the environment<br />

variable FLEUR_INPGEN.<br />

Finally, the inp file is modified according to the arguments of the FLEUR calculator object.<br />

FLEUR.initialize_density(atoms)<br />

Creates a new starting density.<br />

FLEUR.calculate(atoms)<br />

Converge a FLEUR calculation to self-consistency.<br />

Input files should be generated before calling this function FLEUR performs always fixed number of SCF<br />

steps. This function reduces the number of iterations gradually, however, a minimum of five SCF steps is<br />

always performed.<br />

FLEUR.relax(atoms)<br />

Currently, user has to manually define relaxation parameters (atoms to relax, relaxation directions, etc.) in<br />

inp file before calling this function.<br />

Examples<br />

Lattice constant of fcc Ni<br />

from numpy import linspace<br />

from ase.calculators.fleur import FLEUR<br />

from ase.lattice import bulk<br />

from ase.io.trajectory import PickleTrajectory<br />

atoms = bulk(’Ni’, a=3.52)<br />

calc = FLEUR(xc=’PBE’, kmax=3.6, kpts=(10, 10, 10), workdir=’lat_const’)<br />

atoms.set_calculator(calc)<br />

traj = PickleTrajectory(’Ni.traj’,’w’, atoms)<br />

cell0 = atoms.get_cell()<br />

130 Chapter 7. Documentation for modules in <strong>ASE</strong>


for s in linspace(0.95, 1.05, 7):<br />

cell = cell0 * s<br />

atoms.set_cell((cell))<br />

ene = atoms.get_potential_energy()<br />

traj.write()<br />

See the equation of states tutorial for analysis of the results.<br />

CASTEP<br />

Introduction<br />

<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

CASTEP 1 is a software package which uses density functional theory to provide a good atomic-level description<br />

of all manner of materials and molecules. CASTEP can give information about total energies, forces and stresses<br />

on an atomic system, as well as calculating optimum geometries, band structures, optical spectra, phonon spectra<br />

and much more. It can also perform molecular dynamics simulations.<br />

The CASTEP calculator interface class offers intuitive access to all CASTEP settings and most results. All<br />

CASTEP specific settings are accessible via attribute access (i.e. calc.param.keyword = ... or<br />

calc.cell.keyword = ...)<br />

Getting Started:<br />

Set the environment variables appropriately for your system.<br />

>>> export CASTEP_COMMAND=’ ... ’<br />

>>> export CASTEP_PP_PATH=’ ... ’<br />

Running the Calculator<br />

The default initialization command for the CASTEP calculator is<br />

class castep.Castep(directory=’CASTEP’, label=’castep’)<br />

To do a minimal run one only needs to set atoms, this will use all default settings of CASTEP, meaning LDA,<br />

singlepoint, etc..<br />

With a generated castep_keywords.py in place all options are accessible by inspection, i.e. tab-completion. This<br />

works best when using ipython. All options can be accessed via calc.param. or calc.cell.<br />

and documentation is printed with calc.param. ? or calc.cell.<br />

?. All options can also be set directly using calc.keyword = ... or calc.KEYWORD =<br />

... or even calc.KeYwOrD or directly as named arguments in the call to the constructor (e.g.<br />

Castep(task=’GeometryOptimization’)).<br />

All options that go into the .param file are held in an CastepParam instance, while all options that go into<br />

the .cell file and don’t belong to the atoms object are held in an CastepCell instance. Each instance can<br />

be created individually and can be added to calculators by attribute assignment, i.e. calc.param = param or<br />

calc.cell = cell.<br />

All internal variables of the calculator start with an underscore (_). All cell attributes that clearly belong into<br />

the atoms object are blocked. Setting calc.atoms_attribute (e.g. = positions) is sent directly to the<br />

atoms object.<br />

1 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)<br />

pp.567- 570 (2005)<br />

7.14. Calculators 131


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

Arguments:<br />

Key- Description<br />

word<br />

directory The relative path where all input and output files will be placed. If this does not exist, it will be<br />

created. Existing directories will be moved to directory-TIMESTAMP unless<br />

self._rename_existing_dir is set to false.<br />

label The prefix of .param, .cell, .castep, etc. files.<br />

Additional Settings<br />

Internal Description<br />

Setting<br />

_castep_command (=castep): the actual shell command used to call CASTEP.<br />

_check_checkfile (=True): this makes write_param() only write a continue or reuse statement if the<br />

addressed .check or .castep_bin file exists in the directory.<br />

_copy_pspots (=False): if set to True the calculator will actually copy the needed pseudo-potential<br />

(*.usp) file, usually it will only create symlinks.<br />

_export_settings (=True): if this is set to True, all calculator internal settings shown here will be included<br />

in the .param in a comment line (#) and can be read again by merge_param. merge_param<br />

can be forced to ignore this directive using the optional argument<br />

ignore_internal_keys=True.<br />

_force_write (=True): this controls wether the *cell and *param will be overwritten.<br />

_prepare_input_only (=False): If set to True, the calculator will create *cell und *param file but not start the<br />

calculation itself. If this is used to prepare jobs locally and run on a remote cluster it is<br />

recommended to set _copy_pspots = True.<br />

_castep_pp_path (=’.’) : the place where the calculator will look for pseudo-potential files.<br />

_rename_existing_dir (=True) : when using a new instance of the calculator, this will move directories out of<br />

the way that would be overwritten otherwise, appending a date string.<br />

_set_atoms (=False) : setting this to True will overwrite any atoms object previously attached to the<br />

calculator when reading a .castep file. By de- fault, the read() function will only create a<br />

new atoms object if none has been attached and other- wise try to assign forces etc. based<br />

on the atom’s positions. _set_atoms=True could be necessary if one uses CASTEP’s<br />

internal geometry optimization (calc.param.task=’GeometryOptimization’)<br />

because then the positions get out of sync. Warning: this option is generally not<br />

recommended unless one knows one really needs it. There should never be any need, if<br />

CASTEP is used as a single-point calculator.<br />

_track_output(=False) : if set to true, the interface will append a number to the label on all input and<br />

output files, where n is the number of calls to this instance. Warning: this setting may consume<br />

a lot more disk space because of the additio- nal *check files.<br />

_try_reuse (=_track_output) : when setting this, the in- terface will try to fetch the reuse file<br />

from the previous run even if _track_output is True. By de- fault it is equal to<br />

_track_output, but may be overridden.<br />

Since this behavior may not always be desirable for single-point calculations. Regular<br />

reuse for e.g. a geometry-optimization can be achieved by setting calc.param.reuse<br />

= True.<br />

Special features:<br />

.dryrun_ok() Runs castep_command seed -dryrun in a temporary directory return True if all variables<br />

initialized ok. This is a fast way to catch errors in the input. Afterwards _kpoints_used is set.<br />

.merge_param() Takes a filename or filehandler of a .param file or CastepParam instance and merges it into<br />

the current calculator instance, overwriting current settings<br />

132 Chapter 7. Documentation for modules in <strong>ASE</strong>


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

.keyword.clear() Can be used on any option like calc.param.keyword.clear() or<br />

calc.cell.keyword.clear() to return to the CASTEP default.<br />

.initialize() Creates all needed input in the _directory. This can then copied to and run in a place<br />

without <strong>ASE</strong> or even python.<br />

.set_pspot(’’) This automatically sets the pseudo-potential for all present species to<br />

_.usp. Make sure that _castep_pp_path is set correctly.<br />

print(calc) Prints a short summary of the calculator settings and atoms.<br />

ase.io.castep.read_seed(’path-to/seed’) Given you have a combination of<br />

seed.{param,cell,castep} this will return an atoms object with the last ionic positions in the .castep<br />

file and all other settings parsed from the .cell and .param file. If no .castep file is found the positions are<br />

taken from the .cell file. The output directory will be set to the same directory, only the label is preceded<br />

by ‘copy_of_’ to avoid overwriting.<br />

Notes/Issues:<br />

• Currently only the FixAtoms constraint is fully supported for reading and writing.<br />

• There is no support for the CASTEP unit system. Units of eV and Angstrom are used throughout. In particular<br />

when converting total energies from different calculators, one should check that the same CODATA<br />

version is used for constants and conversion factors, respectively.<br />

Example:<br />

#!/usr/bin/python<br />

"""This simple demo calculates the total energy of CO molecules<br />

using once LDA and once PBE as xc-functional. Obviously<br />

some parts in this scripts are longer than necessary, but are shown<br />

to demonstrate some more features."""<br />

import ase<br />

import ase.calculators.castep, ase.io.castep<br />

calc = ase.calculators.castep.Castep()<br />

directory = ’CASTEP_<strong>ASE</strong>_DEMO’<br />

# include interface settings in .param file<br />

calc._export_settings = True<br />

# reuse the same directory<br />

calc._directory = directory<br />

calc._rename_existing_dir = False<br />

calc._label = ’CO_LDA’<br />

# necessary for tasks with changing positions<br />

# such as GeometryOptimization or MolecularDynamics<br />

calc._set_atoms = True<br />

# Param settings<br />

calc.param.xc_functional = ’LDA’<br />

calc.param.cut_off_energy = 400<br />

# Prevent CASTEP from writing *wvfn* files<br />

calc.param.num_dump_cycles = 0<br />

# Cell settings<br />

calc.cell.kpoint_mp_grid = ’1 1 1’<br />

calc.cell.fix_com = False<br />

calc.cell.fix_all_cell = True<br />

7.14. Calculators 133


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

# Set and clear and reset settings (just for shows)<br />

calc.param.task = ’SinglePoint’<br />

# Reset to CASTEP default<br />

calc.param.task.clear()<br />

# all of the following are identical<br />

calc.param.task = ’GeometryOptimization’<br />

calc.task = ’GeometryOptimization’<br />

calc.TASK = ’GeometryOptimization’<br />

calc.Task = ’GeometryOptimization’<br />

# Prepare atoms<br />

mol = ase.atoms.Atoms(’CO’, [[0, 0, 0], [0, 0, 1.2]], cell=[10, 10, 10])<br />

mol.set_calculator(calc)<br />

# Check for correct input<br />

if calc.dryrun_ok():<br />

print(’%s : %s ’ % (mol.calc._label, mol.get_potential_energy()))<br />

else:<br />

print("Found error in input")<br />

print(calc._error)<br />

# Read all settings from previous calculation<br />

mol = ase.io.castep.read_seed(’%s/CO_LDA’ % directory)<br />

# Use the OTF pseudo-potential we have just generated<br />

mol.calc.set_pspot(’OTF’)<br />

# Change some settings<br />

mol.calc.param.xc_functional = ’PBE’<br />

# don’t forget to set an appropriate label<br />

mol.calc._label = ’CO_PBE’<br />

# Recalculate the potential energy<br />

print(’%s : %s ’ % (mol.calc._label, mol.get_potential_energy()))<br />

Gromacs<br />

Introduction<br />

Gromacs is a free classical molecular dynamics package. It is mainly used in modeling of biological systems. It<br />

is part of the ubuntu-linux distribution.<br />

Gromacs Calculator<br />

This <strong>ASE</strong>-interface is a preliminary one and it is VERY SLOW so do not use it for production runs. It is here<br />

because of hopefully we’ll get a QM/MM calculator which is using gromacs as the MM part.<br />

For example:<br />

calc = Gromacs( init_structure_file=infilename, force_field=’oplsaa’, water_model=’tip3p’, define = ‘-<br />

DFLEXIBLE’, integrator = ‘md’, nsteps = ‘0’, nstfout = ‘1’, nstlog = ‘1’, nstenergy = ‘1’, energygrps =<br />

‘System’, nstlist = ‘1’, ns_type = ‘grid’, pbc = ‘xyz’, rlist = ‘1.15’, coulombtype = ‘PME-Switch’, rcoulomb<br />

= ‘0.8’, vdwtype = ‘shift’, rvdw = ‘0.8’, rvdw_switch = ‘0.75’, DispCorr = ‘Ener’)<br />

134 Chapter 7. Documentation for modules in <strong>ASE</strong>


Parameters<br />

<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

The description of the parameters can be found in the Gromacs manual:<br />

http://www.gromacs.org/Documentation/<strong>Manual</strong><br />

except these parameters should be fixed: integrator = ‘md’, nsteps = ‘0’<br />

and extra (ie non-gromacs) parameter:<br />

init_structure_file: str The name of the initial structure file. The structure file should be in .gro format because<br />

pdb reading in <strong>ASE</strong> is not very good.<br />

Example1: Geometry Optimization of a histidine molecule<br />

Initial pdb coordinates (file his.pdb):<br />

COMPND HIS HISTIDINE<br />

REMARK HIS Part of HIC-Up: http://xray.bmc.uu.se/hicup<br />

REMARK HIS Extracted from PDB file pdb1wpu.ent<br />

HETATM 1 N HIS 4234 0.999 -1.683 -0.097 1.00 20.00<br />

HETATM 2 CA HIS 4234 1.191 -0.222 -0.309 1.00 20.00<br />

HETATM 3 C HIS 4234 2.641 0.213 -0.105 1.00 20.00<br />

HETATM 4 O HIS 4234 3.529 -0.651 -0.222 1.00 20.00<br />

HETATM 5 CB HIS 4234 0.245 0.546 0.619 1.00 20.00<br />

HETATM 6 CG HIS 4234 -1.200 0.349 0.280 1.00 20.00<br />

HETATM 7 ND1 HIS 4234 -1.854 -0.849 0.470 1.00 20.00<br />

HETATM 8 CD2 HIS 4234 -2.095 1.176 -0.310 1.00 20.00<br />

HETATM 9 CE1 HIS 4234 -3.087 -0.752 0.006 1.00 20.00<br />

HETATM 10 NE2 HIS 4234 -3.258 0.467 -0.474 1.00 20.00<br />

HETATM 11 OXT HIS 4234 2.889 1.404 0.141 1.00 20.00<br />

REMARK HIS ENDHET<br />

First generate the initial structure in gromacs format (.gro)<br />

pdb2gmx -f his.pdb -o hish.gro -ff oplsaa -water tip3p<br />

Then setup a periodic simulation box<br />

editconf_d -f hish.gro -o hishBOX.gro -box 3 3 3<br />

Finally, relax the structure: The sample file:<br />

#!/usr/bin/env python<br />

""" An example for using gromacs calculator in ase.<br />

Atom positions are relaxed.<br />

A sample call:<br />

"""<br />

./gromacs_example_relax.py hishBOX.gro<br />

from ase import Atoms<br />

from ase.visualize import view<br />

from ase.calculators.gromacs import Gromacs<br />

from ase.optimize import BFGS<br />

from ase.optimize.bfgslinesearch import BFGSLineSearch<br />

from ase.optimize import MDMin<br />

from ase.optimize.sciopt import SciPyFminBFGS, SciPyFminCG<br />

from ase.optimize.sciopt import SciPyFmin<br />

from ase.optimize.sciopt import SciPyOptimizer<br />

import sys<br />

from ase.io import read, write<br />

from ase import units<br />

7.14. Calculators 135


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

infilename = sys.argv[1]<br />

calc = Gromacs(<br />

init_structure_file=infilename,<br />

force_field=’oplsaa’,<br />

water_model=’tip3p’,<br />

define = ’-DFLEXIBLE’,<br />

integrator = ’md’,<br />

nsteps = ’0’,<br />

nstfout = ’1’,<br />

nstlog = ’1’,<br />

nstenergy = ’1’,<br />

energygrps = ’System’,<br />

nstlist = ’1’,<br />

ns_type = ’grid’,<br />

pbc = ’xyz’,<br />

rlist = ’1.15’,<br />

coulombtype = ’PME-Switch’,<br />

rcoulomb = ’0.8’,<br />

vdwtype = ’shift’,<br />

rvdw = ’0.8’,<br />

rvdw_switch = ’0.75’,<br />

DispCorr = ’Ener’)<br />

system = read(’gromacs.gro’)<br />

system.set_calculator(calc)<br />

e_system = system.get_potential_energy()<br />

f_system = system.get_forces()<br />

# SciPyFminCG == non-linear Polak-Ribiere, should be the same as gromacs<br />

dyn = SciPyFminCG(system)<br />

dyn.run(fmax=0.01)<br />

7.14.3 Calculator interface<br />

All calculators must have the following interface:<br />

class ase.calculators.interface.Calculator<br />

Class for demonstrating the <strong>ASE</strong>-calculator interface.<br />

A good implementation of a calculator should store a copy of the atoms object used for the last calculation.<br />

When one of the get_potential_energy, get_forces, or get_stress methods is called, the calculator should<br />

check if anything has changed since the last calculation and only do the calculation if it’s really needed. The<br />

Atoms class implements the methods __eq__ and __ne__ that can be used for checking identity (using ==<br />

and !=): Two sets of atoms are considered identical if they have the same positions, atomic numbers, unit<br />

cell and periodic boundary conditions.<br />

calculation_required(atoms, quantities)<br />

Check if a calculation is required.<br />

Check if the quantities in the quantities list have already been calculated for the atomic configuration<br />

atoms. The quantities can be one or more of: ‘energy’, ‘forces’, ‘stress’, and ‘magmoms’.<br />

get_forces(atoms)<br />

Return the forces.<br />

get_potential_energy(atoms=None, force_consistent=False)<br />

Return total energy.<br />

Both the energy extrapolated to zero Kelvin and the energy consistent with the forces (the free energy)<br />

can be returned.<br />

136 Chapter 7. Documentation for modules in <strong>ASE</strong>


get_stress(atoms)<br />

Return the stress.<br />

set_atoms(atoms)<br />

Let the calculator know the atoms.<br />

<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

This method is optional. If it exists, it will be called when the Atoms.set_calculator() method is called.<br />

Don’t store a reference to atoms - that will create a cyclic reference loop! Store a copy instead.<br />

7.14.4 Electronic structure calculators<br />

These calculators have wave functions, electron densities, eigenvalues and many other quantities. Therefore, it<br />

makes sense to have a set of standard methods for accessing those quantities:<br />

class ase.calculators.interface.DFTCalculator<br />

Class for demonstrating the <strong>ASE</strong> interface to DFT-calculators.<br />

get_bz_k_points()<br />

Return all the k-points in the 1. Brillouin zone.<br />

The coordinates are relative to reciprocal latice vectors.<br />

get_effective_potential(spin=0, pad=True)<br />

Return pseudo-effective-potential array.<br />

get_eigenvalues(kpt=0, spin=0)<br />

Return eigenvalue array.<br />

get_fermi_level()<br />

Return the Fermi level.<br />

get_ibz_k_points()<br />

Return k-points in the irreducible part of the Brillouin zone.<br />

The coordinates are relative to reciprocal latice vectors.<br />

get_k_point_weights()<br />

Weights of the k-points.<br />

The sum of all weights is one.<br />

get_magnetic_moment(atoms=None)<br />

Return the total magnetic moment.<br />

get_number_of_bands()<br />

Return the number of bands.<br />

get_number_of_grid_points()<br />

Return the shape of arrays.<br />

get_number_of_spins()<br />

Return the number of spins in the calculation.<br />

Spin-paired calculations: 1, spin-polarized calculation: 2.<br />

get_occupation_numbers(kpt=0, spin=0)<br />

Return occupation number array.<br />

get_pseudo_density(spin=None, pad=True)<br />

Return pseudo-density array.<br />

If spin is not given, then the total density is returned. Otherwise, the spin up or down density is<br />

returned (spin=0 or 1).<br />

get_pseudo_wave_function(band=0, kpt=0, spin=0, broadcast=True, pad=True)<br />

Return pseudo-wave-function array.<br />

7.14. Calculators 137


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

get_spin_polarized()<br />

Is it a spin-polarized calculation?<br />

get_wannier_localization_matrix(nbands, dirG, kpoint, nextkpoint, G_I, spin)<br />

Calculate integrals for maximally localized Wannier functions.<br />

get_xc_functional()<br />

Return the XC-functional identifier.<br />

‘LDA’, ‘PBE’, ...<br />

initial_wannier(initialwannier, kpointgrid, fixedstates, edf, spin, nbands)<br />

Initial guess for the shape of wannier functions.<br />

Use initial guess for wannier orbitals to determine rotation matrices U and C.<br />

7.14.5 Building new calculators<br />

Adding an <strong>ASE</strong> interface to your favorite force-calculator can be very simple. Take a look at the Python wrapper<br />

we have in the <strong>ASE</strong> code for using the SIESTA code with <strong>ASE</strong>: ase/calculators/siesta.py. Here, a Siesta class<br />

is defined. An instance of this class will simply write the fdf input-file, start the SIESTA Fortran program, and<br />

finally read the energy, forces and stresses from the text output-file.<br />

7.14.6 Building neighbor-lists<br />

The EMT potential and the GPAW DFT calculator both make use of <strong>ASE</strong>’s built-in neighbor-list class:<br />

class ase.calculators.neighborlist.NeighborList(cutoffs, skin=0.3, sorted=False,<br />

self_interaction=True, bothways=False)<br />

Neighbor list object.<br />

cutoffs: list of float List of cutoff radii - one for each atom.<br />

skin: float If no atom has moved more than the skin-distance since the last call to the update() method,<br />

then the neighbor list can be reused. This will save some expensive rebuilds of the list, but extra<br />

neighbors outside the cutoff will be returned.<br />

self_interaction: bool Should an atom return itself as a neighbor?<br />

bothways: bool Return all neighbors. Default is to return only “half” of the neighbors.<br />

Example:<br />

nl = NeighborList([2.3, 1.7])<br />

nl.update(atoms)<br />

indices, offsets = nl.get_neighbors(0)<br />

build(atoms)<br />

Build the list.<br />

get_neighbors(a)<br />

Return neighbors of atom number a.<br />

A list of indices and offsets to neighboring atoms is returned. The positions of the neighbor atoms can<br />

be calculated like this:<br />

indices, offsets = nl.get_neighbors(42)<br />

for i, offset in zip(indices, offsets):<br />

print atoms.positions[i] + dot(offset, atoms.get_cell())<br />

Notice that if get_neighbors(a) gives atom b as a neighbor, then get_neighbors(b) will not return a as<br />

a neighbor - unless bothways=True was used.<br />

138 Chapter 7. Documentation for modules in <strong>ASE</strong>


update(atoms)<br />

Make sure the list is up to date.<br />

7.15 Constraints<br />

<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

When performing minimizations or dynamics one may wish to keep some degrees of freedom in the system fixed.<br />

One way of doing this is by attaching constraint object(s) directly to the atoms object.<br />

Important: setting constraints will freeze the corresponding atom positions. Changing such atom positions can be<br />

achieved:<br />

• by directly setting the positions attribute (see example of setting Special attributes),<br />

• alternatively, by removing the constraints first:<br />

del atoms.constraints<br />

or:<br />

atoms.set_constraint()<br />

and using the set_positions() method.<br />

7.15.1 The FixAtoms class<br />

This class is used for fixing some of the atoms.<br />

class constraints.FixAtoms(indices=None, mask=None)<br />

You must supply either the indices of the atoms that should be fixed or a mask. The mask is a list of booleans, one<br />

for each atom, being true if the atoms should be kept fixed.<br />

For example, to fix the positions of all the Cu atoms in a simulation with the indices keyword:<br />

>>> c = FixAtoms(indices=[atom.index for atom in atoms if atom.symbol == ’Cu’])<br />

>>> atoms.set_constraint(c)<br />

or with the mask keyword:<br />

>>> c = FixAtoms(mask=[atom.symbol == ’Cu’ for atom in atoms])<br />

>>> atoms.set_constraint(c)<br />

7.15.2 The FixBondLength class<br />

This class is used to fix the distance between two atoms specified by their indices (a1 and a2)<br />

class constraints.FixBondLength(a1, a2)<br />

Example of use:<br />

>>> c = FixBondLength(0, 1)<br />

>>> atoms.set_constraint(c)<br />

In this example the distance between the atoms with indices 0 and 1 will be fixed in all following dynamics and/or<br />

minimizations performed on the atoms object.<br />

This constraint is useful for finding minimum energy barriers for reactions where the path can be described well<br />

by a single bond length (see the Dissociation tutorial).<br />

Important: If fixing multiple bond lengths, use the FixBondLengths class below, particularly if the same atom is<br />

fixed to multiple partners.<br />

7.15. Constraints 139


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

7.15.3 The FixBondLengths class<br />

More than one bond length can be fixed by using this class. Especially for cases in which more than one bond<br />

length constraint is applied on the same atom. It is done by specifying the indices of the two atoms forming the<br />

bond in pairs.<br />

class constraints.FixBondLengths(pairs)<br />

Example of use:<br />

>>> c = FixBondLengths([[0, 1], [0, 2]])<br />

>>> atoms.set_constraint(c)<br />

Here the distances between atoms with indices 0 and 1 and atoms with indices 0 and 2 will be fixed. The constraint<br />

is for the same purpose as the FixBondLength class.<br />

7.15.4 The FixedLine class<br />

class ase.constraints.FixedLine(a, direction)<br />

Constrain an atom a to move on a given line only.<br />

The line is defined by its direction.<br />

7.15.5 The FixedPlane class<br />

class ase.constraints.FixedPlane(a, direction)<br />

Constrain an atom a to move in a given plane only.<br />

The plane is defined by its normal: direction.<br />

Example of use: Diffusion of gold atom on Al(100) surface (constraint).<br />

7.15.6 The FixedMode class<br />

class ase.constraints.FixedMode(mode)<br />

Constrain atoms to move along directions orthogonal to a given mode only.<br />

A mode is a list of vectors specifying a direction for each atom. It often comes from<br />

ase.vibrations.Vibrations.get_mode().<br />

7.15.7 The BondSpring class<br />

This constraint applies a Hookean restorative force between two atoms if the distance between them exceeds<br />

a threshhold. This is useful to maintain the identity of molecules in quenched molecular dynamics, without<br />

changing the degrees of freedom or violating conservation of energy. When the distance between the two atoms<br />

is less than the threshhold length, this constraint is completely inactive.<br />

The below example tethers together atoms at index 3 and 4 together:<br />

>>> c = BondSpring(a1=3, a2=4, threshhold_length=1.79,<br />

springconstant=5.)<br />

>>> atoms.set_constraint(c)<br />

Alternatively, this constraint can tether a single atom to a point in space, for example to prevent the top layer of<br />

a slab from subliming during a high-temperature MD simulation. An example of tethering atom at index 3 to its<br />

original position:<br />

>>> c = BondSpring(a1=3, a2=atoms[3].position, threshhold_length=0.94,<br />

springconstant=2.)<br />

>>> atoms.set_constraint(c)<br />

140 Chapter 7. Documentation for modules in <strong>ASE</strong>


Reasonable values of the threshhold and spring constant for some common bonds are below.<br />

Bond threshhold_length springconstant<br />

O-H 1.40 5<br />

C-O 1.79 5<br />

C-H 1.59 7<br />

C=O 1.58 10<br />

Pt sublimation 0.94 2<br />

Cu sublimation 0.97 2<br />

7.15.8 The FixInternals class<br />

<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

This class allows to fix an arbitrary number of bond lengths, angles and dihedral angles. The defined constraints are<br />

satisfied self consistently. To define the constraints one needs to specify the atoms object on which the constraint<br />

works (needed for atomic masses), a list of bond, angle and dihedral constraints. Those constraint definitions<br />

are always list objects containing the value to be set and a list of atomic indices. The epsilon value specifies the<br />

accuracy to which the constraints are fullfilled.<br />

class constraints.FixInternals(atoms, bonds=[bond1, bond2], angles=[angle1], dihedrals=[dihedral1,<br />

dihedral2], epsilon=1.e-7)<br />

Example of use:<br />

>>> bond1 = [1.20, [1, 2]]<br />

>>> angle_indices1 = [2, 3, 4]<br />

>>> dihedral_indices1 = [2, 3, 4, 5]<br />

>>> angle1 = [atoms.get_angle(angle_indices1), angle_indices1]<br />

>>> dihedral1 = [atoms.get_dihedral(dihedral_indices1), \<br />

dihedral_indices1]<br />

>>> c = FixInternals(atoms, bonds=[bonds1], angles=[angles1], \<br />

dihedrals=[dihedral1])<br />

>>> atoms.set_onstraint(c)<br />

This example defines a bond an angle and a dihedral angle constraint to be fixed at the same time.<br />

7.15.9 Combining constraints<br />

It is possible to supply several constraints on an atoms object. For example one may wish to keep the distance<br />

between two nitrogen atoms fixed while relaxing it on a fixed ruthenium surface:<br />

>>> pos = [[0.00000, 0.00000, 9.17625],<br />

... [0.00000, 0.00000, 10.27625],<br />

... [1.37715, 0.79510, 5.00000],<br />

... [0.00000, 3.18039, 5.00000],<br />

... [0.00000, 0.00000, 7.17625],<br />

... [1.37715, 2.38529, 7.17625]]<br />

>>> unitcell = [5.5086, 4.7706, 15.27625]<br />

>>> atoms = Atoms(positions=pos,<br />

... symbols=’N2Ru4’,<br />

... cell=unitcell,<br />

... pbc=[True,True,False])<br />

>>> fa = FixAtoms(mask=[a.symbol == ’Ru’ for a in atoms])<br />

>>> fb = FixBondLength(0, 1)<br />

>>> atoms.set_constraint([fa, fb])<br />

When applying more than one constraint they are passed as a list in the set_constraint() method, and they<br />

will be applied one after the other.<br />

Important: If wanting to fix the length of more than one bond in the simulation, do not supply a list of<br />

FixBondLength instances; instead, use a single instance of FixBondLengths.<br />

7.15. Constraints 141


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

7.15.10 Making your own constraint class<br />

A constraint class must have these two methods:<br />

constraints.adjust_positions(oldpositions, newpositions)<br />

Adjust the newpositions array inplace.<br />

constraints.adjust_forces(positions, forces)<br />

Adjust the forces array inplace.<br />

A simple example:<br />

import numpy as np<br />

class MyConstraint:<br />

"""Constrain an atom to move along a given direction only."""<br />

def __init__(self, a, direction):<br />

self.a = a<br />

self.dir = direction / sqrt(np.dot(direction, direction))<br />

def adjust_positions(self, oldpositions, newpositions):<br />

step = newpositions[self.a] - oldpositions[self.a]<br />

step = np.dot(step, self.dir)<br />

newpositions[self.a] = oldpositions[self.a] + step * self.dir<br />

def adjust_forces(self, positions, forces):<br />

forces[self.a] = self.dir * np.dot(forces[self.a], self.dir)<br />

7.15.11 The Filter class<br />

Constraints can also be applied via filters, which acts as a wrapper around an atoms object. A typical use case will<br />

look like this:<br />

------- -------- ----------<br />

| | | | | |<br />

| Atoms |> atoms = Atoms(...)<br />

>>> filter = Filter(atoms, ...)<br />

>>> dyn = Dynamics(filter, ...)<br />

This class hides some of the atoms in an Atoms object.<br />

class constraints.Filter(atoms, indices=None, mask=None)<br />

You must supply either the indices of the atoms that should be kept visible or a mask. The mask is a list of<br />

booleans, one for each atom, being true if the atom should be kept visible.<br />

Example of use:<br />

>>> from ase import Atoms, Filter<br />

>>> atoms=Atoms(positions=[[ 0 , 0 , 0],<br />

... [ 0.773, 0.600, 0],<br />

... [-0.773, 0.600, 0]],<br />

... symbols=’OH2’)<br />

>>> f1 = Filter(atoms, indices=[1, 2])<br />

>>> f2 = Filter(atoms, mask=[0, 1, 1])<br />

>>> f3 = Filter(atoms, mask=[a.Z == 1 for a in atoms])<br />

>>> f1.get_positions()<br />

[[ 0.773 0.6 0. ]<br />

[-0.773 0.6 0. ]]<br />

142 Chapter 7. Documentation for modules in <strong>ASE</strong>


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

In all three filters only the hydrogen atoms are made visible. When asking for the positions only the positions of<br />

the hydrogen atoms are returned.<br />

7.16 Nudged elastic band<br />

The Nudged Elastic Band method is a technique for finding transition paths (and corresponding energy barriers)<br />

between given initial and final states. The method involves constructing a “chain” of “replicas” or “images” of the<br />

system and relaxing them in a certain way.<br />

Relevant literature References:<br />

1. H. Jonsson, G. Mills, and K. W. Jacobsen, in ‘Classical and Quantum Dynamics in Condensed Phase Systems’,<br />

edited by B. J. Berne, G. Cicotti, and D. F. Coker, World Scientific, 1998 [standard formulation]<br />

2. ‘Improved Tangent Estimate in the NEB method for Finding Minimum Energy Paths and Saddle Points’,<br />

Graeme Henkelman and Hannes Jonsson, J. Chem. Phys. 113, 9978 (2000) [improved tangent estimates]<br />

3. ‘A Climbing-Image NEB Method for Finding Saddle Points and Minimum Energy Paths’, Graeme Henkelman,<br />

Blas P. Uberuaga and Hannes Jonsson, J. Chem. Phys. 113, 9901 (2000)<br />

7.16.1 The NEB class<br />

This module defines one class:<br />

class ase.neb.NEB(images, k=0.1, climb=False, parallel=False, world=None)<br />

Nudged elastic band.<br />

images: list of Atoms objects Images defining path from initial to final state.<br />

k: float or list of floats Spring constant(s). One number or one for each spring.<br />

climb: bool Use a climbing image (default is no climbing image).<br />

parallel: bool Distribute images over processors.<br />

Example of use, between initial and final state which have been previously saved in A.traj and B.traj:<br />

from ase import io<br />

from ase.neb import NEB<br />

from ase.optimize import MDMin<br />

# Read initial and final states:<br />

initial = io.read(’A.traj’)<br />

final = io.read(’B.traj’)<br />

# Make a band consisting of 5 images:<br />

images = [initial]<br />

images += [initial.copy() for i in range(3)]<br />

images += [final]<br />

neb = NEB(images)<br />

# Interpolate linearly the potisions of the three middle images:<br />

neb.interpolate()<br />

# Set calculators:<br />

for image in images[1:4]:<br />

image.set_calculator(MyCalculator(...))<br />

# Optimize:<br />

optimizer = MDMin(neb, trajectory=’A2B.traj’)<br />

optimizer.run(fmax=0.04)<br />

Be sure to use the copy method (or similar) to create new instances of atoms within the list of images fed to the<br />

NEB. Do not use something like [initial for i in range(3)], as it will only create references to the original atoms<br />

object.<br />

Notice the use of the interpolate() method to get a good initial guess for the path from A to B.<br />

7.16. Nudged elastic band 143


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

NEB.interpolate()<br />

Interpolate path linearly from initial to final state.<br />

Only the internal images (not the endpoints) need have calculators attached.<br />

See Also:<br />

optimize: Information about energy minimization (optimization).<br />

calculators: How to use calculators.<br />

Tutorials:<br />

• Diffusion of gold atom on Al(100) surface (NEB)<br />

• Dissociation<br />

• Dissociation<br />

Note: If there are M images and each image has N atoms, then the NEB object behaves like one big Atoms<br />

object with MN atoms, so its get_positions() method will return a MN × 3 array.<br />

7.16.2 Trajectories<br />

The code:<br />

from ase.optimize import QuasiNewton<br />

optimizer = QuasiNewton(neb, trajectory=’A2B.traj’)<br />

will write all images to one file. The Trajectory object knows about NEB calculations, so it will write M images<br />

with N atoms at every iteration and not one big configuration containing MN atoms.<br />

The result of the latest iteration can now be analysed with this command: ag A2B.traj@-5:.<br />

For the example above, you can write the images to individual trajectory files like this:<br />

for i in range(1, 4):<br />

qn.attach(io.PickleTrajectory(’A2B-%d.traj’ % i, ’w’, images[i]))<br />

The result of the latest iteration can be analysed like this:<br />

$ ag A.traj A2B-?.traj B.traj -n -1<br />

7.16.3 Restarting<br />

Restart the calculation like this:<br />

images = io.read(’A2B.traj@-5:’)<br />

7.16.4 Climbing image<br />

The “climbing image” variation involves designating a specific image to behave differently to the rest of the chain:<br />

it feels no spring forces, and the component of the potential force parallel to the chain is reversed, such that it<br />

moves towards the saddle point. This depends on the adjacent images providing a reasonably good approximation<br />

of the correct tangent at the location of the climbing image; thus in general the climbing image is not turned on<br />

until some iterations have been run without it (generally 20% to 50% of the total number of iterations).<br />

To use the climbing image NEB method, instantiate the NEB object like this:<br />

neb = NEB(images, climb=True)<br />

144 Chapter 7. Documentation for modules in <strong>ASE</strong>


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

Note: Quasi-Newton methods, such as BFGS, are not well suited for climbing image NEB calculations. FIRE<br />

have been known to give good results, although convergence is slow.<br />

7.16.5 Parallelization over images<br />

Some calculators can parallelize over the images of a NEB calculation. The script will have to be run with an<br />

MPI-enabled Python interpreter like GPAW‘s gpaw-python. All images exist on all processors, but only some of<br />

them have a calculator attached:<br />

from ase.parallel import rank, size<br />

from ase.calculators.emt import EMT<br />

# Number of internal images:<br />

n = len(images) - 2<br />

j = rank * n // size<br />

for i, image in enumerate(images[1:-1]):<br />

if i == j:<br />

image.set_calculator(EMT())<br />

Create the NEB object with NEB(images, parallel=True) and let the master processes write the images:<br />

if rank % (size // n) == 0:<br />

traj = io.PickleTrajectory(’neb%d.traj’ % j, ’w’, images[1 + j],<br />

master=True)<br />

optimizer.attach(traj)<br />

For a complete example using GPAW, see here.<br />

7.17 Vibration analysis<br />

You can calculate the vibrational modes of a an Atoms object in the harmonic approximation using the<br />

Vibrations.<br />

class ase.vibrations.Vibrations(atoms, indices=None, name=’vib’, delta=0.01, nfree=2)<br />

Class for calculating vibrational modes using finite difference.<br />

The vibrational modes are calculated from a finite difference approximation of the Hessian matrix.<br />

The summary(), get_energies() and get_frequencies() methods all take an optional method keyword. Use<br />

method=’Frederiksen’ to use the method described in:<br />

T. Frederiksen, M. Paulsson, M. Brandbyge, A. P. Jauho: “Inelastic transport theory from firstprinciples:<br />

methodology and applications for nanoscale devices”, Phys. Rev. B 75, 205413<br />

(2007)<br />

atoms: Atoms object The atoms to work on.<br />

indices: list of int List of indices of atoms to vibrate. Default behavior is to vibrate all atoms.<br />

name: str Name to use for files.<br />

delta: float Magnitude of displacements.<br />

nfree: int Number of displacements per atom and cartesian coordinate, 2 and 4 are supported. Default is 2<br />

which will displace each atom +delta and -delta for each cartesian coordinate.<br />

Example:<br />

7.17. Vibration analysis 145


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

>>> from ase import Atoms<br />

>>> from ase.calculators import EMT<br />

>>> from ase.optimize import BFGS<br />

>>> from ase.vibrations import Vibrations<br />

>>> n2 = Atoms(’N2’, [(0, 0, 0), (0, 0, 1.1)],<br />

... calculator=EMT())<br />

>>> BFGS(n2).run(fmax=0.01)<br />

BFGS: 0 16:01:21 0.440339 3.2518<br />

BFGS: 1 16:01:21 0.271928 0.8211<br />

BFGS: 2 16:01:21 0.263278 0.1994<br />

BFGS: 3 16:01:21 0.262777 0.0088<br />

>>> vib = Vibrations(n2)<br />

>>> vib.run()<br />

Writing vib.eq.pckl<br />

Writing vib.0x-.pckl<br />

Writing vib.0x+.pckl<br />

Writing vib.0y-.pckl<br />

Writing vib.0y+.pckl<br />

Writing vib.0z-.pckl<br />

Writing vib.0z+.pckl<br />

Writing vib.1x-.pckl<br />

Writing vib.1x+.pckl<br />

Writing vib.1y-.pckl<br />

Writing vib.1y+.pckl<br />

Writing vib.1z-.pckl<br />

Writing vib.1z+.pckl<br />

>>> vib.summary()<br />

---------------------<br />

# meV cm^-1<br />

---------------------<br />

0 0.0 0.0<br />

1 0.0 0.0<br />

2 0.0 0.0<br />

3 2.5 20.4<br />

4 2.5 20.4<br />

5 152.6 1230.8<br />

---------------------<br />

Zero-point energy: 0.079 eV<br />

>>> vib.write_mode(-1) # write last mode to trajectory file<br />

get_energies(method=’standard’, direction=’central’)<br />

Get vibration energies in eV.<br />

get_frequencies(method=’standard’, direction=’central’)<br />

Get vibration frequencies in cm^-1.<br />

run()<br />

Run the vibration calculations.<br />

This will calculate the forces for 6 displacements per atom +/-x, +/-y, +/-z. Only those calculations<br />

that are not already done will be started. Be aware that an interrupted calculation may produce an<br />

empty file (ending with .pckl), which must be deleted before restarting the job. Otherwise the forces<br />

will not be calculated for that displacement.<br />

Note that the calculations for the different displacements can be done simultaneously by several independent<br />

processes. This feature relies on the existence of files and the subsequent creation of the file<br />

in case it is not found.<br />

summary(method=’standard’, direction=’central’, freq=None, log=)<br />

Print a summary of the vibrational frequencies.<br />

Parameters:<br />

method [string] Can be ‘standard’(default) or ‘Frederiksen’.<br />

146 Chapter 7. Documentation for modules in <strong>ASE</strong>


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

direction: string Direction for finite differences. Can be one of ‘central’ (default), ‘forward’, ‘backward’.<br />

freq [numpy array] Optional. Can be used to create a summary on a set of known frequencies.<br />

log [if specified, write output to a different location than] stdout. Can be an object with a write()<br />

method or the name of a file to create.<br />

write_jmol()<br />

Writes file for viewing of the modes with jmol.<br />

write_mode(n, kT=0.025852157076770025, nimages=30)<br />

Write mode to trajectory file.<br />

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<br />

relaxed ground state or at a saddle point. freeatoms is a list of atom indices for which the vibrational modes will<br />

be calculated, the rest of the atoms are considered frozen. displacements is a list of displacements, one for each<br />

free atom that are used in the finite difference method to calculate the Hessian matrix. method is -1 for backward<br />

differences, 0 for centered differences, and 1 for forward differences.<br />

Warning: Using the dacapo caculator you must make sure that the symmetry program in dacapo finds the<br />

same number of symmetries for the displaced configurations in the vibrational modules as found in the ground<br />

state used as input. This is because the wavefunction is reused from one displacement to the next. One way to<br />

ensure this is to tell dacapo not to use symmetries.<br />

This will show op as a python error ‘Frames are not aligned’. This could be the case for other calculators as<br />

well.<br />

You can get a NetCDF trajectory corresponding to a specific mode by using:<br />

>>> mode=0<br />

>>> vib.create_mode_trajectory(mode=mode,scaling=5)<br />

This will create a NetCDF trajectory file CO_vib_mode_0.traj, corresponding to the highest frequency mode.<br />

scaling is an option argument, that will give the amplitude of the mode, default is 10.<br />

7.18 Phonon calculations<br />

Module for calculating vibrational normal modes for periodic systems using the so-called small displacement<br />

method (see e.g. [Alfe]). So far, space-group symmetries are not exploited to reduce the number of atomic<br />

displacements that must be calculated and subsequent symmetrization of the force constants.<br />

For polar materials the dynamical matrix at the zone center acquires a non-analytical contribution that accounts<br />

for the LO-TO splitting. This contribution requires additional functionality to evaluate and is not included in the<br />

present implementation. Its implementation in conjunction with the small displacement method is described in<br />

[Wang].<br />

7.19 Example<br />

Simple example showing how to calculate the phonon dispersion for bulk aluminum using a 7x7x7 supercell<br />

within effective medium theory:<br />

from ase.structure import bulk<br />

from ase.calculators.emt import EMT<br />

from ase.dft.kpoints import ibz_points, get_bandpath<br />

from ase.phonons import Phonons<br />

# Setup crystal and EMT calculator<br />

atoms = bulk(’Al’, ’fcc’, a=4.05)<br />

calc = EMT()<br />

7.18. Phonon calculations 147


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

# Phonon calculator<br />

N = 7<br />

ph = Phonons(atoms, calc, supercell=(N, N, N), delta=0.05)<br />

ph.run()<br />

# Read forces and assemble the dynamical matrix<br />

ph.read(acoustic=True)<br />

# High-symmetry points in the Brillouin zone<br />

points = ibz_points[’fcc’]<br />

G = points[’Gamma’]<br />

X = points[’X’]<br />

W = points[’W’]<br />

K = points[’K’]<br />

L = points[’L’]<br />

U = points[’U’]<br />

point_names = [’$\Gamma$’, ’X’, ’U’, ’L’, ’$\Gamma$’, ’K’]<br />

path = [G, X, U, L, G, K]<br />

# Band structure in meV<br />

path_kc, q, Q = get_bandpath(path, atoms.cell, 100)<br />

omega_kn = 1000 * ph.band_structure(path_kc)<br />

# Calculate phonon DOS<br />

omega_e, dos_e = ph.dos(kpts=(50, 50, 50), npts=5000, delta=5e-4)<br />

omega_e *= 1000<br />

# Plot the band structure and DOS<br />

import pylab as plt<br />

plt.figure(1, (8, 6))<br />

plt.axes([.1, .07, .67, .85])<br />

for n in range(len(omega_kn[0])):<br />

omega_n = omega_kn[:, n]<br />

plt.plot(q, omega_n, ’k-’, lw=2)<br />

plt.xticks(Q, point_names, fontsize=18)<br />

plt.yticks(fontsize=18)<br />

plt.xlim(q[0], q[-1])<br />

plt.ylabel("Frequency ($\mathrm{meV}$)", fontsize=22)<br />

plt.grid(’on’)<br />

plt.axes([.8, .07, .17, .85])<br />

plt.fill_between(dos_e, omega_e, y2=0, color=’lightgrey’, edgecolor=’k’, lw=1)<br />

plt.ylim(0, 35)<br />

plt.xticks([], [])<br />

plt.yticks([], [])<br />

plt.xlabel("DOS", fontsize=18)<br />

plt.show()<br />

148 Chapter 7. Documentation for modules in <strong>ASE</strong>


Mode inspection using ag:<br />

<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

# Write modes for specific q-vector to trajectory files<br />

ph.write_modes([l/2 for l in L], branches=[2], repeat=(8, 8, 8), kT=3e-4)<br />

7.19. Example 149


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

7.20 Infrared intensities<br />

InfraRed is an extension of Vibrations, in addition to the vibrational modes, also the infrared intensities of<br />

the modes are calculated for an Atoms object.<br />

class ase.infrared.InfraRed(atoms, indices=None, name=’ir’, delta=0.01, nfree=2, directions=None)<br />

Class for calculating vibrational modes and infrared intensities using finite difference.<br />

The vibrational modes are calculated from a finite difference approximation of the Dynamical matrix and<br />

the IR intensities from a finite difference approximation of the gradient of the dipole moment. The method<br />

is described in:<br />

D. Porezag, M. R. Pederson: “Infrared intensities and Raman-scattering activities within densityfunctional<br />

theory”, Phys. Rev. B 54, 7830 (1996)<br />

The calculator object (calc) linked to the Atoms object (atoms) must have the attribute:<br />

>>> calc.get_dipole_moment(atoms)<br />

In addition to the methods included in the Vibrations class the InfraRed class introduces<br />

two new methods; get_spectrum() and write_spectra(). The summary(), get_energies(),<br />

get_frequencies(), get_spectrum() and write_spectra() methods all take an optional method keyword. Use<br />

method=’Frederiksen’ to use the method described in:<br />

T. Frederiksen, M. Paulsson, M. Brandbyge, A. P. Jauho: “Inelastic transport theory from firstprinciples:<br />

methodology and applications for nanoscale devices”, Phys. Rev. B 75, 205413<br />

(2007)<br />

atoms: Atoms object The atoms to work on.<br />

indices: list of int List of indices of atoms to vibrate. Default behavior is to vibrate all atoms.<br />

name: str Name to use for files.<br />

delta: float Magnitude of displacements.<br />

nfree: int Number of displacements per degree of freedom, 2 or 4 are supported. Default is 2 which will<br />

displace each atom +delta and -delta in each cartesian direction.<br />

directions: list of int Cartesian coordinates to calculate the gradient of the dipole moment in. For example<br />

directions = 2 only dipole moment in the z-direction will be considered, whereas for directions = [0,<br />

1] only the dipole moment in the xy-plane will be considered. Default behavior is to use the dipole<br />

moment in all directions.<br />

Example:<br />

>>> from ase.io import read<br />

>>> from ase.calculators.vasp import Vasp<br />

>>> from ase.infrared import InfraRed<br />

>>> water = read(’water.traj’) # read pre-relaxed structure of water molecule<br />

>>> calc = Vasp(prec=’Accurate’,<br />

... ediff=1E-8,<br />

... isym=0,<br />

... idipol=4, # calculate the total dipole moment<br />

... dipol=water.get_center_of_mass(scaled=True),<br />

... ldipol=True)<br />

>>> water.set_calculator(calc)<br />

>>> ir = InfraRed(water)<br />

>>> ir.run()<br />

>>> ir.summary()<br />

-------------------------------------<br />

Mode Frequency Intensity<br />

# meV cm^-1 (D/Å)^2 amu^-1<br />

-------------------------------------<br />

150 Chapter 7. Documentation for modules in <strong>ASE</strong>


0 16.9i 136.2i 1.6108<br />

1 10.5i 84.9i 2.1682<br />

2 5.1i 41.1i 1.7327<br />

3 0.3i 2.2i 0.0080<br />

4 2.4 19.0 0.1186<br />

5 15.3 123.5 1.4956<br />

6 195.5 1576.7 1.6437<br />

7 458.9 3701.3 0.0284<br />

8 473.0 3814.6 1.1812<br />

-------------------------------------<br />

Zero-point energy: 0.573 eV<br />

Static dipole moment: 1.833 D<br />

Maximum force on atom in ‘equilibrium‘: 0.0026 eV/Å<br />

<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

This interface now also works for calculator ‘siesta’, (added get_dipole_moment for siesta).<br />

Example:<br />

>>> #!/usr/bin/env python<br />

>>> from ase.io import read<br />

>>> from ase.calculators.siesta import Siesta<br />

>>> from ase.infrared import InfraRed<br />

>>> bud = read(’bud1.xyz’)<br />

>>> calc = Siesta(label=’bud’,<br />

... meshcutoff=250 * Ry,<br />

... basis=’DZP’,<br />

... kpts=[1, 1, 1])<br />

>>> calc.set_fdf(’DM.MixingWeight’, 0.08)<br />

>>> calc.set_fdf(’DM.NumberPulay’, 3)<br />

>>> calc.set_fdf(’DM.NumberKick’, 20)<br />

>>> calc.set_fdf(’DM.KickMixingWeight’, 0.15)<br />

>>> calc.set_fdf(’SolutionMethod’, ’Diagon’)<br />

>>> calc.set_fdf(’MaxSCFIterations’, 500)<br />

>>> calc.set_fdf(’PAO.BasisType’, ’split’)<br />

>>> #50 meV = 0.003674931 * Ry<br />

>>> calc.set_fdf(’PAO.EnergyShift’, 0.003674931 * Ry )<br />

>>> calc.set_fdf(’LatticeConstant’, 1.000000 * Ang)<br />

>>> calc.set_fdf(’WriteCoorXmol’, ’T’)<br />

>>> bud.set_calculator(calc)<br />

>>> ir = InfraRed(bud)<br />

>>> ir.run()<br />

>>> ir.summary()<br />

get_spectrum(start=800, end=4000, npts=None, width=4, type=’Gaussian’,<br />

method=’standard’, direction=’central’, intensity_unit=’(D/A)2/amu’, normalize=False)<br />

Get infrared spectrum.<br />

The method returns wavenumbers in cm^-1 with corresponding absolute infrared intensity. Start and<br />

end point, and width of the Gaussian/Lorentzian should be given in cm^-1. normalize=True ensures<br />

the integral over the peaks to give the intensity.<br />

write_spectra(out=’ir-spectra.dat’, start=800, end=4000, npts=None, width=10,<br />

type=’Gaussian’, method=’standard’, direction=’central’, intensity_unit=’(D/A)2/amu’,<br />

normalize=False)<br />

Write out infrared spectrum to file.<br />

First column is the wavenumber in cm^-1, the second column the absolute infrared intensities, and the<br />

7.20. Infrared intensities 151


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

third column the absorbance scaled so that data runs from 1 to 0. Start and end point, and width of the<br />

Gaussian/Lorentzian should be given in cm^-1.<br />

7.21 Molecular dynamics<br />

Typical computer simulations involve moving the atoms around, either to optimize a structure (energy minimization)<br />

or to do molecular dynamics. This chapter discusses molecular dynamics, energy minimization algorithms<br />

will be discussed in the optimize section.<br />

A molecular dynamics object will operate on the atoms by moving them according to their forces - it integrates<br />

Newton’s second law numerically. A typical molecular dynamics simulation will use the Velocity Verlet dynamics.<br />

You create the VelocityVerlet object, giving it the atoms and a time step, and then you perform dynamics<br />

by calling its run() method:<br />

dyn = VelocityVerlet(atoms, 5.0 * units.fs)<br />

dyn.run(1000) # take 1000 steps<br />

A number of different algorithms can be used to perform molecular dynamics, with slightly different results.<br />

7.21.1 Choosing the time step<br />

All the dynamics objects need a time step. Choosing it too small will waste computer time, choosing it too large<br />

will make the dynamics unstable, typically the energy increases dramatically (the system “blows up”). If the time<br />

step is only a little to large, the lack of energy conservation is most obvious in Velocity Verlet dynamics, where<br />

energy should otherwise be conserved.<br />

Experience has shown that 5 femtoseconds is a good choice for most metallic systems. Systems with light atoms<br />

(e.g. hydrogen) and/or with strong bonds (carbon) will need a smaller time step.<br />

All the dynamics objects documented here are sufficiently related to have the same optimal time step.<br />

7.21.2 File output<br />

The time evolution of the system can be saved in a trajectory file, by creating a trajectory object, and attaching it<br />

to the dynamics object. This is documented in the module ase.io.trajectory.<br />

Unlike the geometry optimization classes, the molecular dynamics classes do not support giving a trajectory file<br />

name in the constructor. Instead the trajectory must be attached explicitly to the dynamics, and it is stongly<br />

recommended to use the optional interval argument, so every time step is not written to the file.<br />

7.21.3 Logging<br />

A logging mechanism is provided, printing time; total, potential and kinetic energy; and temperature (calculated<br />

from the kinetic energy). It is enabled by giving the logfile argument when the dynamics object is created,<br />

logfile may be an open file, a filename or the string ‘-‘ meaning standard output. Per default, a line is printed<br />

for each timestep, specifying the loginterval argument will chance this to a more reasonable frequency.<br />

The logging can be customized by explicitly attaching a ase.md.MDLogger object to the dynamics:<br />

from ase.md import MDLogger<br />

dyn = VelocityVerlet(atoms, dt=2*ase.units.fs)<br />

dyn.attach(MDLogger(dyn, atoms, ’md.log’, header=False, stress=False,<br />

peratom=True, mode="a"), interval=1000)<br />

This example will skip the header line and write energies per atom instead of total energies. The parameters are<br />

152 Chapter 7. Documentation for modules in <strong>ASE</strong>


header: Print a header line defining the columns.<br />

stress: Print the six components of the stress tensor.<br />

peratom: Print energy per atom instead of total energy.<br />

mode: If ‘a’, append to existing file, if ‘w’ overwrite existing file.<br />

<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

Despite appearances, attaching a logger like this does not create a cyclic reference to the dynamics.<br />

Note: If building your own logging class, be sure not to attach the dynamics object directly to the logging object.<br />

Instead, create a weak reference using the proxy method of the weakref package. See the ase.md.MDLogger<br />

source code for an example. (If this is not done, a cyclic reference may be created which can cause certain<br />

calculators, such as Jacapo, to not terminate correctly.)<br />

7.21.4 Constant NVE simulations (the microcanonical ensemble)<br />

Newton’s second law preserves the total energy of the system, and a straightforward integration of Newton’s<br />

second law therefore leads to simulations preserving the total energy of the system (E), the number of atoms (N)<br />

and the volume of the system (V). The most appropriate algorithm for doing this is velocity Verlet dynamics, since<br />

it gives very good long-term stability of the total energy even with quite large time steps. Fancier algorithms such<br />

as Runge-Kutta may give very good short-term energy preservation, but at the price of a slow drift in energy over<br />

longer timescales, causing trouble for long simulations.<br />

In a typical NVE simulation, the temperature will remain approximately constant, but if significant structural<br />

changes occurs they may result in temperature changes. If external work is done on the system, the temperature is<br />

likely to rise significantly.<br />

Velocity Verlet dynamics<br />

class md.verlet.VelocityVerlet(atoms, timestep)<br />

VelocityVerlet is the only dynamics implementing the NVE ensemble. It requires two arguments, the atoms<br />

and the time step. Choosing a too large time step will immediately be obvious, as the energy will increase with<br />

time, often very rapidly.<br />

Example: See the tutorial Molecular dynamics.<br />

7.21.5 Constant NVT simulations (the canonical ensemble)<br />

Since Newton’s second law conserves energy and not temperature, simulations at constant temperature will somehow<br />

involve coupling the system to a heat bath. This cannot help being somewhat artificial. Two different approaches<br />

are possible within <strong>ASE</strong>. In Langevin dynamics, each atom is coupled to a heat bath through a fluctuating<br />

force and a friction term. In Nosé-Hoover dynamics, a term representing the heat bath through a single degree of<br />

freedom is introduced into the Hamiltonian.<br />

Langevin dynamics<br />

class md.langevin.Langevin(atoms, timestep, temperature, friction)<br />

The Langevin class implements Langevin dynamics, where a (small) friction term and a fluctuating force are added<br />

to Newton’s second law which is then integrated numerically. The temperature of the heat bath and magnitude of<br />

the friction is specified by the user, the amplitude of the fluctuating force is then calculated to give that temperature.<br />

This procedure has some physical justification: in a real metal the atoms are (weakly) coupled to the electron gas,<br />

and the electron gas therefore acts like a heat bath for the atoms. If heat is produced locally, the atoms locally<br />

get a temperature that is higher than the temperature of the electrons, heat is transferred to the electrons and then<br />

rapidly transported away by them. A Langevin equation is probably a reasonable model for this process.<br />

7.21. Molecular dynamics 153


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

A disadvantage of using Langevin dynamics is that if significant heat is produced in the simulation, then the<br />

temperature will stabilize at a value higher than the specified temperature of the heat bath, since a temperature<br />

difference between the system and the heat bath is necessary to get a finite heat flow. Another disadvantage is that<br />

the fluctuating force is stochastic in nature, so repeating the simulation will not give exactly the same trajectory.<br />

When the Langevin object is created, you must specify a time step, a temperature (in energy units) and a friction.<br />

Typical values for the friction are 0.01-0.02 atomic units.<br />

# Room temperature simulation<br />

dyn = Langevin(atoms, 5 * units.fs, units.kB * 300, 0.002)<br />

Both the friction and the temperature can be replaced with arrays giving per-atom values. This is mostly useful<br />

for the friction, where one can choose a rather high friction near the boundaries, and set it to zero in the part of the<br />

system where the phenomenon being studied is located.<br />

Nosé-Hoover dynamics<br />

In Nosé-Hoover dynamics, an extra term is added to the Hamiltonian representing the coupling to the heat bath.<br />

From a pragmatic point of view one can regard Nosé-Hoover dynamics as adding a friction term to Newton’s<br />

second law, but dynamically changing the friction coefficient to move the system towards the desired temperature.<br />

Typically the “friction coefficient” will fluctuate around zero.<br />

Nosé-Hoover dynamics is not implemented as a separate class, but is a special case of NPT dynamics.<br />

Berendsen NVT dynamics<br />

class md.nvtberendsen.NVTBerendsen(atoms, timestep, temperature, taut, fixcm)<br />

In Berendsen NVT simulations the velocities are scaled to achieve the desired temperature. The speed of the<br />

scaling is determined by the parameter taut.<br />

This method does not result proper NVT sampling but it usually is sufficiently good in practise (with large taut).<br />

For discussion see the gromacs manual at www.gromacs.org.<br />

atoms: The list of atoms.<br />

timestep: The time step.<br />

temperature: The desired temperature, in Kelvin.<br />

taut: Time constant for Berendsen temperature coupling.<br />

fixcm: If True, the position and momentum of the center of mass is kept unperturbed. Default: True.<br />

# Room temperature simulation (300K, 0.1 fs time step)<br />

dyn = NVTBerendsen(atoms, 0.1 * units.fs, 300, taut=0.5*1000*units.fs)<br />

7.21.6 Constant NPT simulations (the isothermal-isobaric ensemble)<br />

class md.npt.NPT(atoms, timestep, temperature, externalstress, ttime, pfactor, mask=None)<br />

Dynamics with constant pressure (or optionally, constant stress) and constant temperature (NPT or N,stress,T<br />

ensemble). It uses the combination of Nosé-Hoover and Parrinello-Rahman dynamics proposed by Melchionna et<br />

al. [1] and later modified by Melchionna [2]. The differential equations are integrated using a centered difference<br />

method [3]. Details of the implementation are available in the document XXX NPTdynamics.tex, distributed with<br />

the module.<br />

The dynamics object is called with the following parameters:<br />

atoms: The atoms object.<br />

timestep: The timestep in units matching eV, Å, u. Use the units.fs constant.<br />

temperature: The desired temperature in eV.<br />

154 Chapter 7. Documentation for modules in <strong>ASE</strong>


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

externalstress: The external stress in eV/Å^3. Either a symmetric 3x3 tensor, a 6-vector representing the same, or<br />

a scalar representing the pressure. Note that the stress is positive in tension whereas the pressure is positive<br />

in compression: giving a scalar p is equivalent to giving the tensor (-p. -p, -p, 0, 0, 0).<br />

ttime: Characteristic timescale of the thermostat. Set to None to disable the thermostat.<br />

pfactor: A constant in the barostat differential equation. If a characteristic barostat timescale of ptime is desired,<br />

set pfactor to ptime^2 * B (where B is the Bulk Modulus). Set to None to disable the barostat. Typical<br />

metallic bulk moduli are of the order of 100 GPa or 0.6 eV/Å^3.<br />

mask=None: Optional argument. A tuple of three integers (0 or 1), indicating if the system can change size along<br />

the three Cartesian axes. Set to (1,1,1) or None to allow a fully flexible computational box. Set to (1,1,0) to<br />

disallow elongations along the z-axis etc.<br />

Useful parameter values:<br />

• The same timestep can be used as in Verlet dynamics, i.e. 5 fs is fine for bulk copper.<br />

• The ttime and pfactor are quite critical[4], too small values may cause instabilites and/or wrong fluctuations<br />

in T / p. Too large values cause an oscillation which is slow to die. Good values for the characteristic<br />

times seem to be 25 fs for ttime, and 75 fs for ptime (used to calculate pfactor), at least for bulk copper<br />

with 15000-200000 atoms. But this is not well tested, it is IMPORTANT to monitor the temperature and<br />

stress/pressure fluctuations.<br />

It has the following methods:<br />

NPT.run(n):<br />

Perform n timesteps.<br />

NPT.initialize():<br />

Estimates the dynamic variables for time=-1 to start the algorithm. This is automatically called before the<br />

first timestep.<br />

NPT.set_stress():<br />

Set the external stress. Use with care. It is preferable to set the right value when creating the object.<br />

NPT.set_mask():<br />

Change the mask. Use with care, as you may “freeze” a fluctuation in the strain rate.<br />

NPT.set_strainrate(eps):<br />

Set the strain rate. eps must be an upper-triangular matrix. If you set a strain rate along a direction that is<br />

“masked out” (see set_mask), the strain rate along that direction will be maintained constantly.<br />

NPT.get_gibbs_free_energy():<br />

Gibbs free energy is supposed to be preserved by this dynamics. This is mainly intended as a diagnostic<br />

tool.<br />

References:<br />

[1] S. Melchionna, G. Ciccotti and B. L. Holian, Molecular Physics 78, p. 533 (1993).<br />

[2] S. Melchionna, Physical Review E 61, p. 6165 (2000).<br />

[3] B. L. Holian, A. J. De Groot, W. G. Hoover, and C. G. Hoover, Physical Review A 41, p. 4552 (1990).<br />

[4] F. D. Di Tolla and M. Ronchetti, Physical Review E 48, p. 1726 (1993).<br />

See Also:<br />

The API documentation: md<br />

Berendsen NPT dynamics<br />

class md.nptberendsen.NPTBerendsen(atoms, timestep, temperature, taut, fixcm, pressure, taup,<br />

compressibility)<br />

7.21. Molecular dynamics 155


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

In Berendsen NPT simulations the velocities are scaled to achieve the desired temperature. The speed of the<br />

scaling is determined by the parameter taut.<br />

The atom positions and the simulation cell are scaled in order to achieve the desired pressure.<br />

This method does not result proper NPT sampling but it usually is sufficiently good in practise (with large taut and<br />

taup). For discussion see the gromacs manual at www.gromacs.org. or amber at ambermd.org<br />

atoms: The list of atoms.<br />

timestep: The time step.<br />

temperature: The desired temperature, in Kelvin.<br />

taut: Time constant for Berendsen temperature coupling.<br />

fixcm: If True, the position and momentum of the center of mass is kept unperturbed. Default: True.<br />

pressure: The desired pressure, in bar (1 bar = 1e5 Pa).<br />

taup: Time constant for Berendsen pressure coupling.<br />

compressibility: The compressibility of the material, water 4.57E-5 bar-1, in bar-1<br />

# Room temperature simulation (300K, 0.1 fs time step, atmospheric pressure)<br />

dyn = NPTBerendsen(atoms, timestep=0.1*units.fs, temperature=300,<br />

taut=0.1*1000*units.fs, pressure = 1.01325,<br />

taup=1.0*1000*units.fs, compressibility=4.57e-5)<br />

7.22 Density Functional Theory<br />

7.22.1 Brillouin zone sampling<br />

The k-points are always given relative to the basis vectors of the reciprocal unit cell.<br />

Monkhorst-Pack<br />

ase.dft.kpoints.monkhorst_pack(size)<br />

Construct a uniform sampling of k-space of given size.<br />

The k-points are given as [MonkhorstPack]:<br />

�<br />

i=1,2,3<br />

2ni − Ni − 1<br />

bi,<br />

2Ni<br />

where ni = 1, 2, ..., Ni, size = (N1, N2, N3) and the bi‘s are reciprocal lattice vectors.<br />

ase.dft.kpoints.get_monkhorst_pack_size_and_offset(kpts)<br />

Find Monkhorst-Pack size and offset.<br />

Example:<br />

Returns (size, offset), where:<br />

kpts = monkhorst_pack(size) + offset.<br />

The set of k-points must not have been symmetry reduced.<br />

>>> from ase.dft.kpoints import *<br />

>>> monkhorst_pack((4, 1, 1))<br />

array([[-0.375, 0. , 0. ],<br />

[-0.125, 0. , 0. ],<br />

[ 0.125, 0. , 0. ],<br />

[ 0.375, 0. , 0. ]])<br />

156 Chapter 7. Documentation for modules in <strong>ASE</strong>


get_monkhorst_pack_size_and_offset([[0, 0, 0]])<br />

(array([1, 1, 1]), array([ 0., 0., 0.]))<br />

Chadi-Cohen<br />

Predefined sets of k-points:<br />

dft.kpoints.cc6_1x1<br />

dft.kpoints.cc12_2x3<br />

dft.kpoints.cc18_sq3xsq3<br />

dft.kpoints.cc18_1x1<br />

dft.kpoints.cc54_sq3xsq3<br />

dft.kpoints.cc54_1x1<br />

dft.kpoints.cc162_sq3xsq3<br />

dft.kpoints.cc162_1x1<br />

Naming convention: cc18_sq3xsq3 is 18 k-points for a sq(3)xsq(3) cell.<br />

Try this:<br />

>>> import numpy as np<br />

>>> import pylab as plt<br />

>>> from ase.dft.kpoints import cc162_1x1<br />

>>> B = [(1, 0, 0), (-0.5, 3**0.5 / 2, 0), (0, 0, 1)]<br />

>>> k = np.dot(cc162_1x1, B)<br />

>>> plt.plot(k[:, 0], k[:, 1], ’o’)<br />

[]<br />

>>> p.show()<br />

<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

7.22. Density Functional Theory 157


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

7.22.2 Maximally localized Wannier functions<br />

This page describes how to construct the Wannier orbitals using the class Wannier. The page is organized as<br />

follows:<br />

• Introduction: A short summary of the basic theory.<br />

• The Wannier class : A description of how the Wannier class is used, and the methods defined within.<br />

Introduction<br />

The point of Wannier functions is the transform the extended Bloch eigenstates of a DFT calculation, into a smaller<br />

set of states designed to facilitate the analysis of e.g. chemical bonding. This is achived by designing the Wannier<br />

functions to be localized in real space instead of energy (which would be the eigen states).<br />

The standard Wannier transformation is a unitary rotation of the Bloch states. This implies that the Wannier<br />

functions (WF) span the same Hilbert space as the Bloch states, i.e. they have the same eigenvalue spectrum,<br />

and the original Bloch states can all be exactly reproduced from a linear combination of the WF. For maximally<br />

localized Wannier functions (MLWF), the unitary transformation is chosen such that the spread of the resulting<br />

WF is minimized.<br />

The standard choice is to make a unitary transformation of the occupied bands only, thus resulting in as many WF<br />

as there are occupied bands. If you make a rotation using more bands, the localization will be improved, but the<br />

number of wannier functions increase, thus making orbital based analysis harder.<br />

The class defined here allows for construction of partly occupied MLWF. In this scheme the transformation is still<br />

a unitary rotation for the lowest states (the fixed space), but it uses a dynamically optimized linear combination<br />

of the remaining orbitals (the active space) to improve localization. This implies that e.g. the eigenvalues of<br />

the Bloch states contained in the fixed space can be exactly reproduced by the resulting WF, whereas the largest<br />

eigenvalues of the WF will not necessarily correspond to any “real” eigenvalues (this is irrelevant, as the fixed<br />

space is usually chosen large enough, i.e. high enough above the fermilevel, that the remaining DFT eigenvalues<br />

are meaningless anyway).<br />

For the theory behind this method see the paper “Partly Occupied Wannier Functions” Thygesen, Hansen and<br />

Jacobsen, Phys. Rev. Lett, Vol. 94, 26405 (2005).<br />

The Wannier class<br />

Usual invocation:<br />

from ase.dft import Wannier<br />

wan = Wannier(nwannier=18, calc=GPAW(’save.gpw’), fixedstates=15)<br />

wan.localize() # Optimize rotation to give maximal localization<br />

wan.save(’file.pickle’) # Save localization and rotation matrix<br />

# Re-load using saved wannier data<br />

wan = Wannier(nwannier=18, calc=calc, fixedstates=15, file=’file.pickle’)<br />

# Write a cube file<br />

wan.write_cube(index=5, fname=’wannierfunction5.cube’)<br />

For examples of how to use the Wannier class, see the Wannier tutorial.<br />

class ase.dft.wannier.Wannier(nwannier, calc, file=None, nbands=None, fixedenergy=None,<br />

fixedstates=None, spin=0, initialwannier=’random’, seed=None,<br />

verbose=False)<br />

Maximally localized Wannier Functions<br />

Find the set of maximally localized Wannier functions using the spread functional of Marzari and Vanderbilt<br />

(PRB 56, 1997 page 12847).<br />

Required arguments:<br />

158 Chapter 7. Documentation for modules in <strong>ASE</strong>


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

nwannier: The number of Wannier functions you wish to construct. This must be at least<br />

half the number of electrons in the system and at most equal to the number of bands in the<br />

calculation.<br />

calc: A converged DFT calculator class. If file arg. is not provided, the calculator must<br />

provide the method get_wannier_localization_matrix, and contain the wavefunctions<br />

(save files with only the density is not enough). If the localization matrix is read<br />

from file, this is not needed, unless get_function or write_cube is called.<br />

Optional arguments:<br />

nbands: Bands to include in localization. The number of bands considered by Wannier can<br />

be smaller than the number of bands in the calculator. This is useful if the highest bands of<br />

the DFT calculation are not well converged.<br />

spin: The spin channel to be considered. The Wannier code treats each spin channel independently.<br />

fixedenergy / fixedstates: Fixed part of Heilbert space. Determine the fixed part of<br />

Hilbert space by either a maximal energy or a number of bands (possibly a list for multiple<br />

k-points). Default is None meaning that the number of fixed states is equated to nwannier.<br />

file: Read localization and rotation matrices from this file.<br />

initialwannier: Initial guess for Wannier rotation matrix. Can be ‘bloch’ to start from<br />

the Bloch states, ‘random’ to be randomized, or a list passed to calc.get_initial_wannier.<br />

seed: Seed for random initialwannier.<br />

verbose: True / False level of verbosity.<br />

get_centers(scaled=False)<br />

Calculate the Wannier centers<br />

pos = L / 2pi * phase(diag(Z))<br />

get_function(index, repeat=None)<br />

Get Wannier function on grid.<br />

Returns an array with the funcion values of the indicated Wannier function on a grid with the size of<br />

the repeated unit cell.<br />

For a calculation using k-points the relevant unit cell for eg. visualization of the Wannier orbitals is<br />

not the original unit cell, but rather a larger unit cell defined by repeating the original unit cell by the<br />

number of k-points in each direction. Note that for a Γ-point calculation the large unit cell coinsides<br />

with the original unit cell. The large unitcell also defines the periodicity of the Wannier orbitals.<br />

index can be either a single WF or a coordinate vector in terms of the WFs.<br />

get_functional_value()<br />

Calculate the value of the spread functional.<br />

Tr[|ZI|^2]=sum(I)sum(n) w_i|Z_(i)_nn|^2,<br />

where w_i are weights.<br />

get_hamiltonian(k=0)<br />

Get Hamiltonian at existing k-vector of index k<br />

dag<br />

H(k) = V diag(eps ) V<br />

k k k<br />

get_hamiltonian_kpoint(kpt_c)<br />

Get Hamiltonian at some new arbitrary k-vector<br />

7.22. Density Functional Theory 159


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

_ ik.R<br />

H(k) = >_ e H(R)<br />

R<br />

Warning: This method moves all Wannier functions to cell (0, 0, 0)<br />

get_hopping(R)<br />

Returns the matrix H(R)_nm=.<br />

1 _ -ik.R<br />

H(R) = = --- >_ e H(k)<br />

Nk k<br />

where R is the cell-distance (in units of the basis vectors of the small cell) and n,m are indices of the<br />

Wannier functions.<br />

get_pdos(w, energies, width)<br />

Projected density of states (PDOS).<br />

Returns the (PDOS) for Wannier function w. The calculation is performed over the energy grid specified<br />

in energies. The PDOS is produced as a sum of Gaussians centered at the points of the energy<br />

grid and with the specified width.<br />

get_radii()<br />

Calculate the spread of the Wannier functions.<br />

-- / L \ 2 2<br />

radius**2 = - > | --- | ln |Z|<br />

--d \ 2pi /<br />

initialize(file=None, initialwannier=’random’, seed=None)<br />

Re-initialize current rotation matrix.<br />

Keywords are identical to those of the constructor.<br />

localize(step=0.25, tolerance=1e-08, updaterot=True, updatecoeff=True)<br />

Optimize rotation to give maximal localization<br />

max_spread(directions=[0, 1, 2])<br />

Returns the index of the most delocalized Wannier function together with the value of the spread<br />

functional<br />

save(file)<br />

Save information on localization and rotation matrices to file.<br />

translate(w, R)<br />

Translate the w’th Wannier function<br />

The distance vector R = [n1, n2, n3], is in units of the basis vectors of the small cell.<br />

translate_all_to_cell(cell=[0, 0, 0])<br />

Translate all Wannier functions to specified cell.<br />

Move all Wannier orbitals to a specific unit cell. There exists an arbitrariness in the positions of the<br />

Wannier orbitals relative to the unit cell. This method can move all orbitals to the unit cell specified<br />

by cell. For a Γ-point calculation, this has no effect. For a k-point calculation the periodicity of<br />

the orbitals are given by the large unit cell defined by repeating the original unitcell by the number<br />

of k-points in each direction. In this case it is usefull to move the orbitals away from the boundaries<br />

of the large cell before plotting them. For a bulk calculation with, say 10x10x10 k points, one could<br />

move the orbitals to the cell [2,2,2]. In this way the pbc boundary conditions will not be noticed.<br />

translate_to_cell(w, cell)<br />

Translate the w’th Wannier function to specified cell<br />

write_cube(index, fname, repeat=None, real=True)<br />

Dump specified Wannier function to a cube file<br />

160 Chapter 7. Documentation for modules in <strong>ASE</strong>


In Dacapo, the inialwannier keyword can be a list as described below:<br />

<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

Setup an initial set of Wannier orbitals. initialwannier can set up a starting guess for the Wannier<br />

functions. This is important to speed up convergence in particular for large systems For transition<br />

elements with d electrons you will always find 5 highly localized d-orbitals centered at the atom.<br />

Placing 5 d-like orbitals with a radius of 0.4 Angstroms and center at atom no. 7, and 3 p-like orbitals<br />

with a radius of 0.4 Angstroms and center at atom no. 27 looks like this:<br />

initialwannier = [[[7],2,0.4],[[27],1,0.4]]<br />

Placing only the l=2, m=-2 and m=-1 orbitals at atom no. 7 looks like this:<br />

initialwannier = [[[7],2,-2,0.4],[[7],2,-1,0.4]]<br />

I.e. if you do not specify the m quantum number all allowed values are used. Instead of placing an<br />

orbital at an atom, you can place it at a specified position. For example the following:<br />

initialwannier = [[[0.5,0.5,0.5],0,0.5]]<br />

places an s orbital with radius 0.5 Angstroms at the position (0.5, 0.5, 0.5) in scaled coordinates of<br />

the unit cell.<br />

Note: For calculations using k-points, make sure that the Γ-point is included in the k-point grid. The Wannier<br />

module does not support k-point reduction by symmetry, so you must use the usesymm=False keyword in the<br />

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<br />

the calculation. If this is not done the symmetry program will still use time-reversal symmetry to reduce the<br />

number of k-points by a factor 2. The shift can be performed like this:<br />

from ase import *<br />

kpts = monkhorst_pack((15, 9, 9)) + [2e-5, 0, 0]<br />

7.22.3 Density of states<br />

Example:<br />

calc = ...<br />

dos = DOS(calc, width=0.2)<br />

d = dos.get_dos()<br />

e = dos.get_energies()<br />

You can plot the result like this:<br />

import pylab as plt<br />

plt.plot(e, d)<br />

plt.xlabel(’energy [eV]’)<br />

plt.ylabel(’DOS’)<br />

plt.show()<br />

7.22. Density Functional Theory 161


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

Calculations involving moments of a DOS distribution may be facilitated by the use of<br />

get_distribution_moment() method, as in the following example:<br />

from ase.dft import get_distribution_moment<br />

volume = get_distribution_moment(e,d)<br />

center, width = get_distribution_moment(e,d,(1,2))<br />

More details<br />

class ase.dft.dos.DOS(calc, width=0.1, window=None, npts=201)<br />

Electronic Density Of States object.<br />

calc: calculator object Any <strong>ASE</strong> compliant calculator object.<br />

width: float Width of guassian smearing.<br />

window: tuple of two float Use window=(emin, emax). If not specified, a window big enough to<br />

hold all the eigenvalues will be used.<br />

npts: int Number of points.<br />

get_energies()<br />

Return the array of energies used to sample the DOS. The energies are reported relative to the Fermi<br />

level.<br />

get_dos(spin=None)<br />

Get array of DOS values.<br />

The spin argument can be 0 or 1 (spin up or down) - if not specified, the total DOS is returned.<br />

ase.dft.get_distribution_moment(x, y, order=0)<br />

Return the moment of nth order of distribution.<br />

1st and 2nd order moments of a band correspond to the band’s center and width respectively.<br />

For integration, the trapezoid rule is used.<br />

XXX This page needs more work!<br />

162 Chapter 7. Documentation for modules in <strong>ASE</strong>


7.22.4 STMTool<br />

The STMTool class generates Tersoff-Hamann STM topographs.<br />

<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

Here is how you could make a STM picture from the GPAW code, assuming you have allready generated the the<br />

Al100.gpw GPAW restart file, (see the STM tutorial for a full description):<br />

>>> from <strong>ASE</strong>.Utilities.ElectronicStates import ElectronicStates<br />

>>> from <strong>ASE</strong>.Utilities.STMTool import STMTool<br />

>>> from <strong>ASE</strong>.Visualization.VTK import VTKPlotSTM<br />

>>> loe = ElectronicStates(filename = ’Al100.gpw’)<br />

>>> stm = STMTool(loe,contourvalue=1.0e-4, channel="s",<br />

... normalaxis=2, smoothfactor=0.1) # available channels: s,px,py,pz<br />

>>> stmplot = VTKPlotSTM(stm)<br />

>>> stmplot.set_color_range((3.325,3.55)) # from surface span color range<br />

>>> stmplot.render() # updates picture<br />

From the planewave code dacapo, the dacapo codes own version of the ElectronicStates class must be used:<br />

>>> from Dacapo.ElectronicStates import ElectronicStates<br />

>>> from <strong>ASE</strong>.Utilities.STMTool import STMTool<br />

>>> from <strong>ASE</strong>.Visualization.VTK import VTKPlotSTM<br />

>>> loe = ElectronicStates(filename=’Al100.nc’)<br />

From this point the code is identical to the example above.<br />

The list of keywords for the STMTool object is:<br />

listofeigenstates The ElectronicStates object holding information about each eigenstate of the<br />

slab.<br />

contourvalue The density of states at the Fermi level for which the topograph is generated. This argument is<br />

mandatory, as no universal (simple) default is natural. Often used values are [1.0e-6 - 1.0e-3], but is very<br />

system dependent.<br />

channel Selects whether the topograph is generated by the value or gradient isosurface of the Fermi level DOS.<br />

This adjusts for the orbital character of the DOS of the actual STM tip in the probing energy window, i.e.<br />

the STM tip states that couples to the substrate. Available options are “s”, “px”, “py” and “pz”. Default is<br />

“s”.<br />

normalaxis The surface normal direction, (0,1,2) for (x,y,z) respectively. normalaxis = 2 is default.<br />

smoothfactor The thermal convolution applied to the slab states. It is necessary to apply this due to finite<br />

k-point sampling.<br />

7.22.5 STM linescans<br />

The class ST MLineScan can be used to simulate an STM linescan. It must be initialized with an instance of the<br />

STMTool class.<br />

Note that the linescans are limited to be along one of the axis of the unit cell. The origin of the linescan can only<br />

assume discrete values corresponding to the FFT grid.<br />

The class is used like:<br />

linescan = STMLineScan(stm,fftnumber=12,axis=1)<br />

See more details in the linescansection of the ST Mtutorial.<br />

7.22. Density Functional Theory 163


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

7.22.6 Bader Analysis<br />

Henkelman et. al have implemented a fast and robust algorithm for calculating the electronic charges on individual<br />

atoms in molecules or crystals, based on the Bader partitioning scheme [Bader]. In that method, the<br />

analysis is based purely on the electron density. The partitioning of the density is determined according to its<br />

zero-flux surfaces. Details of their implementation can be found in [Tang]. The program is freely available at<br />

http://theory.cm.utexas.edu/henkelman/research/bader/ where you will also find a description of the method.<br />

The algorithm is very well suited for large solid state physical systems, as well as large biomolecular systems.<br />

The computational time depends only on the size of the 3D grid used to represent the electron density, and scales<br />

linearly with the total number of grid points. As the accuracy of the method depends on the grid spacing, it is<br />

recommended to check for convergnce in this parameter (which should usually by smaller than the default value).<br />

The program takes cube input files. It does not support units, and assumes atomic units for the density (Bohr^-3).<br />

All ase dft calculators have a get_pseudo_density method, which can be used to get the density. A simple<br />

python script for making a cube file, ready for the Bader program, could be:<br />

>>> from ase import *<br />

>>> density = calc.get_pseudo_density() * Bohr**3<br />

>>> write(’filename.cube’, atoms, data=density)<br />

Some calculators (e.g. gpaw) also have a method called get_all_electron_density, in which case this is<br />

preferable to get_pseudo_density.<br />

Note that it is strongly recommended to use version 0.26b or higher of the program, and the examples below refer<br />

to this version.<br />

Example: The water molecule<br />

The following example shows how to do Bader analysis for a water molecule.<br />

First do a ground state calculation, and save the density as a cube file:<br />

from ase import *<br />

from gpaw import *<br />

atoms = molecule(’H2O’, cell=[7.5, 9, 9], calculator=GPAW(h=.17, xc=’PBE’))<br />

atoms.center()<br />

atoms.get_potential_energy()<br />

rho = atoms.calc.get_all_electron_density(gridrefinement=4) * Bohr**3<br />

write(’water_density.cube’, atoms, data=rho)<br />

Then analyse the density cube file by running (use bader -h for a description of the possible options):<br />

$ bader -p all_atom -p atom_index water_density.cube<br />

This will produce a number of files. The ACF.dat file, contains a summary of the Bader analysis:<br />

| # X Y Z CHARGE MIN DIST<br />

| -----------------------------------------------------------------<br />

| 1 7.0865 8.5038 9.0672 9.1121 1.3250<br />

| 2 7.0865 9.9461 7.9403 0.4440 0.2834<br />

| 3 7.0865 7.0615 7.9403 0.4440 0.2834<br />

| -----------------------------------------------------------------<br />

| NUMBER OF ELECTRONS: 9.99999<br />

Revealing that 0.56 electrons have been transfered from each Hydrogen atom to the Oxygen atom.<br />

The BvAtxxxx.dat files, are cube files for each Bader volume, describing the density within that volume. (I.e. it is<br />

just the original cube file, truncated to zero outside the domain of the specific Bader volume).<br />

AtIndex.dat is a cube file with an integer value at each grid point, describing which Bader volume it belongs to.<br />

164 Chapter 7. Documentation for modules in <strong>ASE</strong>


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

The plot below shows the dividing surfaces of the Hydrogen Bader volumes. This was achieved by plotting a<br />

contour surface of AtIndex.dat at an isovalue of 1.5.<br />

You can attach the output charges from the bader program to the atoms for further processing:<br />

from ase import *<br />

from ase.io.bader import attach_charges<br />

# define the molecule as above<br />

atoms = molecule(’H2O’)<br />

atoms.set_cell([7.5, 9, 9])<br />

atoms.center()<br />

# the next two lines are equivalent (only one needed)<br />

attach_charges(atoms)<br />

attach_charges(atoms, ’ACF.dat’)<br />

for atom in atoms:<br />

print ’Atom’, atom.symbol, ’Bader charge’, atom.charge<br />

7.23 Electron transport<br />

The transport module of <strong>ASE</strong> assumes the generic setup of the system in question sketched below:<br />

. . .<br />

. . .<br />

7.23. Electron transport 165


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

There is a central region (blue atoms plus the molecule) connected to two semi-infinite leads constructed by<br />

infinitely repeated principal layers (red atoms). The entire structure may be periodic in the transverse direction,<br />

which can be effectively sampled using k-points (yellowish atoms).<br />

The system is described by a Hamiltonian matrix which must be represented in terms of a localized basis set such<br />

that each element of the Hamiltonian can be ascribed to either the left, central, or right region, or the coupling<br />

between these.<br />

The Hamiltonian can thus be decomposed as:<br />

⎛<br />

. ..<br />

⎜ VL<br />

⎜<br />

⎜V<br />

⎜<br />

H = ⎜<br />

⎝<br />

†<br />

L HL VL<br />

V †<br />

L HC VR<br />

V †<br />

R HR VR<br />

V †<br />

R<br />

⎞<br />

⎟<br />

⎠<br />

. ..<br />

where H L/R describes the left/right principal layer, and HC the central region. V L/R is the coupling between<br />

principal layers, and from the principal layers into the central region. The central region must contain at least one<br />

principal layer on each side, and more if the potential has not converged to its bulk value at this size. The central<br />

region is assumed to be big enough that there is no direct coupling between the two leads. The principal layer<br />

must be so big that there is only coupling between nearest neighbor layers.<br />

Having defined H L/R, V L/R, and HC, the elastic transmission function can be determined using the Nonequilibrium<br />

Green Function (NEGF) method. This is achieved by the class: TransportCalculator (in<br />

ase.transport.calculators) which makes no requirement on the origin of these five matrices.<br />

class ase.transport.calculators.TransportCalculator(energies, h, h1, h2,<br />

s=None, s1=None, s2=None,<br />

align_bf=False)<br />

Determine transport properties of device sandwiched between semi-infinite leads using nonequillibrium<br />

Green function methods.<br />

energies is the energy grid on which the transport properties should be determined.<br />

h1 (h2) is a matrix representation of the Hamiltonian of two principal layers of the left (right) lead, and the<br />

coupling between such layers.<br />

h is a matrix representation of the Hamiltonian of the scattering region. This must include at least on lead<br />

principal layer on each side. The coupling in (out) of the scattering region is assumed to be identical to the<br />

coupling between left (right) principal layers.<br />

s, s1, and s2 are the overlap matrices corresponding to h, h1, and h2. Default is the identity operator.<br />

If align_bf is True, the onsite elements of the Hamiltonians will be shifted to a common fermi level.<br />

This module is stand-alone in the sense that it makes no requirement on the origin of these five matrices. They<br />

can be model Hamiltonians or derived from different kinds of electronic structure codes.<br />

For an example of how to use the transport module, see the GPAW exercise on electron transport<br />

7.24 The data module<br />

7.24.1 Atomic data<br />

This module defines the following variables:<br />

data.atomic_masses<br />

data.atomic_names<br />

data.chemical_symbols<br />

data.covalent_radii<br />

166 Chapter 7. Documentation for modules in <strong>ASE</strong>


data.cpk_colors<br />

data.reference_states<br />

data.vdw_radii<br />

All of these are lists that should be indexed with an atomic number:<br />

>>> from ase.data import *<br />

>>> atomic_names[92]<br />

’Uranium’<br />

>>> atomic_masses[2]<br />

4.0026000000000002<br />

data.atomic_numbers<br />

<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

If you don’t know the atomic number of some element, then you can look it up in the atomic_numbers<br />

dictionary:<br />

>>> atomic_numbers[’Cu’]<br />

29<br />

>>> covalent_radii[29]<br />

1.1699999999999999<br />

The covalent radii are taken from [Cordeo08]. The source of the van der Waals radii is given in vdw.py.<br />

7.24.2 Molecular data<br />

The G1, G2, and G3-databases are available in the molecules module.<br />

Example:<br />

>>> from ase.data.molecules import molecule<br />

>>> atoms = molecule(’H2O’)<br />

All molecular members of each database is conveniently contained in a list of strings (g1, g2, g3), and one can<br />

look up the experimental atomization energy for each molecule. This is extrapolated from experimental heats of<br />

formation at room temperature, using calculated zero-point energies and thermal corrections.<br />

Example:<br />

>>> from ase.data.molecules import molecule, g2, get_atomization_energy<br />

>>> g2[11]<br />

’H2O’<br />

>>> atoms = molecule(g2[11])<br />

>>> get_atomization_energy(g2[11])<br />

232.57990000000001<br />

>>> from ase.units import kcal,mol<br />

>>> get_atomization_energy(g2[11])*kcal/mol<br />

10.08562144637833<br />

where the last line converts the experimental atomization energy of H2O from units of kcal/mol to eV.<br />

7.24.3 S22, s26, and s22x5 data<br />

The s22, s26, and s22x5 databases are available in the s22 module.<br />

Each weakly bonded complex is identified as an entry in a list of strings (s22, s26, s22x5), and is fully created by<br />

a ‘create’-function:<br />

>>> from ase.data.s22 import s22, create_s22_system<br />

>>> sys = s22[0]<br />

>>> sys<br />

’Ammonia_dimer’<br />

7.24. The data module 167


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

>>> atoms = create_s22_system(sys)<br />

>>> atoms.get_chemical_symbols()<br />

[’N’, ’H’, ’H’, ’H’, ’N’, ’H’, ’H’, ’H’]<br />

The coupled-cluster interaction energies for the s22 and s26 systems are retrieved like this:<br />

>>> from ase.data.s22 import s22, get_interaction_energy_s22<br />

>>> get_interaction_energy_s22(s22[0])<br />

-0.1375<br />

in units of eV. For s22 these are not the original energies, but from more recent work where the same (large) basis<br />

set was used for all complexes, yielding more accurate coupled-cluster interaction energies.<br />

The s22x5 database expands on the original s22 data by introducing non-equilibrium geometries for each complex<br />

(0.9, 1.0, 1.2, 1.5, and 2.0 times original intermolecular distance). However, these calculations were done in<br />

accordance with the methods used in the original s22 work, and so is expected to inherit the same problems with<br />

mixed basis set sizes. Assuming the interaction energy error due to this is the same in all 5 geometries for each<br />

complex, the default s22x5 interaction energies are therefore corrected with the energy difference between original<br />

and newer energies at the original separation.<br />

Example:<br />

>>> from ase.data.s22 import *<br />

>>> sys1 = s22[0]<br />

>>> sys1<br />

’Ammonia_dimer’<br />

>>> atoms1 = create_s22_system(sys1)<br />

>>> sys2 = s22x5[0]<br />

>>> sys2<br />

’Ammonia_dimer_0.9’<br />

>>> atoms2 = create_s22_system(sys2)<br />

>>> sys3 = s22x5[1]<br />

>>> sys3<br />

’Ammonia_dimer_1.0’<br />

>>> atoms3 = create_s22_system(sys3)<br />

>>> get_interaction_energy_s22(sys1)<br />

-0.1375<br />

>>> get_interaction_energy_s22(sys2)<br />

-0.1375<br />

>>> get_interaction_energy_s22(sys3)<br />

-0.1375<br />

>>> get_interaction_energy_s22x5(sys2)<br />

-0.10549743024963291<br />

>>> get_interaction_energy_s22x5(sys3)<br />

-0.1375<br />

>>> get_interaction_energy_s22x5(sys3,correct_offset=False)<br />

-0.1362<br />

>>> get_interaction_energy_s22x5(sys1,dist=1.0)<br />

-0.1375<br />

>>> get_interaction_energy_s22x5(sys1,dist=0.9)<br />

-0.10549743024963291<br />

>>> get_interaction_energy_s22x5(sys1,dist=0.9,correct_offset=False)<br />

-0.1045<br />

>>> get_number_of_dimer_atoms(sys1)<br />

[4, 4]<br />

>>> get_s22x5_distance(sys2)<br />

-0.25040236345454536<br />

>>> get_s22x5_distance(sys3)<br />

0.0<br />

where sys1 is an s22 complex in the original geometry, while sys2 and sys3 are two different s22x5 geometries<br />

of the exact same complex. It is seen that the interaction energies for an s22 system and its s22x5 equivalent<br />

(indexed ‘_1.0’) does not neccesarily match when the energy offset-correction is turned off. The last two functions<br />

168 Chapter 7. Documentation for modules in <strong>ASE</strong>


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

are convenience functions, giving the number of atoms in the two molecules constituting a dimer and the relative<br />

intermolecular distance in a dimer (relative to the ‘1.0’ separation, and in Angstrom), respectively.<br />

7.25 Trajectory files<br />

The io.trajectory module defines Trajectory objects, that is objects storing the temporal evolution of a<br />

simulation. A Trajectory file contains one or more Atoms objects, usually to be interpreted as a time series,<br />

although that is not a requirement.<br />

The io.trajectory module currently defines two kinds of Trajectory files, the PickleTrajectory and the<br />

BundleTrajectory. PickleTrajectory is the recommended Trajectory format, BundleTrajectory is only intended<br />

for large molecular dynamics simulations (large meaning millions of atoms).<br />

In the future, other kinds of Trajectories may be defined, with similar Python interface but with different underlying<br />

file formats.<br />

7.25.1 PickleTrajectory<br />

The PickleTrajectory has the interface<br />

class ase.io.trajectory.PickleTrajectory(filename, mode=’r’, atoms=None, master=None,<br />

backup=True)<br />

Reads/writes Atoms objects into a .traj file.<br />

A PickleTrajectory can be created in read, write or append mode.<br />

Parameters:<br />

filename: The name of the parameter file. Should end in .traj.<br />

mode=’r’: The mode.<br />

‘r’ is read mode, the file should already exist, and no atoms argument should be specified.<br />

‘w’ is write mode. If the file already exists, is it renamed by appending .bak to the file name. The<br />

atoms argument specifies the Atoms object to be written to the file, if not given it must instead be given<br />

as an argument to the write() method.<br />

‘a’ is append mode. It acts a write mode, except that data is appended to a preexisting file.<br />

atoms=None: The Atoms object to be written in write or append mode.<br />

master=None: Controls which process does the actual writing. The default is that process number 0 does<br />

this. If this argument is given, processes where it is True will write.<br />

backup=True: Use backup=False to disable renaming of an existing file.<br />

close()<br />

Close the trajectory file.<br />

open(filename, mode)<br />

Opens the file.<br />

For internal use only.<br />

post_write_attach(function, interval=1, *args, **kwargs)<br />

Attach a function to be called after writing ends.<br />

function: The function or callable object to be called.<br />

interval: How often the function is called. Default: every time (1).<br />

All other arguments are stored, and passed to the function.<br />

7.25. Trajectory files 169


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

pre_write_attach(function, interval=1, *args, **kwargs)<br />

Attach a function to be called before writing begins.<br />

function: The function or callable object to be called.<br />

interval: How often the function is called. Default: every time (1).<br />

All other arguments are stored, and passed to the function.<br />

set_atoms(atoms=None)<br />

Associate an Atoms object with the trajectory.<br />

Mostly for internal use.<br />

write(atoms=None)<br />

Write the atoms to the file.<br />

If the atoms argument is not given, the atoms object specified when creating the trajectory object is<br />

used.<br />

Note that there is apparently no methods for reading the trajectory. Reading is instead done by indexing the<br />

trajectory, or by iterating over the trajectory: traj[0] and traj[-1] return the first and last Atoms object in<br />

the trajectory.<br />

Examples<br />

Reading a configuration:<br />

from ase.io.trajectory import PickleTrajectory<br />

traj = PickleTrajectory("example.traj")<br />

atoms = traj[-1]<br />

Reading all configurations:<br />

traj = PickleTrajectory("example.traj")<br />

for atoms in traj:<br />

# Analyze atoms<br />

Writing every 100th time step in a molecular dynamics simulation:<br />

# dyn is the dynamics (e.g. VelocityVerlet, Langevin or similar)<br />

traj = PickleTrajectory("example.traj", "w", atoms)<br />

dyn.attach(traj.write, interval=100)<br />

dyn.run(10000)<br />

traj.close()<br />

7.25.2 BundleTrajectory<br />

The BundleTrajectory has the interface<br />

class ase.io.bundletrajectory.BundleTrajectory(filename, mode=’r’, atoms=None,<br />

backup=True)<br />

Reads and writes atoms into a .bundle directory.<br />

The BundleTrajectory is an alternative way of storing trajectories, intended for large-scale molecular dynamics<br />

simulations, where a single flat file becomes unwieldy. Instead, the data is stored in directory, a<br />

‘bundle’ (the name bundle is inspired from bundles in Mac OS, which are really just directories the user is<br />

supposed to think of as a single file-like unit).<br />

Parameters:<br />

filename: The name of the directory. Preferably ending in .bundle.<br />

170 Chapter 7. Documentation for modules in <strong>ASE</strong>


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

mode (optional): The file opening mode. ‘r’ means open for reading, ‘w’ for writing and ‘a’ for appending.<br />

Default: ‘r’. If opening in write mode, and the filename already exists, the old file is renamed to .bak<br />

(any old .bak file is deleted), except if the existing file is empty.<br />

atoms (optional): The atoms that will be written. Can only be specified in write or append mode. If not<br />

specified, the atoms must be given as an argument to the .write() method instead.<br />

backup=True: Use backup=False to disable renaming of an existing file.<br />

close()<br />

Closes the trajectory.<br />

classmethod delete_bundle(filename)<br />

Deletes a bundle.<br />

static is_bundle(filename)<br />

Check if a filename exists and is a BundleTrajectory.<br />

static is_empty_bundle(filename)<br />

Check if a filename is an empty bundle. Assumes that it is a bundle.<br />

log(text)<br />

Write to the log file in the bundle.<br />

Logging is only possible in write/append mode.<br />

This function is mainly for internal use, but can also be called by the user.<br />

post_write_attach(function, interval=1, *args, **kwargs)<br />

Attach a function to be called after writing ends.<br />

function: The function or callable object to be called.<br />

interval: How often the function is called. Default: every time (1).<br />

All other arguments are stored, and passed to the function.<br />

pre_write_attach(function, interval=1, *args, **kwargs)<br />

Attach a function to be called before writing begins.<br />

function: The function or callable object to be called.<br />

interval: How often the function is called. Default: every time (1).<br />

All other arguments are stored, and passed to the function.<br />

read_extra_data(name, n=0)<br />

Read extra data stored alongside the atoms.<br />

Currently only used to read data stored by an NPT dynamics object. The data is not associated with<br />

individual atoms.<br />

select_data(data, value)<br />

Selects if a given data type should be written.<br />

Data can be written in every frame (specify True), in the first frame only (specify ‘only’) or not at<br />

all (specify False). Not all data types support the ‘only’ keyword, if not supported it is interpreted as<br />

True.<br />

The following data types are supported, the letter in parenthesis indicates the default:<br />

positions (T), numbers (O), tags (O), masses (O), momenta (T), forces (T), energy (T), energies (F),<br />

stress (F), magmoms (T)<br />

If a given property is not present during the first write, it will be not be saved at all.<br />

set_extra_data(name, source=None, once=False)<br />

Adds extra data to be written.<br />

Parameters: name: The name of the data.<br />

7.25. Trajectory files 171


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

source (optional): If specified, a callable object returning the data to be written. If not specified it is<br />

instead assumed that the atoms contains the data as an array of the same name.<br />

once (optional): If specified and True, the data will only be written to the first frame.<br />

write(atoms=None)<br />

Write the atoms to the file.<br />

7.25.3 See also<br />

If the atoms argument is not given, the atoms object specified when creating the trajectory object is<br />

used.<br />

The function ase.io.write() can write a single Atoms object to a Trajectory file.<br />

The function ase.io.read() can read an Atoms object from a Trajectory file, per default it reads the last one.<br />

7.26 Utillity functions and classes<br />

7.26.1 Equation of state<br />

The EquationOfState class can be used to find equilibrium volume, energy, and bulk modulus for solids:<br />

class ase.utils.eos.EquationOfState(volumes, energies, eos=’sjeos’)<br />

Fit equation of state for bulk systems.<br />

The following equation is used:<br />

sjeos (default)<br />

A third order inverse polynomial fit 10.1103/PhysRevB.67.026103<br />

2 3 -1/3<br />

E(V) = c + c t + c t + c t , t = V<br />

0 1 2 3<br />

taylor<br />

A third order Taylor series expansion about the minimum volume<br />

murnaghan<br />

PRB 28, 5480 (1983)<br />

birch<br />

Intermetallic compounds: Principles and Practice,<br />

Vol I: Principles. pages 195-210<br />

birchmurnaghan<br />

PRB 70, 224107<br />

pouriertarantola<br />

PRB 70, 224107<br />

vinet<br />

PRB 70, 224107<br />

antonschmidt<br />

Intermetallics 11, 23-32 (2003)<br />

p3<br />

A third order polynomial fit<br />

172 Chapter 7. Documentation for modules in <strong>ASE</strong>


Use:<br />

See Also:<br />

eos = EquationOfState(volumes, energies, eos=’sjeos’)<br />

v0, e0, B = eos.fit()<br />

eos.plot()<br />

The Equation of state tutorial.<br />

7.26.2 Symmetry analysis<br />

http://spglib.sourceforge.net/pyspglibFor<strong>ASE</strong>/<br />

7.26.3 Phonons<br />

http://phonopy.sourceforge.net/<br />

7.27 Thermochemistry<br />

<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

<strong>ASE</strong> contains a thermochemistry module that lets the user derive commonly desired thermodynamic quantities<br />

from <strong>ASE</strong> output and some user-specified parameters. Two cases are currently handled by this module: the<br />

ideal-gas limit (in which translational and rotational degrees of freedom are taken into account) and the harmonic<br />

limit (generally used for adsorbates, in which all degrees of freedom are treated harmonically). Both cases rely on<br />

good vibrational energies being fed to the calculators, which can be calculated with the vibrations module.<br />

7.27.1 Ideal-gas limit<br />

The thermodynamic quantities of ideal gases are calculated by assuming that all spatial degrees of freedom are separable<br />

into translational, rotational, and vibrational degrees of freedom. The IdealGasThermo class supports<br />

calculation of enthalpy (H), entropy (S), and free energy (G), and has the interface listed below.<br />

class ase.thermochemistry.IdealGasThermo(vib_energies, geometry, electronicenergy=None,<br />

atoms=None, symmetrynumber=None,<br />

spin=None, natoms=None)<br />

Class for calculating thermodynamic properties of a molecule based on statistical mechanical treatments in<br />

the ideal gas approximation.<br />

Inputs for enthalpy calculations:<br />

vib_energies [list] a list of the vibrational energies of the molecule (e.g., from<br />

ase.vibrations.Vibrations.get_energies). The number of vibrations used is automatically calculated<br />

by the geometry and the number of atoms. If more are specified than are needed, then the lowest<br />

numbered vibrations are neglected. If either atoms or natoms is unspecified, then uses the entire list.<br />

Units are eV.<br />

geometry [‘monatomic’, ‘linear’, or ‘nonlinear’] geometry of the molecule<br />

electronicenergy [float] the electronic energy in eV (If electronicenergy is unspecified, then the methods<br />

of this class can be interpreted as the enthalpy and free energy corrections.)<br />

natoms [integer] the number of atoms, used along with ‘geometry’ to determine how many vibrations to<br />

use. (Not needed if an atoms object is supplied in ‘atoms’ or if the user desires the entire list of<br />

vibrations to be used.)<br />

Extra inputs needed for for entropy / free energy calculations:<br />

atoms [an <strong>ASE</strong> atoms object] used to calculate rotational moments of inertia and molecular mass<br />

7.27. Thermochemistry 173


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

Example<br />

symmetrynumber [integer] symmetry number of the molecule. See, for example, Table 10.1 and Appendix<br />

B of C. Cramer “Essentials of Computational Chemistry”, 2nd Ed.<br />

spin [float] the total electronic spin. (0 for molecules in which all electrons are paired, 0.5 for a free radical<br />

with a single unpaired electron, 1.0 for a triplet with two unpaired electrons, such as O_2.)<br />

get_enthalpy(temperature, verbose=True)<br />

Returns the enthalpy, in eV, in the ideal gas approximation at a specified temperature (K).<br />

get_entropy(temperature, pressure, verbose=True)<br />

Returns the entropy, in eV/K, in the ideal gas approximation at a specified temperature (K) and pressure<br />

(Pa).<br />

get_free_energy(temperature, pressure, verbose=True)<br />

Returns the free energy, in eV, in the ideal gas approximation at a specified temperature (K) and<br />

pressure (Pa).<br />

The IdealGasThermo class would generally be called after an energy optimization and a vibrational analysis.<br />

The user needs to supply certain parameters if the entropy or free energy are desired, such as the geometry and<br />

symmetry number. An example on the nitrogen molecule is:<br />

from ase.data.molecules import molecule<br />

from ase.calculators.emt import EMT<br />

from ase.optimize import QuasiNewton<br />

from ase.vibrations import Vibrations<br />

from ase.thermochemistry import IdealGasThermo<br />

atoms = molecule(’N2’)<br />

atoms.set_calculator(EMT())<br />

dyn = QuasiNewton(atoms)<br />

dyn.run(fmax=0.01)<br />

electronicenergy = atoms.get_potential_energy()<br />

vib = Vibrations(atoms)<br />

vib.run()<br />

vib_energies = vib.get_energies()<br />

thermo = IdealGasThermo(vib_energies=vib_energies,<br />

electronicenergy=electronicenergy, atoms=atoms,<br />

geometry=’linear’, symmetrynumber=2, spin=0)<br />

G = thermo.get_free_energy(temperature=298.15, pressure=101325.)<br />

This will give the thermodynamic summary output:<br />

Enthalpy components at T = 298.15 K:<br />

===============================<br />

E_elec 0.000 eV<br />

E_ZPE 0.116 eV<br />

Cv_trans (0->T) 0.039 eV<br />

Cv_rot (0->T) 0.026 eV<br />

Cv_vib (0->T) 0.000 eV<br />

(C_v -> C_p) 0.026 eV<br />

-------------------------------<br />

H 0.206 eV<br />

===============================<br />

Entropy components at T = 298.15 K and P = 101325.0 Pa:<br />

=================================================<br />

S T*S<br />

S_trans (1 atm) 0.0015579 eV/K 0.464 eV<br />

S_rot 0.0004314 eV/K 0.129 eV<br />

174 Chapter 7. Documentation for modules in <strong>ASE</strong>


S_elec 0.0000000 eV/K 0.000 eV<br />

S_vib 0.0000001 eV/K 0.000 eV<br />

S (1 atm -> P) -0.0000000 eV/K -0.000 eV<br />

-------------------------------------------------<br />

S 0.0019893 eV/K 0.593 eV<br />

=================================================<br />

Free energy components at T = 298.15 K and P = 101325.0 Pa:<br />

=======================<br />

H 0.206 eV<br />

-T*S -0.593 eV<br />

-----------------------<br />

G -0.387 eV<br />

=======================<br />

7.27.2 Harmonic limit<br />

<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

In the harmonic limit, all degrees of freedom are treated harmonically. The HarmonicThermo class<br />

supports the calculation of internal energy, entropy, and free energy. This class uses all of the energies<br />

given to it in the vib_energies list; this is a list as can be generated with the .get_energies() method of<br />

ase.vibrations.Vibrations, but the user should take care that all of these energies are real (nonimaginary).<br />

The class HarmonicThermo has the interface described below.<br />

class ase.thermochemistry.HarmonicThermo(vib_energies, electronicenergy=None)<br />

Class for calculating thermodynamic properties in the approximation that all degrees of freedom are treated<br />

harmonically. Often used for adsorbates.<br />

Inputs:<br />

vib_energies [list] a list of the harmonic energies of the adsorbate (e.g., from<br />

ase.vibrations.Vibrations.get_energies). The number of energies should match the number of<br />

degrees of freedom of the adsorbate; i.e., 3*n, where n is the number of atoms. Note that this class<br />

does not check that the user has supplied the correct number of energies. Units of energies are eV.<br />

electronicenergy [float] the electronic energy in eV (If the electronicenergy is unspecified, then the methods<br />

of this class can be interpreted as the energy corrections.)<br />

get_entropy(temperature, verbose=True)<br />

Returns the entropy, in eV/K, in the harmonic approximation at a specified temperature (K).<br />

get_free_energy(temperature, verbose=True)<br />

Returns the free energy, in eV, in the harmonic approximation at a specified temperature (K).<br />

get_internal_energy(temperature, verbose=True)<br />

Returns the internal energy, in eV, in the harmonic approximation at a specified temperature (K).<br />

7.27.3 Background<br />

Ideal gas. The conversion of electronic structure calculations to thermodynamic properties in the ideal-gas<br />

limit is well documented; see, for example, Chapter 10 of Cramer, 2004. The key equations used in the<br />

IdealGasThermo class are summarized here.<br />

C.J. Cramer. Essentials of Computational Chemistry, Second Edition. Wiley, 2004.<br />

The ideal-gas enthalpy is calculated from extrapolation of the energy at 0 K to the relevant temperature (for an<br />

ideal gas, the enthalpy is not a function of pressure):<br />

H(T ) = Eelec + EZPE +<br />

� T<br />

0<br />

CP dT<br />

7.27. Thermochemistry 175


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

where the first two terms are the electronic energy and the zero-point energy, and the integral is over the constantpressure<br />

heat capacity. The heat capacity is separable into translational, rotational, vibrational, and electronic parts<br />

(plus a term of kB to switch from constant-volume to constant-pressure):<br />

CP = kB + CV ,trans + CV ,rot + CV ,vib + CV ,elec<br />

The translational heat capacity is 3/2 kB for a 3-dimensional gas. The rotational heat capacity is 0 for a monatomic<br />

species, kB for a linear molecule, and 3/2 kB for a nonlinear molecule. In this module, the electronic component<br />

of the heat capacity is assumed to be 0. The vibrational heat capacity contains 3N − 6 degrees of freedom for<br />

nonlinear molecules and 3N − 5 degrees of freedom for linear molecules (where N is the number of atoms). The<br />

integrated form of the vibrational heat capacity is:<br />

� T<br />

CV,vibdT =<br />

0<br />

vib �DOF<br />

i<br />

ɛi<br />

e ɛi/kBT − 1<br />

where ɛi are the energies associated with the vibrational frequencies, ɛi = hωi.<br />

The ideal gas entropy can be calculated as a function of temperature and pressure as:<br />

S(T, P ) = S(T, P ◦ ) − kB ln P<br />

P ◦<br />

= Strans + Srot + Selec + Svib − kB ln P<br />

P ◦<br />

where the translational, rotational, electronic, and vibrational components are calculated as below. (Note that<br />

the translational component also includes components from the Stirling approximation, and that the vibrational<br />

degrees of freedom are enumerated the same as in the above.)<br />

� ��2πMkBT Strans = kB ln<br />

h2 �3/2 kBT<br />

P ◦<br />

�<br />

+ 5<br />

�<br />

2<br />

Srot =<br />

⎧<br />

⎪⎨<br />

⎪⎩<br />

Svib = kB<br />

0 � � , if monatomic<br />

2<br />

8π IkBT<br />

kB ln σh2 � �<br />

+ 1<br />

, if linear<br />

� �<br />

√πIAIBIC � 2<br />

8π kBT<br />

kB ln σ h2 � �<br />

3/2<br />

+ 3<br />

�<br />

2 , if nonlinear<br />

vib �DOF<br />

i<br />

�<br />

ɛi<br />

kBT � eɛi/kBT �<br />

��<br />

� −ɛi/kBT<br />

− ln 1 − e<br />

− 1<br />

Selec = kB ln [2 × (spin multiplicity) + 1]<br />

IA through IC are the three principle moments of inertia for a non-linear molecule. I is the degenerate moment of<br />

inertia for a linear molecule. σ is the symmetry number of the molecule.<br />

The ideal-gas free energy is then just calculated from the combination of the enthalpy and entropy:<br />

G(T, P ) = H(T ) − T S(T, P )<br />

176 Chapter 7. Documentation for modules in <strong>ASE</strong>


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

Harmonic limit. The conversion of electronic structure calculation information into thermodynamic properties is<br />

less established for adsorbates. However, the simplest approach often taken is to treat all 3N degrees of freedom<br />

of the adsorbate harmonically since the adsorbate often has no real translational or rotational degrees of freedom.<br />

This is the approach implemented in the HarmonicThermo class. Thus, the internal energy and entropy of the<br />

adsorbate are calculated as<br />

S = kB<br />

and the free energy is calculated as<br />

harm �DOF<br />

ɛi<br />

U(T ) = Eelec + EZPE +<br />

eɛi/kBT − 1<br />

harm �DOF<br />

i<br />

�<br />

i<br />

ɛi<br />

kBT � eɛi/kBT �<br />

��<br />

� −ɛi/kBT<br />

− ln 1 − e<br />

− 1<br />

G(T, P ) = U(T ) − T S(T, P )<br />

In this case, the number of harmonic energies (ɛi) used in the summation is generally 3N, where N is the number<br />

of atoms in the adsorbate.<br />

7.27. Thermochemistry 177


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

178 Chapter 7. Documentation for modules in <strong>ASE</strong>


CHAPTER<br />

EIGHT<br />

FREQUENTLY ASKED QUESTIONS<br />

8.1 <strong>ASE</strong>-GUI<br />

See also the documantation for ag.<br />

8.1.1 How do I export images from a trajectory to png or pov files?<br />

With ag, you can choose File → Save, but this is not fun if you need to do it for many images. Here is how to do<br />

it on the command line for a number of images:<br />

ag images.traj@0 -o image0.pov<br />

ag images.traj@1 -o image1.pov<br />

ag images.traj@2 -o image2.pov<br />

If you have many images, it will be easier to do it using the Python interpreter:<br />

>>> from ase import *<br />

>>> for n, image in enumerate(read(’images.traj@:3’)):<br />

... write(’image%d.pov’ % n, image, run_povray=True, pause=False,<br />

... rotation=’-90x,10z’)<br />

Here, we also:<br />

Try:<br />

• run povray to generate png files<br />

• disable pausing between the images<br />

• set a rotation (choose View → Rotate ... in ag to select the best rotation angles)<br />

>>> help(write)<br />

to see all possibilities or read more here.<br />

8.2 General<br />

8.2.1 Citation: how should I cite <strong>ASE</strong>?<br />

If you find <strong>ASE</strong> useful in your research please cite:<br />

S. R. Bahn and K. W. Jacobsen<br />

An object-oriented scripting interface to a legacy electronic structure code<br />

Comput. Sci. Eng., Vol. 4, 56-66, 2002<br />

BibTex (doc/<strong>ASE</strong>.bib):<br />

179


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

@Article{ISI:000175131400009,<br />

Author = {S. R. Bahn and K. W. Jacobsen},<br />

Title = {An object-oriented scripting interface to a legacy electronic structure code},<br />

JournalFull = {COMPUTING IN SCIENCE \& ENGINEERING},<br />

Year = {2002},<br />

Volume = {4},<br />

Number = {3},<br />

Pages = {56-66},<br />

Month = {MAY-JUN},<br />

Abstract = {The authors have created an object-oriented scripting interface to a mature density fu<br />

code. The interface gives users a high-level, flexible handle on the code without rewriting the<br />

underlying number-crunching code. The authors also discuss the design issues and advantages of<br />

homogeneous interfaces},<br />

Publisher = {IEEE COMPUTER SOC},<br />

Address = {10662 LOS VAQUEROS CIRCLE, PO BOX 3014, LOS ALAMITOS, CA 90720-1314 USA},<br />

Type = {Article},<br />

Language = {English},<br />

Affiliation = {Bahn, SR (Reprint Author), Tech Univ Denmark, Dept Phys, CAMP, Bldg 307, DK-2800 Ly<br />

Tech Univ Denmark, Dept Phys, CAMP, DK-2800 Lyngby, Denmark.},<br />

ISSN = {1521-9615},<br />

Keywords-Plus = {MULTISCALE SIMULATION; GOLD ATOMS},<br />

Subject-Category = {Computer Science, Interdisciplinary Applications},<br />

Author-Email = {bahn@fysik.dtu.dk kwj@fysik.dtu.dk},<br />

Number-of-Cited-References = {19},<br />

Journal-ISO = {Comput. Sci. Eng.},<br />

Journal = {Comput. Sci. Eng.},<br />

Doc-Delivery-Number = {543YL},<br />

Unique-ID = {ISI:000175131400009},<br />

DOI = {10.1109/5992.998641},<br />

}<br />

8.3 Download<br />

Trying to checkout the code via SVN resulted:<br />

[~]$ svn checkout "https://svn.fysik.dtu.dk/projects/ase/trunk"<br />

svn: Unrecognized URL scheme ’https://svn.fysik.dtu.dk/projects/ase/trunk’<br />

This error is diplayed in case the library ‘libsvn_ra_dav’ is missing on your system. The library is used by SVN,<br />

but is not installed by default.<br />

180 Chapter 8. Frequently Asked Questions


CHAPTER<br />

NINE<br />

GLOSSARY<br />

API Application Programming Interface. Automatically generated documentation from docstrings in the source<br />

code using Epydoc. See here.<br />

<strong>ASE</strong> Atomic Simulation Environment.<br />

Class XXX<br />

Constructor XXX<br />

Docstring XXX<br />

DFT Density Functional Theory.<br />

EMT Effective Medium Theory.<br />

HF Hartree-Fock approximation XXX ...<br />

Instance XXX<br />

LAPW In the linearized augmented plane wave (LAPW) method the unit cell of the crystal is divided into two<br />

different types of regions. The first one, called the muffin-tin region, consists of spheres centered around<br />

the atoms, while the second one, called the interstitial region consists of the remaining part of the unit cell.<br />

In the muffin-tin spheres the basis consists of atomic like functions to account for the rapid changes of the<br />

wave function in this area, whereas in the interstitial region the basis functions are plane waves, since the<br />

wave function changes only slowly at some distance from the atomic sites.<br />

Namespace An abstract container of the current scope‘s variables.<br />

ndarray NumPy‘s n-dimensional array. See Numeric arrays in Python.<br />

NumPy XXX See Numeric arrays in Python.<br />

Method XXX<br />

Python XXX What is Python?.<br />

Scope An enclosing context where values and expressions are associated.<br />

181


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

182 Chapter 9. Glossary


There is a mailing list for discussing <strong>ASE</strong>:<br />

• ase-users<br />

The mailing lists below are of interest for active <strong>ASE</strong> developers only:<br />

• ase-developers<br />

• ase-svncheckins<br />

or (mainly) dacapo / <strong>ASE</strong>-2 users / developers:<br />

• campos<br />

• campos-devel<br />

10.1 Internet Relay Chat<br />

CHAPTER<br />

TEN<br />

MAILING LISTS<br />

We have the IRC channel #campos on FreeNode. Please join us if you have any questions. For easy access, you<br />

can use this webclient.<br />

183


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

184 Chapter 10. Mailing Lists


As a developer, you should subscribe to all <strong>ASE</strong> related Mailing Lists.<br />

11.1 Development topics<br />

11.1.1 <strong>Release</strong> notes<br />

Development version in trunk<br />

trunk.<br />

CHAPTER<br />

ELEVEN<br />

<strong>ASE</strong> DEVELOPMENT<br />

• Important backwards incompatible change: The ase.lattice.surface.surface() function now returns a righthanded<br />

unit cell.<br />

• Mopac interface added.<br />

• Gaussian interface added.<br />

Version 3.6.0<br />

24 Feb 2012: tags/3.6.0.<br />

• <strong>ASE</strong> GUI translations added, available: da_DK, en_GB, es_ES.<br />

• New function for making surfaces with arbitrary Miller indices with the smallest possible surface unit cell:<br />

ase.lattice.surface.surface()<br />

• New ase.lattice.bulk() function. Will replace old ase.structure.bulk() function. The new one will produce<br />

a more natural hcp lattice and it will use experimental data for crystal structure and lattice constants if not<br />

provided explicitely.<br />

• New values for ase.data.covalent_radii from Cordeo et al..<br />

• New command line tool: Command line tools and tests based on it: abinit, elk, fleur, nwchem.<br />

• New crystal builder for ag<br />

• Van der Waals radii in ase.data<br />

• <strong>ASE</strong> GUI (ag) now supports velocities for both graphs and coloring<br />

• Cleaned up some name-spaces:<br />

– ase now contains only Atoms and Atom<br />

– ase.calculators is now empty<br />

185


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

Version 3.5.1<br />

24 May 2011: tags/3.5.1.<br />

• Problem with parallel vibration calculations fixed: Ticket #80.<br />

Version 3.5.0<br />

13 April 2011: tags/3.5.0.<br />

• Improved EMT potential: uses a NeighborList object and is now ASAP compatible.<br />

• BFGSLineSearch is now the default (QuasiNewton==BFGSLineSearch).<br />

• There is a new interface to the LAMMPS molecular dynamics code.<br />

• New phonons module.<br />

• Van der Waals corrections for DFT, see GPAW usage.<br />

• New BundleTrajectory added.<br />

• Updated GUI interface:<br />

– Stability and usability improvements.<br />

– Povray render facility.<br />

– Updated expert user mode.<br />

– Enabled customization of colours and atomic radii.<br />

– Enabled user default settings via ~/.ase/gui.py.<br />

• Database library expanded to include:<br />

– The s22, s26 and s22x5 sets of van der Waals bonded dimers and complexes by the Hobza group.<br />

– The DBH24 set of gas-phase reaction barrier heights by the Truhlar group.<br />

• Implementation of the Dimer method.<br />

Version 3.4.1<br />

11 August 2010: tags/3.4.1.<br />

11.1.2 How to contribute<br />

Discussion of <strong>ASE</strong> development takes place on the ase-developer mailing list, and also sometimes on the #gpaw<br />

IRC channel on freenode.<br />

We welcome new developers who would like to help work on improving <strong>ASE</strong>. If you would like to contribute,<br />

your should first tell us what you want to work on. Use the mailing list for that.<br />

SVN access<br />

We don’t give new contributers write access to our SVN repository from day one. So, you will have to create a<br />

patch and send it to the mailing list:<br />

$ svn checkout https://svn.fysik.dtu.dk/projects/ase/trunk myase<br />

$ cd myase<br />

$ # do your thing ...<br />

$ svn diff > patch.txt<br />

Before you send the patch, please read our Coding Conventions and learn how to use pep8.py, pylint and epydoc:<br />

186 Chapter 11. <strong>ASE</strong> development


• Run pep8.py on your code<br />

• Using pylint to check your code<br />

• Run epydoc on your code<br />

<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

One of the current committers will look at the patch and give you some feedback. Maybe the patch is fine and the<br />

committer will commit it to trunk. There could also be some more work to do like:<br />

• make it compatible with all supported pythons (see Installation requirements).<br />

• write more comments<br />

• fix docstrings<br />

• write a test<br />

• add some documentation<br />

Once everyone is happy, the patch can be appied. This patch-feedback loop is not something we have invented to<br />

prevent you from contributing - it should be viewed as an opportunity for you to learn how to write a code that fits<br />

into the <strong>ASE</strong> codebase.<br />

After a couple of contributions, we will probably trust you enough to add you as a committer.<br />

Committers<br />

Here is the list of current committers:<br />

user name real name<br />

anpet Andrew Peterson andy,peterson:stanford,edu<br />

askhl Ask Hjorth Larsen askhl:fysik,dtu,dk<br />

bjork Jonas Bjork J,Bjork:liverpool,ac,uk<br />

dlandis David Landis dlandis:fysik,dtu,dk<br />

dulak Marcin Dulak dulak:fysik,dtu,dk<br />

eojons Elvar Örn Jónsson elvar,jonsson:fysik,dtu,dk<br />

getri George Tritsaris getri:fysik,dtu,dk<br />

grabow Lars Grabow grabow:fysik,dtu,dk<br />

hahansen Heine Anton Hansen hahansen:fysik,dtu,dk<br />

ivca Ivano Eligio Castelli ivca:fysik,dtu,dk<br />

jakobb Jakob Blomquist jakobb:fysik,dtu,dk<br />

jber Jon Bergmann Maronsson jber:fysik,dtu,dk<br />

jblomqvist Janne Blomqvist Janne,Blomqvist:tkk,fi<br />

jensj Jens Jørgen Mortensen jensj:fysik,dtu,dk<br />

jesperf Jesper Friis jesper,friis:sintef,no<br />

jingzhe Jingzhe Chen jingzhe:fysik,dtu,dk<br />

jkitchin John Kitchin jkitchin:andrew,cmu,edu<br />

jussie Jussi Enkovaara jussi,enkovaara:csc,fi<br />

kkaa Kristen Kaasbjerg kkaa:fysik,dtu,dk<br />

kleis Jesper Kleis kleis:fysik,dtu,dk<br />

kwj Karsten Wedel Jacobsen kwj:fysik,dtu,dk<br />

markus Markus Kaukonen markus,kaukonen:iki,fi<br />

miwalter Michael Walter Michael,Walter:fmf,uni-freiburg,de<br />

moses Poul Georg Moses poulgeorgmoses:gmail,com<br />

mvanin Marco Vanin mvanin:fysik,dtu,dk<br />

s032082 Christian Glinsvad s032082:fysik,dtu,dk<br />

schiotz Jakob Schiotz schiotz:fysik,dtu,dk<br />

slabanja Mattias Slabanja slabanja:chalmers,se<br />

strange Mikkel Strange strange:fysik,dtu,dk<br />

tjiang Tao Jiang tjiang:fysik,dtu,dk<br />

tolsen Thomas Olsen tolsen:fysik,dtu,dk<br />

11.1. Development topics 187


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

Former committers:<br />

anro Anthony Goodrow anro:fysik,dtu,dk<br />

carstenr Carsten Rostgaard carstenr:fysik,dtu,dk<br />

hanke Felix Hanke F,Hanke:liverpool,ac,uk<br />

s042606 Janosch Michael Rauba s042606:fysik,dtu,dk<br />

s052580 Troels Kofoed Jacobsen s052580:fysik,dtu,dk<br />

11.1.3 Python 3 strategy<br />

• One codebase for both 2 and 3.<br />

• Use “print(...)” if possible:<br />

print ’bla bla’ # no<br />

print(’bla bla’) # yes<br />

print ’bla bla:’, x # no<br />

print(’bla bla: %s’ % x) # yes<br />

• Don’t do this: print >> f, .... Use f.write(... + ’\n’) or ase.utils.prnt(...,<br />

file=f).<br />

• More help here: http://packages.python.org/six/<br />

11.1.4 Using version control (SVN)<br />

The version control system used in <strong>ASE</strong> development is subversion. A thorough subversion manual can be found<br />

at http://svnbook.red-bean.com/, here is a brief overview of the most basic features needed when developing <strong>ASE</strong>.<br />

• perform svn checkout of ase.<br />

Place it, for example, in ase-svn directory:<br />

cd<br />

svn checkout https://svn.fysik.dtu.dk/projects/ase/trunk ase-svn<br />

This retrieves the code tree from the subversion repository. Prepend PYTHONPATH and PATH environment<br />

variables as described at Installation.<br />

• Updating the working copy of the code (in the directory ase-svn):<br />

svn update<br />

After each (important) update, remove ase/svnrevision.py* files, and run:<br />

python setup.py sdist<br />

to keep the ase/svnrevision.py file up-to-date.<br />

• Checking the status of the working copy (in the directory ase-svn):<br />

svn stat<br />

The status about the files which are not in version control can be surpassed with the -q flag, and the status<br />

with respect to latest additions in server can be checked with the -u flag.<br />

• Committing the changes to the repository<br />

Before sending the changes in the working copy to the repository, working copy should be updated. After<br />

that, the changes can be send with:<br />

svn commit -m "Message to describe the committed changes"<br />

If the -m option is omitted, an editor is opened for writing the log message.<br />

188 Chapter 11. <strong>ASE</strong> development


• Adding files or directories to version control:<br />

svn add filename<br />

<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

If filename is directory, also all the files within the directory are added. Note that svn commit is<br />

required before the new files are actually included in version control.<br />

• <strong>ASE</strong> documentation resides under doc directory, and is also under subversion control. See more at Writing<br />

documentation.<br />

11.1.5 Coding Conventions<br />

Importing modules<br />

In code, like the implementation of <strong>ASE</strong>, we must not use the import * syntax. Import everything explicitly<br />

from exactly the place where it’s defined:<br />

from ase.io import read, write<br />

We distinguish between scripts and code. In your own scripts, it’s OK to use:<br />

from ase.all import *<br />

which will give you the most used symbols.<br />

Python Coding Conventions<br />

Please run pep8.py and pylint on your code before committing.<br />

The rules for the Python part are almost identical to those used by the Docutils project:<br />

Contributed code will not be refused merely because it does not strictly adhere to these conditions; as long as it’s<br />

internally consistent, clean, and correct, it probably will be accepted. But don’t be surprised if the “offending”<br />

code gets fiddled over time to conform to these conventions.<br />

The project shall follow the generic coding conventions as specified in the Style Guide for Python Code and<br />

Docstring Conventions PEPs, summarized, clarified, and extended as follows:<br />

• 4 spaces per indentation level. No hard tabs.<br />

• Very important: Read the Whitespace in Expressions and Statements section of PEP8.<br />

• Avoid introducing trailing whitespaces.<br />

• Try to use only 7-bit ASCII, no 8-bit strings.<br />

• No one-liner compound statements (i.e., no if x: return: use two lines & indentation), except for<br />

degenerate class or method definitions (i.e., class X: pass is OK.).<br />

• Lines should be no more than 78 characters long.<br />

• Use “StudlyCaps” for class names.<br />

• Use “lowercase” or “lowercase_with_underscores” for function, method, and variable names. For short<br />

names, maximum two words, joined lowercase may be used (e.g. “tagname”). For long names with three or<br />

more words, or where it’s hard to parse the split between two words, use lowercase_with_underscores (e.g.,<br />

“note_explicit_target”, “explicit_target”). If in doubt, use underscores.<br />

• Avoid lambda expressions, which are inherently difficult to understand. Named functions are preferable<br />

and superior: they’re faster (no run-time compilation), and well-chosen names serve to document and aid<br />

understanding.<br />

• Avoid functional constructs (filter, map, etc.). Use list comprehensions instead.<br />

• Avoid from __future__ import constructs. They are inappropriate for production code.<br />

11.1. Development topics 189


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

• Use ‘single quotes’ for string literals, and “”“triple double quotes”“” for docstrings. Double quotes are OK<br />

for something like "don’t".<br />

Attention: Thus spake the Lord: Thou shalt indent with four spaces. No more, no less. Four shall be the<br />

number of spaces thou shalt indent, and the number of thy indenting shall be four. Eight shalt thou not indent,<br />

nor either indent thou two, excepting that thou then proceed to four. Tabs are right out.<br />

Georg Brandl<br />

General advice<br />

• Get rid of as many break and continue statements as possible.<br />

Writing documentation in the code<br />

Here is an example of how to write good docstrings:<br />

http://projects.scipy.org/numpy/browser/trunk/doc/example.py<br />

Run pep8.py on your code<br />

The pep8.py program is installed together with <strong>ASE</strong> tools/pep8.py. It will check the PEP8 conventions for you.<br />

Try:<br />

$ pep8.py --help<br />

Using pylint to check your code<br />

A pylintrc trying to follow <strong>ASE</strong> Coding Conventions can be found here: doc/development/pylintrc<br />

Running pylint yourself<br />

Run pylint on a single file like this:<br />

[~]$ pylint mypythonfile.py<br />

Run pylint on a module like this:<br />

[~]$ pylint path/to/module/root/dir<br />

Output from pylint run on <strong>ASE</strong><br />

• pylint_ase<br />

Run epydoc on your code<br />

Run:<br />

$ epydoc --docformat restructuredtext --parse-only --show-imports -v dir<br />

11.1.6 Writing documentation<br />

We use the Sphinx tool to generate the documentation (both HTML and PDF). The documentation is stored in<br />

SVN as text files in the doc directory using the reStructuredText markup language.<br />

190 Chapter 11. <strong>ASE</strong> development


Installing Docutils and Sphinx<br />

<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

The reStructuredText parser that Sphinx needs, is part of the Docutils project. So, we need to install docutils and<br />

sphinx (version>= 0.5).<br />

Other requirements<br />

When building the documentation, a number of png-files are generated. For that to work, you need the following<br />

installed:<br />

• matplotlib<br />

• povray<br />

• dvipng<br />

• pdflatex<br />

• bibtex<br />

• AUCTex<br />

• convert (ImageMagick)<br />

Using Sphinx<br />

First, you should take a look at the documentation for Sphinx and reStructuredText.<br />

If you don’t already have your own copy of the <strong>ASE</strong> package, then get the Latest development release and install<br />

it.<br />

Then cd to the doc directory and build the html-pages:<br />

$ cd ~/ase/doc<br />

$ sphinx-build . _build<br />

Note: Make sure that you build the Sphinx documentation using the corresponding <strong>ASE</strong> version by setting the<br />

environment variables $PYTHONPATH and $PATH.<br />

Make your changes to the .rst files, run the sphinx-build command again, check the results and if things looks<br />

ok, commit:<br />

$ emacs index.rst<br />

$ sphinx-build . _build<br />

$ firefox _build/index.html<br />

$ svn ci -m "..." index.rst<br />

To build a pdf-file, you do this:<br />

$ sphinx-build -b latex . _build<br />

$ cd _build<br />

$ make ase-manual.pdf<br />

Extensions to Sphinx<br />

We have a couple of extensions to Sphinx:<br />

:mol:<br />

:svn:<br />

Use :mol:‘CH_3OH‘ to get CH3OH.<br />

11.1. Development topics 191


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

:trac:<br />

:epydoc:<br />

:math:<br />

.. math::<br />

A role for creating a link to a file in SVN. If you write :svn:‘ase/atoms.py‘, you will get:<br />

ase/atoms.py.<br />

A role for creating a link to a file in Trac. If you write :trac:‘ase/atoms.py‘, you will get:<br />

ase/atoms.py.<br />

A role for creating a link to the API-documentation generated with epydoc. If you write<br />

:epydoc:‘ase.atoms.Atoms‘, you will get: Atoms.<br />

This role is for inline LaTeX-style math. Example: :math:‘\sin(x_n^2)‘ gives you sin(x 2 n).<br />

Write displayed LaTeX-style math. Example:<br />

.. math:: \frac{1}{1+x^2}<br />

gives you:<br />

1<br />

1 + x 2<br />

If you add the line .. default-role:: math, then you can leave out the :math: part like here:<br />

‘\sin(x_n^2)‘.<br />

The implementation of these roles is here: doc/ext.py. Our custom, obsolete, implementation of the math role and<br />

directive is here: doc/mathpng.py. With sphinx >= 0.5 please use sphinx.ext.pngmath.<br />

reStructedText in emacs<br />

For people using emacs, the reStructuredText extension is highly recommended. The intallation procedure is<br />

described in the top of the file, but for most people, it is enough to place it in your emacs load-path (typically<br />

.emacs.d/) and add the lines:<br />

(add-to-list ’load-path "~/.emacs.d")<br />

(require ’rst)<br />

somewhere in your .emacs file.<br />

To make the mode auto load for relevant file extension, you can write something like:<br />

(setq auto-mode-alist<br />

(append ’(("\\.rst$" . rst-mode)<br />

("\\.rest$" . rst-mode)) auto-mode-alist))<br />

In your .emacs file.<br />

Updating Sphinx<br />

Starting a new project with sphinx requires an initial configuration. This is achieved by running sphinxquickstart.<br />

When updating from a very old sphinx you may consider generating new configuration files and<br />

updating the old files accordingly.<br />

Note that the current project is configured up-to-date, so if you are “simply” writing the documentation you must<br />

skip the sphinx-quickstart step and focus on Using Sphinx.<br />

Here is how do you setup the GPAW project with sphinx:<br />

192 Chapter 11. <strong>ASE</strong> development


• cd to the doc directory,<br />

• run sphinx-quickstart and answer the questions (example given for GPAW):<br />

> Root path for the documentation [.]:<br />

> Separate source and build directories (y/N) [n]:<br />

> Name prefix for templates and static dir [.]: _<br />

> Project name: GPAW<br />

> Author name(s): 2008, <strong>CAMd</strong> et al.<br />

> Project version: 0.5<br />

> Project release [0.5]:<br />

> Source file suffix [.rst]:<br />

> Name of your master document (without suffix) [index]: contents<br />

<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

> autodoc: automatically insert docstrings from modules (y/N) [n]: y<br />

> doctest: automatically test code snippets in doctest blocks (y/N) [n]:<br />

> intersphinx: link between Sphinx documentation of different projects (y/N) [n]: y<br />

This will create doc/conf.py and doc/contents.rst. Both these files need to be edited further<br />

(doc/conf.py may for example include options for sphinx.ext.pngmath)<br />

11.1.7 Making movies<br />

A video tutorial can be produced in the following way:<br />

• change the screen resolution to 1280x1024,<br />

• record the movie of the screen (without sound) using recordmydesktop (gtk-recordMyDesktop),<br />

• convert the resulting ogv into avi using mencoder:<br />

mencoder video.ogv -o video.avi -oac copy -ovc lavc<br />

• record and edit the sound track using audacity:<br />

– use 44100 Hz for recording and save the final file as sound.wav,<br />

– make sure not to keep the microphone to close to avoid signal peaks,<br />

– cut microphone signal peaks, insert silences, ...<br />

• edit the movie using avidemux (to match the sound track):<br />

– load the video.avi: File->Open, make sure to use the following options when editing and saving:<br />

Video->Copy, Audio->Copy, Format->AVI,<br />

– add the sound.avi: Audio->Main Track->Audio Source->External WAV,<br />

– cut video frames (or copy and insert still frames to extend the video) to match the sound track. Set<br />

beginning mark and end mark - the cut or copy/paste operation applies to the selected region,<br />

– make sure to save intermediate stages when working on the video File->Save->Save Video (as AVI):<br />

* avidemux caches the audio track so to match the audio to a freshly cut video you can copy the<br />

audio file into another name, and add the sound track from that name,<br />

* sometimes when cutting frames avidemux does not allow to set the markers correctly, and there<br />

is no undo the last step in avidemux!<br />

– save the video_final.avi (that matches the sound track), and encode it into mpeg4 format using mencoder,<br />

using two passes:<br />

11.1. Development topics 193


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

opt="vbitrate=550:mbd=2:dc=10 -vf unsharp=l:0.4:c:0.0:hqdn3d"<br />

mencoder -ovc lavc -lavcopts vcodec=msmpeg4v2:vpass=1 -nosound -o /dev/null video_final.a<br />

mencoder video_final.avi -oac mp3lame -af resample=32000:0:2 -lameopts vbr=3:br=80:mode=3<br />

-ovc lavc -lavcopts acodec=mp3lame:vcodec=msmpeg4v2:vpass=2:$opt \<br />

-info name="Overview and installation of <strong>ASE</strong>":artist=<strong>CAMd</strong>:copyright="<strong>CAMd</strong> 2009" -<br />

– convert video_final.avi into a 800x600 swf file for streaming:<br />

ffmpeg -i video_final.avi -pass 1 -s 800x600 -b:a 256k -ar 44100 -ac 1 \<br />

-vcodec flv -b:v 1200k -g 160 -mbd 2 oi_en_800x600.swf<br />

ffmpeg -i video_final.avi -pass 2 -s 800x600 -b:a 256k -ar 44100 -ac 1 \<br />

-vcodec flv -b:v 1200k -g 160 -mbd 2 -y oi_en_800x600.swf<br />

11.1.8 New release<br />

When it is time for a new release of the code, here is what you have to do:<br />

** Warning: use only three digits release numbers, e.g. 3.1.0,<br />

• Checkout the Latest development release.<br />

• Run the tests.<br />

• Make sure version.py has the correct version number.<br />

• Make a tag in svn, using the current version number (to make sure not to include changes done by other<br />

developers in the meantime!):<br />

svn copy -r 845 https://svn.fysik.dtu.dk/projects/ase/trunk https://svn.fysik.dtu.dk/projects<br />

Note the resulting tag’s revision tags_revision.<br />

• Checkout the source, specyfing the version number in the directory name:<br />

svn co -r tags_revision https://svn.fysik.dtu.dk/projects/ase/tags/3.1.0 ase-3.1.0<br />

• Create the tar file:<br />

cd ase-3.1.0<br />

rm -f MANIFEST ase/svnversion.py*; python setup.py sdist<br />

Note that the tags_revision is put into the name of the tar file automatically. Make sure that you are<br />

getting only tags_revision in the tar file name! Any changes to the source will be reflected as a mixed<br />

or modified revision tag!<br />

• Put the tar file on webX (set it read-able for all):<br />

scp dist/python-ase-3.1.0."tags_revision".tar.gz root@webX:/var/www/wiki/ase-files<br />

• Add a link on News and update the information on the Installation requirements page and the <strong>Release</strong> notes<br />

page.<br />

• Increase the version number in ase/version.py, and commit the change:<br />

cd ~/ase<br />

svn ci -m "Version 3.2.0"<br />

Now the trunk is ready for work on the new version.<br />

• Send announcement email to the ase-users mailing list (see Mailing Lists).<br />

11.1.9 Testing the code<br />

All additions and modifications to <strong>ASE</strong> should be tested.<br />

194 Chapter 11. <strong>ASE</strong> development


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

Test scripts should be put in the ase/test directory. The scripts in this directory may be run by using the script<br />

tools/testase or by using the function:<br />

test.test(verbosity=1, dir=None)<br />

Runs the test scripts in ase/test.<br />

Important: When you fix a bug, add a test to the test suite checking that it is truly fixed. Bugs sometimes come<br />

back, do not give it a second chance!<br />

How to fail successfully<br />

The test suite provided by test.test() automatically runs all test scripts in the ase/test directory and summarizes<br />

the results.<br />

Note: Test scripts are run from within Python using the execfile() function. Among other things, this<br />

provides the test scripts with an specialized global namespace, which means they may fail or behave differently if<br />

you try to run them directly e.g. using python testscript.py.<br />

If a test script causes an exception to be thrown, or otherwise terminates in an unexpected way, it will show up in<br />

this summary. This is the most effective way of raising awareness about emerging conflicts and bugs during the<br />

development cycle of the latest revision.<br />

Remember, great tests should serve a dual purpose:<br />

Working interface To ensure that the class‘es and method‘s in <strong>ASE</strong> are functional and provide the expected<br />

interface. Empirically speaking, code which is not covered by a test script tends to stop working over time.<br />

Replicable results Even if a calculation makes it to the end without crashing, you can never be too sure that the<br />

numerical results are consistent. Don’t just assume they are, assert() it!<br />

test.assert(expression)<br />

Raises an AssertionError if the expression does not evaluate to True.<br />

Example:<br />

from ase import molecule<br />

atoms = molecule(’C60’)<br />

atoms.center(vacuum=4.0)<br />

result = atoms.get_positions().mean(axis=0)<br />

expected = 0.5*atoms.get_cell().diagonal()<br />

tolerance = 1e-4<br />

assert (abs(result - expected) < tolerance).all()<br />

Using functions to repeat calculations with different parameters:<br />

def test(parameter):<br />

# setup atoms here...<br />

atoms.set_something(parameter)<br />

# calculations here...<br />

assert everything_is_going_to_be_alright<br />

if __name__ in [’__main__’, ’__builtin__’]:<br />

test(0.1)<br />

test(0.3)<br />

test(0.7)<br />

Important: Unlike normally, the module __name__ will be set to ’__builtin__’ when a test script is run<br />

by the test suite.<br />

11.1. Development topics 195


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

11.1.10 Translate <strong>ASE</strong><br />

You can contribute by translating the <strong>ASE</strong> GUI, ag, into your language.<br />

How to translate<br />

If any of the below steps prove difficult, be sure to ask on the developer mailing list. These steps should work on<br />

GNU/Linux.<br />

• Download <strong>ASE</strong>.<br />

• Go to ase/gui/po. There is a directory of the form ll or ll_LL for each language, where ll is the<br />

language code and LL the country code. The latter is necessary only if variants of the same language are<br />

spoken in multiple countries.<br />

• If your language is not there already, run LANG=ll make init, substituting the desired language code.<br />

If necessary append the country code as well: LANG=ll_LL ....<br />

• There should now be a template file for your language, ll/LC_MESSAGES/ag.po, which can be filled<br />

out.<br />

You can edit the po-file with any text editor. It is easiest with a dedicated po-editor such as gtranslator, poedit or<br />

the gettext mode in EMACS (the package “gettext-el”). Fill out the missing msgstr entries like this:<br />

#: ../energyforces.py:61<br />

msgid "Calculate potential energy and the force on all atoms"<br />

msgstr "Beregn potentiel energi og kræfter på alle atomer"<br />

Your editor may wholly or partially hide some of the difficult formatting syntax. This next example shows a more<br />

syntactically complex case in case you need it:<br />

#: ../calculator.py:107<br />

msgid ""<br />

"GPAW implements Density Functional Theory using a\n"<br />

"Grid-based real-space representation of the wave\n"<br />

"functions, and the Projector Augmented Wave\n"<br />

"method for handling the core regions. \n"<br />

msgstr ""<br />

"GPAW implementerer tæthedsfunktionalteori med en Gitterbaseret\n"<br />

"repræsentation af bølgefunktioner i det reelle rum, samt\n"<br />

"Projector Augmented Wave-metoden til behandling\n"<br />

"af regionen omkring atomkerner. \n"<br />

If you are maintaining an existing translation, there may be some “fuzzy” messages. These are translations that<br />

were written previously but now need to be reviewed, maybe because the original string has been slightly modified.<br />

Edit them as appropriate and remove the “fuzzy” flag.<br />

There will be a few special constructs such as string substitution codes %(number)d or %s. These should remain<br />

unchanged in the translation as they are replaced by numbers or text at runtime. An underscore like in msgid<br />

"_File" indicates that F is a shortcut key. Conflicting shortcut keys are not a big problem, but avoid them if you<br />

see them. Finally, some messages may have a lot of whitespace in them. This is due to bad programming style;<br />

just try to get approximately the same spacing in your translation.<br />

Already after writing a few translations, you can check that the translation works as expected by following the<br />

instructions in the next section.<br />

Check and commit your translation<br />

• You can check the syntax by running msgfmt -cv ag.po. This will report any syntax errors.<br />

• You can test your translation in ag directly. First issue the command make in ase/gui/po, then reinstall<br />

<strong>ASE</strong> using the usual procedure. The translations will then be in the newly installed <strong>ASE</strong>. If you translate into<br />

the same language as your computer’s locale, you should see the translations when you start ag normally. If<br />

196 Chapter 11. <strong>ASE</strong> development


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

you translate <strong>ASE</strong> into another language, then run LANG=ll_LL.UTF-8 ag. On some operating systems<br />

you may need to run LANGUAGE=ll_LL.UTF-8 ag instead.<br />

Depending on your operating system, you may need to install gettext or locales.<br />

Send the partially or completely translated po-file to the developers mailing list and ask to have it committed. In<br />

fact, we will be quite thrilled if you send an e-mail even before you start, and be sure to send one whenever you<br />

have questions.<br />

Note: Certain uncommon languages such as Lojban, Anglo-Saxon or Klingon may not be compatible with our<br />

current build system. Please let us know if you want to translate <strong>ASE</strong> into such languages.<br />

Maintaining translations<br />

Messages will once in a while be added or changed in the <strong>ASE</strong>. Running make in ase/gui/po automatically<br />

synchronizes all templates with the messages in the current source tree while maximally reusing the existing<br />

translations. Some strings may be marked “fuzzy”, indicating that they need review by translators (this happens<br />

e.g. if an English message is changed only slightly). One can then update the few fuzzy or untranslated messages.<br />

The obvious time to do this is shortly before a new stable release.<br />

If you are a committer, please run make before committing and briefly check by running the translated ag that<br />

nothing is obviously horrible.<br />

11.1.11 To do<br />

Check our issue tracker.<br />

Documentation<br />

Code<br />

• Put example of Verlet dynamics in ase/md<br />

• talk about writing files - pos, py and pckl<br />

• Write more about the parameters of the supported elements of the EMT calculator.<br />

• Could the directions argument of ase.lattice.FaceCenteredCubic etc. have default values?<br />

11.2 Creating an encrypted password for SVN access<br />

Use this cammand:<br />

htpasswd -nm <br />

and type a good password twice. The encrypted password will be printed on the screen.<br />

If you don’t have the htpasswd command, then use Python:<br />

>>> import crypt<br />

>>> passwd = ’’<br />

>>> print crypt.crypt(passwd, passwd)<br />

11.2. Creating an encrypted password for SVN access 197


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

198 Chapter 11. <strong>ASE</strong> development


CHAPTER<br />

TWELVE<br />

BUGS!<br />

If you find a bug in the <strong>ASE</strong> software, please report it to the developers so it can be fixed. We need that feedback<br />

from the community to maintain the quality of the code.<br />

12.1 Bug report<br />

• If you are unsure if it is a real bug, or a usage problem, it is probably best to report the problem on the<br />

ase-users mailing list (see Mailing Lists).<br />

Please provide the failing script as well as the information about your environment (processor architecture,<br />

versions of python and numpy). Then we (or other users) can help you to find out if it is a bug.<br />

Another advantage of reporting bugs on the mailing list: often other users will tell you how to work around<br />

the bug (until it is solved).<br />

• If you think it is a bug, you can also report it directly on our bug tracking system. The advantage of reporting<br />

bugs here is that it is not forgotten (which may be a risk on the mailing list).<br />

We do not guarantee to fix all bugs, but we will do our best.<br />

12.2 Known bugs<br />

A list of known bugs (tickets) is on our Trac.<br />

199


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

200 Chapter 12. Bugs!


CHAPTER<br />

THIRTEEN<br />

PORTING OLD <strong>ASE</strong>-2 CODE TO<br />

VERSION 3<br />

The old Numeric-Python based <strong>ASE</strong>-2 can coexist with the new numpy-based <strong>ASE</strong>-3, because the two packages<br />

have different names: <strong>ASE</strong> and ase respectively. Here is an example of combining both:<br />

from <strong>ASE</strong>.Trajectories.NetCDFTrajectory import NetCDFTrajectory<br />

traj = NetCDFTrajectory(’a.nc’)<br />

loa = traj.GetListOfAtoms(-1)<br />

# Convert to new style Atoms object:<br />

from ase import *<br />

a = Atoms(loa)<br />

The new <strong>ASE</strong> can actually read old NetCDF trajectory files, so this would be simpler:<br />

from ase import *<br />

a = read(’a.nc’)<br />

Note: Reading old NetCDF files in the new <strong>ASE</strong>, works even without having the libnetcdf and<br />

Scientific.IO.NetCDF libraries installed.<br />

13.1 The <strong>ASE</strong>2ase tool<br />

Use the <strong>ASE</strong>2ase tool (source code tools/<strong>ASE</strong>2ase) to convert old scripts:<br />

$ <strong>ASE</strong>2ase oldscript.py<br />

$ diff -u oldscript.py.bak oldscript.py<br />

Check that the differences look OK. The conversion tool isn’t clever enough to get everything right, so you will<br />

have to do some conversion manually also. If you have any problems doing this, then you should not hesitate to<br />

contact the campos-devel mailing list (see Mailing Lists) and ask for help.<br />

201


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

202 Chapter 13. Porting old <strong>ASE</strong>-2 code to version 3


BIBLIOGRAPHY<br />

[Alfe] D. Alfe, PHON: A program to calculate phonons using the small displacement method, Comput. Phys.<br />

Commun. 180, 2622 (2009)<br />

[Wang] Y. Wang et al., A mixed-space approach to first-principles calculations of phonon frequencies for polar<br />

materials, J. Phys.: Cond. Matter 22, 202201 (2010)<br />

[MonkhorstPack] Hendrik J. Monkhorst and James D. Pack: Special points for Brillouin-zone integrations, Phys.<br />

Rev. B 13, 5188–5192 (1976)<br />

[Bader] R. F. W. Bader. Atoms in Molecules: A Quantum Theory. Oxford University Press, New York, 1990.<br />

[Tang] W. Tang, E. Sanville, G. Henkelman. A grid-based Bader analysis algorithm without lattice bias. J. Phys.:<br />

Compute Mater. 21, 084204 (2009).<br />

[Cordeo08] Covalent radii revisited, Beatriz Cordero, Verónica Gómez, Ana E. Platero-Prats, Marc Revés,<br />

Jorge Echeverría, Eduard Cremades, Flavia Barragán and Santiago Alvarez, Dalton Trans., 2008, 2832-2838<br />

DOI:10.1039/B801115J<br />

203


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

204 Bibliography


a<br />

abinit, 112<br />

ase, 51<br />

ase.atom, 65<br />

ase.dft, 162<br />

ase.io.trajectory, 169<br />

ase.lattice.surface, 86<br />

atoms, 53<br />

b<br />

basics, 72<br />

c<br />

calculate, 79<br />

calculators, 109<br />

castep, 131<br />

constraints, 139<br />

d<br />

data, 166<br />

dft, 156<br />

dft.dos, 161<br />

dft.kpoints, 156<br />

dft.stm, 162<br />

dft.wannier, 157<br />

dftb, 117<br />

e<br />

edit, 75<br />

emt, 111<br />

exciting, 128<br />

f<br />

FHI-aims, 124<br />

fleur, 129<br />

g<br />

gromacs, 134<br />

gui, 72<br />

i<br />

infrared, 149<br />

io, 67<br />

j<br />

jacapo, 111<br />

PYTHON MODULE INDEX<br />

l<br />

lammps, 126<br />

lattice, 93<br />

lattice.spacegroup, 23<br />

m<br />

md, 152<br />

md.langevin, 153<br />

md.npt, 154<br />

md.nptberendsen, 155<br />

md.nvtberendsen, 154<br />

md.verlet, 153<br />

mmtk, 127<br />

n<br />

neb, 143<br />

o<br />

optimize, 98<br />

optimize.basin, 101<br />

optimize.bfgslinesearch, 101<br />

optimize.fire, 99<br />

optimize.lbfgs, 99<br />

optimize.mdmin, 100<br />

optimize.qn, 98<br />

optimize.sciopt, 100<br />

p<br />

parallel, 102<br />

phonons, 147<br />

s<br />

setup, 78<br />

siesta, 114<br />

structure, 83<br />

t<br />

test, 194<br />

thermochemistry, 173<br />

tools, 76<br />

transport, 165<br />

turbomole, 119<br />

u<br />

units, 66<br />

205


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

utils, 172<br />

v<br />

vasp, 122<br />

vibrations, 145<br />

view, 75<br />

visualize, 103<br />

visualize.vtk, 103<br />

vtk, 107<br />

206 Python Module Index


Symbols<br />

$HOME, 9<br />

$PATH, 191<br />

$PYTHONPATH, 191<br />

A<br />

Abinit (class in abinit), 113<br />

abinit (module), 112<br />

ABINIT_PP_PATH, 112<br />

ABINIT_SCRIPT, 112<br />

add_adsorbate() (in module ase.lattice.surface), 90<br />

add_axes() (ase.visualize.vtk.atoms.vtkAtoms method),<br />

108<br />

add_cell() (ase.visualize.vtk.atoms.vtkAtoms method),<br />

108<br />

add_forces() (ase.visualize.vtk.atoms.vtkAtoms<br />

method), 108<br />

Atoms (class in ase.atoms), 58<br />

atoms (module), 53<br />

INDEX<br />

B<br />

basics (module), 72<br />

bcc100() (in module ase.lattice.surface), 87<br />

bcc110() (in module ase.lattice.surface), 88<br />

bcc111() (in module ase.lattice.surface), 88<br />

build() (ase.calculators.neighborlist.NeighborList<br />

method), 138<br />

Bulk modulus, 172<br />

bulk() (in module ase.structure), 83<br />

BundleTrajectory (class in ase.io.bundletrajectory), 170<br />

C<br />

calc (ase.atoms.Atoms attribute), 59<br />

calculate (module), 79<br />

add_scalar_property() (ase.visualize.vtk.grid.vtkAtomicPositions calculate() (ase.calculators.fleur.FLEUR method), 130<br />

method), 108<br />

calculation_required() (ase.calculators.interface.Calculator<br />

add_vector_property() (ase.visualize.vtk.grid.vtkAtomicPositions method), 136<br />

method), 109<br />

Calculator (class in ase.calculators.interface), 136<br />

add_velocities() (ase.visualize.vtk.atoms.vtkAtoms calculators (module), 109<br />

method), 108<br />

Castep (class in castep), 131<br />

adjust_forces() (in module constraints), 142<br />

castep (module), 131<br />

adjust_positions() (in module constraints), 142 cell (ase.atoms.Atoms attribute), 59<br />

ag, 72<br />

center() (ase.atoms.Atoms method), 59<br />

Aims (class in FHI-aims), 124<br />

chemical_symbols (in module data), 166<br />

AimsCube (class in FHI-aims), 126<br />

Class, 181<br />

API, 181<br />

close() (ase.io.bundletrajectory.BundleTrajectory<br />

append() (ase.atoms.Atoms method), 59<br />

method), 171<br />

<strong>ASE</strong>, 181<br />

close() (ase.io.trajectory.PickleTrajectory method), 169<br />

ase, 79<br />

constraints (ase.atoms.Atoms attribute), 59<br />

ase (module), 51<br />

constraints (module), 139<br />

ase-gui, 72<br />

Constructor, 181<br />

ase.atom (module), 65<br />

copy() (ase.atoms.Atoms method), 59<br />

ase.dft (module), 162<br />

covalent_radii (in module data), 166<br />

ase.io.trajectory (module), 169<br />

cpk_colors (in module data), 166<br />

ase.lattice.surface (module), 86<br />

ase.transport.calculators.TransportCalculator (class in D<br />

transport), 166<br />

<strong>ASE</strong>2ase, 201<br />

assert() (in module test), 195<br />

Atom (class in ase.atom), 65<br />

atomic_masses (in module data), 166<br />

atomic_names (in module data), 166<br />

atomic_numbers (in module data), 167<br />

data (module), 166<br />

delete_bundle() (ase.io.bundletrajectory.BundleTrajectory<br />

class method), 171<br />

DFT, 181<br />

dft (module), 156<br />

dft.dos (module), 161<br />

207


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

dft.kpoints (module), 156<br />

dft.kpoints.cc12_2x3 (in module dft.kpoints), 157<br />

dft.kpoints.cc162_1x1 (in module dft.kpoints), 157<br />

dft.kpoints.cc162_sq3xsq3 (in module dft.kpoints), 157<br />

dft.kpoints.cc18_1x1 (in module dft.kpoints), 157<br />

dft.kpoints.cc18_sq3xsq3 (in module dft.kpoints), 157<br />

dft.kpoints.cc54_1x1 (in module dft.kpoints), 157<br />

dft.kpoints.cc54_sq3xsq3 (in module dft.kpoints), 157<br />

dft.kpoints.cc6_1x1 (in module dft.kpoints), 157<br />

dft.stm (module), 162<br />

dft.wannier (module), 157<br />

dftb (module), 117<br />

DFTCalculator (class in ase.calculators.interface), 137<br />

diamond100() (in module ase.lattice.surface), 87<br />

diamond111() (in module ase.lattice.surface), 89<br />

Docstring, 181<br />

DOS (class in ase.dft.dos), 162<br />

E<br />

edit (module), 75<br />

edit() (ase.atoms.Atoms method), 59<br />

EMT, 181<br />

EMT (class in emt), 111<br />

emt (module), 111<br />

environment variable<br />

$HOME, 9<br />

$PATH, 191<br />

$PYTHONPATH, 191<br />

ABINIT_PP_PATH, 112<br />

ABINIT_SCRIPT, 112<br />

FLEUR, 129<br />

FLEUR_INPGEN, 129<br />

HOME, 13<br />

LAMMPS_COMMAND, 127<br />

PATH, 13, 188<br />

PYTHONPATH, 13, 18, 188<br />

PYTHONSTARTUP, 16<br />

SIESTA_PP_PATH, 114<br />

SIESTA_SCRIPT, 114<br />

VASP_PP_PATH, 122<br />

VASP_SCRIPT, 122<br />

EquationOfState (class in ase.utils.eos), 172<br />

Exciting (class in ase.calculators.exciting), 128<br />

Exciting (class in exciting), 128<br />

exciting (module), 128<br />

extend() (ase.atoms.Atoms method), 59<br />

F<br />

fcc100() (in module ase.lattice.surface), 87<br />

fcc110() (in module ase.lattice.surface), 87<br />

fcc111() (in module ase.lattice.surface), 88<br />

FHI-aims (module), 124<br />

FieldPlotter (class in ase.visualize.fieldplotter), 106<br />

Filter (class in constraints), 142<br />

FixAtoms (class in constraints), 139<br />

FixBondLength (class in constraints), 139<br />

FixBondLengths (class in constraints), 140<br />

FixedLine (class in ase.constraints), 140<br />

FixedMode (class in ase.constraints), 140<br />

FixedPlane (class in ase.constraints), 140<br />

FixInternals (class in constraints), 141<br />

FLEUR, 129<br />

fleur (module), 129<br />

FLEUR_INPGEN, 129<br />

G<br />

get_actor() (ase.visualize.vtk.module.vtkGlyphModule<br />

method), 109<br />

get_angle() (ase.atoms.Atoms method), 59<br />

get_angular_momentum() (ase.atoms.Atoms method),<br />

60<br />

get_array() (ase.atoms.Atoms method), 60<br />

get_atomic_numbers() (ase.atoms.Atoms method), 60<br />

get_bz_k_points() (ase.calculators.interface.DFTCalculator<br />

method), 137<br />

get_calculation_done() (ase.atoms.Atoms method), 60<br />

get_calculator() (ase.atoms.Atoms method), 60<br />

get_cell() (ase.atoms.Atoms method), 60<br />

get_celldisp() (ase.atoms.Atoms method), 60<br />

get_center_of_mass() (ase.atoms.Atoms method), 60<br />

get_centers() (ase.dft.wannier.Wannier method), 159<br />

get_charges() (ase.atoms.Atoms method), 60<br />

get_chemical_formula() (ase.atoms.Atoms method), 60<br />

get_chemical_symbols() (ase.atoms.Atoms method),<br />

60<br />

get_dihedral() (ase.atoms.Atoms method), 60<br />

get_dipole_moment() (ase.atoms.Atoms method), 60<br />

get_distance() (ase.atoms.Atoms method), 60<br />

get_distribution_moment() (in module ase.dft), 162<br />

get_dos() (ase.dft.dos.DOS method), 162<br />

get_effective_potential()<br />

(ase.calculators.interface.DFTCalculator<br />

method), 137<br />

get_eigenvalues() (ase.calculators.interface.DFTCalculator<br />

method), 137<br />

get_energies() (ase.dft.dos.DOS method), 162<br />

get_energies() (ase.vibrations.Vibrations method), 146<br />

get_enthalpy() (ase.thermochemistry.IdealGasThermo<br />

method), 174<br />

get_entropy() (ase.thermochemistry.HarmonicThermo<br />

method), 175<br />

get_entropy() (ase.thermochemistry.IdealGasThermo<br />

method), 174<br />

get_fermi_level() (ase.calculators.interface.DFTCalculator<br />

method), 137<br />

get_forces() (ase.atoms.Atoms method), 61<br />

get_forces() (ase.calculators.interface.Calculator<br />

method), 136<br />

get_free_energy() (ase.thermochemistry.HarmonicThermo<br />

method), 175<br />

get_free_energy() (ase.thermochemistry.IdealGasThermo<br />

method), 174<br />

get_frequencies() (ase.vibrations.Vibrations method),<br />

146<br />

get_function() (ase.dft.wannier.Wannier method), 159<br />

208 Index


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

get_functional_value() (ase.dft.wannier.Wannier<br />

method), 137<br />

method), 159<br />

get_radii() (ase.dft.wannier.Wannier method), 160<br />

get_hamiltonian() (ase.dft.wannier.Wannier method), get_reciprocal_cell() (ase.atoms.Atoms method), 61<br />

159<br />

get_scaled_positions() (ase.atoms.Atoms method), 61<br />

get_hamiltonian_kpoint() (ase.dft.wannier.Wannier get_spectrum() (ase.infrared.InfraRed method), 151<br />

method), 159<br />

get_spin_polarized() (ase.calculators.interface.DFTCalculator<br />

get_hopping() (ase.dft.wannier.Wannier method), 160<br />

method), 137<br />

get_ibz_k_points() (ase.calculators.interface.DFTCalculator get_stress() (ase.atoms.Atoms method), 61<br />

method), 137<br />

get_stress() (ase.calculators.interface.Calculator<br />

get_initial_magnetic_moments() (ase.atoms.Atoms<br />

method), 136<br />

method), 61<br />

get_stresses() (ase.atoms.Atoms method), 62<br />

get_internal_energy() (ase.thermochemistry.HarmonicThermo get_tags() (ase.atoms.Atoms method), 62<br />

method), 175<br />

get_temperature() (ase.atoms.Atoms method), 62<br />

get_isotropic_pressure() (ase.atoms.Atoms method), 61 get_total_energy() (ase.atoms.Atoms method), 62<br />

get_k_point_weights() (ase.calculators.interface.DFTCalculator get_unstructured_grid()<br />

method), 137<br />

(ase.visualize.vtk.grid.vtkAtomicPositions<br />

get_kinetic_energy() (ase.atoms.Atoms method), 61<br />

method), 109<br />

get_magnetic_moment() (ase.atoms.Atoms method), get_velocities() (ase.atoms.Atoms method), 62<br />

61<br />

get_volume() (ase.atoms.Atoms method), 62<br />

get_magnetic_moment()<br />

get_wannier_localization_matrix()<br />

(ase.calculators.interface.DFTCalculator<br />

(ase.calculators.interface.DFTCalculator<br />

method), 137<br />

method), 138<br />

get_magnetic_moments() (ase.atoms.Atoms method), get_xc_functional() (ase.calculators.interface.DFTCalculator<br />

61<br />

method), 138<br />

get_masses() (ase.atoms.Atoms method), 61<br />

graphene_nanoribbon() (in module ase.structure), 84<br />

get_momenta() (ase.atoms.Atoms method), 61 gromacs (module), 134<br />

get_moments_of_inertia() (ase.atoms.Atoms method), gui, 72<br />

61<br />

gui (module), 72<br />

get_monkhorst_pack_size_and_offset()<br />

ase.dft.kpoints), 156<br />

(in module<br />

H<br />

get_neighbors() (ase.calculators.neighborlist.NeighborListHarmonicThermo<br />

(class in ase.thermochemistry), 175<br />

method), 138<br />

has() (ase.atoms.Atoms method), 62<br />

get_number_of_atoms() (ase.atoms.Atoms method), 61 hcp0001() (in module ase.lattice.surface), 88<br />

get_number_of_bands()<br />

hcp10m10() (in module ase.lattice.surface), 87<br />

(ase.calculators.interface.DFTCalculator HF, 181<br />

method), 137<br />

HOME, 13<br />

get_number_of_grid_points()<br />

(ase.calculators.interface.DFTCalculator I<br />

method), 137<br />

IdealGasThermo (class in ase.thermochemistry), 173<br />

get_number_of_spins()<br />

InfraRed (class in ase.infrared), 150<br />

(ase.calculators.interface.DFTCalculator infrared (module), 149<br />

method), 137<br />

initial_wannier() (ase.calculators.interface.DFTCalculator<br />

get_occupation_numbers()<br />

method), 138<br />

(ase.calculators.interface.DFTCalculator initialize() (ase.dft.wannier.Wannier method), 160<br />

method), 137<br />

initialize_density() (ase.calculators.fleur.FLEUR<br />

get_pbc() (ase.atoms.Atoms method), 61<br />

method), 130<br />

get_pdos() (ase.dft.wannier.Wannier method), 160 Instance, 181<br />

get_points() (ase.visualize.vtk.grid.vtkAtomicPositions interpolate() (neb.NEB method), 143<br />

method), 109<br />

io (module), 67<br />

get_positions() (ase.atoms.Atoms method), 61 is_bundle() (ase.io.bundletrajectory.BundleTrajectory<br />

get_potential_energies() (ase.atoms.Atoms method), 61<br />

static method), 171<br />

get_potential_energy() (ase.atoms.Atoms method), 61 is_empty_bundle() (ase.io.bundletrajectory.BundleTrajectory<br />

get_potential_energy() (ase.calculators.interface.Calculator static method), 171<br />

method), 136<br />

get_pseudo_density() (ase.calculators.interface.DFTCalculator J<br />

method), 137<br />

Jacapo (class in jacapo), 111<br />

get_pseudo_wave_function()<br />

jacapo (module), 111<br />

(ase.calculators.interface.DFTCalculator<br />

Index 209


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

L<br />

LAMMPS (class in lammps), 127<br />

lammps (module), 126<br />

LAMMPS_COMMAND, 127<br />

Langevin (class in md.langevin), 153<br />

LAPW, 181<br />

lattice (module), 93<br />

lattice.spacegroup (module), 23<br />

localize() (ase.dft.wannier.Wannier method), 160<br />

log() (ase.io.bundletrajectory.BundleTrajectory<br />

method), 171<br />

log() (ase.visualize.fieldplotter.FieldPlotter method),<br />

106<br />

log() (ase.visualize.primiplotter.PrimiPlotter method),<br />

105<br />

M<br />

max_spread() (ase.dft.wannier.Wannier method), 160<br />

md (module), 152<br />

md.langevin (module), 153<br />

md.npt (module), 154<br />

md.nptberendsen (module), 155<br />

md.nvtberendsen (module), 154<br />

md.verlet (module), 153<br />

Method, 181<br />

MMTK (class in mmtk), 127<br />

mmtk (module), 127<br />

molecule() (in module ase.data.molecules), 97<br />

monkhorst_pack() (in module ase.dft.kpoints), 156<br />

N<br />

Namespace, 181<br />

nanotube() (in module ase.structure), 84<br />

ndarray, 181<br />

NEB (class in ase.neb), 143<br />

neb (module), 143<br />

NeighborList (class in ase.calculators.neighborlist), 138<br />

new_array() (ase.atoms.Atoms method), 62<br />

NPT (class in md.npt), 154<br />

NPTBerendsen (class in md.nptberendsen), 155<br />

numbers (ase.atoms.Atoms attribute), 62<br />

NumPy, 181<br />

NVTBerendsen (class in md.nvtberendsen), 154<br />

O<br />

open() (ase.io.trajectory.PickleTrajectory method), 169<br />

optimize (module), 98<br />

optimize.basin (module), 101<br />

optimize.bfgslinesearch (module), 101<br />

optimize.fire (module), 99<br />

optimize.lbfgs (module), 99<br />

optimize.mdmin (module), 100<br />

optimize.qn (module), 98<br />

optimize.sciopt (module), 100<br />

P<br />

parallel (module), 102<br />

paropen() (in module ase.parallel), 102<br />

parprint() (in module ase.parallel), 102<br />

PATH, 13, 188<br />

pbc (ase.atoms.Atoms attribute), 62<br />

phonons (module), 147<br />

PickleTrajectory (class in ase.io.trajectory), 169<br />

plot() (ase.visualize.fieldplotter.FieldPlotter method),<br />

106<br />

plot() (ase.visualize.primiplotter.PrimiPlotter method),<br />

105<br />

pop() (ase.atoms.Atoms method), 62<br />

positions (ase.atoms.Atoms attribute), 62<br />

post_write_attach() (ase.io.bundletrajectory.BundleTrajectory<br />

method), 171<br />

post_write_attach() (ase.io.trajectory.PickleTrajectory<br />

method), 169<br />

pre_write_attach() (ase.io.bundletrajectory.BundleTrajectory<br />

method), 171<br />

pre_write_attach() (ase.io.trajectory.PickleTrajectory<br />

method), 169<br />

PrimiPlotter (class in ase.visualize.primiplotter), 104<br />

Python, 181<br />

PYTHONPATH, 13, 18, 188<br />

PYTHONSTARTUP, 16<br />

R<br />

rattle() (ase.atoms.Atoms method), 62<br />

read() (in module ase.io), 67<br />

read_cube_data() (in module io), 70<br />

read_extra_data() (ase.io.bundletrajectory.BundleTrajectory<br />

method), 171<br />

reference_states (in module data), 167<br />

relax() (ase.calculators.fleur.FLEUR method), 130<br />

repeat() (ase.atoms.Atoms method), 62<br />

rotate() (ase.atoms.Atoms method), 62<br />

rotate_dihedral() (ase.atoms.Atoms method), 63<br />

rotate_euler() (ase.atoms.Atoms method), 63<br />

run() (ase.vibrations.Vibrations method), 146<br />

S<br />

save() (ase.dft.wannier.Wannier method), 160<br />

SciPyFminBFGS (class in ase.optimize.sciopt), 100<br />

SciPyFminCG (class in ase.optimize.sciopt), 100<br />

Scope, 181<br />

select_data() (ase.io.bundletrajectory.BundleTrajectory<br />

method), 171<br />

set_actor() (ase.visualize.vtk.module.vtkGlyphModule<br />

method), 109<br />

set_angle() (ase.atoms.Atoms method), 63<br />

set_array() (ase.atoms.Atoms method), 63<br />

set_atomic_numbers() (ase.atoms.Atoms method), 63<br />

set_atoms() (ase.calculators.interface.Calculator<br />

method), 137<br />

set_atoms() (ase.io.trajectory.PickleTrajectory<br />

method), 170<br />

set_background() (ase.visualize.fieldplotter.FieldPlotter<br />

method), 106<br />

210 Index


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

set_background_color()<br />

set_rotation() (ase.visualize.fieldplotter.FieldPlotter<br />

(ase.visualize.fieldplotter.FieldPlotter<br />

method), 107<br />

method), 106<br />

set_rotation() (ase.visualize.primiplotter.PrimiPlotter<br />

set_black_white_colors()<br />

method), 106<br />

(ase.visualize.fieldplotter.FieldPlotter set_scaled_positions() (ase.atoms.Atoms method), 64<br />

method), 106<br />

set_tags() (ase.atoms.Atoms method), 64<br />

set_calculator() (ase.atoms.Atoms method), 63 set_velocities() (ase.atoms.Atoms method), 64<br />

set_cell() (ase.atoms.Atoms method), 63<br />

setup (module), 78<br />

set_charges() (ase.atoms.Atoms method), 64<br />

Siesta (class in siesta), 114<br />

set_chemical_symbols() (ase.atoms.Atoms method), 64 siesta (module), 114<br />

set_color_function() (ase.visualize.fieldplotter.FieldPlotterSIESTA_PP_PATH,<br />

114<br />

method), 106<br />

SIESTA_SCRIPT, 114<br />

set_color_function() (ase.visualize.primiplotter.PrimiPlotter structure (module), 83<br />

method), 105<br />

summary() (ase.vibrations.Vibrations method), 146<br />

set_colors() (ase.visualize.primiplotter.PrimiPlotter<br />

method), 105<br />

T<br />

set_constraint() (ase.atoms.Atoms method), 64 test, 13<br />

set_data_range() (ase.visualize.fieldplotter.FieldPlotter test (module), 194<br />

method), 106<br />

test.test() (in module test), 195<br />

set_dihedral() (ase.atoms.Atoms method), 64<br />

testase, 194<br />

set_dimensions() (ase.visualize.fieldplotter.FieldPlotter thermochemistry (module), 173<br />

method), 107<br />

tools (module), 76<br />

set_dimensions() (ase.visualize.primiplotter.PrimiPlotter translate() (ase.atoms.Atoms method), 64<br />

method), 105<br />

translate() (ase.dft.wannier.Wannier method), 160<br />

set_distance() (ase.atoms.Atoms method), 64<br />

translate_all_to_cell() (ase.dft.wannier.Wannier<br />

set_extra_data() (ase.io.bundletrajectory.BundleTrajectory method), 160<br />

method), 171<br />

translate_to_cell() (ase.dft.wannier.Wannier method),<br />

set_initial_magnetic_moments() (ase.atoms.Atoms<br />

160<br />

method), 64<br />

transport (module), 165<br />

set_invisibility_function()<br />

turbomole (module), 119<br />

(ase.visualize.fieldplotter.FieldPlotter<br />

method), 107<br />

U<br />

set_invisibility_function()<br />

(ase.visualize.primiplotter.PrimiPlotter<br />

method), 105<br />

set_invisible() (ase.visualize.fieldplotter.FieldPlotter<br />

method), 107<br />

set_invisible() (ase.visualize.primiplotter.PrimiPlotter<br />

method), 105<br />

set_log() (ase.visualize.fieldplotter.FieldPlotter<br />

method), 107<br />

units (module), 66<br />

update() (ase.calculators.neighborlist.NeighborList<br />

method), 138<br />

update() (ase.visualize.fieldplotter.FieldPlotter<br />

method), 107<br />

update() (ase.visualize.primiplotter.PrimiPlotter<br />

method), 106<br />

utils (module), 172<br />

set_log() (ase.visualize.primiplotter.PrimiPlotter V<br />

method), 105<br />

Vasp (class in vasp), 122<br />

set_masses() (ase.atoms.Atoms method), 64<br />

vasp (module), 122<br />

set_momenta() (ase.atoms.Atoms method), 64<br />

VASP_PP_PATH, 122<br />

set_pbc() (ase.atoms.Atoms method), 64<br />

VASP_SCRIPT, 122<br />

set_plot_plane() (ase.visualize.fieldplotter.FieldPlotter<br />

vdw_radii (in module data), 167<br />

method), 107<br />

VelocityVerlet (class in md.verlet), 153<br />

set_positions() (ase.atoms.Atoms method), 64<br />

Vibrations (class in ase.vibrations), 145<br />

set_property() (ase.visualize.vtk.module.vtkGlyphModule<br />

vibrations (module), 145<br />

method), 109<br />

view (module), 75<br />

set_radii() (ase.visualize.fieldplotter.FieldPlotter<br />

view() (in module visualize), 103<br />

method), 107<br />

visualize (module), 103<br />

set_radii() (ase.visualize.primiplotter.PrimiPlotter<br />

visualize.vtk (module), 103<br />

method), 106<br />

vtk, 107<br />

set_red_yellow_colors()<br />

vtk (module), 107<br />

(ase.visualize.fieldplotter.FieldPlotter<br />

vtkAtomicPositions (class in ase.visualize.vtk.grid),<br />

method), 107<br />

108<br />

Index 211


<strong>ASE</strong> <strong>Manual</strong>, <strong>Release</strong> 3.6.1.2828<br />

vtkAtoms (class in ase.visualize.vtk.atoms), 107<br />

vtkGlyphModule (class in ase.visualize.vtk.module),<br />

109<br />

W<br />

Wannier (class in ase.dft.wannier), 158<br />

write() (ase.atoms.Atoms method), 65<br />

write() (ase.io.bundletrajectory.BundleTrajectory<br />

method), 172<br />

write() (ase.io.trajectory.PickleTrajectory method), 170<br />

write() (in module ase.io), 68<br />

write_cube() (ase.dft.wannier.Wannier method), 160<br />

write_inp() (ase.calculators.fleur.FLEUR method), 130<br />

write_jmol() (ase.vibrations.Vibrations method), 147<br />

write_mode() (ase.vibrations.Vibrations method), 147<br />

write_spectra() (ase.infrared.InfraRed method), 151<br />

212 Index

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!