Coverage for gpaw/xc/functional.py: 94%
62 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 gpaw.xc.kernel import XCKernel
5class XCFunctional:
6 orbital_dependent = False
7 xp = np
9 def __init__(self, name: str, type: str):
10 self.name = name
11 self.gd = None
12 self.ekin = 0.0
13 self.type = type
14 self.kernel: XCKernel
16 def todict(self):
17 """Get dictionary representation of XC functional.
19 This representation works for libxc kernels; other classes should
20 likely override this function and should probably not rely on
21 this implementation."""
22 return {'type': self.kernel.type,
23 'kernel': self.kernel.name}
25 def tostring(self):
26 """Get string representation of XC functional.
28 This will give the name for libxc functionals but other data for
29 hybrids."""
30 return self.name
32 def get_setup_name(self):
33 return self.name
35 def initialize(self, density, hamiltonian, wfs):
36 pass
38 def set_grid_descriptor(self, gd):
39 self.gd = gd
41 def calculate(self, gd, n_sg, v_sg=None, e_g=None):
42 """Calculate energy and potential.
44 gd: GridDescriptor
45 Descriptor for 3-d grid.
46 n_sg: rank-4 ndarray
47 Spin densities.
48 v_sg: rank-4 ndarray
49 Array for potential. The XC potential is added to the values
50 already there.
51 e_g: rank-3 ndarray
52 Energy density. Values must be written directly, not added.
54 The total XC energy is returned."""
56 if gd is not self.gd:
57 self.set_grid_descriptor(gd)
58 if e_g is None:
59 e_g = gd.empty()
60 if v_sg is None:
61 v_sg = np.zeros_like(n_sg)
62 self.calculate_impl(gd, n_sg, v_sg, e_g)
63 return gd.integrate(e_g)
65 def calculate_impl(self, gd, n_sg, v_sg, e_g):
66 raise NotImplementedError
68 def calculate_paw_correction(self, setup, D_sp, dEdD_sp=None, a=None):
69 raise NotImplementedError
71 def set_positions(self, spos_ac, atom_partition=None):
72 pass
74 def get_description(self):
75 """Get long description of functional as a string, or None."""
76 return None
78 def summary(self, fd):
79 """Write summary of last calculation to file."""
80 pass
82 def write(self, writer, natoms=None):
83 pass
85 def read(self, reader):
86 pass
88 def estimate_memory(self, mem):
89 pass
91 # Orbital dependent stuff:
92 def apply_orbital_dependent_hamiltonian(self, kpt, psit_nG,
93 Htpsit_nG, dH_asp=None):
94 pass
96 def correct_hamiltonian_matrix(self, kpt, H_nn):
97 # In what sense? Some documentation here maybe?
98 pass
100 def add_correction(self, kpt, psit_xG, R_xG, P_axi, c_axi, n_x=None,
101 calculate_change=False):
102 # Which kind of correction is this? Maybe some kind of documentation
103 # could be written? What is required of an implementation?
104 pass
106 def rotate(self, kpt, U_nn):
107 pass
109 def get_kinetic_energy_correction(self):
110 return self.ekin
112 def add_forces(self, F_av):
113 pass
115 def stress_tensor_contribution(self, n_sg, skip_sum=False):
116 raise NotImplementedError('Calculation of stress tensor is not ' +
117 f'implemented for {self.name}')
119 def calculate_spherical(self, rgd, n_sg, v_sg, e_g=None):
120 raise NotImplementedError