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
|