Part 1: Spin-polarized calculations


1 Density of states and band structure for ferromagnetic hexagonal-close-packed Co

By the end of this tutorial, you will be able to:

  • perform a spin-polarized calculation
  • obtain the total magnetization and local magnetic moments
  • plot the projected density of states (DOS) for a spin-polarized system
  • compute the band structure in a second step after self-consistency has been reached

1.1 Task

Perform a spin-polarized DFT calculations for hexagonal-close-packed (HCP) cobalt with initial ferromagnetic moments and obtain the local magnetic moment as well as the DOS. Then, perform a band-structure calculation along the high-symmetry path Γ-M-K-Γ.

In a spin-polarized calculation with ISPIN = 2, the Kohn–Sham (KS) orbitals are two component vectors in spin space. Here, the two components correspond to spin up and down with a global spin-quantization axis. The spin-up and spin-down KS orbitals are allowed to have different eigenvalues. This allows describing collinear magnetic structures also for itinerant electrons. The interaction between the two spin components stems solely from the exchange-correlation functional and potential that depends on the spin-up and spin-down charge densities.

Mind that without spin-orbit coupling the direction of the spin in real space is arbitrary. Only the direction relative to neighboring magnetic moments is relevant and thus ferromagnetic and antiferromagnetic order can be distinguished. In practice, you can perform spin-polarized calculations with the executable vasp_std. Only when spin-orbit coupling is included or noncollinear magnetic structures (with a local spin-quantization axis) are considered, do you need to use the executable vasp_ncl.

1.2 Input

The input files to run this example are prepared at $TUTORIALS/magnetism/e01_hcp-Co. Check them out!

POSCAR


Co2
1.0
   2.4719999032000000    0.0000000000000000    0.0000000000000000
  -1.2359999516013529    2.1408147143262166    0.0000000000000000
   0.0000000000000000    0.0000000000000000    4.0211440800000000
Co
2
direct
   0.3333333333333333    0.6666666666666667    0.2500000000000000 Co
   0.6666666666666667    0.3333333333333333    0.7500000000000000 Co

POSCAR.equiv


Co2
2.4719999032
   1.0000000000000000    0.0000000000000000    0.0000000000000000
  -0.5000000000000000    0.8660254037853866    0.0000000000000000
   0.0000000000000000    0.0000000000000000    1.6266764714653246
Co
2
direct
   0.3333333333333333    0.6666666666666667    0.2500000000000000 Co
   0.6666666666666667    0.3333333333333333    0.7500000000000000 Co

INCAR.scf


SYSTEM = FM Co

ALGO  = Normal 
PREC  = Accurate ! accurate FFTs
EDIFF = 1e-5     ! convergence criterion
ENCUT = 350      ! energy cutoff

ISPIN   = 2
MAGMOM  = 2 2    ! initial magnetic moments
LMAXMIX = 4
LASPH   = T

ISMEAR = 2       ! Methfessel-Paxton method
SIGMA  = 0.1     ! broadening

INCAR.dos


SYSTEM = FM Co

ALGO  = Normal 
PREC  = Accurate ! accurate FFTs
EDIFF = 1e-5     ! convergence criterion
ENCUT = 350      ! energy cutoff

ISPIN   = 2
LMAXMIX = 4
LASPH   = T

# DOS
ICHARG  = 11
ISMEAR  = -5
NEDOS   = 5001

# on-site spin moments and partial DOS
LORBIT  = 11

band/INCAR


SYSTEM = FM Co

ALGO  = Normal 
PREC  = Accurate ! accurate FFTs
EDIFF = 1e-5     ! convergence criterion
ENCUT = 350      ! energy cutoff

ISPIN   = 2
LMAXMIX = 4
LASPH   = T

# bands
ICHARG  = 11
LORBIT  = 11

KPOINTS


Regular k-point mesh
0              ! 0 -> determine number of k points automatically
Gamma          ! generate a Gamma centered mesh
6  6  4        ! subdivisions N_1, N_2 and N_3 along the reciprocal lattice vectors
0  0  0        ! optional shift of the mesh (s_1, s_2, s_3)

band/KPOINTS


k points for band structure in HCP structure
10
line-mode
reciprocal
    0.0000000000     0.0000000000     0.0000000000     Γ
    0.5000000000     0.0000000000     0.0000000000     M

    0.5000000000     0.0000000000     0.0000000000     M
    0.3333333333     0.3333333333     0.0000000000     K

    0.3333333333     0.3333333333     0.0000000000     K
    0.0000000000     0.0000000000     0.0000000000     Γ

POTCAR


Pseudopotential of Co.


The POSCAR file contains two Cobalt atoms in a hexagonal structure. Can you recall what the keyword direct in line 8 means?

Click to see the answer!

The positions are provided in direct coordinates, also called fractional coordinates. The alternative is specifying the positions in Cartesian coordinates.

There are three INCAR files provided: First, INCAR.scf to obtain a self-consistent solution for the spin-up and spin-down charge densities. Here,

  • ISPIN turns on spin-polarized calculations.
  • The magnetic moments are initialized on both Co sites to 2$\mu_B$ with MAGMOM.
  • As we wish to restart the calculation, it is important to set LMAXMIX to 4 for $d$ electrons (and 6 for $f$ electrons). Otherwise the charge density written to the CHGCAR file is incomplete. But in any case, it might speed up convergence as the charge-density mixer consideres states up to LMAXMIX.
  • LASPH should be considered a standard setting, especially for magnetic calculations. It includes aspherical contribution to the gradient corrections inside the PAW spheres.
  • ISMEAR= 2 selects the Methfessel-Paxton method of order 2, which is good for metallic systems, but should be avoided for semi-conductors and insulators.

Second, INCAR.dos includes settings to obtain a smooth DOS:

  • ICHARG = 11 reads the charge density from the CHGCAR file and fixes it throughout the calculation. Note that for a spin-polarized calculation with ISPIN=2, the CHGCAR file contains the spin-up and spin-down charge densities.
  • ISMEAR = -5 sets the tetrahedron method with Blöchl corrections, which yields smoother DOS but is less suited for the electronic convergence.
  • NEDOS sets the number of grid points on which the DOS is evaluated, and
  • LORBIT = 11 must be set to obtain the projected DOS, i.e., in terms of angular-momentum and magnetic quantum numbers $l$ and $m$. Additionally, the partial magnetization can be found in the OUTCAR file.

Third, INCAR.band is provided. Check if you understand all tags and search the VASP Wiki if need be.

The KPOINTS file sets a uniform $\mathbf{k}$ mesh in the first Brilloun zone for the self-consistent field (SCF) and the DOS calculation. Why do we choose the same number of subdivisions for the first two directions and fewer in the third direction? Consider the structure defined in the POSCAR file to find the answer.

Click to see the answer!

The first two lattice vectors, $\mathbf{a}_1$ and $\mathbf{a}_2$, have the same length: $|\mathbf{a}_1|=|\mathbf{a}_2|$. Note that $\mathbf{a}_1$ points in x direction, while $\mathbf{a}_2$ points in $(-1/2, \sqrt(3)/2,0)$. The third lattice vector, $\mathbf{a}_3$, points in z direction and is longer by roughly a factor of $|\mathbf{a}_3|/|\mathbf{a}_1|\approx 1.6$. To emphasize these properties already in the input, you could also rewrite the POSCAR file as in POSCAR.equiv.

