Skip to content

First run with Quantum ESPRESSO

Here we compute the five elastic constants of wurtzite AlN with pw.x, starting from the input files of the relaxed structure. This takes four single-point calculations, 9 s in total on one 32-core node. The output shown below is from these runs.

1. Prepare the template

minelastic writes the input of every strained cell from a template: the pw.x input of the relaxed reference structure. We use examples/qe_aln/pw.in from the repository:

&CONTROL
  calculation = 'scf'
  prefix = 'aln'
  pseudo_dir = './pseudo'
  outdir = './tmp'
/
&SYSTEM
  ibrav = 4, celldm(1) = 5.911804, celldm(3) = 1.603472
  nat = 4, ntyp = 2
  ecutwfc = 50, ecutrho = 400
  occupations = 'fixed'
/
&ELECTRONS
  conv_thr = 1.0d-10
/
&IONS
/
ATOMIC_SPECIES
Al 26.982 Al.pbe-n-kjpaw_psl.1.0.0.UPF
N  14.007 N.pbe-n-kjpaw_psl.1.0.0.UPF
ATOMIC_POSITIONS crystal
Al 0.3333333333 0.6666666667 0.0000
Al 0.6666666667 0.3333333333 0.5000
N  0.3333333333 0.6666666667 0.3818
N  0.6666666667 0.3333333333 0.8818
K_POINTS automatic
8 8 5 0 0 0

It uses the PBE functional and the PAW potentials Al.pbe-n-kjpaw_psl.1.0.0.UPF and N.pbe-n-kjpaw_psl.1.0.0.UPF of pslibrary 1.0.0, with tight cutoffs and convergence threshold; the structure was relaxed with these settings.

Pseudopotential path

Every calculation runs in a directory of its own, so set pseudo_dir to the absolute path of the directory with the pseudopotential files.

Convergence

Elastic constants are obtained from derivatives of the stress with respect to the strain, which are estimated from stress differences of a few GPa. They are therefore much more sensitive to the cutoffs, the k-point mesh, the smearing and the convergence threshold than total energies are. The settings here are chosen to show the workflow; they are not the result of a convergence study. Before using the constants in a publication, check that they change by less than the accuracy you need when the cutoffs are raised and the k-point mesh refined, and relax the reference structure with the final settings.

2. Look at the strain set

minelastic info analyses the structure without writing anything:

$ minelastic info --code qe qe_aln/pw.in --stencil central
space group P6_3mc (186), point group 6mm, elastic type hexagonal
5 independent constants: c11, c12, c13, c33, c44
invariant strains (free lattice parameters) = minimum number of strain patterns: 2
stiffness matrix in the working frame:
          c11            c12            c13              0              0              0
          c12            c11            c13              0              0              0
          c13            c13            c33              0              0              0
            0              0              0            c44              0              0
            0              0              0              0            c44              0
            0              0              0              0              0  (c11 - c12)/2
strain set 'minimal': 2 pattern(s), step 0.01, multipliers (-1, 1)
  pattern 1: xx+yz          s1 = 1 c11, s2 = 1 c12, s3 = 1 c13, s4 = 1 c44
  pattern 2: zz             s1 = 1 c13, s2 = 1 c13, s3 = 1 c33

The crystal is hexagonal, with five independent elastic constants, and two strain patterns determine all of them. Pattern 1 stretches the cell along x and shears it in the yz plane at the same time; pattern 2 stretches it along z. The entry s1 = 1 c11 means that the first stress component of pattern 1, \(\sigma_{xx}\), equals \(c_{11}\) times the strain. Every constant appears alone in at least one stress component, so each is read off directly.

Two points per strain

By default minelastic applies each pattern at \(\pm 0.01\) and \(\pm 0.02\), which makes the numerical derivative more accurate but doubles the number of calculations. For this first run, --stencil central keeps only \(\pm 0.01\) (the multipliers -1 and 1 in the output above).

3. Write the inputs

$ minelastic generate qe qe_aln/pw.in -o el --stencil central
...
4 calculations written to el/ (list in el/STATES)
$ cat el/STATES
s1_m1
s1_p1
s2_m1
s2_p1
$ ls el/s1_p1
pw.in

