diff --git a/src/MNH/mode_mnh_zwork.f90 b/src/MNH/mode_mnh_zwork.f90
index d1a0d05703d839120082ed2dcea7ef0772a86bc7..6c9d5d374190b58269352d0349a520c3335a0474 100644
--- a/src/MNH/mode_mnh_zwork.f90
+++ b/src/MNH/mode_mnh_zwork.f90
@@ -6,9 +6,12 @@
 !-----------------------------------------------------------------
 ! Modifications:
 !  P. Wautelet 10/07/2019: bugfix: MNH_REL_ZT3D_N0: access outside of array was possible
+!  P. Wautelet 20/10/2021: create ZT1DFLAT buffer that can be used for any size and shape arrays (real)
 !-----------------------------------------------------------------
 MODULE MODE_MNH_ZWORK
 
+  use modd_precision, only: MNHINT32, MNHINT64
+
   use mode_msg
 
   IMPLICIT NONE
@@ -71,15 +74,37 @@ MODULE MODE_MNH_ZWORK
   INTEGER                                   :: NT1D_TOP_I , NT1D_TOP_I_MAX = 0  
   INTEGER,SAVE    , ALLOCATABLE, TARGET , DIMENSION(:,:)       :: IT1D
   INTEGER,SAVE    , ALLOCATABLE, TARGET , DIMENSION(:)         :: IT1D_OSIZE
-  
+
+
+  INTEGER, PARAMETER                                 :: JPMAX_T1DFLAT_R = 10       !Used to determine max size of buffer ZT1DFLAT
+                                                                                   !(3D size of the mesh * JPMAX_T1DFLAT_R)
+  INTEGER, PARAMETER                                 :: JPPOOLSTEP_FLAT = 10 !Number of elements added to the pool when too small
+  INTEGER,                SAVE                       :: NPMAX_POOL_T1DFLAT_R = 100 !Maximum size of the pool (max number of arrays)
+  INTEGER(KIND=MNHINT64), ALLOCATABLE, DIMENSION (:) :: NT1DFLAT_POOL_R   !Position in ZT1DFLAT of the beginning of each array
+  INTEGER(KIND=MNHINT64), ALLOCATABLE, DIMENSION (:) :: NT1DFLAT_SIZE_R   !Size of each array
+  INTEGER(KIND=MNHINT64), SAVE                       :: NT1DFLAT_MAXSIZE                        !Total allocated size of ZT1DFLAT
+  INTEGER,                SAVE                       :: NT1DFLAT_TOP_R, NT1DFLAT_TOP_R_MAX = 0  !Position in the pool
+  INTEGER(KIND=MNHINT64), SAVE                       :: NT1DFLAT_POS_R, NT1DFLAT_POS_R_MAX = 0  !Position in the array
+  REAL, SAVE, ALLOCATABLE, TARGET, DIMENSION(:)      :: ZT1DFLAT
+
+  INTERFACE MNH_ALLOCATE_FLAT
+    MODULE PROCEDURE :: MNH_ALLOCATE_ZT1DFLAT_INT32
+    MODULE PROCEDURE :: MNH_ALLOCATE_ZT1DFLAT_INT64
+    MODULE PROCEDURE :: MNH_ALLOCATE_ZT3DFLAT
+  END INTERFACE MNH_ALLOCATE_FLAT
+
+  INTERFACE MNH_RELEASE_FLAT
+    MODULE PROCEDURE :: MNH_REL_ZT1DFLAT
+  END INTERFACE MNH_RELEASE_FLAT
+
 CONTAINS
 
   SUBROUTINE MNH_ALLOC_ZWORK(IMODEL)
 
-    USE MODE_TOOLS_ll, ONLY   : GET_DIM_EXT_ll, GET_INDICE_ll, LWEST_ll,LEAST_ll, LSOUTH_ll, LNORTH_ll
+    USE MODE_TOOLS_ll,   ONLY: GET_DIM_EXT_ll, GET_INDICE_ll, LWEST_ll, LEAST_ll, LSOUTH_ll, LNORTH_ll
 
