(git:ab76537)
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-2025 CP2K developers group <https://cp2k.org> !
4! !
5! SPDX-License-Identifier: GPL-2.0-or-later !
6!--------------------------------------------------------------------------------------------------!
7
10 USE cp_dbcsr_api, ONLY: dbcsr_type
12 USE cp_files, ONLY: close_file,&
23 USE cp_fm_types, ONLY: cp_fm_create,&
32 USE cp_output_handling, ONLY: cp_p_file,&
40 USE kinds, ONLY: default_path_length,&
41 dp
47#include "./base/base_uses.f90"
48
49 IMPLICIT NONE
50
51 PRIVATE
52
53 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_tddfpt2_restart'
54
55 LOGICAL, PARAMETER, PRIVATE :: debug_this_module = .false.
56 ! number of first derivative components (3: d/dx, d/dy, d/dz)
57 INTEGER, PARAMETER, PRIVATE :: nderivs = 3
58 INTEGER, PARAMETER, PRIVATE :: maxspins = 2
59
61
62! **************************************************************************************************
63
64CONTAINS
65
66! **************************************************************************************************
67!> \brief Write Ritz vectors to a binary restart file.
68!> \param evects vectors to store
69!> \param evals TDDFPT eigenvalues
70!> \param gs_mos structure that holds ground state occupied and virtual
71!> molecular orbitals
72!> \param logger a logger object
73!> \param tddfpt_print_section TDDFPT%PRINT input section
74!> \par History
75!> * 08.2016 created [Sergey Chulkov]
76! **************************************************************************************************
77 SUBROUTINE tddfpt_write_restart(evects, evals, gs_mos, logger, tddfpt_print_section)
78 TYPE(cp_fm_type), DIMENSION(:, :), INTENT(in) :: evects
79 REAL(kind=dp), DIMENSION(:), INTENT(in) :: evals
80 TYPE(tddfpt_ground_state_mos), DIMENSION(:), &
81 INTENT(in) :: gs_mos
82 TYPE(cp_logger_type), POINTER :: logger
83 TYPE(section_vals_type), POINTER :: tddfpt_print_section
84
85 CHARACTER(LEN=*), PARAMETER :: routinen = 'tddfpt_write_restart'
86
87 INTEGER :: handle, ispin, istate, nao, nspins, &
88 nstates, ounit
89 INTEGER, DIMENSION(maxspins) :: nmo_active
90
91 IF (btest(cp_print_key_should_output(logger%iter_info, tddfpt_print_section, "RESTART"), cp_p_file)) THEN
92 CALL timeset(routinen, handle)
93
94 nspins = SIZE(evects, 1)
95 nstates = SIZE(evects, 2)
96
97 IF (debug_this_module) THEN
98 cpassert(SIZE(evals) == nstates)
99 cpassert(nspins > 0)
100 cpassert(nstates > 0)
101 END IF
102
103 CALL cp_fm_get_info(evects(1, 1), nrow_global=nao)
104 DO ispin = 1, nspins
105 CALL cp_fm_get_info(evects(ispin, 1), ncol_global=nmo_active(ispin))
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_active(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_active pools of dense matrices with shape [nao x nmo_active(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_active, 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_active
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_active, nmo_active_read
180 LOGICAL :: file_exists
181 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: evals_read
182 TYPE(cp_fm_type) :: evtest
183 TYPE(mp_para_env_type), POINTER :: para_env_global
184 TYPE(section_vals_type), POINTER :: print_key
185
186 CALL timeset(routinen, handle)
187
188 cpassert(ASSOCIATED(tddfpt_section))
189
190 ! generate restart file name
191 CALL section_vals_val_get(tddfpt_section, "WFN_RESTART_FILE_NAME", n_rep_val=n_rep_val)
192 IF (n_rep_val > 0) THEN
193 CALL section_vals_val_get(tddfpt_section, "WFN_RESTART_FILE_NAME", c_val=filename)
194 ELSE
195 print_key => section_vals_get_subs_vals(tddfpt_print_section, "RESTART")
196 filename = cp_print_key_generate_filename(logger, print_key, &
197 extension=".tdwfn", my_local=.false.)
198 END IF
199
200 CALL blacs_env_global%get(para_env=para_env_global)
201
202 IF (para_env_global%is_source()) THEN
203 INQUIRE (file=filename, exist=file_exists)
204
205 IF (.NOT. file_exists) THEN
206 nstates_read = 0
207 CALL para_env_global%bcast(nstates_read)
208
209 CALL cp_warn(__location__, &
210 "User requested to restart the TDDFPT wave functions from the file '"//trim(filename)// &
211 "' which does not exist. Guess wave functions will be constructed using Kohn-Sham orbitals.")
212 CALL timestop(handle)
213 RETURN
214 END IF
215
216 CALL open_file(file_name=filename, file_action="READ", file_form="UNFORMATTED", &
217 file_status="OLD", unit_number=iunit)
218 END IF
219
220 nspins = SIZE(evects, 1)
221 nstates = SIZE(evects, 2)
222
223 DO ispin = 1, nspins
224 CALL fm_pool_create_fm(fm_pool_ao_mo_active(ispin)%pool, evtest)
225 CALL cp_fm_get_info(evtest, nrow_global=nao, ncol_global=nmo_active(ispin))
226 CALL fm_pool_give_back_fm(fm_pool_ao_mo_active(ispin)%pool, evtest)
227 END DO
228
229 IF (para_env_global%is_source()) THEN
230 READ (iunit) nstates_read, nspins_read, nao_read
231
232 IF (nspins_read /= nspins) THEN
233 CALL integer_to_string(nspins, ref_str)
234 CALL integer_to_string(nspins_read, read_str)
235 CALL cp_abort(__location__, &
236 "Restarted TDDFPT wave function contains incompatible number of spin components ("// &
237 trim(read_str)//" instead of "//trim(ref_str)//").")
238 END IF
239
240 IF (nao_read /= nao) THEN
241 CALL integer_to_string(nao, ref_str)
242 CALL integer_to_string(nao_read, read_str)
243 CALL cp_abort(__location__, &
244 "Incompatible number of atomic orbitals ("//trim(read_str)//" instead of "//trim(ref_str)//").")
245 END IF
246
247 READ (iunit) nmo_active_read(1:nspins)
248
249 DO ispin = 1, nspins
250 IF (nmo_active_read(ispin) /= nmo_active(ispin)) THEN
251 CALL cp_abort(__location__, &
252 "Incompatible number of electrons and/or multiplicity.")
253 END IF
254 END DO
255
256 IF (nstates_read /= nstates) THEN
257 CALL integer_to_string(nstates, ref_str)
258 CALL integer_to_string(nstates_read, read_str)
259 CALL cp_warn(__location__, &
260 "TDDFPT restart file contains "//trim(read_str)// &
261 " wave function(s) however "//trim(ref_str)// &
262 " excited states were requested.")
263 END IF
264 END IF
265 CALL para_env_global%bcast(nstates_read)
266
267 ! exit if restart file does not exist
268 IF (nstates_read <= 0) THEN
269 CALL timestop(handle)
270 RETURN
271 END IF
272
273 IF (para_env_global%is_source()) THEN
274 ALLOCATE (evals_read(nstates_read))
275 READ (iunit) evals_read
276 IF (nstates_read <= nstates) THEN
277 evals(1:nstates_read) = evals_read(1:nstates_read)
278 ELSE
279 evals(1:nstates) = evals_read(1:nstates)
280 END IF
281 DEALLOCATE (evals_read)
282 END IF
283 CALL para_env_global%bcast(evals)
284
285 DO istate = 1, nstates_read
286 DO ispin = 1, nspins
287 IF (istate <= nstates) THEN
288 CALL fm_pool_create_fm(fm_pool_ao_mo_active(ispin)%pool, evects(ispin, istate))
289
290 CALL cp_fm_read_unformatted(evects(ispin, istate), iunit)
291
292 CALL cp_fm_column_scale(evects(ispin, istate), gs_mos(ispin)%phases_occ)
293 END IF
294 END DO
295 END DO
296
297 IF (para_env_global%is_source()) &
298 CALL close_file(unit_number=iunit)
299
300 CALL timestop(handle)
301
302 END FUNCTION tddfpt_read_restart
303! **************************************************************************************************
304!> \brief Write Ritz vectors to a binary restart file.
305!> \param evects vectors to store
306!> \param evals TDDFPT eigenvalues
307!> \param gs_mos structure that holds ground state occupied and virtual
308!> molecular orbitals
309!> \param logger a logger object
310!> \param tddfpt_print_section TDDFPT%PRINT input section
311!> \param matrix_s ...
312!> \param S_evects ...
313!> \param sub_env ...
314! **************************************************************************************************
315 SUBROUTINE tddfpt_write_newtonx_output(evects, evals, gs_mos, logger, tddfpt_print_section, &
316 matrix_s, S_evects, sub_env)
317
318 TYPE(cp_fm_type), DIMENSION(:, :), INTENT(in) :: evects
319 REAL(kind=dp), DIMENSION(:), INTENT(in) :: evals
320 TYPE(tddfpt_ground_state_mos), DIMENSION(:), &
321 INTENT(in) :: gs_mos
322 TYPE(cp_logger_type), INTENT(in), POINTER :: logger
323 TYPE(section_vals_type), INTENT(in), POINTER :: tddfpt_print_section
324 TYPE(dbcsr_type), INTENT(in), POINTER :: matrix_s
325 TYPE(cp_fm_type), DIMENSION(:, :), INTENT(INOUT) :: s_evects
326 TYPE(tddfpt_subgroup_env_type), INTENT(in) :: sub_env
327
328 CHARACTER(LEN=*), PARAMETER :: routinen = 'tddfpt_write_newtonx_output'
329
330 INTEGER :: handle, iocc, ispin, istate, ivirt, nao, &
331 nspins, nstates, ounit
332 INTEGER, DIMENSION(maxspins) :: nmo_active, nmo_occ, nmo_virt
333 LOGICAL :: print_phases, print_virtuals, &
334 scale_with_phases
335 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: phase_evects
336 TYPE(cp_fm_struct_type), POINTER :: fmstruct
337 TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:, :) :: evects_mo
338
339 IF (btest(cp_print_key_should_output(logger%iter_info, tddfpt_print_section, "NAMD_PRINT"), cp_p_file)) THEN
340 CALL timeset(routinen, handle)
341 CALL section_vals_val_get(tddfpt_print_section, "NAMD_PRINT%PRINT_VIRTUALS", l_val=print_virtuals)
342 CALL section_vals_val_get(tddfpt_print_section, "NAMD_PRINT%PRINT_PHASES", l_val=print_phases)
343 CALL section_vals_val_get(tddfpt_print_section, "NAMD_PRINT%SCALE_WITH_PHASES", l_val=scale_with_phases)
344
345 nspins = SIZE(evects, 1)
346 nstates = SIZE(evects, 2)
347
348 IF (debug_this_module) THEN
349 cpassert(SIZE(evals) == nstates)
350 cpassert(nspins > 0)
351 cpassert(nstates > 0)
352 END IF
353
354 CALL cp_fm_get_info(gs_mos(1)%mos_occ, nrow_global=nao)
355
356 IF (sub_env%is_split) THEN
357 CALL cp_abort(__location__, "NEWTONX interface print not possible when states"// &
358 " are distributed to different CPU pools.")
359 END IF
360
361 ! test for reduced active orbitals
362 DO ispin = 1, nspins
363 nmo_occ(ispin) = SIZE(gs_mos(ispin)%evals_occ)
364 CALL cp_fm_get_info(evects(ispin, 1), ncol_global=nmo_active(ispin))
365 IF (nmo_occ(ispin) /= nmo_active(ispin)) THEN
366 CALL cp_abort(__location__, "NEWTONX interface print not possible when using"// &
367 " a reduced set of active occupied orbitals.")
368 END IF
369 END DO
370
371 ounit = cp_print_key_unit_nr(logger, tddfpt_print_section, "NAMD_PRINT", &
372 extension=".inp", file_form="FORMATTED", file_action="WRITE", file_status="REPLACE")
373 IF (debug_this_module) CALL tddfpt_check_orthonormality(evects, ounit, s_evects, matrix_s)
374
375 ! print eigenvectors
376 IF (print_virtuals) THEN
377 ALLOCATE (evects_mo(nspins, nstates))
378 DO istate = 1, nstates
379 DO ispin = 1, nspins
380
381 ! transform eigenvectors
382 NULLIFY (fmstruct)
383 nmo_occ(ispin) = SIZE(gs_mos(ispin)%evals_occ)
384 nmo_virt(ispin) = SIZE(gs_mos(ispin)%evals_virt)
385 CALL cp_fm_struct_create(fmstruct, para_env=sub_env%para_env, &
386 context=sub_env%blacs_env, &
387 nrow_global=nmo_virt(ispin), ncol_global=nmo_occ(ispin))
388 CALL cp_fm_create(evects_mo(ispin, istate), fmstruct)
389 CALL cp_fm_struct_release(fmstruct)
390 CALL cp_dbcsr_sm_fm_multiply(matrix_s, evects(ispin, istate), s_evects(ispin, istate), &
391 ncol=nmo_occ(ispin), alpha=1.0_dp, beta=0.0_dp)
392 END DO
393 END DO
394 DO istate = 1, nstates
395 DO ispin = 1, nspins
396 CALL parallel_gemm("T", "N", &
397 nmo_virt(ispin), &
398 nmo_occ(ispin), &
399 nao, &
400 1.0_dp, &
401 gs_mos(ispin)%mos_virt, &
402 s_evects(ispin, istate), & !this also needs to be orthogonalized
403 0.0_dp, &
404 evects_mo(ispin, istate))
405 END DO
406 END DO
407 END IF
408
409 DO istate = 1, nstates
410 DO ispin = 1, nspins
411
412 IF (.NOT. print_virtuals) THEN
413 CALL cp_fm_column_scale(evects(ispin, istate), gs_mos(ispin)%phases_occ)
414 IF (ounit > 0) THEN
415 WRITE (ounit, "(/,A)") "ES EIGENVECTORS SIZE"
416 CALL cp_fm_write_info(evects(ispin, istate), ounit)
417 END IF
418 CALL cp_fm_write_formatted(evects(ispin, istate), ounit, "ES EIGENVECTORS")
419 ELSE
420 CALL cp_fm_column_scale(evects_mo(ispin, istate), gs_mos(ispin)%phases_occ)
421 IF (ounit > 0) THEN
422 WRITE (ounit, "(/,A)") "ES EIGENVECTORS SIZE"
423 CALL cp_fm_write_info(evects_mo(ispin, istate), ounit)
424 END IF
425 CALL cp_fm_write_formatted(evects_mo(ispin, istate), ounit, "ES EIGENVECTORS")
426 END IF
427
428 ! compute and print phase of eigenvectors
429 nmo_occ(ispin) = SIZE(gs_mos(ispin)%evals_occ)
430 ALLOCATE (phase_evects(nmo_occ(ispin)))
431 IF (print_virtuals) THEN
432 CALL compute_phase_eigenvectors(evects_mo(ispin, istate), phase_evects, sub_env)
433 ELSE
434 CALL compute_phase_eigenvectors(evects(ispin, istate), phase_evects, sub_env)
435 END IF
436 IF (ounit > 0) THEN
437 WRITE (ounit, "(/,A,/)") "PHASES ES EIGENVECTORS"
438 DO iocc = 1, nmo_occ(ispin)
439 WRITE (ounit, "(F20.14)") phase_evects(iocc)
440 END DO
441 END IF
442 DEALLOCATE (phase_evects)
443
444 END DO
445 END DO
446
447 IF (print_virtuals) THEN
448 CALL cp_fm_release(evects_mo)
449 END IF
450
451 DO ispin = 1, nspins
452 IF (ounit > 0) THEN
453 WRITE (ounit, "(/,A)") "OCCUPIED MOS SIZE"
454 CALL cp_fm_write_info(gs_mos(ispin)%mos_occ, ounit)
455 END IF
456 CALL cp_fm_write_formatted(gs_mos(ispin)%mos_occ, ounit, "OCCUPIED MO COEFFICIENTS")
457 END DO
458
459 IF (ounit > 0) THEN
460 WRITE (ounit, "(A)") "OCCUPIED MO EIGENVALUES"
461 DO ispin = 1, nspins
462 nmo_occ(ispin) = SIZE(gs_mos(ispin)%evals_occ)
463 DO iocc = 1, nmo_occ(ispin)
464 WRITE (ounit, "(F20.14)") gs_mos(ispin)%evals_occ(iocc)
465 END DO
466 END DO
467 END IF
468!
469 IF (print_virtuals) THEN
470 DO ispin = 1, nspins
471 IF (ounit > 0) THEN
472 WRITE (ounit, "(/,A)") "VIRTUAL MOS SIZE"
473 CALL cp_fm_write_info(gs_mos(ispin)%mos_virt, ounit)
474 END IF
475 CALL cp_fm_write_formatted(gs_mos(ispin)%mos_virt, ounit, "VIRTUAL MO COEFFICIENTS")
476 END DO
477
478 IF (ounit > 0) THEN
479 WRITE (ounit, "(A)") "VIRTUAL MO EIGENVALUES"
480 DO ispin = 1, nspins
481 nmo_virt(ispin) = SIZE(gs_mos(ispin)%evals_virt)
482 DO ivirt = 1, nmo_virt(ispin)
483 WRITE (ounit, "(F20.14)") gs_mos(ispin)%evals_virt(ivirt)
484 END DO
485 END DO
486 END IF
487 END IF
488
489 ! print phases of molecular orbitals
490
491 IF (print_phases) THEN
492 IF (ounit > 0) THEN
493 WRITE (ounit, "(A)") "PHASES OCCUPIED ORBITALS"
494 DO ispin = 1, nspins
495 DO iocc = 1, nmo_occ(ispin)
496 WRITE (ounit, "(F20.14)") gs_mos(ispin)%phases_occ(iocc)
497 END DO
498 END DO
499 IF (print_virtuals) THEN
500 WRITE (ounit, "(A)") "PHASES VIRTUAL ORBITALS"
501 DO ispin = 1, nspins
502 DO ivirt = 1, nmo_virt(ispin)
503 WRITE (ounit, "(F20.14)") gs_mos(ispin)%phases_virt(ivirt)
504 END DO
505 END DO
506 END IF
507 END IF
508 END IF
509
510 CALL cp_print_key_finished_output(ounit, logger, tddfpt_print_section, "NAMD_PRINT")
511
512 CALL timestop(handle)
513 END IF
514
515 END SUBROUTINE tddfpt_write_newtonx_output
516! **************************************************************************************************
517!> \brief ...
518!> \param evects ...
519!> \param ounit ...
520!> \param S_evects ...
521!> \param matrix_s ...
522! **************************************************************************************************
523 SUBROUTINE tddfpt_check_orthonormality(evects, ounit, S_evects, matrix_s)
524
525 TYPE(cp_fm_type), DIMENSION(:, :), INTENT(in) :: evects
526 INTEGER, INTENT(in) :: ounit
527 TYPE(cp_fm_type), DIMENSION(:, :), INTENT(INOUT) :: s_evects
528 TYPE(dbcsr_type), INTENT(in), POINTER :: matrix_s
529
530 CHARACTER(LEN=*), PARAMETER :: routinen = 'tddfpt_check_orthonormality'
531
532 INTEGER :: handle, ispin, ivect, jvect, nspins, &
533 nvects_total
534 INTEGER, DIMENSION(maxspins) :: nactive
535 REAL(kind=dp) :: norm
536 REAL(kind=dp), DIMENSION(maxspins) :: weights
537
538 CALL timeset(routinen, handle)
539
540 nspins = SIZE(evects, 1)
541 nvects_total = SIZE(evects, 2)
542
543 IF (debug_this_module) THEN
544 cpassert(SIZE(s_evects, 1) == nspins)
545 cpassert(SIZE(s_evects, 2) == nvects_total)
546 END IF
547
548 DO ispin = 1, nspins
549 CALL cp_fm_get_info(matrix=evects(ispin, 1), ncol_global=nactive(ispin))
550 END DO
551
552 DO jvect = 1, nvects_total
553 ! <psi1_i | psi1_j>
554 DO ivect = 1, jvect - 1
555 CALL cp_fm_trace(evects(:, jvect), s_evects(:, ivect), weights(1:nspins), accurate=.false.)
556 norm = sum(weights(1:nspins))
557
558 DO ispin = 1, nspins
559 CALL cp_fm_scale_and_add(1.0_dp, evects(ispin, jvect), -norm, evects(ispin, ivect))
560 END DO
561 END DO
562
563 ! <psi1_j | psi1_j>
564 DO ispin = 1, nspins
565 CALL cp_dbcsr_sm_fm_multiply(matrix_s, evects(ispin, jvect), s_evects(ispin, jvect), &
566 ncol=nactive(ispin), alpha=1.0_dp, beta=0.0_dp)
567 END DO
568
569 CALL cp_fm_trace(evects(:, jvect), s_evects(:, jvect), weights(1:nspins), accurate=.false.)
570
571 norm = sum(weights(1:nspins))
572 norm = 1.0_dp/sqrt(norm)
573
574 IF ((ounit > 0) .AND. debug_this_module) WRITE (ounit, '(A,F10.8)') "norm", norm
575
576 END DO
577
578 CALL timestop(handle)
579
580 END SUBROUTINE tddfpt_check_orthonormality
581! **************************************************************************************************
582!> \brief ...
583!> \param evects ...
584!> \param phase_evects ...
585!> \param sub_env ...
586! **************************************************************************************************
587 SUBROUTINE compute_phase_eigenvectors(evects, phase_evects, sub_env)
588
589 ! copied from parts of tddgpt_init_ground_state_mos by S. Chulkov
590
591 TYPE(cp_fm_type), INTENT(in) :: evects
592 REAL(kind=dp), DIMENSION(:), INTENT(out) :: phase_evects
593 TYPE(tddfpt_subgroup_env_type), INTENT(in) :: sub_env
594
595 CHARACTER(len=*), PARAMETER :: routinen = 'compute_phase_eigenvectors'
596 REAL(kind=dp), PARAMETER :: eps_dp = epsilon(0.0_dp)
597
598 INTEGER :: handle, icol_global, icol_local, irow_global, irow_local, ncol_global, &
599 ncol_local, nrow_global, nrow_local, sign_int
600 INTEGER, ALLOCATABLE, DIMENSION(:) :: minrow_neg_array, minrow_pos_array, &
601 sum_sign_array
602 INTEGER, DIMENSION(:), POINTER :: col_indices, row_indices
603 REAL(kind=dp) :: element
604 REAL(kind=dp), CONTIGUOUS, DIMENSION(:, :), &
605 POINTER :: my_block
606
607 CALL timeset(routinen, handle)
608
609 ! compute and print the phase of excited-state eigenvectors:
610 CALL cp_fm_get_info(evects, nrow_global=nrow_global, ncol_global=ncol_global, &
611 nrow_local=nrow_local, ncol_local=ncol_local, local_data=my_block, &
612 row_indices=row_indices, col_indices=col_indices) ! nrow_global either nao or nocc
613
614 ALLOCATE (minrow_neg_array(ncol_global), minrow_pos_array(ncol_global), sum_sign_array(ncol_global))
615 minrow_neg_array(:) = nrow_global
616 minrow_pos_array(:) = nrow_global
617 sum_sign_array(:) = 0
618
619 DO icol_local = 1, ncol_local
620 icol_global = col_indices(icol_local)
621
622 DO irow_local = 1, nrow_local
623 irow_global = row_indices(irow_local)
624
625 element = my_block(irow_local, icol_local)
626
627 sign_int = 0
628 IF (element >= eps_dp) THEN
629 sign_int = 1
630 ELSE IF (element <= -eps_dp) THEN
631 sign_int = -1
632 END IF
633
634 sum_sign_array(icol_global) = sum_sign_array(icol_global) + sign_int
635
636 IF (sign_int > 0) THEN
637 IF (minrow_pos_array(icol_global) > irow_global) &
638 minrow_pos_array(icol_global) = irow_global
639 ELSE IF (sign_int < 0) THEN
640 IF (minrow_neg_array(icol_global) > irow_global) &
641 minrow_neg_array(icol_global) = irow_global
642 END IF
643
644 END DO
645 END DO
646
647 CALL sub_env%para_env%sum(sum_sign_array)
648 CALL sub_env%para_env%min(minrow_neg_array)
649 CALL sub_env%para_env%min(minrow_pos_array)
650
651 DO icol_global = 1, ncol_global
652
653 IF (sum_sign_array(icol_global) > 0) THEN
654 ! most of the expansion coefficients are positive => MO's phase = +1
655 phase_evects(icol_global) = 1.0_dp
656 ELSE IF (sum_sign_array(icol_global) < 0) THEN
657 ! most of the expansion coefficients are negative => MO's phase = -1
658 phase_evects(icol_global) = -1.0_dp
659 ELSE
660 ! equal number of positive and negative expansion coefficients
661 IF (minrow_pos_array(icol_global) <= minrow_neg_array(icol_global)) THEN
662 ! the first positive expansion coefficient has a lower index then
663 ! the first negative expansion coefficient; MO's phase = +1
664 phase_evects(icol_global) = 1.0_dp
665 ELSE
666 ! MO's phase = -1
667 phase_evects(icol_global) = -1.0_dp
668 END IF
669 END IF
670
671 END DO
672
673 DEALLOCATE (minrow_neg_array, minrow_pos_array, sum_sign_array)
674
675 CALL timestop(handle)
676
677 END SUBROUTINE compute_phase_eigenvectors
678
679END 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:311
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:122
logical function, public file_exists(file_name)
Checks if file exists, considering also the file discovery mechanism.
Definition cp_files.F:504
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
subroutine, public fm_pool_give_back_fm(pool, element)
returns the element to 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_create(matrix, matrix_struct, name, use_sp, nrow, ncol, set_zero)
creates a new full matrix with the given structure
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_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
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.
integer function, public tddfpt_read_restart(evects, evals, gs_mos, logger, tddfpt_section, tddfpt_print_section, fm_pool_ao_mo_active, blacs_env_global)
Initialise initial guess vectors by reading (un-normalised) Ritz vectors from 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.