Octopus & phonopy calculation#
Octopus is a real-space (grid based) TDDFT / DFT code using pseudopotentials. This page explains how to calculate phonons with phonopy using Octopus as the force calculator, i.e., using the finite displacement and supercell approach.
How the interface works#
The Octopus interface differs from the other calculator interfaces in the way the crystal structure is exchanged with phonopy:
Octopus users normally describe the crystal structure in an Octopus input file (
inp), using%LatticeParameters,%LatticeVectorsand%ReducedCoordinatesblocks. phonopy, however, reads the unit cell from a VASP-stylePOSCARfile (the default cell file name for--octopus). Octopus can write exactly this file, so the workflow starts by exporting the unit cell from Octopus as aPOSCAR(see below). Lattice vectors inPOSCARare given in Angstrom, as usual; phonopy converts them internally to atomic units. As an alternative, phonopy also accepts the unit cell directly as an Octopus geometry include file (auto-detected, lattice in bohr), for users who prefer to keep the structure in Octopus form.The supercells are written by phonopy as Octopus geometry include files named
geometry-000,geometry-001,geometry-002, … These contain%LatticeParameters,%LatticeVectorsand%ReducedCoordinatesblocks in atomic units (bohr), ready to be pulled into an Octopus input file with theincludedirective.
Octopus uses atomic units, so within this interface the physical units are:
| Distance Atomic mass Force Force constants
-----------------------------------------------------------------
Octopus | au (bohr) AMU hartree/au hartree/au^2
The default displacement distance is 0.02 bohr. Phonon frequencies are
reported in THz, as for the other interfaces.
Pre-process#
A bulk silicon primitive cell is used as the example throughout this page.
Exporting the unit cell from Octopus#
An Octopus calculation normally starts from an input file inp that already
contains the crystal structure, for instance the cell obtained from a geometry
optimization with Octopus. phonopy needs this unit cell as a VASP-style POSCAR
file, which Octopus can write directly: add the geometry output in POSCAR
format to the input file and run a ground-state calculation
(CalculationMode = gs) on the (relaxed) structure.
A complete inp for the silicon primitive cell, using the parameters from the
standard Octopus bulk-silicon tutorial, is:
# Bulk silicon in the diamond structure (2-atom primitive cell).
# Lengths given without a unit are in atomic units (bohr), the Octopus default.
CalculationMode = gs
PeriodicDimensions = 3
# a is the conventional cubic lattice constant of silicon.
a = 5.43*angstrom
%LatticeParameters
a | a | a
%
%LatticeVectors
0.0 | 0.5 | 0.5
0.5 | 0.0 | 0.5
0.5 | 0.5 | 0.0
%
%ReducedCoordinates
"Si" | 0.0 | 0.0 | 0.0
"Si" | 0.25 | 0.25 | 0.25
%
Spacing = 0.5
%KPointsGrid
4 | 4 | 4
%
# Write the structure as a VASP-style POSCAR for phonopy.
%Output
geometry
%
OutputFormat = poscar
This uses Octopus’ default pseudopotential set and LDA exchange-correlation
functional, so no further settings are required to run it. The Spacing and
%KPointsGrid values are the tutorial defaults; for a production calculation
they (and the pseudopotentials/functional) should be converged for your system.
Run Octopus:
% octopus | tee out.log
Octopus writes the cell to static/POSCAR, with lattice vectors in Angstrom and
fractional atomic positions. Copy it to the working directory as POSCAR and
use it as the phonopy unit cell:
% cp static/POSCAR POSCAR
For the silicon input above, the exported POSCAR is:
Si
1.0
0.0000000000 2.7150000000 2.7150000000
2.7150000000 0.0000000000 2.7150000000
2.7150000000 2.7150000000 0.0000000000
Si
2
Direct
0.0000000000 0.0000000000 0.0000000000
0.2500000000 0.2500000000 0.2500000000
Creating supercells with displacements#
In the pre-process, supercell structures with (or without) displacements are created from the unit cell, fully considering crystal symmetry.
To obtain supercells (\(2\times 2\times 2\)) with displacements, run
phonopy-init with the –octopus option:
% phonopy-init --octopus -d --dim 2 2 2 --pa auto
You should find the files geometry-000, geometry-{number} and
phonopy_disp.yaml:
% ls
geometry-000 geometry-001 phonopy_disp.yaml POSCAR
geometry-000 is the perfect supercell structure, phonopy_disp.yaml
contains the information on displacements, and geometry-{number} are the
supercells with atomic displacements. Each geometry-{number} corresponds to
one of the displacements written in phonopy_disp.yaml. Because of the high
symmetry of the diamond structure, only a single displacement
(geometry-001) is generated in this example.
A generated geometry-001 looks like:
%LatticeParameters
14.511546484 | 14.511546484 | 14.511546484
%
%LatticeVectors
0.000000000 | 0.707106781 | 0.707106781
0.707106781 | 0.000000000 | 0.707106781
0.707106781 | 0.707106781 | 0.000000000
%
%ReducedCoordinates
"Si" | 0.000689106 | 0.000000000 | -0.000000000
"Si" | 0.500000000 | 0.000000000 | -0.000000000
...
%
Calculation of sets of forces#
For each geometry-{number} file an Octopus ground-state calculation
(CalculationMode = gs) is run to obtain the forces on the atoms of the
displaced supercell. The geometry-{number} file is pulled into the Octopus
input file inp with the include directive, together with the calculation
settings that are appropriate for your system. It is convenient to run each
displacement in its own directory:
% mkdir disp-001
% cd disp-001
An example inp for the silicon supercell (disp-001/inp) is:
CalculationMode = gs
PeriodicDimensions = 3
Spacing = 0.5*angstrom
BoxShape = parallelepiped
include ../geometry-001
%KPointsGrid
2 | 2 | 2
%
Then run Octopus:
% octopus | tee out.log
Octopus writes the forces into static/info, in the “Forces on the ions”
block (in Hartree/bohr by default):
Forces on the ions [H/b]
Ion x y z
1 Si -1.00521691E-05 -1.11410816E-03 -1.11410816E-03
2 Si 1.34774669E-03 4.66640181E-05 4.66640168E-05
...
Note
Be careful not to relax the structures. The atomic forces induced by the
small displacement written in geometry-{number} are exactly what is needed
for the phonon calculation, so the supercells with displacements must not be
relaxed. Use a ground-state calculation (CalculationMode = gs,
no geometry optimization).
Since the calculation is a supercell calculation, the convergence parameters
(grid Spacing, %KPointsGrid, exchange-correlation
functional, pseudopotentials, …) have to be chosen for your system. The
settings above are only a minimal, fast example.
After the Octopus calculations of all displacements have finished, create the
FORCE_SETS file with the -f option, passing
the static/info files of the displacement calculations:
% phonopy-init -f disp-001/static/info
or, for several displacements,
% phonopy-init -f disp-{001..003}/static/info
The calculator (octopus) is read from phonopy_disp.yaml, so the
--octopus option is not needed again here.
Post-process#
The post-processing is identical to the other calculators: it reads
phonopy_disp.yaml and FORCE_SETS, so the --octopus option is not
required (the calculator is stored in phonopy_disp.yaml).
In the post-process,
Force constants are calculated from the sets of forces,
A part of the dynamical matrix is built from the force constants,
Phonon frequencies and eigenvectors are calculated from the dynamical matrices at the specified q-points.
The density of states (DOS) is plotted by
% phonopy --mesh 20 20 20 -p
Thermal properties are calculated with the sampling mesh by
% phonopy --mesh 20 20 20 -t
You should check the convergence with respect to the mesh numbers. Thermal properties can be plotted by
% phonopy --mesh 20 20 20 -t -p
Projected DOS is calculated and plotted by
% phonopy --mesh 20 20 20 --pdos "1 2, 3 4 5 6" -p
Band structure is plotted by
% phonopy --band "0.5 0.5 0.5 0.0 0.0 0.0 0.5 0.5 0.0 0.0 0.5 0.0" -p
In either case, by setting the -s option, the plot is going to be saved in
the PDF format. If you don’t need to plot the DOS, the (partial) DOS is just
calculated using the --dos option.
Non-analytical term correction (Optional)#
To activate the non-analytical term correction, a BORN file is required. It contains the macroscopic dielectric constant and the Born effective charges of the atoms in the primitive cell. Both quantities can be obtained from Octopus by a linear-response (Sternheimer) calculation of the electromagnetic response.
The BORN file can be generated automatically from the Octopus response
calculation with the phonopy-octopus-born helper (analogous to
phonopy-vasp-born, phonopy-qe-born and phonopy-crystal-born); it can also
be assembled by hand, as described below. The Octopus output already uses the
units expected by phonopy (Born charges in units of the elementary charge,
dielectric tensor dimensionless), so the values are used as-is.
Note
The non-analytical term correction is only relevant for polar (ionic) crystals; for a non-polar crystal such as the silicon used in the rest of this page the Born effective charges vanish by symmetry and the correction has no effect. The example below therefore uses rock-salt NaCl, independently of the silicon force-calculation workflow above.
Computing Born charges and the dielectric tensor with Octopus#
The Born charges and the dielectric tensor are properties of the unit cell
(not the supercell), and this calculation is run entirely with Octopus, so the
structure is provided in the usual Octopus form. Here we use the rock-salt NaCl
primitive cell, written as a geometry include file geometry-unitcell:
a = 5.64*angstrom
%LatticeParameters
a | a | a
%
%LatticeVectors
0.0 | 0.5 | 0.5
0.5 | 0.0 | 0.5
0.5 | 0.5 | 0.0
%
%ReducedCoordinates
"Na" | 0.0 | 0.0 | 0.0
"Cl" | 0.5 | 0.5 | 0.5
%
(If you only have the unit cell as a POSCAR, the same include file can be
produced with phonopy-calc-convert -i POSCAR -o geometry-unitcell --calcin vasp --calcout octopus.)
For a periodic system the electric response is computed with the
\(\vec{k}\cdot\vec{p}\) perturbation, so three runs are performed in the
same directory: a ground state, a kdotp calculation, and finally the
electromagnetic response. Each run restarts from the previous one.
The three runs share the same computational settings, which we collect in a file
common.inp. The geometry is not included here; instead each run’s inp
includes geometry-unitcell directly, alongside common.inp. This keeps the
structure include at the top level — the same pattern as the force calculation
above, where each disp-*/inp includes its own geometry-{number} — rather than
nesting it inside common.inp:
PeriodicDimensions = 3
Spacing = 0.3*angstrom
BoxShape = parallelepiped
PseudopotentialSet = hgh_lda
%KPointsGrid
4 | 4 | 4
%
KPointsUseSymmetries = no
ExperimentalFeatures = yes
Ground state:
CalculationMode = gs include geometry-unitcell include common.inp
\(\vec{k}\cdot\vec{p}\) perturbation (required for the periodic electric response):
CalculationMode = kdotp KdotPCalcSecondOrder = yes include geometry-unitcell include common.inp
Electromagnetic response with Born charges:
CalculationMode = em_resp RestartFixedOccupations = no include geometry-unitcell include common.inp # Static (zero-frequency) response %EMFreqs 1 | 0.0 % EMCalcBornCharges = yes
Run Octopus once per step (replacing the inp file between runs).
Note
Several constraints apply to this (experimental) calculation, hence
ExperimentalFeatures = yes:
kdotpfirst. For a periodic system the electric response reads the \(\vec{k}\cdot\vec{p}\) wavefunctions, so thekdotprun must precedeem_resp.RestartFixedOccupations = noin theem_resprun, so that occupations are recomputed with semiconducting smearing (a gap is required for the \(\vec{k}\cdot\vec{p}\) electric response).LDA only. The Sternheimer linear response used by
em_respevaluates the XC kernel without its gradient terms, so it currently supports only LDA functionals; a GGA functional stops with “GGA functionals are not allowed for now in XCKernel”. Use an LDA functional and matching pseudopotentials. (This restricts theem_resppath only; Octopus’ Casida TDDFT does handle GGA kernels.)No nonlinear core corrections. The Born-charge force derivatives are not implemented for pseudopotentials with NLCC.
The
hgh_lda(Hartwigsen–Goedecker–Hutter LDA) set used above satisfies both the LDA and no-NLCC requirements. As with any response calculation, the grid spacing, k-point mesh and solver convergence have to be checked.
After the em_resp run, the results are written under em_resp/freq_0.0000/.
The macroscopic dielectric tensor \(\epsilon\) is in
em_resp/freq_0.0000/epsilon:
# Real part of dielectric constant
2.588022 0.000000 -0.000000
0.000000 2.588022 -0.000000
-0.000000 -0.000000 2.588022
Isotropic average 2.588022
...
The Born effective-charge tensors \(Z^*\) are in
em_resp/freq_0.0000/born_charges, one \(3\times3\) tensor per atom:
# (Frequency-dependent) Born effective charge tensors
Index: 1 Label: Na Ionic charge: 1.0000
1.141794 0.000000 -0.000000
0.000000 1.141794 0.000000
0.000000 -0.000000 1.141794
Isotropic average 1.141794
Index: 2 Label: Cl Ionic charge: 7.0000
-1.141794 0.000000 0.000000
0.000000 -1.141794 -0.000000
-0.000000 0.000000 -1.141794
Isotropic average -1.141794
# Discrepancy of Born effective charges from acoustic sum rule before correction, per atom
-0.025770 0.000000 -0.000000
0.000000 -0.025770 0.000000
0.000000 -0.000000 -0.025770
Isotropic average -0.025770
Each tensor is printed as three rows of the matrix (\(xx\,xy\,xz\) /
\(yx\,yy\,yz\) / \(zx\,zy\,zz\)). The Isotropic average lines and the
acoustic-sum-rule discrepancy block are not part of the BORN file.
The values are physically sensible: \(Z^*(\mathrm{Na}) \approx +1.14\), \(Z^*(\mathrm{Cl}) \approx -1.14\) and \(\epsilon_\infty \approx 2.59\), close to the experimental NaCl values (\(Z^* \approx \pm 1.1\), \(\epsilon_\infty \approx 2.3\)). The settings above are only a small example; check convergence for production use.
Assembling the BORN file#
The simplest route is the phonopy-octopus-born helper, which reads the
dielectric tensor and Born charges from the em_resp output, symmetrizes them,
keeps the symmetry-independent atoms, and writes the BORN file. Give it the
unit cell and the em_resp results directory:
% phonopy-octopus-born geometry-unitcell em_resp/freq_0.0000 > BORN
The unit cell may be a POSCAR or an Octopus geometry file, but the geometry
file must be in numeric form: the geometry-unitcell produced by
phonopy-calc-convert above qualifies, whereas an input written with variables
such as a = 5.64*angstrom does not (pass a POSCAR in that case). Passing the
geometry file that was included in the em_resp run keeps the atom order
aligned with born_charges.
Alternatively, the BORN file can be written by hand. Following the
BORN format, write:
the unit conversion factor on the first line (use the default by giving a non-numeric placeholder such as
default, or the Octopus factor from Default unit conversion factor for non-analytical term correction),the nine dielectric-tensor components (\(xx\,xy\,xz\,yx\,yy\,yz\,zx\,zy\,zz\)) from
epsilonon the second line,from the third line on, the nine \(Z^*\) components for each symmetry-independent atom of the primitive cell, taken from the corresponding
Index:block ofborn_charges. The symmetry-independent atoms can be identified from theatom_mappingsection printed byphonopy-init --octopus --symmetry -c POSCAR; for NaCl the two atoms (Na and Cl) are inequivalent.
For the NaCl output above, the resulting BORN file is:
default
2.588022 0.0 0.0 0.0 2.588022 0.0 0.0 0.0 2.588022
1.141794 0.0 0.0 0.0 1.141794 0.0 0.0 0.0 1.141794
-1.141794 0.0 0.0 0.0 -1.141794 0.0 0.0 0.0 -1.141794
Post-process with the non-analytical term correction#
With a BORN file in the working directory, phonopy activates the correction
through the --nac option. This also requires the NaCl force constants:
generate phonopy_disp.yaml and FORCE_SETS for NaCl with the same
finite-displacement procedure used for silicon above (create the displaced
supercells with phonopy-init --octopus -d, run the Octopus gs force
calculations, and collect the forces with -f). With phonopy_disp.yaml,
FORCE_SETS and BORN all present in the directory, add --nac to any
post-process command.
The correction is most visible in the band structure, where it produces the LO–TO splitting of the optical branches at \(\Gamma\):
% phonopy --nac --band "0.5 0.5 0.5 0.0 0.0 0.0 0.5 0.5 0.0 0.0 0.5 0.0" -p
The DOS, thermal properties, and projected DOS (onto the Na and Cl atoms) are
obtained exactly as before, with --nac added:
% phonopy --nac --mesh 20 20 20 -p
% phonopy --nac --mesh 20 20 20 -t
% phonopy --nac --mesh 20 20 20 --pdos "1, 2" -p
Without --nac the longitudinal- and transverse-optical modes stay degenerate
at \(\Gamma\); the correction lifts that degeneracy.
Note
Octopus can alternatively compute Born effective charges and infrared
intensities directly through its own linear-response phonon calculation
(CalculationMode = vib_modes with CalcInfrared = yes), which writes them to
vib_modes/infrared. That route is independent of the phonopy finite-
displacement workflow described here.