From e0d7be0e82501ca91144c4d3f67621438c023027 Mon Sep 17 00:00:00 2001
From: Philippe WAUTELET <philippe.wautelet@aero.obs-mip.fr>
Date: Fri, 15 Dec 2023 15:17:42 +0100
Subject: [PATCH] Philippe 15/12/2023: IO: allow more than 999 backup or output
 files

---
 src/LIB/SURCOUCHE/src/modd_io.f90             | 91 ++++++++++---------
 .../SURCOUCHE/src/mode_io_manage_struct.f90   | 44 ++++++---
 src/LIB/SURCOUCHE/src/modn_confio.f90         |  7 +-
 src/MNH/ini_modeln.f90                        | 17 +++-
 src/MNH/modd_outn.f90                         |  4 +-
 src/MNH/modd_parameters.f90                   |  2 -
 src/MNH/read_desfmn.f90                       | 18 ++--
 src/MNH/read_exsegn.f90                       | 20 ++--
 8 files changed, 119 insertions(+), 84 deletions(-)

diff --git a/src/LIB/SURCOUCHE/src/modd_io.f90 b/src/LIB/SURCOUCHE/src/modd_io.f90
index d51c4dd2b..8e37508fd 100644
--- a/src/LIB/SURCOUCHE/src/modd_io.f90
+++ b/src/LIB/SURCOUCHE/src/modd_io.f90
@@ -29,45 +29,48 @@ use modd_precision,  only: CDFINT, LFIINT
 !
 IMPLICIT NONE
 !
+SAVE
 !
 INTEGER, PARAMETER :: NVERB_NO=0, NVERB_FATAL=1, NVERB_ERROR=2, NVERB_WARNING=3, NVERB_INFO=4, NVERB_DEBUG=5
 
 INTEGER                     :: NNULLUNIT = -1  ! /dev/null fortran unit, value set in IO_Init
 CHARACTER(LEN=*), PARAMETER :: CNULLFILE = "/dev/null"
 
-INTEGER, SAVE :: NIO_RANK ! Rank of IO process
-INTEGER, SAVE :: ISP     !! Actual proc number
-INTEGER, SAVE :: ISNPROC !! Total number of allocated processes
-LOGICAL, SAVE :: GSMONOPROC = .FALSE. !! True if sequential execution (ISNPROC = 1) 
+INTEGER :: NIO_RANK             ! Rank of IO process
+INTEGER :: ISP                  ! Actual process number (beginning at 1)
+INTEGER :: ISNPROC              ! Total number of allocated processes
+LOGICAL :: GSMONOPROC = .FALSE. ! True if sequential execution (ISNPROC = 1)
 
-LOGICAL, SAVE :: L1D   = .FALSE. ! TRUE if 1D model version
-LOGICAL, SAVE :: L2D   = .FALSE. ! TRUE if 2D model version
-LOGICAL, SAVE :: LPACK = .FALSE. ! TRUE if FM compression occurs in 1D or 2D model version
+LOGICAL :: L1D   = .FALSE. ! TRUE if 1D model version
+LOGICAL :: L2D   = .FALSE. ! TRUE if 2D model version
+LOGICAL :: LPACK = .FALSE. ! TRUE if FM compression occurs in 1D or 2D model version
 
-LOGICAL, SAVE :: LIOCDF4    = .FALSE. ! TRUE will enable full NetCDF4 (HDF5) I/O support
-LOGICAL, SAVE :: LLFIOUT    = .FALSE. ! TRUE will also force LFI output when LIOCDF4 is on (debug only)  
-LOGICAL, SAVE :: LLFIREAD   = .FALSE. ! TRUE will force LFI read (instead of NetCDF) when LIOCDF4 is on (debug only)  
+LOGICAL :: LIOCDF4    = .FALSE. ! TRUE will enable full NetCDF4 (HDF5) I/O support
+LOGICAL :: LLFIOUT    = .FALSE. ! TRUE will also force LFI output when LIOCDF4 is on (debug only)
+LOGICAL :: LLFIREAD   = .FALSE. ! TRUE will force LFI read (instead of NetCDF) when LIOCDF4 is on (debug only)
 
-LOGICAL, SAVE :: LVERB_OUTLST = .TRUE.  ! TRUE will PRINT_MSG in OUTPUT_LISTINGn files
-LOGICAL, SAVE :: LVERB_STDOUT = .FALSE. ! TRUE will also PRINT_MSG on standard output
-LOGICAL, SAVE :: LVERB_ALLPRC = .FALSE. ! FALSE: only process 0 do PRINT_MSG, TRUE: all processes
-INTEGER, SAVE :: NBUD_VERB        = NVERB_INFO    ! Verbosity level for budgets
-INTEGER, SAVE :: NBUD_ABORT_LEVEL = NVERB_ERROR   ! Level of budget error necessary to force stop of application
-INTEGER, SAVE :: NIO_VERB        = NVERB_INFO    ! Verbosity level for IO
-INTEGER, SAVE :: NIO_ABORT_LEVEL = NVERB_ERROR   ! Level of IO error necessary to force stop of application
+LOGICAL :: LVERB_OUTLST = .TRUE.  ! TRUE will PRINT_MSG in OUTPUT_LISTINGn files
+LOGICAL :: LVERB_STDOUT = .FALSE. ! TRUE will also PRINT_MSG on standard output
+LOGICAL :: LVERB_ALLPRC = .FALSE. ! FALSE: only process 0 do PRINT_MSG, TRUE: all processes
+INTEGER :: NBUD_VERB        = NVERB_INFO    ! Verbosity level for budgets
+INTEGER :: NBUD_ABORT_LEVEL = NVERB_ERROR   ! Level of budget error necessary to force stop of application
+INTEGER :: NIO_VERB        = NVERB_INFO     ! Verbosity level for IO
+INTEGER :: NIO_ABORT_LEVEL = NVERB_ERROR    ! Level of IO error necessary to force stop of application
 
