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