With this in mind, recall that a long lattice vector in real space, leads to a short lattice vector in reciprocal space. So, what ever devision you choose for the third direction, you should choose roughly a factor of $1.6$ more subdevisions to obtain the same resolution along the other reciprocal lattice vectors.

The band/KPOINTS file contains a high-symmetry path for the band-structure calculation.

1.3 Calculation

Open a terminal and navigate to this example's directory, copy the INCAR file for the self-consistent (scf) calculation and run it by entering the following:

cd $TUTORIALS/magnetism/e01_*
cp INCAR.scf INCAR
mpirun -np 2 vasp_std

In the standard output (to the terminal) you find a summary stating the total energy and the total magnetization of the system. How does the total magnetization (mag=) compare to the experimental value of $1.7 \mu_B$/Co [T. WAKIYAMA, J. Phys. Colloques 32 (1971) C1-340-C1-341]? Plot the structure to get a hint!

In [2]:
import py4vasp
mycalc = py4vasp.Calculation.from_path( "./e01_hcp_Co")

mycalc.structure.plot()
Click to see the answer!

There are two Co atoms in the system. So, to compare to the experimental value, the total spin magnetization should be divided by two. The computed value is thus a bit smaller but in relatively good agreement.

While self-consistency is reached much more reliably using the Methfessel-Paxton method, it is better to use the tetrahedron method to obtain a smooth DOS. The partial DOS is only computed when LORBIT>=10. In a second step, we thus fix the charge density and compute the partial DOS with the tetrahedron method:

cp INCAR.dos INCAR
mpirun -np 2 vasp_std

Plot the partial DOS using py4vasp! What are the main features?

In [3]:
import py4vasp
mycalc = py4vasp.Calculation.from_path( "./e01_hcp_Co")

mycalc.dos.plot( "up, down" )
In [4]:
mycalc.dos.plot( "d" )
Click to see the answer!

Most of the magnetization emerges from the d orbitals. The spin-up and spin-down DOS have similar shape but are shifted in energy, such that there is a majority and a minority spin. The relative energy shift is the so-called exchange splitting in the context of the Stoner model.

To perform further analysis, you can get the data as a dictionary using py4vasp:

In [5]:
mycalc.dos.to_dict("d")
Out[5]:
{'energies': array([-11.48428911, -11.47389936, -11.46350961, ...,  40.44369538,
         40.45408513,  40.46447488], shape=(5001,)),
 'up': array([0., 0., 0., ..., 0., 0., 0.], shape=(5001,)),
 'down': array([0., 0., 0., ..., 0., 0., 0.], shape=(5001,)),
 'd_up': array([0., 0., 0., ..., 0., 0., 0.], shape=(5001,)),
 'd_down': array([0., 0., 0., ..., 0., 0., 0.], shape=(5001,)),
 'fermi_energy': np.float64(10.63095529790273)}

Alternatively, check out the PROCAR file.

1.3.1 Local magnetic moments

Open the OUTCAR file and search for the last occurance of magnetization! What information can you find about the local magnetic moments and how does it compare to the following?

In [6]:
mycalc.local_moment.to_dict()
Out[6]:
{'orbital_projection': ['s', 'p', 'd'],
 'charge': array([[0.49616678, 0.53721956, 7.26953177],
        [0.49616678, 0.53721956, 7.26953177]]),
 'total': array([[-0.01722149, -0.0624978 ,  1.60694402],
        [-0.01722149, -0.0624978 ,  1.60694402]])}
In [7]:
sum(mycalc.local_moment.to_dict()['total'][0])
Out[7]:
np.float64(1.5272247280261688)
Click to see the answer!

These are the local magnetic moments in the $s$, $p$ and $d$ orbital on each site. To obtain the total magnetic moment per site the values in the python dictionary have to be summed. Mind that in this calculation only the magnetic moments due to the electronic spin, but not due to the orbital angular momentum, is considered. In $d$ orbitals the orbital moments are small compared to the spin moments, but for $f$ orbitals the contribution might be sizable. It is possible to consider the orbital moments in VASP, but this is covered in part 2.

Do the on-site magnetic moments correspond to the so-called magnetic moments as defined in equation 1?

$$\tag{1} m_{\textrm{atom}} = g m \mu_B $$

Here, $g$ is the $g$ factor), $m$ is the magnetic quantum number and $\mu_B$ is the Bohr magneton. The magnetic moment in Eq. (1) is, e.g., measured in neutron scattering spectroscopy. Or does the computed value correspond to the effective magnetic moment?

$$\tag{2} m^{\textrm{eff}}_{\textrm{atom}} = g \sqrt{(s(s+1))} \mu_B $$

$s$ is the spin quantum number. The effective magnetic moment can be measured in muon scattering or indirectly obtained through Curie's law by measuring the specific heat.

Plot the local magnetic moments using py4vasp! But before, think about which direction the local moments have. Why?

Click to see the answer!

Without spin-orbit coupling the spin-quantization axis is not coupled to real space. Thus, the calculation contains no information about the direction of the magnetic moments. We only know their relative orientation to each other. As the partial magnetization has the same sign for both Co sites, we know the on-site moments are ferromagnetically coupled, as expected when we set the initial magnetic moments using the MAGMOM tag. The plot below hence shows a tentative global direction.

In [8]:
mycalc.local_moment.plot()

Next, run the band-structure calculation in the subdirectory band starting from the converged charge density:

cp CHGCAR POSCAR POTCAR band/.
cd band
mpirun -np 2 vasp_std

Now, plot the band structure using py4vasp! What effect does the exchange splitting we saw in the DOS have on the bands?

In [9]:
import py4vasp
my_band_calc = py4vasp.Calculation.from_path( "./e01_hcp_Co/band")

my_band_calc.band.plot()
Click to see the answer!

The bands of the minority spin are moved up in energy by the exchange splitting. See, for instance, the three spin-up bands around $-0.5\,$eV between $M$ and $K$. The same dispersion can be seen around $1.3\,$eV in the spin-down bands.

1.4 Questions

  1. What does the ISPIN tag set?
  2. Which INCAR tag must be set to obtain local magnetic moments?
  3. What is exchange splitting and where can it be observed?

2 Magnetic unit cell of antiferromagnetic body-centered-cubic Cr

By the end of this tutorial, you will be able to:

  • perform a spin-polarized calculation for an antiferromagnetic (AFM) material
  • restart a spin-polarized calculation

2.1 Task

Perform a spin-polarized calculation for body-centered-cubic (BCC) Cr with AFM order with propagation vector $\mathbf{q}=(1/2,1/2,1/2)$. Consider convergence with respect to k points and compute the band structure using a KPOINTS_OPT file. Finally, compute the partial DOS.

The propagation vector $\mathbf{q}$ describes how the magnetic moments vary spatially within a bulk material. It represents the spatial periodicity of the magnetic order, and can be used to define the magnetic unit cell, which might be larger than the crystallographic unit cell.