-INTEGER, SAVE :: NGEN_VERB        = NVERB_INFO    ! Verbosity level for 'GEN' (generic) messages
-INTEGER, SAVE :: NGEN_ABORT_LEVEL = NVERB_ERROR   ! Level of 'GEN' error necessary to force stop of application
+INTEGER :: NGEN_VERB        = NVERB_INFO    ! Verbosity level for 'GEN' (generic) messages
+INTEGER :: NGEN_ABORT_LEVEL = NVERB_ERROR   ! Level of 'GEN' error necessary to force stop of application
 
 CHARACTER(LEN=NDIRNAMELGTMAX) :: CIO_DIR = '' ! Directory for IO
 
-logical, save :: LIO_ALLOW_NO_BACKUP = .false. ! Allow to have no valid backup time (useful for some tests)
-logical, save :: LIO_NO_WRITE        = .false. ! Disable file writes (useful for benchs)
+LOGICAL :: LIO_ALLOW_NO_BACKUP = .FALSE. ! Allow to have no valid backup time (useful for some tests)
+LOGICAL :: LIO_NO_WRITE        = .FALSE. ! Disable file writes (useful for benchs)
+
+INTEGER :: NFILE_NUM_MAX = 999 ! Maximum number for numbered files (ie backups and outputs)
 
 !Structure containing one pointer to a file
 !Useful to create arrays of pointers to files
 TYPE TFILE_ELT
-  TYPE(TFILEDATA),POINTER :: TFILE => NULL()
+  TYPE(TFILEDATA), POINTER :: TFILE => NULL()
 END TYPE TFILE_ELT
 
 !Structure describing the characteristics of an output or a backup
@@ -76,15 +79,15 @@ TYPE TOUTBAK
   INTEGER           :: NSTEP        !Timestep number
   REAL              :: XTIME        !Time from start of the segment (in seconds and rounded to a timestep)
   INTEGER           :: NOUTDAD = -1 !Index of the corresponding dad file (file with same time)
-  TYPE(TFILEDATA),POINTER :: TFILE => NULL() !Corresponding file
-  TYPE(TFILE_ELT),DIMENSION(:),ALLOCATABLE :: TFILE_IOZ !Corresponding Z-split files
-  INTEGER,DIMENSION(:),POINTER :: NFIELDLIST => NULL() !List of the fields to read or write
+  TYPE(TFILEDATA), POINTER :: TFILE => NULL() !Corresponding file
+  TYPE(TFILE_ELT), DIMENSION(:) ,ALLOCATABLE :: TFILE_IOZ !Corresponding Z-split files
+  INTEGER,DIMENSION(:), POINTER :: NFIELDLIST => NULL() !List of the fields to read or write
 END TYPE TOUTBAK
 
 !Structure describing the characteristics of a file
 TYPE TFILEDATA
-  CHARACTER(LEN=NFILENAMELGTMAX) :: CNAME = '' !Filename
-  CHARACTER(LEN=:),ALLOCATABLE   :: CDIRNAME   !Directory name
+  CHARACTER(LEN=NFILENAMELGTMAX)  :: CNAME = '' !Filename
+  CHARACTER(LEN=:), ALLOCATABLE   :: CDIRNAME   !Directory name
   CHARACTER(LEN=13) :: CTYPE   = "UNKNOWN" !Filetype (PGD, MNH, DES, NML...)
   CHARACTER(LEN=7)  :: CFORMAT = "UNKNOWN" !Fileformat (NETCDF4, LFI, LFICDF4...)
   CHARACTER(LEN=7)  :: CMODE   = "UNKNOWN" !Opening mode (read, write...)
@@ -98,9 +101,9 @@ TYPE TFILEDATA
   LOGICAL           :: LMASTER       = .FALSE. !True if process is master of the file (process that open/read/write/close)
   LOGICAL           :: LMULTIMASTERS = .FALSE. !True if several processes may access the file
 #if ( MNH_REDUCE_DIMENSIONS_IN_FILES == 1 )
-  logical           :: ldimreduced   = .true.  !True if number of dimensions of fields can be reduced (for 2D simulations)
+  LOGICAL           :: LDIMREDUCED   = .TRUE.  !True if number of dimensions of fields can be reduced (for 2D simulations)
 #else
