19 USE dbcsr_api,
ONLY: dbcsr_add,&
27 #include "./base/base_uses.f90"
33 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'almo_scf_lbfgs_types'
41 TYPE lbfgs_history_type
46 INTEGER,
DIMENSION(2) :: istore = 0
47 TYPE(dbcsr_type),
DIMENSION(:, :, :),
ALLOCATABLE :: matrix
48 REAL(KIND=
dp),
DIMENSION(:, :),
ALLOCATABLE :: rho
49 END TYPE lbfgs_history_type
61 TYPE(lbfgs_history_type),
INTENT(INOUT) :: history
62 TYPE(dbcsr_type),
DIMENSION(:),
INTENT(IN) :: variable, gradient
64 CALL lbfgs_history_push(history, variable, vartype=1, action=1)
65 CALL lbfgs_history_push(history, gradient, vartype=2, action=1)
79 TYPE(lbfgs_history_type),
INTENT(INOUT) :: history
80 TYPE(dbcsr_type),
DIMENSION(:),
INTENT(IN) :: variable, gradient
81 TYPE(dbcsr_type),
DIMENSION(:),
INTENT(INOUT) :: direction
85 CALL lbfgs_history_push(history, variable, vartype=1, action=2)
86 CALL lbfgs_history_push(history, gradient, vartype=2, action=2)
88 CALL lbfgs_history_last_rho(history)
90 CALL lbfgs_history_direction(history, gradient, direction)
93 CALL lbfgs_history_push(history, variable, vartype=1, action=1)
94 CALL lbfgs_history_push(history, gradient, vartype=2, action=1)
106 TYPE(lbfgs_history_type),
INTENT(INOUT) :: history
107 INTEGER,
INTENT(IN) :: nspins, nstore
111 nallocate = max(1, nstore)
112 history%nstore = nallocate
113 history%istore(:) = 0
114 ALLOCATE (history%matrix(nspins, nallocate, 2))
115 ALLOCATE (history%rho(nspins, nallocate))
124 TYPE(lbfgs_history_type),
INTENT(INOUT) :: history
126 INTEGER :: ispin, istore, ivartype
129 DO ispin = 1,
SIZE(history%matrix, 1)
131 DO istore = 1, min(history%istore(ivartype) + 1, history%nstore)
133 CALL dbcsr_release(history%matrix(ispin, istore, ivartype))
137 DEALLOCATE (history%matrix)
138 DEALLOCATE (history%rho)
146 SUBROUTINE lbfgs_history_last_rho(history)
148 TYPE(lbfgs_history_type),
INTENT(INOUT) :: history
150 INTEGER :: ispin, istore
159 DO ispin = 1,
SIZE(history%matrix, 1)
161 istore = mod(history%istore(1) - 1, history%nstore) + 1
162 CALL dbcsr_dot(history%matrix(ispin, istore, 1), &
163 history%matrix(ispin, istore, 2), &
164 history%rho(ispin, istore))
166 history%rho(ispin, istore) = 1.0_dp/history%rho(ispin, istore)
174 END SUBROUTINE lbfgs_history_last_rho
186 SUBROUTINE lbfgs_history_push(history, matrix, vartype, action)
187 TYPE(lbfgs_history_type),
INTENT(INOUT) :: history
188 TYPE(dbcsr_type),
DIMENSION(:),
INTENT(IN) :: matrix
189 INTEGER,
INTENT(IN) :: vartype, action
191 INTEGER :: ispin, istore
202 history%istore(vartype) = history%istore(vartype) + 1
204 DO ispin = 1,
SIZE(history%matrix, 1)
206 istore = mod(history%istore(vartype) - 1, history%nstore) + 1
211 IF (history%istore(vartype) <= history%nstore .AND. &
214 CALL dbcsr_create(history%matrix(ispin, istore, vartype), &
215 template=matrix(ispin))
221 IF (action .EQ. 1)
THEN
222 CALL dbcsr_copy(history%matrix(ispin, istore, vartype), matrix(ispin))
224 CALL dbcsr_add(history%matrix(ispin, istore, vartype), matrix(ispin), -1.0_dp, 1.0_dp)
231 IF (action .EQ. 1)
THEN
232 history%istore(vartype) = history%istore(vartype) - 1
235 END SUBROUTINE lbfgs_history_push
243 SUBROUTINE lbfgs_history_direction(history, gradient, direction)
245 TYPE(lbfgs_history_type),
INTENT(INOUT) :: history
246 TYPE(dbcsr_type),
DIMENSION(:),
INTENT(IN) :: gradient
247 TYPE(dbcsr_type),
DIMENSION(:),
INTENT(INOUT) :: direction
249 INTEGER :: ispin, istore, iterm, nterms
250 REAL(kind=
dp) :: beta, gammak
251 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: alpha
252 TYPE(dbcsr_type) :: q
261 IF (history%istore(1) .NE. history%istore(2))
THEN
262 cpabort(
"BFGS APIs are not used correctly")
265 nterms = min(history%istore(1), history%nstore)
270 ALLOCATE (alpha(nterms))
272 DO ispin = 1,
SIZE(history%matrix, 1)
274 CALL dbcsr_create(q, template=gradient(ispin))
276 CALL dbcsr_copy(q, gradient(ispin))
282 istore = mod(history%istore(1) - iterm, history%nstore) + 1
288 CALL dbcsr_dot(history%matrix(ispin, istore, 1), q, alpha(iterm))
289 alpha(iterm) = history%rho(ispin, istore)*alpha(iterm)
290 CALL dbcsr_add(q, history%matrix(ispin, istore, 2), 1.0_dp, -alpha(iterm))
294 IF (iterm .EQ. 1)
THEN
295 CALL dbcsr_dot(history%matrix(ispin, istore, 2), history%matrix(ispin, istore, 2), gammak)
296 gammak = 1.0_dp/(gammak*history%rho(ispin, istore))
305 CALL dbcsr_scale(q, gammak)
308 DO iterm = nterms, 1, -1
311 istore = mod(history%istore(1) - iterm, history%nstore) + 1
313 CALL dbcsr_dot(history%matrix(ispin, istore, 2), q, beta)
314 beta = history%rho(ispin, istore)*beta
315 CALL dbcsr_add(q, history%matrix(ispin, istore, 1), 1.0_dp, alpha(iterm) - beta)
320 CALL dbcsr_scale(q, -1.0)
321 CALL dbcsr_copy(direction(ispin), q)
323 CALL dbcsr_release(q)
329 END SUBROUTINE lbfgs_history_direction
subroutine, public lbfgs_create(history, nspins, nstore)
create history storage for limited memory bfgs
subroutine, public lbfgs_seed(history, variable, gradient)
interface subroutine to store the first variable/gradient pair
subroutine, public lbfgs_release(history)
release the bfgs history
subroutine, public lbfgs_get_direction(history, variable, gradient, direction)
interface subroutine to store a variable/gradient pair and predict direction
various routines to log and control the output. The idea is that decisions about where to log should ...
recursive integer function, public cp_logger_get_default_unit_nr(logger, local, skip_not_ionode)
asks the default unit number of the given logger. try to use cp_logger_get_unit_nr
type(cp_logger_type) function, pointer, public cp_get_default_logger()
returns the default logger
Defines the basic variable types.
integer, parameter, public dp