Comprehensive Python library for phonon calculations that enables lattice dynamics simulations and vibrational property analysis of crystalline materials.
—
The main Phonopy class provides comprehensive phonon calculation capabilities including displacement generation, force constant calculation, band structure analysis, density of states, and thermal property calculations. This class serves as the primary interface for most phonopy operations.
Create and configure Phonopy instances with crystal structure and calculation parameters.
class Phonopy:
def __init__(
self,
unitcell: PhonopyAtoms,
supercell_matrix: ArrayLike = None,
primitive_matrix: ArrayLike | str = None,
nac_params: dict = None,
factor: float = None,
frequency_scale_factor: float = None,
dynamical_matrix_decimals: int = None,
force_constants_decimals: int = None,
group_velocity_delta_q: float = None,
symprec: float = 1e-5,
is_symmetry: bool = True,
store_dense_svecs: bool = True,
use_SNF_supercell: bool = False,
hermitianize_dynamical_matrix: bool = True,
calculator: str = None,
set_factor_by_calculator: bool = False,
log_level: int = 0
):
"""
Initialize Phonopy instance for phonon calculations.
Parameters:
- unitcell: Unit cell structure as PhonopyAtoms object
- supercell_matrix: 3x3 array defining supercell transformation
- primitive_matrix: 3x3 array or string ('auto', 'F', 'I', 'A', 'C', 'P', 'R')
- nac_params: Non-analytical correction parameters dictionary (deprecated)
- factor: Unit conversion factor (deprecated)
- frequency_scale_factor: Frequency scaling factor (deprecated)
- dynamical_matrix_decimals: Decimal places for dynamical matrix (deprecated)
- force_constants_decimals: Decimal places for force constants (deprecated)
- group_velocity_delta_q: Delta-q distance for group velocity calculation
- symprec: Symmetry search precision (default: 1e-5)
- is_symmetry: Whether to search supercell symmetry (default: True)
- store_dense_svecs: Store shortest vectors in dense format (default: True)
- use_SNF_supercell: Use SNF algorithm for supercell building (default: False)
- hermitianize_dynamical_matrix: Force-hermitianize dynamical matrix (default: True)
- calculator: Calculator interface ('vasp', 'qe', 'abinit', etc.)
- set_factor_by_calculator: Set unit factor by calculator (default: False)
- log_level: Logging verbosity (0=quiet, 1=normal, 2=verbose)
"""Example:
from phonopy import Phonopy
from phonopy.structure.atoms import PhonopyAtoms
# Create unit cell
lattice = [[3.17, 0, 0], [0, 3.17, 0], [0, 0, 5.13]]
positions = [[0.33, 0.67, 0], [0.67, 0.33, 0.5]]
numbers = [13, 13] # Aluminum
unitcell = PhonopyAtoms(cell=lattice,
scaled_positions=positions,
numbers=numbers)
# Create Phonopy instance with 3x3x2 supercell
supercell_matrix = [[3, 0, 0], [0, 3, 0], [0, 0, 2]]
ph = Phonopy(unitcell, supercell_matrix, primitive_matrix='auto')Generate atomic displacements for force constant calculations using finite displacement method.
def generate_displacements(
self,
distance: float | None = None,
is_plusminus: Literal["auto"] | bool = "auto",
is_diagonal: bool = True,
is_trigonal: bool = False,
number_of_snapshots: int | Literal["auto"] | None = None,
random_seed: int | None = None,
temperature: float | None = None,
cutoff_frequency: float | None = None,
max_distance: float | None = None,
number_estimation_factor: float | None = None
) -> None:
"""
Generate displacement patterns for force calculations.
Parameters:
- distance: Displacement distance in Angstrom (default: 0.01 if None)
- is_plusminus: Generate both positive and negative displacements ("auto", True, or False)
- is_diagonal: Use diagonal displacement matrix
- is_trigonal: Generate trigonal displacement patterns
- number_of_snapshots: Number of random displacement snapshots (int or "auto")
- random_seed: Seed for random number generator
- temperature: Temperature for random displacements (K)
- cutoff_frequency: Frequency cutoff for random displacements (THz)
- max_distance: Maximum distance between displaced atom and others
- number_estimation_factor: Factor for estimating number of random displacements
"""
def get_displacements(self) -> ndarray:
"""Get generated displacement vectors."""
def get_supercells_with_displacements(self) -> list:
"""Get supercell structures with applied displacements."""Example:
# Generate standard finite displacements
ph.generate_displacements(distance=0.01, is_plusminus=True)
print(f"Generated {len(ph.displacements)} displacements")
# Generate random displacements at finite temperature
ph.generate_displacements(
number_of_snapshots=100,
temperature=300,
random_seed=42
)Calculate interatomic force constants from forces obtained through ab initio calculations.
def produce_force_constants(
self,
fc_calculator: str = "traditional",
fc_calculator_options: str = None,
show_log: bool = True
):
"""
Calculate force constants from forces using specified method.
Parameters:
- fc_calculator: Method ('traditional', 'symfc', 'alm')
- fc_calculator_options: Additional options string for calculator
- show_log: Display calculation progress and information
"""
def set_forces(self, forces: ArrayLike):
"""Set forces on atoms in displaced supercells."""
def get_force_constants(self) -> ndarray:
"""Get calculated second-order force constants matrix."""
def set_force_constants(self, force_constants: ArrayLike):
"""Directly set force constants matrix."""Example:
# After obtaining forces from ab initio calculations
forces = [force_array_1, force_array_2, ...] # From DFT calculations
ph.forces = forces
# Calculate force constants using symmetry
ph.produce_force_constants(fc_calculator='symfc', show_log=True)
# Or set force constants directly
ph.set_force_constants(force_constants_matrix)Calculate and analyze phonon band structures along high-symmetry paths in the Brillouin zone.
def run_band_structure(
self,
paths: ArrayLike,
with_eigenvectors: bool = False,
with_group_velocities: bool = False,
is_band_connection: bool = False,
path_connections: ArrayLike = None,
labels: list = None,
is_legacy_plot: bool = False
):
"""
Calculate phonon band structure along specified k-point paths.
Parameters:
- paths: k-point paths as list of segments or 2D array
- with_eigenvectors: Calculate eigenvectors (mode vectors)
- with_group_velocities: Calculate phonon group velocities
- is_band_connection: Connect bands across path segments
- path_connections: Specify which path segments to connect
- labels: Labels for special k-points
- is_legacy_plot: Use legacy plotting format
"""
def get_band_structure(self):
"""Get BandStructure object with frequencies and k-points."""
def get_band_structure_dict(self) -> dict:
"""Get band structure data as dictionary."""
def write_yaml_band_structure(self, filename: str = "band.yaml"):
"""Write band structure to YAML file."""
def auto_band_structure(
self,
npoints: int = 101,
with_eigenvectors: bool = False,
with_group_velocities: bool = False
) -> dict:
"""
Automatically generate and calculate band structure using seekpath.
Parameters:
- npoints: Number of points along each path segment
- with_eigenvectors: Include eigenvectors in calculation
- with_group_velocities: Include group velocities
Returns:
Dictionary with band structure data and path information
"""Example:
# Manual band structure with custom path
paths = [[[0.0, 0.0, 0.0], # Gamma
[0.5, 0.0, 0.5]], # X
[[0.5, 0.0, 0.5], # X
[0.5, 0.25, 0.75]], # W
[[0.5, 0.25, 0.75], # W
[0.0, 0.0, 0.0]]] # Gamma
ph.run_band_structure(paths, with_eigenvectors=True)
bs = ph.get_band_structure_dict()
# Automatic band structure using seekpath
bs_auto = ph.auto_band_structure(npoints=101, with_group_velocities=True)Perform phonon calculations on regular q-point meshes for integration over the Brillouin zone.
def run_mesh(
self,
mesh: ArrayLike,
shift: ArrayLike = None,
is_time_reversal: bool = True,
is_mesh_symmetry: bool = True,
with_eigenvectors: bool = False,
with_group_velocities: bool = False,
is_gamma_center: bool = False
):
"""
Calculate phonons on regular q-point mesh.
Parameters:
- mesh: Mesh dimensions [nx, ny, nz]
- shift: Mesh shift from origin [sx, sy, sz]
- is_time_reversal: Apply time-reversal symmetry
- is_mesh_symmetry: Use crystal symmetry to reduce q-points
- with_eigenvectors: Calculate eigenvectors at each q-point
- with_group_velocities: Calculate group velocities
- is_gamma_center: Center mesh on gamma point
"""
def get_mesh_dict(self) -> dict:
"""Get mesh calculation results as dictionary."""
def write_hdf5_mesh(self, filename: str = "mesh.hdf5"):
"""Write mesh data to HDF5 file."""
def write_yaml_mesh(self, filename: str = "mesh.yaml"):
"""Write mesh data to YAML file."""Calculate total and projected phonon density of states from mesh calculations.
def run_total_dos(
self,
sigma: float = None,
freq_min: float = None,
freq_max: float = None,
freq_pitch: float = None,
use_tetrahedron_method: bool = True
):
"""
Calculate total phonon density of states.
Parameters:
- sigma: Smearing width for Gaussian method (THz)
- freq_min: Minimum frequency for DOS calculation (THz)
- freq_max: Maximum frequency for DOS calculation (THz)
- freq_pitch: Frequency step size (THz)
- use_tetrahedron_method: Use tetrahedron method (more accurate)
"""
def run_projected_dos(
self,
sigma: float = None,
freq_min: float = None,
freq_max: float = None,
freq_pitch: float = None,
use_tetrahedron_method: bool = True,
direction: ArrayLike = None,
xyz_projection: bool = False
):
"""
Calculate projected phonon density of states.
Parameters:
- sigma: Smearing width for Gaussian method (THz)
- freq_min: Minimum frequency for DOS calculation (THz)
- freq_max: Maximum frequency for DOS calculation (THz)
- freq_pitch: Frequency step size (THz)
- use_tetrahedron_method: Use tetrahedron method
- direction: Projection direction vector
- xyz_projection: Project onto x, y, z directions
"""
def get_total_dos_dict(self) -> dict:
"""Get total DOS data as dictionary."""
def get_projected_dos_dict(self) -> dict:
"""Get projected DOS data as dictionary."""
def write_total_dos(self, filename: str = "total_dos.dat"):
"""Write total DOS to text file."""
def write_projected_dos(self, filename: str = "projected_dos.dat"):
"""Write projected DOS to text file."""Calculate thermodynamic properties including heat capacity, entropy, and free energy.
def run_thermal_properties(
self,
t_min: float = 0,
t_max: float = 1000,
t_step: float = 10,
temperatures: ArrayLike = None,
cutoff_frequency: float = None,
pretend_real: bool = False,
band_indices: ArrayLike = None,
is_projection: bool = False,
classical: bool = False
):
"""
Calculate thermal properties from phonon frequencies.
Parameters:
- t_min: Minimum temperature (K, default: 0)
- t_max: Maximum temperature (K, default: 1000)
- t_step: Temperature step (K, default: 10)
- temperatures: Custom temperature array (overrides t_min/t_max/t_step)
- cutoff_frequency: Ignore frequencies below cutoff (THz)
- pretend_real: Treat imaginary frequencies as real
- band_indices: Specific phonon bands to include
- is_projection: Calculate mode-by-mode contributions
- classical: Use classical statistics instead of quantum
"""
def get_thermal_properties_dict(self) -> dict:
"""
Get thermal properties as dictionary.
Returns:
Dictionary with keys: 'temperatures', 'free_energy', 'entropy',
'heat_capacity', and temperature-dependent values
"""
def write_yaml_thermal_properties(
self,
filename: str = "thermal_properties.yaml"
):
"""Write thermal properties to YAML file."""
def run_thermal_displacements(
self,
temperatures: ArrayLike = None,
direction: ArrayLike = None,
freq_min: float = None,
freq_max: float = None
):
"""
Calculate mean square thermal displacements.
Parameters:
- temperatures: Temperature range for calculation (K)
- direction: Displacement direction vector
- freq_min: Minimum frequency to include (THz)
- freq_max: Maximum frequency to include (THz)
"""
def get_thermal_displacements_dict(self) -> dict:
"""Get thermal displacement data as dictionary."""Calculate phonon properties at specific q-points.
def run_qpoints(
self,
q_points: ArrayLike,
with_eigenvectors: bool = False,
with_dynamical_matrices: bool = False,
with_group_velocities: bool = False,
nac_q_direction: ArrayLike = None
):
"""
Calculate phonons at specific q-points.
Parameters:
- q_points: List of q-point coordinates in reciprocal space
- with_eigenvectors: Calculate phonon eigenvectors
- with_dynamical_matrices: Store dynamical matrices
- with_group_velocities: Calculate group velocities
- nac_q_direction: Direction for non-analytical correction at Gamma
"""
def get_qpoints_dict(self) -> dict:
"""Get q-point calculation results as dictionary."""
def get_frequencies(self, q: ArrayLike) -> ndarray:
"""
Get phonon frequencies at single q-point.
Parameters:
- q: q-point coordinates [qx, qy, qz]
Returns:
Array of phonon frequencies (THz)
"""
def get_frequencies_with_eigenvectors(self, q: ArrayLike) -> tuple:
"""
Get frequencies and eigenvectors at single q-point.
Parameters:
- q: q-point coordinates [qx, qy, qz]
Returns:
Tuple of (frequencies, eigenvectors)
"""Save and load phonopy calculations and results.
def save(
self,
filename: str = "phonopy_params.yaml",
settings: dict = None
):
"""
Save Phonopy instance parameters to YAML file.
Parameters:
- filename: Output file name
- settings: Additional settings to save
"""
def copy(self) -> Phonopy:
"""Create deep copy of Phonopy instance."""
def write_animation(
self,
q_point: ArrayLike = None,
anime_type: str = "v_sim",
band_index: int = None,
amplitude: float = 1,
num_div: int = 20,
shift: ArrayLike = None,
filename: str = None
):
"""
Write phonon mode animation files.
Parameters:
- q_point: q-point for mode visualization [qx, qy, qz]
- anime_type: Animation format ('v_sim', 'arc', 'xyz', 'jmol', 'poscar')
- band_index: Phonon band index to animate
- amplitude: Animation amplitude scaling
- num_div: Number of animation frames
- shift: Phase shift for animation
- filename: Output file name
"""Key properties accessible on Phonopy instances.
# Structure properties
@property
def unitcell(self) -> PhonopyAtoms: ...
@property
def primitive(self) -> PhonopyAtoms: ...
@property
def supercell(self) -> PhonopyAtoms: ...
@property
def supercell_matrix(self) -> ndarray: ...
@property
def primitive_matrix(self) -> ndarray: ...
# Calculation data
@property
def dataset(self) -> dict: ...
@property
def displacements(self) -> ndarray: ...
@property
def forces(self) -> ndarray: ...
@property
def force_constants(self) -> ndarray: ...
# Symmetry and analysis
@property
def symmetry(self): ...
@property
def primitive_symmetry(self): ...
@property
def dynamical_matrix(self): ...
@property
def nac_params(self) -> dict: ...
# Results
@property
def mesh(self): ...
@property
def band_structure(self): ...
@property
def thermal_properties(self): ...
@property
def total_dos(self): ...
@property
def projected_dos(self): ...Example Usage:
# Access calculated results
temps = ph.thermal_properties.temperatures
free_energy = ph.thermal_properties.free_energy
heat_capacity = ph.thermal_properties.heat_capacity
# Get structure information
print(f"Unit cell volume: {ph.unitcell.volume}")
print(f"Supercell dimensions: {ph.supercell_matrix}")
print(f"Number of atoms: {ph.supercell.get_number_of_atoms()}")from phonopy import Phonopy
from phonopy.structure.atoms import PhonopyAtoms
import numpy as np
# 1. Setup structure and Phonopy instance
unitcell = PhonopyAtoms(...) # Create from structure data
ph = Phonopy(unitcell, [[2,0,0],[0,2,0],[0,0,2]])
# 2. Generate displacements and calculate forces (external DFT step)
ph.generate_displacements(distance=0.01)
# ... run DFT calculations for each displaced structure ...
ph.forces = forces_from_dft # Set forces from DFT
# 3. Calculate force constants
ph.produce_force_constants()
# 4. Phonon analysis
# Band structure
ph.auto_band_structure(npoints=101)
band_dict = ph.get_band_structure_dict()
# Density of states
ph.run_mesh([20, 20, 20])
ph.run_total_dos()
dos_dict = ph.get_total_dos_dict()
# Thermal properties
temperatures = np.arange(0, 1000, 10)
ph.run_thermal_properties(temperatures)
thermal_dict = ph.get_thermal_properties_dict()
# 5. Save results
ph.save("phonopy_params.yaml")
ph.write_yaml_band_structure("band.yaml")
ph.write_yaml_thermal_properties("thermal.yaml")Install with Tessl CLI
npx tessl i tessl/pypi-phonopy