StructureFactor
The StructureFactor object contains the structure factor at every q-point and mode, and optionally a temperature if temperature-dependent effects such as the Debye-Waller factor were used in the calculation.
From Phonon Modes
Calculating Scattering Intensities
The structure factors can be used to create a \(S(Q, \omega)\) map
with Q on the x-axis and energy on the y-axis using
StructureFactor.calculate_sqw_map
(see docstring for algorithm details). This requires an array of energy bin
edges as a pint.Quantity. Calculating the Bose population factor
is optional, but if calc_bose=True the temperature stored in
StructureFactor is used. If there is no temperature in StructureFactor,
then it must be provided in the function arguments. This function returns a
generic Spectrum2D object.
from euphonic import ureg, StructureFactor
import numpy as np
sf = StructureFactor.from_json_file('sf_100K.json')
energy_bins = np.arange(-100, 101, 1)*ureg('meV')
sqw_map = sf.calculate_sqw_map(energy_bins, calc_bose=True)
Plotting Dispersion
Calculating Density of States
See Calculating DOS
Docstring
- class StructureFactor(crystal, qpts, frequencies, structure_factors, weights=None, temperature=None)
Stores the structure factor calculated per q-point and per phonon mode
- Variables:
crystal (Crystal) – Lattice and atom information
n_qpts (int) – Number of q-points in the object
qpts ((n_qpts, 3) float ndarray) – Q-point coordinates, in fractional coordinates of the reciprocal lattice
frequencies ((n_qpts, 3*crystal.n_atoms) float Quantity) – Phonon frequencies per q-point and mode
structure_factors ((n_qpts, 3*crystal.n_atoms) float Quantity) – Structure factor per q-point and mode
weights ((n_qpts,) float ndarray) – The weight for each q-point
temperature (float Quantity or None) – The temperature used to calculate any temperature-dependent parts of the structure factor (e.g. Debye-Waller, Bose population factor). None if no temperature-dependent effects have been applied
- Parameters:
crystal (Crystal)
qpts (ndarray)
frequencies (Quantity)
structure_factors (Quantity)
weights (ndarray | None)
temperature (Quantity | None)
- __init__(crystal, qpts, frequencies, structure_factors, weights=None, temperature=None)
- Parameters:
crystal (Crystal) – Lattice and atom information
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
structure_factors (Quantity) – Shape (n_qpts, 3*crystal.n_atoms) float Quantity. Structure factor per q-point and mode
weights (ndarray | None) – Shape (n_qpts,) float ndarray. The weight for each q-point. If None, equal weights are assumed
temperature (Quantity | None) – Scalar float Quantity. The temperature used to calculate any temperature-dependent parts of the structure factor (e.g. Debye-Waller, Bose population factor). None if no temperature-dependent effects have been applied
- Return type:
None
- calculate_1d_average(e_bins, *, calc_bose=True, temperature=None, weights=None)
Bin structure factor in energy, flattening q to produce 1D spectrum
Bose population factor may be applied. The main purpose of this function is to produce a powder-averaged spectrum.
- Parameters:
e_bins (Quantity) – Shape (n_e_bins + 1,) float Quantity. The energy bin edges
calc_bose (bool) – Whether to calculate and apply the Bose population factor
temperature (Quantity | None) – Scalar float Quantity. The temperature to use to calculate the Bose factor. Is only required if StructureFactor.temperature = None, otherwise the temperature stored in StructureFactor will be used
weights (ndarray | None) – Dimensionless weights to be applied in averaging, the same length as qpts. If no weights are provided the weights contained in StructureFactor are used. For details of how this argument is interpreted see docs for
numpy.average()
- Returns:
s_w – 1-D neutron scattering spectrum, averaged over all sampled q-points
- Return type:
- calculate_sqw_map(e_bins, *, calc_bose=True, temperature=None)
Bin the structure factor in energy and apply the Bose population factor to produce a a S(Q,w) map
- Parameters:
e_bins (Quantity) – Shape (n_e_bins + 1,) float Quantity. The energy bin edges
calc_bose (bool) – Whether to calculate and apply the Bose population factor
temperature (Quantity | None) – The temperature to use to calculate the Bose factor. Is only required if StructureFactor.temperature = None, otherwise the temperature stored in StructureFactor will be used
- Returns:
sqw_map – A spectrum containing the q-point bins on the x-axis, energy bins on the y-axis and scattering intensities on the z-axis
- Raises:
ValueError – If a temperature is provided and isn’t consistent with the temperature in the StructureFactor object
- Return type:
Notes
StructureFactor.structure_factors is defined as the mode-resolved \(S(Q, \omega_{\mathbf{q}\nu})\) per atom of sample. To create an \(S(Q,\omega)\) map, it is binned in \(\omega\) and the Bose population factor is applied [1]:
\[S(Q, \omega) = S(Q, \omega_{\mathbf{q}\nu}) \ (n_\nu+\frac{1}{2}\pm\frac{1}{2}) \ \delta(\omega\mp\omega_{\mathbf{q}\nu})\]\(n_\nu\) is the Planck distribution function:
\[n_\nu = \frac{1}{\exp{\frac{\hbar\omega_{\mathbf{q}\nu}}{k_{B}T}} - 1}\]
- to_dict()
Convert to a dictionary. See StructureFactor.from_dict for details on keys/values
- Return type:
dict[str, Any]
- calculate_dos(dos_bins, *, mode_widths=None, mode_widths_min=<Quantity(0.01, 'millielectron_volt')>, adaptive_method='reference', adaptive_error=0.01)
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
- 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.
- Return type:
Notes
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_errorkeyword 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.
- calculate_dos_map(dos_bins, *, mode_widths=None, mode_widths_min=<Quantity(0.01, 'millielectron_volt')>)
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
- Return type:
- classmethod from_json_file(filename)
Read from a JSON file. See from_dict for required fields
- Parameters:
filename (Path | str) – The file to read from
- Return type:
Self
- get_dispersion()
Creates a set of 1-D bands from mode data
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
- Return type:
- to_json_file(filename)
Write to a JSON file. JSON fields are equivalent to from_dict keys
- Parameters:
filename (Path | str) – Name of the JSON file to write to
- Return type:
None
- to_qpoint_frequencies()
Create a QpointFrequencies object
- Return type:
- classmethod from_dict(d)
Convert a dictionary to a StructureFactor object
- Parameters:
d (dict) –
A dictionary with the following keys/values:
’crystal’: dict, see Crystal.from_dict
’qpts’: (n_qpts, 3) float ndarray
’frequencies’: (n_qpts, 3*crystal.n_atoms) float ndarray
’frequencies_unit’: str
’structure_factors’: (n_qpts, 3*crystal.n_atoms) float ndarray
’structure_factors_unit’: str
There are also the following optional keys:
’weights’: (n_qpts,) float ndarray
’temperature’: float
’temperature_unit’: str
- Return type:
Self