(git:374b731)
Loading...
Searching...
No Matches
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
11 USE cp_files, ONLY: close_file,&
21 USE cp_fm_types, ONLY: cp_fm_create,&
30 USE cp_output_handling, ONLY: cp_p_file,&
35 USE dbcsr_api, ONLY: dbcsr_type
39 USE kinds, ONLY: default_path_length,&
40 dp
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
63CONTAINS
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
667END MODULE qs_tddfpt2_restart
methods related to the blacs parallel environment
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
logical function, public file_exists(file_name)
Checks if file exists, considering also the file discovery mechanism.
Definition cp_files.F:494
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
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
subroutine, public cp_fm_struct_release(fmstruct)
releases a full matrix structure
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_write_unformatted(fm, unit)
...
subroutine, public cp_fm_read_unformatted(fm, unit)
...
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)
subroutine, public cp_fm_create(matrix, matrix_struct, name, use_sp)
creates a new full matrix with the given structure
subroutine, public cp_fm_write_formatted(fm, unit, header, value_format)
Write out a full matrix in plain text.
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_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.
subroutine, public tddfpt_write_restart(evects, evals, gs_mos, logger, tddfpt_print_section)
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,...
represent a blacs multidimensional parallel environment (for the mpi corrispective see cp_paratypes/m...
keeps the information about the structure of a full matrix
represent a full matrix
type of a logger, at the moment it contains just a print level starting at which level it should be l...
stores all the informations relevant to an mpi environment
Ground state molecular orbitals.