(git:9ea9339)
Loading...
Searching...
No Matches
rt_propagation_output.F
Go to the documentation of this file.
1!--------------------------------------------------------------------------------------------------!
2! CP2K: A general program to perform molecular dynamics simulations !
3! Copyright 2000-2026 CP2K developers group <https://cp2k.org> !
4! !
5! SPDX-License-Identifier: GPL-2.0-or-later !
6!--------------------------------------------------------------------------------------------------!
7
8! **************************************************************************************************
9!> \brief Routine for the real time propagation output.
10!> \author Florian Schiffmann (02.09)
11! **************************************************************************************************
12
15 USE cell_types, ONLY: cell_type
18 USE cp_dbcsr_api, ONLY: &
19 dbcsr_add, dbcsr_binary_write, dbcsr_convert_offsets_to_sizes, dbcsr_copy, dbcsr_create, &
24 dbcsr_type_antisymmetric, dbcsr_type_no_symmetry
36 USE cp_fm_types, ONLY: cp_fm_create,&
47 cp_p_file,&
53 USE efield_utils, ONLY: make_field
55 USE input_constants, ONLY: ehrenfest,&
60 USE kahan_sum, ONLY: accurate_sum
61 USE kinds, ONLY: default_path_length,&
62 dp
63 USE machine, ONLY: m_flush
64 USE mathconstants, ONLY: twopi
70 USE physcon, ONLY: evolt,&
72 USE pw_env_types, ONLY: pw_env_get,&
74 USE pw_methods, ONLY: pw_zero
76 USE pw_types, ONLY: pw_c1d_gs_type,&
89 USE qs_rho_types, ONLY: qs_rho_get,&
100 USE rt_propagation_types, ONLY: get_rtp,&
104#include "../base/base_uses.f90"
105
106 IMPLICIT NONE
107
108 PRIVATE
109
110 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'rt_propagation_output'
111
112 PUBLIC :: rt_prop_output, &
119
120CONTAINS
121
122! **************************************************************************************************
123!> \brief ...
124!> \param qs_env ...
125!> \param run_type ...
126!> \param delta_iter ...
127!> \param used_time ...
128! **************************************************************************************************
129 SUBROUTINE rt_prop_output(qs_env, run_type, delta_iter, used_time)
130 TYPE(qs_environment_type), POINTER :: qs_env
131 INTEGER, INTENT(in) :: run_type
132 REAL(dp), INTENT(in), OPTIONAL :: delta_iter, used_time
133
134 INTEGER :: i, n_electrons, n_proj, natom, nspin, &
135 output_unit, spin, unit_nr
136 INTEGER, ALLOCATABLE, DIMENSION(:) :: first_sgf, last_sgf
137 INTEGER, DIMENSION(2) :: nelectron_spin
138 INTEGER, DIMENSION(:), POINTER :: row_blk_sizes
139 LOGICAL :: new_file
140 REAL(dp) :: orthonormality, strace, tot_rho_r, trace
141 REAL(kind=dp), DIMENSION(3) :: field, reference_point
142 REAL(kind=dp), DIMENSION(:), POINTER :: qs_tot_rho_r
143 REAL(kind=dp), DIMENSION(:, :), POINTER :: j_int
144 TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
145 TYPE(cp_fm_type), DIMENSION(:), POINTER :: mos_new
146 TYPE(cp_logger_type), POINTER :: logger
147 TYPE(dbcsr_distribution_type), POINTER :: dbcsr_dist
148 TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_s, p_im, p_xyz, rho_new
149 TYPE(dbcsr_type), POINTER :: tmp_ao
150 TYPE(dft_control_type), POINTER :: dft_control
151 TYPE(neighbor_list_set_p_type), DIMENSION(:), &
152 POINTER :: sab_all, sab_orb
153 TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
154 TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
155 TYPE(qs_rho_type), POINTER :: rho
156 TYPE(rt_prop_type), POINTER :: rtp
157 TYPE(section_vals_type), POINTER :: dft_section, input, rtp_section
158
159 NULLIFY (logger, dft_control)
160
161 logger => cp_get_default_logger()
162 CALL get_qs_env(qs_env, &
163 rtp=rtp, &
164 matrix_s=matrix_s, &
165 input=input, &
166 rho=rho, &
167 particle_set=particle_set, &
168 atomic_kind_set=atomic_kind_set, &
169 qs_kind_set=qs_kind_set, &
170 dft_control=dft_control, sab_all=sab_all, sab_orb=sab_orb, &
171 dbcsr_dist=dbcsr_dist, nelectron_spin=nelectron_spin)
172
173 rtp_section => section_vals_get_subs_vals(input, "DFT%REAL_TIME_PROPAGATION")
174
175 CALL get_qs_kind_set(qs_kind_set, nelectron=n_electrons)
176 n_electrons = n_electrons - dft_control%charge
177
178 CALL qs_rho_get(rho_struct=rho, tot_rho_r=qs_tot_rho_r)
179
180 tot_rho_r = accurate_sum(qs_tot_rho_r)
181
182 output_unit = cp_print_key_unit_nr(logger, rtp_section, "PRINT%PROGRAM_RUN_INFO", &
183 extension=".scfLog")
184
185 IF (output_unit > 0) THEN
186 WRITE (output_unit, fmt="(/,(T3,A,T40,I5))") &
187 "Information at iteration step:", rtp%iter
188 WRITE (unit=output_unit, fmt="((T3,A,T41,2F20.10))") &
189 "Total electronic density (r-space): ", &
190 tot_rho_r, &
191 tot_rho_r + &
192 REAL(n_electrons, dp)
193 WRITE (unit=output_unit, fmt="((T3,A,T59,F22.14))") &
194 "Total energy:", rtp%energy_new
195 IF (run_type == ehrenfest) &
196 WRITE (unit=output_unit, fmt="((T3,A,T61,F20.14))") &
197 "Energy difference to previous iteration step:", rtp%energy_new - rtp%energy_old
198 IF (run_type == real_time_propagation) &
199 WRITE (unit=output_unit, fmt="((T3,A,T61,F20.14))") &
200 "Energy difference to initial state:", rtp%energy_new - rtp%energy_old
201 IF (PRESENT(delta_iter)) &
202 WRITE (unit=output_unit, fmt="((T3,A,T61,E20.6))") &
203 "Convergence:", delta_iter
204 IF (rtp%converged) THEN
205 IF (run_type == real_time_propagation) &
206 WRITE (unit=output_unit, fmt="((T3,A,T61,F12.2))") &
207 "Time needed for propagation:", used_time
208 WRITE (unit=output_unit, fmt="(/,(T3,A,3X,F16.14))") &
209 "CONVERGENCE REACHED", rtp%energy_new - rtp%energy_old
210 END IF
211 END IF
212
213 IF (rtp%converged) THEN
214 IF (.NOT. rtp%linear_scaling) THEN
215 CALL get_rtp(rtp=rtp, mos_new=mos_new)
216 CALL rt_calculate_orthonormality(orthonormality, &
217 mos_new, matrix_s(1)%matrix)
218 IF (output_unit > 0) &
219 WRITE (output_unit, fmt="(/,(T3,A,T60,F20.10))") &
220 "Max deviation from orthonormalization:", orthonormality
221 END IF
222 END IF
223
224 IF (output_unit > 0) &
225 CALL m_flush(output_unit)
226 CALL cp_print_key_finished_output(output_unit, logger, rtp_section, &
227 "PRINT%PROGRAM_RUN_INFO")
228
229 IF (rtp%converged) THEN
230 dft_section => section_vals_get_subs_vals(input, "DFT")
231 IF (btest(cp_print_key_should_output(logger%iter_info, &
232 dft_section, "REAL_TIME_PROPAGATION%PRINT%FIELD"), cp_p_file)) &
233 CALL print_field_applied(qs_env, dft_section)
234 CALL make_moment(qs_env)
235 IF (btest(cp_print_key_should_output(logger%iter_info, &
236 dft_section, "REAL_TIME_PROPAGATION%PRINT%E_CONSTITUENTS"), cp_p_file)) THEN
237 CALL print_rtp_energy_components(qs_env, dft_section)
238 END IF
239 IF (.NOT. dft_control%qs_control%dftb) THEN
240 CALL write_available_results(qs_env=qs_env, rtp=rtp)
241 END IF
242
243 IF (rtp%linear_scaling) THEN
244 CALL get_rtp(rtp=rtp, rho_new=rho_new)
245
246 ! Probably have to rebuild the moment matrix, since atoms can also move, in principle
247 IF (dft_control%rtp_control%save_local_moments) THEN
248 ! Save the field value
249 IF (dft_control%apply_efield_field) THEN
250 CALL make_field(dft_control, field, qs_env%sim_step, qs_env%sim_time)
251 rtp%fields(:, rtp%istep + rtp%i_start + 1) = cmplx(field(:), 0.0, kind=dp)
252 END IF
253 IF (.NOT. dft_control%rtp_control%fixed_ions) THEN
254 CALL build_local_moment_matrix(qs_env, rtp%local_moments, 1, reference_point)
255 END IF
256 ! TODO : Is symmetric rho possible?
257 ! Spin + complex parts
258 ! Extensions setup
259 CALL calc_local_moment(rtp%local_moments, rho_new, &
260 rtp%local_moments_work, rtp%moments(:, :, rtp%istep + rtp%i_start + 1))
261 ! Time 1 is zero (start) time
262 rtp%times(rtp%istep + rtp%i_start + 1) = qs_env%sim_time
263 output_unit = cp_logger_get_default_io_unit(logger)
264 CALL print_moments(section_vals_get_subs_vals(rtp_section, "PRINT%MOMENTS"), output_unit, &
265 rtp%moments(:, :, rtp%istep + rtp%i_start + 1), qs_env%sim_time, rtp%track_imag_density)
266 END IF
267
268 IF (btest(cp_print_key_should_output(logger%iter_info, &
269 dft_section, "REAL_TIME_PROPAGATION%PRINT%RESTART"), cp_p_file)) THEN
270 CALL write_rt_p_to_restart(rho_new, .false.)
271 END IF
272 IF (btest(cp_print_key_should_output(logger%iter_info, &
273 dft_section, "REAL_TIME_PROPAGATION%PRINT%RESTART_HISTORY"), cp_p_file)) THEN
274 CALL write_rt_p_to_restart(rho_new, .true.)
275 END IF
276 IF (.NOT. dft_control%qs_control%dftb) THEN
277 !Not sure if these things could also work with dftb or not
278 IF (btest(cp_print_key_should_output(logger%iter_info, &
279 dft_section, "REAL_TIME_PROPAGATION%PRINT%CURRENT"), cp_p_file)) THEN
280 DO spin = 1, SIZE(rho_new)/2
281 CALL rt_current(qs_env, rho_new(2*spin)%matrix, dft_section, spin, SIZE(rho_new)/2)
282 END DO
283 END IF
284 END IF
285 ELSE
286 CALL get_rtp(rtp=rtp, mos_new=mos_new)
287 IF (.NOT. dft_control%qs_control%dftb .AND. .NOT. dft_control%qs_control%xtb) THEN
288 IF (rtp%track_imag_density) THEN
289 NULLIFY (p_im, p_xyz)
290 CALL dbcsr_allocate_matrix_set(p_xyz, 3)
291
292! Linear momentum operator
293! prepare for allocation
294 natom = SIZE(particle_set, 1)
295 ALLOCATE (first_sgf(natom))
296 ALLOCATE (last_sgf(natom))
297 CALL get_particle_set(particle_set, qs_kind_set, &
298 first_sgf=first_sgf, &
299 last_sgf=last_sgf)
300 ALLOCATE (row_blk_sizes(natom))
301 CALL dbcsr_convert_offsets_to_sizes(first_sgf, row_blk_sizes, last_sgf)
302 DEALLOCATE (first_sgf)
303 DEALLOCATE (last_sgf)
304
305 ALLOCATE (p_xyz(1)%matrix)
306 CALL dbcsr_create(matrix=p_xyz(1)%matrix, &
307 name="p_xyz", &
308 dist=dbcsr_dist, matrix_type=dbcsr_type_antisymmetric, &
309 row_blk_size=row_blk_sizes, col_blk_size=row_blk_sizes, &
310 mutable_work=.true.)
311 CALL cp_dbcsr_alloc_block_from_nbl(p_xyz(1)%matrix, sab_orb)
312 CALL dbcsr_set(p_xyz(1)%matrix, 0.0_dp)
313 DO i = 2, 3
314 ALLOCATE (p_xyz(i)%matrix)
315 CALL dbcsr_copy(p_xyz(i)%matrix, p_xyz(1)%matrix, "p_xyz-"//trim(adjustl(cp_to_string(i))))
316 CALL dbcsr_set(p_xyz(i)%matrix, 0.0_dp)
317 END DO
318 CALL build_lin_mom_matrix(qs_env, p_xyz)
319 DEALLOCATE (row_blk_sizes)
320
321 nspin = SIZE(mos_new)/2
322 CALL qs_rho_get(rho, rho_ao_im=p_im)
323 ALLOCATE (j_int(nspin, 3))
324 j_int = 0.0_dp
325
326 NULLIFY (tmp_ao)
327 CALL dbcsr_init_p(tmp_ao)
328 CALL dbcsr_create(tmp_ao, template=matrix_s(1)%matrix, matrix_type=dbcsr_type_no_symmetry, name="tmp")
329 CALL cp_dbcsr_alloc_block_from_nbl(tmp_ao, sab_all)
330 CALL dbcsr_set(tmp_ao, 0.0_dp)
331
332 DO i = 1, 3
333 strace = 0.0_dp
334 DO spin = 1, nspin
335 CALL dbcsr_set(tmp_ao, 0.0_dp)
336 CALL dbcsr_multiply("T", "N", 1.0_dp, p_im(spin)%matrix, p_xyz(i)%matrix, &
337 0.0_dp, tmp_ao)
338 CALL dbcsr_trace(tmp_ao, trace)
339 strace = strace + trace
340! dft_control%rtp_control%vec_pot(1)
341 j_int(spin, i) = -trace + dft_control%rtp_control%vec_pot(i)*nelectron_spin(spin)
342!! j_int(spin, i) = strace
343 END DO
344 END DO
345! PP term missing
346
347 IF (btest(cp_print_key_should_output(logger%iter_info, &
348 dft_section, "REAL_TIME_PROPAGATION%PRINT%CURRENT_INT"), cp_p_file)) THEN
349
350 output_unit = cp_logger_get_default_io_unit(logger)
351 unit_nr = cp_print_key_unit_nr(logger, dft_section, &
352 "REAL_TIME_PROPAGATION%PRINT%CURRENT_INT", extension=".dat", is_new_file=new_file)
353 IF (output_unit > 0) THEN
354 IF (nspin == 2) THEN
355 WRITE (unit=unit_nr, fmt="(I10,F16.6,6(F16.8,1X))") qs_env%sim_step, qs_env%sim_time*femtoseconds, &
356 j_int(1, 1:3), j_int(2, 1:3)
357 ELSE
358 WRITE (unit=unit_nr, fmt="(I10,F16.6,3(F16.8,1X))") qs_env%sim_step, qs_env%sim_time*femtoseconds, &
359 j_int(1, 1:3)
360 END IF
361 END IF
362 CALL cp_print_key_finished_output(unit_nr, logger, dft_section, &
363 "REAL_TIME_PROPAGATION%PRINT%CURRENT_INT")
364 END IF
365 DEALLOCATE (j_int)
366
367 IF (btest(cp_print_key_should_output(logger%iter_info, &
368 dft_section, "REAL_TIME_PROPAGATION%PRINT%CURRENT"), cp_p_file)) THEN
369 DO spin = 1, nspin
370 CALL rt_current(qs_env, p_im(spin)%matrix, dft_section, spin, nspin)
371 END DO
372 END IF
373 CALL dbcsr_deallocate_matrix(tmp_ao)
375 END IF
376
377! projection of molecular orbitals
378 IF (dft_control%rtp_control%is_proj_mo) THEN
379 DO n_proj = 1, SIZE(dft_control%rtp_control%proj_mo_list)
380 CALL compute_and_write_proj_mo(qs_env, mos_new, &
381 dft_control%rtp_control%proj_mo_list(n_proj)%proj_mo, n_proj)
382 END DO
383 END IF
384 END IF
385 CALL write_rt_mos_to_restart(qs_env%mos, mos_new, particle_set, &
386 dft_section, qs_kind_set)
387 END IF
388 END IF
389
390 rtp%energy_old = rtp%energy_new
391
392 IF (.NOT. rtp%converged .AND. rtp%iter >= dft_control%rtp_control%max_iter) &
393 CALL cp_abort(__location__, "EMD did not converge, either increase MAX_ITER "// &
394 "or use a smaller TIMESTEP")
395
396 END SUBROUTINE rt_prop_output
397
398! **************************************************************************************************
399!> \brief computes the effective orthonormality of a set of mos given an s-matrix
400!> orthonormality is the max deviation from unity of the C^T S C
401!> \param orthonormality ...
402!> \param mos_new ...
403!> \param matrix_s ...
404!> \author Florian Schiffmann (02.09)
405! **************************************************************************************************
406 SUBROUTINE rt_calculate_orthonormality(orthonormality, mos_new, matrix_s)
407 REAL(kind=dp), INTENT(out) :: orthonormality
408 TYPE(cp_fm_type), DIMENSION(:), POINTER :: mos_new
409 TYPE(dbcsr_type), OPTIONAL, POINTER :: matrix_s
410
411 CHARACTER(len=*), PARAMETER :: routinen = 'rt_calculate_orthonormality'
412
413 INTEGER :: handle, i, im, ispin, j, k, n, &
414 ncol_local, nrow_local, nspin, re
415 INTEGER, DIMENSION(:), POINTER :: col_indices, row_indices
416 REAL(kind=dp) :: alpha, max_alpha, max_beta
417 TYPE(cp_fm_struct_type), POINTER :: tmp_fm_struct
418 TYPE(cp_fm_type) :: overlap_re, svec_im, svec_re
419
420 NULLIFY (tmp_fm_struct)
421
422 CALL timeset(routinen, handle)
423
424 nspin = SIZE(mos_new)/2
425 max_alpha = 0.0_dp
426 max_beta = 0.0_dp
427 DO ispin = 1, nspin
428 re = ispin*2 - 1
429 im = ispin*2
430 ! get S*C
431 CALL cp_fm_create(svec_re, mos_new(im)%matrix_struct)
432 CALL cp_fm_create(svec_im, mos_new(im)%matrix_struct)
433 CALL cp_fm_get_info(mos_new(im), &
434 nrow_global=n, ncol_global=k)
435 CALL cp_dbcsr_sm_fm_multiply(matrix_s, mos_new(re), &
436 svec_re, k)
437 CALL cp_dbcsr_sm_fm_multiply(matrix_s, mos_new(im), &
438 svec_im, k)
439
440 ! get C^T (S*C)
441 CALL cp_fm_struct_create(tmp_fm_struct, nrow_global=k, ncol_global=k, &
442 para_env=mos_new(re)%matrix_struct%para_env, &
443 context=mos_new(re)%matrix_struct%context)
444 CALL cp_fm_create(overlap_re, tmp_fm_struct)
445
446 CALL cp_fm_struct_release(tmp_fm_struct)
447
448 CALL parallel_gemm('T', 'N', k, k, n, 1.0_dp, mos_new(re), &
449 svec_re, 0.0_dp, overlap_re)
450 CALL parallel_gemm('T', 'N', k, k, n, 1.0_dp, mos_new(im), &
451 svec_im, 1.0_dp, overlap_re)
452
453 CALL cp_fm_release(svec_re)
454 CALL cp_fm_release(svec_im)
455
456 CALL cp_fm_get_info(overlap_re, nrow_local=nrow_local, ncol_local=ncol_local, &
457 row_indices=row_indices, col_indices=col_indices)
458 DO i = 1, nrow_local
459 DO j = 1, ncol_local
460 alpha = overlap_re%local_data(i, j)
461 IF (row_indices(i) == col_indices(j)) alpha = alpha - 1.0_dp
462 max_alpha = max(max_alpha, abs(alpha))
463 END DO
464 END DO
465 CALL cp_fm_release(overlap_re)
466 END DO
467 CALL mos_new(1)%matrix_struct%para_env%max(max_alpha)
468 CALL mos_new(1)%matrix_struct%para_env%max(max_beta)
469 orthonormality = max_alpha
470
471 CALL timestop(handle)
472
473 END SUBROUTINE rt_calculate_orthonormality
474
475! **************************************************************************************************
476!> \brief computes the convergence criterion for RTP and EMD
477!> \param rtp ...
478!> \param matrix_s Overlap matrix without the derivatives
479!> \param delta_mos ...
480!> \param delta_eps ...
481!> \author Florian Schiffmann (02.09)
482! **************************************************************************************************
483
484 SUBROUTINE rt_convergence(rtp, matrix_s, delta_mos, delta_eps)
485 TYPE(rt_prop_type), POINTER :: rtp
486 TYPE(dbcsr_type), POINTER :: matrix_s
487 TYPE(cp_fm_type), DIMENSION(:), INTENT(IN) :: delta_mos
488 REAL(dp), INTENT(out) :: delta_eps
489
490 CHARACTER(len=*), PARAMETER :: routinen = 'rt_convergence'
491 REAL(kind=dp), PARAMETER :: one = 1.0_dp, zero = 0.0_dp
492
493 INTEGER :: handle, i, icol, im, ispin, j, lcol, &
494 lrow, nao, newdim, nmo, nspin, re
495 LOGICAL :: double_col, double_row
496 REAL(kind=dp) :: alpha, max_alpha
497 TYPE(cp_fm_struct_type), POINTER :: newstruct, newstruct1, tmp_fm_struct
498 TYPE(cp_fm_type) :: work, work1, work2
499 TYPE(cp_fm_type), DIMENSION(:), POINTER :: mos_new
500
501 NULLIFY (tmp_fm_struct)
502
503 CALL timeset(routinen, handle)
504
505 CALL get_rtp(rtp=rtp, mos_new=mos_new)
506
507 nspin = SIZE(delta_mos)/2
508 max_alpha = 0.0_dp
509
510 DO i = 1, SIZE(mos_new)
511 CALL cp_fm_scale_and_add(-one, delta_mos(i), one, mos_new(i))
512 END DO
513
514 DO ispin = 1, nspin
515 re = ispin*2 - 1
516 im = ispin*2
517
518 double_col = .true.
519 double_row = .false.
520 CALL cp_fm_struct_double(newstruct, &
521 delta_mos(re)%matrix_struct, &
522 delta_mos(re)%matrix_struct%context, &
523 double_col, &
524 double_row)
525
526 CALL cp_fm_create(work, matrix_struct=newstruct)
527 CALL cp_fm_create(work1, matrix_struct=newstruct)
528
529 CALL cp_fm_get_info(delta_mos(re), ncol_local=lcol, ncol_global=nmo, &
530 nrow_global=nao)
531 CALL cp_fm_get_info(work, ncol_global=newdim)
532
533 CALL cp_fm_set_all(work, zero, zero)
534
535 DO icol = 1, lcol
536 work%local_data(:, icol) = delta_mos(re)%local_data(:, icol)
537 work%local_data(:, icol + lcol) = delta_mos(im)%local_data(:, icol)
538 END DO
539
540 CALL cp_dbcsr_sm_fm_multiply(matrix_s, work, work1, ncol=newdim)
541
542 CALL cp_fm_release(work)
543
544 CALL cp_fm_struct_create(tmp_fm_struct, nrow_global=nmo, ncol_global=nmo, &
545 para_env=delta_mos(re)%matrix_struct%para_env, &
546 context=delta_mos(re)%matrix_struct%context)
547 CALL cp_fm_struct_double(newstruct1, &
548 tmp_fm_struct, &
549 delta_mos(re)%matrix_struct%context, &
550 double_col, &
551 double_row)
552
553 CALL cp_fm_create(work, matrix_struct=newstruct1)
554 CALL cp_fm_create(work2, matrix_struct=newstruct1)
555
556 CALL parallel_gemm("T", "N", nmo, newdim, nao, one, delta_mos(re), &
557 work1, zero, work)
558
559 CALL parallel_gemm("T", "N", nmo, newdim, nao, one, delta_mos(im), &
560 work1, zero, work2)
561
562 CALL cp_fm_get_info(work, nrow_local=lrow)
563 DO i = 1, lrow
564 DO j = 1, lcol
565 alpha = sqrt((work%local_data(i, j) + work2%local_data(i, j + lcol))**2 + &
566 (work%local_data(i, j + lcol) - work2%local_data(i, j))**2)
567 max_alpha = max(max_alpha, abs(alpha))
568 END DO
569 END DO
570
571 CALL cp_fm_release(work)
572 CALL cp_fm_release(work1)
573 CALL cp_fm_release(work2)
574 CALL cp_fm_struct_release(tmp_fm_struct)
575 CALL cp_fm_struct_release(newstruct)
576 CALL cp_fm_struct_release(newstruct1)
577
578 END DO
579
580 CALL delta_mos(1)%matrix_struct%para_env%max(max_alpha)
581 delta_eps = sqrt(max_alpha)
582
583 CALL timestop(handle)
584
585 END SUBROUTINE rt_convergence
586
587! **************************************************************************************************
588!> \brief computes the convergence criterion for RTP and EMD based on the density matrix
589!> \param rtp ...
590!> \param delta_P ...
591!> \param delta_eps ...
592!> \author Samuel Andermatt (02.14)
593! **************************************************************************************************
594
595 SUBROUTINE rt_convergence_density(rtp, delta_P, delta_eps)
596
597 TYPE(rt_prop_type), POINTER :: rtp
598 TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: delta_p
599 REAL(dp), INTENT(out) :: delta_eps
600
601 CHARACTER(len=*), PARAMETER :: routinen = 'rt_convergence_density'
602 REAL(kind=dp), PARAMETER :: one = 1.0_dp, zero = 0.0_dp
603
604 INTEGER :: col_atom, handle, i, ispin, row_atom
605 REAL(dp) :: alpha, max_alpha
606 REAL(dp), DIMENSION(:, :), POINTER :: block_values
607 TYPE(dbcsr_iterator_type) :: iter
608 TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: rho_new
609 TYPE(dbcsr_type), POINTER :: tmp
610 TYPE(mp_comm_type) :: group
611
612 CALL timeset(routinen, handle)
613
614 CALL get_rtp(rtp=rtp, rho_new=rho_new)
615
616 DO i = 1, SIZE(rho_new)
617 CALL dbcsr_add(delta_p(i)%matrix, rho_new(i)%matrix, one, -one)
618 END DO
619 !get the maximum value of delta_P
620 DO i = 1, SIZE(delta_p)
621 !square all entries of both matrices
622 CALL dbcsr_iterator_start(iter, delta_p(i)%matrix)
623 DO WHILE (dbcsr_iterator_blocks_left(iter))
624 CALL dbcsr_iterator_next_block(iter, row_atom, col_atom, block_values)
625 block_values = block_values*block_values
626 END DO
627 CALL dbcsr_iterator_stop(iter)
628 END DO
629 NULLIFY (tmp)
630 ALLOCATE (tmp)
631 CALL dbcsr_create(tmp, template=delta_p(1)%matrix, matrix_type="N")
632 DO ispin = 1, SIZE(delta_p)/2
633 CALL dbcsr_desymmetrize(delta_p(2*ispin - 1)%matrix, tmp)
634 CALL dbcsr_add(delta_p(2*ispin)%matrix, tmp, one, one)
635 END DO
636 !the absolute values are now in the even entries of delta_P
637 max_alpha = zero
638 DO ispin = 1, SIZE(delta_p)/2
639 CALL dbcsr_iterator_start(iter, delta_p(2*ispin)%matrix)
640 DO WHILE (dbcsr_iterator_blocks_left(iter))
641 CALL dbcsr_iterator_next_block(iter, row_atom, col_atom, block_values)
642 alpha = maxval(block_values)
643 IF (alpha > max_alpha) max_alpha = alpha
644 END DO
645 CALL dbcsr_iterator_stop(iter)
646 END DO
647 CALL dbcsr_get_info(delta_p(1)%matrix, group=group)
648 CALL group%max(max_alpha)
649 delta_eps = sqrt(max_alpha)
651 CALL timestop(handle)
652
653 END SUBROUTINE rt_convergence_density
654
655! **************************************************************************************************
656!> \brief interface to qs_moments. Does only work for nonperiodic dipole
657!> \param qs_env ...
658!> \author Florian Schiffmann (02.09)
659! **************************************************************************************************
660
661 SUBROUTINE make_moment(qs_env)
662
663 TYPE(qs_environment_type), POINTER :: qs_env
664
665 CHARACTER(len=*), PARAMETER :: routinen = 'make_moment'
666
667 INTEGER :: handle, output_unit
668 TYPE(cp_logger_type), POINTER :: logger
669 TYPE(dft_control_type), POINTER :: dft_control
670
671 CALL timeset(routinen, handle)
672
673 NULLIFY (dft_control)
674
675 logger => cp_get_default_logger()
676 output_unit = cp_logger_get_default_io_unit(logger)
677 CALL get_qs_env(qs_env, dft_control=dft_control)
678 IF (dft_control%qs_control%dftb) THEN
679 CALL scf_post_calculation_tb(qs_env, "DFTB", .false.)
680 ELSE IF (dft_control%qs_control%xtb) THEN
681 CALL scf_post_calculation_tb(qs_env, "xTB", .false.)
682 ELSE
683 CALL qs_scf_post_moments(qs_env%input, logger, qs_env, output_unit)
684 END IF
685 CALL timestop(handle)
686
687 END SUBROUTINE make_moment
688
689! **************************************************************************************************
690!> \brief Reports the sparsity pattern of the complex density matrix
691!> \param filter_eps ...
692!> \param rho ...
693!> \author Samuel Andermatt (09.14)
694! **************************************************************************************************
695
696 SUBROUTINE report_density_occupation(filter_eps, rho)
697
698 REAL(kind=dp) :: filter_eps
699 TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: rho
700
701 CHARACTER(len=*), PARAMETER :: routinen = 'report_density_occupation'
702
703 INTEGER :: handle, i, im, ispin, re, unit_nr
704 REAL(kind=dp) :: eps, occ
705 TYPE(cp_logger_type), POINTER :: logger
706 TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: tmp
707
708 CALL timeset(routinen, handle)
709
710 logger => cp_get_default_logger()
711 unit_nr = cp_logger_get_default_io_unit(logger)
712 NULLIFY (tmp)
713 CALL dbcsr_allocate_matrix_set(tmp, SIZE(rho))
714 DO i = 1, SIZE(rho)
715 CALL dbcsr_init_p(tmp(i)%matrix)
716 CALL dbcsr_create(tmp(i)%matrix, template=rho(i)%matrix)
717 CALL dbcsr_copy(tmp(i)%matrix, rho(i)%matrix)
718 END DO
719 DO ispin = 1, SIZE(rho)/2
720 re = 2*ispin - 1
721 im = 2*ispin
722 eps = max(filter_eps, 1.0e-11_dp)
723 DO WHILE (eps < 1.1_dp)
724 CALL dbcsr_filter(tmp(re)%matrix, eps)
725 occ = dbcsr_get_occupation(tmp(re)%matrix)
726 IF (unit_nr > 0) WRITE (unit_nr, fmt="((T3,A,I1,A,F15.12,A,T61,F20.10))") "Occupation of rho spin ", &
727 ispin, " eps ", eps, " real: ", occ
728 eps = eps*10
729 END DO
730 eps = max(filter_eps, 1.0e-11_dp)
731 DO WHILE (eps < 1.1_dp)
732 CALL dbcsr_filter(tmp(im)%matrix, eps)
733 occ = dbcsr_get_occupation(tmp(im)%matrix)
734 IF (unit_nr > 0) WRITE (unit_nr, fmt="((T3,A,I1,A,F15.12,A,T61,F20.10))") "Occupation of rho spin ", &
735 ispin, " eps ", eps, " imag: ", occ
736 eps = eps*10.0_dp
737 END DO
738 END DO
740 CALL timestop(handle)
741
742 END SUBROUTINE report_density_occupation
743
744! **************************************************************************************************
745!> \brief Writes the density matrix and the atomic positions to a restart file
746!> \param rho_new ...
747!> \param history ...
748!> \author Samuel Andermatt (09.14)
749! **************************************************************************************************
750
751 SUBROUTINE write_rt_p_to_restart(rho_new, history)
752
753 TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: rho_new
754 LOGICAL :: history
755
756 CHARACTER(LEN=*), PARAMETER :: routinen = 'write_rt_p_to_restart'
757
758 CHARACTER(LEN=default_path_length) :: file_name, project_name
759 INTEGER :: handle, im, ispin, re, unit_nr
760 REAL(kind=dp) :: cs_pos
761 TYPE(cp_logger_type), POINTER :: logger
762
763 CALL timeset(routinen, handle)
764 logger => cp_get_default_logger()
765 IF (logger%para_env%is_source()) THEN
766 unit_nr = cp_logger_get_default_unit_nr(logger, local=.true.)
767 ELSE
768 unit_nr = -1
769 END IF
770
771 project_name = logger%iter_info%project_name
772 DO ispin = 1, SIZE(rho_new)/2
773 re = 2*ispin - 1
774 im = 2*ispin
775 IF (history) THEN
776 WRITE (file_name, '(A,I0,A)') &
777 trim(project_name)//"_LS_DM_SPIN_RE", ispin, "_"//trim(cp_iter_string(logger%iter_info))//"_RESTART.dm"
778 ELSE
779 WRITE (file_name, '(A,I0,A)') trim(project_name)//"_LS_DM_SPIN_RE", ispin, "_RESTART.dm"
780 END IF
781 cs_pos = dbcsr_checksum(rho_new(re)%matrix, pos=.true.)
782 IF (unit_nr > 0) THEN
783 WRITE (unit_nr, '(T2,A,E20.8)') "Writing restart DM "//trim(file_name)//" with checksum: ", cs_pos
784 END IF
785 CALL dbcsr_binary_write(rho_new(re)%matrix, file_name)
786 IF (history) THEN
787 WRITE (file_name, '(A,I0,A)') &
788 trim(project_name)//"_LS_DM_SPIN_IM", ispin, "_"//trim(cp_iter_string(logger%iter_info))//"_RESTART.dm"
789 ELSE
790 WRITE (file_name, '(A,I0,A)') trim(project_name)//"_LS_DM_SPIN_IM", ispin, "_RESTART.dm"
791 END IF
792 cs_pos = dbcsr_checksum(rho_new(im)%matrix, pos=.true.)
793 IF (unit_nr > 0) THEN
794 WRITE (unit_nr, '(T2,A,E20.8)') "Writing restart DM "//trim(file_name)//" with checksum: ", cs_pos
795 END IF
796 CALL dbcsr_binary_write(rho_new(im)%matrix, file_name)
797 END DO
798
799 CALL timestop(handle)
800
801 END SUBROUTINE write_rt_p_to_restart
802
803! **************************************************************************************************
804!> \brief Collocation of the current and printing of it in a cube file
805!> \param qs_env ...
806!> \param P_im ...
807!> \param dft_section ...
808!> \param spin ...
809!> \param nspin ...
810!> \author Samuel Andermatt (06.15)
811! **************************************************************************************************
812 SUBROUTINE rt_current(qs_env, P_im, dft_section, spin, nspin)
813 TYPE(qs_environment_type), POINTER :: qs_env
814 TYPE(dbcsr_type), POINTER :: p_im
815 TYPE(section_vals_type), POINTER :: dft_section
816 INTEGER :: spin, nspin
817
818 CHARACTER(len=*), PARAMETER :: routinen = 'rt_current'
819
820 CHARACTER(len=1) :: char_spin
821 CHARACTER(len=14) :: ext
822 CHARACTER(len=2) :: sdir
823 INTEGER :: dir, handle, print_unit
824 INTEGER, DIMENSION(:), POINTER :: stride(:)
825 LOGICAL :: mpi_io
826 TYPE(cp_logger_type), POINTER :: logger
827 TYPE(current_env_type) :: current_env
828 TYPE(dbcsr_type), POINTER :: tmp, zero
829 TYPE(particle_list_type), POINTER :: particles
830 TYPE(pw_c1d_gs_type) :: gs
831 TYPE(pw_env_type), POINTER :: pw_env
832 TYPE(pw_pool_type), POINTER :: auxbas_pw_pool
833 TYPE(pw_r3d_rs_type) :: rs
834 TYPE(qs_subsys_type), POINTER :: subsys
835
836 CALL timeset(routinen, handle)
837
838 logger => cp_get_default_logger()
839 CALL get_qs_env(qs_env=qs_env, subsys=subsys, pw_env=pw_env)
840 CALL qs_subsys_get(subsys, particles=particles)
841 CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool)
842
843 NULLIFY (zero, tmp)
844 ALLOCATE (zero, tmp)
845 CALL dbcsr_create(zero, template=p_im)
846 CALL dbcsr_copy(zero, p_im)
847 CALL dbcsr_set(zero, 0.0_dp)
848 CALL dbcsr_create(tmp, template=p_im)
849 CALL dbcsr_copy(tmp, p_im)
850 IF (nspin == 1) THEN
851 CALL dbcsr_scale(tmp, 0.5_dp)
852 END IF
853 current_env%gauge = -1
854 current_env%gauge_init = .false.
855 CALL auxbas_pw_pool%create_pw(rs)
856 CALL auxbas_pw_pool%create_pw(gs)
857
858 NULLIFY (stride)
859 ALLOCATE (stride(3))
860
861 DO dir = 1, 3
862
863 CALL pw_zero(rs)
864 CALL pw_zero(gs)
865
866 CALL calculate_jrho_resp(zero, tmp, zero, zero, dir, dir, rs, gs, qs_env, current_env, retain_rsgrid=.true.)
867
868 stride = section_get_ivals(dft_section, "REAL_TIME_PROPAGATION%PRINT%CURRENT%STRIDE")
869
870 IF (dir == 1) THEN
871 sdir = "-x"
872 ELSEIF (dir == 2) THEN
873 sdir = "-y"
874 ELSE
875 sdir = "-z"
876 END IF
877 WRITE (char_spin, "(I1)") spin
878
879 ext = "-SPIN-"//char_spin//sdir//".cube"
880 mpi_io = .true.
881 print_unit = cp_print_key_unit_nr(logger, dft_section, "REAL_TIME_PROPAGATION%PRINT%CURRENT", &
882 extension=ext, file_status="REPLACE", file_action="WRITE", &
883 log_filename=.false., mpi_io=mpi_io)
884
885 CALL cp_pw_to_cube(rs, print_unit, "EMD current", particles=particles, stride=stride, &
886 mpi_io=mpi_io)
887
888 CALL cp_print_key_finished_output(print_unit, logger, dft_section, "REAL_TIME_PROPAGATION%PRINT%CURRENT", &
889 mpi_io=mpi_io)
890
891 END DO
892
893 CALL auxbas_pw_pool%give_back_pw(rs)
894 CALL auxbas_pw_pool%give_back_pw(gs)
895
898
899 DEALLOCATE (stride)
900
901 CALL timestop(handle)
902
903 END SUBROUTINE rt_current
904
905! **************************************************************************************************
906!> \brief Interface routine to trigger writing of results available from normal
907!> SCF. Can write MO-dependent and MO free results (needed for call from
908!> the linear scaling code)
909!> Update: trigger also some of prints for time-dependent runs
910!> \param qs_env ...
911!> \param rtp ...
912!> \par History
913!> 2022-11 Update [Guillaume Le Breton]
914! **************************************************************************************************
915 SUBROUTINE write_available_results(qs_env, rtp)
916 TYPE(qs_environment_type), POINTER :: qs_env
917 TYPE(rt_prop_type), POINTER :: rtp
918
919 CHARACTER(len=*), PARAMETER :: routinen = 'write_available_results'
920
921 INTEGER :: handle
922 TYPE(qs_scf_env_type), POINTER :: scf_env
923
924 CALL timeset(routinen, handle)
925
926 CALL get_qs_env(qs_env, scf_env=scf_env)
927 IF (rtp%linear_scaling) THEN
928 CALL write_mo_free_results(qs_env)
929 ELSE
930 CALL write_mo_free_results(qs_env)
931 CALL write_mo_dependent_results(qs_env, scf_env)
932 ! Time-dependent MO print
933 CALL write_rtp_mos_to_output_unit(qs_env, rtp)
934 CALL write_rtp_mo_cubes(qs_env, rtp)
935 END IF
936
937 CALL timestop(handle)
938
939 END SUBROUTINE write_available_results
940
941! **************************************************************************************************
942!> \brief Print the field applied to the system. Either the electric
943!> field or the vector potential depending on the gauge used
944!> \param qs_env ...
945!> \param dft_section ...
946!> \par History
947!> 2023-01 Created [Guillaume Le Breton]
948! **************************************************************************************************
949 SUBROUTINE print_field_applied(qs_env, dft_section)
950 TYPE(qs_environment_type), POINTER :: qs_env
951 TYPE(section_vals_type), POINTER :: dft_section
952
953 CHARACTER(LEN=3), DIMENSION(3) :: rlab
954 CHARACTER(LEN=default_path_length) :: filename
955 INTEGER :: i, i_step, output_unit, unit_nr
956 LOGICAL :: new_file
957 REAL(kind=dp) :: field(3)
958 TYPE(cp_logger_type), POINTER :: logger
959 TYPE(dft_control_type), POINTER :: dft_control
960 TYPE(rt_prop_type), POINTER :: rtp
961
962 NULLIFY (dft_control)
963
964 logger => cp_get_default_logger()
965 output_unit = cp_logger_get_default_io_unit(logger)
966
967 CALL get_qs_env(qs_env, dft_control=dft_control, rtp=rtp)
968
969 i_step = rtp%istep
970
971 unit_nr = cp_print_key_unit_nr(logger, dft_section, &
972 "REAL_TIME_PROPAGATION%PRINT%FIELD", extension=".dat", is_new_file=new_file)
973
974 IF (output_unit > 0) THEN
975 rlab = [CHARACTER(LEN=3) :: "X", "Y", "Z"]
976 IF (unit_nr /= output_unit) THEN
977 INQUIRE (unit=unit_nr, name=filename)
978 WRITE (unit=output_unit, fmt="(/,T2,A,2(/,T3,A),/)") &
979 "FIELD", "The field applied is written to the file:", &
980 trim(filename)
981 ELSE
982 WRITE (unit=output_unit, fmt="(/,T2,A)") "FIELD APPLIED [a.u.]"
983 WRITE (unit=output_unit, fmt="(T5,3(A,A,E16.8,1X))") &
984 (trim(rlab(i)), "=", dft_control%rtp_control%field(i), i=1, 3)
985 END IF
986
987 IF (new_file) THEN
988 IF (dft_control%apply_efield_field) THEN
989 WRITE (unit=unit_nr, fmt='("#",5X,A,8X,A,3(6X,A))') "Step Nr.", "Time[fs]", " Field X", " Field Y", " Field Z"
990 ELSE IF (dft_control%apply_vector_potential) THEN
991 WRITE (unit=unit_nr, fmt='("#",5X,A,8X,A,6(6X,A))') "Step Nr.", "Time[fs]", " Field X", " Field Y", " Field Z", &
992 " Vec. Pot. X", " Vec. Pot. Y", " Vec. Pot. Z"
993 END IF
994 END IF
995
996 field = 0.0_dp
997 IF (dft_control%apply_efield_field) THEN
998 CALL make_field(dft_control, field, qs_env%sim_step, qs_env%sim_time)
999 WRITE (unit=unit_nr, fmt="(I10,F16.6,3(F16.8,1X))") qs_env%sim_step, qs_env%sim_time*femtoseconds, &
1000 field(1), field(2), field(3)
1001! DO i=1,3
1002! IF (ABS(field(i))< 10E-10) field(i) = 0.0_dp
1003! END IF
1004 ELSE IF (dft_control%apply_vector_potential) THEN
1005 WRITE (unit=unit_nr, fmt="(I10,F16.6,6(F16.8,1X))") qs_env%sim_step, qs_env%sim_time*femtoseconds, &
1006 dft_control%rtp_control%field(1), dft_control%rtp_control%field(2), dft_control%rtp_control%field(3), &
1007 dft_control%rtp_control%vec_pot(1), dft_control%rtp_control%vec_pot(2), dft_control%rtp_control%vec_pot(3)
1008 END IF
1009
1010 END IF
1011
1012 CALL cp_print_key_finished_output(unit_nr, logger, dft_section, &
1013 "REAL_TIME_PROPAGATION%PRINT%FIELD")
1014
1015 END SUBROUTINE print_field_applied
1016
1017! **************************************************************************************************
1018!> \brief Print the components of the total energy used in an RTP calculation
1019!> \param qs_env ...
1020!> \param dft_section ...
1021!> \par History
1022!> 2024-02 Created [ANB]
1023! **************************************************************************************************
1024 SUBROUTINE print_rtp_energy_components(qs_env, dft_section)
1025 TYPE(qs_environment_type), POINTER :: qs_env
1026 TYPE(section_vals_type), POINTER :: dft_section
1027
1028 CHARACTER(LEN=default_path_length) :: filename
1029 INTEGER :: i_step, output_unit, unit_nr
1030 LOGICAL :: new_file
1031 TYPE(cp_logger_type), POINTER :: logger
1032 TYPE(dft_control_type), POINTER :: dft_control
1033 TYPE(qs_energy_type), POINTER :: energy
1034 TYPE(rt_prop_type), POINTER :: rtp
1035
1036 NULLIFY (dft_control, energy, rtp)
1037
1038 logger => cp_get_default_logger()
1039 output_unit = cp_logger_get_default_io_unit(logger)
1040
1041 CALL get_qs_env(qs_env, dft_control=dft_control, rtp=rtp, energy=energy)
1042 i_step = rtp%istep
1043
1044 unit_nr = cp_print_key_unit_nr(logger, dft_section, &
1045 "REAL_TIME_PROPAGATION%PRINT%E_CONSTITUENTS", extension=".ener", &
1046 file_action="WRITE", is_new_file=new_file)
1047
1048 IF (output_unit > 0) THEN
1049 IF (unit_nr /= output_unit) THEN
1050 INQUIRE (unit=unit_nr, name=filename)
1051 WRITE (unit=output_unit, fmt="(/,T2,A,2(/,T3,A),/)") &
1052 "ENERGY_CONSTITUENTS", "Total Energy constituents written to file:", &
1053 trim(filename)
1054 ELSE
1055 WRITE (unit=output_unit, fmt="(/,T2,A)") "ENERGY_CONSTITUENTS"
1056 END IF
1057
1058 IF (new_file) THEN
1059 ! NOTE that these are not all terms contributing to the total energy for RTP, only a selection of those
1060 ! most significant / impactful. Therefore the printed components likely will not add up to the total energy.
1061 WRITE (unit=unit_nr, fmt='("#",5X,A,8X,A,10(6X,A))') "Step Nr.", "Time[fs]", &
1062 "Total ener.[a.u.]", "core[a.u.] ", " overlap [a.u.]", "hartree[a.u.]", " exc. [a.u.] ", &
1063 " hartree 1c[a.u.]", "exc 1c[a.u.] ", "exc admm[a.u.]", "exc 1c admm[a.u.]", "efield LG"
1064
1065 END IF
1066 WRITE (unit=unit_nr, fmt="(I10,F20.6,10(F20.9))") &
1067 qs_env%sim_step, qs_env%sim_time*femtoseconds, &
1068 energy%total, energy%core, energy%core_overlap, energy%hartree, energy%exc, &
1069 energy%hartree_1c, energy%exc1, energy%exc_aux_fit, energy%exc1_aux_fit, energy%efield_core
1070
1071 END IF
1072
1073 CALL cp_print_key_finished_output(unit_nr, logger, dft_section, &
1074 "REAL_TIME_PROPAGATION%PRINT%E_CONSTITUENTS")
1075
1076 END SUBROUTINE print_rtp_energy_components
1077
1078! **************************************************************************************************
1079!> \brief Print the dipole moments into a file
1080!> \param moments_section Section of the input defining the file/stream to print the moments to
1081!> \param info_unit Unit where standard output from the program is written - for add. identifiers
1082!> \param moments Actual moment values (for specific time step)
1083!> \param time Current simulation time
1084!> \param imag_opt Whether to calculate the imaginary part
1085!> \par History
1086!> 10.2025 Created [Marek]
1087! **************************************************************************************************
1088 SUBROUTINE print_moments(moments_section, info_unit, moments, time, imag_opt)
1089 TYPE(section_vals_type), POINTER :: moments_section
1090 INTEGER :: info_unit
1091 COMPLEX(kind=dp), DIMENSION(:, :) :: moments
1092 REAL(kind=dp), OPTIONAL :: time
1093 LOGICAL, OPTIONAL :: imag_opt
1094
1095 CHARACTER(len=14), DIMENSION(4) :: file_extensions
1096 INTEGER :: i, j, ndir, nspin, print_unit
1097 LOGICAL :: imaginary
1098 TYPE(cp_logger_type), POINTER :: logger
1099
1100! Index 1 : spin, Index 2 : direction
1101
1102 nspin = SIZE(moments, 1)
1103 ndir = SIZE(moments, 2)
1104
1105 IF (nspin < 1) cpabort("Zero spin index size in print moments!")
1106 IF (ndir < 1) cpabort("Zero direction index size in print moments!")
1107
1108 imaginary = .true.
1109 IF (PRESENT(imag_opt)) imaginary = imag_opt
1110
1111 ! Get the program run info unit and target unit
1112 ! If these are the same (most likely the case of __STD_OUT__), add
1113 ! extra identifier to the printed output
1114 file_extensions(1) = "_SPIN_A_RE.dat"
1115 file_extensions(2) = "_SPIN_A_IM.dat"
1116 file_extensions(3) = "_SPIN_B_RE.dat"
1117 file_extensions(4) = "_SPIN_B_IM.dat"
1118 logger => cp_get_default_logger()
1119 DO i = 1, nspin
1120 ! Real part
1121 print_unit = cp_print_key_unit_nr(logger, moments_section, extension=file_extensions(2*i - 1))
1122 IF (print_unit == info_unit .AND. print_unit > 0) THEN
1123 ! Do the output with additional suffix
1124 WRITE (print_unit, "(A18)", advance="no") " MOMENTS_TRACE_RE|"
1125 END IF
1126 IF (print_unit > 0) THEN
1127 IF (PRESENT(time)) WRITE (print_unit, "(E20.8E3)", advance="no") time*femtoseconds
1128 DO j = 1, ndir - 1
1129 WRITE (print_unit, "(E20.8E3)", advance="no") real(moments(i, j))
1130 END DO
1131 ! Write the last direction
1132 WRITE (print_unit, "(E20.8E3)") real(moments(i, ndir))
1133 END IF
1134 CALL cp_print_key_finished_output(print_unit, logger, moments_section)
1135 ! Same for imaginary part
1136 IF (imaginary) THEN
1137 print_unit = cp_print_key_unit_nr(logger, moments_section, extension=file_extensions(2*i))
1138 IF (print_unit == info_unit .AND. print_unit > 0) THEN
1139 ! Do the output with additional suffix
1140 WRITE (print_unit, "(A18)", advance="no") " MOMENTS_TRACE_IM|"
1141 END IF
1142 IF (print_unit > 0) THEN
1143 IF (PRESENT(time)) WRITE (print_unit, "(E20.8E3)", advance="no") time*femtoseconds
1144 DO j = 1, ndir - 1
1145 WRITE (print_unit, "(E20.8E3)", advance="no") aimag(moments(i, j))
1146 END DO
1147 ! Write the last direction
1148 WRITE (print_unit, "(E20.8E3)") aimag(moments(i, ndir))
1149 END IF
1150 CALL cp_print_key_finished_output(print_unit, logger, moments_section)
1151 END IF
1152 END DO
1153
1154 END SUBROUTINE print_moments
1155
1156! **************************************************************************************************
1157!> \brief Calculate the values of real/imaginary parts of moments in all directions
1158!> \param moment_matrices Local matrix representations of dipole (position) operator
1159!> \param density_matrices Density matrices (spin and real+complex parts)
1160!> \param work Extra dbcsr matrix for work
1161!> \param moment Resulting moments (spin and direction)
1162!> \param imag_opt Whether to calculate the imaginary part of the moment
1163!> \par History
1164!> 10.2025 Created [Marek]
1165! **************************************************************************************************
1166 SUBROUTINE calc_local_moment(moment_matrices, density_matrices, work, moment, imag_opt)
1167 TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: moment_matrices, density_matrices
1168 TYPE(dbcsr_type) :: work
1169 COMPLEX(kind=dp), DIMENSION(:, :) :: moment
1170 LOGICAL, OPTIONAL :: imag_opt
1171
1172 INTEGER :: i, k, nspin
1173 LOGICAL :: imag
1174 REAL(kind=dp) :: real_moment
1175
1176 imag = .false.
1177 IF (PRESENT(imag_opt)) imag = imag_opt
1178 nspin = SIZE(density_matrices)/2
1179
1180 DO i = 1, nspin
1181 DO k = 1, 3
1182 CALL dbcsr_multiply("N", "N", -1.0_dp, &
1183 density_matrices(2*i - 1)%matrix, moment_matrices(k)%matrix, &
1184 0.0_dp, work)
1185 CALL dbcsr_trace(work, real_moment)
1186 moment(i, k) = cmplx(real_moment, 0.0, kind=dp)
1187 IF (imag) THEN
1188 CALL dbcsr_multiply("N", "N", -1.0_dp, &
1189 density_matrices(2*i)%matrix, moment_matrices(k)%matrix, &
1190 0.0_dp, work)
1191 CALL dbcsr_trace(work, real_moment)
1192 moment(i, k) = moment(i, k) + cmplx(0.0, real_moment, kind=dp)
1193 END IF
1194 END DO
1195 END DO
1196
1197 END SUBROUTINE calc_local_moment
1198
1199! **************************************************************************************************
1200!> \brief Calculate and print the Fourier transforms + polarizabilites from moment trace
1201!> \param rtp_section The RTP input section (needed to access PRINT configurations)
1202!> \param moments Moment trace
1203!> \param times Corresponding times
1204!> \param fields Corresponding fields
1205!> \param rtc rt_control_type that includes metadata
1206!> \param info_opt ...
1207!> \param cell If present, used to change the delta peak representation to be in units of reciprocal lattice
1208!> \par History
1209!> 10.2025 Created [Marek]
1210! **************************************************************************************************
1211 SUBROUTINE print_ft(rtp_section, moments, times, fields, rtc, info_opt, cell)
1212 TYPE(section_vals_type), POINTER :: rtp_section
1213 COMPLEX(kind=dp), DIMENSION(:, :, :), POINTER :: moments
1214 REAL(kind=dp), DIMENSION(:), POINTER :: times
1215 COMPLEX(kind=dp), DIMENSION(:, :), POINTER :: fields
1216 TYPE(rtp_control_type), POINTER :: rtc
1217 INTEGER, OPTIONAL :: info_opt
1218 TYPE(cell_type), OPTIONAL, POINTER :: cell
1219
1220 CHARACTER(len=11), DIMENSION(2) :: file_extensions
1221 CHARACTER(len=20), ALLOCATABLE, DIMENSION(:) :: headers
1222 CHARACTER(len=21) :: prefix
1223 CHARACTER(len=5) :: prefix_format
1224 COMPLEX(kind=dp), ALLOCATABLE, DIMENSION(:) :: omegas_complex, omegas_pade
1225 COMPLEX(kind=dp), ALLOCATABLE, DIMENSION(:, :) :: field_results, field_results_pade, &
1226 pol_results, pol_results_pade, &
1227 results, results_pade, value_series
1228 INTEGER :: ft_unit, i, info_unit, k, n, n_elems, &
1229 n_pade, nspin
1230 LOGICAL :: do_moments_ft, do_polarizability
1231 REAL(kind=dp) :: damping, t0
1232 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: omegas, omegas_pade_real
1233 REAL(kind=dp), DIMENSION(3) :: delta_vec
1234 TYPE(cp_logger_type), POINTER :: logger
1235 TYPE(section_vals_type), POINTER :: moment_ft_section, pol_section
1236
1237! For results, using spin * direction for first index, e.g. for nspin = 2
1238! results(1,:) = (spin=1 and direction=1,:),
1239! results(5,:) = (spin=2 and direction=2,:)
1240
1241 logger => cp_get_default_logger()
1242
1243 moment_ft_section => section_vals_get_subs_vals(rtp_section, "PRINT%MOMENTS_FT")
1244 pol_section => section_vals_get_subs_vals(rtp_section, "PRINT%POLARIZABILITY")
1245
1246 nspin = SIZE(moments, 1)
1247 n = SIZE(times)
1248 n_elems = SIZE(rtc%print_pol_elements, 1)
1249
1250 info_unit = -1
1251 IF (PRESENT(info_opt)) info_unit = info_opt
1252
1253 ! NOTE : Allows for at most 2 spin species
1254 file_extensions(1) = "_SPIN_A.dat"
1255 file_extensions(2) = "_SPIN_B.dat"
1256
1257 ! Determine whether MOMENTS_FT and/or polarizability needs to be calculated
1258 do_moments_ft = cp_printkey_is_on(logger%iter_info, moment_ft_section)
1259 do_polarizability = cp_printkey_is_on(logger%iter_info, pol_section)
1260 do_polarizability = do_polarizability .AND. (n_elems > 0)
1261
1262 damping = rtc%ft_damping
1263 t0 = rtc%ft_t0
1264
1265 ! Determine field ft if polarizability required
1266 IF (do_polarizability) THEN
1267 ALLOCATE (field_results(3, n))
1268 IF (rtc%apply_delta_pulse) THEN
1269 ! Constant real FT
1270 IF (PRESENT(cell)) THEN
1271 delta_vec(:) = (real(rtc%delta_pulse_direction(1), kind=dp)*cell%h_inv(1, :) + &
1272 REAL(rtc%delta_pulse_direction(2), kind=dp)*cell%h_inv(2, :) + &
1273 REAL(rtc%delta_pulse_direction(3), kind=dp)*cell%h_inv(3, :)) &
1274 *twopi*rtc%delta_pulse_scale
1275 ELSE
1276 delta_vec(:) = real(rtc%delta_pulse_direction(:), kind=dp)*rtc%delta_pulse_scale
1277 END IF
1278 DO k = 1, 3
1279 field_results(k, :) = cmplx(delta_vec(k), 0.0, kind=dp)
1280 END DO
1281 ELSE
1282 ! Do explicit FT
1283 CALL multi_fft(times, fields, field_results, &
1284 damping_opt=damping, t0_opt=t0, subtract_initial_opt=.true.)
1285 END IF
1286 END IF
1287
1288 IF (do_moments_ft .OR. do_polarizability) THEN
1289 ! We need to transform at least the moments
1290 ! NOTE : Might be able to save some memory by only doing FT of actually
1291 ! required moments, but for now, doing FT of all moment directions
1292 ALLOCATE (results(3*nspin, n))
1293 ALLOCATE (omegas(n))
1294 ALLOCATE (value_series(3*nspin, n))
1295 DO i = 1, nspin
1296 DO k = 1, 3
1297 value_series(3*(i - 1) + k, :) = moments(i, k, :)
1298 END DO
1299 END DO
1300 ! TODO : Choose whether the initial subtraction is applied in &FT section?
1301 CALL multi_fft(times, value_series, results, omegas, &
1302 damping_opt=damping, t0_opt=t0, subtract_initial_opt=.true.)
1303 DEALLOCATE (value_series)
1304 DO i = 1, nspin
1305 ! Output to FT file, if needed
1306 ft_unit = cp_print_key_unit_nr(logger, moment_ft_section, extension=file_extensions(i), &
1307 file_form="FORMATTED", file_position="REWIND")
1308 ! Print header
1309 IF (ft_unit > 0) THEN
1310 ALLOCATE (headers(7))
1311 headers(2) = " x,real [at.u.]"
1312 headers(3) = " x,imag [at.u.]"
1313 headers(4) = " y,real [at.u.]"
1314 headers(5) = " y,imag [at.u.]"
1315 headers(6) = " z,real [at.u.]"
1316 headers(7) = " z,imag [at.u.]"
1317 IF (info_unit == ft_unit) THEN
1318 headers(1) = "# Energy [eV]"
1319 prefix = " MOMENTS_FT|"
1320 prefix_format = "(A12)"
1321 CALL print_ft_file(ft_unit, headers, omegas, results(3*(i - 1) + 1:3*(i - 1) + 3, :), &
1322 prefix, prefix_format, evolt)
1323 ELSE
1324 headers(1) = "# omega [at.u.]"
1325 CALL print_ft_file(ft_unit, headers, omegas, results(3*(i - 1) + 1:3*(i - 1) + 3, :))
1326 END IF
1327 DEALLOCATE (headers)
1328 END IF
1329 CALL cp_print_key_finished_output(ft_unit, logger, moment_ft_section)
1330 END DO
1331 END IF
1332
1333 IF (rtc%pade_requested .AND. (do_moments_ft .OR. do_polarizability)) THEN
1334 ALLOCATE (omegas_complex(SIZE(omegas)))
1335 omegas_complex(:) = cmplx(omegas(:), 0.0, kind=dp)
1336 n_pade = int((rtc%pade_e_max - rtc%pade_e_min)/rtc%pade_e_step)
1337 ALLOCATE (omegas_pade(n_pade))
1338 ALLOCATE (omegas_pade_real(n_pade))
1339 ! Construct omegas_pade and omegas_complex
1340 DO i = 1, n_pade
1341 omegas_pade_real(i) = (i - 1)*rtc%pade_e_step + rtc%pade_e_min
1342 omegas_pade(i) = cmplx(omegas_pade_real(i), 0.0, kind=dp)
1343 END DO
1344 ALLOCATE (results_pade(nspin*3, n_pade), source=cmplx(0.0, 0.0, kind=dp))
1345 DO i = 1, nspin
1346 DO k = 1, 3
1347 CALL greenx_refine_ft(rtc%pade_fit_e_min, rtc%pade_fit_e_max, omegas_complex, results(3*(i - 1) + k, :), &
1348 omegas_pade, results_pade(3*(i - 1) + k, :))
1349 END DO
1350 ! Print to a file
1351 ft_unit = cp_print_key_unit_nr(logger, moment_ft_section, extension="_PADE"//file_extensions(i), &
1352 file_form="FORMATTED", file_position="REWIND")
1353 IF (ft_unit > 0) THEN
1354 ALLOCATE (headers(7))
1355 headers(2) = " x,real,pade [at.u.]"
1356 headers(3) = " x,imag,pade [at.u.]"
1357 headers(4) = " y,real,pade [at.u.]"
1358 headers(5) = " y,imag,pade [at.u.]"
1359 headers(6) = " z,real,pade [at.u.]"
1360 headers(7) = " z,imag,pade [at.u.]"
1361 IF (info_unit == ft_unit) THEN
1362 headers(1) = "# Energy [eV]"
1363 prefix = " MOMENTS_FT_PADE|"
1364 prefix_format = "(A17)"
1365 CALL print_ft_file(ft_unit, headers, omegas_pade_real, results_pade(3*(i - 1) + 1:3*(i - 1) + 3, :), &
1366 prefix, prefix_format, evolt)
1367 ELSE
1368 headers(1) = "# omega [at.u.]"
1369 CALL print_ft_file(ft_unit, headers, omegas_pade_real, results_pade(3*(i - 1) + 1:3*(i - 1) + 3, :))
1370 END IF
1371 DEALLOCATE (headers)
1372 END IF
1373 END DO
1374 END IF
1375
1376 IF (do_polarizability) THEN
1377 ! get the polarizability elements, as required
1378 ALLOCATE (pol_results(n_elems, n))
1379 DO i = 1, nspin
1380 DO k = 1, n_elems
1381 ! NOTE - field is regularized to small value
1382 pol_results(k, :) = results(3*(i - 1) + &
1383 rtc%print_pol_elements(k, 1), :)/ &
1384 (field_results(rtc%print_pol_elements(k, 2), :) + &
1385 1.0e-10*field_results(rtc%print_pol_elements(k, 2), 2))
1386 END DO
1387 ! Print to the file
1388 ft_unit = cp_print_key_unit_nr(logger, pol_section, extension=file_extensions(i), &
1389 file_form="FORMATTED", file_position="REWIND")
1390 IF (ft_unit > 0) THEN
1391 ALLOCATE (headers(2*n_elems + 1))
1392 DO k = 1, n_elems
1393 WRITE (headers(2*k), "(A16,I2,I2)") "real pol. elem.", &
1394 rtc%print_pol_elements(k, 1), &
1395 rtc%print_pol_elements(k, 2)
1396 WRITE (headers(2*k + 1), "(A16,I2,I2)") "imag pol. elem.", &
1397 rtc%print_pol_elements(k, 1), &
1398 rtc%print_pol_elements(k, 2)
1399 END DO
1400 ! Write header
1401 IF (info_unit == ft_unit) THEN
1402 headers(1) = "# Energy [eV]"
1403 prefix = " POLARIZABILITY|"
1404 prefix_format = "(A16)"
1405 CALL print_ft_file(ft_unit, headers, omegas, pol_results, &
1406 prefix, prefix_format, evolt)
1407 ELSE
1408 headers(1) = "# omega [at.u.]"
1409 CALL print_ft_file(ft_unit, headers, omegas, pol_results)
1410 END IF
1411 DEALLOCATE (headers)
1412 END IF
1413 CALL cp_print_key_finished_output(ft_unit, logger, pol_section)
1414 END DO
1415 END IF
1416
1417 ! Padé polarizability
1418 IF (rtc%pade_requested .AND. do_polarizability) THEN
1419 ! Start with the field pade
1420 ALLOCATE (field_results_pade(3, n_pade))
1421 IF (rtc%apply_delta_pulse) THEN
1422 DO k = 1, 3
1423 field_results_pade(k, :) = cmplx(delta_vec(k), 0.0, kind=dp)
1424 END DO
1425 ELSE
1426 DO k = 1, 3
1427 CALL greenx_refine_ft(rtc%pade_fit_e_min, rtc%pade_fit_e_max, &
1428 omegas_complex, field_results(k, :), &
1429 omegas_pade, field_results_pade(k, :))
1430 END DO
1431 END IF
1432 ! Allocate polarisation pade
1433 ALLOCATE (pol_results_pade(n_elems, n_pade))
1434 ! Refine
1435 DO i = 1, nspin
1436 DO k = 1, n_elems
1437 ! NOTE : Regularization to small value
1438 pol_results_pade(k, :) = results_pade(3*(i - 1) + rtc%print_pol_elements(k, 1), :)/( &
1439 field_results_pade(rtc%print_pol_elements(k, 2), :) + &
1440 field_results_pade(rtc%print_pol_elements(k, 2), 2)*1.0e-10_dp)
1441 END DO
1442 ! Print to the file
1443 ft_unit = cp_print_key_unit_nr(logger, pol_section, extension="_PADE"//file_extensions(i), &
1444 file_form="FORMATTED", file_position="REWIND")
1445 IF (ft_unit > 0) THEN
1446 ALLOCATE (headers(2*n_elems + 1))
1447 DO k = 1, n_elems
1448 WRITE (headers(2*k), "(A16,I2,I2)") "re,pade,pol.", &
1449 rtc%print_pol_elements(k, 1), &
1450 rtc%print_pol_elements(k, 2)
1451 WRITE (headers(2*k + 1), "(A16,I2,I2)") "im,pade,pol.", &
1452 rtc%print_pol_elements(k, 1), &
1453 rtc%print_pol_elements(k, 2)
1454 END DO
1455 ! Write header
1456 IF (info_unit == ft_unit) THEN
1457 headers(1) = "# Energy [eV]"
1458 prefix = " POLARIZABILITY_PADE|"
1459 prefix_format = "(A21)"
1460 CALL print_ft_file(ft_unit, headers, omegas_pade_real, pol_results_pade, &
1461 prefix, prefix_format, evolt)
1462 ELSE
1463 headers(1) = "# omega [at.u.]"
1464 CALL print_ft_file(ft_unit, headers, omegas_pade_real, pol_results_pade)
1465 END IF
1466 DEALLOCATE (headers)
1467 END IF
1468 CALL cp_print_key_finished_output(ft_unit, logger, pol_section)
1469 END DO
1470 DEALLOCATE (field_results_pade)
1471 DEALLOCATE (pol_results_pade)
1472 END IF
1473
1474 IF (rtc%pade_requested .AND. (do_moments_ft .OR. do_polarizability)) THEN
1475 DEALLOCATE (omegas_complex)
1476 DEALLOCATE (omegas_pade)
1477 DEALLOCATE (omegas_pade_real)
1478 DEALLOCATE (results_pade)
1479 END IF
1480
1481 IF (do_polarizability) THEN
1482 DEALLOCATE (pol_results)
1483 DEALLOCATE (field_results)
1484 END IF
1485
1486 IF (do_moments_ft .OR. do_polarizability) THEN
1487 DEALLOCATE (results)
1488 DEALLOCATE (omegas)
1489 END IF
1490 END SUBROUTINE print_ft
1491
1492! **************************************************************************************************
1493!> \brief ...
1494!> \param ft_unit ...
1495!> \param headers ...
1496!> \param xvals ...
1497!> \param yvals ...
1498!> \param prefix ...
1499!> \param prefix_format ...
1500!> \param xscale_opt ...
1501! **************************************************************************************************
1502 SUBROUTINE print_ft_file(ft_unit, headers, xvals, yvals, prefix, prefix_format, xscale_opt)
1503 INTEGER, INTENT(IN) :: ft_unit
1504 CHARACTER(len=20), DIMENSION(:), INTENT(IN) :: headers
1505 REAL(kind=dp), DIMENSION(:), INTENT(IN) :: xvals
1506 COMPLEX(kind=dp), DIMENSION(:, :), INTENT(IN) :: yvals
1507 CHARACTER(len=21), INTENT(IN), OPTIONAL :: prefix
1508 CHARACTER(len=5), INTENT(IN), OPTIONAL :: prefix_format
1509 REAL(kind=dp), INTENT(IN), OPTIONAL :: xscale_opt
1510
1511 INTEGER :: i, j, ncols, nrows
1512 LOGICAL :: do_prefix
1513 REAL(kind=dp) :: xscale
1514
1515 do_prefix = .false.
1516 IF (PRESENT(prefix)) THEN
1517 IF (PRESENT(prefix_format)) THEN
1518 do_prefix = .true.
1519 ELSE
1520 cpabort("Printing of prefix with missing format!")
1521 END IF
1522 END IF
1523
1524 xscale = 1.0_dp
1525 IF (PRESENT(xscale_opt)) xscale = xscale_opt
1526
1527 ncols = SIZE(yvals, 1)
1528 nrows = SIZE(yvals, 2)
1529
1530 ! Check whether enough headers for yvals and xvals is present
1531 IF (SIZE(headers) < 2*ncols + 1) THEN
1532 cpabort("Not enough headers to print the file!")
1533 END IF
1534
1535 IF (SIZE(xvals) < nrows) THEN
1536 cpabort("Not enough xvals to print all yvals!")
1537 END IF
1538
1539 IF (ft_unit > 0) THEN
1540 ! If prefix is present, write prefix
1541 ! Also write energy in eV instead of at.u.
1542 IF (do_prefix) THEN
1543 WRITE (ft_unit, prefix_format, advance="no") prefix
1544 END IF
1545 WRITE (ft_unit, "(A20)", advance="no") headers(1)
1546 ! Print the rest of the headers
1547 DO j = 1, 2*ncols - 1
1548 WRITE (ft_unit, "(A20)", advance="no") headers(j + 1)
1549 END DO
1550 WRITE (ft_unit, "(A20)") headers(2*ncols + 1)
1551 ! Done with the headers, print actual data
1552 DO i = 1, nrows
1553 IF (do_prefix) THEN
1554 WRITE (ft_unit, prefix_format, advance="no") prefix
1555 END IF
1556 WRITE (ft_unit, "(E20.8E3)", advance="no") xvals(i)*xscale
1557 DO j = 1, ncols - 1
1558 WRITE (ft_unit, "(E20.8E3,E20.8E3)", advance="no") &
1559 REAL(yvals(j, i)), aimag(yvals(j, i))
1560 END DO
1561 WRITE (ft_unit, "(E20.8E3,E20.8E3)") &
1562 REAL(yvals(ncols, i)), aimag(yvals(ncols, i))
1563 END DO
1564 END IF
1565 END SUBROUTINE print_ft_file
1566
1567END MODULE rt_propagation_output
Define the atomic kind types and their sub types.
Handles all functions related to the CELL.
Definition cell_types.F:15
Defines control structures, which contain the parameters and the settings for the DFT-based calculati...
subroutine, public dbcsr_scale(matrix, alpha_scalar)
...
subroutine, public dbcsr_deallocate_matrix(matrix)
...
subroutine, public dbcsr_iterator_next_block(iterator, row, column, block, block_number_argument_has_been_removed, row_size, col_size, row_offset, col_offset)
...
logical function, public dbcsr_iterator_blocks_left(iterator)
...
subroutine, public dbcsr_iterator_stop(iterator)
...
subroutine, public dbcsr_desymmetrize(matrix_a, matrix_b)
...
subroutine, public dbcsr_copy(matrix_b, matrix_a, name, keep_sparsity, keep_imaginary)
...
subroutine, public dbcsr_multiply(transa, transb, alpha, matrix_a, matrix_b, beta, matrix_c, first_row, last_row, first_column, last_column, first_k, last_k, retain_sparsity, filter_eps, flop)
...
subroutine, public dbcsr_get_info(matrix, nblkrows_total, nblkcols_total, nfullrows_total, nfullcols_total, nblkrows_local, nblkcols_local, nfullrows_local, nfullcols_local, my_prow, my_pcol, local_rows, local_cols, proc_row_dist, proc_col_dist, row_blk_size, col_blk_size, row_blk_offset, col_blk_offset, distribution, name, matrix_type, group)
...
subroutine, public dbcsr_init_p(matrix)
...
subroutine, public dbcsr_filter(matrix, eps)
...
subroutine, public dbcsr_binary_write(matrix, filepath)
...
real(kind=dp) function, public dbcsr_get_occupation(matrix)
...
subroutine, public dbcsr_iterator_start(iterator, matrix, shared, dynamic, dynamic_byrows)
...
subroutine, public dbcsr_set(matrix, alpha)
...
subroutine, public dbcsr_add(matrix_a, matrix_b, alpha_scalar, beta_scalar)
...
real(kind=dp) function, public dbcsr_checksum(matrix, pos)
Calculates the checksum of a DBCSR matrix.
subroutine, public dbcsr_trace(matrix, trace)
Computes the trace of the given matrix, also known as the sum of its diagonal elements.
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
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
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_double(fmstruct, struct, context, col, row)
creates a struct with twice the number of blocks on each core. If matrix A has to be multiplied with ...
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_set_all(matrix, alpha, beta)
set all elements of a matrix to the same value, and optionally the diagonal to a different one
various routines to log and control the output. The idea is that decisions about where to log should ...
recursive integer function, public cp_logger_get_default_unit_nr(logger, local, skip_not_ionode)
asks the default unit number of the given logger. try to use cp_logger_get_unit_nr
integer function, public cp_logger_get_default_io_unit(logger)
returns the unit nr for the ionode (-1 on all other processors) skips as well checks if the procs cal...
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...
character(len=default_string_length) function, public cp_iter_string(iter_info, print_key, for_file)
returns the iteration string, a string that is useful to create unique filenames (once you trim it)
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)
...
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
logical function, public cp_printkey_is_on(iteration_info, print_key)
returns true if the printlevel activates this printkey does not look if this iteration it should be p...
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...
A wrapper around pw_to_cube() which accepts particle_list_type.
subroutine, public cp_pw_to_cube(pw, unit_nr, title, particles, zeff, stride, max_file_size_mb, zero_tails, silent, mpi_io)
...
all routins needed for a nonperiodic electric field
subroutine, public make_field(dft_control, field, sim_step, sim_time)
computes the amplitude of the efield within a given envelop
Interface to the Greenx library.
subroutine, public greenx_refine_ft(fit_e_min, fit_e_max, x_fit, y_fit, x_eval, y_eval, n_pade_opt)
Refines the FT grid using Padé approximants.
collects all constants needed in input so that they can be used without circular dependencies
integer, parameter, public ehrenfest
integer, parameter, public real_time_propagation
objects that represent the structure of input sections and the data contained in an input section
integer function, dimension(:), pointer, public section_get_ivals(section_vals, keyword_name)
...
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
sums arrays of real/complex numbers with much reduced round-off as compared to a naive implementation...
Definition kahan_sum.F:29
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
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:136
Definition of mathematical constants and functions.
real(kind=dp), parameter, public one
real(kind=dp), parameter, public twopi
real(kind=dp), parameter, public zero
Interface to the message passing library MPI.
basic linear algebra operations for full matrixes
represent a simple array based list of the given type
Define methods related to particle_type.
subroutine, public get_particle_set(particle_set, qs_kind_set, first_sgf, last_sgf, nsgf, nmao, basis)
Get the components of a particle set.
Define the data structure for the particle information.
Definition of physical constants:
Definition physcon.F:68
real(kind=dp), parameter, public femtoseconds
Definition physcon.F:153
real(kind=dp), parameter, public evolt
Definition physcon.F:183
container for various plainwaves related things
subroutine, public pw_env_get(pw_env, pw_pools, cube_info, gridlevel_info, auxbas_pw_pool, auxbas_grid, auxbas_rs_desc, auxbas_rs_grid, rs_descs, rs_grids, xc_pw_pool, vdw_pw_pool, poisson_env, interp_section)
returns the various attributes of the pw env
Manages a pool of grids (to be used for example as tmp objects), but can also be used to instantiate ...
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, mimic, 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_pp, sab_xtb_nonbond, sab_almo, sab_kp, sab_kp_nosym, sab_cneo, 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, xcint_weights, 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, rhoz_cneo_set, ecoul_1c, rho0_s_rs, rho0_s_gs, rhoz_cneo_s_rs, rhoz_cneo_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, harris_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, eeq, rhs, do_rixs, tb_tblite)
Get the QUICKSTEP environment.
Define the quickstep kind type and their sub types.
subroutine, public get_qs_kind_set(qs_kind_set, all_potential_present, tnadd_potential_present, gth_potential_present, sgp_potential_present, paw_atom_present, dft_plus_u_atom_present, maxcgf, maxsgf, maxco, maxco_proj, maxgtops, maxlgto, maxlprj, maxnset, maxsgf_set, ncgf, npgf, nset, nsgf, nshell, maxpol, maxlppl, maxlppnl, maxppnl, nelectron, maxder, max_ngrid_rad, max_sph_harm, maxg_iso_not0, lmax_rho0, basis_rcut, basis_type, total_zeff_corr, npgf_seg, cneo_potential_present, nkind_q, natom_q)
Get attributes of an atomic kind set.
given the response wavefunctions obtained by the application of the (rxp), p, and ((dk-dl)xp) operato...
subroutine, public calculate_jrho_resp(mat_d0, mat_jp, mat_jp_rii, mat_jp_riii, ib, idir, current_rs, current_gs, qs_env, current_env, soft_valid, retain_rsgrid)
Calculation of the idir component of the response current density in the presence of a constant magne...
Type definitiona for linear response calculations.
Definition and initialisation of the mo data type.
Definition qs_mo_io.F:21
subroutine, public write_rt_mos_to_restart(mo_array, rt_mos, particle_set, dft_section, qs_kind_set)
...
Definition qs_mo_io.F:236
Calculates the moment integrals <a|r^m|b> and <a|r x d/dr|b>
Definition qs_moments.F:14
subroutine, public build_local_moment_matrix(qs_env, moments, nmoments, ref_point, ref_points, basis_type)
...
Definition qs_moments.F:583
Define the neighbor list data types and the corresponding functionality.
subroutine, public build_lin_mom_matrix(qs_env, matrix)
Calculation of the linear momentum matrix <mu|∂|nu> over Cartesian Gaussian functions.
superstucture that hold various representations of the density and keeps track of which ones are vali...
subroutine, public qs_rho_get(rho_struct, rho_ao, rho_ao_im, rho_ao_kp, rho_ao_im_kp, rho_r, drho_r, rho_g, drho_g, tau_r, tau_g, rho_r_valid, drho_r_valid, rho_g_valid, drho_g_valid, tau_r_valid, tau_g_valid, tot_rho_r, tot_rho_g, rho_r_sccs, soft_valid, complex_rho_ao)
returns info about the density described by this object. If some representation is not available an e...
Does all kind of post scf calculations for GPW/GAPW.
subroutine, public write_mo_free_results(qs_env)
Write QS results always available (if switched on through the print_keys) Can be called from ls_scf.
subroutine, public qs_scf_post_moments(input, logger, qs_env, output_unit)
Computes and prints electric moments.
subroutine, public write_mo_dependent_results(qs_env, scf_env)
Write QS results available if MO's are present (if switched on through the print_keys) Writes only MO...
Does all kind of post scf calculations for DFTB.
subroutine, public scf_post_calculation_tb(qs_env, tb_type, no_mos)
collects possible post - scf calculations and prints info / computes properties.
module that contains the definitions of the scf types
types that represent a quickstep subsys
subroutine, public qs_subsys_get(subsys, atomic_kinds, atomic_kind_set, particles, particle_set, local_particles, molecules, molecule_set, molecule_kinds, molecule_kind_set, local_molecules, para_env, colvar_p, shell_particles, core_particles, gci, multipoles, natom, nparticle, ncore, nshell, nkind, atprop, virial, results, cell, cell_ref, use_ref_cell, energy, force, qs_kind_set, cp_subsys, nelectron_total, nelectron_spin)
...
Function related to MO projection in RTP calculations.
subroutine, public compute_and_write_proj_mo(qs_env, mos_new, proj_mo, n_proj)
Compute the projection of the current MO coefficients on reference ones and write the results.
Separation of Fourier transform utilities into separate file.
subroutine, public multi_fft(time_series, value_series, result_series, omega_series, damping_opt, t0_opt, subtract_initial_opt)
Calculates the Fourier transform - couples to FFT libraries in CP2K, if available.
Routine for the real time propagation output.
subroutine, public print_ft(rtp_section, moments, times, fields, rtc, info_opt, cell)
Calculate and print the Fourier transforms + polarizabilites from moment trace.
subroutine, public report_density_occupation(filter_eps, rho)
Reports the sparsity pattern of the complex density matrix.
subroutine, public rt_prop_output(qs_env, run_type, delta_iter, used_time)
...
subroutine, public rt_convergence(rtp, matrix_s, delta_mos, delta_eps)
computes the convergence criterion for RTP and EMD
subroutine, public print_moments(moments_section, info_unit, moments, time, imag_opt)
Print the dipole moments into a file.
subroutine, public calc_local_moment(moment_matrices, density_matrices, work, moment, imag_opt)
Calculate the values of real/imaginary parts of moments in all directions.
subroutine, public rt_convergence_density(rtp, delta_p, delta_eps)
computes the convergence criterion for RTP and EMD based on the density matrix
Types and set_get for real time propagation depending on runtype and diagonalization method different...
subroutine, public get_rtp(rtp, exp_h_old, exp_h_new, h_last_iter, rho_old, rho_next, rho_new, mos, mos_new, mos_old, mos_next, s_inv, s_half, s_minus_half, b_mat, c_mat, propagator_matrix, mixing, mixing_factor, s_der, dt, nsteps, sinvh, sinvh_imag, sinvb, admm_mos)
...
Routines needed for EMD.
subroutine, public write_rtp_mos_to_output_unit(qs_env, rtp)
...
subroutine, public write_rtp_mo_cubes(qs_env, rtp)
Write the time dependent amplitude of the MOs in real grid. Very close to qs_scf_post_gpw/qs_scf_post...
Provides all information about an atomic kind.
Type defining parameters related to the simulation cell.
Definition cell_types.F:60
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...
contained for different pw related things
Manages a pool of grids (to be used for example as tmp objects), but can also be used to instantiate ...
Provides all information about a quickstep kind.
keeps the density in various representations, keeping track of which ones are valid.