Coverage for gpaw/tddft/folding.py: 82%
73 statements
« prev ^ index » next coverage.py v7.7.1, created at 2025-07-20 00:19 +0000
« prev ^ index » next coverage.py v7.7.1, created at 2025-07-20 00:19 +0000
1import numpy as np
3from gpaw.tddft.units import au_to_eV
4from gpaw.tddft.units import eV_to_au
7def frequencies(frequencies, foldings, widths, units='eV'):
8 f_w = []
9 for folding in np.array([foldings]).ravel():
10 for width in np.array([widths]).ravel():
11 folding = Folding(folding, width, units)
12 f_w.append(FoldedFrequencies(frequencies, folding, units))
13 return f_w
16def convert_to_au(val, units='eV'):
17 if units == 'eV':
18 return val * eV_to_au
19 elif units == 'au':
20 return val
21 raise RuntimeError('Unknown units: %s' % units)
24class FoldedFrequencies:
25 def __init__(self, frequencies, folding, units='eV'):
26 freqs = np.array([frequencies], dtype=float).ravel()
27 self.frequencies = convert_to_au(freqs, units=units)
28 if isinstance(folding, dict):
29 self.folding = Folding(**folding)
30 else:
31 self.folding = folding
33 def todict(self):
34 d = dict(units='au')
35 for arg in ['frequencies', 'folding']:
36 val = getattr(self, arg)
37 if hasattr(val, 'todict'):
38 val = val.todict()
39 d[arg] = val
40 return d
42 def __repr__(self):
43 s = 'With %s: ' % self.folding
44 s += ', '.join(['%.5f' % (f * au_to_eV) for f in self.frequencies])
45 s += ' eV'
46 return s
49class Frequency:
50 def __init__(self, freq, folding, units='eV'):
51 ff = FoldedFrequencies(freq, folding, units)
52 self.folding = ff.folding
53 self.freq = ff.frequencies[0]
56class Folding:
57 def __init__(self, folding, width, units='eV'):
58 if width is None:
59 folding = None
61 self.folding = folding
62 if self.folding is None:
63 self.width = None
64 else:
65 self.width = convert_to_au(float(width), units=units)
67 if self.folding not in [None, 'Gauss', 'Lorentz']:
68 raise RuntimeError('Unknown folding: %s' % self.folding)
70 if self.folding is None:
71 self.fwhm = 0.0
72 elif self.folding == 'Gauss':
73 self.fwhm = self.width * (2. * np.sqrt(2. * np.log(2.0)))
74 elif self.folding == 'Lorentz':
75 self.fwhm = 2. * self.width
77 def envelope(self, time):
78 if self.folding is None:
79 return 0 * time + 1
80 elif self.folding == 'Gauss':
81 return np.exp(- 0.5 * self.width**2 * time**2)
82 elif self.folding == 'Lorentz':
83 return np.exp(- self.width * time)
85 def todict(self):
86 d = dict(units='au')
87 for arg in ['folding', 'width']:
88 d[arg] = getattr(self, arg)
89 return d
91 def __repr__(self):
92 if self.folding is None:
93 return 'No folding'
94 return f'{self.folding}({self.width * au_to_eV:.5f} eV)'