Let's consider BCC Cr as an example. In its paramagnetic phase, there is only one atom per primitive unit cell. However, in the antiferromagnetic (AFM) phase, the primitive unit cell contains two atoms, one located at fractional coordinates $(0,0,0)$ and the other at $(0.5,0.5,0.5)$. In this AFM configuration, the magnetic moments on the Cr atoms alternate in direction, and the magnetic unit cell is twice the size of the crystallographic unit cell.

To describe this AFM order, we can introduce a propagation vector $\mathbf{q}=(1/2,1/2,1/2)$ in units of the reciprocal lattice vectors. This vector indicates that the magnetic moments oscillate with a periodicity of two lattice constants, which corresponds to the doubling of the unit cell along the body diagonal.

2.2 Input

The input files to run this example are prepared at $TUTORIALS/magnetism/e02_bcc_Cr. Check them out!

POSCAR


BCC Cr
2.9688993551160281
 1.000000000 0.000000000 0.000000000
 0.000000000 1.000000000 0.000000000
 0.000000000 0.000000000 1.000000000
Cr
2
Cartesian
0.000000000 0.000000000 0.000000000 Cr
0.500000000 0.500000000 0.500000000 Cr

INCAR.scf


SYSTEM = AFM Cr

ALGO  = Normal 
PREC  = Accurate ! accurate FFTs
ENCUT = 350      ! energy cutoff
EDIFF = 1e-5     ! convergence criterion

ISPIN   = 2
MAGMOM  = 2 -2   ! initial magnetic moments
LMAXMIX = 4
LASPH   = T

ISMEAR = 0       ! Gaussian smearing
SIGMA  = 0.1     ! broadening

LORBIT = 11
LKPOINTS_OPT = F

INCAR.fine


SYSTEM = AFM Cr

ALGO  = Normal 
PREC  = Accurate ! accurate FFTs
ENCUT = 350      ! energy cutoff
EDIFF = 1e-5     ! convergence criterion

ISPIN   = 2
MAGMOM  = -0.1 0.1 ! only to break the symmetry
LMAXMIX = 4
LASPH   = T

ISMEAR = 0       ! Gaussian smearing
SIGMA  = 0.1     ! broadening

LORBIT = 11
LKPOINTS_OPT = T

ICHARG = 1

INCAR.dos


SYSTEM = AFM Cr

ALGO  = None     ! only postprocessing
PREC  = Accurate ! accurate FFTs
ENCUT = 350      ! energy cutoff


ISPIN   = 2
MAGMOM  = -0.1 0.1 ! only to break the symmetry
LMAXMIX = 4
LASPH   = T

ISMEAR = -5      ! tetrahedron method


LORBIT = 11
LKPOINTS_OPT = F

ICHARG = 11
NEDOS  = 5001
LH5    = T 

KPOINTS.scf


Regular k-point mesh
0              ! 0 -> determine number of k points automatically
Gamma          ! generate a Gamma centered mesh
4  4  4        ! subdivisions N_1, N_2 and N_3 along the reciprocal lattice vectors
0  0  0        ! optional shift of the mesh (s_1, s_2, s_3)

KPOINTS.fine


Regular k-points on finer mesh
0              
Gamma          
8  8  8

KPOINTS_OPT


k points for band structure in BCC structure
10  ! intersections 
line-mode
reciprocal
    0.0000000000     0.0000000000     0.0000000000    Γ
    0.0000000000     0.5000000000     0.0000000000    X

    0.0000000000     0.5000000000     0.0000000000    X
    0.5000000000     0.5000000000     0.0000000000    M

    0.5000000000     0.5000000000     0.0000000000    M
    0.0000000000     0.0000000000     0.0000000000    Γ

POTCAR


Pseudopotential of Cr.


The POSCAR file shows how the scaling factor in line 2 acts. In particular, not only the lattice matrix but also the Cartesian coordinates are scaled. The defined structure is the magnetic unit cell of BCC Cr. In this case, the conventional unit cell of the crystal structure coincides with the magnetic unit cell.

Concerning the INCAR.scf file, check that you understand the meaning of all tags. LKPOINTS_OPT = F ensures that the KPOINTS_OPT file is ignored for now. The initial magnetic moments are set to AFM order by MAGMOM = 2 -2. This breaks the symmetry of the crystal structure, i.e., the two Cr sites are no longer equivalent.

In the subsequent calculation, we will use INCAR.fine on a finer $\mathbf{k}$ mesh. Also, here, the MAGMOM is set in order to break the symmetry. Note that the magnetic moments are not initialized to the values of MAGMOM because ICHARG is set to 1 and, thus, the spin-up and spin-down charge densities are read from the CHGCAR file. We want to compute the band structure for the finer $\mathbf{k}$ mesh, so we set LKPOINTS_OPT=True, i.e., its default.

The INCAR.dos turns off electronic minimization with ALGO = None. This is convenient for postprocessing but requires a converged WAVECAR or vaspwave.h5 file.

The KPOINTS file and the KPOINTS.fine file define a Γ-centered $\mathbf{k}$ mesh with equally spaced $\mathbf{k}$ points. The only difference is the $\mathbf{k}$-mesh density.

The KPOINTS_OPT file is used in combination with the KPOINTS.fine file in the band-structure calculation.

2.3 Calculation

Open a terminal, navigate to this example's directory and run VASP by entering the following:

cd $TUTORIALS/magnetism/e02_*
cp INCAR.scf INCAR
cp KPOINTS.scf KPOINTS
mpirun -np 2 vasp_std

You can see in the summary line of the stdout that the total magnetization vanishes as expected for AFM order. Make sure to save the vaspout.h5 file for later:

cp vaspout.h5 bk.h5

Then print the on-site magnetic moments using py4vasp!

In [10]:
import py4vasp
mycalc = py4vasp.Calculation.from_file( "./e02_bcc_Cr/bk.h5")

mycalc.local_moment.print()
# or

[sum(mycalc.local_moment.to_dict()['total'][i]) for i in range(2)]
MAGMOM = 1.64 -1.64
Out[10]:
[np.float64(1.642995301556537), np.float64(-1.642995301556537)]

Check the computational cost by looking for Total CPU time used in the OUTCAR file. Create a backup for comparison and restart the calculation with a finer $\mathbf{k}$ mesh from the charge density obtained with the coarser $\mathbf{k}$ mesh!

cp OUTCAR OUTCAR.bk
cp INCAR.fine INCAR
cp KPOINTS.fine KPOINTS
rm WAVECAR
mpirun -np 2 vasp_std

Make sure to save the vaspout.h5 file for later:

cp vaspout.h5 bk2.h5

Note that we delete the WAVECAR file so there is no attempt to read it. The attempt would fail because the number of $\mathbf{k}$ points has changed, but the calculation is still influenced by the attempt. That is because when no WAVECAR file is present, the KS orbitals are initialized randomly and the first few steps of the electronic minimization the charge density is fixed. After a failed attempt to read a WAVECAR file, the charge density is not fixed for the first few steps and we do not take full advantage of having already converged on a coarser $\mathbf{k}$ mesh.

In [11]:
mycalc = py4vasp.Calculation.from_file( "./e02_bcc_Cr/bk2.h5")
mycalc.local_moment.print()
MAGMOM = 1.87 -1.87