-    USE MODD_PARAMETERS, ONLY : JPVEXT, XUNDEF
-    USE MODD_DIM_n,      ONLY : NKMAX
+    USE MODD_PARAMETERS, ONLY: JPVEXT, NNEGUNDEF, XUNDEF
+    USE MODD_DIM_n,      ONLY: NKMAX
 
     IMPLICIT NONE
 
@@ -192,6 +217,18 @@ CONTAINS
           NT1D_POOL_I(JI) = JI
        END DO       
        
+!------ Real 1DFLAT pool
+
+       NT1DFLAT_MAXSIZE = INT( IIU, KIND=MNHINT64 ) * IJU * IKU * JPMAX_T1DFLAT_R
+       ALLOCATE( ZT1DFLAT(NT1DFLAT_MAXSIZE) )
+       !$acc enter data create( ZT1DFLAT )
+
+       ALLOCATE( NT1DFLAT_POOL_R(NPMAX_POOL_T1DFLAT_R) )
+       ALLOCATE( NT1DFLAT_SIZE_R(NPMAX_POOL_T1DFLAT_R) )
+       NT1DFLAT_POOL_R(:) = NNEGUNDEF
+       NT1DFLAT_SIZE_R(:) = NNEGUNDEF
+       NT1DFLAT_TOP_R = 0
+
 !------ Default values
        
        !$acc kernels 
@@ -201,8 +238,9 @@ CONTAINS
 
        ZUNIT3D = 1.0
 
-       ZT3D  =  XUNDEF
-       ZT1D  =  XUNDEF
+       ZT3D(:,:,:,:)  = XUNDEF
+       ZT1D(:,:)      = XUNDEF
+       ZT1DFLAT(:)    = XUNDEF
 
        IT3D  = 0.0
        IT1D  = 0.0
@@ -213,7 +251,7 @@ CONTAINS
 
        !$acc update host (ZPSRC_HALO2_WEST,ZPSRC_HALO2_SOUTH)
        !$acc update host (ZUNIT3D)
-       !$acc update host (ZT3D,ZT1D)
+       !$acc update host (ZT3D,ZT1D,ZT1DFLAT)
 
     END IF
 
@@ -482,7 +520,7 @@ CONTAINS
 
     !local
 
-    IF ( (KI .EQ. IIU) .AND. (KJ .EQ. IJU) .AND. (KKB .LE. IKU) .AND. (KKE  .LE. IKU) ) THEN 
+    IF ( (KI .EQ. IIU) .AND. (KJ .EQ. IJU) .AND. (KKB .LE. IKU) .AND. (KKE .LE. IKU) ) THEN
        CALL MNH_GET_ZT3D_N0(KINDEX)
        PTAB(1:,1:,KKB:) => ZT3D(:,:,KKB:KKE,KINDEX)
     ELSE
@@ -935,7 +973,7 @@ CONTAINS
     IF (KI .LE. IIJKU) THEN 
        CALL MNH_GET_IT1D_N0(KINDEX)
        IF (KI .NE. 0) THEN
-          PTAB(1:KI) => IT1D(:,KINDEX)
+          PTAB(1:KI) => IT1D(1:KI,KINDEX)
        ELSE
           PTAB => IT1D_OSIZE
        END IF
@@ -948,6 +986,139 @@ CONTAINS
 
   ! End Integer 1D management
 
