Line data Source code
1 : !--------------------------------------------------------------------------------------------------!
2 : ! CP2K: A general program to perform molecular dynamics simulations !
3 : ! Copyright 2000-2026 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 14330 : 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 7165 : CALL timeset(routineN, handle)
82 :
83 7165 : logger => cp_get_default_logger()
84 : output_unit = cp_print_key_unit_nr(logger, scf_section, "PRINT%PROGRAM_RUN_INFO", &
85 7165 : extension=".log")
86 :
87 : ! decide default settings
88 7165 : CALL qs_ot_settings_init(qs_ot_env(1)%settings)
89 :
90 : ! use ot input new style
91 7165 : ot_section => section_vals_get_subs_vals(scf_section, "OT")
92 7165 : CALL section_vals_get(ot_section, explicit=explicit)
93 :
94 7165 : 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 7165 : "PRINT%PROGRAM_RUN_INFO")
98 :
99 : ! copy the ot settings type so it is identical
100 7165 : nspin = SIZE(qs_ot_env)
101 8420 : DO ispin = 2, nspin
102 8420 : qs_ot_env(ispin)%settings = qs_ot_env(1)%settings
103 : END DO
104 :
105 7165 : CALL timestop(handle)
106 :
107 7165 : END SUBROUTINE ot_scf_read_input
108 :
109 : ! **************************************************************************************************
110 : !> \brief 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 : !> \param mo_array ...
115 : !> \param matrix_dedc ...
116 : !> \param smear ...
117 : !> \param matrix_s ...
118 : !> \param energy ...
119 : !> \param energy_only ...
120 : !> \param delta ...
121 : !> \param qs_ot_env ...
122 : ! **************************************************************************************************
123 75232 : SUBROUTINE ot_scf_mini(mo_array, matrix_dedc, smear, matrix_s, energy, &
124 : energy_only, delta, qs_ot_env)
125 :
126 : TYPE(mo_set_type), DIMENSION(:), INTENT(INOUT) :: mo_array
127 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_dedc
128 : TYPE(smear_type), POINTER :: smear
129 : TYPE(dbcsr_type), POINTER :: matrix_s
130 : REAL(KIND=dp) :: energy
131 : LOGICAL, INTENT(INOUT) :: energy_only
132 : REAL(KIND=dp) :: delta
133 : TYPE(qs_ot_type), DIMENSION(:), POINTER :: qs_ot_env
134 :
135 : CHARACTER(len=*), PARAMETER :: routineN = 'ot_scf_mini'
136 :
137 : INTEGER :: handle, ispin, k, n, nspin
138 : REAL(KIND=dp) :: ener_nondiag, trace
139 75232 : TYPE(cp_1d_r_p_type), ALLOCATABLE, DIMENSION(:) :: expectation_values, occupation_numbers, &
140 75232 : scaling_factor
141 : TYPE(cp_logger_type), POINTER :: logger
142 75232 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_dedc_scaled
143 : TYPE(dbcsr_type), POINTER :: mo_coeff
144 :
145 75232 : CALL timeset(routineN, handle)
146 :
147 75232 : NULLIFY (logger)
148 75232 : logger => cp_get_default_logger()
149 :
150 75232 : nspin = SIZE(mo_array)
151 :
152 313617 : ALLOCATE (occupation_numbers(nspin))
153 238385 : ALLOCATE (scaling_factor(nspin))
154 :
155 75232 : IF (qs_ot_env(1)%settings%do_ener) THEN
156 0 : ALLOCATE (expectation_values(nspin))
157 : END IF
158 :
159 163153 : DO ispin = 1, nspin
160 87921 : CALL get_mo_set(mo_set=mo_array(ispin), occupation_numbers=occupation_numbers(ispin)%array)
161 263127 : ALLOCATE (scaling_factor(ispin)%array(SIZE(occupation_numbers(ispin)%array)))
162 984336 : scaling_factor(ispin)%array = 2.0_dp*occupation_numbers(ispin)%array
163 163153 : IF (qs_ot_env(1)%settings%do_ener) THEN
164 0 : ALLOCATE (expectation_values(ispin)%array(SIZE(occupation_numbers(ispin)%array)))
165 : END IF
166 : END DO
167 :
168 : ! optimizing orbital energies somehow implies non-equivalent orbitals
169 75232 : IF (qs_ot_env(1)%settings%do_ener) THEN
170 0 : CPASSERT(qs_ot_env(1)%settings%do_rotation)
171 : END IF
172 : ! add_nondiag_energy requires do_ener
173 75232 : IF (qs_ot_env(1)%settings%add_nondiag_energy) THEN
174 0 : CPASSERT(qs_ot_env(1)%settings%do_ener)
175 : END IF
176 :
177 : ! get a rotational force
178 75232 : IF (.NOT. energy_only) THEN
179 60918 : IF (qs_ot_env(1)%settings%do_rotation) THEN
180 3220 : DO ispin = 1, SIZE(qs_ot_env)
181 1650 : CALL get_mo_set(mo_set=mo_array(ispin), mo_coeff_b=mo_coeff)
182 1650 : CALL dbcsr_get_info(mo_coeff, nfullrows_total=n, nfullcols_total=k)
183 : CALL dbcsr_multiply('T', 'N', 1.0_dp, mo_coeff, matrix_dedc(ispin)%matrix, &
184 1650 : 0.0_dp, qs_ot_env(ispin)%rot_mat_chc)
185 1650 : CALL dbcsr_copy(qs_ot_env(ispin)%matrix_buf1, qs_ot_env(ispin)%rot_mat_chc)
186 :
187 1650 : CALL dbcsr_scale_by_vector(qs_ot_env(ispin)%matrix_buf1, alpha=scaling_factor(ispin)%array, side='right')
188 : ! create the derivative of the energy wrt to rot_mat_u
189 : CALL dbcsr_multiply('N', 'N', 1.0_dp, qs_ot_env(ispin)%rot_mat_u, qs_ot_env(ispin)%matrix_buf1, &
190 4870 : 0.0_dp, qs_ot_env(ispin)%rot_mat_dedu)
191 : END DO
192 :
193 : ! here we construct the derivative of the free energy with respect to the evals
194 : ! (note that this requires the diagonal elements of chc)
195 : ! the mo occupations should in principle remain unaltered
196 1570 : IF (qs_ot_env(1)%settings%do_ener) THEN
197 0 : DO ispin = 1, SIZE(mo_array)
198 0 : CALL dbcsr_get_diag(qs_ot_env(ispin)%rot_mat_chc, expectation_values(ispin)%array)
199 0 : qs_ot_env(ispin)%ener_gx = expectation_values(ispin)%array
200 : CALL set_mo_occupation(mo_set=mo_array(ispin), &
201 0 : smear=smear, eval_deriv=qs_ot_env(ispin)%ener_gx)
202 : END DO
203 : END IF
204 :
205 : ! chc only needs to be stored in u independent form if we require add_nondiag_energy,
206 : ! which will use it in non-selfconsistent form for e.g. the linesearch
207 : ! transform C^T H C -> U C^T H C U ^ T
208 1570 : IF (qs_ot_env(1)%settings%add_nondiag_energy) THEN
209 0 : DO ispin = 1, SIZE(qs_ot_env)
210 0 : CALL dbcsr_get_info(qs_ot_env(ispin)%rot_mat_u, nfullcols_total=k)
211 : CALL dbcsr_multiply('N', 'N', 1.0_dp, qs_ot_env(ispin)%rot_mat_u, qs_ot_env(ispin)%rot_mat_chc, &
212 0 : 0.0_dp, qs_ot_env(ispin)%matrix_buf1)
213 : CALL dbcsr_multiply('N', 'T', 1.0_dp, qs_ot_env(ispin)%matrix_buf1, qs_ot_env(ispin)%rot_mat_u, &
214 0 : 0.0_dp, qs_ot_env(ispin)%rot_mat_chc)
215 : END DO
216 : END IF
217 : END IF
218 : END IF
219 :
220 : ! evaluate non-diagonal energy contribution
221 75232 : ener_nondiag = 0.0_dp
222 75232 : IF (qs_ot_env(1)%settings%add_nondiag_energy) THEN
223 0 : DO ispin = 1, SIZE(qs_ot_env)
224 : ! transform \tilde H to the current basis of C (assuming non-selfconsistent H)
225 0 : CALL dbcsr_get_info(qs_ot_env(ispin)%rot_mat_u, nfullcols_total=k)
226 : CALL dbcsr_multiply('T', 'N', 1.0_dp, qs_ot_env(ispin)%rot_mat_u, qs_ot_env(ispin)%rot_mat_chc, &
227 0 : 0.0_dp, qs_ot_env(ispin)%matrix_buf1)
228 : CALL dbcsr_multiply('N', 'N', 1.0_dp, qs_ot_env(ispin)%matrix_buf1, qs_ot_env(ispin)%rot_mat_u, &
229 0 : 0.0_dp, qs_ot_env(ispin)%matrix_buf2)
230 :
231 : ! subtract the current ener_x from the diagonal
232 0 : CALL dbcsr_get_diag(qs_ot_env(ispin)%matrix_buf2, expectation_values(ispin)%array)
233 0 : expectation_values(ispin)%array = expectation_values(ispin)%array - qs_ot_env(ispin)%ener_x
234 0 : CALL dbcsr_set_diag(qs_ot_env(ispin)%matrix_buf2, expectation_values(ispin)%array)
235 :
236 : ! get nondiag energy trace (D^T D)
237 0 : CALL dbcsr_dot(qs_ot_env(ispin)%matrix_buf2, qs_ot_env(ispin)%matrix_buf2, trace)
238 0 : ener_nondiag = ener_nondiag + 0.5_dp*qs_ot_env(1)%settings%nondiag_energy_strength*trace
239 :
240 : ! get gradient (again ignoring dependencies of H)
241 0 : IF (.NOT. energy_only) THEN
242 : ! first for the ener_x (-2*(diag(C^T H C)-ener_x))
243 : qs_ot_env(ispin)%ener_gx = qs_ot_env(ispin)%ener_gx - &
244 0 : qs_ot_env(1)%settings%nondiag_energy_strength*expectation_values(ispin)%array
245 :
246 : ! next for the rot_mat_u derivative (2 * k * \tilde H U D)
247 : CALL dbcsr_multiply('N', 'N', 1.0_dp, qs_ot_env(ispin)%rot_mat_chc, qs_ot_env(ispin)%rot_mat_u, &
248 0 : 0.0_dp, qs_ot_env(ispin)%matrix_buf1)
249 : CALL dbcsr_multiply('N', 'N', 2.0_dp*qs_ot_env(1)%settings%nondiag_energy_strength, &
250 : qs_ot_env(ispin)%matrix_buf1, qs_ot_env(ispin)%matrix_buf2, &
251 0 : 1.0_dp, qs_ot_env(ispin)%rot_mat_dedu)
252 : END IF
253 : END DO
254 : END IF
255 :
256 : ! this is kind of a hack so far (costly memory wise), we locally recreate the scaled matrix_hc, and
257 : ! use it in the following, eventually, as occupations numbers get more integrated, it should become possible
258 : ! to remove this.
259 312715 : ALLOCATE (matrix_dedc_scaled(SIZE(matrix_dedc)))
260 162251 : DO ispin = 1, SIZE(matrix_dedc)
261 87019 : ALLOCATE (matrix_dedc_scaled(ispin)%matrix)
262 87019 : CALL dbcsr_copy(matrix_dedc_scaled(ispin)%matrix, matrix_dedc(ispin)%matrix)
263 :
264 : ! as a preconditioner, one might want to scale only with a constant, not with f(i)
265 : ! for the convergence criterion, maybe take it back out
266 87019 : IF (qs_ot_env(1)%settings%occupation_preconditioner) THEN
267 0 : scaling_factor(ispin)%array = 2.0_dp
268 : END IF
269 162251 : CALL dbcsr_scale_by_vector(matrix_dedc_scaled(ispin)%matrix, alpha=scaling_factor(ispin)%array, side='right')
270 : END DO
271 :
272 : ! notice we use qs_ot_env(1) for driving all output and the minimization in case of LSD
273 75232 : qs_ot_env(1)%etotal = energy + ener_nondiag
274 :
275 75232 : CALL ot_mini(qs_ot_env, matrix_dedc_scaled)
276 :
277 75232 : delta = qs_ot_env(1)%delta
278 75232 : energy_only = qs_ot_env(1)%energy_only
279 :
280 : ! generate the orbitals using the new matrix_x
281 162251 : DO ispin = 1, SIZE(qs_ot_env)
282 87019 : CALL get_mo_set(mo_set=mo_array(ispin), mo_coeff_b=mo_coeff)
283 87019 : CALL dbcsr_get_info(mo_coeff, nfullrows_total=n, nfullcols_total=k)
284 162251 : SELECT CASE (qs_ot_env(1)%settings%ot_algorithm)
285 : CASE ("TOD")
286 82413 : IF (ASSOCIATED(matrix_s)) THEN
287 : CALL dbcsr_multiply('N', 'N', 1.0_dp, matrix_s, qs_ot_env(ispin)%matrix_x, &
288 62991 : 0.0_dp, qs_ot_env(ispin)%matrix_sx)
289 : ELSE
290 19422 : CALL dbcsr_copy(qs_ot_env(ispin)%matrix_sx, qs_ot_env(ispin)%matrix_x)
291 : END IF
292 82413 : CALL qs_ot_get_p(qs_ot_env(ispin)%matrix_x, qs_ot_env(ispin)%matrix_sx, qs_ot_env(ispin))
293 82413 : CALL qs_ot_get_orbitals(mo_coeff, qs_ot_env(ispin)%matrix_x, qs_ot_env(ispin))
294 : CASE ("REF")
295 : CALL qs_ot_get_orbitals_ref(mo_coeff, matrix_s, qs_ot_env(ispin)%matrix_x, &
296 : qs_ot_env(ispin)%matrix_sx, qs_ot_env(ispin)%matrix_gx_old, &
297 4606 : qs_ot_env(ispin)%matrix_dx, qs_ot_env(ispin), qs_ot_env(1))
298 : CASE DEFAULT
299 87019 : CPABORT("Algorithm not yet implemented")
300 : END SELECT
301 : END DO
302 :
303 75232 : IF (qs_ot_env(1)%restricted) THEN
304 902 : CALL mo_set_restrict(mo_array, convert_dbcsr=.TRUE.)
305 : END IF
306 : !
307 : ! obtain the new set of OT eigenvalues and set the occupations accordingly
308 : !
309 75232 : IF (qs_ot_env(1)%settings%do_ener) THEN
310 0 : DO ispin = 1, SIZE(mo_array)
311 0 : mo_array(ispin)%eigenvalues = qs_ot_env(ispin)%ener_x
312 : CALL set_mo_occupation(mo_set=mo_array(ispin), &
313 0 : smear=smear)
314 : END DO
315 : END IF
316 :
317 : ! cleanup
318 163153 : DO ispin = 1, SIZE(scaling_factor)
319 163153 : DEALLOCATE (scaling_factor(ispin)%array)
320 : END DO
321 75232 : DEALLOCATE (scaling_factor)
322 75232 : IF (qs_ot_env(1)%settings%do_ener) THEN
323 0 : DO ispin = 1, SIZE(expectation_values)
324 0 : DEALLOCATE (expectation_values(ispin)%array)
325 : END DO
326 0 : DEALLOCATE (expectation_values)
327 : END IF
328 75232 : DEALLOCATE (occupation_numbers)
329 162251 : DO ispin = 1, SIZE(matrix_dedc_scaled)
330 87019 : CALL dbcsr_release(matrix_dedc_scaled(ispin)%matrix)
331 162251 : DEALLOCATE (matrix_dedc_scaled(ispin)%matrix)
332 : END DO
333 75232 : DEALLOCATE (matrix_dedc_scaled)
334 :
335 75232 : CALL timestop(handle)
336 :
337 150464 : END SUBROUTINE ot_scf_mini
338 :
339 : ! **************************************************************************************************
340 : !> \brief initialises qs_ot_env so that mo_coeff is the current point
341 : !> and that the minization can be started.
342 : !> \param mo_array ...
343 : !> \param matrix_s ...
344 : !> \param qs_ot_env ...
345 : !> \param matrix_ks ...
346 : !> \param broyden_adaptive_sigma ...
347 : ! **************************************************************************************************
348 7165 : SUBROUTINE ot_scf_init(mo_array, matrix_s, qs_ot_env, matrix_ks, broyden_adaptive_sigma)
349 :
350 : TYPE(mo_set_type), DIMENSION(:), INTENT(IN) :: mo_array
351 : TYPE(dbcsr_type), POINTER :: matrix_s
352 : TYPE(qs_ot_type), DIMENSION(:), POINTER :: qs_ot_env
353 : TYPE(dbcsr_type), POINTER :: matrix_ks
354 : REAL(KIND=dp) :: broyden_adaptive_sigma
355 :
356 : CHARACTER(len=*), PARAMETER :: routineN = 'ot_scf_init'
357 :
358 : INTEGER :: handle, ispin, k, n, nspin
359 : LOGICAL :: is_equal
360 : TYPE(cp_fm_type), POINTER :: mo_coeff_fm
361 : TYPE(dbcsr_type), POINTER :: mo_coeff
362 :
363 7165 : CALL timeset(routineN, handle)
364 :
365 15677 : DO ispin = 1, SIZE(mo_array)
366 15677 : IF (.NOT. ASSOCIATED(mo_array(ispin)%mo_coeff_b)) THEN
367 0 : CPABORT("Shouldn't get there")
368 : ! we do ot then copy fm to dbcsr
369 : ! allocate that somewhere else ! fm -> dbcsr
370 0 : CALL dbcsr_init_p(mo_array(ispin)%mo_coeff_b)
371 : CALL cp_dbcsr_m_by_n_from_row_template(mo_array(ispin)%mo_coeff_b, template=matrix_ks, &
372 : n=mo_array(ispin)%nmo, &
373 0 : sym=dbcsr_type_no_symmetry)
374 : END IF
375 : END DO
376 :
377 : ! *** set a history for broyden
378 15585 : DO ispin = 1, SIZE(qs_ot_env)
379 15585 : qs_ot_env(ispin)%broyden_adaptive_sigma = broyden_adaptive_sigma
380 : END DO
381 :
382 : ! **** SCP
383 : ! **** SCP
384 : ! adapted for work with the restricted keyword
385 7165 : nspin = SIZE(qs_ot_env)
386 :
387 15585 : DO ispin = 1, nspin
388 :
389 8420 : NULLIFY (mo_coeff)
390 8420 : CALL get_mo_set(mo_set=mo_array(ispin), mo_coeff_b=mo_coeff, mo_coeff=mo_coeff_fm)
391 8420 : CALL copy_fm_to_dbcsr(mo_coeff_fm, mo_coeff) !fm -> dbcsr
392 :
393 8420 : CALL dbcsr_get_info(mo_coeff, nfullrows_total=n, nfullcols_total=k)
394 :
395 : ! allocate
396 8420 : CALL qs_ot_allocate(qs_ot_env(ispin), matrix_ks, mo_coeff_fm%matrix_struct)
397 :
398 : ! set c0,sc0
399 8420 : CALL dbcsr_copy(qs_ot_env(ispin)%matrix_c0, mo_coeff)
400 8420 : IF (ASSOCIATED(matrix_s)) THEN
401 : CALL dbcsr_multiply('N', 'N', 1.0_dp, matrix_s, qs_ot_env(ispin)%matrix_c0, &
402 7230 : 0.0_dp, qs_ot_env(ispin)%matrix_sc0)
403 : ELSE
404 1190 : CALL dbcsr_copy(qs_ot_env(ispin)%matrix_sc0, qs_ot_env(ispin)%matrix_c0)
405 : END IF
406 :
407 : ! init
408 8420 : CALL qs_ot_init(qs_ot_env(ispin))
409 :
410 : ! set x
411 8420 : CALL dbcsr_set(qs_ot_env(ispin)%matrix_x, 0.0_dp)
412 8420 : CALL dbcsr_set(qs_ot_env(ispin)%matrix_sx, 0.0_dp)
413 :
414 8420 : IF (qs_ot_env(ispin)%settings%do_rotation) THEN
415 216 : CALL dbcsr_set(qs_ot_env(ispin)%rot_mat_x, 0.0_dp)
416 : END IF
417 :
418 8420 : IF (qs_ot_env(ispin)%settings%do_ener) THEN
419 0 : is_equal = SIZE(qs_ot_env(ispin)%ener_x) == SIZE(mo_array(ispin)%eigenvalues)
420 0 : CPASSERT(is_equal)
421 0 : qs_ot_env(ispin)%ener_x = mo_array(ispin)%eigenvalues
422 : END IF
423 :
424 15585 : SELECT CASE (qs_ot_env(1)%settings%ot_algorithm)
425 : CASE ("TOD")
426 : ! get c
427 7344 : CALL qs_ot_get_p(qs_ot_env(ispin)%matrix_x, qs_ot_env(ispin)%matrix_sx, qs_ot_env(ispin))
428 : CASE ("REF")
429 1076 : CALL dbcsr_copy(qs_ot_env(ispin)%matrix_x, qs_ot_env(ispin)%matrix_c0)
430 1076 : CALL dbcsr_copy(qs_ot_env(ispin)%matrix_sx, qs_ot_env(ispin)%matrix_sc0)
431 : CASE DEFAULT
432 8420 : CPABORT("Algorithm not yet implemented")
433 : END SELECT
434 :
435 : END DO
436 7165 : CALL timestop(handle)
437 7165 : END SUBROUTINE ot_scf_init
438 :
439 : ! **************************************************************************************************
440 : !> \brief ...
441 : !> \param qs_ot_env ...
442 : ! **************************************************************************************************
443 8420 : SUBROUTINE ot_scf_destroy(qs_ot_env)
444 :
445 : TYPE(qs_ot_type) :: qs_ot_env
446 :
447 8420 : CALL qs_ot_destroy(qs_ot_env)
448 :
449 8420 : END SUBROUTINE ot_scf_destroy
450 :
451 : END MODULE qs_ot_scf
452 :
|