generate prints the same analysis as info (left out here) and writes one directory per strained cell: s1_p1 is pattern 1 at \(+0.01\), s2_m1 pattern 2 at \(-0.01\). Each pw.in is the template with the strained cell written out (ibrav = 0, CELL_PARAMETERS in Å, ATOMIC_POSITIONS crystal) and with tstress and tprnfor switched on; everything else is copied unchanged.

4. Run pw.x

The four calculations are independent. Run them one after another,

for d in $(cat el/STATES); do (cd el/$d && mpirun pw.x -in pw.in > pw.out); done

or at the same time, for example as a Slurm job array:

#!/bin/bash
#SBATCH --array=1-4
d=el/$(sed -n "${SLURM_ARRAY_TASK_ID}p" el/STATES)
cd "$d" && srun pw.x -in pw.in > pw.out

5. Collect the results

$ minelastic collect el
minelastic 0.1.0: P6_3mc (186), hexagonal, 2 strain pattern(s), method 'uncoupled'
  c11 =     445.37 GPa
  c12 =     100.00 GPa
  c13 =      64.21 GPa
  c33 =     437.66 GPa
  c44 =     125.02 GPa
stiffness matrix (GPa, Voigt xx yy zz yz xz xy, working frame):
     445.37    100.00     64.21      0.00      0.00      0.00
     100.00    445.37     64.21      0.00      0.00      0.00
      64.21     64.21    437.66      0.00      0.00      0.00
       0.00      0.00      0.00    125.02      0.00      0.00
       0.00      0.00      0.00      0.00    125.02      0.00
       0.00      0.00      0.00      0.00      0.00    172.68
Born stable: True (eigenvalues 125.0, 125.0, 172.7, 345.4, 385.9, 597.1)
K_VRH = 198.18  G_VRH = 155.29  E = 369.38 GPa  nu = 0.189  A_U = 0.171
consistency (redundant stress components): largest |computed - fitted| = 0.00 GPa (pattern 1, xz)

written el/elastic.json

collect reads the stress of each cell from pw.out and prints:

  • the five independent constants and the full stiffness matrix, in GPa, with \(C_{66} = (c_{11} - c_{12})/2\);
  • the Born stability test: the crystal is mechanically stable if all eigenvalues of the matrix are positive;
  • the Voigt-Reuss-Hill bulk modulus K, shear modulus G and Young's modulus E, Poisson's ratio nu and the universal anisotropy index A_U;
  • a consistency check: the stress components that are not needed for the constants are compared with the values that the fitted tensor predicts. A deviation of more than a few tenths of a GPa points to an unrelaxed reference structure, loose convergence or a lower symmetry than assumed.

6. Use the results

Everything is also written to el/elastic.json:

import json

with open("el/elastic.json") as f:
    res = json.load(f)
print({name: round(value, 2) for name, value in res["constants"].items()})
print(f"bulk modulus {res['properties']['K_H']:.1f} GPa, shear modulus {res['properties']['G_H']:.1f} GPa")
{'c11': 445.37, 'c12': 100.0, 'c13': 64.21, 'c33': 437.66, 'c44': 125.02}
bulk modulus 198.2 GPa, shear modulus 155.3 GPa

res["C"] is the 6 x 6 matrix. The other entries are listed under Command line.

7. Check the result

The same calculation with the six single strains (--scheme asess, 12 cells) gives, with the same settings:

GPa c11 c12 c13 c33 c44
minelastic (4 cells) 445.37 100.00 64.21 437.66 125.02
six single strains (12 cells) 445.35 100.04 64.18 437.66 124.97

The two agree to 0.05 GPa with a third of the calculations. The VASP tutorial gives values a few GPa lower, because the PAW datasets and cutoffs differ.

The forces in the same four cells also give the internal-strain tensor, the force on each atom per unit strain, without further calculations:

$ minelastic collect el --internal-strain
...
internal strain tensor dF/de (eV/A), columns xx yy zz yz xz xy:
  ion   1 x     0.0000    -0.0000     0.0000     0.0000    -5.1051    -8.5575
  ion   1 y    -8.5576     8.5575     0.0000    -5.1051    -0.0000     0.0000
  ion   1 z    -5.2838    -5.2838    11.4889    -0.0000     0.0000     0.0000
...

The relaxed-ion constants need the ions relaxed in each strained cell, or a few more single points with displaced atoms; both are described in Relaxed-ion constants.