# Extremal points and effective mass

This tutorial demonstrates how to find extremal points (maxima, minima, and saddle points) in the Brillouin zone, and calculate effective masses using the *band-edge* utility. LDA silicon was chosen for simplicity, though it is a trivial example as its extremal points are found on high-symmetry lines. *band-edge* is particularly useful when searching for multiple extremal points, and/or points distinct from those of high symmetry.

We use Si here, as it is a simple case: the valence band maximum falls at the Γ point, and the conduction band minum falls on the (001) line connecting and X, at about 0.85 of the distance to X.

At the end of this tutorial the *band-edge* manual that documents its usage in more detail.

Self-consistent LDA potential and energy bands

```
blm init.si --simple --wsite --nk,ins --ctrl=ctrl && lmfa ctrl.si && lmf ctrl.si > out.lmfsc
```

Find conduction band minimum and effective mass:

```
band-edge -floatmn -maxit=20 -r=0.1 -band=5 -q0=0.1,0.2,0.3 si
band-edge -edge2 -maxit=20 -r=.04 -band=5 -gtol=.0001 -q0=-0.02,0.01,0.83 si
band-edge -mass -alat=10.26 -r=.0005,.001,.002,.003 -band=5 -q0=0,0,0.846 si
band-edge -mass -alat=10.26 -r=.0005,.001,.002,.003 -band=5 -q0=0,0,0.846 si
```

### Preliminaries

This tutorial uses a number of Questaal executables and scripts, e.g. *band-edge*, *blm*, *lmfa*, *lmf*, *pfit*, *fmain*, *plbnds*, and *fplot*. They are assumed to be in your path.

### Tutorial

The starting point is a self-consistent LDA calculation. You will need the *init.si* from the basic DFT tutorial for silicon. Starting in a clean directory, paste the *init* file from that tutorial into *init.si* and do

```
blm init.si --simple --wsite --nk,ins --ctrl=ctrl && lmfa ctrl.si && lmf ctrl.si > out.lmfsc
```

The command above repeats all the steps of that tutorial.

It will also be helpful to refer to the Si band structure, which is generated in this tutorial.

#### Find the conduction band effective mass

We will now use the *band-edge* script to accurately locate the position of the conduction band minimum and to calculate the effective mass. This is done in three steps. First do a rough search by **‘floating’** to a point near the minimum. Next, do a more refined search by carrying out a minimization until the gradient is negligibly small. Finally the extremal point is known, calculate the effective mass around this point.

##### 1. Float to low-energy point

*band-edge* script has a **‘float’** option that is useful for doing a quick search to find a low-energy (or high-energy) region of k-space. You specify a starting point, then the script creates a cluster of points around it and checks what is the lowest-energy point. It then uses the lowest-energy point as the next central point, creates a new set of points around it and again moves to the lowest-energy one. This process is repeated until the central point is the lowest-energy point.

Let’s pick a random point (0.1,0.2,0.3) and let *band-edge* float downhill. Run the following command:

```
band-edge -floatmn -maxit=20 -r=0.1 -band=5 -q0=0.1,0.2,0.3 si
```

**‘−floatmn’** tells *band-edge* to seek a minimum-energy point (see additional exercises for a maximum-energy point example). **‘−maxit’** switch limits the number iterations (number of times a set of points is created) in case convergence is not reach before then, **‘−r=’** sets a range that defines how far from the centre the points are generated, **‘−band’** is for the band considered (here conduction band is 5 since 4 electrons and spin degenerate) and lastly **−q0** is the starting k-point. To see what switches *band-edge* has, invoke it without any arguments, or see documentation below.

You should get an output similar to the following:

check that "lmf si" reads input file without error ... ok start iteration 1 of 20 lmf si --band~lst=5~box=0.1,n=12+o,q0=0.1,0.2,0.3 > out.lmf qnow, E : 0.100000 0.200000 0.300000 0.3483071 ← q and energy at this q gradient : -0.154683 0.182791 -0.061850 0.247315 ← gradient and magnitude of gradient q* : 0.160184 0.114033 0.240965 ← estimate minimum point from gradient use : 0.027639 0.147427 0.344721 ← Lowest-energy point in cluster ... start iteration 8 of 20 lmf si --band~lst=5~box=0.1,n=12+o,q0=-0.017083,0.009789,0.834163 > out.lmf qnow, E : -0.017083 0.009789 0.834163 0.1956728 gradient : -0.045677 0.028221 -0.015188 0.055799 q* : -0.004553 0.001048 0.844981 cluster center is extremal point ... exiting loop q @ minimum gradient : -0.017083 0.009789 0.834163 Final estimate for q : -0.017083 0.009789 0.834163

