LCOV - code coverage report
Current view: top level - src/emd - rt_bse_io.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:936074a) Lines: 81.7 % 169 138
Test Date: 2025-12-04 06:27:48 Functions: 90.9 % 11 10

            Line data    Source code
       1              : !--------------------------------------------------------------------------------------------------!
       2              : !   CP2K: A general program to perform molecular dynamics simulations                              !
       3              : !   Copyright 2000-2025 CP2K developers group <https://cp2k.org>                                   !
       4              : !                                                                                                  !
       5              : !   SPDX-License-Identifier: GPL-2.0-or-later                                                      !
       6              : !--------------------------------------------------------------------------------------------------!
       7              : 
       8              : ! **************************************************************************************************
       9              : !> \brief Input/output from the propagation via RT-BSE method.
      10              : !> \author Stepan Marek (08.24)
      11              : ! **************************************************************************************************
      12              : 
      13              : MODULE rt_bse_io
      14              :    USE cp_fm_types, ONLY: cp_fm_type, &
      15              :                           cp_fm_read_unformatted, &
      16              :                           cp_fm_write_unformatted, &
      17              :                           cp_fm_write_formatted
      18              :    USE cp_cfm_types, ONLY: cp_cfm_type, &
      19              :                            cp_fm_to_cfm, &
      20              :                            cp_cfm_to_fm
      21              :    USE kinds, ONLY: dp, &
      22              :                     default_path_length
      23              :    USE cp_fm_basic_linalg, ONLY: cp_fm_trace, &
      24              :                                  cp_fm_transpose
      25              :    USE cp_log_handling, ONLY: cp_logger_type, &
      26              :                               cp_get_default_logger
      27              :    USE cp_output_handling, ONLY: cp_print_key_unit_nr, &
      28              :                                  cp_print_key_finished_output, &
      29              :                                  cp_print_key_generate_filename, &
      30              :                                  low_print_level, &
      31              :                                  medium_print_level
      32              :    USE input_section_types, ONLY: section_vals_type
      33              :    USE rt_bse_types, ONLY: rtbse_env_type, &
      34              :                            multiply_cfm_fm, &
      35              :                            multiply_fm_cfm
      36              :    USE cp_files, ONLY: open_file, &
      37              :                        file_exists, &
      38              :                        close_file
      39              :    USE input_constants, ONLY: do_exact, &
      40              :                               do_bch, &
      41              :                               rtp_bse_ham_g0w0, &
      42              :                               rtp_bse_ham_ks, &
      43              :                               use_rt_restart
      44              :    USE physcon, ONLY: femtoseconds
      45              :    USE rt_propagation_output, ONLY: print_moments
      46              : 
      47              : #include "../base/base_uses.f90"
      48              : 
      49              :    IMPLICIT NONE
      50              : 
      51              :    PRIVATE
      52              : 
      53              :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = "rt_bse_io"
      54              : 
      55              :    #:include "rt_bse_macros.fypp"
      56              : 
      57              :    PUBLIC :: output_moments, &
      58              :              output_field, &
      59              :              read_field, &
      60              :              output_mos_contravariant, &
      61              :              output_mos_covariant, &
      62              :              output_restart, &
      63              :              read_restart, &
      64              :              print_etrs_info_header, &
      65              :              print_etrs_info, &
      66              :              print_timestep_info, &
      67              :              print_rtbse_header_info
      68              : 
      69              : CONTAINS
      70              : 
      71              : ! **************************************************************************************************
      72              : !> \brief Writes the header and basic info to the standard output
      73              : !> \param rtbse_env Entry point - rtbse environment
      74              : ! **************************************************************************************************
      75           12 :    SUBROUTINE print_rtbse_header_info(rtbse_env)
      76              :       TYPE(rtbse_env_type)                               :: rtbse_env
      77              :       TYPE(cp_logger_type), POINTER                      :: logger
      78              : 
      79           12 :       logger => cp_get_default_logger()
      80              : 
      81           12 :       IF (rtbse_env%unit_nr > 0) THEN
      82            6 :          WRITE (rtbse_env%unit_nr, *) ''
      83              :          WRITE (rtbse_env%unit_nr, '(A)') ' /-----------------------------------------------'// &
      84            6 :             '------------------------------\'
      85              :          WRITE (rtbse_env%unit_nr, '(A)') ' |                                               '// &
      86            6 :             '                              |'
      87              :          WRITE (rtbse_env%unit_nr, '(A)') ' |                    Real Time Bethe-Salpeter Propagation'// &
      88            6 :             '                     |'
      89              :          WRITE (rtbse_env%unit_nr, '(A)') ' |                                               '// &
      90            6 :             '                              |'
      91              :          WRITE (rtbse_env%unit_nr, '(A)') ' \-----------------------------------------------'// &
      92            6 :             '------------------------------/'
      93            6 :          WRITE (rtbse_env%unit_nr, *) ''
      94              : 
      95              :          ! Methods used
      96            6 :          WRITE (rtbse_env%unit_nr, '(A19)', advance="no") ' Exponential method'
      97           12 :          SELECT CASE (rtbse_env%mat_exp_method)
      98              :          CASE (do_bch)
      99            6 :             WRITE (rtbse_env%unit_nr, '(A61)') 'BCH'
     100              :          CASE (do_exact)
     101            6 :             WRITE (rtbse_env%unit_nr, '(A61)') 'EXACT'
     102              :          END SELECT
     103              : 
     104            6 :          WRITE (rtbse_env%unit_nr, '(A22)', advance="no") ' Reference Hamiltonian'
     105           12 :          SELECT CASE (rtbse_env%ham_reference_type)
     106              :          CASE (rtp_bse_ham_g0w0)
     107            6 :             WRITE (rtbse_env%unit_nr, '(A58)') 'G0W0'
     108              :          CASE (rtp_bse_ham_ks)
     109            6 :             WRITE (rtbse_env%unit_nr, '(A58)') 'Kohn-Sham'
     110              :          END SELECT
     111              : 
     112            6 :          WRITE (rtbse_env%unit_nr, '(A18,L62)') ' Apply delta pulse', &
     113           12 :             rtbse_env%dft_control%rtp_control%apply_delta_pulse
     114              : 
     115            6 :          WRITE (rtbse_env%unit_nr, '(A)') ''
     116              :       END IF
     117              : 
     118           12 :    END SUBROUTINE print_rtbse_header_info
     119              : 
     120              : ! **************************************************************************************************
     121              : !> \brief Writes the update after single etrs iteration - only for log level > medium
     122              : !> \param rtbse_env Entry point - rtbse environment
     123              : ! **************************************************************************************************
     124         1510 :    SUBROUTINE print_etrs_info(rtbse_env, step, metric)
     125              :       TYPE(rtbse_env_type)                               :: rtbse_env
     126              :       INTEGER                                            :: step
     127              :       REAL(kind=dp)                                      :: metric
     128              :       TYPE(cp_logger_type), POINTER                      :: logger
     129              : 
     130         1510 :       logger => cp_get_default_logger()
     131              : 
     132         1510 :       IF (logger%iter_info%print_level > medium_print_level .AND. rtbse_env%unit_nr > 0) THEN
     133            0 :          WRITE (rtbse_env%unit_nr, '(A7,I5, E20.8E3)') ' RTBSE|', step, metric
     134              :       END IF
     135              : 
     136         1510 :    END SUBROUTINE print_etrs_info
     137              : ! **************************************************************************************************
     138              : !> \brief Writes the header for the etrs iteration updates - only for log level > medium
     139              : !> \param rtbse_env Entry point - rtbse environment
     140              : ! **************************************************************************************************
     141          556 :    SUBROUTINE print_etrs_info_header(rtbse_env)
     142              :       TYPE(rtbse_env_type)                               :: rtbse_env
     143              :       TYPE(cp_logger_type), POINTER                      :: logger
     144              : 
     145          556 :       logger => cp_get_default_logger()
     146              : 
     147          556 :       IF (logger%iter_info%print_level > medium_print_level .AND. rtbse_env%unit_nr > 0) THEN
     148            0 :          WRITE (rtbse_env%unit_nr, '(A13, A20)') ' RTBSE| Iter.', 'Convergence'
     149              :       END IF
     150              : 
     151          556 :    END SUBROUTINE print_etrs_info_header
     152              : ! **************************************************************************************************
     153              : !> \brief Writes the header for the etrs iteration updates - only for log level > low
     154              : !> \param rtbse_env Entry point - rtbse environment
     155              : ! **************************************************************************************************
     156          556 :    SUBROUTINE print_timestep_info(rtbse_env, step, convergence, electron_num_re, etrs_num)
     157              :       TYPE(rtbse_env_type)                               :: rtbse_env
     158              :       INTEGER                                            :: step
     159              :       REAL(kind=dp)                                      :: convergence
     160              :       REAL(kind=dp)                                      :: electron_num_re
     161              :       INTEGER                                            :: etrs_num
     162              :       TYPE(cp_logger_type), POINTER                      :: logger
     163              : 
     164          556 :       logger => cp_get_default_logger()
     165              : 
     166          556 :       IF (logger%iter_info%print_level > low_print_level .AND. rtbse_env%unit_nr > 0) THEN
     167          278 :          WRITE (rtbse_env%unit_nr, '(A23,A20,A20,A17)') " RTBSE| Simulation step", "Convergence", &
     168          556 :             "Electron number", "ETRS Iterations"
     169          278 :          WRITE (rtbse_env%unit_nr, '(A7,I16,E20.8E3,E20.8E3,I17)') ' RTBSE|', step, convergence, &
     170          556 :             electron_num_re, etrs_num
     171              :       END IF
     172              : 
     173          556 :    END SUBROUTINE print_timestep_info
     174              : 
     175              : ! **************************************************************************************************
     176              : !> \brief Outputs the matrix in MO basis for matrix coefficients corresponding to contravariant
     177              : !>        operator, i.e. density matrix
     178              : !> \param rtbse_env Entry point - gwbse environment
     179              : !> \param rho Density matrix in AO basis
     180              : !> \param rtp_section RTP input section
     181              : ! **************************************************************************************************
     182          556 :    SUBROUTINE output_mos_contravariant(rtbse_env, rho, print_key_section)
     183              :       TYPE(rtbse_env_type)                               :: rtbse_env
     184              :       TYPE(cp_cfm_type), DIMENSION(:), POINTER           :: rho
     185              :       TYPE(section_vals_type), POINTER                   :: print_key_section
     186              :       TYPE(cp_logger_type), POINTER                      :: logger
     187              :       INTEGER                                            :: j, rho_unit_re, rho_unit_im
     188              :       CHARACTER(len=14), DIMENSION(4)                    :: file_labels
     189              : 
     190          556 :       file_labels(1) = "_SPIN_A_RE.dat"
     191          556 :       file_labels(2) = "_SPIN_A_IM.dat"
     192          556 :       file_labels(3) = "_SPIN_B_RE.dat"
     193          556 :       file_labels(4) = "_SPIN_B_IM.dat"
     194          556 :       logger => cp_get_default_logger()
     195              :       ! Start by multiplying the current density by MOS
     196         1112 :       DO j = 1, rtbse_env%n_spin
     197          556 :          rho_unit_re = cp_print_key_unit_nr(logger, print_key_section, extension=file_labels(2*j - 1))
     198          556 :          rho_unit_im = cp_print_key_unit_nr(logger, print_key_section, extension=file_labels(2*j))
     199              :          ! Transform the density matrix into molecular orbitals basis and print it out
     200              :          ! S * rho
     201              :          CALL multiply_fm_cfm("N", "N", rtbse_env%n_ao, rtbse_env%n_ao, rtbse_env%n_ao, &
     202              :                               1.0_dp, rtbse_env%S_fm, rho(j), &
     203          556 :                               0.0_dp, rtbse_env%rho_workspace(1))
     204              :          ! C^T * S * rho
     205              :          CALL multiply_fm_cfm("T", "N", rtbse_env%n_ao, rtbse_env%n_ao, rtbse_env%n_ao, &
     206              :                               1.0_dp, rtbse_env%bs_env%fm_mo_coeff_Gamma(j), rtbse_env%rho_workspace(1), &
     207          556 :                               0.0_dp, rtbse_env%rho_workspace(2))
     208              :          ! C^T * S * rho * S
     209              :          CALL multiply_cfm_fm("N", "N", rtbse_env%n_ao, rtbse_env%n_ao, rtbse_env%n_ao, &
     210              :                               1.0_dp, rtbse_env%rho_workspace(2), rtbse_env%S_fm, &
     211          556 :                               0.0_dp, rtbse_env%rho_workspace(1))
     212              :          ! C^T * S * rho * S * C
     213              :          CALL multiply_cfm_fm("N", "N", rtbse_env%n_ao, rtbse_env%n_ao, rtbse_env%n_ao, &
     214              :                               1.0_dp, rtbse_env%rho_workspace(1), rtbse_env%bs_env%fm_mo_coeff_Gamma(j), &
     215          556 :                               0.0_dp, rtbse_env%rho_workspace(2))
     216              :          ! Print real and imaginary parts separately
     217              :          CALL cp_cfm_to_fm(rtbse_env%rho_workspace(2), &
     218          556 :                            rtbse_env%real_workspace(1), rtbse_env%real_workspace(2))
     219          556 :          CALL cp_fm_write_formatted(rtbse_env%real_workspace(1), rho_unit_re)
     220          556 :          CALL cp_fm_write_formatted(rtbse_env%real_workspace(2), rho_unit_im)
     221          556 :          CALL cp_print_key_finished_output(rho_unit_re, logger, print_key_section)
     222         1112 :          CALL cp_print_key_finished_output(rho_unit_im, logger, print_key_section)
     223              :       END DO
     224          556 :    END SUBROUTINE output_mos_contravariant
     225              : ! **************************************************************************************************
     226              : !> \brief Outputs the matrix in MO basis for matrix components corresponding to covariant representation,
     227              : !>        i.e. the Hamiltonian matrix
     228              : !> \param rtbse_env Entry point - gwbse environment
     229              : !> \param cohsex cohsex matrix in AO basis, covariant representation
     230              : !> \param rtp_section RTP input section
     231              : ! **************************************************************************************************
     232            0 :    SUBROUTINE output_mos_covariant(rtbse_env, ham, print_key_section)
     233              :       TYPE(rtbse_env_type)                               :: rtbse_env
     234              :       TYPE(cp_cfm_type), DIMENSION(:), POINTER           :: ham
     235              :       TYPE(section_vals_type), POINTER                   :: print_key_section
     236              :       TYPE(cp_logger_type), POINTER                      :: logger
     237              :       INTEGER                                            :: j, rho_unit_re, rho_unit_im
     238              :       CHARACTER(len=21), DIMENSION(4)                    :: file_labels
     239              : 
     240            0 :       file_labels(1) = "_SPIN_A_RE.dat"
     241            0 :       file_labels(2) = "_SPIN_A_IM.dat"
     242            0 :       file_labels(3) = "_SPIN_B_RE.dat"
     243            0 :       file_labels(4) = "_SPIN_B_IM.dat"
     244            0 :       logger => cp_get_default_logger()
     245            0 :       DO j = 1, rtbse_env%n_spin
     246            0 :          rho_unit_re = cp_print_key_unit_nr(logger, print_key_section, extension=file_labels(2*j - 1))
     247            0 :          rho_unit_im = cp_print_key_unit_nr(logger, print_key_section, extension=file_labels(2*j))
     248              :          ! C^T * cohsex
     249              :          CALL multiply_fm_cfm("T", "N", rtbse_env%n_ao, rtbse_env%n_ao, rtbse_env%n_ao, &
     250              :                               1.0_dp, rtbse_env%bs_env%fm_mo_coeff_Gamma(j), ham(j), &
     251            0 :                               0.0_dp, rtbse_env%rho_workspace(1))
     252              :          ! C^T * cohsex * C
     253              :          CALL multiply_cfm_fm("N", "N", rtbse_env%n_ao, rtbse_env%n_ao, rtbse_env%n_ao, &
     254              :                               1.0_dp, rtbse_env%rho_workspace(1), rtbse_env%bs_env%fm_mo_coeff_Gamma(j), &
     255            0 :                               0.0_dp, rtbse_env%rho_workspace(2))
     256              :          ! Print real and imaginary parts separately
     257              :          CALL cp_cfm_to_fm(rtbse_env%rho_workspace(2), &
     258            0 :                            rtbse_env%real_workspace(1), rtbse_env%real_workspace(2))
     259            0 :          CALL cp_fm_write_formatted(rtbse_env%real_workspace(1), rho_unit_re)
     260            0 :          CALL cp_fm_write_formatted(rtbse_env%real_workspace(2), rho_unit_im)
     261            0 :          CALL cp_print_key_finished_output(rho_unit_re, logger, print_key_section)
     262            0 :          CALL cp_print_key_finished_output(rho_unit_im, logger, print_key_section)
     263              :       END DO
     264            0 :    END SUBROUTINE output_mos_covariant
     265              : ! **************************************************************************************************
     266              : !> \brief Prints the current field components into a file provided by input
     267              : !> \param rtbse_env Entry point - gwbse environment
     268              : !> \param rtp_section RTP input section
     269              : ! **************************************************************************************************
     270          562 :    SUBROUTINE output_field(rtbse_env)
     271              :       TYPE(rtbse_env_type)                               :: rtbse_env
     272              :       TYPE(cp_logger_type), POINTER                      :: logger
     273              :       INTEGER                                            :: field_unit, n, i
     274              : 
     275              :       ! Get logger
     276          562 :       logger => cp_get_default_logger()
     277              :       ! Get file descriptor
     278          562 :       field_unit = cp_print_key_unit_nr(logger, rtbse_env%field_section, extension=".dat")
     279              :       ! If the file descriptor is non-zero, output field
     280              :       ! TODO : Output also in SI
     281          562 :       IF (field_unit /= -1) THEN
     282            0 :          WRITE (field_unit, '(E20.8E3,E20.8E3,E20.8E3,E20.8E3)') rtbse_env%sim_time*femtoseconds, &
     283            0 :             rtbse_env%field(1), rtbse_env%field(2), rtbse_env%field(3)
     284              :       END IF
     285              :       ! Write the output to memory for FT
     286              :       ! Need the absolute index
     287          562 :       n = rtbse_env%sim_step - rtbse_env%sim_start_orig + 1
     288         2248 :       DO i = 1, 3
     289         2248 :          rtbse_env%field_trace(i, n) = CMPLX(rtbse_env%field(i), 0.0, kind=dp)
     290              :       END DO
     291          562 :       rtbse_env%time_trace(n) = rtbse_env%sim_time
     292          562 :       CALL cp_print_key_finished_output(field_unit, logger, rtbse_env%field_section)
     293              : 
     294          562 :    END SUBROUTINE output_field
     295              : ! **************************************************************************************************
     296              : !> \brief Reads the field from the files provided by input - useful for the continuation run
     297              : !> \param rtbse_env Entry point - gwbse environment
     298              : !> \param rtp_section RTP input section
     299              : ! **************************************************************************************************
     300           12 :    SUBROUTINE read_field(rtbse_env)
     301              :       TYPE(rtbse_env_type)                               :: rtbse_env
     302              :       TYPE(cp_logger_type), POINTER                      :: logger
     303              :       CHARACTER(len=default_path_length)                 :: save_name
     304              :       INTEGER                                            :: k, n, field_unit
     305              :       REAL(kind=dp), DIMENSION(3)                        :: real_field
     306              : 
     307              :       ! Get logger
     308           12 :       logger => cp_get_default_logger()
     309              :       ! Get file name
     310           12 :       save_name = cp_print_key_generate_filename(logger, rtbse_env%field_section, extension=".dat", my_local=.FALSE.)
     311           12 :       IF (file_exists(save_name)) THEN
     312              :          CALL open_file(save_name, file_status="OLD", file_form="FORMATTED", file_action="READ", &
     313            0 :                         unit_number=field_unit)
     314            0 :          DO k = rtbse_env%sim_start_orig, rtbse_env%sim_start
     315            0 :             n = k - rtbse_env%sim_start_orig + 1
     316            0 :             READ (field_unit, '(E20.8E3,E20.8E3,E20.8E3,E20.8E3)') rtbse_env%time_trace(n), &
     317            0 :                real_field(1), real_field(2), real_field(3)
     318            0 :             rtbse_env%field_trace(:, n) = CMPLX(real_field(:), 0.0, kind=dp)
     319              :             ! Set the time units back to atomic units
     320            0 :             rtbse_env%time_trace(n) = rtbse_env%time_trace(n)/femtoseconds
     321              :          END DO
     322            0 :          CALL close_file(field_unit)
     323           12 :       ELSE IF (.NOT. rtbse_env%dft_control%rtp_control%apply_delta_pulse .AND. &
     324              :                rtbse_env%dft_control%rtp_control%initial_wfn == use_rt_restart) THEN
     325            2 :          CPWARN("Restart without RT field file - unknown field trace set to zero.")
     326              :       END IF
     327           12 :    END SUBROUTINE read_field
     328              : 
     329              : ! **************************************************************************************************
     330              : !> \brief Outputs the expectation value of moments from a given density matrix
     331              : !> \note  Moments matrix is provided by the rtbse_env, uses rho_workspace(1:3)
     332              : !> \param rtbse_env Entry point - gwbse environment
     333              : !> \param rho Density matrix in AO basis
     334              : !> \param rtp_section RTP section of the input parameters, where moments destination may be present
     335              : ! **************************************************************************************************
     336          562 :    SUBROUTINE output_moments(rtbse_env, rho)
     337              :       TYPE(rtbse_env_type)                               :: rtbse_env
     338              :       TYPE(cp_cfm_type), DIMENSION(:), POINTER           :: rho
     339              :       INTEGER                                            :: i, j, n
     340              :       REAL(kind=dp), DIMENSION(3)                        :: moments_re
     341              : 
     342          562 :       n = rtbse_env%sim_step - rtbse_env%sim_start_orig + 1
     343              : 
     344         1124 :       DO j = 1, rtbse_env%n_spin
     345              :          ! Need to transpose due to the definition of trace function
     346          562 :          CALL cp_cfm_to_fm(msource=rho(j), mtargetr=rtbse_env%real_workspace(2))
     347         2248 :          DO i = 1, 3
     348              :             ! Moments should be symmetric, test without transopose?
     349         1686 :             CALL cp_fm_transpose(rtbse_env%moments(i), rtbse_env%real_workspace(1))
     350         1686 :             CALL cp_fm_trace(rtbse_env%real_workspace(1), rtbse_env%real_workspace(2), moments_re(i))
     351              :             ! Scale by spin degeneracy and electron charge
     352         1686 :             moments_re(i) = -moments_re(i)*rtbse_env%spin_degeneracy
     353         2248 :             rtbse_env%moments_trace(j, i, n) = CMPLX(moments_re(i), 0.0, kind=dp)
     354              :          END DO
     355              :          ! Same for imaginary part
     356          562 :          CALL cp_cfm_to_fm(msource=rho(j), mtargeti=rtbse_env%real_workspace(2))
     357         2810 :          DO i = 1, 3
     358         1686 :             CALL cp_fm_transpose(rtbse_env%moments(i), rtbse_env%real_workspace(1))
     359         1686 :             CALL cp_fm_trace(rtbse_env%real_workspace(1), rtbse_env%real_workspace(2), moments_re(i))
     360              :             ! Scale by spin degeneracy and electron charge
     361         1686 :             moments_re(i) = -moments_re(i)*rtbse_env%spin_degeneracy
     362         2248 :             rtbse_env%moments_trace(j, i, n) = rtbse_env%moments_trace(j, i, n) + CMPLX(0.0, moments_re(i), kind=dp)
     363              :          END DO
     364              :       END DO
     365              :       ! Output to the file
     366              :       CALL print_moments(rtbse_env%moments_section, rtbse_env%unit_nr, rtbse_env%moments_trace(:, :, n), &
     367          562 :                          rtbse_env%sim_time, .TRUE.)
     368          562 :    END SUBROUTINE output_moments
     369              : ! **************************************************************************************************
     370              : !> \brief Outputs the restart info (last finished iteration step) + restard density matrix
     371              : !> \param restart_section Print key section for the restart files
     372              : !> \param rho Density matrix in AO basis
     373              : !> \param time_index Time index to be written into the info file
     374              : ! **************************************************************************************************
     375          556 :    SUBROUTINE output_restart(rtbse_env, rho, time_index)
     376              :       TYPE(rtbse_env_type), POINTER                      :: rtbse_env
     377              :       TYPE(cp_cfm_type), DIMENSION(:), POINTER           :: rho
     378              :       INTEGER                                            :: time_index
     379          556 :       TYPE(cp_fm_type), DIMENSION(:), POINTER            :: workspace
     380              :       CHARACTER(len=17), DIMENSION(4)                    :: file_labels
     381              :       TYPE(cp_logger_type), POINTER                      :: logger
     382              :       INTEGER                                            :: rho_unit_nr, i
     383              : 
     384              :       ! Default labels distinguishing up to two spin species and real/imaginary parts
     385          556 :       file_labels(1) = "_SPIN_A_RE.matrix"
     386          556 :       file_labels(2) = "_SPIN_A_IM.matrix"
     387          556 :       file_labels(3) = "_SPIN_B_RE.matrix"
     388          556 :       file_labels(4) = "_SPIN_B_IM.matrix"
     389              : 
     390         1112 :       logger => cp_get_default_logger()
     391              : 
     392          556 :       workspace => rtbse_env%real_workspace
     393              : 
     394         1112 :       DO i = 1, rtbse_env%n_spin
     395          556 :          CALL cp_cfm_to_fm(rho(i), workspace(1), workspace(2))
     396              :          ! Real part
     397              :          rho_unit_nr = cp_print_key_unit_nr(logger, rtbse_env%restart_section, extension=file_labels(2*i - 1), &
     398          556 :                                             file_form="UNFORMATTED", file_position="REWIND")
     399          556 :          CALL cp_fm_write_unformatted(workspace(1), rho_unit_nr)
     400          556 :          CALL cp_print_key_finished_output(rho_unit_nr, logger, rtbse_env%restart_section)
     401              :          ! Imag part
     402              :          rho_unit_nr = cp_print_key_unit_nr(logger, rtbse_env%restart_section, extension=file_labels(2*i), &
     403          556 :                                             file_form="UNFORMATTED", file_position="REWIND")
     404          556 :          CALL cp_fm_write_unformatted(workspace(2), rho_unit_nr)
     405          556 :          CALL cp_print_key_finished_output(rho_unit_nr, logger, rtbse_env%restart_section)
     406              :          ! Info
     407              :          rho_unit_nr = cp_print_key_unit_nr(logger, rtbse_env%restart_section, extension=".info", &
     408          556 :                                             file_form="UNFORMATTED", file_position="REWIND")
     409          556 :          IF (rho_unit_nr > 0) WRITE (rho_unit_nr) time_index
     410         1112 :          CALL cp_print_key_finished_output(rho_unit_nr, logger, rtbse_env%restart_section)
     411              :       END DO
     412          556 :    END SUBROUTINE output_restart
     413              : ! **************************************************************************************************
     414              : !> \brief Reads the density matrix from restart files and updates the starting time
     415              : !> \param restart_section Print key section for the restart files
     416              : !> \param rho Density matrix in AO basis
     417              : !> \param time_index Time index to be written into the info file
     418              : ! **************************************************************************************************
     419            6 :    SUBROUTINE read_restart(rtbse_env)
     420              :       TYPE(rtbse_env_type), POINTER                      :: rtbse_env
     421              :       TYPE(cp_logger_type), POINTER                      :: logger
     422              :       CHARACTER(len=default_path_length)                 :: save_name, save_name_2
     423              :       INTEGER                                            :: rho_unit_nr, j
     424              :       CHARACTER(len=17), DIMENSION(4)                    :: file_labels
     425              : 
     426              :       ! This allows the delta kick and output of moment at time 0 in all cases
     427              :       ! except the case when both imaginary and real parts of the density are read
     428            6 :       rtbse_env%restart_extracted = .FALSE.
     429            6 :       logger => cp_get_default_logger()
     430              :       ! Start by probing/loading info file
     431            6 :       save_name = cp_print_key_generate_filename(logger, rtbse_env%restart_section, extension=".info", my_local=.FALSE.)
     432            6 :       IF (file_exists(save_name)) THEN
     433              :          CALL open_file(save_name, file_status="OLD", file_form="UNFORMATTED", file_action="READ", &
     434            6 :                         unit_number=rho_unit_nr)
     435            6 :          READ (rho_unit_nr) rtbse_env%sim_start
     436            6 :          CALL close_file(rho_unit_nr)
     437            9 :          IF (rtbse_env%unit_nr > 0) WRITE (rtbse_env%unit_nr, '(A31,I25,A24)') " RTBSE| Starting from timestep ", &
     438            6 :             rtbse_env%sim_start, ", delta kick NOT applied"
     439              :       ELSE
     440            0 :          CPWARN("Restart required but no info file found - starting from sim_step given in input")
     441              :       END IF
     442              : 
     443              :       ! Default labels distinguishing up to two spin species and real/imaginary parts
     444            6 :       file_labels(1) = "_SPIN_A_RE.matrix"
     445            6 :       file_labels(2) = "_SPIN_A_IM.matrix"
     446            6 :       file_labels(3) = "_SPIN_B_RE.matrix"
     447            6 :       file_labels(4) = "_SPIN_B_IM.matrix"
     448           12 :       DO j = 1, rtbse_env%n_spin
     449              :          save_name = cp_print_key_generate_filename(logger, rtbse_env%restart_section, &
     450            6 :                                                     extension=file_labels(2*j - 1), my_local=.FALSE.)
     451              :          save_name_2 = cp_print_key_generate_filename(logger, rtbse_env%restart_section, &
     452            6 :                                                       extension=file_labels(2*j), my_local=.FALSE.)
     453           12 :          IF (file_exists(save_name) .AND. file_exists(save_name_2)) THEN
     454              :             CALL open_file(save_name, file_status="OLD", file_form="UNFORMATTED", file_action="READ", &
     455            6 :                            unit_number=rho_unit_nr)
     456            6 :             CALL cp_fm_read_unformatted(rtbse_env%real_workspace(1), rho_unit_nr)
     457            6 :             CALL close_file(rho_unit_nr)
     458              :             CALL open_file(save_name_2, file_status="OLD", file_form="UNFORMATTED", file_action="READ", &
     459            6 :                            unit_number=rho_unit_nr)
     460            6 :             CALL cp_fm_read_unformatted(rtbse_env%real_workspace(2), rho_unit_nr)
     461            6 :             CALL close_file(rho_unit_nr)
     462              :             CALL cp_fm_to_cfm(rtbse_env%real_workspace(1), rtbse_env%real_workspace(2), &
     463            6 :                               rtbse_env%rho(j))
     464            6 :             rtbse_env%restart_extracted = .TRUE.
     465              :          ELSE
     466            0 :             CPWARN("Restart without some restart matrices - starting from SCF density.")
     467              :          END IF
     468              :       END DO
     469            6 :    END SUBROUTINE read_restart
     470              : END MODULE rt_bse_io
        

Generated by: LCOV version 2.0-1