(git:34ef472)
qs_tddfpt2_restart.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 
9  USE cp_blacs_env, ONLY: cp_blacs_env_type
11  USE cp_files, ONLY: close_file,&
12  open_file
15  cp_fm_trace
16  USE cp_fm_pool_types, ONLY: cp_fm_pool_p_type,&
20  cp_fm_struct_type
21  USE cp_fm_types, ONLY: cp_fm_create,&
24  cp_fm_release,&
25  cp_fm_type,&
29  USE cp_log_handling, ONLY: cp_logger_type
30  USE cp_output_handling, ONLY: cp_p_file,&
35  USE dbcsr_api, ONLY: dbcsr_type
37  section_vals_type,&
39  USE kinds, ONLY: default_path_length,&
40  dp
41  USE message_passing, ONLY: mp_para_env_type
42  USE parallel_gemm_api, ONLY: parallel_gemm
43  USE qs_tddfpt2_subgroups, ONLY: tddfpt_subgroup_env_type
44  USE qs_tddfpt2_types, ONLY: tddfpt_ground_state_mos
46 #include "./base/base_uses.f90"
47 
48  IMPLICIT NONE
49 
50  PRIVATE
51 
52  CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_tddfpt2_restart'
53 
54  LOGICAL, PARAMETER, PRIVATE :: debug_this_module = .false.
55  ! number of first derivative components (3: d/dx, d/dy, d/dz)
56  INTEGER, PARAMETER, PRIVATE :: nderivs = 3
57  INTEGER, PARAMETER, PRIVATE :: maxspins = 2
58 
60 
61 ! **************************************************************************************************
62 
63 CONTAINS
64 
65 ! **************************************************************************************************
66 !> \brief Write Ritz vectors to a binary restart file.
67 !> \param evects vectors to store
68 !> \param evals TDDFPT eigenvalues
69 !> \param gs_mos structure that holds ground state occupied and virtual
70 !> molecular orbitals
71 !> \param logger a logger object
72 !> \param tddfpt_print_section TDDFPT%PRINT input section
73 !> \par History
74 !> * 08.2016 created [Sergey Chulkov]
75 ! **************************************************************************************************
76  SUBROUTINE tddfpt_write_restart(evects, evals, gs_mos, logger, tddfpt_print_section)
77  TYPE(cp_fm_type), DIMENSION(:, :), INTENT(in) :: evects
78  REAL(kind=dp), DIMENSION(:), INTENT(in) :: evals
79  TYPE(tddfpt_ground_state_mos), DIMENSION(:), &
80  INTENT(in) :: gs_mos
81  TYPE(cp_logger_type), POINTER :: logger
82  TYPE(section_vals_type), POINTER :: tddfpt_print_section
83 
84  CHARACTER(LEN=*), PARAMETER :: routinen = 'tddfpt_write_restart'
85 
86  INTEGER :: handle, ispin, istate, nao, nspins, &
87  nstates, ounit
88  INTEGER, DIMENSION(maxspins) :: nmo_occ
89 
90  IF (btest(cp_print_key_should_output(logger%iter_info, tddfpt_print_section, "RESTART"), cp_p_file)) THEN
91  CALL timeset(routinen, handle)
92 
93  nspins = SIZE(evects, 1)
94  nstates = SIZE(evects, 2)
95 
96  IF (debug_this_module) THEN
97  cpassert(SIZE(evals) == nstates)
98  cpassert(nspins > 0)
99  cpassert(nstates > 0)
100  END IF
101 
102  CALL cp_fm_get_info(gs_mos(1)%mos_occ, nrow_global=nao)
103 
104  DO ispin = 1, nspins
105  nmo_occ(ispin) = SIZE(gs_mos(ispin)%evals_occ)
106  END DO
107 
108  ounit = cp_print_key_unit_nr(logger, tddfpt_print_section, "RESTART", &
109  extension=".tdwfn", file_status="REPLACE", file_action="WRITE", &
110  do_backup=.true., file_form="UNFORMATTED")
111 
112  IF (ounit > 0) THEN
113  WRITE (ounit) nstates, nspins, nao
114  WRITE (ounit) nmo_occ(1:nspins)
115  WRITE (ounit) evals
116  END IF
117 
118  DO istate = 1, nstates
119  DO ispin = 1, nspins
120  ! TDDFPT wave function is actually stored as a linear combination of virtual MOs
121  ! that replaces the corresponding deoccupied MO. Unfortunately, the phase
122  ! of the occupied MOs varies depending on the eigensolver used as well as
123  ! how eigenvectors are distributed across computational cores. The phase is important
124  ! because TDDFPT wave functions are used to compute a response electron density
125  ! \rho^{-} = 1/2 * [C_{0} * evect^T + evect * C_{0}^{-}], where C_{0} is the expansion
126  ! coefficients of the reference ground-state wave function. To make the restart file
127  ! transferable, TDDFPT wave functions are stored in assumption that all ground state
128  ! MOs have a positive phase.
129  CALL cp_fm_column_scale(evects(ispin, istate), gs_mos(ispin)%phases_occ)
130 
131  CALL cp_fm_write_unformatted(evects(ispin, istate), ounit)
132 
133  CALL cp_fm_column_scale(evects(ispin, istate), gs_mos(ispin)%phases_occ)
134  END DO
135  END DO
136 
137  CALL cp_print_key_finished_output(ounit, logger, tddfpt_print_section, "RESTART")
138 
139  CALL timestop(handle)
140  END IF
141 
142  END SUBROUTINE tddfpt_write_restart
143 
144 ! **************************************************************************************************
145 !> \brief Initialise initial guess vectors by reading (un-normalised) Ritz vectors
146 !> from a binary restart file.
147 !> \param evects vectors to initialise (initialised on exit)
148 !> \param evals TDDFPT eigenvalues (initialised on exit)
149 !> \param gs_mos structure that holds ground state occupied and virtual
150 !> molecular orbitals
151 !> \param logger a logger object
152 !> \param tddfpt_section TDDFPT input section
153 !> \param tddfpt_print_section TDDFPT%PRINT input section
154 !> \param fm_pool_ao_mo_occ pools of dense matrices with shape [nao x nmo_occ(spin)]
155 !> \param blacs_env_global BLACS parallel environment involving all the processor
156 !> \return the number of excited states found in the restart file
157 !> \par History
158 !> * 08.2016 created [Sergey Chulkov]
159 ! **************************************************************************************************
160  FUNCTION tddfpt_read_restart(evects, evals, gs_mos, logger, tddfpt_section, tddfpt_print_section, &
161  fm_pool_ao_mo_occ, blacs_env_global) RESULT(nstates_read)
162  TYPE(cp_fm_type), DIMENSION(:, :), INTENT(inout) :: evects
163  REAL(kind=dp), DIMENSION(:), INTENT(out) :: evals
164  TYPE(tddfpt_ground_state_mos), DIMENSION(:), &
165  INTENT(in) :: gs_mos
166  TYPE(cp_logger_type), POINTER :: logger
167  TYPE(section_vals_type), POINTER :: tddfpt_section, tddfpt_print_section
168  TYPE(cp_fm_pool_p_type), DIMENSION(:), INTENT(in) :: fm_pool_ao_mo_occ
169  TYPE(cp_blacs_env_type), POINTER :: blacs_env_global
170  INTEGER :: nstates_read
171 
172  CHARACTER(LEN=*), PARAMETER :: routinen = 'tddfpt_read_restart'
173 
174  CHARACTER(len=20) :: read_str, ref_str
175  CHARACTER(LEN=default_path_length) :: filename
176  INTEGER :: handle, ispin, istate, iunit, n_rep_val, &
177  nao, nao_read, nspins, nspins_read, &
178  nstates
179  INTEGER, DIMENSION(maxspins) :: nmo_occ, nmo_occ_read
180  LOGICAL :: file_exists
181  REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: evals_read
182  TYPE(mp_para_env_type), POINTER :: para_env_global
183  TYPE(section_vals_type), POINTER :: print_key
184 
185  CALL timeset(routinen, handle)
186 
187  cpassert(ASSOCIATED(tddfpt_section))
188 
189  ! generate restart file name
190  CALL section_vals_val_get(tddfpt_section, "WFN_RESTART_FILE_NAME", n_rep_val=n_rep_val)
191  IF (n_rep_val > 0) THEN
192  CALL section_vals_val_get(tddfpt_section, "WFN_RESTART_FILE_NAME", c_val=filename)
193  ELSE
194  print_key => section_vals_get_subs_vals(tddfpt_print_section, "RESTART")
195  filename = cp_print_key_generate_filename(logger, print_key, &
196  extension=".tdwfn", my_local=.false.)
197  END IF
198 
199  CALL blacs_env_global%get(para_env=para_env_global)
200 
201  IF (para_env_global%is_source()) THEN
202  INQUIRE (file=filename, exist=file_exists)
203 
204  IF (.NOT. file_exists) THEN
205  nstates_read = 0
206  CALL para_env_global%bcast(nstates_read)
207 
208  CALL cp_warn(__location__, &
209  "User requested to restart the TDDFPT wave functions from the file '"//trim(filename)// &
210  "' which does not exist. Guess wave functions will be constructed using Kohn-Sham orbitals.")
211  CALL timestop(handle)
212  RETURN
213  END IF
214 
215  CALL open_file(file_name=filename, file_action="READ", file_form="UNFORMATTED", &
216  file_status="OLD", unit_number=iunit)
217  END IF
218 
219  nspins = SIZE(evects, 1)
220  nstates = SIZE(evects, 2)
221  CALL cp_fm_get_info(gs_mos(1)%mos_occ, nrow_global=nao)
222 
223  DO ispin = 1, nspins
224  nmo_occ(ispin) = SIZE(gs_mos(ispin)%evals_occ)
225  END DO
226 
227  IF (para_env_global%is_source()) THEN
228  READ (iunit) nstates_read, nspins_read, nao_read
229 
230  IF (nspins_read /= nspins) THEN
231  CALL integer_to_string(nspins, ref_str)
232  CALL integer_to_string(nspins_read, read_str)
233  CALL cp_abort(__location__, &
234  "Restarted TDDFPT wave function contains incompatible number of spin components ("// &
235  trim(read_str)//" instead of "//trim(ref_str)//").")
236  END IF
237 
238  IF (nao_read /= nao) THEN
239  CALL integer_to_string(nao, ref_str)
240  CALL integer_to_string(nao_read, read_str)
241  CALL cp_abort(__location__, &
242  "Incompatible number of atomic orbitals ("//trim(read_str)//" instead of "//trim(ref_str)//").")
243  END IF
244 
245  READ (iunit) nmo_occ_read(1:nspins)
246 
247  DO ispin = 1, nspins
248  IF (nmo_occ_read(ispin) /= nmo_occ(ispin)) THEN
249  CALL cp_abort(__location__, &
250  "Incompatible number of electrons and/or multiplicity.")
251  END IF
252  END DO
253 
254  IF (nstates_read /= nstates) THEN
255  CALL integer_to_string(nstates, ref_str)
256  CALL integer_to_string(nstates_read, read_str)
257  CALL cp_warn(__location__, &
258  "TDDFPT restart file contains "//trim(read_str)// &
259  " wave function(s) however "//trim(ref_str)// &
260  " excited states were requested.")
261  END IF
262  END IF
263  CALL para_env_global%bcast(nstates_read)
264 
265  ! exit if restart file does not exist
266  IF (nstates_read <= 0) THEN
267  CALL timestop(handle)
268  RETURN
269  END IF
270 
271  IF (para_env_global%is_source()) THEN
272  ALLOCATE (evals_read(nstates_read))
273  READ (iunit) evals_read
274  IF (nstates_read <= nstates) THEN
275  evals(1:nstates_read) = evals_read(1:nstates_read)
276  ELSE
277  evals(1:nstates) = evals_read(1:nstates)
278  END IF
279  DEALLOCATE (evals_read)
280  END IF
281  CALL para_env_global%bcast(evals)
282 
283  DO istate = 1, nstates_read
284  DO ispin = 1, nspins
285  IF (istate <= nstates) THEN
286  CALL fm_pool_create_fm(fm_pool_ao_mo_occ(ispin)%pool, evects(ispin, istate))
287 
288  CALL cp_fm_read_unformatted(evects(ispin, istate), iunit)
289 
290  CALL cp_fm_column_scale(evects(ispin, istate), gs_mos(ispin)%phases_occ)
291  END IF
292  END DO
293  END DO
294 
295  IF (para_env_global%is_source()) &
296  CALL close_file(unit_number=iunit)
297 
298  CALL timestop(handle)
299 
300  END FUNCTION tddfpt_read_restart
301 ! **************************************************************************************************
302 !> \brief Write Ritz vectors to a binary restart file.
303 !> \param evects vectors to store
304 !> \param evals TDDFPT eigenvalues
305 !> \param gs_mos structure that holds ground state occupied and virtual
306 !> molecular orbitals
307 !> \param logger a logger object
308 !> \param tddfpt_print_section TDDFPT%PRINT input section
309 !> \param matrix_s ...
310 !> \param S_evects ...
311 !> \param sub_env ...
312 ! **************************************************************************************************
313  SUBROUTINE tddfpt_write_newtonx_output(evects, evals, gs_mos, logger, tddfpt_print_section, &
314  matrix_s, S_evects, sub_env)
315 
316  TYPE(cp_fm_type), DIMENSION(:, :), INTENT(in) :: evects
317  REAL(kind=dp), DIMENSION(:), INTENT(in) :: evals
318  TYPE(tddfpt_ground_state_mos), DIMENSION(:), &
319  INTENT(in) :: gs_mos
320  TYPE(cp_logger_type), INTENT(in), POINTER :: logger
321  TYPE(section_vals_type), INTENT(in), POINTER :: tddfpt_print_section
322  TYPE(dbcsr_type), INTENT(in), POINTER :: matrix_s
323  TYPE(cp_fm_type), DIMENSION(:, :), INTENT(in) :: s_evects
324  TYPE(tddfpt_subgroup_env_type), INTENT(in) :: sub_env
325 
326  CHARACTER(LEN=*), PARAMETER :: routinen = 'tddfpt_write_newtonx_output'
327 
328  INTEGER :: handle, iocc, ispin, istate, ivirt, nao, &
329  nspins, nstates, ounit
330  INTEGER, DIMENSION(maxspins) :: nmo_occ, nmo_virt
331  LOGICAL :: print_phases, print_virtuals, &
332  scale_with_phases
333  REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: phase_evects
334  TYPE(cp_fm_struct_type), POINTER :: fmstruct
335  TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:, :) :: evects_mo
336 
337  IF (btest(cp_print_key_should_output(logger%iter_info, tddfpt_print_section, "NAMD_PRINT"), cp_p_file)) THEN
338  CALL timeset(routinen, handle)
339  CALL section_vals_val_get(tddfpt_print_section, "NAMD_PRINT%PRINT_VIRTUALS", l_val=print_virtuals)
340  CALL section_vals_val_get(tddfpt_print_section, "NAMD_PRINT%PRINT_PHASES", l_val=print_phases)
341  CALL section_vals_val_get(tddfpt_print_section, "NAMD_PRINT%SCALE_WITH_PHASES", l_val=scale_with_phases)
342 
343  nspins = SIZE(evects, 1)
344  nstates = SIZE(evects, 2)
345 
346  IF (debug_this_module) THEN
347  cpassert(SIZE(evals) == nstates)
348  cpassert(nspins > 0)
349  cpassert(nstates > 0)
350  END IF
351 
352  CALL cp_fm_get_info(gs_mos(1)%mos_occ, nrow_global=nao)
353 
354  IF (sub_env%is_split) THEN
355  CALL cp_abort(__location__, "NEWTONX interface print not possible when states"// &
356  " are distributed to different CPU pools.")
357  END IF
358 
359  ounit = cp_print_key_unit_nr(logger, tddfpt_print_section, "NAMD_PRINT", &
360  extension=".inp", file_form="FORMATTED", file_action="WRITE", file_status="REPLACE")
361  IF (debug_this_module) CALL tddfpt_check_orthonormality(evects, ounit, s_evects, matrix_s)
362 
363  ! print eigenvectors
364  IF (print_virtuals) THEN
365  ALLOCATE (evects_mo(nspins, nstates))
366  DO istate = 1, nstates
367  DO ispin = 1, nspins
368 
369  ! transform eigenvectors
370  NULLIFY (fmstruct)
371  nmo_occ(ispin) = SIZE(gs_mos(ispin)%evals_occ)
372  nmo_virt(ispin) = SIZE(gs_mos(ispin)%evals_virt)
373  CALL cp_fm_struct_create(fmstruct, para_env=sub_env%para_env, &
374  context=sub_env%blacs_env, &
375  nrow_global=nmo_virt(ispin), ncol_global=nmo_occ(ispin))
376  CALL cp_fm_create(evects_mo(ispin, istate), fmstruct)
377  CALL cp_fm_struct_release(fmstruct)
378  CALL cp_dbcsr_sm_fm_multiply(matrix_s, evects(ispin, istate), s_evects(ispin, istate), &
379  ncol=nmo_occ(ispin), alpha=1.0_dp, beta=0.0_dp)
380  END DO
381  END DO
382  DO istate = 1, nstates
383  DO ispin = 1, nspins
384  CALL parallel_gemm("T", "N", &
385  nmo_virt(ispin), &
386  nmo_occ(ispin), &
387  nao, &
388  1.0_dp, &
389  gs_mos(ispin)%mos_virt, &
390  s_evects(ispin, istate), & !this also needs to be orthogonalized
391  0.0_dp, &
392  evects_mo(ispin, istate))
393  END DO
394  END DO
395  END IF
396 
397  DO istate = 1, nstates
398  DO ispin = 1, nspins
399 
400  IF (.NOT. print_virtuals) THEN
401  CALL cp_fm_column_scale(evects(ispin, istate), gs_mos(ispin)%phases_occ)
402  IF (ounit > 0) THEN
403  WRITE (ounit, "(/,A)") "ES EIGENVECTORS SIZE"
404  CALL cp_fm_write_info(evects(ispin, istate), ounit)
405  END IF
406  CALL cp_fm_write_formatted(evects(ispin, istate), ounit, "ES EIGENVECTORS")
407  ELSE
408  CALL cp_fm_column_scale(evects_mo(ispin, istate), gs_mos(ispin)%phases_occ)
409  IF (ounit > 0) THEN
410  WRITE (ounit, "(/,A)") "ES EIGENVECTORS SIZE"
411  CALL cp_fm_write_info(evects_mo(ispin, istate), ounit)
412  END IF
413  CALL cp_fm_write_formatted(evects_mo(ispin, istate), ounit, "ES EIGENVECTORS")
414  END IF
415 
416  ! compute and print phase of eigenvectors
417  nmo_occ(ispin) = SIZE(gs_mos(ispin)%evals_occ)
418  ALLOCATE (phase_evects(nmo_occ(ispin)))
419  IF (print_virtuals) THEN
420  CALL compute_phase_eigenvectors(evects_mo(ispin, istate), phase_evects, sub_env)
421  ELSE
422  CALL compute_phase_eigenvectors(evects(ispin, istate), phase_evects, sub_env)
423  END IF
424  IF (ounit > 0) THEN
425  WRITE (ounit, "(/,A,/)") "PHASES ES EIGENVECTORS"
426  DO iocc = 1, nmo_occ(ispin)
427  WRITE (ounit, "(F20.14)") phase_evects(iocc)
428  END DO
429  END IF
430  DEALLOCATE (phase_evects)
431 
432  END DO
433  END DO
434 
435  IF (print_virtuals) THEN
436  CALL cp_fm_release(evects_mo)
437  END IF
438 
439  DO ispin = 1, nspins
440  IF (ounit > 0) THEN
441  WRITE (ounit, "(/,A)") "OCCUPIED MOS SIZE"
442  CALL cp_fm_write_info(gs_mos(ispin)%mos_occ, ounit)
443  END IF
444  CALL cp_fm_write_formatted(gs_mos(ispin)%mos_occ, ounit, "OCCUPIED MO COEFFICIENTS")
445  END DO
446 
447  IF (ounit > 0) THEN
448  WRITE (ounit, "(A)") "OCCUPIED MO EIGENVALUES"
449  DO ispin = 1, nspins
450  nmo_occ(ispin) = SIZE(gs_mos(ispin)%evals_occ)
451  DO iocc = 1, nmo_occ(ispin)
452  WRITE (ounit, "(F20.14)") gs_mos(ispin)%evals_occ(iocc)
453  END DO
454  END DO
455  END IF
456 !
457  IF (print_virtuals) THEN
458  DO ispin = 1, nspins
459  IF (ounit > 0) THEN
460  WRITE (ounit, "(/,A)") "VIRTUAL MOS SIZE"
461  CALL cp_fm_write_info(gs_mos(ispin)%mos_virt, ounit)
462  END IF
463  CALL cp_fm_write_formatted(gs_mos(ispin)%mos_virt, ounit, "VIRTUAL MO COEFFICIENTS")
464  END DO
465 
466  IF (ounit > 0) THEN
467  WRITE (ounit, "(A)") "VIRTUAL MO EIGENVALUES"
468  DO ispin = 1, nspins
469  nmo_virt(ispin) = SIZE(gs_mos(ispin)%evals_virt)
470  DO ivirt = 1, nmo_virt(ispin)
471  WRITE (ounit, "(F20.14)") gs_mos(ispin)%evals_virt(ivirt)
472  END DO
473  END DO
474  END IF
475  END IF
476 
477  ! print phases of molecular orbitals
478 
479  IF (print_phases) THEN
480  IF (ounit > 0) THEN
481  WRITE (ounit, "(A)") "PHASES OCCUPIED ORBITALS"
482  DO ispin = 1, nspins
483  DO iocc = 1, nmo_occ(ispin)
484  WRITE (ounit, "(F20.14)") gs_mos(ispin)%phases_occ(iocc)
485  END DO
486  END DO
487  IF (print_virtuals) THEN
488  WRITE (ounit, "(A)") "PHASES VIRTUAL ORBITALS"
489  DO ispin = 1, nspins
490  DO ivirt = 1, nmo_virt(ispin)
491  WRITE (ounit, "(F20.14)") gs_mos(ispin)%phases_virt(ivirt)
492  END DO
493  END DO
494  END IF
495  END IF
496  END IF
497 
498  CALL cp_print_key_finished_output(ounit, logger, tddfpt_print_section, "NAMD_PRINT")
499 
500  CALL timestop(handle)
501  END IF
502 
503  END SUBROUTINE tddfpt_write_newtonx_output
504 ! **************************************************************************************************
505 !> \brief ...
506 !> \param evects ...
507 !> \param ounit ...
508 !> \param S_evects ...
509 !> \param matrix_s ...
510 ! **************************************************************************************************
511  SUBROUTINE tddfpt_check_orthonormality(evects, ounit, S_evects, matrix_s)
512 
513  TYPE(cp_fm_type), DIMENSION(:, :), INTENT(in) :: evects
514  INTEGER, INTENT(in) :: ounit
515  TYPE(cp_fm_type), DIMENSION(:, :), INTENT(in) :: s_evects
516  TYPE(dbcsr_type), INTENT(in), POINTER :: matrix_s
517 
518  CHARACTER(LEN=*), PARAMETER :: routinen = 'tddfpt_check_orthonormality'
519 
520  INTEGER :: handle, ispin, ivect, jvect, nspins, &
521  nvects_total
522  INTEGER, DIMENSION(maxspins) :: nactive
523  REAL(kind=dp) :: norm
524  REAL(kind=dp), DIMENSION(maxspins) :: weights
525 
526  CALL timeset(routinen, handle)
527 
528  nspins = SIZE(evects, 1)
529  nvects_total = SIZE(evects, 2)
530 
531  IF (debug_this_module) THEN
532  cpassert(SIZE(s_evects, 1) == nspins)
533  cpassert(SIZE(s_evects, 2) == nvects_total)
534  END IF
535 
536  DO ispin = 1, nspins
537  CALL cp_fm_get_info(matrix=evects(ispin, 1), ncol_global=nactive(ispin))
538  END DO
539 
540  DO jvect = 1, nvects_total
541  ! <psi1_i | psi1_j>
542  DO ivect = 1, jvect - 1
543  CALL cp_fm_trace(evects(:, jvect), s_evects(:, ivect), weights(1:nspins), accurate=.false.)
544  norm = sum(weights(1:nspins))
545 
546  DO ispin = 1, nspins
547  CALL cp_fm_scale_and_add(1.0_dp, evects(ispin, jvect), -norm, evects(ispin, ivect))
548  END DO
549  END DO
550 
551  ! <psi1_j | psi1_j>
552  DO ispin = 1, nspins
553  CALL cp_dbcsr_sm_fm_multiply(matrix_s, evects(ispin, jvect), s_evects(ispin, jvect), &
554  ncol=nactive(ispin), alpha=1.0_dp, beta=0.0_dp)
555  END DO
556 
557  CALL cp_fm_trace(evects(:, jvect), s_evects(:, jvect), weights(1:nspins), accurate=.false.)
558 
559  norm = sum(weights(1:nspins))
560  norm = 1.0_dp/sqrt(norm)
561 
562  IF ((ounit > 0) .AND. debug_this_module) WRITE (ounit, '(A,F10.8)') "norm", norm
563 
564  END DO
565 
566  CALL timestop(handle)
567 
568  END SUBROUTINE tddfpt_check_orthonormality
569 ! **************************************************************************************************
570 !> \brief ...
571 !> \param evects ...
572 !> \param phase_evects ...
573 !> \param sub_env ...
574 ! **************************************************************************************************
575  SUBROUTINE compute_phase_eigenvectors(evects, phase_evects, sub_env)
576 
577  ! copied from parts of tddgpt_init_ground_state_mos by S. Chulkov
578 
579  TYPE(cp_fm_type), INTENT(in) :: evects
580  REAL(kind=dp), DIMENSION(:), INTENT(out) :: phase_evects
581  TYPE(tddfpt_subgroup_env_type), INTENT(in) :: sub_env
582 
583  CHARACTER(len=*), PARAMETER :: routinen = 'compute_phase_eigenvectors'
584  REAL(kind=dp), PARAMETER :: eps_dp = epsilon(0.0_dp)
585 
586  INTEGER :: handle, icol_global, icol_local, irow_global, irow_local, ncol_global, &
587  ncol_local, nrow_global, nrow_local, sign_int
588  INTEGER, ALLOCATABLE, DIMENSION(:) :: minrow_neg_array, minrow_pos_array, &
589  sum_sign_array
590  INTEGER, DIMENSION(:), POINTER :: col_indices, row_indices
591  REAL(kind=dp) :: element
592  REAL(kind=dp), CONTIGUOUS, DIMENSION(:, :), &
593  POINTER :: my_block
594 
595  CALL timeset(routinen, handle)
596 
597  ! compute and print the phase of excited-state eigenvectors:
598  CALL cp_fm_get_info(evects, nrow_global=nrow_global, ncol_global=ncol_global, &
599  nrow_local=nrow_local, ncol_local=ncol_local, local_data=my_block, &
600  row_indices=row_indices, col_indices=col_indices) ! nrow_global either nao or nocc
601 
602  ALLOCATE (minrow_neg_array(ncol_global), minrow_pos_array(ncol_global), sum_sign_array(ncol_global))
603  minrow_neg_array(:) = nrow_global
604  minrow_pos_array(:) = nrow_global
605  sum_sign_array(:) = 0
606 
607  DO icol_local = 1, ncol_local
608  icol_global = col_indices(icol_local)
609 
610  DO irow_local = 1, nrow_local
611  irow_global = row_indices(irow_local)
612 
613  element = my_block(irow_local, icol_local)
614 
615  sign_int = 0
616  IF (element >= eps_dp) THEN
617  sign_int = 1
618  ELSE IF (element <= -eps_dp) THEN
619  sign_int = -1
620  END IF
621 
622  sum_sign_array(icol_global) = sum_sign_array(icol_global) + sign_int
623 
624  IF (sign_int > 0) THEN
625  IF (minrow_pos_array(icol_global) > irow_global) &
626  minrow_pos_array(icol_global) = irow_global
627  ELSE IF (sign_int < 0) THEN
628  IF (minrow_neg_array(icol_global) > irow_global) &
629  minrow_neg_array(icol_global) = irow_global
630  END IF
631 
632  END DO
633  END DO
634 
635  CALL sub_env%para_env%sum(sum_sign_array)
636  CALL sub_env%para_env%min(minrow_neg_array)
637  CALL sub_env%para_env%min(minrow_pos_array)
638 
639  DO icol_global = 1, ncol_global
640 
641  IF (sum_sign_array(icol_global) > 0) THEN
642  ! most of the expansion coefficients are positive => MO's phase = +1
643  phase_evects(icol_global) = 1.0_dp
644  ELSE IF (sum_sign_array(icol_global) < 0) THEN
645  ! most of the expansion coefficients are negative => MO's phase = -1
646  phase_evects(icol_global) = -1.0_dp
647  ELSE
648  ! equal number of positive and negative expansion coefficients
649  IF (minrow_pos_array(icol_global) <= minrow_neg_array(icol_global)) THEN
650  ! the first positive expansion coefficient has a lower index then
651  ! the first negative expansion coefficient; MO's phase = +1
652  phase_evects(icol_global) = 1.0_dp
653  ELSE
654  ! MO's phase = -1
655  phase_evects(icol_global) = -1.0_dp
656  END IF
657  END IF
658 
659  END DO
660 
661  DEALLOCATE (minrow_neg_array, minrow_pos_array, sum_sign_array)
662 
663  CALL timestop(handle)
664 
665  END SUBROUTINE compute_phase_eigenvectors
666 
667 END MODULE qs_tddfpt2_restart
methods related to the blacs parallel environment
Definition: cp_blacs_env.F:15
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
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_column_scale(matrixa, scaling)
scales column i of matrix a with scaling(i)
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....
pool for for elements that are retained and released
subroutine, public fm_pool_create_fm(pool, element, name)
returns an element, allocating it if none is in the pool
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_write_unformatted(fm, unit)
...
Definition: cp_fm_types.F:2147
subroutine, public cp_fm_read_unformatted(fm, unit)
...
Definition: cp_fm_types.F:2379
subroutine, public cp_fm_write_info(matrix, io_unit)
Write nicely formatted info about the FM to the given I/O unit (including the underlying FM struct)
Definition: cp_fm_types.F:1048
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
subroutine, public cp_fm_write_formatted(fm, unit, header, value_format)
Write out a full matrix in plain text.
Definition: cp_fm_types.F:2251
various routines to log and control the output. The idea is that decisions about where to log should ...
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...
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_path_length
Definition: kinds.F:58
Interface to the message passing library MPI.
basic linear algebra operations for full matrixes
integer function, public tddfpt_read_restart(evects, evals, gs_mos, logger, tddfpt_section, tddfpt_print_section, fm_pool_ao_mo_occ, blacs_env_global)
Initialise initial guess vectors by reading (un-normalised) Ritz vectors from a binary restart file.
subroutine, public tddfpt_write_restart(evects, evals, gs_mos, logger, tddfpt_print_section)
Write Ritz vectors to a binary restart file.
subroutine, public tddfpt_check_orthonormality(evects, ounit, S_evects, matrix_s)
...
subroutine, public tddfpt_write_newtonx_output(evects, evals, gs_mos, logger, tddfpt_print_section, matrix_s, S_evects, sub_env)
Write Ritz vectors to a binary restart file.
Utilities for string manipulations.
subroutine, public integer_to_string(inumber, string)
Converts an integer number to a string. The WRITE statement will return an error message,...