smooth_disorder.disorder_linewidth¶
- class smooth_disorder.disorder_linewidth.PDCModel(*args: Any, **kwargs: Any)[source]¶
Bases:
ModulePyTorch model for fitting the grain-boundary length L and defect scattering coefficient R to the measured disordered VDOS.
- The forward pass computes the PDC (phonon disorder convolution) model VDOS:
Γ_defect = R·1e-6 · ω² · g^{DR} · (ρ_dis/ρ_crys)
Γ_Casimir = v_g / (L·1e1 [Å]) · 1e-2 · THzToCm
Γ = Γ_defect + Γ_Casimir
g_model = Σ_{ω’} X(ω’) · L(ω−ω’, Γ(ω’)/2) · Δω’, here L(x, η), where η is the half width
where X = g_crystal/ρ_crys is passed in as an argument (kept in notebook scope so the LBFGS closure can reference it directly).
Learnable parameter vector: model_params = [L, R] with L in nm and R in units of 1e-6. Call model_params.detach().cpu().numpy() after fitting to read the optimised values.
- smooth_disorder.disorder_linewidth.calculate_vdos_and_average_speed_with_frequency(frequencies_flat: ndarray, weights_flat: ndarray, speed_flat: ndarray, gamma_min_plateau: float, structure_file: str, weights_sum: int)[source]¶
Compute the VDOS and frequency-resolved mean group speed via Lorentzian broadening.
The vibrational density of states and frequency-resolved group speed are:
g(ω) = [1/(V·Σ_q w_q)] · Σ_{q,n} w_q · L(ω−ω_{q,n}, η)
v_g(ω) = [Σ_{q,n} w_q·|v_{q,n}|·L(ω−ω_{q,n}, η)] / [Σ_{q,n} w_q·L(ω−ω_{q,n}, η)]
where η =
gamma_min_plateau[cm⁻¹] is the Lorentzian half-width at half-maximum.v_gis set to 0 where VDOS ≈ 0 to avoid division by zero.Output VDOS is converted from cm·Å⁻³ to THz⁻¹·nm⁻³:
conversion_factor = 1000 · THzToCm / (2π)
- Parameters:
frequencies_flat (np.ndarray, shape (N,)) – Sorted flattened mode frequencies in cm⁻¹ (output of
flatten_arrays()).weights_flat (np.ndarray, shape (N,)) – Sorted flattened BZ weights (output of
flatten_arrays()).speed_flat (np.ndarray, shape (N,)) – Sorted flattened RMS group speeds in m/s (output of
flatten_arrays()).gamma_min_plateau (float) – Lorentzian half-width (HWHM) η in cm⁻¹. Controls spectral resolution.
structure_file (str) – Path to the structure file (POSCAR/CIF/XYZ); used to read the unit-cell volume.
weights_sum (int) – Sum of un-repeated BZ weights (output of
flatten_arrays()).
- Returns:
vdos_return (np.ndarray) – VDOS in THz⁻¹ nm⁻³, evaluated on
frequencies_bin.speed_average_return (np.ndarray) – Frequency-resolved mean group speed in m/s, evaluated on
frequencies_bin.frequencies_bin (np.ndarray) – Frequency grid in cm⁻¹ on which VDOS and speed are evaluated.
- smooth_disorder.disorder_linewidth.calculate_vdos_with_frequency(frequencies_flat: ndarray, weights_flat: ndarray, gamma_min_plateau: float, structure_file: str, weights_sum: int)[source]¶
Compute the VDOS via Lorentzian broadening (no group speed).
Same Lorentzian broadening as
calculate_vdos_and_average_speed_with_frequency()but omits the weighted speed accumulation. Use for disordered structures where group velocity is ill-defined and only the VDOS is needed.- Parameters:
frequencies_flat (np.ndarray, shape (N,)) – Sorted flattened mode frequencies in cm⁻¹ (output of
flatten_arrays_freq_only()).weights_flat (np.ndarray, shape (N,)) – Sorted flattened BZ weights (output of
flatten_arrays_freq_only()).gamma_min_plateau (float) – Lorentzian half-width (HWHM) η in cm⁻¹. Controls spectral resolution.
structure_file (str) – Path to the structure file (POSCAR/CIF/XYZ); used to read the unit-cell volume.
weights_sum (int) – Sum of un-repeated BZ weights (output of
flatten_arrays_freq_only()).
- Returns:
vdos_return (np.ndarray) – VDOS in THz⁻¹ nm⁻³, evaluated on
frequencies_bin.frequencies_bin (np.ndarray) – Frequency grid in cm⁻¹ on which the VDOS is evaluated.
- smooth_disorder.disorder_linewidth.evaluate_linewidth_and_model_prediction(density_crystal, density_disordered, freq_disordered, vdos_disordered, interp_shifted_freq_crystal, interp_shifted_vdos_crystal, interp_shifted_speed_crystal, L, R)[source]¶
Evaluate the disorder linewidth model and predicted PDC VDOS for given L and R.
Two scattering mechanisms contribute (see Phys. Rev. X 15, 041041 (2025)):
Γ_defect(ω) = R · ω² · g^{shifted}(ω) · (ρ_dis/ρ_crys) [cm⁻¹] Γ_Casimir(ω) = v_g(ω) / L · 1e-2 · THzToCm [cm⁻¹]
where L is in Å and the unit path is m/s ÷ Å = 1e10 s⁻¹ = 1e-2 THz → ×THzToCm → cm⁻¹.
The predicted disordered VDOS (PDC model) is the crystal VDOS convolved with a Lorentzian of half-width Γ(ω)/2:
g_model(ω) = ρ_dis · Σ_{ω’} [g_crystal(ω’)/ρ_crys] · L(ω−ω’, Γ(ω’)/2) · Δω’
implemented as a matrix–vector broadcast over the (N_dis × N_interp) frequency-difference matrix.
- Parameters:
density_crystal (float) – Crystal mass density in g/cm³.
density_disordered (float) – Disordered structure mass density in g/cm³.
freq_disordered (np.ndarray, shape (N_dis,)) – Frequency grid for the disordered VDOS in cm⁻¹.
vdos_disordered (np.ndarray, shape (N_dis,)) – Measured disordered VDOS in THz⁻¹ nm⁻³. Not consumed internally; passed for caller convenience so all outputs of
prepare_fitting_inputs()can be forwarded directly.interp_shifted_freq_crystal (np.ndarray, shape (N_interp,)) – Uniform crystal frequency grid in cm⁻¹.
interp_shifted_vdos_crystal (np.ndarray, shape (N_interp,)) – Density-shifted crystal VDOS in THz⁻¹ nm⁻³.
interp_shifted_speed_crystal (np.ndarray, shape (N_interp,)) – Density-shifted mean group speed in m/s.
L (float) – Grain-boundary mean free path (Casimir length) in Å.
R (float) – Defect scattering coefficient in cm THz nm³.
- Returns:
vdos_PDC (np.ndarray, shape (N_dis,)) – PDC model VDOS in THz⁻¹ nm⁻³, evaluated on
freq_disordered.disorder_linewidth (np.ndarray, shape (N_interp,)) – Total disorder linewidth Γ(ω) = Γ_defect + Γ_Casimir in cm⁻¹.
defect_linewidth (np.ndarray, shape (N_interp,)) – Defect (Rayleigh) scattering contribution Γ_defect(ω) in cm⁻¹.
Casimir_model_linewidth (np.ndarray, shape (N_interp,)) – Casimir (grain-boundary) scattering contribution Γ_Casimir(ω) in cm⁻¹.
- smooth_disorder.disorder_linewidth.flatten_arrays(frequencies, weights, group_velocities)[source]¶
Flatten and sort 2D mesh arrays (N_qpts × N_bands) to 1D, sorted by frequency.
Scalar speed per mode is the RMS of the 3D velocity:
|v_{q,s}| = sqrt((v_x² + v_y² + v_z²) / 3)
weights_sumis computed before repeating weights to preserve the correct normalisation denominator for the VDOS integral.- Parameters:
frequencies (np.ndarray, shape (N_qpts, N_bands)) – Phonon frequencies in cm⁻¹.
weights (np.ndarray, shape (N_qpts,)) – BZ integration weights (integers).
group_velocities (np.ndarray, shape (N_qpts, N_bands, 3)) – Group velocities in m/s.
- Returns:
frequencies_flat (np.ndarray, shape (N_qpts × N_bands,)) – Sorted flattened frequencies in cm⁻¹.
weights_flat (np.ndarray, shape (N_qpts × N_bands,)) – Weights repeated N_bands times and sorted to match
frequencies_flat.speed_flat (np.ndarray, shape (N_qpts × N_bands,)) – RMS group speeds in m/s, sorted to match
frequencies_flat.weights_sum (int) – Sum of the original (un-repeated) BZ weights; used as the VDOS normalisation denominator.
- smooth_disorder.disorder_linewidth.flatten_arrays_freq_only(frequencies, weights)[source]¶
Flatten and sort 2D mesh frequency array to 1D (no group velocities).
Use this variant when only the VDOS is needed and group speed is not required, e.g. for disordered structures where group velocity is ill-defined.
- Parameters:
frequencies (np.ndarray, shape (N_qpts, N_bands)) – Phonon frequencies in cm⁻¹.
weights (np.ndarray, shape (N_qpts,)) – BZ integration weights (integers).
- Returns:
frequencies_flat (np.ndarray, shape (N_qpts × N_bands,)) – Sorted flattened frequencies in cm⁻¹.
weights_flat (np.ndarray, shape (N_qpts × N_bands,)) – Weights repeated N_bands times and sorted to match
frequencies_flat.weights_sum (int) – Sum of the original (un-repeated) BZ weights.
- smooth_disorder.disorder_linewidth.lorentzian_numpy(x, eta)[source]¶
Lorentzian spectral function evaluated with NumPy.
L(x, η) = (1/π) · η / (x² + η²)
where η is the half-width at half-maximum (HWHM).
Warning
This convention differs from the paper (Phys. Rev. X 15, 041041 (2025)), where η denotes the full width at half-maximum (FWHM): L(x, η) = (1/π) · (η/2) / (x² + (η/2)²). The two are consistent when
etahere (disorder linewidth) is passed into the function after dividing by two.- Parameters:
x (np.ndarray) – Frequency offset (ω − ω₀) in cm⁻¹.
eta (float or np.ndarray) – Lorentzian half-width at half-maximum (HWHM) in cm⁻¹.
- Returns:
np.ndarray – Lorentzian values, same shape as
x.
- smooth_disorder.disorder_linewidth.lorentzian_torch(x, eta)[source]¶
Lorentzian spectral function evaluated with PyTorch (supports autodiff).
L(x, η) = (1/π) · η / (x² + η²)
where η is the half-width at half-maximum (HWHM). Used inside
PDCModelso that gradients flow through the Lorentzian during L-BFGS fitting.- Parameters:
x (torch.Tensor) – Frequency offset (ω − ω₀) in cm⁻¹.
eta (torch.Tensor) – Lorentzian half-width at half-maximum (HWHM) in cm⁻¹.
- Returns:
torch.Tensor – Lorentzian values, same shape as
x.
- smooth_disorder.disorder_linewidth.prepare_fitting_inputs(crystal_poscar, disordered_poscar, disordered_vdos_save, shifted_save, n_interp=2680)[source]¶
Load and prepare all inputs needed for disorder-linewidth fitting.
Reads mass densities from POSCAR files and VDOS/speed data from the HDF5 files written by
save_vdos_data_to_files()andsave_vdos_speed_data_to_files().The density-shifted crystal VDOS and speed are resampled onto a uniform grid of
n_interppoints to reduce the size of the (N_dis × N_interp) frequency-difference matrix built insideevaluate_linewidth_and_model_prediction().- Parameters:
crystal_poscar (str) – Path to the crystal POSCAR file; used to compute crystal mass density.
disordered_poscar (str) – Path to the disordered structure POSCAR file; used to compute disordered mass density.
disordered_vdos_save (str) – Path (without
.hdf5) to the disordered VDOS HDF5 file produced bysave_vdos_data_to_files().shifted_save (str) – Path (without
.hdf5) to the density-shifted crystal VDOS + speed HDF5 file produced bysave_vdos_speed_data_to_files()after the frequency-shift correction.n_interp (int, optional) – Number of interpolation points for the crystal frequency grid (default 2680).
- Returns:
density_crystal (float) – Mass density of the crystal in g/cm³.
density_disordered (float) – Mass density of the disordered structure in g/cm³.
freq_disordered (np.ndarray) – Frequency grid for the disordered VDOS in cm⁻¹.
vdos_disordered (np.ndarray) – Disordered VDOS in THz⁻¹ nm⁻³.
interp_shifted_freq_crystal (np.ndarray) – Uniform frequency grid for the interpolated crystal data in cm⁻¹.
interp_shifted_vdos_crystal (np.ndarray) – Crystal VDOS (density-shifted) interpolated onto
interp_shifted_freq_crystalin THz⁻¹ nm⁻³.interp_shifted_speed_crystal (np.ndarray) – Mean group speed (density-shifted) interpolated onto
interp_shifted_freq_crystalin m/s.
- smooth_disorder.disorder_linewidth.run_band_structure_manual(poscar_path: str, fc2_path: str, supercell_matrix: ndarray, path: list, labels: list, npoints: int = 51)[source]¶
Run a Phonopy band-structure calculation along a user-supplied BZ path.
- Parameters:
poscar_path (str) – Path to the POSCAR file (primitive cell).
fc2_path (str) – Path to the second-order force constants HDF5 file.
supercell_matrix (np.ndarray, shape (3, 3)) – Supercell transformation matrix used when computing the force constants.
path (list of list of list of float) – List of q-point segment endpoints in reduced coordinates, e.g.
[[[0,0,0],[0.5,0,0],[0.5,0,0.5]]].labels (list of str) – High-symmetry point labels for each segment endpoint, e.g.
['Γ', 'M', 'L'].npoints (int, optional) – Number of q-points per path segment (default 51).
- Returns:
frequencies (list of np.ndarray) – Frequencies in THz for each path segment, shape (npoints, N_bands) per segment.
distances (list of np.ndarray) – Cumulative path distances for each segment (used as the x-axis in band plots), shape (npoints,) per segment.
qpoints (list of np.ndarray) – q-point coordinates for each segment, shape (npoints, 3) per segment.
- smooth_disorder.disorder_linewidth.run_phonon_mesh(poscar_path: str, fc2_path: str, supercell_matrix: ndarray, mesh: list, is_gamma_center: bool = True)[source]¶
Diagonalise the dynamical matrix on a uniform BZ mesh via Phonopy.
Converts Phonopy output units on return:
frequencies: THz → cm⁻¹ (×THzToCm ≈ 33.356)
group velocities: THz·Å → m/s (×THz×Angstrom)
- Parameters:
poscar_path (str) – Path to the POSCAR file (primitive cell).
fc2_path (str) – Path to the second-order force constants HDF5 file.
supercell_matrix (np.ndarray, shape (3, 3)) – Supercell transformation matrix used when computing the force constants.
is_gamma_center (bool, optional) – Whether the mesh is Γ-centred (default True).
- Returns:
dict – Dictionary with keys:
frequencies_cm: np.ndarray, shape (N_qpts, N_bands) — phonon frequencies in cm⁻¹.weights: np.ndarray, shape (N_qpts,) — BZ integration weights (integers).qpoints: np.ndarray, shape (N_qpts, 3) — q-point coordinates in reduced coordinates.group_velocities_ms: np.ndarray, shape (N_qpts, N_bands, 3) — Cartesian group velocities in m/s.
- smooth_disorder.disorder_linewidth.save_mesh_data_to_files(filename: str, frequencies_cm: ndarray, weights: ndarray, qpoints: ndarray, group_velocities_ms: ndarray)[source]¶
Write mesh data (frequencies, weights, qpoints, group velocities) to HDF5.
- Parameters:
filename (str) – Output path without extension; saves to
{filename}.hdf5.frequencies_cm (np.ndarray, shape (N_qpts, N_bands)) – Phonon frequencies in cm⁻¹.
weights (np.ndarray, shape (N_qpts,)) – BZ integration weights (integers).
qpoints (np.ndarray, shape (N_qpts, 3)) – q-point coordinates in reduced coordinates.
group_velocities_ms (np.ndarray, shape (N_qpts, N_bands, 3)) – Group velocities in m/s.
- smooth_disorder.disorder_linewidth.save_vdos_data_to_files(filename: str, frequencies_bin: ndarray, vdos_return: ndarray)[source]¶
Write VDOS vs frequency to HDF5.
- Parameters:
filename (str) – Output path without extension; saves to
{filename}.hdf5.frequencies_bin (np.ndarray) – Frequency grid in cm⁻¹.
vdos_return (np.ndarray) – VDOS in THz⁻¹ nm⁻³.
- smooth_disorder.disorder_linewidth.save_vdos_speed_data_to_files(filename: str, frequencies_bin: ndarray, vdos_return: ndarray, speed_average_return: ndarray)[source]¶
Write VDOS and mean group speed vs frequency to HDF5.
- Parameters:
filename (str) – Output path without extension; saves to
{filename}.hdf5.frequencies_bin (np.ndarray) – Frequency grid in cm⁻¹.
vdos_return (np.ndarray) – VDOS in THz⁻¹ nm⁻³.
speed_average_return (np.ndarray) – Frequency-resolved mean group speed in m/s.