Compare the OUTCAR files! Search for LOOP to compare the computational effort. Then, go to the end of the files and compare the total charge and magnetization (x). What do you see?

Click to get a hint!

You may want to use one or all of these commands:

grep LOOP OUTCAR
grep LOOP OUTCAR.bk
vimdiff OUTCAR OUTCAR.bk
Click to see the answer!

The calculation including more $\mathbf{k}$ points is clearly more expensive. We note that the on-site magnetic moments were not converged on the coarser $\mathbf{k}$ mesh. The on-site charge, on the other hand, barely changed after increasing the $\mathbf{k}$-mesh density. This emphasizes that one needs to perform a convergence study exactly for the quantity of interest.

Plot the band structure along the $\mathbf{k}$ path specified in the KPOINTS_OPT file using py4vasp! You can click the label in the legend to activate and deactivate plotting a specific line.

In [12]:
mycalc.band.plot("kpoints_opt")

Finally, compute the DOS in a pure postprocessing calculation! Additionally, we set LH5=True in order to plot the magnetization.

cd $TUTORIALS/magnetism/e02_*
cp INCAR.dos INCAR
mpirun -np 2 vasp_std

Plot the DOS at one of the Cr sites! Is there any exchange splitting? How do the spin-up and spin-down DOS differ?

In [13]:
mycalc = py4vasp.Calculation.from_path( "./e02_bcc_Cr/")
mycalc.dos.plot("1")
Click to see the answer!

The majority spin has a larger DOS than the minority spin. There is no exchange splitting like in the ferromagnetic case.

Can you tell what the Cr DOS at site 2 will look like?

Click to see the answer!

Due to the AFM order, the majority and minority spin will be opposite to site 1.

In [14]:
mycalc.dos.plot("2")

Plot the magnetic structure using py4vasp!

In [15]:
mycalc.local_moment.plot()

While the local magnetic moments rely on some projection method (selected by LORBIT), the magnetization on the plane wave grid is a simple byproduct of spin-polarized DFT. It can be read from the vaspwave.h5 file and shown using a quiver plot as follows:

In [16]:
mycalc.density.to_contour("magnetization", a=0.5)+mycalc.density.to_quiver(a=0.5)

Here, the argument for the contour plot selects the magnetization and a plane orthogonal to the first lattice vector at the fraction of 0.5. For the quiver plot, the default density is the magnetization (since a charge density is a scalar in every point and cannot be nicely illustrated as a quiver plot) so only the plane is parsed as an argument. Hence, the graph shows the magnetization density of site 2.

2.4 Questions

  1. Does MAGMOM influence the symmetrization of the charge density?
  2. What is ALGO=None?
  3. Is it strictly necessary to converge the total energy with respect to the $\mathbf{k}$-mesh density?
  4. How can a calculation be restarted when the $\mathbf{k}$ mesh has changed?

3 DOS of $e_g$ and $t_{2g}$ orbitals in antiferromagnetic NiO

By the end of this tutorial, you will be able to:

  • set the Fermi energy mid-gap
  • adjust the density mixer to converge more quickly
  • plot combinations of orbitals in py4vasp

3.1 Task

Compute the partial DOS of Ni $e_g$ and $t_{2g}$ orbitals in AFM NiO.

To understand the magnetic properties of a system, it is often useful to consider the orbital splitting in crystal field theory as a first step. NiO is a transition metal oxide, where Ni$^{2+}$ is neighboring six equivalent O$^{2-}$ ions which together forms an NiO$_{6}$ octahedron. The Ni $d$ orbitals split into $t_{2g}$ and $e_g$ orbitals according to their symmetry properties with respect to the operations of the octahedral point group (O$_h$) as summarized in the character table of O$_h$. The octahedral point group is the group of symmetry operations for an octahedron and comprises all rotations on the Ni site that leave the system invariant.

The names $t_{2g}$ and $e_g$ are Mulliken symbols for irreducible representations. The $e_g$ set contains the d$_{z^2}$ and $d_{x^2-y^2}$ orbitals. The 'e' refers to doubly degenerate, i.e., there are two orbitals with the same energy. The 'g' refers to gerade, which is German for 'even' and means symmetric with respect to inversion. The $t_{2g}$ manifold contains the d$_{xy}$, d$_{xz}$, and d$_{yz}$ orbitals. The 't' refers to triply degenerate, and the 'g', as before, refers to gerade. '2' indicates that the manifold is anti-symmetric with respect to a vertical mirror plane perpendicular to the principal axis.

The lobes of the $e_{g}$ orbitals point towards the O$^{2-}$ ligands, while the $t_{2g}$ can maximally avoid the direction of the ligands. The negative point charge of the O$^{2-}$ ligands repels the $d$ electrons. Thus, $e_{g}$ is expected to be higher in energy due to the octahedral crystal field.

In the ionic limit, Ni$^{2+}$ has an electronic configuration of [Ar]3d$^8$. 6 of the electrons are expected to fully occupy the $t_{2g}$ orbitals, while 2 electrons may form a total-spin-$1$ configuration in the $e_{g}$ orbitals. So, we can expect a maximum value of $2\mu_B/$f.u. for the magnetization.

No description has been provided for this image

3.2 Input

The input files to run this example are prepared at $TUTORIALS/magnetism/e03_NiO. Check them out!

POSCAR


AFM  NiO
   4.17000000000000         
     1.0000000000000000    0.5000000000000000    0.5000000000000000
     0.5000000000000000    1.0000000000000000    0.5000000000000000
     0.5000000000000000    0.5000000000000000    1.0000000000000000
   Ni O     
    2 2      
Direct
  0.0000000000000000  0.0000000000000000  0.0000000000000000
  0.5000000000000000  0.5000000000000000  0.5000000000000000
  0.2500000000000000  0.2500000000000000  0.2500000000000000
  0.7500000000000000  0.7500000000000000  0.7500000000000000

INCAR


SYSTEM   = NiO

ISTART   = 0

ISPIN    = 2
MAGMOM   = 2.0 -2.0 2*0
LASPH    = T

EDIFF    = 1E-8

ISMEAR   = -5
EFERMI   = MIDGAP

ALGO     = Normal
IMIX     = 4
AMIX     = 0.8
BMIX     = 0.00001
AMIX_MAG = 0.8
BMIX_MAG = 0.00001
LMAXMIX  = 4

LORBIT   = 11

EMIN     = 3.5
EMAX     = 10
NEDOS    = 5001

KPOINTS


k points
 0
gamma
 6  6  6
 0  0  0

POTCAR


Pseudopotential of Ni and O_s.


Read about density mixing on the VASP Wiki! Consider the options of IMIX. For IMIX=4, the Pulay-mixing method is used. There are two coefficients for both the charge (AMIX, BMIX) and the magnetic degrees of freedom (AMIX_MAG, BMIX_MAG), respectively. For magnetic calculations, it can be advantages to use linear mixing, i.e. setting BMIX and BMIX_MAG to very small values, but not zero for numerical reasons.

The Fermi energy is set midgap using EFERMI = MIDGAP.

3.3 Calculation

Open a terminal, navigate to this example's directory, run VASP by entering the following:

cd $TUTORIALS/magnetism/e03_*
mpirun -np 2 vasp_std

Plot the DOS of the Ni $e_g$ and $t_{2g}$ orbitals using py4vasp!

In [17]:
import py4vasp
mycalc = py4vasp.Calculation.from_path( "./e03_NiO")

dos = mycalc.dos.read("dxy, dyz, dz2, dxz, dx2y2")  
(
 py4vasp.plot(dos["energies"], dos["dxy_up"] + dos["dyz_up"] + dos["dxz_up"], "t2g") +
 py4vasp.plot(dos["energies"], -dos["dz2_up"] -dos["dx2y2_up"], "eg") 
)

The orbitals are combined to obtain the linear combination that yields the irreducible representations. The Fermi energy is in the middle of the gap.

Let us compute the size of the gap!

In [18]:
import numpy as np
def gap(calc, select=""):
    homo = np.amax((calc.band.to_dict()['bands_up'][calc.band.to_dict()['occupations_up'] > 0.5]))
    lumo = np.amin((calc.band.to_dict(select)['bands_up'][calc.band.to_dict(select)['occupations_up'] < 0.5]))
    return lumo - homo

print("Band gap (in eV):", gap(mycalc))
Band gap (in eV): 1.0009658844341

The size of the gap is very clearly underestimated compared to the experimentally measured gap of about 4.2eV, see discussion by Dudarev et al., PRB 57, 1505 (1998). This is due to the inherent issue that DFT underestimates the exchange interaction. There are various strategies to improve the computed size of the gap. One is to include on-site Coulomb interaction $U$ which will be discussed in the next exercise.

Inspecting the DOS further, we see that the $t_{2g}$ orbitals are fully occupied. Now, consider the occupation of the $e_{g}$ orbitals on each Ni site! Click the labels in the legend to selectively (de)activate the lines.

In [19]:
dos = mycalc.dos.read("1(dz2, dx2y2) 2(dz2, dx2y2)") 
(
     py4vasp.plot(dos["energies"], dos["Ni_1_dz2_up"] + dos["Ni_1_dx2y2_up"], "Ni 1 eg up")+
     py4vasp.plot(dos["energies"], -dos["Ni_1_dz2_down"] - dos["Ni_1_dx2y2_down"], "Ni 1 eg down")+
     py4vasp.plot(dos["energies"], dos["Ni_2_dz2_up"] + dos["Ni_2_dx2y2_up"], "Ni 2 eg up")+
     py4vasp.plot(dos["energies"], -dos["Ni_2_dz2_down"] - dos["Ni_2_dx2y2_down"], "Ni 2 eg down")
)

We see that the minority spin alternates between the Ni sites. And we see that, on each site, the majority spin is almost fully occupied and the minority spin almost fully unoccupied.

To see the resulting on-site magnetic moment for one Ni site, execute the following:

In [20]:
def Ni_moment(calc):
    return sum(calc.local_moment.to_dict()['total'][0])

print("Ni moment: ", Ni_moment(mycalc))
Ni moment:  1.340099442291938

How does it compare to the experimental value of about 1.9$\mu_B$? For an overview see Kwon and Min, PRB, 62, 73 (2000).

As a final step, you can visualize the magnetic structure!

In [21]:
mycalc.local_moment.plot()

3.4 Questions

  1. How can one select linear density mixing?
  2. Which tag sets the Fermi energy mid gap?
  3. Is the DOS of $t_{2g}$ orbitals directly computed in VASP?

4 Including on-site Coulomb interaction and pseudopotential selection for NiO relaxation

By the end of this tutorial, you will be able to:

  • perform a volume relaxation using a fit of an equation of state
  • select the projector-augmented–wave (PAW) potential and compare calculated values using different PAWs
  • run an LSDA+U calculation using the method by Dudarev et al. Phys. Rev. B 57, 1505 (1998)

4.1 Task

Fit the equation of state AFM NiO for U=8eV and J=0.95eV considering different PAW pseudopotentials and monitor the equilibrium lattice constant, the electronic bandgap, and the on-site magnetic moment.

The DFT+U method is an extension of density functional theory (DFT) designed to better treat strongly correlated electrons, especially in transition metal oxides and f-electron systems (like rare earths or actinides). The standard local density approximation (LDA) and generalized gradient approximation (GGA) often fails for such systems because it underestimates the on-site Coulomb repulsion (Hubbard U), which leads to incorrect predictions like metallic behavior for known Mott insulators. Traditionally the method is often referred to as LDA+U or LSDA+U although it can be combined with other exchange-correlation functionals, line GGA or even meta GGA.

This exercise is a quick interlude focussing on choosing the PAW potential and the DFT+U method which is also important for nonmagnetic calculations.

4.2 Input

The input files to run this example are partially prepared at $TUTORIALS/magnetism/e04_NiO_LSDA+U. Check them out!

POSCAR.tmp


AFM  NiO
1        
     1.0000000000000000    0.5000000000000000    0.5000000000000000
     0.5000000000000000    1.0000000000000000    0.5000000000000000
     0.5000000000000000    0.5000000000000000    1.0000000000000000
   Ni O     
    2 2      
Direct
  0.0000000000000000  0.0000000000000000  0.0000000000000000
  0.5000000000000000  0.5000000000000000  0.5000000000000000
  0.2500000000000000  0.2500000000000000  0.2500000000000000
  0.7500000000000000  0.7500000000000000  0.7500000000000000

INCAR.tmp


SYSTEM   = NiO

ISTART   = 0

# Magnetism
ISPIN    = 2
MAGMOM   = 2.0 -2.0 2*0
LASPH    = T

# FFT grid
ENCUT    = 500 
PREC     = Acc

# Convergence criterion
EDIFF    = 1E-8

# Smearing/k integration
ISMEAR   = -5
EFERMI   = MIDGAP

# Algorithm and density mixing
ALGO     = Normal
IMIX     = 4
AMIX     = 0.8
BMIX     = 0.00001
AMIX_MAG = 0.8
BMIX_MAG = 0.00001
LMAXMIX  = 4

# compute bandgap
BANDGAP = WEIGHT

# compute on-site moment
LORBIT  = 11

KPOINTS


k points
 0
gamma
 6  6  6
 0  0  0

POT_GGA_PAW_PBE/


Ni, Ni_GW, Ni_pv, Ni_sv_GW, and O, O_GW, O_GW_new, O_h, O_h_GW, O_s, O_s_GW


Based on this, let us create the input for the individual calculations. Compare different PAW pseudopotentials! Look in the directory POT_GGA_PAW_PBE and see what possible choices there are. Read about available PAW pseudopotentials and try deciding which one to use in this calculation. Consider the value of ENMAX and the atomic configuration underlying each potential.

We will use the following combination:

cd $TUTORIALS/magnetism/e04_*
mkdir PAW_NiO PAW_Ni_sv_GWO_s
cat POT_GGA_PAW_PBE/Ni/POTCAR        POT_GGA_PAW_PBE/O/POTCAR       > PAW_NiO/POTCAR
cat POT_GGA_PAW_PBE/Ni_sv_GW/POTCAR  POT_GGA_PAW_PBE/O_s/POTCAR     > PAW_Ni_sv_GWO_s/POTCAR

Why?

Click to see the answer!