-  logical           :: ldimreduced   = .false. !True if number of dimensions of fields can be reduced (for 2D simulations)
+  LOGICAL           :: LDIMREDUCED   = .FALSE. !True if number of dimensions of fields can be reduced (for 2D simulations)
 #endif
   !
   INTEGER           :: NSUBFILES_IOZ = 0       !Number of sub-files (Z-split files based on this file)
@@ -108,8 +111,8 @@ TYPE TFILEDATA
                                                !the 2 sub-files are abcd.Z001 and abcd.Z002
   TYPE(TFILE_ELT),DIMENSION(:),ALLOCATABLE :: TFILES_IOZ !Corresponding Z-split files
   !
-  INTEGER              :: NMODEL = 0              !Model number corresponding to the file (field not always set)
-  INTEGER,DIMENSION(3) :: NMNHVERSION = (/0,0,0/) !MesoNH version used to create the file
+  INTEGER               :: NMODEL = 0              !Model number corresponding to the file (field not always set)
+  INTEGER, DIMENSION(3) :: NMNHVERSION = (/0,0,0/) !MesoNH version used to create the file
   !
 #ifdef MNH_IOLFI
   ! Fields for LFI files
@@ -131,7 +134,7 @@ TYPE TFILEDATA
   LOGICAL                :: LNCCOMPRESS_LOSSY      = .FALSE.                  ! Do lossy compression on float fields
   INTEGER(KIND=CDFINT)   :: NNCCOMPRESS_LOSSY_ALGO = NF90_QUANTIZE_GRANULARBR ! Lossy compression algorithm
   INTEGER(KIND=CDFINT)   :: NNCCOMPRESS_LOSSY_NSD  = 3                  ! Number of Significant Digits (or Bits)
-  type(tdimsnc), pointer :: tncdims => Null()     ! Dimensions of netCDF file
+  TYPE(TDIMSNC), POINTER :: TNCDIMS => NULL()     ! Dimensions of netCDF file
 #endif
   !
   !Fields for other files
@@ -140,28 +143,28 @@ TYPE TFILEDATA
   CHARACTER(LEN=11) :: CFORM   = "UNKNOWN" !Fortran FORM (FORMATTED/UNFORMATTED)
   CHARACTER(LEN=10) :: CACCESS = "UNKNOWN" !Fortran ACCESS (DIRECT/SEQUENTIAL/STREAM)
   !
-  TYPE(TFILEDATA),POINTER :: TDADFILE   => NULL() !Corresponding dad file
-  TYPE(TFILEDATA),POINTER :: TDESFILE   => NULL() !Corresponding .des file
-  TYPE(TFILEDATA),POINTER :: TDATAFILE  => NULL() !Corresponding data file (if .des file)
-  TYPE(TFILEDATA),POINTER :: TMAINFILE  => NULL() !Corresponding main file if the file is an sub-file
+  TYPE(TFILEDATA), POINTER :: TDADFILE   => NULL() !Corresponding dad file
+  TYPE(TFILEDATA), POINTER :: TDESFILE   => NULL() !Corresponding .des file
+  TYPE(TFILEDATA), POINTER :: TDATAFILE  => NULL() !Corresponding data file (if .des file)
+  TYPE(TFILEDATA), POINTER :: TMAINFILE  => NULL() !Corresponding main file if the file is an sub-file
   !
-  TYPE(TFILEDATA),POINTER :: TFILE_PREV => NULL()
-  TYPE(TFILEDATA),POINTER :: TFILE_NEXT => NULL()
+  TYPE(TFILEDATA), POINTER :: TFILE_PREV => NULL()
+  TYPE(TFILEDATA), POINTER :: TFILE_NEXT => NULL()
 END TYPE TFILEDATA
 
 !Structure containing a pointer to a file (useful to create arrays of pointers to files)
 TYPE TPTR2FILE
-  TYPE(TFILEDATA),POINTER :: TZFILE => NULL()
+  TYPE(TFILEDATA), POINTER :: TZFILE => NULL()
 END TYPE
 
-TYPE(TFILEDATA),POINTER,SAVE :: TFILE_FIRST => NULL()
-TYPE(TFILEDATA),POINTER,SAVE :: TFILE_LAST  => NULL()
+TYPE(TFILEDATA), POINTER :: TFILE_FIRST => NULL()
+TYPE(TFILEDATA), POINTER :: TFILE_LAST  => NULL()
 
-TYPE(TFILEDATA),POINTER,SAVE :: TFILE_SURFEX  => NULL() !Pointer used to find the file used when writing SURFEX fields in write_surf_mnh.f90
+TYPE(TFILEDATA), POINTER :: TFILE_SURFEX  => NULL() !Pointer used to find the file used when writing SURFEX fields in write_surf_mnh.f90
 
-TYPE(TFILEDATA),POINTER,SAVE :: TFILE_OUTPUTLISTING  => NULL() !Pointer used to point to the file used when writing to OUTPUT_LISTINGn file
+TYPE(TFILEDATA), POINTER :: TFILE_OUTPUTLISTING  => NULL() !Pointer used to point to the file used when writing to OUTPUT_LISTINGn file
 
 !Non existing file which can be used as a dummy target