Take a look at the first line beginning with *lmf*. *band-edge* tells you what command it uses for the energy of each point in the cluster around your starting point. In each iteration **qnow** gives the current central k-point and its energy in Rydbergs. **‘use’** prints the lowest-energy k-point in the cluster of points around the middle point; this will then be used as the central point in the next iteration. The cluster of 13 k-points and their energies are printed to *bnds.si*. Take a look and you will see that **(-0.017083, 0.009789, 0.834163)** is indeed the lowest-energy point in the cluster.

As the iterations proceed, note that the energies at **qnow** are going down as we float to a low-energy region. After 8 iterations, the following is printed: **‘cluster center is extremal point … exiting loop’**. The central **q**-point is the lowest-energy point and the float routine is finished.

##### 2. Gradient minimization

Starting from the low-energy point we floated to, the next step is to do a more refined search using a gradient minimization approach. *band-edge* creates a new cluster of points, does a quadratic fit and then traces the gradients to a minimum point. Run the following command:

```
band-edge -edge2 -maxit=20 -r=.04 -band=5 -gtol=.0001 -q0="-0.017083 0.009789 0.834163" si
```

**‘edge2’** specifies what gradient minimization algorithm to use. All the switches are explained in the documentation below.

The output is similar to before but now subsequent iterations (**use**) tracks the gradient rather than the minimum-energy point in the cluster

qnow, E : -0.017083 0.009789 0.834163 0.1956728 gradient : -0.064590 0.036226 -0.009795 0.074700 ← gradient and magnitude of gradient q* : -0.000123 -0.000442 0.843534 use : -0.000123 -0.000442 0.843534 ... qnow, E : -0.000045 0.000000 0.845004 0.2122582 gradient : -0.000004 0.000000 -0.000004 0.000006 q* : -0.000044 0.000000 0.845009 use : -0.000044 0.000000 0.845009 gradient converged to tolerance gtol = .0001 q @ minimum gradient : -0.000045 0.000000 0.845004 Final estimate for q : -0.000044 0.000000 0.845009

Note how the gradient magnitude is decreasing with each step until it falls below the specified tolerance (**gtol**). The gradient minimization converged in this case, with minimum gradient at **(0, 0, 0.846)**.

##### 3. Calculate effective mass

Now that we have accurately determined the conduction band minimum, we can calculate the effective mass. This is done by fitting a quadratic form to a set of points around the conduction band minimum. Run the following command:

```
band-edge -mass -alat=10.26 --h5 -r=.0005,.001,.002,.003 -band=5 -q0=0,0,0.845 si
```

**-mass**tells*band-edge*to estimate the effective mass tensor.**-alat**specifies the lattice constant (found in various places such as the*lmf**stdout*,*init*or*site*file). The lattice constant is needed to convert to atomic units since the code reports k-points in units of .**-r**specifies the radii of the four clusters of points around the central point; each radius has 32 points (points and faces of an icosohedron). The extra points improve the accuracy of the quadratic fitting.

The last line of the output prints the three effective mass components in atomic units. So for silicon, the effective mass is anisotropic with lighter masses in two directions and a heavier effective mass in the third direction.

```
0.941601 0.187815 0.187815
```

The masses are fairly close to experimental values for Si.

To see the principal axes (eigenvectors of the mass tensor) do the following:

```
echo princ | pfit 2 bndsa.si
```

The three columns below **eval** are the three principal axes (eigenvectors of the quadratic form). The first points along *z*, while the latter two (which are degenerate) lie in the *x-y* plane.

### The band-edge manual

