diff --git a/docs/methods/properties/optical/rtbse.md b/docs/methods/properties/optical/rtbse.md index 627debd708..42103ec56c 100644 --- a/docs/methods/properties/optical/rtbse.md +++ b/docs/methods/properties/optical/rtbse.md @@ -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 diff --git a/src/emd/rt_bse_io.F b/src/emd/rt_bse_io.F index 0446f9f5b9..07a1fbf35b 100644 --- a/src/emd/rt_bse_io.F +++ b/src/emd/rt_bse_io.F @@ -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)* & diff --git a/src/emd/rt_bse_types.F b/src/emd/rt_bse_types.F index 30c55a4f49..ef5c74aa2f 100644 --- a/src/emd/rt_bse_types.F +++ b/src/emd/rt_bse_types.F @@ -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 diff --git a/src/input_cp2k_dft.F b/src/input_cp2k_dft.F index 132d4a50ef..9357bfc464 100644 --- a/src/input_cp2k_dft.F +++ b/src/input_cp2k_dft.F @@ -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