+  !-------- Real 1DFLAT Pool Managment
+
+  FUNCTION MNH_GET_ZT1DFLAT( KSIZE ) RESULT( KINDEX )
+
+    USE MODD_PARAMETERS, ONLY: NNEGUNDEF
+
+    IMPLICIT NONE
+
+    INTEGER(KIND=MNHINT64), INTENT(IN)  :: KSIZE
+    INTEGER                             :: KINDEX
+
+    CHARACTER(LEN=32) :: YAVAIL, YMAX, YSIZE
+    INTEGER(KIND=MNHINT64), ALLOCATABLE, DIMENSION (:) :: IT1DFLAT_POOL_R
+    INTEGER(KIND=MNHINT64), ALLOCATABLE, DIMENSION (:) :: IT1DFLAT_SIZE_R
+
+    IF ( NT1DFLAT_POS_R + KSIZE > NT1DFLAT_MAXSIZE ) THEN
+      WRITE( YSIZE,  '( I0 )' ) KSIZE
+      WRITE( YAVAIL, '( I0 )' ) NT1DFLAT_MAXSIZE - NT1DFLAT_POS_R
+      WRITE( YMAX,   '( I0 )' ) NT1DFLAT_MAXSIZE
+      call Print_msg( NVERB_FATAL, 'GEN', 'MNH_GET_ZT1DFLAT', 'ZT1DFLAT too small (asked=' // Trim( ysize ) // &
+                      ', available=' // Trim( yavail ) // ', total=' // Trim( ymax ) // ')' )
+    ELSE
+      NT1DFLAT_TOP_R = NT1DFLAT_TOP_R + 1
+      KINDEX = NT1DFLAT_TOP_R
+
+      IF ( KINDEX > NPMAX_POOL_T1DFLAT_R ) THEN
+        WRITE( YSIZE,  '( I0 )' ) NPMAX_POOL_T1DFLAT_R
+        WRITE( YMAX,   '( I0 )' ) NPMAX_POOL_T1DFLAT_R+JPPOOLSTEP_FLAT
+        call Print_msg( NVERB_INFO, 'GEN', 'MNH_GET_ZT1DFLAT', 'pool for ZT1DFLAT was too small (' // TRIM( YSIZE ) &
+                        // '->' // TRIM( YMAX ) // ')' )
+
+        ALLOCATE( IT1DFLAT_POOL_R(NPMAX_POOL_T1DFLAT_R+JPPOOLSTEP_FLAT) )
+        ALLOCATE( IT1DFLAT_SIZE_R(NPMAX_POOL_T1DFLAT_R+JPPOOLSTEP_FLAT) )
+
+        IT1DFLAT_POOL_R(1:NPMAX_POOL_T1DFLAT_R) = NT1DFLAT_POOL_R(:)
+        IT1DFLAT_SIZE_R(1:NPMAX_POOL_T1DFLAT_R) = NT1DFLAT_SIZE_R(:)
+        IT1DFLAT_POOL_R(NPMAX_POOL_T1DFLAT_R+1:) = NNEGUNDEF
+        IT1DFLAT_SIZE_R(NPMAX_POOL_T1DFLAT_R+1:) = NNEGUNDEF
+
+        CALL MOVE_ALLOC( FROM = IT1DFLAT_POOL_R, TO = NT1DFLAT_POOL_R )
+        CALL MOVE_ALLOC( FROM = IT1DFLAT_SIZE_R, TO = NT1DFLAT_SIZE_R )
+
+        NPMAX_POOL_T1DFLAT_R = NPMAX_POOL_T1DFLAT_R + JPPOOLSTEP_FLAT
+      END IF
+
+      NT1DFLAT_POOL_R( KINDEX ) = NT1DFLAT_POS_R + 1
+      NT1DFLAT_SIZE_R( KINDEX ) = KSIZE
+
+      NT1DFLAT_POS_R = NT1DFLAT_POS_R + KSIZE
+
+      IF ( NT1DFLAT_TOP_R > NT1DFLAT_TOP_R_MAX ) NT1DFLAT_TOP_R_MAX = NT1DFLAT_TOP_R
+      IF ( NT1DFLAT_POS_R > NT1DFLAT_POS_R_MAX ) NT1DFLAT_POS_R_MAX = NT1DFLAT_POS_R
+    END IF
+
+  END FUNCTION MNH_GET_ZT1DFLAT
+
+
+  SUBROUTINE MNH_REL_ZT1DFLAT( KINDEX )
+
+    USE MODD_PARAMETERS, ONLY: NNEGUNDEF
+
+    IMPLICIT NONE
+
+    INTEGER :: KINDEX
+
+    !Release only if last block
+    IF ( KINDEX /= NT1DFLAT_TOP_R ) &
+      call Print_msg( NVERB_FATAL, 'GEN', 'MNH_REL_ZT1DFLAT', 'trying to release block that is not the last one' )
+
+    NT1DFLAT_TOP_R = NT1DFLAT_TOP_R - 1
+    NT1DFLAT_POS_R = NT1DFLAT_POS_R - NT1DFLAT_SIZE_R( KINDEX )
+
+    NT1DFLAT_POOL_R( KINDEX ) = NNEGUNDEF
+    NT1DFLAT_SIZE_R( KINDEX ) = NNEGUNDEF
+
+  END SUBROUTINE MNH_REL_ZT1DFLAT
+
+
+  FUNCTION MNH_ALLOCATE_ZT1DFLAT_INT32( PTAB, KSIZE ) RESULT( KINDEX )
+
+    REAL, POINTER, CONTIGUOUS , DIMENSION(:), INTENT(INOUT) :: PTAB
+    INTEGER(KIND=MNHINT32),                   INTENT(IN)    :: KSIZE
+    INTEGER                                                 :: KINDEX
+
+    kindex = MNH_Allocate_zt1dflat_int64( ptab, Int( ksize, kind = MNHINT64 ) )
+
+  END FUNCTION MNH_ALLOCATE_ZT1DFLAT_INT32
+
+
+  FUNCTION MNH_ALLOCATE_ZT1DFLAT_INT64( PTAB, KSIZE ) RESULT( KINDEX )
+
+    REAL, POINTER, CONTIGUOUS , DIMENSION(:), INTENT(INOUT) :: PTAB
+    INTEGER(KIND=MNHINT64),                   INTENT(IN)    :: KSIZE
+    INTEGER                                                 :: KINDEX
+
+    kindex = MNH_Get_zt1dflat( ksize )
+    ptab(1:KSIZE) => zt1dflat( NT1DFLAT_POOL_R(kindex) : NT1DFLAT_POOL_R(kindex)+ksize-1 )
+
+  END FUNCTION MNH_ALLOCATE_ZT1DFLAT_INT64
+
+
+  FUNCTION MNH_ALLOCATE_ZT3DFLAT( PTAB, KIB, KIE, KJB, KJE, KKB, KKE ) RESULT ( KINDEX )
+
+    REAL, POINTER, CONTIGUOUS , DIMENSION(:,:,:), INTENT(INOUT) :: PTAB
+    INTEGER,                                      INTENT(IN)    :: KIB
+    INTEGER,                                      INTENT(IN)    :: KIE
+    INTEGER,                                      INTENT(IN)    :: KJB
+    INTEGER,                                      INTENT(IN)    :: KJE
+    INTEGER,                                      INTENT(IN)    :: KKB
+    INTEGER,                                      INTENT(IN)    :: KKE
+    INTEGER                                                     :: KINDEX
+
+    INTEGER(KIND=MNHINT64) :: ISIZE
+    INTEGER(KIND=MNHINT64) :: IIB, IIE, IJB, IJE, IKB, IKE
+
+    IIB = KIB
+    IIE = KIE
+    IJB = KJB
+    IJE = KJE
+    IKB = KKB
+    IKE = KKE
+
+    ISIZE = ( IIE - IIB + 1_MNHINT64 ) * ( IJE - IJB + 1_MNHINT64 ) * ( IIE - IIB + 1_MNHINT64 )
+
+    kindex = MNH_Get_zt1dflat( isize )
+
+    ptab(KIB:KIE, KJB:KJE, KKB:KKE) => zt1dflat( NT1DFLAT_POOL_R(kindex) : NT1DFLAT_POOL_R(kindex)+isize-1 )
+
+  END FUNCTION MNH_ALLOCATE_ZT3DFLAT
+
+  ! End Real 1DFLAT management
+
+
   SUBROUTINE MNH_CHECK_IN_ZT3D(HSUB)
     IMPLICIT NONE