(git:8917686)
Loading...
Searching...
No Matches
rt_bse_io.F
Go to the documentation of this file.
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
14 USE cp_fm_types, ONLY: cp_fm_type, &
18 USE cp_cfm_types, ONLY: cp_cfm_type, &
21 USE kinds, ONLY: dp, &
33 USE rt_bse_types, ONLY: rtbse_env_type, &
36 USE cp_files, ONLY: open_file, &
39 USE input_constants, ONLY: do_exact, &
40 do_bch, &
47 USE physcon, ONLY: evolt, femtoseconds
51
52#include "../base/base_uses.f90"
53
54 IMPLICIT NONE
55
56 PRIVATE
57
58 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = "rt_bse_io"
59
60 ! RESTART.trace on-disk format version - bump whenever the header or record layout changes
61 INTEGER, PARAMETER, PRIVATE :: restart_trace_version = 1
62
63
64
65
66 PUBLIC :: output_moments, &
68 read_field, &
83
84CONTAINS
85
86! **************************************************************************************************
87!> \brief Writes the header and basic info to the standard output
88!> \param rtbse_env Entry point - rtbse environment
89! **************************************************************************************************
90 SUBROUTINE print_rtbse_header_info(rtbse_env)
91 TYPE(rtbse_env_type) :: rtbse_env
92 TYPE(cp_logger_type), POINTER :: logger
93
94 logger => cp_get_default_logger()
95
96 IF (rtbse_env%unit_nr > 0) THEN
97 WRITE (rtbse_env%unit_nr, *) ''
98 WRITE (rtbse_env%unit_nr, '(A)') ' /-----------------------------------------------'// &
99 '------------------------------\'
100 WRITE (rtbse_env%unit_nr, '(A)') ' | '// &
101 ' |'
102 WRITE (rtbse_env%unit_nr, '(A)') ' | Real Time Bethe-Salpeter Propagation'// &
103 ' |'
104 WRITE (rtbse_env%unit_nr, '(A)') ' | '// &
105 ' |'
106 WRITE (rtbse_env%unit_nr, '(A)') ' \-----------------------------------------------'// &
107 '------------------------------/'
108 WRITE (rtbse_env%unit_nr, *) ''
109
110 ! Methods used
111 WRITE (rtbse_env%unit_nr, '(A19)', advance="no") ' Exponential method'
112 SELECT CASE (rtbse_env%mat_exp_method)
113 CASE (do_bch)
114 WRITE (rtbse_env%unit_nr, '(A61)') 'BCH'
115 CASE (do_exact)
116 WRITE (rtbse_env%unit_nr, '(A61)') 'EXACT'
117 END SELECT
118
119 WRITE (rtbse_env%unit_nr, '(A22)', advance="no") ' Reference Hamiltonian'
120 SELECT CASE (rtbse_env%ham_reference_type)
121 CASE (rtp_bse_ham_g0w0)
122 WRITE (rtbse_env%unit_nr, '(A58)') 'G0W0'
123 CASE (rtp_bse_ham_ks)
124 WRITE (rtbse_env%unit_nr, '(A58)') 'Kohn-Sham'
125 END SELECT
126
127 WRITE (rtbse_env%unit_nr, '(A18,L62)') ' Apply delta pulse', &
128 rtbse_env%dft_control%rtp_control%apply_delta_pulse
129
130 WRITE (rtbse_env%unit_nr, '(A)') ''
131 END IF
132
133 END SUBROUTINE print_rtbse_header_info
134
135! **************************************************************************************************
136!> \brief Writes the update after single etrs iteration - only for log level > medium
137!> \param rtbse_env Entry point - rtbse environment
138! **************************************************************************************************
139 SUBROUTINE print_etrs_info(rtbse_env, step, metric)
140 TYPE(rtbse_env_type) :: rtbse_env
141 INTEGER :: step
142 REAL(kind=dp) :: metric
143 TYPE(cp_logger_type), POINTER :: logger
144
145 logger => cp_get_default_logger()
146
147 IF (logger%iter_info%print_level > medium_print_level .AND. rtbse_env%unit_nr > 0) THEN
148 WRITE (rtbse_env%unit_nr, '(A7,I5, E20.8E3)') ' RTBSE|', step, metric
149 END IF
150
151 END SUBROUTINE print_etrs_info
152! **************************************************************************************************
153!> \brief Writes the header for the etrs iteration updates - only for log level > medium
154!> \param rtbse_env Entry point - rtbse environment
155! **************************************************************************************************
156 SUBROUTINE print_etrs_info_header(rtbse_env)
157 TYPE(rtbse_env_type) :: rtbse_env
158 TYPE(cp_logger_type), POINTER :: logger
159
160 logger => cp_get_default_logger()
161
162 IF (logger%iter_info%print_level > medium_print_level .AND. rtbse_env%unit_nr > 0) THEN
163 WRITE (rtbse_env%unit_nr, '(A13, A20)') ' RTBSE| Iter.', 'Convergence'
164 END IF
165
166 END SUBROUTINE print_etrs_info_header
167! **************************************************************************************************
168!> \brief Writes the summary line of a completed propagation timestep
169!> \param rtbse_env Entry point - rtbse environment
170!> \param step Index of the completed timestep
171!> \param electron_num_re Real part of the electron number, one entry per spin channel
172!> \param convergence Optional convergence metric reached by the ETRS iteration
173!> \param etrs_num Optional number of ETRS iterations used in this timestep
174!> \param step_walltime Optional wall time of this timestep, in seconds
175! **************************************************************************************************
176 SUBROUTINE print_timestep_info(rtbse_env, step, electron_num_re, convergence, etrs_num, &
177 step_walltime)
178 TYPE(rtbse_env_type) :: rtbse_env
179 INTEGER :: step
180 REAL(kind=dp), DIMENSION(:), INTENT(IN) :: electron_num_re
181 REAL(kind=dp), OPTIONAL :: convergence
182 INTEGER, OPTIONAL :: etrs_num
183 REAL(kind=dp), OPTIONAL :: step_walltime
184 TYPE(cp_logger_type), POINTER :: logger
185 LOGICAL :: flag_lrrtbse
186 INTEGER :: nch
187
188 logger => cp_get_default_logger()
189 ! one electron-number column per spin channel (1 = closed shell, 2 = open shell alpha/beta)
190 nch = SIZE(electron_num_re)
191
192 IF (.NOT. PRESENT(convergence) .OR. .NOT. PRESENT(etrs_num)) THEN
193 flag_lrrtbse = .true.
194 ELSE
195 flag_lrrtbse = .false.
196 END IF
197
198 IF (logger%iter_info%print_level > low_print_level .AND. rtbse_env%unit_nr > 0) THEN
199 IF (flag_lrrtbse) THEN
200 IF (step == 0) THEN
201 IF (PRESENT(step_walltime)) THEN
202 WRITE (rtbse_env%unit_nr, '(A45,T70,F11.3)') &
203 " RTBSE| Estimated runtime for propagation [s]", &
204 step_walltime*real(rtbse_env%sim_nsteps, dp)
205 WRITE (rtbse_env%unit_nr, '(A)') &
206 " RTBSE|"
207 IF (nch == 1) THEN
208 WRITE (rtbse_env%unit_nr, '(A23,T27,A13,T66,A15)') &
209 " RTBSE| Simulation step", "Step time [s]", "Electron number"
210 ELSE
211 ! T67/T88 (not T66/T86): each α/β is 2 bytes but 1 display col, so the byte
212 ! anchor is +1 per unicode char to right-align ')' under the value's last digit.
213 ! T anchors carry +1 byte per α/β before the ')' (α col → +1, β col → +2),
214 ! since each is 2 bytes but 1 display col; right-aligns ')' on the last digit.
215 WRITE (rtbse_env%unit_nr, '(A23,T27,A13,T47,A15,T68,A15)') &
216 " RTBSE| Simulation step", "Step time [s]", α"El. number ()", β"El. number ()"
217 END IF
218 ELSE
219 IF (nch == 1) THEN
220 WRITE (rtbse_env%unit_nr, '(A23,T66,A15)') " RTBSE| Simulation step", "Electron number"
221 ELSE
222 WRITE (rtbse_env%unit_nr, '(A23,T47,A15,T68,A15)') &
223 " RTBSE| Simulation step", α"El. number ()", β"El. number ()"
224 END IF
225 END IF
226 END IF
227 IF (PRESENT(step_walltime)) THEN
228 IF (nch == 1) THEN
229 WRITE (rtbse_env%unit_nr, '(A7,I16,T30,F10.3,T69,E12.3E3)') &
230 ' RTBSE|', step, step_walltime, electron_num_re(1)
231 ELSE
232 WRITE (rtbse_env%unit_nr, '(A7,I16,T30,F10.3,T49,E12.3E3,T69,E12.3E3)') &
233 ' RTBSE|', step, step_walltime, electron_num_re(1), electron_num_re(2)
234 END IF
235 ELSE
236 IF (nch == 1) THEN
237 WRITE (rtbse_env%unit_nr, '(A7,I16,T61,E20.8E3)') ' RTBSE|', step, electron_num_re(1)
238 ELSE
239 WRITE (rtbse_env%unit_nr, '(A7,I16,T49,E12.3E3,T69,E12.3E3)') &
240 ' RTBSE|', step, electron_num_re(1), electron_num_re(2)
241 END IF
242 END IF
243 ELSE
244 WRITE (rtbse_env%unit_nr, '(A23,A20,A20,A17)') " RTBSE| Simulation step", "Convergence", &
245 "Electron number", "ETRS Iterations"
246 WRITE (rtbse_env%unit_nr, '(A7,I16,E20.8E3,E20.8E3,I17)') ' RTBSE|', step, convergence, &
247 electron_num_re(1), etrs_num
248 END IF
249 END IF
250
251 END SUBROUTINE print_timestep_info
252
253! **************************************************************************************************
254!> \brief Outputs the matrix in MO basis for matrix coefficients corresponding to contravariant
255!> operator, i.e. density matrix
256!> \param rtbse_env Entry point - gwbse environment
257!> \param rho Density matrix in AO basis
258!> \param rtp_section RTP input section
259! **************************************************************************************************
260 SUBROUTINE output_mos_contravariant(rtbse_env, rho, print_key_section)
261 TYPE(rtbse_env_type) :: rtbse_env
262 TYPE(cp_cfm_type), DIMENSION(:), POINTER :: rho
263 TYPE(section_vals_type), POINTER :: print_key_section
264 TYPE(cp_logger_type), POINTER :: logger
265 INTEGER :: j, rho_unit_re, rho_unit_im
266 CHARACTER(len=14), DIMENSION(4) :: file_labels
267
268 file_labels(1) = "_SPIN_A_RE.dat"
269 file_labels(2) = "_SPIN_A_IM.dat"
270 file_labels(3) = "_SPIN_B_RE.dat"
271 file_labels(4) = "_SPIN_B_IM.dat"
272 logger => cp_get_default_logger()
273
274 ! In the linearized RT-BSE active-MO path, rho is already in the MO basis
275 ! restricted to the active window (sized mo_active x mo_active). Dump it
276 ! directly without the AO-side C^T S * rho * S C transformation.
277 IF (ASSOCIATED(rtbse_env%real_workspace_mo)) THEN
278 DO j = 1, rtbse_env%n_spin
279 rho_unit_re = cp_print_key_unit_nr(logger, print_key_section, extension=file_labels(2*j - 1))
280 rho_unit_im = cp_print_key_unit_nr(logger, print_key_section, extension=file_labels(2*j))
281 CALL cp_cfm_to_fm(rho(j), rtbse_env%real_workspace_mo(1), rtbse_env%real_workspace_mo(2))
282 CALL cp_fm_write_formatted(rtbse_env%real_workspace_mo(1), rho_unit_re)
283 CALL cp_fm_write_formatted(rtbse_env%real_workspace_mo(2), rho_unit_im)
284 CALL cp_print_key_finished_output(rho_unit_re, logger, print_key_section)
285 CALL cp_print_key_finished_output(rho_unit_im, logger, print_key_section)
286 END DO
287 RETURN
288 END IF
289 ! Start by multiplying the current density by MOS
290 DO j = 1, rtbse_env%n_spin
291 rho_unit_re = cp_print_key_unit_nr(logger, print_key_section, extension=file_labels(2*j - 1))
292 rho_unit_im = cp_print_key_unit_nr(logger, print_key_section, extension=file_labels(2*j))
293 ! Transform the density matrix into molecular orbitals basis and print it out
294 ! S * rho
295 CALL multiply_fm_cfm("N", "N", rtbse_env%n_ao, rtbse_env%n_ao, rtbse_env%n_ao, &
296 1.0_dp, rtbse_env%S_fm, rho(j), &
297 0.0_dp, rtbse_env%rho_workspace(1))
298 ! C^T * S * rho
299 CALL multiply_fm_cfm("T", "N", rtbse_env%n_ao, rtbse_env%n_ao, rtbse_env%n_ao, &
300 1.0_dp, rtbse_env%bs_env%fm_mo_coeff_Gamma(j), rtbse_env%rho_workspace(1), &
301 0.0_dp, rtbse_env%rho_workspace(2))
302 ! C^T * S * rho * S
303 CALL multiply_cfm_fm("N", "N", rtbse_env%n_ao, rtbse_env%n_ao, rtbse_env%n_ao, &
304 1.0_dp, rtbse_env%rho_workspace(2), rtbse_env%S_fm, &
305 0.0_dp, rtbse_env%rho_workspace(1))
306 ! C^T * S * rho * S * C
307 CALL multiply_cfm_fm("N", "N", rtbse_env%n_ao, rtbse_env%n_ao, rtbse_env%n_ao, &
308 1.0_dp, rtbse_env%rho_workspace(1), rtbse_env%bs_env%fm_mo_coeff_Gamma(j), &
309 0.0_dp, rtbse_env%rho_workspace(2))
310 ! Print real and imaginary parts separately
311 CALL cp_cfm_to_fm(rtbse_env%rho_workspace(2), &
312 rtbse_env%real_workspace(1), rtbse_env%real_workspace(2))
313 CALL cp_fm_write_formatted(rtbse_env%real_workspace(1), rho_unit_re)
314 CALL cp_fm_write_formatted(rtbse_env%real_workspace(2), rho_unit_im)
315 CALL cp_print_key_finished_output(rho_unit_re, logger, print_key_section)
316 CALL cp_print_key_finished_output(rho_unit_im, logger, print_key_section)
317 END DO
318 END SUBROUTINE output_mos_contravariant
319! **************************************************************************************************
320!> \brief Outputs the matrix in MO basis for matrix components corresponding to covariant representation,
321!> i.e. the Hamiltonian matrix
322!> \param rtbse_env Entry point - gwbse environment
323!> \param cohsex cohsex matrix in AO basis, covariant representation
324!> \param rtp_section RTP input section
325! **************************************************************************************************
326 SUBROUTINE output_mos_covariant(rtbse_env, ham, print_key_section)
327 TYPE(rtbse_env_type) :: rtbse_env
328 TYPE(cp_cfm_type), DIMENSION(:), POINTER :: ham
329 TYPE(section_vals_type), POINTER :: print_key_section
330 TYPE(cp_logger_type), POINTER :: logger
331 INTEGER :: j, rho_unit_re, rho_unit_im
332 CHARACTER(len=21), DIMENSION(4) :: file_labels
333
334 file_labels(1) = "_SPIN_A_RE.dat"
335 file_labels(2) = "_SPIN_A_IM.dat"
336 file_labels(3) = "_SPIN_B_RE.dat"
337 file_labels(4) = "_SPIN_B_IM.dat"
338 logger => cp_get_default_logger()
339 DO j = 1, rtbse_env%n_spin
340 rho_unit_re = cp_print_key_unit_nr(logger, print_key_section, extension=file_labels(2*j - 1))
341 rho_unit_im = cp_print_key_unit_nr(logger, print_key_section, extension=file_labels(2*j))
342 ! C^T * cohsex
343 CALL multiply_fm_cfm("T", "N", rtbse_env%n_ao, rtbse_env%n_ao, rtbse_env%n_ao, &
344 1.0_dp, rtbse_env%bs_env%fm_mo_coeff_Gamma(j), ham(j), &
345 0.0_dp, rtbse_env%rho_workspace(1))
346 ! C^T * cohsex * C
347 CALL multiply_cfm_fm("N", "N", rtbse_env%n_ao, rtbse_env%n_ao, rtbse_env%n_ao, &
348 1.0_dp, rtbse_env%rho_workspace(1), rtbse_env%bs_env%fm_mo_coeff_Gamma(j), &
349 0.0_dp, rtbse_env%rho_workspace(2))
350 ! Print real and imaginary parts separately
351 CALL cp_cfm_to_fm(rtbse_env%rho_workspace(2), &
352 rtbse_env%real_workspace(1), rtbse_env%real_workspace(2))
353 CALL cp_fm_write_formatted(rtbse_env%real_workspace(1), rho_unit_re)
354 CALL cp_fm_write_formatted(rtbse_env%real_workspace(2), rho_unit_im)
355 CALL cp_print_key_finished_output(rho_unit_re, logger, print_key_section)
356 CALL cp_print_key_finished_output(rho_unit_im, logger, print_key_section)
357 END DO
358 END SUBROUTINE output_mos_covariant
359! **************************************************************************************************
360!> \brief Prints the current field components into a file provided by input
361!> \param rtbse_env Entry point - gwbse environment
362!> \param rtp_section RTP input section
363! **************************************************************************************************
364 SUBROUTINE output_field(rtbse_env, append_opt)
365 TYPE(rtbse_env_type) :: rtbse_env
366 LOGICAL, OPTIONAL :: append_opt
367 TYPE(cp_logger_type), POINTER :: logger
368 INTEGER :: field_unit, n, i
369 LOGICAL :: append
370
371 ! Figure out whether we are appending or not, true by default
372 append = .true.
373 IF (PRESENT(append_opt)) append = .false.
374
375 ! First, write the current field to memory
376 ! Need the absolute index
377 n = rtbse_env%sim_step - rtbse_env%sim_start_orig + 1
378 DO i = 1, 3
379 rtbse_env%field_trace(i, n) = cmplx(rtbse_env%field(i), 0.0, kind=dp)
380 END DO
381 rtbse_env%time_trace(n) = rtbse_env%sim_time
382
383 ! Now, continue to file output
384 ! Get logger
385 logger => cp_get_default_logger()
386 ! Get file descriptor
387 field_unit = cp_print_key_unit_nr(logger, rtbse_env%field_section, extension=".dat")
388 IF (append) THEN
389 CALL print_rt_file(field_unit, xvals=rtbse_env%time_trace(n:n), &
390 yvals=rtbse_env%field_trace(:, n:n), &
391 xscale_opt=femtoseconds, comp_opt=rt_file_comp_real)
392 ELSE
393 CALL print_rt_file(field_unit, [ &
394 "# Time [fs]", &
395 " field x [at.u.]", &
396 " field y [at.u.]", &
397 " field z [at.u.]"], &
398 rtbse_env%time_trace(n:n), rtbse_env%field_trace(:, n:n), &
399 xscale_opt=femtoseconds, comp_opt=rt_file_comp_real)
400 END IF
401 CALL cp_print_key_finished_output(field_unit, logger, rtbse_env%field_section)
402
403 END SUBROUTINE output_field
404! **************************************************************************************************
405!> \brief Reads the field from the files provided by input - useful for the continuation run
406!> \param rtbse_env Entry point - gwbse environment
407!> \param rtp_section RTP input section
408! **************************************************************************************************
409 SUBROUTINE read_field(rtbse_env)
410 TYPE(rtbse_env_type) :: rtbse_env
411 TYPE(cp_logger_type), POINTER :: logger
412 CHARACTER(len=default_path_length) :: save_name
413 INTEGER :: k, n, field_unit
414 REAL(kind=dp), DIMENSION(3) :: real_field
415
416 ! Get logger
417 logger => cp_get_default_logger()
418 ! Get file name
419 save_name = cp_print_key_generate_filename(logger, rtbse_env%field_section, extension=".dat", my_local=.false.)
420 IF (file_exists(save_name)) THEN
421 CALL open_file(save_name, file_status="OLD", file_form="FORMATTED", file_action="READ", &
422 unit_number=field_unit)
423 ! Skip the first line - it contains headers
424 READ (field_unit, '()')
425 DO k = rtbse_env%sim_start_orig, rtbse_env%sim_start
426 n = k - rtbse_env%sim_start_orig + 1
427 READ (field_unit, '(E20.8E3,E20.8E3,E20.8E3,E20.8E3)') rtbse_env%time_trace(n), &
428 real_field(1), real_field(2), real_field(3)
429 rtbse_env%field_trace(:, n) = cmplx(real_field(:), 0.0, kind=dp)
430 ! Set the time units back to atomic units
431 rtbse_env%time_trace(n) = rtbse_env%time_trace(n)/femtoseconds
432 END DO
433 CALL close_file(field_unit)
434 ELSE IF (.NOT. rtbse_env%dft_control%rtp_control%apply_delta_pulse .AND. &
435 rtbse_env%dft_control%rtp_control%initial_wfn == use_rt_restart) THEN
436 cpwarn("Restart without RT field file - unknown field trace set to zero.")
437 END IF
438 END SUBROUTINE read_field
439
440! **************************************************************************************************
441!> \brief Outputs the expectation value of moments from a given density matrix
442!> \note Moments matrix is provided by the rtbse_env, uses rho_workspace(1:3)
443!> \param rtbse_env Entry point - gwbse environment
444!> \param rho Density matrix in AO basis
445!> \param rtp_section RTP section of the input parameters, where moments destination may be present
446! **************************************************************************************************
447 SUBROUTINE output_moments(rtbse_env, rho)
448 TYPE(rtbse_env_type) :: rtbse_env
449 TYPE(cp_cfm_type), DIMENSION(:), POINTER :: rho
450 INTEGER :: i, j, n
451 REAL(kind=dp), DIMENSION(3) :: moments_re
452 TYPE(cp_fm_type), DIMENSION(:), POINTER :: ws
453
454 n = rtbse_env%sim_step - rtbse_env%sim_start_orig + 1
455
456 ! In linearized RT-BSE rho and moments are MO-active sized; otherwise AO sized.
457 IF (ASSOCIATED(rtbse_env%real_workspace_mo)) THEN
458 ws => rtbse_env%real_workspace_mo
459 ELSE
460 ws => rtbse_env%real_workspace
461 END IF
462
463 DO j = 1, rtbse_env%n_spin
464 ! Need to transpose due to the definition of trace function
465 CALL cp_cfm_to_fm(msource=rho(j), mtargetr=ws(2))
466 DO i = 1, 3
467 ! Moments should be symmetric, test without transopose?
468 CALL cp_fm_transpose(rtbse_env%moments(i, j), ws(1))
469 CALL cp_fm_trace(ws(1), ws(2), moments_re(i))
470 ! Scale by spin degeneracy and electron charge
471 moments_re(i) = -moments_re(i)*rtbse_env%spin_degeneracy
472 rtbse_env%moments_trace(j, i, n) = cmplx(moments_re(i), 0.0, kind=dp)
473 END DO
474 ! Same for imaginary part
475 CALL cp_cfm_to_fm(msource=rho(j), mtargeti=ws(2))
476 DO i = 1, 3
477 CALL cp_fm_transpose(rtbse_env%moments(i, j), ws(1))
478 CALL cp_fm_trace(ws(1), ws(2), moments_re(i))
479 ! Scale by spin degeneracy and electron charge
480 moments_re(i) = -moments_re(i)*rtbse_env%spin_degeneracy
481 rtbse_env%moments_trace(j, i, n) = rtbse_env%moments_trace(j, i, n) + cmplx(0.0, moments_re(i), kind=dp)
482 END DO
483 END DO
484 ! Output to the file
485 CALL print_moments(rtbse_env%moments_section, rtbse_env%unit_nr, rtbse_env%moments_trace(:, :, n), &
486 rtbse_env%sim_time, .true., append_opt=(rtbse_env%sim_step /= rtbse_env%sim_start_orig))
487 END SUBROUTINE output_moments
488! **************************************************************************************************
489!> \brief Outputs the restart info (last finished iteration step) + restard density matrix
490!> \param restart_section Print key section for the restart files
491!> \param rho Density matrix in AO basis
492!> \param time_index Time index to be written into the info file
493! **************************************************************************************************
494 SUBROUTINE output_restart(rtbse_env, rho, time_index)
495 TYPE(rtbse_env_type), POINTER :: rtbse_env
496 TYPE(cp_cfm_type), DIMENSION(:), POINTER :: rho
497 INTEGER :: time_index
498 TYPE(cp_fm_type), DIMENSION(:), POINTER :: workspace
499 CHARACTER(len=17), DIMENSION(4) :: file_labels
500 TYPE(cp_logger_type), POINTER :: logger
501 INTEGER :: rho_unit_nr, i
502
503 ! Default labels distinguishing up to two spin species and real/imaginary parts
504 file_labels(1) = "_SPIN_A_RE.matrix"
505 file_labels(2) = "_SPIN_A_IM.matrix"
506 file_labels(3) = "_SPIN_B_RE.matrix"
507 file_labels(4) = "_SPIN_B_IM.matrix"
508
509 logger => cp_get_default_logger()
510
511 workspace => rtbse_env%real_workspace
512
513 DO i = 1, rtbse_env%n_spin
514 CALL cp_cfm_to_fm(rho(i), workspace(1), workspace(2))
515 ! Real part
516 rho_unit_nr = cp_print_key_unit_nr(logger, rtbse_env%restart_section, extension=file_labels(2*i - 1), &
517 file_form="UNFORMATTED", file_position="REWIND")
518 CALL cp_fm_write_unformatted(workspace(1), rho_unit_nr)
519 CALL cp_print_key_finished_output(rho_unit_nr, logger, rtbse_env%restart_section)
520 ! Imag part
521 rho_unit_nr = cp_print_key_unit_nr(logger, rtbse_env%restart_section, extension=file_labels(2*i), &
522 file_form="UNFORMATTED", file_position="REWIND")
523 CALL cp_fm_write_unformatted(workspace(2), rho_unit_nr)
524 CALL cp_print_key_finished_output(rho_unit_nr, logger, rtbse_env%restart_section)
525 ! Info
526 rho_unit_nr = cp_print_key_unit_nr(logger, rtbse_env%restart_section, extension=".info", &
527 file_form="UNFORMATTED", file_position="REWIND")
528 IF (rho_unit_nr > 0) WRITE (rho_unit_nr) time_index
529 CALL cp_print_key_finished_output(rho_unit_nr, logger, rtbse_env%restart_section)
530 END DO
531 END SUBROUTINE output_restart
532! **************************************************************************************************
533!> \brief Reads the density matrix from restart files and updates the starting time
534!> \param restart_section Print key section for the restart files
535!> \param rho Density matrix in AO basis
536!> \param time_index Time index to be written into the info file
537! **************************************************************************************************
538 SUBROUTINE read_restart(rtbse_env)
539 TYPE(rtbse_env_type), POINTER :: rtbse_env
540 TYPE(cp_logger_type), POINTER :: logger
541 CHARACTER(len=default_path_length) :: save_name, save_name_2
542 INTEGER :: rho_unit_nr, j
543 CHARACTER(len=17), DIMENSION(4) :: file_labels
544
545 ! This allows the delta kick and output of moment at time 0 in all cases
546 ! except the case when both imaginary and real parts of the density are read
547 rtbse_env%restart_extracted = .false.
548 logger => cp_get_default_logger()
549 ! Start by probing/loading info file
550 save_name = cp_print_key_generate_filename(logger, rtbse_env%restart_section, extension=".info", my_local=.false.)
551 IF (file_exists(save_name)) THEN
552 CALL open_file(save_name, file_status="OLD", file_form="UNFORMATTED", file_action="READ", &
553 unit_number=rho_unit_nr)
554 READ (rho_unit_nr) rtbse_env%sim_start
555 CALL close_file(rho_unit_nr)
556 IF (rtbse_env%unit_nr > 0) WRITE (rtbse_env%unit_nr, '(A31,I25,A24)') " RTBSE| Starting from timestep ", &
557 rtbse_env%sim_start, ", delta kick NOT applied"
558 ELSE
559 cpwarn("Restart required but no info file found - starting from sim_step given in input")
560 END IF
561
562 ! Default labels distinguishing up to two spin species and real/imaginary parts
563 file_labels(1) = "_SPIN_A_RE.matrix"
564 file_labels(2) = "_SPIN_A_IM.matrix"
565 file_labels(3) = "_SPIN_B_RE.matrix"
566 file_labels(4) = "_SPIN_B_IM.matrix"
567 DO j = 1, rtbse_env%n_spin
568 save_name = cp_print_key_generate_filename(logger, rtbse_env%restart_section, &
569 extension=file_labels(2*j - 1), my_local=.false.)
570 save_name_2 = cp_print_key_generate_filename(logger, rtbse_env%restart_section, &
571 extension=file_labels(2*j), my_local=.false.)
572 IF (file_exists(save_name) .AND. file_exists(save_name_2)) THEN
573 CALL open_file(save_name, file_status="OLD", file_form="UNFORMATTED", file_action="READ", &
574 unit_number=rho_unit_nr)
575 CALL cp_fm_read_unformatted(rtbse_env%real_workspace(1), rho_unit_nr)
576 CALL close_file(rho_unit_nr)
577 CALL open_file(save_name_2, file_status="OLD", file_form="UNFORMATTED", file_action="READ", &
578 unit_number=rho_unit_nr)
579 CALL cp_fm_read_unformatted(rtbse_env%real_workspace(2), rho_unit_nr)
580 CALL close_file(rho_unit_nr)
581 CALL cp_fm_to_cfm(rtbse_env%real_workspace(1), rtbse_env%real_workspace(2), &
582 rtbse_env%rho(j))
583 rtbse_env%restart_extracted = .true.
584 ELSE
585 cpwarn("Restart without some restart matrices - starting from SCF density.")
586 END IF
587 END DO
588 END SUBROUTINE read_restart
589! **************************************************************************************************
590!> \brief Linearized RT-BSE restart writer. Writes the restart set: lab-frame MO-active density
591!> matrices, the .info step index (sim_step = steps completed = the resume step), the
592!> once-per-run C_active gauge reference, and the appended RESTART.trace record feeding the
593!> FT prefix on continuation. All indices derive from sim_step so the .info/.trace
594!> bookkeeping cannot drift apart. (Full RTBSE uses the upstream output_restart above.)
595!> \param rtbse_env RT-BSE environment
596!> \param rho Density matrix (lab frame) to store
597! **************************************************************************************************
598 SUBROUTINE output_restart_linearized(rtbse_env, rho)
599 TYPE(rtbse_env_type), POINTER :: rtbse_env
600 TYPE(cp_cfm_type), DIMENSION(:), POINTER :: rho
601 TYPE(cp_fm_type), DIMENSION(:), POINTER :: workspace
602 CHARACTER(len=17), DIMENSION(4) :: file_labels
603 CHARACTER(len=16), DIMENSION(2) :: c_file_labels
604 TYPE(cp_logger_type), POINTER :: logger
605 INTEGER :: rho_unit_nr, i
606
607 ! Default labels distinguishing up to two spin species and real/imaginary parts
608 file_labels(1) = "_SPIN_A_RE.matrix"
609 file_labels(2) = "_SPIN_A_IM.matrix"
610 file_labels(3) = "_SPIN_B_RE.matrix"
611 file_labels(4) = "_SPIN_B_IM.matrix"
612 c_file_labels(1) = "_SPIN_A_C.matrix"
613 c_file_labels(2) = "_SPIN_B_C.matrix"
614
615 logger => cp_get_default_logger()
616
617 ! In linearized RT-BSE rho is MO-active sized; otherwise AO sized.
618 IF (ASSOCIATED(rtbse_env%real_workspace_mo)) THEN
619 workspace => rtbse_env%real_workspace_mo
620 ELSE
621 workspace => rtbse_env%real_workspace
622 END IF
623
624 DO i = 1, rtbse_env%n_spin
625 CALL cp_cfm_to_fm(rho(i), workspace(1), workspace(2))
626 ! Real part
627 rho_unit_nr = cp_print_key_unit_nr(logger, rtbse_env%restart_section, extension=file_labels(2*i - 1), &
628 file_form="UNFORMATTED", file_position="REWIND")
629 CALL cp_fm_write_unformatted(workspace(1), rho_unit_nr)
630 CALL cp_print_key_finished_output(rho_unit_nr, logger, rtbse_env%restart_section)
631 ! Imag part
632 rho_unit_nr = cp_print_key_unit_nr(logger, rtbse_env%restart_section, extension=file_labels(2*i), &
633 file_form="UNFORMATTED", file_position="REWIND")
634 CALL cp_fm_write_unformatted(workspace(2), rho_unit_nr)
635 CALL cp_print_key_finished_output(rho_unit_nr, logger, rtbse_env%restart_section)
636 ! Info
637 rho_unit_nr = cp_print_key_unit_nr(logger, rtbse_env%restart_section, extension=".info", &
638 file_form="UNFORMATTED", file_position="REWIND")
639 IF (rho_unit_nr > 0) WRITE (rho_unit_nr) rtbse_env%sim_step
640 CALL cp_print_key_finished_output(rho_unit_nr, logger, rtbse_env%restart_section)
641 END DO
642
643 ! Once-per-run C_active dump (linearized only): gauge reference for the restart basis bridge
644 IF (ASSOCIATED(rtbse_env%real_workspace_mo) .AND. .NOT. rtbse_env%restart_C_written) THEN
645 DO i = 1, rtbse_env%n_spin
646 rho_unit_nr = cp_print_key_unit_nr(logger, rtbse_env%restart_section, extension=c_file_labels(i), &
647 file_form="UNFORMATTED", file_position="REWIND")
648 CALL cp_fm_write_unformatted(rtbse_env%C_active(i), rho_unit_nr)
649 CALL cp_print_key_finished_output(rho_unit_nr, logger, rtbse_env%restart_section)
650 END DO
651 rtbse_env%restart_C_written = .true.
652 END IF
653
654 CALL write_restart_trace(rtbse_env)
655 END SUBROUTINE output_restart_linearized
656! **************************************************************************************************
657!> \brief Appends the current observable-trace record to RESTART.trace. Records are keyed by the
658!> observable slot n_slot = sim_step - sim_start_orig + 1 - the SAME index output_moments/
659!> output_field write (both drivers bump sim_step inside the propagation call before the
660!> output calls run). On the first call of a run the file is rewritten from memory (header +
661!> records 1..n_slot), truncating leftovers from an aborted run; subsequent calls append one
662!> record. Ionode writes; layout matches read_restart_trace verbatim.
663!> \param rtbse_env RT-BSE environment
664! **************************************************************************************************
665 SUBROUTINE write_restart_trace(rtbse_env)
666 TYPE(rtbse_env_type), POINTER :: rtbse_env
667 TYPE(cp_logger_type), POINTER :: logger
668 CHARACTER(len=default_path_length) :: save_name
669 INTEGER :: trace_unit, n, n_eps, n_slot
670
671 logger => cp_get_default_logger()
672 save_name = cp_print_key_generate_filename(logger, rtbse_env%restart_section, extension=".trace", my_local=.false.)
673
674 IF (rtbse_env%unit_nr > 0) THEN
675 n_slot = rtbse_env%sim_step - rtbse_env%sim_start_orig + 1
676 IF (ASSOCIATED(rtbse_env%real_workspace_mo)) THEN
677 ! scalar row count is safe: determine_active_mo_window takes the union window across
678 ! spins, so eps_active is rectangular (mo_active, n_spin) by construction
679 n_eps = SIZE(rtbse_env%eps_active, 1)
680 ELSE
681 n_eps = 0
682 END IF
683 IF (.NOT. rtbse_env%restart_trace_written) THEN
684 CALL open_file(save_name, file_status="UNKNOWN", file_form="UNFORMATTED", file_action="WRITE", &
685 file_position="REWIND", unit_number=trace_unit)
686 WRITE (trace_unit) restart_trace_version
687 IF (ASSOCIATED(rtbse_env%real_workspace_mo)) THEN
688 WRITE (trace_unit) rtbse_env%n_spin, rtbse_env%mo_active, rtbse_env%n_ao
689 ELSE
690 WRITE (trace_unit) rtbse_env%n_spin, rtbse_env%n_ao, rtbse_env%n_ao
691 END IF
692 WRITE (trace_unit) rtbse_env%sim_dt
693 WRITE (trace_unit) real(rtbse_env%dft_control%rtp_control%delta_pulse_direction, dp), &
694 rtbse_env%dft_control%rtp_control%delta_pulse_scale
695 WRITE (trace_unit) n_eps
696 IF (n_eps > 0) WRITE (trace_unit) rtbse_env%eps_active
697 DO n = 1, n_slot
698 WRITE (trace_unit) n, rtbse_env%time_trace(n), rtbse_env%field_trace(:, n), &
699 rtbse_env%moments_trace(:, :, n)
700 END DO
701 ELSE
702 CALL open_file(save_name, file_status="OLD", file_form="UNFORMATTED", file_action="WRITE", &
703 file_position="APPEND", unit_number=trace_unit)
704 WRITE (trace_unit) n_slot, rtbse_env%time_trace(n_slot), rtbse_env%field_trace(:, n_slot), &
705 rtbse_env%moments_trace(:, :, n_slot)
706 END IF
707 CALL close_file(trace_unit)
708 END IF
709 rtbse_env%restart_trace_written = .true.
710 END SUBROUTINE write_restart_trace
711! **************************************************************************************************
712!> \brief Early phase of the restart read: the starting step index from the .info file, the original
713!> run's dt peeked from the RESTART.trace header (so ENFORCE_MAX_DT can inherit it), and an
714!> SCF_GUESS hygiene check. Runs BEFORE initialize_maximum_timestep; the trace prefix records
715!> are loaded separately by read_restart_trace once the trace arrays are sized.
716!> \param rtbse_env RT-BSE environment
717! **************************************************************************************************
718 SUBROUTINE read_restart_info(rtbse_env)
719 TYPE(rtbse_env_type), POINTER :: rtbse_env
720 TYPE(cp_logger_type), POINTER :: logger
721 CHARACTER(len=default_path_length) :: save_name
722 INTEGER :: info_unit, trace_unit, version
723 TYPE(scf_control_type), POINTER :: scf_control
724
725 logger => cp_get_default_logger()
726
727 save_name = cp_print_key_generate_filename(logger, rtbse_env%restart_section, extension=".info", my_local=.false.)
728 IF (file_exists(save_name)) THEN
729 CALL open_file(save_name, file_status="OLD", file_form="UNFORMATTED", file_action="READ", &
730 unit_number=info_unit)
731 READ (info_unit) rtbse_env%sim_start
732 CALL close_file(info_unit)
733 IF (rtbse_env%unit_nr > 0) WRITE (rtbse_env%unit_nr, '(A31,I25,A24)') " RTBSE| Starting from timestep ", &
734 rtbse_env%sim_start, ", delta kick NOT applied"
735 ELSE
736 cpwarn("Restart required but no info file found - starting from sim_step given in input")
737 END IF
738
739 ! Peek the original run's dt from the trace header (version, dims record, dt) so ENFORCE_MAX_DT
740 ! can inherit it rather than recompute a window-dependent dt. The dims record is skipped here;
741 ! read_restart_trace re-reads the full header and validates it once the trace arrays are sized.
742 save_name = cp_print_key_generate_filename(logger, rtbse_env%restart_section, extension=".trace", my_local=.false.)
743 IF (file_exists(save_name)) THEN
744 CALL open_file(save_name, file_status="OLD", file_form="UNFORMATTED", file_action="READ", &
745 unit_number=trace_unit)
746 READ (trace_unit) version
747 IF (version == restart_trace_version) THEN
748 READ (trace_unit)
749 READ (trace_unit) rtbse_env%sim_dt_restart
750 END IF
751 CALL close_file(trace_unit)
752 END IF
753
754 ! Hygiene nudge only - correctness is protected by the restart basis bridge (linearized path)
755 NULLIFY (scf_control)
756 CALL get_qs_env(rtbse_env%qs_env, scf_control=scf_control)
757 IF (scf_control%density_guess /= restart_guess) THEN
758 cpwarn("RT_RESTART without SCF_GUESS RESTART - SCF may reconverge to a gauge-rotated MO basis.")
759 END IF
760 END SUBROUTINE read_restart_info
761! **************************************************************************************************
762!> \brief Reads the RESTART.trace prefix (records 1..sim_start) into the in-memory moment/field/
763!> time traces so the continuation FT covers the full history. Header guards: version,
764!> n_spin, dims, dt (abort); kick params (warn); eps_active > 0.1 meV (warn). All ranks read
765!> (the traces are replicated). Record layout matches write_restart_trace verbatim.
766!> \param rtbse_env RT-BSE environment
767! **************************************************************************************************
768 SUBROUTINE read_restart_trace(rtbse_env)
769 TYPE(rtbse_env_type), POINTER :: rtbse_env
770 TYPE(cp_logger_type), POINTER :: logger
771 CHARACTER(len=default_path_length) :: save_name, err_msg
772 INTEGER :: trace_unit, version, n_spin_file, &
773 n_basis_file, n_ao_file, n_eps, n, &
774 n_read_max, ios
775 REAL(kind=dp) :: dt_file, kick_scale_file, t_rec
776 REAL(kind=dp), DIMENSION(3) :: kick_dir_file
777 REAL(kind=dp), DIMENSION(:, :), ALLOCATABLE :: eps_file
778 COMPLEX(kind=dp), DIMENSION(3) :: field_rec
779 COMPLEX(kind=dp), DIMENSION(:, :), ALLOCATABLE :: mom_rec
780
781 logger => cp_get_default_logger()
782 save_name = cp_print_key_generate_filename(logger, rtbse_env%restart_section, extension=".trace", my_local=.false.)
783 ! No trace + real prior history: the FT would run on a zero prefix - either a guaranteed
784 ! multi_fft abort AFTER the full propagation (default FT%START_TIME=0, delta_t=0) or a
785 ! silently wrong tail-only spectrum (START_TIME>0). Fail fast instead.
786 IF (.NOT. file_exists(save_name)) THEN
787 IF (rtbse_env%sim_start > 0) THEN
788 CALL cp_abort(__location__, &
789 "RT_RESTART without RESTART.trace - the continuation FT would miss the pre-restart "// &
790 "history. Restore the original run's RESTART.trace next to the density restart files.")
791 END IF
792 RETURN
793 END IF
794
795 CALL open_file(save_name, file_status="OLD", file_form="UNFORMATTED", file_action="READ", &
796 unit_number=trace_unit)
797 READ (trace_unit) version
798 IF (version /= restart_trace_version) THEN
799 WRITE (err_msg, '(A,I0,A,I0)') "RESTART.trace: format version ", version, &
800 " does not match this binary's version ", restart_trace_version
801 CALL cp_abort(__location__, trim(err_msg))
802 END IF
803 READ (trace_unit) n_spin_file, n_basis_file, n_ao_file
804 IF (n_spin_file /= rtbse_env%n_spin) cpabort("RESTART.trace: n_spin mismatch")
805 IF (n_ao_file /= rtbse_env%n_ao) cpabort("RESTART.trace: n_ao mismatch")
806 ! v1 is strict same-window: the linearized active-MO count must match (D6)
807 IF (ASSOCIATED(rtbse_env%real_workspace_mo) .AND. n_basis_file /= rtbse_env%mo_active) THEN
808 CALL cp_abort(__location__, &
809 "RESTART.trace: active-MO count differs from the original run - same-window continuation only")
810 END IF
811 READ (trace_unit) dt_file
812 ! ENFORCE_MAX_DT inherits dt_file (read_restart_info -> initialize_maximum_timestep), so this
813 ! fires only on the manual path (ENFORCE off + user dt /= original); name the exact fix.
814 IF (abs(dt_file - rtbse_env%sim_dt) > 1.0e-12_dp*max(1.0_dp, abs(rtbse_env%sim_dt))) THEN
815 WRITE (err_msg, '(A,ES16.9,A)') &
816 "RESTART.trace: TIMESTEP differs from the original run - continuation undefined. "// &
817 "Set MD%TIMESTEP [fs] ", dt_file*femtoseconds, &
818 " or enable RTBSE%ENFORCE_MAX_DT to inherit it automatically."
819 CALL cp_abort(__location__, trim(err_msg))
820 END IF
821 READ (trace_unit) kick_dir_file, kick_scale_file
822 IF (maxval(abs(kick_dir_file - real(rtbse_env%dft_control%rtp_control%delta_pulse_direction, dp))) > 1.0e-12_dp .OR. &
823 abs(kick_scale_file - rtbse_env%dft_control%rtp_control%delta_pulse_scale) > 1.0e-12_dp) THEN
824 CALL cp_warn(__location__, &
825 "RESTART.trace: delta-kick parameters differ from the original run - FT normalization inconsistent.")
826 END IF
827 READ (trace_unit) n_eps
828 IF (n_eps > 0) THEN
829 ALLOCATE (eps_file(n_eps, rtbse_env%n_spin))
830 READ (trace_unit) eps_file
831 IF (ASSOCIATED(rtbse_env%real_workspace_mo)) THEN
832 IF (n_eps /= SIZE(rtbse_env%eps_active, 1)) THEN
833 CALL cp_abort(__location__, "RESTART.trace: active-window size mismatch")
834 END IF
835 ! eps_active is not populated yet (built later in the Hamiltonian init); stash for the
836 ! post-Hamiltonian consistency check in check_restart_eps_consistency.
837 ALLOCATE (rtbse_env%eps_active_restart(n_eps, rtbse_env%n_spin))
838 rtbse_env%eps_active_restart(:, :) = eps_file
839 END IF
840 DEALLOCATE (eps_file)
841 END IF
842
843 ALLOCATE (mom_rec(rtbse_env%n_spin, 3))
844 n_read_max = 0
845 DO
846 READ (trace_unit, iostat=ios) n, t_rec, field_rec, mom_rec
847 IF (ios /= 0) EXIT
848 ! Fill through slot sim_start+1: both drivers bump sim_step inside the propagation call
849 ! (etrs_scf_loop / solve_rk4_timestep), so the live loop's first step writes slot
850 ! sim_start+2 and slot sim_start+1 must be reloaded here.
851 IF (n > rtbse_env%sim_start + 1) EXIT
852 IF (n > SIZE(rtbse_env%time_trace)) THEN
853 cpabort("RESTART.trace: record index exceeds trace size - increase MOTION%MD%STEPS")
854 END IF
855 rtbse_env%time_trace(n) = t_rec
856 rtbse_env%field_trace(:, n) = field_rec
857 rtbse_env%moments_trace(:, :, n) = mom_rec
858 n_read_max = max(n_read_max, n)
859 END DO
860 DEALLOCATE (mom_rec)
861 CALL close_file(trace_unit)
862 IF (n_read_max < rtbse_env%sim_start) THEN
863 cpwarn("RESTART.trace: fewer records than restart step - trace prefix incomplete.")
864 END IF
865 END SUBROUTINE read_restart_trace
866! **************************************************************************************************
867!> \brief Compares the original run's active eigenvalues (stashed by read_restart_trace) against
868!> the recomputed eps_active, once the Hamiltonian is built. Prints the max deviation and
869!> warns above 0.1 meV (GW analytic continuation gives run-to-run QP noise above FP, so the
870!> threshold is deliberately loose). Frees the stash. No-op if nothing was stashed.
871!> \param rtbse_env RT-BSE environment
872! **************************************************************************************************
873 SUBROUTINE check_restart_eps_consistency(rtbse_env)
874 TYPE(rtbse_env_type), POINTER :: rtbse_env
875 REAL(kind=dp) :: eps_dev
876
877 IF (.NOT. ASSOCIATED(rtbse_env%eps_active_restart)) RETURN
878
879 eps_dev = maxval(abs(rtbse_env%eps_active_restart - rtbse_env%eps_active))
880 IF (rtbse_env%unit_nr > 0) WRITE (rtbse_env%unit_nr, '(A,ES12.3,A)') &
881 " RTBSE| Restart eps_active max deviation vs original run ", eps_dev, " Ha"
882 ! 0.1 meV = 1.0e-4 eV, converted to Ha via evolt (Ha -> eV factor)
883 IF (eps_dev > 1.0e-4_dp/evolt) THEN
884 CALL cp_warn(__location__, &
885 "RESTART.trace: active eigenvalues deviate beyond 0.1 meV - "// &
886 "Hamiltonian changed; continuation is physically inconsistent.")
887 END IF
888
889 DEALLOCATE (rtbse_env%eps_active_restart)
890 NULLIFY (rtbse_env%eps_active_restart)
891 END SUBROUTINE check_restart_eps_consistency
892! **************************************************************************************************
893!> \brief Late phase of the restart read: overwrites rho from the lab-frame restart matrices and
894!> sets restart_extracted. MO-active for the linearized path, AO otherwise
895!> (cp_fm_read_unformatted aborts on a size mismatch, guarding a changed active window).
896!> \param rtbse_env RT-BSE environment
897! **************************************************************************************************
898 SUBROUTINE read_restart_density(rtbse_env)
899 TYPE(rtbse_env_type), POINTER :: rtbse_env
900 TYPE(cp_logger_type), POINTER :: logger
901 CHARACTER(len=default_path_length) :: save_name, save_name_2
902 INTEGER :: rho_unit_nr, j
903 CHARACTER(len=17), DIMENSION(4) :: file_labels
904 TYPE(cp_fm_type), DIMENSION(:), POINTER :: ws
905
906 ! This allows the delta kick and output of moment at time 0 in all cases
907 ! except the case when both imaginary and real parts of the density are read
908 rtbse_env%restart_extracted = .false.
909 logger => cp_get_default_logger()
910
911 IF (ASSOCIATED(rtbse_env%real_workspace_mo)) THEN
912 ws => rtbse_env%real_workspace_mo
913 ELSE
914 ws => rtbse_env%real_workspace
915 END IF
916
917 ! Default labels distinguishing up to two spin species and real/imaginary parts
918 file_labels(1) = "_SPIN_A_RE.matrix"
919 file_labels(2) = "_SPIN_A_IM.matrix"
920 file_labels(3) = "_SPIN_B_RE.matrix"
921 file_labels(4) = "_SPIN_B_IM.matrix"
922 DO j = 1, rtbse_env%n_spin
923 save_name = cp_print_key_generate_filename(logger, rtbse_env%restart_section, &
924 extension=file_labels(2*j - 1), my_local=.false.)
925 save_name_2 = cp_print_key_generate_filename(logger, rtbse_env%restart_section, &
926 extension=file_labels(2*j), my_local=.false.)
927 IF (file_exists(save_name) .AND. file_exists(save_name_2)) THEN
928 CALL open_file(save_name, file_status="OLD", file_form="UNFORMATTED", file_action="READ", &
929 unit_number=rho_unit_nr)
930 CALL cp_fm_read_unformatted(ws(1), rho_unit_nr)
931 CALL close_file(rho_unit_nr)
932 CALL open_file(save_name_2, file_status="OLD", file_form="UNFORMATTED", file_action="READ", &
933 unit_number=rho_unit_nr)
934 CALL cp_fm_read_unformatted(ws(2), rho_unit_nr)
935 CALL close_file(rho_unit_nr)
936 CALL cp_fm_to_cfm(ws(1), ws(2), &
937 rtbse_env%rho(j))
938 rtbse_env%restart_extracted = .true.
939 ELSE
940 cpwarn("Restart without some restart matrices - starting from SCF density.")
941 END IF
942 END DO
943 END SUBROUTINE read_restart_density
944! **************************************************************************************************
945!> \brief Reads the previous run's C_active slabs (gauge reference for the restart basis bridge).
946!> \param rtbse_env RT-BSE environment
947!> \param C_old Caller-created fm array (n_spin) on fm_struct_ao_mo_active, filled on success
948!> \param found .TRUE. iff all per-spin C files were present and read
949! **************************************************************************************************
950 SUBROUTINE read_restart_c(rtbse_env, C_old, found)
951 TYPE(rtbse_env_type), POINTER :: rtbse_env
952 TYPE(cp_fm_type), DIMENSION(:), POINTER :: c_old
953 LOGICAL, INTENT(OUT) :: found
954 TYPE(cp_logger_type), POINTER :: logger
955 CHARACTER(len=default_path_length) :: save_name
956 CHARACTER(len=16), DIMENSION(2) :: c_file_labels
957 INTEGER :: c_unit, j
958
959 c_file_labels(1) = "_SPIN_A_C.matrix"
960 c_file_labels(2) = "_SPIN_B_C.matrix"
961 logger => cp_get_default_logger()
962 found = .false.
963 DO j = 1, rtbse_env%n_spin
964 save_name = cp_print_key_generate_filename(logger, rtbse_env%restart_section, &
965 extension=c_file_labels(j), my_local=.false.)
966 IF (.NOT. file_exists(save_name)) THEN
967 cpwarn("Restart without C_active file - assuming identical MO gauge (no basis bridge).")
968 RETURN
969 END IF
970 CALL open_file(save_name, file_status="OLD", file_form="UNFORMATTED", file_action="READ", &
971 unit_number=c_unit)
972 CALL cp_fm_read_unformatted(c_old(j), c_unit)
973 CALL close_file(c_unit)
974 END DO
975 found = .true.
976 END SUBROUTINE read_restart_c
977END MODULE rt_bse_io
Represents a complex full matrix distributed on many processors.
subroutine, public cp_fm_to_cfm(msourcer, msourcei, mtarget)
Construct a complex full matrix by taking its real and imaginary parts from two separate real-value f...
subroutine, public cp_cfm_to_fm(msource, mtargetr, mtargeti)
Copy real and imaginary parts of a complex full matrix into separate real-value full matrices.
Utility routines to open and close files. Tracking of preconnections.
Definition cp_files.F:16
subroutine, public open_file(file_name, file_status, file_form, file_action, file_position, file_pad, unit_number, debug, skip_get_unit_number, file_access)
Opens the requested file using a free unit number.
Definition cp_files.F:311
subroutine, public close_file(unit_number, file_status, keep_preconnection)
Close an open file given by its logical unit number. Optionally, keep the file and unit preconnected.
Definition cp_files.F:122
logical function, public file_exists(file_name)
Checks if file exists, considering also the file discovery mechanism.
Definition cp_files.F:504
Basic linear algebra operations for full matrices.
subroutine, public cp_fm_transpose(matrix, matrixt)
transposes a matrix matrixt = matrix ^ T
represent a full matrix distributed on many processors
Definition cp_fm_types.F:15
subroutine, public cp_fm_write_unformatted(fm, unit)
...
subroutine, public cp_fm_read_unformatted(fm, unit)
...
subroutine, public cp_fm_write_formatted(fm, unit, header, value_format)
Write out a full matrix in plain text.
various routines to log and control the output. The idea is that decisions about where to log should ...
type(cp_logger_type) function, pointer, public cp_get_default_logger()
returns the default logger
routines to handle the output, The idea is to remove the decision of wheter to output and what to out...
integer function, public cp_print_key_unit_nr(logger, basis_section, print_key_path, extension, middle_name, local, log_filename, ignore_should_output, file_form, file_position, file_action, file_status, do_backup, on_file, is_new_file, mpi_io, fout)
...
integer, parameter, public low_print_level
integer, parameter, public medium_print_level
character(len=default_path_length) function, public cp_print_key_generate_filename(logger, print_key, middle_name, extension, my_local)
Utility function that returns a unit number to write the print key. Might open a file with a unique f...
subroutine, public cp_print_key_finished_output(unit_nr, logger, basis_section, print_key_path, local, ignore_should_output, on_file, mpi_io)
should be called after you finish working with a unit obtained with cp_print_key_unit_nr,...
collects all constants needed in input so that they can be used without circular dependencies
integer, parameter, public do_bch
integer, parameter, public use_rt_restart
integer, parameter, public do_exact
integer, parameter, public rtp_bse_ham_g0w0
integer, parameter, public restart_guess
integer, parameter, public rtp_bse_ham_ks
objects that represent the structure of input sections and the data contained in an input section
Defines the basic variable types.
Definition kinds.F:23
integer, parameter, public dp
Definition kinds.F:34
integer, parameter, public default_path_length
Definition kinds.F:58
Definition of physical constants:
Definition physcon.F:68
real(kind=dp), parameter, public femtoseconds
Definition physcon.F:153
real(kind=dp), parameter, public evolt
Definition physcon.F:183
subroutine, public get_qs_env(qs_env, atomic_kind_set, qs_kind_set, cell, super_cell, cell_ref, use_ref_cell, kpoints, dft_control, mos, sab_orb, sab_all, qmmm, qmmm_periodic, mimic, sac_ae, sac_ppl, sac_lri, sap_ppnl, sab_vdw, sab_scp, sap_oce, sab_lrc, sab_se, sab_xtbe, sab_tbe, sab_core, sab_xb, sab_xtb_pp, sab_xtb_nonbond, sab_almo, sab_kp, sab_kp_nosym, sab_cneo, particle_set, energy, force, matrix_h, matrix_h_im, matrix_ks, matrix_ks_im, matrix_vxc, run_rtp, rtp, matrix_h_kp, matrix_h_im_kp, matrix_ks_kp, matrix_ks_im_kp, matrix_vxc_kp, kinetic_kp, matrix_s_kp, matrix_w_kp, matrix_s_ri_aux_kp, matrix_s, matrix_s_ri_aux, matrix_w, matrix_p_mp2, matrix_p_mp2_admm, matrix_vhxc, rho, rho_xc, pw_env, ewald_env, ewald_pw, active_space, mpools, input, para_env, blacs_env, scf_control, rel_control, kinetic, qs_charges, vppl, xcint_weights, rho_core, rho_nlcc, rho_nlcc_g, ks_env, ks_qmmm_env, wf_history, scf_env, local_particles, local_molecules, distribution_2d, dbcsr_dist, molecule_kind_set, molecule_set, subsys, cp_subsys, oce, local_rho_set, rho_atom_set, task_list, task_list_soft, rho0_atom_set, rho0_mpole, rhoz_set, rhoz_cneo_set, ecoul_1c, rho0_s_rs, rho0_s_gs, rhoz_cneo_s_rs, rhoz_cneo_s_gs, do_kpoints, has_unit_metric, requires_mo_derivs, mo_derivs, mo_loc_history, nkind, natom, nelectron_total, nelectron_spin, efield, neighbor_list_id, linres_control, xas_env, virial, cp_ddapc_env, cp_ddapc_ewald, outer_scf_history, outer_scf_ihistory, x_data, et_coupling, dftb_potential, results, se_taper, se_store_int_env, se_nddo_mpole, se_nonbond_env, admm_env, lri_env, lri_density, exstate_env, ec_env, harris_env, dispersion_env, gcp_env, vee, rho_external, external_vxc, mask, mp2_env, bs_env, kg_env, wanniercentres, atprop, ls_scf_env, do_transport, transport_env, v_hartree_rspace, s_mstruct_changed, rho_changed, potential_changed, forces_up_to_date, mscfg_env, almo_scf_env, gradient_history, variable_history, embed_pot, spin_embed_pot, polar_env, mos_last_converged, eeq, rhs, do_rixs, tb_tblite)
Get the QUICKSTEP environment.
Input/output from the propagation via RT-BSE method.
Definition rt_bse_io.F:13
subroutine, public read_restart_c(rtbse_env, c_old, found)
Reads the previous run's C_active slabs (gauge reference for the restart basis bridge).
Definition rt_bse_io.F:951
subroutine, public output_restart_linearized(rtbse_env, rho)
Linearized RT-BSE restart writer. Writes the restart set: lab-frame MO-active density matrices,...
Definition rt_bse_io.F:599
subroutine, public print_rtbse_header_info(rtbse_env)
Writes the header and basic info to the standard output.
Definition rt_bse_io.F:91
subroutine, public output_mos_covariant(rtbse_env, ham, print_key_section)
Outputs the matrix in MO basis for matrix components corresponding to covariant representation,...
Definition rt_bse_io.F:327
subroutine, public output_restart(rtbse_env, rho, time_index)
Outputs the restart info (last finished iteration step) + restard density matrix.
Definition rt_bse_io.F:495
subroutine, public check_restart_eps_consistency(rtbse_env)
Compares the original run's active eigenvalues (stashed by read_restart_trace) against the recomputed...
Definition rt_bse_io.F:874
subroutine, public print_etrs_info(rtbse_env, step, metric)
Writes the update after single etrs iteration - only for log level > medium.
Definition rt_bse_io.F:140
subroutine, public read_field(rtbse_env)
Reads the field from the files provided by input - useful for the continuation run.
Definition rt_bse_io.F:410
subroutine, public print_etrs_info_header(rtbse_env)
Writes the header for the etrs iteration updates - only for log level > medium.
Definition rt_bse_io.F:157
subroutine, public output_mos_contravariant(rtbse_env, rho, print_key_section)
Outputs the matrix in MO basis for matrix coefficients corresponding to contravariant operator,...
Definition rt_bse_io.F:261
subroutine, public output_field(rtbse_env, append_opt)
Prints the current field components into a file provided by input.
Definition rt_bse_io.F:365
subroutine, public print_timestep_info(rtbse_env, step, electron_num_re, convergence, etrs_num, step_walltime)
Writes the summary line of a completed propagation timestep.
Definition rt_bse_io.F:178
subroutine, public read_restart_info(rtbse_env)
Early phase of the restart read: the starting step index from the .info file, the original run's dt p...
Definition rt_bse_io.F:719
subroutine, public read_restart(rtbse_env)
Reads the density matrix from restart files and updates the starting time.
Definition rt_bse_io.F:539
subroutine, public read_restart_density(rtbse_env)
Late phase of the restart read: overwrites rho from the lab-frame restart matrices and sets restart_e...
Definition rt_bse_io.F:899
subroutine, public read_restart_trace(rtbse_env)
Reads the RESTART.trace prefix (records 1..sim_start) into the in-memory moment/field/ time traces so...
Definition rt_bse_io.F:769
subroutine, public output_moments(rtbse_env, rho)
Outputs the expectation value of moments from a given density matrix.
Definition rt_bse_io.F:448
Data storage and other types for propagation via RT-BSE method.
subroutine, public multiply_cfm_fm(trans_c, trans_r, na, nb, nc, alpha, matrix_c, matrix_r, beta, res)
Multiplies complex matrix by a real matrix from the right.
subroutine, public multiply_fm_cfm(trans_r, trans_c, na, nb, nc, alpha, matrix_r, matrix_c, beta, res)
Multiplies real matrix by a complex matrix from the right.
Routine for the real time propagation output.
subroutine, public print_rt_file(rt_unit, headers, xvals, yvals, prefix, prefix_format, xscale_opt, comp_opt)
...
subroutine, public print_moments(moments_section, info_unit, moments, time, imag_opt, append_opt)
Print the dipole moments into a file.
integer, parameter, public rt_file_comp_real
parameters that control an scf iteration
Represent a complex full matrix.
represent a full matrix
type of a logger, at the moment it contains just a print level starting at which level it should be l...