(git:31b3539)
Loading...
Searching...
No Matches
qs_ot_eigensolver.F
Go to the documentation of this file.
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 an eigen-space solver for the generalised symmetric eigenvalue problem
10!> for sparse matrices, needing only multiplications
11!> \author Joost VandeVondele (25.08.2002)
12! **************************************************************************************************
15 USE cp_cfm_diag, ONLY: cp_cfm_heevd
16 USE cp_cfm_types, ONLY: cp_cfm_create,&
21 USE cp_dbcsr_api, ONLY: &
23 dbcsr_scale, dbcsr_set, dbcsr_type, dbcsr_type_no_symmetry
34 USE cp_fm_types, ONLY: cp_fm_create,&
47 USE kinds, ONLY: dp
48 USE mathconstants, ONLY: z_one,&
49 z_zero
62 USE qs_mo_types, ONLY: mo_set_type
63 USE qs_ot, ONLY: qs_ot_get_orbitals,&
70 USE qs_ot_minimizer, ONLY: ot_mini
71 USE qs_ot_types, ONLY: qs_ot_allocate,&
78#include "./base/base_uses.f90"
79
80 IMPLICIT NONE
81 PRIVATE
82
83! *** Global parameters ***
84
85 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_ot_eigensolver'
86
87! *** Public subroutines ***
88
90
91CONTAINS
92
93! on input c contains the initial guess (should not be zero !)
94! on output c spans the subspace
95! **************************************************************************************************
96!> \brief ...
97!> \param matrix_h ...
98!> \param matrix_s ...
99!> \param matrix_orthogonal_space_fm ...
100!> \param matrix_c_fm ...
101!> \param preconditioner ...
102!> \param eps_gradient ...
103!> \param iter_max ...
104!> \param size_ortho_space ...
105!> \param silent ...
106!> \param ot_settings ...
107! **************************************************************************************************
108 SUBROUTINE ot_eigensolver(matrix_h, matrix_s, matrix_orthogonal_space_fm, &
109 matrix_c_fm, preconditioner, eps_gradient, &
110 iter_max, size_ortho_space, silent, ot_settings)
111
112 TYPE(dbcsr_type), POINTER :: matrix_h, matrix_s
113 TYPE(cp_fm_type), INTENT(IN), OPTIONAL :: matrix_orthogonal_space_fm
114 TYPE(cp_fm_type), INTENT(INOUT) :: matrix_c_fm
115 TYPE(preconditioner_type), OPTIONAL, POINTER :: preconditioner
116 REAL(kind=dp) :: eps_gradient
117 INTEGER, INTENT(IN) :: iter_max
118 INTEGER, INTENT(IN), OPTIONAL :: size_ortho_space
119 LOGICAL, INTENT(IN), OPTIONAL :: silent
120 TYPE(qs_ot_settings_type), INTENT(IN), OPTIONAL :: ot_settings
121
122 CHARACTER(len=*), PARAMETER :: routinen = 'ot_eigensolver'
123 INTEGER, PARAMETER :: max_iter_inner_loop = 40
124 REAL(kind=dp), PARAMETER :: rone = 1.0_dp, rzero = 0.0_dp
125
126 INTEGER :: handle, ieigensolver, iter_total, k, n, &
127 ortho_k, ortho_space_k, output_unit
128 LOGICAL :: energy_only, my_silent, ortho, &
129 ref_algorithm
130 REAL(kind=dp) :: delta, energy
131 TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_hc
132 TYPE(dbcsr_type), POINTER :: matrix_buf1_ortho, matrix_buf2_ortho, &
133 matrix_c, matrix_orthogonal_space, &
134 matrix_os_ortho, matrix_s_ortho
135 TYPE(qs_ot_type), DIMENSION(:), POINTER :: qs_ot_env
136
137 CALL timeset(routinen, handle)
138
139 output_unit = cp_logger_get_default_io_unit()
140
141 IF (PRESENT(silent)) THEN
142 my_silent = silent
143 ELSE
144 my_silent = .false.
145 END IF
146
147 NULLIFY (matrix_c) ! fm->dbcsr
148
149 CALL cp_fm_get_info(matrix_c_fm, nrow_global=n, ncol_global=k) ! fm->dbcsr
150 ALLOCATE (matrix_c)
151 ref_algorithm = .false.
152 IF (PRESENT(ot_settings)) ref_algorithm = ot_settings%ot_algorithm == "REF"
153 IF (ref_algorithm) THEN
154 CALL dbcsr_init_p(matrix_c)
155 CALL cp_dbcsr_m_by_n_from_row_template(matrix_c, template=matrix_h, n=k, &
156 sym=dbcsr_type_no_symmetry)
157 CALL copy_fm_to_dbcsr(matrix_c_fm, matrix_c)
158 ELSE
159 CALL cp_fm_to_dbcsr_row_template(matrix_c, fm_in=matrix_c_fm, template=matrix_h)
160 END IF
161
162 iter_total = 0
163
164 outer_scf: DO
165
166 NULLIFY (qs_ot_env)
167
168 NULLIFY (matrix_s_ortho)
169 NULLIFY (matrix_os_ortho)
170 NULLIFY (matrix_buf1_ortho)
171 NULLIFY (matrix_buf2_ortho)
172 NULLIFY (matrix_orthogonal_space)
173
174 ALLOCATE (qs_ot_env(1))
175 ALLOCATE (matrix_hc(1))
176 NULLIFY (matrix_hc(1)%matrix)
177 CALL dbcsr_init_p(matrix_hc(1)%matrix)
178
179 ortho = .false.
180 IF (PRESENT(matrix_orthogonal_space_fm)) ortho = .true.
181
182 ! decide settings
183 IF (PRESENT(ot_settings)) THEN
184 qs_ot_env(1)%settings = ot_settings
185 ELSE
186 CALL qs_ot_settings_init(qs_ot_env(1)%settings)
187 ! overwrite defaults
188 qs_ot_env(1)%settings%ds_min = 0.10_dp
189 END IF
190
191 IF (ortho) THEN
192 ALLOCATE (matrix_orthogonal_space)
193 CALL cp_fm_to_dbcsr_row_template(matrix_orthogonal_space, fm_in=matrix_orthogonal_space_fm, template=matrix_h)
194 CALL cp_fm_get_info(matrix_orthogonal_space_fm, ncol_global=ortho_space_k)
195
196 IF (PRESENT(size_ortho_space)) ortho_space_k = size_ortho_space
197 ortho_k = ortho_space_k + k
198 ELSE
199 ortho_k = k
200 END IF
201
202 ! allocate
203 CALL qs_ot_allocate(qs_ot_env(1), matrix_s, matrix_c_fm%matrix_struct, ortho_k=ortho_k)
204 IF (ref_algorithm) THEN
205 CALL dbcsr_copy(matrix_hc(1)%matrix, qs_ot_env(1)%matrix_x, 'matrix_hc')
206 ELSE
207 CALL dbcsr_copy(matrix_hc(1)%matrix, matrix_c, 'matrix_hc')
208 END IF
209
210 IF (ortho) THEN
211 ! construct an initial guess that is orthogonal to matrix_orthogonal_space
212
213 CALL dbcsr_init_p(matrix_s_ortho)
214 CALL dbcsr_copy(matrix_s_ortho, matrix_orthogonal_space, name="matrix_s_ortho")
215
216 CALL dbcsr_init_p(matrix_os_ortho)
217 CALL cp_dbcsr_m_by_n_from_template(matrix_os_ortho, template=matrix_h, m=ortho_space_k, n=ortho_space_k, &
218 sym=dbcsr_type_no_symmetry)
219
220 CALL dbcsr_init_p(matrix_buf1_ortho)
221 CALL cp_dbcsr_m_by_n_from_template(matrix_buf1_ortho, template=matrix_h, m=ortho_space_k, n=k, &
222 sym=dbcsr_type_no_symmetry)
223
224 CALL dbcsr_init_p(matrix_buf2_ortho)
225 CALL cp_dbcsr_m_by_n_from_template(matrix_buf2_ortho, template=matrix_h, m=ortho_space_k, n=k, &
226 sym=dbcsr_type_no_symmetry)
227
228 CALL dbcsr_multiply('N', 'N', 1.0_dp, matrix_s, matrix_orthogonal_space, &
229 0.0_dp, matrix_s_ortho)
230 CALL dbcsr_multiply('T', 'N', rone, matrix_s_ortho, matrix_s_ortho, &
231 rzero, matrix_os_ortho)
232
233 CALL cp_dbcsr_cholesky_decompose(matrix_os_ortho, &
234 para_env=qs_ot_env(1)%para_env, blacs_env=qs_ot_env(1)%blacs_env)
235 CALL cp_dbcsr_cholesky_invert(matrix_os_ortho, &
236 para_env=qs_ot_env(1)%para_env, blacs_env=qs_ot_env(1)%blacs_env, &
237 uplo_to_full=.true.)
238
239 CALL dbcsr_multiply('T', 'N', rone, matrix_s_ortho, matrix_c, &
240 rzero, matrix_buf1_ortho)
241 CALL dbcsr_multiply('N', 'N', rone, matrix_os_ortho, matrix_buf1_ortho, &
242 rzero, matrix_buf2_ortho)
243 CALL dbcsr_multiply('N', 'N', -rone, matrix_s_ortho, matrix_buf2_ortho, &
244 rone, matrix_c)
245
246 ! make matrix_c0 an orthogonal basis, matrix_c contains sc0
247 CALL dbcsr_copy(qs_ot_env(1)%matrix_c0, matrix_c)
248 CALL dbcsr_multiply('N', 'N', 1.0_dp, matrix_s, qs_ot_env(1)%matrix_c0, &
249 0.0_dp, matrix_c)
250
251 CALL make_basis_sv(qs_ot_env(1)%matrix_c0, k, matrix_c, &
252 qs_ot_env(1)%para_env, qs_ot_env(1)%blacs_env)
253
254 ! copy sc0 and matrix_s_ortho in qs_ot_env(1)%matrix_sc0
255 !CALL dbcsr_copy_columns(qs_ot_env(1)%matrix_sc0,matrix_s_ortho,ortho_space_k,1,1)
256 CALL dbcsr_copy_columns_hack(qs_ot_env(1)%matrix_sc0, matrix_s_ortho, ortho_space_k, 1, 1, &
257 para_env=qs_ot_env(1)%para_env, blacs_env=qs_ot_env(1)%blacs_env)
258 !CALL dbcsr_copy_columns(qs_ot_env(1)%matrix_sc0,matrix_c,k,1,ortho_space_k+1)
259 CALL dbcsr_copy_columns_hack(qs_ot_env(1)%matrix_sc0, matrix_c, k, 1, ortho_space_k + 1, &
260 para_env=qs_ot_env(1)%para_env, blacs_env=qs_ot_env(1)%blacs_env)
261
262 CALL dbcsr_release_p(matrix_buf1_ortho)
263 CALL dbcsr_release_p(matrix_buf2_ortho)
264 CALL dbcsr_release_p(matrix_os_ortho)
265 CALL dbcsr_release_p(matrix_s_ortho)
266
267 ELSE
268
269 ! set c0,sc0
270 CALL dbcsr_copy(qs_ot_env(1)%matrix_c0, matrix_c)
271 CALL dbcsr_multiply('N', 'N', 1.0_dp, matrix_s, qs_ot_env(1)%matrix_c0, &
272 0.0_dp, qs_ot_env(1)%matrix_sc0)
273
274 CALL make_basis_sv(qs_ot_env(1)%matrix_c0, k, qs_ot_env(1)%matrix_sc0, &
275 qs_ot_env(1)%para_env, qs_ot_env(1)%blacs_env)
276 END IF
277
278 ! init
279 CALL qs_ot_init(qs_ot_env(1))
280 energy_only = qs_ot_env(1)%energy_only
281
282 SELECT CASE (qs_ot_env(1)%settings%ot_algorithm)
283 CASE ("TOD")
284 CALL dbcsr_set(qs_ot_env(1)%matrix_x, 0.0_dp)
285 CALL dbcsr_set(qs_ot_env(1)%matrix_sx, 0.0_dp)
286 CALL qs_ot_get_p(qs_ot_env(1)%matrix_x, qs_ot_env(1)%matrix_sx, qs_ot_env(1))
287 CALL qs_ot_get_orbitals(matrix_c, qs_ot_env(1)%matrix_x, qs_ot_env(1))
288 CASE ("REF")
289 CALL dbcsr_copy(qs_ot_env(1)%matrix_x, qs_ot_env(1)%matrix_c0)
290 CALL dbcsr_copy(qs_ot_env(1)%matrix_sx, qs_ot_env(1)%matrix_sc0)
291 CALL dbcsr_copy(matrix_c, qs_ot_env(1)%matrix_c0)
292 CASE DEFAULT
293 cpabort("OT eigensolver supports ALGORITHM STRICT or IRAC")
294 END SELECT
295
296 ! if present preconditioner, use it
297
298 IF (PRESENT(preconditioner)) THEN
299 IF (ASSOCIATED(preconditioner)) THEN
301 CALL qs_ot_new_preconditioner(qs_ot_env(1), preconditioner)
302 ELSE
303 ! we should presumably make one
304 END IF
305 END IF
306 END IF
307
308 ! *** Eigensolver loop ***
309 ieigensolver = 0
310 eigensolver_loop: DO
311
312 ieigensolver = ieigensolver + 1
313 iter_total = iter_total + 1
314
315 ! the energy is cHc, the gradient is 2*H*c
316 CALL dbcsr_multiply('N', 'N', 1.0_dp, matrix_h, matrix_c, &
317 0.0_dp, matrix_hc(1)%matrix)
318 CALL dbcsr_dot(matrix_c, matrix_hc(1)%matrix, energy)
319 IF (.NOT. energy_only) THEN
320 CALL dbcsr_scale(matrix_hc(1)%matrix, 2.0_dp)
321 END IF
322
323 qs_ot_env(1)%etotal = energy
324 CALL ot_mini(qs_ot_env, matrix_hc)
325 delta = qs_ot_env(1)%delta
326 energy_only = qs_ot_env(1)%energy_only
327
328 SELECT CASE (qs_ot_env(1)%settings%ot_algorithm)
329 CASE ("TOD")
330 CALL dbcsr_multiply('N', 'N', 1.0_dp, matrix_s, qs_ot_env(1)%matrix_x, &
331 0.0_dp, qs_ot_env(1)%matrix_sx)
332 CALL qs_ot_get_p(qs_ot_env(1)%matrix_x, qs_ot_env(1)%matrix_sx, qs_ot_env(1))
333 CALL qs_ot_get_orbitals(matrix_c, qs_ot_env(1)%matrix_x, qs_ot_env(1))
334 CASE ("REF")
335 CALL qs_ot_get_orbitals_ref(matrix_c, matrix_s, qs_ot_env(1)%matrix_x, &
336 qs_ot_env(1)%matrix_sx, qs_ot_env(1)%matrix_gx_old, &
337 qs_ot_env(1)%matrix_dx, qs_ot_env(1), qs_ot_env(1))
338 END SELECT
339
340 ! exit on convergence or if maximum of inner loop cycles is reached
341 IF (delta < eps_gradient .OR. ieigensolver >= max_iter_inner_loop) EXIT eigensolver_loop
342 ! exit if total number of steps is reached, but not during a line search step
343 IF (iter_total >= iter_max .AND. qs_ot_env(1)%OT_METHOD_FULL /= "OT LS") EXIT eigensolver_loop
344
345 END DO eigensolver_loop
346
347 CALL qs_ot_destroy(qs_ot_env(1))
348 DEALLOCATE (qs_ot_env)
349 CALL dbcsr_release_p(matrix_hc(1)%matrix)
350 DEALLOCATE (matrix_hc)
351 CALL dbcsr_release_p(matrix_orthogonal_space)
352
353 IF (delta < eps_gradient) THEN
354 IF ((output_unit > 0) .AND. .NOT. my_silent) THEN
355 WRITE (unit=output_unit, fmt="(T2,A,I0,A)") &
356 "OT| Eigensolver reached convergence in ", iter_total, " iterations"
357 END IF
358 EXIT outer_scf
359 END IF
360 IF (iter_total >= iter_max) THEN
361 IF (output_unit > 0) THEN
362 IF (my_silent) THEN
363 WRITE (output_unit, "(A,T60,E20.10)") " WARNING OT eigensolver did not converge: current gradient", delta
364 ELSE
365 WRITE (output_unit, *) "WARNING : did not converge in ot_eigensolver"
366 WRITE (output_unit, *) "number of iterations ", iter_total, " exceeded maximum"
367 WRITE (output_unit, *) "current gradient / target gradient", delta, " / ", eps_gradient
368 END IF
369 END IF
370 EXIT outer_scf
371 END IF
372
373 END DO outer_scf
374
375 CALL copy_dbcsr_to_fm(matrix_c, matrix_c_fm) ! fm->dbcsr
376 CALL dbcsr_release_p(matrix_c) ! fm->dbcsr
377
378 CALL timestop(handle)
379
380 END SUBROUTINE ot_eigensolver
381
382! **************************************************************************************************
383!> \brief solve a fixed complex Hermitian generalized eigenproblem by OT
384!> \param matrix_h real part of H(k)
385!> \param matrix_h_im imaginary part of H(k)
386!> \param matrix_s real part of S(k)
387!> \param matrix_s_im imaginary part of S(k)
388!> \param matrix_c_cfm complex orbital coefficients
389!> \param preconditioner optional complex k-point preconditioner
390!> \param eps_gradient requested OT gradient accuracy
391!> \param iter_max maximum number of OT iterations
392!> \param eigenvalues ...
393!> \param silent suppress successful convergence output
394!> \param ot_settings OT algorithm and minimizer settings
395!> \param matrix_t ...
396!> \param matrix_t_im ...
397!> \param mo_set ...
398! **************************************************************************************************
399 SUBROUTINE ot_eigensolver_complex(matrix_h, matrix_h_im, matrix_s, matrix_s_im, &
400 matrix_c_cfm, preconditioner, &
401 eps_gradient, iter_max, eigenvalues, silent, ot_settings, &
402 matrix_t, matrix_t_im, mo_set)
403
404 TYPE(dbcsr_type), POINTER :: matrix_h, matrix_h_im, matrix_s, &
405 matrix_s_im
406 TYPE(cp_cfm_type), INTENT(INOUT) :: matrix_c_cfm
407 TYPE(preconditioner_type), OPTIONAL, POINTER :: preconditioner
408 REAL(kind=dp), INTENT(IN) :: eps_gradient
409 INTEGER, INTENT(IN) :: iter_max
410 REAL(kind=dp), DIMENSION(:), INTENT(OUT), OPTIONAL :: eigenvalues
411 LOGICAL, INTENT(IN), OPTIONAL :: silent
412 TYPE(qs_ot_settings_type), INTENT(IN), OPTIONAL :: ot_settings
413 TYPE(dbcsr_type), OPTIONAL, POINTER :: matrix_t, matrix_t_im
414 TYPE(mo_set_type), INTENT(IN), OPTIONAL :: mo_set
415
416 CHARACTER(len=*), PARAMETER :: routinen = 'ot_eigensolver_complex'
417 INTEGER, PARAMETER :: max_iter_inner_loop = 40
418
419 INTEGER :: handle, ieigensolver, iter_total, k, n, &
420 output_unit
421 LOGICAL :: energy_only, my_silent, &
422 preconditioner_rejected
423 REAL(kind=dp) :: delta, energy_im, energy_re
424 TYPE(cp_fm_type) :: matrix_c_fm, matrix_c_fm_im
425 TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_hc, matrix_hc_im
426 TYPE(dbcsr_type), POINTER :: matrix_c, matrix_c_im, matrix_tmp
427 TYPE(preconditioner_type), POINTER :: local_preconditioner
428 TYPE(qs_ot_type), DIMENSION(:), POINTER :: qs_ot_env
429
430 CALL timeset(routinen, handle)
431 output_unit = cp_logger_get_default_io_unit()
432 my_silent = .false.
433 IF (PRESENT(silent)) my_silent = silent
434 NULLIFY (local_preconditioner)
435
436 CALL cp_fm_create(matrix_c_fm, matrix_c_cfm%matrix_struct)
437 CALL cp_fm_create(matrix_c_fm_im, matrix_c_cfm%matrix_struct)
438 CALL cp_cfm_to_fm(matrix_c_cfm, matrix_c_fm, matrix_c_fm_im)
439 CALL cp_fm_get_info(matrix_c_fm, nrow_global=n, ncol_global=k)
440 cpassert(n > 0 .AND. k > 0)
441 ALLOCATE (matrix_c, matrix_c_im, matrix_tmp)
442 CALL dbcsr_init_p(matrix_c)
443 CALL cp_dbcsr_m_by_n_from_row_template(matrix_c, template=matrix_h, n=k, &
444 sym=dbcsr_type_no_symmetry)
445 CALL dbcsr_init_p(matrix_c_im)
446 CALL cp_dbcsr_m_by_n_from_row_template(matrix_c_im, template=matrix_h, n=k, &
447 sym=dbcsr_type_no_symmetry)
448 CALL dbcsr_init_p(matrix_tmp)
449 CALL cp_dbcsr_m_by_n_from_row_template(matrix_tmp, template=matrix_h, n=k, &
450 sym=dbcsr_type_no_symmetry)
451 CALL copy_fm_to_dbcsr(matrix_c_fm, matrix_c)
452 CALL copy_fm_to_dbcsr(matrix_c_fm_im, matrix_c_im)
453
454 iter_total = 0
455 outer_scf: DO
456 ALLOCATE (qs_ot_env(1), matrix_hc(1), matrix_hc_im(1))
457 NULLIFY (matrix_hc(1)%matrix, matrix_hc_im(1)%matrix)
458
459 IF (PRESENT(ot_settings)) THEN
460 qs_ot_env(1)%settings = ot_settings
461 ELSE
462 CALL qs_ot_settings_init(qs_ot_env(1)%settings)
463 qs_ot_env(1)%settings%ds_min = 0.10_dp
464 END IF
465
466 CALL qs_ot_allocate(qs_ot_env(1), matrix_s, matrix_c_fm%matrix_struct)
467 CALL qs_ot_allocate_complex_state(qs_ot_env(1), matrix_s)
468 CALL dbcsr_init_p(matrix_hc(1)%matrix)
469 CALL dbcsr_copy(matrix_hc(1)%matrix, qs_ot_env(1)%matrix_x, 'matrix_hc')
470 CALL dbcsr_init_p(matrix_hc_im(1)%matrix)
471 CALL dbcsr_copy(matrix_hc_im(1)%matrix, qs_ot_env(1)%matrix_x_im, 'matrix_hc_im')
472
473 CALL dbcsr_copy(qs_ot_env(1)%matrix_c0, matrix_c)
474 CALL dbcsr_copy(qs_ot_env(1)%matrix_c0_im, matrix_c_im)
475 CALL dbcsr_multiply('N', 'N', 1.0_dp, matrix_s, matrix_c, &
476 0.0_dp, qs_ot_env(1)%matrix_sc0)
477 CALL dbcsr_multiply('N', 'N', 1.0_dp, matrix_s_im, matrix_c_im, &
478 0.0_dp, matrix_tmp)
479 CALL dbcsr_add(qs_ot_env(1)%matrix_sc0, matrix_tmp, &
480 alpha_scalar=1.0_dp, beta_scalar=-1.0_dp)
481 CALL dbcsr_multiply('N', 'N', 1.0_dp, matrix_s, matrix_c_im, &
482 0.0_dp, qs_ot_env(1)%matrix_sc0_im)
483 CALL dbcsr_multiply('N', 'N', 1.0_dp, matrix_s_im, matrix_c, &
484 0.0_dp, matrix_tmp)
485 CALL dbcsr_add(qs_ot_env(1)%matrix_sc0_im, matrix_tmp, &
486 alpha_scalar=1.0_dp, beta_scalar=1.0_dp)
487
488 CALL qs_ot_init(qs_ot_env(1))
489 energy_only = qs_ot_env(1)%energy_only
490 SELECT CASE (qs_ot_env(1)%settings%ot_algorithm)
491 CASE ('TOD')
492 CALL dbcsr_set(qs_ot_env(1)%matrix_x, 0.0_dp)
493 CALL dbcsr_set(qs_ot_env(1)%matrix_x_im, 0.0_dp)
494 CALL dbcsr_set(qs_ot_env(1)%matrix_sx, 0.0_dp)
495 CALL dbcsr_set(qs_ot_env(1)%matrix_sx_im, 0.0_dp)
496 CALL qs_ot_get_orbitals_complex(matrix_c, matrix_c_im, matrix_s, matrix_s_im, &
497 qs_ot_env(1))
498 CASE ('REF')
499 CALL dbcsr_copy(qs_ot_env(1)%matrix_x, qs_ot_env(1)%matrix_c0)
500 CALL dbcsr_copy(qs_ot_env(1)%matrix_x_im, qs_ot_env(1)%matrix_c0_im)
501 CALL dbcsr_copy(qs_ot_env(1)%matrix_sx, qs_ot_env(1)%matrix_sc0)
502 CALL dbcsr_copy(qs_ot_env(1)%matrix_sx_im, qs_ot_env(1)%matrix_sc0_im)
503 CALL qs_ot_get_orbitals_ref_complex(matrix_c, matrix_c_im, matrix_s, matrix_s_im, &
504 qs_ot_env(1), qs_ot_env(1))
505 CASE DEFAULT
506 cpabort('Complex OT eigensolver supports ALGORITHM STRICT or IRAC')
507 END SELECT
508
509 IF (.NOT. PRESENT(preconditioner) .AND. .NOT. ASSOCIATED(local_preconditioner) .AND. &
510 qs_ot_env(1)%settings%preconditioner_type /= ot_precond_none) THEN
511 ALLOCATE (local_preconditioner)
512 CALL init_preconditioner(local_preconditioner, qs_ot_env(1)%para_env, qs_ot_env(1)%blacs_env)
513 SELECT CASE (qs_ot_env(1)%settings%preconditioner_type)
516 local_preconditioner, qs_ot_env(1)%matrix_c0, qs_ot_env(1)%matrix_c0_im, &
517 matrix_h, matrix_h_im, matrix_s, matrix_s_im, &
518 qs_ot_env(1)%settings%energy_gap, &
519 qs_ot_env(1)%settings%fermi_low_rank_max_rank, &
520 qs_ot_env(1)%settings%precond_solver_type)
522 IF (qs_ot_env(1)%settings%ot_algorithm == 'TOD') THEN
523 ! State-selective FULL_ALL models can destabilize the finite STRICT fixed-H chart
524 ! even when the tangent metric is positive. Retain a well-defined eigensolver with
525 ! their S^-1 base; IRAC can use the complete state-dependent inverse below.
527 local_preconditioner, matrix_s, matrix_s_im, &
528 qs_ot_env(1)%settings%precond_solver_type)
529 ELSE IF (qs_ot_env(1)%settings%preconditioner_type == ot_precond_full_all) THEN
530 IF (.NOT. PRESENT(mo_set)) THEN
531 cpabort('Complex FULL_ALL eigensolver preconditioning requires MO energy labels')
532 END IF
534 local_preconditioner, qs_ot_env(1)%matrix_c0, qs_ot_env(1)%matrix_c0_im, &
535 matrix_h, matrix_h_im, matrix_s, matrix_s_im, mo_set, &
536 qs_ot_env(1)%settings%energy_gap, qs_ot_env(1)%settings%precond_solver_type)
537 ELSE
539 local_preconditioner, qs_ot_env(1)%matrix_c0, qs_ot_env(1)%matrix_c0_im, &
540 matrix_h, matrix_h_im, matrix_s, matrix_s_im, &
541 qs_ot_env(1)%settings%energy_gap, qs_ot_env(1)%settings%precond_solver_type)
542 END IF
544 IF (.NOT. PRESENT(mo_set)) THEN
545 cpabort('Complex FULL_SINGLE eigensolver preconditioning requires MO energy labels')
546 END IF
548 local_preconditioner, matrix_h, matrix_h_im, matrix_s, matrix_s_im, mo_set, &
549 qs_ot_env(1)%settings%energy_gap, qs_ot_env(1)%settings%precond_solver_type)
552 local_preconditioner, qs_ot_env(1)%matrix_c0, qs_ot_env(1)%matrix_c0_im, &
553 matrix_h, matrix_h_im, matrix_s, matrix_s_im, &
554 qs_ot_env(1)%settings%energy_gap, qs_ot_env(1)%settings%precond_solver_type)
556 IF (.NOT. PRESENT(matrix_t) .OR. .NOT. PRESENT(matrix_t_im)) THEN
557 cpabort('Complex FULL_KINETIC eigensolver preconditioning requires T(k)')
558 END IF
559 IF (.NOT. ASSOCIATED(matrix_t) .OR. .NOT. ASSOCIATED(matrix_t_im)) THEN
560 cpabort('Complex FULL_KINETIC eigensolver preconditioning requires T(k)')
561 END IF
563 local_preconditioner, matrix_t, matrix_t_im, matrix_s, matrix_s_im, &
564 qs_ot_env(1)%settings%energy_gap, qs_ot_env(1)%settings%precond_solver_type)
567 local_preconditioner, matrix_s, matrix_s_im, &
568 qs_ot_env(1)%settings%precond_solver_type)
569 CASE DEFAULT
570 cpabort('Unsupported complex K-point OT eigensolver preconditioner')
571 END SELECT
572 END IF
573
574 IF (PRESENT(preconditioner)) THEN
575 IF (ASSOCIATED(preconditioner)) THEN
577 CALL qs_ot_new_preconditioner(qs_ot_env(1), preconditioner)
578 END IF
579 END IF
580 ELSE IF (ASSOCIATED(local_preconditioner)) THEN
581 CALL qs_ot_new_preconditioner(qs_ot_env(1), local_preconditioner)
582 END IF
583
584 IF (qs_ot_env(1)%settings%ot_algorithm == 'TOD') THEN
585 CALL qs_ot_prepare_complex_tangent_metric(qs_ot_env(1), preconditioner_rejected)
586 IF (preconditioner_rejected .AND. ASSOCIATED(local_preconditioner)) THEN
587 CALL destroy_preconditioner(local_preconditioner)
588 CALL init_preconditioner(local_preconditioner, &
589 qs_ot_env(1)%para_env, qs_ot_env(1)%blacs_env)
591 local_preconditioner, matrix_s, matrix_s_im, &
592 qs_ot_env(1)%settings%precond_solver_type)
593 CALL qs_ot_new_preconditioner(qs_ot_env(1), local_preconditioner)
594 CALL qs_ot_prepare_complex_tangent_metric(qs_ot_env(1), preconditioner_rejected)
595 cpassert(.NOT. preconditioner_rejected)
596 END IF
597 END IF
598
599 ieigensolver = 0
600 eigensolver_loop: DO
601 ieigensolver = ieigensolver + 1
602 iter_total = iter_total + 1
603
604 ! H*C = (Hre*Cre-Him*Cim) + i*(Hre*Cim+Him*Cre).
605 CALL dbcsr_multiply('N', 'N', 1.0_dp, matrix_h, matrix_c, &
606 0.0_dp, matrix_hc(1)%matrix)
607 CALL dbcsr_multiply('N', 'N', 1.0_dp, matrix_h_im, matrix_c_im, &
608 0.0_dp, matrix_tmp)
609 CALL dbcsr_add(matrix_hc(1)%matrix, matrix_tmp, &
610 alpha_scalar=1.0_dp, beta_scalar=-1.0_dp)
611 CALL dbcsr_multiply('N', 'N', 1.0_dp, matrix_h, matrix_c_im, &
612 0.0_dp, matrix_hc_im(1)%matrix)
613 CALL dbcsr_multiply('N', 'N', 1.0_dp, matrix_h_im, matrix_c, &
614 0.0_dp, matrix_tmp)
615 CALL dbcsr_add(matrix_hc_im(1)%matrix, matrix_tmp, &
616 alpha_scalar=1.0_dp, beta_scalar=1.0_dp)
617
618 CALL dbcsr_dot(matrix_c, matrix_hc(1)%matrix, energy_re)
619 CALL dbcsr_dot(matrix_c_im, matrix_hc_im(1)%matrix, energy_im)
620 qs_ot_env(1)%etotal = energy_re + energy_im
621 IF (.NOT. energy_only) THEN
622 CALL dbcsr_scale(matrix_hc(1)%matrix, 2.0_dp)
623 CALL dbcsr_scale(matrix_hc_im(1)%matrix, 2.0_dp)
624 END IF
625 CALL ot_mini(qs_ot_env, matrix_hc, matrix_hc_im=matrix_hc_im)
626 delta = qs_ot_env(1)%delta
627 energy_only = qs_ot_env(1)%energy_only
628
629 SELECT CASE (qs_ot_env(1)%settings%ot_algorithm)
630 CASE ('TOD')
631 CALL qs_ot_get_orbitals_complex(matrix_c, matrix_c_im, matrix_s, matrix_s_im, &
632 qs_ot_env(1))
633 CASE ('REF')
634 CALL qs_ot_get_orbitals_ref_complex(matrix_c, matrix_c_im, matrix_s, matrix_s_im, &
635 qs_ot_env(1), qs_ot_env(1))
636 END SELECT
637
638 IF (delta < eps_gradient .OR. ieigensolver >= max_iter_inner_loop) EXIT eigensolver_loop
639 IF (iter_total >= iter_max .AND. qs_ot_env(1)%OT_METHOD_FULL /= 'OT LS') EXIT eigensolver_loop
640 END DO eigensolver_loop
641
642 CALL qs_ot_destroy(qs_ot_env(1))
643 DEALLOCATE (qs_ot_env)
644 CALL dbcsr_release_p(matrix_hc(1)%matrix)
645 CALL dbcsr_release_p(matrix_hc_im(1)%matrix)
646 DEALLOCATE (matrix_hc, matrix_hc_im)
647
648 IF (delta < eps_gradient) THEN
649 IF (output_unit > 0 .AND. .NOT. my_silent) THEN
650 WRITE (unit=output_unit, fmt='(T2,A,I0,A)') &
651 'OT| Complex eigensolver reached convergence in ', iter_total, ' iterations'
652 END IF
653 EXIT outer_scf
654 END IF
655 IF (iter_total >= iter_max) THEN
656 IF (output_unit > 0) THEN
657 WRITE (output_unit, '(A,T60,E20.10)') &
658 ' WARNING complex OT eigensolver did not converge: current gradient', delta
659 END IF
660 EXIT outer_scf
661 END IF
662 END DO outer_scf
663
664 CALL copy_dbcsr_to_fm(matrix_c, matrix_c_fm)
665 CALL copy_dbcsr_to_fm(matrix_c_im, matrix_c_fm_im)
666 IF (PRESENT(eigenvalues)) THEN
667 CALL canonicalize_complex_subspace(matrix_h, matrix_h_im, matrix_c_fm, &
668 matrix_c_fm_im, eigenvalues)
669 END IF
670 CALL cp_fm_to_cfm(matrix_c_fm, matrix_c_fm_im, matrix_c_cfm)
671 CALL cp_fm_release(matrix_c_fm)
672 CALL cp_fm_release(matrix_c_fm_im)
673 CALL dbcsr_release_p(matrix_c)
674 CALL dbcsr_release_p(matrix_c_im)
675 CALL dbcsr_release_p(matrix_tmp)
676 IF (ASSOCIATED(local_preconditioner)) THEN
677 CALL destroy_preconditioner(local_preconditioner)
678 DEALLOCATE (local_preconditioner)
679 END IF
680 CALL timestop(handle)
681
682 END SUBROUTINE ot_eigensolver_complex
683
684! **************************************************************************************************
685!> \brief diagonalize C^H H C and rotate a complex orthonormal orbital subspace
686!> \param matrix_h ...
687!> \param matrix_h_im ...
688!> \param coeff_re ...
689!> \param coeff_im ...
690!> \param eigenvalues ...
691! **************************************************************************************************
692 SUBROUTINE canonicalize_complex_subspace(matrix_h, matrix_h_im, coeff_re, coeff_im, eigenvalues)
693 TYPE(dbcsr_type), POINTER :: matrix_h, matrix_h_im
694 TYPE(cp_fm_type), INTENT(INOUT) :: coeff_re, coeff_im
695 REAL(kind=dp), DIMENSION(:), INTENT(OUT) :: eigenvalues
696
697 INTEGER :: nao, nmo
698 TYPE(cp_cfm_type) :: coeff, eigenvectors, hblock, hc, rotated
699 TYPE(cp_fm_type) :: hc_im, hc_re
700
701 CALL cp_fm_get_info(coeff_re, nrow_global=nao, ncol_global=nmo)
702 cpassert(SIZE(eigenvalues) >= nmo)
703 CALL cp_fm_create(hc_re, coeff_re%matrix_struct)
704 CALL cp_fm_create(hc_im, coeff_re%matrix_struct)
705 CALL cp_dbcsr_sm_fm_multiply(matrix_h, coeff_re, hc_re, nmo)
706 CALL cp_dbcsr_sm_fm_multiply(matrix_h_im, coeff_im, hc_re, nmo, &
707 alpha=-1.0_dp, beta=1.0_dp)
708 CALL cp_dbcsr_sm_fm_multiply(matrix_h, coeff_im, hc_im, nmo)
709 CALL cp_dbcsr_sm_fm_multiply(matrix_h_im, coeff_re, hc_im, nmo, &
710 alpha=1.0_dp, beta=1.0_dp)
711
712 CALL cp_cfm_create(coeff, coeff_re%matrix_struct)
713 CALL cp_cfm_create(hc, coeff_re%matrix_struct)
714 CALL cp_cfm_create(rotated, coeff_re%matrix_struct)
715 CALL cp_cfm_create(hblock, coeff_re%matrix_struct, nrow=nmo, ncol=nmo)
716 CALL cp_cfm_create(eigenvectors, coeff_re%matrix_struct, nrow=nmo, ncol=nmo)
717 CALL cp_fm_to_cfm(coeff_re, coeff_im, coeff)
718 CALL cp_fm_to_cfm(hc_re, hc_im, hc)
719 CALL cp_cfm_gemm('C', 'N', nmo, nmo, nao, z_one, coeff, hc, z_zero, hblock)
720 CALL cp_cfm_heevd(hblock, eigenvectors, eigenvalues(1:nmo))
721 CALL cp_cfm_gemm('N', 'N', nao, nmo, nmo, z_one, coeff, eigenvectors, z_zero, rotated)
722 CALL cp_cfm_to_fm(rotated, coeff_re, coeff_im)
723
724 CALL cp_cfm_release(eigenvectors)
725 CALL cp_cfm_release(hblock)
726 CALL cp_cfm_release(rotated)
727 CALL cp_cfm_release(hc)
728 CALL cp_cfm_release(coeff)
729 CALL cp_fm_release(hc_im)
730 CALL cp_fm_release(hc_re)
731 END SUBROUTINE canonicalize_complex_subspace
732
733END MODULE qs_ot_eigensolver
Basic linear algebra operations for complex full matrices.
subroutine, public cp_cfm_gemm(transa, transb, m, n, k, alpha, matrix_a, matrix_b, beta, matrix_c, a_first_col, a_first_row, b_first_col, b_first_row, c_first_col, c_first_row)
Performs one of the matrix-matrix operations: matrix_c = alpha * op1( matrix_a ) * op2( matrix_b ) + ...
used for collecting diagonalization schemes available for cp_cfm_type
Definition cp_cfm_diag.F:14
subroutine, public cp_cfm_heevd(matrix, eigenvectors, eigenvalues)
Perform a diagonalisation of a complex matrix.
Definition cp_cfm_diag.F:94
Represents a complex full matrix distributed on many processors.
subroutine, public cp_cfm_release(matrix)
Releases a full matrix.
subroutine, public cp_fm_to_cfm(msourcer, msourcei, mtarget)
Construct a complex full matrix by taking its real and imaginary parts from two separate real-value f...
subroutine, public cp_cfm_create(matrix, matrix_struct, name, nrow, ncol, set_zero)
Creates a new full matrix with the given structure.
subroutine, public cp_cfm_to_fm(msource, mtargetr, mtargeti)
Copy real and imaginary parts of a complex full matrix into separate real-value full matrices.
subroutine, public dbcsr_release_p(matrix)
...
subroutine, public dbcsr_scale(matrix, alpha_scalar)
...
subroutine, public dbcsr_copy(matrix_b, matrix_a, name, keep_sparsity, keep_imaginary)
...
subroutine, public dbcsr_multiply(transa, transb, alpha, matrix_a, matrix_b, beta, matrix_c, first_row, last_row, first_column, last_column, first_k, last_k, retain_sparsity, filter_eps, flop)
...
subroutine, public dbcsr_init_p(matrix)
...
subroutine, public dbcsr_set(matrix, alpha)
...
subroutine, public dbcsr_add(matrix_a, matrix_b, alpha_scalar, beta_scalar)
...
Interface to (sca)lapack for the Cholesky based procedures.
subroutine, public cp_dbcsr_cholesky_decompose(matrix, n, para_env, blacs_env)
used to replace a symmetric positive def. matrix M with its cholesky decomposition U: M = U^T * U,...
subroutine, public cp_dbcsr_cholesky_invert(matrix, n, para_env, blacs_env, uplo_to_full)
used to replace the cholesky decomposition by the inverse
subroutine, public dbcsr_dot(matrix_a, matrix_b, trace)
Computes the dot product of two matrices, also known as the trace of their matrix product.
DBCSR operations in CP2K.
subroutine, public cp_dbcsr_sm_fm_multiply(matrix, fm_in, fm_out, ncol, alpha, beta)
multiply a dbcsr with a fm matrix
subroutine, public copy_dbcsr_to_fm(matrix, fm, plan, check_plan)
Copy a DBCSR matrix to a BLACS matrix.
subroutine, public cp_fm_to_dbcsr_row_template(matrix, fm_in, template)
Utility function to copy a specially shaped fm to dbcsr_matrix The result matrix will be the matrix i...
subroutine, public cp_dbcsr_m_by_n_from_row_template(matrix, template, n, sym)
Utility function to create dbcsr matrix, m x n matrix (n arbitrary) with the same processor grid and ...
subroutine, public cp_dbcsr_m_by_n_from_template(matrix, template, m, n, sym)
Utility function to create an arbitrary shaped dbcsr matrix with the same processor grid as the templ...
subroutine, public dbcsr_copy_columns_hack(matrix_b, matrix_a, ncol, source_start, target_start, para_env, blacs_env)
hack for dbcsr_copy_columns
subroutine, public copy_fm_to_dbcsr(fm, matrix, keep_sparsity)
Copy a BLACS matrix to a dbcsr matrix.
represent a full matrix distributed on many processors
Definition cp_fm_types.F:15
subroutine, public cp_fm_get_info(matrix, name, nrow_global, ncol_global, nrow_block, ncol_block, nrow_local, ncol_local, row_indices, col_indices, local_data, context, nrow_locals, ncol_locals, matrix_struct, para_env)
returns all kind of information about the full matrix
subroutine, public cp_fm_create(matrix, matrix_struct, name, nrow, ncol, set_zero)
creates a new full matrix with the given structure
various routines to log and control the output. The idea is that decisions about where to log should ...
integer function, public cp_logger_get_default_io_unit(logger)
returns the unit nr for the ionode (-1 on all other processors) skips as well checks if the procs cal...
collects all constants needed in input so that they can be used without circular dependencies
integer, parameter, public ot_precond_full_all_covariant
integer, parameter, public ot_precond_full_kinetic
integer, parameter, public ot_precond_full_single
integer, parameter, public ot_precond_none
integer, parameter, public ot_precond_full_single_inverse
integer, parameter, public ot_precond_fermi_low_rank
integer, parameter, public ot_precond_s_inverse
integer, parameter, public ot_precond_full_all
Defines the basic variable types.
Definition kinds.F:23
integer, parameter, public dp
Definition kinds.F:34
Definition of mathematical constants and functions.
complex(kind=dp), parameter, public z_one
complex(kind=dp), parameter, public z_zero
types of preconditioners
subroutine, public init_preconditioner(preconditioner_env, para_env, blacs_env)
...
subroutine, public destroy_preconditioner(preconditioner_env)
...
logical function, public preconditioner_in_use(preconditioner)
...
computes preconditioners, and implements methods to apply them currently used in qs_ot
subroutine, public make_preconditioner_complex_full_all(preconditioner_env, matrix_c_re, matrix_c_im, matrix_h_re, matrix_h_im, matrix_s_re, matrix_s_im, mo_set, energy_gap, solver_type)
Construct FULL_ALL directly from one complex H(k), S(k), and C(k) channel.
subroutine, public make_preconditioner_complex_full_s_inverse(preconditioner_env, matrix_s_re, matrix_s_im, solver_type)
Construct a complex FULL_S_INVERSE preconditioner.
subroutine, public make_preconditioner_complex_full_single(preconditioner_env, matrix_h_re, matrix_h_im, matrix_s_re, matrix_s_im, mo_set, energy_gap, solver_type)
Construct a complex FULL_SINGLE preconditioner from H(k) and S(k).
subroutine, public make_preconditioner_complex_full_single_inverse(preconditioner_env, matrix_c_re, matrix_c_im, matrix_h_re, matrix_h_im, matrix_s_re, matrix_s_im, energy_gap, solver_type)
Construct a complex FULL_SINGLE_INVERSE preconditioner without discarding Im(H,S,C).
subroutine, public make_preconditioner_complex_full_all_covariant(preconditioner_env, matrix_c_re, matrix_c_im, matrix_h_re, matrix_h_im, matrix_s_re, matrix_s_im, energy_gap, solver_type, occupation_signature)
Construct rotation-covariant FULL_ALL for one complex k-point channel.
subroutine, public make_preconditioner_complex_fermi_low_rank(preconditioner_env, matrix_c_re, matrix_c_im, matrix_h_re, matrix_h_im, matrix_s_re, matrix_s_im, energy_gap, max_rank, solver_type)
Construct FERMI_LOW_RANK directly for one complex k-point channel.
subroutine, public make_preconditioner_complex_full_kinetic(preconditioner_env, matrix_t_re, matrix_t_im, matrix_s_re, matrix_s_im, energy_gap, solver_type)
Construct a complex FULL_KINETIC preconditioner.
collects routines that perform operations directly related to MOs
Definition and initialisation of the mo data type.
Definition qs_mo_types.F:22
an eigen-space solver for the generalised symmetric eigenvalue problem for sparse matrices,...
subroutine, public ot_eigensolver_complex(matrix_h, matrix_h_im, matrix_s, matrix_s_im, matrix_c_cfm, preconditioner, eps_gradient, iter_max, eigenvalues, silent, ot_settings, matrix_t, matrix_t_im, mo_set)
solve a fixed complex Hermitian generalized eigenproblem by OT
subroutine, public ot_eigensolver(matrix_h, matrix_s, matrix_orthogonal_space_fm, matrix_c_fm, preconditioner, eps_gradient, iter_max, size_ortho_space, silent, ot_settings)
...
orbital transformations
subroutine, public ot_mini(qs_ot_env, matrix_hc, matrix_hc_im, matrix_hc_physical, matrix_hc_physical_im, para_env_inter_kp, gradient_only, gradient_prepared)
...
orbital transformations
Definition qs_ot_types.F:15
subroutine, public qs_ot_init(qs_ot_env)
init matrices, needs c0 and sc0 so that c0*sc0=1
subroutine, public qs_ot_settings_init(settings)
sets default values for the settings type
subroutine, public qs_ot_allocate(qs_ot_env, matrix_s, fm_struct_ref, ortho_k, energy_dimension)
allocates the data in qs_ot_env, for a calculation with fm_struct_ref ortho_k allows for specifying a...
subroutine, public qs_ot_allocate_complex_state(qs_ot_env, matrix_s)
...
subroutine, public qs_ot_destroy(qs_ot_env)
deallocates data
orbital transformations
Definition qs_ot.F:15
subroutine, public qs_ot_get_p(matrix_x, matrix_sx, qs_ot_env)
computes p=x*S*x and the matrix functionals related matrices
Definition qs_ot.F:2344
subroutine, public qs_ot_get_orbitals_ref_complex(matrix_c, matrix_c_im, matrix_s, matrix_s_im, qs_ot_env, qs_ot_env1)
update complex REF k-point orbitals and their S(k)C(k) images
Definition qs_ot.F:1687
subroutine, public qs_ot_prepare_complex_tangent_metric(qs_ot_env, preconditioner_rejected)
Prepare the inverse metric used to project a complex STRICT gradient. An unusable preconditioner is d...
Definition qs_ot.F:3122
subroutine, public qs_ot_get_orbitals(matrix_c, matrix_x, qs_ot_env)
c=(c0*cos(p^0.5)+x*sin(p^0.5)*p^(-0.5)) x rot_mat_u this assumes that x is already ortho to S*C0,...
Definition qs_ot.F:2910
subroutine, public qs_ot_get_orbitals_ref(matrix_c, matrix_s, matrix_x, matrix_sx, matrix_gx_old, matrix_dx, qs_ot_env, qs_ot_env1)
...
Definition qs_ot.F:1582
subroutine, public qs_ot_new_preconditioner(qs_ot_env, preconditioner)
gets ready to use the preconditioner/ or renew the preconditioner only keeps a pointer to the precond...
Definition qs_ot.F:1072
subroutine, public qs_ot_get_orbitals_complex(matrix_c, matrix_c_im, matrix_s, matrix_s_im, qs_ot_env)
update complex K-point orbitals with the finite STRICT transformation
Definition qs_ot.F:2960
Represent a complex full matrix.
represent a full matrix
notice, this variable needs to be copyable, needed for spins as e.g. in qs_ot_scf
Definition qs_ot_types.F:80