58 REAL(
dp),
DIMENSION(:, :, :),
INTENT(IN) :: matrix
60 INTEGER :: i, n1, n2, n3, ndiis
63 ndiis = optimization%n_diis
64 eps = optimization%eps_diis
65 damp = optimization%damping
69 history%max_history = ndiis
72 history%damping = damp
73 history%eps_diis = eps
74 ALLOCATE (history%dmat(ndiis + 1, ndiis + 1))
76 ALLOCATE (history%hmat(ndiis))
81 history%hmat(i)%energy = 0.0_dp
82 history%hmat(i)%error = 0.0_dp
83 ALLOCATE (history%hmat(i)%emat(n1, n2, n3))
84 ALLOCATE (history%hmat(i)%fmat(n1, n2, n3))
85 ALLOCATE (history%hmat(i)%pmat(n1, n2, n3))
104 REAL(
dp),
DIMENSION(:, :, :),
INTENT(IN) :: pmat, fmat, emat
105 REAL(
dp),
INTENT(IN) :: energy, error
107 INTEGER :: nlen, nmax, nnow
109 nmax = history%max_history
110 nlen = min(history%hlen + 1, nmax)
111 nnow = history%hpos + 1
112 IF (nnow > nmax) nnow = 1
114 history%hmat(nnow)%energy = energy
115 history%hmat(nnow)%error = error
116 history%hmat(nnow)%pmat = pmat
117 history%hmat(nnow)%fmat = fmat
118 history%hmat(nnow)%emat = emat
171 REAL(
dp),
DIMENSION(:, :, :),
INTENT(INOUT) :: fmat
173 REAL(
dp),
INTENT(IN) :: err
175 INTEGER :: i, info, j, lwork, na, nb, nlen, nm, &
177 REAL(
dp) :: a, rcond, t
178 REAL(
dp),
ALLOCATABLE,
DIMENSION(:) :: s, work
179 REAL(
dp),
ALLOCATABLE,
DIMENSION(:, :) :: vec
181 nmax = history%max_history
184 IF (history%hlen > 1)
THEN
185 IF (err < history%eps_diis)
THEN
189 ALLOCATE (vec(nmax + 1, 2), s(nmax + 1), work(lwork))
192 vec(nlen + 1, 1) = 1._dp
193 history%dmat(1:nlen, nlen + 1) = 1._dp
194 history%dmat(nlen + 1, 1:nlen) = 1._dp
195 history%dmat(nlen + 1, nlen + 1) = 0._dp
198 IF (na < 1) na = nmax + na
201 IF (nb < 1) nb = nmax + nb
202 t = sum(history%hmat(na)%emat*history%hmat(nb)%emat)
203 history%dmat(i, j) = t
204 history%dmat(j, i) = t
207 CALL dgelss(nlen + 1, nlen + 1, 1, history%dmat, nmax + 1, vec, nmax + 1, s, &
208 rcond, rank, work, lwork, info)
213 IF (na < 1) na = nmax + na
214 fmat = fmat + vec(i, 1)*history%hmat(na)%fmat
217 DEALLOCATE (vec, s, work)
221 IF (nm < 1) nm = history%max_history
222 fmat = a*history%hmat(nnow)%fmat + (1._dp - a)*history%hmat(nm)%fmat
224 ELSEIF (history%hlen == 1)
THEN
225 fmat = history%hmat(nnow)%fmat
pure subroutine, public atom_history_init(history, optimization, matrix)
Initialise a circular buffer to keep Kohn-Sham and density matrices from previous iteration.
pure subroutine, public atom_history_update(history, pmat, fmat, emat, energy, error)
Add matrices from the current iteration into the circular buffer.