72 matrix_c_fm, preconditioner, eps_gradient, &
73 iter_max, size_ortho_space, silent, ot_settings)
75 TYPE(
dbcsr_type),
POINTER :: matrix_h, matrix_s
76 TYPE(
cp_fm_type),
INTENT(IN),
OPTIONAL :: matrix_orthogonal_space_fm
79 REAL(kind=
dp) :: eps_gradient
80 INTEGER,
INTENT(IN) :: iter_max
81 INTEGER,
INTENT(IN),
OPTIONAL :: size_ortho_space
82 LOGICAL,
INTENT(IN),
OPTIONAL :: silent
85 CHARACTER(len=*),
PARAMETER :: routinen =
'ot_eigensolver'
86 INTEGER,
PARAMETER :: max_iter_inner_loop = 40
87 REAL(kind=
dp),
PARAMETER :: rone = 1.0_dp, rzero = 0.0_dp
89 INTEGER :: handle, ieigensolver, iter_total, k, n, &
90 ortho_k, ortho_space_k, output_unit
91 LOGICAL :: energy_only, my_silent, ortho
92 REAL(kind=
dp) :: delta, energy
94 TYPE(
dbcsr_type),
POINTER :: matrix_buf1_ortho, matrix_buf2_ortho, &
95 matrix_c, matrix_orthogonal_space, &
96 matrix_os_ortho, matrix_s_ortho
97 TYPE(
qs_ot_type),
DIMENSION(:),
POINTER :: qs_ot_env
99 CALL timeset(routinen, handle)
103 IF (
PRESENT(silent))
THEN
121 NULLIFY (matrix_s_ortho)
122 NULLIFY (matrix_os_ortho)
123 NULLIFY (matrix_buf1_ortho)
124 NULLIFY (matrix_buf2_ortho)
125 NULLIFY (matrix_orthogonal_space)
127 ALLOCATE (qs_ot_env(1))
128 ALLOCATE (matrix_hc(1))
129 NULLIFY (matrix_hc(1)%matrix)
131 CALL dbcsr_copy(matrix_hc(1)%matrix, matrix_c,
'matrix_hc')
134 IF (
PRESENT(matrix_orthogonal_space_fm)) ortho = .true.
137 IF (
PRESENT(ot_settings))
THEN
138 qs_ot_env(1)%settings = ot_settings
142 qs_ot_env(1)%settings%ds_min = 0.10_dp
146 ALLOCATE (matrix_orthogonal_space)
148 CALL cp_fm_get_info(matrix_orthogonal_space_fm, ncol_global=ortho_space_k)
150 IF (
PRESENT(size_ortho_space)) ortho_space_k = size_ortho_space
151 ortho_k = ortho_space_k + k
157 CALL qs_ot_allocate(qs_ot_env(1), matrix_s, matrix_c_fm%matrix_struct, ortho_k=ortho_k)
163 CALL dbcsr_copy(matrix_s_ortho, matrix_orthogonal_space, name=
"matrix_s_ortho")
167 sym=dbcsr_type_no_symmetry)
171 sym=dbcsr_type_no_symmetry)
175 sym=dbcsr_type_no_symmetry)
177 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, matrix_s, matrix_orthogonal_space, &
178 0.0_dp, matrix_s_ortho)
179 CALL dbcsr_multiply(
'T',
'N', rone, matrix_s_ortho, matrix_s_ortho, &
180 rzero, matrix_os_ortho)
183 para_env=qs_ot_env(1)%para_env, blacs_env=qs_ot_env(1)%blacs_env)
185 para_env=qs_ot_env(1)%para_env, blacs_env=qs_ot_env(1)%blacs_env, &
189 rzero, matrix_buf1_ortho)
190 CALL dbcsr_multiply(
'N',
'N', rone, matrix_os_ortho, matrix_buf1_ortho, &
191 rzero, matrix_buf2_ortho)
192 CALL dbcsr_multiply(
'N',
'N', -rone, matrix_s_ortho, matrix_buf2_ortho, &
196 CALL dbcsr_copy(qs_ot_env(1)%matrix_c0, matrix_c)
197 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, matrix_s, qs_ot_env(1)%matrix_c0, &
201 qs_ot_env(1)%para_env, qs_ot_env(1)%blacs_env)
206 para_env=qs_ot_env(1)%para_env, blacs_env=qs_ot_env(1)%blacs_env)
209 para_env=qs_ot_env(1)%para_env, blacs_env=qs_ot_env(1)%blacs_env)
219 CALL dbcsr_copy(qs_ot_env(1)%matrix_c0, matrix_c)
220 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, matrix_s, qs_ot_env(1)%matrix_c0, &
221 0.0_dp, qs_ot_env(1)%matrix_sc0)
223 CALL make_basis_sv(qs_ot_env(1)%matrix_c0, k, qs_ot_env(1)%matrix_sc0, &
224 qs_ot_env(1)%para_env, qs_ot_env(1)%blacs_env)
229 energy_only = qs_ot_env(1)%energy_only
232 CALL dbcsr_set(qs_ot_env(1)%matrix_x, 0.0_dp)
233 CALL dbcsr_set(qs_ot_env(1)%matrix_sx, 0.0_dp)
236 CALL qs_ot_get_p(qs_ot_env(1)%matrix_x, qs_ot_env(1)%matrix_sx, qs_ot_env(1))
255 ieigensolver = ieigensolver + 1
256 iter_total = iter_total + 1
260 0.0_dp, matrix_hc(1)%matrix)
261 CALL dbcsr_dot(matrix_c, matrix_hc(1)%matrix, energy)
262 IF (.NOT. energy_only)
THEN
266 qs_ot_env(1)%etotal = energy
267 CALL ot_mini(qs_ot_env, matrix_hc)
268 delta = qs_ot_env(1)%delta
269 energy_only = qs_ot_env(1)%energy_only
271 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, matrix_s, qs_ot_env(1)%matrix_x, &
272 0.0_dp, qs_ot_env(1)%matrix_sx)
274 CALL qs_ot_get_p(qs_ot_env(1)%matrix_x, qs_ot_env(1)%matrix_sx, qs_ot_env(1))
278 IF (delta < eps_gradient .OR. ieigensolver >= max_iter_inner_loop)
EXIT eigensolver_loop
280 IF (iter_total >= iter_max .AND. qs_ot_env(1)%OT_METHOD_FULL /=
"OT LS")
EXIT eigensolver_loop
282 END DO eigensolver_loop
285 DEALLOCATE (qs_ot_env)
287 DEALLOCATE (matrix_hc)
290 IF (delta < eps_gradient)
THEN
291 IF ((output_unit > 0) .AND. .NOT. my_silent)
THEN
292 WRITE (unit=output_unit, fmt=
"(T2,A,I0,A)") &
293 "OT| Eigensolver reached convergence in ", iter_total,
" iterations"
297 IF (iter_total >= iter_max)
THEN
298 IF (output_unit > 0)
THEN
300 WRITE (output_unit,
"(A,T60,E20.10)")
" WARNING OT eigensolver did not converge: current gradient", delta
302 WRITE (output_unit, *)
"WARNING : did not converge in ot_eigensolver"
303 WRITE (output_unit, *)
"number of iterations ", iter_total,
" exceeded maximum"
304 WRITE (output_unit, *)
"current gradient / target gradient", delta,
" / ", eps_gradient
315 CALL timestop(handle)