Phonopy should be run with the --eigvecs flag, or EIGENVECTORS=.TRUE.
to enable creation of a Euphonic QpointPhononModes object.
Using QpointPhononModes.from_phonopy
Euphonic can read frequencies and eigenvectors from Phonopy files with the following default names:
mesh.yaml/mesh.hdf5
qpoints.yaml/qpoints.hdf5
bands.yaml/bands.hdf5
The file to be read can be specified with the phonon_name argument. Some of
these files do not include the crystal information, so it must be read from a
phonopy.yaml file, which can be specified with the summary_name
argument. A path can also be specified.
The stored frequencies can be reordered by comparing eigenvectors using
QpointPhononModes.reorder_frequencies.
This means that the same mode will have the same index across different
q-points, so will be plotted as the same colour in a dispersion plot,
allowing modes to be followed across q-space (see Plotting)
The coherent scattering length is a physical property of the nucleus.
To provide this data explicitly, the scattering_lengths argument can
be set as a dictionary mapping each atom identity to a pint.Quantity
(see Units for details).
Alternatively, this argument may be a string referring to a data file
with the coherent_scattering_length property. (See Reference Data for details.)
By default, QpointPhononModes.calculate_structure_factor will use the "Sears1992" data set included in Euphonic.
If you have a custom data file, this can be used instead.
The following example shows a full calculation from the force constants to the
structure factor with Debye-Waller:
importseekpathimportnumpyasnpfromeuphonicimportureg,QpointPhononModes,ForceConstantsfromeuphonic.utilimportmp_grid# Read the force constantsfc=ForceConstants.from_castep('quartz.castep_bin')# Generate a recommended q-point path to calculate the structure factor on# using seekpathcell=fc.crystal.to_spglib_cell()qpts=seekpath.get_explicit_k_path(cell)["explicit_kpoints_rel"]# Calculate frequencies/eigenvectors for the q-point pathphonons=fc.calculate_qpoint_phonon_modes(qpts,asr='reciprocal')# For the Debye-Waller calculation, generate and calculate# frequencies/eigenvectors on a grid (generate a Monkhorst-Pack grid of# q-points using the mp-grid helper function)q_grid=mp_grid([5,5,5])phonons_grid=fc.calculate_qpoint_phonon_modes(q_grid,asr='reciprocal')# Now calculate the Debye-Waller exponenttemperature=5*ureg('K')dw=phonons_grid.calculate_debye_waller(temperature)# Calculate the structure factor for each q-point in phonons. A# StructureFactor object is returnedfm=ureg('fm')scattering_lengths={'Si':4.1491*fm,'O':5.803*fm}sf=phonons.calculate_structure_factor(scattering_lengths,dw=dw)
The Debye-Waller factor is an optional part of the structure factor
calculation. The exponent part of the Debye-Waller factor is independent of Q
and should be precalculated using
QpointPhononModes.calculate_debye_waller
(see the docstring for algorithm details). This requires a QpointPhononModes
object calculated on a grid of q-points and a temperature, and returns a
DebyeWaller object. The Debye-Waller exponent can be
calculated by:
Partial and neutron-weighted density of states can be calculated using
QpointPhononModes.calculate_pdos.
Like DOS, this requires an array of energy bin edges in energy units. This
returns a Spectrum1DCollection object, containing
the atom-resolved partial density of states. If weighting is supplied, or
the cross_sections are specified (this can be done in the same way as the
scattering lengths) the neutron-weighted partial
density of states is returned. This is also resolved per-atom, and units are
area/energy per atom of sample.
The Spectrum1DCollection.metadata attribute labels each PDOS spectrum by
species and index, and Spectrum1DCollection methods
can be used to obtain per-species or total PDOS. For example, to produce both total
and species-resolved coherent neutron-weighted PDOS:
importnumpyasnpfromeuphonicimportureg,QpointPhononModesphonons=QpointPhononModes.from_castep('quartz-grid.phonon')ebins=np.arange(0,165,0.1)*ureg('meV')pdos=phonons.calculate_pdos(ebins,weighting='coherent')# atom resolved pdosspecies_pdos=pdos.group_by('species')# species resolved pdostotal_dos=pdos.sum()# total dos
A class to read and store vibrational data from model (e.g. CASTEP)
output files
Variables:
crystal – Lattice and atom information
n_qpts – Number of q-points in the object
qpts – Shape (n_qpts, 3) float ndarray. Q-point coordinates, in
fractional coordinates of the reciprocal lattice
weights – Shape (n_qpts,) float ndarray. The weight for each q-point,
for Brillouin Zone integration over symmetry-reduced q-points
frequencies – Shape (n_qpts, 3*crystal.n_atoms) float Quantity. Phonon
frequencies per q-point and mode
eigenvectors – Shape (n_qpts, 3*crystal.n_atoms, crystal.n_atoms, 3) complex
ndarray. The dynamical matrix eigenvectors in Cartesian
coordinates, using the same Cartesian basis as the
cell_vectors in the crystal object
qpts (ndarray) – Shape (n_qpts, 3) float ndarray. Q-point coordinates, in
fractional coordinates of the reciprocal lattice
frequencies (Quantity) – Shape (n_qpts, 3*crystal.n_atoms) float Quantity. Phonon
frequencies per q-point and mode
eigenvectors (ndarray) – Shape (n_qpts, 3*crystal.n_atoms, crystal.n_atoms, 3)
complax ndarray. The dynamical matrix eigenvectors in
Cartesian coordinates, using the same Cartesian basis
as the cell_vectors in the crystal object
weights (ndarray | None) – Shape (n_qpts,) float ndarray. The weight for each q-point,
for Brillouin Zone integration over symmetry-reduced
q-points. If None, equal weights are assumed
By doing a dot product of eigenvectors at adjacent q-points,
determines which modes are most similar and reorders the
frequencies at each q-point. This means that the same mode
will have the same index across different q-points, so will
be plotted as the same colour in a dispersion plot, and can
be followed across q-space.
Parameters:
reorder_gamma (bool) – Whether to reorder frequencies at gamma-equivalent points.
If an analytical correction has been applied at the gamma
points (i.e LO-TO splitting) mode assignments can be
incorrect at adjacent q-points where the correction hasn’t
been applied. So you might not want to reorder at gamma for
some materials
Calculate the one phonon inelastic scattering for neutrons at
each q-point
Parameters:
scattering_lengths (str | dict[str, Quantity]) –
Dataset of coherent scattering length for each
element in the structure. This may be provided in 3 ways:
A string naming an appropriate data collection packaged with
Euphonic (including the default value ‘Sears1992’). This will be
passed to the collection argument of
euphonic.util.get_reference_data().
A string filename for a user’s customised data file in the same
format as those packaged with Euphonic.
An explicit dictionary of float Quantity, giving spin- and
isotope-averaged coherent scattering length for each element in
the structure, e.g.:
{'O':5.803*ureg('fm'),'Zn':5.680*ureg('fm')}
dw (DebyeWaller | None) – Data for thermal motion effects. Typically this is computed over a
converged Monkhort-Pack grid, which need not correspond to the
q-points of this QpointPhononModes object.
Returns:
sf – An object containing the structure factor for each q-point
and phonon mode
This method calculates the mode-resolved (not binned in energy)
coherent one-phonon neutron scattering function
\(S(Q, \omega_{\mathbf{q}\nu})\)per atom, as defined in
[1]:
Where \(\nu\) runs over phonon modes, \(\kappa\) runs
over atoms, \(b_\kappa\) is the coherent neutron
scattering length, \(M_{\kappa}\) is the atom mass,
\(r_{\kappa}\) is the vector from the origin to atom
\(\kappa\) in the unit cell,
\(\mathbf{e}_{\mathbf{q}\nu\kappa}\) are the normalised
Cartesian eigenvectors, \(\omega_{\mathbf{q}\nu}\) are
the frequencies and \(\exp\left(-W_\kappa\right)\) is the
Debye-Waller factor. \(N_{atom}\) is the number of atoms in
the unit cell, so the returned structure factor is per atom
of sample.
Calculate the 3 x 3 Debye-Waller exponent for each atom over the
q-points contained in this object
Parameters:
temperature (Quantity) – Scalar float Quantity. The temperature to use in the
Debye-Waller calculation
frequency_min (Quantity) – Scalar float Quantity in energy units. Excludes frequencies below
this limit from the calculation, as the calculation contains a
1/frequency factor which would result in infinite values. This
also allows negative frequencies to be excluded
symmetrise (bool) – Whether to symmetrise the Debye-Waller factor based on the
crystal symmetry operations. Note that if the Debye-Waller
exponent is not symmetrised, the results may not be the
same for unfolded and symmetry-reduced q-point grids
Returns:
dw – An object containing the 3x3 Debye-Waller exponent matrix
for each atom
As part of the structure factor calculation,
\(\exp\left(W_\kappa\right)\) is the anisotropic
Debye-Waller factor for atom \(\kappa\), and the exponent can
be written as:
This function calculates the \(W^{\alpha\beta}_{\kappa}\)
part of the exponent, which is a
\(N_\mathrm{atom}\times3\times3\) matrix that is
independent of Q, so for efficiency can be precalculated to be
used in the structure factor calculation. The Debye-Waller
exponent matrix is calculated by [2]:
Where the sum is over q-points and modes \(\nu\) in the
first Brillouin Zone (BZ), \(\kappa\) runs over atoms,
\(\alpha,\beta\) run over the Cartesian directions,
\(M_{\kappa}\) is the atom mass,
\(e_{q\nu\kappa\alpha}\) are the scalar components of the
normalised Cartesian eigenvectors, \(\omega_{\mathbf{q}\nu}\)
are the frequencies, and \(\mathrm{weight}_\mathbf{q}\)
is the per q-point symmetry weight (if the q-points are not
symmetry-reduced, all weights will be equal).
Calculates partial density of states for each atom in the unit
cell
Parameters:
dos_bins (Quantity) – Shape (n_e_bins + 1,) float Quantity. The energy bin edges
to use for calculating the DOS.
mode_widths (Quantity | None) – Shape (n_qpts, n_branches) float Quantity in energy units.
The broadening width for each mode at each q-point, for
adaptive broadening.
mode_widths_min (Quantity) – Scalar float Quantity in energy units. Sets a lower limit on
the mode widths, as mode widths of zero will result in
infinitely sharp peaks.
adaptive_method (Literal['reference', 'fast']) – String. Specifies whether to use slow, reference adaptive method or
faster, approximate method. Allowed options are ‘reference’
or ‘fast’, default is ‘reference’.
adaptive_error (float) – Scalar float. Acceptable error for gaussian approximations
when using the fast adaptive method, defined as the absolute
difference between the areas of the true and approximate gaussians
adaptive_error_fit (Literal['cheby-log', 'cubic']) – Select parametrisation of kernel width spacing to adaptive_error
when using fast approximate method. ‘cheby-log’ is recommended:
for backward-compatibilty, ‘cubic’ is the default.
weighting (str | None) – One of {‘coherent’, ‘incoherent’, ‘coherent-plus-incoherent’}.
If provided, produces a neutron-weighted DOS, weighted by
either the coherent, incoherent, or sum of coherent and
incoherent neutron scattering cross-sections.
cross_sections (str | dict[str, Quantity]) –
A dataset of cross-sections for each element in the structure,
it can be a string specifying a dataset, or a dictionary
explicitly giving the cross-sections for each element.
If cross_sections is a string, it is passed to the collection
argument of euphonic.util.get_reference_data(). This
collection must contain the ‘coherent_cross_section’ or
‘incoherent_cross_section’ physical property, depending on
the weighting argument. If weighting is None, this
string argument is not used.
If cross sections is a dictionary, the weighting argument is
ignored, and these cross-sections are used directly to calculate
the neutron-weighted DOS. It must contain a key for each element
in the structure, and each value must be a Quantity in the
appropriate units, e.g:
{'La':8.0*ureg('barn'),'Zr':9.5*ureg('barn')}
Returns:
dos – A collection of spectra, with the energy bins on the x-axis
and PDOS for each atom in the unit cell on the y-axis,
metadata describes the index and species of each PDOS. If
the PDOS is not neutron-weighted, it is in units of modes
per energy unit per atom, such that the integrated area of
the total DOS is equal to 3. If the PDOS is weighted by the
neutron cross-section, it is in units of area per unit
energy per atom, see Notes for details.
Where \(N_\mathrm{atom}\) is the number of atoms in the unit cell,
\(\mathrm{weight}_\mathbf{q}\) is the per q-point weight,
\(e_{\mathbf{q}\nu\kappa\alpha}\) is the normalised
eigenvector at \(\mathbf{q}\) for mode \(\nu\), atom
\(\kappa\) in Cartesian direction \(\alpha\) and
\(\omega_{\mathbf{q}\nu}\) is the phonon frequency at
\(\mathbf{q}\) for mode \(\nu\), and the sum
\(BZ\) is over the 1st Brillouin Zone.
Where \(\sigma_\kappa\) is the neutron scattering cross
section, \(M_\mathrm{avg}\) is the average mass of atoms in the
unit cell and \(M_\kappa\) is the mass of atom
\(\kappa\), so the neutron-weighted PDOS is returned in
units of area per unit energy.
Reads precalculated phonon mode data from a CASTEP .phonon file
Parameters:
filename (Path | str) – The path and name of the .phonon file to read
average_repeat_points (bool) – If multiple frequency/eigenvectors blocks are included with the
same q-point index (i.e. for Gamma-point with LO-TO splitting),
scale the weights such that these sum to the given weight
prefer_non_loto (bool) – If multiple frequency/eigenvector blocks are provided with the same
q-point index and all-but-one include a direction vector, use the
data from the point without a direction vector. (i.e. use the
“exact” Gamma data without non-analytic correction.) This option
takes priority over average_repeat_points.
Reads precalculated phonon mode data from a Phonopy
mesh/band/qpoints.yaml/hdf5 file. May also read from
phonopy.yaml for structure information.
Parameters:
path (Path | str) – Path to directory containing the file(s)
phonon_name (Path | str) – Name of Phonopy file including the frequencies
phonon_format (str | None) – Format of the phonon_name file if it isn’t obvious from the
phonon_name extension, one of {‘yaml’, ‘hdf5’}
summary_name (Path | str) – Name of Phonopy summary file to read the crystal information
from. Crystal information in the phonon_name file takes
priority, but if it isn’t present, crystal information is
read from summary_name instead
Calculates a density of states, in units of modes per atom per
energy unit, such that the integrated area is equal to 3.
Parameters:
dos_bins (Quantity) – Shape (n_e_bins + 1,) float Quantity in energy units. The
energy bin edges to use for calculating the DOS
mode_widths (Quantity | None) – Shape (n_qpts, n_branches) float Quantity in energy units.
The broadening width for each mode at each q-point, for
adaptive broadening
mode_widths_min (Quantity) – Scalar float Quantity in energy units. Sets a lower limit on
the mode widths, as mode widths of zero will result in
infinitely sharp peaks
adaptive_method (Literal['reference', 'fast']) – String. Specifies whether to use slow, reference adaptive method or
faster, approximate method.
adaptive_error (float) – Scalar float. Acceptable error for gaussian approximations
when using the fast adaptive method, defined as the absolute
difference between the areas of the true and approximate gaussians
adaptive_error_fit (Literal['cheby-log', 'cubic']) – Select parametrisation of kernel width spacing to adaptive_error.
‘cheby-log’ is recommended: for backward-compatibilty, ‘cubic’ is
the default.
Returns:
dos – A spectrum containing the energy bins on the x-axis and DOS
on the y-axis. The DOS is in units of modes per energy unit
per atom, such that the integrated area is equal to 3.
The fast adaptive broadening method reduces computation time by
reducing the number of Gaussian functions that have to be evaluated.
Broadening kernels are only evaulated for a subset of mode width values
with intermediate values approximated using interpolation.
The adaptive_error keyword argument is used to determine how many
broadening kernels are computed exactly. The more exact kernels are
used, the more accurate the Gaussian approximations will be, but
computation time will also be increased.
Produces a bandstructure-like plot, using the DOS at each q-point
Parameters:
dos_bins (Quantity) – Shape (n_e_bins + 1,) float Quantity in energy units. The
energy bin edges to use for calculating the DOS
mode_widths (Quantity | None) – Shape (n_qpts, n_branches) float Quantity in energy units.
The broadening width for each mode at each q-point, for
adaptive broadening
mode_widths_min (Quantity) – Scalar float Quantity in energy units. Sets a lower limit on
the mode widths, as mode widths of zero will result in
infinitely sharp peaks
Returns:
dos_map – A 2D spectrum containing the q-point bins on the x-axis, energy
bins on the y-axis and DOS on the z-axis
Bands follow the same q-point order as in the qpts array, with
x-axis spacing corresponding to the absolute distances between
q-points. Discontinuities will appear as large jumps on the
x-axis.
Returns:
dispersion – A sequence of mode bands with a common x-axis