(git:495eafe)
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 WRITE (string1, *) icontact
95 WRITE (string2, *) ispin
96
97 ! try to read from the filename that is generated automatically from the printkey
98 contact_section => section_vals_get_subs_vals(negf_section, "CONTACT")
99 print_key => section_vals_get_subs_vals(contact_section, "RESTART", i_rep_section=icontact)
100
101 IF (my_h00) THEN
102 IF (ispin == 0) THEN
103 middle_name = "N"//trim(string1)//"-H00"
104 ELSE
105 middle_name = "N"//trim(string1)//"-H00-S"//trim(string2)
106 END IF
107 filename = negf_generate_filename(logger, print_key, middle_name=middle_name, &
108 extension=".hs", my_local=.false.)
109 END IF
110
111 IF (my_h01) THEN
112 IF (ispin == 0) THEN
113 middle_name = "N"//trim(string1)//"-H01"
114 ELSE
115 middle_name = "N"//trim(string1)//"-H01-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_s00) THEN
122 middle_name = "N"//trim(string1)//"-S00"
123 filename = negf_generate_filename(logger, print_key, middle_name=middle_name, &
124 extension=".hs", my_local=.false.)
125 END IF
126
127 IF (my_s01) THEN
128 middle_name = "N"//trim(string1)//"-S01"
129 filename = negf_generate_filename(logger, print_key, middle_name=middle_name, &
130 extension=".hs", my_local=.false.)
131 END IF
132
133 ! try to read from the filename that is generated automatically from the printkey
134 print_key => section_vals_get_subs_vals(negf_section, "SCATTERING_REGION%RESTART")
135
136 IF (my_h) THEN
137 IF (ispin == 0) THEN
138 middle_name = "Hs"
139 ELSE
140 middle_name = "Hs-S"//trim(string2)
141 END IF
142 filename = negf_generate_filename(logger, print_key, middle_name=middle_name, &
143 extension=".hs", my_local=.false.)
144 END IF
145
146 IF (my_s) THEN
147 middle_name = "Ss"
148 filename = negf_generate_filename(logger, print_key, middle_name=middle_name, &
149 extension=".hs", my_local=.false.)
150 END IF
151
152 IF (my_hc) THEN
153 IF (ispin == 0) THEN
154 middle_name = "Hsc-N"//trim(string1)
155 ELSE
156 middle_name = "Hsc-N"//trim(string1)//"-S"//trim(string2)
157 END IF
158 filename = negf_generate_filename(logger, print_key, middle_name=middle_name, &
159 extension=".hs", my_local=.false.)
160 END IF
161
162 IF (my_sc) THEN
163 middle_name = "Ssc-N"//trim(string1)
164 filename = negf_generate_filename(logger, print_key, middle_name=middle_name, &
165 extension=".hs", my_local=.false.)
166 END IF
167
168 ! try to read from the filename that is generated automatically from the printkey
169 print_key => section_vals_get_subs_vals(negf_section, "PRINT%RESTART")
170
171 IF (my_h_scf) THEN
172 filename = negf_generate_filename(logger, print_key, &
173 extension="", my_local=.false., iter_string=.true.)
174 END IF
175
176 INQUIRE (file=filename, exist=exist)
177
178 END SUBROUTINE negf_restart_file_name
179
180! **************************************************************************************************
181!> \brief ...
182!> \param logger the logger for the parallel environment, iteration info
183!> and filename generation
184!> \param print_key ...
185!> \param middle_name name to be added to the generated filename, useful when
186!> print_key activates different distinct outputs, to be able to
187!> distinguish them
188!> \param extension extension to be applied to the filename (including the ".")
189!> \param my_local if the unit should be local to this task, or global to the
190!> program (defaults to false).
191!> \param iter_string ...
192!> \return ...
193!> \par History
194!> * 12.2025 created [Dmitry Ryndyk]
195! **************************************************************************************************
196 FUNCTION negf_generate_filename(logger, print_key, middle_name, extension, &
197 my_local, iter_string) RESULT(filename)
198 TYPE(cp_logger_type), POINTER :: logger
199 TYPE(section_vals_type), POINTER :: print_key
200 CHARACTER(len=*), INTENT(IN), OPTIONAL :: middle_name
201 CHARACTER(len=*), INTENT(IN) :: extension
202 LOGICAL, INTENT(IN), OPTIONAL :: my_local, iter_string
203 CHARACTER(len=default_path_length) :: filename
204
205 CHARACTER(len=default_path_length) :: outname, outpath, postfix, root
206 CHARACTER(len=default_string_length) :: my_middle_name
207 INTEGER :: my_ind1, my_ind2
208 LOGICAL :: has_root
209
210 CALL section_vals_val_get(print_key, "FILENAME", c_val=outpath)
211 IF (outpath(1:1) == '=') THEN
212 cpassert(len(outpath) - 1 <= len(filename))
213 filename = outpath(2:)
214 RETURN
215 END IF
216 IF (outpath == "__STD_OUT__") outpath = ""
217 outname = outpath
218 has_root = .false.
219 my_ind1 = index(outpath, "/")
220 my_ind2 = len_trim(outpath)
221 IF (my_ind1 /= 0) THEN
222 has_root = .true.
223 DO WHILE (index(outpath(my_ind1 + 1:my_ind2), "/") /= 0)
224 my_ind1 = index(outpath(my_ind1 + 1:my_ind2), "/") + my_ind1
225 END DO
226 IF (my_ind1 == my_ind2) THEN
227 outname = ""
228 ELSE
229 outname = outpath(my_ind1 + 1:my_ind2)
230 END IF
231 END IF
232
233 IF (PRESENT(middle_name)) THEN
234 IF (outname /= "") THEN
235 my_middle_name = "-"//trim(outname)//"-"//middle_name
236 ELSE
237 my_middle_name = "-"//middle_name
238 END IF
239 ELSE
240 IF (outname /= "") THEN
241 my_middle_name = "-"//trim(outname)
242 ELSE
243 my_middle_name = ""
244 END IF
245 END IF
246
247 IF (.NOT. has_root) THEN
248 root = trim(logger%iter_info%project_name)//trim(my_middle_name)
249 ELSE IF (outname == "") THEN
250 root = outpath(1:my_ind1)//trim(logger%iter_info%project_name)//trim(my_middle_name)
251 ELSE
252 root = outpath(1:my_ind1)//my_middle_name(2:len_trim(my_middle_name))
253 END IF
254
255 IF (PRESENT(iter_string) .AND. iter_string) THEN
256 ! use the cp_iter_string as a postfix
257 postfix = "-"//trim(cp_iter_string(logger%iter_info, print_key=print_key, for_file=.true.))
258 IF (trim(postfix) == "-") postfix = ""
259 ! and add the extension
260 postfix = trim(postfix)//extension
261 ELSE
262 postfix = extension
263 END IF
264
265 ! and let the logger generate the filename
266 CALL cp_logger_generate_filename(logger, res=filename, &
267 root=root, postfix=postfix, local=my_local)
268
269 END FUNCTION negf_generate_filename
270
271! **************************************************************************************************
272!> \brief Prints full matrix to a file.
273!> \param filename ...
274!> \param matrix ...
275!> \par History
276!> * 12.2025 created [Dmitry Ryndyk]
277! **************************************************************************************************
278 SUBROUTINE negf_print_matrix_to_file(filename, matrix)
279 CHARACTER(LEN=default_path_length), INTENT(IN) :: filename
280 REAL(kind=dp), DIMENSION(:, :), INTENT(IN) :: matrix
281
282 CHARACTER(len=100) :: sfmt
283 INTEGER :: i, j, ncol, nrow, print_unit
284
285 CALL open_file(file_name=filename, file_status="REPLACE", &
286 file_form="FORMATTED", file_action="WRITE", &
287 file_position="REWIND", unit_number=print_unit)
288
289 nrow = SIZE(matrix, 1)
290 ncol = SIZE(matrix, 2)
291 WRITE (sfmt, "('(',i0,'(E15.5))')") ncol
292 WRITE (print_unit, *) nrow, ncol
293 DO i = 1, nrow
294 WRITE (print_unit, sfmt) (matrix(i, j), j=1, ncol)
295 END DO
296
297 CALL close_file(print_unit)
298
299 END SUBROUTINE negf_print_matrix_to_file
300
301! **************************************************************************************************
302!> \brief Reads full matrix from a file.
303!> \param filename ...
304!> \param matrix ...
305!> \par History
306!> * 12.2025 created [Dmitry Ryndyk]
307! **************************************************************************************************
308 SUBROUTINE negf_read_matrix_from_file(filename, matrix)
309 CHARACTER(LEN=default_path_length), INTENT(IN) :: filename
310 REAL(kind=dp), DIMENSION(:, :), INTENT(INOUT) :: matrix
311
312 INTEGER :: i, j, ncol, nrow, print_unit
313
314 CALL open_file(file_name=filename, file_status="OLD", &
315 file_form="FORMATTED", file_action="READ", &
316 file_position="REWIND", unit_number=print_unit)
317
318 READ (print_unit, *) nrow, ncol
319 DO i = 1, nrow
320 READ (print_unit, *) (matrix(i, j), j=1, ncol)
321 END DO
322
323 CALL close_file(print_unit)
324
325 END SUBROUTINE negf_read_matrix_from_file
326
327END 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:279
subroutine, public negf_read_matrix_from_file(filename, matrix)
Reads full matrix from a file.
Definition negf_io.F:309
type of a logger, at the moment it contains just a print level starting at which level it should be l...