Anharmonic Force Constants with thirdorder.py
As an alternative to phono3py, we also support anharmonic force constants generated from ShengBTE’s thirdorder.py script (specifically, when used with QE as the force calculator). These constants can also be used with the phonon transport app from Phoebe.
Step 1: Run pw.x
Again, we start by calculating the total energy of the silicon unit cell. This calculation will create the ground state charge density and wavefunctions that are used in further calculations.
To run, go to the folder ./example/Silicon-ph/qe-phonons
in the phoebe repository.
The file scf.in
is the input file for the pw.x
executable, and is shown below:
&control
calculation = "scf"
restart_mode = "from_scratch"
prefix = "silicon"
tstress = .true.
tprnfor = .true.,
pseudo_dir = "../../pseudoPotentials/"
outdir = "./out"
/
&system
ibrav = 2
celldm(1) = 10.2
nat = 2
ntyp = 1
ecutwfc = 30.
/
&electrons
conv_thr = 1.0d-14
/
ATOMIC_SPECIES
Si 28.086 Si.pz-vbc.UPF
ATOMIC_POSITIONS alat
Si 0.00 0.00 0.00
Si 0.25 0.25 0.25
K_POINTS automatic
6 6 6 0 0 0
A detailed description of these parameters can be found on Quantum ESPRESSO’s website. The most important parameters are:
K_POINTS: the parameter controlling the integration mesh of wavevectors on the Brillouin zone. Phonon properties should be converged against this mesh (more wavevectors is better). Tip:
ph.x
calculations are faster when the k-mesh is gamma-centered.ecutwfc: the parameter controlling the number of G-vectors used in the plane-wave expansion of the wavefunction. Phonon frequencies should be converged against this value.
conv_thr: this parameter controls the total energy convergence threshold. Note that a low value of conv_thr may result in poorly converged phonon properties.
prefix: prefix of some output files. Make sure to use a consistent value of prefix throughout your calculations.
outdir: name of the scratch folder. Must be used consistently throughout the run so that it points to the correct files.
This list is obviously not complete, and for your research project you may need to use more functionalities from QE’s pw.x
.
Simply run it as:
/path/to/qe/pw.x -in scf.in > scf.out
after substituting the suitable path to the pw.x executable.
Step 2: Run ph.x
The input file ph.in
is as follows:
phonons of Si
&inputph
tr2_ph = 1.0d-14
prefix = "silicon"
ldisp = .true.
nq1 = 4
nq2 = 4
nq3 = 4
outdir = "./out"
fildyn = "silicon.dyn"
/
The values of nqX
select the Monkhorst-Pack grid of q-points centered at Gamma, for which we will compute the phonon properties.
Also, it’s important that prefix
and outdir
are the same as those used in the pw.x
calculation from step 2.
Use a good value of tr2_ph
(smaller is better, but harder to converge), which (indirectly) checks the convergence of phonon frequencies.
Run the code as:
/path/to/qe/bin/ph.x -in ph.in > ph.out
If the code executes correctly and completely, you should see a number of files called {fildyn}*
, as many files as the number of irreducible q-points.
Note
We recommend you parallelize this calculation using the npool
flag from QE. This parameter controls the parallelization over k-points. It gives an almost linear speedup, but is bound by the number of k-points. For example, the below line will run QE divided into “pools” of 4 k-points:
mpirun -np 4 /path/to/qe/bin/ph.x -npool 4 -in ph.in > ph.out
Note
For a real calculation, we strongly recommend to check the convergence of the phonon frequencies with respect to the k-point mesh, the q-point mesh, the wavefunction cutoff and the tr2_ph
parameter. We also recommend to using a small conv_thr
, as done here in the scf.in
file above.
Step 3: Run q2r.x
The code ph.x
has created a set of silicon.dyn*
files, which contain the dynamical matrix at every irreducible q-point.
ow, we run q2r.x
in order to Fourier transform the dynamical matrices in the reciprocal space representation to the real space representation, where they represent the harmonic interatomic force constants.
The input file q2r.in
is minimal:
&input
fildyn='silicon.dyn',
flfrc='silicon.fc'
/
where the first variable must match the path to the dynamical matrices created earlier by ph.x
, and flfrc
specifies the name of the output file q2r.x
will create, which contains the harmonic force constants.
In the working folder ./example/Silicon-ph/qe-phonons
run the command:
./path/to/qe/bin/q2r.x -in q2r.in > q2r.out
If the code run successfully, you should see a new file silicon.fc
.
Step 4: Calculate Anharmonic Force Constants
In this section, we want to use a finite-displacement approach to compute the matrix of third derivatives of the total energy with respect to ionic displacements.
To calculate these third-order force constants, we will use Quantum ESPRESSO to compute energies/forces, and a script provided by ShengBTE called thirdorder.py
to generate a pattern of displacements on a supercell of the original silicon crystal. We then use QE to calculate the forces associated with these displacement patterns.
Download
thirdorder.py
from the ShengBTE websiteUntar the file, and cd into the
./thirdorder
directory that has been just createdModify the source code in the following way:
Modify line 559 of file
thirdorder_core.c
, from#include "spglib/spglib.h"
to#include "spglib.h"
.In file
setup.py
, set line 10 asINCLUDE_DIRS = ["/your/path/to/phoebe/build/spglib_src/src"]
and line 13 asLIBRARY_DIRS = ["/your/path/to/phoebe/build/spglib_build"]
.
After making these modifications, open a terminal in the
./thirdorder
directory and type:./compile.sh
If everything works, you should find a
*.so
file in the subdirectories of./thirdorder/build
.Now, go back to the Phoebe example directory
/path/to/phoebe/example/Silicon-ph/thirdorder.py-anharmonic/
. Let’s check the filesupercell_template.in
:&control calculation = 'scf' restart_mode='from_scratch', prefix='silicon', tstress = .true. tprnfor = .true., pseudo_dir = '../../pseudoPotentials/', outdir='./out', / &system ibrav = 0 nat = ##NATOMS## ntyp = 1, ecutwfc = 30. / &electrons conv_thr = 1.0d-10 / ATOMIC_SPECIES Si 28.086 Si.pz-vbc.UPF ##COORDINATES## ##CELL## K_POINTS automatic 3 3 3 0 0 0
As you can see, the file is the same as
scf.in
, but with a few notable modificatons:Set
tstress
andtprnfor
to true.Removed
celldm
(and you should removealat
, if used)Set
ibrav=0
Set a
##NATOMS##
in place of the number of atoms for thenat
variable.Removed
CELL_PARAMETERS
andATOMIC_POSITIONS
sections and replaced them with tags##COORDINATES##
and##CELL##
.Modified the k-points, as the k-point density should decrease as the inverse of the size of the supercell we will set up. In this case, we initially set a k-point mesh of 6x6x6 points, but we will set up a supercell of size 2x2x2 and thus the new supercell k-point mesh is 3x3x3.
Note
If you use the K_POINTS gamma
keyword, make sure you don’t use the patched version of QE modified for the electron-phonon coupling, or use it with K_POINTS automatic
.
Now, we generate a set of atomic displacements on a supercell. These displacements are needed to compute the third-order force constants. From the Phoebe
example/Silicon-ph/thirdorder.py-anharmonic/
directory, execute the following:ln -s /your/path/to/thirdorder_espresso.py . python3 thirdorder_espresso.py scf.in sow 2 2 2 -3 supercell_template.in
In the first command, we link the script provided by
thirdorder
. Make sure you change the path to point to thethirdorder_espresso.py
script. Next, you can see the script takes 7 parameters:scf.in
- the QE input for the unit cell.sow
- tells the script to generate displaced supercells.2 2 2
- three parameters indicating the dimensions of the supercell, which here is 2x2x2.-3
- indicates that we only include interactions up to the third-nearest neighbor.supercell_template.in
- we pass the path to the supercell template discussed above.
This script will create a lot of input files, potentially up to the cube of the number of atoms in the supercell. Therefore, choose an appropriate number of nearest neighbors (and make sure to converge the thermal conductivity against this parameter).
It’s time to run all of these supercell calculations! You can do this by typing in the terminal:
for f in DISP.supercell_template.in.*; do mpirun -np 4 pw.x -in $f > $f.out done
This step may take a while. It could be worth using
npools
or other parallization methods where relevant, as well as more cores if they are available to you. Note, production quality anharmonic force constant calculations can be quite computationally demanding – this is just a demo calculation.Finally, we postprocess all these forces by typing:
# find and sort the files find . -name 'DISP.supercell_template.in.*out' | sort -n | python3 # collect (aka reap) the forces from each pw.x output file thirdorder_espresso.py scf.in reap 2 2 2 -3
Note here that you should use the same parameters (here, 2 2 2 -3) used for generating the supercell displacements. You should see a new file called
FORCE_CONSTANTS_3RD
with the desired output.
If all went well, you will have computed the ab-initio matrix of third-order force constants.
To run a calculation with Phoebe using these force constants, we would use an input file similar to the following:
appName = "phononTransport"
phFC2FileName = "qe-phonons/silicon.fc"
phFC3FileName = "thirdorder.py-anharmonic/FORCE_CONSTANTS_3RD"
sumRuleFC2 = "simple"
qMesh = [6,6,6]
temperatures = [300.]
smearingMethod = "gaussian"
smearingWidth = 10. cmm1
solverBTE = ["variational"]
scatteringMatrixInMemory = true
boundaryLength = 1. mum
windowType = "population"
Where the key difference from the file used in the phonon transport app is that the phFC2FileName
and phFC3FileName
now point to the files generated by q2r.x
for the harmonic forces and thirdorder.py
for the anharmonic forces.
Phoebe will then produce the desired transport output in the same way as for the previous tutorial using phono3py inputs.