124 SUBROUTINE ot_scf_mini(mo_array, matrix_dedc, smear, matrix_s, energy, &
125 energy_only, delta, qs_ot_env)
127 TYPE(
mo_set_type),
DIMENSION(:),
INTENT(INOUT) :: mo_array
128 TYPE(dbcsr_p_type),
DIMENSION(:),
POINTER :: matrix_dedc
130 TYPE(dbcsr_type),
POINTER :: matrix_s
131 REAL(kind=
dp) :: energy
132 LOGICAL,
INTENT(INOUT) :: energy_only
133 REAL(kind=
dp) :: delta
134 TYPE(
qs_ot_type),
DIMENSION(:),
POINTER :: qs_ot_env
136 CHARACTER(len=*),
PARAMETER :: routinen =
'ot_scf_mini'
138 INTEGER :: handle, ispin, k, n, nspin
139 REAL(kind=
dp) :: ener_nondiag, trace
140 TYPE(
cp_1d_r_p_type),
ALLOCATABLE,
DIMENSION(:) :: expectation_values, occupation_numbers, &
143 TYPE(dbcsr_p_type),
DIMENSION(:),
POINTER :: matrix_dedc_scaled
144 TYPE(dbcsr_type),
POINTER :: mo_coeff
146 CALL timeset(routinen, handle)
151 nspin =
SIZE(mo_array)
153 ALLOCATE (occupation_numbers(nspin))
154 ALLOCATE (scaling_factor(nspin))
156 IF (qs_ot_env(1)%settings%do_ener)
THEN
157 ALLOCATE (expectation_values(nspin))
161 CALL get_mo_set(mo_set=mo_array(ispin), occupation_numbers=occupation_numbers(ispin)%array)
162 ALLOCATE (scaling_factor(ispin)%array(
SIZE(occupation_numbers(ispin)%array)))
163 scaling_factor(ispin)%array = 2.0_dp*occupation_numbers(ispin)%array
164 IF (qs_ot_env(1)%settings%do_ener)
THEN
165 ALLOCATE (expectation_values(ispin)%array(
SIZE(occupation_numbers(ispin)%array)))
170 IF (qs_ot_env(1)%settings%do_ener)
THEN
171 cpassert(qs_ot_env(1)%settings%do_rotation)
174 IF (qs_ot_env(1)%settings%add_nondiag_energy)
THEN
175 cpassert(qs_ot_env(1)%settings%do_ener)
179 IF (.NOT. energy_only)
THEN
180 IF (qs_ot_env(1)%settings%do_rotation)
THEN
181 DO ispin = 1,
SIZE(qs_ot_env)
182 CALL get_mo_set(mo_set=mo_array(ispin), mo_coeff_b=mo_coeff)
183 CALL dbcsr_get_info(mo_coeff, nfullrows_total=n, nfullcols_total=k)
184 CALL dbcsr_multiply(
'T',
'N', 1.0_dp, mo_coeff, matrix_dedc(ispin)%matrix, &
185 0.0_dp, qs_ot_env(ispin)%rot_mat_chc)
186 CALL dbcsr_copy(qs_ot_env(ispin)%matrix_buf1, qs_ot_env(ispin)%rot_mat_chc)
188 CALL dbcsr_scale_by_vector(qs_ot_env(ispin)%matrix_buf1, alpha=scaling_factor(ispin)%array, side=
'right')
190 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, qs_ot_env(ispin)%rot_mat_u, qs_ot_env(ispin)%matrix_buf1, &
191 0.0_dp, qs_ot_env(ispin)%rot_mat_dedu)
197 IF (qs_ot_env(1)%settings%do_ener)
THEN
198 DO ispin = 1,
SIZE(mo_array)
199 CALL dbcsr_get_diag(qs_ot_env(ispin)%rot_mat_chc, expectation_values(ispin)%array)
200 qs_ot_env(ispin)%ener_gx = expectation_values(ispin)%array
202 smear=smear, eval_deriv=qs_ot_env(ispin)%ener_gx)
209 IF (qs_ot_env(1)%settings%add_nondiag_energy)
THEN
210 DO ispin = 1,
SIZE(qs_ot_env)
211 CALL dbcsr_get_info(qs_ot_env(ispin)%rot_mat_u, nfullcols_total=k)
212 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, qs_ot_env(ispin)%rot_mat_u, qs_ot_env(ispin)%rot_mat_chc, &
213 0.0_dp, qs_ot_env(ispin)%matrix_buf1)
214 CALL dbcsr_multiply(
'N',
'T', 1.0_dp, qs_ot_env(ispin)%matrix_buf1, qs_ot_env(ispin)%rot_mat_u, &
215 0.0_dp, qs_ot_env(ispin)%rot_mat_chc)
222 ener_nondiag = 0.0_dp
223 IF (qs_ot_env(1)%settings%add_nondiag_energy)
THEN
224 DO ispin = 1,
SIZE(qs_ot_env)
226 CALL dbcsr_get_info(qs_ot_env(ispin)%rot_mat_u, nfullcols_total=k)
227 CALL dbcsr_multiply(
'T',
'N', 1.0_dp, qs_ot_env(ispin)%rot_mat_u, qs_ot_env(ispin)%rot_mat_chc, &
228 0.0_dp, qs_ot_env(ispin)%matrix_buf1)
229 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, qs_ot_env(ispin)%matrix_buf1, qs_ot_env(ispin)%rot_mat_u, &
230 0.0_dp, qs_ot_env(ispin)%matrix_buf2)
233 CALL dbcsr_get_diag(qs_ot_env(ispin)%matrix_buf2, expectation_values(ispin)%array)
234 expectation_values(ispin)%array = expectation_values(ispin)%array - qs_ot_env(ispin)%ener_x
235 CALL dbcsr_set_diag(qs_ot_env(ispin)%matrix_buf2, expectation_values(ispin)%array)
238 CALL dbcsr_dot(qs_ot_env(ispin)%matrix_buf2, qs_ot_env(ispin)%matrix_buf2, trace)
239 ener_nondiag = ener_nondiag + 0.5_dp*qs_ot_env(1)%settings%nondiag_energy_strength*trace
242 IF (.NOT. energy_only)
THEN
244 qs_ot_env(ispin)%ener_gx = qs_ot_env(ispin)%ener_gx - &
245 qs_ot_env(1)%settings%nondiag_energy_strength*expectation_values(ispin)%array
248 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, qs_ot_env(ispin)%rot_mat_chc, qs_ot_env(ispin)%rot_mat_u, &
249 0.0_dp, qs_ot_env(ispin)%matrix_buf1)
250 CALL dbcsr_multiply(
'N',
'N', 2.0_dp*qs_ot_env(1)%settings%nondiag_energy_strength, &
251 qs_ot_env(ispin)%matrix_buf1, qs_ot_env(ispin)%matrix_buf2, &
252 1.0_dp, qs_ot_env(ispin)%rot_mat_dedu)
260 ALLOCATE (matrix_dedc_scaled(
SIZE(matrix_dedc)))
261 DO ispin = 1,
SIZE(matrix_dedc)
262 ALLOCATE (matrix_dedc_scaled(ispin)%matrix)
263 CALL dbcsr_copy(matrix_dedc_scaled(ispin)%matrix, matrix_dedc(ispin)%matrix)
267 IF (qs_ot_env(1)%settings%occupation_preconditioner)
THEN
268 scaling_factor(ispin)%array = 2.0_dp
270 CALL dbcsr_scale_by_vector(matrix_dedc_scaled(ispin)%matrix, alpha=scaling_factor(ispin)%array, side=
'right')
274 qs_ot_env(1)%etotal = energy + ener_nondiag
276 CALL ot_mini(qs_ot_env, matrix_dedc_scaled)
278 delta = qs_ot_env(1)%delta
279 energy_only = qs_ot_env(1)%energy_only
282 DO ispin = 1,
SIZE(qs_ot_env)
283 CALL get_mo_set(mo_set=mo_array(ispin), mo_coeff_b=mo_coeff)
284 CALL dbcsr_get_info(mo_coeff, nfullrows_total=n, nfullcols_total=k)
285 SELECT CASE (qs_ot_env(1)%settings%ot_algorithm)
287 IF (
ASSOCIATED(matrix_s))
THEN
288 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, matrix_s, qs_ot_env(ispin)%matrix_x, &
289 0.0_dp, qs_ot_env(ispin)%matrix_sx)
291 CALL dbcsr_copy(qs_ot_env(ispin)%matrix_sx, qs_ot_env(ispin)%matrix_x)
293 CALL qs_ot_get_p(qs_ot_env(ispin)%matrix_x, qs_ot_env(ispin)%matrix_sx, qs_ot_env(ispin))
297 qs_ot_env(ispin)%matrix_sx, qs_ot_env(ispin)%matrix_gx_old, &
298 qs_ot_env(ispin)%matrix_dx, qs_ot_env(ispin), qs_ot_env(1))
300 cpabort(
"Algorithm not yet implemented")
304 IF (qs_ot_env(1)%restricted)
THEN
310 IF (qs_ot_env(1)%settings%do_ener)
THEN
311 DO ispin = 1,
SIZE(mo_array)
312 mo_array(ispin)%eigenvalues = qs_ot_env(ispin)%ener_x
319 DO ispin = 1,
SIZE(scaling_factor)
320 DEALLOCATE (scaling_factor(ispin)%array)
322 DEALLOCATE (scaling_factor)
323 IF (qs_ot_env(1)%settings%do_ener)
THEN
324 DO ispin = 1,
SIZE(expectation_values)
325 DEALLOCATE (expectation_values(ispin)%array)
327 DEALLOCATE (expectation_values)
329 DEALLOCATE (occupation_numbers)
330 DO ispin = 1,
SIZE(matrix_dedc_scaled)
331 CALL dbcsr_release(matrix_dedc_scaled(ispin)%matrix)
332 DEALLOCATE (matrix_dedc_scaled(ispin)%matrix)
334 DEALLOCATE (matrix_dedc_scaled)
336 CALL timestop(handle)
351 SUBROUTINE ot_scf_init(mo_array, matrix_s, qs_ot_env, matrix_ks, broyden_adaptive_sigma)
353 TYPE(
mo_set_type),
DIMENSION(:),
INTENT(IN) :: mo_array
354 TYPE(dbcsr_type),
POINTER :: matrix_s
355 TYPE(
qs_ot_type),
DIMENSION(:),
POINTER :: qs_ot_env
356 TYPE(dbcsr_type),
POINTER :: matrix_ks
357 REAL(kind=
dp) :: broyden_adaptive_sigma
359 CHARACTER(len=*),
PARAMETER :: routinen =
'ot_scf_init'
361 INTEGER :: handle, ispin, k, n, nspin
364 TYPE(dbcsr_type),
POINTER :: mo_coeff
366 CALL timeset(routinen, handle)
368 DO ispin = 1,
SIZE(mo_array)
369 IF (.NOT.
ASSOCIATED(mo_array(ispin)%mo_coeff_b))
THEN
370 cpabort(
"Shouldn't get there")
373 CALL dbcsr_init_p(mo_array(ispin)%mo_coeff_b)
375 n=mo_array(ispin)%nmo, &
376 sym=dbcsr_type_no_symmetry)
381 DO ispin = 1,
SIZE(qs_ot_env)
382 qs_ot_env(ispin)%broyden_adaptive_sigma = broyden_adaptive_sigma
388 nspin =
SIZE(qs_ot_env)
393 CALL get_mo_set(mo_set=mo_array(ispin), mo_coeff_b=mo_coeff, mo_coeff=mo_coeff_fm)
396 CALL dbcsr_get_info(mo_coeff, nfullrows_total=n, nfullcols_total=k)
399 CALL qs_ot_allocate(qs_ot_env(ispin), matrix_ks, mo_coeff_fm%matrix_struct)
402 CALL dbcsr_copy(qs_ot_env(ispin)%matrix_c0, mo_coeff)
403 IF (
ASSOCIATED(matrix_s))
THEN
404 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, matrix_s, qs_ot_env(ispin)%matrix_c0, &
405 0.0_dp, qs_ot_env(ispin)%matrix_sc0)
407 CALL dbcsr_copy(qs_ot_env(ispin)%matrix_sc0, qs_ot_env(ispin)%matrix_c0)
414 CALL dbcsr_set(qs_ot_env(ispin)%matrix_x, 0.0_dp)
415 CALL dbcsr_set(qs_ot_env(ispin)%matrix_sx, 0.0_dp)
417 IF (qs_ot_env(ispin)%settings%do_rotation)
THEN
418 CALL dbcsr_set(qs_ot_env(ispin)%rot_mat_x, 0.0_dp)
421 IF (qs_ot_env(ispin)%settings%do_ener)
THEN
422 is_equal =
SIZE(qs_ot_env(ispin)%ener_x) ==
SIZE(mo_array(ispin)%eigenvalues)
424 qs_ot_env(ispin)%ener_x = mo_array(ispin)%eigenvalues
427 SELECT CASE (qs_ot_env(1)%settings%ot_algorithm)
430 CALL qs_ot_get_p(qs_ot_env(ispin)%matrix_x, qs_ot_env(ispin)%matrix_sx, qs_ot_env(ispin))
432 CALL dbcsr_copy(qs_ot_env(ispin)%matrix_x, qs_ot_env(ispin)%matrix_c0)
433 CALL dbcsr_copy(qs_ot_env(ispin)%matrix_sx, qs_ot_env(ispin)%matrix_sc0)
435 cpabort(
"Algorithm not yet implemented")
439 CALL timestop(handle)