wiki:Documentation/UserGuide/Printlev

Last check: 2020/04/20, D. Goll

Control diagnostic text output

The control of text output in ORCHIDEE trunk is controlled by the externalized parameter PRINTLEV. It replaces BAVARD, LONGPRINT and local hard coded debug variables in ORCHIDEE trunk since revision 2348.

PRINTLEV : global parameter

PRINTLEV is an externalised parameter used to define a global level of output text information. Default value is 1.

PRINTLEV definition:

  • 0 no output.
  • 1 minimum writing for long simulations only at initialization and finalization phase (default)
  • 2 more basic information for long simulations, some daily information can be written, nothing must be written at each time step.
  • 3 first debug level: entering and leaving important subroutines can be reported.
  • 4 higher debug level: input parameters to major subroutines can be reported, other debug information.

In the code, use the following syntax:

IF (printlev>=1) WRITE(numout,*) 'This is a very important write statement...'
IF (printlev>=3) WRITE(numout,*) 'This is a debug print...'

PRINTLEV_modulename : local parameter to one module

The function get_ printlev('modulename') makes it possible to have a local write level in a module. Setting PRINTLEV_modulename in run.def changes then the write level in that module. The default value is the global PRINTLEV value. This functionality is available only in modules where the function get_printlev() is called. get_printlev should be called once in the initialization part for the module to define a new local saved variable. This new variable should be used in the whole module for all write statements instead of printlev.

For example in module condveg: In the beginning, declare a private module variable, before CONTAINS:

INTEGER, SAVE :: printlev_loc   !! Local level of text output for this module

In subroutine condveg_initialize:

!! Initialize local printlev
printlev_loc=get_printlev('condveg') 

In the example the function printlev_loc will read the variable PRINTLEV_condveg from run.def. The default value is the same as the global printlev variable.

In the rest of the module, all write statements should be done as follows:

IF (printlev_loc>=1) WRITE(numout,*) 'This is a (important) print related to initialization or finalization phase'
IF (printlev_loc>=3) WRITE(numout,*) 'This is a (less important) debug print, e.g. for entering or leaving subroutines'

How to add printlev_loc in a new module

Add in the beginning of the module before CONTAINS, the declaration of printlev_loc. This variable must be PRIVATE (the keyword PRIVATE must only be set once).

 PRIVATE
 INTEGER(i_std), SAVE       :: printlev_loc       !! Local level of text output for current module
!$OMP THREADPRIVATE(printlev_loc)

The subroutine get_printlev must then be added before the first write statement in the module. Depending on the module strucuture, do as below.

Case 1) If the module contains an initialization subroutine called only once, add call to get_printlev as follow, where xxxx should be replaced by the name of the module:

    !! Initialize local printlev
    printlev_loc=get_printlev('xxxx')

Case 2) If there is no specific subroutine for initialization, add in the first called public subroutine using a logical firstcall_xxxx:

    IF (firstcall_xxxx) THEN
      !! Initialize local printlev
      printlev_loc=get_printlev('xxxx')
      firstcall_xxxx=.FALSE.
    END IF

Note that firstcall_xxxx must be declared as a private module variable, before CONTAINS as follow:

  LOGICAL, SAVE             :: firstcall_xxxx = .TRUE.   !! first call flag
!$OMP THREADPRIVATE(firstcall_xxxx)

Even though this variable firstcall_xxxx is local to the module, it must have a specific name (by adding_xxxx) unique in ORCHIDEE. This is a constraint from the assimilation tool.

Case 3) If there is no initialization subroutine and there are several public subroutines that can be called in different orders the above IF (firstcall_xxxx)... section should be added in each of them. Note that xxxx should still be the same in the whole module. Only the first subroutine which is called will then do the call to get_printlev. For example in module sapiens_agriculture.

Last modified 4 years ago Last modified on 2020-04-20T13:15:09+02:00