Coverage for gpaw/utilities/bader.py: 37%

30 statements  

« prev     ^ index     » next       coverage.py v7.7.1, created at 2025-07-14 00:18 +0000

1from __future__ import annotations 

2import subprocess 

3import sys 

4from pathlib import Path 

5 

6import numpy as np 

7from ase.io import write 

8from ase.units import Bohr 

9from gpaw.new.ase_interface import GPAW 

10 

11 

12def read_bader_charges(filename: str | Path = 'ACF.dat') -> np.ndarray: 

13 path = Path(filename) 

14 charges = [] 

15 with path.open() as fd: 

16 for line in fd: 

17 words = line.split() 

18 if len(words) == 7: 

19 charges.append(float(words[4])) 

20 return np.array(charges) 

21 

22 

23def main(gpw_file_name: str): 

24 calc = GPAW(gpw_file_name) 

25 dens = calc.dft.densities() 

26 n_sR = dens.all_electron_densities(grid_spacing=0.05) 

27 # NOTE: Ignoring ASE's hint for **kwargs in write() because it is wrong: 

28 write('density.cube', 

29 calc.atoms, 

30 data=n_sR.data.sum(axis=0) * Bohr**3) # type: ignore 

31 subprocess.run('bader -p all_atom density.cube'.split()) 

32 ne = n_sR.integrate().sum() 

33 print(f'{ne:.6f} electrons') 

34 charges = calc.atoms.numbers - read_bader_charges() 

35 for symbol, charge in zip(calc.atoms.symbols, charges): 

36 print(f'{symbol:2} {charge:10.6f} |e|') 

37 

38 

39if __name__ == '__main__': 

40 main(sys.argv[1])