LAMMPS & phono3py calculation#
Phono3py drives a LAMMPS force calculation in the same way as an ab-initio
calculator: it builds fc3 (and optionally fc2) supercells with atomic
displacements, LAMMPS evaluates the forces on every atom, and phono3py collects
them into FORCES_FC3 (and FORCES_FC2). This is convenient in combination
with machine-learning potentials (for example the ACE pace or the polynomial
polymlp pair_style).
Workflow#
(Optional) Relax the unit cell with the potential (Appendix: structure optimization using LAMMPS).
Generate supercells with displacements (Generating supercells with displacements).
Compute forces with LAMMPS for every supercell (Force calculation and FORCES_FC3).
Create
FORCES_FC3(andFORCES_FC2) withphono3py-init --cf3(Force calculation and FORCES_FC3).Calculate the lattice thermal conductivity with
phono3py-load(Running the thermal conductivity calculation).
Assumptions:
The LAMMPS calculation uses
units metalandatom_style atomic.LAMMPS version 15Sep2022 or later is assumed.
Forces are read from a LAMMPS dump written in a specific format (Force calculation and FORCES_FC3).
A worked example is in the example
directory:
Si-lammps-ace (ACE pace potential).
LAMMPS structure format#
Phono3py reads and writes crystal structures in the LAMMPS
read_data format, identically to
phonopy. The supported keywords, the rotation to the LAMMPS triclinic box
convention, and the handling of Atom Type Labels and Masses are documented
in the phonopy LAMMPS
documentation.
Two points are worth repeating here:
A structure written for LAMMPS is a rotated copy of the phono3py cell. The forces from LAMMPS are rotated back automatically when
FORCES_FC3is created.Phono3py writes a
Massessection into every supercell it generates, so the LAMMPS input script for the force calculation needs nomasscommand.Massesmay be omitted from the input unit cell file, since the masses are taken from the element labels.
Generating supercells with displacements#
There are two routes, depending on how the unit cell is provided. After either
route, phono3py_disp.yaml and the supercell files (supercell,
supercell-00001, supercell-00002, …) are created. Many fc3 supercells are
generated because fc3 needs displacement pairs; the file index uses five digits.
Route (a): from a LAMMPS structure file#
When the unit cell is already in the LAMMPS format (e.g. lammps_structure_Si),
generate the supercells directly:
% phono3py-init --lammps -c lammps_structure_Si -d --dim 2 2 2
A larger supercell for fc2 than for fc3 can be requested with --dim-fc2, which
adds supercell_fc2-xxxxx files:
% phono3py-init --lammps -c lammps_structure_Si -d --dim 2 2 2 --dim-fc2 4 4 4
Route (b): from a unit cell defined in yaml#
A LAMMPS structure file is expressed in the rotated triclinic convention. To keep
the cell in its original (for example, the symmetric, unrotated) orientation,
define it in yaml and generate the supercells with a short script. A silicon
conventional cell saved as phono3py_unitcell.yaml:
unit_cell:
lattice:
- [5.431000000000000, 0.000000000000000, 0.000000000000000] # a
- [0.000000000000000, 5.431000000000000, 0.000000000000000] # b
- [0.000000000000000, 0.000000000000000, 5.431000000000000] # c
points:
- {symbol: Si, coordinates: [0.00, 0.00, 0.00]}
- {symbol: Si, coordinates: [0.00, 0.50, 0.50]}
- {symbol: Si, coordinates: [0.50, 0.00, 0.50]}
- {symbol: Si, coordinates: [0.50, 0.50, 0.00]}
- {symbol: Si, coordinates: [0.25, 0.25, 0.25]}
- {symbol: Si, coordinates: [0.25, 0.75, 0.75]}
- {symbol: Si, coordinates: [0.75, 0.25, 0.75]}
- {symbol: Si, coordinates: [0.75, 0.75, 0.25]}
import phono3py
from phonopy.interface.calculator import write_supercells_with_displacements
from phonopy.interface.phonopy_yaml import read_cell_yaml
cell = read_cell_yaml("phono3py_unitcell.yaml")
ph3 = phono3py.load(
unitcell=cell, supercell_matrix=[2, 2, 2], calculator="lammps", produce_fc=False
)
ph3.generate_displacements()
ph3.save("phono3py_disp.yaml")
write_supercells_with_displacements(
"lammps", ph3.supercell, ph3.supercells_with_displacements, zfill_width=5
)
primitive_matrix defaults to "auto", so it is not passed. With route (b),
phono3py_disp.yaml stores the cell in the original (unrotated) orientation,
whereas route (a) stores the rotated triclinic cell. In both cases the supercells
follow the LAMMPS structure file format.
Force calculation and FORCES_FC3#
Phono3py reads forces from a LAMMPS dump written in a fixed text format. For each
supercell-xxxxx, evaluate the forces once with run 0 (no time integration):
units metal
read_data supercell-00001
pair_style <potential>
pair_coeff <...>
dump phonopy all custom 1 force.* id type x y z fx fy fz
dump_modify phonopy format line "%d %d %15.8f %15.8f %15.8f %15.8f %15.8f %15.8f"
run 0
Only the pair_style/pair_coeff lines change between potentials. Keep the
dump and dump_modify lines verbatim so that phono3py can parse the output;
force.* expands to force.0 for run 0. Loop over all supercells, e.g.:
for f in supercell-*; do
num=${f#supercell-}
sed "s/supercell-00001/$f/" in.force > in.tmp
lmp -in in.tmp
mv force.0 force.$num
done
Collect the forces into FORCES_FC3 (and FORCES_FC2 with --cf2 if a separate
fc2 supercell was used):
% phono3py-init --cf3 force.{00001..00111}
phono3py_disp.yaml is required. Phono3py subtracts the drift force (the net
force on each supercell) and rotates the forces back from the LAMMPS frame to the
phono3py cell, printing the rotation matrix R:
Forces parsed from LAMMPS output were rotated by F=R.F(lammps) with R:
1.00000 0.00000 0.00000
0.00000 1.00000 0.00000
0.00000 0.00000 1.00000
Running the thermal conductivity calculation#
Once FORCES_FC3 exists, run phono3py-load, which reads phono3py_disp.yaml
and FORCES_FC3 automatically. The first run also creates fc3.hdf5 and
fc2.hdf5. For example, the BTE-RTA lattice thermal conductivity at 300 K with
an 11x11x11 sampling mesh:
% phono3py-load --mesh 11 11 11 --br --ts 300
kappa-m111111.hdf5 is written with the result.
Examples#
Si-lammps-ace (ACE)#
This uses the LAMMPS pair_style pace (atomic cluster expansion). Any LAMMPS
build with the ML-PACE package can run it, including the conda-forge lammps
package:
pair_style pace
pair_coeff * * Si_npj_CompMat2021.ace Si
The potential file Si_npj_CompMat2021.ace is from the dataset accompanying Y.
Lysogorskiy et al., “Performant implementation of the atomic cluster expansion
(PACE) and application to copper and silicon”, npj Comput. Mater. 7, 97
(2021), distributed on Zenodo (https://doi.org/10.5281/zenodo.4734036) under
the CC-BY-4.0 license. Download it into the working directory; it is not
redistributed with phono3py.
The example uses the 8-atom conventional cell and a 2x2x2 supercell, the same as
the VASP Si-PBEsol example, so the lattice thermal conductivities can be
compared directly. At 300 K the ACE result is 118.9 W/m-K (11x11x11 mesh) and
132.7 W/m-K (19x19x19 mesh), somewhat higher than the PBEsol values of 109.1 and
124.4 W/m-K.
The unit cell uses the experimental room-temperature lattice constant of silicon, a = 5.431 A. Because the ACE equilibrium constant differs slightly, a small residual stress may appear as near-zero or slightly imaginary acoustic frequencies around Gamma; relax the cell with the potential to remove it (see the appendix below).
Appendix: structure optimization using LAMMPS#
Relax the crystal structure with the potential before the phonon calculation so that the residual forces, and the residual stress on the lattice, vanish. The following relaxes both the cell and the internal coordinates:
units metal
read_data unitcell
pair_style pace
pair_coeff * * Si_npj_CompMat2021.ace Si
variable etol equal 0.0
variable ftol equal 1e-8
variable maxiter equal 1000
variable maxeval equal 100000
fix relax all box/relax iso 0.0 vmax 0.001
minimize ${etol} ${ftol} ${maxiter} ${maxeval}
write_data dump.unitcell
Drop the fix box/relax line to relax only the internal coordinates. More
instruction is found at
https://gist.github.com/lan496/e9dff8449cd7489f6722b276282e66a0.