There are 7 options for the oxygen potential: All of them correspond to the same atomic configuration. The first aspect is that they are distinct by their hardness. _s is particularly soft with a low energy cutoff, and _h is particularly hard, which is important in molecules with short bond lengths. A second aspect is that the potentials with _GW are particularly suited for calculations involving unoccupied states, e.g., for optical properties. Since here we investigate a bulk material (not very short bond length) where the main property of interest is magnetism, a ground state property emerging from the Ni 3d state, we can choose a computationally cheap O potential without significant loss of accuracy.

For Ni, there are 4 potentials, and some have a different atomic configuration. However, all of them include the 3d shell, and we do not expect the additional inclusion of p or s states to influence the magnetic properties. Again, magnetism is a ground state property and it is not necessary to opt for _GW.

Next, we need subdirectories for each PAW potential and U value. Execute the following in the Terminal:

for d in PAW_Ni_sv_GWO_s PAW_NiO 
do 
    cd $d
    mkdir U_0.0 U_3.0 U_8.0
    cd ..
done 

We write POSCAR files based on POSCAR.tmp centered around an educated guess for the equilibrium lattice constant for each PAW potential and U value. Execute the following:

In [22]:
import ase.io

pot = ["PAW_NiO","PAW_Ni_sv_GWO_s"]

u = [0.0, 3.0, 8.0]

a = {
     "PAW_NiO": [4.064, 4.064, 4.035],
     "PAW_Ni_sv_GWO_s": [4.067, 4.085, 4.119]
    }

scale = [0.950, 0.975, 1.000, 1.025, 1.050]

s=ase.io.read("./e04_NiO_LSDA+U/POSCAR.tmp")

for p in pot:
    for i in range(3):
        for l in range(5):
            # structure
            s_out=s.copy()
            s_out.set_cell(s.cell*a[p][i]*scale[l],scale_atoms=True)
            # to file
            filename="./e04_NiO_LSDA+U/"+p+"/U_{:.1f}/POSCAR.".format(u[i])+str(l)
            ase.io.write(filename,s_out)

Copy the POTCAR files in the appropriate subdirectories!

cd $TUTORIALS/magnetism/e04_*
for d in PAW_Ni_sv_GWO_s PAW_NiO 
do 
    for u in U_0.0 U_3.0 U_8.0
    do
        cp $d/POTCAR $d/$u/.
    done
done 

The INCAR files are all based on INCAR.tmp but differ in the block that defined the exchange-correlation functional. Here, we choose LDA by setting XC = CA. Then, various values for the on-site Coulomb repulsion are added. Finally, these can be copied to the subdirectories as follows:

cd $TUTORIALS/magnetism/e04_*
cp INCAR.tmp INCAR.U_0.0
echo """
# Exchange-correlation functional
XC        = CA

""" >> INCAR.U_0.0 

cp INCAR.tmp INCAR.U_3.0
echo """
# Exchange-correlation functional
XC        = CA
LDAU      = .TRUE.
LDAUTYPE  = 2 
LDAUL     = 2 -1      # l quantum number where U is added for each atom; -1 is no U added
LDAUU     = 3.00 0.00 # on-site Coulomb interaction (in eV) for each atom 
LDAUJ     = 0.95 0.00 # on-site exchange interaction (in eV) for each atom
""" >> INCAR.U_3.0 

cp INCAR.tmp INCAR.U_8.0
echo """
# Exchange-correlation functional
XC        = CA
LDAU      = .TRUE.
LDAUTYPE  = 2 
LDAUL     = 2 -1      # l quantum number where U is added for each atom; -1 is no U added
LDAUU     = 8.00 0.00 # on-site Coulomb interaction (in eV) for each atom 
LDAUJ     = 0.95 0.00 # on-site exchange interaction (in eV) for each atom
""" >> INCAR.U_8.0

for d in PAW_Ni_sv_GWO_s PAW_NiO 
do 
    for u in U_0.0 U_3.0 U_8.0
    do
        cp INCAR.$u $d/$u/INCAR
        cp KPOINTS $d/$u/.
        cp run $d/$u/.
    done
done 

To get an overview of the subdirectories in which we will run the calculations, execute the following in the Terminal:

cd $TUTORIALS/magnetism/e04_*
ls PAW_Ni*/U*

4.3 Calculation

Since this calculation takes quite some time, we recommend skipping the calculation described in Section 4.3.1 and using the data prepared in Section 4.3.2 instead!

Alternatively, you can continue with Section 4.3.1 and read about DFT+U on the VASP Wiki. You may also check the references therein. Particularly, S. L. Dudarev, G. A. Botton, S. Y. Savrasov, C. J. Humphreys, and A. P. Sutton, Phys. Rev. B 57, 1505 (1998).

4.3.1 Performing the calculation

Open a terminal, navigate to this example's directory, run VASP for the two different POTCAR files, 3 U values and 4 different lattice constants, respectively. Execute the following:

cd $TUTORIALS/magnetism/e04_*
for d in PAW_Ni_sv_GWO_s PAW_NiO
do 
    for u in U_0.0 U_3.0 U_8.0
    do
        cd $d/$u
        vasp_rm
        bash run
        cd ../..
    done
done

where run contains the following instructions:

for i in 0 1 2 3 4
do
    cp POSCAR.$i POSCAR
    mpirun -np 4 vasp_std
    cp vaspout.h5 vaspout_$i.h5
    cp OUTCAR OUTCAR_$i
    vasp_rm
done

Shortly after you started the calculation you can open $TUTORIALS/magnetism/e04_NiO_LSDA+U/NiO/U_0.0/OUTCAR_2 look for fundamental gap. Read the documentation of the BANDGAP tag and print the same data using the Python script below:

In [23]:
import py4vasp as pv
calc = pv.Calculation.from_file("e04_NiO_LSDA+U/PAW_NiO/U_0.0/vaspout_2.h5")
calc.bandgap.print()
Band structure
--------------
                       spin independent             spin component 1             spin component 2
val. band max:               8.412756                     8.412756                     8.412756
cond. band min:              8.859691                     8.859691                     8.859691
fundamental gap:             0.446935                     0.446935                     0.446935
VBM @ kpoint:       0.3333   0.3333   0.1667     0.3333   0.3333   0.1667     0.3333   0.3333   0.1667
CBM @ kpoint:       0.5000   0.3333   0.3333     0.5000   0.3333   0.3333     0.5000   0.3333   0.3333

lower band:                  8.036631                     8.036631                     8.036631
upper band:                  8.859691                     8.859691                     8.859691
direct gap:                  0.823060                     0.823060                     0.823060
@ kpoint:           0.5000   0.3333   0.3333     0.5000   0.3333   0.3333     0.5000   0.3333   0.3333

Fermi energy:                8.636224

The following Python script uses some helper functions to extract the total energy, on-site magnetic moment and fundamental bandgap for the set of parameters.

In [24]:
import py4vasp as pv
import numpy as np
import pandas as pd

pot = ["PAW_NiO","PAW_Ni_sv_GWO_s"]

u = [0.0, 3.0, 8.0]

a = { 
     "PAW_NiO": [4.064, 4.064, 4.035],
     "PAW_Ni_sv_GWO_s": [4.067, 4.085, 4.119]
    }   

