# Reading and Writing FHI-aims files; ASE atoms object¶

Note

The demonstrations in this part of the tutorial are done in Python REPL, with >>> being its prompt. We will assume you have the following geometry.in in your current folder:

lattice_vector 0.00000 1.77999 1.77999
lattice_vector 1.77999 0.00000 1.77999
lattice_vector 1.77999 1.77999 0.00000

atom_frac 0.00000 0.00000 0.00000 C
atom_frac 0.25000 0.25000 0.25000 C


ASE will read any file with *.in extension as being an FHI-aims geometry file. You can simply read a file by:

>>> from ase.io import read
Atoms(symbols='C2', pbc=True, cell=[[0.0, 1.77999, 1.77999], [1.77999, 0.0, 1.77999], [1.77999, 1.77999, 0.0]])

The above statement creates an ASE atoms object, which has many helpful methods available. With the aid of the ASE atoms object you can get many important properties in single-line statements, e.g. atom positions in cartesian and fractional coordinates, the lattice parameters, the volume of the cell, reciprocal cell, as it's shown in the following example:
>>> structure = read('geometry.in')
>>> structure.get_positions()
array([[0.      , 0.      , 0.      ],
[0.889995, 0.889995, 0.889995]])
>>> structure.get_scaled_positions()
array([[0.  , 0.  , 0.  ],
[0.25, 0.25, 0.25]])
>>> structure.cell.cellpar()
array([ 2.517286,  2.517286,  2.517286, 60.      , 60.      , 60.      ])
>>> structure.get_volume()
11.279313897067997
>>> structure.cell.reciprocal()
Cell([[-0.28090045449693557, 0.2809004544969354, 0.28090045449693535], [0.2809004544969353, -0.2809004544969353, 0.2809004544969355], [0.28090045449693546, 0.28090045449693535, -0.28090045449693535]])


You can also modify it, for example change composition, lattice vectors, create a supercell, add magnetic moments to atoms and much more (cf. documentation):

# expand the structure volume by 15%, elongating each lattice vector by 1.15^(1/3) = 1.05
# with scaling the atomic coordinates
>>> structure.set_cell(structure.cell * 1.05, scale_atoms=True)
>>> structure
Atoms(symbols='C2', pbc=True, cell=[[0.0, 1.8689895, 1.8689895], [1.8689895, 0.0, 1.8689895], [1.8689895, 1.8689895, 0.0]])
>>> structure.get_scaled_positions()
array([[0.  , 0.  , 0.  ],
[0.25, 0.25, 0.25]])
# Make a 2x2x2 supercell
>>> structure *= (2, 2, 2)
>>> structure
Atoms(symbols='C16', pbc=True, cell=[[0.0, 3.737979, 3.737979], [3.737979, 0.0, 3.737979], [3.737979, 3.737979, 0.0]])
# Change one of the atoms to hydrogen
>>> structure.symbols[1] = 'H'
>>> structure
Atoms(symbols='CHC14', pbc=True, cell=[[0.0, 3.737979, 3.737979], [3.737979, 0.0, 3.737979], [3.737979, 3.737979, 0.0]])


Per-atom quantities, such as magnetic moments, should be set as an iterable with its length equal to the number of atoms. Collinear spin calculations require setting initial magnetic moments to drive the result away from the paramagnetic solution.

With the same syntax, you can also import geometries of different format (e.g. VASP, quantum espresso, etc.). The list of supported codes indicates whether the format is supported.

To learn all about the available Atoms object methods we refer to the ASE Getting started tutorial.

Writing FHI-aims geometry files is as simple as reading them

>>> structure.write('geometry-from-ase.in', scaled=True)
# If you look into your directory you'll find a new filed named geometry-from-ase.in!

This writes the atoms object structure to the file geometry.in in the aims format (determined by the file extension) in fractional coordinates. Format can also be passed explicitly:
>>> structure.write('POSCAR', format='aims', scaled=True)


This will print out the structure object in the POSCAR file in FHI-aims format.