Skip to content

Commit 66646dc

Browse files
committed
Add linear dependency checks in tddft _lr_eig
1 parent 9253c88 commit 66646dc

File tree

1 file changed

+15
-7
lines changed

1 file changed

+15
-7
lines changed

pyscf/tdscf/_lr_eig.py

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -697,7 +697,7 @@ def real_eig(aop, x0, precond, tol_residual=1e-5, nroots=1, x0sym=None, pick=Non
697697
Y_new = XY_new[:,A_size:].T
698698
if x0sym is None:
699699
V, W = VW_Gram_Schmidt_fill_holder(
700-
V_holder[:,:m1], W_holder[:,:m1], X_new, Y_new)
700+
V_holder[:,:m1], W_holder[:,:m1], X_new, Y_new, lindep)
701701
else:
702702
xt_ir = xt_ir[r_index]
703703
xt_orth_ir = []
@@ -706,7 +706,7 @@ def real_eig(aop, x0, precond, tol_residual=1e-5, nroots=1, x0sym=None, pick=Non
706706
for ir in set(xt_ir):
707707
idx = np.nonzero(xt_ir == ir)[0]
708708
_V, _W = VW_Gram_Schmidt_fill_holder(
709-
V_holder[:,:m1], W_holder[:,:m1], X_new[:,idx], Y_new[:,idx])
709+
V_holder[:,:m1], W_holder[:,:m1], X_new[:,idx], Y_new[:,idx], lindep)
710710
V.append(_V)
711711
W.append(_W)
712712
xt_orth_ir.append([ir] * len(_V))
@@ -932,7 +932,7 @@ def TDDFT_subspace_eigen_solver(a, b, sigma, pi, nroots):
932932
y = x_p_y - x
933933
return omega, x, y
934934

935-
def VW_Gram_Schmidt_fill_holder(V_holder, W_holder, X_new, Y_new, lindep=1e-6):
935+
def VW_Gram_Schmidt_fill_holder(V_holder, W_holder, X_new, Y_new, lindep=1e-12):
936936
'''
937937
QR orthogonalization for (X_new, Y_new) basis vectors, then apply symmetric
938938
orthogonalization for {[X, Y]}, and its dual basis vectors {[Y, X]}
@@ -953,7 +953,7 @@ def VW_Gram_Schmidt_fill_holder(V_holder, W_holder, X_new, Y_new, lindep=1e-6):
953953
s21 = X_new.T.dot(Y_new)
954954
s21 += Y_new.T.dot(X_new)
955955
e, c = np.linalg.eigh(s11)
956-
mask = e > lindep**2
956+
mask = e > lindep
957957
e = e[mask]
958958
if e.size == 0:
959959
return (np.zeros([0, x0_size], dtype=X_new.dtype),
@@ -962,9 +962,10 @@ def VW_Gram_Schmidt_fill_holder(V_holder, W_holder, X_new, Y_new, lindep=1e-6):
962962

963963
csc = c.T.dot(s21).dot(c)
964964
n = csc.shape[0]
965+
lindep_sqrt = lindep**.5
965966
for i in range(n):
966967
w, u = np.linalg.eigh(csc[i:,i:])
967-
mask = 1 - abs(w) > lindep
968+
mask = 1 - abs(w) > lindep_sqrt
968969
if np.any(mask):
969970
c = c[:,i:]
970971
break
@@ -975,13 +976,20 @@ def VW_Gram_Schmidt_fill_holder(V_holder, W_holder, X_new, Y_new, lindep=1e-6):
975976
u = u[:,mask]
976977
c_orth = c.dot(u)
977978

978-
if e[0] < 1e-6 or 1-abs(w[0]) < 1e-3:
979-
# Rerun the orthogonalization to reduce numerical errors
979+
if e[0] < lindep_sqrt or any(abs(w)> 1-1e-3):
980+
# Rerun the orthogonalization to reduce numerical errors.
981+
# When w~=1-1e-3, errors in the orthogonalization (off-diagonal terms)
982+
# is near 1e-6.
980983
e, c = np.linalg.eigh(c_orth.T.dot(s11).dot(c_orth))
981984
c *= e**-.5
982985
c_orth = c_orth.dot(c)
983986
csc = c_orth.T.dot(s21).dot(c_orth)
987+
wlast = w
984988
w, u = np.linalg.eigh(csc)
989+
990+
mask = 1 - abs(w) > lindep_sqrt
991+
w = w[mask]
992+
u = u[:,mask]
985993
c_orth = c_orth.dot(u)
986994

987995
# Symmetric diagonalize

0 commit comments

Comments
 (0)