128 SUBROUTINE ot_scf_mini(mo_array, matrix_dedc, smear, matrix_s, energy, &
129 energy_only, delta, qs_ot_env)
131 TYPE(
mo_set_type),
DIMENSION(:),
INTENT(INOUT) :: mo_array
132 TYPE(
dbcsr_p_type),
DIMENSION(:),
POINTER :: matrix_dedc
135 REAL(kind=
dp) :: energy
136 LOGICAL,
INTENT(INOUT) :: energy_only
137 REAL(kind=
dp) :: delta
138 TYPE(
qs_ot_type),
DIMENSION(:),
POINTER :: qs_ot_env
140 CHARACTER(len=*),
PARAMETER :: routinen =
'ot_scf_mini'
142 INTEGER :: handle, ispin, k, n, nspin
143 REAL(kind=
dp) :: ener_nondiag, trace
144 TYPE(
cp_1d_r_p_type),
ALLOCATABLE,
DIMENSION(:) :: expectation_values, occupation_numbers, &
147 TYPE(
dbcsr_p_type),
DIMENSION(:),
POINTER :: matrix_dedc_physical, matrix_dedc_scaled
150 CALL timeset(routinen, handle)
155 nspin =
SIZE(mo_array)
157 ALLOCATE (occupation_numbers(nspin))
158 ALLOCATE (scaling_factor(nspin))
160 IF (qs_ot_env(1)%settings%do_ener)
THEN
161 ALLOCATE (expectation_values(nspin))
165 CALL get_mo_set(mo_set=mo_array(ispin), occupation_numbers=occupation_numbers(ispin)%array)
166 ALLOCATE (scaling_factor(ispin)%array(
SIZE(occupation_numbers(ispin)%array)))
167 scaling_factor(ispin)%array = 2.0_dp*occupation_numbers(ispin)%array
168 IF (qs_ot_env(1)%settings%do_ener)
THEN
169 ALLOCATE (expectation_values(ispin)%array(
SIZE(occupation_numbers(ispin)%array)))
174 IF (qs_ot_env(1)%settings%do_ener)
THEN
175 cpassert(qs_ot_env(1)%settings%do_rotation)
178 IF (qs_ot_env(1)%settings%add_nondiag_energy)
THEN
179 cpassert(qs_ot_env(1)%settings%do_ener)
183 IF (.NOT. energy_only)
THEN
184 IF (qs_ot_env(1)%settings%do_rotation)
THEN
185 DO ispin = 1,
SIZE(qs_ot_env)
186 CALL get_mo_set(mo_set=mo_array(ispin), mo_coeff_b=mo_coeff)
187 CALL dbcsr_get_info(mo_coeff, nfullrows_total=n, nfullcols_total=k)
188 CALL dbcsr_multiply(
'T',
'N', 1.0_dp, mo_coeff, matrix_dedc(ispin)%matrix, &
189 0.0_dp, qs_ot_env(ispin)%rot_mat_chc)
190 CALL dbcsr_copy(qs_ot_env(ispin)%matrix_buf1, qs_ot_env(ispin)%rot_mat_chc)
192 CALL dbcsr_scale_by_vector(qs_ot_env(ispin)%matrix_buf1, alpha=scaling_factor(ispin)%array, side=
'right')
194 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, qs_ot_env(ispin)%rot_mat_u, qs_ot_env(ispin)%matrix_buf1, &
195 0.0_dp, qs_ot_env(ispin)%rot_mat_dedu)
201 IF (qs_ot_env(1)%settings%do_ener)
THEN
202 DO ispin = 1,
SIZE(mo_array)
203 CALL dbcsr_get_diag(qs_ot_env(ispin)%rot_mat_chc, expectation_values(ispin)%array)
204 qs_ot_env(ispin)%ener_gx = expectation_values(ispin)%array
206 smear=smear, eval_deriv=qs_ot_env(ispin)%ener_gx)
213 IF (qs_ot_env(1)%settings%add_nondiag_energy)
THEN
214 DO ispin = 1,
SIZE(qs_ot_env)
215 CALL dbcsr_get_info(qs_ot_env(ispin)%rot_mat_u, nfullcols_total=k)
216 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, qs_ot_env(ispin)%rot_mat_u, qs_ot_env(ispin)%rot_mat_chc, &
217 0.0_dp, qs_ot_env(ispin)%matrix_buf1)
218 CALL dbcsr_multiply(
'N',
'T', 1.0_dp, qs_ot_env(ispin)%matrix_buf1, qs_ot_env(ispin)%rot_mat_u, &
219 0.0_dp, qs_ot_env(ispin)%rot_mat_chc)
226 ener_nondiag = 0.0_dp
227 IF (qs_ot_env(1)%settings%add_nondiag_energy)
THEN
228 DO ispin = 1,
SIZE(qs_ot_env)
230 CALL dbcsr_get_info(qs_ot_env(ispin)%rot_mat_u, nfullcols_total=k)
231 CALL dbcsr_multiply(
'T',
'N', 1.0_dp, qs_ot_env(ispin)%rot_mat_u, qs_ot_env(ispin)%rot_mat_chc, &
232 0.0_dp, qs_ot_env(ispin)%matrix_buf1)
233 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, qs_ot_env(ispin)%matrix_buf1, qs_ot_env(ispin)%rot_mat_u, &
234 0.0_dp, qs_ot_env(ispin)%matrix_buf2)
237 CALL dbcsr_get_diag(qs_ot_env(ispin)%matrix_buf2, expectation_values(ispin)%array)
238 expectation_values(ispin)%array = expectation_values(ispin)%array - qs_ot_env(ispin)%ener_x
239 CALL dbcsr_set_diag(qs_ot_env(ispin)%matrix_buf2, expectation_values(ispin)%array)
242 CALL dbcsr_dot(qs_ot_env(ispin)%matrix_buf2, qs_ot_env(ispin)%matrix_buf2, trace)
243 ener_nondiag = ener_nondiag + 0.5_dp*qs_ot_env(1)%settings%nondiag_energy_strength*trace
246 IF (.NOT. energy_only)
THEN
248 qs_ot_env(ispin)%ener_gx = qs_ot_env(ispin)%ener_gx - &
249 qs_ot_env(1)%settings%nondiag_energy_strength*expectation_values(ispin)%array
252 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, qs_ot_env(ispin)%rot_mat_chc, qs_ot_env(ispin)%rot_mat_u, &
253 0.0_dp, qs_ot_env(ispin)%matrix_buf1)
254 CALL dbcsr_multiply(
'N',
'N', 2.0_dp*qs_ot_env(1)%settings%nondiag_energy_strength, &
255 qs_ot_env(ispin)%matrix_buf1, qs_ot_env(ispin)%matrix_buf2, &
256 1.0_dp, qs_ot_env(ispin)%rot_mat_dedu)
264 ALLOCATE (matrix_dedc_scaled(
SIZE(matrix_dedc)))
265 NULLIFY (matrix_dedc_physical)
266 IF (qs_ot_env(1)%settings%occupation_preconditioner)
THEN
267 ALLOCATE (matrix_dedc_physical(
SIZE(matrix_dedc)))
269 DO ispin = 1,
SIZE(matrix_dedc)
270 ALLOCATE (matrix_dedc_scaled(ispin)%matrix)
271 CALL dbcsr_copy(matrix_dedc_scaled(ispin)%matrix, matrix_dedc(ispin)%matrix)
273 IF (qs_ot_env(1)%settings%occupation_preconditioner)
THEN
274 ALLOCATE (matrix_dedc_physical(ispin)%matrix)
275 CALL dbcsr_copy(matrix_dedc_physical(ispin)%matrix, matrix_dedc(ispin)%matrix)
277 alpha=2.0_dp*occupation_numbers(ispin)%array, side=
'right')
278 scaling_factor(ispin)%array = 2.0_dp
280 CALL dbcsr_scale_by_vector(matrix_dedc_scaled(ispin)%matrix, alpha=scaling_factor(ispin)%array, side=
'right')
284 qs_ot_env(1)%etotal = energy + ener_nondiag
286 IF (qs_ot_env(1)%settings%occupation_preconditioner .AND. &
287 (qs_ot_env(1)%settings%ot_method ==
"CG" .OR. &
288 qs_ot_env(1)%settings%ot_method ==
"SD"))
THEN
289 CALL ot_mini(qs_ot_env, matrix_dedc_scaled, matrix_hc_physical=matrix_dedc_physical)
291 CALL ot_mini(qs_ot_env, matrix_dedc_scaled)
294 delta = qs_ot_env(1)%delta
295 energy_only = qs_ot_env(1)%energy_only
298 DO ispin = 1,
SIZE(qs_ot_env)
299 CALL get_mo_set(mo_set=mo_array(ispin), mo_coeff_b=mo_coeff)
300 CALL dbcsr_get_info(mo_coeff, nfullrows_total=n, nfullcols_total=k)
301 SELECT CASE (qs_ot_env(1)%settings%ot_algorithm)
303 IF (
ASSOCIATED(matrix_s))
THEN
304 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, matrix_s, qs_ot_env(ispin)%matrix_x, &
305 0.0_dp, qs_ot_env(ispin)%matrix_sx)
307 CALL dbcsr_copy(qs_ot_env(ispin)%matrix_sx, qs_ot_env(ispin)%matrix_x)
309 CALL qs_ot_get_p(qs_ot_env(ispin)%matrix_x, qs_ot_env(ispin)%matrix_sx, qs_ot_env(ispin))
313 qs_ot_env(ispin)%matrix_sx, qs_ot_env(ispin)%matrix_gx_old, &
314 qs_ot_env(ispin)%matrix_dx, qs_ot_env(ispin), qs_ot_env(1))
316 cpabort(
"Algorithm not yet implemented")
320 IF (qs_ot_env(1)%restricted)
THEN
326 IF (qs_ot_env(1)%settings%do_ener)
THEN
327 DO ispin = 1,
SIZE(mo_array)
328 mo_array(ispin)%eigenvalues = qs_ot_env(ispin)%ener_x
335 DO ispin = 1,
SIZE(scaling_factor)
336 DEALLOCATE (scaling_factor(ispin)%array)
338 DEALLOCATE (scaling_factor)
339 IF (qs_ot_env(1)%settings%do_ener)
THEN
340 DO ispin = 1,
SIZE(expectation_values)
341 DEALLOCATE (expectation_values(ispin)%array)
343 DEALLOCATE (expectation_values)
345 DEALLOCATE (occupation_numbers)
346 DO ispin = 1,
SIZE(matrix_dedc_scaled)
348 DEALLOCATE (matrix_dedc_scaled(ispin)%matrix)
350 DEALLOCATE (matrix_dedc_scaled)
351 IF (
ASSOCIATED(matrix_dedc_physical))
THEN
352 DO ispin = 1,
SIZE(matrix_dedc_physical)
354 DEALLOCATE (matrix_dedc_physical(ispin)%matrix)
356 DEALLOCATE (matrix_dedc_physical)
359 CALL timestop(handle)
372 SUBROUTINE ot_scf_init(mo_array, matrix_s, qs_ot_env, matrix_ks, broyden_adaptive_sigma)
374 TYPE(
mo_set_type),
DIMENSION(:),
INTENT(IN) :: mo_array
376 TYPE(
qs_ot_type),
DIMENSION(:),
POINTER :: qs_ot_env
378 REAL(kind=
dp) :: broyden_adaptive_sigma
380 CHARACTER(len=*),
PARAMETER :: routinen =
'ot_scf_init'
382 INTEGER :: handle, ispin, k, n, nspin
387 CALL timeset(routinen, handle)
389 DO ispin = 1,
SIZE(mo_array)
390 IF (.NOT.
ASSOCIATED(mo_array(ispin)%mo_coeff_b))
THEN
391 cpabort(
"Shouldn't get there")
396 n=mo_array(ispin)%nmo, &
397 sym=dbcsr_type_no_symmetry)
402 DO ispin = 1,
SIZE(qs_ot_env)
403 qs_ot_env(ispin)%broyden_adaptive_sigma = broyden_adaptive_sigma
409 nspin =
SIZE(qs_ot_env)
416 CALL get_mo_set(mo_set=mo_array(ispin), mo_coeff_b=mo_coeff, mo_coeff=mo_coeff_fm)
419 CALL dbcsr_get_info(mo_coeff, nfullrows_total=n, nfullcols_total=k)
422 CALL qs_ot_allocate(qs_ot_env(ispin), matrix_ks, mo_coeff_fm%matrix_struct)
425 CALL dbcsr_copy(qs_ot_env(ispin)%matrix_c0, mo_coeff)
426 IF (
ASSOCIATED(matrix_s))
THEN
427 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, matrix_s, qs_ot_env(ispin)%matrix_c0, &
428 0.0_dp, qs_ot_env(ispin)%matrix_sc0)
430 CALL dbcsr_copy(qs_ot_env(ispin)%matrix_sc0, qs_ot_env(ispin)%matrix_c0)
437 CALL dbcsr_set(qs_ot_env(ispin)%matrix_x, 0.0_dp)
438 CALL dbcsr_set(qs_ot_env(ispin)%matrix_sx, 0.0_dp)
440 IF (qs_ot_env(ispin)%settings%do_rotation)
THEN
441 CALL dbcsr_set(qs_ot_env(ispin)%rot_mat_x, 0.0_dp)
442 CALL dbcsr_set(qs_ot_env(ispin)%rot_mat_u, 0.0_dp)
446 IF (qs_ot_env(ispin)%settings%do_ener)
THEN
447 is_equal =
SIZE(qs_ot_env(ispin)%ener_x) ==
SIZE(mo_array(ispin)%eigenvalues)
449 qs_ot_env(ispin)%ener_x = mo_array(ispin)%eigenvalues
452 SELECT CASE (qs_ot_env(1)%settings%ot_algorithm)
455 CALL qs_ot_get_p(qs_ot_env(ispin)%matrix_x, qs_ot_env(ispin)%matrix_sx, qs_ot_env(ispin))
457 CALL dbcsr_copy(qs_ot_env(ispin)%matrix_x, qs_ot_env(ispin)%matrix_c0)
458 CALL dbcsr_copy(qs_ot_env(ispin)%matrix_sx, qs_ot_env(ispin)%matrix_sc0)
460 cpabort(
"Algorithm not yet implemented")
464 CALL timestop(handle)