34#include "./base/base_uses.f90"
42 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'qs_ot_minimizer'
63 TYPE(
qs_ot_type),
DIMENSION(:),
POINTER :: qs_ot_env
66 CHARACTER(len=*),
PARAMETER :: routinen =
'ot_mini'
68 INTEGER :: handle, ispin, nspin
69 LOGICAL :: do_ener, do_ks
72 CALL timeset(routinen, handle)
74 nspin =
SIZE(qs_ot_env)
76 do_ks = qs_ot_env(1)%settings%ks
77 do_ener = qs_ot_env(1)%settings%do_ener
79 qs_ot_env(1)%OT_METHOD_FULL =
""
82 IF (.NOT. qs_ot_env(1)%energy_only)
THEN
83 qs_ot_env(1)%gradient = 0.0_dp
86 SELECT CASE (qs_ot_env(1)%settings%ot_algorithm)
89 qs_ot_env(ispin)%matrix_sx, &
90 qs_ot_env(ispin)%matrix_gx, qs_ot_env(ispin))
93 qs_ot_env(ispin)%matrix_x, qs_ot_env(ispin)%matrix_sx, &
94 qs_ot_env(ispin)%matrix_gx, qs_ot_env(ispin))
96 cpabort(
"ALGORITHM NYI")
100 IF (qs_ot_env(1)%use_dx)
THEN
102 CALL dbcsr_dot(qs_ot_env(ispin)%matrix_gx, qs_ot_env(ispin)%matrix_dx, tmp)
103 qs_ot_env(1)%gradient = qs_ot_env(1)%gradient + tmp
104 IF (qs_ot_env(1)%settings%do_rotation)
THEN
105 CALL dbcsr_dot(qs_ot_env(ispin)%rot_mat_gx, qs_ot_env(ispin)%rot_mat_dx, tmp)
106 qs_ot_env(1)%gradient = qs_ot_env(1)%gradient + 0.5_dp*tmp
110 tmp = dot_product(qs_ot_env(ispin)%ener_gx, qs_ot_env(ispin)%ener_dx)
111 qs_ot_env(1)%gradient = qs_ot_env(1)%gradient + tmp
115 CALL dbcsr_dot(qs_ot_env(ispin)%matrix_gx, qs_ot_env(ispin)%matrix_gx, tmp)
116 qs_ot_env(1)%gradient = qs_ot_env(1)%gradient - tmp
117 IF (qs_ot_env(1)%settings%do_rotation)
THEN
118 CALL dbcsr_dot(qs_ot_env(ispin)%rot_mat_gx, qs_ot_env(ispin)%rot_mat_gx, tmp)
119 qs_ot_env(1)%gradient = qs_ot_env(1)%gradient - 0.5_dp*tmp
123 tmp = dot_product(qs_ot_env(ispin)%ener_gx, qs_ot_env(ispin)%ener_gx)
124 qs_ot_env(1)%gradient = qs_ot_env(1)%gradient - tmp
130 SELECT CASE (qs_ot_env(1)%settings%OT_METHOD)
132 IF (current_point_is_fine(qs_ot_env))
THEN
133 qs_ot_env(1)%OT_METHOD_FULL =
"OT CG"
134 CALL ot_new_cg_direction(qs_ot_env)
135 qs_ot_env(1)%line_search_count = 0
137 qs_ot_env(1)%OT_METHOD_FULL =
"OT LS"
139 CALL do_line_search(qs_ot_env)
141 IF (current_point_is_fine(qs_ot_env))
THEN
142 qs_ot_env(1)%OT_METHOD_FULL =
"OT SD"
143 CALL ot_new_sd_direction(qs_ot_env)
144 qs_ot_env(1)%line_search_count = 0
146 qs_ot_env(1)%OT_METHOD_FULL =
"OT LS"
148 CALL do_line_search(qs_ot_env)
150 qs_ot_env(1)%OT_METHOD_FULL =
"OT DIIS"
151 CALL ot_diis_step(qs_ot_env)
153 qs_ot_env(1)%OT_METHOD_FULL =
"OT BROY"
154 CALL ot_broyden_step(qs_ot_env)
156 cpabort(
"OT_METHOD NYI")
159 CALL timestop(handle)
172 FUNCTION current_point_is_fine(qs_ot_env)
RESULT(res)
173 TYPE(
qs_ot_type),
DIMENSION(:),
POINTER :: qs_ot_env
179 IF (.NOT. qs_ot_env(1)%energy_only)
THEN
182 IF (qs_ot_env(1)%line_search_count .EQ. 0)
THEN
187 IF (qs_ot_env(1)%line_search_might_be_done)
THEN
195 END FUNCTION current_point_is_fine
204 SUBROUTINE do_line_search(qs_ot_env)
205 TYPE(
qs_ot_type),
DIMENSION(:),
POINTER :: qs_ot_env
207 SELECT CASE (qs_ot_env(1)%settings%line_search_method)
209 CALL do_line_search_gold(qs_ot_env)
211 CALL do_line_search_3pnt(qs_ot_env)
213 CALL do_line_search_2pnt(qs_ot_env)
215 CALL do_line_search_adapt(qs_ot_env)
217 CALL do_line_search_none(qs_ot_env)
221 END SUBROUTINE do_line_search
230 SUBROUTINE take_step(ds, qs_ot_env)
232 TYPE(
qs_ot_type),
DIMENSION(:),
POINTER :: qs_ot_env
234 CHARACTER(len=*),
PARAMETER :: routinen =
'take_step'
236 INTEGER :: handle, ispin, nspin
237 LOGICAL :: do_ener, do_ks
239 CALL timeset(routinen, handle)
241 nspin =
SIZE(qs_ot_env)
243 do_ks = qs_ot_env(1)%settings%ks
244 do_ener = qs_ot_env(1)%settings%do_ener
248 IF (qs_ot_env(1)%use_dx)
THEN
251 CALL dbcsr_add(qs_ot_env(ispin)%matrix_x, qs_ot_env(ispin)%matrix_dx, &
252 alpha_scalar=1.0_dp, beta_scalar=ds)
253 IF (qs_ot_env(ispin)%settings%do_rotation)
THEN
254 CALL dbcsr_add(qs_ot_env(ispin)%rot_mat_x, qs_ot_env(ispin)%rot_mat_dx, &
255 alpha_scalar=1.0_dp, beta_scalar=ds)
261 qs_ot_env(ispin)%ener_x = qs_ot_env(ispin)%ener_x + ds*qs_ot_env(ispin)%ener_dx
267 CALL dbcsr_add(qs_ot_env(ispin)%matrix_x, qs_ot_env(ispin)%matrix_gx, &
268 alpha_scalar=1.0_dp, beta_scalar=-ds)
269 IF (qs_ot_env(ispin)%settings%do_rotation)
THEN
270 CALL dbcsr_add(qs_ot_env(ispin)%rot_mat_x, qs_ot_env(ispin)%rot_mat_gx, &
271 alpha_scalar=1.0_dp, beta_scalar=-ds)
277 qs_ot_env(ispin)%ener_x = qs_ot_env(ispin)%ener_x - ds*qs_ot_env(ispin)%ener_gx
281 CALL timestop(handle)
282 END SUBROUTINE take_step
289 SUBROUTINE do_line_search_gold(qs_ot_env)
291 TYPE(
qs_ot_type),
DIMENSION(:),
POINTER :: qs_ot_env
293 CHARACTER(len=*),
PARAMETER :: routinen =
'do_line_search_gold'
294 REAL(kind=
dp),
PARAMETER :: gold_sec = 0.3819_dp
296 INTEGER :: count, handle
299 CALL timeset(routinen, handle)
301 qs_ot_env(1)%line_search_count = qs_ot_env(1)%line_search_count + 1
302 count = qs_ot_env(1)%line_search_count
303 qs_ot_env(1)%line_search_might_be_done = .false.
304 qs_ot_env(1)%energy_only = .true.
306 IF (count + 1 .GT.
SIZE(qs_ot_env(1)%OT_pos))
THEN
309 cpabort(
"MAX ITER EXCEEDED : FATAL")
312 IF (qs_ot_env(1)%line_search_count .EQ. 1)
THEN
313 qs_ot_env(1)%line_search_left = 1
314 qs_ot_env(1)%line_search_right = 0
315 qs_ot_env(1)%line_search_mid = 1
316 qs_ot_env(1)%ot_pos(1) = 0.0_dp
317 qs_ot_env(1)%ot_energy(1) = qs_ot_env(1)%etotal
318 qs_ot_env(1)%ot_pos(2) = qs_ot_env(1)%ds_min/gold_sec
320 qs_ot_env(1)%ot_energy(count) = qs_ot_env(1)%etotal
324 IF (qs_ot_env(1)%line_search_right .EQ. 0)
THEN
325 IF (qs_ot_env(1)%ot_energy(count - 1) .LT. qs_ot_env(1)%ot_energy(count))
THEN
326 qs_ot_env(1)%line_search_right = count
327 qs_ot_env(1)%ot_pos(count + 1) = qs_ot_env(1)%ot_pos(qs_ot_env(1)%line_search_mid) + &
328 (qs_ot_env(1)%ot_pos(qs_ot_env(1)%line_search_right) - &
329 qs_ot_env(1)%ot_pos(qs_ot_env(1)%line_search_mid))*gold_sec
331 qs_ot_env(1)%line_search_left = qs_ot_env(1)%line_search_mid
332 qs_ot_env(1)%line_search_mid = count
333 qs_ot_env(1)%ot_pos(count + 1) = qs_ot_env(1)%ot_pos(count)/gold_sec
337 IF (qs_ot_env(1)%ot_pos(count) .LT. qs_ot_env(1)%ot_pos(qs_ot_env(1)%line_search_mid))
THEN
338 IF (qs_ot_env(1)%ot_energy(count) .LT. qs_ot_env(1)%ot_energy(qs_ot_env(1)%line_search_mid))
THEN
339 qs_ot_env(1)%line_search_right = qs_ot_env(1)%line_search_mid
340 qs_ot_env(1)%line_search_mid = count
342 qs_ot_env(1)%line_search_left = count
345 IF (qs_ot_env(1)%ot_energy(count) .LT. qs_ot_env(1)%ot_energy(qs_ot_env(1)%line_search_mid))
THEN
346 qs_ot_env(1)%line_search_left = qs_ot_env(1)%line_search_mid
347 qs_ot_env(1)%line_search_mid = count
349 qs_ot_env(1)%line_search_right = count
353 IF ((qs_ot_env(1)%ot_pos(qs_ot_env(1)%line_search_right) &
354 - qs_ot_env(1)%ot_pos(qs_ot_env(1)%line_search_mid)) .GT. &
355 (qs_ot_env(1)%ot_pos(qs_ot_env(1)%line_search_mid) &
356 - qs_ot_env(1)%ot_pos(qs_ot_env(1)%line_search_left)))
THEN
357 qs_ot_env(1)%ot_pos(count + 1) = &
358 qs_ot_env(1)%ot_pos(qs_ot_env(1)%line_search_mid) + &
359 gold_sec*(qs_ot_env(1)%ot_pos(qs_ot_env(1)%line_search_right) &
360 - qs_ot_env(1)%ot_pos(qs_ot_env(1)%line_search_mid))
362 qs_ot_env(1)%ot_pos(count + 1) = &
363 qs_ot_env(1)%ot_pos(qs_ot_env(1)%line_search_left) + &
364 gold_sec*(qs_ot_env(1)%ot_pos(qs_ot_env(1)%line_search_mid) &
365 - qs_ot_env(1)%ot_pos(qs_ot_env(1)%line_search_left))
368 IF (((qs_ot_env(1)%ot_pos(qs_ot_env(1)%line_search_right) &
369 - qs_ot_env(1)%ot_pos(qs_ot_env(1)%line_search_mid)) .LT. &
370 qs_ot_env(1)%ds_min*qs_ot_env(1)%settings%gold_target) .AND. &
371 ((qs_ot_env(1)%ot_pos(qs_ot_env(1)%line_search_mid) &
372 - qs_ot_env(1)%ot_pos(qs_ot_env(1)%line_search_left)) .LT. &
373 qs_ot_env(1)%ds_min*qs_ot_env(1)%settings%gold_target))
THEN
374 qs_ot_env(1)%energy_only = .false.
375 qs_ot_env(1)%line_search_might_be_done = .true.
379 ds = qs_ot_env(1)%OT_pos(count + 1) - qs_ot_env(1)%OT_pos(count)
380 qs_ot_env(1)%ds_min = qs_ot_env(1)%OT_pos(count + 1)
382 CALL take_step(ds, qs_ot_env)
384 CALL timestop(handle)
386 END SUBROUTINE do_line_search_gold
392 SUBROUTINE do_line_search_3pnt(qs_ot_env)
394 TYPE(
qs_ot_type),
DIMENSION(:),
POINTER :: qs_ot_env
396 CHARACTER(len=*),
PARAMETER :: routinen =
'do_line_search_3pnt'
398 INTEGER :: count, handle
399 REAL(kind=
dp) :: denom, ds, fa, fb, fc, nom, pos, val, &
402 CALL timeset(routinen, handle)
404 qs_ot_env(1)%line_search_might_be_done = .false.
405 qs_ot_env(1)%energy_only = .true.
408 qs_ot_env(1)%line_search_count = qs_ot_env(1)%line_search_count + 1
409 count = qs_ot_env(1)%line_search_count
410 qs_ot_env(1)%ot_energy(count) = qs_ot_env(1)%etotal
413 qs_ot_env(1)%ot_pos(count) = 0.0_dp
414 qs_ot_env(1)%ot_pos(count + 1) = qs_ot_env(1)%ds_min*0.8_dp
416 IF (qs_ot_env(1)%OT_energy(count) .GT. qs_ot_env(1)%OT_energy(count - 1))
THEN
417 qs_ot_env(1)%OT_pos(count + 1) = qs_ot_env(1)%ds_min*0.5_dp
419 qs_ot_env(1)%OT_pos(count + 1) = qs_ot_env(1)%ds_min*1.4_dp
422 xa = qs_ot_env(1)%OT_pos(1)
423 xb = qs_ot_env(1)%OT_pos(2)
424 xc = qs_ot_env(1)%OT_pos(3)
425 fa = qs_ot_env(1)%OT_energy(1)
426 fb = qs_ot_env(1)%OT_energy(2)
427 fc = qs_ot_env(1)%OT_energy(3)
428 nom = (xb - xa)**2*(fb - fc) - (xb -
xc)**2*(fb - fa)
429 denom = (xb - xa)*(fb - fc) - (xb -
xc)*(fb - fa)
430 IF (abs(denom) .LE. 1.0e-18_dp*max(abs(fb - fc), abs(fb - fa)))
THEN
433 pos = xb - 0.5_dp*nom/denom
435 val = (pos - xa)*(pos - xb)*fc/((
xc - xa)*(
xc - xb)) + &
436 (pos - xb)*(pos -
xc)*fa/((xa - xb)*(xa -
xc)) + &
437 (pos -
xc)*(pos - xa)*fb/((xb -
xc)*(xb - xa))
438 IF (val .LT. fa .AND. val .LE. fb .AND. val .LE. fc)
THEN
440 qs_ot_env(1)%OT_pos(count + 1) = max(maxval(qs_ot_env(1)%OT_pos(1:3))*0.01_dp, &
441 min(pos, maxval(qs_ot_env(1)%OT_pos(1:3))*4.0_dp))
443 qs_ot_env(1)%OT_pos(count + 1) = maxval(qs_ot_env(1)%OT_pos(1:3))*2.0_dp
445 qs_ot_env(1)%energy_only = .false.
446 qs_ot_env(1)%line_search_might_be_done = .true.
450 ds = qs_ot_env(1)%OT_pos(count + 1) - qs_ot_env(1)%OT_pos(count)
451 qs_ot_env(1)%ds_min = qs_ot_env(1)%OT_pos(count + 1)
453 CALL take_step(ds, qs_ot_env)
455 CALL timestop(handle)
457 END SUBROUTINE do_line_search_3pnt
463 SUBROUTINE do_line_search_2pnt(qs_ot_env)
465 TYPE(
qs_ot_type),
DIMENSION(:),
POINTER :: qs_ot_env
467 CHARACTER(len=*),
PARAMETER :: routinen =
'do_line_search_2pnt'
469 INTEGER :: count, handle
470 REAL(kind=
dp) :: a, b, c, ds, pos, val, x0, x1
472 CALL timeset(routinen, handle)
474 qs_ot_env(1)%line_search_might_be_done = .false.
475 qs_ot_env(1)%energy_only = .true.
478 qs_ot_env(1)%line_search_count = qs_ot_env(1)%line_search_count + 1
479 count = qs_ot_env(1)%line_search_count
480 qs_ot_env(1)%ot_energy(count) = qs_ot_env(1)%etotal
483 qs_ot_env(1)%ot_pos(count) = 0.0_dp
484 qs_ot_env(1)%ot_grad(count) = qs_ot_env(1)%gradient
485 qs_ot_env(1)%ot_pos(count + 1) = qs_ot_env(1)%ds_min*1.0_dp
488 c = qs_ot_env(1)%ot_energy(1)
489 b = qs_ot_env(1)%ot_grad(1)
490 x1 = qs_ot_env(1)%ot_pos(2)
491 a = (qs_ot_env(1)%ot_energy(2) - b*x1 - c)/(x1**2)
492 IF (a .LE. 0.0_dp) a = 1.0e-15_dp
494 val = a*pos**2 + b*pos + c
495 qs_ot_env(1)%energy_only = .false.
496 qs_ot_env(1)%line_search_might_be_done = .true.
497 IF (val .LT. qs_ot_env(1)%ot_energy(1) .AND. val .LE. qs_ot_env(1)%ot_energy(2))
THEN
500 qs_ot_env(1)%OT_pos(count + 1) = max(maxval(qs_ot_env(1)%OT_pos(1:2))*0.01_dp, &
501 min(pos, maxval(qs_ot_env(1)%OT_pos(1:2))*4.0_dp))
503 qs_ot_env(1)%OT_pos(count + 1) = maxval(qs_ot_env(1)%OT_pos(1:2))*2.0_dp
508 ds = qs_ot_env(1)%OT_pos(count + 1) - qs_ot_env(1)%OT_pos(count)
509 qs_ot_env(1)%ds_min = qs_ot_env(1)%OT_pos(count + 1)
511 CALL take_step(ds, qs_ot_env)
513 CALL timestop(handle)
515 END SUBROUTINE do_line_search_2pnt
521 SUBROUTINE do_line_search_adapt(qs_ot_env)
523 TYPE(
qs_ot_type),
DIMENSION(:),
POINTER :: qs_ot_env
525 CHARACTER(len=*),
PARAMETER :: routinen =
'do_line_search_adapt'
526 REAL(kind=
dp),
PARAMETER :: grow_factor = 2.0_dp, &
527 shrink_factor = 0.5_dp
529 INTEGER :: count, handle, il, im, ir
530 REAL(kind=
dp) :: a, b, c, denom, ds, el, em, er, &
531 step_size, xl, xm, xr
533 CALL timeset(routinen, handle)
535 qs_ot_env(1)%line_search_count = qs_ot_env(1)%line_search_count + 1
536 count = qs_ot_env(1)%line_search_count
537 qs_ot_env(1)%line_search_might_be_done = .false.
538 qs_ot_env(1)%energy_only = .true.
540 IF (count + 1 >
SIZE(qs_ot_env(1)%OT_pos))
THEN
543 cpabort(
"MAX ITER EXCEEDED : FATAL")
547 IF (qs_ot_env(1)%line_search_count == 1)
THEN
548 qs_ot_env(1)%line_search_left = 1
549 qs_ot_env(1)%line_search_right = 0
550 qs_ot_env(1)%line_search_mid = 1
551 qs_ot_env(1)%ot_Pos(1) = 0.0_dp
552 qs_ot_env(1)%ot_energy(1) = qs_ot_env(1)%etotal
553 qs_ot_env(1)%ot_Pos(2) = qs_ot_env(1)%ds_min*grow_factor
555 qs_ot_env(1)%ot_energy(count) = qs_ot_env(1)%etotal
559 IF (qs_ot_env(1)%line_search_right == 0)
THEN
560 IF (qs_ot_env(1)%ot_energy(count - 1) < qs_ot_env(1)%ot_energy(count))
THEN
561 qs_ot_env(1)%line_search_right = count
562 qs_ot_env(1)%ot_Pos(count + 1) = qs_ot_env(1)%ot_Pos(qs_ot_env(1)%line_search_mid) + &
563 (qs_ot_env(1)%ot_Pos(qs_ot_env(1)%line_search_right) - &
564 qs_ot_env(1)%ot_Pos(qs_ot_env(1)%line_search_mid))*shrink_factor
567 qs_ot_env(1)%line_search_left = qs_ot_env(1)%line_search_mid
568 qs_ot_env(1)%line_search_mid = count
569 qs_ot_env(1)%ot_Pos(count + 1) = qs_ot_env(1)%ot_Pos(count)*grow_factor
573 IF (qs_ot_env(1)%ot_pos(count) < qs_ot_env(1)%ot_pos(qs_ot_env(1)%line_search_mid))
THEN
574 IF (qs_ot_env(1)%ot_energy(count) < qs_ot_env(1)%ot_energy(qs_ot_env(1)%line_search_mid))
THEN
575 qs_ot_env(1)%line_search_right = qs_ot_env(1)%line_search_mid
576 qs_ot_env(1)%line_search_mid = count
578 qs_ot_env(1)%line_search_left = count
581 IF (qs_ot_env(1)%ot_energy(count) < qs_ot_env(1)%ot_energy(qs_ot_env(1)%line_search_mid))
THEN
582 qs_ot_env(1)%line_search_left = qs_ot_env(1)%line_search_mid
583 qs_ot_env(1)%line_search_mid = count
585 qs_ot_env(1)%line_search_right = count
588 il = qs_ot_env(1)%line_search_left
589 im = qs_ot_env(1)%line_search_mid
590 ir = qs_ot_env(1)%line_search_right
591 xl = qs_ot_env(1)%OT_pos(il)
592 xm = qs_ot_env(1)%OT_pos(im)
593 xr = qs_ot_env(1)%OT_pos(ir)
594 el = qs_ot_env(1)%ot_energy(il)
595 em = qs_ot_env(1)%ot_energy(im)
596 er = qs_ot_env(1)%ot_energy(ir)
600 qs_ot_env(1)%ot_Pos(count + 1) = qs_ot_env(1)%ot_Pos(ir)*grow_factor
603 denom = (xl - xm)*(xl - xr)*(xm - xr)
604 a = (xr*(em - el) + xm*(el - er) + xl*(er - em))/denom
605 b = (xr**2*(el - em) + xm**2*(er - el) + xl**2*(em - er))/denom
606 c = (xm*xr*(xm - xr)*el + xr*xl*(xr - xl)*em + xr*xm*(xr - xm)*er)/denom
608 IF (abs(a) /= 0.0_dp)
THEN
609 step_size = -b/(2.0_dp*a)
613 cpassert(step_size >= 0.0_dp)
614 qs_ot_env(1)%ot_Pos(count + 1) = step_size
615 qs_ot_env(1)%line_search_might_be_done = .true.
616 qs_ot_env(1)%energy_only = .false.
620 qs_ot_env(1)%ot_Pos(count + 1) = qs_ot_env(1)%ot_Pos(im) + &
621 (qs_ot_env(1)%ot_Pos(ir) - qs_ot_env(1)%ot_Pos(im))*shrink_factor
626 ds = qs_ot_env(1)%OT_pos(count + 1) - qs_ot_env(1)%OT_pos(count)
627 qs_ot_env(1)%ds_min = qs_ot_env(1)%OT_pos(count + 1)
629 CALL take_step(ds, qs_ot_env)
631 CALL timestop(handle)
633 END SUBROUTINE do_line_search_adapt
639 SUBROUTINE do_line_search_none(qs_ot_env)
640 TYPE(
qs_ot_type),
DIMENSION(:),
POINTER :: qs_ot_env
642 CALL take_step(qs_ot_env(1)%ds_min, qs_ot_env)
644 END SUBROUTINE do_line_search_none
655 SUBROUTINE ot_new_sd_direction(qs_ot_env)
656 TYPE(
qs_ot_type),
DIMENSION(:),
POINTER :: qs_ot_env
658 CHARACTER(len=*),
PARAMETER :: routinen =
'ot_new_sd_direction'
660 INTEGER :: handle, ispin, itmp, k, n, nener, nspin
661 LOGICAL :: do_ener, do_ks
665 CALL timeset(routinen, handle)
669 nspin =
SIZE(qs_ot_env)
671 do_ks = qs_ot_env(1)%settings%ks
672 do_ener = qs_ot_env(1)%settings%do_ener
674 IF (
ASSOCIATED(qs_ot_env(1)%preconditioner))
THEN
675 IF (.NOT. qs_ot_env(1)%use_dx) cpabort(
"use dx")
676 qs_ot_env(1)%gnorm = 0.0_dp
680 qs_ot_env(ispin)%matrix_gx, qs_ot_env(ispin)%matrix_dx)
681 CALL dbcsr_dot(qs_ot_env(ispin)%matrix_gx, qs_ot_env(ispin)%matrix_dx, tmp)
682 qs_ot_env(1)%gnorm = qs_ot_env(1)%gnorm + tmp
684 IF (qs_ot_env(1)%gnorm .LT. 0.0_dp)
THEN
689 CALL dbcsr_scale(qs_ot_env(ispin)%matrix_dx, -1.0_dp)
691 IF (qs_ot_env(1)%settings%do_rotation)
THEN
694 CALL dbcsr_copy(qs_ot_env(ispin)%rot_mat_dx, qs_ot_env(ispin)%rot_mat_gx)
695 CALL dbcsr_dot(qs_ot_env(ispin)%rot_mat_gx, qs_ot_env(ispin)%rot_mat_dx, tmp)
697 qs_ot_env(1)%gnorm = qs_ot_env(1)%gnorm + 0.5_dp*tmp
700 CALL dbcsr_scale(qs_ot_env(ispin)%rot_mat_dx, -1.0_dp)
706 qs_ot_env(ispin)%ener_dx = qs_ot_env(ispin)%ener_gx
707 tmp = dot_product(qs_ot_env(ispin)%ener_dx, qs_ot_env(ispin)%ener_gx)
708 qs_ot_env(1)%gnorm = qs_ot_env(1)%gnorm + tmp
709 qs_ot_env(ispin)%ener_dx = -qs_ot_env(ispin)%ener_dx
713 qs_ot_env(1)%gnorm = 0.0_dp
716 CALL dbcsr_dot(qs_ot_env(ispin)%matrix_gx, qs_ot_env(ispin)%matrix_gx, tmp)
717 qs_ot_env(1)%gnorm = qs_ot_env(1)%gnorm + tmp
719 IF (qs_ot_env(1)%settings%do_rotation)
THEN
721 CALL dbcsr_dot(qs_ot_env(ispin)%rot_mat_gx, qs_ot_env(ispin)%rot_mat_gx, tmp)
723 qs_ot_env(1)%gnorm = qs_ot_env(1)%gnorm + 0.5_dp*tmp
729 tmp = dot_product(qs_ot_env(ispin)%ener_gx, qs_ot_env(ispin)%ener_gx)
730 qs_ot_env(1)%gnorm = qs_ot_env(1)%gnorm + tmp
741 CALL dbcsr_get_info(qs_ot_env(ispin)%matrix_x, nfullcols_total=itmp)
747 nener = nener +
SIZE(qs_ot_env(ispin)%ener_x)
751 IF (int(n, kind=
int_8)*int(k, kind=
int_8) + nener /= 0)
THEN
752 qs_ot_env(1)%delta = sqrt(abs(qs_ot_env(1)%gnorm)/(int(n, kind=
int_8)*int(k, kind=
int_8) + nener))
753 qs_ot_env(1)%gradient = -qs_ot_env(1)%gnorm
755 qs_ot_env(1)%delta = 0.0_dp
756 qs_ot_env(1)%gradient = 0.0_dp
759 CALL timestop(handle)
761 END SUBROUTINE ot_new_sd_direction
772 SUBROUTINE ot_new_cg_direction(qs_ot_env)
773 TYPE(
qs_ot_type),
DIMENSION(:),
POINTER :: qs_ot_env
775 CHARACTER(len=*),
PARAMETER :: routinen =
'ot_new_cg_direction'
777 INTEGER :: handle, ispin, itmp, k, n, nener, nspin
778 LOGICAL :: do_ener, do_ks
779 REAL(kind=
dp) :: beta_pr, gnorm_cross, test_down, tmp
782 CALL timeset(routinen, handle)
784 nspin =
SIZE(qs_ot_env)
787 do_ks = qs_ot_env(1)%settings%ks
788 do_ener = qs_ot_env(1)%settings%do_ener
793 CALL dbcsr_dot(qs_ot_env(ispin)%matrix_gx, qs_ot_env(ispin)%matrix_gx_old, tmp)
794 gnorm_cross = gnorm_cross + tmp
796 IF (qs_ot_env(1)%settings%do_rotation)
THEN
798 CALL dbcsr_dot(qs_ot_env(ispin)%rot_mat_gx, qs_ot_env(ispin)%rot_mat_gx_old, tmp)
800 gnorm_cross = gnorm_cross + 0.5_dp*tmp
806 tmp = dot_product(qs_ot_env(ispin)%ener_gx, qs_ot_env(ispin)%ener_gx_old)
807 gnorm_cross = gnorm_cross + tmp
811 IF (
ASSOCIATED(qs_ot_env(1)%preconditioner))
THEN
815 qs_ot_env(ispin)%matrix_gx, qs_ot_env(ispin)%matrix_gx_old)
817 qs_ot_env(1)%gnorm = 0.0_dp
820 CALL dbcsr_dot(qs_ot_env(ispin)%matrix_gx, qs_ot_env(ispin)%matrix_gx_old, tmp)
821 qs_ot_env(1)%gnorm = qs_ot_env(1)%gnorm + tmp
823 IF (qs_ot_env(1)%gnorm .LT. 0.0_dp)
THEN
827 CALL dbcsr_copy(qs_ot_env(ispin)%matrix_gx, qs_ot_env(ispin)%matrix_gx_old)
829 IF (qs_ot_env(1)%settings%do_rotation)
THEN
832 CALL dbcsr_copy(qs_ot_env(ispin)%rot_mat_gx_old, qs_ot_env(ispin)%rot_mat_gx)
833 CALL dbcsr_dot(qs_ot_env(ispin)%rot_mat_gx, qs_ot_env(ispin)%rot_mat_gx_old, tmp)
835 qs_ot_env(1)%gnorm = qs_ot_env(1)%gnorm + 0.5_dp*tmp
838 CALL dbcsr_copy(qs_ot_env(ispin)%rot_mat_gx, qs_ot_env(ispin)%rot_mat_gx_old)
844 qs_ot_env(ispin)%ener_gx_old = qs_ot_env(ispin)%ener_gx
845 tmp = dot_product(qs_ot_env(ispin)%ener_gx, qs_ot_env(ispin)%ener_gx_old)
846 qs_ot_env(1)%gnorm = qs_ot_env(1)%gnorm + tmp
847 qs_ot_env(ispin)%ener_gx = qs_ot_env(ispin)%ener_gx_old
852 qs_ot_env(1)%gnorm = 0.0_dp
854 CALL dbcsr_dot(qs_ot_env(ispin)%matrix_gx, qs_ot_env(ispin)%matrix_gx, tmp)
855 qs_ot_env(1)%gnorm = qs_ot_env(1)%gnorm + tmp
856 CALL dbcsr_copy(qs_ot_env(ispin)%matrix_gx_old, qs_ot_env(ispin)%matrix_gx)
858 IF (qs_ot_env(1)%settings%do_rotation)
THEN
860 CALL dbcsr_dot(qs_ot_env(ispin)%rot_mat_gx, qs_ot_env(ispin)%rot_mat_gx, tmp)
862 qs_ot_env(1)%gnorm = qs_ot_env(1)%gnorm + 0.5_dp*tmp
863 CALL dbcsr_copy(qs_ot_env(ispin)%rot_mat_gx_old, qs_ot_env(ispin)%rot_mat_gx)
869 tmp = dot_product(qs_ot_env(ispin)%ener_gx, qs_ot_env(ispin)%ener_gx)
870 qs_ot_env(1)%gnorm = qs_ot_env(1)%gnorm + tmp
871 qs_ot_env(ispin)%ener_gx_old = qs_ot_env(ispin)%ener_gx
882 CALL dbcsr_get_info(qs_ot_env(ispin)%matrix_x, nfullcols_total=itmp)
888 nener = nener +
SIZE(qs_ot_env(ispin)%ener_x)
892 IF (int(n, kind=
int_8)*int(k, kind=
int_8) + nener /= 0)
THEN
893 qs_ot_env(1)%delta = sqrt(abs(qs_ot_env(1)%gnorm)/(int(n, kind=
int_8)*int(k, kind=
int_8) + nener))
894 beta_pr = (qs_ot_env(1)%gnorm - gnorm_cross)/qs_ot_env(1)%gnorm_old
896 qs_ot_env(1)%delta = 0.0_dp
899 beta_pr = max(beta_pr, 0.0_dp)
904 CALL dbcsr_add(qs_ot_env(ispin)%matrix_dx, qs_ot_env(ispin)%matrix_gx, &
905 alpha_scalar=beta_pr, beta_scalar=-1.0_dp)
906 CALL dbcsr_dot(qs_ot_env(ispin)%matrix_gx, qs_ot_env(ispin)%matrix_dx, tmp)
907 test_down = test_down + tmp
908 IF (qs_ot_env(1)%settings%do_rotation)
THEN
909 CALL dbcsr_add(qs_ot_env(ispin)%rot_mat_dx, qs_ot_env(ispin)%rot_mat_gx, &
910 alpha_scalar=beta_pr, beta_scalar=-1.0_dp)
911 CALL dbcsr_dot(qs_ot_env(ispin)%rot_mat_gx, qs_ot_env(ispin)%rot_mat_dx, tmp)
912 test_down = test_down + 0.5_dp*tmp
918 qs_ot_env(ispin)%ener_dx = beta_pr*qs_ot_env(ispin)%ener_dx - qs_ot_env(ispin)%ener_gx
919 tmp = dot_product(qs_ot_env(ispin)%ener_gx, qs_ot_env(ispin)%ener_dx)
920 test_down = test_down + tmp
924 IF (test_down .GE. 0.0_dp)
THEN
928 CALL dbcsr_add(qs_ot_env(ispin)%matrix_dx, qs_ot_env(ispin)%matrix_gx, &
929 alpha_scalar=beta_pr, beta_scalar=-1.0_dp)
930 IF (qs_ot_env(1)%settings%do_rotation)
THEN
931 CALL dbcsr_add(qs_ot_env(ispin)%rot_mat_dx, &
932 qs_ot_env(ispin)%rot_mat_gx, alpha_scalar=beta_pr, beta_scalar=-1.0_dp)
938 qs_ot_env(ispin)%ener_dx = beta_pr*qs_ot_env(ispin)%ener_dx - qs_ot_env(ispin)%ener_gx
943 qs_ot_env(1)%gradient = beta_pr*qs_ot_env(1)%gradient - qs_ot_env(1)%gnorm
944 qs_ot_env(1)%gnorm_old = qs_ot_env(1)%gnorm
946 CALL timestop(handle)
948 END SUBROUTINE ot_new_cg_direction
954 SUBROUTINE ot_diis_step(qs_ot_env)
955 TYPE(
qs_ot_type),
DIMENSION(:),
POINTER :: qs_ot_env
957 CHARACTER(len=*),
PARAMETER :: routinen =
'ot_diis_step'
959 INTEGER :: diis_bound, diis_m, handle, i, info, &
960 ispin, itmp, j, k, n, nener, nspin
961 LOGICAL :: do_ener, do_ks, do_ot_sd
962 REAL(kind=
dp) :: overlap, tmp, tr_xnew_gx, tr_xold_gx
965 CALL timeset(routinen, handle)
969 do_ks = qs_ot_env(1)%settings%ks
970 do_ener = qs_ot_env(1)%settings%do_ener
971 nspin =
SIZE(qs_ot_env)
973 diis_m = qs_ot_env(1)%settings%diis_m
975 IF (qs_ot_env(1)%diis_iter .LT. diis_m)
THEN
976 diis_bound = qs_ot_env(1)%diis_iter + 1
981 j = mod(qs_ot_env(1)%diis_iter, diis_m) + 1
987 CALL dbcsr_copy(qs_ot_env(ispin)%matrix_h_x(j)%matrix, qs_ot_env(ispin)%matrix_x)
988 IF (qs_ot_env(ispin)%settings%do_rotation)
THEN
989 CALL dbcsr_copy(qs_ot_env(ispin)%rot_mat_h_x(j)%matrix, qs_ot_env(ispin)%rot_mat_x)
995 qs_ot_env(ispin)%ener_h_x(j, :) = qs_ot_env(ispin)%ener_x(:)
998 IF (
ASSOCIATED(qs_ot_env(1)%preconditioner))
THEN
999 qs_ot_env(1)%gnorm = 0.0_dp
1003 qs_ot_env(ispin)%matrix_gx, qs_ot_env(ispin)%matrix_h_e(j)%matrix)
1004 CALL dbcsr_dot(qs_ot_env(ispin)%matrix_gx, qs_ot_env(ispin)%matrix_h_e(j)%matrix, &
1006 qs_ot_env(1)%gnorm = qs_ot_env(1)%gnorm + tmp
1008 IF (qs_ot_env(1)%gnorm .LT. 0.0_dp)
THEN
1012 CALL dbcsr_scale(qs_ot_env(ispin)%matrix_h_e(j)%matrix, -qs_ot_env(1)%ds_min)
1014 IF (qs_ot_env(1)%settings%do_rotation)
THEN
1016 CALL dbcsr_copy(qs_ot_env(ispin)%rot_mat_h_e(j)%matrix, qs_ot_env(ispin)%rot_mat_gx)
1017 CALL dbcsr_dot(qs_ot_env(ispin)%rot_mat_gx, qs_ot_env(ispin)%rot_mat_h_e(j)%matrix, &
1019 qs_ot_env(1)%gnorm = qs_ot_env(1)%gnorm + 0.5_dp*tmp
1022 CALL dbcsr_scale(qs_ot_env(ispin)%rot_mat_h_e(j)%matrix, -qs_ot_env(1)%ds_min)
1028 qs_ot_env(ispin)%ener_h_e(j, :) = qs_ot_env(ispin)%ener_gx(:)
1029 tmp = dot_product(qs_ot_env(ispin)%ener_h_e(j, :), qs_ot_env(ispin)%ener_gx(:))
1030 qs_ot_env(1)%gnorm = qs_ot_env(1)%gnorm + tmp
1031 qs_ot_env(ispin)%ener_h_e(j, :) = -qs_ot_env(1)%ds_min*qs_ot_env(ispin)%ener_h_e(j, :)
1035 qs_ot_env(1)%gnorm = 0.0_dp
1038 CALL dbcsr_dot(qs_ot_env(ispin)%matrix_gx, qs_ot_env(ispin)%matrix_gx, tmp)
1039 qs_ot_env(1)%gnorm = qs_ot_env(1)%gnorm + tmp
1040 CALL dbcsr_add(qs_ot_env(ispin)%matrix_h_e(j)%matrix, &
1041 qs_ot_env(ispin)%matrix_gx, alpha_scalar=0.0_dp, beta_scalar=-qs_ot_env(1)%ds_min)
1043 IF (qs_ot_env(1)%settings%do_rotation)
THEN
1045 CALL dbcsr_dot(qs_ot_env(ispin)%rot_mat_gx, qs_ot_env(ispin)%rot_mat_gx, tmp)
1046 qs_ot_env(1)%gnorm = qs_ot_env(1)%gnorm + 0.5_dp*tmp
1047 CALL dbcsr_add(qs_ot_env(ispin)%rot_mat_h_e(j)%matrix, &
1048 qs_ot_env(ispin)%rot_mat_gx, alpha_scalar=0.0_dp, beta_scalar=-qs_ot_env(1)%ds_min)
1054 tmp = dot_product(qs_ot_env(ispin)%ener_gx(:), qs_ot_env(ispin)%ener_gx(:))
1055 qs_ot_env(1)%gnorm = qs_ot_env(1)%gnorm + tmp
1056 qs_ot_env(ispin)%ener_h_e(j, :) = -qs_ot_env(1)%ds_min*qs_ot_env(ispin)%ener_gx(:)
1066 CALL dbcsr_get_info(qs_ot_env(ispin)%matrix_x, nfullcols_total=itmp)
1072 nener = nener +
SIZE(qs_ot_env(ispin)%ener_x)
1076 IF (int(n, kind=
int_8)*int(k, kind=
int_8) + nener /= 0)
THEN
1077 qs_ot_env(1)%delta = sqrt(abs(qs_ot_env(1)%gnorm)/(int(n, kind=
int_8)*int(k, kind=
int_8) + nener))
1078 qs_ot_env(1)%gradient = -qs_ot_env(1)%gnorm
1080 qs_ot_env(1)%delta = 0.0_dp
1081 qs_ot_env(1)%gradient = 0.0_dp
1085 DO i = 1, diis_bound
1091 qs_ot_env(1)%ls_diis(i, j) = 0.0_dp
1094 CALL dbcsr_dot(qs_ot_env(ispin)%matrix_h_e(j)%matrix, &
1095 qs_ot_env(ispin)%matrix_h_e(i)%matrix, &
1097 qs_ot_env(1)%ls_diis(i, j) = qs_ot_env(1)%ls_diis(i, j) + tmp
1098 IF (qs_ot_env(ispin)%settings%do_rotation)
THEN
1099 CALL dbcsr_dot(qs_ot_env(ispin)%rot_mat_h_e(j)%matrix, &
1100 qs_ot_env(ispin)%rot_mat_h_e(i)%matrix, &
1102 qs_ot_env(1)%ls_diis(i, j) = qs_ot_env(1)%ls_diis(i, j) + 0.5_dp*tmp
1108 tmp = dot_product(qs_ot_env(ispin)%ener_h_e(j, :), qs_ot_env(ispin)%ener_h_e(i, :))
1109 qs_ot_env(1)%ls_diis(i, j) = qs_ot_env(1)%ls_diis(i, j) + tmp
1113 qs_ot_env(1)%ls_diis(i, j) = 0.0_dp
1116 CALL dbcsr_dot(qs_ot_env(ispin)%matrix_gx, &
1117 qs_ot_env(ispin)%matrix_h_e(i)%matrix, &
1119 qs_ot_env(1)%ls_diis(i, j) = qs_ot_env(1)%ls_diis(i, j) - qs_ot_env(1)%ds_min*tmp
1120 IF (qs_ot_env(ispin)%settings%do_rotation)
THEN
1121 CALL dbcsr_dot(qs_ot_env(ispin)%rot_mat_gx, &
1122 qs_ot_env(ispin)%rot_mat_h_e(i)%matrix, &
1124 qs_ot_env(1)%ls_diis(i, j) = qs_ot_env(1)%ls_diis(i, j) - qs_ot_env(1)%ds_min*0.5_dp*tmp
1130 tmp = dot_product(qs_ot_env(ispin)%ener_gx(:), qs_ot_env(ispin)%ener_h_e(i, :))
1131 qs_ot_env(1)%ls_diis(i, j) = qs_ot_env(1)%ls_diis(i, j) - qs_ot_env(1)%ds_min*tmp
1135 qs_ot_env(1)%ls_diis(j, i) = qs_ot_env(1)%ls_diis(i, j)
1136 qs_ot_env(1)%ls_diis(i, diis_bound + 1) = 1.0_dp
1137 qs_ot_env(1)%ls_diis(diis_bound + 1, i) = 1.0_dp
1138 qs_ot_env(1)%c_diis(i) = 0.0_dp
1140 qs_ot_env(1)%ls_diis(diis_bound + 1, diis_bound + 1) = 0.0_dp
1141 qs_ot_env(1)%c_diis(diis_bound + 1) = 1.0_dp
1143 qs_ot_env(1)%lss_diis = qs_ot_env(1)%ls_diis
1145 CALL dgesv(diis_bound + 1, 1, qs_ot_env(1)%lss_diis, diis_m + 1, qs_ot_env(1)%ipivot, &
1146 qs_ot_env(1)%c_diis, diis_m + 1, info)
1148 IF (info .NE. 0)
THEN
1156 CALL dbcsr_set(qs_ot_env(ispin)%matrix_x, 0.0_dp)
1157 DO i = 1, diis_bound
1158 CALL dbcsr_add(qs_ot_env(ispin)%matrix_x, &
1159 qs_ot_env(ispin)%matrix_h_e(i)%matrix, &
1160 alpha_scalar=1.0_dp, beta_scalar=qs_ot_env(1)%c_diis(i))
1162 DO i = 1, diis_bound
1163 CALL dbcsr_add(qs_ot_env(ispin)%matrix_x, &
1164 qs_ot_env(ispin)%matrix_h_x(i)%matrix, &
1165 alpha_scalar=1.0_dp, beta_scalar=qs_ot_env(1)%c_diis(i))
1167 IF (qs_ot_env(ispin)%settings%do_rotation)
THEN
1168 CALL dbcsr_set(qs_ot_env(ispin)%rot_mat_x, 0.0_dp)
1169 DO i = 1, diis_bound
1170 CALL dbcsr_add(qs_ot_env(ispin)%rot_mat_x, &
1171 qs_ot_env(ispin)%rot_mat_h_e(i)%matrix, &
1172 alpha_scalar=1.0_dp, beta_scalar=qs_ot_env(1)%c_diis(i))
1174 DO i = 1, diis_bound
1175 CALL dbcsr_add(qs_ot_env(ispin)%rot_mat_x, &
1176 qs_ot_env(ispin)%rot_mat_h_x(i)%matrix, &
1177 alpha_scalar=1.0_dp, beta_scalar=qs_ot_env(1)%c_diis(i))
1184 qs_ot_env(ispin)%ener_x(:) = 0.0_dp
1185 DO i = 1, diis_bound
1186 qs_ot_env(ispin)%ener_x(:) = qs_ot_env(ispin)%ener_x(:) &
1187 + qs_ot_env(1)%c_diis(i)*qs_ot_env(ispin)%ener_h_e(i, :)
1189 DO i = 1, diis_bound
1190 qs_ot_env(ispin)%ener_x(:) = qs_ot_env(ispin)%ener_x(:) &
1191 + qs_ot_env(1)%c_diis(i)*qs_ot_env(ispin)%ener_h_x(i, :)
1195 qs_ot_env(1)%diis_iter = qs_ot_env(1)%diis_iter + 1
1196 IF (qs_ot_env(1)%settings%safer_diis)
THEN
1204 CALL dbcsr_dot(qs_ot_env(ispin)%matrix_h_x(j)%matrix, &
1205 qs_ot_env(ispin)%matrix_gx, tmp)
1206 tr_xold_gx = tr_xold_gx + tmp
1207 CALL dbcsr_dot(qs_ot_env(ispin)%matrix_x, &
1208 qs_ot_env(ispin)%matrix_gx, tmp)
1209 tr_xnew_gx = tr_xnew_gx + tmp
1210 IF (qs_ot_env(ispin)%settings%do_rotation)
THEN
1211 CALL dbcsr_dot(qs_ot_env(ispin)%rot_mat_h_x(j)%matrix, &
1212 qs_ot_env(ispin)%rot_mat_gx, tmp)
1213 tr_xold_gx = tr_xold_gx + 0.5_dp*tmp
1214 CALL dbcsr_dot(qs_ot_env(ispin)%rot_mat_x, &
1215 qs_ot_env(ispin)%rot_mat_gx, tmp)
1216 tr_xnew_gx = tr_xnew_gx + 0.5_dp*tmp
1222 tmp = dot_product(qs_ot_env(ispin)%ener_h_x(j, :), qs_ot_env(ispin)%ener_gx(:))
1223 tr_xold_gx = tr_xold_gx + tmp
1224 tmp = dot_product(qs_ot_env(ispin)%ener_x(:), qs_ot_env(ispin)%ener_gx(:))
1225 tr_xnew_gx = tr_xnew_gx + tmp
1228 overlap = (tr_xnew_gx - tr_xold_gx)
1230 IF (overlap .GT. 0.0_dp)
THEN
1237 qs_ot_env(1)%OT_METHOD_FULL =
"OT SD"
1240 CALL dbcsr_set(qs_ot_env(ispin)%matrix_x, 0.0_dp)
1241 CALL dbcsr_add(qs_ot_env(ispin)%matrix_x, &
1242 qs_ot_env(ispin)%matrix_h_e(j)%matrix, &
1244 CALL dbcsr_add(qs_ot_env(ispin)%matrix_x, &
1245 qs_ot_env(ispin)%matrix_h_x(j)%matrix, &
1247 IF (qs_ot_env(ispin)%settings%do_rotation)
THEN
1248 CALL dbcsr_set(qs_ot_env(ispin)%rot_mat_x, 0.0_dp)
1249 CALL dbcsr_add(qs_ot_env(ispin)%rot_mat_x, &
1250 qs_ot_env(ispin)%rot_mat_h_e(j)%matrix, &
1252 CALL dbcsr_add(qs_ot_env(ispin)%rot_mat_x, &
1253 qs_ot_env(ispin)%rot_mat_h_x(j)%matrix, &
1260 qs_ot_env(ispin)%ener_x(:) = 0._dp
1261 qs_ot_env(ispin)%ener_x(:) = qs_ot_env(ispin)%ener_x(:) + qs_ot_env(ispin)%ener_h_e(j, :)
1262 qs_ot_env(ispin)%ener_x(:) = qs_ot_env(ispin)%ener_x(:) + qs_ot_env(ispin)%ener_h_x(j, :)
1267 CALL timestop(handle)
1269 END SUBROUTINE ot_diis_step
1276 SUBROUTINE ot_broyden_step(qs_ot_env)
1277 TYPE(
qs_ot_type),
DIMENSION(:),
POINTER :: qs_ot_env
1279 INTEGER :: diis_bound, diis_m, i, ispin, itmp, j, &
1281 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: circ_index
1282 LOGICAL :: adaptive_sigma, do_ener, do_ks, &
1283 enable_flip, forget_history
1284 REAL(kind=
dp) :: beta, eta,
gamma, omega, sigma, &
1285 sigma_dec, sigma_min, tmp, tmp2
1286 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: f, x
1287 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: g, s
1290 eta = qs_ot_env(1)%settings%broyden_eta
1291 omega = qs_ot_env(1)%settings%broyden_omega
1292 sigma_dec = qs_ot_env(1)%settings%broyden_sigma_decrease
1293 sigma_min = qs_ot_env(1)%settings%broyden_sigma_min
1294 forget_history = qs_ot_env(1)%settings%broyden_forget_history
1295 adaptive_sigma = qs_ot_env(1)%settings%broyden_adaptive_sigma
1296 enable_flip = qs_ot_env(1)%settings%broyden_enable_flip
1298 do_ks = qs_ot_env(1)%settings%ks
1299 do_ener = qs_ot_env(1)%settings%do_ener
1301 beta = qs_ot_env(1)%settings%broyden_beta
1302 gamma = qs_ot_env(1)%settings%broyden_gamma
1303 IF (adaptive_sigma)
THEN
1304 IF (qs_ot_env(1)%broyden_adaptive_sigma .LT. 0.0_dp)
THEN
1305 sigma = qs_ot_env(1)%settings%broyden_sigma
1307 sigma = qs_ot_env(1)%broyden_adaptive_sigma
1310 sigma = qs_ot_env(1)%settings%broyden_sigma
1314 IF (do_ener .OR. .NOT. do_ks .OR. qs_ot_env(1)%settings%do_rotation)
THEN
1315 cpabort(
"Not yet implemented")
1318 nspin =
SIZE(qs_ot_env)
1320 diis_m = qs_ot_env(1)%settings%diis_m
1322 IF (qs_ot_env(1)%diis_iter .LT. diis_m)
THEN
1323 diis_bound = qs_ot_env(1)%diis_iter + 1
1329 k = 2*diis_bound + 1
1334 ALLOCATE (circ_index(diis_bound))
1341 j = mod(qs_ot_env(1)%diis_iter, diis_m) + 1
1344 CALL dbcsr_copy(qs_ot_env(ispin)%matrix_h_x(j)%matrix, qs_ot_env(ispin)%matrix_x)
1347 IF (
ASSOCIATED(qs_ot_env(1)%preconditioner))
THEN
1348 qs_ot_env(1)%gnorm = 0.0_dp
1351 qs_ot_env(ispin)%matrix_gx, qs_ot_env(ispin)%matrix_h_e(j)%matrix)
1352 CALL dbcsr_dot(qs_ot_env(ispin)%matrix_gx, qs_ot_env(ispin)%matrix_h_e(j)%matrix, &
1354 qs_ot_env(1)%gnorm = qs_ot_env(1)%gnorm + tmp
1356 IF (qs_ot_env(1)%gnorm .LT. 0.0_dp)
THEN
1360 CALL dbcsr_scale(qs_ot_env(ispin)%matrix_h_e(j)%matrix, -1.0_dp)
1363 qs_ot_env(1)%gnorm = 0.0_dp
1365 CALL dbcsr_dot(qs_ot_env(ispin)%matrix_gx, qs_ot_env(ispin)%matrix_gx, tmp)
1366 qs_ot_env(1)%gnorm = qs_ot_env(1)%gnorm + tmp
1367 CALL dbcsr_add(qs_ot_env(ispin)%matrix_h_e(j)%matrix, &
1368 qs_ot_env(ispin)%matrix_gx, alpha_scalar=0.0_dp, beta_scalar=-1.0_dp)
1376 CALL dbcsr_get_info(qs_ot_env(ispin)%matrix_x, nfullcols_total=itmp)
1381 IF (int(n, kind=
int_8)*int(k, kind=
int_8) /= 0)
THEN
1382 qs_ot_env(1)%delta = sqrt(abs(qs_ot_env(1)%gnorm)/(int(n, kind=
int_8)*int(k, kind=
int_8)))
1383 qs_ot_env(1)%gradient = -qs_ot_env(1)%gnorm
1385 qs_ot_env(1)%delta = 0.0_dp
1386 qs_ot_env(1)%gradient = 0.0_dp
1389 IF (diis_bound == diis_m)
THEN
1390 DO i = 1, diis_bound
1391 circ_index(i) = mod(j + i - 1, diis_m) + 1
1394 DO i = 1, diis_bound
1402 DO i = 1, diis_bound
1404 qs_ot_env(ispin)%matrix_h_x(circ_index(i))%matrix, &
1405 qs_ot_env(ispin)%matrix_h_x(circ_index(i))%matrix, tmp)
1406 s(i, i) = s(i, i) + tmp
1408 qs_ot_env(ispin)%matrix_h_e(circ_index(i))%matrix, &
1409 qs_ot_env(ispin)%matrix_h_e(circ_index(i))%matrix, tmp)
1410 s(i + diis_bound, i + diis_bound) = s(i + diis_bound, i + diis_bound) + tmp
1412 qs_ot_env(ispin)%matrix_h_x(circ_index(i))%matrix, &
1413 qs_ot_env(ispin)%matrix_x, tmp)
1414 s(i, 2*diis_bound + 1) = s(i, 2*diis_bound + 1) + tmp
1415 s(i, 2*diis_bound + 1) = s(2*diis_bound + 1, i)
1417 qs_ot_env(ispin)%matrix_h_e(circ_index(i))%matrix, &
1418 qs_ot_env(ispin)%matrix_x, tmp)
1419 s(i + diis_bound, 2*diis_bound + 1) = s(i + diis_bound, 2*diis_bound + 1) + tmp
1420 s(i + diis_bound, 2*diis_bound + 1) = s(2*diis_bound + 1, diis_bound + i)
1421 DO k = (i + 1), diis_bound
1423 qs_ot_env(ispin)%matrix_h_x(circ_index(i))%matrix, &
1424 qs_ot_env(ispin)%matrix_h_x(circ_index(k))%matrix, &
1426 s(i, k) = s(i, k) + tmp
1429 qs_ot_env(ispin)%matrix_h_e(circ_index(i))%matrix, &
1430 qs_ot_env(ispin)%matrix_h_e(circ_index(k))%matrix, &
1432 s(diis_bound + i, diis_bound + k) = s(diis_bound + i, diis_bound + k) + tmp
1433 s(diis_bound + k, diis_bound + i) = s(diis_bound + i, diis_bound + k)
1435 DO k = 1, diis_bound
1437 qs_ot_env(ispin)%matrix_h_x(circ_index(i))%matrix, &
1438 qs_ot_env(ispin)%matrix_h_e(circ_index(k))%matrix, tmp)
1439 s(i, k + diis_bound) = s(i, k + diis_bound) + tmp
1440 s(k + diis_bound, i) = s(i, k + diis_bound)
1443 CALL dbcsr_dot(qs_ot_env(ispin)%matrix_x, qs_ot_env(ispin)%matrix_x, tmp)
1444 s(2*diis_bound + 1, 2*diis_bound + 1) = s(2*diis_bound + 1, 2*diis_bound + 1) + tmp
1448 k = 2*diis_bound + 1
1450 s(k, :) = s(k, :)/tmp
1451 s(:, k) = s(:, k)/tmp
1453 IF (diis_bound .GT. 1)
THEN
1460 qs_ot_env(ispin)%matrix_h_x(circ_index(i))%matrix, &
1461 qs_ot_env(ispin)%matrix_h_e(circ_index(i))%matrix, &
1465 qs_ot_env(ispin)%matrix_h_x(circ_index(i - 1))%matrix, &
1466 qs_ot_env(ispin)%matrix_h_e(circ_index(i))%matrix, &
1470 qs_ot_env(ispin)%matrix_h_x(circ_index(i))%matrix, &
1471 qs_ot_env(ispin)%matrix_h_e(circ_index(i - 1))%matrix, &
1475 qs_ot_env(ispin)%matrix_h_x(circ_index(i - 1))%matrix, &
1476 qs_ot_env(ispin)%matrix_h_e(circ_index(i - 1))%matrix, &
1480 qs_ot_env(1)%c_broy(i - 1) = tmp2
1483 qs_ot_env(1)%energy_h(j) = qs_ot_env(1)%etotal
1486 i = minloc(qs_ot_env(1)%energy_h(1:diis_bound), dim=1)
1488 sigma = sigma_dec*sigma
1489 qs_ot_env(1)%OT_METHOD_FULL =
"OT BTRK"
1491 CALL dbcsr_set(qs_ot_env(ispin)%matrix_x, 0.0_dp)
1492 CALL dbcsr_add(qs_ot_env(ispin)%matrix_x, &
1493 qs_ot_env(ispin)%matrix_h_x(i)%matrix, &
1494 alpha_scalar=1.0_dp, beta_scalar=(1.0_dp -
gamma))
1495 CALL dbcsr_add(qs_ot_env(ispin)%matrix_x, &
1496 qs_ot_env(ispin)%matrix_h_x(circ_index(diis_bound))%matrix, &
1497 alpha_scalar=1.0_dp, beta_scalar=
gamma)
1501 DO i = 2, diis_bound
1508 f(diis_bound + i) = 1.0
1509 f(diis_bound + i - 1) = -1.0
1512 IF (enable_flip)
THEN
1513 IF (qs_ot_env(1)%c_broy(i - 1) .GT. 0)
THEN
1520 x(:) = tmp*x - matmul(g, f)
1523 tmp = dot_product(f, matmul(s, f))
1525 f(:) = matmul(s, f)/tmp
1527 g(:, :) = g + spread(x, dim=2, ncopies=
SIZE(f))*spread(f, dim=1, ncopies=
SIZE(x))
1530 f(2*diis_bound) = 1.0_dp
1531 x(:) = -beta*matmul(g, f)
1535 CALL dbcsr_set(qs_ot_env(ispin)%matrix_x, 0.0_dp)
1536 DO i = 1, diis_bound
1537 CALL dbcsr_add(qs_ot_env(ispin)%matrix_x, &
1538 qs_ot_env(ispin)%matrix_h_e(circ_index(i))%matrix, &
1539 alpha_scalar=1.0_dp, beta_scalar=-x(i + diis_bound))
1541 DO i = 1, diis_bound
1542 CALL dbcsr_add(qs_ot_env(ispin)%matrix_x, &
1543 qs_ot_env(ispin)%matrix_h_x(circ_index(i))%matrix, &
1544 alpha_scalar=1.0_dp, beta_scalar=x(i))
1548 IF (adaptive_sigma)
THEN
1549 tmp = new_sigma(g, s, diis_bound)
1552 sigma = min(omega*sigma, tmp)
1558 CALL dbcsr_dot(qs_ot_env(ispin)%matrix_gx, &
1559 qs_ot_env(ispin)%matrix_x, &
1567 IF (tmp .GE. 0.0_dp)
THEN
1568 qs_ot_env(1)%OT_METHOD_FULL =
"OT TURN"
1569 IF (forget_history)
THEN
1570 qs_ot_env(1)%diis_iter = 0
1572 sigma = sigma*sigma_dec
1573 CALL dbcsr_add(qs_ot_env(ispin)%matrix_x, &
1574 qs_ot_env(ispin)%matrix_h_x(circ_index(diis_bound))%matrix, &
1575 alpha_scalar=-1.0_dp, beta_scalar=1.0_dp)
1577 CALL dbcsr_add(qs_ot_env(ispin)%matrix_x, &
1578 qs_ot_env(ispin)%matrix_h_x(circ_index(diis_bound))%matrix, &
1579 alpha_scalar=1.0_dp, beta_scalar=1.0_dp)
1585 DEALLOCATE (s, g, f, x, circ_index)
1588 qs_ot_env(1)%diis_iter = qs_ot_env(1)%diis_iter + 1
1589 qs_ot_env(1)%broyden_adaptive_sigma = max(sigma, sigma_min)
1591 END SUBROUTINE ot_broyden_step
1600 FUNCTION new_sigma(G, S, n)
RESULT(sigma)
1606 REAL(kind=
dp),
DIMENSION(:, :) :: g, s
1608 REAL(kind=
dp) :: sigma
1610 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: eigv
1611 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: h
1614 CALL hess_g(g, s, h, n)
1621 sigma = sum(abs(eigv**2))/sum(abs(eigv))
1624 sigma = sum(abs(eigv))/max(1,
SIZE(eigv))
1627 sigma = (maxval(abs(eigv)) + minval(abs(eigv)))*0.5_dp
1630 DEALLOCATE (h, eigv)
1631 END FUNCTION new_sigma
1640 SUBROUTINE hess_g(G, S, H, n)
1647 REAL(kind=
dp),
DIMENSION(:, :) :: g, s, h
1651 REAL(kind=
dp) :: tmp
1652 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: v
1653 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: q
1663 tmp = sqrt(dot_product(q(:, 1), matmul(s, q(:, 1))))
1664 q(:, :) = q(:, :)/tmp
1667 v(:) = matmul(g, q(:, i))
1669 h(j, i) = dot_product(q(:, j), matmul(s, v))
1670 v(:) = v - h(j, i)*q(:, j)
1673 tmp = dot_product(v, matmul(s, v))
1674 IF (tmp .LE. 0.0_dp)
THEN
1680 IF (abs(tmp) .LT. 1e-9_dp)
THEN
1685 q(:, i + 1) = v/h(i + 1, i)
1690 END SUBROUTINE hess_g
subroutine, public dbcsr_scale(matrix, alpha_scalar)
...
subroutine, public dbcsr_copy(matrix_b, matrix_a, name, keep_sparsity, keep_imaginary)
...
subroutine, public dbcsr_get_info(matrix, nblkrows_total, nblkcols_total, nfullrows_total, nfullcols_total, nblkrows_local, nblkcols_local, nfullrows_local, nfullcols_local, my_prow, my_pcol, local_rows, local_cols, proc_row_dist, proc_col_dist, row_blk_size, col_blk_size, row_blk_offset, col_blk_offset, distribution, name, matrix_type, group)
...
subroutine, public dbcsr_set(matrix, alpha)
...
subroutine, public dbcsr_add(matrix_a, matrix_b, alpha_scalar, beta_scalar)
...
subroutine, public dbcsr_init_random(matrix, keep_sparsity)
Fills the given matrix with random numbers.
subroutine, public dbcsr_dot(matrix_a, matrix_b, trace)
Computes the dot product of two matrices, also known as the trace of their matrix product.
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
Calculation of the incomplete Gamma function F_n(t) for multi-center integrals over Cartesian Gaussia...
Defines the basic variable types.
integer, parameter, public int_8
integer, parameter, public dp
Collection of simple mathematical functions and subroutines.
subroutine, public diamat_all(a, eigval, dac)
Diagonalize the symmetric n by n matrix a using the LAPACK library. Only the upper triangle of matrix...
computes preconditioners, and implements methods to apply them currently used in qs_ot
subroutine, public ot_mini(qs_ot_env, matrix_hc)
...
subroutine, public qs_ot_get_derivative_ref(matrix_hc, matrix_x, matrix_sx, matrix_gx, qs_ot_env)
...
subroutine, public qs_ot_get_derivative(matrix_hc, matrix_x, matrix_sx, matrix_gx, qs_ot_env)
this routines computes dE/dx=dx, with dx ortho to sc0 needs dE/dC=hc,C0,X,SX,p if preconditioned it w...
Exchange and Correlation functional calculations.
type of a logger, at the moment it contains just a print level starting at which level it should be l...