Ignore:
Timestamp:
Mar 9, 2026, 10:29:53 AM (9 days ago)
Author:
jbclement
Message:

PEM:

  • Introduction of a configurable display/logging system with options 'out2term', 'out2log', 'verbosity_lvl'. All messages now use verbosity levels ('LVL_NFO', 'LVL_WRN', 'LVL_ERR' and 'LVL_DBG').
  • Code encapsulation improvements with systematic privacy/protection of module variables.
  • Addition of workflow safety checks for required executables, dependencies (e.g. 'ncdump'), input files and callphys keys.
  • Renaming of PEM starting and diagnostic files ("startevol.nc" into "startevo.nc", "diagevol.nc" into "diagevo.nc").

JBC

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/LMDZ.COMMON/libf/evolution/display.F90

    r4076 r4110  
    2525implicit none
    2626
    27 ! VARIABLES
    28 ! ---------
    29 character(128) :: dir = ' '      ! Current directory
    30 character(32)  :: logname = ' '  ! User name
    31 character(32)  :: hostname = ' ' ! Machine/station name
     27! PARAMETERS
     28! ----------
     29integer(di),    parameter          :: LVL_ERR = 0_di    ! Only errors
     30integer(di),    parameter          :: LVL_WRN = 1_di    ! Warnings
     31integer(di),    parameter          :: LVL_NFO = 2_di    ! Information (default)
     32integer(di),    parameter          :: LVL_DBG = 3_di    ! Debug
     33character(11),  parameter, private :: logfile_name = 'pem_run.log'
     34character(128), protected, private :: curr_dir = ' '    ! Current directory
     35character(32),  protected, private :: username = ' '    ! User name
     36character(32),  protected, private :: hostname = ' '    ! Machine/station name
     37integer(di),    protected, private :: verbosity_lvl = LVL_NFO
     38logical(k4),    protected, private :: out2term = .true. ! Flag to output to terminal
     39logical(k4),    protected, private :: out2log = .false. ! Flag to output to log file
     40integer(di),    protected, private :: logunit = -1_di   ! Log file unit
    3241
    3342contains
    3443!+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
     44
     45!=======================================================================
     46SUBROUTINE set_display_config(out2term_in,out2log_in,verbosity_lvl_in)
     47!-----------------------------------------------------------------------
     48! NAME
     49!     set_display_config
     50!
     51! DESCRIPTION
     52!     Setter for 'display' configuration parameters.
     53!
     54! AUTHORS & DATE
     55!     JB Clement, 03/2026
     56!
     57! NOTES
     58!
     59!-----------------------------------------------------------------------
     60
     61! DECLARATION
     62! -----------
     63implicit none
     64
     65! ARGUMENTS
     66! ---------
     67logical(k4), intent(in) :: out2term_in, out2log_in
     68integer(di), intent(in) :: verbosity_lvl_in
     69
     70! LOCAL VARIABLES
     71! ---------------
     72integer(di)    :: ierr
     73character(100) :: msg
     74
     75! CODE
     76! ----
     77out2term = out2term_in
     78out2log = out2log_in
     79verbosity_lvl = verbosity_lvl_in
     80call print_msg('out2term      = '//merge('true ','false',out2term),LVL_NFO)
     81call print_msg('out2log       = '//merge('true ','false',out2log),LVL_NFO)
     82write(msg,'(a,i1)') 'verbosity_lvl = ',verbosity_lvl
     83call print_msg(msg,LVL_NFO)
     84if (verbosity_lvl < 0 .or. verbosity_lvl > 3) then
     85    write(stderr,'(a,i5,a)') '[ERROR] Stopping in "'//__FILE__//'" at line ',__LINE__,'.'
     86    write(stderr,'(a)') '[ERROR] Reason: ''verbosity_lvl'' outside admissible range [0,3]!'
     87    write(stderr,'(a)') '[ERROR] Houston, we have a problem! Error code = 1'
     88    error stop 1
     89end if
     90
     91if (out2log) then
     92    open(newunit = logunit,file = logfile_name,status = 'replace',form = 'formatted',action = 'write',iostat = ierr)
     93    if (ierr /= 0) then
     94        write(stderr,'(a,i5,a)') '[ERROR] Stopping in "'//__FILE__//'" at line ',__LINE__,'.'
     95        write(stderr,'(a)') '[ERROR] Reason: error opening file "'//logfile_name//'"!'
     96        write(stderr,'(a,i3)') '[ERROR] Houston, we have a problem! Error code = ',ierr
     97        error stop ierr
     98    endif
     99endif
     100if (.not. out2term .and. .not. out2log) write(stdout,*) 'Warning: no output is set!'
     101
     102END SUBROUTINE set_display_config
     103!=======================================================================
    35104
    36105!=======================================================================
     
    59128character(10)             :: time
    60129character(5)              :: zone
     130character(100)            :: msg
    61131integer(di), dimension(8) :: values
    62132
    63133! CODE
    64134! ----
    65 write(stdout,*) '  *    .          .   +     .    *        .  +      .    .       .      '
    66 write(stdout,*) '           +         _______  ________  ____    ____      *           + '
    67 write(stdout,*) ' +   .        *     |_   __ \|_   __  ||_   \  /   _|          .       *'
    68 write(stdout,*) '          .     .     | |__) | | |_ \_|  |   \/   |  *        *      .  '
    69 write(stdout,*) '       .              |  ___/  |  _| _   | |\  /| |      .        .     '
    70 write(stdout,*) '.  *          *      _| |_    _| |__/ | _| |_\/_| |_                  * '
    71 write(stdout,*) '            +       |_____|  |________||_____||_____|   +     .         '
    72 write(stdout,*) '  .      *          .   *       .   +       *          .        +      .'
     135call print_msg('  *    .          .   +     .    *        .  +      .    .       .      ',LVL_NFO)
     136call print_msg('           +         _______  ________  ____    ____      *           + ',LVL_NFO)
     137call print_msg(' +   .        *     |_   __ \|_   __  ||_   \  /   _|          .       *',LVL_NFO)
     138call print_msg('          .     .     | |__) | | |_ \_|  |   \/   |  *        *      .  ',LVL_NFO)
     139call print_msg('       .              |  ___/  |  _| _   | |\  /| |      .        .     ',LVL_NFO)
     140call print_msg('.  *          *      _| |_    _| |__/ | _| |_\/_| |_                  * ',LVL_NFO)
     141call print_msg('            +       |_____|  |________||_____||_____|   +     .         ',LVL_NFO)
     142call print_msg('  .      *          .   *       .   +       *          .        +      .',LVL_NFO)
    73143
    74144! Some user info
    75145call date_and_time(date,time,zone,values)
    76 call getcwd(dir)
    77 call getlog(logname)
     146call getcwd(curr_dir)
     147call getlog(username)
    78148call hostnm(hostname)
    79 write(stdout,*)
    80 write(stdout,*) '********* PEM information *********'
    81 write(stdout,*)                     '+ User     : '//trim(logname)
    82 write(stdout,*)                     '+ Machine  : '//trim(hostname)
    83 write(stdout,*)                     '+ Directory: '//trim(dir)
    84 write(stdout,'(a,i2,a,i2,a,i4)')   ' + Date     : ',values(3),'/',values(2),'/',values(1)
    85 write(stdout,'(a,i2,a,i2,a,i2,a)') ' + Time     : ',values(5),':',values(6),':',values(7)
    86 write(stdout,*)
    87 write(stdout,*) '********* Initialization *********'
     149call print_msg('',LVL_NFO)
     150call print_msg('********* PEM information *********',LVL_NFO)
     151call print_msg('+ User     : '//trim(username),LVL_NFO)
     152call print_msg('+ Machine  : '//trim(hostname),LVL_NFO)
     153call print_msg('+ Directory: '//trim(curr_dir),LVL_NFO)
     154write(msg,'(a,i2,a,i2,a,i4)') '+ Date     : ',values(3),'/',values(2),'/',values(1)
     155call print_msg(msg,LVL_NFO)
     156write(msg,'(a,i2,a,i2,a,i2,a)') '+ Time     : ',values(5),':',values(6),':',values(7)
     157call print_msg(msg,LVL_NFO)
     158call print_msg('',LVL_NFO)
     159call print_msg('********* Initialization *********',LVL_NFO)
    88160
    89161END SUBROUTINE print_ini
     
    105177!
    106178!-----------------------------------------------------------------------
    107 
    108 ! DEPENDENCIES
    109 ! ------------
    110 use utility, only: format_duration, int2str
    111179
    112180! DECLARATION
     
    119187integer(di), intent(in) :: i_pem_run
    120188
    121 ! CODE
    122 ! ----
    123 write(stdout,*)
    124 write(stdout,*) '****** PEM final information *******'
    125 write(*,'(a,f16.4,a)')         ' + The run PEM #'//int2str(i_pem_run)//' achieved ', n_yr_run, ' Planetary years, completed in '//format_duration(dur_secs)//'.'
    126 write(*,'(a,f16.4,a,f16.4,a)') ' + The workflow has achieved ', n_yr_sim, ' Planetary years =', n_yr_sim*r_plnt2earth_yr, ' Earth years.'
    127 write(*,'(a,f16.4,a)')         ' + The reached date is now ', (pem_ini_date + n_yr_sim)*r_plnt2earth_yr, ' Earth years.'
    128 write(*,*)                      '+ PEM: so far, so good!'
    129 write(stdout,*) '************************************'
     189! LOCAL VARIABLES
     190! ---------------
     191character(100) :: msg
     192
     193! CODE
     194! ----
     195call print_msg('',LVL_NFO)
     196call print_msg('****** PEM final information *******',LVL_NFO)
     197write(msg,'(a,i0,a,f16.4,a)') ' + The run PEM #',i_pem_run,' achieved ', n_yr_run, ' Planetary years, completed in '//format_duration(dur_secs)//'.'
     198call print_msg(msg,LVL_NFO)
     199write(msg,'(a,f16.4,a,f16.4,a)') ' + The workflow has achieved ', n_yr_sim, ' Planetary years =', n_yr_sim*r_plnt2earth_yr, ' Earth years.'
     200call print_msg(msg,LVL_NFO)
     201write(msg,'(a,f16.4,a)') ' + The reached date is now ', (pem_ini_date + n_yr_sim)*r_plnt2earth_yr, ' Earth years.'
     202call print_msg(msg,LVL_NFO)
     203call print_msg('+ PEM: so far, so good!',LVL_NFO)
     204call print_msg('************************************',LVL_NFO)
    130205call but_why(n_yr_run)
    131206
     207! Close log file
     208if (out2log) close(logunit)
     209
    132210END SUBROUTINE print_end
    133211!=======================================================================
    134212
    135213!=======================================================================
    136 SUBROUTINE print_msg(message,frmt)
     214SUBROUTINE print_msg(message,lvl)
    137215!-----------------------------------------------------------------------
    138216! NAME
     
    140218!
    141219! DESCRIPTION
    142 !     Print a simple message (string).
    143 !
    144 ! AUTHORS & DATE
    145 !     JB Clement, 02/2026
     220!     Print a message (string) based on verbosity.
     221!
     222! AUTHORS & DATE
     223!     JB Clement, 03/2026
    146224!
    147225! NOTES
     
    155233! ARGUMENTS
    156234! ---------
    157 character(*), intent(in)           :: message
    158 character(*), intent(in), optional :: frmt
    159 
    160 ! CODE
    161 ! ----
    162 if (present(frmt)) then
    163     write(stdout,frmt) message
    164 else
    165     write(stdout,*) message
     235character(*), intent(in) :: message
     236integer(di),  intent(in) :: lvl
     237
     238! LOCAL VARIABLES
     239! ---------------
     240character(:), allocatable :: prefix
     241integer(di)               :: outunit
     242
     243! CODE
     244! ----
     245! Filter based on verbosity
     246if (lvl > verbosity_lvl) return
     247
     248! Prefix selection
     249select case (lvl)
     250    case (LVL_ERR)
     251        prefix = '[ERROR] '
     252    case (LVL_WRN)
     253        prefix = '[WARNING] '
     254    case (LVL_NFO)
     255        prefix = ''
     256    case (LVL_DBG)
     257        prefix = '[DEBUGGING] '
     258    case default
     259        write(stderr,'(a,i5,a)') '[ERROR] Stopping in "'//__FILE__//'" at line ',__LINE__,'.'
     260        write(stderr,'(a)') '[ERROR] Reason: unknown verbosity level for the message!'
     261        write(stderr,'(a)') '[ERROR] Houston, we have a problem! Error code = 1'
     262        error stop 1
     263end select
     264
     265! Terminal output
     266if (out2term) then
     267    if (lvl == LVL_ERR) then
     268        outunit = stderr
     269    else
     270        outunit = stdout
     271    end if
     272    write(outunit,'(a)') prefix//message
    166273end if
    167274
     275! Log file output
     276if (out2log) write(logunit,'(a)') prefix//message
     277
    168278END SUBROUTINE print_msg
    169279!=======================================================================
    170280
    171281!=======================================================================
    172 SUBROUTINE print_err(message,frmt)
    173 !-----------------------------------------------------------------------
    174 ! NAME
    175 !     print_err
    176 !
    177 ! DESCRIPTION
    178 !     Print a simple message (string).
    179 !
    180 ! AUTHORS & DATE
    181 !     JB Clement, 02/2026
     282FUNCTION format_duration(secs) RESULT(str)
     283!-----------------------------------------------------------------------
     284! NAME
     285!     format_duration
     286!
     287! DESCRIPTION
     288!     Converts a duration in seconds into a compact Xd HH:MM:SS format.
     289!
     290! AUTHORS & DATE
     291!     JB Clement, 01/2026
    182292!
    183293! NOTES
     
    191301! ARGUMENTS
    192302! ---------
    193 character(*), intent(in)           :: message
    194 character(*), intent(in), optional :: frmt
    195 
    196 ! CODE
    197 ! ----
    198 if (present(frmt)) then
    199     write(stderr,frmt) message
     303real(dp), intent(in) :: secs
     304
     305! LOCAL VARIABLES
     306! ---------------
     307integer(di)               :: days, hours, minutes, seconds
     308character(:), allocatable :: str
     309character(32)             :: tmp ! Work buffer
     310
     311! CODE
     312! ----
     313days = int(secs/86400._dp,di)
     314hours = int(mod(secs,86400._dp)/3600._dp,di)
     315minutes = int(mod(secs,3600._dp)/60._dp,di)
     316seconds = int(mod(secs,60._dp),di)
     317
     318if (days > 0_li) then
     319   write(tmp,'(i0,"d ",i2.2,":",i2.2,":",i2.2)') days, hours, minutes, seconds
    200320else
    201     write(stderr,*) message
     321   write(tmp,'(i2.2,":",i2.2,":",i2.2)') hours, minutes, seconds
    202322end if
    203323
    204 END SUBROUTINE print_err
     324str = trim(adjustl(tmp))
     325
     326END FUNCTION  format_duration
    205327!=======================================================================
    206328
     
    342464
    343465if (gottacatch_emall_()) then
    344     write(stdout,*)
     466    call print_msg('',LVL_NFO)
    345467    if (abs(n_yr_run - first_gen) < minieps) then
    346468        do i = 1,size(surprise)
    347             write(stdout,*) trim(surprise(i))
     469            call print_msg(trim(surprise(i)),LVL_NFO)
    348470        end do
    349         write(stdout,*) ' '
     471        call print_msg('',LVL_NFO)
    350472        do i = 1,size(exeggutor,1)
    351             write(stdout,*) trim(confusion(exeggutor(i,:)))
     473            call print_msg(trim(confusion(exeggutor(i,:))),LVL_NFO)
    352474        end do
    353475    else
    354476        do i = 1,size(why_not)
    355             write(stdout,*) trim(why_not(i))
     477            call print_msg(trim(why_not(i)),LVL_NFO)
    356478        end do
    357479    end if
     
    396518    flag = trim(why_yes) == 'yes'
    397519    if (.not. flag) then
    398         write(stdout,*)
    399         write(stdout,*) trim(confusion(who))
     520        call print_msg('',LVL_NFO)
     521        call print_msg(trim(confusion(who)),LVL_NFO)
    400522    end if
    401523end if
Note: See TracChangeset for help on using the changeset viewer.