From a947bc2a8e0b0da41e6f29f3a6347b4e2b82dc92 Mon Sep 17 00:00:00 2001
From: Philippe WAUTELET <philippe.wautelet@aero.obs-mip.fr>
Date: Thu, 15 Dec 2016 10:20:49 +0100
Subject: [PATCH] Philippe 15/12/2016: IO: * added TPFILE argument to
 IO_WRITE_FIELD_NC4 * added optional KZFILE argument to IO_WRITE_FIELD_NC4_ *
 provide the correct file to IO_WRITE_FIELD_NC4 if z-splitted   file in
 IO_WRITE_FIELD_BYFIELD_N0 * added TFILE_IOZ array of pointer to TOUTBAK type
 to point   to z-splitted files * manage z-splitted files in IO_FILE_OPEN_ll
 and IO_FILE_CLOSE_ll * manage z-splitted files in IO_PREPARE_BAKOUT_STRUCT *
 created IO_FILE_FIND_BYNAME subroutine * merged linked lists concerning
 output and backup files

---
 src/LIB/SURCOUCHE/src/fmwrit_ll.f90           | 42 ++++----
 src/LIB/SURCOUCHE/src/modd_io.f90             | 13 ++-
 src/LIB/SURCOUCHE/src/mode_fm.f90             | 54 ++++++++++-
 .../SURCOUCHE/src/mode_io_manage_struct.f90   | 97 +++++++++++++++++--
 src/LIB/SURCOUCHE/src/mode_netcdf.f90         | 29 ++++--
 5 files changed, 196 insertions(+), 39 deletions(-)

diff --git a/src/LIB/SURCOUCHE/src/fmwrit_ll.f90 b/src/LIB/SURCOUCHE/src/fmwrit_ll.f90
index 354b17653..9141ee8c5 100644
--- a/src/LIB/SURCOUCHE/src/fmwrit_ll.f90
+++ b/src/LIB/SURCOUCHE/src/fmwrit_ll.f90
@@ -676,15 +676,15 @@ CONTAINS
           IF (LPACK .AND. L1D .AND. SIZE(PFIELD,1)==IHEXTOT .AND. SIZE(PFIELD,2)==IHEXTOT) THEN 
              ZFIELDP=>PFIELD(JPHEXT+1:JPHEXT+1,JPHEXT+1:JPHEXT+1)
              IF (LLFIOUT) CALL IO_WRITE_FIELD_LFI(TPFIELD,TZFD%FLU,ZFIELDP,IRESP)
-             IF (LIOCDF4) CALL IO_WRITE_FIELD_NC4(TPFIELD,TZFD%CDF,ZFIELDP,IRESP)
+             IF (LIOCDF4) CALL IO_WRITE_FIELD_NC4(TPFILE,TPFIELD,TZFD%CDF,ZFIELDP,IRESP)
              !    ELSE IF (LPACK .AND. L2D .AND. YDIR=='XY') THEN
           ELSEIF (LPACK .AND. L2D .AND. SIZE(PFIELD,2)==IHEXTOT) THEN
              ZFIELDP=>PFIELD(:,JPHEXT+1:JPHEXT+1)
              IF (LLFIOUT) CALL IO_WRITE_FIELD_LFI(TPFIELD,TZFD%FLU,ZFIELDP,IRESP)
-             IF (LIOCDF4) CALL IO_WRITE_FIELD_NC4(TPFIELD,TZFD%CDF,ZFIELDP,IRESP)
+             IF (LIOCDF4) CALL IO_WRITE_FIELD_NC4(TPFILE,TPFIELD,TZFD%CDF,ZFIELDP,IRESP)
           ELSE
              IF (LLFIOUT) CALL IO_WRITE_FIELD_LFI(TPFIELD,TZFD%FLU,PFIELD,IRESP)
-             IF (LIOCDF4) CALL IO_WRITE_FIELD_NC4(TPFIELD,TZFD%CDF,PFIELD,IRESP)
+             IF (LIOCDF4) CALL IO_WRITE_FIELD_NC4(TPFILE,TPFIELD,TZFD%CDF,PFIELD,IRESP)
           END IF
        ELSE ! multiprocessor execution
           CALL SECOND_MNH2(T0)
@@ -747,7 +747,7 @@ CONTAINS
           !
           IF (ISP == TZFD%OWNER)  THEN             
              IF (LLFIOUT) CALL IO_WRITE_FIELD_LFI(TPFIELD,TZFD%FLU,ZFIELDP,IRESP)
-             IF (LIOCDF4) CALL IO_WRITE_FIELD_NC4(TPFIELD,TZFD%CDF,ZFIELDP,IRESP)
+             IF (LIOCDF4) CALL IO_WRITE_FIELD_NC4(TPFILE,TPFIELD,TZFD%CDF,ZFIELDP,IRESP)
           END IF
 #ifdef MNH_GA
 !!$         IF (ISP .EQ. 1 ) THEN
@@ -1167,8 +1167,7 @@ CONTAINS
     USE MODE_FD_ll, ONLY : GETFD,JPFINL,FD_LL
     USE MODE_ALLOCBUFFER_ll
     USE MODE_GATHER_ll
