The FHI-AIMS code offers to output the grid data either as CUBE or as XSF files. However, the structure of data in those XSF files is somewhat different from what one gets from VASP by applying the v2xsf tool on a LOCPOT or CHGCAR file. The loadXSF and loadXSFGeom functions need to be modified in order to read the FHI-AIMS data correctly. Essentially, the grid data in the FHI-AIMS generated XSF files, including the grid dimensions and the ordering of the data points, are the same as they would be in the corresponding CUBE files (except that lengths are fortunately still expressed in angstrom, not bohr, in XSF). The consequences can be summarized into the following three points:
- Even for periodic systems, the grid dimensions need not be the same as the dimensions of the periodic cell. The default behavior for periodic systems, if you do not specify anything to the contrary in the
control.in file, is still such that the grid covers the whole unit cell. However, a grid covering the unit cell means something slightly different for FHI-AIMS compared to what it means for VASP. There are no repeated data points at the unit cell boundary in FHI-AIMS like there would be in the XSF output from VASP. The first and the last point along an axis are not identical. The logic of FHI-AIMS is that the positions of nodes that form the grid are centers of the corresponding "voxels", which implies that the first and last point (node) along a particular axis do not in fact lie right on the cell boundary but they are shifted by half the voxel size (=half the grid step). Let me illustrate this by a concrete example: Suppose we have a 10x10x10 cell, which we want to sample with a grid in which the neighboring points are separated by the step of 0.1. The corresponding grid we expect to get from VASP would have 101x101x101 points, the origin would be at (0,0,0) and the grid vectors (pointing from the grid origin to the final points along the corresponding axes) would be
The first and the one-hundred-first points are duplicates of each other in any of the three main directions.
In XSF from FHI-AIMS, in contrast, there would be just 100x100x100 data points. The origin would be at (0.05, 0.05, 0.05) and the grid vectors would be shorter by one "voxel" compared to VASP, like this:
9.9 0.0 0.0
0.0 9.9 0.0
0.0 0.0 9.9
Well, actually, the grid vectors from FHI-AIMS would be
0.0 0.0 9.9
0.0 9.9 0.0
9.9 0.0 0.0
as I will explain in the next point. Anyway, the control.in file of FHI-AIMS allows a fine-tuned control over the grid size and position, by using the cube origin and cube edge keywords. So, in principle, the user could always extract the same grid from FHI-AIMS as it would have been obtained from VASP. But it would be rather awkward. In particular, the cube origin in control.in does not really mean origin. Instead, it specifies the center of the grid. So it would have to be something like half the lattice vector in every direction minus half the grid step in every direction in order to obtain the desired result. I want to avoid having to do this when using FHI-AIMS. It should be possible as the XSF file contains both the information on the lattice vectors (as PRIMVEC) as well as the independent information on the grid dimensions. The lattice vectors would still be
10.0 0.0 0.0
0.0 10.0 0.0
0.0 0.0 10.0
even from FHI-AIMS, but the grid vectors would differ from the lattice vectors and the origin would be non-zero. The loading functions in ppafm/io.py need to interpret this information correctly.
- The arrangement of data on the grid as for the order of the axes is the same in the FHI-AIMS-generated XSF files as it is in CUBE files. Consequently, the first and third grid axes are swapped with respect to the lattice vectors in periodic systems. Likewise, these grid axis are also swapped with respect to the Cartesian axes in non-periodic systems. Again, this could in principle be recognized by the loading function(s) since the grid vectors are recorded in the XSF file and can be compared to the lattice vectors in the same file.
- Finally, the Hartree (electrostatic) potential is given in the Ha (rather than eV) units by FHI-AIMS. This is a point were I got a bit desperate because, in contrast to the issues above, there is no record inside the XSF file to indicate in what units the data are supposed to be expressed. After having figured out how to solve the other issues, I really did not want to introduce some new keyword argument to the PP-AFM code that would explicitly specify whether the input is from FHI-AIMS or from VASP. So, my proposed solution: Whenever the
loadXSF functions detects that the first and third grid vectors have been swapped, a matter which has to be decided anyway, assume that the data originate from FHI-AIMS and, if moreover the data being read are expected to be a potential (rather than density), do the conversion from Ha to eV.
The FHI-AIMS code offers to output the grid data either as CUBE or as XSF files. However, the structure of data in those XSF files is somewhat different from what one gets from VASP by applying the
v2xsftool on a LOCPOT or CHGCAR file. TheloadXSFandloadXSFGeomfunctions need to be modified in order to read the FHI-AIMS data correctly. Essentially, the grid data in the FHI-AIMS generated XSF files, including the grid dimensions and the ordering of the data points, are the same as they would be in the corresponding CUBE files (except that lengths are fortunately still expressed in angstrom, not bohr, in XSF). The consequences can be summarized into the following three points:control.infile, is still such that the grid covers the whole unit cell. However, a grid covering the unit cell means something slightly different for FHI-AIMS compared to what it means for VASP. There are no repeated data points at the unit cell boundary in FHI-AIMS like there would be in the XSF output from VASP. The first and the last point along an axis are not identical. The logic of FHI-AIMS is that the positions of nodes that form the grid are centers of the corresponding "voxels", which implies that the first and last point (node) along a particular axis do not in fact lie right on the cell boundary but they are shifted by half the voxel size (=half the grid step). Let me illustrate this by a concrete example: Suppose we have a 10x10x10 cell, which we want to sample with a grid in which the neighboring points are separated by the step of 0.1. The corresponding grid we expect to get from VASP would have 101x101x101 points, the origin would be at (0,0,0) and the grid vectors (pointing from the grid origin to the final points along the corresponding axes) would beIn XSF from FHI-AIMS, in contrast, there would be just 100x100x100 data points. The origin would be at (0.05, 0.05, 0.05) and the grid vectors would be shorter by one "voxel" compared to VASP, like this:
control.infile of FHI-AIMS allows a fine-tuned control over the grid size and position, by using thecube originandcube edgekeywords. So, in principle, the user could always extract the same grid from FHI-AIMS as it would have been obtained from VASP. But it would be rather awkward. In particular, thecube originincontrol.indoes not really mean origin. Instead, it specifies the center of the grid. So it would have to be something like half the lattice vector in every direction minus half the grid step in every direction in order to obtain the desired result. I want to avoid having to do this when using FHI-AIMS. It should be possible as the XSF file contains both the information on the lattice vectors (as PRIMVEC) as well as the independent information on the grid dimensions. The lattice vectors would still beeven from FHI-AIMS, but the grid vectors would differ from the lattice vectors and the origin would be non-zero. The loading functions in
ppafm/io.pyneed to interpret this information correctly.loadXSFfunctions detects that the first and third grid vectors have been swapped, a matter which has to be decided anyway, assume that the data originate from FHI-AIMS and, if moreover the data being read are expected to be a potential (rather than density), do the conversion from Ha to eV.