(git:b195825)
qs_linres_methods.F
Go to the documentation of this file.
1 !--------------------------------------------------------------------------------------------------!
2 ! CP2K: A general program to perform molecular dynamics simulations !
3 ! Copyright 2000-2024 CP2K developers group <https://cp2k.org> !
4 ! !
5 ! SPDX-License-Identifier: GPL-2.0-or-later !
6 !--------------------------------------------------------------------------------------------------!
7 
8 ! **************************************************************************************************
9 !> \brief localize wavefunctions
10 !> linear response scf
11 !> \par History
12 !> created 07-2005 [MI]
13 !> \author MI
14 ! **************************************************************************************************
16  USE cp_control_types, ONLY: dft_control_type
19  USE cp_files, ONLY: close_file,&
20  open_file
22  cp_fm_trace
25  cp_fm_struct_type
26  USE cp_fm_types, ONLY: cp_fm_create,&
29  cp_fm_release,&
31  cp_fm_to_fm,&
32  cp_fm_type
34  cp_logger_type,&
35  cp_to_string
36  USE cp_output_handling, ONLY: cp_p_file,&
41  USE dbcsr_api, ONLY: dbcsr_checksum,&
42  dbcsr_copy,&
43  dbcsr_p_type,&
44  dbcsr_set,&
45  dbcsr_type
46  USE input_constants, ONLY: do_loc_none,&
47  op_loc_berry,&
52  section_vals_type,&
54  USE kinds, ONLY: default_path_length,&
56  dp
57  USE machine, ONLY: m_flush,&
59  USE message_passing, ONLY: mp_para_env_type
60  USE parallel_gemm_api, ONLY: parallel_gemm
61  USE preconditioner, ONLY: apply_preconditioner,&
64  USE qs_environment_types, ONLY: get_qs_env,&
65  qs_environment_type
67  USE qs_linres_kernel, ONLY: apply_op_2
68  USE qs_linres_types, ONLY: linres_control_type
69  USE qs_loc_main, ONLY: qs_loc_driver
70  USE qs_loc_types, ONLY: get_qs_loc_env,&
71  localized_wfn_control_type,&
73  qs_loc_env_type
74  USE qs_loc_utils, ONLY: loc_write_restart,&
77  USE qs_mo_types, ONLY: get_mo_set,&
78  mo_set_type
81  USE qs_p_env_types, ONLY: qs_p_env_type
83  USE qs_rho_types, ONLY: qs_rho_type
84  USE string_utilities, ONLY: xstring
85 #include "./base/base_uses.f90"
86 
87  IMPLICIT NONE
88 
89  PRIVATE
90 
91  ! *** Public subroutines ***
94  PUBLIC :: build_dm_response
95 
96  CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_linres_methods'
97 
98 ! **************************************************************************************************
99 
100 CONTAINS
101 
102 ! **************************************************************************************************
103 !> \brief Find the centers and spreads of the wfn,
104 !> if required apply a localization algorithm
105 !> \param qs_env ...
106 !> \param linres_control ...
107 !> \param nspins ...
108 !> \param centers_only ...
109 !> \par History
110 !> 07.2005 created [MI]
111 !> \author MI
112 ! **************************************************************************************************
113  SUBROUTINE linres_localize(qs_env, linres_control, nspins, centers_only)
114 
115  TYPE(qs_environment_type), POINTER :: qs_env
116  TYPE(linres_control_type), POINTER :: linres_control
117  INTEGER, INTENT(IN) :: nspins
118  LOGICAL, INTENT(IN), OPTIONAL :: centers_only
119 
120  INTEGER :: iounit, ispin, istate, nmoloc(2)
121  LOGICAL :: my_centers_only
122  TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:) :: mos_localized
123  TYPE(cp_fm_type), POINTER :: mo_coeff
124  TYPE(cp_logger_type), POINTER :: logger
125  TYPE(localized_wfn_control_type), POINTER :: localized_wfn_control
126  TYPE(mo_set_type), DIMENSION(:), POINTER :: mos
127  TYPE(qs_loc_env_type), POINTER :: qs_loc_env
128  TYPE(section_vals_type), POINTER :: loc_print_section, loc_section, &
129  lr_section
130 
131  NULLIFY (logger, lr_section, loc_section, loc_print_section, localized_wfn_control)
132  logger => cp_get_default_logger()
133  lr_section => section_vals_get_subs_vals(qs_env%input, "PROPERTIES%LINRES")
134  loc_section => section_vals_get_subs_vals(lr_section, "LOCALIZE")
135  loc_print_section => section_vals_get_subs_vals(lr_section, "LOCALIZE%PRINT")
136  iounit = cp_print_key_unit_nr(logger, lr_section, "PRINT%PROGRAM_RUN_INFO", &
137  extension=".linresLog")
138  my_centers_only = .false.
139  IF (PRESENT(centers_only)) my_centers_only = centers_only
140 
141  NULLIFY (mos, mo_coeff, qs_loc_env)
142  CALL get_qs_env(qs_env=qs_env, mos=mos)
143  ALLOCATE (qs_loc_env)
144  CALL qs_loc_env_create(qs_loc_env)
145  linres_control%qs_loc_env => qs_loc_env
146  CALL qs_loc_control_init(qs_loc_env, loc_section, do_homo=.true.)
147  CALL get_qs_loc_env(qs_loc_env, localized_wfn_control=localized_wfn_control)
148 
149  ALLOCATE (mos_localized(nspins))
150  DO ispin = 1, nspins
151  CALL get_mo_set(mo_set=mos(ispin), mo_coeff=mo_coeff)
152  CALL cp_fm_create(mos_localized(ispin), mo_coeff%matrix_struct)
153  CALL cp_fm_to_fm(mo_coeff, mos_localized(ispin))
154  END DO
155 
156  nmoloc(1:2) = 0
157  IF (my_centers_only) THEN
158  localized_wfn_control%set_of_states = state_loc_all
159  localized_wfn_control%localization_method = do_loc_none
160  localized_wfn_control%operator_type = op_loc_berry
161  END IF
162 
163  CALL qs_loc_init(qs_env, qs_loc_env, loc_section, mos_localized=mos_localized, &
164  do_homo=.true.)
165 
166  ! The orbital centers are stored in linres_control%localized_wfn_control
167  DO ispin = 1, nspins
168  CALL qs_loc_driver(qs_env, qs_loc_env, loc_print_section, myspin=ispin, &
169  ext_mo_coeff=mos_localized(ispin))
170  CALL get_mo_set(mo_set=mos(ispin), mo_coeff=mo_coeff)
171  CALL cp_fm_to_fm(mos_localized(ispin), mo_coeff)
172  END DO
173 
174  CALL loc_write_restart(qs_loc_env, loc_print_section, mos, &
175  mos_localized, do_homo=.true.)
176  CALL cp_fm_release(mos_localized)
177 
178  ! Write Centers and Spreads on std out
179  IF (iounit > 0) THEN
180  DO ispin = 1, nspins
181  WRITE (iounit, "(/,T2,A,I2)") &
182  "WANNIER CENTERS for spin ", ispin
183  WRITE (iounit, "(/,T18,A,3X,A)") &
184  "--------------- Centers --------------- ", &
185  "--- Spreads ---"
186  DO istate = 1, SIZE(localized_wfn_control%centers_set(ispin)%array, 2)
187  WRITE (iounit, "(T5,A6,I6,2X,3f12.6,5X,f12.6)") &
188  'state ', istate, localized_wfn_control%centers_set(ispin)%array(1:3, istate), &
189  localized_wfn_control%centers_set(ispin)%array(4, istate)
190  END DO
191  END DO
192  CALL m_flush(iounit)
193  END IF
194 
195  END SUBROUTINE linres_localize
196 
197 ! **************************************************************************************************
198 !> \brief scf loop to optimize the first order wavefunctions (psi1)
199 !> given a perturbation as an operator applied to the ground
200 !> state orbitals (h1_psi0)
201 !> psi1 is defined wrt psi0_order (can be a subset of the occupied space)
202 !> The reference ground state is defined through qs_env (density and ground state MOs)
203 !> psi1 is orthogonal to the occupied orbitals in the ground state MO set (qs_env%mos)
204 !> \param p_env ...
205 !> \param qs_env ...
206 !> \param psi1 ...
207 !> \param h1_psi0 ...
208 !> \param psi0_order ...
209 !> \param iounit ...
210 !> \param should_stop ...
211 !> \par History
212 !> 07.2005 created [MI]
213 !> \author MI
214 ! **************************************************************************************************
215  SUBROUTINE linres_solver(p_env, qs_env, psi1, h1_psi0, psi0_order, iounit, should_stop)
216  TYPE(qs_p_env_type) :: p_env
217  TYPE(qs_environment_type), POINTER :: qs_env
218  TYPE(cp_fm_type), DIMENSION(:), INTENT(IN) :: psi1, h1_psi0, psi0_order
219  INTEGER, INTENT(IN) :: iounit
220  LOGICAL, INTENT(OUT) :: should_stop
221 
222  CHARACTER(LEN=*), PARAMETER :: routinen = 'linres_solver'
223 
224  INTEGER :: handle, ispin, iter, maxnmo, nao, ncol, &
225  nmo, nocc, nspins
226  LOGICAL :: restart
227  REAL(dp) :: alpha, beta, norm_res, t1, t2
228  REAL(dp), DIMENSION(:), POINTER :: tr_pap, tr_rz0, tr_rz00, tr_rz1
229  TYPE(cp_fm_struct_type), POINTER :: tmp_fm_struct
230  TYPE(cp_fm_type) :: buf
231  TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:) :: ap, chc, mo_coeff_array, p, r, z
232  TYPE(cp_fm_type), DIMENSION(:), POINTER :: sc
233  TYPE(cp_fm_type), POINTER :: mo_coeff
234  TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_ks, matrix_s, matrix_t
235  TYPE(dbcsr_type), POINTER :: matrix_x
236  TYPE(dft_control_type), POINTER :: dft_control
237  TYPE(linres_control_type), POINTER :: linres_control
238  TYPE(mo_set_type), DIMENSION(:), POINTER :: mos
239  TYPE(mp_para_env_type), POINTER :: para_env
240 
241  CALL timeset(routinen, handle)
242 
243  NULLIFY (dft_control, linres_control, matrix_s, matrix_t, matrix_ks, para_env)
244  NULLIFY (mos, tmp_fm_struct, mo_coeff)
245 
246  t1 = m_walltime()
247 
248  CALL get_qs_env(qs_env=qs_env, &
249  matrix_ks=matrix_ks, &
250  matrix_s=matrix_s, &
251  kinetic=matrix_t, &
252  dft_control=dft_control, &
253  linres_control=linres_control, &
254  para_env=para_env, &
255  mos=mos)
256 
257  nspins = dft_control%nspins
258  CALL cp_fm_get_info(psi1(1), nrow_global=nao)
259  maxnmo = 0
260  DO ispin = 1, nspins
261  CALL cp_fm_get_info(psi1(ispin), ncol_global=ncol)
262  maxnmo = max(maxnmo, ncol)
263  END DO
264  !
265  CALL check_p_env_init(p_env, linres_control, nspins)
266  !
267  ! allocate the vectors
268  ALLOCATE (tr_pap(nspins), tr_rz0(nspins), tr_rz00(nspins), tr_rz1(nspins), &
269  r(nspins), p(nspins), z(nspins), ap(nspins))
270  !
271  DO ispin = 1, nspins
272  CALL cp_fm_create(r(ispin), psi1(ispin)%matrix_struct)
273  CALL cp_fm_create(p(ispin), psi1(ispin)%matrix_struct)
274  CALL cp_fm_create(z(ispin), psi1(ispin)%matrix_struct)
275  CALL cp_fm_create(ap(ispin), psi1(ispin)%matrix_struct)
276  END DO
277  !
278  ! build C0 occupied vectors and S*C0 matrix
279  ALLOCATE (sc(nspins), mo_coeff_array(nspins))
280  DO ispin = 1, nspins
281  CALL get_mo_set(mos(ispin), mo_coeff=mo_coeff, homo=nocc)
282  NULLIFY (tmp_fm_struct)
283  CALL cp_fm_struct_create(tmp_fm_struct, nrow_global=nao, &
284  ncol_global=nocc, para_env=para_env, &
285  context=mo_coeff%matrix_struct%context)
286  CALL cp_fm_create(mo_coeff_array(ispin), tmp_fm_struct)
287  CALL cp_fm_to_fm(mo_coeff, mo_coeff_array(ispin), nocc)
288  CALL cp_fm_create(sc(ispin), tmp_fm_struct)
289  CALL cp_fm_struct_release(tmp_fm_struct)
290  END DO
291  !
292  ! Allocate C0_order'*H*C0_order
293  ALLOCATE (chc(nspins))
294  DO ispin = 1, nspins
295  CALL cp_fm_get_info(psi1(ispin), ncol_global=nmo)
296  NULLIFY (tmp_fm_struct)
297  CALL cp_fm_struct_create(tmp_fm_struct, nrow_global=nmo, &
298  ncol_global=nmo, para_env=para_env, &
299  context=mo_coeff%matrix_struct%context)
300  CALL cp_fm_create(chc(ispin), tmp_fm_struct)
301  CALL cp_fm_struct_release(tmp_fm_struct)
302  END DO
303  !
304  DO ispin = 1, nspins
305  !
306  ! C0_order' * H * C0_order
307  associate(mo_coeff => psi0_order(ispin))
308  CALL cp_fm_create(buf, mo_coeff%matrix_struct)
309  CALL cp_fm_get_info(mo_coeff, ncol_global=ncol)
310  CALL cp_dbcsr_sm_fm_multiply(matrix_ks(ispin)%matrix, mo_coeff, buf, ncol)
311  CALL parallel_gemm('T', 'N', ncol, ncol, nao, -1.0_dp, mo_coeff, buf, 0.0_dp, chc(ispin))
312  CALL cp_fm_release(buf)
313  END associate
314  !
315  ! S * C0
316  CALL cp_fm_get_info(mo_coeff_array(ispin), ncol_global=ncol)
317  CALL cp_dbcsr_sm_fm_multiply(matrix_s(1)%matrix, mo_coeff_array(ispin), sc(ispin), ncol)
318  END DO
319  !
320  ! header
321  IF (iounit > 0) THEN
322  WRITE (iounit, "(/,T3,A,T16,A,T25,A,T38,A,T52,A,T72,A,/,T3,A)") &
323  "Iteration", "Method", "Restart", "Stepsize", "Convergence", "Time", &
324  repeat("-", 78)
325  END IF
326  !
327  ! orthogonalize x with respect to the psi0
328  CALL preortho(psi1, mo_coeff_array, sc)
329  !
330  ! build the preconditioner
331  IF (linres_control%preconditioner_type /= ot_precond_none) THEN
332  IF (p_env%new_preconditioner) THEN
333  DO ispin = 1, nspins
334  IF (ASSOCIATED(matrix_t)) THEN
335  CALL make_preconditioner(p_env%preconditioner(ispin), &
336  linres_control%preconditioner_type, ot_precond_solver_default, &
337  matrix_ks(ispin)%matrix, matrix_s(1)%matrix, matrix_t(1)%matrix, &
338  mos(ispin), linres_control%energy_gap)
339  ELSE
340  NULLIFY (matrix_x)
341  CALL make_preconditioner(p_env%preconditioner(ispin), &
342  linres_control%preconditioner_type, ot_precond_solver_default, &
343  matrix_ks(ispin)%matrix, matrix_s(1)%matrix, matrix_x, &
344  mos(ispin), linres_control%energy_gap)
345  END IF
346  END DO
347  p_env%new_preconditioner = .false.
348  END IF
349  END IF
350  !
351  ! initialization of the linear solver
352  !
353  ! A * x0
354  CALL apply_op(qs_env, p_env, psi0_order, psi1, ap, chc)
355  !
356  !
357  ! r_0 = b - Ax0
358  DO ispin = 1, nspins
359  CALL cp_fm_to_fm(h1_psi0(ispin), r(ispin))
360  CALL cp_fm_scale_and_add(-1.0_dp, r(ispin), -1.0_dp, ap(ispin))
361  END DO
362  !
363  ! proj r
364  CALL postortho(r, mo_coeff_array, sc)
365  !
366  ! preconditioner
367  linres_control%flag = ""
368  IF (linres_control%preconditioner_type .EQ. ot_precond_none) THEN
369  !
370  ! z_0 = r_0
371  DO ispin = 1, nspins
372  CALL cp_fm_to_fm(r(ispin), z(ispin))
373  END DO
374  linres_control%flag = "CG"
375  ELSE
376  !
377  ! z_0 = M * r_0
378  DO ispin = 1, nspins
379  CALL apply_preconditioner(p_env%preconditioner(ispin), r(ispin), &
380  z(ispin))
381  END DO
382  linres_control%flag = "PCG"
383  END IF
384  !
385  DO ispin = 1, nspins
386  !
387  ! p_0 = z_0
388  CALL cp_fm_to_fm(z(ispin), p(ispin))
389  !
390  ! trace(r_0 * z_0)
391  CALL cp_fm_trace(r(ispin), z(ispin), tr_rz0(ispin))
392  END DO
393  IF (sum(tr_rz0) < 0.0_dp) cpabort("tr(r_j*z_j) < 0")
394  norm_res = abs(sum(tr_rz0))/sqrt(real(nspins*nao*maxnmo, dp))
395  !
396  alpha = 0.0_dp
397  restart = .false.
398  should_stop = .false.
399  iteration: DO iter = 1, linres_control%max_iter
400  !
401  ! check convergence
402  linres_control%converged = .false.
403  IF (norm_res .LT. linres_control%eps) THEN
404  linres_control%converged = .true.
405  END IF
406  !
407  t2 = m_walltime()
408  IF (iter .EQ. 1 .OR. mod(iter, 1) .EQ. 0 .OR. linres_control%converged &
409  .OR. restart .OR. should_stop) THEN
410  IF (iounit > 0) THEN
411  WRITE (iounit, "(T5,I5,T18,A3,T28,L1,T38,1E8.2,T48,F16.10,T68,F8.2)") &
412  iter, linres_control%flag, restart, alpha, norm_res, t2 - t1
413  CALL m_flush(iounit)
414  END IF
415  END IF
416  !
417  IF (linres_control%converged) THEN
418  IF (iounit > 0) THEN
419  WRITE (iounit, "(T3,A,I4,A)") "The linear solver converged in ", iter, " iterations."
420  CALL m_flush(iounit)
421  END IF
422  EXIT iteration
423  ELSE IF (should_stop) THEN
424  IF (iounit > 0) THEN
425  WRITE (iounit, "(T3,A,I4,A)") "The linear solver did NOT converge! External stop"
426  CALL m_flush(iounit)
427  END IF
428  EXIT iteration
429  END IF
430  !
431  ! Max number of iteration reached
432  IF (iter == linres_control%max_iter) THEN
433  IF (iounit > 0) THEN
434  CALL cp_warn(__location__, &
435  "The linear solver didn't converge! Maximum number of iterations reached.")
436  CALL m_flush(iounit)
437  END IF
438  linres_control%converged = .false.
439  END IF
440  !
441  ! Apply the operators that do not depend on the perturbation
442  CALL apply_op(qs_env, p_env, psi0_order, p, ap, chc)
443  !
444  ! proj Ap onto the virtual subspace
445  CALL postortho(ap, mo_coeff_array, sc)
446  !
447  DO ispin = 1, nspins
448  !
449  ! tr(Ap_j*p_j)
450  CALL cp_fm_trace(ap(ispin), p(ispin), tr_pap(ispin))
451  END DO
452  !
453  ! alpha = tr(r_j*z_j) / tr(Ap_j*p_j)
454  IF (sum(tr_pap) < 1.0e-10_dp) THEN
455  alpha = 1.0_dp
456  ELSE
457  alpha = sum(tr_rz0)/sum(tr_pap)
458  END IF
459  DO ispin = 1, nspins
460  !
461  ! x_j+1 = x_j + alpha * p_j
462  CALL cp_fm_scale_and_add(1.0_dp, psi1(ispin), alpha, p(ispin))
463  END DO
464  !
465  ! need to recompute the residue
466  restart = .false.
467  IF (mod(iter, linres_control%restart_every) .EQ. 0) THEN
468  !
469  ! r_j+1 = b - A * x_j+1
470  CALL apply_op(qs_env, p_env, psi0_order, psi1, ap, chc)
471  !
472  DO ispin = 1, nspins
473  CALL cp_fm_to_fm(h1_psi0(ispin), r(ispin))
474  CALL cp_fm_scale_and_add(-1.0_dp, r(ispin), -1.0_dp, ap(ispin))
475  END DO
476  CALL postortho(r, mo_coeff_array, sc)
477  !
478  restart = .true.
479  ELSE
480  ! proj Ap onto the virtual subspace
481  CALL postortho(ap, mo_coeff_array, sc)
482  !
483  ! r_j+1 = r_j - alpha * Ap_j
484  DO ispin = 1, nspins
485  CALL cp_fm_scale_and_add(1.0_dp, r(ispin), -alpha, ap(ispin))
486  END DO
487  restart = .false.
488  END IF
489  !
490  ! preconditioner
491  linres_control%flag = ""
492  IF (linres_control%preconditioner_type .EQ. ot_precond_none) THEN
493  !
494  ! z_j+1 = r_j+1
495  DO ispin = 1, nspins
496  CALL cp_fm_to_fm(r(ispin), z(ispin))
497  END DO
498  linres_control%flag = "CG"
499  ELSE
500  !
501  ! z_j+1 = M * r_j+1
502  DO ispin = 1, nspins
503  CALL apply_preconditioner(p_env%preconditioner(ispin), r(ispin), &
504  z(ispin))
505  END DO
506  linres_control%flag = "PCG"
507  END IF
508  !
509  DO ispin = 1, nspins
510  !
511  ! tr(r_j+1*z_j+1)
512  CALL cp_fm_trace(r(ispin), z(ispin), tr_rz1(ispin))
513  END DO
514  IF (sum(tr_rz1) < 0.0_dp) cpabort("tr(r_j+1*z_j+1) < 0")
515  norm_res = sum(tr_rz1)/sqrt(real(nspins*nao*maxnmo, dp))
516  !
517  ! beta = tr(r_j+1*z_j+1) / tr(r_j*z_j)
518  IF (sum(tr_rz0) < 1.0e-10_dp) THEN
519  beta = 0.0_dp
520  ELSE
521  beta = sum(tr_rz1)/sum(tr_rz0)
522  END IF
523  DO ispin = 1, nspins
524  !
525  ! p_j+1 = z_j+1 + beta * p_j
526  CALL cp_fm_scale_and_add(beta, p(ispin), 1.0_dp, z(ispin))
527  tr_rz00(ispin) = tr_rz0(ispin)
528  tr_rz0(ispin) = tr_rz1(ispin)
529  END DO
530  !
531  ! Can we exit the SCF loop?
532  CALL external_control(should_stop, "LINRES", target_time=qs_env%target_time, &
533  start_time=qs_env%start_time)
534 
535  END DO iteration
536  !
537  ! proj psi1
538  CALL preortho(psi1, mo_coeff_array, sc)
539  !
540  !
541  ! clean up
542  CALL cp_fm_release(r)
543  CALL cp_fm_release(p)
544  CALL cp_fm_release(z)
545  CALL cp_fm_release(ap)
546  !
547  CALL cp_fm_release(mo_coeff_array)
548  CALL cp_fm_release(sc)
549  CALL cp_fm_release(chc)
550  !
551  DEALLOCATE (tr_pap, tr_rz0, tr_rz00, tr_rz1)
552  !
553  CALL timestop(handle)
554  !
555  END SUBROUTINE linres_solver
556 
557 ! **************************************************************************************************
558 !> \brief ...
559 !> \param qs_env ...
560 !> \param p_env ...
561 !> \param c0 ...
562 !> \param v ...
563 !> \param Av ...
564 !> \param chc ...
565 ! **************************************************************************************************
566  SUBROUTINE apply_op(qs_env, p_env, c0, v, Av, chc)
567  !
568  TYPE(qs_environment_type), INTENT(IN), POINTER :: qs_env
569  TYPE(qs_p_env_type) :: p_env
570  TYPE(cp_fm_type), DIMENSION(:), INTENT(IN) :: c0, v, av, chc
571 
572  CHARACTER(LEN=*), PARAMETER :: routinen = 'apply_op'
573 
574  INTEGER :: handle, ispin, nc1, nc2, nc3, nc4, nr1, &
575  nr2, nr3, nr4, nspins
576  REAL(dp) :: chksum
577  TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_ks, matrix_s
578  TYPE(dft_control_type), POINTER :: dft_control
579  TYPE(linres_control_type), POINTER :: linres_control
580  TYPE(qs_rho_type), POINTER :: rho
581 
582  CALL timeset(routinen, handle)
583 
584  NULLIFY (dft_control, matrix_ks, matrix_s, linres_control)
585  CALL get_qs_env(qs_env=qs_env, &
586  matrix_ks=matrix_ks, &
587  matrix_s=matrix_s, &
588  dft_control=dft_control, &
589  linres_control=linres_control)
590 
591  nspins = dft_control%nspins
592 
593  DO ispin = 1, nspins
594  !c0, v, Av, chc
595  CALL cp_fm_get_info(c0(ispin), ncol_global=nc1, nrow_global=nr1)
596  CALL cp_fm_get_info(v(ispin), ncol_global=nc2, nrow_global=nr2)
597  CALL cp_fm_get_info(av(ispin), ncol_global=nc3, nrow_global=nr3)
598  CALL cp_fm_get_info(chc(ispin), ncol_global=nc4, nrow_global=nr4)
599  IF (.NOT. (nc1 == nc2 .AND. nr1 == nr2 .AND. nc1 == nc3 .AND. nr1 == nr3 &
600  .AND. nc4 == nr4 .AND. nc1 <= nc4)) THEN
601  CALL cp_abort(__location__, &
602  "Number of vectors inconsistent or CHC matrix too small")
603  END IF
604  END DO
605 
606  ! apply the uncoupled operator
607  DO ispin = 1, nspins
608  CALL apply_op_1(v(ispin), av(ispin), matrix_ks(ispin)%matrix, &
609  matrix_s(1)%matrix, chc(ispin))
610  END DO
611 
612  IF (linres_control%do_kernel) THEN
613 
614  ! build DM, refill p1, build_dm_response keeps sparse structure
615  DO ispin = 1, nspins
616  CALL dbcsr_copy(p_env%p1(ispin)%matrix, matrix_s(1)%matrix)
617  END DO
618  CALL build_dm_response(c0, v, p_env%p1)
619 
620  chksum = 0.0_dp
621  DO ispin = 1, nspins
622  chksum = chksum + dbcsr_checksum(p_env%p1(ispin)%matrix)
623  END DO
624 
625  ! skip the kernel if the DM is very small
626  IF (chksum .GT. 1.0e-14_dp) THEN
627 
628  CALL p_env_check_i_alloc(p_env, qs_env)
629 
630  CALL p_env_update_rho(p_env, qs_env)
631 
632  CALL get_qs_env(qs_env, rho=rho) ! that could be called before
633  CALL qs_rho_update_rho(rho, qs_env=qs_env) ! that could be called before
634  IF (dft_control%qs_control%gapw) THEN
635  CALL prepare_gapw_den(qs_env)
636  ELSEIF (dft_control%qs_control%gapw_xc) THEN
637  CALL prepare_gapw_den(qs_env, do_rho0=.false.)
638  END IF
639 
640  DO ispin = 1, nspins
641  CALL dbcsr_set(p_env%kpp1(ispin)%matrix, 0.0_dp)
642  IF (ASSOCIATED(p_env%kpp1_admm)) CALL dbcsr_set(p_env%kpp1_admm(ispin)%matrix, 0.0_dp)
643  END DO
644 
645  CALL apply_op_2(qs_env, p_env, c0, av)
646 
647  END IF
648 
649  END IF
650 
651  CALL timestop(handle)
652 
653  END SUBROUTINE apply_op
654 
655 ! **************************************************************************************************
656 !> \brief ...
657 !> \param v ...
658 !> \param Av ...
659 !> \param matrix_ks ...
660 !> \param matrix_s ...
661 !> \param chc ...
662 ! **************************************************************************************************
663  SUBROUTINE apply_op_1(v, Av, matrix_ks, matrix_s, chc)
664  !
665  TYPE(cp_fm_type), INTENT(IN) :: v, av
666  TYPE(dbcsr_type), INTENT(IN) :: matrix_ks, matrix_s
667  TYPE(cp_fm_type), INTENT(IN) :: chc
668 
669  CHARACTER(LEN=*), PARAMETER :: routinen = 'apply_op_1'
670 
671  INTEGER :: handle, ncol, nrow
672  TYPE(cp_fm_type) :: buf
673 
674  CALL timeset(routinen, handle)
675  !
676  CALL cp_fm_create(buf, v%matrix_struct)
677  !
678  CALL cp_fm_get_info(v, ncol_global=ncol, nrow_global=nrow)
679  ! H * v
680  CALL cp_dbcsr_sm_fm_multiply(matrix_ks, v, av, ncol)
681  ! v * e (chc already multiplied by -1)
682  CALL parallel_gemm('N', 'N', nrow, ncol, ncol, 1.0_dp, v, chc, 0.0_dp, buf)
683  ! S * ve
684  CALL cp_dbcsr_sm_fm_multiply(matrix_s, buf, av, ncol, alpha=1.0_dp, beta=1.0_dp)
685  !Results is H*C1 - S*<iHj>*C1
686  !
687  CALL cp_fm_release(buf)
688  !
689  CALL timestop(handle)
690  !
691  END SUBROUTINE apply_op_1
692 
693 !MERGE
694 ! **************************************************************************************************
695 !> \brief ...
696 !> \param v ...
697 !> \param psi0 ...
698 !> \param S_psi0 ...
699 ! **************************************************************************************************
700  SUBROUTINE preortho(v, psi0, S_psi0)
701  !v = (I-PS)v
702  !
703  TYPE(cp_fm_type), DIMENSION(:), INTENT(IN) :: v, psi0, s_psi0
704 
705  CHARACTER(LEN=*), PARAMETER :: routinen = 'preortho'
706 
707  INTEGER :: handle, ispin, mp, mt, mv, np, nspins, &
708  nt, nv
709  TYPE(cp_fm_struct_type), POINTER :: tmp_fm_struct
710  TYPE(cp_fm_type) :: buf
711 
712  CALL timeset(routinen, handle)
713  !
714  NULLIFY (tmp_fm_struct)
715  !
716  nspins = SIZE(v, 1)
717  !
718  DO ispin = 1, nspins
719  CALL cp_fm_get_info(v(ispin), ncol_global=mv, nrow_global=nv)
720  CALL cp_fm_get_info(psi0(ispin), ncol_global=mp, nrow_global=np)
721  !
722  CALL cp_fm_struct_create(tmp_fm_struct, nrow_global=nv, ncol_global=mp, &
723  para_env=v(ispin)%matrix_struct%para_env, &
724  context=v(ispin)%matrix_struct%context)
725  CALL cp_fm_create(buf, tmp_fm_struct)
726  CALL cp_fm_struct_release(tmp_fm_struct)
727  !
728  CALL cp_fm_get_info(buf, ncol_global=mt, nrow_global=nt)
729  cpassert(nv == np)
730  cpassert(mt >= mv)
731  cpassert(mt >= mp)
732  cpassert(nt == nv)
733  !
734  ! buf = v' * S_psi0
735  CALL parallel_gemm('T', 'N', mv, mp, nv, 1.0_dp, v(ispin), s_psi0(ispin), 0.0_dp, buf)
736  ! v = v - psi0 * buf'
737  CALL parallel_gemm('N', 'T', nv, mv, mp, -1.0_dp, psi0(ispin), buf, 1.0_dp, v(ispin))
738  !
739  CALL cp_fm_release(buf)
740  END DO
741  !
742  CALL timestop(handle)
743  !
744  END SUBROUTINE preortho
745 
746 ! **************************************************************************************************
747 !> \brief projects first index of v onto the virtual subspace
748 !> \param v matrix to be projected
749 !> \param psi0 matrix with occupied orbitals
750 !> \param S_psi0 matrix containing product of metric and occupied orbitals
751 ! **************************************************************************************************
752  SUBROUTINE postortho(v, psi0, S_psi0)
753  !v = (I-SP)v
754  !
755  TYPE(cp_fm_type), DIMENSION(:), INTENT(IN) :: v, psi0, s_psi0
756 
757  CHARACTER(LEN=*), PARAMETER :: routinen = 'postortho'
758 
759  INTEGER :: handle, ispin, mp, mt, mv, np, nspins, &
760  nt, nv
761  TYPE(cp_fm_struct_type), POINTER :: tmp_fm_struct
762  TYPE(cp_fm_type) :: buf
763 
764  CALL timeset(routinen, handle)
765  !
766  NULLIFY (tmp_fm_struct)
767  !
768  nspins = SIZE(v, 1)
769  !
770  DO ispin = 1, nspins
771  CALL cp_fm_get_info(v(ispin), ncol_global=mv, nrow_global=nv)
772  CALL cp_fm_get_info(psi0(ispin), ncol_global=mp, nrow_global=np)
773  !
774  CALL cp_fm_struct_create(tmp_fm_struct, nrow_global=nv, ncol_global=mp, &
775  para_env=v(ispin)%matrix_struct%para_env, &
776  context=v(ispin)%matrix_struct%context)
777  CALL cp_fm_create(buf, tmp_fm_struct)
778  CALL cp_fm_struct_release(tmp_fm_struct)
779  !
780  CALL cp_fm_get_info(buf, ncol_global=mt, nrow_global=nt)
781  cpassert(nv == np)
782  cpassert(mt >= mv)
783  cpassert(mt >= mp)
784  cpassert(nt == nv)
785  !
786  ! buf = v' * psi0
787  CALL parallel_gemm('T', 'N', mv, mp, nv, 1.0_dp, v(ispin), psi0(ispin), 0.0_dp, buf)
788  ! v = v - S_psi0 * buf'
789  CALL parallel_gemm('N', 'T', nv, mv, mp, -1.0_dp, s_psi0(ispin), buf, 1.0_dp, v(ispin))
790  !
791  CALL cp_fm_release(buf)
792  END DO
793  !
794  CALL timestop(handle)
795  !
796  END SUBROUTINE postortho
797 
798 ! **************************************************************************************************
799 !> \brief ...
800 !> \param qs_env ...
801 !> \param linres_section ...
802 !> \param vec ...
803 !> \param ivec ...
804 !> \param tag ...
805 !> \param ind ...
806 ! **************************************************************************************************
807  SUBROUTINE linres_write_restart(qs_env, linres_section, vec, ivec, tag, ind)
808  TYPE(qs_environment_type), POINTER :: qs_env
809  TYPE(section_vals_type), POINTER :: linres_section
810  TYPE(cp_fm_type), DIMENSION(:), INTENT(IN) :: vec
811  INTEGER, INTENT(IN) :: ivec
812  CHARACTER(LEN=*) :: tag
813  INTEGER, INTENT(IN), OPTIONAL :: ind
814 
815  CHARACTER(LEN=*), PARAMETER :: routinen = 'linres_write_restart'
816 
817  CHARACTER(LEN=default_path_length) :: filename
818  CHARACTER(LEN=default_string_length) :: my_middle, my_pos, my_status
819  INTEGER :: handle, i, i_block, ia, ie, iounit, &
820  ispin, j, max_block, nao, nmo, nspins, &
821  rst_unit
822  REAL(kind=dp), DIMENSION(:, :), POINTER :: vecbuffer
823  TYPE(cp_fm_type), POINTER :: mo_coeff
824  TYPE(cp_logger_type), POINTER :: logger
825  TYPE(mo_set_type), DIMENSION(:), POINTER :: mos
826  TYPE(mp_para_env_type), POINTER :: para_env
827  TYPE(section_vals_type), POINTER :: print_key
828 
829  NULLIFY (logger, mo_coeff, mos, para_env, print_key, vecbuffer)
830 
831  CALL timeset(routinen, handle)
832 
833  logger => cp_get_default_logger()
834 
835  IF (btest(cp_print_key_should_output(logger%iter_info, linres_section, "PRINT%RESTART", &
836  used_print_key=print_key), &
837  cp_p_file)) THEN
838 
839  iounit = cp_print_key_unit_nr(logger, linres_section, &
840  "PRINT%PROGRAM_RUN_INFO", extension=".Log")
841 
842  CALL get_qs_env(qs_env=qs_env, &
843  mos=mos, &
844  para_env=para_env)
845 
846  nspins = SIZE(mos)
847 
848  my_status = "REPLACE"
849  my_pos = "REWIND"
850  CALL xstring(tag, ia, ie)
851  IF (PRESENT(ind)) THEN
852  my_middle = "RESTART-"//tag(ia:ie)//trim(adjustl(cp_to_string(ivec)))
853  ELSE
854  my_middle = "RESTART-"//tag(ia:ie)
855  IF (ivec > 1) THEN
856  my_status = "OLD"
857  my_pos = "APPEND"
858  END IF
859  END IF
860  rst_unit = cp_print_key_unit_nr(logger, linres_section, "PRINT%RESTART", &
861  extension=".lr", middle_name=trim(my_middle), file_status=trim(my_status), &
862  file_position=trim(my_pos), file_action="WRITE", file_form="UNFORMATTED")
863 
864  filename = cp_print_key_generate_filename(logger, print_key, &
865  extension=".lr", middle_name=trim(my_middle), my_local=.false.)
866 
867  IF (iounit > 0) THEN
868  WRITE (unit=iounit, fmt="(T2,A)") &
869  "LINRES| Writing response functions to the restart file <"//trim(adjustl(filename))//">"
870  END IF
871 
872  !
873  ! write data to file
874  ! use the scalapack block size as a default for buffering columns
875  CALL get_mo_set(mos(1), mo_coeff=mo_coeff)
876  CALL cp_fm_get_info(mo_coeff, nrow_global=nao, ncol_block=max_block)
877  ALLOCATE (vecbuffer(nao, max_block))
878 
879  IF (PRESENT(ind)) THEN
880  IF (rst_unit > 0) WRITE (rst_unit) ind, ivec, nspins, nao
881  ELSE
882  IF (rst_unit > 0) WRITE (rst_unit) ivec, nspins, nao
883  END IF
884 
885  DO ispin = 1, nspins
886  CALL cp_fm_get_info(vec(ispin), ncol_global=nmo)
887 
888  IF (rst_unit > 0) WRITE (rst_unit) nmo
889 
890  DO i = 1, nmo, max(max_block, 1)
891  i_block = min(max_block, nmo - i + 1)
892  CALL cp_fm_get_submatrix(vec(ispin), vecbuffer, 1, i, nao, i_block)
893  ! doing this in one write would increase efficiency, but breaks RESTART compatibility.
894  ! to old ones, and in cases where max_block is different between runs, as might happen during
895  ! restarts with a different number of CPUs
896  DO j = 1, i_block
897  IF (rst_unit > 0) WRITE (rst_unit) vecbuffer(1:nao, j)
898  END DO
899  END DO
900  END DO
901 
902  DEALLOCATE (vecbuffer)
903 
904  CALL cp_print_key_finished_output(rst_unit, logger, linres_section, &
905  "PRINT%RESTART")
906  END IF
907 
908  CALL timestop(handle)
909 
910  END SUBROUTINE linres_write_restart
911 
912 ! **************************************************************************************************
913 !> \brief ...
914 !> \param qs_env ...
915 !> \param linres_section ...
916 !> \param vec ...
917 !> \param ivec ...
918 !> \param tag ...
919 !> \param ind ...
920 ! **************************************************************************************************
921  SUBROUTINE linres_read_restart(qs_env, linres_section, vec, ivec, tag, ind)
922  TYPE(qs_environment_type), POINTER :: qs_env
923  TYPE(section_vals_type), POINTER :: linres_section
924  TYPE(cp_fm_type), DIMENSION(:), INTENT(IN) :: vec
925  INTEGER, INTENT(IN) :: ivec
926  CHARACTER(LEN=*) :: tag
927  INTEGER, INTENT(INOUT), OPTIONAL :: ind
928 
929  CHARACTER(LEN=*), PARAMETER :: routinen = 'linres_read_restart'
930 
931  CHARACTER(LEN=default_path_length) :: filename
932  CHARACTER(LEN=default_string_length) :: my_middle
933  INTEGER :: handle, i, i_block, ia, ie, iostat, iounit, ispin, iv, iv1, ivec_tmp, j, &
934  max_block, n_rep_val, nao, nao_tmp, nmo, nmo_tmp, nspins, nspins_tmp, rst_unit
935  LOGICAL :: file_exists
936  REAL(kind=dp), DIMENSION(:, :), POINTER :: vecbuffer
937  TYPE(cp_fm_type), POINTER :: mo_coeff
938  TYPE(cp_logger_type), POINTER :: logger
939  TYPE(mo_set_type), DIMENSION(:), POINTER :: mos
940  TYPE(mp_para_env_type), POINTER :: para_env
941  TYPE(section_vals_type), POINTER :: print_key
942 
943  file_exists = .false.
944 
945  CALL timeset(routinen, handle)
946 
947  NULLIFY (mos, para_env, logger, print_key, vecbuffer)
948  logger => cp_get_default_logger()
949 
950  iounit = cp_print_key_unit_nr(logger, linres_section, &
951  "PRINT%PROGRAM_RUN_INFO", extension=".Log")
952 
953  CALL get_qs_env(qs_env=qs_env, &
954  para_env=para_env, &
955  mos=mos)
956 
957  nspins = SIZE(mos)
958 
959  rst_unit = -1
960  IF (para_env%is_source()) THEN
961  CALL section_vals_val_get(linres_section, "WFN_RESTART_FILE_NAME", &
962  n_rep_val=n_rep_val)
963 
964  CALL xstring(tag, ia, ie)
965  IF (PRESENT(ind)) THEN
966  my_middle = "RESTART-"//tag(ia:ie)//trim(adjustl(cp_to_string(ivec)))
967  ELSE
968  my_middle = "RESTART-"//tag(ia:ie)
969  END IF
970 
971  IF (n_rep_val > 0) THEN
972  CALL section_vals_val_get(linres_section, "WFN_RESTART_FILE_NAME", c_val=filename)
973  CALL xstring(filename, ia, ie)
974  filename = filename(ia:ie)//trim(my_middle)//".lr"
975  ELSE
976  ! try to read from the filename that is generated automatically from the printkey
977  print_key => section_vals_get_subs_vals(linres_section, "PRINT%RESTART")
978  filename = cp_print_key_generate_filename(logger, print_key, &
979  extension=".lr", middle_name=trim(my_middle), my_local=.false.)
980  END IF
981  INQUIRE (file=filename, exist=file_exists)
982  !
983  ! open file
984  IF (file_exists) THEN
985  CALL open_file(file_name=trim(filename), &
986  file_action="READ", &
987  file_form="UNFORMATTED", &
988  file_position="REWIND", &
989  file_status="OLD", &
990  unit_number=rst_unit)
991 
992  IF (iounit > 0) WRITE (iounit, "(T2,A)") &
993  "LINRES| Reading response wavefunctions from the restart file <"//trim(adjustl(filename))//">"
994  ELSE
995  IF (iounit > 0) WRITE (iounit, "(T2,A)") &
996  "LINRES| Restart file <"//trim(adjustl(filename))//"> not found"
997  END IF
998  END IF
999 
1000  CALL para_env%bcast(file_exists)
1001 
1002  IF (file_exists) THEN
1003 
1004  CALL get_mo_set(mos(1), mo_coeff=mo_coeff)
1005  CALL cp_fm_get_info(mo_coeff, nrow_global=nao, ncol_block=max_block)
1006 
1007  ALLOCATE (vecbuffer(nao, max_block))
1008  !
1009  ! read headers
1010  IF (PRESENT(ind)) THEN
1011  iv1 = ivec
1012  ELSE
1013  iv1 = 1
1014  END IF
1015  DO iv = iv1, ivec
1016 
1017  IF (PRESENT(ind)) THEN
1018  IF (rst_unit > 0) READ (rst_unit, iostat=iostat) ind, ivec_tmp, nspins_tmp, nao_tmp
1019  CALL para_env%bcast(iostat)
1020  CALL para_env%bcast(ind)
1021  ELSE
1022  IF (rst_unit > 0) READ (rst_unit, iostat=iostat) ivec_tmp, nspins_tmp, nao_tmp
1023  CALL para_env%bcast(iostat)
1024  END IF
1025 
1026  IF (iostat .NE. 0) EXIT
1027  CALL para_env%bcast(ivec_tmp)
1028  CALL para_env%bcast(nspins_tmp)
1029  CALL para_env%bcast(nao_tmp)
1030 
1031  ! check that the number nao, nmo and nspins are
1032  ! the same as in the current mos
1033  IF (nspins_tmp .NE. nspins) cpabort("nspins not consistent")
1034  IF (nao_tmp .NE. nao) cpabort("nao not consistent")
1035  !
1036  DO ispin = 1, nspins
1037  CALL get_mo_set(mos(ispin), mo_coeff=mo_coeff)
1038  CALL cp_fm_get_info(mo_coeff, ncol_global=nmo)
1039  !
1040  IF (rst_unit > 0) READ (rst_unit) nmo_tmp
1041  CALL para_env%bcast(nmo_tmp)
1042  IF (nmo_tmp .NE. nmo) cpabort("nmo not consistent")
1043  !
1044  ! read the response
1045  DO i = 1, nmo, max(max_block, 1)
1046  i_block = min(max_block, nmo - i + 1)
1047  DO j = 1, i_block
1048  IF (rst_unit > 0) READ (rst_unit) vecbuffer(1:nao, j)
1049  END DO
1050  IF (iv .EQ. ivec_tmp) THEN
1051  CALL para_env%bcast(vecbuffer)
1052  CALL cp_fm_set_submatrix(vec(ispin), vecbuffer, 1, i, nao, i_block)
1053  END IF
1054  END DO
1055  END DO
1056  IF (ivec .EQ. ivec_tmp) EXIT
1057  END DO
1058 
1059  IF (iostat /= 0) THEN
1060  IF (iounit > 0) WRITE (iounit, "(T2,A)") &
1061  "LINRES| Restart file <"//trim(adjustl(filename))//"> not found"
1062  END IF
1063 
1064  DEALLOCATE (vecbuffer)
1065 
1066  END IF
1067 
1068  IF (para_env%is_source()) THEN
1069  IF (file_exists) CALL close_file(unit_number=rst_unit)
1070  END IF
1071 
1072  CALL timestop(handle)
1073 
1074  END SUBROUTINE linres_read_restart
1075 
1076 ! **************************************************************************************************
1077 !> \brief ...
1078 !> \param p_env ...
1079 !> \param linres_control ...
1080 !> \param nspins ...
1081 ! **************************************************************************************************
1082  SUBROUTINE check_p_env_init(p_env, linres_control, nspins)
1083  !
1084  TYPE(qs_p_env_type) :: p_env
1085  TYPE(linres_control_type), INTENT(IN) :: linres_control
1086  INTEGER, INTENT(IN) :: nspins
1087 
1088  INTEGER :: ispin, ncol, nrow
1089 
1090  IF (linres_control%preconditioner_type /= ot_precond_none) THEN
1091  cpassert(ASSOCIATED(p_env%preconditioner))
1092  DO ispin = 1, nspins
1093  CALL cp_fm_get_info(p_env%PS_psi0(ispin), nrow_global=nrow, ncol_global=ncol)
1094  cpassert(nrow == p_env%n_ao(ispin))
1095  cpassert(ncol == p_env%n_mo(ispin))
1096  END DO
1097  END IF
1098 
1099  END SUBROUTINE check_p_env_init
1100 
1101 END MODULE qs_linres_methods
Defines control structures, which contain the parameters and the settings for the DFT-based calculati...
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
Routines to handle the external control of CP2K.
subroutine, public external_control(should_stop, flag, globenv, target_time, start_time, force_check)
External manipulations during a run : when the <PROJECT_NAME>.EXIT_$runtype command is sent the progr...
Utility routines to open and close files. Tracking of preconnections.
Definition: cp_files.F:16
subroutine, public open_file(file_name, file_status, file_form, file_action, file_position, file_pad, unit_number, debug, skip_get_unit_number, file_access)
Opens the requested file using a free unit number.
Definition: cp_files.F:308
subroutine, public close_file(unit_number, file_status, keep_preconnection)
Close an open file given by its logical unit number. Optionally, keep the file and unit preconnected.
Definition: cp_files.F:119
basic linear algebra operations for full matrices
subroutine, public cp_fm_scale_and_add(alpha, matrix_a, beta, matrix_b)
calc A <- alpha*A + beta*B optimized for alpha == 1.0 (just add beta*B) and beta == 0....
represent the structure of a full matrix
Definition: cp_fm_struct.F:14
subroutine, public cp_fm_struct_create(fmstruct, para_env, context, nrow_global, ncol_global, nrow_block, ncol_block, descriptor, first_p_pos, local_leading_dimension, template_fmstruct, square_blocks, force_block)
allocates and initializes a full matrix structure
Definition: cp_fm_struct.F:125
subroutine, public cp_fm_struct_release(fmstruct)
releases a full matrix structure
Definition: cp_fm_struct.F:320
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
Definition: cp_fm_types.F:1016
subroutine, public cp_fm_set_submatrix(fm, new_values, start_row, start_col, n_rows, n_cols, alpha, beta, transpose)
sets a submatrix of a full matrix fm(start_row:start_row+n_rows,start_col:start_col+n_cols) = alpha*o...
Definition: cp_fm_types.F:768
subroutine, public cp_fm_get_submatrix(fm, target_m, start_row, start_col, n_rows, n_cols, transpose)
gets a submatrix of a full matrix op(target_m)(1:n_rows,1:n_cols) =fm(start_row:start_row+n_rows,...
Definition: cp_fm_types.F:901
subroutine, public cp_fm_create(matrix, matrix_struct, name, use_sp)
creates a new full matrix with the given structure
Definition: cp_fm_types.F:167
various routines to log and control the output. The idea is that decisions about where to log should ...
type(cp_logger_type) function, pointer, public cp_get_default_logger()
returns the default logger
routines to handle the output, The idea is to remove the decision of wheter to output and what to out...
integer function, public cp_print_key_unit_nr(logger, basis_section, print_key_path, extension, middle_name, local, log_filename, ignore_should_output, file_form, file_position, file_action, file_status, do_backup, on_file, is_new_file, mpi_io, fout)
...
character(len=default_path_length) function, public cp_print_key_generate_filename(logger, print_key, middle_name, extension, my_local)
Utility function that returns a unit number to write the print key. Might open a file with a unique f...
subroutine, public cp_print_key_finished_output(unit_nr, logger, basis_section, print_key_path, local, ignore_should_output, on_file, mpi_io)
should be called after you finish working with a unit obtained with cp_print_key_unit_nr,...
integer, parameter, public cp_p_file
integer function, public cp_print_key_should_output(iteration_info, basis_section, print_key_path, used_print_key, first_time)
returns what should be done with the given property if btest(res,cp_p_store) then the property should...
collects all constants needed in input so that they can be used without circular dependencies
integer, parameter, public state_loc_all
integer, parameter, public do_loc_none
integer, parameter, public op_loc_berry
integer, parameter, public ot_precond_solver_default
integer, parameter, public ot_precond_none
objects that represent the structure of input sections and the data contained in an input section
recursive type(section_vals_type) function, pointer, public section_vals_get_subs_vals(section_vals, subsection_name, i_rep_section, can_return_null)
returns the values of the requested subsection
subroutine, public section_vals_val_get(section_vals, keyword_name, i_rep_section, i_rep_val, n_rep_val, val, l_val, i_val, r_val, c_val, l_vals, i_vals, r_vals, c_vals, explicit)
returns the requested value
Defines the basic variable types.
Definition: kinds.F:23
integer, parameter, public dp
Definition: kinds.F:34
integer, parameter, public default_string_length
Definition: kinds.F:57
integer, parameter, public default_path_length
Definition: kinds.F:58
Machine interface based on Fortran 2003 and POSIX.
Definition: machine.F:17
subroutine, public m_flush(lunit)
flushes units if the &GLOBAL flag is set accordingly
Definition: machine.F:106
real(kind=dp) function, public m_walltime()
returns time from a real-time clock, protected against rolling early/easily
Definition: machine.F:123
Interface to the message passing library MPI.
basic linear algebra operations for full matrixes
computes preconditioners, and implements methods to apply them currently used in qs_ot
subroutine, public make_preconditioner(preconditioner_env, precon_type, solver_type, matrix_h, matrix_s, matrix_t, mo_set, energy_gap, convert_precond_to_dbcsr, chol_type)
...
Routines to calculate 2nd order kernels from a given response density in ao basis linear response scf...
subroutine, public build_dm_response(c0, c1, dm)
This routine builds response density in dbcsr format.
subroutine, public get_qs_env(qs_env, atomic_kind_set, qs_kind_set, cell, super_cell, cell_ref, use_ref_cell, kpoints, dft_control, mos, sab_orb, sab_all, qmmm, qmmm_periodic, sac_ae, sac_ppl, sac_lri, sap_ppnl, sab_vdw, sab_scp, sap_oce, sab_lrc, sab_se, sab_xtbe, sab_tbe, sab_core, sab_xb, sab_xtb_nonbond, sab_almo, sab_kp, sab_kp_nosym, particle_set, energy, force, matrix_h, matrix_h_im, matrix_ks, matrix_ks_im, matrix_vxc, run_rtp, rtp, matrix_h_kp, matrix_h_im_kp, matrix_ks_kp, matrix_ks_im_kp, matrix_vxc_kp, kinetic_kp, matrix_s_kp, matrix_w_kp, matrix_s_RI_aux_kp, matrix_s, matrix_s_RI_aux, matrix_w, matrix_p_mp2, matrix_p_mp2_admm, rho, rho_xc, pw_env, ewald_env, ewald_pw, active_space, mpools, input, para_env, blacs_env, scf_control, rel_control, kinetic, qs_charges, vppl, rho_core, rho_nlcc, rho_nlcc_g, ks_env, ks_qmmm_env, wf_history, scf_env, local_particles, local_molecules, distribution_2d, dbcsr_dist, molecule_kind_set, molecule_set, subsys, cp_subsys, oce, local_rho_set, rho_atom_set, task_list, task_list_soft, rho0_atom_set, rho0_mpole, rhoz_set, ecoul_1c, rho0_s_rs, rho0_s_gs, do_kpoints, has_unit_metric, requires_mo_derivs, mo_derivs, mo_loc_history, nkind, natom, nelectron_total, nelectron_spin, efield, neighbor_list_id, linres_control, xas_env, virial, cp_ddapc_env, cp_ddapc_ewald, outer_scf_history, outer_scf_ihistory, x_data, et_coupling, dftb_potential, results, se_taper, se_store_int_env, se_nddo_mpole, se_nonbond_env, admm_env, lri_env, lri_density, exstate_env, ec_env, dispersion_env, gcp_env, vee, rho_external, external_vxc, mask, mp2_env, bs_env, kg_env, WannierCentres, atprop, ls_scf_env, do_transport, transport_env, v_hartree_rspace, s_mstruct_changed, rho_changed, potential_changed, forces_up_to_date, mscfg_env, almo_scf_env, gradient_history, variable_history, embed_pot, spin_embed_pot, polar_env, mos_last_converged, rhs)
Get the QUICKSTEP environment.
subroutine, public prepare_gapw_den(qs_env, local_rho_set, do_rho0, kind_set_external)
...
linres kernel functions
subroutine, public apply_op_2(qs_env, p_env, c0, Av)
...
localize wavefunctions linear response scf
subroutine, public linres_write_restart(qs_env, linres_section, vec, ivec, tag, ind)
...
subroutine, public linres_read_restart(qs_env, linres_section, vec, ivec, tag, ind)
...
subroutine, public linres_solver(p_env, qs_env, psi1, h1_psi0, psi0_order, iounit, should_stop)
scf loop to optimize the first order wavefunctions (psi1) given a perturbation as an operator applied...
subroutine, public linres_localize(qs_env, linres_control, nspins, centers_only)
Find the centers and spreads of the wfn, if required apply a localization algorithm.
Type definitiona for linear response calculations.
Driver for the localization that should be general for all the methods available and all the definiti...
Definition: qs_loc_main.F:22
subroutine, public qs_loc_driver(qs_env, qs_loc_env, print_loc_section, myspin, ext_mo_coeff)
set up the calculation of localized orbitals
Definition: qs_loc_main.F:96
New version of the module for the localization of the molecular orbitals This should be able to use d...
Definition: qs_loc_types.F:25
subroutine, public get_qs_loc_env(qs_loc_env, cell, local_molecules, localized_wfn_control, moloc_coeff, op_sm_set, op_fm_set, para_env, particle_set, weights, dim_op)
...
Definition: qs_loc_types.F:317
subroutine, public qs_loc_env_create(qs_loc_env)
...
Definition: qs_loc_types.F:166
Some utilities for the construction of the localization environment.
Definition: qs_loc_utils.F:13
subroutine, public loc_write_restart(qs_loc_env, section, mo_array, coeff_localized, do_homo, evals, do_mixed)
...
Definition: qs_loc_utils.F:701
subroutine, public qs_loc_control_init(qs_loc_env, loc_section, do_homo, do_mixed, do_xas, nloc_xas, spin_xas)
initializes everything needed for localization of the HOMOs
subroutine, public qs_loc_init(qs_env, qs_loc_env, localize_section, mos_localized, do_homo, do_mo_cubes, mo_loc_history, evals, tot_zeff_corr, do_mixed)
initializes everything needed for localization of the molecular orbitals
Definition and initialisation of the mo data type.
Definition: qs_mo_types.F:22
subroutine, public get_mo_set(mo_set, maxocc, homo, lfomo, nao, nelectron, n_el_f, nmo, eigenvalues, occupation_numbers, mo_coeff, mo_coeff_b, uniform_occupation, kTS, mu, flexible_electron_count)
Get the components of a MO set data structure.
Definition: qs_mo_types.F:397
Utility functions for the perturbation calculations.
subroutine, public p_env_update_rho(p_env, qs_env)
...
subroutine, public p_env_check_i_alloc(p_env, qs_env)
checks that the intenal storage is allocated, and allocs it if needed
basis types for the calculation of the perturbation of density theory.
methods of the rho structure (defined in qs_rho_types)
subroutine, public qs_rho_update_rho(rho_struct, qs_env, rho_xc_external, local_rho_set, task_list_external, task_list_external_soft, pw_env_external, para_env_external)
updates rho_r and rho_g to the rhorho_ao. if use_kinetic_energy_density also computes tau_r and tau_g...
superstucture that hold various representations of the density and keeps track of which ones are vali...
Definition: qs_rho_types.F:18
Utilities for string manipulations.
elemental subroutine, public xstring(string, ia, ib)
...