-    !JUANZ    
-    USE MODD_IO_ll, ONLY : ISNPROC
+    !JUANZ
     USE MODE_IO_ll, ONLY : io_file,io_rank
     USE MODD_TIMEZ, ONLY : TIMEZ
     USE MODE_MNH_TIMING, ONLY : SECOND_MNH2
@@ -1248,15 +1247,15 @@ CONTAINS
           IF (LPACK .AND. L1D .AND. SIZE(PFIELD,1)==IHEXTOT .AND. SIZE(PFIELD,2)==IHEXTOT) THEN 
              ZFIELDP=>PFIELD(JPHEXT+1:JPHEXT+1,JPHEXT+1:JPHEXT+1,:)
              IF (LLFIOUT) CALL IO_WRITE_FIELD_LFI(TPFIELD,TZFD%FLU,ZFIELDP,IRESP)
-             IF (LIOCDF4) CALL IO_WRITE_FIELD_NC4(TPFIELD,TZFD%CDF,ZFIELDP,IRESP)
+             IF (LIOCDF4) CALL IO_WRITE_FIELD_NC4(TPFILE,TPFIELD,TZFD%CDF,ZFIELDP,IRESP)
              !    ELSE IF (LPACK .AND. L2D .AND. YDIR=='XY') THEN
           ELSEIF (LPACK .AND. L2D .AND. SIZE(PFIELD,2)==IHEXTOT) THEN
              ZFIELDP=>PFIELD(:,JPHEXT+1:JPHEXT+1,:)
              IF (LLFIOUT) CALL IO_WRITE_FIELD_LFI(TPFIELD,TZFD%FLU,ZFIELDP,IRESP)
-             IF (LIOCDF4) CALL IO_WRITE_FIELD_NC4(TPFIELD,TZFD%CDF,ZFIELDP,IRESP)
+             IF (LIOCDF4) CALL IO_WRITE_FIELD_NC4(TPFILE,TPFIELD,TZFD%CDF,ZFIELDP,IRESP)
           ELSE
              IF (LLFIOUT) CALL IO_WRITE_FIELD_LFI(TPFIELD,TZFD%FLU,PFIELD,IRESP)
-             IF (LIOCDF4) CALL IO_WRITE_FIELD_NC4(TPFIELD,TZFD%CDF,PFIELD,IRESP)
+             IF (LIOCDF4) CALL IO_WRITE_FIELD_NC4(TPFILE,TPFIELD,TZFD%CDF,PFIELD,IRESP)
           END IF
        ELSEIF ( (TZFD%nb_procio .eq. 1 ) .OR. ( YDIR == '--' ) ) THEN  ! multiprocessor execution & 1 proc IO
           ! write 3D field in 1 time = output for graphique
@@ -1279,7 +1278,7 @@ CONTAINS
           !
           IF (ISP == TZFD%OWNER)  THEN
              IF (LLFIOUT) CALL IO_WRITE_FIELD_LFI(TPFIELD,TZFD%FLU,ZFIELDP,IRESP)
