Coverage for gpaw/analyse/eed.py: 95%
39 statements
« prev ^ index » next coverage.py v7.7.1, created at 2025-07-14 00:18 +0000
« prev ^ index » next coverage.py v7.7.1, created at 2025-07-14 00:18 +0000
1import numpy as np
2from ase.units import Bohr, Hartree
3from ase.parallel import paropen
4from ase.data import vdw_radii
6import gpaw.cgpaw as cgpaw
7from gpaw.io.fmf import FMF
10class ExteriorElectronDensity:
12 """Exterior electron density to describe MIES spectra.
14 Simple approach to describe MIES spectra after
15 Y. Harada et al., Chem. Rev. 97 (1997) 1897
16 """
18 def __init__(self, gd, atoms):
19 """Find the grid points outside of the van der Waals radii
20 of the atoms"""
22 assert gd.orthogonal
23 self.gd = gd
25 n = len(atoms)
26 atom_c = atoms.positions / Bohr
27 vdWradius = np.empty(n)
28 for a, atom in enumerate(atoms):
29 vdWradius[a] = self.get_vdWradius(atom.number)
31 # define the exterior region mask
32 mask = gd.empty(dtype=int)
33 cgpaw.eed_region(mask, atom_c, gd.beg_c, gd.end_c,
34 gd.h_cv.diagonal().copy(), vdWradius)
35 self.mask = mask
37 def get_weight(self, psit_G):
38 """Get the weight of a wave function in the exterior region
39 (outside of the van der Waals radius). The augmentation sphere
40 is assumed to be smaller than the van der Waals radius and hence
41 does not contribute."""
43 # smooth part
44 weigth = self.gd.integrate(np.where(self.mask == 1,
45 (psit_G * psit_G.conj()).real,
46 0.0))
48 return weigth
50 def get_vdWradius(self, Z):
51 """Return van der Waals radius in Bohr"""
52 r = vdw_radii[Z] / Bohr
53 if np.isnan(r):
54 msg = 'van der Waals radius for Z=' + str(Z) + ' not known!'
55 raise RuntimeError(msg)
56 else:
57 return r
59 def write_mies_weights(self, wfs):
60 file = 'eed_mies.dat'
61 with paropen(file, 'a') as out:
62 fmf = FMF(['exterior electron density weights after',
63 'Y. Harada et al., Chem. Rev. 97 (1997) 1897'])
64 print(fmf.header(), end=' ', file=out)
65 print(fmf.data(['band index: n',
66 'k-point index: k',
67 'spin index: s',
68 'k-point weight: weight',
69 'energy: energy [eV]',
70 'occupation number: occ',
71 'relative EED weight: eed_weight']), end=' ',
72 file=out)
74 print(
75 '#; n k s weight energy occ eed_weight',
76 file=out)
77 for kpt in wfs.kpt_u:
78 for n in range(wfs.bd.nbands):
79 print('%4d %3d %1d %8.5f %10.5f %10.5f %10.5f' %
80 (n, kpt.k, kpt.s, kpt.weight,
81 kpt.eps_n[n] * Hartree,
82 kpt.f_n[n],
83 self.get_weight(kpt.psit_nG[n])
84 ), file=out)
85 if hasattr(out, 'flush'):
86 out.flush()