scale = [0.950, 0.975, 1.000, 1.025, 1.050]

def get_energy(i,l,p):
    c=pv.Calculation.from_file("./e04_NiO_LSDA+U/"+p+"/U_{:.1f}/vaspout_{:}.h5".format(u[i],l))
    return c.energy[-1].to_dict()['energy(sigma->0)']

def get_volume(i,l,p):
    b=a[p][i]*scale[l]
    print(b, b**3)
    return (a[p][i]*scale[l])**3

def get_lattice_constant(i,l,p):
    return a[p][i]*scale[l]

def get_U(i,l,p):
    return u[i]

def get_fundamental(i,l,p):
    c=pv.Calculation.from_file("./e04_NiO_LSDA+U/"+p+"/U_{:.1f}/vaspout_{:}.h5".format(u[i],l))
    return c.bandgap.read()['fundamental']

def get_moment(i,l,p):
    c=pv.Calculation.from_file("./e04_NiO_LSDA+U/"+p+"/U_{:.1f}/vaspout_{:}.h5".format(u[i],l))
    return round(np.sum(c.local_moment.read()['total'][0]),3)

data = { 
  "lattice constants": [get_lattice_constant(i,l,p) for i in range(3) for l in range(5) for p in pot],
  "U (in eV)": [get_U(i,l,p) for i in range(3) for l in range(5) for p in pot],
  "total energy (in eV)": [get_energy(i,l,p) for i in range(3) for l in range(5) for p in pot],
  "PAW potential": [p  for i in range(3) for l in range(5) for p in pot ],
  "fundamental bandgap (in eV)": [get_fundamental(i,l,p) for i in range(3) for l in range(5) for p in pot],
  "on-site moment (in muB)": [get_moment(i,l,p) for i in range(3) for l in range(5) for p in pot] 
}

df = pd.DataFrame(data)
df.to_csv('e04_NiO_LSDA+U/mydata.csv', index=False)
4.3.2 Skipping the calculation

Execute the following to read the data from file instead of computing it as described in the previous section.

In [25]:
import pandas as pd
df = pd.read_csv('e04_NiO_LSDA+U/data.csv')

When you prepared the whole setup but skipped Section 4.3.1, you can execute the following in the Terminal in order to run a single calculation

cd $TUTORIALS/magnetism/e04_*
cd PAW_NiO/U_8.0
cp POSCAR.2 POSCAR
mpirun -np 4 vasp_std
cp vaspout.h5 vaspout_2.h5
cp OUTCAR OUTCAR_2

Then, you can open $TUTORIALS/magnetism/e04_NiO_LSDA+U/NiO/U_8.0/OUTCAR_2 and look for fundamental gap. Read the documentation of the BANDGAP tag and print the same data using the Python script below:

In [26]:
import py4vasp as pv
calc = pv.Calculation.from_file("e04_NiO_LSDA+U/PAW_NiO/U_8.0/vaspout_2.h5")
calc.bandgap.print()
Band structure
--------------
                       spin independent             spin component 1             spin component 2
val. band max:               7.160797                     7.160797                     7.160797
cond. band min:             10.735997                    10.735997                    10.735997
fundamental gap:             3.575200                     3.575200                     3.575200
VBM @ kpoint:       0.5000   0.5000   0.5000     0.5000   0.5000   0.5000     0.5000   0.5000   0.5000
CBM @ kpoint:       0.5000   0.3333   0.3333     0.5000   0.3333   0.3333     0.5000   0.3333   0.3333

lower band:                  6.885102                     6.885102                     6.885102
upper band:                 10.900366                    10.900366                    10.900366
direct gap:                  4.015264                     4.015264                     4.015264
@ kpoint:           0.5000   0.5000   0.3333     0.5000   0.5000   0.3333     0.5000   0.5000   0.3333

Fermi energy:                8.948397
4.3.3 Analysis

Let us fit the Birch-Murnaghan equation of state! df_extended is a dataframe that will hold both the setup and the analysis.

In [27]:
from ase.eos import EquationOfState

extended_dfs = []
for p, group in df.groupby('PAW potential'):
    for u_value, g in group.groupby('U (in eV)'):
        volumes = g['lattice constants'].values**3
        energies = g['total energy (in eV)'].values
        eos = EquationOfState(volumes, energies, eos='birchmurnaghan')
        v0, e0, B = eos.fit()

        # Add results to a copy of the group
        g_extended = g.copy()
        g_extended['equilibrium lattice constant (in Å)'] = v0**(1/3)
        g_extended['equilibrium volume (in ų)'] = v0
        g_extended['minimum energy (in eV)'] = e0
        g_extended['bulk modulus in (eV/ų)'] = B

        # Append to the list
        extended_dfs.append(g_extended)

# Combine all groups back into one DataFrame
df_extended = pd.concat(extended_dfs, ignore_index=True)
df_extended
Out[27]:
lattice constants U (in eV) total energy (in eV) PAW potential fundamental bandgap (in eV) on-site moment (in muB) equilibrium lattice constant (in Å) equilibrium volume (in ų) minimum energy (in eV) bulk modulus in (eV/ų)
0 3.860800 0.0 -26.390711 PAW_NiO 0.406628 0.897 4.064369 67.139690 -27.113975 0.789642
1 3.962400 0.0 -26.949133 PAW_NiO 0.428786 0.985 4.064369 67.139690 -27.113975 0.789642
2 4.064000 0.0 -27.113992 PAW_NiO 0.446935 1.063 4.064369 67.139690 -27.113975 0.789642
3 4.165600 0.0 -26.978612 PAW_NiO 0.457956 1.130 4.064369 67.139690 -27.113975 0.789642
4 4.267200 0.0 -26.615759 PAW_NiO 0.460449 1.185 4.064369 67.139690 -27.113975 0.789642
5 3.860800 3.0 -24.954936 PAW_NiO 1.414804 1.273 4.064386 67.140525 -25.647010 0.761359
6 3.962400 3.0 -25.488605 PAW_NiO 1.444470 1.332 4.064386 67.140525 -25.647010 0.761359
7 4.064000 3.0 -25.647054 PAW_NiO 1.459294 1.381 4.064386 67.140525 -25.647010 0.761359
8 4.165600 3.0 -25.516045 PAW_NiO 1.459609 1.421 4.064386 67.140525 -25.647010 0.761359
9 4.267200 3.0 -25.163308 PAW_NiO 1.445897 1.454 4.064386 67.140525 -25.647010 0.761359
10 3.833250 8.0 -22.899825 PAW_NiO 3.697964 1.662 4.035195 65.704266 -23.518713 0.712837
11 3.934125 8.0 -23.375590 PAW_NiO 3.650899 1.685 4.035195 65.704266 -23.518713 0.712837
12 4.035000 8.0 -23.518909 PAW_NiO 3.575212 1.706 4.035195 65.704266 -23.518713 0.712837
13 4.135875 8.0 -23.396933 PAW_NiO 3.471735 1.724 4.035195 65.704266 -23.518713 0.712837
14 4.236750 8.0 -23.065906 PAW_NiO 3.171302 1.740 4.035195 65.704266 -23.518713 0.712837
15 3.863650 0.0 -28.227482 PAW_Ni_sv_GWO_s 0.430335 0.945 4.066571 67.248895 -28.937556 0.784075
16 3.965325 0.0 -28.776264 PAW_Ni_sv_GWO_s 0.453031 1.032 4.066571 67.248895 -28.937556 0.784075
17 4.067000 0.0 -28.938110 PAW_Ni_sv_GWO_s 0.470732 1.107 4.066571 67.248895 -28.937556 0.784075
18 4.168675 0.0 -28.800143 PAW_Ni_sv_GWO_s 0.480531 1.170 4.066571 67.248895 -28.937556 0.784075
19 4.270350 0.0 -28.436267 PAW_Ni_sv_GWO_s 0.481443 1.221 4.066571 67.248895 -28.937556 0.784075
20 3.880750 3.0 -26.151315 PAW_Ni_sv_GWO_s 1.501121 1.334 4.085210 68.177816 -26.846606 0.754945
21 3.982875 3.0 -26.687364 PAW_Ni_sv_GWO_s 1.523146 1.387 4.085210 68.177816 -26.846606 0.754945
22 4.085000 3.0 -26.847213 PAW_Ni_sv_GWO_s 1.530766 1.431 4.085210 68.177816 -26.846606 0.754945
23 4.187125 3.0 -26.713849 PAW_Ni_sv_GWO_s 1.524065 1.465 4.085210 68.177816 -26.846606 0.754945
24 4.289250 3.0 -26.358725 PAW_Ni_sv_GWO_s 1.505020 1.493 4.085210 68.177816 -26.846606 0.754945
25 3.913050 8.0 -22.327825 PAW_Ni_sv_GWO_s 3.897360 1.644 4.119349 69.901363 -22.995955 0.711746
26 4.016025 8.0 -22.842484 PAW_Ni_sv_GWO_s 3.853403 1.674 4.119349 69.901363 -22.995955 0.711746
27 4.119000 8.0 -22.996005 PAW_Ni_sv_GWO_s 3.512612 1.699 4.119349 69.901363 -22.995955 0.711746
28 4.221975 8.0 -22.867931 PAW_Ni_sv_GWO_s 2.972935 1.720 4.119349 69.901363 -22.995955 0.711746
29 4.324950 8.0 -22.521736 PAW_Ni_sv_GWO_s 2.485159 1.737 4.119349 69.901363 -22.995955 0.711746

