def updateDIIS(self,F,P):
FPS = dot([F,P,self.S])
SPF = self.adj(FPS)
# error must be in orthonormal basis
error = dot([self.X,FPS-SPF,self.X])
self.fockSet.append(self.F)
self.errorSet.append(error)
numFock = len(self.fockSet)
# limit subspace, hardcoded for now
if numFock > 8:
del self.fockSet[0]
del self.errorSet[0]
numFock -= 1
B = np.zeros((numFock + 1,numFock + 1))
B[-1,:] = B[:,-1] = -1.0
B[-1,-1] = 0.0
# B is symmetric
for i in range(numFock):
for j in range(i+1):
B[i,j] = B[j,i] = \
np.real(np.trace(np.dot(self.adj(self.errorSet[i]),
self.errorSet[j])))
residual = np.zeros(numFock + 1)
residual[-1] = -1.0
weights = np.linalg.solve(B,residual)
# weights is 1 x numFock + 1, but first numFock values
# should sum to one if we are doing DIIS correctly
assert np.isclose(sum(weights[:-1]),1.0)
F = np.zeros((self.nbasis,self.nbasis),dtype='complex')
for i, Fock in enumerate(self.fockSet):
F += weights[i] * Fock
return F
评论列表
文章目录