mirror of
https://github.com/triqs/dft_tools
synced 2024-12-22 04:13:47 +01:00
Fixed a bug in the orthogonalization routine
There was a very nasty bug in the preparation of the block matrix 'p_mat'. The point is that this matrix is created once for all k-points with the band dimension being the maximum possible. However, only a part of the matrix is used at every k-point but the orthogonalization is done for the whole matrix. The problem was that if the number of bands for a given k-point was smaller than that for the next k-point them for the next k-point some part of 'p_mat' still contained data from the previous step, which messed up the orthonormalization. Now, 'p_mat' is set to zero at each step of the loop. Also, property 'nion' was added to ProjectorShell since it is used very often.
This commit is contained in:
parent
f994b82704
commit
c1b3000c00
@ -154,24 +154,26 @@ class ProjectorGroup:
|
|||||||
|
|
||||||
ndim = i2_bl
|
ndim = i2_bl
|
||||||
p_mat = np.zeros((ndim, nb_max), dtype=np.complex128)
|
p_mat = np.zeros((ndim, nb_max), dtype=np.complex128)
|
||||||
|
# Note that 'ns' and 'nk' are the same for all shells
|
||||||
for isp in xrange(ns):
|
for isp in xrange(ns):
|
||||||
for ik in xrange(nk):
|
for ik in xrange(nk):
|
||||||
nb = self.ib_win[ik, isp, 1] - self.ib_win[ik, isp, 0] + 1
|
nb = self.ib_win[ik, isp, 1] - self.ib_win[ik, isp, 0] + 1
|
||||||
# Combine all projectors of the group to one block projector
|
# Combine all projectors of the group to one block projector
|
||||||
|
p_mat[:, :] = 0.0j # !!! Clean-up from the last k-point!
|
||||||
for ish in self.ishells:
|
for ish in self.ishells:
|
||||||
shell = self.shells[ish]
|
shell = self.shells[ish]
|
||||||
blocks = bl_map[ish]['bmat_blocks']
|
blocks = bl_map[ish]['bmat_blocks']
|
||||||
|
nion = shell.nion # !!!
|
||||||
for ion in xrange(nion):
|
for ion in xrange(nion):
|
||||||
i1, i2 = blocks[ion]
|
i1, i2 = blocks[ion]
|
||||||
p_mat[i1:i2, :nb] = shell.proj_win[ion, isp, ik, :nlm, :nb]
|
p_mat[i1:i2, :nb] = shell.proj_win[ion, isp, ik, :nlm, :nb]
|
||||||
# Now orthogonalize the obtained block projector
|
# Now orthogonalize the obtained block projector
|
||||||
p_orth, overl, eig = self.orthogonalize_projector_matrix(p_mat)
|
p_orth, overl, eig = self.orthogonalize_projector_matrix(p_mat)
|
||||||
# print "ik = ", ik
|
|
||||||
# print overl.real
|
|
||||||
# Distribute back projectors in the same order
|
# Distribute back projectors in the same order
|
||||||
for ish in self.ishells:
|
for ish in self.ishells:
|
||||||
shell = self.shells[ish]
|
shell = self.shells[ish]
|
||||||
blocks = bl_map[ish]['bmat_blocks']
|
blocks = bl_map[ish]['bmat_blocks']
|
||||||
|
nion = shell.nion # !!!
|
||||||
for ion in xrange(nion):
|
for ion in xrange(nion):
|
||||||
i1, i2 = blocks[ion]
|
i1, i2 = blocks[ion]
|
||||||
shell.proj_win[ion, isp, ik, :nlm, :nb] = p_orth[i1:i2, :nb]
|
shell.proj_win[ion, isp, ik, :nlm, :nb] = p_orth[i1:i2, :nb]
|
||||||
|
@ -47,11 +47,7 @@ class ProjectorShell:
|
|||||||
self.lm2 = (self.lorb+1)**2
|
self.lm2 = (self.lorb+1)**2
|
||||||
|
|
||||||
self.ndim = self.extract_tmatrices(sh_pars)
|
self.ndim = self.extract_tmatrices(sh_pars)
|
||||||
# if self.tmatrix is None:
|
self.nion = len(self.ion_list)
|
||||||
# self.ndim = self.lm2 - self.lm1
|
|
||||||
# else:
|
|
||||||
## TODO: generalize this to a tmatrix for every ion
|
|
||||||
# self.ndim = self.tmatrix.shape[0]
|
|
||||||
|
|
||||||
# Pre-select a subset of projectors (this should be an array view => no memory is wasted)
|
# Pre-select a subset of projectors (this should be an array view => no memory is wasted)
|
||||||
# !!! This sucks but I have to change the order of 'ib' and 'ilm' indices here
|
# !!! This sucks but I have to change the order of 'ib' and 'ilm' indices here
|
||||||
|
Loading…
Reference in New Issue
Block a user