71 matrix_c_fm, preconditioner, eps_gradient, &
72 iter_max, size_ortho_space, silent, ot_settings)
74 TYPE(dbcsr_type),
POINTER :: matrix_h, matrix_s
75 TYPE(
cp_fm_type),
INTENT(IN),
OPTIONAL :: matrix_orthogonal_space_fm
78 REAL(kind=
dp) :: eps_gradient
79 INTEGER,
INTENT(IN) :: iter_max
80 INTEGER,
INTENT(IN),
OPTIONAL :: size_ortho_space
81 LOGICAL,
INTENT(IN),
OPTIONAL :: silent
84 CHARACTER(len=*),
PARAMETER :: routinen =
'ot_eigensolver'
85 INTEGER,
PARAMETER :: max_iter_inner_loop = 40
86 REAL(kind=
dp),
PARAMETER :: rone = 1.0_dp, rzero = 0.0_dp
88 INTEGER :: handle, ieigensolver, iter_total, k, n, &
89 ortho_k, ortho_space_k, output_unit
90 LOGICAL :: energy_only, my_silent, ortho
91 REAL(kind=
dp) :: delta, energy
92 TYPE(dbcsr_p_type),
DIMENSION(:),
POINTER :: matrix_hc
93 TYPE(dbcsr_type),
POINTER :: matrix_buf1_ortho, matrix_buf2_ortho, &
94 matrix_c, matrix_orthogonal_space, &
95 matrix_os_ortho, matrix_s_ortho
96 TYPE(
qs_ot_type),
DIMENSION(:),
POINTER :: qs_ot_env
98 CALL timeset(routinen, handle)
102 IF (
PRESENT(silent))
THEN
120 NULLIFY (matrix_s_ortho)
121 NULLIFY (matrix_os_ortho)
122 NULLIFY (matrix_buf1_ortho)
123 NULLIFY (matrix_buf2_ortho)
124 NULLIFY (matrix_orthogonal_space)
126 ALLOCATE (qs_ot_env(1))
127 ALLOCATE (matrix_hc(1))
128 NULLIFY (matrix_hc(1)%matrix)
129 CALL dbcsr_init_p(matrix_hc(1)%matrix)
130 CALL dbcsr_copy(matrix_hc(1)%matrix, matrix_c,
'matrix_hc')
133 IF (
PRESENT(matrix_orthogonal_space_fm)) ortho = .true.
136 IF (
PRESENT(ot_settings))
THEN
137 qs_ot_env(1)%settings = ot_settings
141 qs_ot_env(1)%settings%ds_min = 0.10_dp
145 ALLOCATE (matrix_orthogonal_space)
147 CALL cp_fm_get_info(matrix_orthogonal_space_fm, ncol_global=ortho_space_k)
149 IF (
PRESENT(size_ortho_space)) ortho_space_k = size_ortho_space
150 ortho_k = ortho_space_k + k
156 CALL qs_ot_allocate(qs_ot_env(1), matrix_s, matrix_c_fm%matrix_struct, ortho_k=ortho_k)
161 CALL dbcsr_init_p(matrix_s_ortho)
162 CALL dbcsr_copy(matrix_s_ortho, matrix_orthogonal_space, name=
"matrix_s_ortho")
164 CALL dbcsr_init_p(matrix_os_ortho)
166 sym=dbcsr_type_no_symmetry)
168 CALL dbcsr_init_p(matrix_buf1_ortho)
170 sym=dbcsr_type_no_symmetry)
172 CALL dbcsr_init_p(matrix_buf2_ortho)
174 sym=dbcsr_type_no_symmetry)
176 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, matrix_s, matrix_orthogonal_space, &
177 0.0_dp, matrix_s_ortho)
178 CALL dbcsr_multiply(
'T',
'N', rone, matrix_s_ortho, matrix_s_ortho, &
179 rzero, matrix_os_ortho)
182 para_env=qs_ot_env(1)%para_env, blacs_env=qs_ot_env(1)%blacs_env)
184 para_env=qs_ot_env(1)%para_env, blacs_env=qs_ot_env(1)%blacs_env, &
185 upper_to_full=.true.)
187 CALL dbcsr_multiply(
'T',
'N', rone, matrix_s_ortho, matrix_c, &
188 rzero, matrix_buf1_ortho)
189 CALL dbcsr_multiply(
'N',
'N', rone, matrix_os_ortho, matrix_buf1_ortho, &
190 rzero, matrix_buf2_ortho)
191 CALL dbcsr_multiply(
'N',
'N', -rone, matrix_s_ortho, matrix_buf2_ortho, &
195 CALL dbcsr_copy(qs_ot_env(1)%matrix_c0, matrix_c)
196 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, matrix_s, qs_ot_env(1)%matrix_c0, &
200 qs_ot_env(1)%para_env, qs_ot_env(1)%blacs_env)
205 para_env=qs_ot_env(1)%para_env, blacs_env=qs_ot_env(1)%blacs_env)
208 para_env=qs_ot_env(1)%para_env, blacs_env=qs_ot_env(1)%blacs_env)
210 CALL dbcsr_release_p(matrix_buf1_ortho)
211 CALL dbcsr_release_p(matrix_buf2_ortho)
212 CALL dbcsr_release_p(matrix_os_ortho)
213 CALL dbcsr_release_p(matrix_s_ortho)
218 CALL dbcsr_copy(qs_ot_env(1)%matrix_c0, matrix_c)
219 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, matrix_s, qs_ot_env(1)%matrix_c0, &
220 0.0_dp, qs_ot_env(1)%matrix_sc0)
222 CALL make_basis_sv(qs_ot_env(1)%matrix_c0, k, qs_ot_env(1)%matrix_sc0, &
223 qs_ot_env(1)%para_env, qs_ot_env(1)%blacs_env)
228 energy_only = qs_ot_env(1)%energy_only
231 CALL dbcsr_set(qs_ot_env(1)%matrix_x, 0.0_dp)
232 CALL dbcsr_set(qs_ot_env(1)%matrix_sx, 0.0_dp)
235 CALL qs_ot_get_p(qs_ot_env(1)%matrix_x, qs_ot_env(1)%matrix_sx, qs_ot_env(1))
254 ieigensolver = ieigensolver + 1
255 iter_total = iter_total + 1
258 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, matrix_h, matrix_c, &
259 0.0_dp, matrix_hc(1)%matrix)
260 CALL dbcsr_dot(matrix_c, matrix_hc(1)%matrix, energy)
261 IF (.NOT. energy_only)
THEN
262 CALL dbcsr_scale(matrix_hc(1)%matrix, 2.0_dp)
265 qs_ot_env(1)%etotal = energy
266 CALL ot_mini(qs_ot_env, matrix_hc)
267 delta = qs_ot_env(1)%delta
268 energy_only = qs_ot_env(1)%energy_only
270 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, matrix_s, qs_ot_env(1)%matrix_x, &
271 0.0_dp, qs_ot_env(1)%matrix_sx)
273 CALL qs_ot_get_p(qs_ot_env(1)%matrix_x, qs_ot_env(1)%matrix_sx, qs_ot_env(1))
277 IF (delta < eps_gradient .OR. ieigensolver >= max_iter_inner_loop)
EXIT eigensolver_loop
279 IF (iter_total >= iter_max .AND. qs_ot_env(1)%OT_METHOD_FULL /=
"OT LS")
EXIT eigensolver_loop
281 END DO eigensolver_loop
284 DEALLOCATE (qs_ot_env)
285 CALL dbcsr_release_p(matrix_hc(1)%matrix)
286 DEALLOCATE (matrix_hc)
287 CALL dbcsr_release_p(matrix_orthogonal_space)
289 IF (delta < eps_gradient)
THEN
290 IF ((output_unit > 0) .AND. .NOT. my_silent)
THEN
291 WRITE (unit=output_unit, fmt=
"(T2,A,I0,A)") &
292 "OT| Eigensolver reached convergence in ", iter_total,
" iterations"
296 IF (iter_total >= iter_max)
THEN
297 IF (output_unit > 0)
THEN
299 WRITE (output_unit,
"(A,T60,E20.10)")
" WARNING OT eigensolver did not converge: current gradient", delta
301 WRITE (output_unit, *)
"WARNING : did not converge in ot_eigensolver"
302 WRITE (output_unit, *)
"number of iterations ", iter_total,
" exceeded maximum"
303 WRITE (output_unit, *)
"current gradient / target gradient", delta,
" / ", eps_gradient
312 CALL dbcsr_release_p(matrix_c)
314 CALL timestop(handle)