(git:98357aa)
Loading...
Searching...
No Matches
negf_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 Routines for reading and writing NEGF restart files.
10!> \author Dmitry Ryndyk (12.2025)
11! **************************************************************************************************
12MODULE negf_io
13
14 USE cp_files, ONLY: close_file,&
22 USE kinds, ONLY: default_path_length,&
24 dp
25#include "./base/base_uses.f90"
26
27 IMPLICIT NONE
28
29 PRIVATE
30
31 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'negf_io'
32
33 PUBLIC :: negf_restart_file_name, &
36
37CONTAINS
38
39! **************************************************************************************************
40!> \brief Checks if the restart file exists and returns the filename.
41!> \param filename ...
42!> \param exist ...
43!> \param negf_section ...
44!> \param logger ...
45!> \param icontact ...
46!> \param ispin ...
47!> \param h00 ...
48!> \param h01 ...
49!> \param s00 ...
50!> \param s01 ...
51!> \param h ...
52!> \param s ...
53!> \param hc ...
54!> \param sc ...
55!> \param h_scf ...
56!> \par History
57!> * 12.2025 created [Dmitry Ryndyk]
58! **************************************************************************************************
59 SUBROUTINE negf_restart_file_name(filename, exist, negf_section, logger, icontact, ispin, h00, h01, &
60 s00, s01, h, s, hc, sc, h_scf)
61 CHARACTER(LEN=default_path_length), INTENT(OUT) :: filename
62 LOGICAL, INTENT(OUT) :: exist
63 TYPE(section_vals_type), POINTER :: negf_section
64 TYPE(cp_logger_type), POINTER :: logger
65 INTEGER, INTENT(IN), OPTIONAL :: icontact, ispin
66 LOGICAL, INTENT(IN), OPTIONAL :: h00, h01, s00, s01, h, s, hc, sc, h_scf
67
68 CHARACTER(len=default_string_length) :: middle_name, string1, string2
69 LOGICAL :: my_h, my_h00, my_h01, my_h_scf, my_hc, &
70 my_s, my_s00, my_s01, my_sc
71 TYPE(section_vals_type), POINTER :: contact_section, print_key
72
73 my_h00 = .false.
74 IF (PRESENT(h00)) my_h00 = h00
75 my_h01 = .false.
76 IF (PRESENT(h01)) my_h01 = h01
77 my_s00 = .false.
78 IF (PRESENT(s00)) my_s00 = s00
79 my_s01 = .false.
80 IF (PRESENT(s01)) my_s01 = s01
81 my_h = .false.
82 IF (PRESENT(h)) my_h = h
83 my_s = .false.
84 IF (PRESENT(s)) my_s = s
85 my_hc = .false.
86 IF (PRESENT(hc)) my_hc = hc
87 my_sc = .false.
88 IF (PRESENT(sc)) my_sc = sc
89 my_h_scf = .false.
90 IF (PRESENT(h_scf)) my_h_scf = h_scf
91
92 exist = .false.
93
94 IF (my_h00 .OR. my_h01 .OR. my_s00 .OR. my_s01) THEN
95 IF (.NOT. PRESENT(icontact)) THEN
96 cpabort("Missing contact index for NEGF restart filename")
97 END IF
98 WRITE (string1, *) icontact
99
100 IF (my_h00 .OR. my_h01) THEN
101 IF (.NOT. PRESENT(ispin)) THEN
102 cpabort("Missing spin index for NEGF restart filename")
103 END IF
104 WRITE (string2, *) ispin
105 END IF
106
107 ! Try to read from the filename that is generated automatically from the print key.
108 contact_section => section_vals_get_subs_vals(negf_section, "CONTACT")
109 print_key => section_vals_get_subs_vals(contact_section, "RESTART", i_rep_section=icontact)
110
111 IF (my_h00) THEN
112 IF (ispin == 0) THEN
113 middle_name = "N"//trim(string1)//"-H00"
114 ELSE
115 middle_name = "N"//trim(string1)//"-H00-S"//trim(string2)
116 END IF
117 filename = negf_generate_filename(logger, print_key, middle_name=middle_name, &
118 extension=".hs", my_local=.false.)
119 END IF
120
121 IF (my_h01) THEN
122 IF (ispin == 0) THEN
123 middle_name = "N"//trim(string1)//"-H01"
124 ELSE
125 middle_name = "N"//trim(string1)//"-H01-S"//trim(string2)
126 END IF
127 filename = negf_generate_filename(logger, print_key, middle_name=middle_name, &
128 extension=".hs", my_local=.false.)
129 END IF
130
131 IF (my_s00) THEN
132 middle_name = "N"//trim(string1)//"-S00"
133 filename = negf_generate_filename(logger, print_key, middle_name=middle_name, &
134 extension=".hs", my_local=.false.)
135 END IF
136
137 IF (my_s01) THEN
138 middle_name = "N"//trim(string1)//"-S01"
139 filename = negf_generate_filename(logger, print_key, middle_name=middle_name, &
140 extension=".hs", my_local=.false.)
141 END IF
142 END IF
143
144 IF (my_h .OR. my_s .OR. my_hc .OR. my_sc) THEN
145 IF (my_h .OR. my_hc) THEN
146 IF (.NOT. PRESENT(ispin)) THEN
147 cpabort("Missing spin index for NEGF restart filename")
148 END IF
149 WRITE (string2, *) ispin
150 END IF
151
152 IF (my_hc .OR. my_sc) THEN
153 IF (.NOT. PRESENT(icontact)) THEN
154 cpabort("Missing contact index for NEGF restart filename")
155 END IF
156 WRITE (string1, *) icontact
157 END IF
158
159 ! Try to read from the filename that is generated automatically from the print key.
160 print_key => section_vals_get_subs_vals(negf_section, "SCATTERING_REGION%RESTART")
161
162 IF (my_h) THEN
163 IF (ispin == 0) THEN
164 middle_name = "Hs"
165 ELSE
166 middle_name = "Hs-S"//trim(string2)
167 END IF
168 filename = negf_generate_filename(logger, print_key, middle_name=middle_name, &
169 extension=".hs", my_local=.false.)
170 END IF
171
172 IF (my_s) THEN
173 middle_name = "Ss"
174 filename = negf_generate_filename(logger, print_key, middle_name=middle_name, &
175 extension=".hs", my_local=.false.)
176 END IF
177
178 IF (my_hc) THEN
179 IF (ispin == 0) THEN
180 middle_name = "Hsc-N"//trim(string1)
181 ELSE
182 middle_name = "Hsc-N"//trim(string1)//"-S"//trim(string2)
183 END IF
184 filename = negf_generate_filename(logger, print_key, middle_name=middle_name, &
185 extension=".hs", my_local=.false.)
186 END IF
187
188 IF (my_sc) THEN
189 middle_name = "Ssc-N"//trim(string1)
190 filename = negf_generate_filename(logger, print_key, middle_name=middle_name, &
191 extension=".hs", my_local=.false.)
192 END IF
193 END IF
194
195 IF (my_h_scf) THEN
196 ! Try to read from the filename that is generated automatically from the print key.
197 print_key => section_vals_get_subs_vals(negf_section, "PRINT%RESTART")
198 filename = negf_generate_filename(logger, print_key, &
199 extension="", my_local=.false., iter_string=.true.)
200 END IF
201
202 INQUIRE (file=filename, exist=exist)
203
204 END SUBROUTINE negf_restart_file_name
205
206! **************************************************************************************************
207!> \brief ...
208!> \param logger the logger for the parallel environment, iteration info
209!> and filename generation
210!> \param print_key ...
211!> \param middle_name name to be added to the generated filename, useful when
212!> print_key activates different distinct outputs, to be able to
213!> distinguish them
214!> \param extension extension to be applied to the filename (including the ".")
215!> \param my_local if the unit should be local to this task, or global to the
216!> program (defaults to false).
217!> \param iter_string ...
218!> \return ...
219!> \par History
220!> * 12.2025 created [Dmitry Ryndyk]
221! **************************************************************************************************
222 FUNCTION negf_generate_filename(logger, print_key, middle_name, extension, &
223 my_local, iter_string) RESULT(filename)
224 TYPE(cp_logger_type), POINTER :: logger
225 TYPE(section_vals_type), POINTER :: print_key
226 CHARACTER(len=*), INTENT(IN), OPTIONAL :: middle_name
227 CHARACTER(len=*), INTENT(IN) :: extension
228 LOGICAL, INTENT(IN), OPTIONAL :: my_local, iter_string
229 CHARACTER(len=default_path_length) :: filename
230
231 CHARACTER(len=default_path_length) :: outname, outpath, postfix, root
232 CHARACTER(len=default_string_length) :: my_middle_name
233 INTEGER :: my_ind1, my_ind2
234 LOGICAL :: has_root
235
236 CALL section_vals_val_get(print_key, "FILENAME", c_val=outpath)
237 IF (outpath(1:1) == '=') THEN
238 cpassert(len(outpath) - 1 <= len(filename))
239 filename = outpath(2:)
240 RETURN
241 END IF
242 IF (outpath == "__STD_OUT__") outpath = ""
243 outname = outpath
244 has_root = .false.
245 my_ind1 = index(outpath, "/")
246 my_ind2 = len_trim(outpath)
247 IF (my_ind1 /= 0) THEN
248 has_root = .true.
249 DO WHILE (index(outpath(my_ind1 + 1:my_ind2), "/") /= 0)
250 my_ind1 = index(outpath(my_ind1 + 1:my_ind2), "/") + my_ind1
251 END DO
252 IF (my_ind1 == my_ind2) THEN
253 outname = ""
254 ELSE
255 outname = outpath(my_ind1 + 1:my_ind2)
256 END IF
257 END IF
258
259 IF (PRESENT(middle_name)) THEN
260 IF (outname /= "") THEN
261 my_middle_name = "-"//trim(outname)//"-"//middle_name
262 ELSE
263 my_middle_name = "-"//middle_name
264 END IF
265 ELSE
266 IF (outname /= "") THEN
267 my_middle_name = "-"//trim(outname)
268 ELSE
269 my_middle_name = ""
270 END IF
271 END IF
272
273 IF (.NOT. has_root) THEN
274 root = trim(logger%iter_info%project_name)//trim(my_middle_name)
275 ELSE IF (outname == "") THEN
276 root = outpath(1:my_ind1)//trim(logger%iter_info%project_name)//trim(my_middle_name)
277 ELSE
278 root = outpath(1:my_ind1)//my_middle_name(2:len_trim(my_middle_name))
279 END IF
280
281 postfix = extension
282 IF (PRESENT(iter_string)) THEN
283 IF (iter_string) THEN
284 ! use the cp_iter_string as a postfix
285 postfix = "-"//trim(cp_iter_string(logger%iter_info, print_key=print_key, for_file=.true.))
286 IF (trim(postfix) == "-") postfix = ""
287 ! and add the extension
288 postfix = trim(postfix)//extension
289 END IF
290 END IF
291
292 ! and let the logger generate the filename
293 CALL cp_logger_generate_filename(logger, res=filename, &
294 root=root, postfix=postfix, local=my_local)
295
296 END FUNCTION negf_generate_filename
297
298! **************************************************************************************************
299!> \brief Prints full matrix to a file.
300!> \param filename ...
301!> \param matrix ...
302!> \par History
303!> * 12.2025 created [Dmitry Ryndyk]
304! **************************************************************************************************
305 SUBROUTINE negf_print_matrix_to_file(filename, matrix)
306 CHARACTER(LEN=default_path_length), INTENT(IN) :: filename
307 REAL(kind=dp), DIMENSION(:, :), INTENT(IN) :: matrix
308
309 CHARACTER(len=100) :: sfmt
310 INTEGER :: i, j, ncol, nrow, print_unit
311
312 CALL open_file(file_name=filename, file_status="REPLACE", &
313 file_form="FORMATTED", file_action="WRITE", &
314 file_position="REWIND", unit_number=print_unit)
315
316 nrow = SIZE(matrix, 1)
317 ncol = SIZE(matrix, 2)
318 WRITE (sfmt, "('(',i0,'(E15.5))')") ncol
319 WRITE (print_unit, *) nrow, ncol
320 DO i = 1, nrow
321 WRITE (print_unit, sfmt) (matrix(i, j), j=1, ncol)
322 END DO
323
324 CALL close_file(print_unit)
325
326 END SUBROUTINE negf_print_matrix_to_file
327
328! **************************************************************************************************
329!> \brief Reads full matrix from a file.
330!> \param filename ...
331!> \param matrix ...
332!> \par History
333!> * 12.2025 created [Dmitry Ryndyk]
334! **************************************************************************************************
335 SUBROUTINE negf_read_matrix_from_file(filename, matrix)
336 CHARACTER(LEN=default_path_length), INTENT(IN) :: filename
337 REAL(kind=dp), DIMENSION(:, :), INTENT(INOUT) :: matrix
338
339 INTEGER :: i, j, ncol, nrow, print_unit
340
341 CALL open_file(file_name=filename, file_status="OLD", &
342 file_form="FORMATTED", file_action="READ", &
343 file_position="REWIND", unit_number=print_unit)
344
345 READ (print_unit, *) nrow, ncol
346 DO i = 1, nrow
347 READ (print_unit, *) (matrix(i, j), j=1, ncol)
348 END DO
349
350 CALL close_file(print_unit)
351
352 END SUBROUTINE negf_read_matrix_from_file
353
354END MODULE negf_io
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
various routines to log and control the output. The idea is that decisions about where to log should ...
subroutine, public cp_logger_generate_filename(logger, res, root, postfix, local)
generates a unique filename (ie adding eventual suffixes and process ids)
routines to handle the output, The idea is to remove the decision of wheter to output and what to out...
character(len=default_string_length) function, public cp_iter_string(iter_info, print_key, for_file)
returns the iteration string, a string that is useful to create unique filenames (once you trim it)
objects that represent the structure of input sections and the data contained in an input section
recursive type(section_vals_type) function, pointer, public section_vals_get_subs_vals(section_vals, subsection_name, i_rep_section, can_return_null)
returns the values of the requested subsection
subroutine, public section_vals_val_get(section_vals, keyword_name, i_rep_section, i_rep_val, n_rep_val, val, l_val, i_val, r_val, c_val, l_vals, i_vals, r_vals, c_vals, explicit)
returns the requested value
Defines the basic variable types.
Definition kinds.F:23
integer, parameter, public dp
Definition kinds.F:34
integer, parameter, public default_string_length
Definition kinds.F:57
integer, parameter, public default_path_length
Definition kinds.F:58
Routines for reading and writing NEGF restart files.
Definition negf_io.F:12
subroutine, public negf_restart_file_name(filename, exist, negf_section, logger, icontact, ispin, h00, h01, s00, s01, h, s, hc, sc, h_scf)
Checks if the restart file exists and returns the filename.
Definition negf_io.F:61
subroutine, public negf_print_matrix_to_file(filename, matrix)
Prints full matrix to a file.
Definition negf_io.F:306
subroutine, public negf_read_matrix_from_file(filename, matrix)
Reads full matrix from a file.
Definition negf_io.F:336
type of a logger, at the moment it contains just a print level starting at which level it should be l...