(git:34ef472)
cp_output_handling.F
Go to the documentation of this file.
1 !--------------------------------------------------------------------------------------------------!
2 ! CP2K: A general program to perform molecular dynamics simulations !
3 ! Copyright 2000-2024 CP2K developers group <https://cp2k.org> !
4 ! !
5 ! SPDX-License-Identifier: GPL-2.0-or-later !
6 !--------------------------------------------------------------------------------------------------!
7 
8 ! **************************************************************************************************
9 !> \brief routines to handle the output, The idea is to remove the
10 !> decision of wheter to output and what to output from the code
11 !> that does the output, and centralize it here.
12 !> \note
13 !> These were originally together with the log handling routines,
14 !> but have been spawned off. Some dependencies are still there,
15 !> and some of the comments about log handling also applies to output
16 !> handling: @see cp_log_handling
17 !> \par History
18 !> 12.2001 created [fawzi]
19 !> 08.2002 updated to new logger [fawzi]
20 !> 10.2004 big rewrite of the output methods, connected to the new
21 !> input, and iteration_info [fawzi]
22 !> 08.2005 property flags [fawzi]
23 !> \author Fawzi Mohamed
24 ! **************************************************************************************************
26  USE cp_files, ONLY: close_file,&
27  open_file
30  cp_iteration_info_type,&
36  cp_logger_type,&
37  cp_to_string
40  keyword_type
45  section_type,&
47  section_vals_type,&
49  USE kinds, ONLY: default_path_length,&
51  USE machine, ONLY: m_mov
52  USE memory_utilities, ONLY: reallocate
53  USE message_passing, ONLY: mp_file_delete,&
55  mp_file_type
56  USE string_utilities, ONLY: compress,&
57  s2a
58 #include "../base/base_uses.f90"
59 
60  IMPLICIT NONE
61  PRIVATE
62 
63  LOGICAL, PRIVATE, PARAMETER :: debug_this_module = .true.
64  CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'cp_output_handling'
69 
70  INTEGER, PARAMETER, PUBLIC :: add_last_no = 0, &
71  add_last_numeric = 1, &
73  INTEGER, PARAMETER, PUBLIC :: silent_print_level = 0, &
74  low_print_level = 1, &
75  medium_print_level = 2, &
76  high_print_level = 3, &
78 
79 !! flags controlling the printing and storing of a property.
80 !!
81 !! cp_out_none: do not calculate the property
82 !! cp_out_file_if : if the printkey says it calculate and output the property
83 !! cp_out_store_if : if the printkey says it calculate and store in memory
84 !! the property
85 !! cp_out_file_each: calculate and output the property with the same periodicity
86 !! as said in the printkey (irrespective of the activation of
87 !! the printkey)
88 !! cp_out_store_each: calculate and store the property with the same periodicity
89 !! as said in the printkey (irrespective of the activation of
90 !! the printkey)
91 !! cp_out_file: always calculate and output the property
92 !! cp_out_store: always calculate and store in memory the property
93 !! cp_out_calc: just calculate the value (independently from the fact that there
94 !! should be output)
95 !! cp_out_default: the default value for property flags (cp_out_file_if)
96 !!
97 !! this flags can be ior-ed together:
98 !! ior(cp_out_file_if,cp_out_store_if): if the printkey says it both print
99 !! and store the property
100 !!
101 !! there is no guarantee that a property is not stored if it is not necessary
102 !! not all printkeys have a control flag
103  INTEGER, PUBLIC, PARAMETER :: cp_p_file_if = 3, cp_p_store_if = 4, &
105  INTEGER, PUBLIC, PARAMETER :: cp_out_none = 0, cp_out_file_if = ibset(0, cp_p_file_if), &
106  cp_out_store_if = ibset(0, cp_p_store_if), cp_out_file = ibset(0, cp_p_file), &
107  cp_out_store = ibset(0, cp_p_store), cp_out_calc = ibset(0, cp_p_calc), &
108  cp_out_file_each = ibset(0, cp_p_file_each), &
109  cp_out_store_each = ibset(0, cp_p_store_each), &
111 
112 ! Flag determining if MPI I/O should be enabled for functions that support it
113  LOGICAL, PRIVATE, SAVE :: enable_mpi_io = .false.
114 ! Public functions to set/get the flags
115  PUBLIC :: cp_mpi_io_set, cp_mpi_io_get
116 
117 ! **************************************************************************************************
118 !> \brief stores the flags_env controlling the output of properties
119 !> \param ref_count reference count (see doc/ReferenceCounting.html)
120 !> \param n_flags number of flags stored in this type
121 !> \param names names of the stored flags
122 !> \param control_val value of the flag
123 !> \param input the input (with all the printkeys)
124 !> \param logger logger and iteration information (to know if output is needed)
125 !> \param strict if flags that were not stored can be read
126 !> \param default_val default value of the flags that are not explicitly
127 !> stored
128 !> \note
129 !> Two features of this object should be:
130 !> 1) easy state storage, one should be able to store the state of the
131 !> flags, to some changes to them just for one (or few) force evaluations
132 !> and then reset the original state. The actual implementation is good
133 !> in this respect
134 !> 2) work well with subsections. This is a problem at the moment, as
135 !> if you pass just a subsection of the input the control flags get lost.
136 !> A better implementation should be done storing the flags also in the
137 !> input itself to be transparent
138 !> \author fawzi
139 ! **************************************************************************************************
140  TYPE cp_out_flags_type
141  INTEGER :: ref_count = 0, n_flags = 0
142  CHARACTER(default_string_length), DIMENSION(:), POINTER :: names => null()
143  INTEGER, DIMENSION(:), POINTER :: control_val => null()
144  TYPE(section_vals_type), POINTER :: input => null()
145  TYPE(cp_logger_type), POINTER :: logger => null()
146  LOGICAL :: strict = .false.
147  INTEGER :: default_val = 0
148  END TYPE cp_out_flags_type
149 
150 CONTAINS
151 
152 ! **************************************************************************************************
153 !> \brief creates a print_key section
154 !> \param print_key_section the print key to create
155 !> \param location from where in the source code cp_print_key_section_create() is called
156 !> \param name the name of the print key
157 !> \param description the description of the print key
158 !> \param print_level print level starting at which the printing takes place
159 !> (defaults to debug_print_level)
160 !> \param each_iter_names ...
161 !> \param each_iter_values ...
162 !> \param add_last ...
163 !> \param filename ...
164 !> \param common_iter_levels ...
165 !> \param citations ...
166 !> \param unit_str specifies an unit of measure for output quantity. If not
167 !> provided the control is totally left to how the output was coded
168 !> (i.e. USERS have no possibility to change it)
169 !> \author fawzi
170 ! **************************************************************************************************
171  SUBROUTINE cp_print_key_section_create(print_key_section, location, name, description, &
172  print_level, each_iter_names, each_iter_values, add_last, filename, &
173  common_iter_levels, citations, unit_str)
174  TYPE(section_type), POINTER :: print_key_section
175  CHARACTER(len=*), INTENT(IN) :: location, name, description
176  INTEGER, INTENT(IN), OPTIONAL :: print_level
177  CHARACTER(LEN=*), DIMENSION(:), INTENT(IN), &
178  OPTIONAL :: each_iter_names
179  INTEGER, DIMENSION(:), INTENT(IN), OPTIONAL :: each_iter_values
180  INTEGER, INTENT(IN), OPTIONAL :: add_last
181  CHARACTER(LEN=*), INTENT(IN), OPTIONAL :: filename
182  INTEGER, INTENT(IN), OPTIONAL :: common_iter_levels
183  INTEGER, DIMENSION(:), OPTIONAL :: citations
184  CHARACTER(LEN=*), INTENT(IN), OPTIONAL :: unit_str
185 
186  CHARACTER(len=default_path_length) :: my_filename
187  INTEGER :: i_each, i_iter, my_add_last, &
188  my_comm_iter_levels, my_print_level, &
189  my_value
190  LOGICAL :: check, ext_each
191  TYPE(keyword_type), POINTER :: keyword
192  TYPE(section_type), POINTER :: subsection
193 
194  cpassert(.NOT. ASSOCIATED(print_key_section))
195  my_print_level = debug_print_level
196  IF (PRESENT(print_level)) my_print_level = print_level
197 
198  CALL section_create(print_key_section, location=location, name=name, description=description, &
199  n_keywords=2, n_subsections=0, repeats=.false., &
200  citations=citations)
201 
202  NULLIFY (keyword, subsection)
203  CALL keyword_create(keyword, __location__, name="_SECTION_PARAMETERS_", &
204  description="Level starting at which this property is printed", &
205  usage="silent", &
206  default_i_val=my_print_level, lone_keyword_i_val=silent_print_level, &
207  enum_c_vals=s2a("on", "off", "silent", "low", "medium", "high", "debug"), &
208  enum_i_vals=(/silent_print_level - 1, debug_print_level + 1, &
211  CALL section_add_keyword(print_key_section, keyword)
212  CALL keyword_release(keyword)
213 
214  CALL keyword_create(keyword, __location__, name="__CONTROL_VAL", &
215  description=' hidden parameter that controls storage, printing,...'// &
216  ' of the print_key', &
217  default_i_val=cp_out_default)
218  CALL section_add_keyword(print_key_section, keyword)
219  CALL keyword_release(keyword)
220 
221  CALL section_create(subsection, __location__, name="EACH", &
222  description="This section specifies how often this property is printed. "// &
223  "Each keyword inside this section is mapping to a specific iteration level and "// &
224  "the value of each of these keywords is matched with the iteration level during "// &
225  "the calculation. How to handle the last iteration is treated "// &
226  "separately in ADD_LAST (this mean that each iteration level (MD, GEO_OPT, etc..), "// &
227  "though equal to 0, might print the last iteration). If an iteration level is specified "// &
228  "that is not present in the flow of the calculation it is just ignored.", &
229  n_keywords=2, n_subsections=0, repeats=.false., &
230  citations=citations)
231 
232  ! Enforce the presence or absence of both.. or give an error
233  check = (PRESENT(each_iter_names)) .EQV. (PRESENT(each_iter_values))
234  cpassert(check)
235  ext_each = (PRESENT(each_iter_names)) .AND. (PRESENT(each_iter_values))
236 
237  DO i_each = 1, SIZE(each_possible_labels)
238  my_value = 1
239  IF (ext_each) THEN
240  check = sum(index(each_iter_names, each_possible_labels(i_each))) <= 1
241  cpassert(check)
242  DO i_iter = 1, SIZE(each_iter_names)
243  IF (index(trim(each_iter_names(i_iter)), trim(each_possible_labels(i_each))) /= 0) THEN
244  my_value = each_iter_values(i_iter)
245  END IF
246  END DO
247  END IF
248  CALL keyword_create(keyword, __location__, name=trim(each_possible_labels(i_each)), &
249  description=trim(each_desc_labels(i_each)), &
250  usage=trim(each_possible_labels(i_each))//" <INTEGER>", &
251  default_i_val=my_value)
252  CALL section_add_keyword(subsection, keyword)
253  CALL keyword_release(keyword)
254  END DO
255  CALL section_add_subsection(print_key_section, subsection)
256  CALL section_release(subsection)
257 
258  my_add_last = add_last_no
259  IF (PRESENT(add_last)) THEN
260  my_add_last = add_last
261  END IF
262  CALL keyword_create(keyword, __location__, name="ADD_LAST", &
263  description="If the last iteration should be added, and if it "// &
264  "should be marked symbolically (with lowercase letter l) or with "// &
265  "the iteration number. "// &
266  "Not every iteration level is able to identify the last iteration "// &
267  "early enough to be able to output. When this keyword is activated "// &
268  "all iteration levels are checked for the last iteration step.", &
269  usage="ADD_LAST (NO|NUMERIC|SYMBOLIC)", &
270  enum_c_vals=s2a("no", "numeric", "symbolic"), &
271  enum_i_vals=(/add_last_no, add_last_numeric, add_last_symbolic/), &
272  enum_desc=s2a("Do not mark last iteration specifically", &
273  "Mark last iteration with its iteration number", &
274  "Mark last iteration with lowercase letter l"), &
275  default_i_val=my_add_last)
276  CALL section_add_keyword(print_key_section, keyword)
277  CALL keyword_release(keyword)
278 
279  my_comm_iter_levels = 0
280  IF (PRESENT(common_iter_levels)) my_comm_iter_levels = common_iter_levels
281  CALL keyword_create(keyword, __location__, name="COMMON_ITERATION_LEVELS", &
282  description="How many iterations levels should be written"// &
283  " in the same file (no extra information about the actual"// &
284  " iteration level is written to the file)", &
285  usage="COMMON_ITERATION_LEVELS <INTEGER>", &
286  default_i_val=my_comm_iter_levels)
287  CALL section_add_keyword(print_key_section, keyword)
288  CALL keyword_release(keyword)
289 
290  my_filename = ""
291  IF (PRESENT(filename)) my_filename = filename
292  CALL keyword_create(keyword, __location__, name="FILENAME", &
293  description=' controls part of the filename for output. '// &
294  ' use __STD_OUT__ (exactly as written here) for the screen or standard logger. '// &
295  ' use filename to obtain projectname-filename. '// &
296  ' use ./filename to get filename.'// &
297  ' A middle name (if present), iteration numbers'// &
298  ' and extension are always added to the filename.'// &
299  ' if you want to avoid it use =filename, in this'// &
300  ' case the filename is always exactly as typed.'// &
301  ' Please note that this can lead to clashes of'// &
302  ' filenames.', &
303  usage="FILENAME ./filename ", &
304  default_lc_val=my_filename)
305  CALL section_add_keyword(print_key_section, keyword)
306  CALL keyword_release(keyword)
307 
308  CALL keyword_create(keyword, __location__, name="LOG_PRINT_KEY", &
309  description="This keywords enables the logger for the print_key (a message is printed on "// &
310  "screen everytime data, controlled by this print_key, are written)", &
311  usage="LOG_PRINT_KEY <LOGICAL>", default_l_val=.false., lone_keyword_l_val=.true.)
312  CALL section_add_keyword(print_key_section, keyword)
313  CALL keyword_release(keyword)
314 
315  IF (PRESENT(unit_str)) THEN
316  CALL keyword_create(keyword, __location__, name="UNIT", &
317  description='Specify the unit of measurement for the quantity in output. '// &
318  "All available CP2K units can be used.", &
319  usage="UNIT angstrom", default_c_val=trim(unit_str))
320  CALL section_add_keyword(print_key_section, keyword)
321  CALL keyword_release(keyword)
322  END IF
323  END SUBROUTINE cp_print_key_section_create
324 
325 ! **************************************************************************************************
326 !> \brief returns what should be done with the given property
327 !> if btest(res,cp_p_store) then the property should be stored in memory
328 !> if btest(res,cp_p_file) then the property should be print ed to a file
329 !> if res==0 then nothing should be done
330 !> \param iteration_info information about the actual iteration level
331 !> \param basis_section section that contains the printkey
332 !> \param print_key_path path to the printkey- "%" between sections, and
333 !> optionally a "/" and a logical flag to check). Might be empty.
334 !> \param used_print_key here the print_key that was used is returned
335 !> \param first_time if it ist the first time that an output is written
336 !> (not fully correct, but most of the time)
337 !> \return ...
338 !> \author fawzi
339 !> \note
340 !> not all the propreties support can be stored
341 ! **************************************************************************************************
342  FUNCTION cp_print_key_should_output(iteration_info, basis_section, &
343  print_key_path, used_print_key, first_time) &
344  result(res)
345  TYPE(cp_iteration_info_type), INTENT(IN) :: iteration_info
346  TYPE(section_vals_type), INTENT(IN), TARGET :: basis_section
347  CHARACTER(len=*), INTENT(IN), OPTIONAL :: print_key_path
348  TYPE(section_vals_type), INTENT(INOUT), OPTIONAL, &
349  POINTER :: used_print_key
350  LOGICAL, INTENT(OUT), OPTIONAL :: first_time
351  INTEGER :: res
352 
353  INTEGER :: end_str, my_control_val, to_path
354  LOGICAL :: flags, is_iter, is_on
355  TYPE(section_vals_type), POINTER :: print_key
356 
357  res = 0
358  IF (PRESENT(first_time)) first_time = .false.
359  cpassert(basis_section%ref_count > 0)
360  IF (PRESENT(used_print_key)) NULLIFY (used_print_key)
361 
362  IF (PRESENT(print_key_path)) THEN
363  end_str = len_trim(print_key_path)
364  to_path = index(print_key_path, "/")
365  IF (to_path < 1) THEN
366  to_path = end_str + 1
367  END IF
368 
369  IF (to_path > 1) THEN
370  print_key => section_vals_get_subs_vals(basis_section, &
371  print_key_path(1:(to_path - 1)))
372  ELSE
373  print_key => basis_section
374  END IF
375  cpassert(ASSOCIATED(print_key))
376  cpassert(print_key%ref_count > 0)
377  IF (to_path + 1 < end_str) THEN
378  CALL section_vals_val_get(print_key, print_key_path((to_path + 1):end_str), &
379  l_val=flags)
380  ELSE
381  flags = .true.
382  END IF
383  ELSE
384  print_key => basis_section
385  flags = .true.
386  END IF
387  IF (PRESENT(used_print_key)) used_print_key => print_key
388 
389  IF (.NOT. flags) RETURN
390 
391  CALL section_vals_val_get(print_key, "__CONTROL_VAL", &
392  i_val=my_control_val)
393  is_on = cp_printkey_is_on(iteration_info, print_key)
394 
395  ! a shortcut for most common case
396  IF (my_control_val == cp_out_default .AND. .NOT. is_on) RETURN
397 
398  is_iter = cp_printkey_is_iter(iteration_info, print_key, first_time=first_time)
399 
400  IF (btest(my_control_val, cp_p_store)) THEN
401  res = ibset(res, cp_p_store)
402  ELSE IF (btest(my_control_val, cp_p_store_if) .AND. is_iter .AND. is_on) THEN
403  res = ibset(res, cp_p_store)
404  ELSE IF (btest(my_control_val, cp_p_store_each) .AND. is_iter) THEN
405  res = ibset(res, cp_p_store)
406  END IF
407 
408  IF (btest(my_control_val, cp_p_file)) THEN
409  res = ibset(res, cp_p_file)
410  ELSE IF (btest(my_control_val, cp_p_file_if) .AND. is_iter .AND. is_on) THEN
411  res = ibset(res, cp_p_file)
412  ELSE IF (btest(my_control_val, cp_p_file_each) .AND. is_iter) THEN
413  res = ibset(res, cp_p_file)
414  END IF
415  IF (btest(my_control_val, cp_p_calc) .OR. res /= 0) THEN
416  res = ibset(res, cp_p_calc)
417  END IF
418  END FUNCTION cp_print_key_should_output
419 
420 ! **************************************************************************************************
421 !> \brief returns true if the printlevel activates this printkey
422 !> does not look if this iteration it should be printed
423 !> \param iteration_info information about the actual iteration level
424 !> \param print_key the section values of the key to be printed
425 !> \return ...
426 !> \author fawzi
427 ! **************************************************************************************************
428  FUNCTION cp_printkey_is_on(iteration_info, print_key) RESULT(res)
429  TYPE(cp_iteration_info_type), INTENT(IN) :: iteration_info
430  TYPE(section_vals_type), POINTER :: print_key
431  LOGICAL :: res
432 
433  INTEGER :: print_level
434 
435  cpassert(iteration_info%ref_count > 0)
436  IF (.NOT. ASSOCIATED(print_key)) THEN
437  res = (iteration_info%print_level > debug_print_level)
438  ELSE
439  cpassert(print_key%ref_count > 0)
440  CALL section_vals_val_get(print_key, "_SECTION_PARAMETERS_", i_val=print_level)
441  res = iteration_info%print_level >= print_level
442  END IF
443  END FUNCTION cp_printkey_is_on
444 
445 ! **************************************************************************************************
446 !> \brief returns if the actual iteration matches those selected by the
447 !> given printkey. Does not check it the prinkey is active (at the
448 !> actual print_level)
449 !> \param iteration_info information about the actual iteration level
450 !> \param print_key the section values of the key to be printed
451 !> \param first_time returns if it is the first time that output is written
452 !> (not fully correct, but most of the time)
453 !> \return ...
454 !> \author fawzi
455 ! **************************************************************************************************
456  FUNCTION cp_printkey_is_iter(iteration_info, print_key, first_time) &
457  result(res)
458  TYPE(cp_iteration_info_type), INTENT(IN) :: iteration_info
459  TYPE(section_vals_type), POINTER :: print_key
460  LOGICAL, INTENT(OUT), OPTIONAL :: first_time
461  LOGICAL :: res
462 
463  INTEGER :: add_last, ilevel, iter_nr, ival
464  LOGICAL :: first, level_passed
465 
466  cpassert(iteration_info%ref_count > 0)
467  IF (.NOT. ASSOCIATED(print_key)) THEN
468  res = (iteration_info%print_level > debug_print_level)
469  first = all(iteration_info%iteration(1:iteration_info%n_rlevel) == 1)
470  ELSE
471  cpassert(print_key%ref_count > 0)
472  res = .false.
473  first = .false.
474  CALL section_vals_val_get(print_key, "ADD_LAST", i_val=add_last)
475  res = .true.
476  first = .true.
477  DO ilevel = 1, iteration_info%n_rlevel
478  level_passed = .false.
479  CALL section_vals_val_get(print_key, "EACH%"//trim(iteration_info%level_name(ilevel)), &
480  i_val=ival)
481  IF (ival > 0) THEN
482  iter_nr = iteration_info%iteration(ilevel)
483  IF (iter_nr/ival > 1) first = .false.
484  IF (modulo(iter_nr, ival) == 0) THEN
485  level_passed = .true.
486  END IF
487  END IF
488  IF (add_last == add_last_numeric .OR. add_last == add_last_symbolic) THEN
489  IF (iteration_info%last_iter(ilevel)) THEN
490  level_passed = .true.
491  END IF
492  END IF
493  IF (.NOT. level_passed) res = .false.
494  END DO
495  END IF
496  first = first .AND. res
497  IF (PRESENT(first_time)) first_time = first
498  END FUNCTION cp_printkey_is_iter
499 
500 ! **************************************************************************************************
501 !> \brief returns the iteration string, a string that is useful to create
502 !> unique filenames (once you trim it)
503 !> \param iter_info the iteration info from where to take the iteration
504 !> number
505 !> \param print_key the print key to optionally show the last iteration
506 !> symbolically
507 !> \param for_file if the string is to be used for file generation
508 !> (and should consequently ignore some iteration levels depending
509 !> on COMMON_ITERATION_LEVELS).
510 !> Defaults to false.
511 !> \return ...
512 !> \author fawzi
513 !> \note
514 !> If the root level is 1 removes it
515 ! **************************************************************************************************
516  FUNCTION cp_iter_string(iter_info, print_key, for_file) RESULT(res)
517  TYPE(cp_iteration_info_type), POINTER :: iter_info
518  TYPE(section_vals_type), OPTIONAL, POINTER :: print_key
519  LOGICAL, INTENT(IN), OPTIONAL :: for_file
520  CHARACTER(len=default_string_length) :: res
521 
522  INTEGER :: add_last, c_i_level, ilevel, n_rlevel, &
523  s_level
524  LOGICAL :: my_for_file
525  TYPE(section_vals_type), POINTER :: my_print_key
526 
527  res = ""
528  my_for_file = .false.
529  IF (PRESENT(for_file)) my_for_file = for_file
530  cpassert(ASSOCIATED(iter_info))
531  cpassert(iter_info%ref_count > 0)
532  NULLIFY (my_print_key)
533  IF (PRESENT(print_key)) my_print_key => print_key
534  s_level = 1
535  IF (ASSOCIATED(my_print_key)) THEN
536  CALL section_vals_val_get(my_print_key, "ADD_LAST", i_val=add_last)
537  CALL section_vals_val_get(my_print_key, "COMMON_ITERATION_LEVELS", i_val=c_i_level)
538  n_rlevel = iter_info%n_rlevel
539  IF (my_for_file) n_rlevel = min(n_rlevel, max(0, n_rlevel - c_i_level))
540  DO ilevel = s_level, n_rlevel
541  IF (iter_info%last_iter(ilevel)) THEN
542  IF (add_last == add_last_symbolic) THEN
543  WRITE (res(9*ilevel - 8:9*ilevel), "('l_')")
544  ELSE
545  WRITE (res(9*ilevel - 8:9*ilevel), "(i8,'_')") iter_info%iteration(ilevel)
546  END IF
547  ELSE
548  WRITE (res(9*ilevel - 8:9*ilevel), "(i8,'_')") iter_info%iteration(ilevel)
549  END IF
550  END DO
551  ELSE
552  DO ilevel = s_level, iter_info%n_rlevel
553  WRITE (res(9*ilevel - 8:9*ilevel), "(i8,'_')") iter_info%iteration(ilevel)
554  END DO
555  END IF
556  CALL compress(res, .true.)
557  IF (len_trim(res) > 0) THEN
558  res(len_trim(res):len_trim(res)) = " "
559  END IF
560  END FUNCTION cp_iter_string
561 
562 ! **************************************************************************************************
563 !> \brief adds one to the actual iteration
564 !> \param iteration_info the iteration info to update
565 !> \param last if this iteration is the last one (defaults to false)
566 !> \param iter_nr ...
567 !> \param increment ...
568 !> \param iter_nr_out ...
569 !> \author fawzi
570 !> \note
571 !> this is supposed to be called at the beginning of each iteration
572 ! **************************************************************************************************
573  SUBROUTINE cp_iterate(iteration_info, last, iter_nr, increment, iter_nr_out)
574  TYPE(cp_iteration_info_type), POINTER :: iteration_info
575  LOGICAL, INTENT(IN), OPTIONAL :: last
576  INTEGER, INTENT(IN), OPTIONAL :: iter_nr, increment
577  INTEGER, INTENT(OUT), OPTIONAL :: iter_nr_out
578 
579  INTEGER :: my_increment
580  LOGICAL :: my_last
581 
582  my_last = .false.
583  my_increment = 1
584  IF (PRESENT(last)) my_last = last
585  IF (PRESENT(increment)) my_increment = increment
586  IF (PRESENT(iter_nr_out)) iter_nr_out = -1
587 
588  cpassert(ASSOCIATED(iteration_info))
589  cpassert(iteration_info%ref_count > 0)
590  IF (PRESENT(iter_nr)) THEN
591  iteration_info%iteration(iteration_info%n_rlevel) = iter_nr
592  ELSE
593  iteration_info%iteration(iteration_info%n_rlevel) = &
594  iteration_info%iteration(iteration_info%n_rlevel) + my_increment
595  END IF
596  ! If requested provide the value of the iteration level
597  IF (PRESENT(iter_nr_out)) iter_nr_out = iteration_info%iteration(iteration_info%n_rlevel)
598 
599  ! Possibly setup the LAST flag
600  iteration_info%last_iter(iteration_info%n_rlevel) = my_last
601  END SUBROUTINE cp_iterate
602 
603 ! **************************************************************************************************
604 !> \brief Adds an iteration level
605 !> \param iteration_info the iteration info to which an iteration level has
606 !> to be added
607 !> \param level_name the name of this level, for pretty printing only, right now
608 !> \param n_rlevel_new number of iteration levels after this call
609 !> \author fawzi
610 ! **************************************************************************************************
611  SUBROUTINE cp_add_iter_level(iteration_info, level_name, n_rlevel_new)
612  TYPE(cp_iteration_info_type), POINTER :: iteration_info
613  CHARACTER(LEN=*), INTENT(IN) :: level_name
614  INTEGER, INTENT(OUT), OPTIONAL :: n_rlevel_new
615 
616  INTEGER :: i
617  LOGICAL :: found
618 
619  cpassert(ASSOCIATED(iteration_info))
620  cpassert(iteration_info%ref_count > 0)
621  found = .false.
622  DO i = 1, SIZE(each_possible_labels)
623  IF (trim(level_name) == trim(each_possible_labels(i))) THEN
624  found = .true.
625  EXIT
626  END IF
627  END DO
628  IF (found) THEN
629  CALL cp_iteration_info_retain(iteration_info)
630  iteration_info%n_rlevel = iteration_info%n_rlevel + 1
631  CALL reallocate(iteration_info%iteration, 1, iteration_info%n_rlevel)
632  CALL reallocate(iteration_info%level_name, 1, iteration_info%n_rlevel)
633  CALL reallocate(iteration_info%last_iter, 1, iteration_info%n_rlevel)
634  iteration_info%iteration(iteration_info%n_rlevel) = 0
635  iteration_info%level_name(iteration_info%n_rlevel) = level_name
636  iteration_info%last_iter(iteration_info%n_rlevel) = .false.
637  IF (PRESENT(n_rlevel_new)) n_rlevel_new = iteration_info%n_rlevel
638  ELSE
639  CALL cp_abort(__location__, &
640  "Trying to create an iteration level ("//trim(level_name)//") not defined. "// &
641  "Please update the module: cp_iter_types.")
642  END IF
643 
644  END SUBROUTINE cp_add_iter_level
645 
646 ! **************************************************************************************************
647 !> \brief Removes an iteration level
648 !> \param iteration_info the iteration info to which an iteration level has
649 !> to be removed
650 !> \param level_name level_name to be destroyed (if does not match gives an error)
651 !> \param n_rlevel_att iteration level before the call (to do some checks)
652 !> \author fawzi
653 ! **************************************************************************************************
654  SUBROUTINE cp_rm_iter_level(iteration_info, level_name, n_rlevel_att)
655  TYPE(cp_iteration_info_type), POINTER :: iteration_info
656  CHARACTER(LEN=*), INTENT(IN) :: level_name
657  INTEGER, INTENT(IN), OPTIONAL :: n_rlevel_att
658 
659  LOGICAL :: check
660 
661  cpassert(ASSOCIATED(iteration_info))
662  cpassert(iteration_info%ref_count > 0)
663  IF (PRESENT(n_rlevel_att)) THEN
664  cpassert(n_rlevel_att == iteration_info%n_rlevel)
665  END IF
666  CALL cp_iteration_info_release(iteration_info)
667  ! This check that the iteration levels are consistently created and destroyed..
668  ! Never remove this check..
669  check = iteration_info%level_name(iteration_info%n_rlevel) == level_name
670  cpassert(check)
671  iteration_info%n_rlevel = iteration_info%n_rlevel - 1
672  CALL reallocate(iteration_info%iteration, 1, iteration_info%n_rlevel)
673  CALL reallocate(iteration_info%level_name, 1, iteration_info%n_rlevel)
674  CALL reallocate(iteration_info%last_iter, 1, iteration_info%n_rlevel)
675  END SUBROUTINE cp_rm_iter_level
676 
677 ! **************************************************************************************************
678 !> \brief Utility function that returns a unit number to write the print key.
679 !> Might open a file with a unique filename, generated from
680 !> the print_key name and iteration info.
681 !>
682 !> Normally a valid unit (>0) is returned only if cp_print_key_should_output
683 !> says that the print_key should be printed, and if the unit is global
684 !> only the io node has a valid unit.
685 !> So in many cases you can decide if you should print just checking if
686 !> the returned units is bigger than 0.
687 !>
688 !> IMPORTANT you should call cp_finished_output when an iteration output is
689 !> finished (to immediately close the file that might have been opened)
690 !> \param logger the logger for the parallel environment, iteration info
691 !> and filename generation
692 !> \param print_key ...
693 !> \param middle_name name to be added to the generated filename, useful when
694 !> print_key activates different distinct outputs, to be able to
695 !> distinguish them
696 !> \param extension extension to be applied to the filename (including the ".")
697 !> \param my_local if the unit should be local to this task, or global to the
698 !> program (defaults to false).
699 !> \return ...
700 !> \author Fawzi Mohamed
701 ! **************************************************************************************************
702  FUNCTION cp_print_key_generate_filename(logger, print_key, middle_name, extension, &
703  my_local) RESULT(filename)
704  TYPE(cp_logger_type), POINTER :: logger
705  TYPE(section_vals_type), POINTER :: print_key
706  CHARACTER(len=*), INTENT(IN), OPTIONAL :: middle_name
707  CHARACTER(len=*), INTENT(IN) :: extension
708  LOGICAL, INTENT(IN) :: my_local
709  CHARACTER(len=default_path_length) :: filename
710 
711  CHARACTER(len=default_path_length) :: outpath, postfix, root
712  CHARACTER(len=default_string_length) :: my_middle_name, outname
713  INTEGER :: my_ind1, my_ind2
714  LOGICAL :: has_root
715 
716  CALL section_vals_val_get(print_key, "FILENAME", c_val=outpath)
717  IF (outpath(1:1) == '=') THEN
718  cpassert(len(outpath) - 1 <= len(filename))
719  filename = outpath(2:)
720  RETURN
721  END IF
722  IF (outpath == "__STD_OUT__") outpath = ""
723  outname = outpath
724  has_root = .false.
725  my_ind1 = index(outpath, "/")
726  my_ind2 = len_trim(outpath)
727  IF (my_ind1 /= 0) THEN
728  has_root = .true.
729  DO WHILE (index(outpath(my_ind1 + 1:my_ind2), "/") /= 0)
730  my_ind1 = index(outpath(my_ind1 + 1:my_ind2), "/") + my_ind1
731  END DO
732  IF (my_ind1 == my_ind2) THEN
733  outname = ""
734  ELSE
735  outname = outpath(my_ind1 + 1:my_ind2)
736  END IF
737  END IF
738 
739  IF (PRESENT(middle_name)) THEN
740  IF (outname /= "") THEN
741  my_middle_name = "-"//trim(outname)//"-"//middle_name
742  ELSE
743  my_middle_name = "-"//middle_name
744  END IF
745  ELSE
746  IF (outname /= "") THEN
747  my_middle_name = "-"//trim(outname)
748  ELSE
749  my_middle_name = ""
750  END IF
751  END IF
752 
753  IF (.NOT. has_root) THEN
754  root = trim(logger%iter_info%project_name)//trim(my_middle_name)
755  ELSE IF (outname == "") THEN
756  root = outpath(1:my_ind1)//trim(logger%iter_info%project_name)//trim(my_middle_name)
757  ELSE
758  root = outpath(1:my_ind1)//my_middle_name(2:len_trim(my_middle_name))
759  END IF
760 
761  ! use the cp_iter_string as a postfix
762  postfix = "-"//trim(cp_iter_string(logger%iter_info, print_key=print_key, for_file=.true.))
763  IF (trim(postfix) == "-") postfix = ""
764 
765  ! and add the extension
766  postfix = trim(postfix)//extension
767  ! and let the logger generate the filename
768  CALL cp_logger_generate_filename(logger, res=filename, &
769  root=root, postfix=postfix, local=my_local)
770 
771  END FUNCTION cp_print_key_generate_filename
772 
773 ! **************************************************************************************************
774 !> \brief ...
775 !> \param logger ...
776 !> \param basis_section ...
777 !> \param print_key_path ...
778 !> \param extension ...
779 !> \param middle_name ...
780 !> \param local ...
781 !> \param log_filename ...
782 !> \param ignore_should_output ...
783 !> \param file_form ...
784 !> \param file_position ...
785 !> \param file_action ...
786 !> \param file_status ...
787 !> \param do_backup ...
788 !> \param on_file ...
789 !> \param is_new_file true if this rank created a new (or rewound) file, false otherwise
790 !> \param mpi_io True if the file should be opened in parallel on all processors belonging to
791 !> the communicator group. Automatically disabled if the file form or access mode
792 !> is unsuitable for MPI IO. Return value indicates whether MPI was actually used
793 !> and therefore the flag must also be passed to the file closing directive.
794 !> \param fout Name of the actual file where the output will be written. Needed mainly for MPI IO
795 !> because inquiring the filename from the MPI filehandle does not work across
796 !> all MPI libraries.
797 !> \return ...
798 ! **************************************************************************************************
799  FUNCTION cp_print_key_unit_nr(logger, basis_section, print_key_path, extension, &
800  middle_name, local, log_filename, ignore_should_output, file_form, file_position, &
801  file_action, file_status, do_backup, on_file, is_new_file, mpi_io, &
802  fout) RESULT(res)
803  TYPE(cp_logger_type), POINTER :: logger
804  TYPE(section_vals_type), INTENT(IN) :: basis_section
805  CHARACTER(len=*), INTENT(IN), OPTIONAL :: print_key_path
806  CHARACTER(len=*), INTENT(IN) :: extension
807  CHARACTER(len=*), INTENT(IN), OPTIONAL :: middle_name
808  LOGICAL, INTENT(IN), OPTIONAL :: local, log_filename, ignore_should_output
809  CHARACTER(len=*), INTENT(IN), OPTIONAL :: file_form, file_position, file_action, &
810  file_status
811  LOGICAL, INTENT(IN), OPTIONAL :: do_backup, on_file
812  LOGICAL, INTENT(OUT), OPTIONAL :: is_new_file
813  LOGICAL, INTENT(INOUT), OPTIONAL :: mpi_io
814  CHARACTER(len=default_path_length), INTENT(OUT), &
815  OPTIONAL :: fout
816  INTEGER :: res
817 
818  CHARACTER(len=default_path_length) :: filename, filename_bak, filename_bak_1, &
819  filename_bak_2
820  CHARACTER(len=default_string_length) :: my_file_action, my_file_form, &
821  my_file_position, my_file_status, &
822  outpath
823  INTEGER :: c_i_level, f_backup_level, i, mpi_amode, &
824  my_backup_level, my_nbak, nbak, &
825  s_backup_level, unit_nr
826  LOGICAL :: do_log, found, my_do_backup, my_local, &
827  my_mpi_io, my_on_file, &
828  my_should_output, replace
829  TYPE(cp_iteration_info_type), POINTER :: iteration_info
830  TYPE(mp_file_type) :: mp_unit
831  TYPE(section_vals_type), POINTER :: print_key
832 
833  my_local = .false.
834  my_do_backup = .false.
835  my_mpi_io = .false.
836  replace = .false.
837  found = .false.
838  res = -1
839  my_file_form = "FORMATTED"
840  my_file_position = "APPEND"
841  my_file_action = "WRITE"
842  my_file_status = "UNKNOWN"
843  my_on_file = .false.
844  mpi_amode = 0
845  IF (PRESENT(file_form)) my_file_form = file_form
846  IF (PRESENT(file_position)) my_file_position = file_position
847  IF (PRESENT(file_action)) my_file_action = file_action
848  IF (PRESENT(file_status)) my_file_status = file_status
849  IF (PRESENT(do_backup)) my_do_backup = do_backup
850  IF (PRESENT(on_file)) my_on_file = on_file
851  IF (PRESENT(local)) my_local = local
852  IF (PRESENT(is_new_file)) is_new_file = .false.
853  IF (PRESENT(mpi_io)) THEN
854 #if defined(__parallel)
855  IF (cp_mpi_io_get() .AND. logger%para_env%num_pe > 1 .AND. mpi_io) THEN
856  my_mpi_io = .true.
857  ELSE
858  my_mpi_io = .false.
859  END IF
860  IF (my_mpi_io) THEN
861  CALL mp_file_get_amode(mpi_io, replace, mpi_amode, trim(my_file_form), &
862  trim(my_file_action), trim(my_file_status), trim(my_file_position))
863  replace = replace .AND. logger%para_env%is_source()
864  END IF
865 #else
866  my_mpi_io = .false.
867 #endif
868  ! Set return value
869  mpi_io = my_mpi_io
870  END IF
871  NULLIFY (print_key)
872  cpassert(ASSOCIATED(logger))
873  cpassert(basis_section%ref_count > 0)
874  cpassert(logger%ref_count > 0)
875  my_should_output = btest(cp_print_key_should_output(logger%iter_info, &
876  basis_section, print_key_path, used_print_key=print_key), cp_p_file)
877  IF (PRESENT(ignore_should_output)) my_should_output = my_should_output .OR. ignore_should_output
878  IF (.NOT. my_should_output) RETURN
879  IF (my_local .OR. &
880  logger%para_env%is_source() .OR. &
881  my_mpi_io) THEN
882 
883  CALL section_vals_val_get(print_key, "FILENAME", c_val=outpath)
884  IF (outpath == '__STD_OUT__' .AND. .NOT. my_on_file) THEN
885  res = cp_logger_get_default_unit_nr(logger, local=my_local)
886  ELSE
887  !
888  ! complex logic to build filename:
889  ! 1) Try to avoid '--' and '-.'
890  ! 2) If outPath contains '/' (as in ./filename) do not prepend the project_name
891  !
892  ! if it is actually a full path, use it as the root
893  filename = cp_print_key_generate_filename(logger, print_key, middle_name, extension, &
894  my_local)
895  ! Give back info about a possible existence of the file if required
896  IF (PRESENT(is_new_file)) THEN
897  INQUIRE (file=filename, exist=found)
898  is_new_file = .NOT. found
899  IF (my_file_position == "REWIND") is_new_file = .true.
900  END IF
901  ! Check is we have to log any operation performed on the file..
902  do_log = .false.
903  IF (PRESENT(log_filename)) THEN
904  do_log = log_filename
905  ELSE
906  CALL section_vals_val_get(print_key, "LOG_PRINT_KEY", l_val=do_log)
907  END IF
908  ! If required do a backup
909  IF (my_do_backup) THEN
910  INQUIRE (file=filename, exist=found)
911  CALL section_vals_val_get(print_key, "BACKUP_COPIES", i_val=nbak)
912  IF (nbak /= 0) THEN
913  iteration_info => logger%iter_info
914  s_backup_level = 0
915  IF (ASSOCIATED(print_key%ibackup)) s_backup_level = SIZE(print_key%ibackup)
916  CALL section_vals_val_get(print_key, "COMMON_ITERATION_LEVELS", i_val=c_i_level)
917  my_backup_level = max(1, iteration_info%n_rlevel - c_i_level + 1)
918  f_backup_level = max(s_backup_level, my_backup_level)
919  IF (f_backup_level > s_backup_level) THEN
920  CALL reallocate(print_key%ibackup, 1, f_backup_level)
921  DO i = s_backup_level + 1, f_backup_level
922  print_key%ibackup(i) = 0
923  END DO
924  END IF
925  IF (found) THEN
926  print_key%ibackup(my_backup_level) = print_key%ibackup(my_backup_level) + 1
927  my_nbak = print_key%ibackup(my_backup_level)
928  ! Recent backup copies correspond to lower backup indexes
929  DO i = min(nbak, my_nbak), 2, -1
930  filename_bak_1 = trim(filename)//".bak-"//adjustl(cp_to_string(i))
931  filename_bak_2 = trim(filename)//".bak-"//adjustl(cp_to_string(i - 1))
932  IF (do_log) THEN
933  unit_nr = cp_logger_get_unit_nr(logger, local=my_local)
934  IF (unit_nr > 0) &
935  WRITE (unit_nr, *) "Moving file "//trim(filename_bak_2)// &
936  " into file "//trim(filename_bak_1)//"."
937  END IF
938  INQUIRE (file=filename_bak_2, exist=found)
939  IF (.NOT. found) THEN
940  IF (do_log) THEN
941  unit_nr = cp_logger_get_unit_nr(logger, local=my_local)
942  IF (unit_nr > 0) &
943  WRITE (unit_nr, *) "File "//trim(filename_bak_2)//" not existing.."
944  END IF
945  ELSE
946  CALL m_mov(trim(filename_bak_2), trim(filename_bak_1))
947  END IF
948  END DO
949  ! The last backup is always the one with index 1
950  filename_bak = trim(filename)//".bak-"//adjustl(cp_to_string(1))
951  IF (do_log) THEN
952  unit_nr = cp_logger_get_unit_nr(logger, local=my_local)
953  IF (unit_nr > 0) &
954  WRITE (unit_nr, *) "Moving file "//trim(filename)//" into file "//trim(filename_bak)//"."
955  END IF
956  CALL m_mov(trim(filename), trim(filename_bak))
957  ELSE
958  ! Zero the backup history for this new iteration level..
959  print_key%ibackup(my_backup_level) = 0
960  END IF
961  END IF
962  END IF
963 
964  IF (.NOT. my_mpi_io) THEN
965  CALL open_file(file_name=filename, file_status=my_file_status, &
966  file_form=my_file_form, file_action=my_file_action, &
967  file_position=my_file_position, unit_number=res)
968  ELSE
969  IF (replace) CALL mp_file_delete(filename)
970  CALL mp_unit%open(groupid=logger%para_env, &
971  filepath=filename, amode_status=mpi_amode)
972  IF (PRESENT(fout)) fout = filename
973  res = mp_unit%get_handle()
974  END IF
975  IF (do_log) THEN
976  unit_nr = cp_logger_get_unit_nr(logger, local=my_local)
977  IF (unit_nr > 0) &
978  WRITE (unit_nr, *) "Writing "//trim(print_key%section%name)//" "// &
979  trim(cp_iter_string(logger%iter_info))//" to "// &
980  trim(filename)
981  END IF
982  END IF
983  ELSE
984  res = -1
985  END IF
986  END FUNCTION cp_print_key_unit_nr
987 
988 ! **************************************************************************************************
989 !> \brief should be called after you finish working with a unit obtained with
990 !> cp_print_key_unit_nr, so that the file that might have been opened
991 !> can be closed.
992 !>
993 !> the inputs should be exactly the same of the corresponding
994 !> cp_print_key_unit_nr
995 !> \param unit_nr ...
996 !> \param logger ...
997 !> \param basis_section ...
998 !> \param print_key_path ...
999 !> \param local ...
1000 !> \param ignore_should_output ...
1001 !> \param on_file ...
1002 !> \param mpi_io True if file was opened in parallel with MPI
1003 !> \par History
1004 !> 08.2002 created [fawzi]
1005 !> \author Fawzi Mohamed
1006 !> \note
1007 !> closes if the corresponding filename of the printkey is
1008 !> not __STD_OUT__
1009 ! **************************************************************************************************
1010  SUBROUTINE cp_print_key_finished_output(unit_nr, logger, basis_section, &
1011  print_key_path, local, ignore_should_output, on_file, &
1012  mpi_io)
1013  INTEGER, INTENT(INOUT) :: unit_nr
1014  TYPE(cp_logger_type), POINTER :: logger
1015  TYPE(section_vals_type), INTENT(IN) :: basis_section
1016  CHARACTER(len=*), INTENT(IN), OPTIONAL :: print_key_path
1017  LOGICAL, INTENT(IN), OPTIONAL :: local, ignore_should_output, on_file, &
1018  mpi_io
1019 
1020  CHARACTER(len=default_string_length) :: outpath
1021  LOGICAL :: my_local, my_mpi_io, my_on_file, &
1022  my_should_output
1023  TYPE(mp_file_type) :: mp_unit
1024  TYPE(section_vals_type), POINTER :: print_key
1025 
1026  my_local = .false.
1027  my_on_file = .false.
1028  my_mpi_io = .false.
1029  NULLIFY (print_key)
1030  IF (PRESENT(local)) my_local = local
1031  IF (PRESENT(on_file)) my_on_file = on_file
1032  IF (PRESENT(mpi_io)) my_mpi_io = mpi_io
1033  cpassert(ASSOCIATED(logger))
1034  cpassert(basis_section%ref_count > 0)
1035  cpassert(logger%ref_count > 0)
1036  my_should_output = btest(cp_print_key_should_output(logger%iter_info, basis_section, &
1037  print_key_path, used_print_key=print_key), cp_p_file)
1038  IF (PRESENT(ignore_should_output)) my_should_output = my_should_output .OR. ignore_should_output
1039  IF (my_should_output .AND. (my_local .OR. &
1040  logger%para_env%is_source() .OR. &
1041  my_mpi_io)) THEN
1042  CALL section_vals_val_get(print_key, "FILENAME", c_val=outpath)
1043  IF (my_on_file .OR. outpath .NE. '__STD_OUT__') THEN
1044  cpassert(unit_nr > 0)
1045  IF (.NOT. my_mpi_io) THEN
1046  CALL close_file(unit_nr, "KEEP")
1047  ELSE
1048  CALL mp_unit%set_handle(unit_nr)
1049  CALL mp_unit%close()
1050  END IF
1051  unit_nr = -1
1052  ELSE
1053  unit_nr = -1
1054  END IF
1055  END IF
1056  cpassert(unit_nr == -1)
1057  unit_nr = -1
1058  END SUBROUTINE cp_print_key_finished_output
1059 
1060 ! **************************************************************************************************
1061 !> \brief Sets flag which determines whether or not to use MPI I/O for I/O routines that
1062 !> have been parallized with MPI
1063 !> \param flag ...
1064 !> \par History
1065 !> 09.2018 created [Nico Holmberg]
1066 ! **************************************************************************************************
1067  SUBROUTINE cp_mpi_io_set(flag)
1068  LOGICAL, INTENT(IN) :: flag
1069 
1070  enable_mpi_io = flag
1071  END SUBROUTINE cp_mpi_io_set
1072 
1073 ! **************************************************************************************************
1074 !> \brief Gets flag which determines whether or not to use MPI I/O for I/O routines that
1075 !> have been parallized with MPI
1076 !> \return ...
1077 !> \par History
1078 !> 09.2018 created [Nico Holmberg]
1079 ! **************************************************************************************************
1080  FUNCTION cp_mpi_io_get() RESULT(flag)
1081  LOGICAL :: flag
1082 
1083  flag = enable_mpi_io
1084  END FUNCTION cp_mpi_io_get
1085 
1086 END MODULE cp_output_handling
static GRID_HOST_DEVICE int modulo(int a, int m)
Equivalent of Fortran's MODULO, which always return a positive number. https://gcc....
Definition: grid_common.h:117
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:308
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:119
Collection of routines to handle the iteration info.
Definition: cp_iter_types.F:11
character(len=default_path_length), dimension(18), parameter, public each_possible_labels
Definition: cp_iter_types.F:30
subroutine, public cp_iteration_info_retain(iteration_info)
retains the iteration_info (see doc/ReferenceCounting.html)
subroutine, public cp_iteration_info_release(iteration_info)
releases the iteration_info (see doc/ReferenceCounting.html)
character(len=default_path_length), dimension(18), parameter, public each_desc_labels
Definition: cp_iter_types.F:50
various routines to log and control the output. The idea is that decisions about where to log should ...
recursive integer function, public cp_logger_get_default_unit_nr(logger, local, skip_not_ionode)
asks the default unit number of the given logger. try to use cp_logger_get_unit_nr
integer function, public cp_logger_get_unit_nr(logger, local)
returns the unit nr for the requested kind of log.
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...
integer, parameter, public cp_out_calc
integer, parameter, public cp_out_file_each
integer, parameter, public cp_p_store_each
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)
subroutine, public cp_mpi_io_set(flag)
Sets flag which determines whether or not to use MPI I/O for I/O routines that have been parallized w...
integer, parameter, public cp_out_default
integer, parameter, public cp_out_store_if
integer, parameter, public debug_print_level
integer, parameter, public cp_out_store_each
integer, parameter, public cp_p_calc
integer, parameter, public cp_p_store_if
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 cp_out_file_if
integer, parameter, public cp_out_store
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,...
integer, parameter, public cp_p_file
integer, parameter, public cp_out_none
integer, parameter, public high_print_level
logical function, public cp_mpi_io_get()
Gets flag which determines whether or not to use MPI I/O for I/O routines that have been parallized w...
logical function, public cp_printkey_is_on(iteration_info, print_key)
returns true if the printlevel activates this printkey does not look if this iteration it should be p...
subroutine, public cp_iterate(iteration_info, last, iter_nr, increment, iter_nr_out)
adds one to the actual iteration
integer, parameter, public add_last_symbolic
integer, parameter, public cp_p_file_if
subroutine, public cp_rm_iter_level(iteration_info, level_name, n_rlevel_att)
Removes an iteration level.
integer function, public cp_print_key_should_output(iteration_info, basis_section, print_key_path, used_print_key, first_time)
returns what should be done with the given property if btest(res,cp_p_store) then the property should...
integer, parameter, public add_last_numeric
integer, parameter, public silent_print_level
integer, parameter, public cp_out_file
integer, parameter, public cp_p_file_each
integer, parameter, public cp_p_store
integer, parameter, public add_last_no
subroutine, public cp_print_key_section_create(print_key_section, location, name, description, print_level, each_iter_names, each_iter_values, add_last, filename, common_iter_levels, citations, unit_str)
creates a print_key section
subroutine, public cp_add_iter_level(iteration_info, level_name, n_rlevel_new)
Adds an iteration level.
represents keywords in an input
subroutine, public keyword_release(keyword)
releases the given keyword (see doc/ReferenceCounting.html)
subroutine, public keyword_create(keyword, location, name, description, usage, type_of_var, n_var, repeats, variants, default_val, default_l_val, default_r_val, default_lc_val, default_c_val, default_i_val, default_l_vals, default_r_vals, default_c_vals, default_i_vals, lone_keyword_val, lone_keyword_l_val, lone_keyword_r_val, lone_keyword_c_val, lone_keyword_i_val, lone_keyword_l_vals, lone_keyword_r_vals, lone_keyword_c_vals, lone_keyword_i_vals, enum_c_vals, enum_i_vals, enum, enum_strict, enum_desc, unit_str, citations, deprecation_notice, removed)
creates a keyword object
objects that represent the structure of input sections and the data contained in an input section
subroutine, public section_create(section, location, name, description, n_keywords, n_subsections, repeats, citations)
creates a list of keywords
subroutine, public section_add_keyword(section, keyword)
adds a keyword to the given section
subroutine, public section_add_subsection(section, subsection)
adds a subsection to the given 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
recursive subroutine, public section_release(section)
releases the given keyword list (see doc/ReferenceCounting.html)
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 default_string_length
Definition: kinds.F:57
integer, parameter, public default_path_length
Definition: kinds.F:58
Machine interface based on Fortran 2003 and POSIX.
Definition: machine.F:17
subroutine, public m_mov(source, TARGET)
...
Definition: machine.F:595
Utility routines for the memory handling.
Interface to the message passing library MPI.
subroutine, public mp_file_delete(filepath, info)
Deletes a file. Auxiliary routine to emulate 'replace' action for mp_file_open. Only the master proce...
subroutine, public mp_file_get_amode(mpi_io, replace, amode, form, action, status, position)
(parallel) Utility routine to determine MPI file access mode based on variables
Utilities for string manipulations.
subroutine, public compress(string, full)
Eliminate multiple space characters in a string. If full is .TRUE., then all spaces are eliminated.