Line data Source code
1 : !--------------------------------------------------------------------------------------------------!
2 : ! CP2K: A general program to perform molecular dynamics simulations !
3 : ! Copyright 2000-2025 CP2K developers group <https://cp2k.org> !
4 : ! !
5 : ! SPDX-License-Identifier: GPL-2.0-or-later !
6 : !--------------------------------------------------------------------------------------------------!
7 :
8 : ! **************************************************************************************************
9 : !> \brief basic functionality for using ot in the scf routines.
10 : !> \par History
11 : !> 01.2003 : Joost VandeVondele : adapted for LSD
12 : !> \author Joost VandeVondele (25.08.2002)
13 : ! **************************************************************************************************
14 : MODULE qs_ot_scf
15 : USE cp_array_utils, ONLY: cp_1d_r_p_type
16 : USE cp_dbcsr_api, ONLY: &
17 : dbcsr_copy, dbcsr_get_info, dbcsr_init_p, dbcsr_multiply, dbcsr_p_type, dbcsr_release, &
18 : dbcsr_set, dbcsr_type, dbcsr_type_no_symmetry
19 : USE cp_dbcsr_contrib, ONLY: dbcsr_dot,&
20 : dbcsr_get_diag,&
21 : dbcsr_scale_by_vector,&
22 : dbcsr_set_diag
23 : USE cp_dbcsr_operations, ONLY: copy_fm_to_dbcsr,&
24 : cp_dbcsr_m_by_n_from_row_template
25 : USE cp_fm_types, ONLY: cp_fm_type
26 : USE cp_log_handling, ONLY: cp_get_default_logger,&
27 : cp_logger_type
28 : USE cp_output_handling, ONLY: cp_print_key_finished_output,&
29 : cp_print_key_unit_nr
30 : USE input_section_types, ONLY: section_vals_get,&
31 : section_vals_get_subs_vals,&
32 : section_vals_type
33 : USE kinds, ONLY: dp
34 : USE qs_mo_occupation, ONLY: set_mo_occupation
35 : USE qs_mo_types, ONLY: get_mo_set,&
36 : mo_set_restrict,&
37 : mo_set_type
38 : USE qs_ot, ONLY: qs_ot_get_orbitals,&
39 : qs_ot_get_orbitals_ref,&
40 : qs_ot_get_p
41 : USE qs_ot_minimizer, ONLY: ot_mini
42 : USE qs_ot_types, ONLY: ot_readwrite_input,&
43 : qs_ot_allocate,&
44 : qs_ot_destroy,&
45 : qs_ot_init,&
46 : qs_ot_settings_init,&
47 : qs_ot_type
48 : USE scf_control_types, ONLY: smear_type
49 : #include "./base/base_uses.f90"
50 :
51 : IMPLICIT NONE
52 :
53 : PRIVATE
54 :
55 : CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_ot_scf'
56 : ! *** Public subroutines ***
57 :
58 : PUBLIC :: ot_scf_init
59 : PUBLIC :: ot_scf_mini
60 : PUBLIC :: ot_scf_destroy
61 : PUBLIC :: ot_scf_read_input
62 :
63 : CONTAINS
64 :
65 : ! **************************************************************************************************
66 : !> \brief ...
67 : !> \param qs_ot_env ...
68 : !> \param scf_section ...
69 : ! **************************************************************************************************
70 13378 : SUBROUTINE ot_scf_read_input(qs_ot_env, scf_section)
71 : TYPE(qs_ot_type), DIMENSION(:), POINTER :: qs_ot_env
72 : TYPE(section_vals_type), POINTER :: scf_section
73 :
74 : CHARACTER(len=*), PARAMETER :: routineN = 'ot_scf_read_input'
75 :
76 : INTEGER :: handle, ispin, nspin, output_unit
77 : LOGICAL :: explicit
78 : TYPE(cp_logger_type), POINTER :: logger
79 : TYPE(section_vals_type), POINTER :: ot_section
80 :
81 6689 : CALL timeset(routineN, handle)
82 :
83 6689 : logger => cp_get_default_logger()
84 : output_unit = cp_print_key_unit_nr(logger, scf_section, "PRINT%PROGRAM_RUN_INFO", &
85 6689 : extension=".log")
86 :
87 : ! decide default settings
88 6689 : CALL qs_ot_settings_init(qs_ot_env(1)%settings)
89 :
90 : ! use ot input new style
91 6689 : ot_section => section_vals_get_subs_vals(scf_section, "OT")
92 6689 : CALL section_vals_get(ot_section, explicit=explicit)
93 :
94 6689 : CALL ot_readwrite_input(qs_ot_env(1)%settings, ot_section, output_unit)
95 :
96 : CALL cp_print_key_finished_output(output_unit, logger, scf_section, &
97 6689 : "PRINT%PROGRAM_RUN_INFO")
98 :
99 : ! copy the ot settings type so it is identical
100 6689 : nspin = SIZE(qs_ot_env)
101 7922 : DO ispin = 2, nspin
102 7922 : qs_ot_env(ispin)%settings = qs_ot_env(1)%settings
103 : END DO
104 :
105 6689 : CALL timestop(handle)
106 :
107 6689 : END SUBROUTINE ot_scf_read_input
108 : ! **************************************************************************************************
109 : !
110 : ! performs the actual minimisation, needs only limited info
111 : ! updated for restricted calculations
112 : ! matrix_dedc is the derivative of the energy with respect to the orbitals (except for a factor 2*fi)
113 : ! a null pointer for matrix_s implies that matrix_s is the unit matrix
114 : !
115 : !
116 : ! **************************************************************************************************
117 : !> \brief ...
118 : !> \param mo_array ...
119 : !> \param matrix_dedc ...
120 : !> \param smear ...
121 : !> \param matrix_s ...
122 : !> \param energy ...
123 : !> \param energy_only ...
124 : !> \param delta ...
125 : !> \param qs_ot_env ...
126 : ! **************************************************************************************************
127 70392 : SUBROUTINE ot_scf_mini(mo_array, matrix_dedc, smear, matrix_s, energy, &
128 : energy_only, delta, qs_ot_env)
129 :
130 : TYPE(mo_set_type), DIMENSION(:), INTENT(INOUT) :: mo_array
131 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_dedc
132 : TYPE(smear_type), POINTER :: smear
133 : TYPE(dbcsr_type), POINTER :: matrix_s
134 : REAL(KIND=dp) :: energy
135 : LOGICAL, INTENT(INOUT) :: energy_only
136 : REAL(KIND=dp) :: delta
137 : TYPE(qs_ot_type), DIMENSION(:), POINTER :: qs_ot_env
138 :
139 : CHARACTER(len=*), PARAMETER :: routineN = 'ot_scf_mini'
140 :
141 : INTEGER :: handle, ispin, k, n, nspin
142 : REAL(KIND=dp) :: ener_nondiag, trace
143 70392 : TYPE(cp_1d_r_p_type), ALLOCATABLE, DIMENSION(:) :: expectation_values, occupation_numbers, &
144 70392 : scaling_factor
145 : TYPE(cp_logger_type), POINTER :: logger
146 70392 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_dedc_scaled
147 : TYPE(dbcsr_type), POINTER :: mo_coeff
148 :
149 70392 : CALL timeset(routineN, handle)
150 :
151 70392 : NULLIFY (logger)
152 70392 : logger => cp_get_default_logger()
153 :
154 70392 : nspin = SIZE(mo_array)
155 :
156 293655 : ALLOCATE (occupation_numbers(nspin))
157 223263 : ALLOCATE (scaling_factor(nspin))
158 :
159 70392 : IF (qs_ot_env(1)%settings%do_ener) THEN
160 0 : ALLOCATE (expectation_values(nspin))
161 : END IF
162 :
163 152871 : DO ispin = 1, nspin
164 82479 : CALL get_mo_set(mo_set=mo_array(ispin), occupation_numbers=occupation_numbers(ispin)%array)
165 246801 : ALLOCATE (scaling_factor(ispin)%array(SIZE(occupation_numbers(ispin)%array)))
166 951284 : scaling_factor(ispin)%array = 2.0_dp*occupation_numbers(ispin)%array
167 152871 : IF (qs_ot_env(1)%settings%do_ener) THEN
168 0 : ALLOCATE (expectation_values(ispin)%array(SIZE(occupation_numbers(ispin)%array)))
169 : END IF
170 : END DO
171 :
172 : ! optimizing orbital energies somehow implies non-equivalent orbitals
173 70392 : IF (qs_ot_env(1)%settings%do_ener) THEN
174 0 : CPASSERT(qs_ot_env(1)%settings%do_rotation)
175 : END IF
176 : ! add_nondiag_energy requires do_ener
177 70392 : IF (qs_ot_env(1)%settings%add_nondiag_energy) THEN
178 0 : CPASSERT(qs_ot_env(1)%settings%do_ener)
179 : END IF
180 :
181 : ! get a rotational force
182 70392 : IF (.NOT. energy_only) THEN
183 56112 : IF (qs_ot_env(1)%settings%do_rotation) THEN
184 3190 : DO ispin = 1, SIZE(qs_ot_env)
185 1630 : CALL get_mo_set(mo_set=mo_array(ispin), mo_coeff_b=mo_coeff)
186 1630 : CALL dbcsr_get_info(mo_coeff, nfullrows_total=n, nfullcols_total=k)
187 : CALL dbcsr_multiply('T', 'N', 1.0_dp, mo_coeff, matrix_dedc(ispin)%matrix, &
188 1630 : 0.0_dp, qs_ot_env(ispin)%rot_mat_chc)
189 1630 : CALL dbcsr_copy(qs_ot_env(ispin)%matrix_buf1, qs_ot_env(ispin)%rot_mat_chc)
190 :
191 1630 : CALL dbcsr_scale_by_vector(qs_ot_env(ispin)%matrix_buf1, alpha=scaling_factor(ispin)%array, side='right')
192 : ! create the derivative of the energy wrt to rot_mat_u
193 : CALL dbcsr_multiply('N', 'N', 1.0_dp, qs_ot_env(ispin)%rot_mat_u, qs_ot_env(ispin)%matrix_buf1, &
194 4820 : 0.0_dp, qs_ot_env(ispin)%rot_mat_dedu)
195 : END DO
196 :
197 : ! here we construct the derivative of the free energy with respect to the evals
198 : ! (note that this requires the diagonal elements of chc)
199 : ! the mo occupations should in principle remain unaltered
200 1560 : IF (qs_ot_env(1)%settings%do_ener) THEN
201 0 : DO ispin = 1, SIZE(mo_array)
202 0 : CALL dbcsr_get_diag(qs_ot_env(ispin)%rot_mat_chc, expectation_values(ispin)%array)
203 0 : qs_ot_env(ispin)%ener_gx = expectation_values(ispin)%array
204 : CALL set_mo_occupation(mo_set=mo_array(ispin), &
205 0 : smear=smear, eval_deriv=qs_ot_env(ispin)%ener_gx)
206 : END DO
207 : END IF
208 :
209 : ! chc only needs to be stored in u independent form if we require add_nondiag_energy,
210 : ! which will use it in non-selfconsistent form for e.g. the linesearch
211 : ! transform C^T H C -> U C^T H C U ^ T
212 1560 : IF (qs_ot_env(1)%settings%add_nondiag_energy) THEN
213 0 : DO ispin = 1, SIZE(qs_ot_env)
214 0 : CALL dbcsr_get_info(qs_ot_env(ispin)%rot_mat_u, nfullcols_total=k)
215 : CALL dbcsr_multiply('N', 'N', 1.0_dp, qs_ot_env(ispin)%rot_mat_u, qs_ot_env(ispin)%rot_mat_chc, &
216 0 : 0.0_dp, qs_ot_env(ispin)%matrix_buf1)
217 : CALL dbcsr_multiply('N', 'T', 1.0_dp, qs_ot_env(ispin)%matrix_buf1, qs_ot_env(ispin)%rot_mat_u, &
218 0 : 0.0_dp, qs_ot_env(ispin)%rot_mat_chc)
219 : END DO
220 : END IF
221 : END IF
222 : END IF
223 :
224 : ! evaluate non-diagonal energy contribution
225 70392 : ener_nondiag = 0.0_dp
226 70392 : IF (qs_ot_env(1)%settings%add_nondiag_energy) THEN
227 0 : DO ispin = 1, SIZE(qs_ot_env)
228 : ! transform \tilde H to the current basis of C (assuming non-selfconsistent H)
229 0 : CALL dbcsr_get_info(qs_ot_env(ispin)%rot_mat_u, nfullcols_total=k)
230 : CALL dbcsr_multiply('T', 'N', 1.0_dp, qs_ot_env(ispin)%rot_mat_u, qs_ot_env(ispin)%rot_mat_chc, &
231 0 : 0.0_dp, qs_ot_env(ispin)%matrix_buf1)
232 : CALL dbcsr_multiply('N', 'N', 1.0_dp, qs_ot_env(ispin)%matrix_buf1, qs_ot_env(ispin)%rot_mat_u, &
233 0 : 0.0_dp, qs_ot_env(ispin)%matrix_buf2)
234 :
235 : ! subtract the current ener_x from the diagonal
236 0 : CALL dbcsr_get_diag(qs_ot_env(ispin)%matrix_buf2, expectation_values(ispin)%array)
237 0 : expectation_values(ispin)%array = expectation_values(ispin)%array - qs_ot_env(ispin)%ener_x
238 0 : CALL dbcsr_set_diag(qs_ot_env(ispin)%matrix_buf2, expectation_values(ispin)%array)
239 :
240 : ! get nondiag energy trace (D^T D)
241 0 : CALL dbcsr_dot(qs_ot_env(ispin)%matrix_buf2, qs_ot_env(ispin)%matrix_buf2, trace)
242 0 : ener_nondiag = ener_nondiag + 0.5_dp*qs_ot_env(1)%settings%nondiag_energy_strength*trace
243 :
244 : ! get gradient (again ignoring dependencies of H)
245 0 : IF (.NOT. energy_only) THEN
246 : ! first for the ener_x (-2*(diag(C^T H C)-ener_x))
247 : qs_ot_env(ispin)%ener_gx = qs_ot_env(ispin)%ener_gx - &
248 0 : qs_ot_env(1)%settings%nondiag_energy_strength*expectation_values(ispin)%array
249 :
250 : ! next for the rot_mat_u derivative (2 * k * \tilde H U D)
251 : CALL dbcsr_multiply('N', 'N', 1.0_dp, qs_ot_env(ispin)%rot_mat_chc, qs_ot_env(ispin)%rot_mat_u, &
252 0 : 0.0_dp, qs_ot_env(ispin)%matrix_buf1)
253 : CALL dbcsr_multiply('N', 'N', 2.0_dp*qs_ot_env(1)%settings%nondiag_energy_strength, &
254 : qs_ot_env(ispin)%matrix_buf1, qs_ot_env(ispin)%matrix_buf2, &
255 0 : 1.0_dp, qs_ot_env(ispin)%rot_mat_dedu)
256 : END IF
257 : END DO
258 : END IF
259 :
260 : ! this is kind of a hack so far (costly memory wise), we locally recreate the scaled matrix_hc, and
261 : ! use it in the following, eventually, as occupations numbers get more integrated, it should become possible
262 : ! to remove this.
263 292753 : ALLOCATE (matrix_dedc_scaled(SIZE(matrix_dedc)))
264 151969 : DO ispin = 1, SIZE(matrix_dedc)
265 81577 : ALLOCATE (matrix_dedc_scaled(ispin)%matrix)
266 81577 : CALL dbcsr_copy(matrix_dedc_scaled(ispin)%matrix, matrix_dedc(ispin)%matrix)
267 :
268 : ! as a preconditioner, one might want to scale only with a constant, not with f(i)
269 : ! for the convergence criterion, maybe take it back out
270 81577 : IF (qs_ot_env(1)%settings%occupation_preconditioner) THEN
271 0 : scaling_factor(ispin)%array = 2.0_dp
272 : END IF
273 151969 : CALL dbcsr_scale_by_vector(matrix_dedc_scaled(ispin)%matrix, alpha=scaling_factor(ispin)%array, side='right')
274 : END DO
275 :
276 : ! notice we use qs_ot_env(1) for driving all output and the minimization in case of LSD
277 70392 : qs_ot_env(1)%etotal = energy + ener_nondiag
278 :
279 70392 : CALL ot_mini(qs_ot_env, matrix_dedc_scaled)
280 :
281 70392 : delta = qs_ot_env(1)%delta
282 70392 : energy_only = qs_ot_env(1)%energy_only
283 :
284 : ! generate the orbitals using the new matrix_x
285 151969 : DO ispin = 1, SIZE(qs_ot_env)
286 81577 : CALL get_mo_set(mo_set=mo_array(ispin), mo_coeff_b=mo_coeff)
287 81577 : CALL dbcsr_get_info(mo_coeff, nfullrows_total=n, nfullcols_total=k)
288 151969 : SELECT CASE (qs_ot_env(1)%settings%ot_algorithm)
289 : CASE ("TOD")
290 76971 : IF (ASSOCIATED(matrix_s)) THEN
291 : CALL dbcsr_multiply('N', 'N', 1.0_dp, matrix_s, qs_ot_env(ispin)%matrix_x, &
292 57701 : 0.0_dp, qs_ot_env(ispin)%matrix_sx)
293 : ELSE
294 19270 : CALL dbcsr_copy(qs_ot_env(ispin)%matrix_sx, qs_ot_env(ispin)%matrix_x)
295 : END IF
296 76971 : CALL qs_ot_get_p(qs_ot_env(ispin)%matrix_x, qs_ot_env(ispin)%matrix_sx, qs_ot_env(ispin))
297 76971 : CALL qs_ot_get_orbitals(mo_coeff, qs_ot_env(ispin)%matrix_x, qs_ot_env(ispin))
298 : CASE ("REF")
299 : CALL qs_ot_get_orbitals_ref(mo_coeff, matrix_s, qs_ot_env(ispin)%matrix_x, &
300 : qs_ot_env(ispin)%matrix_sx, qs_ot_env(ispin)%matrix_gx_old, &
301 4606 : qs_ot_env(ispin)%matrix_dx, qs_ot_env(ispin), qs_ot_env(1))
302 : CASE DEFAULT
303 81577 : CPABORT("Algorithm not yet implemented")
304 : END SELECT
305 : END DO
306 :
307 70392 : IF (qs_ot_env(1)%restricted) THEN
308 902 : CALL mo_set_restrict(mo_array, convert_dbcsr=.TRUE.)
309 : END IF
310 : !
311 : ! obtain the new set of OT eigenvalues and set the occupations accordingly
312 : !
313 70392 : IF (qs_ot_env(1)%settings%do_ener) THEN
314 0 : DO ispin = 1, SIZE(mo_array)
315 0 : mo_array(ispin)%eigenvalues = qs_ot_env(ispin)%ener_x
316 : CALL set_mo_occupation(mo_set=mo_array(ispin), &
317 0 : smear=smear)
318 : END DO
319 : END IF
320 :
321 : ! cleanup
322 152871 : DO ispin = 1, SIZE(scaling_factor)
323 152871 : DEALLOCATE (scaling_factor(ispin)%array)
324 : END DO
325 70392 : DEALLOCATE (scaling_factor)
326 70392 : IF (qs_ot_env(1)%settings%do_ener) THEN
327 0 : DO ispin = 1, SIZE(expectation_values)
328 0 : DEALLOCATE (expectation_values(ispin)%array)
329 : END DO
330 0 : DEALLOCATE (expectation_values)
331 : END IF
332 70392 : DEALLOCATE (occupation_numbers)
333 151969 : DO ispin = 1, SIZE(matrix_dedc_scaled)
334 81577 : CALL dbcsr_release(matrix_dedc_scaled(ispin)%matrix)
335 151969 : DEALLOCATE (matrix_dedc_scaled(ispin)%matrix)
336 : END DO
337 70392 : DEALLOCATE (matrix_dedc_scaled)
338 :
339 70392 : CALL timestop(handle)
340 :
341 140784 : END SUBROUTINE ot_scf_mini
342 : !
343 : ! initialises qs_ot_env so that mo_coeff is the current point
344 : ! and that the mimizization can be started.
345 : !
346 : ! **************************************************************************************************
347 : !> \brief ...
348 : !> \param mo_array ...
349 : !> \param matrix_s ...
350 : !> \param qs_ot_env ...
351 : !> \param matrix_ks ...
352 : !> \param broyden_adaptive_sigma ...
353 : ! **************************************************************************************************
354 6689 : SUBROUTINE ot_scf_init(mo_array, matrix_s, qs_ot_env, matrix_ks, broyden_adaptive_sigma)
355 :
356 : TYPE(mo_set_type), DIMENSION(:), INTENT(IN) :: mo_array
357 : TYPE(dbcsr_type), POINTER :: matrix_s
358 : TYPE(qs_ot_type), DIMENSION(:), POINTER :: qs_ot_env
359 : TYPE(dbcsr_type), POINTER :: matrix_ks
360 : REAL(KIND=dp) :: broyden_adaptive_sigma
361 :
362 : CHARACTER(len=*), PARAMETER :: routineN = 'ot_scf_init'
363 :
364 : INTEGER :: handle, ispin, k, n, nspin
365 : LOGICAL :: is_equal
366 : TYPE(cp_fm_type), POINTER :: mo_coeff_fm
367 : TYPE(dbcsr_type), POINTER :: mo_coeff
368 :
369 6689 : CALL timeset(routineN, handle)
370 :
371 14703 : DO ispin = 1, SIZE(mo_array)
372 14703 : IF (.NOT. ASSOCIATED(mo_array(ispin)%mo_coeff_b)) THEN
373 0 : CPABORT("Shouldn't get there")
374 : ! we do ot then copy fm to dbcsr
375 : ! allocate that somewhere else ! fm -> dbcsr
376 0 : CALL dbcsr_init_p(mo_array(ispin)%mo_coeff_b)
377 : CALL cp_dbcsr_m_by_n_from_row_template(mo_array(ispin)%mo_coeff_b, template=matrix_ks, &
378 : n=mo_array(ispin)%nmo, &
379 0 : sym=dbcsr_type_no_symmetry)
380 : END IF
381 : END DO
382 :
383 : ! *** set a history for broyden
384 14611 : DO ispin = 1, SIZE(qs_ot_env)
385 14611 : qs_ot_env(ispin)%broyden_adaptive_sigma = broyden_adaptive_sigma
386 : END DO
387 :
388 : ! **** SCP
389 : ! **** SCP
390 : ! adapted for work with the restricted keyword
391 6689 : nspin = SIZE(qs_ot_env)
392 :
393 14611 : DO ispin = 1, nspin
394 :
395 7922 : NULLIFY (mo_coeff)
396 7922 : CALL get_mo_set(mo_set=mo_array(ispin), mo_coeff_b=mo_coeff, mo_coeff=mo_coeff_fm)
397 7922 : CALL copy_fm_to_dbcsr(mo_coeff_fm, mo_coeff) !fm -> dbcsr
398 :
399 7922 : CALL dbcsr_get_info(mo_coeff, nfullrows_total=n, nfullcols_total=k)
400 :
401 : ! allocate
402 7922 : CALL qs_ot_allocate(qs_ot_env(ispin), matrix_ks, mo_coeff_fm%matrix_struct)
403 :
404 : ! set c0,sc0
405 7922 : CALL dbcsr_copy(qs_ot_env(ispin)%matrix_c0, mo_coeff)
406 7922 : IF (ASSOCIATED(matrix_s)) THEN
407 : CALL dbcsr_multiply('N', 'N', 1.0_dp, matrix_s, qs_ot_env(ispin)%matrix_c0, &
408 6752 : 0.0_dp, qs_ot_env(ispin)%matrix_sc0)
409 : ELSE
410 1170 : CALL dbcsr_copy(qs_ot_env(ispin)%matrix_sc0, qs_ot_env(ispin)%matrix_c0)
411 : END IF
412 :
413 : ! init
414 7922 : CALL qs_ot_init(qs_ot_env(ispin))
415 :
416 : ! set x
417 7922 : CALL dbcsr_set(qs_ot_env(ispin)%matrix_x, 0.0_dp)
418 7922 : CALL dbcsr_set(qs_ot_env(ispin)%matrix_sx, 0.0_dp)
419 :
420 7922 : IF (qs_ot_env(ispin)%settings%do_rotation) THEN
421 212 : CALL dbcsr_set(qs_ot_env(ispin)%rot_mat_x, 0.0_dp)
422 : END IF
423 :
424 7922 : IF (qs_ot_env(ispin)%settings%do_ener) THEN
425 0 : is_equal = SIZE(qs_ot_env(ispin)%ener_x) == SIZE(mo_array(ispin)%eigenvalues)
426 0 : CPASSERT(is_equal)
427 0 : qs_ot_env(ispin)%ener_x = mo_array(ispin)%eigenvalues
428 : END IF
429 :
430 14611 : SELECT CASE (qs_ot_env(1)%settings%ot_algorithm)
431 : CASE ("TOD")
432 : ! get c
433 6846 : CALL qs_ot_get_p(qs_ot_env(ispin)%matrix_x, qs_ot_env(ispin)%matrix_sx, qs_ot_env(ispin))
434 : CASE ("REF")
435 1076 : CALL dbcsr_copy(qs_ot_env(ispin)%matrix_x, qs_ot_env(ispin)%matrix_c0)
436 1076 : CALL dbcsr_copy(qs_ot_env(ispin)%matrix_sx, qs_ot_env(ispin)%matrix_sc0)
437 : CASE DEFAULT
438 7922 : CPABORT("Algorithm not yet implemented")
439 : END SELECT
440 :
441 : END DO
442 6689 : CALL timestop(handle)
443 6689 : END SUBROUTINE ot_scf_init
444 :
445 : ! **************************************************************************************************
446 : !> \brief ...
447 : !> \param qs_ot_env ...
448 : ! **************************************************************************************************
449 7922 : SUBROUTINE ot_scf_destroy(qs_ot_env)
450 :
451 : TYPE(qs_ot_type) :: qs_ot_env
452 :
453 7922 : CALL qs_ot_destroy(qs_ot_env)
454 :
455 7922 : END SUBROUTINE ot_scf_destroy
456 :
457 : END MODULE qs_ot_scf
458 :
|