-             IF (LIOCDF4) CALL IO_WRITE_FIELD_NC4(TPFIELD,TZFD%CDF,ZFIELDP,IRESP)
+             IF (LIOCDF4) CALL IO_WRITE_FIELD_NC4(TPFILE,TPFIELD,TZFD%CDF,ZFIELDP,IRESP)
           END IF
           !
           CALL MPI_BCAST(IRESP,1,MPI_INTEGER,TZFD%OWNER-1,TZFD&
@@ -1341,7 +1340,7 @@ CONTAINS
                TIMEZ%T_WRIT3D_RECV=TIMEZ%T_WRIT3D_RECV + T1 - T0
                !
                IF (LLFIOUT) CALL IO_WRITE_FIELD_LFI(TPFIELD,TZFD_IOZ%FLU,ZSLIDE_ll,IRESP,KVERTLEVEL=JKK)
-               IF (LIOCDF4) CALL IO_WRITE_FIELD_NC4(TPFIELD,TZFD_IOZ%CDF,ZSLIDE_ll,IRESP,KVERTLEVEL=JKK)
+               IF (LIOCDF4) CALL IO_WRITE_FIELD_NC4(TPFILE,TPFIELD,TZFD_IOZ%CDF,ZSLIDE_ll,IRESP,KVERTLEVEL=JKK,KZFILE=IK_FILE+1)
                CALL SECOND_MNH2(T2)
                TIMEZ%T_WRIT3D_WRIT=TIMEZ%T_WRIT3D_WRIT + T2 - T1
             END IF
@@ -1460,7 +1459,7 @@ CONTAINS
                    TIMEZ%T_WRIT3D_RECV=TIMEZ%T_WRIT3D_RECV + T1 - T0
                    !JUANIOZ 
                    IF (LLFIOUT) CALL IO_WRITE_FIELD_LFI(TPFIELD,TZFD_IOZ%FLU,ZSLIDE_ll,IRESP,KVERTLEVEL=JKK)
-                   IF (LIOCDF4) CALL IO_WRITE_FIELD_NC4(TPFIELD,TZFD_IOZ%CDF,ZSLIDE_ll,IRESP,KVERTLEVEL=JKK)
+                   IF (LIOCDF4) CALL IO_WRITE_FIELD_NC4(TPFILE,TPFIELD,TZFD_IOZ%CDF,ZSLIDE_ll,IRESP,KVERTLEVEL=JKK,KZFILE=IK_FILE+1)
                    CALL SECOND_MNH2(T2)
                    TIMEZ%T_WRIT3D_WRIT=TIMEZ%T_WRIT3D_WRIT + T2 - T1
                 END IF
@@ -1901,6 +1900,7 @@ CONTAINS
     USE MODD_IO_ll
     USE MODD_FM
     USE MODE_FD_ll, ONLY : GETFD,JPFINL,FD_LL
+    USE MODE_IO_MANAGE_STRUCT, ONLY: IO_FILE_FIND_BYNAME
     !*      0.    DECLARATIONS
     !             ------------
     !
@@ -1923,6 +1923,7 @@ CONTAINS
     CHARACTER(len=5)                         :: YK_FILE  
     CHARACTER(len=128)                       :: YFILE_IOZ  
     TYPE(FD_ll), POINTER                     :: TZFD_IOZ 
+    TYPE(TFILEDATA),POINTER                  :: TZFILE
     INTEGER,DIMENSION(1) :: IDIMS
     !
     IDIMS(1) = 0
@@ -1934,11 +1935,11 @@ CONTAINS
     IF (ASSOCIATED(TZFD)) THEN
        IF (GSMONOPROC) THEN ! sequential execution
           IF (LLFIOUT) CALL IO_WRITE_FIELD_LFI(TPFIELD,TZFD%FLU,KFIELD,IRESP)
-          IF (LIOCDF4) CALL IO_WRITE_FIELD_NC4(TPFIELD,TZFD%CDF,KFIELD,IRESP)
+          IF (LIOCDF4) CALL IO_WRITE_FIELD_NC4(TPFILE,TPFIELD,TZFD%CDF,KFIELD,IRESP)
        ELSE 
           IF (ISP == TZFD%OWNER)  THEN
              IF (LLFIOUT) CALL IO_WRITE_FIELD_LFI(TPFIELD,TZFD%FLU,KFIELD,IRESP)
-             IF (LIOCDF4) CALL IO_WRITE_FIELD_NC4(TPFIELD,TZFD%CDF,KFIELD,IRESP)
+             IF (LIOCDF4) CALL IO_WRITE_FIELD_NC4(TPFILE,TPFIELD,TZFD%CDF,KFIELD,IRESP)
           END IF
           !
           CALL MPI_BCAST(IRESP,1,MPI_INTEGER,TZFD%OWNER-1,TZFD%COMM,IERR)
@@ -1952,7 +1953,14 @@ CONTAINS
              IK_RANK = TZFD_IOZ%OWNER
              IF ( ISP == IK_RANK )  THEN
                 IF (LLFIOUT) CALL IO_WRITE_FIELD_LFI(TPFIELD,TZFD_IOZ%FLU,KFIELD,IRESP)
-                IF (LIOCDF4) CALL IO_WRITE_FIELD_NC4(TPFIELD,TZFD_IOZ%CDF,KFIELD,IRESP)
+                IF (LIOCDF4) THEN
+                  CALL IO_FILE_FIND_BYNAME(TRIM(TPFILE%CNAME)//YK_FILE,TZFILE,IRESP)
+                  IF (IRESP/=0) THEN
+                    PRINT *,'FATAL: IO_WRITE_FIELD_BYFIELD_N0: file ',TRIM(TRIM(TPFILE%CNAME)//YK_FILE),' not found in list'
+                    STOP
+                  END IF
+                  CALL IO_WRITE_FIELD_NC4(TZFILE,TPFIELD,TZFD_IOZ%CDF,KFIELD,IRESP)
+                END IF
              END IF
           END DO
        ENDIF
@@ -2436,11 +2444,11 @@ CONTAINS
     IF (ASSOCIATED(TZFD)) THEN
        IF (GSMONOPROC) THEN ! sequential execution
           IF (LLFIOUT) CALL IO_WRITE_FIELD_LFI(TPFIELD,TZFD%FLU,HFIELD,IRESP)
-          IF (LIOCDF4) CALL IO_WRITE_FIELD_NC4(TPFIELD,TZFD%CDF,HFIELD,IRESP)
+          IF (LIOCDF4) CALL IO_WRITE_FIELD_NC4(TPFILE,TPFIELD,TZFD%CDF,HFIELD,IRESP)
        ELSE 
           IF (ISP == TZFD%OWNER)  THEN
              IF (LLFIOUT) CALL IO_WRITE_FIELD_LFI(TPFIELD,TZFD%FLU,HFIELD,IRESP)
-             IF (LIOCDF4) CALL IO_WRITE_FIELD_NC4(TPFIELD,TZFD%CDF,HFIELD,IRESP)
+             IF (LIOCDF4) CALL IO_WRITE_FIELD_NC4(TPFILE,TPFIELD,TZFD%CDF,HFIELD,IRESP)
           END IF
           !
           CALL MPI_BCAST(IRESP,1,MPI_INTEGER,TZFD%OWNER-1,TZFD%COMM,IERR)
diff --git a/src/LIB/SURCOUCHE/src/modd_io.f90 b/src/LIB/SURCOUCHE/src/modd_io.f90
index 7cb024053..8487b96c2 100644
--- a/src/LIB/SURCOUCHE/src/modd_io.f90
+++ b/src/LIB/SURCOUCHE/src/modd_io.f90
@@ -38,6 +38,12 @@ TYPE LFIPARAM
   INTEGER :: FITYP   ! FM File Type (used in FMCLOSE)
 END TYPE LFIPARAM
 
+!Structure containing one pointer to a file
+!Useful to create arrays of pointers to files
+TYPE TFILE_ELT
+  TYPE(TFILEDATA),POINTER :: TFILE
+END TYPE TFILE_ELT
+
 !Structure describing the characteristics of an output or a backup
 TYPE TOUTBAK
   INTEGER           :: NID = -1     !Backup number
@@ -46,6 +52,7 @@ TYPE TOUTBAK
   INTEGER           :: NOUTDAD = -1 !Index of the corresponding dad file (file with same time)
   CHARACTER(LEN=28) :: CDADFILENAME !Filename of dad
   TYPE(TFILEDATA),POINTER :: TFILE => NULL() !Corresponding file
+  TYPE(TFILE_ELT),DIMENSION(:),ALLOCATABLE :: TFILE_IOZ !Corresponding Z-splitted files
   INTEGER,DIMENSION(:),POINTER :: NFIELDLIST => NULL() !List of the fields to read or write
 END TYPE TOUTBAK
 
@@ -76,9 +83,7 @@ TYPE TFILEDATA
   TYPE(TFILEDATA),POINTER :: TFILE_NEXT => NULL()
 END TYPE TFILEDATA
 
-TYPE(TFILEDATA),POINTER,SAVE :: TFILE_BAK_FIRST => NULL()
-TYPE(TFILEDATA),POINTER,SAVE :: TFILE_OUT_FIRST => NULL()
-TYPE(TFILEDATA),POINTER,SAVE :: TFILE_BAK_LAST  => NULL()
-TYPE(TFILEDATA),POINTER,SAVE :: TFILE_OUT_LAST  => NULL()
+TYPE(TFILEDATA),POINTER,SAVE :: TFILE_FIRST => NULL()
+TYPE(TFILEDATA),POINTER,SAVE :: TFILE_LAST  => NULL()
 
 END MODULE MODD_IO_ll
diff --git a/src/LIB/SURCOUCHE/src/mode_fm.f90 b/src/LIB/SURCOUCHE/src/mode_fm.f90
index a04d04e3f..67acb8ba4 100644
--- a/src/LIB/SURCOUCHE/src/mode_fm.f90
+++ b/src/LIB/SURCOUCHE/src/mode_fm.f90
@@ -132,15 +132,19 @@ END SUBROUTINE FMLOOK_ll
 
 SUBROUTINE IO_FILE_OPEN_ll(TPFILE,HFIPRI,KRESP)
 !
-USE MODD_IO_ll, ONLY: LIOCDF4,TFILEDATA
+USE MODD_IO_ll, ONLY: ISP,LIOCDF4,TFILEDATA
 USE MODE_FD_ll, ONLY: FD_ll,GETFD
+USE MODE_IO_MANAGE_STRUCT, ONLY: IO_FILE_FIND_BYNAME
 !
 TYPE(TFILEDATA),  INTENT(INOUT) :: TPFILE ! File structure
 CHARACTER(LEN=*), INTENT(IN)    :: HFIPRI ! File for prints in FM
 INTEGER,          INTENT(OUT)   :: KRESP  ! Return code
 !
 INTEGER :: ININAR ! Number of articles present in LFI file (unused here)
-TYPE(FD_ll), POINTER  :: TZFDLFI
+INTEGER :: JI,IRESP
+CHARACTER (LEN=3) :: YNUMBER  ! Character string for Z-level
+TYPE(FD_ll), POINTER  :: TZFDLFI,TZFD_IOZ
+TYPE(TFILEDATA),POINTER :: TZFILE_IOZ
 !
 IF (TPFILE%LOPENED) THEN
   PRINT *,'ERROR: IO_FILE_OPEN_ll: file ',TRIM(TPFILE%CNAME),' already opened'
@@ -154,7 +158,25 @@ TPFILE%LOPENED = .TRUE.
 TPFILE%NOPEN   = TPFILE%NOPEN + 1
 !
 TZFDLFI=>GETFD(ADJUSTL(TRIM(TPFILE%CNAME)//'.lfi'))
-IF (LIOCDF4) TPFILE%NNCID = TZFDLFI%CDF%NCID
+!TZFDLFI%CDF exists only if ISP == TZFDLFI%OWNER
+IF (ISP == TZFDLFI%OWNER .AND. LIOCDF4) TPFILE%NNCID = TZFDLFI%CDF%NCID
+!
+IF (TZFDLFI%NB_PROCIO>1) THEN
+  DO JI = 1,TZFDLFI%NB_PROCIO
+    WRITE (YNUMBER,FMT="(I3.3)") JI
+    TZFD_IOZ => GETFD(TRIM(TPFILE%CNAME)//'.Z'//YNUMBER//'.lfi')
+    IF (ISP == TZFD_IOZ%OWNER .AND. LIOCDF4) THEN
+      CALL IO_FILE_FIND_BYNAME(TRIM(TPFILE%CNAME)//'.Z'//YNUMBER,TZFILE_IOZ,IRESP)
+      IF (IRESP/=0) THEN
+        PRINT *,'FATAL: IO_FILE_OPEN_ll: file ',TRIM(TRIM(TPFILE%CNAME)//'.Z'//YNUMBER),' not found in list'
+        STOP
+      END IF
+      TZFILE_IOZ%NNCID   = TZFD_IOZ%CDF%NCID
+      TZFILE_IOZ%LOPENED = .TRUE.
+      TZFILE_IOZ%NOPEN   = TZFILE_IOZ%NOPEN + 1
+    END IF
+  END DO
+END IF
 !
 END SUBROUTINE IO_FILE_OPEN_ll
 
@@ -383,23 +405,49 @@ END SUBROUTINE FMOPEN_ll
 SUBROUTINE IO_FILE_CLOSE_ll(TPFILE,HFIPRI,KRESP)
 !
 USE MODD_IO_ll, ONLY: TFILEDATA
+USE MODE_FD_ll, ONLY: FD_ll,GETFD
+USE MODE_IO_MANAGE_STRUCT, ONLY: IO_FILE_FIND_BYNAME
 !
 TYPE(TFILEDATA),  INTENT(INOUT) :: TPFILE ! File structure
 CHARACTER(LEN=*), INTENT(IN)    :: HFIPRI ! File for prints in FM
 INTEGER,          INTENT(OUT)   :: KRESP  ! Return code
 !
+INTEGER                 :: INB_PROCIO, IRESP, JI
+CHARACTER (LEN=3)       :: YNUMBER  ! Character string for Z-level
+TYPE(FD_ll), POINTER    :: TZFDLFI
+TYPE(TFILEDATA),POINTER :: TZFILE_IOZ
+!
 IF (.NOT.TPFILE%LOPENED) THEN
   PRINT *,'ERROR: IO_FILE_CLOSE_ll: trying to close a file not opened: ',TRIM(TPFILE%CNAME)
   CALL ABORT
   STOP
 ENDIF
 !
+!Next lines done before the close to be sure the FD_ll still exists
+TZFDLFI=>GETFD(ADJUSTL(TRIM(TPFILE%CNAME)//'.lfi'))
+INB_PROCIO=TZFDLFI%NB_PROCIO
+!
 CALL FMCLOS_ll(TPFILE%CNAME,'KEEP',HFIPRI,KRESP,TPFILE=TPFILE)
 !
 TPFILE%LOPENED = .FALSE.
 TPFILE%NCLOSE  = TPFILE%NCLOSE + 1
 TPFILE%NNCID   = -1
 !
+IF (INB_PROCIO>1) THEN
+  DO JI = 1,TZFDLFI%NB_PROCIO
+    WRITE (YNUMBER,FMT="(I3.3)") JI
+    CALL IO_FILE_FIND_BYNAME(TRIM(TPFILE%CNAME)//'.Z'//YNUMBER,TZFILE_IOZ,IRESP)
+    IF (IRESP/=0) THEN
+      PRINT *,'ERROR: IO_FILE_CLOSE_ll: file ',TRIM(TRIM(TPFILE%CNAME)//'.Z'//YNUMBER),' not found in list'
+    END IF
+    IF (TZFILE_IOZ%LOPENED) THEN
+      TZFILE_IOZ%LOPENED = .FALSE.
+      TZFILE_IOZ%NCLOSE  = TZFILE_IOZ%NCLOSE + 1
+      TZFILE_IOZ%NNCID   = -1
+    END IF
+  END DO
+END IF
+!
 END SUBROUTINE IO_FILE_CLOSE_ll
 
 SUBROUTINE FMCLOS_ll(HFILEM,HSTATU,HFIPRI,KRESP,OPARALLELIO,TPFILE)
diff --git a/src/LIB/SURCOUCHE/src/mode_io_manage_struct.f90 b/src/LIB/SURCOUCHE/src/mode_io_manage_struct.f90
index f85038a76..155417349 100644
--- a/src/LIB/SURCOUCHE/src/mode_io_manage_struct.f90
+++ b/src/LIB/SURCOUCHE/src/mode_io_manage_struct.f90
@@ -164,8 +164,8 @@ DO IMI = 1, NMODEL
   ALLOCATE(OUT_MODEL(IMI)%TBACKUPN(IBAK_NUMB))
   ALLOCATE(OUT_MODEL(IMI)%TOUTPUTN(IOUT_NUMB))
   !
-  CALL POPULATE_STRUCT(TFILE_BAK_FIRST,TFILE_BAK_LAST,IBAK_STEP,"BACKUP",OUT_MODEL(IMI)%TBACKUPN)
-  CALL POPULATE_STRUCT(TFILE_OUT_FIRST,TFILE_OUT_LAST,IOUT_STEP,"OUTPUT",OUT_MODEL(IMI)%TOUTPUTN)
+  CALL POPULATE_STRUCT(TFILE_FIRST,TFILE_LAST,IBAK_STEP,"BACKUP",OUT_MODEL(IMI)%TBACKUPN)
+  CALL POPULATE_STRUCT(TFILE_FIRST,TFILE_LAST,IOUT_STEP,"OUTPUT",OUT_MODEL(IMI)%TOUTPUTN)
   !
   !* Find dad output number
   !
@@ -460,13 +460,16 @@ END SUBROUTINE SORT_ENTRIES
 !#########################################################################
 SUBROUTINE POPULATE_STRUCT(TPFILE_FIRST,TPFILE_LAST,KSTEPS,HFILETYPE,TPBAKOUTN)
 !#########################################################################
+  !
+  USE MODD_CONFZ, ONLY: NB_PROCIO_W
   !
   TYPE(TFILEDATA),           POINTER,INTENT(INOUT) :: TPFILE_FIRST,TPFILE_LAST
   INTEGER,DIMENSION(:),              INTENT(IN)    :: KSTEPS
   CHARACTER(LEN=*),                  INTENT(IN)    :: HFILETYPE
   TYPE(TOUTBAK),DIMENSION(:),POINTER,INTENT(OUT)   :: TPBAKOUTN
   !
-  CHARACTER (LEN=4) :: YNUMBER          ! Character string for the file number
+  CHARACTER (LEN=3) :: YNUMBER          ! Character string for the file number
+  INTEGER :: JI
   !
   IPOS = 0
   DO JOUT = 1,SIZE(KSTEPS)
@@ -490,10 +493,10 @@ SUBROUTINE POPULATE_STRUCT(TPFILE_FIRST,TPFILE_LAST,KSTEPS,HFILETYPE,TPBAKOUTN)
         TPBAKOUTN(IPOS)%TFILE => TPFILE_LAST
         TPBAKOUTN(IPOS)%TFILE%CTYPE=HFILETYPE
         TPBAKOUTN(IPOS)%TFILE%CMODE="WRITE"
-        WRITE (YNUMBER,FMT="('.',I3.3)") IPOS
+        WRITE (YNUMBER,FMT="(I3.3)") IPOS
         IF (HFILETYPE=='OUTPUT') THEN
           ! Add a "OUT" suffix for output files
-          TPBAKOUTN(IPOS)%TFILE%CNAME=ADJUSTL(ADJUSTR(IO_SURF_MNH_MODEL(IMI)%COUTFILE)//'.OUT'//YNUMBER)
+          TPBAKOUTN(IPOS)%TFILE%CNAME=ADJUSTL(ADJUSTR(IO_SURF_MNH_MODEL(IMI)%COUTFILE)//'.OUT.'//YNUMBER)
           !Reduce the float precision if asked
           TPBAKOUTN(IPOS)%TFILE%LNCREDUCE_FLOAT_PRECISION = LOUT_REDUCE_FLOAT_PRECISION(IMI)
           !Set compression if asked
@@ -504,7 +507,7 @@ SUBROUTINE POPULATE_STRUCT(TPFILE_FIRST,TPFILE_LAST,KSTEPS,HFILETYPE,TPBAKOUTN)
           END IF
           TPBAKOUTN(IPOS)%TFILE%NNCCOMPRESS_LEVEL = NOUT_COMPRESS_LEVEL(IMI)
         ELSE IF (HFILETYPE=='BACKUP') THEN
-          TPBAKOUTN(IPOS)%TFILE%CNAME=ADJUSTL(ADJUSTR(IO_SURF_MNH_MODEL(IMI)%COUTFILE)//YNUMBER)
+          TPBAKOUTN(IPOS)%TFILE%CNAME=ADJUSTL(ADJUSTR(IO_SURF_MNH_MODEL(IMI)%COUTFILE)//'.'//YNUMBER)
         ELSE
           PRINT *,'Error: unknown filetype (',TRIM(HFILETYPE),')'
           CALL ABORT
@@ -517,19 +520,97 @@ SUBROUTINE POPULATE_STRUCT(TPFILE_FIRST,TPFILE_LAST,KSTEPS,HFILETYPE,TPBAKOUTN)
             TPBAKOUTN(IPOS)%TFILE%CFORMAT='NETCDF4'
           ELSE
             TPBAKOUTN(IPOS)%TFILE%CFORMAT='LFICDF4'
-            TPBAKOUTN(IPOS)%TFILE%NLFINPRAR= 22+2*(4+NRR+NSV)
+            IF (HFILETYPE=='BACKUP') TPBAKOUTN(IPOS)%TFILE%NLFINPRAR= 22+2*(4+NRR+NSV)
           END IF
         ELSE IF (LLFIOUT) THEN
           TPBAKOUTN(IPOS)%TFILE%CFORMAT='LFI'
-          TPBAKOUTN(IPOS)%TFILE%NLFINPRAR= 22+2*(4+NRR+NSV)
+          IF (HFILETYPE=='BACKUP') TPBAKOUTN(IPOS)%TFILE%NLFINPRAR= 22+2*(4+NRR+NSV)
         ELSE
           PRINT *,'Error: unknown backup/output fileformat'
           CALL ABORT
         ENDIF
+        !
+        !Create file structures if Z-splitted files
+        IF (NB_PROCIO_W>1) THEN
+          ALLOCATE(TPBAKOUTN(IPOS)%TFILE_IOZ(NB_PROCIO_W))
+          IF (NB_PROCIO_W>999) THEN
+            print *,'ERROR in SET_GRID: more than 999 z-levels'
+            STOP
+          END IF
+          DO JI = 1,NB_PROCIO_W
+            ALLOCATE(TPFILE_LAST%TFILE_NEXT)
+            TPFILE_LAST%TFILE_NEXT%TFILE_PREV => TPFILE_LAST
+            TPFILE_LAST => TPFILE_LAST%TFILE_NEXT
+            TPBAKOUTN(IPOS)%TFILE_IOZ(JI)%TFILE => TPFILE_LAST
+            TPBAKOUTN(IPOS)%TFILE_IOZ(JI)%TFILE%CTYPE=HFILETYPE
+            TPBAKOUTN(IPOS)%TFILE_IOZ(JI)%TFILE%CMODE="WRITE"
+            WRITE (YNUMBER,FMT="(I3.3)") JI
+            TPBAKOUTN(IPOS)%TFILE_IOZ(JI)%TFILE%CNAME = TRIM(TPBAKOUTN(IPOS)%TFILE%CNAME)//'.Z'//YNUMBER
+            IF (HFILETYPE=='OUTPUT') THEN
+              !Reduce the float precision if asked
+              TPBAKOUTN(IPOS)%TFILE_IOZ(JI)%TFILE%LNCREDUCE_FLOAT_PRECISION = LOUT_REDUCE_FLOAT_PRECISION(IMI)
+              !Set compression if asked
+              TPBAKOUTN(IPOS)%TFILE_IOZ(JI)%TFILE%LNCCOMPRESS = LOUT_COMPRESS(IMI)
+              IF ( NOUT_COMPRESS_LEVEL(IMI)<0 .OR. NOUT_COMPRESS_LEVEL(IMI)>9 ) THEN
+                PRINT *,'ERROR: NOUT_COMPRESS_LEVEL must be in the [0..9] range. Value forced to 4'
+                NOUT_COMPRESS_LEVEL(IMI) = 4
+              END IF
+              TPBAKOUTN(IPOS)%TFILE_IOZ(JI)%TFILE%NNCCOMPRESS_LEVEL = NOUT_COMPRESS_LEVEL(IMI)
+            END IF
+            TPBAKOUTN(IPOS)%TFILE_IOZ(JI)%TFILE%NLFITYPE=1 !1: to be transfered
+!PW: TODO: set NLFIVERB only when useful (only if LFI file...)
+            TPBAKOUTN(IPOS)%TFILE_IOZ(JI)%TFILE%NLFIVERB=NVERB
+            IF (LIOCDF4) THEN
+              IF (.NOT.LLFIOUT) THEN
+                TPBAKOUTN(IPOS)%TFILE_IOZ(JI)%TFILE%CFORMAT='NETCDF4'
+              ELSE
+                TPBAKOUTN(IPOS)%TFILE_IOZ(JI)%TFILE%CFORMAT='LFICDF4'
+              END IF
+            ELSE IF (LLFIOUT) THEN
+              TPBAKOUTN(IPOS)%TFILE_IOZ(JI)%TFILE%CFORMAT='LFI'
+              !TPBAKOUTN(IPOS)%TFILE_IOZ(JI)%TFILE%NLFINPRAR= 0
+            ELSE
+              PRINT *,'Error: unknown backup/output fileformat'
+              CALL ABORT
+            ENDIF
+          END DO
+        END IF
+        !
     END IF
   END DO
 END SUBROUTINE POPULATE_STRUCT
 !
 END SUBROUTINE IO_PREPARE_BAKOUT_STRUCT
 !
+SUBROUTINE IO_FILE_FIND_BYNAME(HNAME,TPFILE,KRESP)
+!
+USE MODD_IO_ll, ONLY: TFILE_FIRST,TFILEDATA
+!
+CHARACTER(LEN=*),       INTENT(IN)  :: HNAME  ! Name of the file to find
+TYPE(TFILEDATA),POINTER,INTENT(OUT) :: TPFILE ! File structure to return
+INTEGER,                INTENT(OUT) :: KRESP  ! Return value
+!
+TYPE(TFILEDATA),POINTER :: TZFILE ! File structure
+!
+NULLIFY(TPFILE)
+KRESP = 0
+!
+TZFILE => TFILE_FIRST
+!
+DO
+  IF (TRIM(TZFILE%CNAME) == TRIM(HNAME) ) THEN
+    TPFILE => TZFILE
+    EXIT
+  END IF
+  IF (.NOT.ASSOCIATED(TZFILE%TFILE_NEXT)) EXIT
+  TZFILE => TZFILE%TFILE_NEXT
+END DO
+!
+IF (.NOT.ASSOCIATED(TPFILE)) THEN
+  PRINT *,'ERROR: IO_FILE_FIND_BYNAME: file ',TRIM(HNAME),' not found in list'
+  KRESP = -1 !File not found
+END IF  
+!
+END SUBROUTINE IO_FILE_FIND_BYNAME
+!
 END MODULE MODE_IO_MANAGE_STRUCT
diff --git a/src/LIB/SURCOUCHE/src/mode_netcdf.f90 b/src/LIB/SURCOUCHE/src/mode_netcdf.f90
index da68aef61..8beac9810 100644
--- a/src/LIB/SURCOUCHE/src/mode_netcdf.f90
+++ b/src/LIB/SURCOUCHE/src/mode_netcdf.f90
@@ -541,37 +541,52 @@ IF (status /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__,'NCWRITX2[NF90_PUT_VAR
 KRESP = IRESP
 END SUBROUTINE NCWRITX2
 
-SUBROUTINE IO_WRITE_FIELD_NC4_X2(TPFILE,TPFIELD,PZCDF,PFIELD,KRESP,KVERTLEVEL)
+SUBROUTINE IO_WRITE_FIELD_NC4_X2(TPFILE,TPFIELD,PZCDF,PFIELD,KRESP,KVERTLEVEL,KZFILE)
 !
 USE MODD_FM, ONLY : FMHEADER
+USE MODE_IO_MANAGE_STRUCT, ONLY: IO_FILE_FIND_BYNAME
 !
-TYPE(TFILEDATA),       INTENT(IN) :: TPFILE
+TYPE(TFILEDATA),TARGET,INTENT(IN) :: TPFILE
 TYPE(TFIELDDATA),      INTENT(IN) :: TPFIELD
 TYPE(IOCDF), POINTER              :: PZCDF
 REAL,DIMENSION(:,:),   INTENT(IN) :: PFIELD   ! array containing the data field
 INTEGER,               INTENT(OUT):: KRESP
 INTEGER,OPTIONAL,      INTENT(IN) :: KVERTLEVEL ! Number of the vertical level (needed for Z-level splitted files)
+INTEGER,OPTIONAL,      INTENT(IN) :: KZFILE     ! Number of the Z-level splitted file
 !
 INTEGER(KIND=IDCDF_KIND) :: STATUS
 INTEGER(KIND=IDCDF_KIND) :: INCID
 CHARACTER(LEN=4)         :: YSUFFIX
+CHARACTER(LEN=3)         :: YNUMBER
 CHARACTER(LEN=LEN(TPFIELD%CMNHNAME)+4) :: YVARNAME
 INTEGER(KIND=IDCDF_KIND) :: IVARID
 INTEGER(KIND=IDCDF_KIND), DIMENSION(SIZE(SHAPE(PFIELD))) :: IVDIMS
 INTEGER                  :: IRESP
+TYPE(TFILEDATA),POINTER  :: TZFILE
 !
 IRESP = 0
 
 IF (PRESENT(KVERTLEVEL)) THEN
   WRITE(YSUFFIX,'(I4.4)') KVERTLEVEL
+  IF (.NOT.PRESENT(KZFILE)) THEN
+    PRINT *,'FATAL: IO_WRITE_FIELD_NC4_X2: KZFILE argument not provided'
+    STOP
+  END IF
+  WRITE(YNUMBER,'(I3.3)') KZFILE
   YVARNAME = TRIM(TPFIELD%CMNHNAME)//YSUFFIX
+!PW: TODO: try to not do a find (for better perf)
+  CALL IO_FILE_FIND_BYNAME(TRIM(TPFILE%CNAME)//'.Z'//YNUMBER,TZFILE,IRESP)
+  IF (IRESP/=0) THEN
+    PRINT *,'FATAL: IO_FILE_OPEN_ll: file ',TRIM(TRIM(TPFILE%CNAME)//'.Z'//YNUMBER),' not found in list'
+    STOP
+  END IF
 ELSE
   YVARNAME = TRIM(TPFIELD%CMNHNAME)
+  TZFILE => TPFILE
 ENDIF
 
 ! Get the Netcdf file ID
-INCID = TPFILE%NNCID
-
+INCID = TZFILE%NNCID
 ! NetCDF var names can't contain '%' nor '.' 
 YVARNAME = str_replace(YVARNAME, '%', '__')
 YVARNAME = str_replace(YVARNAME, '.', '--')
@@ -583,15 +598,15 @@ IF (STATUS /= NF90_NOERR) THEN
    CALL FILLVDIMS(PZCDF, INT(SHAPE(PFIELD),KIND=IDCDF_KIND), TPFIELD%CDIR, IVDIMS)
 
    ! Define the variable 
-   IF (TPFILE%LNCREDUCE_FLOAT_PRECISION) THEN
+   IF (TZFILE%LNCREDUCE_FLOAT_PRECISION) THEN
      STATUS = NF90_DEF_VAR(INCID, YVARNAME, NF90_FLOAT,  IVDIMS, IVARID)
    ELSE
      STATUS = NF90_DEF_VAR(INCID, YVARNAME, NF90_DOUBLE, IVDIMS, IVARID)
    END IF
    IF (status /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__,'IO_WRITE_FIELD_NC4_X2[NF90_DEF_VAR]')
    ! Add compression if asked for
-   IF (TPFILE%LNCCOMPRESS) THEN
-     STATUS = NF90_DEF_VAR_DEFLATE(INCID, IVARID, SHUFFLE, DEFLATE, TPFILE%NNCCOMPRESS_LEVEL)
+   IF (TZFILE%LNCCOMPRESS) THEN
+     STATUS = NF90_DEF_VAR_DEFLATE(INCID, IVARID, SHUFFLE, DEFLATE, TZFILE%NNCCOMPRESS_LEVEL)
      IF (status /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__,'IO_WRITE_FIELD_NC4_X2[NF90_DEF_VAR_DEFLATE]')
    END IF
    CALL IO_WRITE_FIELD_ATTR_NC4(TPFIELD,INCID,IVARID)
-- 
GitLab