Coverage for calorine/tools/phonons.py: 100%

19 statements  

« prev     ^ index     » next       coverage.py v7.2.5, created at 2024-07-26 09:34 +0000

1from typing import Any, Dict 

2 

3import numpy as np 

4from ase import Atoms 

5from ase.calculators.singlepoint import SinglePointCalculator 

6 

7try: 

8 from phonopy import Phonopy 

9 from phonopy.structure.atoms import PhonopyAtoms 

10except ModuleNotFoundError: # pragma: no cover 

11 raise ModuleNotFoundError('phonopy (https://pypi.org/project/phonopy/) is ' 

12 'required in order to use the functionality ' 

13 'in the phonons module.' 

14 ) # pragma: no cover 

15 

16 

17def get_force_constants(structure: Atoms, 

18 calculator: SinglePointCalculator, 

19 supercell_matrix: np.ndarray, 

20 kwargs_phonopy: Dict[str, Any] = {}, 

21 kwargs_generate_displacements: Dict[str, Any] = {}) -> Phonopy: 

22 """ 

23 Calculates the force constants for a given structure using 

24 `phonopy <https://phonopy.github.io/phonopy/>`_, which needs to be cited if this function 

25 is used for generating data for publication. 

26 The function returns a `Phonopy` object that can be used to calculate, e.g., 

27 the phonon dispersion, the phonon density of states as well as related quantities such 

28 as the thermal displacements and the free energy. 

29 

30 Parameters 

31 ---------- 

32 structure 

33 structure for which to compute the phonon dispersion; usually this is a primitive cell 

34 calculator 

35 ASE calculator to use for the calculation of forces 

36 supercell_matrix 

37 specification of supercell size handed over to phonopy; 

38 should be a tuple of three values or a matrix 

39 kwargs_phonopy 

40 *Expert option*: 

41 keyword arguments used when initializing the `Phonopy` object; 

42 this includes, e.g., the tolerance used when determining the symmetry (`symprec`) and 

43 `parameters for the non-analytical corrections 

44 <https://phonopy.github.io/phonopy/phonopy-module.html#non-analytical-term-correction>`_ 

45 (`nac_params`) 

46 kwargs_generate_displacements 

47 *Expert option*: 

48 keyword arguments to be handed over to the `generate_displacements` method; 

49 this includes in particular the `distance` keyword, which specifies the 

50 magnitude of the atomic displacement imposed when calculating the force constant matrix 

51 """ 

52 

53 # prepare primitive unit cell for phonopy 

54 structure_ph = PhonopyAtoms(symbols=structure.symbols, 

55 cell=structure.cell, 

56 scaled_positions=structure.get_scaled_positions(), 

57 pbc=structure.pbc) 

58 

59 # prepare supercells 

60 phonon = Phonopy(structure_ph, supercell_matrix, **kwargs_phonopy) 

61 phonon.generate_displacements(**kwargs_generate_displacements) 

62 

63 # compute force constant matrix 

64 forces = [] 

65 for structure_ph in phonon.supercells_with_displacements: 

66 structure_ase = Atoms(symbols=structure_ph.symbols, 

67 cell=structure_ph.cell, 

68 scaled_positions=structure_ph.scaled_positions, 

69 pbc=structure.pbc) 

70 structure_ase.calc = calculator 

71 forces.append(structure_ase.get_forces().copy()) 

72 

73 phonon.forces = forces 

74 phonon.produce_force_constants() 

75 

76 return phonon