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