Coverage for rhodent/writers/dos.py: 96%

26 statements  

« prev     ^ index     » next       coverage.py v7.9.1, created at 2025-08-01 16:57 +0000

1from __future__ import annotations 

2 

3import numpy as np 

4from numpy.typing import NDArray 

5 

6from gpaw.mpi import world 

7 

8from ..voronoi import AtomProjectionsType 

9 

10 

11def write_density_of_states(out_fname: str, 

12 energies: list[float] | NDArray[np.float64], 

13 dos: list[float] | NDArray[np.float64], 

14 sigma: float, 

15 zerofermi: bool = False): 

16 """ Write the broadened :term:`DOS` to a text file. 

17 

18 Parameters 

19 ---------- 

20 out_fname 

21 File name of the resulting data file. 

22 energies 

23 Array of energies in units of eV. 

24 dos 

25 Array of DOS corresponding to the :attr:`energies`. 

26 sigma 

27 Gaussian broadening width in units of eV. 

28 zerofermi 

29 True if energies are to be relative to Fermi level, False if relative to vacuum. 

30 """ 

31 if zerofermi: 

32 zerostr = 'relative to Fermi level' 

33 else: 

34 zerostr = 'relative to vacuum level' 

35 

36 header = (f'DOS {zerostr}\n' 

37 f'Gaussian folding, Width {sigma:.4f} eV\n' 

38 'Energy (eV) DOS (1/eV)') 

39 np.savetxt(out_fname, np.array([energies, dos]).T, fmt=['%12.6f', '%18.8e'], header=header) 

40 

41 

42def write_partial_density_of_states(out_fname: str, 

43 energies: list[float] | NDArray[np.float64], 

44 pdos: list[float] | NDArray[np.float64], 

45 atom_projections: AtomProjectionsType, 

46 sigma: float, 

47 zerofermi: bool = False): 

48 """ Write the broadened :term:`PDOS` to a text file. 

49 

50 Parameters 

51 ---------- 

52 out_fname 

53 File name of the resulting data file. 

54 energies 

55 Array of energies in units of eV. 

56 pdos 

57 Array of PDOS corresponding to the :attr:`energies`. 

58 atom_projections 

59 Atom projections. 

60 sigma 

61 Gaussian broadening width in units of eV. 

62 zerofermi 

63 True if energies are to be relative to Fermi level, False if relative to vacuum. 

64 """ 

65 if world.rank != 0: 

66 return 

67 

68 Ni = len(atom_projections) 

69 if zerofermi: 

70 zerostr = 'relative to Fermi level' 

71 else: 

72 zerostr = 'relative to vacuum level' 

73 

74 savedata = np.zeros((len(energies), Ni + 1)) 

75 savedata[:, 0] = energies 

76 savedata[:, 1:] = pdos 

77 

78 projectionsstr = '\n'.join([f' {i:4.0f}: {str(proj)}' 

79 for i, proj in enumerate(atom_projections)]) 

80 projcolumns = ' '.join([f'PDOS {i:4.0f} (1/eV)' for i in range(Ni)]) 

81 

82 header = (f'PDOS {zerostr}\n' 

83 'Atomic projections:\n' 

84 f'{projectionsstr}\n' 

85 f'Gaussian folding, Width {sigma:.4f} eV\n' 

86 f'Energy (eV) {projcolumns}') 

87 fmt = ['%13.6f'] + Ni*['%18.8e'] 

88 np.savetxt(out_fname, savedata, fmt, header=header)