*band-edge* is shell script that calls *lmf* (or any Questaal executable that can generate energy bands through the `--band`

switch.

Its purpose is to find band extrema and it operates in four distinct modes. All modes start from a reference **q** point, and compute energy bands in a cluster of points around the reference. One band in particular is selected out. The cluster of points are arranged in some regular polyhedron with 12, 20, or 32 points in a shell. You specify the radius of the polyhedron (or radii of multiple shells if desired). Energy bands are generated by invoking *lmf* or similar code with the `--band`

switch, which is invoked in a special-purpose **box** mode that makes bands for clusters of **q** points centered around a reference.

The four modes are:

- (
**-floatmx**or**-floatmn**) Update the current**q**point by indentifying whichever point in the cluster has the maximum value (**-floatmx**) or minimum value (**-floatmn**). If the central point is the extremal point,*band-edge*exits. Otherwise, the extremal point becomes the new central point and the cycle is repeated. - (
**-edge**) The selected energy band at a given cluster of points is subject to a least-squares fit and the gradient in**q**extracted. The**q**point and gradient are fed to a Broyden minimization algorithm built into the*fmin*utility.*fmin*returns a new estimate for the extremal point. The process is iterated until the gradient falls below a specified tolerance. - (
**-edge2**) The selected energy band at a given cluster of points is fit to a quadratic polynomial in*q*,_{x}*q*,_{y}*q*and the extremal point is estimated from the extremal point of the parabola. This new point becomes the reference point; the process is iterated until the gradient falls below a specified tolerance._{z} - (
**-mass**) The selected energy band at a given cluster of points is fit to a quadratic polynomial. The normal matrix is diagonalized; its eigenvalues are the tensor effective masses and eigenvectors are the principal axes of the mass tensor.

Usage : `band-edge switches ext`

`ext`

is the extension in *ctrl.ext*, the input file the band code uses to generate . By default *band-edge* uses *lmf* (but see **-cmd** below).

Choose between one of the following modes :

**-edge**

Seek extremal q by calculating and minimizing it using a Broyden algorithm**-edge2 | -edge2=***fac*

Seek extremal q using 1st and 2nd derivatives of , from a polynomial fit to on the cluster.

Calculates`qnew = (1-fac)*qold + fac*qmin`

where`qmin`

is extremal point estimated from quadratic form.

`fac`

is used if it is specified; otherwise`fac=1`

. Independently of`fac`

, the change in**q**might be limited by**dqmx**(below)**-floatmx**

Update reference**q**with largest in cluster. Iterate until the reference point (cluster center) is the maximum point.**-floatmn**

Update reference**q**with smallest in cluster. Iterate until the reference point (cluster center) is the minimum point.**-mass**

Fit bands around**q0**to estimate effective mass tensor.

Required switches:

**-q0=#,#,#**

Starting value of reference**q****-band=***n*

Specify band indexto optimize*n***-r=#[,#2,#3,…]**

Shell radius (or radii)**r**for cluster centered at**q****-alat=***a*

Lattice constant*a*(a.u.). It is not needed except in the calculation of effective mass (required there because**q**has units 2*π**a*).

Optional switches:

**-h | --h | --help**

show this message**-cmd=***strn*

use*strn*in place of default command to generate bands, e.g.

`-cmd="mpirun -n 16 lmf"`

Default**cmd**is`lmf`

.**-n=12 | -n=20 | -n=32**

Specify number of points in shell of radius**r****-dqmx=#**

Maximum allowed change n any component of**q**for one iteration**-gtol=#**

Convergence tolerance in the gradient (applies to`-edge`

and`-edge2`

)**–maxit=#**

Maximum number of iterations to attempt**–spin1**

replace`--band`

with`-band~spin1`

**–spin2**

replace`--band`

with`-band~spin2`

**–noexec**

Show what**cmd**will be executed, without executing it**–h5**’ Tell the bands maker to write bands in hdf5 format

### Additional Exercises

**1) Valence band maximum and effective mass**

Although we know the valence band maximum for silicon is at the point, we will use it as an example for finding a maximum point. Try starting from the point **(0.1,0.1,0.1)**. In the float step, change the **floatmn** (for minimum) to **floatmx** (for maximum) and change the band number to 4 (for valence band). Notice the energies are going up. Now do a gradient minimization from the point you floated to, remember to change the band number to 4. The valence band maximum is in a flatter region so try using a smaller excursion radius, say 0.001. Then calculate the effective mass. Your values should be around **(-0.34, -0.56, -0.88)**. The negative signs indicate a maximum point (**−mass** = hole mass); a saddle point would have at least one positive sign.