Using the scripts below, plot the equilibrium lattice constant, magnetic moment and bandgap as a function of the U value for both choices of the PAW potential. Do all quantities depend on the choice of the PAW potential? Is the dependence only present in DFT+U or also for the plain LSDA calculation?

In [28]:
import matplotlib.pyplot as plt

plot_data = {}

for p, group in df_extended.groupby('PAW potential'):
    us, mags, gaps, elat = [], [], [], []
    for u_value, g in group.groupby('U (in eV)'):
        # Get the equilibrium lattice constant for this group
        a_eq = g['equilibrium lattice constant (in Å)'].iloc[0]

        # Find the row with lattice constant closest to equilibrium
        idx = (g['lattice constants'] - a_eq).abs().idxmin()
        closest_row = g.loc[idx]

        # Record U and magnetic moment
        us.append(u_value)
        mags.append(closest_row["on-site moment (in muB)"])
        gaps.append(closest_row['fundamental bandgap (in eV)'])
        elat.append(g['equilibrium lattice constant (in Å)'].values[-1])

    # Store in dict by PAW potential
    plot_data[p] = (us, mags, gaps, elat)
In [29]:
plt.figure(figsize=(8, 5))
for p, (us, mags, gaps, elat) in plot_data.items():
    plt.plot(us, elat, marker='o', label=p)

plt.xlabel("U value (in eV)")
plt.ylabel("Equilibrium lattice constant (in Å)")
plt.title("Equilibrium lattice constant vs U value for each PAW Potential")
plt.legend()
plt.grid(True)
plt.tight_layout()
plt.show()
No description has been provided for this image

The equilibrium lattice constant shows a dramatically different behaviour as a function of U for the two PAW potentials. For the Ni_sv_GW the Ni p and s orbitals are both in the valence. These hybridize with the Ni d orbitals. For increasing U values the d states are pushed away from the Fermi energy and decrease in size. Thus, the entangled sp orbitals expand and the lattice constant increases.

On the other hand, the simple Ni PAW potential holds the sp orbitals in the frozen core. Hence, they cannot expand and the lattice constant does not increase. Instead the lattice constant even slightly decreases due to the shrinking d orbitals.

In [30]:
plt.figure(figsize=(8, 5))
for p, (us, mags, gaps, elat) in plot_data.items():
    plt.plot(us, mags, marker='o', label=p)

plt.xlabel("U value (in eV)")
plt.ylabel("Magnetic moment (in muB)")
plt.title("Magnetic moment vs U value for each PAW Potential")
plt.legend()
plt.grid(True)
plt.tight_layout()
plt.show()
No description has been provided for this image

Here, we see that increasing the on-site Coulomb interaction can have a significant effect on the on-site magnetic moments at the equilibrium lattice constant. Yet, since the magnetic moment arises in the Ni d orbitals, the effect of the selected PAW potentials is very small.

In [31]:
plt.figure(figsize=(8, 5))
for p, (us, mags, gaps, elat) in plot_data.items():
    plt.plot(us, gaps, marker='o', label=p)

plt.xlabel("U value (in eV)")
plt.ylabel("Bandgap (in eV)")
plt.title("Fundamental bandgap vs U value for each PAW Potential")
plt.legend()
plt.grid(True)
plt.tight_layout()
plt.show()
No description has been provided for this image

We finally see that the choice of the PAW potential has vanishing effects on the electronic bandgap at the equilibrium lattice constant as a function of U. This emphasizes that one has to consider multiple aspects when selecting a PAW potential. In this example, the DFT+U method plays a central role, as well as the quantity of interest. The most accurate results are always obtained with the more expensive PAW potentials, which may, e.g., treat more electrons as valence, or use a higher cutoff energy. However, if the quantity of interest is not sensitive to the choice of the PAW potential it is better to opt for a cheaper pseudopotential to avoid unnecessary computational cost.

Also note that the quantity of interest may depend on the volume. Many publications use the experimental lattice constant, but you should keep in mind that the equilibrium lattice constant depends amongst other aspects on the selected exchange-correlation functional. See below how the bandgap changes with the lattice constant.

In [32]:
import plotly.express as px
for p, group in df.groupby('PAW potential'):
    fig = px.line(
    group,
    x='lattice constants',
    y='fundamental bandgap (in eV)',
    color='U (in eV)',
    markers=True,
    title=p+': Bandgap vs lattice constant for different U values'
    )

    fig.update_layout(
    xaxis_title='Lattice constant (Å)',
    yaxis_title='Fundamental bandgap (in eV)',
    legend_title='U (eV)',
    template='plotly_white'
    )

    fig.show()

4.4 Questions

  1. What is an equation of state?
  2. Is there a particular quantity that the choice of the PAW potential should be based on?
  3. What options does the LDAUTYPE tag offer?

Well done! You have finished Part 1 of the magnetism tutorial!