-TYPE(TFILEDATA),TARGET, SAVE :: TFILE_DUMMY = TFILEDATA(CNAME="dummy",CDIRNAME=NULL(),TFILES_IOZ=NULL())
+TYPE(TFILEDATA), TARGET :: TFILE_DUMMY = TFILEDATA( CNAME="dummy", CDIRNAME=NULL(), TFILES_IOZ=NULL() )
 
 END MODULE MODD_IO
diff --git a/src/LIB/SURCOUCHE/src/mode_io_manage_struct.f90 b/src/LIB/SURCOUCHE/src/mode_io_manage_struct.f90
index 54d694804..b99165cae 100644
--- a/src/LIB/SURCOUCHE/src/mode_io_manage_struct.f90
+++ b/src/LIB/SURCOUCHE/src/mode_io_manage_struct.f90
@@ -137,7 +137,7 @@ DO IMI = 1, NMODEL
     IOUT_STEP(IOUT_NUMB) = 1 ! 1 is the 1st step number
   END IF
   !
-  DO JOUT = 1,JPOUTMAX
+  DO JOUT = 1, NFILE_NUM_MAX
     IF (XBAK_TIME(IMI,JOUT) >= 0.) THEN
       IBAK_NUMB = IBAK_NUMB + 1
       IBAK_STEP(IBAK_NUMB) = NINT(XBAK_TIME(IMI,JOUT)/DYN_MODEL(IMI)%XTSTEP) + 1
@@ -148,7 +148,7 @@ DO IMI = 1, NMODEL
     END IF
   END DO
   !
-  DO JOUT = 1,JPOUTMAX
+  DO JOUT = 1, NFILE_NUM_MAX
     IF (NBAK_STEP(IMI,JOUT) > 0) THEN
       IBAK_NUMB = IBAK_NUMB + 1
       IBAK_STEP(IBAK_NUMB) = NBAK_STEP(IMI,JOUT)
@@ -391,7 +391,7 @@ SUBROUTINE IO_SYNC_MODELS_FLOAT(KNUMB,PTIMES)
   !
   INTEGER :: JKLOOP ! Loop index
   !
-  DO JOUT = 1,JPOUTMAX
+  DO JOUT = 1, NFILE_NUM_MAX
     IF (PTIMES(IMI,JOUT) >= 0.) THEN
       KNUMB = KNUMB + 1
       !Value is rounded to nearest timestep
@@ -415,7 +415,7 @@ SUBROUTINE IO_SYNC_MODELS_INT(KNUMB,KSTEPS)
   !
   INTEGER :: JKLOOP ! Loop index
   !
-  DO JOUT = 1,JPOUTMAX
+  DO JOUT = 1, NFILE_NUM_MAX
     IF (KSTEPS(IMI,JOUT) > 0) THEN
       KNUMB = KNUMB + 1
       !Output/backup time is propagated to nested models (with higher numbers)
@@ -440,7 +440,7 @@ SUBROUTINE FIND_NEXT_AVAIL_SLOT_FLOAT(PTIMES,kIDX)
   !Find next (starting from KIDX) non 'allocated' element
   DO WHILE ( PTIMES(KIDX) >= 0. )
     KIDX = KIDX + 1
-    IF (KIDX > JPOUTMAX) CALL PRINT_MSG(NVERB_FATAL,'IO','FIND_NEXT_AVAIL_SLOT_FLOAT','JPOUTMAX too small')
+    IF (KIDX > NFILE_NUM_MAX) CALL PRINT_MSG(NVERB_FATAL,'IO','FIND_NEXT_AVAIL_SLOT_FLOAT','NFILE_NUM_MAX too small')
   END DO
 END SUBROUTINE FIND_NEXT_AVAIL_SLOT_FLOAT
 !
@@ -454,7 +454,7 @@ SUBROUTINE FIND_NEXT_AVAIL_SLOT_INT(KSTEPS,KIDX)
   !Find next (starting from KIDX) non 'allocated' element
   DO WHILE ( KSTEPS(IDX) >= 0 )
     KIDX = KIDX + 1
-    IF (KIDX > JPOUTMAX) CALL PRINT_MSG(NVERB_FATAL,'IO','FIND_NEXT_AVAIL_SLOT_INT','JPOUTMAX too small')
+    IF (KIDX > NFILE_NUM_MAX) CALL PRINT_MSG(NVERB_FATAL,'IO','FIND_NEXT_AVAIL_SLOT_INT','NFILE_NUM_MAX too small')
   END DO
 END SUBROUTINE FIND_NEXT_AVAIL_SLOT_INT
 !
