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