(git:ed6f26b)
Loading...
Searching...
No Matches
atom_optimization.F
Go to the documentation of this file.
1!--------------------------------------------------------------------------------------------------!
2! CP2K: A general program to perform molecular dynamics simulations !
3! Copyright 2000-2025 CP2K developers group <https://cp2k.org> !
4! !
5! SPDX-License-Identifier: GPL-2.0-or-later !
6!--------------------------------------------------------------------------------------------------!
7
8! **************************************************************************************************
9!> \brief Optimizer for the atomic code
10! **************************************************************************************************
13 USE kinds, ONLY: dp
14#include "./base/base_uses.f90"
15
16 IMPLICIT NONE
17
18 PRIVATE
19
20 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'atom_optimization'
21
22 TYPE hmat_type
23 REAL(dp) :: energy = 0.0_dp
24 REAL(dp) :: error = 0.0_dp
25 REAL(dp), DIMENSION(:, :, :), POINTER :: emat => null()
26 REAL(dp), DIMENSION(:, :, :), POINTER :: fmat => null()
27 REAL(dp), DIMENSION(:, :, :), POINTER :: pmat => null()
28 END TYPE hmat_type
29
31 INTEGER :: max_history = 0
32 INTEGER :: hlen = 0
33 INTEGER :: hpos = 0
34 REAL(dp) :: damping = 0.0_dp
35 REAL(dp) :: eps_diis = 0.0_dp
36 REAL(dp), DIMENSION(:, :), POINTER :: dmat => null()
37 TYPE(hmat_type), DIMENSION(:), POINTER :: hmat => null()
38 END TYPE atom_history_type
39
40 PUBLIC :: atom_opt_fmat, &
42
43CONTAINS
44
45! **************************************************************************************************
46!> \brief Initialise a circular buffer to keep Kohn-Sham and density matrices from previous iteration.
47!> \param history object to initialise
48!> \param optimization optimisation parameters
49!> \param matrix reference matrix. Historic matrices will have the same size as
50!> this reference matrix
51!> \par History
52!> * 08.2016 new structure element: density matrix [Juerg Hutter]
53!> * 08.2008 created [Juerg Hutter]
54! **************************************************************************************************
55 PURE SUBROUTINE atom_history_init(history, optimization, matrix)
56 TYPE(atom_history_type), INTENT(INOUT) :: history
57 TYPE(atom_optimization_type), INTENT(IN) :: optimization
58 REAL(dp), DIMENSION(:, :, :), INTENT(IN) :: matrix
59
60 INTEGER :: i, n1, n2, n3, ndiis
61 REAL(dp) :: damp, eps
62
63 ndiis = optimization%n_diis
64 eps = optimization%eps_diis
65 damp = optimization%damping
66
67 CALL atom_history_release(history)
68
69 history%max_history = ndiis
70 history%hlen = 0
71 history%hpos = 0
72 history%damping = damp
73 history%eps_diis = eps
74 ALLOCATE (history%dmat(ndiis + 1, ndiis + 1))
75
76 ALLOCATE (history%hmat(ndiis))
77 n1 = SIZE(matrix, 1)
78 n2 = SIZE(matrix, 2)
79 n3 = SIZE(matrix, 3)
80 DO i = 1, 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))
86 END DO
87
88 END SUBROUTINE atom_history_init
89
90! **************************************************************************************************
91!> \brief Add matrices from the current iteration into the circular buffer.
92!> \param history object to keep historic matrices
93!> \param pmat density matrix
94!> \param fmat Kohn-Sham matrix
95!> \param emat error matrix
96!> \param energy total energy
97!> \param error convergence
98!> \par History
99!> * 08.2016 new formal argument: density matrix [Juerg Hutter]
100!> * 08.2008 created [Juerg Hutter]
101! **************************************************************************************************
102 PURE SUBROUTINE atom_history_update(history, pmat, fmat, emat, energy, error)
103 TYPE(atom_history_type), INTENT(INOUT) :: history
104 REAL(dp), DIMENSION(:, :, :), INTENT(IN) :: pmat, fmat, emat
105 REAL(dp), INTENT(IN) :: energy, error
106
107 INTEGER :: nlen, nmax, nnow
108
109 nmax = history%max_history
110 nlen = min(history%hlen + 1, nmax)
111 nnow = history%hpos + 1
112 IF (nnow > nmax) nnow = 1
113
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
119
120 history%hlen = nlen
121 history%hpos = nnow
122
123 END SUBROUTINE atom_history_update
124
125! **************************************************************************************************
126!> \brief Release circular buffer to keep historic matrices.
127!> \param history object to release
128!> \par History
129!> * 08.2008 created [Juerg Hutter]
130! **************************************************************************************************
131 PURE SUBROUTINE atom_history_release(history)
132 TYPE(atom_history_type), INTENT(INOUT) :: history
133
134 INTEGER :: i
135
136 history%max_history = 0
137 history%hlen = 0
138 history%hpos = 0
139 history%damping = 0._dp
140 history%eps_diis = 0._dp
141 IF (ASSOCIATED(history%dmat)) THEN
142 DEALLOCATE (history%dmat)
143 END IF
144 IF (ASSOCIATED(history%hmat)) THEN
145 DO i = 1, SIZE(history%hmat)
146 IF (ASSOCIATED(history%hmat(i)%emat)) THEN
147 DEALLOCATE (history%hmat(i)%emat)
148 END IF
149 IF (ASSOCIATED(history%hmat(i)%fmat)) THEN
150 DEALLOCATE (history%hmat(i)%fmat)
151 END IF
152 IF (ASSOCIATED(history%hmat(i)%pmat)) THEN
153 DEALLOCATE (history%hmat(i)%pmat)
154 END IF
155 END DO
156 DEALLOCATE (history%hmat)
157 END IF
158
159 END SUBROUTINE atom_history_release
160
161! **************************************************************************************************
162!> \brief Construct a Kohn-Sham matrix for the next iteration based on the historic data.
163!> \param fmat new Kohn-Sham matrix
164!> \param history historic matrices
165!> \param err convergence
166!> \par History
167!> * 08.2016 renamed to atom_opt_fmat() [Juerg Hutter]
168!> * 08.2008 created as atom_opt() [Juerg Hutter]
169! **************************************************************************************************
170 SUBROUTINE atom_opt_fmat(fmat, history, err)
171 REAL(dp), DIMENSION(:, :, :), INTENT(INOUT) :: fmat
172 TYPE(atom_history_type), INTENT(INOUT) :: history
173 REAL(dp), INTENT(IN) :: err
174
175 INTEGER :: i, info, j, lwork, na, nb, nlen, nm, &
176 nmax, nnow, rank
177 REAL(dp) :: a, rcond, t
178 REAL(dp), ALLOCATABLE, DIMENSION(:) :: s, work
179 REAL(dp), ALLOCATABLE, DIMENSION(:, :) :: vec
180
181 nmax = history%max_history
182 nnow = history%hpos
183 a = history%damping
184 IF (history%hlen > 1) THEN
185 IF (err < history%eps_diis) THEN
186 ! DIIS
187 rcond = 1.e-10_dp
188 lwork = 25*nmax
189 ALLOCATE (vec(nmax + 1, 2), s(nmax + 1), work(lwork))
190 nlen = history%hlen
191 vec = 0._dp
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
196 DO i = 1, nlen
197 na = nnow + 1 - i
198 IF (na < 1) na = nmax + na
199 DO j = i, nlen
200 nb = nnow + 1 - j
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
205 END DO
206 END DO
207 CALL dgelss(nlen + 1, nlen + 1, 1, history%dmat, nmax + 1, vec, nmax + 1, s, &
208 rcond, rank, work, lwork, info)
209 cpassert(info == 0)
210 fmat = 0._dp
211 DO i = 1, nlen
212 na = nnow + 1 - i
213 IF (na < 1) na = nmax + na
214 fmat = fmat + vec(i, 1)*history%hmat(na)%fmat
215 END DO
216
217 DEALLOCATE (vec, s, work)
218 ELSE
219 ! damping
220 nm = nnow - 1
221 IF (nm < 1) nm = history%max_history
222 fmat = a*history%hmat(nnow)%fmat + (1._dp - a)*history%hmat(nm)%fmat
223 END IF
224 ELSEIF (history%hlen == 1) THEN
225 fmat = history%hmat(nnow)%fmat
226 ELSE
227 cpabort("")
228 END IF
229
230 END SUBROUTINE atom_opt_fmat
231
232END MODULE atom_optimization
Optimizer for the atomic code.
subroutine, public atom_opt_fmat(fmat, history, err)
Construct a Kohn-Sham matrix for the next iteration based on the historic data.
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_release(history)
Release circular buffer to keep historic matrices.
pure subroutine, public atom_history_update(history, pmat, fmat, emat, energy, error)
Add matrices from the current iteration into the circular buffer.
Define the atom type and its sub types.
Definition atom_types.F:15
Defines the basic variable types.
Definition kinds.F:23
integer, parameter, public dp
Definition kinds.F:34
Information on optimization procedure.
Definition atom_types.F:280