mirror of
https://github.com/cp2k/cp2k.git
synced 2026-07-26 05:05:16 -04:00
RTBSE : Change of input structure
More than one FT is carried out in the code, so the global FT parameters were moved to the &RTBSE section in the input. Also, allowed for more than one element of polarizability to be printed out.
This commit is contained in:
parent
b7def88a23
commit
32401ac82c
4 changed files with 202 additions and 102 deletions
|
|
@ -183,6 +183,16 @@ continue running the calculation in the same directory for longer time without r
|
|||
calculated time steps. Note that total length of the propagation time controls the energy/frequency
|
||||
precision, while timestep size controls the energy/frequency range.
|
||||
|
||||
For applied field pulse not centered at zero in time, one can use
|
||||
[FT_START_TIME](#CP2K_INPUT.FORCE_EVAL.DFT.REAL_TIME_PROPAGATION.RTBSE.FT_START_TIME) to set the
|
||||
center of Fourier transforms to a provided time $t_0$. Furthermore, the damping $\gamma$ in the
|
||||
Fourier transform is controlled by
|
||||
[FT_DAMPING](#CP2K_INPUT.FORCE_EVAL.DFT.REAL_TIME_PROPAGATION.RTBSE.FT_DAMPING) parameter.
|
||||
Explicilty, in such case, the Fourier transform of function $f(t)$ is
|
||||
|
||||
$$ f(\omega) = \int dt e^{i (\omega + i \gamma) t } f(t + t_0)
|
||||
$$
|
||||
|
||||
### Example Input
|
||||
|
||||
A typical input file which runs the RTBSE propagation will have the
|
||||
|
|
@ -206,8 +216,6 @@ one
|
|||
&END MOMENTS
|
||||
&MOMENTS_FT
|
||||
FILENAME MOMENTS-FT
|
||||
DAMPING 0.1 ! Exponential damping
|
||||
START_TIME ! Fourier transform offset
|
||||
&END MOMENTS_FT
|
||||
&FIELD
|
||||
FILENAME FIELD
|
||||
|
|
@ -215,6 +223,7 @@ one
|
|||
&POLARIZABILITY
|
||||
FILENAME POLARIZABILITY
|
||||
ELEMENT 1 1
|
||||
ELEMENT 2 2 ! print two different elements of tensor
|
||||
&END POLARIZABILITY
|
||||
&END PRINT
|
||||
&END REAL_TIME_PROPAGATION
|
||||
|
|
|
|||
|
|
@ -552,6 +552,7 @@ CONTAINS
|
|||
DO i = 1, 3
|
||||
rtbse_env%moments_trace(i)%series(n) = CMPLX(moments_re(i), moments_im(i), kind=dp)
|
||||
END DO
|
||||
rtbse_env%time_trace%series(n) = timestamp
|
||||
END DO
|
||||
! Change back to atomic units in the trace
|
||||
rtbse_env%time_trace%series(:) = rtbse_env%time_trace%series(:)/femtoseconds
|
||||
|
|
@ -576,7 +577,7 @@ CONTAINS
|
|||
! Stores the data in ready for output format
|
||||
! - first dimension is 6 - 1 - real part along x, 2 - imag part along x, 3 - real part along y, ...
|
||||
REAL(kind=dp), DIMENSION(:, :), ALLOCATABLE :: ft_full_series
|
||||
INTEGER :: i, n, ft_unit
|
||||
INTEGER :: i, n, ft_unit
|
||||
|
||||
logger => cp_get_default_logger()
|
||||
|
||||
|
|
@ -594,19 +595,17 @@ CONTAINS
|
|||
DO i = 1, 3
|
||||
! Real part of the value first
|
||||
value_series(:) = REAL(rtbse_env%moments_trace(i)%series(:))
|
||||
CALL ft_simple(rtbse_env%time_trace%series, value_series, omega_series, ft_real_series, ft_imag_series, &
|
||||
rtbse_env%ft_damping, rtbse_env%ft_start)
|
||||
CALL ft_simple(rtbse_env%time_trace%series, value_series, ft_real_series, ft_imag_series, &
|
||||
damping_opt=rtbse_env%ft_damping, t0_opt=rtbse_env%ft_start, subtract_initial_opt=.TRUE.)
|
||||
ft_full_series(2*i - 1, :) = ft_real_series(:)
|
||||
ft_full_series(2*i, :) = ft_imag_series(:)
|
||||
! Now imaginary part
|
||||
value_series(:) = AIMAG(rtbse_env%moments_trace(i)%series(:))
|
||||
CALL ft_simple(rtbse_env%time_trace%series, value_series, omega_series, ft_real_series, ft_imag_series, &
|
||||
rtbse_env%ft_damping, rtbse_env%ft_start)
|
||||
CALL ft_simple(rtbse_env%time_trace%series, value_series, ft_real_series, ft_imag_series, omega_series, &
|
||||
damping_opt=rtbse_env%ft_damping, t0_opt=rtbse_env%ft_start, subtract_initial_opt=.TRUE.)
|
||||
ft_full_series(2*i - 1, :) = ft_full_series(2*i - 1, :) - ft_imag_series
|
||||
ft_full_series(2*i, :) = ft_full_series(2*i, :) + ft_real_series
|
||||
END DO
|
||||
DEALLOCATE (ft_real_series)
|
||||
DEALLOCATE (ft_imag_series)
|
||||
DEALLOCATE (value_series)
|
||||
! Now, write these to file
|
||||
ft_unit = cp_print_key_unit_nr(logger, rtbse_env%ft_section, extension=".dat", &
|
||||
|
|
@ -620,6 +619,8 @@ CONTAINS
|
|||
END DO
|
||||
END IF
|
||||
CALL cp_print_key_finished_output(ft_unit, logger, rtbse_env%ft_section)
|
||||
DEALLOCATE (ft_real_series)
|
||||
DEALLOCATE (ft_imag_series)
|
||||
DEALLOCATE (omega_series)
|
||||
DEALLOCATE (ft_full_series)
|
||||
END SUBROUTINE output_moments_ft
|
||||
|
|
@ -637,14 +638,15 @@ CONTAINS
|
|||
ft_imag_series, &
|
||||
value_series
|
||||
COMPLEX(kind=dp), DIMENSION(:), ALLOCATABLE :: moment_series, &
|
||||
field_series, &
|
||||
polarizability_series
|
||||
field_series
|
||||
COMPLEX(kind=dp), DIMENSION(:, :), ALLOCATABLE :: polarizability_series
|
||||
INTEGER :: pol_unit, &
|
||||
i, n
|
||||
i, k, n, n_elems
|
||||
|
||||
logger => cp_get_default_logger()
|
||||
|
||||
n = rtbse_env%sim_nsteps + 2
|
||||
n_elems = SIZE(rtbse_env%pol_elements, 1)
|
||||
! All allocations together, although could save some memory, if required by consequent deallocations
|
||||
ALLOCATE (omega_series(n), source=0.0_dp)
|
||||
ALLOCATE (ft_real_series(n), source=0.0_dp)
|
||||
|
|
@ -652,66 +654,87 @@ CONTAINS
|
|||
ALLOCATE (value_series(n), source=0.0_dp)
|
||||
ALLOCATE (moment_series(n), source=CMPLX(0.0, 0.0, kind=dp))
|
||||
ALLOCATE (field_series(n), source=CMPLX(0.0, 0.0, kind=dp))
|
||||
ALLOCATE (polarizability_series(n), source=CMPLX(0.0, 0.0, kind=dp))
|
||||
ALLOCATE (polarizability_series(n_elems, n), source=CMPLX(0.0, 0.0, kind=dp))
|
||||
|
||||
! The moment ft
|
||||
! Real part
|
||||
value_series(:) = REAL(rtbse_env%moments_trace(rtbse_env%pol_element(1))%series(:))
|
||||
CALL ft_simple(rtbse_env%time_trace%series, value_series, omega_series, ft_real_series, ft_imag_series, &
|
||||
rtbse_env%ft_damping, rtbse_env%ft_start, .TRUE.)
|
||||
moment_series(:) = CMPLX(ft_real_series(:), ft_imag_series(:), kind=dp)
|
||||
! Imaginary part
|
||||
value_series(:) = AIMAG(rtbse_env%moments_trace(rtbse_env%pol_element(1))%series(:))
|
||||
CALL ft_simple(rtbse_env%time_trace%series, value_series, omega_series, ft_real_series, ft_imag_series, &
|
||||
rtbse_env%ft_damping, rtbse_env%ft_start, .TRUE.)
|
||||
moment_series(:) = moment_series(:) + CMPLX(-ft_imag_series(:), ft_real_series(:), kind=dp)
|
||||
DO k = 1, n_elems
|
||||
! The moment ft
|
||||
! Real part
|
||||
value_series(:) = REAL(rtbse_env%moments_trace(rtbse_env%pol_elements(k, 1))%series(:))
|
||||
CALL ft_simple(rtbse_env%time_trace%series, value_series, ft_real_series, ft_imag_series, &
|
||||
damping_opt=rtbse_env%ft_damping, t0_opt=rtbse_env%ft_start, subtract_initial_opt=.TRUE.)
|
||||
moment_series(:) = CMPLX(ft_real_series(:), ft_imag_series(:), kind=dp)
|
||||
! Imaginary part
|
||||
value_series(:) = AIMAG(rtbse_env%moments_trace(rtbse_env%pol_elements(k, 1))%series(:))
|
||||
CALL ft_simple(rtbse_env%time_trace%series, value_series, ft_real_series, ft_imag_series, omega_series, &
|
||||
damping_opt=rtbse_env%ft_damping, t0_opt=rtbse_env%ft_start, subtract_initial_opt=.TRUE.)
|
||||
moment_series(:) = moment_series(:) + CMPLX(-ft_imag_series(:), ft_real_series(:), kind=dp)
|
||||
|
||||
! Calculate the field transform - store it in ft_real_series
|
||||
IF (rtbse_env%dft_control%rtp_control%apply_delta_pulse) THEN
|
||||
! Only divide by constant magnitude in atomic units
|
||||
field_series(:) = CMPLX(rtbse_env%dft_control%rtp_control%delta_pulse_scale, 0.0, kind=dp)
|
||||
ELSE
|
||||
! Calculate the transform of the field as well and divide by it
|
||||
! The field FT is not damped - assume field is localised in time
|
||||
! The field is strictly real
|
||||
CALL ft_simple(rtbse_env%time_trace%series, rtbse_env%field_trace(rtbse_env%pol_element(2))%series, &
|
||||
omega_series, ft_real_series, ft_imag_series, 0.0_dp, rtbse_env%ft_start, .FALSE.)
|
||||
! Regularization for the case when ft_series becomes identically zero - TODO : Set in config
|
||||
field_series(:) = CMPLX(ft_real_series(:), ft_imag_series(:) + 1.0e-20, kind=dp)
|
||||
END IF
|
||||
! Divide to get the polarizability series
|
||||
! Real part
|
||||
polarizability_series(:) = moment_series(:)/field_series(:)
|
||||
! Calculate the field transform - store it in ft_real_series
|
||||
IF (rtbse_env%dft_control%rtp_control%apply_delta_pulse) THEN
|
||||
! Only divide by constant magnitude in atomic units
|
||||
! TODO : Fix for field with more than one direction
|
||||
field_series(:) = CMPLX( &
|
||||
rtbse_env%dft_control%rtp_control%delta_pulse_direction(rtbse_env%pol_elements(k, 2))* &
|
||||
rtbse_env%dft_control%rtp_control%delta_pulse_scale, 0.0, kind=dp)
|
||||
ELSE
|
||||
! Calculate the transform of the field as well and divide by it
|
||||
! The field FT is not damped - assume field is localised in time
|
||||
! The field is strictly real
|
||||
CALL ft_simple(rtbse_env%time_trace%series, rtbse_env%field_trace(rtbse_env%pol_elements(k, 2))%series, &
|
||||
ft_real_series, ft_imag_series, omega_series, &
|
||||
0.0_dp, rtbse_env%ft_start, .FALSE.)
|
||||
! Regularization for the case when ft_series becomes identically zero - TODO : Set in config
|
||||
field_series(:) = CMPLX(ft_real_series(:), ft_imag_series(:) + 1.0e-20, kind=dp)
|
||||
END IF
|
||||
! Divide to get the polarizability series
|
||||
polarizability_series(k, :) = moment_series(:)/field_series(:)
|
||||
END DO
|
||||
|
||||
! Change units to eV for energy
|
||||
! use value_series for energy and moment_series for polarizability
|
||||
value_series(:) = omega_series(:)*evolt
|
||||
! Use below for printing of field FT in case of problems
|
||||
! PRINT *, "=== Field FT"
|
||||
! DO i=1,n
|
||||
! PRINT '(E20.8E3,E20.8E3,E20.8E3)', value_series(i), REAL(field_series(i)), AIMAG(field_series(i))
|
||||
! END DO
|
||||
! PRINT *, "=== Field FT"
|
||||
! Print out the polarizability to a file
|
||||
pol_unit = cp_print_key_unit_nr(logger, rtbse_env%pol_section, extension=".dat", &
|
||||
file_form="FORMATTED", file_position="REWIND")
|
||||
! Printing for both the stdout and separate file
|
||||
IF (pol_unit > 0) THEN
|
||||
IF (pol_unit == rtbse_env%unit_nr) THEN
|
||||
WRITE (pol_unit, '(A16,A20,A22,A22)') &
|
||||
" POLARIZABILITY|", "Energy [eV]", "Real polarizability", "Imag polarizability"
|
||||
DO i = 1, n
|
||||
WRITE (pol_unit, '(A16,E20.8E3,E22.8E3,E22.8E3)') &
|
||||
" POLARIZABILITY|", value_series(i), REAL(polarizability_series(i)), AIMAG(polarizability_series(i))
|
||||
END DO
|
||||
! Print the stdout preline
|
||||
WRITE (pol_unit, '(A16)', advance="no") " POLARIZABILITY|"
|
||||
ELSE
|
||||
WRITE (pol_unit, '(A1,A19,A20,A20,A20)') &
|
||||
"#", "omega [a.u.]", "Energy [eV]", "Real polarizability", "Imag polarizability"
|
||||
DO i = 1, n
|
||||
WRITE (pol_unit, '(E20.8E3,E20.8E3,E20.8E3,E20.8E3)') &
|
||||
omega_series(i), value_series(i), REAL(polarizability_series(i)), AIMAG(polarizability_series(i))
|
||||
END DO
|
||||
CALL cp_print_key_finished_output(pol_unit, logger, rtbse_env%ft_section)
|
||||
! Print also the energy in atomic units
|
||||
WRITE (pol_unit, '(A1,A19)', advance="no") "#", "omega [a.u.]"
|
||||
END IF
|
||||
! Common - print the energy in eV
|
||||
WRITE (pol_unit, '(A20)', advance="no") "Energy [eV]"
|
||||
! Print a header for each polarizability element
|
||||
DO k = 1, n_elems - 1
|
||||
WRITE (pol_unit, '(A16,I2,I2,A16,I2,I2)', advance="no") &
|
||||
"Real pol.", rtbse_env%pol_elements(k, 1), rtbse_env%pol_elements(k, 2), &
|
||||
"Imag pol.", rtbse_env%pol_elements(k, 1), rtbse_env%pol_elements(k, 2)
|
||||
END DO
|
||||
WRITE (pol_unit, '(A16,I2,I2,A16,I2,I2)') &
|
||||
"Real pol.", rtbse_env%pol_elements(n_elems, 1), rtbse_env%pol_elements(n_elems, 2), &
|
||||
"Imag pol.", rtbse_env%pol_elements(n_elems, 1), rtbse_env%pol_elements(n_elems, 2)
|
||||
DO i = 1, n
|
||||
IF (pol_unit == rtbse_env%unit_nr) THEN
|
||||
! Print the stdout preline
|
||||
WRITE (pol_unit, '(A16)', advance="no") " POLARIZABILITY|"
|
||||
ELSE
|
||||
! omega in a.u.
|
||||
WRITE (pol_unit, '(E20.8E3)', advance="no") omega_series(i)
|
||||
END IF
|
||||
! Common values
|
||||
WRITE (pol_unit, '(E20.8E3)', advance="no") value_series(i)
|
||||
DO k = 1, n_elems - 1
|
||||
WRITE (pol_unit, '(E20.8E3,E20.8E3)', advance="no") &
|
||||
REAL(polarizability_series(k, i)), AIMAG(polarizability_series(k, i))
|
||||
END DO
|
||||
! Print the final value and advance
|
||||
WRITE (pol_unit, '(E20.8E3,E20.8E3)') &
|
||||
REAL(polarizability_series(n_elems, i)), AIMAG(polarizability_series(n_elems, i))
|
||||
END DO
|
||||
CALL cp_print_key_finished_output(pol_unit, logger, rtbse_env%pol_section)
|
||||
END IF
|
||||
|
||||
DEALLOCATE (value_series)
|
||||
|
|
@ -739,13 +762,13 @@ CONTAINS
|
|||
!> \date 09.2024
|
||||
! **************************************************************************************************
|
||||
! So far only for defined one dimensional series
|
||||
SUBROUTINE ft_simple(time_series, value_series, omega_series, result_series, iresult_series, &
|
||||
SUBROUTINE ft_simple(time_series, value_series, result_series, iresult_series, omega_series, &
|
||||
damping_opt, t0_opt, subtract_initial_opt)
|
||||
REAL(kind=dp), DIMENSION(:) :: time_series
|
||||
REAL(kind=dp), DIMENSION(:) :: value_series
|
||||
REAL(kind=dp), DIMENSION(:) :: omega_series
|
||||
REAL(kind=dp), DIMENSION(:) :: result_series
|
||||
REAL(kind=dp), DIMENSION(:) :: iresult_series
|
||||
REAL(kind=dp), DIMENSION(:), OPTIONAL :: omega_series
|
||||
REAL(kind=dp), OPTIONAL :: damping_opt
|
||||
REAL(kind=dp), OPTIONAL :: t0_opt
|
||||
LOGICAL, OPTIONAL :: subtract_initial_opt
|
||||
|
|
@ -777,7 +800,9 @@ CONTAINS
|
|||
! Default damping so that at the end of the time series, divide value by e^-4
|
||||
damping = 4.0_dp/(time_series(N) - time_series(t0_i))
|
||||
IF (PRESENT(damping_opt)) THEN
|
||||
IF (damping_opt >= 0.0_dp) damping = damping_opt
|
||||
! Damping is given a time in which the moments reduce by factor of 1/e
|
||||
IF (damping_opt > 0.0_dp) damping = 1.0_dp/damping_opt
|
||||
IF (damping_opt == 0.0_dp) damping = 0.0_dp
|
||||
END IF
|
||||
|
||||
IF (PRESENT(subtract_initial_opt)) THEN
|
||||
|
|
@ -792,11 +817,11 @@ CONTAINS
|
|||
delta_omega = twopi/(time_series(N) - time_series(1))
|
||||
! Subtract initial value, if requested (default is to subtract the value)
|
||||
value_subtract = 0.0_dp
|
||||
IF (subtract_initial) value_subtract = value_series(t0_i)
|
||||
IF (subtract_initial) value_subtract = value_series(1)
|
||||
DO i = 1, N
|
||||
result_series(i) = 0.0_dp
|
||||
iresult_series(i) = 0.0_dp
|
||||
omega_series(i) = delta_omega*(i - 1)
|
||||
IF (PRESENT(omega_series)) omega_series(i) = delta_omega*(i - 1)
|
||||
DO j = 1, N
|
||||
j_wrap = MODULO(j + t0_i - 2, N) + 1
|
||||
result_series(i) = result_series(i) + COS(twopi*(i - 1)*(j - 1)/N)* &
|
||||
|
|
|
|||
|
|
@ -78,13 +78,6 @@ MODULE rt_bse_types
|
|||
USE gw_integrals, ONLY: build_3c_integral_block
|
||||
USE gw_large_cell_Gamma, ONLY: compute_3c_integrals
|
||||
USE qs_tensors, ONLY: neighbor_list_3c_destroy
|
||||
! USE gw_utils, ONLY: create_and_init_bs_env_for_gw,&
|
||||
! setup_AO_and_RI_basis_set,&
|
||||
! get_RI_basis_and_basis_function_indices,&
|
||||
! set_heuristic_parameters,&
|
||||
! set_parallelization_parameters,&
|
||||
! allocate_and_fill_matrices_and_arrays,&
|
||||
! create_tensors
|
||||
USE libint_wrapper, ONLY: cp_libint_static_init
|
||||
USE libint_2c_3c, ONLY: libint_potential_type
|
||||
USE input_constants, ONLY: use_mom_ref_coac, &
|
||||
|
|
@ -99,6 +92,7 @@ MODULE rt_bse_types
|
|||
USE physcon, ONLY: angstrom
|
||||
USE mathconstants, ONLY: z_zero
|
||||
USE input_section_types, ONLY: section_vals_type, &
|
||||
section_vals_get, &
|
||||
section_vals_val_get, &
|
||||
section_vals_get_subs_vals
|
||||
|
||||
|
|
@ -204,7 +198,7 @@ MODULE rt_bse_types
|
|||
ft_damping = 0.0_dp, &
|
||||
ft_start = 0.0_dp
|
||||
! Which element of polarizability to print out
|
||||
INTEGER, DIMENSION(2) :: pol_element = [1, 1]
|
||||
INTEGER, DIMENSION(:, :), POINTER :: pol_elements => NULL()
|
||||
TYPE(dft_control_type), POINTER :: dft_control => NULL()
|
||||
! DEBUG : Trying keeping the reference to previous environments inside this one
|
||||
TYPE(qs_environment_type), POINTER :: qs_env => NULL()
|
||||
|
|
@ -290,9 +284,12 @@ CONTAINS
|
|||
TYPE(rt_prop_type), POINTER :: rtp
|
||||
TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_s
|
||||
TYPE(mo_set_type), DIMENSION(:), POINTER :: mos
|
||||
INTEGER :: i, k
|
||||
INTEGER :: i, j, k, single_pol_index
|
||||
TYPE(section_vals_type), POINTER :: input, bs_sec, md_sec
|
||||
INTEGER, DIMENSION(:), POINTER :: pol_tmp
|
||||
LOGICAL :: pol_elements_explicit, &
|
||||
pol_vector_known
|
||||
REAL(kind=dp), DIMENSION(3) :: pol_vector
|
||||
|
||||
! Allocate the storage for the gwbse environment
|
||||
NULLIFY (rtbse_env)
|
||||
|
|
@ -346,20 +343,75 @@ CONTAINS
|
|||
rtbse_env%sim_start_orig = rtbse_env%sim_start
|
||||
CALL section_vals_val_get(md_sec, "STEPS", i_val=rtbse_env%sim_nsteps)
|
||||
! Get the values for the FT
|
||||
CALL section_vals_val_get(input, "DFT%REAL_TIME_PROPAGATION%PRINT%MOMENTS_FT%DAMPING", &
|
||||
CALL section_vals_val_get(input, "DFT%REAL_TIME_PROPAGATION%RTBSE%FT_DAMPING", &
|
||||
r_val=rtbse_env%ft_damping)
|
||||
CALL section_vals_val_get(input, "DFT%REAL_TIME_PROPAGATION%PRINT%MOMENTS_FT%START_TIME", &
|
||||
CALL section_vals_val_get(input, "DFT%REAL_TIME_PROPAGATION%RTBSE%FT_START_TIME", &
|
||||
r_val=rtbse_env%ft_start)
|
||||
! TODO : Units for starting time and damping - so far give atomic units
|
||||
! Handle ELEMENT keywords
|
||||
! By default, if the keywords are not present, check whether just one element in polarization/delta_pulse direction
|
||||
! is non-zero. If that is the case, print 3 finite elements of polarizability. Otherwise, warn and print
|
||||
! just diagonal elements for each non-zero e-field element
|
||||
! Iterate over all ELEMENT keywords
|
||||
CALL section_vals_val_get(input, "DFT%REAL_TIME_PROPAGATION%PRINT%POLARIZABILITY%ELEMENT", &
|
||||
i_vals=pol_tmp)
|
||||
IF (SIZE(pol_tmp) < 2) CPABORT("Less than two elements provided for polarizability")
|
||||
rtbse_env%pol_element(:) = pol_tmp(:)
|
||||
! Do basic sanity checks for pol_element
|
||||
DO k = 1, 2
|
||||
IF (rtbse_env%pol_element(k) > 3 .OR. rtbse_env%pol_element(k) < 1) &
|
||||
CPABORT("Polarisation tensor element not 1,2 or 3 in at least one index")
|
||||
END DO
|
||||
n_rep_val=k, explicit=pol_elements_explicit)
|
||||
IF (pol_elements_explicit) THEN
|
||||
! By default, fill with 1 1 elements
|
||||
ALLOCATE (rtbse_env%pol_elements(k, 2), source=1)
|
||||
DO i = 1, k
|
||||
CALL section_vals_val_get(input, "DFT%REAL_TIME_PROPAGATION%PRINT%POLARIZABILITY%ELEMENT", &
|
||||
i_vals=pol_tmp, i_rep_val=i)
|
||||
IF (SIZE(pol_tmp) < 2) CPABORT("Less than two elements provided for polarizability")
|
||||
rtbse_env%pol_elements(i, :) = pol_tmp(:)
|
||||
END DO
|
||||
! Do basic sanity checks for pol_element
|
||||
DO j = 1, k
|
||||
DO i = 1, 2
|
||||
IF (rtbse_env%pol_elements(j, i) > 3 .OR. rtbse_env%pol_elements(j, i) < 1) &
|
||||
CPABORT("Polarisation tensor element not 1,2 or 3 in at least one index")
|
||||
END DO
|
||||
END DO
|
||||
ELSE
|
||||
! Figure out whether delta direction or polarization is applicable
|
||||
pol_vector_known = .FALSE.
|
||||
IF (rtbse_env%dft_control%rtp_control%apply_delta_pulse) THEN
|
||||
! Delta pulse polarization
|
||||
pol_vector(:) = rtbse_env%dft_control%rtp_control%delta_pulse_direction(:)
|
||||
pol_vector_known = .TRUE.
|
||||
ELSE IF (SIZE(rtbse_env%dft_control%efield_fields) > 0) THEN
|
||||
! real time field polarization
|
||||
! Maybe generalize for all fields?
|
||||
pol_vector(:) = rtbse_env%dft_control%efield_fields(1)%efield%polarisation(:)
|
||||
pol_vector_known = .TRUE.
|
||||
END IF
|
||||
! Check whether the vector is not explicitly zero
|
||||
IF (DOT_PRODUCT(pol_vector, pol_vector) == 0.0_dp) pol_vector_known = .FALSE.
|
||||
IF (pol_vector_known) THEN
|
||||
! Iterate over the pol vector, check whether just one is non-zero
|
||||
single_pol_index = -1
|
||||
DO i = 1, 3
|
||||
IF (pol_vector(i) /= 0.0_dp .AND. &
|
||||
pol_vector(MODULO(i, 3) + 1) == 0.0_dp .AND. &
|
||||
pol_vector(MODULO(i + 1, 3) + 1) == 0.0_dp) THEN
|
||||
single_pol_index = i
|
||||
EXIT
|
||||
END IF
|
||||
END DO
|
||||
IF (single_pol_index > 0) THEN
|
||||
! Print 3 elements
|
||||
ALLOCATE (rtbse_env%pol_elements(3, 2), source=1)
|
||||
DO i = 1, 3
|
||||
rtbse_env%pol_elements(i, 1) = i
|
||||
rtbse_env%pol_elements(i, 2) = single_pol_index
|
||||
END DO
|
||||
ELSE
|
||||
! More than one non-zero efield component - abort
|
||||
CPABORT("RTBSE : Guess for polarizability elements failed - please specify")
|
||||
END IF
|
||||
ELSE
|
||||
! Pol vector is unknown, but polarizability is requested - abort and request an element
|
||||
CPABORT("RTBSE : Guess for polarizability elements failed - please specify")
|
||||
END IF
|
||||
END IF
|
||||
|
||||
! Get the restart section
|
||||
rtbse_env%restart_section => section_vals_get_subs_vals(input, "DFT%REAL_TIME_PROPAGATION%PRINT%RESTART")
|
||||
|
|
@ -572,6 +624,8 @@ CONTAINS
|
|||
END DO
|
||||
DEALLOCATE (rtbse_env%time_trace%series)
|
||||
|
||||
DEALLOCATE (rtbse_env%pol_elements)
|
||||
|
||||
! Deallocate the neighbour list that is not deallocated in gw anymore
|
||||
IF (ASSOCIATED(rtbse_env%bs_env%nl_3c%ij_list)) CALL neighbor_list_3c_destroy(rtbse_env%bs_env%nl_3c)
|
||||
! Deallocate the storage for the environment itself
|
||||
|
|
|
|||
|
|
@ -89,6 +89,7 @@ MODULE input_cp2k_dft
|
|||
lchar_t,&
|
||||
real_t
|
||||
USE kinds, ONLY: dp
|
||||
USE physcon, ONLY: femtoseconds
|
||||
USE pw_spline_utils, ONLY: no_precond,&
|
||||
precond_spl3_1,&
|
||||
precond_spl3_2,&
|
||||
|
|
@ -1962,22 +1963,6 @@ CONTAINS
|
|||
each_iter_names=s2a("MD"), &
|
||||
each_iter_values=(/1/), &
|
||||
filename="MOMENTS_FT")
|
||||
CALL keyword_create(keyword, __LOCATION__, "DAMPING", &
|
||||
description="Sets the exponential damping of the time trace before carrying out Fourier transform. "// &
|
||||
"For negative values (the default), calculates the damping at the run time so that the last point "// &
|
||||
"in the time trace is reduced by factor e^(-4). Uses atomic units of inverse time.", &
|
||||
type_of_var=real_t, &
|
||||
default_r_val=-1.0_dp)
|
||||
CALL section_add_keyword(print_key, keyword)
|
||||
CALL keyword_release(keyword)
|
||||
CALL keyword_create(keyword, __LOCATION__, "START_TIME", &
|
||||
description="The starting time from which damping is applied and from which on the trace is "// &
|
||||
"considered for the Fourier transform. Useful for real-time pulse - "// &
|
||||
"one can specify the center of the pulse as the starting point.", &
|
||||
type_of_var=real_t, &
|
||||
default_r_val=0.0_dp)
|
||||
CALL section_add_keyword(print_key, keyword)
|
||||
CALL keyword_release(keyword)
|
||||
CALL section_add_subsection(print_section, print_key)
|
||||
CALL section_release(print_key)
|
||||
! Marek : Chosen element of (Fourier transformed) polarizability tensor (energy dependent) - text format
|
||||
|
|
@ -1993,8 +1978,10 @@ CONTAINS
|
|||
filename="POLARIZABILITY")
|
||||
CALL keyword_create(keyword, __LOCATION__, "ELEMENT", &
|
||||
description="Specifies the element of polarizability which is to be printed out "// &
|
||||
"(indexing starts at 1).", &
|
||||
type_of_var=integer_t, default_i_vals=(/1, 1/), n_var=2, usage="ELEMENT 1 1")
|
||||
"(indexing starts at 1). If not explicitly provided, RTBSE code tries to guess "// &
|
||||
"the optimal values - for applied electric field (both delta pulse and RT field) "// &
|
||||
"with only a single non-zero cartesian component, prints the 3 trivially available elements.", &
|
||||
type_of_var=integer_t, default_i_vals=(/1, 1/), n_var=2, usage="ELEMENT 1 1", repeats=.TRUE.)
|
||||
CALL section_add_keyword(print_key, keyword)
|
||||
CALL keyword_release(keyword)
|
||||
CALL section_add_subsection(print_section, print_key)
|
||||
|
|
@ -2067,6 +2054,31 @@ CONTAINS
|
|||
"Use G0W0 Hamiltonian for Green's function propagation"))
|
||||
CALL section_add_keyword(section, keyword)
|
||||
CALL keyword_release(keyword)
|
||||
! Marek : Options for the Fourier transform
|
||||
CALL keyword_create(keyword, __LOCATION__, "FT_DAMPING", &
|
||||
description="Numerical Fourier transform (required for calculation of "// &
|
||||
"MOMENTS_FT and POLARIZABILITY) can oscillate "// &
|
||||
"when the final values are far away from zero. "// &
|
||||
"This keyword controls the exponential damping in the Fourier transform "// &
|
||||
"(Fourier transform is used for calculation of MOMENTS_FT and POLARIZABILITY). "// &
|
||||
"For negative values (the default), calculates the damping at the run time so that the last point "// &
|
||||
"in the time trace is reduced by factor e^(-4). When set manually, determines the time in which "// &
|
||||
"the moments trace is reduced by factor of e^(-1).", &
|
||||
type_of_var=real_t, &
|
||||
unit_str="fs", &
|
||||
default_r_val=-1.0_dp/femtoseconds)
|
||||
CALL section_add_keyword(section, keyword)
|
||||
CALL keyword_release(keyword)
|
||||
CALL keyword_create(keyword, __LOCATION__, "FT_START_TIME", &
|
||||
description="The starting time from which damping is applied and from which on the trace is "// &
|
||||
"considered for the Fourier transform (Fourier transform is used for the calculation of "// &
|
||||
"MOMENTS_FT and POLARIZABILITY). Useful for real-time pulse - "// &
|
||||
"one can specify the center of the pulse as the starting point.", &
|
||||
type_of_var=real_t, &
|
||||
unit_str="fs", &
|
||||
default_r_val=0.0_dp)
|
||||
CALL section_add_keyword(section, keyword)
|
||||
CALL keyword_release(keyword)
|
||||
|
||||
END SUBROUTINE create_rtbse_section
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue