LCOV - code coverage report
Current view: top level - shared/libpaw/src - m_libpaw_tools.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 16.0 % 181 29
Test Date: 2026-09-21 22:40:37 Functions: 33.3 % 18 6

            Line data    Source code
       1              : !!****m* ABINIT/m_libpaw_tools
       2              : !! NAME
       3              : !!  m_libpaw_tools
       4              : !!
       5              : !! FUNCTION
       6              : !!  Several libPAW tools: message printing, error handling, string handling...
       7              : !!
       8              : !! COPYRIGHT
       9              : !!  Copyright (C) 2014-2026 ABINIT group (MT, MG, ...)
      10              : !!  This file is distributed under the terms of the
      11              : !!  GNU General Public License, see ~abinit/COPYING
      12              : !!  or http://www.gnu.org/copyleft/gpl.txt .
      13              : !!
      14              : !! NOTES
      15              : !!  Parts of this module come directly from hide_write & hide_leave src files delivered with ABINIT.
      16              : !!
      17              : !!  FOR DEVELOPPERS: in order to preserve the portability of libPAW library,
      18              : !!  please consult ~abinit/src/??_libpaw/libpaw-coding-rules.txt
      19              : !!
      20              : !! SOURCE
      21              : 
      22              : #include "libpaw.h"
      23              : 
      24              : module m_libpaw_tools
      25              : 
      26              :  USE_DEFS
      27              :  USE_MPI_WRAPPERS
      28              : 
      29              : #if defined HAVE_YAML
      30              :   use yaml_output
      31              : #endif
      32              : #ifdef LIBPAW_HAVE_NETCDF
      33              :   use netcdf
      34              : #endif
      35              : 
      36              :  implicit none
      37              : 
      38              :  private
      39              : 
      40              : !PUBLIC FUNCTIONS - MESSAGE HANDLING
      41              :  public  :: libpaw_wrtout         ! Parallel output of messages
      42              :  public  :: libpaw_msg_hndl       ! Basic error handler
      43              :  public  :: libpaw_flush          ! Wrapper for the standard flush routine
      44              :  public  :: libpaw_spmsg_getcount ! Get number of special messages (WARNING/COMMENT) already printed
      45              :  public  :: libpaw_spmsg_mpisum   ! Reduce number of special messages (WARNING/COMMENT) over MPI comm
      46              :  public  :: libpaw_write_comm_set ! Set the MPI communicator used for parallel write
      47              :  public  :: libpaw_log_flag_set   ! Set the flag controlling the filling of the LOG file
      48              :  public  :: libpaw_netcdf_check   ! Stop execution after a NetCDF I/O error
      49              : 
      50              : !PUBLIC FUNCTIONS - STRING HANDLING
      51              :  public  :: libpaw_basename       ! String, base name extraction from path
      52              :  public  :: libpaw_to_upper       ! String conversion to uppercase
      53              :  public  :: libpaw_lstrip         ! String right blanks removal
      54              :  public  :: libpaw_indent         ! String indentation
      55              : 
      56              : !PUBLIC FUNCTIONS - IO TOOLS
      57              :  public :: libpaw_get_free_unit  ! Get a free I/O unit
      58              : 
      59              : !PRIVATE FUNCTIONS
      60              :  private :: libpaw_wrtout_myproc  ! Sequential output of messages
      61              :  private :: libpaw_write_lines    ! OS-compatible string output
      62              :  private :: libpaw_leave          ! Clean exit of F90 routines
      63              :  private :: libpaw_die            ! Clean exit
      64              :  private :: libpaw_lock_and_write ! Write a string to a file with locking mechanism
      65              : 
      66              : !PRIVATE VARIABLES
      67              :  integer,save :: LIBPAW_WRITE_COMM=xmpi_world ! Communicator used for the parallel write
      68              :  integer,save :: LIBPAW_COMMENT_COUNT=0           ! Number of COMMENTs printed in log file
      69              :  integer,save :: LIBPAW_WARNING_COUNT=0           ! Number of WARNINGs printed in log file
      70              :  integer,save :: LIBPAW_EXIT_FLAG=0               ! Flag set to 1 if an exit is requested
      71              :  logical,save :: LIBPAW_HAS_LOG_FILE=.TRUE.       ! Flag: True if std output exists
      72              : 
      73              : !PRIVATE PARAMETERS
      74              :  integer,parameter :: LIBPAW_NULL_UNIT=-1     ! Fake null unit
      75              :  character(len=25),parameter :: LIBPAW_MPIABORTFILE="__LIBPAW_MPIABORTFILE__"
      76              : #if defined HAVE_OS_WINDOWS
      77              :  character(len=3),parameter :: LIBPAW_NULL_FILE="NUL"
      78              : #else
      79              :  character(len=9),parameter :: LIBPAW_NULL_FILE="/dev/null"
      80              : #endif
      81              : 
      82              : !!***
      83              : 
      84              : CONTAINS !===========================================================
      85              : 
      86              : !!****f* m_libpaw_tools/libpaw_wrtout
      87              : !! NAME
      88              : !! libpaw_wrtout
      89              : !!
      90              : !! FUNCTION
      91              : !!  Organizes the sequential or parallel version of the write intrinsic
      92              : !!
      93              : !! INPUTS
      94              : !!  msg=(character(len=*)) message to be written
      95              : !!  unit=unit number for writing. The named constant dev_null defined in defs_basis can be used to avoid any printing.
      96              : !!  [mode_paral]= --optional argument--
      97              : !!   'COLL' if all procs are calling the routine with the same message to be written once only. Default.
      98              : !!   'PERS' if the procs are calling the routine with different messages each to be written,
      99              : !!          or if one proc is calling the routine
     100              : !!   "INIT" to change the rank of the master node that prints the message if "COLL" is used.
     101              : !!
     102              : !! OUTPUT
     103              : !!  (only writing)
     104              : !!
     105              : !! NOTES
     106              : !!  This routine comes directly from the WRTOUT routine delivered with ABINIT.
     107              : !!
     108              : !! SOURCE
     109              : 
     110            0 : subroutine libpaw_wrtout(unit,msg,mode_paral)
     111              : 
     112              : !Arguments ------------------------------------
     113              :  integer,intent(in) :: unit
     114              :  character(len=*),intent(in) :: msg
     115              :  character(len=*),optional,intent(in) :: mode_paral
     116              : 
     117              : !Local variables ------------------------------
     118              :  integer :: comm,me,nproc
     119              :  integer,save :: master=0
     120            0 :  character(len=len(msg)+50) :: string
     121              :  character(len=500) :: my_mode_paral
     122              : 
     123              : !******************************************************************
     124              : 
     125            0 :  if ((unit==std_out).and.(.not.LIBPAW_HAS_LOG_FILE)) RETURN
     126            0 :  if (unit==LIBPAW_NULL_UNIT) RETURN
     127              : 
     128            0 :  my_mode_paral = "COLL"; if (PRESENT(mode_paral)) my_mode_paral = mode_paral
     129              : 
     130              : !Communicator used for the parallel write
     131            0 :  comm=LIBPAW_WRITE_COMM
     132            0 :  nproc = xmpi_comm_size(comm)
     133            0 :  me    = xmpi_comm_rank(comm)
     134              : 
     135            0 :  if ((my_mode_paral=='COLL').or.(nproc==1)) then
     136            0 :    if (me==master) then
     137            0 :      call libpaw_wrtout_myproc(unit,msg)
     138              :    end if
     139            0 :  else if (my_mode_paral=='PERS') then
     140            0 :    call libpaw_write_lines(unit,msg)
     141            0 :  else if (my_mode_paral=='INIT') then
     142            0 :    master=unit
     143              :  else
     144            0 :    write(string,'(7a)')ch10,&
     145            0 : &   'libpaw_wrtout: ERROR -',ch10,&
     146            0 : &   '  Unknown write mode: ',my_mode_paral,ch10,&
     147            0 : &   '  Continuing anyway ...'
     148            0 :    write(unit,'(A)') trim(string)
     149              :  end if
     150              : 
     151            0 : end subroutine libpaw_wrtout
     152              : !!***
     153              : 
     154              : !----------------------------------------------------------------------
     155              : 
     156              : !!****f* m_libpaw_tools/libpaw_wrtout_myproc
     157              : !! NAME
     158              : !!  libpaw_wrtout_myproc
     159              : !!
     160              : !! FUNCTION
     161              : !!  Do the output for one proc.
     162              : !!
     163              : !! INPUTS
     164              : !!  unit=unit number for writing
     165              : !!  msg=(character(len=*)) message to be written
     166              : !!
     167              : !! OUTPUT
     168              : !!  (only writing)
     169              : !!
     170              : !! NOTES
     171              : !!  This routine comes directly from the WRTOUT_MYPROC routine delivered with ABINIT.
     172              : !!
     173              : !! SOURCE
     174              : 
     175            0 : subroutine libpaw_wrtout_myproc(unit,msg)
     176              : 
     177              : !Arguments ------------------------------------
     178              : !scalars
     179              :  integer,intent(in) :: unit
     180              :  character(len=*),intent(in) :: msg
     181              : 
     182              : !Local variables ------------------------------
     183              : !scalars
     184              :  logical :: print_std_err
     185              : !arrays
     186              : 
     187              : !******************************************************************
     188              : 
     189            0 :  print_std_err=(unit==std_out.and.(index(trim(msg),'BUG')/=0.or.index(trim(msg),'ERROR')/=0))
     190              : 
     191              : !Print message
     192            0 :  call libpaw_write_lines(unit,msg)
     193            0 :  if (print_std_err) then
     194            0 :    call libpaw_write_lines(std_err,msg)
     195              :  end if
     196              : 
     197              : !Append "Contact Abinit group" to BUG messages
     198            0 :  if (index(trim(msg),'BUG')/=0) then
     199            0 :    write(unit,'(a)') '  Action: contact libPAW developers.'
     200            0 :    if (print_std_err) write(std_err, '(a)' ) '  Action: contact libPAW developers.'
     201            0 :    write(unit,*); if (print_std_err) write(std_err,*)
     202              :  end if
     203              : 
     204              : !Count the number of warnings and comments. Only take into
     205              : !account unit std_out, in order not to duplicate these numbers.
     206            0 :  if (index(trim(msg),'WARNING')/=0 .and. unit==std_out) LIBPAW_WARNING_COUNT=LIBPAW_WARNING_COUNT+1
     207            0 :  if (index(trim(msg),'COMMENT')/=0 .and. unit==std_out) LIBPAW_COMMENT_COUNT=LIBPAW_COMMENT_COUNT+1
     208            0 :  if (index(trim(msg),'Exit'   )/=0) LIBPAW_EXIT_FLAG=1
     209              : 
     210            0 : end subroutine libpaw_wrtout_myproc
     211              : !!***
     212              : 
     213              : !----------------------------------------------------------------------
     214              : 
     215              : !!****f* m_libpaw_tools/libpaw_write_lines
     216              : !! NAME
     217              : !!  libpaw_write_lines
     218              : !!
     219              : !! FUNCTION
     220              : !!  This routine receives a string, split the message in lines according to the
     221              : !!  ch10 character and output the text to the specified unit.
     222              : !!  Allows to treat correctly the write operations for Unix (+DOS) and MacOS.
     223              : !!
     224              : !! INPUTS
     225              : !!  unit=unit number for writing
     226              : !!  msg=(character(len=*)) message to be written
     227              : !!
     228              : !! OUTPUT
     229              : !!  (only writing)
     230              : !!
     231              : !! NOTES
     232              : !!  This routine comes directly from the WRITE_LINES routine delivered with ABINIT.
     233              : !!
     234              : !! SOURCE
     235              : 
     236            0 : subroutine libpaw_write_lines(unit,msg)
     237              : 
     238              : !Arguments ------------------------------------
     239              : !scalars
     240              :  integer,intent(in) :: unit
     241              :  character(len=*),intent(in) :: msg
     242              : 
     243              : !Local variables ------------------------------
     244              : !scalars
     245              :  integer :: msg_size,ii,jj,rtnpos
     246              : #if defined HAVE_YAML
     247              :  character(len = len_trim(msg)) :: msg_out
     248              : #endif
     249              : 
     250              : !******************************************************************
     251              : 
     252            0 :  msg_size=len_trim(msg)
     253              : 
     254              : #if defined HAVE_YAML
     255              :  if (msg_size>0 .and. unit==std_out) then
     256              :     ! Change any carriage return into space.
     257              :     do ii = 1, msg_size
     258              :        if (msg(ii:ii) /= char(10)) then
     259              :           msg_out(ii:ii) = msg(ii:ii)
     260              :        else
     261              :           msg_out(ii:ii) = " "
     262              :        end if
     263              :     end do
     264              :     call yaml_comment(msg_out)
     265              :  end if
     266              :  return
     267              : #endif
     268              : 
     269            0 :  if (msg_size==0) then
     270            0 :    write(unit,*) ; return
     271              :  end if
     272              : 
     273              : !Here, split the message, according to the char(10) characters (carriage return).
     274              : !This technique is portable accross different OS.
     275            0 :  rtnpos=index(msg,ch10)
     276            0 :  if (rtnpos==0) then
     277            0 :    write(unit,"(a)") msg(1:msg_size) ; return
     278              :  end if
     279              : 
     280              :  ii=1; jj=rtnpos
     281              :  do
     282            0 :    if (ii==jj) then
     283            0 :      write(unit,*)
     284              :    else
     285            0 :      write(unit,'(a)') msg(ii:jj-1)
     286              :    end if
     287            0 :    ii=jj+1 ; if (ii>msg_size) exit
     288            0 :    jj=index(msg(ii:msg_size),ch10)
     289            0 :    if (jj==0) then
     290            0 :      jj=msg_size+1
     291              :    else
     292            0 :      jj=jj+ii-1
     293              :    end if
     294              :  end do
     295              : 
     296            0 :  if (msg(msg_size:msg_size)==ch10) write(unit,*)
     297              : 
     298              : end subroutine libpaw_write_lines
     299              : !!***
     300              : 
     301              : !----------------------------------------------------------------------
     302              : 
     303              : !!****f* m_libpaw_tools/libpaw_msg_hndl
     304              : !! NAME
     305              : !!  libpaw_msg_hndl
     306              : !!
     307              : !! FUNCTION
     308              : !!  Basic error handler.
     309              : !!
     310              : !! INPUTS
     311              : !!  msg=string containing additional information on the nature of the problem
     312              : !!  level=string defining the type of problem. Possible values are:
     313              : !!   COMMENT, WARNING, ERROR,BUG
     314              : !!  mode_paral=Either "COLL" or "PERS".
     315              : !!  [line]=line number of the file where problem occurred (optional)
     316              : !!  [file]=name of the f90 file containing the caller (optional)
     317              : !!
     318              : !! OUTPUT
     319              : !!  (only writing)
     320              : !!
     321              : !! NOTES
     322              : !!  This routine comes directly from the MSG_HNDL routine delivered with ABINIT.
     323              : !!
     324              : !! SOURCE
     325              : 
     326            0 : subroutine libpaw_msg_hndl(msg,level,mode_paral,file,line)
     327              : 
     328              : !Arguments ------------------------------------
     329              :  integer,optional,intent(in) :: line
     330              :  character(len=*),intent(in) :: level,msg,mode_paral
     331              :  character(len=*),optional,intent(in) :: file
     332              : 
     333              : !Local variables ------------------------------
     334              :  logical :: file_exists
     335              :  character(len=500) :: f90name='Unknown'
     336            0 :  character(len=LEN(msg)) :: my_msg
     337            0 :  character(len=MAX(4*LEN(msg),2000)) :: sbuf
     338              : 
     339              : ! *********************************************************************
     340              : 
     341            0 :  my_msg=libpaw_lstrip(msg)
     342              : 
     343            0 :  write(sbuf,'(3a)') ch10,"--- !",TRIM(level)
     344            0 :  if (PRESENT(file)) then
     345            0 :    f90name=libpaw_basename(file)
     346            0 :    write(sbuf,'(4a)') trim(sbuf),ch10,"src_file: ",TRIM(f90name)
     347              :  end if
     348            0 :  if (PRESENT(line)) then
     349            0 :    write(sbuf,'(3a,i0)') trim(sbuf),ch10,"src_line: ",line
     350              :  end if
     351            0 :  write(sbuf,'(8a)') trim(sbuf),ch10,&
     352            0 : &  "message: |",ch10,trim(libpaw_indent(my_msg)),ch10,&
     353            0 : &  "...",ch10
     354              : 
     355            0 :  select case (libpaw_to_upper(level))
     356              :  case ('COMMENT','WARNING')
     357            0 :    call libpaw_wrtout(std_out,sbuf,mode_paral)
     358              :  case ('ERROR','BUG')
     359            0 :    call libpaw_wrtout(std_out,sbuf,mode_paral)
     360            0 :    inquire(file=LIBPAW_MPIABORTFILE,exist=file_exists)
     361            0 :    if ((.not.file_exists).and.xmpi_comm_size(xmpi_world)>1) then
     362            0 :      call libpaw_lock_and_write(LIBPAW_MPIABORTFILE,sbuf)
     363              :    end if
     364            0 :    call libpaw_leave(mode_paral)
     365              :  case default
     366            0 :    write(sbuf,'(4a)') ch10,' libpaw_msg_hndl: BUG**2 - ',ch10,' Wrong value for level!'
     367            0 :    call libpaw_die(sbuf)
     368              :  end select
     369              : 
     370            0 : end subroutine libpaw_msg_hndl
     371              : !!***
     372              : 
     373              : !----------------------------------------------------------------------
     374              : 
     375              : !!****f* m_libpaw_tools/libpaw_spmsg_getcount
     376              : !! NAME
     377              : !!  libpaw_spmsg_getcount
     378              : !!
     379              : !! FUNCTION
     380              : !!  Get the values of the counters of special messages (WARNING, COMMENT)
     381              : !!
     382              : !! INPUTS
     383              : !!  ncomment= number of COMMENTs in log file
     384              : !!  nwarning= number of WARNINGs in log file
     385              : !!  nexit=    1 if exit requested
     386              : !!
     387              : !! OUTPUT
     388              : !!  (only counters updated)
     389              : !!
     390              : !! NOTES
     391              : !!  This routine comes directly from the SPECIALMSG_GETCOUNT routine delivered with ABINIT.
     392              : !!
     393              : !! SOURCE
     394              : 
     395         1426 : subroutine libpaw_spmsg_getcount(ncomment,nwarning,nexit)
     396              : 
     397              : !Arguments ------------------------------------
     398              :  integer,intent(out) :: ncomment,nexit,nwarning
     399              : 
     400              : !Local variables ------------------------------
     401              : 
     402              : ! **********************************************************************
     403              : 
     404         1426 :  ncomment=LIBPAW_COMMENT_COUNT
     405         1426 :  nwarning=LIBPAW_WARNING_COUNT
     406         1426 :  nexit   =LIBPAW_EXIT_FLAG
     407              : 
     408         1426 : end subroutine libpaw_spmsg_getcount
     409              : !!***
     410              : 
     411              : !----------------------------------------------------------------------
     412              : 
     413              : !!****f* m_libpaw_tools/libpaw_spmsg_mpisum
     414              : !! NAME
     415              : !!  libpaw_spmsg_mpisum
     416              : !!
     417              : !! FUNCTION
     418              : !!  Reduce the counters of special messages (WARNING, COMMENTS, EXIT) over a MPI communicator
     419              : !!
     420              : !! INPUTS
     421              : !!  mpicomm= MPI communicator
     422              : !!
     423              : !! OUTPUT
     424              : !!  (only counters updated)
     425              : !!
     426              : !! NOTES
     427              : !!  This routine comes directly from the SPECIALMSG_MPISUM routine delivered with ABINIT.
     428              : !!
     429              : !! SOURCE
     430              : 
     431            0 : subroutine libpaw_spmsg_mpisum(mpicomm)
     432              : 
     433              : !Arguments ------------------------------------
     434              :  integer,intent(in) :: mpicomm
     435              : 
     436              : !Local variables ------------------------------
     437              :  integer :: ierr
     438              :  integer :: buf(3)
     439              : 
     440              : ! **********************************************************************
     441              : 
     442            0 :   buf(1)=LIBPAW_COMMENT_COUNT;buf(2)=LIBPAW_WARNING_COUNT;buf(3)=LIBPAW_EXIT_FLAG
     443              : 
     444            0 :   call xmpi_sum(buf,mpicomm,ierr)
     445              : 
     446            0 :   LIBPAW_COMMENT_COUNT=buf(1)
     447            0 :   LIBPAW_WARNING_COUNT=buf(2)
     448            0 :   LIBPAW_EXIT_FLAG=buf(3) ; if (LIBPAW_EXIT_FLAG/=0) LIBPAW_EXIT_FLAG=1
     449              : 
     450            0 : end subroutine libpaw_spmsg_mpisum
     451              : !!***
     452              : 
     453              : !----------------------------------------------------------------------
     454              : 
     455              : !!****f* m_libpaw_tools/libpaw_write_comm_set
     456              : !! NAME
     457              : !!  libpaw_write_comm_set
     458              : !!
     459              : !! FUNCTION
     460              : !!  Set the MPI communicator used for parallel write
     461              : !!
     462              : !! INPUTS
     463              : !!  new_write_comm= new value for the parallel write MPI communicator
     464              : !!
     465              : !! OUTPUT
     466              : !!
     467              : !! SOURCE
     468              : 
     469        20971 : subroutine libpaw_write_comm_set(new_write_comm)
     470              : 
     471              : !Arguments ------------------------------------
     472              :  integer,intent(in) :: new_write_comm
     473              : 
     474              : !Local variables ------------------------------
     475              : 
     476              : ! **********************************************************************
     477              : 
     478        20971 :  LIBPAW_WRITE_COMM=new_write_comm
     479              : 
     480        20971 : end subroutine libpaw_write_comm_set
     481              : !!***
     482              : 
     483              : !----------------------------------------------------------------------
     484              : 
     485              : !!****f* m_libpaw_tools/libpaw_log_flag_set
     486              : !! NAME
     487              : !!  libpaw_log_flag_set
     488              : !!
     489              : !! FUNCTION
     490              : !!  Set the flag controlling the filling of the LOG file
     491              : !!
     492              : !! INPUTS
     493              : !!  log_flag= new value for LOG file flag
     494              : !!            True: the log file is filled; False: no the log file
     495              : !!
     496              : !! OUTPUT
     497              : !!
     498              : !! SOURCE
     499              : 
     500          278 : subroutine libpaw_log_flag_set(log_flag)
     501              : 
     502              : !Arguments ------------------------------------
     503              :  logical,intent(in) :: log_flag
     504              : 
     505              : !Local variables ------------------------------
     506              : 
     507              : ! **********************************************************************
     508              : 
     509          278 :  LIBPAW_HAS_LOG_FILE=log_flag
     510              : 
     511          278 : end subroutine libpaw_log_flag_set
     512              : !!***
     513              : 
     514              : !----------------------------------------------------------------------
     515              : 
     516              : !!****f* m_libpaw_tool/libpaw_netcdf_check
     517              : !! NAME
     518              : !!  libpaw_netcdf_check
     519              : !!
     520              : !! FUNCTION
     521              : !!  Error handler for Netcdf calls.
     522              : !!
     523              : !! INPUTS
     524              : !!  ncerr=Status error returned by the Netcdf library.
     525              : !!  msg=User-defined string with info on the action that was performed
     526              : !!  file= name of the file.
     527              : !!  line= line number.
     528              : !!
     529              : !! NOTES
     530              : !!  This routine is usually interfaced with the macros defined in libpaw.h
     531              : !!
     532              : !! SOURCE
     533              : 
     534            0 : subroutine libpaw_netcdf_check(ncerr,msg,file,line)
     535              : 
     536              : !Arguments ------------------------------------
     537              :  integer,intent(in) :: ncerr
     538              :  character(len=*),intent(in) :: msg
     539              :  character(len=*),optional,intent(in) :: file
     540              :  integer,optional,intent(in) :: line
     541              : 
     542              : !Local variables-------------------------------
     543              :  integer :: f90line
     544              :  character(len=500) :: f90name
     545              :  character(len=1024) :: nc_msg
     546              :  character(len=2048) :: my_msg
     547              : 
     548              : ! *************************************************************************
     549              : 
     550              : #ifdef LIBPAW_HAVE_NETCDF
     551            0 :  if (ncerr /= NF90_NOERR) then
     552            0 :    if (PRESENT(line)) then
     553            0 :      f90line=line
     554              :    else
     555            0 :      f90line=0
     556              :    end if
     557            0 :    if (PRESENT(file)) then
     558            0 :      f90name = libpaw_basename(file)
     559              :    else
     560            0 :      f90name='Subroutine Unknown'
     561              :    end if
     562              :    !
     563              :    ! Append Netcdf string to user-defined message.
     564            0 :    write(nc_msg,'(a,3x,a)')' - NetCDF library returned:',TRIM(nf90_strerror(ncerr))
     565            0 :    my_msg = TRIM(msg) // TRIM(nc_msg)
     566              : 
     567            0 :    call libpaw_msg_hndl(my_msg,"ERROR","PERS",f90name,f90line)
     568              :  end if
     569              : #else
     570              :  call libpaw_die("LIBPAW_HAVE_NETCDF is not defined!")
     571              : #endif
     572              : 
     573            0 : end subroutine libpaw_netcdf_check
     574              : !!***
     575              : 
     576              : !----------------------------------------------------------------------
     577              : 
     578              : !!****f* m_libpaw_tools/libpaw_leave
     579              : !! NAME
     580              : !!  libpaw_leave
     581              : !!
     582              : !! FUNCTION
     583              : !!  Routine for clean exit of f90 code, taking into account possible parallelization.
     584              : !!
     585              : !! INPUTS
     586              : !!  mode_paral=
     587              : !!   'COLL' if all procs are calling the routine with the same msg to be written once only
     588              : !!   'PERS' if the procs are calling the routine with different msgs each to be written,
     589              : !!          or if one proc is calling the routine
     590              : !!  [exit_status]=(optional, default=1 or -1, see below) the return code of the routine
     591              : !!
     592              : !! OUTPUT
     593              : !!  (only writing)
     594              : !!
     595              : !! NOTES
     596              : !!  This routine comes directly from the LEAVE_NEW routine delivered with ABINIT.
     597              : !!  By default, it uses "call exit(1)", that is not completely portable.
     598              : !!
     599              : !! SOURCE
     600              : 
     601            0 : subroutine libpaw_leave(mode_paral,exit_status)
     602              : 
     603              : !Arguments ------------------------------------
     604              :  integer,intent(in),optional :: exit_status
     605              :  character(len=4),intent(in) :: mode_paral
     606              : 
     607              : !Local variables ------------------------------
     608              : 
     609              : ! **********************************************************************
     610              : 
     611            0 :  call libpaw_wrtout(std_out,ch10//' leave_new : decision taken to exit ...','PERS')
     612              : 
     613              : !Caveat: Do not use MPI collective calls!
     614            0 :  if (mode_paral=="COLL") then
     615            0 :    call libpaw_wrtout(std_out,"Why COLL? Are you sure that ALL the processors are calling leave_new?")
     616              :  end if
     617              : 
     618            0 :  if (present(exit_status)) then
     619            0 :    call xmpi_abort(exit_status=exit_status)
     620              :  else
     621            0 :    call xmpi_abort()
     622              :  end if
     623              : 
     624            0 : end subroutine libpaw_leave
     625              : !!***
     626              : 
     627              : !----------------------------------------------------------------------
     628              : 
     629              : !!****f* m_libpaw_tools/libpaw_die
     630              : !! NAME
     631              : !!  libpaw_die
     632              : !!
     633              : !! FUNCTION
     634              : !!  Stop smoothly the execution in case of unexpected events reporting the
     635              : !!  line number and the file name where the error occurred as well as the
     636              : !!  MPI rank of the processor.
     637              : !!
     638              : !! INPUTS
     639              : !!  msg=String containing additional information on the nature of the problem
     640              : !!  [file]=Name of the f90 file containing the caller
     641              : !!  [line]=Line number of the file where problem occurred
     642              : !!
     643              : !! NOTES
     644              : !!  This routine comes directly from the DIE routine delivered with ABINIT.
     645              : !!
     646              : !! SOURCE
     647              : 
     648            0 : subroutine libpaw_die(message,file,line)
     649              : 
     650              : !Arguments ------------------------------------
     651              :  integer,optional,intent(in) :: line
     652              :  character(len=*),intent(in) :: message
     653              :  character(len=*),optional,intent(in) :: file
     654              : 
     655              : !Local variables ------------------------------
     656              :  integer :: rank
     657              :  integer :: f90line=0
     658              :  character(len=10) :: lnum,strank
     659              :  character(len=500) :: f90name='Subroutine Unknown'
     660              :  character(len=500) :: msg
     661              : 
     662              : ! *********************************************************************
     663              : 
     664            0 :  if (PRESENT(line)) f90line=line
     665            0 :  if (PRESENT(file)) f90name= libpaw_basename(file)
     666              : 
     667            0 :  rank=xmpi_comm_rank(xmpi_world) !Determine my rank inside world communicator
     668              : 
     669            0 :  write(lnum,"(i0)") f90line
     670            0 :  write(strank,"(i0)") rank
     671            0 :  msg=TRIM(f90name)//':'//TRIM(lnum)//' P'//TRIM(strank)
     672            0 :  write(msg,'(a,2x,2a,2x,a)') ch10,TRIM(msg),ch10,TRIM(message)
     673              : 
     674            0 :  call libpaw_wrtout(std_out,msg,'PERS')
     675            0 :  call libpaw_leave('PERS')
     676              : 
     677            0 : end subroutine libpaw_die
     678              : !!***
     679              : 
     680              : !----------------------------------------------------------------------
     681              : 
     682              : !!****f* m_libpaw_tools/libpaw_lock_and_write
     683              : !! NAME
     684              : !!  libpaw_lock_and_write
     685              : !!
     686              : !! FUNCTION
     687              : !!  Writes a string to filename with locking mechanism.
     688              : !!
     689              : !! INPUTS
     690              : !!  filename= Name of the file.
     691              : !!  string= Input string.
     692              : !!
     693              : !! SOURCE
     694              : 
     695            0 : subroutine libpaw_lock_and_write(filename,string)
     696              : 
     697              : !Arguments ------------------------------------
     698              :  character(len=*),intent(in) :: filename,string
     699              : 
     700              : !Local variables-------------------------------
     701              :  integer :: lock_unit,file_unit
     702            0 :  character(len=len(filename)+5) :: lock
     703              : 
     704              : ! *********************************************************************
     705              : 
     706              :  !Try to acquire the lock.
     707            0 :  lock=trim(filename)//".lock"
     708            0 :  lock_unit=libpaw_get_free_unit()
     709            0 :  open(unit=lock_unit,file=trim(lock),status='new',err=99)
     710              : 
     711            0 :  file_unit=libpaw_get_free_unit()
     712            0 :  open(unit=file_unit,file=trim(filename),form="formatted")
     713            0 :  call libpaw_write_lines(file_unit,string)
     714            0 :  close(lock_unit,status="delete")
     715            0 :  close(file_unit)
     716            0 :  return
     717              : 
     718              : 99 continue
     719              : 
     720              : end subroutine libpaw_lock_and_write
     721              : !!***
     722              : 
     723              : !----------------------------------------------------------------------
     724              : 
     725              : !!****f* m_libpaw_tools/libpaw_get_free_unit
     726              : !! NAME
     727              : !!  libpaw_get_free_unit
     728              : !!
     729              : !! FUNCTION
     730              : !!  Obtain a free logical Fortran unit.
     731              : !!
     732              : !! OUTPUT
     733              : !!  The unit number (free unit)
     734              : !!  Raises:
     735              : !!   -1 if no logical unit is free (!)
     736              : !!
     737              : !! SOURCE
     738              : 
     739           17 : integer function libpaw_get_free_unit()
     740              : 
     741              : !Local variables-------------------------------
     742              :  integer,parameter :: MIN_UNIT_NUMBER=10
     743              : #ifdef FC_NAG
     744              :   integer,parameter :: MAX_UNIT_NUMBER=64    ! There's a serious problem in Nag6.0. In principle
     745              :                                              ! Maximum unit number: 2147483647
     746              : #else
     747              :  integer,parameter :: MAX_UNIT_NUMBER=1024
     748              : #endif
     749              :  integer :: iunt
     750              :  logical :: isopen
     751              : 
     752              : ! *********************************************************************
     753              : 
     754           17 :  do iunt=MAX_UNIT_NUMBER,MIN_UNIT_NUMBER,-1
     755           17 :    inquire(unit=iunt,opened=isopen)
     756           17 :    if (.not.isopen) then
     757              :       libpaw_get_free_unit=iunt; return
     758              :    end if
     759              :  end do
     760              :  libpaw_get_free_unit=-1
     761              : 
     762              : end function libpaw_get_free_unit
     763              : !!***
     764              : 
     765              : !----------------------------------------------------------------------
     766              : 
     767              : !!****f* m_libpaw_tools/libpaw_flush
     768              : !! NAME
     769              : !!  libpaw_flush
     770              : !!
     771              : !! FUNCTION
     772              : !!  Wrapper for the standard flush routine
     773              : !!  Available only if the compiler implements this intrinsic procedure.
     774              : !!
     775              : !! INPUTS
     776              : !!  unit=Fortran logical Unit number
     777              : !!
     778              : !! NOTES
     779              : !!  This routine comes directly from the FLUSH_UNIT routine delivered with ABINIT.
     780              : !!
     781              : !! SOURCE
     782              : 
     783            0 : subroutine libpaw_flush(unit)
     784              : 
     785              : !Arguments ------------------------------------
     786              :  integer,intent(in) :: unit
     787              : 
     788              : !Local variables ------------------------------
     789              :  integer, parameter :: dev_null=-1
     790              :  logical :: isopen
     791              : 
     792              : !************************************************************************
     793              : 
     794            0 :  if (unit==dev_null) return
     795              : 
     796              : !FLUSH on unconnected unit is illegal: F95 std., 9.3.5.
     797            0 :  inquire(unit=unit,opened=isopen)
     798              : 
     799              : #if defined HAVE_FC_FLUSH
     800            0 :  if (isopen) then
     801            0 :    call flush(unit)
     802              :  endif
     803              : #elif defined HAVE_FC_FLUSH_
     804              :  if (isopen) then
     805              :    call flush_(unit)
     806              :   end if
     807              : #endif
     808              : 
     809              : end subroutine libpaw_flush
     810              : !!***
     811              : 
     812              : !----------------------------------------------------------------------
     813              : 
     814              : !!****f* m_libpaw_tools/libpaw_basename
     815              : !! NAME
     816              : !! libpaw_basename
     817              : !!
     818              : !! FUNCTION
     819              : !!  Returns the final component of a pathname (function version).
     820              : !!
     821              : !! INPUTS
     822              : !!  string=The input string
     823              : !!
     824              : !! NOTES
     825              : !!  This routine comes directly from the BASENAME routine delivered with ABINIT.
     826              : !!  If the input string in not a valid path to a file, a blank strink is returned
     827              : !!
     828              : !! SOURCE
     829              : 
     830            1 : pure function libpaw_basename(istr) result(ostr)
     831              : 
     832              : !Arguments ------------------------------------
     833              :  character(len=*),intent(in) :: istr
     834              :  character(len=LEN_TRIM(istr)) :: ostr
     835              : 
     836              : !Local variables ------------------------------
     837              :  integer :: ic,nch_trim,nch
     838              :  character(len=1),parameter :: BLANK=' '
     839              :  character(len=1),parameter :: DIR_SEPARATOR = '/'
     840              : 
     841              : !************************************************************************
     842              : 
     843            1 :  nch     =LEN     (istr)
     844            1 :  nch_trim=LEN_TRIM(istr)
     845              : 
     846            1 :  ic = INDEX (TRIM(istr), DIR_SEPARATOR, back=.TRUE.)
     847            1 :  if (ic >= 1 .and. ic <= nch_trim-1) then ! there is stuff after the separator.
     848            1 :    ostr = istr(ic+1:nch_trim)
     849            0 :  else if (ic==0 .or. ic == nch_trim+1) then ! no separator in string or zero length string,
     850            0 :    ostr = TRIM(istr)     ! return trimmed string.
     851              :  else                    ! (ic == nch_trim) separator is the last char.
     852            0 :    ostr = BLANK ! This is not a valid path to a file, return blank.
     853              :  end if
     854            1 :  return
     855              : 
     856            1 : end function libpaw_basename
     857              : !!***
     858              : 
     859              : !----------------------------------------------------------------------
     860              : 
     861              : !!****f* m_libpaw_tools/to_upper
     862              : !! NAME
     863              : !!  libpaw_to_upper
     864              : !!
     865              : !! FUNCTION
     866              : !!  Convert a string to UPPER CASE (function version).
     867              : !!
     868              : !! INPUTS
     869              : !!   istr=Input string
     870              : !!
     871              : !! NOTES
     872              : !!  This routine comes directly from the TOUPPER routine delivered with ABINIT.
     873              : !!
     874              : !! SOURCE
     875              : 
     876         5263 : pure function libpaw_to_upper(istr) result(ostr)
     877              : 
     878              : !Arguments ------------------------------------
     879              :  character(len=*),intent(in) :: istr
     880              :  character(len=LEN_TRIM(istr)) :: ostr
     881              : 
     882              : !Local variables ------------------------------
     883              :  integer,parameter :: ASCII_aa=ICHAR('a')
     884              :  integer,parameter :: ASCII_zz=ICHAR('z')
     885              :  integer,parameter :: SHIFT=ICHAR('a')-ICHAR('A')
     886              :  integer :: ic,iasc
     887              : 
     888              : ! *********************************************************************
     889              : 
     890        36841 :  do ic=1,LEN_TRIM(istr)
     891        31578 :    iasc=IACHAR(istr(ic:ic))
     892        36841 :    if (iasc>=ASCII_aa.and.iasc<=ASCII_zz) then
     893        31578 :      ostr(ic:ic)=ACHAR(iasc-SHIFT)
     894              :    else
     895            0 :      ostr(ic:ic)=istr(ic:ic)
     896              :    end if
     897              :  end do
     898              : 
     899         5263 : end function libpaw_to_upper
     900              : !!***
     901              : 
     902              : !----------------------------------------------------------------------
     903              : 
     904              : !!****f* m_libpaw_tools/libpaw_lstrip
     905              : !! NAME
     906              : !!  libpaw_lstrip
     907              : !!
     908              : !! FUNCTION
     909              : !!  Removes leading spaces from the input string.
     910              : !!
     911              : !! NOTES
     912              : !!  This routine comes directly from the LSTRIP routine delivered with ABINIT.
     913              : !!
     914              : !! SOURCE
     915              : 
     916            0 : pure function libpaw_lstrip(istr) result(ostr)
     917              : 
     918              : !Arguments ------------------------------------
     919              :  character(len=*),intent(in) :: istr
     920              :  character(len=len(istr)) :: ostr
     921              : 
     922              : !Local variables ------------------------------
     923              :  integer :: ii,jj,lg
     924              :  character(len=1),parameter :: BLANK=' '
     925              : 
     926              : ! *********************************************************************
     927              : 
     928            0 :  lg=LEN(istr)
     929            0 :  do ii=1,lg
     930            0 :    if (istr(ii:ii)/=BLANK) EXIT
     931              :  end do
     932              : 
     933            0 :  ostr = " "
     934            0 :  do jj=1,lg-ii+1
     935            0 :    ostr(jj:jj) = istr(ii:ii)
     936            0 :    ii=ii+1
     937              :  end do
     938              : 
     939            0 : end function libpaw_lstrip
     940              : !!***
     941              : 
     942              : !----------------------------------------------------------------------
     943              : 
     944              : !!****f* m_libpaw_tools/libpaw_indent
     945              : !! NAME
     946              : !!  libpaw_indent
     947              : !!
     948              : !! FUNCTION
     949              : !!  Indent text (function version).
     950              : !!
     951              : !! INPUTS
     952              : !!   istr=Input string
     953              : !!
     954              : !! NOTES
     955              : !!  This routine comes directly from the INDENT routine delivered with ABINIT.
     956              : !!
     957              : !! SOURCE
     958              : 
     959            0 : pure function libpaw_indent(istr) result(ostr)
     960              : 
     961              : !Arguments ------------------------------------
     962              :  character(len=*),intent(in) :: istr
     963              :  character(len=len(istr)*4+4) :: ostr
     964              : 
     965              : !Local variables-------------------------------
     966              :  character(len=1),parameter :: NCHAR = char(10)
     967              :  integer,parameter :: n=4
     968              :  integer :: ii,jj,kk
     969              :  character(len=1) :: ch
     970              : 
     971              : ! *********************************************************************
     972              : 
     973            0 :  ostr=" "
     974            0 :  jj=n
     975            0 :  do ii=1,LEN_TRIM(istr)
     976            0 :    ch=istr(ii:ii)
     977            0 :    jj=jj+1
     978            0 :    if (ch==NCHAR) then
     979            0 :       ostr(jj:jj)=NCHAR
     980            0 :       do kk=jj+1,jj+n
     981            0 :         ostr(kk:kk)=" "
     982              :       end do
     983              :       jj=jj+n
     984              :    else
     985            0 :      ostr(jj:jj)=ch
     986              :    end if
     987              :  end do
     988              : 
     989            0 : end function libpaw_indent
     990              : !!***
     991              : 
     992              : !----------------------------------------------------------------------
     993              : 
     994              : end module m_libpaw_tools
     995              : !!***
        

Generated by: LCOV version 2.3-1