99 TYPE(
dbcsr_type),
INTENT(IN) :: sample_err, sample_var
100 INTEGER,
INTENT(IN) :: error_type, max_length
102 CHARACTER(len=*),
PARAMETER :: routineN =
'almo_scf_diis_init_dbcsr'
104 INTEGER :: handle, idomain, im, ndomains
106 CALL timeset(routinen, handle)
108 IF (max_length .LE. 0)
THEN
109 cpabort(
"DIIS: max_length is less than zero")
112 diis_env%diis_env_type = diis_env_dbcsr
114 diis_env%max_buffer_length = max_length
115 diis_env%buffer_length = 0
116 diis_env%error_type = error_type
117 diis_env%in_point = 1
119 ALLOCATE (diis_env%m_err(diis_env%max_buffer_length))
120 ALLOCATE (diis_env%m_var(diis_env%max_buffer_length))
123 DO im = 1, diis_env%max_buffer_length
133 ALLOCATE (diis_env%m_b(ndomains))
136 diis_env%m_b(:)%domain = 100
137 DO idomain = 1, ndomains
138 IF (diis_env%m_b(idomain)%domain .GT. 0)
THEN
139 ALLOCATE (diis_env%m_b(idomain)%mdata(1, 1))
140 diis_env%m_b(idomain)%mdata(:, :) = 0.0_dp
144 CALL timestop(handle)
158 SUBROUTINE almo_scf_diis_init_domain(diis_env, sample_err, error_type, &
163 INTENT(IN) :: sample_err
164 INTEGER,
INTENT(IN) :: error_type, max_length
166 CHARACTER(len=*),
PARAMETER :: routineN =
'almo_scf_diis_init_domain'
168 INTEGER :: handle, idomain, ndomains
170 CALL timeset(routinen, handle)
172 IF (max_length .LE. 0)
THEN
173 cpabort(
"DIIS: max_length is less than zero")
176 diis_env%diis_env_type = diis_env_domain
178 diis_env%max_buffer_length = max_length
179 diis_env%buffer_length = 0
180 diis_env%error_type = error_type
181 diis_env%in_point = 1
183 ndomains =
SIZE(sample_err)
185 ALLOCATE (diis_env%d_err(diis_env%max_buffer_length, ndomains))
186 ALLOCATE (diis_env%d_var(diis_env%max_buffer_length, ndomains))
193 ALLOCATE (diis_env%m_b(ndomains))
197 diis_env%m_b(:)%domain = sample_err(:)%domain
198 DO idomain = 1, ndomains
199 IF (diis_env%m_b(idomain)%domain .GT. 0)
THEN
200 ALLOCATE (diis_env%m_b(idomain)%mdata(1, 1))
201 diis_env%m_b(idomain)%mdata(:, :) = 0.0_dp
205 CALL timestop(handle)
222 TYPE(
dbcsr_type),
INTENT(IN),
OPTIONAL :: var, err
224 INTENT(IN),
OPTIONAL :: d_var, d_err
226 CHARACTER(len=*),
PARAMETER :: routinen =
'almo_scf_diis_push'
228 INTEGER :: handle, idomain, in_point, irow, &
229 ndomains, old_buffer_length
230 REAL(kind=
dp) :: trace0
231 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: m_b_tmp
233 CALL timeset(routinen, handle)
235 IF (diis_env%diis_env_type .EQ. diis_env_dbcsr)
THEN
236 IF (.NOT. (
PRESENT(var) .AND.
PRESENT(err)))
THEN
237 cpabort(
"provide DBCSR matrices")
239 ELSE IF (diis_env%diis_env_type .EQ. diis_env_domain)
THEN
240 IF (.NOT. (
PRESENT(d_var) .AND.
PRESENT(d_err)))
THEN
241 cpabort(
"provide domain submatrices")
244 cpabort(
"illegal DIIS ENV type")
247 in_point = diis_env%in_point
250 IF (diis_env%diis_env_type .EQ. diis_env_dbcsr)
THEN
251 CALL dbcsr_copy(diis_env%m_var(in_point), var)
252 CALL dbcsr_copy(diis_env%m_err(in_point), err)
253 ELSE IF (diis_env%diis_env_type .EQ. diis_env_domain)
THEN
259 old_buffer_length = diis_env%buffer_length
260 diis_env%buffer_length = diis_env%buffer_length + 1
261 IF (diis_env%buffer_length .GT. diis_env%max_buffer_length) &
262 diis_env%buffer_length = diis_env%max_buffer_length
287 ndomains =
SIZE(diis_env%m_b)
288 IF (old_buffer_length .LT. diis_env%buffer_length)
THEN
289 ALLOCATE (m_b_tmp(diis_env%buffer_length + 1, diis_env%buffer_length + 1))
290 DO idomain = 1, ndomains
291 IF (diis_env%m_b(idomain)%domain .GT. 0)
THEN
292 m_b_tmp(:, :) = 0.0_dp
293 m_b_tmp(1:diis_env%buffer_length, 1:diis_env%buffer_length) = &
294 diis_env%m_b(idomain)%mdata(:, :)
295 DEALLOCATE (diis_env%m_b(idomain)%mdata)
296 ALLOCATE (diis_env%m_b(idomain)%mdata(diis_env%buffer_length + 1, &
297 diis_env%buffer_length + 1))
298 diis_env%m_b(idomain)%mdata(:, :) = m_b_tmp(:, :)
303 DO idomain = 1, ndomains
304 IF (diis_env%m_b(idomain)%domain .GT. 0)
THEN
305 diis_env%m_b(idomain)%mdata(1, in_point + 1) = -1.0_dp
306 diis_env%m_b(idomain)%mdata(in_point + 1, 1) = -1.0_dp
307 DO irow = 1, diis_env%buffer_length
308 IF (diis_env%diis_env_type .EQ. diis_env_dbcsr)
THEN
309 trace0 = almo_scf_diis_error_overlap(diis_env, &
310 a=diis_env%m_err(irow), b=diis_env%m_err(in_point))
311 ELSE IF (diis_env%diis_env_type .EQ. diis_env_domain)
THEN
312 trace0 = almo_scf_diis_error_overlap(diis_env, &
313 d_a=diis_env%d_err(irow, idomain), &
314 d_b=diis_env%d_err(in_point, idomain))
316 diis_env%m_b(idomain)%mdata(irow + 1, in_point + 1) = trace0
317 diis_env%m_b(idomain)%mdata(in_point + 1, irow + 1) = trace0
323 diis_env%in_point = diis_env%in_point + 1
324 IF (diis_env%in_point .GT. diis_env%max_buffer_length) diis_env%in_point = 1
326 CALL timestop(handle)
341 TYPE(
dbcsr_type),
INTENT(INOUT),
OPTIONAL :: extr_var
343 INTENT(INOUT),
OPTIONAL :: d_extr_var
345 CHARACTER(len=*),
PARAMETER :: routinen =
'almo_scf_diis_extrapolate'
347 INTEGER :: handle, idomain, im, info, lwork, &
349 REAL(kind=
dp) :: checksum
350 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: coeff, eigenvalues, tmp1, work
351 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: m_b_copy
354 CALL timeset(routinen, handle)
358 IF (logger%para_env%is_source())
THEN
364 IF (diis_env%diis_env_type .EQ. diis_env_dbcsr)
THEN
365 IF (.NOT.
PRESENT(extr_var))
THEN
366 cpabort(
"provide DBCSR matrix")
368 ELSE IF (diis_env%diis_env_type .EQ. diis_env_domain)
THEN
369 IF (.NOT.
PRESENT(d_extr_var))
THEN
370 cpabort(
"provide domain submatrices")
373 cpabort(
"illegal DIIS ENV type")
377 ALLOCATE (eigenvalues(diis_env%buffer_length + 1))
378 ALLOCATE (m_b_copy(diis_env%buffer_length + 1, diis_env%buffer_length + 1))
380 ndomains =
SIZE(diis_env%m_b)
382 DO idomain = 1, ndomains
384 IF (diis_env%m_b(idomain)%domain .GT. 0)
THEN
386 m_b_copy(:, :) = diis_env%m_b(idomain)%mdata(:, :)
390 ALLOCATE (work(max(1, lwork)))
391 CALL dsyev(
'V',
'L', diis_env%buffer_length + 1, m_b_copy, &
392 diis_env%buffer_length + 1, eigenvalues, work, lwork, info)
397 ALLOCATE (work(max(1, lwork)))
398 CALL dsyev(
'V',
'L', diis_env%buffer_length + 1, m_b_copy, &
399 diis_env%buffer_length + 1, eigenvalues, work, lwork, info)
400 IF (info .NE. 0) cpabort(
"DSYEV failed")
410 ALLOCATE (tmp1(diis_env%buffer_length + 1))
411 ALLOCATE (coeff(diis_env%buffer_length + 1))
412 tmp1(:) = -1.0_dp*m_b_copy(1, :)/eigenvalues(:)
413 coeff(:) = matmul(m_b_copy, tmp1)
425 IF (diis_env%diis_env_type .EQ. diis_env_dbcsr)
THEN
427 DO im = 1, diis_env%buffer_length
428 CALL dbcsr_add(extr_var, diis_env%m_var(im), &
429 1.0_dp, coeff(im + 1))
430 checksum = checksum + coeff(im + 1)
432 ELSE IF (diis_env%diis_env_type .EQ. diis_env_domain)
THEN
434 d_extr_var(idomain), &
437 DO im = 1, diis_env%buffer_length
439 coeff(im + 1), diis_env%d_var(im, idomain), &
441 checksum = checksum + coeff(im + 1)
452 DEALLOCATE (eigenvalues)
453 DEALLOCATE (m_b_copy)
455 CALL timestop(handle)
Subroutines to handle submatrices.
Types to handle submatrices.