LCOV - code coverage report
Current view: top level - src/emd - rt_bse_io.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:3db43b4) Lines: 83.7 % 172 144
Test Date: 2026-04-03 06:55:30 Functions: 90.9 % 11 10

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

Generated by: LCOV version 2.0-1