@@ -538,9 +538,21 @@ SUBROUTINE POPULATE_STRUCT(TPFILE_FIRST,TPFILE_LAST,KSTEPS,HFILETYPE,TPBAKOUTN,K
   TYPE(TOUTBAK),DIMENSION(:),POINTER,INTENT(IN)    :: TPBAKOUTN
   INTEGER,                           INTENT(IN)    :: KMI ! Model number
   !
-  CHARACTER (LEN=3) :: YNUMBER          ! Character string for the file number
+  CHARACTER (LEN=:), ALLOCATABLE :: YNUMBER ! Character string for the file number
   INTEGER :: JI
-  !
+
+  IF ( NFILE_NUM_MAX < 1000 ) THEN
+    ALLOCATE( CHARACTER(LEN=3) :: YNUMBER )
+  ELSE IF ( NFILE_NUM_MAX < 10000 ) THEN
+    ALLOCATE( CHARACTER(LEN=4) :: YNUMBER )
+  ELSE IF ( NFILE_NUM_MAX < 100000 ) THEN
+    ALLOCATE( CHARACTER(LEN=5) :: YNUMBER )
+  ELSE IF ( NFILE_NUM_MAX < 1000000 ) THEN
+    ALLOCATE( CHARACTER(LEN=6) :: YNUMBER )
+  ELSE
+    CALL PRINT_MSG( NVERB_FATAL, 'IO', 'POPULATE_STRUCT', 'NFILE_NUM_MAX is too large' )
+  END IF
+
   IPOS = 0
   DO JOUT = 1,SIZE(KSTEPS)
     IF (KSTEPS(JOUT) >= 0) THEN
@@ -548,9 +560,6 @@ SUBROUTINE POPULATE_STRUCT(TPFILE_FIRST,TPFILE_LAST,KSTEPS,HFILETYPE,TPBAKOUTN,K
         TPBAKOUTN(IPOS)%NID = IPOS
         TPBAKOUTN(IPOS)%NSTEP = KSTEPS(JOUT)
         TPBAKOUTN(IPOS)%XTIME = (KSTEPS(JOUT)-1)*DYN_MODEL(IMI)%XTSTEP
-        IF (IPOS>999) THEN
-          CALL PRINT_MSG(NVERB_FATAL,'IO','POPULATE_STRUCT','more than 999 backups/outputs')
-        END IF
         IF (.NOT.ASSOCIATED(TPFILE_FIRST)) THEN
           ALLOCATE(TPFILE_FIRST)
           TPFILE_LAST => TPFILE_FIRST
@@ -562,7 +571,18 @@ SUBROUTINE POPULATE_STRUCT(TPFILE_FIRST,TPFILE_LAST,KSTEPS,HFILETYPE,TPBAKOUTN,K
         TPBAKOUTN(IPOS)%TFILE => TPFILE_LAST
         TPBAKOUTN(IPOS)%TFILE%CTYPE=HFILETYPE
         TPBAKOUTN(IPOS)%TFILE%CMODE="WRITE"
-        WRITE (YNUMBER,FMT="(I3.3)") IPOS
+        IF ( NFILE_NUM_MAX  < 1000 ) THEN
+          WRITE ( YNUMBER, FMT = "(I3.3)" ) IPOS
+        ELSE IF ( NFILE_NUM_MAX  < 10000 ) THEN
+          WRITE ( YNUMBER, FMT = "(I4.4)" ) IPOS
+        ELSE IF ( NFILE_NUM_MAX  < 100000 ) THEN
+          WRITE ( YNUMBER, FMT = "(I5.5)" ) IPOS
+        ELSE IF ( NFILE_NUM_MAX  < 1000000 ) THEN
+          WRITE ( YNUMBER, FMT = "(I6.6)" ) IPOS
+        ELSE
+          CALL PRINT_MSG( NVERB_FATAL, 'IO', 'POPULATE_STRUCT', 'NFILE_NUM_MAX is too large' )
+        END IF
+
         IF (TRIM(HFILETYPE)=='MNHOUTPUT') THEN
           ! Add a "OUT" suffix for output files
           TPBAKOUTN(IPOS)%TFILE%CNAME=ADJUSTL(ADJUSTR(IO_SURF_MNH_MODEL(IMI)%COUTFILE)//'.OUT.'//YNUMBER)
diff --git a/src/LIB/SURCOUCHE/src/modn_confio.f90 b/src/LIB/SURCOUCHE/src/modn_confio.f90
index 7c89947c1..359778258 100644
--- a/src/LIB/SURCOUCHE/src/modn_confio.f90
+++ b/src/LIB/SURCOUCHE/src/modn_confio.f90
@@ -1,4 +1,4 @@
-!MNH_LIC Copyright 2014-2020 CNRS, Meteo-France and Universite Paul Sabatier
+!MNH_LIC Copyright 2014-2023 CNRS, Meteo-France and Universite Paul Sabatier
 !MNH_LIC This is part of the Meso-NH software governed by the CeCILL-C licence
 !MNH_LIC version 1. See LICENSE, CeCILL-C_V1-en.txt and CeCILL-C_V1-fr.txt
 !MNH_LIC for details. version 1.
@@ -39,7 +39,7 @@
 !
 USE MODD_IO, ONLY : LVERB_OUTLST, LVERB_STDOUT, LVERB_ALLPRC, &
                     NBUD_VERB, NBUD_ABORT_LEVEL, NIO_VERB, NIO_ABORT_LEVEL, NGEN_VERB, NGEN_ABORT_LEVEL, &
-                    CIO_DIR, LIO_ALLOW_NO_BACKUP, LIO_NO_WRITE
+                    CIO_DIR, LIO_ALLOW_NO_BACKUP, LIO_NO_WRITE, NFILE_NUM_MAX
 !
 IMPLICIT NONE
 !
@@ -53,7 +53,8 @@ NAMELIST/NAM_CONFIO/LCDF4, LLFIOUT, LLFIREAD,                 &
                     NBUD_VERB, NBUD_ABORT_LEVEL,              &
                     NIO_VERB,  NIO_ABORT_LEVEL,               &
                     NGEN_VERB, NGEN_ABORT_LEVEL, CIO_DIR,     &
-                    LIO_ALLOW_NO_BACKUP, LIO_NO_WRITE
+                    LIO_ALLOW_NO_BACKUP, LIO_NO_WRITE,        &
+                    NFILE_NUM_MAX
 !
 END MODULE MODN_CONFIO
 
diff --git a/src/MNH/ini_modeln.f90 b/src/MNH/ini_modeln.f90
index ce91fc05c..4277d47e8 100644
--- a/src/MNH/ini_modeln.f90
+++ b/src/MNH/ini_modeln.f90
@@ -362,7 +362,7 @@ USE MODD_GET_n
 USE MODD_GRID_n
 USE MODD_GRID,              only: XLONORI,XLATORI
 USE MODD_IBM_PARAM_n,       only: LIBM, XIBM_IEPS, XIBM_LS, XIBM_XMUT
-USE MODD_IO,                only: CIO_DIR, TFILEDATA, TFILE_DUMMY
+USE MODD_IO,                only: CIO_DIR, NFILE_NUM_MAX, TFILEDATA, TFILE_DUMMY
 USE MODD_IO_SURF_MNH,       only: IO_SURF_MNH_MODEL
 USE MODD_LATZ_EDFLX
 USE MODD_LBC_n,             only: CLBCX, CLBCY
@@ -504,6 +504,7 @@ REAL, PARAMETER :: NALBUV_DEFAULT = 0.01 ! Arbitrary low value for XALBUV
 INTEGER             :: JSV     ! Loop index
 INTEGER             :: IRESP   ! Return code of FM routines
 INTEGER             :: ILUOUT  ! Logical unit number of output-listing
+CHARACTER(LEN=6)    :: YNUM
 CHARACTER(LEN=28)   :: YNAME
 INTEGER             :: IIU     ! Upper dimension in x direction (local)
 INTEGER             :: IJU     ! Upper dimension in y direction (local)
@@ -1877,9 +1878,21 @@ CALL INI_BIKHARDT_n (NDXRATIO_ALL(KMI),NDYRATIO_ALL(KMI),KMI)
 !               ----------------------------
 !
 IF (KMI == 1) THEN
+  IF ( NFILE_NUM_MAX < 1000 ) THEN
+    YNUM= '000'
+  ELSE IF ( NFILE_NUM_MAX < 10000 ) THEN
+    YNUM= '0000'
+  ELSE IF ( NFILE_NUM_MAX < 100000 ) THEN
+    YNUM= '00000'
+  ELSE IF ( NFILE_NUM_MAX < 1000000 ) THEN
+    YNUM= '000000'
+  ELSE
+    CALL PRINT_MSG( NVERB_FATAL, 'IO', 'INI_MODEL_n', 'NFILE_NUM_MAX is too large' )
+  END IF
+
   DO IMI = 1 , NMODEL
     WRITE(IO_SURF_MNH_MODEL(IMI)%COUTFILE,'(A,".",I1,".",A)') CEXP,IMI,TRIM(ADJUSTL(CSEG))
-    WRITE(YNAME, '(A,".",I1,".",A)') CEXP,IMI,TRIM(ADJUSTL(CSEG))//'.000'
+    WRITE( YNAME, '(A,".",I1,".",A)' ) CEXP, IMI, TRIM(ADJUSTL(CSEG)) // '.' // TRIM(YNUM)
     CALL IO_File_add2list(LUNIT_MODEL(IMI)%TDIAFILE,YNAME,'MNHDIACHRONIC','WRITE', &
                           HDIRNAME=CIO_DIR,                                        &
                           KLFINPRAR=INT(50,KIND=LFIINT),KLFITYPE=1,KLFIVERB=NVERB, &
diff --git a/src/MNH/modd_outn.f90 b/src/MNH/modd_outn.f90
index 7a3ff7e78..54458482b 100644
--- a/src/MNH/modd_outn.f90
+++ b/src/MNH/modd_outn.f90
@@ -1,4 +1,4 @@
-!MNH_LIC Copyright 1994-2019 CNRS, Meteo-France and Universite Paul Sabatier
+!MNH_LIC Copyright 1994-2023 CNRS, Meteo-France and Universite Paul Sabatier
 !MNH_LIC This is part of the Meso-NH software governed by the CeCILL-C licence
 !MNH_LIC version 1. See LICENSE, CeCILL-C_V1-en.txt and CeCILL-C_V1-fr.txt
 !MNH_LIC for details. version 1.
@@ -38,7 +38,7 @@
 !             ------------
 !
 !
-USE MODD_PARAMETERS, ONLY: JPMODELMAX, JPOUTMAX
+USE MODD_PARAMETERS, ONLY: JPMODELMAX
 USE MODD_IO,         ONLY: TOUTBAK
 IMPLICIT NONE
 
diff --git a/src/MNH/modd_parameters.f90 b/src/MNH/modd_parameters.f90
index 3b477bf0d..390c17fe4 100644
--- a/src/MNH/modd_parameters.f90
+++ b/src/MNH/modd_parameters.f90
@@ -36,7 +36,6 @@
 !!      Modification 17/11/00 (P.Jabouille) add the dummy array size
 !!      Modification 22/01/01 (D.Gazen) change JPSVMAX from 100 to 200
 !!                                         and JPBUMAX from 120 to 250
-!!      Modification 17/05/04 (P.Jabouille) add JPOUTMAX
 !!      J.Escobar : 15/09/2015 : WENO5 & JPHEXT <> 1
 !!      B.VIE 2016 LIMA
 !  P. Wautelet: 05/2016-04/2018: new data structures and calls for I/O
@@ -77,7 +76,6 @@ INTEGER, PARAMETER :: NNEGUNDEF = -999  ! default value for undefined or unused
 !                                       ! field (negative value guaranteed)
 INTEGER, PARAMETER :: JPDUMMY  = 20   ! Size of dummy array
 !
-INTEGER, PARAMETER :: JPOUTMAX = 999    ! Maximum allowed number of OUTput files
 INTEGER, PARAMETER :: JPOUTVARMAX = 192 ! Maximum allowed number of variables in an output file
 !
 INTEGER, PARAMETER :: NBUNAMELGTMAX   = 32  ! Maximum length of a budget name
diff --git a/src/MNH/read_desfmn.f90 b/src/MNH/read_desfmn.f90
index 3ced113c5..e556cdf01 100644
--- a/src/MNH/read_desfmn.f90
+++ b/src/MNH/read_desfmn.f90
@@ -202,7 +202,7 @@ END MODULE MODI_READ_DESFM_n
 !
 !*       0.    DECLARATIONS
 !              ------------
-USE MODD_IO,              ONLY: TFILEDATA
+USE MODD_IO,              ONLY: NFILE_NUM_MAX, TFILEDATA
 USE MODD_LUNIT_n,         ONLY: TLUOUT
 USE MODD_NEB_n,           ONLY: NEBN_INIT
 USE MODD_PARAMETERS
@@ -502,19 +502,19 @@ IF (KMI == 1) THEN
   CALL POSNAM( TZDESFILE, 'NAM_BACKUP', GFOUND )
   IF (GFOUND) THEN
     IF (.NOT.ALLOCATED(XBAK_TIME)) THEN
-      ALLOCATE(XBAK_TIME(NMODEL,JPOUTMAX))
+      ALLOCATE(XBAK_TIME(NMODEL,NFILE_NUM_MAX))
       XBAK_TIME(:,:) = XNEGUNDEF
     END IF
     IF (.NOT.ALLOCATED(XOUT_TIME)) THEN
-      ALLOCATE(XOUT_TIME(NMODEL,JPOUTMAX)) !Allocate *OUT* variables to prevent
+      ALLOCATE(XOUT_TIME(NMODEL,NFILE_NUM_MAX)) !Allocate *OUT* variables to prevent
       XOUT_TIME(:,:) = XNEGUNDEF
     END IF
     IF (.NOT.ALLOCATED(NBAK_STEP)) THEN
-      ALLOCATE(NBAK_STEP(NMODEL,JPOUTMAX))
+      ALLOCATE(NBAK_STEP(NMODEL,NFILE_NUM_MAX))
       NBAK_STEP(:,:) = NNEGUNDEF
     END IF
     IF (.NOT.ALLOCATED(NOUT_STEP)) THEN
-      ALLOCATE(NOUT_STEP(NMODEL,JPOUTMAX)) !problems if NAM_OUTPUT does not exist
+      ALLOCATE(NOUT_STEP(NMODEL,NFILE_NUM_MAX)) !problems if NAM_OUTPUT does not exist
       NOUT_STEP(:,:) = NNEGUNDEF
     END IF
     IF (.NOT.ALLOCATED(COUT_VAR)) THEN
@@ -529,19 +529,19 @@ IF (KMI == 1) THEN
   CALL POSNAM( TZDESFILE, 'NAM_OUTPUT', GFOUND )
   IF (GFOUND) THEN
     IF (.NOT.ALLOCATED(XBAK_TIME)) THEN
-      ALLOCATE(XBAK_TIME(NMODEL,JPOUTMAX)) !Allocate *BAK* variables to prevent
+      ALLOCATE(XBAK_TIME(NMODEL,NFILE_NUM_MAX)) !Allocate *BAK* variables to prevent
       XBAK_TIME(:,:) = XNEGUNDEF
     END IF
     IF (.NOT.ALLOCATED(XOUT_TIME)) THEN
-      ALLOCATE(XOUT_TIME(NMODEL,JPOUTMAX))
+      ALLOCATE(XOUT_TIME(NMODEL,NFILE_NUM_MAX))
       XOUT_TIME(:,:) = XNEGUNDEF
     END IF
     IF (.NOT.ALLOCATED(NBAK_STEP)) THEN
-      ALLOCATE(NBAK_STEP(NMODEL,JPOUTMAX)) !problems if NAM_BACKUP does not exist
+      ALLOCATE(NBAK_STEP(NMODEL,NFILE_NUM_MAX)) !problems if NAM_BACKUP does not exist
       NBAK_STEP(:,:) = NNEGUNDEF
     END IF
     IF (.NOT.ALLOCATED(NOUT_STEP)) THEN
-      ALLOCATE(NOUT_STEP(NMODEL,JPOUTMAX))
+      ALLOCATE(NOUT_STEP(NMODEL,NFILE_NUM_MAX))
       NOUT_STEP(:,:) = NNEGUNDEF
     END IF
     IF (.NOT.ALLOCATED(COUT_VAR)) THEN
diff --git a/src/MNH/read_exsegn.f90 b/src/MNH/read_exsegn.f90
index 8fed63820..4177b9fe7 100644
--- a/src/MNH/read_exsegn.f90
+++ b/src/MNH/read_exsegn.f90
@@ -334,8 +334,8 @@ USE MODD_FOREFIRE
 #endif
 USE MODD_GET_n
 USE MODD_GR_FIELD_n
-USE MODD_IO,   ONLY: TFILEDATA
-USE MODD_LUNIT_n, ONLY: TLUOUT
+USE MODD_IO,              ONLY: NFILE_NUM_MAX, TFILEDATA
+USE MODD_LUNIT_n,         ONLY: TLUOUT
 USE MODD_NEB_n,           ONLY: NEBN_INIT, LSIGMAS, LSUBG_COND, CCONDENS, LSTATNW
 USE MODD_NSV,             NSV_USER_n=>NSV_USER
 USE MODD_PARAMETERS
@@ -598,19 +598,19 @@ IF (KMI == 1) THEN
   IF (GFOUND) THEN
     !Should have been allocated before in READ_DESFM_n
     IF (.NOT.ALLOCATED(XBAK_TIME)) THEN
-      ALLOCATE(XBAK_TIME(NMODEL,JPOUTMAX))
+      ALLOCATE(XBAK_TIME(NMODEL,NFILE_NUM_MAX))
       XBAK_TIME(:,:) = XNEGUNDEF
     END IF
     IF (.NOT.ALLOCATED(XOUT_TIME)) THEN
-      ALLOCATE(XOUT_TIME(NMODEL,JPOUTMAX)) !Allocate *OUT* variables to prevent
+      ALLOCATE(XOUT_TIME(NMODEL,NFILE_NUM_MAX)) !Allocate *OUT* variables to prevent
       XOUT_TIME(:,:) = XNEGUNDEF
     END IF
     IF (.NOT.ALLOCATED(NBAK_STEP)) THEN
-      ALLOCATE(NBAK_STEP(NMODEL,JPOUTMAX))
+      ALLOCATE(NBAK_STEP(NMODEL,NFILE_NUM_MAX))
       NBAK_STEP(:,:) = NNEGUNDEF
     END IF
     IF (.NOT.ALLOCATED(NOUT_STEP)) THEN
-      ALLOCATE(NOUT_STEP(NMODEL,JPOUTMAX)) !problems if NAM_OUTPUT does not exist
+      ALLOCATE(NOUT_STEP(NMODEL,NFILE_NUM_MAX)) !problems if NAM_OUTPUT does not exist
       NOUT_STEP(:,:) = NNEGUNDEF
     END IF
     IF (.NOT.ALLOCATED(COUT_VAR)) THEN
@@ -630,19 +630,19 @@ IF (KMI == 1) THEN
   IF (GFOUND) THEN
     !Should have been allocated before in READ_DESFM_n
     IF (.NOT.ALLOCATED(XBAK_TIME)) THEN
-      ALLOCATE(XBAK_TIME(NMODEL,JPOUTMAX)) !Allocate *BAK* variables to prevent
+      ALLOCATE(XBAK_TIME(NMODEL,NFILE_NUM_MAX)) !Allocate *BAK* variables to prevent
       XBAK_TIME(:,:) = XNEGUNDEF
     END IF
     IF (.NOT.ALLOCATED(XOUT_TIME)) THEN
-      ALLOCATE(XOUT_TIME(NMODEL,JPOUTMAX))
+      ALLOCATE(XOUT_TIME(NMODEL,NFILE_NUM_MAX))
       XOUT_TIME(:,:) = XNEGUNDEF
     END IF
     IF (.NOT.ALLOCATED(NBAK_STEP)) THEN
-      ALLOCATE(NBAK_STEP(NMODEL,JPOUTMAX)) !problems if NAM_BACKUP does not exist
+      ALLOCATE(NBAK_STEP(NMODEL,NFILE_NUM_MAX)) !problems if NAM_BACKUP does not exist
       NBAK_STEP(:,:) = NNEGUNDEF
     END IF
     IF (.NOT.ALLOCATED(NOUT_STEP)) THEN
-      ALLOCATE(NOUT_STEP(NMODEL,JPOUTMAX))
+      ALLOCATE(NOUT_STEP(NMODEL,NFILE_NUM_MAX))
       NOUT_STEP(:,:) = NNEGUNDEF
     END IF
     IF (.NOT.ALLOCATED(COUT_VAR)) THEN
-- 
GitLab