LCOV - code coverage report
Current view: top level - src/motion - rt_propagation.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:123285f) Lines: 96.9 % 293 284
Test Date: 2026-11-04 00:58:17 Functions: 100.0 % 8 8

            Line data    Source code
       1              : !--------------------------------------------------------------------------------------------------!
       2              : !   CP2K: A general program to perform molecular dynamics simulations                              !
       3              : !   Copyright 2000-2026 CP2K developers group <https://cp2k.org>                                   !
       4              : !                                                                                                  !
       5              : !   SPDX-License-Identifier: GPL-2.0-or-later                                                      !
       6              : !--------------------------------------------------------------------------------------------------!
       7              : 
       8              : ! **************************************************************************************************
       9              : !> \brief Routines for the real time propagation.
      10              : !> \author Florian Schiffmann (02.09)
      11              : ! **************************************************************************************************
      12              : 
      13              : MODULE rt_propagation
      14              :    USE bibliography,                    ONLY: Andermatt2016,&
      15              :                                               cite_reference
      16              :    USE cell_types,                      ONLY: cell_type
      17              :    USE cp_control_types,                ONLY: dft_control_type,&
      18              :                                               rtp_control_type
      19              :    USE cp_dbcsr_api,                    ONLY: dbcsr_copy,&
      20              :                                               dbcsr_create,&
      21              :                                               dbcsr_p_type,&
      22              :                                               dbcsr_release,&
      23              :                                               dbcsr_set
      24              :    USE cp_external_control,             ONLY: external_control
      25              :    USE cp_fm_types,                     ONLY: cp_fm_set_all,&
      26              :                                               cp_fm_to_fm,&
      27              :                                               cp_fm_type
      28              :    USE cp_log_handling,                 ONLY: cp_get_default_logger,&
      29              :                                               cp_logger_get_default_io_unit,&
      30              :                                               cp_logger_get_default_unit_nr,&
      31              :                                               cp_logger_type,&
      32              :                                               cp_to_string
      33              :    USE cp_output_handling,              ONLY: cp_add_iter_level,&
      34              :                                               cp_iterate,&
      35              :                                               cp_p_file,&
      36              :                                               cp_print_key_generate_filename,&
      37              :                                               cp_print_key_should_output,&
      38              :                                               cp_print_key_unit_nr,&
      39              :                                               cp_rm_iter_level
      40              :    USE efield_utils,                    ONLY: calculate_ecore_efield
      41              :    USE force_env_methods,               ONLY: force_env_calc_energy_force
      42              :    USE force_env_types,                 ONLY: force_env_get,&
      43              :                                               force_env_type
      44              :    USE global_types,                    ONLY: global_environment_type
      45              :    USE hfx_admm_utils,                  ONLY: hfx_admm_init
      46              :    USE input_constants,                 ONLY: do_admm_basis_projection,&
      47              :                                               do_admm_exch_scaling_none,&
      48              :                                               do_admm_purify_none,&
      49              :                                               real_time_propagation,&
      50              :                                               use_restart_wfn,&
      51              :                                               use_rt_restart,&
      52              :                                               use_scf_wfn
      53              :    USE input_cp2k_restarts,             ONLY: write_restart
      54              :    USE input_section_types,             ONLY: section_vals_get,&
      55              :                                               section_vals_get_subs_vals,&
      56              :                                               section_vals_type,&
      57              :                                               section_vals_val_get,&
      58              :                                               section_vals_val_set
      59              :    USE kinds,                           ONLY: default_path_length,&
      60              :                                               dp
      61              :    USE machine,                         ONLY: m_walltime
      62              :    USE md_environment_types,            ONLY: md_environment_type
      63              :    USE moments_utils,                   ONLY: get_reference_point
      64              :    USE pw_env_types,                    ONLY: pw_env_type
      65              :    USE qs_core_hamiltonian,             ONLY: qs_matrix_h_allocate_imag_from_real
      66              :    USE qs_energy_init,                  ONLY: qs_energies_init
      67              :    USE qs_energy_types,                 ONLY: qs_energy_type
      68              :    USE qs_environment_types,            ONLY: get_qs_env,&
      69              :                                               qs_environment_type
      70              :    USE qs_external_potential,           ONLY: external_c_potential,&
      71              :                                               external_e_potential
      72              :    USE qs_ks_methods,                   ONLY: qs_ks_allocate_basics,&
      73              :                                               qs_ks_update_qs_env
      74              :    USE qs_ks_types,                     ONLY: qs_ks_did_change,&
      75              :                                               qs_ks_env_type,&
      76              :                                               set_ks_env
      77              :    USE qs_mo_io,                        ONLY: wfn_restart_file_name
      78              :    USE qs_mo_types,                     ONLY: get_mo_set,&
      79              :                                               init_mo_set,&
      80              :                                               mo_set_type
      81              :    USE qs_moments,                      ONLY: build_local_moment_matrix
      82              :    USE qs_rho_methods,                  ONLY: allocate_rho_ao_imag_from_real
      83              :    USE qs_rho_types,                    ONLY: qs_rho_set,&
      84              :                                               qs_rho_type
      85              :    USE rt_delta_pulse,                  ONLY: apply_delta_pulse
      86              :    USE rt_hfx_utils,                    ONLY: rtp_hfx_rebuild
      87              :    USE rt_projection_mo_utils,          ONLY: init_mo_projection
      88              :    USE rt_propagation_methods,          ONLY: propagation_step,&
      89              :                                               rtp_localize
      90              :    USE rt_propagation_output,           ONLY: calc_local_moment,&
      91              :                                               print_ft,&
      92              :                                               print_moments,&
      93              :                                               rt_prop_output
      94              :    USE rt_propagation_types,            ONLY: get_rtp,&
      95              :                                               rt_prop_create,&
      96              :                                               rt_prop_type,&
      97              :                                               rtp_create_SinvH_imag,&
      98              :                                               rtp_history_create
      99              :    USE rt_propagation_utils,            ONLY: calc_S_derivs,&
     100              :                                               calc_update_rho,&
     101              :                                               calc_update_rho_sparse,&
     102              :                                               get_restart_wfn,&
     103              :                                               read_moments,&
     104              :                                               recalculate_fields,&
     105              :                                               warn_section_unused
     106              :    USE rt_propagation_velocity_gauge,   ONLY: velocity_gauge_ks_matrix
     107              :    USE rt_propagator_init,              ONLY: init_propagators,&
     108              :                                               rt_initialize_rho_from_mos
     109              : #include "../base/base_uses.f90"
     110              : 
     111              :    IMPLICIT NONE
     112              : 
     113              :    PRIVATE
     114              : 
     115              :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'rt_propagation'
     116              : 
     117              :    PUBLIC :: rt_prop_setup
     118              : 
     119              : CONTAINS
     120              : 
     121              : ! **************************************************************************************************
     122              : !> \brief creates rtp_type, gets the initial state, either by reading MO's
     123              : !>        from file or calling SCF run
     124              : !> \param force_env ...
     125              : !> \author Florian Schiffmann (02.09)
     126              : ! **************************************************************************************************
     127              : 
     128         1070 :    SUBROUTINE rt_prop_setup(force_env)
     129              :       TYPE(force_env_type), POINTER                      :: force_env
     130              : 
     131              :       INTEGER                                            :: aspc_order
     132              :       LOGICAL                                            :: magnetic, track_current, &
     133              :                                                             track_current_int, vel_reprs
     134              :       TYPE(dft_control_type), POINTER                    :: dft_control
     135              :       TYPE(global_environment_type), POINTER             :: globenv
     136              :       TYPE(qs_energy_type), POINTER                      :: energy
     137              :       TYPE(qs_environment_type), POINTER                 :: qs_env
     138              :       TYPE(rt_prop_type), POINTER                        :: rtp
     139              :       TYPE(rtp_control_type), POINTER                    :: rtp_control
     140              :       TYPE(section_vals_type), POINTER :: current_int_section, current_section, hfx_sections, &
     141              :          input, ls_scf_section, md_section, motion_section, print_moments_section, &
     142              :          rtp_print_section, rtp_section
     143              : 
     144          214 :       NULLIFY (qs_env, rtp_control, dft_control)
     145              : 
     146          214 :       CALL cite_reference(Andermatt2016)
     147              : 
     148          214 :       CALL force_env_get(force_env=force_env, qs_env=qs_env, globenv=globenv)
     149          214 :       CALL get_qs_env(qs_env, dft_control=dft_control, energy=energy)
     150          214 :       rtp_control => dft_control%rtp_control
     151              : 
     152              :       ! The RTP/EMD ADMM implementation (density fit, KS merge and forces) only supports
     153              :       ! basis projection without purification and without exchange scaling
     154          214 :       IF (dft_control%do_admm) THEN
     155           12 :          IF (dft_control%admm_control%purification_method /= do_admm_purify_none) THEN
     156              :             CALL cp_abort(__LOCATION__, "RTP/EMD with ADMM requires ADMM_PURIFICATION_METHOD NONE "// &
     157            0 :                           "(the default is MO_DIAG). Use e.g. ADMM_TYPE ADMM2.")
     158              :          END IF
     159           12 :          IF (dft_control%admm_control%method /= do_admm_basis_projection) THEN
     160              :             CALL cp_abort(__LOCATION__, "RTP/EMD with ADMM requires METHOD BASIS_PROJECTION. "// &
     161            0 :                           "ADMMQ and ADMMS are not implemented for RTP/EMD.")
     162              :          END IF
     163           12 :          IF (dft_control%admm_control%scaling_model /= do_admm_exch_scaling_none) THEN
     164              :             CALL cp_abort(__LOCATION__, "RTP/EMD with ADMM requires EXCH_SCALING_MODEL NONE. "// &
     165            0 :                           "ADMMP and ADMMS are not implemented for RTP/EMD.")
     166              :          END IF
     167              :       END IF
     168              : 
     169              :       ! Takes care that an initial wavefunction/density is available
     170              :       ! Can either be by performing an scf loop or reading a restart
     171          214 :       CALL rt_initial_guess(qs_env, force_env, rtp_control)
     172              : 
     173              :       ! Initializes the extrapolation
     174          214 :       NULLIFY (rtp)
     175          214 :       CALL get_qs_env(qs_env=qs_env, rtp=rtp, input=input)
     176          214 :       aspc_order = rtp_control%aspc_order
     177          214 :       CALL rtp_history_create(rtp, aspc_order)
     178              : 
     179              :       ! Reads the simulation parameters from the input
     180          214 :       motion_section => section_vals_get_subs_vals(force_env%root_section, "MOTION")
     181          214 :       md_section => section_vals_get_subs_vals(motion_section, "MD")
     182          214 :       hfx_sections => section_vals_get_subs_vals(force_env%root_section, "FORCE_EVAL%DFT%XC%HF")
     183          214 :       rtp_section => section_vals_get_subs_vals(force_env%root_section, "FORCE_EVAL%DFT%REAL_TIME_PROPAGATION")
     184          214 :       print_moments_section => section_vals_get_subs_vals(force_env%root_section, "FORCE_EVAL%DFT%PRINT%MOMENTS")
     185          214 :       CALL section_vals_val_get(md_section, "TIMESTEP", r_val=qs_env%rtp%dt)
     186          214 :       CALL section_vals_val_get(md_section, "STEP_START_VAL", i_val=qs_env%rtp%i_start)
     187          214 :       CALL section_vals_val_get(md_section, "STEPS", i_val=rtp%nsteps)
     188          214 :       CALL section_vals_val_get(md_section, "MAX_STEPS", i_val=rtp%max_steps)
     189              : 
     190          214 :       ls_scf_section => section_vals_get_subs_vals(input, "DFT%LS_SCF")
     191          214 :       CALL section_vals_val_get(ls_scf_section, "EPS_FILTER", r_val=rtp%filter_eps)
     192          214 :       IF (.NOT. qs_env%rtp%linear_scaling) rtp%filter_eps = 0.0_dp
     193          214 :       IF (rtp_control%acc_ref < 1) rtp_control%acc_ref = 1
     194          214 :       rtp%filter_eps_small = rtp%filter_eps/rtp_control%acc_ref
     195          214 :       CALL section_vals_val_get(ls_scf_section, "EPS_LANCZOS", r_val=rtp%lanzcos_threshold)
     196          214 :       CALL section_vals_val_get(ls_scf_section, "MAX_ITER_LANCZOS", i_val=rtp%lanzcos_max_iter)
     197          214 :       CALL section_vals_val_get(ls_scf_section, "SIGN_SQRT_ORDER", i_val=rtp%newton_schulz_order)
     198          214 :       CALL section_vals_get(hfx_sections, explicit=rtp%do_hfx)
     199          214 :       CALL section_vals_val_get(print_moments_section, "MAGNETIC", l_val=magnetic)
     200          214 :       CALL section_vals_val_get(print_moments_section, "VEL_REPRS", l_val=vel_reprs)
     201              : 
     202              :       ! The imaginary part of the density matrix (needed for the current) is generically
     203              :       ! nonzero whenever the propagated state is not stationary, independently of whether
     204              :       ! an explicit time-dependent field/vector potential is applied: e.g. an excited
     205              :       ! state prepared by occupation swap, from LR-TDDFT, or via a MOM-constrained SCF.
     206              :       ! Rather than trying to detect every possible way of preparing such a state, track
     207              :       ! the imaginary density whenever the user actually requests output that needs it.
     208          214 :       rtp_print_section => section_vals_get_subs_vals(rtp_section, "PRINT")
     209          214 :       current_section => section_vals_get_subs_vals(rtp_print_section, "CURRENT")
     210          214 :       current_int_section => section_vals_get_subs_vals(rtp_print_section, "CURRENT_INT")
     211          214 :       CALL section_vals_get(current_section, explicit=track_current)
     212          214 :       CALL section_vals_get(current_int_section, explicit=track_current_int)
     213              : 
     214              :       rtp%track_imag_density = (magnetic) .OR. (vel_reprs) .OR. (rtp_control%velocity_gauge) &
     215              :                                .OR. (rtp%do_hfx) .OR. (.NOT. rtp_control%fixed_ions) &
     216          214 :                                .OR. (track_current) .OR. (track_current_int)
     217          214 :       rtp%propagate_complex_ks = rtp%do_hfx .OR. rtp_control%velocity_gauge
     218              : 
     219              :       ! Marek : In case some print sections that apply so far only to RTBSE are present,
     220              :       !         warn the user that the quantities will not be in fact printed out
     221              :       CALL warn_section_unused(rtp_print_section, "DENSITY_MATRIX", &
     222          214 :                                "DENSITY_MATRIX printing not implemented for non-RTBSE code.")
     223              : 
     224              :       CALL rt_init_complex_quantities(qs_env, imag_p=rtp%track_imag_density, &
     225          214 :                                       imag_ks=rtp%propagate_complex_ks, imag_h=rtp_control%velocity_gauge)
     226              : 
     227          214 :       IF (rtp_control%save_local_moments) CALL rt_init_local_moments(rtp, qs_env)
     228              : 
     229              :       ! Hmm, not really like to initialize with the structure of S but I reckon it is
     230              :       ! done everywhere like this
     231          214 :       IF (rtp%do_hfx) CALL rtp_hfx_rebuild(qs_env)
     232              : 
     233              :       ! Setup the MO projection environment if required
     234          214 :       IF (rtp_control%is_proj_mo) CALL init_mo_projection(qs_env, rtp_control)
     235              : 
     236          214 :       CALL init_propagation_run(qs_env)
     237          214 :       IF (.NOT. rtp_control%fixed_ions) THEN
     238              :          !derivativs of the overlap needed for EMD
     239           76 :          CALL calc_S_derivs(qs_env)
     240              :          ! a bit hidden, but computes SinvH and SinvB (calc_SinvH for CN,EM and ARNOLDI)
     241              :          ! make_etrs_exp in case of ETRS in combination with TAYLOR and PADE
     242              :       END IF
     243          214 :       CALL init_propagators(qs_env)
     244          214 :       IF (rtp_control%fixed_ions) THEN
     245          138 :          CALL run_propagation(qs_env, force_env, globenv)
     246              :       ELSE
     247           76 :          rtp_control%initial_step = .TRUE.
     248           76 :          CALL force_env_calc_energy_force(force_env, calc_force=.TRUE.)
     249           76 :          rtp_control%initial_step = .FALSE.
     250           76 :          rtp%energy_old = energy%total
     251              :       END IF
     252              : 
     253          214 :       IF (rtp_control%save_local_moments) THEN
     254              :          ! Call routines for outputs and deallocations of FT observables
     255           18 :          CALL final_ft_output(qs_env)
     256              :       END IF
     257              : 
     258          214 :       IF (ASSOCIATED(rtp_control%print_pol_elements)) DEALLOCATE (rtp_control%print_pol_elements)
     259              : 
     260          214 :    END SUBROUTINE rt_prop_setup
     261              : 
     262              : ! **************************************************************************************************
     263              : !> \brief calculates the matrices needed in the first step of EMD/RTP
     264              : !> \param qs_env ...
     265              : !> \author Florian Schiffmann (02.09)
     266              : ! **************************************************************************************************
     267              : 
     268          214 :    SUBROUTINE init_propagation_run(qs_env)
     269              :       TYPE(qs_environment_type), POINTER                 :: qs_env
     270              : 
     271              :       REAL(KIND=dp), PARAMETER                           :: zero = 0.0_dp
     272              : 
     273              :       INTEGER                                            :: i, ispin, re
     274              :       INTEGER, DIMENSION(2)                              :: nelectron_spin
     275          214 :       TYPE(cp_fm_type), DIMENSION(:), POINTER            :: mos_new, mos_old
     276          214 :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: matrix_ks, rho_new, rho_old
     277              :       TYPE(dft_control_type), POINTER                    :: dft_control
     278          214 :       TYPE(mo_set_type), DIMENSION(:), POINTER           :: mos
     279              :       TYPE(rt_prop_type), POINTER                        :: rtp
     280              :       TYPE(rtp_control_type), POINTER                    :: rtp_control
     281              : 
     282          214 :       NULLIFY (dft_control, rtp, rtp_control)
     283              : 
     284          214 :       CALL cite_reference(Andermatt2016)
     285              : 
     286              :       CALL get_qs_env(qs_env, &
     287              :                       rtp=rtp, &
     288          214 :                       dft_control=dft_control)
     289          214 :       rtp_control => dft_control%rtp_control
     290              : 
     291          214 :       IF (rtp_control%initial_wfn == use_scf_wfn) THEN
     292          178 :          IF (rtp_control%apply_delta_pulse .OR. rtp_control%apply_delta_pulse_mag) THEN
     293           60 :             CALL apply_delta_pulse(qs_env, rtp, rtp_control)
     294              :          ELSE
     295          118 :             IF (.NOT. rtp%linear_scaling) THEN
     296           82 :                CALL get_rtp(rtp=rtp, mos_old=mos_old)
     297           82 :                CALL get_qs_env(qs_env, mos=mos)
     298          182 :                DO i = 1, SIZE(mos)
     299          100 :                   CALL cp_fm_to_fm(mos(i)%mo_coeff, mos_old(2*i - 1))
     300          182 :                   CALL cp_fm_set_all(mos_old(2*i), zero, zero)
     301              :                END DO
     302              :             END IF
     303              :          END IF
     304              :       END IF
     305              : 
     306          214 :       IF (.NOT. rtp%linear_scaling) THEN
     307          122 :          CALL get_rtp(rtp=rtp, mos_old=mos_old, mos_new=mos_new)
     308          434 :          DO i = 1, SIZE(mos_old)
     309          434 :             CALL cp_fm_to_fm(mos_old(i), mos_new(i))
     310              :          END DO
     311          122 :          CALL calc_update_rho(qs_env)
     312              :       ELSE
     313           92 :          IF (rtp_control%initial_wfn == use_scf_wfn) THEN
     314              :             CALL get_qs_env(qs_env, &
     315              :                             matrix_ks=matrix_ks, &
     316              :                             mos=mos, &
     317           76 :                             nelectron_spin=nelectron_spin)
     318           76 :             IF (ASSOCIATED(mos)) THEN
     319              :                !The wavefunction was minimized by an mo based algorith. P is therefore calculated from the mos
     320           66 :                IF (ASSOCIATED(rtp%mos)) THEN
     321           40 :                   IF (ASSOCIATED(rtp%mos%old)) THEN
     322              :                      ! Delta kick was applied and the results is in rtp%mos%old
     323           40 :                      CALL rt_initialize_rho_from_mos(rtp, mos, mos_old=rtp%mos%old)
     324              :                   ELSE
     325            0 :                      CALL rt_initialize_rho_from_mos(rtp, mos)
     326              :                   END IF
     327              :                ELSE
     328           26 :                   CALL rt_initialize_rho_from_mos(rtp, mos)
     329              :                END IF
     330              :             ELSE
     331              :                ! The wavefunction was minimized using a linear scaling method.
     332              :                ! The density matrix is therefore taken from the ls_scf_env.
     333           10 :                CALL get_rtp(rtp=rtp, rho_old=rho_old, rho_new=rho_new)
     334           24 :                DO ispin = 1, SIZE(rho_old)/2
     335           14 :                   re = 2*ispin - 1
     336           14 :                   CALL dbcsr_copy(rho_old(re)%matrix, qs_env%ls_scf_env%matrix_p(ispin))
     337           24 :                   CALL dbcsr_copy(rho_new(re)%matrix, qs_env%ls_scf_env%matrix_p(ispin))
     338              :                END DO
     339              :             END IF
     340           76 :             CALL calc_update_rho_sparse(qs_env)
     341              :          END IF
     342              :       END IF
     343              :       ! Modify KS matrix to include the additional terms in the velocity gauge
     344          214 :       IF (rtp_control%velocity_gauge) THEN
     345              :          ! As matrix_h and matrix_h_im are not updated by qs_ks_update_qs_env()
     346              :          ! the non-gauge transformed non-local part has to be subtracted here
     347           12 :          CALL velocity_gauge_ks_matrix(qs_env, subtract_nl_term=.TRUE.)
     348              :       END IF
     349          214 :       CALL qs_ks_update_qs_env(qs_env, calculate_forces=.FALSE.)
     350              : 
     351          214 :    END SUBROUTINE init_propagation_run
     352              : 
     353              : ! **************************************************************************************************
     354              : !> \brief performs the real RTP run, gets information from MD section
     355              : !>        uses MD as iteration level
     356              : !> \param qs_env ...
     357              : !> \param force_env ...
     358              : !> \param globenv ...
     359              : !> \author Florian Schiffmann (02.09)
     360              : ! **************************************************************************************************
     361              : 
     362          138 :    SUBROUTINE run_propagation(qs_env, force_env, globenv)
     363              :       TYPE(qs_environment_type), POINTER                 :: qs_env
     364              :       TYPE(force_env_type), POINTER                      :: force_env
     365              :       TYPE(global_environment_type), POINTER             :: globenv
     366              : 
     367              :       CHARACTER(len=*), PARAMETER                        :: routineN = 'run_propagation'
     368              : 
     369              :       INTEGER                                            :: aspc_order, handle, i_iter, i_step, &
     370              :                                                             max_iter, max_steps, output_unit, &
     371              :                                                             unit_nr
     372              :       LOGICAL                                            :: moments_read, should_stop
     373              :       REAL(Kind=dp)                                      :: eps_ener, time_iter_start, &
     374              :                                                             time_iter_stop, used_time
     375              :       TYPE(cp_logger_type), POINTER                      :: logger
     376          138 :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: rho_new
     377              :       TYPE(dft_control_type), POINTER                    :: dft_control
     378              :       TYPE(pw_env_type), POINTER                         :: pw_env
     379              :       TYPE(qs_energy_type), POINTER                      :: energy
     380              :       TYPE(rt_prop_type), POINTER                        :: rtp
     381              :       TYPE(rtp_control_type), POINTER                    :: rtp_control
     382              :       TYPE(section_vals_type), POINTER                   :: input, moments_section, rtp_section
     383              : 
     384          138 :       should_stop = .FALSE.
     385          138 :       CALL timeset(routineN, handle)
     386              : 
     387          138 :       CALL cite_reference(Andermatt2016)
     388              : 
     389          138 :       NULLIFY (logger, dft_control, energy, rtp, rtp_control, input, rtp_section)
     390          138 :       logger => cp_get_default_logger()
     391          138 :       IF (logger%para_env%is_source()) THEN
     392           69 :          unit_nr = cp_logger_get_default_unit_nr(logger, local=.TRUE.)
     393              :       ELSE
     394              :          unit_nr = -1
     395              :       END IF
     396              : 
     397          138 :       CALL get_qs_env(qs_env=qs_env, dft_control=dft_control, rtp=rtp, energy=energy, input=input)
     398              : 
     399          138 :       rtp_control => dft_control%rtp_control
     400          138 :       max_steps = MIN(rtp%nsteps, rtp%max_steps)
     401          138 :       max_iter = rtp_control%max_iter
     402          138 :       eps_ener = rtp_control%eps_ener
     403              : 
     404          138 :       aspc_order = rtp_control%aspc_order
     405              : 
     406          138 :       rtp%energy_old = energy%total
     407          138 :       time_iter_start = m_walltime()
     408          138 :       CALL cp_add_iter_level(logger, "MD")
     409          138 :       CALL cp_iterate(logger%iter_info, iter_nr=0)
     410          138 :       IF (rtp%i_start >= max_steps) CALL cp_abort(__LOCATION__, &
     411            0 :                                                   "maximum step number smaller than initial step value")
     412              : 
     413          138 :       rtp_section => section_vals_get_subs_vals(input, "DFT%REAL_TIME_PROPAGATION")
     414              :       output_unit = cp_print_key_unit_nr(logger, rtp_section, "PRINT%PROGRAM_RUN_INFO", &
     415          138 :                                          extension=".scfLog")
     416              :       ! Add the zero iteration moments to the moment trace
     417          138 :       IF (rtp_control%save_local_moments) THEN
     418           18 :          CALL get_rtp(rtp, rho_new=rho_new)
     419           18 :          moments_section => section_vals_get_subs_vals(rtp_section, "PRINT%MOMENTS")
     420              :          ! TODO : Conditions on when not to read the files
     421           18 :          CALL read_moments(moments_section, 0, rtp%i_start, rtp%moments, rtp%times, moments_read)
     422              :          ! Recalculate the field at times in the trace/Read the field from the files
     423           18 :          CALL recalculate_fields(rtp%fields, rtp%times, 0, rtp%i_start, dft_control)
     424           18 :          IF (.NOT. moments_read) THEN
     425           18 :             CALL calc_local_moment(rtp%local_moments, rho_new, rtp%local_moments_work, rtp%moments(:, :, 1))
     426           18 :             qs_env%sim_time = REAL(rtp%i_start, dp)*rtp%dt
     427           18 :             rtp%times(1) = qs_env%sim_time
     428              :             CALL print_moments(moments_section, output_unit, rtp%moments(:, :, 1), &
     429           18 :                                qs_env%sim_time, rtp%track_imag_density)
     430              :          END IF
     431              :       END IF
     432              : 
     433          514 :       DO i_step = rtp%i_start + 1, max_steps
     434          376 :          IF (output_unit > 0) THEN
     435              :             WRITE (output_unit, FMT="(/,(T2,A,T40,I6))") &
     436          188 :                "Real time propagation step:", i_step
     437              :          END IF
     438          376 :          energy%efield_core = 0.0_dp
     439          376 :          qs_env%sim_time = REAL(i_step, dp)*rtp%dt
     440          376 :          CALL get_qs_env(qs_env, pw_env=pw_env)
     441          376 :          pw_env%poisson_env%parameters%dbc_params%time = qs_env%sim_time
     442          376 :          qs_env%sim_step = i_step
     443          376 :          rtp%istep = i_step - rtp%i_start
     444          376 :          CALL calculate_ecore_efield(qs_env, .FALSE.)
     445          376 :          IF (dft_control%apply_external_potential) THEN
     446            0 :             IF (.NOT. dft_control%expot_control%static) THEN
     447            0 :                dft_control%eval_external_potential = .TRUE.
     448              :             END IF
     449              :          END IF
     450          376 :          CALL external_c_potential(qs_env, calculate_forces=.FALSE.)
     451          376 :          CALL external_e_potential(qs_env)
     452          376 :          CALL cp_iterate(logger%iter_info, last=(i_step == max_steps), iter_nr=i_step)
     453          376 :          rtp%converged = .FALSE.
     454         1256 :          DO i_iter = 1, max_iter
     455         1256 :             IF (i_step == rtp%i_start + 1 .AND. i_iter == 2 .AND. rtp_control%hfx_redistribute) THEN
     456            0 :                CALL qs_ks_did_change(qs_env%ks_env, s_mstruct_changed=.TRUE.)
     457              :             END IF
     458         1256 :             rtp%iter = i_iter
     459         1256 :             CALL propagation_step(qs_env, rtp, rtp_control)
     460         1256 :             CALL qs_ks_update_qs_env(qs_env, calculate_forces=.FALSE.)
     461         1256 :             rtp%energy_new = energy%total
     462         1256 :             IF (rtp%converged) EXIT
     463         1256 :             CALL rt_prop_output(qs_env, real_time_propagation, rtp%delta_iter)
     464              :          END DO
     465          514 :          IF (rtp%converged) THEN
     466          376 :             CALL external_control(should_stop, "MD", globenv=globenv)
     467          376 :             IF (should_stop) CALL cp_iterate(logger%iter_info, last=.TRUE., iter_nr=i_step)
     468          376 :             time_iter_stop = m_walltime()
     469          376 :             used_time = time_iter_stop - time_iter_start
     470          376 :             time_iter_start = time_iter_stop
     471          376 :             CALL rt_prop_output(qs_env, real_time_propagation, delta_iter=rtp%delta_iter, used_time=used_time)
     472          376 :             CALL rt_write_input_restart(force_env=force_env, qs_env=qs_env)
     473          376 :             IF (MODULO(i_step, dft_control%localize_each) == 0) THEN
     474          376 :                CALL rtp_localize(qs_env, rtp)
     475              :             END IF
     476          376 :             IF (should_stop) EXIT
     477              :          ELSE
     478              :             EXIT
     479              :          END IF
     480              :       END DO
     481          138 :       CALL cp_rm_iter_level(logger, "MD")
     482              : 
     483          138 :       IF (.NOT. rtp%converged) THEN
     484              :          CALL cp_abort(__LOCATION__, "propagation did not converge, "// &
     485            0 :                        "either increase MAX_ITER or use a smaller TIMESTEP")
     486              :       END IF
     487              : 
     488          138 :       CALL timestop(handle)
     489              : 
     490          138 :    END SUBROUTINE run_propagation
     491              : 
     492              : ! **************************************************************************************************
     493              : !> \brief overwrites some values in the input file such that the .restart
     494              : !>        file will contain the appropriate information
     495              : !> \param md_env ...
     496              : !> \param qs_env ...
     497              : !> \param force_env ...
     498              : !> \author Florian Schiffmann (02.09)
     499              : ! **************************************************************************************************
     500              : 
     501          376 :    SUBROUTINE rt_write_input_restart(md_env, qs_env, force_env)
     502              :       TYPE(md_environment_type), OPTIONAL, POINTER       :: md_env
     503              :       TYPE(qs_environment_type), OPTIONAL, POINTER       :: qs_env
     504              :       TYPE(force_env_type), POINTER                      :: force_env
     505              : 
     506              :       CHARACTER(len=default_path_length)                 :: file_name
     507          376 :       REAL(KIND=dp), DIMENSION(:), POINTER               :: tmp_vals
     508              :       TYPE(cp_logger_type), POINTER                      :: logger
     509              :       TYPE(dft_control_type), POINTER                    :: dft_control
     510              :       TYPE(section_vals_type), POINTER                   :: dft_section, efield_section, &
     511              :                                                             motion_section, print_key, &
     512              :                                                             root_section, rt_section
     513              : 
     514          376 :       CALL get_qs_env(qs_env=qs_env, dft_control=dft_control)
     515          376 :       root_section => force_env%root_section
     516          376 :       motion_section => section_vals_get_subs_vals(root_section, "MOTION")
     517          376 :       dft_section => section_vals_get_subs_vals(root_section, "FORCE_EVAL%DFT")
     518          376 :       rt_section => section_vals_get_subs_vals(root_section, "FORCE_EVAL%DFT%REAL_TIME_PROPAGATION")
     519              : 
     520          376 :       CALL section_vals_val_set(rt_section, "INITIAL_WFN", i_val=use_rt_restart)
     521          376 :       CALL section_vals_val_set(rt_section, "APPLY_DELTA_PULSE", l_val=.FALSE.)
     522          376 :       CALL section_vals_val_set(rt_section, "APPLY_DELTA_PULSE_MAG", l_val=.FALSE.)
     523          376 :       CALL section_vals_val_set(rt_section, "APPLY_WFN_MIX_INIT_RESTART", l_val=.FALSE.)
     524              : 
     525          376 :       logger => cp_get_default_logger()
     526              : 
     527              :       ! to continue propagating the TD wavefunction we need to read from the new .rtpwfn
     528          376 :       IF (BTEST(cp_print_key_should_output(logger%iter_info, &
     529              :                                            rt_section, "PRINT%RESTART"), cp_p_file)) THEN
     530          138 :          print_key => section_vals_get_subs_vals(rt_section, "PRINT%RESTART")
     531              :          file_name = cp_print_key_generate_filename(logger, print_key, &
     532          138 :                                                     extension=".rtpwfn", my_local=.FALSE.)
     533          138 :          CALL section_vals_val_set(dft_section, "WFN_RESTART_FILE_NAME", c_val=TRIM(file_name))
     534              :       END IF
     535              : 
     536              :       ! coming from RTP
     537          376 :       IF (.NOT. PRESENT(md_env)) THEN
     538          376 :          CALL section_vals_val_set(motion_section, "MD%STEP_START_VAL", i_val=force_env%qs_env%sim_step)
     539              :       END IF
     540              : 
     541          376 :       IF (dft_control%apply_vector_potential) THEN
     542           26 :          efield_section => section_vals_get_subs_vals(root_section, "FORCE_EVAL%DFT%EFIELD")
     543              :          NULLIFY (tmp_vals)
     544           26 :          ALLOCATE (tmp_vals(3))
     545          104 :          tmp_vals = dft_control%efield_fields(1)%efield%vec_pot_initial
     546              :          CALL section_vals_val_set(efield_section, "VEC_POT_INITIAL", &
     547              :                                    r_vals_ptr=tmp_vals, &
     548           26 :                                    i_rep_section=1)
     549              :       END IF
     550              : 
     551          376 :       CALL write_restart(md_env=md_env, root_section=root_section)
     552              : 
     553          376 :    END SUBROUTINE rt_write_input_restart
     554              : 
     555              : ! **************************************************************************************************
     556              : !> \brief Creates the initial electronic states and allocates the necessary
     557              : !>        matrices
     558              : !> \param qs_env ...
     559              : !> \param force_env ...
     560              : !> \param rtp_control ...
     561              : !> \author Florian Schiffmann (02.09)
     562              : ! **************************************************************************************************
     563              : 
     564          214 :    SUBROUTINE rt_initial_guess(qs_env, force_env, rtp_control)
     565              :       TYPE(qs_environment_type), POINTER                 :: qs_env
     566              :       TYPE(force_env_type), POINTER                      :: force_env
     567              :       TYPE(rtp_control_type), POINTER                    :: rtp_control
     568              : 
     569              :       INTEGER                                            :: homo, ispin
     570              :       LOGICAL                                            :: energy_consistency
     571              :       TYPE(cp_fm_type), POINTER                          :: mo_coeff
     572          214 :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: matrix_s
     573              :       TYPE(dft_control_type), POINTER                    :: dft_control
     574              : 
     575          214 :       NULLIFY (matrix_s, dft_control)
     576          214 :       CALL get_qs_env(qs_env, dft_control=dft_control)
     577          214 :       CPASSERT(ASSOCIATED(qs_env))
     578              : 
     579          392 :       SELECT CASE (rtp_control%initial_wfn)
     580              :       CASE (use_scf_wfn)
     581          178 :          qs_env%sim_time = 0.0_dp
     582          178 :          qs_env%sim_step = 0
     583          178 :          energy_consistency = .TRUE.
     584              :          !in the linear scaling case we need a correct kohn-sham matrix, which we cannot get with consistent energies
     585          178 :          IF (rtp_control%linear_scaling) energy_consistency = .FALSE.
     586              :          CALL force_env_calc_energy_force(force_env, calc_force=.FALSE., &
     587          178 :                                           consistent_energies=energy_consistency)
     588          178 :          qs_env%run_rtp = .TRUE.
     589          178 :          ALLOCATE (qs_env%rtp)
     590          178 :          CALL get_qs_env(qs_env, matrix_s=matrix_s)
     591          178 :          IF (dft_control%do_admm) THEN
     592           10 :             CALL hfx_admm_init(qs_env)
     593              :             CALL rt_prop_create(qs_env%rtp, qs_env%mos, qs_env%mpools, dft_control, matrix_s(1)%matrix, &
     594           10 :                                 rtp_control%linear_scaling, qs_env%admm_env%mos_aux_fit)
     595              :          ELSE
     596              :             CALL rt_prop_create(qs_env%rtp, qs_env%mos, qs_env%mpools, dft_control, matrix_s(1)%matrix, &
     597          168 :                                 rtp_control%linear_scaling)
     598              :          END IF
     599              : 
     600              :       CASE (use_restart_wfn, use_rt_restart)
     601           36 :          CALL qs_energies_init(qs_env, .FALSE.)
     602           36 :          IF (.NOT. rtp_control%linear_scaling .OR. rtp_control%initial_wfn == use_restart_wfn) THEN
     603           86 :             DO ispin = 1, SIZE(qs_env%mos)
     604           52 :                CALL get_mo_set(qs_env%mos(ispin), mo_coeff=mo_coeff, homo=homo)
     605           86 :                IF (.NOT. ASSOCIATED(mo_coeff)) THEN
     606              :                   CALL init_mo_set(qs_env%mos(ispin), &
     607              :                                    qs_env%mpools%ao_mo_fm_pools(ispin)%pool, &
     608           52 :                                    name="qs_env%mo"//TRIM(ADJUSTL(cp_to_string(ispin))))
     609              :                END IF
     610              :             END DO
     611           34 :             IF (dft_control%do_admm) CALL hfx_admm_init(qs_env)
     612              :          END IF
     613           36 :          ALLOCATE (qs_env%rtp)
     614           36 :          CALL get_qs_env(qs_env, matrix_s=matrix_s)
     615              :          CALL rt_prop_create(qs_env%rtp, qs_env%mos, qs_env%mpools, dft_control, matrix_s(1)%matrix, &
     616           36 :                              rtp_control%linear_scaling, qs_env%admm_env%mos_aux_fit)
     617           36 :          CALL get_restart_wfn(qs_env)
     618           36 :          CPASSERT(ASSOCIATED(qs_env))
     619              : 
     620          250 :          qs_env%run_rtp = .TRUE.
     621              :       END SELECT
     622              : 
     623          214 :    END SUBROUTINE rt_initial_guess
     624              : 
     625              : ! **************************************************************************************************
     626              : !> \brief ...
     627              : !> \param qs_env ...
     628              : !> \param imag_p ...
     629              : !> \param imag_ks ...
     630              : !> \param imag_h ...
     631              : ! **************************************************************************************************
     632          214 :    SUBROUTINE rt_init_complex_quantities(qs_env, imag_p, imag_ks, imag_h)
     633              :       TYPE(qs_environment_type), POINTER                 :: qs_env
     634              :       LOGICAL, INTENT(in)                                :: imag_p, imag_ks, imag_h
     635              : 
     636              :       TYPE(dft_control_type), POINTER                    :: dft_control
     637              :       TYPE(qs_ks_env_type), POINTER                      :: ks_env
     638              :       TYPE(qs_rho_type), POINTER                         :: rho
     639              :       TYPE(rt_prop_type), POINTER                        :: rtp
     640              : 
     641          214 :       NULLIFY (ks_env, rho, dft_control)
     642              : 
     643              :       CALL get_qs_env(qs_env, &
     644              :                       dft_control=dft_control, &
     645              :                       ks_env=ks_env, &
     646              :                       rho=rho, &
     647          214 :                       rtp=rtp)
     648              : 
     649              :       ! rho
     650          214 :       CALL qs_rho_set(rho, complex_rho_ao=imag_p)
     651          214 :       IF (imag_p) CALL allocate_rho_ao_imag_from_real(rho, qs_env)
     652              : 
     653              :       ! ks
     654          214 :       CALL set_ks_env(ks_env, complex_ks=imag_ks)
     655          214 :       IF (imag_ks) THEN
     656           50 :          CALL qs_ks_allocate_basics(qs_env, is_complex=imag_ks)
     657           50 :          IF (.NOT. dft_control%rtp_control%fixed_ions) THEN
     658           26 :             CALL rtp_create_SinvH_imag(rtp, dft_control%nspins)
     659              :          END IF
     660              :       END IF
     661              : 
     662              :       ! h
     663          214 :       IF (imag_h) CALL qs_matrix_h_allocate_imag_from_real(qs_env)
     664              : 
     665          214 :    END SUBROUTINE rt_init_complex_quantities
     666              : 
     667              : ! **************************************************************************************************
     668              : !> \brief Allocates and fills the local moment matrices (only available for linear scaling)
     669              : !> \param rtp Real time propagtion properties - local moment matrices are stored there
     670              : !> \param qs_env QS environment necessary for moment matrix calculation
     671              : ! **************************************************************************************************
     672           18 :    SUBROUTINE rt_init_local_moments(rtp, qs_env)
     673              :       TYPE(rt_prop_type), POINTER                        :: rtp
     674              :       TYPE(qs_environment_type), POINTER                 :: qs_env
     675              : 
     676              :       INTEGER                                            :: k, nspin, output_unit
     677              :       REAL(kind=dp), DIMENSION(3)                        :: reference_point
     678              :       TYPE(cp_logger_type), POINTER                      :: logger
     679           18 :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: matrix_s, rho_old
     680              :       TYPE(dft_control_type), POINTER                    :: dft_control
     681              :       TYPE(rtp_control_type), POINTER                    :: rtc
     682              :       TYPE(section_vals_type), POINTER                   :: input, moments_section
     683              : 
     684           36 :       logger => cp_get_default_logger()
     685           18 :       output_unit = cp_logger_get_default_io_unit(logger)
     686              : 
     687           18 :       CALL get_qs_env(qs_env, dft_control=dft_control, matrix_s=matrix_s, input=input)
     688           18 :       rtc => dft_control%rtp_control
     689              :       moments_section => section_vals_get_subs_vals(input, &
     690           18 :                                                     "DFT%REAL_TIME_PROPAGATION%PRINT%MOMENTS")
     691              : 
     692              :       ! Construct the local moments matrix - copy from matrix_s structure
     693              :       ! NOTE : construction where blocks are allocated by neighbour lists does not seem to work,
     694              :       ! so doing a copy instead of:
     695              :       !    CALL dbcsr_create(rtp%local_moments(k)%matrix, template=matrix_s(1)%matrix, &
     696              :       !       name="Local moment")
     697              :       !    CALL cp_dbcsr_alloc_block_from_nbl(rtp%local_moments(k)%matrix, sab_all)
     698           18 :       NULLIFY (rtp%local_moments)
     699           72 :       ALLOCATE (rtp%local_moments(3))
     700           72 :       DO k = 1, 3
     701           54 :          NULLIFY (rtp%local_moments(k)%matrix)
     702           54 :          ALLOCATE (rtp%local_moments(k)%matrix)
     703           54 :          CALL dbcsr_create(rtp%local_moments(k)%matrix, template=matrix_s(1)%matrix, name="Local moment")
     704           54 :          CALL dbcsr_copy(rtp%local_moments(k)%matrix, matrix_s(1)%matrix)
     705           72 :          CALL dbcsr_set(rtp%local_moments(k)%matrix, 0.0_dp)
     706              :       END DO
     707              :       ! Workspace allocation
     708           18 :       NULLIFY (rtp%local_moments_work)
     709           18 :       ALLOCATE (rtp%local_moments_work)
     710           18 :       CALL dbcsr_create(rtp%local_moments_work, template=rtp%local_moments(1)%matrix, name="tmp")
     711           18 :       CALL dbcsr_copy(rtp%local_moments_work, rtp%local_moments(1)%matrix)
     712              : 
     713              :       CALL get_reference_point(rpoint=reference_point, qs_env=qs_env, &
     714           18 :                                reference=rtc%moment_trace_ref_type, ref_point=rtc%moment_trace_user_ref_point)
     715              : 
     716           18 :       CALL build_local_moment_matrix(qs_env, rtp%local_moments, 1, reference_point)
     717              : 
     718              :       ! Allocate the moments trace and output start moments
     719           18 :       CALL get_rtp(rtp, rho_old=rho_old)
     720           18 :       nspin = SIZE(rho_old)/2
     721          576 :       ALLOCATE (rtp%moments(SIZE(rho_old)/2, 3, rtp%nsteps + 1), source=CMPLX(0.0, 0.0, kind=dp))
     722           18 :       NULLIFY (rtp%times)
     723           54 :       ALLOCATE (rtp%times(rtp%nsteps + 1))
     724           18 :       NULLIFY (rtp%fields)
     725          270 :       ALLOCATE (rtp%fields(3, rtp%nsteps + 1), source=CMPLX(0.0, 0.0, kind=dp))
     726              : 
     727           18 :    END SUBROUTINE rt_init_local_moments
     728              : 
     729              : ! **************************************************************************************************
     730              : !> \brief Allocates and fills the local moment matrices (only available for linear scaling)
     731              : !> \param qs_env QS environment necessary for moment matrix calculation
     732              : ! **************************************************************************************************
     733           18 :    SUBROUTINE final_ft_output(qs_env)
     734              :       TYPE(qs_environment_type), POINTER                 :: qs_env
     735              : 
     736              :       INTEGER                                            :: k, unit_nr
     737              :       TYPE(cell_type), POINTER                           :: cell
     738              :       TYPE(cp_logger_type), POINTER                      :: logger
     739              :       TYPE(dft_control_type), POINTER                    :: dft_control
     740              :       TYPE(rt_prop_type), POINTER                        :: rtp
     741              :       TYPE(section_vals_type), POINTER                   :: input, rtp_section
     742              : 
     743           18 :       CALL get_qs_env(qs_env, cell=cell, rtp=rtp, input=input, dft_control=dft_control)
     744           18 :       rtp_section => section_vals_get_subs_vals(input, "DFT%REAL_TIME_PROPAGATION")
     745           18 :       logger => cp_get_default_logger()
     746           18 :       unit_nr = cp_logger_get_default_io_unit(logger)
     747              :       CALL print_ft(rtp_section, rtp%moments, rtp%times, rtp%fields, dft_control%rtp_control, &
     748           18 :                     info_opt=unit_nr, cell=cell)
     749              :       ! Deallocating the local moments matrices and array
     750           72 :       DO k = 1, 3
     751           54 :          CALL dbcsr_release(rtp%local_moments(k)%matrix)
     752           72 :          DEALLOCATE (rtp%local_moments(k)%matrix)
     753              :       END DO
     754           18 :       DEALLOCATE (rtp%local_moments)
     755           18 :       CALL dbcsr_release(rtp%local_moments_work)
     756           18 :       DEALLOCATE (rtp%local_moments_work)
     757           18 :       DEALLOCATE (rtp%moments)
     758           18 :       DEALLOCATE (rtp%times)
     759           18 :       DEALLOCATE (rtp%fields)
     760           18 :    END SUBROUTINE final_ft_output
     761              : 
     762              : END MODULE rt_propagation
        

Generated by: LCOV version 2.0-1