(git:374b731)
Loading...
Searching...
No Matches
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,&
49 USE kinds, ONLY: default_path_length,&
51 USE machine, ONLY: m_mov
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, &
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), &
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
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
150CONTAINS
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"), &
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
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
1086END 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....
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.
character(len=default_path_length), dimension(18), parameter, public each_possible_labels
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
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.
contains the information about the current state of the program to be able to decide if output is nec...
type of a logger, at the moment it contains just a print level starting at which level it should be l...
represent a keyword in the input
represent a section of the input file