Coverage for calorine/tools/phonons.py: 100%
22 statements
« prev ^ index » next coverage.py v7.6.4, created at 2025-05-07 12:55 +0000
« prev ^ index » next coverage.py v7.6.4, created at 2025-05-07 12:55 +0000
1from typing import Any, Dict
3import numpy as np
4from ase import Atoms
5from ase.calculators.singlepoint import SinglePointCalculator
7try:
8 from phonopy import Phonopy
9 from phonopy.structure.atoms import PhonopyAtoms
10 phonopy_exists = True
11except ModuleNotFoundError: # pragma: no cover
12 phonopy_exists = False
13 Phonopy = None
16def get_force_constants(structure: Atoms,
17 calculator: SinglePointCalculator,
18 supercell_matrix: np.ndarray,
19 kwargs_phonopy: Dict[str, Any] = {},
20 kwargs_generate_displacements: Dict[str, Any] = {}) -> Phonopy:
21 """
22 Calculates the force constants for a given structure using
23 `phonopy <https://phonopy.github.io/phonopy/>`_, which needs to be cited if this function
24 is used for generating data for publication.
25 The function returns a `Phonopy` object that can be used to calculate, e.g.,
26 the phonon dispersion, the phonon density of states as well as related quantities such
27 as the thermal displacements and the free energy.
29 Parameters
30 ----------
31 structure
32 structure for which to compute the phonon dispersion; usually this is a primitive cell
33 calculator
34 ASE calculator to use for the calculation of forces
35 supercell_matrix
36 specification of supercell size handed over to phonopy;
37 should be a tuple of three values or a matrix
38 kwargs_phonopy
39 *Expert option*:
40 keyword arguments used when initializing the `Phonopy` object;
41 this includes, e.g., the tolerance used when determining the symmetry (`symprec`) and
42 `parameters for the non-analytical corrections
43 <https://phonopy.github.io/phonopy/phonopy-module.html#non-analytical-term-correction>`_
44 (`nac_params`)
45 kwargs_generate_displacements
46 *Expert option*:
47 keyword arguments to be handed over to the `generate_displacements` method;
48 this includes in particular the `distance` keyword, which specifies the
49 magnitude of the atomic displacement imposed when calculating the force constant matrix
50 """
51 if not phonopy_exists:
52 raise ModuleNotFoundError('phonopy (https://pypi.org/project/phonopy/) is '
53 'required in order to use the functionality '
54 'in the phonons module.') # pragma: no cover
56 # prepare primitive unit cell for phonopy
57 structure_ph = PhonopyAtoms(symbols=structure.symbols,
58 cell=structure.cell,
59 scaled_positions=structure.get_scaled_positions(),
60 pbc=structure.pbc)
62 # make sure we are using the masses intended by the user
63 structure_ph.masses = structure.get_masses()
65 # prepare supercells
66 phonon = Phonopy(structure_ph, supercell_matrix, **kwargs_phonopy)
67 phonon.generate_displacements(**kwargs_generate_displacements)
69 # compute force constant matrix
70 forces = []
71 for structure_ph in phonon.supercells_with_displacements:
72 structure_ase = Atoms(symbols=structure_ph.symbols,
73 cell=structure_ph.cell,
74 scaled_positions=structure_ph.scaled_positions,
75 pbc=structure.pbc)
76 structure_ase.calc = calculator
77 forces.append(structure_ase.get_forces().copy())
79 phonon.forces = forces
80 phonon.produce_force_constants()
82 return phonon