59 REAL(
dp),
DIMENSION(:, :, :),
INTENT(IN) :: matrix
61 INTEGER :: i, n1, n2, n3, ndiis
64 ndiis = optimization%n_diis
65 eps = optimization%eps_diis
66 damp = optimization%damping
70 history%max_history = ndiis
73 history%damping = damp
74 history%eps_diis = eps
75 ALLOCATE (history%dmat(ndiis + 1, ndiis + 1))
77 ALLOCATE (history%hmat(ndiis))
82 history%hmat(i)%energy = 0.0_dp
83 history%hmat(i)%error = 0.0_dp
84 ALLOCATE (history%hmat(i)%emat(n1, n2, n3))
85 ALLOCATE (history%hmat(i)%fmat(n1, n2, n3))
86 ALLOCATE (history%hmat(i)%pmat(n1, n2, n3))
105 REAL(
dp),
DIMENSION(:, :, :),
INTENT(IN) :: pmat, fmat, emat
106 REAL(
dp),
INTENT(IN) :: energy, error
108 INTEGER :: nlen, nmax, nnow
110 nmax = history%max_history
111 nlen = min(history%hlen + 1, nmax)
112 nnow = history%hpos + 1
113 IF (nnow > nmax) nnow = 1
115 history%hmat(nnow)%energy = energy
116 history%hmat(nnow)%error = error
117 history%hmat(nnow)%pmat = pmat
118 history%hmat(nnow)%fmat = fmat
119 history%hmat(nnow)%emat = emat
172 REAL(
dp),
DIMENSION(:, :, :),
INTENT(INOUT) :: fmat
174 REAL(
dp),
INTENT(IN) :: err
176 INTEGER :: i, info, j, lwork, na, nb, nlen, nm, &
178 REAL(
dp) :: a, rcond, t
179 REAL(
dp),
ALLOCATABLE,
DIMENSION(:) :: s, work
180 REAL(
dp),
ALLOCATABLE,
DIMENSION(:, :) :: vec
182 nmax = history%max_history
185 IF (history%hlen > 1)
THEN
186 IF (err < history%eps_diis)
THEN
190 ALLOCATE (vec(nmax + 1, 2), s(nmax + 1), work(lwork))
193 vec(nlen + 1, 1) = 1._dp
194 history%dmat(1:nlen, nlen + 1) = 1._dp
195 history%dmat(nlen + 1, 1:nlen) = 1._dp
196 history%dmat(nlen + 1, nlen + 1) = 0._dp
199 IF (na < 1) na = nmax + na
202 IF (nb < 1) nb = nmax + nb
203 t = sum(history%hmat(na)%emat*history%hmat(nb)%emat)
204 history%dmat(i, j) = t
205 history%dmat(j, i) = t
208 CALL lapack_sgelss(nlen + 1, nlen + 1, 1, history%dmat, nmax + 1, vec, nmax + 1, s, &
209 rcond, rank, work, lwork, info)
214 IF (na < 1) na = nmax + na
215 fmat = fmat + vec(i, 1)*history%hmat(na)%fmat
218 DEALLOCATE (vec, s, work)
222 IF (nm < 1) nm = history%max_history
223 fmat = a*history%hmat(nnow)%fmat + (1._dp - a)*history%hmat(nm)%fmat
225 ELSEIF (history%hlen == 1)
THEN
226 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.