diff --git a/src/MNH/advection_metsv.f90 b/src/MNH/advection_metsv.f90
index 43e6ce771ed6f7b1a9b1a57a3e6e3d8d63f073e5..ea8140defaeb3f620ac5e6b7bc28c6211106f6b5 100644
--- a/src/MNH/advection_metsv.f90
+++ b/src/MNH/advection_metsv.f90
@@ -174,8 +174,8 @@ use mode_argslist_ll,    only: ADD3DFIELD_ll, ADD4DFIELD_ll, CLEANLIST_ll, LIST_
 use mode_budget,         only: Budget_store_init, Budget_store_end
 #ifdef MNH_OPENACC
 USE MODE_DEVICE
-USE MODE_MNH_ZWORK,      ONLY: MNH_ALLOCATE_FLAT, MNH_CHECK_IN_ZT3D, MNH_CHECK_OUT_ZT3D, &
-                               MNH_GET_ZT3D, MNH_RELEASE_FLAT, MNH_REL_ZT3D, ZT3D
+USE MODE_MNH_ZWORK,      ONLY: MNH_MEM_GET, MNH_MEM_POSITION_PIN, MNH_MEM_RELEASE, &
+                               MNH_GET_ZT3D, MNH_REL_ZT3D, ZT3D
 #endif
 use mode_exchange_ll,    only: UPDATE_HALO_ll
 USE MODE_IO_FIELD_WRITE, only: IO_Field_write
@@ -255,10 +255,6 @@ REAL, DIMENSION(:,:,:),pointer , contiguous :: ZCFLW
 !                                                 ! CFL numbers on each direction
 REAL, DIMENSION(:,:,:),pointer , contiguous :: ZCFL
 !                                                 ! CFL number
-#ifdef MNH_OPENACC
-INTEGER :: IZRUCPPM,IZRVCPPM,IZRWCPPM,IZCFLU,IZCFLV,IZCFLW,IZCFL
-#endif
-!
 REAL :: ZCFLU_MAX, ZCFLV_MAX, ZCFLW_MAX, ZCFL_MAX ! maximum CFL numbers
 !
 REAL, DIMENSION(:,:,:),pointer , contiguous :: ZTH
@@ -267,40 +263,24 @@ REAL, DIMENSION(:,:,:),pointer , contiguous :: ZRTHS_OTHER
 REAL, DIMENSION(:,:,:),pointer , contiguous :: ZRTKES_OTHER
 REAL, DIMENSION(:,:,:),pointer , contiguous :: ZRTHS_PPM
 REAL, DIMENSION(:,:,:),pointer , contiguous :: ZRTKES_PPM
-#ifdef MNH_OPENACC
-INTEGER :: IZTH,IZTKE,IZRTHS_OTHER,IZRTKES_OTHER,IZRTHS_PPM,IZRTKES_PPM
-#endif
 REAL, DIMENSION(:,:,:,:),pointer , contiguous :: ZR
 REAL, DIMENSION(:,:,:,:),pointer , contiguous :: ZSV
 REAL, DIMENSION(:,:,:,:),pointer , contiguous :: ZSNWC
 REAL, DIMENSION(:,:,:,:),pointer , contiguous :: ZSNWC_INIT
 REAL, DIMENSION(:,:,:,:),pointer , contiguous :: ZRSNWCS
-#ifdef MNH_OPENACC
-INTEGER :: IZR,IZSV,IZSNWC,IZSNWC_INIT,IZRSNWCS
-#endif
 ! Guess at the sub time step
 REAL, DIMENSION(:,:,:,:),pointer , contiguous :: ZRRS_OTHER
 REAL, DIMENSION(:,:,:,:),pointer , contiguous :: ZRSVS_OTHER
 REAL, DIMENSION(:,:,:,:),pointer , contiguous :: ZRSNWCS_OTHER
-#ifdef MNH_OPENACC
-INTEGER :: IZRRS_OTHER,IZRSVS_OTHER,IZRSNWCS_OTHER
-#endif
 ! Tendencies since the beginning of the time step
 REAL, DIMENSION(:,:,:,:),pointer , contiguous :: ZRRS_PPM
 REAL, DIMENSION(:,:,:,:),pointer , contiguous :: ZRSVS_PPM
 REAL, DIMENSION(:,:,:,:),pointer , contiguous :: ZRSNWCS_PPM
-#ifdef MNH_OPENACC
-INTEGER :: IZRRS_PPM,IZRSVS_PPM,IZRSNWCS_PPM   
-#endif
 ! Guess at the end of the sub time step
 REAL, DIMENSION(:,:,:),pointer , contiguous :: ZRHOX1,ZRHOX2
 REAL, DIMENSION(:,:,:),pointer , contiguous :: ZRHOY1,ZRHOY2
 REAL, DIMENSION(:,:,:),pointer , contiguous :: ZRHOZ1,ZRHOZ2
 REAL, DIMENSION(:,:,:),pointer , contiguous :: ZT,ZEXN,ZLV,ZLS,ZCPH
-#ifdef MNH_OPENACC
-INTEGER :: IZRHOX1,IZRHOX2,IZRHOY1,IZRHOY2,IZRHOZ1,IZRHOZ2 &
-          ,IZT,IZEXN,IZLV,IZLS,IZCPH 
-#endif
 
 ! Temporary advected rhodj for PPM routines
 !
@@ -399,42 +379,44 @@ allocate( ZLV          ( JIU,JJU,JKU )               )
 allocate( ZLS          ( JIU,JJU,JKU )               )
 allocate( ZCPH         ( JIU,JJU,JKU )               )
 #else
-CALL MNH_CHECK_IN_ZT3D("ADVECTION_METSV")
-IZRUCPPM       = MNH_ALLOCATE_FLAT( ZRUCPPM      , JIU, JJU, JKU               )
-IZRVCPPM       = MNH_ALLOCATE_FLAT( ZRVCPPM      , JIU, JJU, JKU               )
-IZRWCPPM       = MNH_ALLOCATE_FLAT( ZRWCPPM      , JIU, JJU, JKU               )
-IZCFLU         = MNH_ALLOCATE_FLAT( ZCFLU        , JIU, JJU, JKU               )
-IZCFLV         = MNH_ALLOCATE_FLAT( ZCFLV        , JIU, JJU, JKU               )
-IZCFLW         = MNH_ALLOCATE_FLAT( ZCFLW        , JIU, JJU, JKU               )
-IZCFL          = MNH_ALLOCATE_FLAT( ZCFL         , JIU, JJU, JKU               )
-IZTH           = MNH_ALLOCATE_FLAT( ZTH          , JIU, JJU, JKU               )
-IZTKE          = MNH_ALLOCATE_FLAT( ZTKE         , JIU, JJU, SIZE(PTKET,3)     )
-IZRTHS_OTHER   = MNH_ALLOCATE_FLAT( ZRTHS_OTHER  , JIU, JJU, JKU               )
-IZRTKES_OTHER  = MNH_ALLOCATE_FLAT( ZRTKES_OTHER , JIU, JJU, SIZE(PTKET,3)     )
-IZRTHS_PPM     = MNH_ALLOCATE_FLAT( ZRTHS_PPM    , JIU, JJU, JKU               )
-IZRTKES_PPM    = MNH_ALLOCATE_FLAT( ZRTKES_PPM   , JIU, JJU, SIZE(PTKET,3)     )
-IZR            = MNH_ALLOCATE_FLAT( ZR           , JIU, JJU, JKU, SIZE(PRT, 4) )
-IZSV           = MNH_ALLOCATE_FLAT( ZSV          , JIU, JJU, JKU, SIZE(PSVT,4) )
-IZSNWC         = MNH_ALLOCATE_FLAT( ZSNWC        , JIU, JJU, JKU, NBLOWSNOW_2D )
-IZSNWC_INIT    = MNH_ALLOCATE_FLAT( ZSNWC_INIT   , JIU, JJU, JKU, NBLOWSNOW_2D )
-IZRSNWCS       = MNH_ALLOCATE_FLAT( ZRSNWCS      , JIU, JJU, JKU, NBLOWSNOW_2D )
-IZRRS_OTHER    = MNH_ALLOCATE_FLAT( ZRRS_OTHER   , JIU, JJU, JKU, SIZE(PRT, 4) )
-IZRSVS_OTHER   = MNH_ALLOCATE_FLAT( ZRSVS_OTHER  , JIU, JJU, JKU, SIZE(PSVT,4) )
-IZRSNWCS_OTHER = MNH_ALLOCATE_FLAT( ZRSNWCS_OTHER, JIU, JJU, JKU, NBLOWSNOW_2D )
-IZRRS_PPM      = MNH_ALLOCATE_FLAT( ZRRS_PPM     , JIU, JJU, JKU, SIZE(PRT, 4) )
-IZRSVS_PPM     = MNH_ALLOCATE_FLAT( ZRSVS_PPM    , JIU, JJU, JKU, SIZE(PSVT,4) )
-IZRSNWCS_PPM   = MNH_ALLOCATE_FLAT( ZRSNWCS_PPM  , JIU, JJU, JKU, NBLOWSNOW_2D )
-IZRHOX1        = MNH_ALLOCATE_FLAT( ZRHOX1       , JIU, JJU, JKU               )
-IZRHOX2        = MNH_ALLOCATE_FLAT( ZRHOX2       , JIU, JJU, JKU               )
-IZRHOY1        = MNH_ALLOCATE_FLAT( ZRHOY1       , JIU, JJU, JKU               )
-IZRHOY2        = MNH_ALLOCATE_FLAT( ZRHOY2       , JIU, JJU, JKU               )
-IZRHOZ1        = MNH_ALLOCATE_FLAT( ZRHOZ1       , JIU, JJU, JKU               )
-IZRHOZ2        = MNH_ALLOCATE_FLAT( ZRHOZ2       , JIU, JJU, JKU               )
-IZT            = MNH_ALLOCATE_FLAT( ZT           , JIU, JJU, JKU               )
-IZEXN          = MNH_ALLOCATE_FLAT( ZEXN         , JIU, JJU, JKU               )
-IZLV           = MNH_ALLOCATE_FLAT( ZLV          , JIU, JJU, JKU               )
-IZLS           = MNH_ALLOCATE_FLAT( ZLS          , JIU, JJU, JKU               )
-IZCPH          = MNH_ALLOCATE_FLAT( ZCPH         , JIU, JJU, JKU                )
+!Pin positions in the pools of MNH memory
+CALL MNH_MEM_POSITION_PIN()
+
+CALL MNH_MEM_GET( ZRUCPPM      , JIU, JJU, JKU               )
+CALL MNH_MEM_GET( ZRVCPPM      , JIU, JJU, JKU               )
+CALL MNH_MEM_GET( ZRWCPPM      , JIU, JJU, JKU               )
+CALL MNH_MEM_GET( ZCFLU        , JIU, JJU, JKU               )
+CALL MNH_MEM_GET( ZCFLV        , JIU, JJU, JKU               )
+CALL MNH_MEM_GET( ZCFLW        , JIU, JJU, JKU               )
+CALL MNH_MEM_GET( ZCFL         , JIU, JJU, JKU               )
+CALL MNH_MEM_GET( ZTH          , JIU, JJU, JKU               )
+CALL MNH_MEM_GET( ZTKE         , JIU, JJU, SIZE(PTKET,3)     )
+CALL MNH_MEM_GET( ZRTHS_OTHER  , JIU, JJU, JKU               )
+CALL MNH_MEM_GET( ZRTKES_OTHER , JIU, JJU, SIZE(PTKET,3)     )
+CALL MNH_MEM_GET( ZRTHS_PPM    , JIU, JJU, JKU               )
+CALL MNH_MEM_GET( ZRTKES_PPM   , JIU, JJU, SIZE(PTKET,3)     )
+CALL MNH_MEM_GET( ZR           , JIU, JJU, JKU, SIZE(PRT, 4) )
+CALL MNH_MEM_GET( ZSV          , JIU, JJU, JKU, SIZE(PSVT,4) )
+CALL MNH_MEM_GET( ZSNWC        , JIU, JJU, JKU, NBLOWSNOW_2D )
+CALL MNH_MEM_GET( ZSNWC_INIT   , JIU, JJU, JKU, NBLOWSNOW_2D )
+CALL MNH_MEM_GET( ZRSNWCS      , JIU, JJU, JKU, NBLOWSNOW_2D )
+CALL MNH_MEM_GET( ZRRS_OTHER   , JIU, JJU, JKU, SIZE(PRT, 4) )
+CALL MNH_MEM_GET( ZRSVS_OTHER  , JIU, JJU, JKU, SIZE(PSVT,4) )
+CALL MNH_MEM_GET( ZRSNWCS_OTHER, JIU, JJU, JKU, NBLOWSNOW_2D )
+CALL MNH_MEM_GET( ZRRS_PPM     , JIU, JJU, JKU, SIZE(PRT, 4) )
+CALL MNH_MEM_GET( ZRSVS_PPM    , JIU, JJU, JKU, SIZE(PSVT,4) )
+CALL MNH_MEM_GET( ZRSNWCS_PPM  , JIU, JJU, JKU, NBLOWSNOW_2D )
+CALL MNH_MEM_GET( ZRHOX1       , JIU, JJU, JKU               )
+CALL MNH_MEM_GET( ZRHOX2       , JIU, JJU, JKU               )
+CALL MNH_MEM_GET( ZRHOY1       , JIU, JJU, JKU               )
+CALL MNH_MEM_GET( ZRHOY2       , JIU, JJU, JKU               )
+CALL MNH_MEM_GET( ZRHOZ1       , JIU, JJU, JKU               )
+CALL MNH_MEM_GET( ZRHOZ2       , JIU, JJU, JKU               )
+CALL MNH_MEM_GET( ZT           , JIU, JJU, JKU               )
+CALL MNH_MEM_GET( ZEXN         , JIU, JJU, JKU               )
+CALL MNH_MEM_GET( ZLV          , JIU, JJU, JKU               )
+CALL MNH_MEM_GET( ZLS          , JIU, JJU, JKU               )
+CALL MNH_MEM_GET( ZCPH         , JIU, JJU, JKU                )
 #endif
 
 !$acc data present( ZRUCPPM, ZRVCPPM, ZRWCPPM, ZCFLU, ZCFLV, ZCFLW, ZCFL, ZTH,                        &
@@ -1113,16 +1095,8 @@ deallocate ( ZRUCPPM, ZRVCPPM, ZRWCPPM, ZCFLU, ZCFLV, ZCFLW, ZCFL, ZTH,
             ZRRS_PPM, ZRSVS_PPM, ZRSNWCS_PPM, ZRHOX1, ZRHOX2, ZRHOY1, ZRHOY2, ZRHOZ1, ZRHOZ2, &
             ZT, ZEXN, ZLV, ZLS, ZCPH                                                          )
 #else
-CALL MNH_RELEASE_FLAT ( IZRHOX1, IZRHOX2, IZRHOY1, IZRHOY2, IZRHOZ1, IZRHOZ2, &
-                        IZT, IZEXN, IZLV, IZLS, IZCPH                         )
-
-CALL MNH_RELEASE_FLAT ( IZR, IZSV, IZSNWC, IZSNWC_INIT, IZRSNWCS, IZRRS_OTHER, IZRSVS_OTHER, &
-                        IZRSNWCS_OTHER, IZRRS_PPM, IZRSVS_PPM, IZRSNWCS_PPM)
-
-CALL MNH_RELEASE_FLAT ( IZRUCPPM, IZRVCPPM, IZRWCPPM, IZCFLU, IZCFLV, IZCFLW, IZCFL, IZTH, &
-                        IZTKE, IZRTHS_OTHER, IZRTKES_OTHER, IZRTHS_PPM, IZRTKES_PPM        )
-
-CALL MNH_CHECK_OUT_ZT3D("ADVECTION_METSV")
+!Release all memory allocated with MNH_MEM_GET calls since last call to MNH_MEM_POSITION_PIN
+CALL MNH_MEM_RELEASE()
 #endif
 
 !$acc end data
diff --git a/src/MNH/emoist.f90 b/src/MNH/emoist.f90
index 962e7961e6766a51a50e4fb82c6dd3ff7984a909..40fe38c23e9e696c9de67640428a9bce158a0f56 100644
--- a/src/MNH/emoist.f90
+++ b/src/MNH/emoist.f90
@@ -101,7 +101,7 @@ USE MODD_CST
 USE MODD_DYN_n, ONLY : LOCEAN
 
 #ifdef MNH_OPENACC
-USE  MODE_MNH_ZWORK, ONLY: MNH_ALLOCATE_FLAT, MNH_RELEASE_FLAT
+USE MODE_MNH_ZWORK, ONLY: MNH_MEM_GET, MNH_MEM_POSITION_PIN, MNH_MEM_RELEASE
 #endif
 use mode_mppdb
 
@@ -130,9 +130,6 @@ REAL,DIMENSION(:,:,:),  INTENT(OUT):: PEMOIST ! result
 !*       0.2 declarations of local variables
 !
 REAL,DIMENSION(:,:,:), pointer,contiguous :: ZA, ZRW
-#ifdef MNH_OPENACC
-INTEGER                                   :: IZA,IZRW
-#endif
 !                ZA = coeft A, ZRW = total mixing ratio rw 
 REAL                                  :: ZDELTA  ! = Rv/Rd - 1
 INTEGER                               :: JRR     ! moist loop counter
@@ -160,8 +157,11 @@ JKU =  size( pthlm, 3 )
 allocate( za  (JIU,JJU,JKU) )
 allocate( zrw (JIU,JJU,JKU ) )
 #else
-IZA  = MNH_ALLOCATE_FLAT( za,  JIU, JJU, JKU )
-IZRW = MNH_ALLOCATE_FLAT( zrw, JIU, JJU, JKU )
+!Pin positions in the pools of MNH memory
+CALL MNH_MEM_POSITION_PIN()
+
+CALL MNH_MEM_GET( za,  JIU, JJU, JKU )
+CALL MNH_MEM_GET( zrw, JIU, JJU, JKU )
 #endif
 
 !$acc data present( za, zrw )
@@ -272,7 +272,8 @@ end if
 #ifndef MNH_OPENACC
 deallocate( za, zrw )
 #else
-CALL MNH_RELEASE_FLAT(  iza, izrw )
+!Release all memory allocated with MNH_MEM_GET calls since last call to MNH_MEM_POSITION_PIN
+CALL MNH_MEM_RELEASE()
 #endif
 
 !$acc end data
diff --git a/src/MNH/etheta.f90 b/src/MNH/etheta.f90
index 5bf6e04d4a1217908bc7c0c614237cbb731865a6..b9f0fa5d184c9d90d9999f43e360a1ef9a991666 100644
--- a/src/MNH/etheta.f90
+++ b/src/MNH/etheta.f90
@@ -104,7 +104,7 @@ USE MODD_CST
 USE MODD_DYN_n, ONLY : LOCEAN
 
 #ifdef MNH_OPENACC
-USE MODE_MNH_ZWORK, ONLY: MNH_ALLOCATE_FLAT , MNH_RELEASE_FLAT
+USE MODE_MNH_ZWORK, ONLY: MNH_MEM_GET, MNH_MEM_POSITION_PIN, MNH_MEM_RELEASE
 #endif
 use mode_mppdb
 
@@ -137,9 +137,6 @@ REAL, DIMENSION(:,:,:),  INTENT(OUT):: PETHETA ! result
 !
 REAL,DIMENSION(:,:,:), pointer , contiguous :: ZA, ZRW
 !                ZA = coeft A, ZRW = total mixing ratio rw
-#ifdef MNH_OPENACC
-INTEGER  :: IZA, IZRW
-#endif
 REAL                                  :: ZDELTA  ! = Rv/Rd - 1
 INTEGER                               :: JRR     ! moist loop counter
 !
@@ -160,8 +157,11 @@ end if
 allocate( za  ( size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ) ) )
 allocate( zrw ( size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ) ) )
 #else
-iza  = MNH_ALLOCATE_FLAT( za  , size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ) )
-izrw = MNH_ALLOCATE_FLAT( zrw , size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ) )
+!Pin positions in the pools of MNH memory
+CALL MNH_MEM_POSITION_PIN()
+
+CALL MNH_MEM_GET( za  , size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ) )
+CALL MNH_MEM_GET( zrw , size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ) )
 #endif
 
 !$acc data present( za, zrw )
@@ -251,7 +251,8 @@ end if
 #ifndef MNH_OPENACC
 deallocate (za, zrw)
 #else
-CALL MNH_RELEASE_FLAT( iza, izrw )
+!Release all memory allocated with MNH_MEM_GET calls since last call to MNH_MEM_POSITION_PIN
+CALL MNH_MEM_RELEASE()
 #endif
 
 !$acc end data
diff --git a/src/MNH/gradient_u.f90 b/src/MNH/gradient_u.f90
index 3d89a476eafcb8370dd253fb5156ce3510c5c88b..57d1f6c41c592e0b0e7d2564228ef161ccbcafcf 100644
--- a/src/MNH/gradient_u.f90
+++ b/src/MNH/gradient_u.f90
@@ -195,7 +195,7 @@ END FUNCTION GX_U_M
 USE MODI_SHUMAN_DEVICE
 USE MODD_CONF
 !
-USE MODE_MNH_ZWORK, ONLY: MNH_ALLOCATE_FLAT, MNH_RELEASE_FLAT
+USE MODE_MNH_ZWORK, ONLY: MNH_MEM_GET, MNH_MEM_POSITION_PIN, MNH_MEM_RELEASE
 !
 IMPLICIT NONE
 !
@@ -212,7 +212,6 @@ REAL, DIMENSION(:,:,:), INTENT(OUT) :: PGX_U_M_DEVICE ! result mass point
 !*       0.2   declaration of local variables
 !
 REAL, DIMENSION(:,:,:), pointer , contiguous ::  ZTMP1_DEVICE, ZTMP2_DEVICE, ZTMP3_DEVICE
-INTEGER :: IZTMP1_DEVICE, IZTMP2_DEVICE, IZTMP3_DEVICE
 !
 INTEGER  :: JIU,JJU,JKU
 INTEGER  :: JI,JJ,JK
@@ -224,9 +223,12 @@ JIU =  size(pa, 1 )
 JJU =  size(pa, 2 )
 JKU =  size(pa, 3 )
 
-iztmp1_device = MNH_ALLOCATE_FLAT( ztmp1_device, JIU, JJU, JKU )
-iztmp2_device = MNH_ALLOCATE_FLAT( ztmp2_device, JIU, JJU, JKU )
-iztmp3_device = MNH_ALLOCATE_FLAT( ztmp3_device, JIU, JJU, JKU )
+!Pin positions in the pools of MNH memory
+CALL MNH_MEM_POSITION_PIN()
+
+CALL MNH_MEM_GET( ztmp1_device, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ztmp2_device, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ztmp3_device, JIU, JJU, JKU )
 
 !$acc data present( ztmp1_device, ztmp2_device, ztmp3_device )
 
@@ -268,7 +270,8 @@ END IF
 
 !$acc end data
 
-CALL MNH_RELEASE_FLAT( iztmp1_device, iztmp2_device, iztmp3_device )
+!Release all memory allocated with MNH_MEM_GET calls since last call to MNH_MEM_POSITION_PIN
+CALL MNH_MEM_RELEASE()
 
 !$acc end data
 
@@ -385,7 +388,7 @@ END FUNCTION GY_U_UV
 USE MODI_SHUMAN_DEVICE
 USE MODD_CONF
 !
-USE MODE_MNH_ZWORK, ONLY: MNH_ALLOCATE_FLAT, MNH_RELEASE_FLAT
+USE MODE_MNH_ZWORK, ONLY: MNH_MEM_GET, MNH_MEM_POSITION_PIN, MNH_MEM_RELEASE
 !
 IMPLICIT NONE
 !
@@ -403,7 +406,6 @@ REAL, DIMENSION(:,:,:), INTENT(OUT) :: PGY_U_UV_DEVICE ! result UV point
 !*       0.2   declaration of local variables
 !
 REAL, DIMENSION(:,:,:), pointer , contiguous :: ZTMP1_DEVICE, ZTMP2_DEVICE, ZTMP3_DEVICE
-INTEGER :: IZTMP1_DEVICE, IZTMP2_DEVICE, IZTMP3_DEVICE
 !
 INTEGER  :: JIU,JJU,JKU
 INTEGER  :: JI,JJ,JK
@@ -416,9 +418,12 @@ JIU =  size(pa, 1 )
 JJU =  size(pa, 2 )
 JKU =  size(pa, 3 )
 
-iztmp1_device = MNH_ALLOCATE_FLAT( ztmp1_device, JIU, JJU, JKU )
-iztmp2_device = MNH_ALLOCATE_FLAT( ztmp2_device, JIU, JJU, JKU )
-iztmp3_device = MNH_ALLOCATE_FLAT( ztmp3_device, JIU, JJU, JKU )
+!Pin positions in the pools of MNH memory
+CALL MNH_MEM_POSITION_PIN()
+
+CALL MNH_MEM_GET( ztmp1_device, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ztmp2_device, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ztmp3_device, JIU, JJU, JKU )
 
 !$acc data present( ztmp1_device, ztmp2_device, ztmp3_device )
 
@@ -468,7 +473,8 @@ END IF
 
 !$acc end data
 
-CALL MNH_RELEASE_FLAT( iztmp1_device, iztmp2_device, iztmp3_device )
+!Release all memory allocated with MNH_MEM_GET calls since last call to MNH_MEM_POSITION_PIN
+CALL MNH_MEM_RELEASE()
 
 !$acc end data
 
@@ -568,7 +574,7 @@ END FUNCTION GZ_U_UW
 !
 !
 USE MODI_SHUMAN_DEVICE
-USE MODE_MNH_ZWORK, ONLY: MNH_ALLOCATE_FLAT, MNH_RELEASE_FLAT
+USE MODE_MNH_ZWORK, ONLY: MNH_MEM_GET, MNH_MEM_POSITION_PIN, MNH_MEM_RELEASE
 !
 IMPLICIT NONE
 !
@@ -583,7 +589,6 @@ REAL, DIMENSION(:,:,:), INTENT(OUT) :: PGZ_U_UW_DEVICE ! result UW point
 !*       0.2   declaration of local variables
 !
 REAL, DIMENSION(:,:,:), pointer , contiguous :: ZTMP1_DEVICE, ZTMP2_DEVICE
-INTEGER :: IZTMP1_DEVICE, IZTMP2_DEVICE
 !
 INTEGER  :: JIU,JJU,JKU
 !----------------------------------------------------------------------------
@@ -594,8 +599,11 @@ JIU =  size(pa, 1 )
 JJU =  size(pa, 2 )
 JKU =  size(pa, 3 )
 
-iztmp1_device = MNH_ALLOCATE_FLAT( ztmp1_device, JIU, JJU, JKU )
-iztmp2_device = MNH_ALLOCATE_FLAT( ztmp2_device, JIU, JJU, JKU )
+!Pin positions in the pools of MNH memory
+CALL MNH_MEM_POSITION_PIN()
+
+CALL MNH_MEM_GET( ztmp1_device, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ztmp2_device, JIU, JJU, JKU )
 
 !$acc data present( ztmp1_device, ztmp2_device )
 
@@ -611,7 +619,8 @@ PGZ_U_UW_DEVICE(:,:,:)= ZTMP1_DEVICE(:,:,:) / ZTMP2_DEVICE(:,:,:)
 
 !$acc end data
 
-CALL MNH_RELEASE_FLAT( iztmp1_device, iztmp2_device )
+!Release all memory allocated with MNH_MEM_GET calls since last call to MNH_MEM_POSITION_PIN
+CALL MNH_MEM_RELEASE()
 
 !$acc end data
 
diff --git a/src/MNH/gradient_v.f90 b/src/MNH/gradient_v.f90
index 33a49d5e1f99a2937ab9c669759958a13bd9d976..57ebbd0d967878f9f953a6845cc8d7667398779c 100644
--- a/src/MNH/gradient_v.f90
+++ b/src/MNH/gradient_v.f90
@@ -193,7 +193,7 @@ END FUNCTION GY_V_M
 !
 USE MODI_SHUMAN_DEVICE
 USE MODD_CONF
-USE MODE_MNH_ZWORK, ONLY: MNH_ALLOCATE_FLAT, MNH_RELEASE_FLAT
+USE MODE_MNH_ZWORK, ONLY: MNH_MEM_GET, MNH_MEM_POSITION_PIN, MNH_MEM_RELEASE
 !
 IMPLICIT NONE
 !
@@ -208,7 +208,6 @@ REAL, DIMENSION(:,:,:), INTENT(IN) :: PDZY     ! metric coefficient dzy
 REAL, DIMENSION(:,:,:), INTENT(OUT) :: PGY_V_M_DEVICE ! result mass point
 !
 REAL, DIMENSION(:,:,:), pointer , contiguous ::  ZTMP1_DEVICE, ZTMP2_DEVICE, ZTMP3_DEVICE
-INTEGER :: IZTMP1_DEVICE, IZTMP2_DEVICE, IZTMP3_DEVICE
 !
 INTEGER  :: JIU,JJU,JKU
 INTEGER  :: JI,JJ,JK
@@ -225,9 +224,12 @@ JIU =  size(pa, 1 )
 JJU =  size(pa, 2 )
 JKU =  size(pa, 3 )
 
-iztmp1_device = MNH_ALLOCATE_FLAT( ztmp1_device, JIU, JJU, JKU )
-iztmp2_device = MNH_ALLOCATE_FLAT( ztmp2_device, JIU, JJU, JKU )
-iztmp3_device = MNH_ALLOCATE_FLAT( ztmp3_device, JIU, JJU, JKU )
+!Pin positions in the pools of MNH memory
+CALL MNH_MEM_POSITION_PIN()
+
+CALL MNH_MEM_GET( ztmp1_device, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ztmp2_device, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ztmp3_device, JIU, JJU, JKU )
 
 !$acc data present( ztmp1_device, ztmp2_device, ztmp3_device )
 
@@ -270,7 +272,8 @@ END IF
 
 !$acc end data
 
-CALL MNH_RELEASE_FLAT( iztmp1_device, iztmp2_device, iztmp3_device )
+!Release all memory allocated with MNH_MEM_GET calls since last call to MNH_MEM_POSITION_PIN
+CALL MNH_MEM_RELEASE()
 
 !$acc end data
 
@@ -385,7 +388,7 @@ END FUNCTION GX_V_UV
 !
 USE MODI_SHUMAN_DEVICE
 USE MODD_CONF
-USE MODE_MNH_ZWORK, ONLY: MNH_ALLOCATE_FLAT, MNH_RELEASE_FLAT
+USE MODE_MNH_ZWORK, ONLY: MNH_MEM_GET, MNH_MEM_POSITION_PIN, MNH_MEM_RELEASE
 !
 IMPLICIT NONE
 !
@@ -402,7 +405,6 @@ REAL, DIMENSION(:,:,:), INTENT(OUT) :: PGX_V_UV_DEVICE ! result UV point
 !*       0.2   declaration of local variables
 !
 REAL, DIMENSION(:,:,:), pointer , contiguous ::  ZTMP1_DEVICE, ZTMP2_DEVICE, ZTMP3_DEVICE, ZTMP4_DEVICE
-INTEGER :: IZTMP1_DEVICE, IZTMP2_DEVICE, IZTMP3_DEVICE, IZTMP4_DEVICE
 !
 INTEGER  :: JIU,JJU,JKU
 INTEGER  :: JI,JJ,JK
@@ -415,10 +417,13 @@ JIU =  size(pa, 1 )
 JJU =  size(pa, 2 )
 JKU =  size(pa, 3 )
 
-iztmp1_device = MNH_ALLOCATE_FLAT( ztmp1_device, JIU, JJU, JKU )
-iztmp2_device = MNH_ALLOCATE_FLAT( ztmp2_device, JIU, JJU, JKU )
-iztmp3_device = MNH_ALLOCATE_FLAT( ztmp3_device, JIU, JJU, JKU )
-iztmp4_device = MNH_ALLOCATE_FLAT( ztmp4_device, JIU, JJU, JKU )
+!Pin positions in the pools of MNH memory
+CALL MNH_MEM_POSITION_PIN()
+
+CALL MNH_MEM_GET( ztmp1_device, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ztmp2_device, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ztmp3_device, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ztmp4_device, JIU, JJU, JKU )
 
 !$acc data present( ztmp1_device, ztmp2_device, ztmp3_device, ztmp4_device )
 
@@ -468,7 +473,8 @@ END IF
 
 !$acc end data
 
-CALL MNH_RELEASE_FLAT( iztmp1_device, iztmp2_device, iztmp3_device, iztmp4_device )
+!Release all memory allocated with MNH_MEM_GET calls since last call to MNH_MEM_POSITION_PIN
+CALL MNH_MEM_RELEASE()
 
 !$acc end data
 
@@ -570,7 +576,7 @@ END FUNCTION GZ_V_VW
 !
 USE MODI_SHUMAN_DEVICE
 USE MODI_SHUMAN
-USE MODE_MNH_ZWORK, ONLY: MNH_ALLOCATE_FLAT, MNH_RELEASE_FLAT
+USE MODE_MNH_ZWORK, ONLY: MNH_MEM_GET, MNH_MEM_POSITION_PIN, MNH_MEM_RELEASE
 !
 IMPLICIT NONE
 !
@@ -585,7 +591,6 @@ REAL, DIMENSION(:,:,:), INTENT(OUT) :: PGZ_V_VW_DEVICE ! result VW point
 !*       0.2   declaration of local variables
 !
 REAL, DIMENSION(:,:,:), pointer , contiguous :: ZTMP1_DEVICE, ZTMP2_DEVICE
-INTEGER :: IZTMP1_DEVICE, IZTMP2_DEVICE
 !
 INTEGER  :: JIU,JJU,JKU
 !----------------------------------------------------------------------------
@@ -596,8 +601,11 @@ JIU =  size(pa, 1 )
 JJU =  size(pa, 2 )
 JKU =  size(pa, 3 )
 
-iztmp1_device = MNH_ALLOCATE_FLAT( ztmp1_device, JIU, JJU, JKU )
-iztmp2_device = MNH_ALLOCATE_FLAT( ztmp2_device, JIU, JJU, JKU )
+!Pin positions in the pools of MNH memory
+CALL MNH_MEM_POSITION_PIN()
+
+CALL MNH_MEM_GET( ztmp1_device, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ztmp2_device, JIU, JJU, JKU )
 
 !$acc data present( ztmp1_device, ztmp2_device )
 
@@ -613,7 +621,8 @@ PGZ_V_VW_DEVICE(:,:,:)= ZTMP1_DEVICE(:,:,:) / ZTMP2_DEVICE(:,:,:)
 
 !$acc end data
 
-CALL MNH_RELEASE_FLAT( iztmp1_device, iztmp2_device )
+!Release all memory allocated with MNH_MEM_GET calls since last call to MNH_MEM_POSITION_PIN
+CALL MNH_MEM_RELEASE()
 
 !$acc end data
 
diff --git a/src/MNH/gradient_w.f90 b/src/MNH/gradient_w.f90
index 7053c663e29b12cefe5af5179ba3417f7f67b941..aa095ecb9129e4319a27ccb34e82aaa2cd7897ea 100644
--- a/src/MNH/gradient_w.f90
+++ b/src/MNH/gradient_w.f90
@@ -174,7 +174,7 @@ END FUNCTION GZ_W_M
 !
 USE MODI_SHUMAN_DEVICE
 USE MODI_SHUMAN
-USE MODE_MNH_ZWORK, ONLY: MNH_ALLOCATE_FLAT, MNH_RELEASE_FLAT
+USE MODE_MNH_ZWORK, ONLY: MNH_MEM_GET, MNH_MEM_POSITION_PIN, MNH_MEM_RELEASE
 !
 IMPLICIT NONE
 !
@@ -189,7 +189,6 @@ REAL, DIMENSION(:,:,:),  INTENT(OUT) :: PGZ_W_M_DEVICE ! result mass point
 !*       0.2   declaration of local variables
 !
 REAL, DIMENSION(:,:,:), pointer , contiguous ::  ZTMP1_DEVICE, ZTMP2_DEVICE
-INTEGER :: IZTMP1_DEVICE, IZTMP2_DEVICE
 !
 INTEGER  :: JIU,JJU,JKU
 !----------------------------------------------------------------------------
@@ -200,8 +199,11 @@ JIU =  size(pa, 1 )
 JJU =  size(pa, 2 )
 JKU =  size(pa, 3 )
 
-iztmp1_device = MNH_ALLOCATE_FLAT( ztmp1_device, JIU, JJU, JKU )
-iztmp2_device = MNH_ALLOCATE_FLAT( ztmp2_device, JIU, JJU, JKU )
+!Pin positions in the pools of MNH memory
+CALL MNH_MEM_POSITION_PIN()
+
+CALL MNH_MEM_GET( ztmp1_device, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ztmp2_device, JIU, JJU, JKU )
 
 !$acc data present( ztmp1_device, ztmp2_device )
 
@@ -217,7 +219,8 @@ PGZ_W_M_DEVICE(:,:,:)= ZTMP1_DEVICE(:,:,:)/ZTMP2_DEVICE(:,:,:)
 
 !$acc end data
 
-CALL MNH_RELEASE_FLAT( iztmp1_device, iztmp2_device )
+!Release all memory allocated with MNH_MEM_GET calls since last call to MNH_MEM_POSITION_PIN
+CALL MNH_MEM_RELEASE()
 
 !$acc end data
 
@@ -323,7 +326,7 @@ END FUNCTION GX_W_UW
 !
 USE MODI_SHUMAN_DEVICE
 USE MODD_CONF
-USE MODE_MNH_ZWORK, ONLY: MNH_ALLOCATE_FLAT, MNH_RELEASE_FLAT
+USE MODE_MNH_ZWORK, ONLY: MNH_MEM_GET, MNH_MEM_POSITION_PIN, MNH_MEM_RELEASE
 !
 IMPLICIT NONE
 !
@@ -340,7 +343,6 @@ REAL, DIMENSION(:,:,:),  INTENT(OUT) :: PGX_W_UW_DEVICE ! result UW point
 !*       0.2   declaration of local variables
 !
 REAL, DIMENSION(:,:,:), pointer , contiguous ::  ZTMP1_DEVICE, ZTMP2_DEVICE, ZTMP3_DEVICE, ZTMP4_DEVICE, ZTMP5_DEVICE
-INTEGER :: IZTMP1_DEVICE, IZTMP2_DEVICE, IZTMP3_DEVICE,IZTMP4_DEVICE,IZTMP5_DEVICE
 !
 INTEGER  :: JIU,JJU,JKU
 !----------------------------------------------------------------------------
@@ -351,11 +353,14 @@ JIU =  size(pa, 1 )
 JJU =  size(pa, 2 )
 JKU =  size(pa, 3 )
 
-iztmp1_device = MNH_ALLOCATE_FLAT( ztmp1_device, JIU, JJU, JKU )
-iztmp2_device = MNH_ALLOCATE_FLAT( ztmp2_device, JIU, JJU, JKU )
-iztmp3_device = MNH_ALLOCATE_FLAT( ztmp3_device, JIU, JJU, JKU )
-iztmp4_device = MNH_ALLOCATE_FLAT( ztmp4_device, JIU, JJU, JKU )
-iztmp5_device = MNH_ALLOCATE_FLAT( ztmp5_device, JIU, JJU, JKU )
+!Pin positions in the pools of MNH memory
+CALL MNH_MEM_POSITION_PIN()
+
+CALL MNH_MEM_GET( ztmp1_device, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ztmp2_device, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ztmp3_device, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ztmp4_device, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ztmp5_device, JIU, JJU, JKU )
 
 !$acc data present( ztmp1_device, ztmp2_device, ztmp3_device, ztmp4_device, ztmp5_device )
 
@@ -388,7 +393,8 @@ END IF
 
 !$acc end data
 
-CALL MNH_RELEASE_FLAT( iztmp1_device, iztmp2_device, iztmp3_device, iztmp4_device, iztmp5_device )
+!Release all memory allocated with MNH_MEM_GET calls since last call to MNH_MEM_POSITION_PIN
+CALL MNH_MEM_RELEASE()
 
 !$acc end data
 
@@ -494,7 +500,7 @@ END FUNCTION GY_W_VW
 !
 USE MODI_SHUMAN_DEVICE
 USE MODD_CONF
-USE MODE_MNH_ZWORK, ONLY: MNH_ALLOCATE_FLAT, MNH_RELEASE_FLAT
+USE MODE_MNH_ZWORK, ONLY: MNH_MEM_GET, MNH_MEM_POSITION_PIN, MNH_MEM_RELEASE
 !
 IMPLICIT NONE
 !
@@ -511,7 +517,6 @@ REAL, DIMENSION(:,:,:),  INTENT(OUT) :: PGY_W_VW_DEVICE ! result VW point
 !*       0.2   declaration of local variables
 !
 REAL, DIMENSION(:,:,:), pointer , contiguous ::  ZTMP1_DEVICE, ZTMP2_DEVICE, ZTMP3_DEVICE, ZTMP4_DEVICE, ZTMP5_DEVICE
-INTEGER :: IZTMP1_DEVICE, IZTMP2_DEVICE, IZTMP3_DEVICE,IZTMP4_DEVICE,IZTMP5_DEVICE
 !
 INTEGER  :: JIU,JJU,JKU
 !
@@ -523,11 +528,14 @@ JIU =  size(pa, 1 )
 JJU =  size(pa, 2 )
 JKU =  size(pa, 3 )
 
-iztmp1_device = MNH_ALLOCATE_FLAT( ztmp1_device, JIU, JJU, JKU )
-iztmp2_device = MNH_ALLOCATE_FLAT( ztmp2_device, JIU, JJU, JKU )
-iztmp3_device = MNH_ALLOCATE_FLAT( ztmp3_device, JIU, JJU, JKU )
-iztmp4_device = MNH_ALLOCATE_FLAT( ztmp4_device, JIU, JJU, JKU )
-iztmp5_device = MNH_ALLOCATE_FLAT( ztmp5_device, JIU, JJU, JKU )
+!Pin positions in the pools of MNH memory
+CALL MNH_MEM_POSITION_PIN()
+
+CALL MNH_MEM_GET( ztmp1_device, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ztmp2_device, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ztmp3_device, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ztmp4_device, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ztmp5_device, JIU, JJU, JKU )
 
 !$acc data present( ztmp1_device, ztmp2_device, ztmp3_device, ztmp4_device, ztmp5_device )
 
@@ -560,7 +568,8 @@ END IF
 
 !$acc end data
 
-CALL MNH_RELEASE_FLAT( iztmp1_device, iztmp2_device, iztmp3_device, iztmp4_device, iztmp5_device )
+!Release all memory allocated with MNH_MEM_GET calls since last call to MNH_MEM_POSITION_PIN
+CALL MNH_MEM_RELEASE()
 
 !$acc end data
 
diff --git a/src/MNH/ice4_fast_rg.f90 b/src/MNH/ice4_fast_rg.f90
index 039cd33f8c5b44c1b03e14682e7c074de2126408..4847d925cd0e5ef53211ee64bbe9f6522089b5a0 100644
--- a/src/MNH/ice4_fast_rg.f90
+++ b/src/MNH/ice4_fast_rg.f90
@@ -108,7 +108,7 @@ USE MODD_RAIN_ICE_PARAM, ONLY: NDRYLBDAG,NDRYLBDAR,NDRYLBDAS,X0DEPG,X1DEPG,XCOLE
                                XLBRDRYG2,XLBRDRYG3,XLBSDRYG1,XLBSDRYG2,XLBSDRYG3,XRCFRI
 
 #ifdef MNH_OPENACC
-USE MODE_MNH_ZWORK,      ONLY: MNH_ALLOCATE_FLAT, MNH_RELEASE_FLAT, MNH_REL_GT1DFLAT, MNH_REL_IT1DFLAT
+USE MODE_MNH_ZWORK,      ONLY: MNH_MEM_GET, MNH_MEM_POSITION_PIN, MNH_MEM_RELEASE
 #endif
 USE MODE_MPPDB
 
@@ -185,13 +185,6 @@ REAL,    DIMENSION(:), POINTER, CONTIGUOUS :: ZVEC1, ZVEC2, ZVEC3
 REAL,    DIMENSION(:), POINTER, CONTIGUOUS :: ZZW,         &
                                               ZRDRYG_INIT, & !Initial dry growth rate of the graupeln
                                               ZRWETG_INIT    !Initial wet growth rate of the graupeln
-#ifdef MNH_OPENACC
-INTEGER                                    :: II1, IIVEC1, IIVEC2
-INTEGER                                    :: IDXGDRY
-INTEGER                                    :: IZDRY, IZDRYG, IZMASK
-INTEGER                                    :: IZVEC1, IZVEC2, IZVEC3
-INTEGER                                    :: IZZW, IZRDRYG_INIT, IZRWETG_INIT
-#endif
 !
 !-------------------------------------------------------------------------------
 !
@@ -257,21 +250,24 @@ allocate( zzw        ( isize ) )
 allocate( zrdryg_init( isize ) )
 allocate( zrwetg_init( isize ) )
 #else
-II1    = MNH_ALLOCATE_FLAT( I1,    ISIZE )
-IIVEC1 = MNH_ALLOCATE_FLAT( IVEC1, ISIZE )
-IIVEC2 = MNH_ALLOCATE_FLAT( IVEC2, ISIZE )
-
-IDXGDRY      = MNH_ALLOCATE_FLAT( gdry,        isize )
-
-IZDRY        = MNH_ALLOCATE_FLAT( zdry,        isize )
-IZDRYG       = MNH_ALLOCATE_FLAT( zdryg,       isize )
-IZMASK       = MNH_ALLOCATE_FLAT( zmask,       isize )
-IZVEC1       = MNH_ALLOCATE_FLAT( zvec1,       isize )
-IZVEC2       = MNH_ALLOCATE_FLAT( zvec2,       isize )
-IZVEC3       = MNH_ALLOCATE_FLAT( zvec3,       isize )
-IZZW         = MNH_ALLOCATE_FLAT( zzw,         isize )
-IZRDRYG_INIT = MNH_ALLOCATE_FLAT( zrdryg_init, isize )
-IZRWETG_INIT = MNH_ALLOCATE_FLAT( zrwetg_init, isize )
+!Pin positions in the pools of MNH memory
+CALL MNH_MEM_POSITION_PIN()
+
+CALL MNH_MEM_GET( I1,    ISIZE )
+CALL MNH_MEM_GET( IVEC1, ISIZE )
+CALL MNH_MEM_GET( IVEC2, ISIZE )
+
+CALL MNH_MEM_GET( gdry,        isize )
+
+CALL MNH_MEM_GET( zdry,        isize )
+CALL MNH_MEM_GET( zdryg,       isize )
+CALL MNH_MEM_GET( zmask,       isize )
+CALL MNH_MEM_GET( zvec1,       isize )
+CALL MNH_MEM_GET( zvec2,       isize )
+CALL MNH_MEM_GET( zvec3,       isize )
+CALL MNH_MEM_GET( zzw,         isize )
+CALL MNH_MEM_GET( zrdryg_init, isize )
+CALL MNH_MEM_GET( zrwetg_init, isize )
 #endif
 
 !$acc data create ( IGDRY ) &
@@ -855,21 +851,8 @@ deallocate( ivec2       )
 deallocate( ivec1       )
 deallocate( i1          )
 #else
-CALL MNH_RELEASE_FLAT( IZRWETG_INIT )
-CALL MNH_RELEASE_FLAT( IZRDRYG_INIT )
-CALL MNH_RELEASE_FLAT( IZZW   )
-CALL MNH_RELEASE_FLAT( IZVEC3 )
-CALL MNH_RELEASE_FLAT( IZVEC2 )
-CALL MNH_RELEASE_FLAT( IZVEC1 )
-CALL MNH_RELEASE_FLAT( IZMASK )
-CALL MNH_RELEASE_FLAT( IZDRYG )
-CALL MNH_RELEASE_FLAT( IZDRY  )
-
-CALL MNH_REL_GT1DFLAT( IDXGDRY )
-
-CALL MNH_REL_IT1DFLAT( IIVEC2 )
-CALL MNH_REL_IT1DFLAT( IIVEC1 )
-CALL MNH_REL_IT1DFLAT( II1    )
+!Release all memory allocated with MNH_MEM_GET calls since last call to MNH_MEM_POSITION_PIN
+CALL MNH_MEM_RELEASE()
 #endif
 
 !$acc end data
diff --git a/src/MNH/ice4_fast_rs.f90 b/src/MNH/ice4_fast_rs.f90
index 1304368e4a7a914d9b8d4cbc30eaaac08ec781bd..bba6ba67b3c4aeca38ce8ff1935525186b2e7b34 100644
--- a/src/MNH/ice4_fast_rs.f90
+++ b/src/MNH/ice4_fast_rs.f90
@@ -94,7 +94,7 @@ USE MODD_RAIN_ICE_PARAM, ONLY: NACCLBDAR,NACCLBDAS,NGAMINC,X0DEPS,X1DEPS,XACCINT
                                XRIMINTP1,XRIMINTP2,XSRIMCG,XSRIMCG2,XSRIMCG3
 
 #ifdef MNH_OPENACC
-USE MODE_MNH_ZWORK,      ONLY: MNH_ALLOCATE_FLAT, MNH_RELEASE_FLAT, MNH_REL_GT1DFLAT, MNH_REL_IT1DFLAT
+USE MODE_MNH_ZWORK,      ONLY: MNH_MEM_GET, MNH_MEM_POSITION_PIN, MNH_MEM_RELEASE
 #endif
 USE MODE_MPPDB
 
@@ -153,13 +153,6 @@ LOGICAL, DIMENSION(:), POINTER, CONTIGUOUS :: GRIM, GACC
 REAL,    DIMENSION(:), POINTER, CONTIGUOUS :: ZRIM, ZACC, ZMASK
 REAL,    DIMENSION(:), POINTER, CONTIGUOUS :: ZVEC1, ZVEC2, ZVEC3
 REAL,    DIMENSION(:), POINTER, CONTIGUOUS :: ZZW, ZZW2, ZZW6, ZFREEZ_RATE
-#ifdef MNH_OPENACC
-INTEGER                                    :: II1, IIVEC1, IIVEC2
-INTEGER                                    :: IDXGRIM, IDXGACC
-INTEGER                                    :: IZRIM, IZACC, IZMASK
-INTEGER                                    :: IZVEC1, IZVEC2, IZVEC3
-INTEGER                                    :: IZZW, IZZW2, IZZW6, IZFREEZ_RATE
-#endif
 
 !$acc data present( PCOMPUTE, PRHODREF, PLVFACT, PLSFACT, PPRES, PDV, PKA, PCJ,                        &
 !$acc&              PLBDAR, PLBDAS, PT, PRVT, PRCT, PRRT, PRST, PRIAGGS, PRCRIMSS, PRCRIMSG, PRSRIMCG, &
@@ -218,23 +211,26 @@ allocate( zzw2        ( isize ) )
 allocate( zzw6        ( isize ) )
 allocate( zfreez_rate ( isize ) )
 #else
-II1    = MNH_ALLOCATE_FLAT( I1,    ISIZE )
-IIVEC1 = MNH_ALLOCATE_FLAT( IVEC1, ISIZE )
-IIVEC2 = MNH_ALLOCATE_FLAT( IVEC2, ISIZE )
+!Pin positions in the pools of MNH memory
+CALL MNH_MEM_POSITION_PIN()
+
+CALL MNH_MEM_GET( I1,    ISIZE )
+CALL MNH_MEM_GET( IVEC1, ISIZE )
+CALL MNH_MEM_GET( IVEC2, ISIZE )
 
-IDXGRIM = MNH_ALLOCATE_FLAT( grim, ISIZE )
-IDXGACC = MNH_ALLOCATE_FLAT( gacc, ISIZE )
+CALL MNH_MEM_GET( grim, ISIZE )
+CALL MNH_MEM_GET( gacc, ISIZE )
 
-IZRIM        = MNH_ALLOCATE_FLAT( zrim,        ISIZE )
-IZACC        = MNH_ALLOCATE_FLAT( zacc,        ISIZE )
-IZMASK       = MNH_ALLOCATE_FLAT( zmask,       ISIZE )
-IZVEC1       = MNH_ALLOCATE_FLAT( zvec1,       ISIZE )
-IZVEC2       = MNH_ALLOCATE_FLAT( zvec2,       ISIZE )
-IZVEC3       = MNH_ALLOCATE_FLAT( zvec3,       ISIZE )
-IZZW         = MNH_ALLOCATE_FLAT( zzw,         ISIZE )
-IZZW2        = MNH_ALLOCATE_FLAT( zzw2,        ISIZE )
-IZZW6        = MNH_ALLOCATE_FLAT( zzw6,        ISIZE )
-IZFREEZ_RATE = MNH_ALLOCATE_FLAT( zfreez_rate, ISIZE )
+CALL MNH_MEM_GET( zrim,        ISIZE )
+CALL MNH_MEM_GET( zacc,        ISIZE )
+CALL MNH_MEM_GET( zmask,       ISIZE )
+CALL MNH_MEM_GET( zvec1,       ISIZE )
+CALL MNH_MEM_GET( zvec2,       ISIZE )
+CALL MNH_MEM_GET( zvec3,       ISIZE )
+CALL MNH_MEM_GET( zzw,         ISIZE )
+CALL MNH_MEM_GET( zzw2,        ISIZE )
+CALL MNH_MEM_GET( zzw6,        ISIZE )
+CALL MNH_MEM_GET( zfreez_rate, ISIZE )
 #endif
 !
 !$acc data present( I1, IVEC1, IVEC2, GRIM, GACC, ZRIM, ZACC, ZMASK, ZVEC1, ZVEC2, ZVEC3, ZZW, ZZW2, ZZW6, ZFREEZ_RATE ) &
@@ -769,23 +765,8 @@ deallocate( ivec2       )
 deallocate( ivec1       )
 deallocate( i1          )
 #else
-CALL MNH_RELEASE_FLAT( IZFREEZ_RATE )
-CALL MNH_RELEASE_FLAT( IZZW6        )
-CALL MNH_RELEASE_FLAT( IZZW2        )
-CALL MNH_RELEASE_FLAT( IZZW         )
-CALL MNH_RELEASE_FLAT( IZVEC3       )
-CALL MNH_RELEASE_FLAT( IZVEC2       )
-CALL MNH_RELEASE_FLAT( IZVEC1       )
-CALL MNH_RELEASE_FLAT( IZMASK       )
-CALL MNH_RELEASE_FLAT( IZACC        )
-CALL MNH_RELEASE_FLAT( IZRIM        )
-
-CALL MNH_REL_GT1DFLAT( IDXGACC )
-CALL MNH_REL_GT1DFLAT( IDXGRIM )
-
-CALL MNH_REL_IT1DFLAT( IIVEC2 )
-CALL MNH_REL_IT1DFLAT( IIVEC1 )
-CALL MNH_REL_IT1DFLAT( II1    )
+!Release all memory allocated with MNH_MEM_GET calls since last call to MNH_MEM_POSITION_PIN
+CALL MNH_MEM_RELEASE()
 #endif
 
 !$acc end data
diff --git a/src/MNH/ice4_sedimentation_split.f90 b/src/MNH/ice4_sedimentation_split.f90
index d500c1a0c6b58759b3d54040136f0bb219674ad4..9a1d3049ef80600c67454f0875ff759adadcf902 100644
--- a/src/MNH/ice4_sedimentation_split.f90
+++ b/src/MNH/ice4_sedimentation_split.f90
@@ -403,7 +403,7 @@ USE MODD_RAIN_ICE_DESCR, ONLY: XCC,XCEXVT,XDC,XLBEXC,XRTMIN
 USE MODD_RAIN_ICE_PARAM, ONLY: XEXCSEDI,XEXSEDG,XEXSEDH,XEXSEDR,XEXSEDS,XFSEDG,XFSEDH,XFSEDI,XFSEDR,XFSEDS
 
 #ifdef MNH_OPENACC
-USE MODE_MNH_ZWORK,      ONLY: MNH_ALLOCATE_FLAT, MNH_RELEASE_FLAT, MNH_REL_IT1DFLAT
+USE MODE_MNH_ZWORK,      ONLY: MNH_MEM_GET, MNH_MEM_POSITION_PIN, MNH_MEM_RELEASE
 
 #endif
 use mode_mppdb
@@ -438,10 +438,6 @@ REAL, DIMENSION(:,:,:,:),     INTENT(INOUT), OPTIONAL :: PFPR    ! upper-air pre
 character(len=10)                              :: yspe ! String for error message
 INTEGER                                        :: IDX, ISEDIM
 INTEGER                                        :: JI, JJ, JK, JL
-#ifdef MNH_OPENACC
-INTEGER                                        :: II1, II2, II3
-INTEGER                                        :: IZMRCHANGE, IZMAX_TSTEP, IZRSMIN, IZREMAINT, IZWSED
-#endif
 INTEGER, DIMENSION(:),     POINTER, CONTIGUOUS :: I1, I2, I3 ! Used to replace the COUNT
 LOGICAL                                        :: GPRESENT_PFPR
 REAL                                           :: ZINVTSTEP
@@ -489,18 +485,21 @@ allocate( zremaint(size( prhodref, 1 ), size( prhodref, 2 ) ) )
 
 allocate( zwsed(size( prhodref, 1 ), size( prhodref, 2 ), 0 : size( prhodref, 3 ) + 1 ) )
 #else
-II1 = MNH_ALLOCATE_FLAT( i1, kit * kjt * kkt )
-II2 = MNH_ALLOCATE_FLAT( i2, kit * kjt * kkt )
-II3 = MNH_ALLOCATE_FLAT( i3, kit * kjt * kkt )
+!Pin positions in the pools of MNH memory
+CALL MNH_MEM_POSITION_PIN()
+
+CALL MNH_MEM_GET( i1, kit * kjt * kkt )
+CALL MNH_MEM_GET( i2, kit * kjt * kkt )
+CALL MNH_MEM_GET( i3, kit * kjt * kkt )
 
-IZMRCHANGE  = MNH_ALLOCATE_FLAT( zmrchange,  kit, kjt )
-IZMAX_TSTEP = MNH_ALLOCATE_FLAT( zmax_tstep, kit, kjt )
+CALL MNH_MEM_GET( zmrchange,  kit, kjt )
+CALL MNH_MEM_GET( zmax_tstep, kit, kjt )
 
-IZRSMIN = MNH_ALLOCATE_FLAT( zrsmin, Size( xrtmin ) )
+CALL MNH_MEM_GET( zrsmin, Size( xrtmin ) )
 
-IZREMAINT = MNH_ALLOCATE_FLAT( zremaint, Size( prhodref, 1 ), Size( prhodref, 2 ) )
+CALL MNH_MEM_GET( zremaint, Size( prhodref, 1 ), Size( prhodref, 2 ) )
 
-IZWSED = MNH_ALLOCATE_FLAT( zwsed, 1, Size( prhodref, 1 ), 1, Size( prhodref, 2 ), 0, Size( prhodref, 3 ) + 1 )
+CALL MNH_MEM_GET( zwsed, 1, Size( prhodref, 1 ), 1, Size( prhodref, 2 ), 0, Size( prhodref, 3 ) + 1 )
 #endif
 
 !$acc data present( i1, i2, i3, zmrchange, zmax_tstep, zrsmin, zremaint, zwsed )
@@ -722,10 +721,8 @@ deallocate( i3 )
 deallocate( i2 )
 deallocate( i1 )
 #else
-CALL MNH_REL_IT1DFLAT( ii3 )
-CALL MNH_REL_IT1DFLAT( ii2 )
-CALL MNH_REL_IT1DFLAT( ii1 )
-CALL MNH_RELEASE_FLAT( IZMRCHANGE, IZMAX_TSTEP, IZRSMIN, IZREMAINT, IZWSED )
+!Release all memory allocated with MNH_MEM_GET calls since last call to MNH_MEM_POSITION_PIN
+CALL MNH_MEM_RELEASE()
 #endif
 
 !$acc end data
diff --git a/src/MNH/ice4_tendencies.f90 b/src/MNH/ice4_tendencies.f90
index 6e6d056ec65125636a0b60332fc09a295d2baaad..ce8006f95aab69e78cdaf143b3a34e4261cea000 100644
--- a/src/MNH/ice4_tendencies.f90
+++ b/src/MNH/ice4_tendencies.f90
@@ -186,7 +186,7 @@ USE MODD_RAIN_ICE_DESCR, ONLY: XLBDAS_MAX,XLBEXG,XLBEXH,XLBEXR,XLBEXS,XLBG,XLBH,
 USE MODD_RAIN_ICE_PARAM, ONLY: XSCFAC
 
 #ifdef MNH_OPENACC
-USE MODE_MNH_ZWORK,      ONLY: MNH_ALLOCATE_FLAT, MNH_RELEASE_FLAT
+USE MODE_MNH_ZWORK,      ONLY: MNH_MEM_GET, MNH_MEM_POSITION_PIN, MNH_MEM_RELEASE
 #endif
 
 USE MODI_ICE4_COMPUTE_PDF
@@ -333,17 +333,6 @@ REAL,    DIMENSION(:), POINTER, CONTIGUOUS :: ZRVT, ZRCT, ZRRT, ZRIT, ZRST, ZRGT
                                     & ZLBDAR, ZLBDAS, ZLBDAG, ZLBDAH, ZLBDAR_RF, &
                                     & ZRGSI, ZRGSI_MR
 REAL, DIMENSION(:,:,:), POINTER, CONTIGUOUS :: ZRRT3D, ZRST3D, ZRGT3D, ZRHT3D
-#ifdef MNH_OPENACC
-INTEGER                             :: IZWETG
-INTEGER                             :: IZRVT, IZRCT, IZRRT, IZRIT, IZRST, IZRGT,       &
-                                       IZT, IZTHT, IZRHT,                              &
-                                       IZZW,                                           &
-                                       IZKA, IZDV, IZAI, IZCJ,                         &
-                                       IZRF,                                           &
-                                       IZLBDAR, IZLBDAS, IZLBDAG, IZLBDAH, IZLBDAR_RF, &
-                                       IZRGSI, IZRGSI_MR
-INTEGER                             :: IZRRT3D, IZRST3D, IZRGT3D, IZRHT3D
-#endif
 !
 !$acc data present(PCOMPUTE,PEXN,PRHODREF,PLVFACT,PLSFACT,K1,K2,K3,PPRES,PCF,PCIT,PT,PTHT,                             &
 !$acc&                PRVT,PRCT,PRRT,PRIT,PRST,PRGT,PRHT,PSIGMA_RC,PRVHENI_MR,PRRHONG_MR,PRIMLTC_MR,                   &
@@ -433,35 +422,39 @@ allocate( zrst3d(kit, kjt, kkt ) )
 allocate( zrgt3d(kit, kjt, kkt ) )
 allocate( zrht3d(kit, kjt, kkt ) )
 #else
+!Pin positions in the pools of MNH memory
+CALL MNH_MEM_POSITION_PIN()
+
 allocate( gldcompute(isize ) )
-IZWETG = MNH_ALLOCATE_FLAT( zwetg, isize )
-IZRVT = MNH_ALLOCATE_FLAT( zrvt, isize )
-IZRCT = MNH_ALLOCATE_FLAT( zrct, isize )
-IZRRT = MNH_ALLOCATE_FLAT( zrrt, isize )
-IZRIT = MNH_ALLOCATE_FLAT( zrit, isize )
-IZRST = MNH_ALLOCATE_FLAT( zrst, isize )
-IZRGT = MNH_ALLOCATE_FLAT( zrgt, isize )
-IZT   = MNH_ALLOCATE_FLAT( zt,   isize )
-IZTHT = MNH_ALLOCATE_FLAT( ztht, isize )
-IZRHT = MNH_ALLOCATE_FLAT( zrht, isize )
-IZZW = MNH_ALLOCATE_FLAT( zzw, isize )
-IZKA = MNH_ALLOCATE_FLAT( zka, isize )
-IZDV = MNH_ALLOCATE_FLAT( zdv, isize )
-IZAI = MNH_ALLOCATE_FLAT( zai, isize )
-IZCJ = MNH_ALLOCATE_FLAT( zcj, isize )
-IZRF = MNH_ALLOCATE_FLAT( zrf, isize )
-IZLBDAR = MNH_ALLOCATE_FLAT( zlbdar, isize )
-IZLBDAS = MNH_ALLOCATE_FLAT( zlbdas, isize )
-IZLBDAG = MNH_ALLOCATE_FLAT( zlbdag, isize )
-IZLBDAH = MNH_ALLOCATE_FLAT( zlbdah, isize )
-IZLBDAR_RF = MNH_ALLOCATE_FLAT( zlbdar_rf, isize )
-IZRGSI     = MNH_ALLOCATE_FLAT( zrgsi,     isize )
-IZRGSI_MR  = MNH_ALLOCATE_FLAT( zrgsi_mr,  isize )
 
-IZRRT3D = MNH_ALLOCATE_FLAT( zrrt3d, kit, kjt, kkt )
-IZRST3D = MNH_ALLOCATE_FLAT( zrst3d, kit, kjt, kkt )
-IZRGT3D = MNH_ALLOCATE_FLAT( zrgt3d, kit, kjt, kkt )
-IZRHT3D = MNH_ALLOCATE_FLAT( zrht3d, kit, kjt, kkt )
+CALL MNH_MEM_GET( zwetg, isize )
+CALL MNH_MEM_GET( zrvt, isize )
+CALL MNH_MEM_GET( zrct, isize )
+CALL MNH_MEM_GET( zrrt, isize )
+CALL MNH_MEM_GET( zrit, isize )
+CALL MNH_MEM_GET( zrst, isize )
+CALL MNH_MEM_GET( zrgt, isize )
+CALL MNH_MEM_GET( zt,   isize )
+CALL MNH_MEM_GET( ztht, isize )
+CALL MNH_MEM_GET( zrht, isize )
+CALL MNH_MEM_GET( zzw, isize )
+CALL MNH_MEM_GET( zka, isize )
+CALL MNH_MEM_GET( zdv, isize )
+CALL MNH_MEM_GET( zai, isize )
+CALL MNH_MEM_GET( zcj, isize )
+CALL MNH_MEM_GET( zrf, isize )
+CALL MNH_MEM_GET( zlbdar, isize )
+CALL MNH_MEM_GET( zlbdas, isize )
+CALL MNH_MEM_GET( zlbdag, isize )
+CALL MNH_MEM_GET( zlbdah, isize )
+CALL MNH_MEM_GET( zlbdar_rf, isize )
+CALL MNH_MEM_GET( zrgsi,     isize )
+CALL MNH_MEM_GET( zrgsi_mr,  isize )
+
+CALL MNH_MEM_GET( zrrt3d, kit, kjt, kkt )
+CALL MNH_MEM_GET( zrst3d, kit, kjt, kkt )
+CALL MNH_MEM_GET( zrgt3d, kit, kjt, kkt )
+CALL MNH_MEM_GET( zrht3d, kit, kjt, kkt )
 #endif
 
 !$acc data create( GLDCOMPUTE )  &
@@ -1011,30 +1004,9 @@ deallocate( zrvt     )
 deallocate( zwetg    )
 deallocate( gldcompute )
 #else
-CALL MNH_RELEASE_FLAT( IZRRT3D, IZRST3D, IZRGT3D, IZRHT3D )
-CALL MNH_RELEASE_FLAT( IZRGSI_MR )
-CALL MNH_RELEASE_FLAT( IZRGSI )
-CALL MNH_RELEASE_FLAT( IZLBDAR_RF )
-CALL MNH_RELEASE_FLAT( IZLBDAH )
-CALL MNH_RELEASE_FLAT( IZLBDAG )
-CALL MNH_RELEASE_FLAT( IZLBDAS )
-CALL MNH_RELEASE_FLAT( IZLBDAR )
-CALL MNH_RELEASE_FLAT( IZRF )
-CALL MNH_RELEASE_FLAT( IZCJ )
-CALL MNH_RELEASE_FLAT( IZAI )
-CALL MNH_RELEASE_FLAT( IZDV )
-CALL MNH_RELEASE_FLAT( IZKA )
-CALL MNH_RELEASE_FLAT( IZZW )
-CALL MNH_RELEASE_FLAT( IZRHT )
-CALL MNH_RELEASE_FLAT( IZTHT )
-CALL MNH_RELEASE_FLAT( IZT )
-CALL MNH_RELEASE_FLAT( IZRGT )
-CALL MNH_RELEASE_FLAT( IZRST )
-CALL MNH_RELEASE_FLAT( IZRIT )
-CALL MNH_RELEASE_FLAT( IZRRT )
-CALL MNH_RELEASE_FLAT( IZRCT )
-CALL MNH_RELEASE_FLAT( IZRVT )
-CALL MNH_RELEASE_FLAT( IZWETG )
+!Release all memory allocated with MNH_MEM_GET calls since last call to MNH_MEM_POSITION_PIN
+CALL MNH_MEM_RELEASE()
+
 deallocate( gldcompute )
 #endif
 
diff --git a/src/MNH/mode_mnh_zwork.f90 b/src/MNH/mode_mnh_zwork.f90
index bbd89b7cbd5a5c47428ae2cb31c6b45104825cc2..42e04e0d85d8fbf947a279ee0c1056e437d928b6 100644
--- a/src/MNH/mode_mnh_zwork.f90
+++ b/src/MNH/mode_mnh_zwork.f90
@@ -8,10 +8,12 @@
 !  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)
 !  P. Wautelet 31/01/2022: add new functionalities for integers, logicals and real flat pools
+!  P. Wautelet 03/02/2022: manage memory with a LIFO pool
 !-----------------------------------------------------------------
 MODULE MODE_MNH_ZWORK
 
-  use modd_precision, only: MNHINT32, MNHINT64
+  use modd_precision,  only: MNHINT32, MNHINT64
+  use modd_parameters, only: NNEGUNDEF
 
   use mode_msg
 
@@ -77,8 +79,22 @@ MODULE MODE_MNH_ZWORK
   INTEGER,SAVE    , ALLOCATABLE, TARGET , DIMENSION(:)         :: IT1D_OSIZE
 
 
+  TYPE :: TMNH_MEM_POS
+    INTEGER :: NPOS_G = NNEGUNDEF !Position in the logical array
+    INTEGER :: NPOS_I = NNEGUNDEF !Position in the integer array
+    INTEGER :: NPOS_R = NNEGUNDEF !Position in the real array
+
+    INTEGER :: NPOS_POOL_G = NNEGUNDEF !Position in the logical pool array
+    INTEGER :: NPOS_POOL_I = NNEGUNDEF !Position in the integer pool array
+    INTEGER :: NPOS_POOL_R = NNEGUNDEF !Position in the real pool array
+  END TYPE TMNH_MEM_POS
+
   INTEGER, PARAMETER                                 :: JPPOOLSTEP_FLAT = 10 !Number of elements added to the pool when too small
 
+  INTEGER, SAVE                                      :: NMAXSIZE_POOL_POS = 20 !Initial maximum number of entries in TPOOL_POS
+  TYPE(TMNH_MEM_POS), ALLOCATABLE, DIMENSION(:)      :: TPOOL_POS !Pool to store positions (LIFO way)
+  INTEGER, SAVE                                      :: NPOOL_POS, NPOOL_POS_MAX = 0 !Position in the pool
+
   !------ Logical 1DFLAT pool
   INTEGER, PARAMETER                                 :: JPMAX_T1DFLAT_G = 10       !Used to determine max size of buffer GT1DFLAT
                                                                                    !(3D size of the mesh * JPMAX_T1DFLAT_G)
@@ -144,6 +160,8 @@ MODULE MODE_MNH_ZWORK
   INTEGER(KIND=MNHINT64), PRIVATE, SAVE :: NCALL_MNH_ALLOCATE_ZT2DFLAT = 0
   INTEGER(KIND=MNHINT64), PRIVATE, SAVE :: NCALL_MNH_ALLOCATE_ZT3DFLAT = 0
   INTEGER(KIND=MNHINT64), PRIVATE, SAVE :: NCALL_MNH_ALLOCATE_ZT4DFLAT = 0
+  INTEGER(KIND=MNHINT64), PRIVATE, SAVE :: NCALL_MNH_MEM_POSITION_PIN  = 0
+  INTEGER(KIND=MNHINT64), PRIVATE, SAVE :: NCALL_MNH_MEM_RELEASE       = 0
   INTEGER(KIND=MNHINT64), PRIVATE, SAVE :: NTOT_GETSIZE_ZT1DFLAT       = 0 !Sum of all requested sizes in MNH_REL_ZT1DFLAT
   INTEGER(KIND=MNHINT64), PRIVATE, SAVE :: NTOT_RELSIZE_ZT1DFLAT       = 0 !Sum of all released sizes in MNH_REL_ZT1DFLAT
   INTEGER(KIND=MNHINT64), PRIVATE, SAVE :: NTOT_ALLOCSIZE_ZT1DFLAT     = 0 !Sum of all requested sizes in MNH_ALLOCATE_ZT1DFLAT
@@ -152,7 +170,7 @@ MODULE MODE_MNH_ZWORK
   INTEGER(KIND=MNHINT64), PRIVATE, SAVE :: NTOT_ALLOCSIZE_ZT4DFLAT     = 0 !Sum of all requested sizes in MNH_ALLOCATE_ZT4DFLAT
 
 
-  INTERFACE MNH_ALLOCATE_FLAT
+  INTERFACE MNH_MEM_GET
     MODULE PROCEDURE :: MNH_ALLOCATE_GT1DFLAT_INT32
     MODULE PROCEDURE :: MNH_ALLOCATE_GT1DFLAT_INT64
     MODULE PROCEDURE :: MNH_ALLOCATE_GT2DFLAT
@@ -173,12 +191,7 @@ MODULE MODE_MNH_ZWORK
     MODULE PROCEDURE :: MNH_ALLOCATE_ZT3DFLAT_SIZE
     MODULE PROCEDURE :: MNH_ALLOCATE_ZT4DFLAT
     MODULE PROCEDURE :: MNH_ALLOCATE_ZT4DFLAT_SIZE
-  END INTERFACE MNH_ALLOCATE_FLAT
-
-  INTERFACE MNH_RELEASE_FLAT
-    MODULE PROCEDURE :: MNH_REL_ZT1DFLAT
-    MODULE PROCEDURE :: MNH_REL_ZT1DFLAT_N0
-  END INTERFACE MNH_RELEASE_FLAT
+  END INTERFACE MNH_MEM_GET
 
 CONTAINS
 
@@ -300,6 +313,9 @@ CONTAINS
           NT1D_POOL_I(JI) = JI
        END DO       
        
+
+       ALLOCATE( TPOOL_POS(NMAXSIZE_POOL_POS) )
+
 !------ Logical 1DFLAT pool
 
        NT1DFLAT_MAXSIZE_G = INT( IIU, KIND=MNHINT64 ) * IJU * IKU * JPMAX_T1DFLAT_G
@@ -1181,41 +1197,41 @@ CONTAINS
   END SUBROUTINE MNH_REL_GT1DFLAT
 
 
-  FUNCTION MNH_ALLOCATE_GT1DFLAT_INT32( OTAB, KSIZE ) RESULT( KINDEX )
+  SUBROUTINE MNH_ALLOCATE_GT1DFLAT_INT32( OTAB, KSIZE )
 
     LOGICAL, POINTER, CONTIGUOUS , DIMENSION(:), INTENT(INOUT) :: OTAB
     INTEGER(KIND=MNHINT32),                      INTENT(IN)    :: KSIZE
-    INTEGER                                                    :: KINDEX
 
-    kindex = MNH_Allocate_gt1dflat_int64( otab, Int( ksize, kind = MNHINT64 ) )
+    call MNH_Allocate_gt1dflat_int64( otab, Int( ksize, kind = MNHINT64 ) )
 
-  END FUNCTION MNH_ALLOCATE_GT1DFLAT_INT32
+  END SUBROUTINE MNH_ALLOCATE_GT1DFLAT_INT32
 
 
-  FUNCTION MNH_ALLOCATE_GT1DFLAT_INT64( OTAB, KSIZE ) RESULT( KINDEX )
+  SUBROUTINE MNH_ALLOCATE_GT1DFLAT_INT64( OTAB, KSIZE )
 
     LOGICAL, POINTER, CONTIGUOUS , DIMENSION(:), INTENT(INOUT) :: OTAB
     INTEGER(KIND=MNHINT64),                      INTENT(IN)    :: KSIZE
-    INTEGER                                                    :: KINDEX
+
+    INTEGER :: IPOS
 
     NCALL_MNH_ALLOCATE_GT1DFLAT = NCALL_MNH_ALLOCATE_GT1DFLAT + 1
     NTOT_ALLOCSIZE_GT1DFLAT     = NTOT_ALLOCSIZE_GT1DFLAT + KSIZE
 
-    kindex = MNH_Get_gt1dflat( ksize )
-    otab(1:KSIZE) => gt1dflat( NT1DFLAT_POOL_G(kindex) : NT1DFLAT_POOL_G(kindex)+ksize-1 )
+    ipos = MNH_Get_gt1dflat( ksize )
+    otab(1:KSIZE) => gt1dflat( NT1DFLAT_POOL_G(ipos) : NT1DFLAT_POOL_G(ipos)+ksize-1 )
 
-  END FUNCTION MNH_ALLOCATE_GT1DFLAT_INT64
+  END SUBROUTINE MNH_ALLOCATE_GT1DFLAT_INT64
 
 
-  FUNCTION MNH_ALLOCATE_GT2DFLAT( OTAB, KIB, KIE, KJB, KJE ) RESULT ( KINDEX )
+  SUBROUTINE MNH_ALLOCATE_GT2DFLAT( OTAB, KIB, KIE, KJB, KJE )
 
     LOGICAL, POINTER, CONTIGUOUS , DIMENSION(:,:), INTENT(INOUT) :: OTAB
     INTEGER,                                       INTENT(IN)    :: KIB
     INTEGER,                                       INTENT(IN)    :: KIE
     INTEGER,                                       INTENT(IN)    :: KJB
     INTEGER,                                       INTENT(IN)    :: KJE
-    INTEGER                                                      :: KINDEX
 
+    INTEGER                :: IPOS
     INTEGER(KIND=MNHINT64) :: ISIZE
     INTEGER(KIND=MNHINT64) :: IIB, IIE, IJB, IJE
 
@@ -1230,26 +1246,25 @@ CONTAINS
 
     NTOT_ALLOCSIZE_GT2DFLAT = NTOT_ALLOCSIZE_GT2DFLAT + ISIZE
 
-    kindex = MNH_Get_gt1dflat( isize )
+    ipos = MNH_Get_gt1dflat( isize )
 
-    otab(KIB:KIE, KJB:KJE) => gt1dflat( NT1DFLAT_POOL_G(kindex) : NT1DFLAT_POOL_G(kindex)+isize-1 )
+    otab(KIB:KIE, KJB:KJE) => gt1dflat( NT1DFLAT_POOL_G(ipos) : NT1DFLAT_POOL_G(ipos)+isize-1 )
 
-  END FUNCTION MNH_ALLOCATE_GT2DFLAT
+  END SUBROUTINE MNH_ALLOCATE_GT2DFLAT
 
 
-  FUNCTION MNH_ALLOCATE_GT2DFLAT_SIZE( OTAB, KISIZE, KJSIZE ) RESULT ( KINDEX )
+  SUBROUTINE MNH_ALLOCATE_GT2DFLAT_SIZE( OTAB, KISIZE, KJSIZE )
 
     LOGICAL, POINTER, CONTIGUOUS , DIMENSION(:,:), INTENT(INOUT) :: OTAB
     INTEGER,                                       INTENT(IN)    :: KISIZE
     INTEGER,                                       INTENT(IN)    :: KJSIZE
-    INTEGER                                                      :: KINDEX
 
-    KINDEX = MNH_ALLOCATE_GT2DFLAT( OTAB, 1, KISIZE, 1, KJSIZE )
+    CALL MNH_ALLOCATE_GT2DFLAT( OTAB, 1, KISIZE, 1, KJSIZE )
 
-  END FUNCTION MNH_ALLOCATE_GT2DFLAT_SIZE
+  END SUBROUTINE MNH_ALLOCATE_GT2DFLAT_SIZE
 
 
-  FUNCTION MNH_ALLOCATE_GT3DFLAT( OTAB, KIB, KIE, KJB, KJE, KKB, KKE ) RESULT ( KINDEX )
+  SUBROUTINE MNH_ALLOCATE_GT3DFLAT( OTAB, KIB, KIE, KJB, KJE, KKB, KKE )
 
     LOGICAL, POINTER, CONTIGUOUS , DIMENSION(:,:,:), INTENT(INOUT) :: OTAB
     INTEGER,                                         INTENT(IN)    :: KIB
@@ -1258,8 +1273,8 @@ CONTAINS
     INTEGER,                                         INTENT(IN)    :: KJE
     INTEGER,                                         INTENT(IN)    :: KKB
     INTEGER,                                         INTENT(IN)    :: KKE
-    INTEGER                                                        :: KINDEX
 
+    INTEGER                :: IPOS
     INTEGER(KIND=MNHINT64) :: ISIZE
     INTEGER(KIND=MNHINT64) :: IIB, IIE, IJB, IJE, IKB, IKE
 
@@ -1276,24 +1291,23 @@ CONTAINS
 
     NTOT_ALLOCSIZE_GT3DFLAT = NTOT_ALLOCSIZE_GT3DFLAT + ISIZE
 
-    kindex = MNH_Get_gt1dflat( isize )
+    ipos = MNH_Get_gt1dflat( isize )
 
-    otab(KIB:KIE, KJB:KJE, KKB:KKE) => gt1dflat( NT1DFLAT_POOL_G(kindex) : NT1DFLAT_POOL_G(kindex)+isize-1 )
+    otab(KIB:KIE, KJB:KJE, KKB:KKE) => gt1dflat( NT1DFLAT_POOL_G(ipos) : NT1DFLAT_POOL_G(ipos)+isize-1 )
 
-  END FUNCTION MNH_ALLOCATE_GT3DFLAT
+  END SUBROUTINE MNH_ALLOCATE_GT3DFLAT
 
 
-  FUNCTION MNH_ALLOCATE_GT3DFLAT_SIZE( OTAB, KISIZE, KJSIZE, KKSIZE ) RESULT ( KINDEX )
+  SUBROUTINE MNH_ALLOCATE_GT3DFLAT_SIZE( OTAB, KISIZE, KJSIZE, KKSIZE )
 
     LOGICAL, POINTER, CONTIGUOUS , DIMENSION(:,:,:), INTENT(INOUT) :: OTAB
     INTEGER,                                         INTENT(IN)    :: KISIZE
     INTEGER,                                         INTENT(IN)    :: KJSIZE
     INTEGER,                                         INTENT(IN)    :: KKSIZE
-    INTEGER                                                      :: KINDEX
 
-    KINDEX = MNH_ALLOCATE_GT3DFLAT( OTAB, 1, KISIZE, 1, KJSIZE, 1, KKSIZE )
+    CALL MNH_ALLOCATE_GT3DFLAT( OTAB, 1, KISIZE, 1, KJSIZE, 1, KKSIZE )
 
-  END FUNCTION MNH_ALLOCATE_GT3DFLAT_SIZE
+  END SUBROUTINE MNH_ALLOCATE_GT3DFLAT_SIZE
 
 
   ! End Logical 1DFLAT management
@@ -1384,41 +1398,41 @@ CONTAINS
   END SUBROUTINE MNH_REL_IT1DFLAT
 
 
-  FUNCTION MNH_ALLOCATE_IT1DFLAT_INT32( KTAB, KSIZE ) RESULT( KINDEX )
+  SUBROUTINE MNH_ALLOCATE_IT1DFLAT_INT32( KTAB, KSIZE )
 
     INTEGER, POINTER, CONTIGUOUS , DIMENSION(:), INTENT(INOUT) :: KTAB
     INTEGER(KIND=MNHINT32),                      INTENT(IN)    :: KSIZE
-    INTEGER                                                    :: KINDEX
 
-    kindex = MNH_Allocate_it1dflat_int64( ktab, Int( ksize, kind = MNHINT64 ) )
+    call MNH_Allocate_it1dflat_int64( ktab, Int( ksize, kind = MNHINT64 ) )
 
-  END FUNCTION MNH_ALLOCATE_IT1DFLAT_INT32
+  END SUBROUTINE MNH_ALLOCATE_IT1DFLAT_INT32
 
 
-  FUNCTION MNH_ALLOCATE_IT1DFLAT_INT64( KTAB, KSIZE ) RESULT( KINDEX )
+  SUBROUTINE MNH_ALLOCATE_IT1DFLAT_INT64( KTAB, KSIZE )
 
     INTEGER, POINTER, CONTIGUOUS , DIMENSION(:), INTENT(INOUT) :: KTAB
     INTEGER(KIND=MNHINT64),                      INTENT(IN)    :: KSIZE
-    INTEGER                                                    :: KINDEX
+
+    INTEGER :: IPOS
 
     NCALL_MNH_ALLOCATE_IT1DFLAT = NCALL_MNH_ALLOCATE_IT1DFLAT + 1
     NTOT_ALLOCSIZE_IT1DFLAT     = NTOT_ALLOCSIZE_IT1DFLAT + KSIZE
 
-    kindex = MNH_Get_it1dflat( ksize )
-    ktab(1:KSIZE) => it1dflat( NT1DFLAT_POOL_I(kindex) : NT1DFLAT_POOL_I(kindex)+ksize-1 )
+    ipos = MNH_Get_it1dflat( ksize )
+    ktab(1:KSIZE) => it1dflat( NT1DFLAT_POOL_I(ipos) : NT1DFLAT_POOL_I(ipos)+ksize-1 )
 
-  END FUNCTION MNH_ALLOCATE_IT1DFLAT_INT64
+  END SUBROUTINE MNH_ALLOCATE_IT1DFLAT_INT64
 
 
-  FUNCTION MNH_ALLOCATE_IT2DFLAT( KTAB, KIB, KIE, KJB, KJE ) RESULT ( KINDEX )
+  SUBROUTINE MNH_ALLOCATE_IT2DFLAT( KTAB, KIB, KIE, KJB, KJE )
 
     INTEGER, POINTER, CONTIGUOUS , DIMENSION(:,:), INTENT(INOUT) :: KTAB
     INTEGER,                                       INTENT(IN)    :: KIB
     INTEGER,                                       INTENT(IN)    :: KIE
     INTEGER,                                       INTENT(IN)    :: KJB
     INTEGER,                                       INTENT(IN)    :: KJE
-    INTEGER                                                      :: KINDEX
 
+    INTEGER                :: IPOS
     INTEGER(KIND=MNHINT64) :: ISIZE
     INTEGER(KIND=MNHINT64) :: IIB, IIE, IJB, IJE
 
@@ -1433,26 +1447,25 @@ CONTAINS
 
     NTOT_ALLOCSIZE_IT2DFLAT = NTOT_ALLOCSIZE_IT2DFLAT + ISIZE
 
-    kindex = MNH_Get_it1dflat( isize )
+    ipos = MNH_Get_it1dflat( isize )
 
-    ktab(KIB:KIE, KJB:KJE) => it1dflat( NT1DFLAT_POOL_I(kindex) : NT1DFLAT_POOL_I(kindex)+isize-1 )
+    ktab(KIB:KIE, KJB:KJE) => it1dflat( NT1DFLAT_POOL_I(ipos) : NT1DFLAT_POOL_I(ipos)+isize-1 )
 
-  END FUNCTION MNH_ALLOCATE_IT2DFLAT
+  END SUBROUTINE MNH_ALLOCATE_IT2DFLAT
 
 
-  FUNCTION MNH_ALLOCATE_IT2DFLAT_SIZE( KTAB, KISIZE, KJSIZE ) RESULT ( KINDEX )
+  SUBROUTINE MNH_ALLOCATE_IT2DFLAT_SIZE( KTAB, KISIZE, KJSIZE )
 
     INTEGER, POINTER, CONTIGUOUS , DIMENSION(:,:), INTENT(INOUT) :: KTAB
     INTEGER,                                       INTENT(IN)    :: KISIZE
     INTEGER,                                       INTENT(IN)    :: KJSIZE
-    INTEGER                                                      :: KINDEX
 
-    KINDEX = MNH_ALLOCATE_IT2DFLAT( KTAB, 1, KISIZE, 1, KJSIZE )
+    CALL MNH_ALLOCATE_IT2DFLAT( KTAB, 1, KISIZE, 1, KJSIZE )
 
-  END FUNCTION MNH_ALLOCATE_IT2DFLAT_SIZE
+  END SUBROUTINE MNH_ALLOCATE_IT2DFLAT_SIZE
 
 
-  FUNCTION MNH_ALLOCATE_IT3DFLAT( KTAB, KIB, KIE, KJB, KJE, KKB, KKE ) RESULT ( KINDEX )
+  SUBROUTINE MNH_ALLOCATE_IT3DFLAT( KTAB, KIB, KIE, KJB, KJE, KKB, KKE )
 
     INTEGER, POINTER, CONTIGUOUS , DIMENSION(:,:,:), INTENT(INOUT) :: KTAB
     INTEGER,                                         INTENT(IN)    :: KIB
@@ -1461,8 +1474,8 @@ CONTAINS
     INTEGER,                                         INTENT(IN)    :: KJE
     INTEGER,                                         INTENT(IN)    :: KKB
     INTEGER,                                         INTENT(IN)    :: KKE
-    INTEGER                                                        :: KINDEX
 
+    INTEGER                :: IPOS
     INTEGER(KIND=MNHINT64) :: ISIZE
     INTEGER(KIND=MNHINT64) :: IIB, IIE, IJB, IJE, IKB, IKE
 
@@ -1479,24 +1492,23 @@ CONTAINS
 
     NTOT_ALLOCSIZE_IT3DFLAT = NTOT_ALLOCSIZE_IT3DFLAT + ISIZE
 
-    kindex = MNH_Get_it1dflat( isize )
+    ipos = MNH_Get_it1dflat( isize )
 
-    ktab(KIB:KIE, KJB:KJE, KKB:KKE) => it1dflat( NT1DFLAT_POOL_I(kindex) : NT1DFLAT_POOL_I(kindex)+isize-1 )
+    ktab(KIB:KIE, KJB:KJE, KKB:KKE) => it1dflat( NT1DFLAT_POOL_I(ipos) : NT1DFLAT_POOL_I(ipos)+isize-1 )
 
-  END FUNCTION MNH_ALLOCATE_IT3DFLAT
+  END SUBROUTINE MNH_ALLOCATE_IT3DFLAT
 
 
-  FUNCTION MNH_ALLOCATE_IT3DFLAT_SIZE( KTAB, KISIZE, KJSIZE, KKSIZE ) RESULT ( KINDEX )
+  SUBROUTINE MNH_ALLOCATE_IT3DFLAT_SIZE( KTAB, KISIZE, KJSIZE, KKSIZE )
 
     INTEGER, POINTER, CONTIGUOUS , DIMENSION(:,:,:), INTENT(INOUT) :: KTAB
     INTEGER,                                         INTENT(IN)    :: KISIZE
     INTEGER,                                         INTENT(IN)    :: KJSIZE
     INTEGER,                                         INTENT(IN)    :: KKSIZE
-    INTEGER                                                        :: KINDEX
 
-    KINDEX = MNH_ALLOCATE_IT3DFLAT( KTAB, 1, KISIZE, 1, KJSIZE, 1, KKSIZE )
+    CALL MNH_ALLOCATE_IT3DFLAT( KTAB, 1, KISIZE, 1, KJSIZE, 1, KKSIZE )
 
-  END FUNCTION MNH_ALLOCATE_IT3DFLAT_SIZE
+  END SUBROUTINE MNH_ALLOCATE_IT3DFLAT_SIZE
 
 
   ! End Integer 1DFLAT management
@@ -1621,41 +1633,41 @@ CONTAINS
   END SUBROUTINE MNH_REL_ZT1DFLAT
 
 
-  FUNCTION MNH_ALLOCATE_ZT1DFLAT_INT32( PTAB, KSIZE ) RESULT( KINDEX )
+  SUBROUTINE MNH_ALLOCATE_ZT1DFLAT_INT32( PTAB, KSIZE )
 
     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 ) )
+    CALL MNH_Allocate_zt1dflat_int64( ptab, Int( ksize, kind = MNHINT64 ) )
 
-  END FUNCTION MNH_ALLOCATE_ZT1DFLAT_INT32
+  END SUBROUTINE MNH_ALLOCATE_ZT1DFLAT_INT32
 
 
-  FUNCTION MNH_ALLOCATE_ZT1DFLAT_INT64( PTAB, KSIZE ) RESULT( KINDEX )
+  SUBROUTINE MNH_ALLOCATE_ZT1DFLAT_INT64( PTAB, KSIZE )
 
     REAL, POINTER, CONTIGUOUS , DIMENSION(:), INTENT(INOUT) :: PTAB
     INTEGER(KIND=MNHINT64),                   INTENT(IN)    :: KSIZE
-    INTEGER                                                 :: KINDEX
+
+    INTEGER :: IPOS
 
     NCALL_MNH_ALLOCATE_ZT1DFLAT = NCALL_MNH_ALLOCATE_ZT1DFLAT + 1
     NTOT_ALLOCSIZE_ZT1DFLAT     = NTOT_ALLOCSIZE_ZT1DFLAT + KSIZE
 
-    kindex = MNH_Get_zt1dflat( ksize )
-    ptab(1:KSIZE) => zt1dflat( NT1DFLAT_POOL_R(kindex) : NT1DFLAT_POOL_R(kindex)+ksize-1 )
+    ipos = MNH_Get_zt1dflat( ksize )
+    ptab(1:KSIZE) => zt1dflat( NT1DFLAT_POOL_R(ipos) : NT1DFLAT_POOL_R(ipos)+ksize-1 )
 
-  END FUNCTION MNH_ALLOCATE_ZT1DFLAT_INT64
+  END SUBROUTINE MNH_ALLOCATE_ZT1DFLAT_INT64
 
 
-  FUNCTION MNH_ALLOCATE_ZT2DFLAT( PTAB, KIB, KIE, KJB, KJE ) RESULT ( KINDEX )
+  SUBROUTINE MNH_ALLOCATE_ZT2DFLAT( PTAB, KIB, KIE, KJB, KJE )
 
     REAL, POINTER, CONTIGUOUS , DIMENSION(:,:), INTENT(INOUT) :: PTAB
     INTEGER,                                    INTENT(IN)    :: KIB
     INTEGER,                                    INTENT(IN)    :: KIE
     INTEGER,                                    INTENT(IN)    :: KJB
     INTEGER,                                    INTENT(IN)    :: KJE
-    INTEGER                                                   :: KINDEX
 
+    INTEGER                :: IPOS
     INTEGER(KIND=MNHINT64) :: ISIZE
     INTEGER(KIND=MNHINT64) :: IIB, IIE, IJB, IJE
 
@@ -1670,26 +1682,25 @@ CONTAINS
 
     NTOT_ALLOCSIZE_ZT2DFLAT = NTOT_ALLOCSIZE_ZT2DFLAT + ISIZE
 
-    kindex = MNH_Get_zt1dflat( isize )
+    ipos = MNH_Get_zt1dflat( isize )
 
-    ptab(KIB:KIE, KJB:KJE) => zt1dflat( NT1DFLAT_POOL_R(kindex) : NT1DFLAT_POOL_R(kindex)+isize-1 )
+    ptab(KIB:KIE, KJB:KJE) => zt1dflat( NT1DFLAT_POOL_R(ipos) : NT1DFLAT_POOL_R(ipos)+isize-1 )
 
-  END FUNCTION MNH_ALLOCATE_ZT2DFLAT
+  END SUBROUTINE MNH_ALLOCATE_ZT2DFLAT
 
 
-  FUNCTION MNH_ALLOCATE_ZT2DFLAT_SIZE( PTAB, KISIZE, KJSIZE ) RESULT ( KINDEX )
+  SUBROUTINE MNH_ALLOCATE_ZT2DFLAT_SIZE( PTAB, KISIZE, KJSIZE )
 
     REAL, POINTER, CONTIGUOUS , DIMENSION(:,:), INTENT(INOUT) :: PTAB
     INTEGER,                                    INTENT(IN)    :: KISIZE
     INTEGER,                                    INTENT(IN)    :: KJSIZE
-    INTEGER                                                   :: KINDEX
 
-    KINDEX = MNH_ALLOCATE_ZT2DFLAT( PTAB, 1, KISIZE, 1, KJSIZE )
+    CALL MNH_ALLOCATE_ZT2DFLAT( PTAB, 1, KISIZE, 1, KJSIZE )
 
-  END FUNCTION MNH_ALLOCATE_ZT2DFLAT_SIZE
+  END SUBROUTINE MNH_ALLOCATE_ZT2DFLAT_SIZE
 
 
-  FUNCTION MNH_ALLOCATE_ZT3DFLAT( PTAB, KIB, KIE, KJB, KJE, KKB, KKE ) RESULT ( KINDEX )
+  SUBROUTINE MNH_ALLOCATE_ZT3DFLAT( PTAB, KIB, KIE, KJB, KJE, KKB, KKE )
 
     REAL, POINTER, CONTIGUOUS , DIMENSION(:,:,:), INTENT(INOUT) :: PTAB
     INTEGER,                                      INTENT(IN)    :: KIB
@@ -1698,8 +1709,8 @@ CONTAINS
     INTEGER,                                      INTENT(IN)    :: KJE
     INTEGER,                                      INTENT(IN)    :: KKB
     INTEGER,                                      INTENT(IN)    :: KKE
-    INTEGER                                                     :: KINDEX
 
+    INTEGER                :: IPOS
     INTEGER(KIND=MNHINT64) :: ISIZE
     INTEGER(KIND=MNHINT64) :: IIB, IIE, IJB, IJE, IKB, IKE
 
@@ -1716,27 +1727,26 @@ CONTAINS
 
     NTOT_ALLOCSIZE_ZT3DFLAT = NTOT_ALLOCSIZE_ZT3DFLAT + ISIZE
 
-    kindex = MNH_Get_zt1dflat( isize )
+    ipos = MNH_Get_zt1dflat( isize )
 
-    ptab(KIB:KIE, KJB:KJE, KKB:KKE) => zt1dflat( NT1DFLAT_POOL_R(kindex) : NT1DFLAT_POOL_R(kindex)+isize-1 )
+    ptab(KIB:KIE, KJB:KJE, KKB:KKE) => zt1dflat( NT1DFLAT_POOL_R(ipos) : NT1DFLAT_POOL_R(ipos)+isize-1 )
 
-  END FUNCTION MNH_ALLOCATE_ZT3DFLAT
+  END SUBROUTINE MNH_ALLOCATE_ZT3DFLAT
 
 
-  FUNCTION MNH_ALLOCATE_ZT3DFLAT_SIZE( PTAB, KISIZE, KJSIZE, KKSIZE ) RESULT ( KINDEX )
+  SUBROUTINE MNH_ALLOCATE_ZT3DFLAT_SIZE( PTAB, KISIZE, KJSIZE, KKSIZE )
 
     REAL, POINTER, CONTIGUOUS , DIMENSION(:,:,:), INTENT(INOUT) :: PTAB
     INTEGER,                                      INTENT(IN)    :: KISIZE
     INTEGER,                                      INTENT(IN)    :: KJSIZE
     INTEGER,                                      INTENT(IN)    :: KKSIZE
-    INTEGER                                                     :: KINDEX
 
-    KINDEX = MNH_ALLOCATE_ZT3DFLAT( PTAB, 1, KISIZE, 1, KJSIZE, 1, KKSIZE )
+    CALL MNH_ALLOCATE_ZT3DFLAT( PTAB, 1, KISIZE, 1, KJSIZE, 1, KKSIZE )
 
-  END FUNCTION MNH_ALLOCATE_ZT3DFLAT_SIZE
+  END SUBROUTINE MNH_ALLOCATE_ZT3DFLAT_SIZE
 
 
-  FUNCTION MNH_ALLOCATE_ZT4DFLAT( PTAB, KIB, KIE, KJB, KJE, KKB, KKE, KPB, KPE ) RESULT ( KINDEX )
+  SUBROUTINE MNH_ALLOCATE_ZT4DFLAT( PTAB, KIB, KIE, KJB, KJE, KKB, KKE, KPB, KPE )
 
     REAL, POINTER, CONTIGUOUS , DIMENSION(:,:,:,:), INTENT(INOUT) :: PTAB
     INTEGER,                                        INTENT(IN)    :: KIB
@@ -1747,8 +1757,8 @@ CONTAINS
     INTEGER,                                        INTENT(IN)    :: KKE
     INTEGER,                                        INTENT(IN)    :: KPB
     INTEGER,                                        INTENT(IN)    :: KPE
-    INTEGER                                                       :: KINDEX
 
+    INTEGER                :: IPOS
     INTEGER(KIND=MNHINT64) :: ISIZE
     INTEGER(KIND=MNHINT64) :: IIB, IIE, IJB, IJE, IKB, IKE, IPB, IPE
 
@@ -1767,14 +1777,14 @@ CONTAINS
 
     NTOT_ALLOCSIZE_ZT4DFLAT = NTOT_ALLOCSIZE_ZT4DFLAT + ISIZE
 
-    kindex = MNH_Get_zt1dflat( isize )
+    ipos = MNH_Get_zt1dflat( isize )
 
-    ptab(KIB:KIE, KJB:KJE, KKB:KKE, KPB:KPE ) => zt1dflat( NT1DFLAT_POOL_R(kindex) : NT1DFLAT_POOL_R(kindex)+isize-1 )
+    ptab(KIB:KIE, KJB:KJE, KKB:KKE, KPB:KPE ) => zt1dflat( NT1DFLAT_POOL_R(ipos) : NT1DFLAT_POOL_R(ipos)+isize-1 )
 
-  END FUNCTION MNH_ALLOCATE_ZT4DFLAT
+  END SUBROUTINE MNH_ALLOCATE_ZT4DFLAT
 
 
-  FUNCTION MNH_ALLOCATE_ZT4DFLAT_SIZE( PTAB, KISIZE, KJSIZE, KKSIZE, KPSIZE ) RESULT ( KINDEX )
+  SUBROUTINE MNH_ALLOCATE_ZT4DFLAT_SIZE( PTAB, KISIZE, KJSIZE, KKSIZE, KPSIZE )
 
     REAL, POINTER, CONTIGUOUS , DIMENSION(:,:,:,:), INTENT(INOUT) :: PTAB
     INTEGER,                                        INTENT(IN)    :: KISIZE
@@ -1783,15 +1793,103 @@ CONTAINS
     INTEGER,                                        INTENT(IN)    :: KPSIZE
     INTEGER                                                     :: KINDEX
 
-    KINDEX = MNH_ALLOCATE_ZT4DFLAT( PTAB, 1, KISIZE, 1, KJSIZE, 1, KKSIZE, 1, KPSIZE )
+    CALL MNH_ALLOCATE_ZT4DFLAT( PTAB, 1, KISIZE, 1, KJSIZE, 1, KKSIZE, 1, KPSIZE )
 
-  END FUNCTION MNH_ALLOCATE_ZT4DFLAT_SIZE
+  END SUBROUTINE MNH_ALLOCATE_ZT4DFLAT_SIZE
 
 
   ! End Real 1DFLAT management
 
 
+
+  SUBROUTINE MNH_MEM_POSITION_PIN()
+    ! Function that stores the current position of the different preallocated arrays in the position pool
+    CHARACTER(LEN=32) :: YMAX, YSIZE
+    TYPE(TMNH_MEM_POS), ALLOCATABLE, DIMENSION(:) :: TZPOOL
+
+    NCALL_MNH_MEM_POSITION_PIN = NCALL_MNH_MEM_POSITION_PIN + 1
+
+    NPOOL_POS = NPOOL_POS + 1
+
+    IF ( NPOOL_POS > NMAXSIZE_POOL_POS ) THEN
+      WRITE( YSIZE,  '( I0 )' ) NMAXSIZE_POOL_POS
+      WRITE( YMAX,   '( I0 )' ) NMAXSIZE_POOL_POS + JPPOOLSTEP_FLAT
+      call Print_msg( NVERB_INFO, 'GEN', 'MNH_MEM_POSITION_PIN', 'pool was too small (' // TRIM( YSIZE ) &
+                      // '->' // TRIM( YMAX ) // ')' )
+
+      ALLOCATE( TZPOOL(NMAXSIZE_POOL_POS + JPPOOLSTEP_FLAT) )
+
+      TZPOOL(1:NMAXSIZE_POOL_POS) = TPOOL_POS(:)
+
+      CALL MOVE_ALLOC( FROM = TZPOOL, TO = TPOOL_POS )
+
+      NMAXSIZE_POOL_POS = NMAXSIZE_POOL_POS + JPPOOLSTEP_FLAT
+    END IF
+
+    TPOOL_POS(NPOOL_POS)%NPOS_G = NT1DFLAT_POS_G !Position in the logical array
+    TPOOL_POS(NPOOL_POS)%NPOS_I = NT1DFLAT_POS_I !Position in the integer array
+    TPOOL_POS(NPOOL_POS)%NPOS_R = NT1DFLAT_POS_R !Position in the real array
+
+    TPOOL_POS(NPOOL_POS)%NPOS_POOL_G = NT1DFLAT_TOP_G !Position in the logical pool array
+    TPOOL_POS(NPOOL_POS)%NPOS_POOL_I = NT1DFLAT_TOP_I !Position in the logical pool array
+    TPOOL_POS(NPOOL_POS)%NPOS_POOL_R = NT1DFLAT_TOP_R !Position in the logical pool array
+
+  END SUBROUTINE MNH_MEM_POSITION_PIN
+
+
+  SUBROUTINE MNH_MEM_RELEASE( )
+    ! Function that set the current position in the different preallocated arrays
+    ! to the last values in the position pool
+    ! This can be used to release previously allocated memory
+    USE MODD_PARAMETERS, ONLY: NNEGUNDEF
+
+    NCALL_MNH_MEM_RELEASE = NCALL_MNH_MEM_RELEASE + 1
+
+    !Stats for sizes
+    NTOT_RELSIZE_GT1DFLAT = NTOT_RELSIZE_GT1DFLAT + NT1DFLAT_POS_G - TPOOL_POS(NPOOL_POS)%NPOS_G
+    NTOT_RELSIZE_IT1DFLAT = NTOT_RELSIZE_IT1DFLAT + NT1DFLAT_POS_I - TPOOL_POS(NPOOL_POS)%NPOS_I
+    NTOT_RELSIZE_ZT1DFLAT = NTOT_RELSIZE_ZT1DFLAT + NT1DFLAT_POS_R - TPOOL_POS(NPOOL_POS)%NPOS_R
+
+    !Stats for pools
+    NCALL_MNH_REL_GT1DFLAT = NCALL_MNH_REL_GT1DFLAT + NT1DFLAT_TOP_G - TPOOL_POS(NPOOL_POS)%NPOS_POOL_G
+    NCALL_MNH_REL_IT1DFLAT = NCALL_MNH_REL_IT1DFLAT + NT1DFLAT_TOP_I - TPOOL_POS(NPOOL_POS)%NPOS_POOL_I
+    NCALL_MNH_REL_ZT1DFLAT = NCALL_MNH_REL_ZT1DFLAT + NT1DFLAT_TOP_R - TPOOL_POS(NPOOL_POS)%NPOS_POOL_R
+
+    !Clean up pools
+    NT1DFLAT_POOL_G( TPOOL_POS(NPOOL_POS)%NPOS_POOL_G + 1 : NT1DFLAT_TOP_G ) = NNEGUNDEF
+    NT1DFLAT_SIZE_G( TPOOL_POS(NPOOL_POS)%NPOS_POOL_G + 1 : NT1DFLAT_TOP_G ) = NNEGUNDEF
+    NT1DFLAT_POOL_I( TPOOL_POS(NPOOL_POS)%NPOS_POOL_I + 1 : NT1DFLAT_TOP_I ) = NNEGUNDEF
+    NT1DFLAT_SIZE_I( TPOOL_POS(NPOOL_POS)%NPOS_POOL_I + 1 : NT1DFLAT_TOP_I ) = NNEGUNDEF
+    NT1DFLAT_POOL_R( TPOOL_POS(NPOOL_POS)%NPOS_POOL_R + 1 : NT1DFLAT_TOP_R ) = NNEGUNDEF
+    NT1DFLAT_SIZE_R( TPOOL_POS(NPOOL_POS)%NPOS_POOL_R + 1 : NT1DFLAT_TOP_R ) = NNEGUNDEF
+
+    NT1DFLAT_POS_G = TPOOL_POS(NPOOL_POS)%NPOS_G !Position in the logical array
+    NT1DFLAT_POS_I = TPOOL_POS(NPOOL_POS)%NPOS_I !Position in the integer array
+    NT1DFLAT_POS_R = TPOOL_POS(NPOOL_POS)%NPOS_R !Position in the real array
+
+    NT1DFLAT_TOP_G = TPOOL_POS(NPOOL_POS)%NPOS_POOL_G !Position in the logical pool array
+    NT1DFLAT_TOP_I = TPOOL_POS(NPOOL_POS)%NPOS_POOL_I !Position in the logical pool array
+    NT1DFLAT_TOP_R = TPOOL_POS(NPOOL_POS)%NPOS_POOL_R !Position in the logical pool array
+
+    TPOOL_POS(NPOOL_POS)%NPOS_G = NNEGUNDEF
+    TPOOL_POS(NPOOL_POS)%NPOS_I = NNEGUNDEF
+    TPOOL_POS(NPOOL_POS)%NPOS_R = NNEGUNDEF
+
+    TPOOL_POS(NPOOL_POS)%NPOS_POOL_G = NNEGUNDEF
+    TPOOL_POS(NPOOL_POS)%NPOS_POOL_I = NNEGUNDEF
+    TPOOL_POS(NPOOL_POS)%NPOS_POOL_R = NNEGUNDEF
+
+    NPOOL_POS = NPOOL_POS - 1
+
+  END SUBROUTINE MNH_MEM_RELEASE
+
+
   SUBROUTINE PRINT_FLATPOOL_STATS()
+    cmnhmsg(1) = 'MNH memory pool: number of calls:'
+    Write( cmnhmsg(2), "( '  MNH_MEM_POSITION_PIN  = ', I20 )" ) NCALL_MNH_MEM_POSITION_PIN
+    Write( cmnhmsg(3), "( '  MNH_MEM_RELEASE       = ', I20 )" ) NCALL_MNH_MEM_RELEASE
+    Write( cmnhmsg(4), "( '-------------------------', '--------------------' )" )
+    call Print_msg( NVERB_INFO, 'GEN', 'FLAT_STATS' )
 
     cmnhmsg(1) = 'LOGICAL flat pool: Number of calls:'
     Write( cmnhmsg(2), "( '  MNH_GET_GT1DFLAT        = ', I20 )" ) NCALL_MNH_GET_GT1DFLAT
diff --git a/src/MNH/mode_prandtl.f90 b/src/MNH/mode_prandtl.f90
index 0a898573e60c521877fd20d75fe9738dd2de9538..262fd50fed1d75c6003960c69b8b245bca554e48 100644
--- a/src/MNH/mode_prandtl.f90
+++ b/src/MNH/mode_prandtl.f90
@@ -16,7 +16,7 @@ USE MODD_PARAMETERS, ONLY : JPVEXT_TURB
 
 #ifdef MNH_OPENACC
 use mode_msg
-USE MODE_MNH_ZWORK , ONLY : MNH_ALLOCATE_FLAT , MNH_RELEASE_FLAT, MNH_REL_GT1DFLAT
+USE MODE_MNH_ZWORK,  ONLY: MNH_MEM_GET, MNH_MEM_POSITION_PIN, MNH_MEM_RELEASE
 #endif
 
 #ifdef MNH_BITREP
@@ -43,11 +43,13 @@ REAL, DIMENSION(:,:,:), INTENT(INOUT) :: PF      ! function F to smooth
 REAL, DIMENSION(SIZE(PF,1),SIZE(PF,2),SIZE(PF,3)) :: ZCOEF
 #else
 REAL, DIMENSION(:,:,:), pointer,contiguous ::  ZCOEF
-INTEGER ::  IZCOEF
 #endif
 
 #ifdef MNH_OPENACC
- IZCOEF = MNH_ALLOCATE_FLAT( ZCOEF , SIZE(PF,1),SIZE(PF,2),SIZE(PF,3) )
+!Pin positions in the pools of MNH memory
+CALL MNH_MEM_POSITION_PIN()
+
+CALL MNH_MEM_GET( ZCOEF , SIZE(PF,1),SIZE(PF,2),SIZE(PF,3) )
 #endif
 
 !$acc data present( PPHI3, PF_LIM, PF ) present( ZCOEF )
@@ -68,7 +70,8 @@ PF(:,:,:) =     ZCOEF(:,:,:)   * PF    &
 !$acc end data
 
 #ifdef MNH_OPENACC
-CALL MNH_RELEASE_FLAT(IZCOEF)
+!Release all memory allocated with MNH_MEM_GET calls since last call to MNH_MEM_POSITION_PIN
+CALL MNH_MEM_RELEASE()
 #endif
 
 END SUBROUTINE SMOOTH_TURB_FUNCT
@@ -94,9 +97,6 @@ SUBROUTINE PHI3(PREDTH1,PREDR1,PRED2TH3,PRED2R3,PRED2THR3,HTURBDIM,OUSERV,PPHI3)
   INTEGER                               :: IKB, IKE
   LOGICAL,DIMENSION(:,:,:),  pointer , contiguous :: GPHI3LOGIC
   REAL,   DIMENSION(:,:,:),  pointer , contiguous :: ZW1, ZW2
-#ifdef MNH_OPENACC
-  INTEGER                                         :: IGPHI3LOGIC, IZW1, IZW2
-#endif
 
   INTEGER  :: JIU,JJU,JKU
   INTEGER  :: JI,JJ,JK
@@ -115,9 +115,12 @@ allocate( zw1      ( size( predth1, 1 ), size( predth1, 2 ), size( predth1, 3 )
 allocate( zw2      ( size( predth1, 1 ), size( predth1, 2 ), size( predth1, 3 ) ) )
 allocate( gphi3logic( size( predth1, 1 ), size( predth1, 2 ), size( predth1, 3 ) ) )
 #else
-izw1        = MNH_ALLOCATE_FLAT( zw1       , JIU,JJU,JKU )
-izw2        = MNH_ALLOCATE_FLAT( zw2       , JIU,JJU,JKU )
-igphi3logic = MNH_ALLOCATE_FLAT( gphi3logic, JIU,JJU,JKU )
+!Pin positions in the pools of MNH memory
+CALL MNH_MEM_POSITION_PIN()
+
+CALL MNH_MEM_GET( zw1       , JIU,JJU,JKU )
+CALL MNH_MEM_GET( zw2       , JIU,JJU,JKU )
+CALL MNH_MEM_GET( gphi3logic, JIU,JJU,JKU )
 #endif
 
 !$acc data present( zw1, zw2, gphi3logic )
@@ -190,8 +193,8 @@ PPHI3(:,:,IKE+1)=PPHI3(:,:,IKE)
 #ifndef MNH_OPENACC
 deallocate ( zw1,zw2,gphi3logic)
 #else
-CALL MNH_RELEASE_FLAT(IZW1,IZW2)
-CALL MNH_REL_GT1DFLAT(IGPHI3LOGIC)
+!Release all memory allocated with MNH_MEM_GET calls since last call to MNH_MEM_POSITION_PIN
+CALL MNH_MEM_RELEASE()
 #endif
 
 !$acc end data
@@ -223,16 +226,16 @@ SUBROUTINE PSI_SV(PREDTH1,PREDR1,PREDS1,PRED2THS,PRED2RS,PPHI3,PPSI3,PPSI_SV)
   INTEGER :: IKB, IKE
   INTEGER :: JSV
   LOGICAL, DIMENSION(:,:,:),  pointer , contiguous :: GPSILOGIC
-#ifdef MNH_OPENACC
-  INTEGER                                          :: IGPSILOGIC
-#endif
 
 !$acc data present( PREDTH1, PREDR1, PREDS1, PRED2THS, PRED2RS, PPHI3, PPSI3, PPSI_SV )
 
 #ifndef MNH_OPENACC  
 allocate( gpsilogic( size( pred2ths, 1 ), size( pred2ths, 2 ), size( pred2ths, 3 ) ) )
 #else
-igpsilogic = MNH_ALLOCATE_FLAT( gpsilogic , size( pred2ths, 1 ), size( pred2ths, 2 ), size( pred2ths, 3 ) )
+!Pin positions in the pools of MNH memory
+CALL MNH_MEM_POSITION_PIN()
+
+CALL MNH_MEM_GET( gpsilogic , size( pred2ths, 1 ), size( pred2ths, 2 ), size( pred2ths, 3 ) )
 #endif  
 
 !$acc data present( gpsilogic )
@@ -269,7 +272,8 @@ END DO
 #ifndef MNH_OPENACC
 deallocate( gpsilogic )
 #else
-CALL MNH_REL_GT1DFLAT(IGPSILOGIC)
+!Release all memory allocated with MNH_MEM_GET calls since last call to MNH_MEM_POSITION_PIN
+CALL MNH_MEM_RELEASE()
 #endif
 
 !$acc end data
@@ -463,13 +467,15 @@ SUBROUTINE D_PHI3DTDZ2_O_DDTDZ(PPHI3,PREDTH1,PREDR1,PRED2TH3,PRED2THR3,PDTDZ,HTU
   INTEGER :: IKB, IKE
 #ifdef MNH_OPENACC
   REAL, DIMENSION(:,:,:), pointer , contiguous :: ZTMP1_DEVICE
-  INTEGER  :: IZTMP1_DEVICE
 #endif
 
 !$acc data present( PPHI3, PREDTH1, PREDR1, PRED2TH3, PRED2THR3, PDTDZ, PD_PHI3DTDZ2_O_DDTDZ )
 
 #ifdef MNH_OPENACC
-iztmp1_device = MNH_ALLOCATE_FLAT( ztmp1_device, size( predth1, 1 ), size( predth1, 2 ), size( predth1, 3 ) )
+!Pin positions in the pools of MNH memory
+CALL MNH_MEM_POSITION_PIN()
+
+CALL MNH_MEM_GET( ztmp1_device, size( predth1, 1 ), size( predth1, 2 ), size( predth1, 3 ) )
 #endif
 
 !$acc data present( ztmp1_device )
@@ -547,7 +553,8 @@ PD_PHI3DTDZ2_O_DDTDZ(:,:,IKE+1)=PD_PHI3DTDZ2_O_DDTDZ(:,:,IKE)
 !$acc end data
 
 #ifdef MNH_OPENACC
-CALL MNH_RELEASE_FLAT( iztmp1_device )
+!Release all memory allocated with MNH_MEM_GET calls since last call to MNH_MEM_POSITION_PIN
+CALL MNH_MEM_RELEASE()
 #endif
 
 !$acc end data
diff --git a/src/MNH/modeln.f90 b/src/MNH/modeln.f90
index b75a4f1851be90afb3eb9db7b2f873237dd079e2..29f3dee3b4b3ad8474d20ca5d6fdd602d39bba13 100644
--- a/src/MNH/modeln.f90
+++ b/src/MNH/modeln.f90
@@ -378,7 +378,7 @@ use mode_menu_diachro,     only: MENU_DIACHRO
 #endif
 USE MODE_MNH_TIMING
 #ifdef MNH_OPENACC
-USE MODE_MNH_ZWORK,      ONLY: MNH_ALLOCATE_FLAT, MNH_RELEASE_FLAT
+USE MODE_MNH_ZWORK,      ONLY: MNH_MEM_GET, MNH_MEM_POSITION_PIN, MNH_MEM_RELEASE
 #endif
 USE MODE_MODELN_HANDLER
 USE MODE_MPPDB
@@ -490,9 +490,6 @@ INTEGER :: ISYNCHRO          ! model synchronic index relative to its father
 INTEGER      :: IMI ! Current model index
 REAL, DIMENSION(:,:), POINTER, CONTIGUOUS :: ZSEA
 REAL, DIMENSION(:,:), POINTER, CONTIGUOUS :: ZTOWN
-#ifdef MNH_OPENACC
-INTEGER :: IZSEA, IZTOWN
-#endif
 ! Dummy pointers needed to correct an ifort Bug
 REAL, DIMENSION(:), POINTER :: DPTR_XZHAT
 REAL, DIMENSION(:), POINTER :: DPTR_XBMX1,DPTR_XBMX2,DPTR_XBMX3,DPTR_XBMX4
@@ -547,14 +544,8 @@ LOGICAL :: KHHONI
 !
 REAL, DIMENSION(:,:,:), ALLOCATABLE :: ZRUS,ZRVS
 REAL, DIMENSION(:,:,:), POINTER, CONTIGUOUS :: ZRWS
-#ifdef MNH_OPENACC
-INTEGER :: IZRWS
-#endif
 REAL, DIMENSION(:,:,:), POINTER, CONTIGUOUS :: ZPABST !To give pressure at t
                                                      ! (and not t+1) to resolved_cloud
-#ifdef MNH_OPENACC
-INTEGER :: IZPABST
-#endif
 REAL, DIMENSION(:,:,:), ALLOCATABLE :: ZJ
 !
 TYPE(LIST_ll), POINTER :: TZFIELDC_ll   ! list of fields to exchange
@@ -579,10 +570,11 @@ allocate( ZRVS  (SIZE(XTHT,1),SIZE(XTHT,2),SIZE(XTHT,3)) )
 allocate( ZRWS  (SIZE(XTHT,1),SIZE(XTHT,2),SIZE(XTHT,3)) )
 allocate( ZPABST(SIZE(XTHT,1),SIZE(XTHT,2),SIZE(XTHT,3)) )
 #else
-IZRWS   = MNH_ALLOCATE_FLAT( ZRWS,   SIZE( XTHT, 1 ), SIZE( XTHT, 2 ), SIZE( XTHT, 3 ) )
-IZPABST = MNH_ALLOCATE_FLAT( ZPABST, SIZE( XTHT, 1 ), SIZE( XTHT, 2 ), SIZE( XTHT, 3 ) )
-IZSEA = -1  !Set to -1 because not (yet) allocated
-IZTOWN = -1 !Set to -1 because not (yet) allocated
+!Pin positions in the pools of MNH memory
+CALL MNH_MEM_POSITION_PIN()
+
+CALL MNH_MEM_GET( ZRWS,   SIZE( XTHT, 1 ), SIZE( XTHT, 2 ), SIZE( XTHT, 3 ) )
+CALL MNH_MEM_GET( ZPABST, SIZE( XTHT, 1 ), SIZE( XTHT, 2 ), SIZE( XTHT, 3 ) )
 #endif
 allocate( ZJ    (SIZE(XTHT,1),SIZE(XTHT,2),SIZE(XTHT,3)) )
 allocate( ZWETDEPAER(SIZE(XRSVS,1), SIZE(XRSVS,2), SIZE(XRSVS,3), NSV_AER) )
@@ -1941,8 +1933,10 @@ IF (CCLOUD /= 'NONE' .AND. CELEC == 'NONE') THEN
     ALLOCATE (ZSEA(SIZE(XRHODJ,1),SIZE(XRHODJ,2)))
     ALLOCATE (ZTOWN(SIZE(XRHODJ,1),SIZE(XRHODJ,2)))
 #else
-    IZSEA  = MNH_ALLOCATE_FLAT( ZSEA,  SIZE( XRHODJ, 1 ), SIZE( XRHODJ, 2 ) )
-    IZTOWN = MNH_ALLOCATE_FLAT( ZTOWN, SIZE( XRHODJ, 1 ), SIZE( XRHODJ, 2 ) )
+    CALL MNH_MEM_GET( ZSEA,  SIZE( XRHODJ, 1 ), SIZE( XRHODJ, 2 ) )
+
+    CALL MNH_MEM_POSITION_PIN()
+    CALL MNH_MEM_GET( ZTOWN, SIZE( XRHODJ, 1 ), SIZE( XRHODJ, 2 ) )
 #endif
     CALL MNHGET_SURF_PARAM_n (PSEA=ZSEA(:,:),PTOWN=ZTOWN(:,:))
 !$acc update device( ZSEA, ZTOWN )
@@ -1969,7 +1963,7 @@ IF (CCLOUD /= 'NONE' .AND. CELEC == 'NONE') THEN
 #ifndef MNH_OPENACC
     DEALLOCATE(ZTOWN)
 #else
-    CALL MNH_RELEASE_FLAT( IZTOWN )
+    CALL MNH_MEM_RELEASE() !Release ZTOWN
 #endif
   ELSE
     CALL RESOLVED_CLOUD ( CCLOUD, CACTCCN, CSCONV, CMF_CLOUD, NRR, NSPLITR,    &
@@ -2056,8 +2050,10 @@ IF (CELEC /= 'NONE' .AND. (CCLOUD(1:3) == 'ICE')) THEN
     ALLOCATE (ZSEA(SIZE(XRHODJ,1),SIZE(XRHODJ,2)))
     ALLOCATE (ZTOWN(SIZE(XRHODJ,1),SIZE(XRHODJ,2)))
 #else
-    IZSEA  = MNH_ALLOCATE_FLAT( ZSEA,  SIZE( XRHODJ, 1 ), SIZE( XRHODJ, 2 ) )
-    IZTOWN = MNH_ALLOCATE_FLAT( ZTOWN, SIZE( XRHODJ, 1 ), SIZE( XRHODJ, 2 ) )
+    CALL MNH_MEM_GET( ZSEA,  SIZE( XRHODJ, 1 ), SIZE( XRHODJ, 2 ) )
+
+    CALL MNH_MEM_POSITION_PIN()
+    CALL MNH_MEM_GET( ZTOWN, SIZE( XRHODJ, 1 ), SIZE( XRHODJ, 2 ) )
 #endif
     CALL MNHGET_SURF_PARAM_n (PSEA=ZSEA(:,:),PTOWN=ZTOWN(:,:))
     CALL RESOLVED_ELEC_n (CCLOUD, CSCONV, CMF_CLOUD,                     &
@@ -2075,7 +2071,7 @@ IF (CELEC /= 'NONE' .AND. (CCLOUD(1:3) == 'ICE')) THEN
 #ifndef MNH_OPENACC
     DEALLOCATE(ZTOWN)
 #else
-    CALL MNH_RELEASE_FLAT( IZTOWN )
+    CALL MNH_MEM_RELEASE() !Release ZTOWN
 #endif
   ELSE
     CALL RESOLVED_ELEC_n (CCLOUD, CSCONV, CMF_CLOUD,                     &
@@ -2408,16 +2404,10 @@ END IF
 
 #ifndef MNH_OPENACC
 IF ( ALLOCATED( ZSEA ) ) DEALLOCATE( ZSEA )
-#else
-IF ( IZSEA /= -1 ) CALL MNH_RELEASE_FLAT( IZSEA )
-#endif
-
-#ifndef MNH_OPENACC
 DEALLOCATE( ZRWS )
 DEALLOCATE( ZPABST )
 #else
-CALL MNH_RELEASE_FLAT( IZPABST )
-CALL MNH_RELEASE_FLAT( IZRWS )
+CALL MNH_MEM_RELEASE()
 #endif
 
 END SUBROUTINE MODEL_n
diff --git a/src/MNH/prandtl.f90 b/src/MNH/prandtl.f90
index 41ebf0536775ddf51e42b725e17e0d6ee05fbccd..a0bf5e1cca0a919aa61ecd735bbb66eb862526c6 100644
--- a/src/MNH/prandtl.f90
+++ b/src/MNH/prandtl.f90
@@ -219,7 +219,7 @@ USE MODI_SHUMAN_DEVICE
 #endif
 !
 #ifdef MNH_OPENACC
-USE MODE_MNH_ZWORK, ONLY: MNH_ALLOCATE_FLAT, MNH_RELEASE_FLAT
+USE MODE_MNH_ZWORK, ONLY: MNH_MEM_GET, MNH_MEM_POSITION_PIN, MNH_MEM_RELEASE
 #endif
 !
 IMPLICIT NONE
@@ -276,9 +276,6 @@ REAL, DIMENSION(:,:,:), INTENT(OUT)  ::  PEMOIST ! coefficient E_moist
 !
 REAL, DIMENSION(:,:,:),  pointer , contiguous :: ZW1
 REAL, DIMENSION(:,:,:),  pointer , contiguous :: ZW2 ! work arrays
-#ifdef MNH_OPENACC
-INTEGER                                      :: IZW1, IZW2
-#endif
 !                                                     
 INTEGER :: IKB      ! vertical index value for the first inner mass point
 INTEGER :: IKE      ! vertical index value for the last inner mass point
@@ -294,7 +291,6 @@ REAL, DIMENSION(:,:,:), pointer , contiguous :: ZTMP2_DEVICE
 REAL, DIMENSION(:,:,:), pointer , contiguous :: ZTMP3_DEVICE
 REAL, DIMENSION(:,:,:), pointer , contiguous :: ZTMP4_DEVICE
 REAL, DIMENSION(:,:,:), pointer , contiguous :: ZTMP5_DEVICE
-INTEGER   :: IZTMP1_DEVICE,IZTMP2_DEVICE,IZTMP3_DEVICE,IZTMP4_DEVICE,IZTMP5_DEVICE
 #endif
 TYPE(TFIELDDATA)  :: TZFIELD
 !
@@ -336,16 +332,17 @@ JKU =  size( pthlm, 3 )
 allocate( zw1(JIU,JJU,JKU ) )
 allocate( zw2(JIU,JJU,JKU ) )
 #else
-izw1 = MNH_ALLOCATE_FLAT( zw1, JIU,JJU,JKU )
-izw2 = MNH_ALLOCATE_FLAT( zw2, JIU,JJU,JKU )
-#endif
+!Pin positions in the pools of MNH memory
+CALL MNH_MEM_POSITION_PIN()
 
-#ifdef MNH_OPENACC
-iztmp1_device = MNH_ALLOCATE_FLAT( ztmp1_device, JIU,JJU,JKU )
-iztmp2_device = MNH_ALLOCATE_FLAT( ztmp2_device, JIU,JJU,JKU )
-iztmp3_device = MNH_ALLOCATE_FLAT( ztmp3_device, JIU,JJU,JKU )
-iztmp4_device = MNH_ALLOCATE_FLAT( ztmp4_device, JIU,JJU,JKU )
-iztmp5_device = MNH_ALLOCATE_FLAT( ztmp5_device, JIU,JJU,JKU )
+CALL MNH_MEM_GET( zw1, JIU,JJU,JKU )
+CALL MNH_MEM_GET( zw2, JIU,JJU,JKU )
+
+CALL MNH_MEM_GET( ztmp1_device, JIU,JJU,JKU )
+CALL MNH_MEM_GET( ztmp2_device, JIU,JJU,JKU )
+CALL MNH_MEM_GET( ztmp3_device, JIU,JJU,JKU )
+CALL MNH_MEM_GET( ztmp4_device, JIU,JJU,JKU )
+CALL MNH_MEM_GET( ztmp5_device, JIU,JJU,JKU )
 #endif
 
 !$acc data present( zw1, zw2, ztmp1_device, ztmp2_device, ztmp3_device, ztmp4_device, ztmp5_device )
@@ -1263,7 +1260,8 @@ end if
 !$acc end data
 
 #ifdef MNH_OPENACC
-CALL MNH_RELEASE_FLAT( IZW1, IZW2, IZTMP1_DEVICE, IZTMP2_DEVICE, IZTMP3_DEVICE, IZTMP4_DEVICE, IZTMP5_DEVICE )
+!Release all memory allocated with MNH_MEM_GET calls since last call to MNH_MEM_POSITION_PIN
+call MNH_MEM_RELEASE()
 #else
 DEALLOCATE(ZW1,ZW2)
 #endif
diff --git a/src/MNH/rain_ice.f90 b/src/MNH/rain_ice.f90
index 4e6708e61d54dc4fb7d495a8d405a1d7aa6cabf6..dd8f5ccb6823c8d0024f7e35af8f4827b2057568 100644
--- a/src/MNH/rain_ice.f90
+++ b/src/MNH/rain_ice.f90
@@ -255,7 +255,7 @@ USE MODI_BITREP
 #endif
 USE MODI_ICE4_RAINFR_VERT
 #ifdef MNH_OPENACC
-USE MODE_MNH_ZWORK , ONLY : MNH_ALLOCATE_FLAT, MNH_RELEASE_FLAT, MNH_REL_GT1DFLAT, MNH_REL_IT1DFLAT
+USE MODE_MNH_ZWORK,                    ONLY: MNH_MEM_GET, MNH_MEM_POSITION_PIN, MNH_MEM_RELEASE
 #endif
 
 IMPLICIT NONE
@@ -336,15 +336,9 @@ INTEGER                           :: IKE,IKTE      !
 !
 INTEGER                           :: IMICRO
 INTEGER, DIMENSION(:), POINTER, CONTIGUOUS :: I1,I2,I3 ! Used to replace the COUNT
-#ifdef MNH_OPENACC
-INTEGER :: II1,II2,II3
-#endif
 INTEGER                           :: JL       ! and PACK intrinsics
 LOGICAL, DIMENSION(:,:,:), POINTER, CONTIGUOUS &
                                          :: GMICRO ! Test where to compute all processes
-#ifdef MNH_OPENACC
-INTEGER :: IGMICRO
-#endif
 REAL                              :: ZINVTSTEP
 REAL                              :: ZCOEFFRCM
 REAL, DIMENSION(:), POINTER, CONTIGUOUS   :: ZRVT    ! Water vapor m.r. at t
@@ -355,9 +349,6 @@ REAL, DIMENSION(:), POINTER, CONTIGUOUS   :: ZRST    ! Snow/aggregate m.r. at t
 REAL, DIMENSION(:), POINTER, CONTIGUOUS   :: ZRGT    ! Graupel m.r. at t
 REAL, DIMENSION(:), POINTER, CONTIGUOUS   :: ZRHT    ! Hail m.r. at t
 REAL, DIMENSION(:), POINTER, CONTIGUOUS   :: ZCIT    ! Pristine ice conc. at t
-#ifdef MNH_OPENACC
-INTEGER :: IZRVT,IZRCT,IZRRT,IZRIT,IZRST,IZRGT,IZRHT,IZCIT
-#endif
 !
 REAL, DIMENSION(:), POINTER, CONTIGUOUS   :: ZRVS    ! Water vapor m.r. source
 REAL, DIMENSION(:), POINTER, CONTIGUOUS   :: ZRCS    ! Cloud water m.r. source
@@ -369,9 +360,6 @@ REAL, DIMENSION(:), POINTER, CONTIGUOUS   :: ZRHS    ! Hail m.r. source
 REAL, DIMENSION(:), POINTER, CONTIGUOUS   :: ZTHS    ! Theta source
 REAL, DIMENSION(:), POINTER, CONTIGUOUS   :: ZTHT    ! Potential temperature
 REAL, DIMENSION(:), POINTER, CONTIGUOUS   :: ZTHLT   ! Liquid potential temperature
-#ifdef MNH_OPENACC
-INTEGER :: IZRVS,IZRCS,IZRRS,IZRIS,IZRSS,IZRGS,IZRHS,IZTHS,IZTHT,IZTHLT
-#endif
 !
 REAL, DIMENSION(:), POINTER, CONTIGUOUS   :: ZRHODREF, &      ! RHO Dry REFerence
                                      ZRHODJ,   &      ! RHO times Jacobian
@@ -410,23 +398,12 @@ REAL, DIMENSION(:), POINTER, CONTIGUOUS   :: ZRHODREF, &      ! RHO Dry REFerenc
                                      ZHLC_LRCLOCAL    ! HLCLOUDS : LWC that is Low  LWC local in LCF
                                                       !    note that ZRC/CF = ZHLC_HRCLOCAL+ ZHLC_LRCLOCAL
                                                       !                     = ZHLC_HRC/HCF+ ZHLC_LRC/LCF
-#ifdef MNH_OPENACC
-INTEGER :: IZRHODREF,IZZT,IZPRES,IZEXNREF,IZSIGMA_RC,IZCF,IZRF
-INTEGER :: IZHLC_HCF,IZHLC_LCF,IZHLC_HRC,IZHLC_LRC,IZHLC_RCMAX
-INTEGER :: IZRCRAUTC,IZHLC_HRCLOCAL,IZHLC_LRCLOCAL
-INTEGER :: IZZW,IZLSFACT,IZLVFACT,IZUSW,IZSSI,IZLBDAR,IZLBDAR_RF
-INTEGER :: IZLBDAS,IZLBDAG,IZLBDAH,IZRDRYG,IZRWETG,IZAI,IZCJ
-INTEGER :: IZKA,IZDV,IZRHODJ
-#endif
 
 REAL, DIMENSION(:,:,:), POINTER, CONTIGUOUS :: ZRR, ZRS, ZRG ! work arrays
 #ifdef MNH_OPENACC
 REAL, DIMENSION(:,:,:), POINTER, CONTIGUOUS :: ZRS_ZERO, ZRG_ZERO ! work arrays filled with zeros
 #endif
 REAL, DIMENSION(:,:,:), POINTER, CONTIGUOUS :: ZT ! Temperature
-#ifdef MNH_OPENACC
-INTEGER :: IZRR, IZRS, IZRG, IZRS_ZERO, IZRG_ZERO, IZT
-#endif
 
 INTEGER :: IIU,IJU,IKU, IIJKU
 !
@@ -500,9 +477,12 @@ IIJKU = IIU * IJU * IKU
 #ifndef MNH_OPENACC
 ALLOCATE( I1(SIZE(PEXNREF)), I2(SIZE(PEXNREF)), I3(SIZE(PEXNREF)) )
 #else
-II1 = MNH_ALLOCATE_FLAT( I1, IIJKU )
-II2 = MNH_ALLOCATE_FLAT( I2, IIJKU )
-II3 = MNH_ALLOCATE_FLAT( I3, IIJKU )
+!Pin positions in the pools of MNH memory
+CALL MNH_MEM_POSITION_PIN()
+
+CALL MNH_MEM_GET( I1, IIJKU )
+CALL MNH_MEM_GET( I2, IIJKU )
+CALL MNH_MEM_GET( I3, IIJKU )
 #endif
 
 #ifndef MNH_OPENACC
@@ -512,13 +492,13 @@ ALLOCATE( ZRS   (IIU,IJU,IKU) )
 ALLOCATE( ZRG   (IIU,IJU,IKU) )
 ALLOCATE( ZT    (IIU,IJU,IKU) )
 #else
-IGMICRO   = MNH_ALLOCATE_FLAT( GMICRO,  IIU,IJU,IKU )
-IZRR      = MNH_ALLOCATE_FLAT( ZRR,     IIU,IJU,IKU )
-IZRS      = MNH_ALLOCATE_FLAT( ZRS,     IIU,IJU,IKU )
-IZRG      = MNH_ALLOCATE_FLAT( ZRG,     IIU,IJU,IKU )
-IZRS_ZERO = MNH_ALLOCATE_FLAT( ZRS_ZERO,IIU,IJU,IKU )
-IZRG_ZERO = MNH_ALLOCATE_FLAT( ZRG_ZERO,IIU,IJU,IKU )
-IZT       = MNH_ALLOCATE_FLAT( ZT,      IIU,IJU,IKU )
+CALL MNH_MEM_GET( GMICRO,  IIU,IJU,IKU )
+CALL MNH_MEM_GET( ZRR,     IIU,IJU,IKU )
+CALL MNH_MEM_GET( ZRS,     IIU,IJU,IKU )
+CALL MNH_MEM_GET( ZRG,     IIU,IJU,IKU )
+CALL MNH_MEM_GET( ZRS_ZERO,IIU,IJU,IKU )
+CALL MNH_MEM_GET( ZRG_ZERO,IIU,IJU,IKU )
+CALL MNH_MEM_GET( ZT,      IIU,IJU,IKU )
 #endif
 
 !$acc data present( I1, I2, I3, GMICRO, ZRR, ZRS, ZRG, ZRS_ZERO, ZRG_ZERO, ZT )
@@ -652,73 +632,76 @@ IF( IMICRO >= 0 ) THEN
     ALLOCATE(ZRHODJ(0))
   END IF
 #else
-IZRVT  = MNH_ALLOCATE_FLAT(ZRVT,IMICRO)
-IZRCT  = MNH_ALLOCATE_FLAT(ZRCT,IMICRO)
-IZRRT  = MNH_ALLOCATE_FLAT(ZRRT,IMICRO)
-IZRIT  = MNH_ALLOCATE_FLAT(ZRIT,IMICRO)
-IZRST  = MNH_ALLOCATE_FLAT(ZRST,IMICRO)
-IZRGT  = MNH_ALLOCATE_FLAT(ZRGT,IMICRO)
+  !Pin positions in the pools of MNH memory
+  CALL MNH_MEM_POSITION_PIN()
+
+  CALL MNH_MEM_GET(ZRVT,IMICRO)
+  CALL MNH_MEM_GET(ZRCT,IMICRO)
+  CALL MNH_MEM_GET(ZRRT,IMICRO)
+  CALL MNH_MEM_GET(ZRIT,IMICRO)
+  CALL MNH_MEM_GET(ZRST,IMICRO)
+  CALL MNH_MEM_GET(ZRGT,IMICRO)
   IF ( KRR == 7 ) THEN
-IZRHT    = MNH_ALLOCATE_FLAT(ZRHT,IMICRO)
+    CALL MNH_MEM_GET(ZRHT,IMICRO)
   ELSE
-IZRHT    = MNH_ALLOCATE_FLAT(ZRHT,0)
+    CALL MNH_MEM_GET(ZRHT,0)
   END IF
-IZCIT  = MNH_ALLOCATE_FLAT(ZCIT,IMICRO)
-IZRVS  = MNH_ALLOCATE_FLAT(ZRVS,IMICRO)
-IZRCS  = MNH_ALLOCATE_FLAT(ZRCS,IMICRO)
-IZRRS  = MNH_ALLOCATE_FLAT(ZRRS,IMICRO)
-IZRIS  = MNH_ALLOCATE_FLAT(ZRIS,IMICRO)
-IZRSS  = MNH_ALLOCATE_FLAT(ZRSS,IMICRO)
-IZRGS  = MNH_ALLOCATE_FLAT(ZRGS,IMICRO)
+  CALL MNH_MEM_GET(ZCIT,IMICRO)
+  CALL MNH_MEM_GET(ZRVS,IMICRO)
+  CALL MNH_MEM_GET(ZRCS,IMICRO)
+  CALL MNH_MEM_GET(ZRRS,IMICRO)
+  CALL MNH_MEM_GET(ZRIS,IMICRO)
+  CALL MNH_MEM_GET(ZRSS,IMICRO)
+  CALL MNH_MEM_GET(ZRGS,IMICRO)
   IF ( KRR == 7 ) THEN
-IZRHS    = MNH_ALLOCATE_FLAT(ZRHS,IMICRO)
+    CALL MNH_MEM_GET(ZRHS,IMICRO)
   ELSE
-IZRHS    = MNH_ALLOCATE_FLAT(ZRHS,0)
+    CALL MNH_MEM_GET(ZRHS,0)
   END IF
-IZTHS  = MNH_ALLOCATE_FLAT(ZTHS,IMICRO)
-IZTHT  = MNH_ALLOCATE_FLAT(ZTHT,IMICRO)
-IZTHLT  = MNH_ALLOCATE_FLAT(ZTHLT,IMICRO)
-IZRHODREF  = MNH_ALLOCATE_FLAT(ZRHODREF,IMICRO)
-IZZT  = MNH_ALLOCATE_FLAT(ZZT,IMICRO)
-IZPRES  = MNH_ALLOCATE_FLAT(ZPRES,IMICRO)
-IZEXNREF  = MNH_ALLOCATE_FLAT(ZEXNREF,IMICRO)
-IZSIGMA_RC  = MNH_ALLOCATE_FLAT(ZSIGMA_RC,IMICRO)
-IZCF  = MNH_ALLOCATE_FLAT(ZCF,IMICRO)
-IZRF  = MNH_ALLOCATE_FLAT(ZRF,IMICRO)
-IZHLC_HCF  = MNH_ALLOCATE_FLAT(ZHLC_HCF,IMICRO)
-IZHLC_LCF  = MNH_ALLOCATE_FLAT(ZHLC_LCF,IMICRO)
-IZHLC_HRC  = MNH_ALLOCATE_FLAT(ZHLC_HRC,IMICRO)
-IZHLC_LRC  = MNH_ALLOCATE_FLAT(ZHLC_LRC,IMICRO)
-IZHLC_RCMAX  = MNH_ALLOCATE_FLAT(ZHLC_RCMAX,IMICRO)
-IZRCRAUTC  = MNH_ALLOCATE_FLAT(ZRCRAUTC,IMICRO)
-IZHLC_HRCLOCAL  = MNH_ALLOCATE_FLAT(ZHLC_HRCLOCAL,IMICRO)
-IZHLC_LRCLOCAL  = MNH_ALLOCATE_FLAT(ZHLC_LRCLOCAL,IMICRO)
-!
-IZZW  = MNH_ALLOCATE_FLAT(ZZW,IMICRO)
-IZLSFACT  = MNH_ALLOCATE_FLAT(ZLSFACT,IMICRO)
-IZLVFACT  = MNH_ALLOCATE_FLAT(ZLVFACT,IMICRO)
-IZUSW  = MNH_ALLOCATE_FLAT(ZUSW,IMICRO)
-IZSSI  = MNH_ALLOCATE_FLAT(ZSSI,IMICRO)
-IZLBDAR  = MNH_ALLOCATE_FLAT(ZLBDAR,IMICRO)
-IZLBDAR_RF  = MNH_ALLOCATE_FLAT(ZLBDAR_RF,IMICRO)
-IZLBDAS  = MNH_ALLOCATE_FLAT(ZLBDAS,IMICRO)
-IZLBDAG  = MNH_ALLOCATE_FLAT(ZLBDAG,IMICRO)
+  CALL MNH_MEM_GET(ZTHS,IMICRO)
+  CALL MNH_MEM_GET(ZTHT,IMICRO)
+  CALL MNH_MEM_GET(ZTHLT,IMICRO)
+  CALL MNH_MEM_GET(ZRHODREF,IMICRO)
+  CALL MNH_MEM_GET(ZZT,IMICRO)
+  CALL MNH_MEM_GET(ZPRES,IMICRO)
+  CALL MNH_MEM_GET(ZEXNREF,IMICRO)
+  CALL MNH_MEM_GET(ZSIGMA_RC,IMICRO)
+  CALL MNH_MEM_GET(ZCF,IMICRO)
+  CALL MNH_MEM_GET(ZRF,IMICRO)
+  CALL MNH_MEM_GET(ZHLC_HCF,IMICRO)
+  CALL MNH_MEM_GET(ZHLC_LCF,IMICRO)
+  CALL MNH_MEM_GET(ZHLC_HRC,IMICRO)
+  CALL MNH_MEM_GET(ZHLC_LRC,IMICRO)
+  CALL MNH_MEM_GET(ZHLC_RCMAX,IMICRO)
+  CALL MNH_MEM_GET(ZRCRAUTC,IMICRO)
+  CALL MNH_MEM_GET(ZHLC_HRCLOCAL,IMICRO)
+  CALL MNH_MEM_GET(ZHLC_LRCLOCAL,IMICRO)
+
+  CALL MNH_MEM_GET(ZZW,IMICRO)
+  CALL MNH_MEM_GET(ZLSFACT,IMICRO)
+  CALL MNH_MEM_GET(ZLVFACT,IMICRO)
+  CALL MNH_MEM_GET(ZUSW,IMICRO)
+  CALL MNH_MEM_GET(ZSSI,IMICRO)
+  CALL MNH_MEM_GET(ZLBDAR,IMICRO)
+  CALL MNH_MEM_GET(ZLBDAR_RF,IMICRO)
+  CALL MNH_MEM_GET(ZLBDAS,IMICRO)
+  CALL MNH_MEM_GET(ZLBDAG,IMICRO)
   IF ( KRR == 7 ) THEN
-IZLBDAH    = MNH_ALLOCATE_FLAT(ZLBDAH,IMICRO)
+    CALL MNH_MEM_GET(ZLBDAH,IMICRO)
   ELSE
-IZLBDAH    = MNH_ALLOCATE_FLAT(ZLBDAH,0)
+    CALL MNH_MEM_GET(ZLBDAH,0)
   END IF
-IZRDRYG  = MNH_ALLOCATE_FLAT(ZRDRYG,IMICRO)
-IZRWETG  = MNH_ALLOCATE_FLAT(ZRWETG,IMICRO)
-IZAI  = MNH_ALLOCATE_FLAT(ZAI,IMICRO)
-IZCJ  = MNH_ALLOCATE_FLAT(ZCJ,IMICRO)
-IZKA  = MNH_ALLOCATE_FLAT(ZKA,IMICRO)
-IZDV  = MNH_ALLOCATE_FLAT(ZDV,IMICRO)
+  CALL MNH_MEM_GET(ZRDRYG,IMICRO)
+  CALL MNH_MEM_GET(ZRWETG,IMICRO)
+  CALL MNH_MEM_GET(ZAI,IMICRO)
+  CALL MNH_MEM_GET(ZCJ,IMICRO)
+  CALL MNH_MEM_GET(ZKA,IMICRO)
+  CALL MNH_MEM_GET(ZDV,IMICRO)
 !
   IF (LBU_ENABLE .OR. LLES_CALL .OR. LCHECK ) THEN
-IZRHODJ    = MNH_ALLOCATE_FLAT(ZRHODJ,IMICRO)
+    CALL MNH_MEM_GET(ZRHODJ,IMICRO)
   ELSE
-IZRHODJ    = MNH_ALLOCATE_FLAT(ZRHODJ,0)
+    CALL MNH_MEM_GET(ZRHODJ,0)
   END IF
 #endif
  
@@ -1236,14 +1219,8 @@ IZRHODJ    = MNH_ALLOCATE_FLAT(ZRHODJ,0)
   DEALLOCATE(ZHLC_HRCLOCAL)
   DEALLOCATE(ZHLC_LRCLOCAL)
 #else
-  CALL MNH_RELEASE_FLAT(IZKA,IZDV,IZRHODJ)
-  CALL MNH_RELEASE_FLAT(IZLBDAS,IZLBDAG,IZLBDAH,IZRDRYG,IZRWETG,IZAI,IZCJ)
-  CALL MNH_RELEASE_FLAT(IZZW,IZLSFACT,IZLVFACT,IZUSW,IZSSI,IZLBDAR,IZLBDAR_RF)
-  CALL MNH_RELEASE_FLAT(IZRCRAUTC,IZHLC_HRCLOCAL,IZHLC_LRCLOCAL)
-  CALL MNH_RELEASE_FLAT(IZHLC_HCF,IZHLC_LCF,IZHLC_HRC,IZHLC_LRC,IZHLC_RCMAX)
-  CALL MNH_RELEASE_FLAT(IZRHODREF,IZZT,IZPRES,IZEXNREF,IZSIGMA_RC,IZCF,IZRF)
-  CALL MNH_RELEASE_FLAT(IZRVS,IZRCS,IZRRS,IZRIS,IZRSS,IZRGS,IZRHS,IZTHS,IZTHT,IZTHLT)
-  CALL MNH_RELEASE_FLAT(IZRVT,IZRCT,IZRRT,IZRIT,IZRST,IZRGT,IZRHT,IZCIT)
+  !Release all memory allocated with MNH_MEM_GET calls since last call to MNH_MEM_POSITION_PIN
+  CALL MNH_MEM_RELEASE()
 #endif
 END IF
 !
@@ -1310,11 +1287,8 @@ END IF
 DEALLOCATE ( I1,I2,I3 )
 DEALLOCATE ( GMICRO, ZRR, ZRS, ZRG, ZT )
 #else
-CALL MNH_REL_IT1DFLAT( II3 )
-CALL MNH_REL_IT1DFLAT( II2 )
-CALL MNH_REL_IT1DFLAT( II1 )
-CALL MNH_REL_GT1DFLAT ( IGMICRO )
-CALL MNH_RELEASE_FLAT( IZRR, IZRS, IZRG, IZRS_ZERO, IZRG_ZERO, IZT )
+!Release all memory allocated with MNH_MEM_GET calls since beginning of subroutine
+CALL MNH_MEM_RELEASE()
 #endif
 
 !$acc end data
diff --git a/src/MNH/rain_ice_nucleation.f90 b/src/MNH/rain_ice_nucleation.f90
index 494f012b1c9f0a5ec1c16184e2f2aaa95fb8c5fc..9b411edbfb81f6b2377f6549ac2ccc2e5744ffe8 100644
--- a/src/MNH/rain_ice_nucleation.f90
+++ b/src/MNH/rain_ice_nucleation.f90
@@ -46,7 +46,7 @@ use modi_bitrep
 #endif
 
 #ifdef MNH_OPENACC
-USE MODE_MNH_ZWORK,       ONLY: MNH_ALLOCATE_FLAT, MNH_RELEASE_FLAT, MNH_REL_GT1DFLAT, MNH_REL_IT1DFLAT
+USE MODE_MNH_ZWORK,       ONLY: MNH_MEM_GET, MNH_MEM_POSITION_PIN, MNH_MEM_RELEASE
 #endif
 
 IMPLICIT NONE
@@ -80,13 +80,7 @@ REAL, DIMENSION(:,:,:), OPTIONAL, INTENT(IN)    :: PRHT    ! Hail m.r. at t
 INTEGER                                :: INEGT
 INTEGER                                :: JL       ! and PACK intrinsics
 INTEGER, DIMENSION(:),     POINTER, CONTIGUOUS :: I1,I2,I3 ! Used to replace the COUNT
-#ifdef MNH_OPENACC
-INTEGER :: II1,II2,II3
-#endif
 LOGICAL, DIMENSION(:,:,:), POINTER, CONTIGUOUS :: GNEGT    ! Test where to compute the HEN process
-#ifdef MNH_OPENACC
-INTEGER :: IGNEGT
-#endif
 REAL                                   :: ZZWMAX
 REAL,    DIMENSION(:), POINTER, CONTIGUOUS     :: ZRVT     ! Water vapor m.r. at t
 REAL,    DIMENSION(:), POINTER, CONTIGUOUS     :: ZCIT     ! Pristine ice conc. at t
@@ -95,13 +89,7 @@ REAL,    DIMENSION(:), POINTER, CONTIGUOUS     :: ZZT,   & ! Temperature
                                           ZZW,   & ! Work array
                                           ZUSW,  & ! Undersaturation over water
                                           ZSSI     ! Supersaturation over ice
-#ifdef MNH_OPENACC
-INTEGER :: IZRVT,IZCIT,IZZT,IZPRES,IZZW,IZUSW,IZSSI
-#endif
 REAL,    DIMENSION(:,:,:), POINTER, CONTIGUOUS :: ZW      ! work array
-#ifdef MNH_OPENACC
-INTEGER :: IZW
-#endif
 
 INTEGER :: JIU,JJU,JKU, JIJKU
 
@@ -155,11 +143,14 @@ allocate( i3( JIJKU ) )
 allocate( gnegt( JIU,JJU,JKU ) )
 allocate( zw   ( JIU,JJU,JKU ) )
 #else
-II1 = MNH_ALLOCATE_FLAT( i1, JIJKU )
-II2 = MNH_ALLOCATE_FLAT( i2, JIJKU )
-II3 = MNH_ALLOCATE_FLAT( i3, JIJKU )
-IGNEGT = MNH_ALLOCATE_FLAT( gnegt, JIU,JJU,JKU )
-IZW =    MNH_ALLOCATE_FLAT( zw   , JIU,JJU,JKU )
+!Pin positions in the pools of MNH memory
+CALL MNH_MEM_POSITION_PIN()
+
+CALL MNH_MEM_GET( i1, JIJKU )
+CALL MNH_MEM_GET( i2, JIJKU )
+CALL MNH_MEM_GET( i3, JIJKU )
+CALL MNH_MEM_GET( gnegt, JIU,JJU,JKU )
+CALL MNH_MEM_GET( zw   , JIU,JJU,JKU )
 #endif
 
 !$acc data present( i1, i2, i3, gnegt, zw )
@@ -203,13 +194,16 @@ IF( INEGT >= 1 ) THEN
   ALLOCATE(ZUSW(INEGT))
   ALLOCATE(ZSSI(INEGT))
 #else
-  IZRVT   = MNH_ALLOCATE_FLAT( ZRVT,  INEGT )
-  IZCIT   = MNH_ALLOCATE_FLAT( ZCIT,  INEGT )
-  IZZT    = MNH_ALLOCATE_FLAT( ZZT,   INEGT )
-  IZPRES  = MNH_ALLOCATE_FLAT( ZPRES, INEGT )
-  IZZW    = MNH_ALLOCATE_FLAT( ZZW,   INEGT )
-  IZUSW   = MNH_ALLOCATE_FLAT( ZUSW,  INEGT )
-  IZSSI   = MNH_ALLOCATE_FLAT( ZSSI,  INEGT )
+  !Pin positions in the pools of MNH memory
+  CALL MNH_MEM_POSITION_PIN()
+
+  CALL MNH_MEM_GET( ZRVT,  INEGT )
+  CALL MNH_MEM_GET( ZCIT,  INEGT )
+  CALL MNH_MEM_GET( ZZT,   INEGT )
+  CALL MNH_MEM_GET( ZPRES, INEGT )
+  CALL MNH_MEM_GET( ZZW,   INEGT )
+  CALL MNH_MEM_GET( ZUSW,  INEGT )
+  CALL MNH_MEM_GET( ZSSI,  INEGT )
 #endif
   
 !$acc data present( zrvt, zcit, zzt, zpres, zzw, zusw, zssi )
@@ -348,9 +342,9 @@ END IF
   DEALLOCATE(ZCIT)
   DEALLOCATE(ZRVT)
 #else
-  CALL MNH_RELEASE_FLAT( izrvt, izcit, izzt, izpres, izzw, izusw, izssi )
-#endif  
-  
+  !Release all memory allocated with MNH_MEM_GET calls since last call to MNH_MEM_POSITION_PIN
+  CALL MNH_MEM_RELEASE()
+#endif
 END IF
 !
 !*       3.1.3   budget storage
@@ -372,11 +366,8 @@ END IF
 #ifndef MNH_OPENACC
 deallocate (i1, i2, i3, gnegt, zw )
 #else
-CALL MNH_REL_IT1DFLAT( ii3 )
-CALL MNH_REL_IT1DFLAT( ii2 )
-CALL MNH_REL_IT1DFLAT( ii1 )
-CALL MNH_REL_GT1DFLAT( IGNEGT )
-CALL MNH_RELEASE_FLAT( IZW )
+!Release all memory allocated with MNH_MEM_GET calls since beginning of subroutine
+CALL MNH_MEM_RELEASE()
 #endif
 !$acc end data
 
diff --git a/src/MNH/rain_ice_sedimentation_split.f90 b/src/MNH/rain_ice_sedimentation_split.f90
index 39ab2ffd7fd532840e09c60abf9eea5be34e511f..7e9471339418294952e1541d9a733ce7d80d0260 100644
--- a/src/MNH/rain_ice_sedimentation_split.f90
+++ b/src/MNH/rain_ice_sedimentation_split.f90
@@ -52,7 +52,7 @@ USE MODI_BITREP
 #endif
 
 #ifdef MNH_OPENACC
-USE MODE_MNH_ZWORK,      ONLY: MNH_ALLOCATE_FLAT, MNH_RELEASE_FLAT, MNH_REL_GT1DFLAT, MNH_REL_IT1DFLAT
+USE MODE_MNH_ZWORK,      ONLY: MNH_MEM_GET, MNH_MEM_POSITION_PIN, MNH_MEM_RELEASE
 #endif
 
 IMPLICIT NONE
@@ -106,22 +106,13 @@ INTEGER                                :: JL
 INTEGER, DIMENSION(:),     POINTER, CONTIGUOUS :: IC1, IC2, IC3 ! Used to replace the COUNT
 INTEGER, DIMENSION(:),     POINTER, CONTIGUOUS :: IR1, IR2, IR3 ! Used to replace the COUNT
 INTEGER, DIMENSION(:),     POINTER, CONTIGUOUS :: IS1, IS2, IS3 ! Used to replace the COUNT
-#ifdef MNH_OPENACC
-INTEGER :: IIC1, IIC2, IIC3, IIR1, IIR2, IIR3, IIS1, IIS2, IIS3
-#endif
 INTEGER, DIMENSION(:),     POINTER, CONTIGUOUS :: II1, II2, II3 ! Used to replace the COUNT
 INTEGER, DIMENSION(:),     POINTER, CONTIGUOUS :: IG1, IG2, IG3 ! Used to replace the COUNT
 INTEGER, DIMENSION(:),     POINTER, CONTIGUOUS :: IH1, IH2, IH3 ! Used to replace the COUNT
-#ifdef MNH_OPENACC
-INTEGER :: III1, III2, III3, IIG1, IIG2, IIG3, IIH1, IIH2, IIH3
-#endif
 
 LOGICAL                                :: GPRESENT_PFPR, GPRESENT_PSEA
 LOGICAL, DIMENSION(:,:),   POINTER, CONTIGUOUS :: GDEP
 LOGICAL, DIMENSION(:,:,:), POINTER, CONTIGUOUS :: GSEDIMR, GSEDIMC, GSEDIMI, GSEDIMS, GSEDIMG, GSEDIMH ! Where to compute the SED processes
-#ifdef MNH_OPENACC
-INTEGER :: IGDEP,IGSEDIMR, IGSEDIMC, IGSEDIMI, IGSEDIMS, IGSEDIMG, IGSEDIMH
-#endif
 REAL                                   :: ZINVTSTEP
 REAL                                   :: ZTSPLITR            ! Small time step for rain sedimentation
 REAL                                   :: ZTMP1, ZTMP2, ZTMP3 ! Intermediate variables
@@ -145,16 +136,10 @@ REAL,    DIMENSION(:,:),   POINTER, CONTIGUOUS :: ZOMPSEA,ZTMP1_2D,ZTMP2_2D,ZTMP
 REAL,    DIMENSION(:,:,:), POINTER, CONTIGUOUS :: ZRAY,   &   ! Cloud Mean radius
                                           ZLBC,   &   ! XLBC weighted by sea fraction
                                           ZFSEDC
-#ifdef MNH_OPENACC
-INTEGER :: IZCONC_TMP,IZCONC3D,IZOMPSEA,IZTMP1_2D,IZTMP2_2D,IZTMP3_2D,IZTMP4_2D,IZRAY,IZLBC,IZFSEDC
-#endif
 
 REAL,    DIMENSION(:,:,:), POINTER, CONTIGUOUS :: ZPRCS,ZPRRS,ZPRSS,ZPRGS,ZPRHS   ! Mixing ratios created during the time step
 REAL,    DIMENSION(:,:,:), POINTER, CONTIGUOUS :: ZW          ! Work array
 REAL,    DIMENSION(:,:,:), POINTER, CONTIGUOUS :: ZWSED       ! sedimentation fluxes
-#ifdef MNH_OPENACC
-INTEGER :: IZPRCS,IZPRRS,IZPRSS,IZPRGS,IZPRHS,IZW,IZWSED
-#endif
 
 INTEGER :: IIU,IJU,IKU, IIJKU
 !
@@ -215,24 +200,27 @@ ALLOCATE( II1(IIJKU), II2(IIJKU), II3(IIJKU) )
 ALLOCATE( IG1(IIJKU), IG2(IIJKU), IG3(IIJKU) )
 ALLOCATE( IH1(IIJKU), IH2(IIJKU), IH3(IIJKU) )
 #else
-IIC1 = MNH_ALLOCATE_FLAT(IC1,IIJKU)
-IIC2 = MNH_ALLOCATE_FLAT(IC2,IIJKU)
-IIC3 = MNH_ALLOCATE_FLAT(IC3,IIJKU)
-IIR1 = MNH_ALLOCATE_FLAT(IR1,IIJKU)
-IIR2 = MNH_ALLOCATE_FLAT(IR2,IIJKU)
-IIR3 = MNH_ALLOCATE_FLAT(IR3,IIJKU)
-IIS1 = MNH_ALLOCATE_FLAT(IS1,IIJKU)
-IIS2 = MNH_ALLOCATE_FLAT(IS2,IIJKU)
-IIS3 = MNH_ALLOCATE_FLAT(IS3,IIJKU)
-III1 = MNH_ALLOCATE_FLAT(II1,IIJKU)
-III2 = MNH_ALLOCATE_FLAT(II2,IIJKU)
-III3 = MNH_ALLOCATE_FLAT(II3,IIJKU)
-IIG1 = MNH_ALLOCATE_FLAT(IG1,IIJKU)
-IIG2 = MNH_ALLOCATE_FLAT(IG2,IIJKU)
-IIG3 = MNH_ALLOCATE_FLAT(IG3,IIJKU)
-IIH1 = MNH_ALLOCATE_FLAT(IH1,IIJKU)
-IIH2 = MNH_ALLOCATE_FLAT(IH2,IIJKU)
-IIH3 = MNH_ALLOCATE_FLAT(IH3,IIJKU)
+!Pin positions in the pools of MNH memory
+CALL MNH_MEM_POSITION_PIN()
+
+CALL MNH_MEM_GET(IC1,IIJKU)
+CALL MNH_MEM_GET(IC2,IIJKU)
+CALL MNH_MEM_GET(IC3,IIJKU)
+CALL MNH_MEM_GET(IR1,IIJKU)
+CALL MNH_MEM_GET(IR2,IIJKU)
+CALL MNH_MEM_GET(IR3,IIJKU)
+CALL MNH_MEM_GET(IS1,IIJKU)
+CALL MNH_MEM_GET(IS2,IIJKU)
+CALL MNH_MEM_GET(IS3,IIJKU)
+CALL MNH_MEM_GET(II1,IIJKU)
+CALL MNH_MEM_GET(II2,IIJKU)
+CALL MNH_MEM_GET(II3,IIJKU)
+CALL MNH_MEM_GET(IG1,IIJKU)
+CALL MNH_MEM_GET(IG2,IIJKU)
+CALL MNH_MEM_GET(IG3,IIJKU)
+CALL MNH_MEM_GET(IH1,IIJKU)
+CALL MNH_MEM_GET(IH2,IIJKU)
+CALL MNH_MEM_GET(IH3,IIJKU)
 #endif
 #ifndef MNH_OPENACC
 ALLOCATE( GDEP(IIU,IJU) )
@@ -243,13 +231,13 @@ ALLOCATE( GSEDIMS(IIU,IJU,IKU) )
 ALLOCATE( GSEDIMG(IIU,IJU,IKU) )
 ALLOCATE( GSEDIMH(IIU,IJU,IKU) )
 #else
-IGDEP    = MNH_ALLOCATE_FLAT( GDEP,IIU,IJU )
-IGSEDIMR = MNH_ALLOCATE_FLAT( GSEDIMR,IIU,IJU,IKU )
-IGSEDIMC = MNH_ALLOCATE_FLAT( GSEDIMC,IIU,IJU,IKU )
-IGSEDIMI = MNH_ALLOCATE_FLAT( GSEDIMI,IIU,IJU,IKU )
-IGSEDIMS = MNH_ALLOCATE_FLAT( GSEDIMS,IIU,IJU,IKU )
-IGSEDIMG = MNH_ALLOCATE_FLAT( GSEDIMG,IIU,IJU,IKU )
-IGSEDIMH = MNH_ALLOCATE_FLAT( GSEDIMH,IIU,IJU,IKU )
+CALL MNH_MEM_GET( GDEP,IIU,IJU )
+CALL MNH_MEM_GET( GSEDIMR,IIU,IJU,IKU )
+CALL MNH_MEM_GET( GSEDIMC,IIU,IJU,IKU )
+CALL MNH_MEM_GET( GSEDIMI,IIU,IJU,IKU )
+CALL MNH_MEM_GET( GSEDIMS,IIU,IJU,IKU )
+CALL MNH_MEM_GET( GSEDIMG,IIU,IJU,IKU )
+CALL MNH_MEM_GET( GSEDIMH,IIU,IJU,IKU )
 #endif
 ALLOCATE( ZRTMIN(SIZE(XRTMIN)) )
 #ifndef MNH_OPENACC
@@ -271,32 +259,32 @@ ALLOCATE( ZPRHS  (IIU,IJU,IKU) )
 ALLOCATE( ZW     (IIU,IJU,IKU) )
 ALLOCATE( ZWSED  (IIU,IJU,0:IKU+1) )
 #else
-IZCONC_TMP = MNH_ALLOCATE_FLAT( ZCONC_TMP,IIU,IJU )
-IZOMPSEA   = MNH_ALLOCATE_FLAT( ZOMPSEA  ,IIU,IJU )
-IZTMP1_2D  = MNH_ALLOCATE_FLAT( ZTMP1_2D ,IIU,IJU )
-IZTMP2_2D  = MNH_ALLOCATE_FLAT( ZTMP2_2D ,IIU,IJU )
-IZTMP3_2D  = MNH_ALLOCATE_FLAT( ZTMP3_2D ,IIU,IJU )
-IZTMP4_2D  = MNH_ALLOCATE_FLAT( ZTMP4_2D ,IIU,IJU )
-IZCONC3D   = MNH_ALLOCATE_FLAT( ZCONC3D,IIU,IJU,IKU )
-IZRAY      = MNH_ALLOCATE_FLAT( ZRAY   ,IIU,IJU,IKU )
-IZLBC      = MNH_ALLOCATE_FLAT( ZLBC   ,IIU,IJU,IKU )
-IZFSEDC    = MNH_ALLOCATE_FLAT( ZFSEDC ,IIU,IJU,IKU )
-IZPRCS     = MNH_ALLOCATE_FLAT( ZPRCS  ,IIU,IJU,IKU )
-IZPRRS     = MNH_ALLOCATE_FLAT( ZPRRS  ,IIU,IJU,IKU )
-IZPRSS     = MNH_ALLOCATE_FLAT( ZPRSS  ,IIU,IJU,IKU )
-IZPRGS     = MNH_ALLOCATE_FLAT( ZPRGS  ,IIU,IJU,IKU )
-IZPRHS     = MNH_ALLOCATE_FLAT( ZPRHS  ,IIU,IJU,IKU )
-IZW = MNH_ALLOCATE_FLAT( ZW     ,IIU,IJU,IKU )
-ALLOCATE( ZWSED  (IIU,IJU,0:IKU+1) )
+CALL MNH_MEM_GET( ZCONC_TMP,IIU,IJU )
+CALL MNH_MEM_GET( ZOMPSEA  ,IIU,IJU )
+CALL MNH_MEM_GET( ZTMP1_2D ,IIU,IJU )
+CALL MNH_MEM_GET( ZTMP2_2D ,IIU,IJU )
+CALL MNH_MEM_GET( ZTMP3_2D ,IIU,IJU )
+CALL MNH_MEM_GET( ZTMP4_2D ,IIU,IJU )
+CALL MNH_MEM_GET( ZCONC3D,IIU,IJU,IKU )
+CALL MNH_MEM_GET( ZRAY   ,IIU,IJU,IKU )
+CALL MNH_MEM_GET( ZLBC   ,IIU,IJU,IKU )
+CALL MNH_MEM_GET( ZFSEDC ,IIU,IJU,IKU )
+CALL MNH_MEM_GET( ZPRCS  ,IIU,IJU,IKU )
+CALL MNH_MEM_GET( ZPRRS  ,IIU,IJU,IKU )
+CALL MNH_MEM_GET( ZPRSS  ,IIU,IJU,IKU )
+CALL MNH_MEM_GET( ZPRGS  ,IIU,IJU,IKU )
+CALL MNH_MEM_GET( ZPRHS  ,IIU,IJU,IKU )
+CALL MNH_MEM_GET( ZW     ,IIU,IJU,IKU )
+CALL MNH_MEM_GET( ZWSED, 1, IIU, 1, IJU, 0, IKU+1 )
 #endif
 
 !$acc data present( IC1, IC2, IC3, IR1, IR2, IR3, IS1, IS2, IS3, II1, II2, II3, IG1, IG2, IG3, IH1, IH2, IH3,&
 !$acc &            GDEP, GSEDIMR, GSEDIMC,  GSEDIMI,  GSEDIMS,  GSEDIMG,  GSEDIMH )                          &
-!$acc &    create( ZRTMIN , ZWSED )                                                                          &
+!$acc &    create( ZRTMIN )                                                                                  &
 !$acc &    present(ZCONC_TMP,                                                                                &
 !$acc &            ZOMPSEA, ZTMP1_2D, ZTMP2_2D, ZTMP3_2D, ZTMP4_2D, ZCONC3D,                                 &
 !$acc &            ZRAY, ZLBC, ZFSEDC,                                                                       &
-!$acc &            ZPRCS, ZPRRS, ZPRSS, ZPRGS, ZPRHS, ZW                                                     )
+!$acc &            ZPRCS, ZPRRS, ZPRSS, ZPRGS, ZPRHS, ZW, ZWSED                                              )
 
 IF ( PRESENT( PFPR ) ) THEN
   GPRESENT_PFPR = .TRUE.
@@ -762,46 +750,15 @@ END IF
 
 #ifndef MNH_OPENACC
 DEALLOCATE(IC1, IC2, IC3, IR1, IR2, IR3, IS1, IS2, IS3, II1, II2, II3, IG1, IG2, IG3, IH1, IH2, IH3)
-#else
-CALL MNH_REL_IT1DFLAT( IIH3 )
-CALL MNH_REL_IT1DFLAT( IIH2 )
-CALL MNH_REL_IT1DFLAT( IIH1 )
-CALL MNH_REL_IT1DFLAT( IIG3 )
-CALL MNH_REL_IT1DFLAT( IIG2 )
-CALL MNH_REL_IT1DFLAT( IIG1 )
-CALL MNH_REL_IT1DFLAT( III3 )
-CALL MNH_REL_IT1DFLAT( III2 )
-CALL MNH_REL_IT1DFLAT( III1 )
-CALL MNH_REL_IT1DFLAT( IIS3 )
-CALL MNH_REL_IT1DFLAT( IIS2 )
-CALL MNH_REL_IT1DFLAT( IIS1 )
-CALL MNH_REL_IT1DFLAT( IIR3 )
-CALL MNH_REL_IT1DFLAT( IIR2 )
-CALL MNH_REL_IT1DFLAT( IIR1 )
-CALL MNH_REL_IT1DFLAT( IIC3 )
-CALL MNH_REL_IT1DFLAT( IIC2 )
-CALL MNH_REL_IT1DFLAT( IIC1 )
-#endif
-#ifndef MNH_OPENACC
 DEALLOCATE(GDEP, GSEDIMR, GSEDIMC,  GSEDIMI,  GSEDIMS,  GSEDIMG,  GSEDIMH)
-#else
-CALL MNH_REL_GT1DFLAT( IGSEDIMH )
-CALL MNH_REL_GT1DFLAT( IGSEDIMG )
-CALL MNH_REL_GT1DFLAT( IGSEDIMS )
-CALL MNH_REL_GT1DFLAT( IGSEDIMI )
-CALL MNH_REL_GT1DFLAT( IGSEDIMC )
-CALL MNH_REL_GT1DFLAT( IGSEDIMR )
-CALL MNH_REL_GT1DFLAT( IGDEP    )
-#endif
 DEALLOCATE(ZRTMIN)
-#ifndef MNH_OPENACC
 DEALLOCATE(ZCONC_TMP,ZOMPSEA, ZTMP1_2D, ZTMP2_2D, ZTMP3_2D, ZTMP4_2D, ZCONC3D)
 DEALLOCATE(ZRAY, ZLBC, ZFSEDC,ZPRCS, ZPRRS, ZPRSS, ZPRGS, ZPRHS, ZW)
+DEALLOCATE(ZWSED)
 #else
-CALL MNH_RELEASE_FLAT( IZRAY, IZLBC, IZFSEDC,IZPRCS, IZPRRS, IZPRSS, IZPRGS, IZPRHS, IZW )
-CALL MNH_RELEASE_FLAT( IZCONC_TMP, IZOMPSEA, IZTMP1_2D, IZTMP2_2D, IZTMP3_2D, IZTMP4_2D, IZCONC3D )
+!Release all memory allocated with MNH_MEM_GET calls since last call to MNH_MEM_POSITION_PIN
+CALL MNH_MEM_RELEASE()
 #endif
-DEALLOCATE(ZWSED)
 
 !$acc end data
 
diff --git a/src/MNH/resolved_cloud.f90 b/src/MNH/resolved_cloud.f90
index 02b590708e9a06cdd7447e403c154c06a8c9485c..e8e69e2f54f6b85944b4d83e2f2302d45b27b253 100644
--- a/src/MNH/resolved_cloud.f90
+++ b/src/MNH/resolved_cloud.f90
@@ -339,7 +339,7 @@ USE MODI_SHUMAN_DEVICE
 #endif
 USE MODI_SLOW_TERMS
 #ifdef MNH_OPENACC
-USE MODE_MNH_ZWORK,      ONLY: MNH_ALLOCATE_FLAT, MNH_RELEASE_FLAT, MNH_REL_GT1DFLAT
+USE MODE_MNH_ZWORK,      ONLY: MNH_MEM_GET, MNH_MEM_POSITION_PIN, MNH_MEM_RELEASE
 #endif
 !
 IMPLICIT NONE
@@ -475,9 +475,6 @@ INTEGER :: JI,JJ,JK,JL
 REAL, DIMENSION(:,:,:), POINTER , CONTIGUOUS :: ZDZZ
 REAL, DIMENSION(:,:,:), POINTER , CONTIGUOUS :: ZEXN
 REAL, DIMENSION(:,:,:), POINTER , CONTIGUOUS :: ZZZ
-#ifdef MNH_OPENACC
-INTEGER :: IZDZZ, IZEXN, IZZZ
-#endif
                                     ! model layer height
 ! REAL  :: ZMASSTOT                   ! total mass  for one water category
 !                                     ! including the negative values
@@ -490,9 +487,6 @@ INTEGER                               :: ISVEND ! last  scalar index for microph
 REAL, DIMENSION(:),        ALLOCATABLE          :: ZRSMIN ! Minimum value for tendencies
 LOGICAL, DIMENSION(:,:,:), POINTER , CONTIGUOUS :: LLMICRO ! mask to limit computation
 REAL, DIMENSION(:,:,:,:),  POINTER , CONTIGUOUS :: ZFPR
-#ifdef MNH_OPENACC
-INTEGER :: ILLMICRO, IZFPR
-#endif
 !
 INTEGER                               :: JMOD, JMOD_IFN
 LOGICAL                               :: GWEST,GEAST,GNORTH,GSOUTH
@@ -502,9 +496,6 @@ REAL, DIMENSION(:,:,:),   POINTER , CONTIGUOUS :: ZICEFR
 REAL, DIMENSION(:,:,:),   POINTER , CONTIGUOUS :: ZPRCFR
 REAL, DIMENSION(:,:,:),   POINTER , CONTIGUOUS :: ZTHSSTEP
 REAL, DIMENSION(:,:,:,:), POINTER , CONTIGUOUS :: ZRSSTEP
-#ifdef MNH_OPENACC
-INTEGER :: IZINPRI, IZICEFR, IZPRCFR, IZTHSSTEP, IZRSSTEP
-#endif
 !
 INTEGER  :: JIU,JJU,JKU
 !
@@ -609,28 +600,31 @@ allocate ( ZINPRI   ( JIU,JJU ) )
 allocate ( ZTHSSTEP ( SIZE(PTHS,1), SIZE(PTHS,2), SIZE(PTHS,3) ) )
 allocate ( ZRSSTEP  ( SIZE(PRS,1),  SIZE(PRS,2),  SIZE(PRS,3), SIZE(PRS,4) ) )
 #else
-ILLMICRO  = MNH_ALLOCATE_FLAT( LLMICRO   ,JIU,JJU,JKU )
-IZDZZ     = MNH_ALLOCATE_FLAT( ZDZZ      ,JIU,JJU,JKU )
+!Pin positions in the pools of MNH memory
+CALL MNH_MEM_POSITION_PIN()
+
+CALL MNH_MEM_GET( LLMICRO   ,JIU,JJU,JKU )
+CALL MNH_MEM_GET( ZDZZ      ,JIU,JJU,JKU )
 if ( hcloud == 'ICE3' .or. hcloud == 'ICE4' ) then
-  IZEXN     = MNH_ALLOCATE_FLAT( ZEXN    ,JIU,JJU,JKU )
-  IZFPR     = MNH_ALLOCATE_FLAT( ZFPR    ,JIU,JJU,JKU,KRR )
+  CALL MNH_MEM_GET( ZEXN    ,JIU,JJU,JKU )
+  CALL MNH_MEM_GET( ZFPR    ,JIU,JJU,JKU,KRR )
 else
-  IZEXN     = MNH_ALLOCATE_FLAT( ZEXN    ,0,0,0 )
-  IZFPR     = MNH_ALLOCATE_FLAT( ZFPR    ,0,0,0,0 )
+  CALL MNH_MEM_GET( ZEXN    ,0,0,0 )
+  CALL MNH_MEM_GET( ZFPR    ,0,0,0,0 )
 end if
 
 if ( hcloud == 'LIMA' .and. lptsplit ) then
-  IZICEFR   = MNH_ALLOCATE_FLAT( ZICEFR  ,JIU,JJU,JKU )
-  IZPRCFR   = MNH_ALLOCATE_FLAT( ZPRCFR  ,JIU,JJU,JKU )
+  CALL MNH_MEM_GET( ZICEFR  ,JIU,JJU,JKU )
+  CALL MNH_MEM_GET( ZPRCFR  ,JIU,JJU,JKU )
 else
-  IZICEFR   = MNH_ALLOCATE_FLAT( ZICEFR  ,0,0,0 )
-  IZPRCFR   = MNH_ALLOCATE_FLAT( ZPRCFR  ,0,0,0 )
+  CALL MNH_MEM_GET( ZICEFR  ,0,0,0 )
+  CALL MNH_MEM_GET( ZPRCFR  ,0,0,0 )
 end if
 
-IZZZ      = MNH_ALLOCATE_FLAT( ZZZ       ,JIU,JJU,JKU )
-IZINPRI   = MNH_ALLOCATE_FLAT( ZINPRI    ,JIU,JJU )
-IZTHSSTEP = MNH_ALLOCATE_FLAT( ZTHSSTEP , SIZE(PTHS,1), SIZE(PTHS,2), SIZE(PTHS,3) )
-IZRSSTEP  = MNH_ALLOCATE_FLAT( ZRSSTEP  , SIZE(PRS,1),  SIZE(PRS,2), SIZE(PRS,3), SIZE(PRS,4) )
+CALL MNH_MEM_GET( ZZZ       ,JIU,JJU,JKU )
+CALL MNH_MEM_GET( ZINPRI    ,JIU,JJU )
+CALL MNH_MEM_GET( ZTHSSTEP , SIZE(PTHS,1), SIZE(PTHS,2), SIZE(PTHS,3) )
+CALL MNH_MEM_GET( ZRSSTEP  , SIZE(PRS,1),  SIZE(PRS,2), SIZE(PRS,3), SIZE(PRS,4) )
 #endif
 
 
@@ -1302,16 +1296,8 @@ deallocate( ZEXN )
 deallocate( ZDZZ )
 deallocate( LLMICRO )
 #else
-CALL MNH_RELEASE_FLAT( IZRSSTEP )
-CALL MNH_RELEASE_FLAT( IZTHSSTEP )
-CALL MNH_RELEASE_FLAT( IZINPRI )
-CALL MNH_RELEASE_FLAT( IZZZ )
-CALL MNH_RELEASE_FLAT( IZPRCFR )
-CALL MNH_RELEASE_FLAT( IZICEFR )
-CALL MNH_RELEASE_FLAT( IZFPR )
-CALL MNH_RELEASE_FLAT( IZEXN )
-CALL MNH_RELEASE_FLAT( IZDZZ )
-CALL MNH_REL_GT1DFLAT( ILLMICRO )
+!Release all memory allocated with MNH_MEM_GET calls since last call to MNH_MEM_POSITION_PIN
+CALL MNH_MEM_RELEASE()
 #endif
 
 !$acc end data
diff --git a/src/MNH/sources_neg_correct.f90 b/src/MNH/sources_neg_correct.f90
index e1aca301746c5536a4f9b43907f1a77e72c0d359..5eb676fc262539d6ca591cc5f57e373a3fe7c0e6 100644
--- a/src/MNH/sources_neg_correct.f90
+++ b/src/MNH/sources_neg_correct.f90
@@ -31,9 +31,9 @@ use modd_nsv,        only: nsv_c2r2beg, nsv_c2r2end, nsv_lima_beg, nsv_lima_end,
 use modd_param_lima, only: lcold_lima => lcold, lrain_lima => lrain, lspro_lima => lspro, lwarm_lima => lwarm, &
                            xctmin_lima => xctmin, xrtmin_lima => xrtmin
 
-use mode_budget,         only: Budget_store_init, Budget_store_end
+use mode_budget,     only: Budget_store_init, Budget_store_end
 #ifdef MNH_OPENACC
-use mode_mnh_zwork,  only: Mnh_allocate_flat , Mnh_release_flat
+use mode_mnh_zwork,  only: Mnh_mem_get, Mnh_mem_position_pin, Mnh_mem_release
 #endif
 use mode_mppdb
 use mode_msg
@@ -63,9 +63,6 @@ integer :: jrmax
 integer :: jsv
 integer :: isv_lima_end
 real, dimension(:, :, :), pointer, contiguous :: zt, zexn, zlv, zls, zcph, zcor
-#ifdef MNH_OPENACC
-integer :: izt, izexn, izlv, izls, izcph, izcor
-#endif
 
 if ( krr == 0 ) return
 
@@ -173,20 +170,23 @@ else
 end if
 if ( .not. Associated( zcor ) ) Allocate( zcor(0, 0, 0) )
 #else
-izt   = Mnh_allocate_flat( zt,   jiu, jju, jku )
-izexn = Mnh_allocate_flat( zexn, jiu, jju, jku )
-izlv  = Mnh_allocate_flat( zlv,  jiu, jju, jku )
-izcph = Mnh_allocate_flat( zcph, jiu, jju, jku )
+!Pin positions in the pools of MNH memory
+call Mnh_mem_position_pin()
+
+call Mnh_mem_get( zt,   jiu, jju, jku )
+call Mnh_mem_get( zexn, jiu, jju, jku )
+call Mnh_mem_get( zlv,  jiu, jju, jku )
+call Mnh_mem_get( zcph, jiu, jju, jku )
 if ( hcloud == 'ICE3' .or. hcloud == 'ICE4' .or. hcloud == 'LIMA' ) then
-  izls = Mnh_allocate_flat( zls, jiu, jju, jku )
+  call Mnh_mem_get( zls, jiu, jju, jku )
   if ( krr > 3 ) then
-    izcor = Mnh_allocate_flat( zcor, jiu, jju, jku )
+    call Mnh_mem_get( zcor, jiu, jju, jku )
   else
-    izcor = Mnh_allocate_flat( zcor, 0, 0, 0 )
+    call Mnh_mem_get( zcor, 0, 0, 0 )
   end if
 else
-  izls  = Mnh_allocate_flat( zls,  0, 0, 0 )
-  izcor = Mnh_allocate_flat( zcor, 0, 0, 0 )
+  call Mnh_mem_get( zls,  0, 0, 0 )
+  call Mnh_mem_get( zcor, 0, 0, 0 )
 end if
 #endif
 
@@ -411,7 +411,8 @@ end select CLOUD
 #ifndef MNH_OPENACC
 deallocate( zexn, zlv, zcph, zls, zcor )
 #else
-call Mnh_release_flat ( izt, izexn, izlv, izcph, izls, izcor )
+!Release all memory allocated with Mnh_mem_get calls since last call to Mnh_mem_position_pin
+call Mnh_mem_release()
 #endif
 
 if ( hbudname /= 'NECON' .and. hbudname /= 'NEGA' ) then
diff --git a/src/MNH/tke_eps_sources.f90 b/src/MNH/tke_eps_sources.f90
index 1d427f976859ba57b27b84445b7219faf99c5ca2..b9c038e697c516180e60442cf01585aaf9fa8f17 100644
--- a/src/MNH/tke_eps_sources.f90
+++ b/src/MNH/tke_eps_sources.f90
@@ -187,7 +187,7 @@ use mode_budget,         only: Budget_store_add, Budget_store_end, Budget_store_
 USE MODE_EXCHANGE_ll,    ONLY: UPDATE_HALO_ll
 USE MODE_IO_FIELD_WRITE, only: IO_Field_write
 #ifdef MNH_OPENACC
-USE MODE_MNH_ZWORK,      ONLY: MNH_ALLOCATE_FLAT, MNH_RELEASE_FLAT
+USE MODE_MNH_ZWORK,      ONLY: MNH_MEM_GET, MNH_MEM_POSITION_PIN, MNH_MEM_RELEASE
 #endif
 use mode_mppdb
 !
@@ -256,9 +256,6 @@ REAL, DIMENSION(:,:,:), pointer , contiguous ::         &
        ZFLX,     & ! horizontal or vertical flux of the treated variable
        ZSOURCE,  & ! source of evolution for the treated variable
        ZKEFF       ! effectif diffusion coeff = LT * SQRT( TKE )
-#ifdef MNH_OPENACC
-INTEGER ::  IZA,IZRES,IZFLX,IZSOURCE,IZKEFF
-#endif
 INTEGER             :: IIB,IIE,IJB,IJE,IKB,IKE
                                     ! Index values for the Beginning and End
                                     ! mass points of the domain 
@@ -270,7 +267,6 @@ TYPE(TFIELDDATA) :: TZFIELD
 !
 #ifdef MNH_OPENACC
 REAL, DIMENSION(:,:,:), pointer , contiguous :: ZTMP1_DEVICE, ZTMP2_DEVICE, ZTMP3_DEVICE, ZTMP4_DEVICE
-INTEGER :: IZTMP1_DEVICE, IZTMP2_DEVICE, IZTMP3_DEVICE, IZTMP4_DEVICE
 #endif
 !
 INTEGER  :: JIU,JJU,JKU
@@ -315,18 +311,19 @@ allocate( zflx   (JIU,JJU,JKU ) )
 allocate( zsource(JIU,JJU,JKU ) )
 allocate( zkeff  (JIU,JJU,JKU ) )
 #else
-iza      = MNH_ALLOCATE_FLAT( za     ,JIU,JJU,JKU)
-izres    = MNH_ALLOCATE_FLAT( zres   ,JIU,JJU,JKU)
-izflx    = MNH_ALLOCATE_FLAT( zflx   ,JIU,JJU,JKU)
-izsource = MNH_ALLOCATE_FLAT( zsource,JIU,JJU,JKU)
-izkeff   = MNH_ALLOCATE_FLAT( zkeff  ,JIU,JJU,JKU)
-#endif
+!Pin positions in the pools of MNH memory
+CALL MNH_MEM_POSITION_PIN()
 
-#ifdef MNH_OPENACC
-iztmp1_device = MNH_ALLOCATE_FLAT( ztmp1_device,JIU,JJU,JKU)
-iztmp2_device = MNH_ALLOCATE_FLAT( ztmp2_device,JIU,JJU,JKU)
-iztmp3_device = MNH_ALLOCATE_FLAT( ztmp3_device,JIU,JJU,JKU)
-iztmp4_device = MNH_ALLOCATE_FLAT( ztmp4_device,JIU,JJU,JKU)
+CALL MNH_MEM_GET( za     ,JIU,JJU,JKU)
+CALL MNH_MEM_GET( zres   ,JIU,JJU,JKU)
+CALL MNH_MEM_GET( zflx   ,JIU,JJU,JKU)
+CALL MNH_MEM_GET( zsource,JIU,JJU,JKU)
+CALL MNH_MEM_GET( zkeff  ,JIU,JJU,JKU)
+
+CALL MNH_MEM_GET( ztmp1_device,JIU,JJU,JKU)
+CALL MNH_MEM_GET( ztmp2_device,JIU,JJU,JKU)
+CALL MNH_MEM_GET( ztmp3_device,JIU,JJU,JKU)
+CALL MNH_MEM_GET( ztmp4_device,JIU,JJU,JKU)
 #endif
 
 !$acc data present( ZA, ZRES, ZFLX, ZSOURCE, ZKEFF, ZTMP1_DEVICE, ZTMP2_DEVICE, ZTMP3_DEVICE, ZTMP4_DEVICE )
@@ -675,7 +672,8 @@ end if
 #ifndef MNH_OPENACC
 deallocate( ZA, ZRES, ZFLX, ZSOURCE, ZKEFF )
 #else
-CALL MNH_RELEASE_FLAT( IZA, IZRES, IZFLX, IZSOURCE, IZKEFF, IZTMP1_DEVICE, IZTMP2_DEVICE, IZTMP3_DEVICE, IZTMP4_DEVICE )
+!Release all memory allocated with MNH_MEM_GET calls since last call to MNH_MEM_POSITION_PIN
+CALL MNH_MEM_RELEASE()
 #endif
 
 !$acc end data
diff --git a/src/MNH/tridiag_thermo.f90 b/src/MNH/tridiag_thermo.f90
index b7462995ab901cec46ef8542d071f4a2429e092e..5cf3bb25b7d0468e5750d5d548b4ae063febd078 100644
--- a/src/MNH/tridiag_thermo.f90
+++ b/src/MNH/tridiag_thermo.f90
@@ -158,7 +158,7 @@ USE MODI_BITREP
 #endif
 !
 #ifdef MNH_OPENACC
-USE MODE_MNH_ZWORK , ONLY : MNH_ALLOCATE_FLAT , MNH_RELEASE_FLAT
+USE MODE_MNH_ZWORK, ONLY: MNH_MEM_GET, MNH_MEM_POSITION_PIN, MNH_MEM_RELEASE
 #endif
 !
 IMPLICIT NONE
@@ -186,13 +186,7 @@ REAL, DIMENSION(:,:,:), pointer , contiguous :: ZMZM_RHODJ
 REAL, DIMENSION(:,:,:), pointer , contiguous :: ZA, ZB, ZC
 REAL, DIMENSION(:,:,:), pointer , contiguous :: ZY ,ZGAM
                                          ! RHS of the equation, 3D work array
-#ifdef MNH_OPENACC
-INTEGER :: IZRHODJ_DFDDTDZ_O_DZ2,IZMZM_RHODJ,IZA,IZB,IZC,IZY,IZGAM
-#endif
 REAL, DIMENSION(:,:), pointer , contiguous   :: ZBET
-#ifdef MNH_OPENACC
-INTEGER :: IZBET
-#endif
                                          ! 2D work array
 INTEGER             :: JI,JJ,JK      ! loop counter
 INTEGER             :: IKB,IKE       ! inner vertical limits
@@ -202,7 +196,6 @@ INTEGER             :: IKTB,IKTE    ! start, end of k loops in physical domain
 !
 #ifdef MNH_OPENACC
 REAL, DIMENSION(:,:,:), pointer , contiguous :: ZTMP1_DEVICE
-INTEGER :: IZTMP1_DEVICE
 #endif
 
 INTEGER  :: JIU,JJU,JKU
@@ -234,18 +227,19 @@ allocate( zy                  (JIU,JJU,JKU ) )
 allocate( zgam                (JIU,JJU,JKU ) )
 allocate( zbet                (JIU,JJU ) )
 #else
-izrhodj_dfddtdz_o_dz2 = MNH_ALLOCATE_FLAT( zrhodj_dfddtdz_o_dz2, JIU, JJU, JKU )
-izmzm_rhodj           = MNH_ALLOCATE_FLAT( zmzm_rhodj          , JIU, JJU, JKU )
-iza                   = MNH_ALLOCATE_FLAT( za                  , JIU, JJU, JKU )
-izb                   = MNH_ALLOCATE_FLAT( zb                  , JIU, JJU, JKU )
-izc                   = MNH_ALLOCATE_FLAT( zc                  , JIU, JJU, JKU )
-izy                   = MNH_ALLOCATE_FLAT( zy                  , JIU, JJU, JKU )
-izgam                 = MNH_ALLOCATE_FLAT( zgam                , JIU, JJU, JKU )
-izbet                 = MNH_ALLOCATE_FLAT( zbet                , JIU, JJU )
-#endif
+!Pin positions in the pools of MNH memory
+CALL MNH_MEM_POSITION_PIN()
 
-#ifdef MNH_OPENACC
-iztmp1_device = MNH_ALLOCATE_FLAT( ztmp1_device, JIU, JJU, JKU )
+CALL MNH_MEM_GET( zrhodj_dfddtdz_o_dz2, JIU, JJU, JKU )
+CALL MNH_MEM_GET( zmzm_rhodj          , JIU, JJU, JKU )
+CALL MNH_MEM_GET( za                  , JIU, JJU, JKU )
+CALL MNH_MEM_GET( zb                  , JIU, JJU, JKU )
+CALL MNH_MEM_GET( zc                  , JIU, JJU, JKU )
+CALL MNH_MEM_GET( zy                  , JIU, JJU, JKU )
+CALL MNH_MEM_GET( zgam                , JIU, JJU, JKU )
+CALL MNH_MEM_GET( zbet                , JIU, JJU )
+
+CALL MNH_MEM_GET( ztmp1_device, JIU, JJU, JKU )
 #endif
 
 !$acc data present( zrhodj_dfddtdz_o_dz2, zmzm_rhodj, za, zb, zc, zy, zgam, zbet, ztmp1_device )
@@ -482,8 +476,8 @@ end if
 #ifndef MNH_OPENACC
 deallocate (zrhodj_dfddtdz_o_dz2,zmzm_rhodj,za,zb,zc,zy,zgam,zbet)
 #else
-CALL MNH_RELEASE_FLAT( IZRHODJ_DFDDTDZ_O_DZ2, IZMZM_RHODJ, IZA, IZB, IZC, IZY, IZGAM, &
-                       IZBET, iztmp1_device )
+!Release all memory allocated with MNH_MEM_GET calls since last call to MNH_MEM_POSITION_PIN
+CALL MNH_MEM_RELEASE()
 #endif
 
 !$acc end data
diff --git a/src/MNH/tridiag_tke.f90 b/src/MNH/tridiag_tke.f90
index 87251eada65f31b54c4426723eb42a284b73cb15..b4fa21b73e7b9f7b468ed74c32474b9fb82b681e 100644
--- a/src/MNH/tridiag_tke.f90
+++ b/src/MNH/tridiag_tke.f90
@@ -143,7 +143,7 @@ USE MODD_PARAMETERS
 USE MODE_MPPDB
 !
 #ifdef MNH_OPENACC
-USE MODE_MNH_ZWORK,  ONLY: MNH_ALLOCATE_FLAT, MNH_RELEASE_FLAT
+USE MODE_MNH_ZWORK,      ONLY: MNH_MEM_GET, MNH_MEM_POSITION_PIN, MNH_MEM_RELEASE
 #endif
 !
 IMPLICIT NONE
@@ -173,9 +173,6 @@ INTEGER             :: IKT          ! array size in k direction
 INTEGER             :: IKTB,IKTE    ! start, end of k loops in physical domain
 REAL, DIMENSION(:,:,:), pointer , contiguous :: ZY ,ZGAM ! RHS of the equation, 3D work array
 REAL, DIMENSION(:,:),   pointer , contiguous :: ZBET     ! 2D work array
-#ifdef MNH_OPENACC
-INTEGER :: IZY ,IZGAM, IZBET
-#endif
 !
 INTEGER  :: JIU,JJU,JKU
 ! ---------------------------------------------------------------------------
@@ -200,9 +197,12 @@ allocate( zy  (JIU,JJU,JKU ) )
 allocate( zgam(JIU,JJU,JKU ) )
 allocate( zbet(JIU,JJU ) )
 #else
-izy   = MNH_ALLOCATE_FLAT( zy  , JIU, JJU, JKU )
-izgam = MNH_ALLOCATE_FLAT( zgam, JIU, JJU, JKU )
-izbet = MNH_ALLOCATE_FLAT( zbet, JIU, JJU )
+!Pin positions in the pools of MNH memory
+CALL MNH_MEM_POSITION_PIN()
+
+CALL MNH_MEM_GET( zy  , JIU, JJU, JKU )
+CALL MNH_MEM_GET( zgam, JIU, JJU, JKU )
+CALL MNH_MEM_GET( zbet, JIU, JJU )
 #endif
 
 !$acc data present( ZY, ZGAM, ZBET )
@@ -350,7 +350,8 @@ end if
 #ifndef MNH_OPENACC
 deallocate( ZY, ZGAM, ZBET )
 #else
-CALL MNH_RELEASE_FLAT( IZY, IZGAM, IZBET )
+!Release all memory allocated with MNH_MEM_GET calls since last call to MNH_MEM_POSITION_PIN
+CALL MNH_MEM_RELEASE()
 #endif
 
 !$acc end data
diff --git a/src/MNH/tridiag_w.f90 b/src/MNH/tridiag_w.f90
index 4a572e2c986d5aafee3978ce8dc2a0791512eee9..56796decfc2f9aed3f91f0f12e1553e0533f9490 100644
--- a/src/MNH/tridiag_w.f90
+++ b/src/MNH/tridiag_w.f90
@@ -162,7 +162,7 @@ USE MODI_BITREP
 #endif
 !
 #ifdef MNH_OPENACC
-USE MODE_MNH_ZWORK,  ONLY: MNH_ALLOCATE_FLAT, MNH_RELEASE_FLAT
+USE MODE_MNH_ZWORK,      ONLY: MNH_MEM_GET, MNH_MEM_POSITION_PIN, MNH_MEM_RELEASE
 #endif
 !
 IMPLICIT NONE
@@ -186,9 +186,6 @@ REAL, DIMENSION(:,:,:), pointer , contiguous :: ZMZM_RHODJ
 REAL, DIMENSION(:,:,:), pointer , contiguous :: ZA, ZB, ZC
 REAL, DIMENSION(:,:,:), pointer , contiguous :: ZY ,ZGAM ! RHS of the equation, 3D work array
 REAL, DIMENSION(:,:),   pointer , contiguous :: ZBET     ! 2D work array
-#ifdef MNH_OPENACC
-INTEGER :: IZRHODJ_DFDDWDZ_O_DZ2,IZMZM_RHODJ,IZA, IZB, IZC,IZY ,IZGAM,IZBET
-#endif
 !
 INTEGER                              :: JK            ! loop counter
 INTEGER                              :: IKB,IKE       ! inner vertical limits
@@ -222,14 +219,17 @@ allocate( zy                  (JIU,JJU,JKU ) )
 allocate( zgam                (JIU,JJU,JKU ) )
 allocate( zbet                (JIU,JJU ) )
 #else
-izrhodj_dfddwdz_o_dz2 = MNH_ALLOCATE_FLAT( zrhodj_dfddwdz_o_dz2,JIU,JJU,JKU )
-izmzm_rhodj           = MNH_ALLOCATE_FLAT( zmzm_rhodj          ,JIU,JJU,JKU )
-iza                   = MNH_ALLOCATE_FLAT( za                  ,JIU,JJU,JKU )
-izb                   = MNH_ALLOCATE_FLAT( zb                  ,JIU,JJU,JKU )
-izc                   = MNH_ALLOCATE_FLAT( zc                  ,JIU,JJU,JKU )
-izy                   = MNH_ALLOCATE_FLAT( zy                  ,JIU,JJU,JKU )
-izgam                 = MNH_ALLOCATE_FLAT( zgam                ,JIU,JJU,JKU )
-izbet                 = MNH_ALLOCATE_FLAT( zbet                ,JIU,JJU )
+!Pin positions in the pools of MNH memory
+CALL MNH_MEM_POSITION_PIN()
+
+CALL MNH_MEM_GET( zrhodj_dfddwdz_o_dz2,JIU,JJU,JKU )
+CALL MNH_MEM_GET( zmzm_rhodj          ,JIU,JJU,JKU )
+CALL MNH_MEM_GET( za                  ,JIU,JJU,JKU )
+CALL MNH_MEM_GET( zb                  ,JIU,JJU,JKU )
+CALL MNH_MEM_GET( zc                  ,JIU,JJU,JKU )
+CALL MNH_MEM_GET( zy                  ,JIU,JJU,JKU )
+CALL MNH_MEM_GET( zgam                ,JIU,JJU,JKU )
+CALL MNH_MEM_GET( zbet                ,JIU,JJU )
 #endif 
 
 !$acc data present( ZRHODJ_DFDDWDZ_O_DZ2, ZMZM_RHODJ, ZA, ZB, ZC, ZY, ZGAM, ZBET )
@@ -464,7 +464,8 @@ end if
 #ifndef MNH_OPENACC
 deallocate (ZRHODJ_DFDDWDZ_O_DZ2, ZMZM_RHODJ, ZA, ZB, ZC, ZY, ZGAM, ZBET)
 #else
-CALL MNH_RELEASE_FLAT( IZRHODJ_DFDDWDZ_O_DZ2, IZMZM_RHODJ, IZA, IZB, IZC, IZY, IZGAM, IZBET )
+!Release all memory allocated with MNH_MEM_GET calls since last call to MNH_MEM_POSITION_PIN
+CALL MNH_MEM_RELEASE()
 #endif
 
 
diff --git a/src/MNH/tridiag_wind.f90 b/src/MNH/tridiag_wind.f90
index 7e3c0dfce6c9207d969094c0d19a644f2c10c988..d0c16c3fb3b16ca54f69a215d3b08cb83a0d8997 100644
--- a/src/MNH/tridiag_wind.f90
+++ b/src/MNH/tridiag_wind.f90
@@ -149,7 +149,7 @@ USE MODD_PARAMETERS
 use mode_mppdb
 
 #ifdef MNH_OPENACC
-USE MODE_MNH_ZWORK,  ONLY: MNH_ALLOCATE_FLAT, MNH_RELEASE_FLAT
+USE MODE_MNH_ZWORK,      ONLY: MNH_MEM_GET, MNH_MEM_POSITION_PIN, MNH_MEM_RELEASE
 #endif
 
 IMPLICIT NONE
@@ -179,9 +179,6 @@ INTEGER             :: IKT          ! array size in k direction
 INTEGER             :: IKTB,IKTE    ! start, end of k loops in physical domain
 REAL, DIMENSION(:,:,:), pointer , contiguous :: ZY ,ZGAM ! RHS of the equation, 3D work array
 REAL, DIMENSION(:,:),   pointer , contiguous :: ZBET     ! 2D work array
-#ifdef MNH_OPENACC
-INTEGER :: IZY ,IZGAM, IZBET
-#endif
 !
 INTEGER  :: JIU,JJU,JKU
 !
@@ -207,9 +204,12 @@ allocate( zy  (JIU,JJU,JKU ) )
 allocate( zgam(JIU,JJU,JKU ) )
 allocate( zbet(JIU,JJU ) )
 #else
-izy   = MNH_ALLOCATE_FLAT( zy  , JIU, JJU, JKU )
-izgam = MNH_ALLOCATE_FLAT( zgam, JIU, JJU, JKU )
-izbet = MNH_ALLOCATE_FLAT( zbet, JIU, JJU )
+!Pin positions in the pools of MNH memory
+CALL MNH_MEM_POSITION_PIN()
+
+CALL MNH_MEM_GET( zy  , JIU, JJU, JKU )
+CALL MNH_MEM_GET( zgam, JIU, JJU, JKU )
+CALL MNH_MEM_GET( zbet, JIU, JJU )
 #endif
 
 !$acc data present( ZY, ZGAM, ZBET )
@@ -350,7 +350,8 @@ end if
 #ifndef MNH_OPENACC
 deallocate ( zy,zgam,zbet )
 #else
-CALL MNH_RELEASE_FLAT( izy, izgam, izbet )
+!Release all memory allocated with MNH_MEM_GET calls since last call to MNH_MEM_POSITION_PIN
+CALL MNH_MEM_RELEASE()
 #endif
 
 !$acc end data
diff --git a/src/MNH/turb.f90 b/src/MNH/turb.f90
index 753c9c42ccf4ffb5aefdefc9c2145fba10c6be5c..5fb7783864178765c28a69e7382125d3fb32220e 100644
--- a/src/MNH/turb.f90
+++ b/src/MNH/turb.f90
@@ -9,7 +9,7 @@ module mode_turb
 
 #ifdef MNH_OPENACC
   use mode_msg
-  USE MODE_MNH_ZWORK, ONLY: MNH_ALLOCATE_FLAT, MNH_RELEASE_FLAT
+  USE MODE_MNH_ZWORK, ONLY: MNH_MEM_GET, MNH_MEM_POSITION_PIN, MNH_MEM_RELEASE
 #endif
 
 #ifdef MNH_BITREP
@@ -418,11 +418,6 @@ REAL, POINTER , CONTIGUOUS, DIMENSION(:,:,:) ::&
           ZMWTH,ZMWR,ZMTH2,ZMR2,ZMTHR,&  ! 3rd order moments
           ZFWTH,ZFWR,ZFTH2,ZFR2,ZFTHR,&  ! opposite of verticale derivate of 3rd order moments
           ZTHLM                          ! initial potential temp.
-#ifdef MNH_OPENACC
-INTEGER :: IZCP,IZEXN,IZT,IZLOCPEXNM,IZLEPS,IZTRH,IZATHETA,IZAMOIST &
-          ,IZCOEF_DISS,IZFRAC_ICE,IZMWTH,IZMWR,IZMTH2,IZMR2,IZMTHR &
-          ,IZFWTH,IZFWR,IZFTH2,IZFR2,IZFTHR,IZTHLM
-#endif
 !
 REAL, POINTER , CONTIGUOUS, DIMENSION(:,:,:,:) ::     &
           ZRM                            ! initial mixing ratio
@@ -441,16 +436,9 @@ REAL, POINTER , CONTIGUOUS, DIMENSION(:,:) ::  ZTAU11M,ZTAU12M,  &
 !
             ! Virtual Potential Temp. used
             ! in the Deardorff mixing length computation
-#ifdef MNH_OPENACC
-INTEGER :: IZRM,IZTAU11M,IZTAU12M,IZTAU22M,IZTAU33M,IZUSLOPE,IZVSLOPE &
-          ,IZCDUEFF,IZUSTAR,IZLMO,IZRVM,IZSFRV
-#endif
 REAL, DIMENSION(:,:,:), POINTER , CONTIGUOUS  :: &
           ZLVOCPEXNM,ZLSOCPEXNM,      &  ! Lv/Cp/EXNREF and Ls/Cp/EXNREF at t-1
           ZATHETA_ICE,ZAMOIST_ICE        ! coefficients for s = f (Thetal,Rnp)
-#ifdef MNH_OPENACC
-INTEGER :: IZLVOCPEXNM,IZLSOCPEXNM,IZATHETA_ICE,IZAMOIST_ICE
-#endif
 !
 REAL                :: ZEXPL        ! 1-PIMPL deg of expl.
 REAL                :: ZRVORD       ! RV/RD
@@ -469,14 +457,10 @@ REAL                :: ZALPHA       ! work coefficient :
 REAL :: ZTIME1, ZTIME2
 REAL, DIMENSION(:,:,:), pointer , contiguous :: ZTT,ZEXNE,ZLV,ZCPH
 REAL, DIMENSION(:,:,:), pointer , contiguous :: ZSHEAR, ZDUDZ, ZDVDZ
-#ifdef MNH_OPENACC
-INTEGER :: IZTT,IZEXNE,IZLV,IZCPH,IZSHEAR, IZDUDZ, IZDVDZ
-#endif
 TYPE(TFIELDDATA) :: TZFIELD
 !
 #ifdef MNH_OPENACC
 REAL, DIMENSION(:,:,:), pointer , contiguous :: ZTMP1_DEVICE,ZTMP2_DEVICE,ZTMP3_DEVICE
-INTEGER :: IZTMP1_DEVICE,IZTMP2_DEVICE,IZTMP3_DEVICE
 #endif
 !
 INTEGER  :: JIU,JJU,JKU
@@ -615,74 +599,74 @@ allocate( zdudz (JIU,JJU, JKU_TURB ) )
 allocate( zdvdz (JIU,JJU, JKU_TURB ) )
 
 #else
-IZCP        = MNH_ALLOCATE_FLAT( ZCP,        JIU, JJU, JKU )
-IZEXN       = MNH_ALLOCATE_FLAT( ZEXN,       JIU, JJU, JKU )
-IZT         = MNH_ALLOCATE_FLAT( ZT,         JIU, JJU, JKU )
-IZLOCPEXNM  = MNH_ALLOCATE_FLAT( ZLOCPEXNM,  JIU, JJU, JKU )
-IZLEPS      = MNH_ALLOCATE_FLAT( ZLEPS,      JIU, JJU, JKU )
-IZTRH       = MNH_ALLOCATE_FLAT( ZTRH,       JIU, JJU, JKU )
-IZATHETA    = MNH_ALLOCATE_FLAT( ZATHETA,    JIU, JJU, JKU )
-IZAMOIST    = MNH_ALLOCATE_FLAT( ZAMOIST,    JIU, JJU, JKU )
-IZCOEF_DISS = MNH_ALLOCATE_FLAT( ZCOEF_DISS, JIU, JJU, JKU )
-IZFRAC_ICE  = MNH_ALLOCATE_FLAT( ZFRAC_ICE,  JIU, JJU, JKU )
-
-IZMWTH = MNH_ALLOCATE_FLAT( ZMWTH, JIU, JJU, JKU )
-IZMWR  = MNH_ALLOCATE_FLAT( ZMWR,  JIU, JJU, JKU )
-IZMTH2 = MNH_ALLOCATE_FLAT( ZMTH2, JIU, JJU, JKU )
-IZMR2  = MNH_ALLOCATE_FLAT( ZMR2,  JIU, JJU, JKU )
-IZMTHR = MNH_ALLOCATE_FLAT( ZMTHR, JIU, JJU, JKU )
-
-IZFWTH = MNH_ALLOCATE_FLAT( ZFWTH, JIU, JJU, JKU )
-IZFWR  = MNH_ALLOCATE_FLAT( ZFWR,  JIU, JJU, JKU )
-IZFTH2 = MNH_ALLOCATE_FLAT( ZFTH2, JIU, JJU, JKU )
-IZFR2  = MNH_ALLOCATE_FLAT( ZFR2,  JIU, JJU, JKU )
-IZFTHR = MNH_ALLOCATE_FLAT( ZFTHR, JIU, JJU, JKU )
-IZTHLM = MNH_ALLOCATE_FLAT( ZTHLM, JIU, JJU, JKU )
+!Pin positions in the pools of MNH memory
+CALL MNH_MEM_POSITION_PIN()
+
+CALL MNH_MEM_GET( ZCP,        JIU, JJU, JKU )
+CALL MNH_MEM_GET( ZEXN,       JIU, JJU, JKU )
+CALL MNH_MEM_GET( ZT,         JIU, JJU, JKU )
+CALL MNH_MEM_GET( ZLOCPEXNM,  JIU, JJU, JKU )
+CALL MNH_MEM_GET( ZLEPS,      JIU, JJU, JKU )
+CALL MNH_MEM_GET( ZTRH,       JIU, JJU, JKU )
+CALL MNH_MEM_GET( ZATHETA,    JIU, JJU, JKU )
+CALL MNH_MEM_GET( ZAMOIST,    JIU, JJU, JKU )
+CALL MNH_MEM_GET( ZCOEF_DISS, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ZFRAC_ICE,  JIU, JJU, JKU )
+
+CALL MNH_MEM_GET( ZMWTH, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ZMWR,  JIU, JJU, JKU )
+CALL MNH_MEM_GET( ZMTH2, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ZMR2,  JIU, JJU, JKU )
+CALL MNH_MEM_GET( ZMTHR, JIU, JJU, JKU )
+
+CALL MNH_MEM_GET( ZFWTH, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ZFWR,  JIU, JJU, JKU )
+CALL MNH_MEM_GET( ZFTH2, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ZFR2,  JIU, JJU, JKU )
+CALL MNH_MEM_GET( ZFTHR, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ZTHLM, JIU, JJU, JKU )
 
 JLU_ZRM = 0 
 IF ( HTURBLEN == 'BL89' .OR. HTURBLEN == 'RM17' .OR. ORMC01 ) JLU_ZRM = SIZE(PRT,4)
-IZRM = MNH_ALLOCATE_FLAT( ZRM, JIU, JJU, JKU, JLU_ZRM )
+CALL MNH_MEM_GET( ZRM, JIU, JJU, JKU, JLU_ZRM )
 
-IZTAU11M = MNH_ALLOCATE_FLAT( ZTAU11M, JIU, JJU )
-IZTAU12M = MNH_ALLOCATE_FLAT( ZTAU12M, JIU, JJU )
-IZTAU22M = MNH_ALLOCATE_FLAT( ZTAU22M, JIU, JJU )
-IZTAU33M = MNH_ALLOCATE_FLAT( ZTAU33M, JIU, JJU )
-IZUSLOPE = MNH_ALLOCATE_FLAT( ZUSLOPE, JIU, JJU )
-IZVSLOPE = MNH_ALLOCATE_FLAT( ZVSLOPE, JIU, JJU )
-IZCDUEFF = MNH_ALLOCATE_FLAT( ZCDUEFF, JIU, JJU )
-IZLMO    = MNH_ALLOCATE_FLAT( ZLMO,    JIU, JJU )
+CALL MNH_MEM_GET( ZTAU11M, JIU, JJU )
+CALL MNH_MEM_GET( ZTAU12M, JIU, JJU )
+CALL MNH_MEM_GET( ZTAU22M, JIU, JJU )
+CALL MNH_MEM_GET( ZTAU33M, JIU, JJU )
+CALL MNH_MEM_GET( ZUSLOPE, JIU, JJU )
+CALL MNH_MEM_GET( ZVSLOPE, JIU, JJU )
+CALL MNH_MEM_GET( ZCDUEFF, JIU, JJU )
+CALL MNH_MEM_GET( ZLMO,    JIU, JJU )
 
 JJU_ORMC01 = 0
 IF (ORMC01) JJU_ORMC01 = SIZE(PTHLT,2)
-IZUSTAR = MNH_ALLOCATE_FLAT( ZUSTAR, JIU, JJU_ORMC01 )
-IZRVM   = MNH_ALLOCATE_FLAT( ZRVM,   JIU, JJU_ORMC01 )
-IZSFRV  = MNH_ALLOCATE_FLAT( ZSFRV,  JIU, JJU_ORMC01 )
+CALL MNH_MEM_GET( ZUSTAR, JIU, JJU_ORMC01 )
+CALL MNH_MEM_GET( ZRVM,   JIU, JJU_ORMC01 )
+CALL MNH_MEM_GET( ZSFRV,  JIU, JJU_ORMC01 )
 
 JKU_CLOUD = 0 
 IF ( HCLOUD == 'KHKO' .OR. HCLOUD == 'C2R2' ) JKU_CLOUD = size( put, 3 )
-iztt   = MNH_ALLOCATE_FLAT( ztt,   JIU, JJU, JKU_CLOUD )
-izexne = MNH_ALLOCATE_FLAT( zexne, JIU, JJU, JKU_CLOUD )
-izlv   = MNH_ALLOCATE_FLAT( zlv,   JIU, JJU, JKU_CLOUD )
-izcph  = MNH_ALLOCATE_FLAT( zcph,  JIU, JJU, JKU_CLOUD )
+CALL MNH_MEM_GET( ztt,   JIU, JJU, JKU_CLOUD )
+CALL MNH_MEM_GET( zexne, JIU, JJU, JKU_CLOUD )
+CALL MNH_MEM_GET( zlv,   JIU, JJU, JKU_CLOUD )
+CALL MNH_MEM_GET( zcph,  JIU, JJU, JKU_CLOUD )
 
 JKU_TURB = 0  
 IF ( HTURBLEN == 'BL89' .OR. HTURBLEN == 'RM17' ) JKU_TURB = size( put, 3 )
-izshear = MNH_ALLOCATE_FLAT( zshear, JIU, JJU, JKU_TURB )
+CALL MNH_MEM_GET( zshear, JIU, JJU, JKU_TURB )
 
 JKU_TURB = 0
 IF ( HTURBLEN == 'RM17' ) JKU_TURB = size( put, 3 )
-izdudz = MNH_ALLOCATE_FLAT( zdudz, JIU, JJU, JKU_TURB )
-izdvdz = MNH_ALLOCATE_FLAT( zdvdz, JIU, JJU, JKU_TURB )
-
-#endif
+CALL MNH_MEM_GET( zdudz, JIU, JJU, JKU_TURB )
+CALL MNH_MEM_GET( zdvdz, JIU, JJU, JKU_TURB )
 
-#ifdef MNH_OPENACC
-iztmp1_device = MNH_ALLOCATE_FLAT( ztmp1_device, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ztmp1_device, JIU, JJU, JKU )
 
 JKU_TURB = 0
 IF (HTURBDIM=="1DIM") JKU_TURB = size( pthlt, 3 )
-iztmp2_device = MNH_ALLOCATE_FLAT( ztmp2_device, JIU, JJU, JKU_TURB )
-iztmp3_device = MNH_ALLOCATE_FLAT( ztmp3_device, JIU, JJU, JKU_TURB )
+CALL MNH_MEM_GET( ztmp2_device, JIU, JJU, JKU_TURB )
+CALL MNH_MEM_GET( ztmp3_device, JIU, JJU, JKU_TURB )
 
 #endif
 
@@ -1604,21 +1588,8 @@ deallocate( zcp, zexn, zt, zlocpexnm, zleps, ztrh,         &
             zustar, zrvm, zsfrv,                           &
             ztt, zexne, zlv, zcph, zshear,  zdudz,  zdvdz  )
 #else
-
-CALL MNH_RELEASE_FLAT( iztt, izexne, izlv, izcph, izshear,  izdudz,  izdvdz, &
-                       iztmp1_device, iztmp2_device, iztmp3_device       )
-
-CALL MNH_RELEASE_FLAT( iztau11m, iztau12m, iztau22m, iztau33m,   &
-                       izuslope, izvslope, izcdueff, izlmo,      &
-                       izustar, izrvm, izsfrv                   )
-
-CALL MNH_RELEASE_FLAT( izrm)
-
-CALL MNH_RELEASE_FLAT( izmwth, izmwr, izmth2, izmr2, izmthr,        &
-                       izfwth, izfwr, izfth2, izfr2, izfthr, izthlm )
-
-CALL MNH_RELEASE_FLAT( izcp, izexn, izt, izlocpexnm, izleps, iztrh, &
-                       izatheta, izamoist, izcoef_diss, izfrac_ice  )
+!Release all memory allocated with MNH_MEM_GET calls since last call to MNH_MEM_POSITION_PIN
+CALL MNH_MEM_RELEASE()
 #endif
 
 !$acc end data
@@ -1764,9 +1735,6 @@ REAL, DIMENSION(:,:,:), INTENT(OUT)   :: PAMOIST,PATHETA
 REAL                :: ZEPS         ! XMV / XMD
 real, dimension(:,:,:), pointer , contiguous :: zrvsat
 real, dimension(:,:,:), pointer , contiguous :: zdrvsatdt
-#ifdef MNH_OPENACC
-INTEGER :: izrvsat, izdrvsatdt
-#endif
 !
 !-------------------------------------------------------------------------------
 
@@ -1783,8 +1751,11 @@ INTEGER :: izrvsat, izdrvsatdt
   allocate( zrvsat   ( size( pexn, 1 ), size( pexn, 2 ), size( pexn, 3 ) ) )
   allocate( zdrvsatdt( size( pexn, 1 ), size( pexn, 2 ), size( pexn, 3 ) ) )
 #else
-izrvsat    = MNH_ALLOCATE_FLAT( zrvsat   , size( pexn, 1 ), size( pexn, 2 ), size( pexn, 3 ) )
-izdrvsatdt = MNH_ALLOCATE_FLAT( zdrvsatdt, size( pexn, 1 ), size( pexn, 2 ), size( pexn, 3 ) )
+!Pin positions in the pools of MNH memory
+CALL MNH_MEM_POSITION_PIN()
+
+CALL MNH_MEM_GET( zrvsat   , size( pexn, 1 ), size( pexn, 2 ), size( pexn, 3 ) )
+CALL MNH_MEM_GET( zdrvsatdt, size( pexn, 1 ), size( pexn, 2 ), size( pexn, 3 ) )
 #endif
 
 !$acc data present( zrvsat, zdrvsatdt )
@@ -1859,7 +1830,8 @@ izdrvsatdt = MNH_ALLOCATE_FLAT( zdrvsatdt, size( pexn, 1 ), size( pexn, 2 ), siz
 #ifndef MNH_OPENACC 
   deallocate( zrvsat, zdrvsatdt )
 #else
-  CALL MNH_RELEASE_FLAT( izrvsat, izdrvsatdt )
+  !Release all memory allocated with MNH_MEM_GET calls since last call to MNH_MEM_POSITION_PIN
+  CALL MNH_MEM_RELEASE()
 #endif
  
 !$acc end data
@@ -2350,13 +2322,9 @@ REAL, DIMENSION(:,:,:), POINTER , CONTIGUOUS ::     &
             ZDTHLDZ,ZDRTDZ,     &!dtheta_l/dz, drt_dz used for computing the stablity
 !                                ! criterion
             ZETHETA,ZEMOIST             !coef ETHETA and EMOIST
-#ifdef MNH_OPENACC
-INTEGER :: IZWORK2D,IZDTHLDZ,IZDRTDZ,IZETHETA,IZEMOIST
-#endif
 !
 #ifdef MNH_OPENACC
 REAL, DIMENSION(:,:,:), POINTER , CONTIGUOUS :: ZTMP1_DEVICE,ZTMP2_DEVICE
-INTEGER :: IZTMP1_DEVICE,IZTMP2_DEVICE
 #endif
 INTEGER  :: JIU,JJU,JKU
 LOGICAL :: GOCEAN !Intermediate variable used to work around a Cray compiler bug (CCE 13.0.0)
@@ -2395,16 +2363,17 @@ allocate( ZDRTDZ (JIU,JJU,JKU) )
 allocate( ZETHETA(JIU,JJU,JKU) )
 allocate( ZEMOIST(JIU,JJU,JKU) )
 #else
-IZWORK2D = MNH_ALLOCATE_FLAT( ZWORK2D, JIU, JJU )
-IZDTHLDZ = MNH_ALLOCATE_FLAT( ZDTHLDZ, JIU, JJU, JKU )
-IZDRTDZ  = MNH_ALLOCATE_FLAT( ZDRTDZ,  JIU, JJU, JKU )
-IZETHETA = MNH_ALLOCATE_FLAT( ZETHETA, JIU, JJU, JKU )
-IZEMOIST = MNH_ALLOCATE_FLAT( ZEMOIST, JIU, JJU, JKU )
-#endif
+!Pin positions in the pools of MNH memory
+CALL MNH_MEM_POSITION_PIN()
 
-#ifdef MNH_OPENACC
-IZTMP1_DEVICE = MNH_ALLOCATE_FLAT( ZTMP1_DEVICE, JIU, JJU, JKU )
-IZTMP2_DEVICE = MNH_ALLOCATE_FLAT( ZTMP2_DEVICE, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ZWORK2D, JIU, JJU )
+CALL MNH_MEM_GET( ZDTHLDZ, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ZDRTDZ,  JIU, JJU, JKU )
+CALL MNH_MEM_GET( ZETHETA, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ZEMOIST, JIU, JJU, JKU )
+
+CALL MNH_MEM_GET( ZTMP1_DEVICE, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ZTMP2_DEVICE, JIU, JJU, JKU )
 #endif
 
 !$acc data present(zwork2d, zdthldz, zdrtdz, zetheta, zemoist, &
@@ -2619,8 +2588,8 @@ end if
 #ifndef MNH_OPENACC
 deallocate(zwork2d, zdthldz, zdrtdz, zetheta, zemoist ) 
 #else
-CALL MNH_RELEASE_FLAT( izwork2d, izdthldz, izdrtdz, izetheta, izemoist, &
-                       iztmp1_device, iztmp2_device )
+!Release all memory allocated with MNH_MEM_GET calls since last call to MNH_MEM_POSITION_PIN
+CALL MNH_MEM_RELEASE()
 #endif
 
 !$acc end data
diff --git a/src/MNH/turb_hor_dyn_corr.f90 b/src/MNH/turb_hor_dyn_corr.f90
index 9803af84270e37a21dd1375c85cce8e007232ae8..902dd306be4d3fd679e5bb002519706c25d2c2a7 100644
--- a/src/MNH/turb_hor_dyn_corr.f90
+++ b/src/MNH/turb_hor_dyn_corr.f90
@@ -153,7 +153,7 @@ USE MODD_NSV
 USE MODE_IO_FIELD_WRITE, only: IO_Field_write
 USE MODE_ll
 #ifdef MNH_OPENACC
-USE MODE_MNH_ZWORK,      ONLY: MNH_ALLOCATE_FLAT, MNH_RELEASE_FLAT
+USE MODE_MNH_ZWORK,      ONLY: MNH_MEM_GET, MNH_MEM_POSITION_PIN, MNH_MEM_RELEASE
 #endif
 use mode_mppdb
 !
@@ -233,9 +233,6 @@ REAL, DIMENSION(:,:,:), pointer , contiguous :: ZFLX,ZWORK ! work arrays, PK is
 !
 REAL, DIMENSION(:,:),   pointer , contiguous :: ZDIRSINZW
       ! sinus of the angle between the vertical and the normal to the orography
-#ifdef MNH_OPENACC
-INTEGER :: IZFLX,IZWORK,IZDIRSINZW
-#endif
 INTEGER             :: IKB,IKE
                                     ! Index values for the Beginning and End
                                     ! mass points of the domain  
@@ -246,9 +243,6 @@ REAL, DIMENSION(:,:,:), pointer , contiguous :: GX_U_M_PUM
 REAL, DIMENSION(:,:,:), pointer , contiguous :: GY_V_M_PVM
 REAL, DIMENSION(:,:,:), pointer , contiguous :: GZ_W_M_PWM
 REAL, DIMENSION(:,:,:), pointer , contiguous :: GZ_W_M_ZWP
-#ifdef MNH_OPENACC
-INTEGER :: IGX_U_M_PUM,IGY_V_M_PVM,IGZ_W_M_PWM,IGZ_W_M_ZWP
-#endif
 REAL, DIMENSION(:,:,:), pointer , contiguous :: ZMZF_DZZ   ! MZF(PDZZ)
 REAL, DIMENSION(:,:,:), pointer , contiguous :: ZDFDDWDZ   ! formal derivative of the
 !                                                 ! flux (variable: dW/dz)
@@ -259,10 +253,6 @@ REAL, DIMENSION(:,:,:), pointer , contiguous :: ZDV_DZ_DZS_DY ! dv/dz*dzs/dy sur
 REAL, DIMENSION(:,:,:), pointer , contiguous :: ZDU_DX        ! du/dx        surf
 REAL, DIMENSION(:,:,:), pointer , contiguous :: ZDV_DY        ! dv/dy        surf
 REAL, DIMENSION(:,:,:), pointer , contiguous :: ZDW_DZ        ! dw/dz        surf
-#ifdef MNH_OPENACC
-INTEGER :: IZMZF_DZZ,IZDFDDWDZ,IZWP,IZDU_DZ_DZS_DX,IZDV_DZ_DZS_DY &
-           ,IZDU_DX,IZDV_DY,IZDW_DZ 
-#endif
 !
 INTEGER                :: IINFO_ll      ! return code of parallel routine
 TYPE(LIST_ll), POINTER :: TZFIELDS_ll   ! list of fields to exchange
@@ -273,13 +263,9 @@ REAL :: ZTIME1, ZTIME2
 REAL, DIMENSION(:,:,:), pointer , contiguous :: ZCOEFF , ZDZZ
                                     ! coefficients for the uncentred gradient 
                                     ! computation near the ground
-#ifdef MNH_OPENACC
-INTEGER  :: IZCOEFF , IZDZZ
-#endif
 !
 #ifdef MNH_OPENACC
 REAL, DIMENSION(:,:,:), pointer , contiguous :: ZTMP1_DEVICE, ZTMP2_DEVICE, ZTMP3_DEVICE, ZTMP4_DEVICE
-INTEGER :: IZTMP1_DEVICE, IZTMP2_DEVICE, IZTMP3_DEVICE, IZTMP4_DEVICE
 #endif
 TYPE(TFIELDDATA) :: TZFIELD
 !
@@ -357,34 +343,35 @@ allocate( zdw_dz       (JIU,JJU, 1 ) )
 allocate( zcoeff(JIU,JJU, 1 + jpvext : 3 + jpvext ) )
 allocate( zdzz  (JIU,JJU, 1 + jpvext : 3 + jpvext ) )
 #else
-izflx          = MNH_ALLOCATE_FLAT( zflx,  JIU, JJU, JKU )
-izwork         = MNH_ALLOCATE_FLAT( zwork, JIU, JJU, JKU )
+!Pin positions in the pools of MNH memory
+CALL MNH_MEM_POSITION_PIN()
 
-izdirsinzw     = MNH_ALLOCATE_FLAT( zdirsinzw,JIU,JJU )
+CALL MNH_MEM_GET( zflx,  JIU, JJU, JKU )
+CALL MNH_MEM_GET( zwork, JIU, JJU, JKU )
 
-igx_u_m_pum    = MNH_ALLOCATE_FLAT( gx_u_m_pum, JIU, JJU, JKU )
-igy_v_m_pvm    = MNH_ALLOCATE_FLAT( gy_v_m_pvm, JIU, JJU, JKU )
-igz_w_m_pwm    = MNH_ALLOCATE_FLAT( gz_w_m_pwm, JIU, JJU, JKU )
-igz_w_m_zwp    = MNH_ALLOCATE_FLAT( gz_w_m_zwp, JIU, JJU, JKU )
-izmzf_dzz      = MNH_ALLOCATE_FLAT( zmzf_dzz,   JIU, JJU, JKU )
-izdfddwdz      = MNH_ALLOCATE_FLAT( zdfddwdz,   JIU, JJU, JKU )
-izwp           = MNH_ALLOCATE_FLAT( zwp,        JIU, JJU, JKU )
+CALL MNH_MEM_GET( zdirsinzw,JIU,JJU )
 
-izdu_dz_dzs_dx = MNH_ALLOCATE_FLAT( zdu_dz_dzs_dx,1, JIU, 1, JJU, 1 , 1 )
-izdv_dz_dzs_dy = MNH_ALLOCATE_FLAT( zdv_dz_dzs_dy,1, JIU, 1, JJU, 1 , 1 )
-izdu_dx        = MNH_ALLOCATE_FLAT( zdu_dx,       1, JIU, 1, JJU, 1 , 1 )
-izdv_dy        = MNH_ALLOCATE_FLAT( zdv_dy,       1, JIU, 1, JJU, 1 , 1 )
-izdw_dz        = MNH_ALLOCATE_FLAT( zdw_dz,       1, JIU, 1, JJU, 1 , 1 )
+CALL MNH_MEM_GET( gx_u_m_pum, JIU, JJU, JKU )
+CALL MNH_MEM_GET( gy_v_m_pvm, JIU, JJU, JKU )
+CALL MNH_MEM_GET( gz_w_m_pwm, JIU, JJU, JKU )
+CALL MNH_MEM_GET( gz_w_m_zwp, JIU, JJU, JKU )
+CALL MNH_MEM_GET( zmzf_dzz,   JIU, JJU, JKU )
+CALL MNH_MEM_GET( zdfddwdz,   JIU, JJU, JKU )
+CALL MNH_MEM_GET( zwp,        JIU, JJU, JKU )
 
-izcoeff        = MNH_ALLOCATE_FLAT( zcoeff,1, JIU, 1, JJU, 1 + jpvext, 3 + jpvext )
-izdzz          = MNH_ALLOCATE_FLAT( zdzz,  1, JIU, 1, JJU, 1 + jpvext, 3 + jpvext )
-#endif
+CALL MNH_MEM_GET( zdu_dz_dzs_dx,1, JIU, 1, JJU, 1 , 1 )
+CALL MNH_MEM_GET( zdv_dz_dzs_dy,1, JIU, 1, JJU, 1 , 1 )
+CALL MNH_MEM_GET( zdu_dx,       1, JIU, 1, JJU, 1 , 1 )
+CALL MNH_MEM_GET( zdv_dy,       1, JIU, 1, JJU, 1 , 1 )
+CALL MNH_MEM_GET( zdw_dz,       1, JIU, 1, JJU, 1 , 1 )
 
-#ifdef MNH_OPENACC
-iztmp1_device = MNH_ALLOCATE_FLAT( ztmp1_device, JIU, JJU, JKU )
-iztmp2_device = MNH_ALLOCATE_FLAT( ztmp2_device, JIU, JJU, JKU )
-iztmp3_device = MNH_ALLOCATE_FLAT( ztmp3_device, JIU, JJU, JKU )
-iztmp4_device = MNH_ALLOCATE_FLAT( ztmp4_device, JIU, JJU, JKU )
+CALL MNH_MEM_GET( zcoeff,1, JIU, 1, JJU, 1 + jpvext, 3 + jpvext )
+CALL MNH_MEM_GET( zdzz,  1, JIU, 1, JJU, 1 + jpvext, 3 + jpvext )
+
+CALL MNH_MEM_GET( ztmp1_device, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ztmp2_device, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ztmp3_device, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ztmp4_device, JIU, JJU, JKU )
 #endif
 
 !$acc data present(ZFLX, ZWORK, ZDIRSINZW, ZCOEFF, ZDZZ,                  &
@@ -1329,15 +1316,9 @@ DEALLOCATE (ZFLX, ZWORK, ZDIRSINZW, ZCOEFF, ZDZZ,                  &
             ZMZF_DZZ, ZDFDDWDZ, ZWP,                               &
             ZDU_DZ_DZS_DX, ZDV_DZ_DZS_DY, ZDU_DX, ZDV_DY, ZDW_DZ   )
 #else
-CALL MNH_RELEASE_FLAT( IZTMP1_DEVICE, IZTMP2_DEVICE, IZTMP3_DEVICE, IZTMP4_DEVICE )
-CALL MNH_RELEASE_FLAT( IZFLX, IZWORK, IZDIRSINZW,                                 &
-                       IGX_U_M_PUM, IGY_V_M_PVM, IGZ_W_M_PWM, IGZ_W_M_ZWP,        &
-                       IZMZF_DZZ, IZDFDDWDZ, IZWP,                                &
-                       IZDU_DZ_DZS_DX, IZDV_DZ_DZS_DY, IZDU_DX, IZDV_DY, IZDW_DZ, &
-                       IZCOEFF, IZDZZ                                             )
-
+!Release all memory allocated with MNH_MEM_GET calls since last call to MNH_MEM_POSITION_PIN
+CALL MNH_MEM_RELEASE()
 #endif
-     
 
 !$acc end data
 
diff --git a/src/MNH/turb_hor_splt.f90 b/src/MNH/turb_hor_splt.f90
index 078d9a562343ffc7c524865c3eb2038e4887b9b0..b30e280c6be04a887b09b5b50eb78f39e54f5003 100644
--- a/src/MNH/turb_hor_splt.f90
+++ b/src/MNH/turb_hor_splt.f90
@@ -269,7 +269,7 @@ USE MODI_TURB_HOR
 USE MODI_TURB_HOR_TKE
 !
 #ifdef MNH_OPENACC
-USE MODE_MNH_ZWORK,      ONLY: MNH_ALLOCATE_FLAT, MNH_RELEASE_FLAT
+USE MODE_MNH_ZWORK,      ONLY: MNH_MEM_GET, MNH_MEM_POSITION_PIN, MNH_MEM_RELEASE
 #endif
 !
 IMPLICIT NONE
@@ -352,9 +352,6 @@ REAL,POINTER , CONTIGUOUS,DIMENSION(:,:,:) :: ZINV_PDXX    ! 1./PDXX
 REAL,POINTER , CONTIGUOUS,DIMENSION(:,:,:) :: ZINV_PDYY    ! 1./PDYY
 REAL,POINTER , CONTIGUOUS,DIMENSION(:,:,:) :: ZINV_PDZZ    ! 1./PDZZ
 REAL,POINTER , CONTIGUOUS,DIMENSION(:,:,:) :: ZMZM_PRHODJ  ! MZM(PRHODJ)
-#ifdef MNH_OPENACC
-INTEGER :: IZK,IZINV_PDXX,IZINV_PDYY,IZINV_PDZZ,IZMZM_PRHODJ
-#endif
 !
 INTEGER :: JSPLT ! current split
 !
@@ -371,16 +368,11 @@ REAL,POINTER , CONTIGUOUS,DIMENSION(:,:,:)   :: ZUM, ZVM, ZWM, ZTHLM, ZTKEM
 REAL,POINTER , CONTIGUOUS,DIMENSION(:,:,:,:) :: ZRM, ZSVM
 REAL,POINTER , CONTIGUOUS,DIMENSION(:,:,:)   :: ZRUS, ZRVS, ZRWS, ZRTHLS
 REAL,POINTER , CONTIGUOUS,DIMENSION(:,:,:,:) :: ZRRS, ZRSVS
-#ifdef MNH_OPENACC
-INTEGER :: IZUM, IZVM, IZWM, IZTHLM, IZTKEM, IZRM, IZSVM &
-         , IZRUS, IZRVS, IZRWS, IZRTHLS, IZRRS, IZRSVS
-#endif
 !
 TYPE(LIST_ll), POINTER, SAVE :: TZFIELDS_ll
 !
 #ifdef MNH_OPENACC
 REAL, DIMENSION(:,:,:), POINTER , CONTIGUOUS :: ZTMP1_DEVICE,ZTMP2_DEVICE
-INTEGER :: IZTMP1_DEVICE,IZTMP2_DEVICE
 #endif
 ! ---------------------------------------------------------------------------
 
@@ -466,16 +458,17 @@ ALLOCATE(ZINV_PDYY(JIU,JJU,JKU))
 ALLOCATE(ZINV_PDZZ(JIU,JJU,JKU))
 ALLOCATE(ZMZM_PRHODJ(JIU,JJU,JKU))
 #else
-IZK          = MNH_ALLOCATE_FLAT( ZK,          JIU, JJU, JKU )
-IZINV_PDXX   = MNH_ALLOCATE_FLAT( ZINV_PDXX,   JIU, JJU, JKU )
-IZINV_PDYY   = MNH_ALLOCATE_FLAT( ZINV_PDYY,   JIU, JJU, JKU )
-IZINV_PDZZ   = MNH_ALLOCATE_FLAT( ZINV_PDZZ,   JIU, JJU, JKU )
-IZMZM_PRHODJ = MNH_ALLOCATE_FLAT( ZMZM_PRHODJ, JIU, JJU, JKU )
-#endif
+!Pin positions in the pools of MNH memory
+CALL MNH_MEM_POSITION_PIN()
 
-#ifdef MNH_OPENACC
-IZTMP1_DEVICE = MNH_ALLOCATE_FLAT( ZTMP1_DEVICE, JIU, JJU, JKU )
-IZTMP2_DEVICE = MNH_ALLOCATE_FLAT( ZTMP2_DEVICE, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ZK,          JIU, JJU, JKU )
+CALL MNH_MEM_GET( ZINV_PDXX,   JIU, JJU, JKU )
+CALL MNH_MEM_GET( ZINV_PDYY,   JIU, JJU, JKU )
+CALL MNH_MEM_GET( ZINV_PDZZ,   JIU, JJU, JKU )
+CALL MNH_MEM_GET( ZMZM_PRHODJ, JIU, JJU, JKU )
+
+CALL MNH_MEM_GET( ZTMP1_DEVICE, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ZTMP2_DEVICE, JIU, JJU, JKU )
 #endif
 
 !$acc data present( ZK, ZINV_PDXX, ZINV_PDYY, ZINV_PDZZ, ZMZM_PRHODJ, &
@@ -521,23 +514,26 @@ IF (KSPLIT>1 .AND. CPROGRAM=='MESONH') THEN
   ALLOCATE(ZRTHLS(SIZE(PRTHLS,1),SIZE(PRTHLS,2),SIZE(PRTHLS,3)))
   ALLOCATE(ZRRS(SIZE(PRRS,1),SIZE(PRRS,2),SIZE(PRRS,3),SIZE(PRRS,4)))
 #else
-  IZUM    = MNH_ALLOCATE_FLAT( ZUM, JIU, JJU, JKU )
-  IZVM    = MNH_ALLOCATE_FLAT( ZVM, JIU, JJU, JKU )
-  IZWM    = MNH_ALLOCATE_FLAT( ZWM, JIU, JJU, JKU )
-  
-  IZTHLM  = MNH_ALLOCATE_FLAT( ZTHLM, JIU, JJU, JKU )
-  IZTKEM  = MNH_ALLOCATE_FLAT( ZTKEM, JIU, JJU, JKU )
-  
-  IZRUS   = MNH_ALLOCATE_FLAT( ZRUS, JIU, JJU, JKU )
-  IZRVS   = MNH_ALLOCATE_FLAT( ZRVS, JIU, JJU, JKU )
-  IZRWS   = MNH_ALLOCATE_FLAT( ZRWS, JIU, JJU, JKU )
+  !Pin positions in the pools of MNH memory
+  CALL MNH_MEM_POSITION_PIN()
+
+  CALL MNH_MEM_GET( ZUM, JIU, JJU, JKU )
+  CALL MNH_MEM_GET( ZVM, JIU, JJU, JKU )
+  CALL MNH_MEM_GET( ZWM, JIU, JJU, JKU )
+
+  CALL MNH_MEM_GET( ZTHLM, JIU, JJU, JKU )
+  CALL MNH_MEM_GET( ZTKEM, JIU, JJU, JKU )
+
+  CALL MNH_MEM_GET( ZRUS, JIU, JJU, JKU )
+  CALL MNH_MEM_GET( ZRVS, JIU, JJU, JKU )
+  CALL MNH_MEM_GET( ZRWS, JIU, JJU, JKU )
 
-  IZRTHLS = MNH_ALLOCATE_FLAT( ZRTHLS, JIU, JJU, JKU )
+  CALL MNH_MEM_GET( ZRTHLS, JIU, JJU, JKU )
 
-  IZSVM   = MNH_ALLOCATE_FLAT( ZSVM,  JIU, JJU, JKU, SIZE(PSVM,4)  )
-  IZRM    = MNH_ALLOCATE_FLAT( ZRM,   JIU, JJU, JKU, SIZE(PRM,4)   )
-  IZRSVS  = MNH_ALLOCATE_FLAT( ZRSVS, JIU, JJU, JKU, SIZE(PRSVS,4) )
-  IZRRS   = MNH_ALLOCATE_FLAT( ZRRS,  JIU, JJU, JKU, SIZE(PRRS,4)  )
+  CALL MNH_MEM_GET( ZSVM,  JIU, JJU, JKU, SIZE(PSVM,4)  )
+  CALL MNH_MEM_GET( ZRM,   JIU, JJU, JKU, SIZE(PRM,4)   )
+  CALL MNH_MEM_GET( ZRSVS, JIU, JJU, JKU, SIZE(PRSVS,4) )
+  CALL MNH_MEM_GET( ZRRS,  JIU, JJU, JKU, SIZE(PRRS,4)  )
   
 #endif
   
@@ -762,11 +758,7 @@ IF (KSPLIT>1 .AND. CPROGRAM=='MESONH') THEN
   DEALLOCATE(ZRTHLS)
   DEALLOCATE(ZRRS)
 #else
-  CALL MNH_RELEASE_FLAT( IZRRS  )
-  CALL MNH_RELEASE_FLAT( IZRSVS )
-  CALL MNH_RELEASE_FLAT( IZRM   )
-  CALL MNH_RELEASE_FLAT( IZSVM  )
-  CALL MNH_RELEASE_FLAT( izum, izvm, izwm, izthlm, iztkem, izrus, izrvs, izrws, izrthls )
+  CALL MNH_MEM_RELEASE()
 #endif
   
   !
@@ -816,8 +808,8 @@ DEALLOCATE(ZINV_PDYY)
 DEALLOCATE(ZINV_PDZZ)
 DEALLOCATE(ZMZM_PRHODJ)
 #else
-CALL MNH_RELEASE_FLAT( IZK, IZINV_PDXX, IZINV_PDYY, IZINV_PDZZ, IZMZM_PRHODJ, &
-                       IZTMP1_DEVICE, IZTMP2_DEVICE )
+!Release all memory allocated with MNH_MEM_GET calls since beginning of subroutine
+CALL MNH_MEM_RELEASE()
 #endif
 
 if ( mppdb_initialized ) then
diff --git a/src/MNH/turb_hor_sv_flux.f90 b/src/MNH/turb_hor_sv_flux.f90
index 458c2bd0592ff936b144407c77f62b75ad4220e1..bd352dcef38aa6f2317a283bfe9f001bdf6e6128 100644
--- a/src/MNH/turb_hor_sv_flux.f90
+++ b/src/MNH/turb_hor_sv_flux.f90
@@ -137,7 +137,7 @@ USE MODI_LES_MEAN_SUBGRID
 USE MODI_SECOND_MNH
 !
 #ifdef MNH_OPENACC
-USE MODE_MNH_ZWORK,      ONLY: MNH_ALLOCATE_FLAT, MNH_RELEASE_FLAT
+USE MODE_MNH_ZWORK,      ONLY: MNH_MEM_GET, MNH_MEM_POSITION_PIN, MNH_MEM_RELEASE
 #endif
 !
 IMPLICIT NONE
@@ -186,9 +186,6 @@ INTEGER             :: IKB,IKE
 INTEGER             :: JSV          ! loop counter
 INTEGER             :: ISV          ! number of scalar var.
 REAL, DIMENSION(:,:,:), pointer , contiguous :: ZCOEFF
-#ifdef MNH_OPENACC
-INTEGER :: IZFLXX, IZFLXY, IZWORK2D, IZCOEFF
-#endif
                                     ! coefficients for the uncentred gradient 
                                     ! computation near the ground
 !
@@ -198,8 +195,7 @@ REAL :: ZTIME1, ZTIME2
 !
 #ifdef MNH_OPENACC
 REAL, DIMENSION(:,:,:), pointer , contiguous :: ZTMP1_DEVICE, ZTMP2_DEVICE, ZTMP3_DEVICE, &
-     ZTMP4_DEVICE, ZTMP5_DEVICE
-INTEGER :: IZTMP1_DEVICE, IZTMP2_DEVICE, IZTMP3_DEVICE, IZTMP4_DEVICE, IZTMP5_DEVICE
+                                                ZTMP4_DEVICE, ZTMP5_DEVICE
 #endif
 !
 INTEGER  :: JIU,JJU,JKU
@@ -248,20 +244,21 @@ allocate( zwork2d(JIU,JJU, 1 ) )
 
 allocate( zcoeff(JIU,JJU, 1 + jpvext : 3 + jpvext ) )
 #else
-izflxx   = MNH_ALLOCATE_FLAT( zflxx, JIU, JJU, JKU )
-izflxy   = MNH_ALLOCATE_FLAT( zflxy, JIU, JJU, JKU )
+!Pin positions in the pools of MNH memory
+CALL MNH_MEM_POSITION_PIN()
 
-izwork2d = MNH_ALLOCATE_FLAT( zwork2d, 1, JIU, 1, JJU, 1, 1 )
+CALL MNH_MEM_GET( zflxx, JIU, JJU, JKU )
+CALL MNH_MEM_GET( zflxy, JIU, JJU, JKU )
 
-izcoeff  = MNH_ALLOCATE_FLAT( zcoeff,  1, JIU, 1, JJU, 1 + jpvext, 3 + jpvext )
-#endif
+CALL MNH_MEM_GET( zwork2d, 1, JIU, 1, JJU, 1, 1 )
 
-#ifdef MNH_OPENACC
-iztmp1_device = MNH_ALLOCATE_FLAT( ztmp1_device, JIU, JJU, JKU )
-iztmp2_device = MNH_ALLOCATE_FLAT( ztmp2_device, JIU, JJU, JKU )
-iztmp3_device = MNH_ALLOCATE_FLAT( ztmp3_device, JIU, JJU, JKU )
-iztmp4_device = MNH_ALLOCATE_FLAT( ztmp4_device, JIU, JJU, JKU )
-iztmp5_device = MNH_ALLOCATE_FLAT( ztmp5_device, JIU, JJU, JKU )
+CALL MNH_MEM_GET( zcoeff,  1, JIU, 1, JJU, 1 + jpvext, 3 + jpvext )
+
+CALL MNH_MEM_GET( ztmp1_device, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ztmp2_device, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ztmp3_device, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ztmp4_device, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ztmp5_device, JIU, JJU, JKU )
 #endif
 
 !$acc data present( ZFLXX, ZFLXY, ZWORK2D, ZCOEFF, &
@@ -642,8 +639,8 @@ end if
 #ifndef MNH_OPENACC
 deallocate( ZFLXX, ZFLXY, ZWORK2D, ZCOEFF )
 #else
-CALL MNH_RELEASE_FLAT( IZFLXX, IZFLXY, IZWORK2D, IZCOEFF, &
-                       IZTMP1_DEVICE, IZTMP2_DEVICE, IZTMP3_DEVICE, IZTMP4_DEVICE, IZTMP5_DEVICE )
+!Release all memory allocated with MNH_MEM_GET calls since last call to MNH_MEM_POSITION_PIN
+CALL MNH_MEM_RELEASE()
 #endif
 
 !$acc end data
diff --git a/src/MNH/turb_hor_thermo_corr.f90 b/src/MNH/turb_hor_thermo_corr.f90
index 137754554bb70ca7fedd1f12eae2df2edecf1125..3c4d4877355864790db10e39043841e4ddcf0806 100644
--- a/src/MNH/turb_hor_thermo_corr.f90
+++ b/src/MNH/turb_hor_thermo_corr.f90
@@ -151,7 +151,7 @@ USE MODI_BITREP
 #endif
 !
 #ifdef MNH_OPENACC
-USE MODE_MNH_ZWORK,      ONLY: MNH_ALLOCATE_FLAT, MNH_RELEASE_FLAT
+USE MODE_MNH_ZWORK,      ONLY: MNH_MEM_GET, MNH_MEM_POSITION_PIN, MNH_MEM_RELEASE
 #endif
 !
 IMPLICIT NONE
@@ -206,9 +206,6 @@ INTEGER             :: IKB,IKE
                                     ! Index values for the Beginning and End
                                     ! mass points of the domain  
 REAL, DIMENSION(:,:,:), pointer , contiguous :: ZCOEFF
-#ifdef MNH_OPENACC
-INTEGER :: IZFLX,IZWORK,IZA,IZCOEFF
-#endif
                                     ! coefficients for the uncentred gradient 
                                     ! computation near the ground
 REAL :: ZTIME1, ZTIME2
@@ -218,8 +215,6 @@ TYPE(TFIELDDATA) :: TZFIELD
 INTEGER :: IKU
 REAL, DIMENSION(:,:,:), pointer , contiguous :: ZTMP1_DEVICE, ZTMP2_DEVICE, ZTMP3_DEVICE, ZTMP4_DEVICE
 REAL, DIMENSION(:,:,:), pointer , contiguous :: ZTMP5_DEVICE, ZTMP6_DEVICE, ZTMP7_DEVICE, ZTMP8_DEVICE
-INTEGER :: IZTMP1_DEVICE, IZTMP2_DEVICE, IZTMP3_DEVICE, IZTMP4_DEVICE ,&
-           IZTMP5_DEVICE, IZTMP6_DEVICE, IZTMP7_DEVICE, IZTMP8_DEVICE
 #endif
 !
 INTEGER  :: JIU,JJU,JKU
@@ -269,22 +264,23 @@ allocate( za   (JIU,JJU,JKU ) )
 
 allocate( zcoeff(JIU,JJU, 1 + jpvext : 3 + jpvext ) )
 #else
-izflx  = MNH_ALLOCATE_FLAT( zflx ,  JIU, JJU, JKU )
-izwork = MNH_ALLOCATE_FLAT( zwork , JIU, JJU, JKU )
-iza    = MNH_ALLOCATE_FLAT( za ,    JIU, JJU, JKU )
+!Pin positions in the pools of MNH memory
+CALL MNH_MEM_POSITION_PIN()
 
-izcoeff= MNH_ALLOCATE_FLAT( zcoeff, 1, JIU, 1, JJU, 1 + jpvext, 3 + jpvext )
-#endif
+CALL MNH_MEM_GET( zflx ,  JIU, JJU, JKU )
+CALL MNH_MEM_GET( zwork , JIU, JJU, JKU )
+CALL MNH_MEM_GET( za ,    JIU, JJU, JKU )
 
-#ifdef MNH_OPENACC
-iztmp1_device= MNH_ALLOCATE_FLAT( ztmp1_device, JIU, JJU, JKU )
-iztmp2_device= MNH_ALLOCATE_FLAT( ztmp2_device, JIU, JJU, JKU )
-iztmp3_device= MNH_ALLOCATE_FLAT( ztmp3_device, JIU, JJU, JKU )
-iztmp4_device= MNH_ALLOCATE_FLAT( ztmp4_device, JIU, JJU, JKU )
-iztmp5_device= MNH_ALLOCATE_FLAT( ztmp5_device, JIU, JJU, JKU )
-iztmp6_device= MNH_ALLOCATE_FLAT( ztmp6_device, JIU, JJU, JKU )
-iztmp7_device= MNH_ALLOCATE_FLAT( ztmp7_device, JIU, JJU, JKU )
-iztmp8_device= MNH_ALLOCATE_FLAT( ztmp8_device, JIU, JJU, JKU )
+CALL MNH_MEM_GET( zcoeff, 1, JIU, 1, JJU, 1 + jpvext, 3 + jpvext )
+
+CALL MNH_MEM_GET( ztmp1_device, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ztmp2_device, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ztmp3_device, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ztmp4_device, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ztmp5_device, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ztmp6_device, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ztmp7_device, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ztmp8_device, JIU, JJU, JKU )
 #endif
 
 !$acc data present( ZFLX, ZWORK, ZA, ZCOEFF,                                    &
@@ -890,9 +886,8 @@ end if
 #ifndef MNH_OPENACC
 deallocate (zflx,zwork,za,zcoeff)
 #else
-CALL MNH_RELEASE_FLAT( IZFLX, IZWORK, IZA, IZCOEFF,                                &
-                       IZTMP1_DEVICE, IZTMP2_DEVICE, IZTMP3_DEVICE, IZTMP4_DEVICE, &
-                       IZTMP5_DEVICE, IZTMP6_DEVICE, IZTMP7_DEVICE, IZTMP8_DEVICE  )
+!Release all memory allocated with MNH_MEM_GET calls since last call to MNH_MEM_POSITION_PIN
+CALL MNH_MEM_RELEASE()
 #endif
 
 !$acc end data
diff --git a/src/MNH/turb_hor_thermo_flux.f90 b/src/MNH/turb_hor_thermo_flux.f90
index eddbe7796f75eef0872da86e01e9055588eb63c1..4e0bd16f6fb8501bfaf4c9f5f7b2bc9e243153a3 100644
--- a/src/MNH/turb_hor_thermo_flux.f90
+++ b/src/MNH/turb_hor_thermo_flux.f90
@@ -152,7 +152,7 @@ USE MODI_LES_MEAN_SUBGRID
 USE MODI_SECOND_MNH
 !
 #ifdef MNH_OPENACC
-USE MODE_MNH_ZWORK,      ONLY: MNH_ALLOCATE_FLAT, MNH_RELEASE_FLAT
+USE MODE_MNH_ZWORK,      ONLY: MNH_MEM_GET, MNH_MEM_POSITION_PIN, MNH_MEM_RELEASE
 #endif
 !
 IMPLICIT NONE
@@ -215,17 +215,12 @@ INTEGER             :: IKB,IKE,IKU
 REAL, DIMENSION(:,:,:), pointer , contiguous :: ZCOEFF
                                     ! coefficients for the uncentred gradient 
                                     ! computation near the ground
-#ifdef MNH_OPENACC
-INTEGER :: IZFLX,IZFLXC,IZCOEFF
-#endif
 !
 REAL :: ZTIME1, ZTIME2
 !
 #ifdef MNH_OPENACC
 REAL, DIMENSION(:,:,:), pointer , contiguous :: ZTMP1_DEVICE, ZTMP2_DEVICE, ZTMP3_DEVICE, ZTMP4_DEVICE
 REAL, DIMENSION(:,:,:), pointer , contiguous :: ZTMP5_DEVICE, ZTMP6_DEVICE, ZTMP7_DEVICE, ZTMP8_DEVICE
-INTEGER ::  IZTMP1_DEVICE, IZTMP2_DEVICE, IZTMP3_DEVICE, IZTMP4_DEVICE, &
-            IZTMP5_DEVICE, IZTMP6_DEVICE, IZTMP7_DEVICE, IZTMP8_DEVICE
 #endif
 !
 TYPE(TFIELDDATA) :: TZFIELD
@@ -283,23 +278,23 @@ allocate( zflxc(JIU,JJU,JKU) )
 
 allocate( zcoeff(JIU,JJU, 1 + jpvext : 3 + jpvext ) )
 #else
-izflx  = MNH_ALLOCATE_FLAT( zflx,  JIU, JJU, JKU )
-izflxc = MNH_ALLOCATE_FLAT( zflxc, JIU, JJU, JKU )
-! izvptv= MNH_ALLOCATE_FLAT( zvptv, JIU, JJU, JKU )
+!Pin positions in the pools of MNH memory
+CALL MNH_MEM_POSITION_PIN()
 
-izcoeff= MNH_ALLOCATE_FLAT( zcoeff, 1, JIU, 1, JJU, 1 + jpvext, 3 + jpvext )
+CALL MNH_MEM_GET( zflx,  JIU, JJU, JKU )
+CALL MNH_MEM_GET( zflxc, JIU, JJU, JKU )
+! CALL MNH_MEM_GET( zvptv, JIU, JJU, JKU )
 
-#endif
+CALL MNH_MEM_GET( zcoeff, 1, JIU, 1, JJU, 1 + jpvext, 3 + jpvext )
 
-#ifdef MNH_OPENACC
-iztmp1_device = MNH_ALLOCATE_FLAT( ztmp1_device, JIU, JJU, JKU )
-iztmp2_device = MNH_ALLOCATE_FLAT( ztmp2_device, JIU, JJU, JKU )
-iztmp3_device = MNH_ALLOCATE_FLAT( ztmp3_device, JIU, JJU, JKU )
-iztmp4_device = MNH_ALLOCATE_FLAT( ztmp4_device, JIU, JJU, JKU )
-iztmp5_device = MNH_ALLOCATE_FLAT( ztmp5_device, JIU, JJU, JKU )
-iztmp6_device = MNH_ALLOCATE_FLAT( ztmp6_device, JIU, JJU, JKU )
-iztmp7_device = MNH_ALLOCATE_FLAT( ztmp7_device, JIU, JJU, JKU )
-iztmp8_device = MNH_ALLOCATE_FLAT( ztmp8_device, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ztmp1_device, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ztmp2_device, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ztmp3_device, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ztmp4_device, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ztmp5_device, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ztmp6_device, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ztmp7_device, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ztmp8_device, JIU, JJU, JKU )
 #endif
 
 !$acc data present( ZFLX, ZFLXC, ZCOEFF,                                    &
@@ -1851,9 +1846,8 @@ end if
 #ifndef MNH_OPENACC
 deallocate (zflx,zflxc,zcoeff)
 #else
-CALL MNH_RELEASE_FLAT( IZFLX, IZFLXC, IZCOEFF,                                     &
-                       IZTMP1_DEVICE, IZTMP2_DEVICE, IZTMP3_DEVICE, IZTMP4_DEVICE, &
-                       IZTMP5_DEVICE, IZTMP6_DEVICE, IZTMP7_DEVICE, IZTMP8_DEVICE  )
+!Release all memory allocated with MNH_MEM_GET calls since last call to MNH_MEM_POSITION_PIN
+CALL MNH_MEM_RELEASE()
 #endif
 
 !$acc end data
diff --git a/src/MNH/turb_hor_tke.f90 b/src/MNH/turb_hor_tke.f90
index 1a673d844cac815ff917d4319a0bfc6b77d99917..dac1e826edf89f16feb60d21e4b6746eb82e856a 100644
--- a/src/MNH/turb_hor_tke.f90
+++ b/src/MNH/turb_hor_tke.f90
@@ -100,7 +100,7 @@ USE MODI_LES_MEAN_SUBGRID
 USE MODI_SECOND_MNH
 
 #ifdef MNH_OPENACC
-USE MODE_MNH_ZWORK,  ONLY: MNH_ALLOCATE_FLAT, MNH_RELEASE_FLAT
+USE MODE_MNH_ZWORK,      ONLY: MNH_MEM_GET, MNH_MEM_POSITION_PIN, MNH_MEM_RELEASE
 #endif
 
 IMPLICIT NONE
@@ -134,15 +134,11 @@ REAL, DIMENSION(:,:,:), pointer , contiguous :: ZCOEFF
                                     ! computation near the ground
 !
 REAL, DIMENSION(:,:,:), pointer , contiguous :: ZFLX
-#ifdef MNH_OPENACC
-INTEGER :: IZCOEFF,IZFLX
-#endif
 !
 REAL :: ZTIME1, ZTIME2
 !
 #ifdef MNH_OPENACC
 REAL, DIMENSION(:,:,:), pointer , contiguous :: ZTMP1_DEVICE, ZTMP2_DEVICE, ZTMP3_DEVICE, ZTMP4_DEVICE
-INTEGER :: IZTMP1_DEVICE, IZTMP2_DEVICE, IZTMP3_DEVICE, IZTMP4_DEVICE
 #endif
 !
 INTEGER  :: JIU,JJU,JKU
@@ -181,17 +177,17 @@ allocate( zflx (JIU,JJU,JKU ) )
 
 allocate( zcoeff(JIU,JJU, 1 + jpvext : 3 + jpvext ) )
 #else
-izflx   = MNH_ALLOCATE_FLAT( zflx, JIU, JJU, JKU )
+!Pin positions in the pools of MNH memory
+CALL MNH_MEM_POSITION_PIN()
 
-izcoeff = MNH_ALLOCATE_FLAT( zcoeff, 1, JIU, 1, JJU, 1 + jpvext, 3 + jpvext )
-#endif
+CALL MNH_MEM_GET( zflx, JIU, JJU, JKU )
 
+CALL MNH_MEM_GET( zcoeff, 1, JIU, 1, JJU, 1 + jpvext, 3 + jpvext )
 
-#ifdef MNH_OPENACC
-iztmp1_device = MNH_ALLOCATE_FLAT( ztmp1_device, JIU, JJU, JKU )
-iztmp2_device = MNH_ALLOCATE_FLAT( ztmp2_device, JIU, JJU, JKU )
-iztmp3_device = MNH_ALLOCATE_FLAT( ztmp3_device, JIU, JJU, JKU )
-iztmp4_device = MNH_ALLOCATE_FLAT( ztmp4_device, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ztmp1_device, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ztmp2_device, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ztmp3_device, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ztmp4_device, JIU, JJU, JKU )
 #endif
 
 !$acc data present( ZCOEFF, ZFLX, &
@@ -527,8 +523,8 @@ end if
 #ifndef MNH_OPENACC
 deallocate( ZCOEFF, ZFLX )
 #else
-CALL MNH_RELEASE_FLAT( IZFLX, IZCOEFF, &
-                       IZTMP1_DEVICE, IZTMP2_DEVICE, IZTMP3_DEVICE, IZTMP4_DEVICE )
+!Release all memory allocated with MNH_MEM_GET calls since last call to MNH_MEM_POSITION_PIN
+CALL MNH_MEM_RELEASE()
 #endif
 
 !$acc end data
diff --git a/src/MNH/turb_hor_uv.f90 b/src/MNH/turb_hor_uv.f90
index ad31595c551b4db16f1344fc1c5e914666ec42d1..2d15fd75f5434180c314b9307d60bcd618ba6877 100644
--- a/src/MNH/turb_hor_uv.f90
+++ b/src/MNH/turb_hor_uv.f90
@@ -155,7 +155,7 @@ USE MODI_BITREP
 #endif
 !
 #ifdef MNH_OPENACC
-USE MODE_MNH_ZWORK,      ONLY: MNH_ALLOCATE_FLAT, MNH_RELEASE_FLAT
+USE MODE_MNH_ZWORK,      ONLY: MNH_MEM_GET, MNH_MEM_POSITION_PIN, MNH_MEM_RELEASE
 #endif
 !
 IMPLICIT NONE
@@ -217,9 +217,6 @@ INTEGER             :: IKB,IKE
 !
 REAL, DIMENSION(:,:,:), pointer , contiguous :: GY_U_UV_PUM
 REAL, DIMENSION(:,:,:), pointer , contiguous :: GX_V_UV_PVM
-#ifdef MNH_OPENACC
-INTEGER :: IZFLX,IZWORK,IZDIRSINZW,IGY_U_UV_PUM,IGX_V_UV_PVM
-#endif
 !
 REAL :: ZTIME1, ZTIME2
 !
@@ -231,8 +228,6 @@ REAL, DIMENSION(:,:,:), pointer , contiguous :: ZTMP4_DEVICE
 REAL, DIMENSION(:,:,:), pointer , contiguous :: ZTMP5_DEVICE
 REAL, DIMENSION(:,:,:), pointer , contiguous :: ZTMP6_DEVICE
 REAL, DIMENSION(:,:,:), pointer , contiguous :: ZTMP7_DEVICE
-INTEGER :: IZTMP1_DEVICE, IZTMP2_DEVICE, IZTMP3_DEVICE, IZTMP4_DEVICE,&
-           IZTMP5_DEVICE,IZTMP6_DEVICE,IZTMP7_DEVICE
 #endif
 TYPE(TFIELDDATA) :: TZFIELD
 !
@@ -289,23 +284,24 @@ allocate( zdirsinzw(JIU,JJU ) )
 allocate( gy_u_uv_pum(JIU,JJU,JKU ) )
 allocate( gx_v_uv_pvm(JIU,JJU,JKU ) )
 #else
-izflx  = MNH_ALLOCATE_FLAT( zflx,  JIU, JJU, JKU )
-izwork = MNH_ALLOCATE_FLAT( zwork, JIU, JJU, JKU )
+!Pin positions in the pools of MNH memory
+CALL MNH_MEM_POSITION_PIN()
 
-izdirsinzw = MNH_ALLOCATE_FLAT( zdirsinzw, JIU, JJU )
+CALL MNH_MEM_GET( zflx,  JIU, JJU, JKU )
+CALL MNH_MEM_GET( zwork, JIU, JJU, JKU )
 
-igy_u_uv_pum = MNH_ALLOCATE_FLAT( gy_u_uv_pum, JIU, JJU, JKU )
-igx_v_uv_pvm = MNH_ALLOCATE_FLAT( gx_v_uv_pvm, JIU, JJU, JKU )
-#endif
+CALL MNH_MEM_GET( zdirsinzw, JIU, JJU )
 
-#ifdef MNH_OPENACC
-iztmp1_device = MNH_ALLOCATE_FLAT( ztmp1_device, JIU, JJU, JKU )
-iztmp2_device = MNH_ALLOCATE_FLAT( ztmp2_device, JIU, JJU, JKU )
-iztmp3_device = MNH_ALLOCATE_FLAT( ztmp3_device, JIU, JJU, JKU )
-iztmp4_device = MNH_ALLOCATE_FLAT( ztmp4_device, JIU, JJU, JKU )
-iztmp5_device = MNH_ALLOCATE_FLAT( ztmp5_device, JIU, JJU, JKU )
-iztmp6_device = MNH_ALLOCATE_FLAT( ztmp6_device, JIU, JJU, JKU )
-iztmp7_device = MNH_ALLOCATE_FLAT( ztmp7_device, JIU, JJU, JKU )
+CALL MNH_MEM_GET( gy_u_uv_pum, JIU, JJU, JKU )
+CALL MNH_MEM_GET( gx_v_uv_pvm, JIU, JJU, JKU )
+
+CALL MNH_MEM_GET( ztmp1_device, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ztmp2_device, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ztmp3_device, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ztmp4_device, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ztmp5_device, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ztmp6_device, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ztmp7_device, JIU, JJU, JKU )
 #endif
 
 !$acc data present( ZFLX, ZWORK, ZDIRSINZW, GY_U_UV_PUM, GX_V_UV_PVM,       &
@@ -835,9 +831,8 @@ end if
 #ifndef MNH_OPENACC
 deallocate ( ZFLX, ZWORK, ZDIRSINZW, GY_U_UV_PUM, GX_V_UV_PVM )
 #else
-CALL MNH_RELEASE_FLAT( IZFLX, IZWORK, IZDIRSINZW, IGY_U_UV_PUM, IGX_V_UV_PVM,      &
-                       IZTMP1_DEVICE, IZTMP2_DEVICE, IZTMP3_DEVICE, IZTMP4_DEVICE, &
-                       IZTMP5_DEVICE, IZTMP6_DEVICE, IZTMP7_DEVICE                 )
+!Release all memory allocated with MNH_MEM_GET calls since last call to MNH_MEM_POSITION_PIN
+CALL MNH_MEM_RELEASE()
 #endif
      
 
diff --git a/src/MNH/turb_hor_uw.f90 b/src/MNH/turb_hor_uw.f90
index dc4bacc2db9f1a463b17ffdf6cee2fa64a023b2d..3be5e10613fde6a02f86eb6cf4f0292593cb5266 100644
--- a/src/MNH/turb_hor_uw.f90
+++ b/src/MNH/turb_hor_uw.f90
@@ -139,7 +139,7 @@ USE MODI_LES_MEAN_SUBGRID
 USE MODI_SECOND_MNH
 
 #ifdef MNH_OPENACC
-USE MODE_MNH_ZWORK,      ONLY: MNH_ALLOCATE_FLAT, MNH_RELEASE_FLAT
+USE MODE_MNH_ZWORK,      ONLY: MNH_MEM_GET, MNH_MEM_POSITION_PIN, MNH_MEM_RELEASE
 #endif
 
 IMPLICIT NONE
@@ -187,9 +187,6 @@ INTEGER             :: IKB,IKE,IKU
 INTEGER             :: JSV          ! scalar loop counter
 !
 REAL, DIMENSION(:,:,:), pointer , contiguous :: GX_W_UW_PWM
-#ifdef MNH_OPENACC
-INTEGER :: IZFLX,IZWORK,IGX_W_UW_PWM
-#endif
 !
 REAL :: ZTIME1, ZTIME2
 !
@@ -198,7 +195,6 @@ REAL, DIMENSION(:,:,:), pointer , contiguous :: ZTMP1_DEVICE
 REAL, DIMENSION(:,:,:), pointer , contiguous :: ZTMP2_DEVICE
 REAL, DIMENSION(:,:,:), pointer , contiguous :: ZTMP3_DEVICE
 REAL, DIMENSION(:,:,:), pointer , contiguous :: ZTMP4_DEVICE
-INTEGER :: IZTMP1_DEVICE, IZTMP2_DEVICE, IZTMP3_DEVICE, IZTMP4_DEVICE
 #endif
 TYPE(TFIELDDATA) :: TZFIELD
 !
@@ -245,17 +241,18 @@ allocate( zwork(JIU,JJU,JKU ) )
 
 allocate( gx_w_uw_pwm(JIU,JJU,JKU ) )
 #else
-izflx        = MNH_ALLOCATE_FLAT( zflx,  JIU, JJU, JKU )
-izwork       = MNH_ALLOCATE_FLAT( zwork, JIU, JJU, JKU )
+!Pin positions in the pools of MNH memory
+CALL MNH_MEM_POSITION_PIN()
 
-igx_w_uw_pwm = MNH_ALLOCATE_FLAT( gx_w_uw_pwm, JIU, JJU, JKU )
-#endif
+CALL MNH_MEM_GET( zflx,  JIU, JJU, JKU )
+CALL MNH_MEM_GET( zwork, JIU, JJU, JKU )
 
-#ifdef MNH_OPENACC
-iztmp1_device = MNH_ALLOCATE_FLAT( ztmp1_device, JIU, JJU, JKU )
-iztmp2_device = MNH_ALLOCATE_FLAT( ztmp2_device, JIU, JJU, JKU )
-iztmp3_device = MNH_ALLOCATE_FLAT( ztmp3_device, JIU, JJU, JKU )
-iztmp4_device = MNH_ALLOCATE_FLAT( ztmp4_device, JIU, JJU, JKU )
+CALL MNH_MEM_GET( gx_w_uw_pwm, JIU, JJU, JKU )
+
+CALL MNH_MEM_GET( ztmp1_device, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ztmp2_device, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ztmp3_device, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ztmp4_device, JIU, JJU, JKU )
 #endif
 
 !$acc data present( ZFLX, ZWORK, GX_W_UW_PWM, &
@@ -594,8 +591,8 @@ end if
 #ifndef MNH_OPENACC
 deallocate( ZFLX, ZWORK, GX_W_UW_PWM )
 #else
-CALL MNH_RELEASE_FLAT( IZFLX, IZWORK, IGX_W_UW_PWM, &
-                       IZTMP1_DEVICE, IZTMP2_DEVICE, IZTMP3_DEVICE, IZTMP4_DEVICE )
+!Release all memory allocated with MNH_MEM_GET calls since last call to MNH_MEM_POSITION_PIN
+CALL MNH_MEM_RELEASE()
 #endif
 
 !$acc end data
diff --git a/src/MNH/turb_hor_vw.f90 b/src/MNH/turb_hor_vw.f90
index a3340a9a021d10636c471425df18d8d74dcd1876..6e6a7fab1aeed4956d27bc70a13ac6608cf40375 100644
--- a/src/MNH/turb_hor_vw.f90
+++ b/src/MNH/turb_hor_vw.f90
@@ -138,7 +138,7 @@ USE MODI_LES_MEAN_SUBGRID
 USE MODI_SECOND_MNH
 
 #ifdef MNH_OPENACC
-USE MODE_MNH_ZWORK,      ONLY: MNH_ALLOCATE_FLAT, MNH_RELEASE_FLAT
+USE MODE_MNH_ZWORK,      ONLY: MNH_MEM_GET, MNH_MEM_POSITION_PIN, MNH_MEM_RELEASE
 #endif
 
 IMPLICIT NONE
@@ -185,9 +185,6 @@ INTEGER             :: IKB,IKE,IKU
 INTEGER             :: JSV          ! scalar loop counter
 !
 REAL, DIMENSION(:,:,:), pointer , contiguous :: GY_W_VW_PWM
-#ifdef MNH_OPENACC
-INTEGER :: IZFLX,IZWORK,IGY_W_VW_PWM
-#endif
 !
 REAL :: ZTIME1, ZTIME2
 !
@@ -196,7 +193,6 @@ REAL, DIMENSION(:,:,:), pointer , contiguous :: ZTMP1_DEVICE
 REAL, DIMENSION(:,:,:), pointer , contiguous :: ZTMP2_DEVICE
 REAL, DIMENSION(:,:,:), pointer , contiguous :: ZTMP3_DEVICE
 REAL, DIMENSION(:,:,:), pointer , contiguous :: ZTMP4_DEVICE
-INTEGER :: IZTMP1_DEVICE, IZTMP2_DEVICE, IZTMP3_DEVICE, IZTMP4_DEVICE
 #endif
 TYPE(TFIELDDATA) :: TZFIELD
 !
@@ -242,17 +238,18 @@ allocate( zwork(JIU,JJU,JKU ) )
 
 allocate( gy_w_vw_pwm(JIU,JJU,JKU ) )
 #else
-izflx        = MNH_ALLOCATE_FLAT( zflx,  JIU, JJU, JKU )
-izwork       = MNH_ALLOCATE_FLAT( zwork, JIU, JJU, JKU )
+!Pin positions in the pools of MNH memory
+CALL MNH_MEM_POSITION_PIN()
 
-igy_w_vw_pwm = MNH_ALLOCATE_FLAT( gy_w_vw_pwm, JIU, JJU, JKU )
-#endif
+CALL MNH_MEM_GET( zflx,  JIU, JJU, JKU )
+CALL MNH_MEM_GET( zwork, JIU, JJU, JKU )
 
-#ifdef MNH_OPENACC
-iztmp1_device = MNH_ALLOCATE_FLAT( ztmp1_device, JIU, JJU, JKU )
-iztmp2_device = MNH_ALLOCATE_FLAT( ztmp2_device, JIU, JJU, JKU )
-iztmp3_device = MNH_ALLOCATE_FLAT( ztmp3_device, JIU, JJU, JKU )
-iztmp4_device = MNH_ALLOCATE_FLAT( ztmp4_device, JIU, JJU, JKU )
+CALL MNH_MEM_GET( gy_w_vw_pwm, JIU, JJU, JKU )
+
+CALL MNH_MEM_GET( ztmp1_device, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ztmp2_device, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ztmp3_device, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ztmp4_device, JIU, JJU, JKU )
 #endif
 
 !$acc data present( ZFLX, ZWORK, GY_W_VW_PWM, &
@@ -623,8 +620,8 @@ end if
 #ifndef MNH_OPENACC
 deallocate( ZFLX, ZWORK, GY_W_VW_PWM )
 #else
-CALL MNH_RELEASE_FLAT( IZFLX, IZWORK, IGY_W_VW_PWM, &
-                       IZTMP1_DEVICE, IZTMP2_DEVICE, IZTMP3_DEVICE, IZTMP4_DEVICE )
+!Release all memory allocated with MNH_MEM_GET calls since last call to MNH_MEM_POSITION_PIN
+CALL MNH_MEM_RELEASE()
 #endif
 
 !$acc end data
diff --git a/src/MNH/turb_ver.f90 b/src/MNH/turb_ver.f90
index ebc1dc40bcc7817831b13d981e3ea7a5272f2c94..21851b90b55999a8d88dca1c9ee8b92559cb71f4 100644
--- a/src/MNH/turb_ver.f90
+++ b/src/MNH/turb_ver.f90
@@ -343,7 +343,7 @@ USE MODE_PRANDTL
 USE MODI_SECOND_MNH
 !
 #ifdef MNH_OPENACC
-USE MODE_MNH_ZWORK,      ONLY: MNH_ALLOCATE_FLAT, MNH_RELEASE_FLAT
+USE MODE_MNH_ZWORK,      ONLY: MNH_MEM_GET, MNH_MEM_POSITION_PIN, MNH_MEM_RELEASE
 #endif
 !
 IMPLICIT NONE
@@ -457,20 +457,11 @@ REAL, DIMENSION(:,:,:), pointer,contiguous ::  &
        ZTHLP,    & ! guess of potential temperature due to vert. turbulent flux
        ZRP         ! guess of total water due to vert. turbulent flux
 
-#ifdef MNH_OPENACC
-INTEGER :: izbeta,izsqrt_tke,izdth_dz,izdr_dz,izred2th3,izred2r3,izred2thr3, &
-           izbll_o_e,izetheta,izemoist,izredth1,izredr1,izphi3,izpsi3, &
-           izd,izwthv,izwu,izwv,izthlp,izrp
-#endif
-
 REAL, DIMENSION(:,:,:,:), pointer , contiguous ::  &
        ZPSI_SV,  & ! Prandtl number for scalars
        ZREDS1,   & ! 1D Redelsperger number R_sv
        ZRED2THS, & ! 3D Redelsperger number R*2_thsv
        ZRED2RS     ! 3D Redelsperger number R*2_rsv
-#ifdef MNH_OPENACC
-INTEGER :: IZPSI_SV,IZREDS1,IZRED2THS,IZRED2RS
-#endif
 !
 LOGICAL :: GUSERV    ! flag to use water vapor
 INTEGER :: IKB,IKE   ! index value for the Beginning
@@ -584,26 +575,29 @@ allocate( zwv      (JIU,JJU,JKU) )
 allocate( zthlp    (JIU,JJU,JKU) )
 allocate( zrp      (JIU,JJU,JKU) )
 #else
-izbeta     = MNH_ALLOCATE_FLAT( zbeta,     JIU, JJU, JKU )
-izsqrt_tke = MNH_ALLOCATE_FLAT( zsqrt_tke, JIU, JJU, JKU )
-izdth_dz   = MNH_ALLOCATE_FLAT( zdth_dz,   JIU, JJU, JKU )
-izdr_dz    = MNH_ALLOCATE_FLAT( zdr_dz,    JIU, JJU, JKU )
-izred2th3  = MNH_ALLOCATE_FLAT( zred2th3,  JIU, JJU, JKU )
-izred2r3   = MNH_ALLOCATE_FLAT( zred2r3,   JIU, JJU, JKU )
-izred2thr3 = MNH_ALLOCATE_FLAT( zred2thr3, JIU, JJU, JKU )
-izbll_o_e  = MNH_ALLOCATE_FLAT( zbll_o_e,  JIU, JJU, JKU )
-izetheta   = MNH_ALLOCATE_FLAT( zetheta,   JIU, JJU, JKU )
-izemoist   = MNH_ALLOCATE_FLAT( zemoist,   JIU, JJU, JKU )
-izredth1   = MNH_ALLOCATE_FLAT( zredth1,   JIU, JJU, JKU )
-izredr1    = MNH_ALLOCATE_FLAT( zredr1,    JIU, JJU, JKU )
-izphi3     = MNH_ALLOCATE_FLAT( zphi3,     JIU, JJU, JKU )
-izpsi3     = MNH_ALLOCATE_FLAT( zpsi3,     JIU, JJU, JKU )
-izd        = MNH_ALLOCATE_FLAT( zd,        JIU, JJU, JKU )
-izwthv     = MNH_ALLOCATE_FLAT( zwthv,     JIU, JJU, JKU )
-izwu       = MNH_ALLOCATE_FLAT( zwu,       JIU, JJU, JKU )
-izwv       = MNH_ALLOCATE_FLAT( zwv,       JIU, JJU, JKU )
-izthlp     = MNH_ALLOCATE_FLAT( zthlp,     JIU, JJU, JKU )
-izrp       = MNH_ALLOCATE_FLAT( zrp,       JIU, JJU, JKU )
+!Pin positions in the pools of MNH memory
+CALL MNH_MEM_POSITION_PIN()
+
+CALL MNH_MEM_GET( zbeta,     JIU, JJU, JKU )
+CALL MNH_MEM_GET( zsqrt_tke, JIU, JJU, JKU )
+CALL MNH_MEM_GET( zdth_dz,   JIU, JJU, JKU )
+CALL MNH_MEM_GET( zdr_dz,    JIU, JJU, JKU )
+CALL MNH_MEM_GET( zred2th3,  JIU, JJU, JKU )
+CALL MNH_MEM_GET( zred2r3,   JIU, JJU, JKU )
+CALL MNH_MEM_GET( zred2thr3, JIU, JJU, JKU )
+CALL MNH_MEM_GET( zbll_o_e,  JIU, JJU, JKU )
+CALL MNH_MEM_GET( zetheta,   JIU, JJU, JKU )
+CALL MNH_MEM_GET( zemoist,   JIU, JJU, JKU )
+CALL MNH_MEM_GET( zredth1,   JIU, JJU, JKU )
+CALL MNH_MEM_GET( zredr1,    JIU, JJU, JKU )
+CALL MNH_MEM_GET( zphi3,     JIU, JJU, JKU )
+CALL MNH_MEM_GET( zpsi3,     JIU, JJU, JKU )
+CALL MNH_MEM_GET( zd,        JIU, JJU, JKU )
+CALL MNH_MEM_GET( zwthv,     JIU, JJU, JKU )
+CALL MNH_MEM_GET( zwu,       JIU, JJU, JKU )
+CALL MNH_MEM_GET( zwv,       JIU, JJU, JKU )
+CALL MNH_MEM_GET( zthlp,     JIU, JJU, JKU )
+CALL MNH_MEM_GET( zrp,       JIU, JJU, JKU )
 #endif
 
 #ifndef MNH_OPENACC
@@ -612,10 +606,10 @@ allocate( zreds1  (JIU,JJU,JKU, nsv ) )
 allocate( zred2ths(JIU,JJU,JKU, nsv ) )
 allocate( zred2rs (JIU,JJU,JKU, nsv ) )
 #else
-izpsi_sv  = MNH_ALLOCATE_FLAT( zpsi_sv,  JIU, JJU, JKU, nsv )
-izreds1   = MNH_ALLOCATE_FLAT( zreds1,   JIU, JJU, JKU, nsv )
-izred2ths = MNH_ALLOCATE_FLAT( zred2ths, JIU, JJU, JKU, nsv )
-izred2rs  = MNH_ALLOCATE_FLAT( zred2rs,  JIU, JJU, JKU, nsv )
+CALL MNH_MEM_GET( zpsi_sv,  JIU, JJU, JKU, nsv )
+CALL MNH_MEM_GET( zreds1,   JIU, JJU, JKU, nsv )
+CALL MNH_MEM_GET( zred2ths, JIU, JJU, JKU, nsv )
+CALL MNH_MEM_GET( zred2rs,  JIU, JJU, JKU, nsv )
 #endif
 
 !$acc data present (ZBETA, ZSQRT_TKE, ZDTH_DZ, ZDR_DZ, ZRED2TH3, ZRED2R3, ZRED2THR3,&
@@ -922,10 +916,8 @@ DEALLOCATE(zbeta,zsqrt_tke,zdth_dz,zdr_dz,zred2th3,zred2r3,zred2thr3, &
            zd,zwthv,zwu,zwv,zthlp,zrp)
 DEALLOCATE(zpsi_sv,zreds1,zred2ths,zred2rs)
 #else
-CALL MNH_RELEASE_FLAT( izpsi_sv, izreds1, izred2ths, izred2rs )
-CALL MNH_RELEASE_FLAT( izbeta, izsqrt_tke, izdth_dz, izdr_dz, izred2th3, izred2r3, izred2thr3, &
-                       izbll_o_e, izetheta, izemoist, izredth1, izredr1, izphi3, izpsi3,       &
-                       izd, izwthv, izwu, izwv, izthlp, izrp )
+!Release all memory allocated with MNH_MEM_GET calls since last call to MNH_MEM_POSITION_PIN
+CALL MNH_MEM_RELEASE()
 #endif
 
 !$acc end data
diff --git a/src/MNH/turb_ver_dyn_flux.f90 b/src/MNH/turb_ver_dyn_flux.f90
index 18d9a481bf8b26e8b2546ee1d9abf6be2550d5f6..bc102b8378f2c6fabfc5307bb9f7cdfe980219c8 100644
--- a/src/MNH/turb_ver_dyn_flux.f90
+++ b/src/MNH/turb_ver_dyn_flux.f90
@@ -321,7 +321,7 @@ USE MODE_MSG
 #endif
 !
 #ifdef MNH_OPENACC
-USE MODE_MNH_ZWORK,      ONLY: MNH_ALLOCATE_FLAT, MNH_RELEASE_FLAT
+USE MODE_MNH_ZWORK,      ONLY: MNH_MEM_GET, MNH_MEM_POSITION_PIN, MNH_MEM_RELEASE
 #endif
 
 IMPLICIT NONE
@@ -396,9 +396,6 @@ REAL, DIMENSION(:,:,:), pointer , contiguous ::  &
        ZFLXZ,  &   ! vertical flux of the treated variable
        ZSOURCE,  & ! source of evolution for the treated variable
        ZKEFF       ! effectif diffusion coeff = LT * SQRT( TKE )
-#ifdef MNH_OPENACC
-INTEGER :: IZDIRSINZW,IZCOEFS,IZA,IZRES,IZFLXZ,IZSOURCE,IZKEFF
-#endif
 INTEGER             :: IIB,IIE, &   ! I index values for the Beginning and End
                        IJB,IJE, &   ! mass points of the domain in the 3 direct.
                        IKB,IKE      !
@@ -410,16 +407,12 @@ REAL, DIMENSION(:,:,:), pointer , contiguous :: ZCOEFFLXU, &
                                     ! coefficients for the surface flux
                                     ! evaluation and copy of PUSLOPEM and
                                     ! PVSLOPEM in local 3D arrays
-#ifdef MNH_OPENACC
-INTEGER :: IZCOEFFLXU,IZCOEFFLXV,IZUSLOPEM,IZVSLOPEM
-#endif
 INTEGER             :: IIU,IJU      ! size of array in x,y,z directions
 !
 REAL :: ZTIME1, ZTIME2
 !
 #ifdef MNH_OPENACC
 REAL, DIMENSION(:,:,:), pointer , contiguous :: ZTMP1_DEVICE,ZTMP2_DEVICE,ZTMP3_DEVICE,ZTMP4_DEVICE
-INTEGER :: IZTMP1_DEVICE,IZTMP2_DEVICE,IZTMP3_DEVICE,IZTMP4_DEVICE
 #endif
 TYPE(TFIELDDATA) :: TZFIELD
 !
@@ -488,27 +481,28 @@ allocate( zcoefflxv(JIU,JJU, 1 ) )
 allocate( zuslopem (JIU,JJU, 1 ) )
 allocate( zvslopem (JIU,JJU, 1 ) )
 #else
-izdirsinzw = MNH_ALLOCATE_FLAT( zdirsinzw, JIU, JJU )
+!Pin positions in the pools of MNH memory
+CALL MNH_MEM_POSITION_PIN()
 
-izcoefs    = MNH_ALLOCATE_FLAT( zcoefs, 1, JIU, 1, JJU, 1, 1 )
+CALL MNH_MEM_GET( zdirsinzw, JIU, JJU )
 
-iza        = MNH_ALLOCATE_FLAT( za,      JIU, JJU, JKU )
-izres      = MNH_ALLOCATE_FLAT( zres,    JIU, JJU, JKU )
-izflxz     = MNH_ALLOCATE_FLAT( zflxz,   JIU, JJU, JKU )
-izsource   = MNH_ALLOCATE_FLAT( zsource, JIU, JJU, JKU )
-izkeff     = MNH_ALLOCATE_FLAT( zkeff,   JIU, JJU, JKU )
+CALL MNH_MEM_GET( zcoefs, 1, JIU, 1, JJU, 1, 1 )
 
-izcoefflxu = MNH_ALLOCATE_FLAT( zcoefflxu, 1, JIU, 1, JJU, 1 , 1 )
-izcoefflxv = MNH_ALLOCATE_FLAT( zcoefflxv, 1, JIU, 1, JJU, 1 , 1 )
-izuslopem  = MNH_ALLOCATE_FLAT( zuslopem,  1, JIU, 1, JJU, 1 , 1 )
-izvslopem  = MNH_ALLOCATE_FLAT( zvslopem,  1, JIU, 1, JJU, 1 , 1 )
-#endif
+CALL MNH_MEM_GET( za,      JIU, JJU, JKU )
+CALL MNH_MEM_GET( zres,    JIU, JJU, JKU )
+CALL MNH_MEM_GET( zflxz,   JIU, JJU, JKU )
+CALL MNH_MEM_GET( zsource, JIU, JJU, JKU )
+CALL MNH_MEM_GET( zkeff,   JIU, JJU, JKU )
 
-#ifdef MNH_OPENACC
-iztmp1_device = MNH_ALLOCATE_FLAT( ztmp1_device, JIU, JJU, JKU )
-iztmp2_device = MNH_ALLOCATE_FLAT( ztmp2_device, JIU, JJU, JKU )
-iztmp3_device = MNH_ALLOCATE_FLAT( ztmp3_device, JIU, JJU, JKU )
-iztmp4_device = MNH_ALLOCATE_FLAT( ztmp4_device, JIU, JJU, JKU )
+CALL MNH_MEM_GET( zcoefflxu, 1, JIU, 1, JJU, 1 , 1 )
+CALL MNH_MEM_GET( zcoefflxv, 1, JIU, 1, JJU, 1 , 1 )
+CALL MNH_MEM_GET( zuslopem,  1, JIU, 1, JJU, 1 , 1 )
+CALL MNH_MEM_GET( zvslopem,  1, JIU, 1, JJU, 1 , 1 )
+
+CALL MNH_MEM_GET( ztmp1_device, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ztmp2_device, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ztmp3_device, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ztmp4_device, JIU, JJU, JKU )
 #endif
 
 !$acc data present( zdirsinzw, zcoefs, za, zres, zflxz, zsource, zkeff, zcoefflxu, zcoefflxv, zuslopem, zvslopem, &
@@ -1700,9 +1694,8 @@ end if
 #ifndef MNH_OPENACC
 deallocate (zdirsinzw,zcoefs,za,zres,zflxz,zsource,zkeff,zcoefflxu,zcoefflxv,zuslopem,zvslopem)
 #else
-CALL MNH_RELEASE_FLAT( izdirsinzw, izcoefs, iza, izres, izflxz, izsource, izkeff, &
-                       izcoefflxu, izcoefflxv, izuslopem, izvslopem,              &
-                       iztmp1_device, iztmp2_device, iztmp3_device, iztmp4_device )
+!Release all memory allocated with MNH_MEM_GET calls since last call to MNH_MEM_POSITION_PIN
+CALL MNH_MEM_RELEASE()
 #endif
 !$acc end data
 
diff --git a/src/MNH/turb_ver_thermo_corr.f90 b/src/MNH/turb_ver_thermo_corr.f90
index 6e1170f5e0cae9fa68f54f78bdffb875d6e4d24b..24ce39bb52d7db957a6ce53a190da296bdc69f5b 100644
--- a/src/MNH/turb_ver_thermo_corr.f90
+++ b/src/MNH/turb_ver_thermo_corr.f90
@@ -318,7 +318,7 @@ USE MODI_BITREP
 #endif
 !
 #ifdef MNH_OPENACC
-USE MODE_MNH_ZWORK,      ONLY: MNH_ALLOCATE_FLAT, MNH_RELEASE_FLAT
+USE MODE_MNH_ZWORK,      ONLY: MNH_MEM_GET, MNH_MEM_POSITION_PIN, MNH_MEM_RELEASE
 #endif
 
 IMPLICIT NONE
@@ -390,18 +390,12 @@ REAL, DIMENSION(:,:,:), pointer , contiguous ::  &
        ZF,       & ! Flux in dTh/dt =-dF/dz (evaluated at t-1)(or rt instead of Th)
        ZDFDDTDZ, & ! dF/d(dTh/dz)
        ZDFDDRDZ    ! dF/d(dr/dz)
-#ifdef MNH_OPENACC
-INTEGER :: IZFLXZ,IZKEFF,IZF,IZDFDDTDZ,IZDFDDRDZ
-#endif
 INTEGER             :: IKB,IKE      ! I index values for the Beginning and End
                                     ! mass points of the domain in the 3 direct.
 INTEGER             :: I1,I2        ! For ZCOEFF allocation
 REAL, DIMENSION(:,:,:),POINTER , CONTIGUOUS  :: ZCOEFF
                                     ! coefficients for the uncentred gradient 
                                     ! computation near the ground
-#ifdef MNH_OPENACC
-INTEGER            :: IZCOEFF
-#endif
 !
 REAL :: ZTIME1, ZTIME2
 !
@@ -415,8 +409,6 @@ LOGICAL :: GFTHR    ! flag to use w'th'r'
 #ifdef MNH_OPENACC
 REAL, DIMENSION(:,:,:), pointer , contiguous :: ZTMP1_DEVICE,ZTMP2_DEVICE,ZTMP3_DEVICE,ZTMP4_DEVICE
 REAL, DIMENSION(:,:,:), pointer , contiguous :: ZTMP5_DEVICE,ZTMP6_DEVICE,ZTMP7_DEVICE,ZTMP8_DEVICE
-INTEGER  :: IZTMP1_DEVICE,IZTMP2_DEVICE,IZTMP3_DEVICE,IZTMP4_DEVICE
-INTEGER  :: IZTMP5_DEVICE,IZTMP6_DEVICE,IZTMP7_DEVICE,IZTMP8_DEVICE
 #endif
 TYPE(TFIELDDATA) :: TZFIELD
 !
@@ -490,25 +482,25 @@ allocate( zdfddrdz  (JIU,JJU,JKU) )
 
 allocate( zcoeff(JIU,JJU, i1 : i2 ) )
 #else
-izflxz    = MNH_ALLOCATE_FLAT( zflxz,    JIU, JJU, JKU )
-izkeff    = MNH_ALLOCATE_FLAT( zkeff,    JIU, JJU, JKU )
-izf       = MNH_ALLOCATE_FLAT( zf,       JIU, JJU, JKU )
-izdfddtdz = MNH_ALLOCATE_FLAT( zdfddtdz, JIU, JJU, JKU )
-izdfddrdz = MNH_ALLOCATE_FLAT( zdfddrdz, JIU, JJU, JKU )
+!Pin positions in the pools of MNH memory
+CALL MNH_MEM_POSITION_PIN()
 
-izcoeff   = MNH_ALLOCATE_FLAT( zcoeff, 1, JIU, 1, JJU, i1, i2 )
+CALL MNH_MEM_GET( zflxz,    JIU, JJU, JKU )
+CALL MNH_MEM_GET( zkeff,    JIU, JJU, JKU )
+CALL MNH_MEM_GET( zf,       JIU, JJU, JKU )
+CALL MNH_MEM_GET( zdfddtdz, JIU, JJU, JKU )
+CALL MNH_MEM_GET( zdfddrdz, JIU, JJU, JKU )
 
-#endif
+CALL MNH_MEM_GET( zcoeff, 1, JIU, 1, JJU, i1, i2 )
 
-#ifdef MNH_OPENACC
-iztmp1_device = MNH_ALLOCATE_FLAT( ztmp1_device, JIU, JJU, JKU )
-iztmp2_device = MNH_ALLOCATE_FLAT( ztmp2_device, JIU, JJU, JKU )
-iztmp3_device = MNH_ALLOCATE_FLAT( ztmp3_device, JIU, JJU, JKU )
-iztmp4_device = MNH_ALLOCATE_FLAT( ztmp4_device, JIU, JJU, JKU )
-iztmp5_device = MNH_ALLOCATE_FLAT( ztmp5_device, JIU, JJU, JKU )
-iztmp6_device = MNH_ALLOCATE_FLAT( ztmp6_device, JIU, JJU, JKU )
-iztmp7_device = MNH_ALLOCATE_FLAT( ztmp7_device, JIU, JJU, JKU )
-iztmp8_device = MNH_ALLOCATE_FLAT( ztmp8_device, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ztmp1_device, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ztmp2_device, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ztmp3_device, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ztmp4_device, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ztmp5_device, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ztmp6_device, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ztmp7_device, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ztmp8_device, JIU, JJU, JKU )
 #endif
 
 !$acc data present( zflxz, zkeff, zf, zdfddtdz, zdfddrdz, zcoeff,           &
@@ -1540,9 +1532,8 @@ end if
 #ifndef MNH_OPENACC
 deallocate( zflxz, zkeff, zf , zdfddtdz , zdfddrdz , zcoeff )
 #else
-CALL MNH_RELEASE_FLAT( IZFLXZ, IZKEFF, IZF, IZDFDDTDZ, IZDFDDRDZ, IZCOEFF,         &
-                       IZTMP1_DEVICE, IZTMP2_DEVICE, IZTMP3_DEVICE, IZTMP4_DEVICE, &
-                       IZTMP5_DEVICE, IZTMP6_DEVICE, IZTMP7_DEVICE, IZTMP8_DEVICE  )
+!Release all memory allocated with MNH_MEM_GET calls since last call to MNH_MEM_POSITION_PIN
+CALL MNH_MEM_RELEASE()
 #endif
 
 !$acc end data
diff --git a/src/MNH/turb_ver_thermo_flux.f90 b/src/MNH/turb_ver_thermo_flux.f90
index 1b0bfcf93f2363052b492f9a87f01df47caeeb55..3d8ea72169752939f3f03be74cc9f1cc189d15d9 100644
--- a/src/MNH/turb_ver_thermo_flux.f90
+++ b/src/MNH/turb_ver_thermo_flux.f90
@@ -376,7 +376,7 @@ USE MODE_PRANDTL
 USE MODI_SECOND_MNH
 !
 #ifdef MNH_OPENACC
-USE MODE_MNH_ZWORK,      ONLY: MNH_ALLOCATE_FLAT, MNH_RELEASE_FLAT
+USE MODE_MNH_ZWORK,      ONLY: MNH_MEM_GET, MNH_MEM_POSITION_PIN, MNH_MEM_RELEASE
 #endif
 
 IMPLICIT NONE
@@ -521,11 +521,7 @@ REAL, DIMENSION(:,:,:), pointer , contiguous ::  &
        ZCLD_THOLD
 REAL, DIMENSION(:,:,:), pointer , contiguous :: ZALT
 #ifdef MNH_OPENACC
-INTEGER :: IZA, IZFLXZ, IZSOURCE, IZKEFF, IZF, IZDFDDTDZ, IZDFDDRDZ, IZ3RDMOMENT, IZF_NEW, IZRWTHL, IZRWRNP, IZCLD_THOLD, IZALT
-#endif
-#ifdef MNH_OPENACC
 REAL, DIMENSION(:,:,:), pointer , contiguous :: ZTMP1_DEVICE,ZTMP2_DEVICE,ZTMP3_DEVICE,ZTMP4_DEVICE
-INTEGER :: IZTMP1_DEVICE,IZTMP2_DEVICE,IZTMP3_DEVICE,IZTMP4_DEVICE
 #endif
 TYPE(TFIELDDATA) :: TZFIELD
 
@@ -617,26 +613,27 @@ allocate( zrwrnp    (JIU,JJU,JKU ) )
 allocate( zcld_thold(JIU,JJU,JKU ) )
 allocate( zalt      (JIU,JJU,JKU ) )
 #else
-iza         = MNH_ALLOCATE_FLAT( za,         JIU,JJU,JKU )
-izflxz      = MNH_ALLOCATE_FLAT( zflxz,      JIU,JJU,JKU )
-izsource    = MNH_ALLOCATE_FLAT( zsource,    JIU,JJU,JKU )
-izkeff      = MNH_ALLOCATE_FLAT( zkeff,      JIU,JJU,JKU )
-izf         = MNH_ALLOCATE_FLAT( zf,         JIU,JJU,JKU )
-izdfddtdz   = MNH_ALLOCATE_FLAT( zdfddtdz,   JIU,JJU,JKU )
-izdfddrdz   = MNH_ALLOCATE_FLAT( zdfddrdz,   JIU,JJU,JKU )
-iz3rdmoment = MNH_ALLOCATE_FLAT( z3rdmoment, JIU,JJU,JKU )
-izf_new     = MNH_ALLOCATE_FLAT( zf_new,     JIU,JJU,JKU )
-izrwthl     = MNH_ALLOCATE_FLAT( zrwthl,     JIU,JJU,JKU )
-izrwrnp     = MNH_ALLOCATE_FLAT( zrwrnp,     JIU,JJU,JKU )
-izcld_thold = MNH_ALLOCATE_FLAT( zcld_thold, JIU,JJU,JKU )
-izalt       = MNH_ALLOCATE_FLAT( zalt,       JIU,JJU,JKU )
-#endif
+!Pin positions in the pools of MNH memory
+CALL MNH_MEM_POSITION_PIN()
 
-#ifdef MNH_OPENACC
-iztmp1_device = MNH_ALLOCATE_FLAT( ztmp1_device, JIU, JJU, JKU )
-iztmp2_device = MNH_ALLOCATE_FLAT( ztmp2_device, JIU, JJU, JKU )
-iztmp3_device = MNH_ALLOCATE_FLAT( ztmp3_device, JIU, JJU, JKU )
-iztmp4_device = MNH_ALLOCATE_FLAT( ztmp4_device, JIU, JJU, JKU )
+CALL MNH_MEM_GET( za,         JIU,JJU,JKU )
+CALL MNH_MEM_GET( zflxz,      JIU,JJU,JKU )
+CALL MNH_MEM_GET( zsource,    JIU,JJU,JKU )
+CALL MNH_MEM_GET( zkeff,      JIU,JJU,JKU )
+CALL MNH_MEM_GET( zf,         JIU,JJU,JKU )
+CALL MNH_MEM_GET( zdfddtdz,   JIU,JJU,JKU )
+CALL MNH_MEM_GET( zdfddrdz,   JIU,JJU,JKU )
+CALL MNH_MEM_GET( z3rdmoment, JIU,JJU,JKU )
+CALL MNH_MEM_GET( zf_new,     JIU,JJU,JKU )
+CALL MNH_MEM_GET( zrwthl,     JIU,JJU,JKU )
+CALL MNH_MEM_GET( zrwrnp,     JIU,JJU,JKU )
+CALL MNH_MEM_GET( zcld_thold, JIU,JJU,JKU )
+CALL MNH_MEM_GET( zalt,       JIU,JJU,JKU )
+
+CALL MNH_MEM_GET( ztmp1_device, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ztmp2_device, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ztmp3_device, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ztmp4_device, JIU, JJU, JKU )
 #endif
 
 !$acc data present( ZA, ZFLXZ, ZSOURCE, ZKEFF, ZF, ZDFDDTDZ, ZDFDDRDZ, Z3RDMOMENT,  &
@@ -1487,7 +1484,6 @@ DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
 END DO
 !$acc end kernels
 #endif
-#if 1
   !
   ! replace the flux by the Leonard terms above ZALT and ZCLD_THOLD
   IF (LHGRAD) THEN
@@ -1497,7 +1493,6 @@ END DO
    END WHERE
 !$acc end kernels
   END IF
-#endif
   !
 !$acc kernels
   ZFLXZ(:,:,KKA) = ZFLXZ(:,:,IKB) 
@@ -1802,9 +1797,8 @@ end if
 #ifndef MNH_OPENACC
 Deallocate( za, zflxz, zsource, zkeff, zf, zdfddtdz, zdfddrdz, z3rdmoment, zf_new, zrwthl, zrwrnp, zcld_thold, zalt )
 #else
-CALL MNH_RELEASE_FLAT( IZA, IZFLXZ, IZSOURCE, IZKEFF, IZF, IZDFDDTDZ, IZDFDDRDZ, IZ3RDMOMENT, &
-                       IZF_NEW, IZRWTHL, IZRWRNP, IZCLD_THOLD, IZALT,                         &
-                       IZTMP1_DEVICE, IZTMP2_DEVICE, IZTMP3_DEVICE, IZTMP4_DEVICE             )
+!Release all memory allocated with MNH_MEM_GET calls since last call to MNH_MEM_POSITION_PIN
+CALL MNH_MEM_RELEASE()
 #endif
 
 !$acc end data
diff --git a/src/ZSOLVER/advection_metsv.f90 b/src/ZSOLVER/advection_metsv.f90
index 3f0444f7f3aabc1f9bf65b6fe04bfb3f663a19ff..71049d6b13e44ddc001321e47de63207bcca7a1f 100644
--- a/src/ZSOLVER/advection_metsv.f90
+++ b/src/ZSOLVER/advection_metsv.f90
@@ -175,8 +175,8 @@ use mode_argslist_ll,    only: ADD3DFIELD_ll, ADD4DFIELD_ll, CLEANLIST_ll, LIST_
 use mode_budget,         only: Budget_store_init, Budget_store_end
 #ifdef MNH_OPENACC
 USE MODE_DEVICE
-USE MODE_MNH_ZWORK,      ONLY: MNH_ALLOCATE_FLAT, MNH_CHECK_IN_ZT3D, MNH_CHECK_OUT_ZT3D, &
-                               MNH_GET_ZT3D, MNH_RELEASE_FLAT, MNH_REL_ZT3D, ZT3D
+USE MODE_MNH_ZWORK,      ONLY: MNH_MEM_GET, MNH_MEM_POSITION_PIN, MNH_MEM_RELEASE, &
+                               MNH_GET_ZT3D, MNH_REL_ZT3D, ZT3D
 #endif
 use mode_exchange_ll,    only: UPDATE_HALO_ll
 USE MODE_IO_FIELD_WRITE, only: IO_Field_write
@@ -257,10 +257,6 @@ REAL, DIMENSION(:,:,:),pointer , contiguous :: ZCFLW
 !                                                 ! CFL numbers on each direction
 REAL, DIMENSION(:,:,:),pointer , contiguous :: ZCFL
 !                                                 ! CFL number
-#ifdef MNH_OPENACC
-INTEGER :: IZRUCPPM,IZRVCPPM,IZRWCPPM,IZCFLU,IZCFLV,IZCFLW,IZCFL
-#endif
-!
 REAL :: ZCFLU_MAX, ZCFLV_MAX, ZCFLW_MAX, ZCFL_MAX ! maximum CFL numbers
 !
 REAL, DIMENSION(:,:,:),pointer , contiguous :: ZTH
@@ -269,40 +265,24 @@ REAL, DIMENSION(:,:,:),pointer , contiguous :: ZRTHS_OTHER
 REAL, DIMENSION(:,:,:),pointer , contiguous :: ZRTKES_OTHER
 REAL, DIMENSION(:,:,:),pointer , contiguous :: ZRTHS_PPM
 REAL, DIMENSION(:,:,:),pointer , contiguous :: ZRTKES_PPM
-#ifdef MNH_OPENACC
-INTEGER :: IZTH,IZTKE,IZRTHS_OTHER,IZRTKES_OTHER,IZRTHS_PPM,IZRTKES_PPM
-#endif
 REAL, DIMENSION(:,:,:,:),pointer , contiguous :: ZR
 REAL, DIMENSION(:,:,:,:),pointer , contiguous :: ZSV
 REAL, DIMENSION(:,:,:,:),pointer , contiguous :: ZSNWC
 REAL, DIMENSION(:,:,:,:),pointer , contiguous :: ZSNWC_INIT
 REAL, DIMENSION(:,:,:,:),pointer , contiguous :: ZRSNWCS
-#ifdef MNH_OPENACC
-INTEGER :: IZR,IZSV,IZSNWC,IZSNWC_INIT,IZRSNWCS
-#endif
 ! Guess at the sub time step
 REAL, DIMENSION(:,:,:,:),pointer , contiguous :: ZRRS_OTHER
 REAL, DIMENSION(:,:,:,:),pointer , contiguous :: ZRSVS_OTHER
 REAL, DIMENSION(:,:,:,:),pointer , contiguous :: ZRSNWCS_OTHER
-#ifdef MNH_OPENACC
-INTEGER :: IZRRS_OTHER,IZRSVS_OTHER,IZRSNWCS_OTHER
-#endif
 ! Tendencies since the beginning of the time step
 REAL, DIMENSION(:,:,:,:),pointer , contiguous :: ZRRS_PPM
 REAL, DIMENSION(:,:,:,:),pointer , contiguous :: ZRSVS_PPM
 REAL, DIMENSION(:,:,:,:),pointer , contiguous :: ZRSNWCS_PPM
-#ifdef MNH_OPENACC
-INTEGER :: IZRRS_PPM,IZRSVS_PPM,IZRSNWCS_PPM   
-#endif
 ! Guess at the end of the sub time step
 REAL, DIMENSION(:,:,:),pointer , contiguous :: ZRHOX1,ZRHOX2
 REAL, DIMENSION(:,:,:),pointer , contiguous :: ZRHOY1,ZRHOY2
 REAL, DIMENSION(:,:,:),pointer , contiguous :: ZRHOZ1,ZRHOZ2
 REAL, DIMENSION(:,:,:),pointer , contiguous :: ZT,ZEXN,ZLV,ZLS,ZCPH
-#ifdef MNH_OPENACC
-INTEGER :: IZRHOX1,IZRHOX2,IZRHOY1,IZRHOY2,IZRHOZ1,IZRHOZ2 &
-          ,IZT,IZEXN,IZLV,IZLS,IZCPH 
-#endif
 
 ! Temporary advected rhodj for PPM routines
 !
@@ -401,42 +381,44 @@ allocate( ZLV          ( JIU,JJU,JKU )               )
 allocate( ZLS          ( JIU,JJU,JKU )               )
 allocate( ZCPH         ( JIU,JJU,JKU )               )
 #else
-CALL MNH_CHECK_IN_ZT3D("ADVECTION_METSV")
-IZRUCPPM       = MNH_ALLOCATE_FLAT( ZRUCPPM      , JIU, JJU, JKU               )
-IZRVCPPM       = MNH_ALLOCATE_FLAT( ZRVCPPM      , JIU, JJU, JKU               )
-IZRWCPPM       = MNH_ALLOCATE_FLAT( ZRWCPPM      , JIU, JJU, JKU               )
-IZCFLU         = MNH_ALLOCATE_FLAT( ZCFLU        , JIU, JJU, JKU               )
-IZCFLV         = MNH_ALLOCATE_FLAT( ZCFLV        , JIU, JJU, JKU               )
-IZCFLW         = MNH_ALLOCATE_FLAT( ZCFLW        , JIU, JJU, JKU               )
-IZCFL          = MNH_ALLOCATE_FLAT( ZCFL         , JIU, JJU, JKU               )
-IZTH           = MNH_ALLOCATE_FLAT( ZTH          , JIU, JJU, JKU               )
-IZTKE          = MNH_ALLOCATE_FLAT( ZTKE         , JIU, JJU, SIZE(PTKET,3)     )
-IZRTHS_OTHER   = MNH_ALLOCATE_FLAT( ZRTHS_OTHER  , JIU, JJU, JKU               )
-IZRTKES_OTHER  = MNH_ALLOCATE_FLAT( ZRTKES_OTHER , JIU, JJU, SIZE(PTKET,3)     )
-IZRTHS_PPM     = MNH_ALLOCATE_FLAT( ZRTHS_PPM    , JIU, JJU, JKU               )
-IZRTKES_PPM    = MNH_ALLOCATE_FLAT( ZRTKES_PPM   , JIU, JJU, SIZE(PTKET,3)     )
-IZR            = MNH_ALLOCATE_FLAT( ZR           , JIU, JJU, JKU, SIZE(PRT, 4) )
-IZSV           = MNH_ALLOCATE_FLAT( ZSV          , JIU, JJU, JKU, SIZE(PSVT,4) )
-IZSNWC         = MNH_ALLOCATE_FLAT( ZSNWC        , JIU, JJU, JKU, NBLOWSNOW_2D )
-IZSNWC_INIT    = MNH_ALLOCATE_FLAT( ZSNWC_INIT   , JIU, JJU, JKU, NBLOWSNOW_2D )
-IZRSNWCS       = MNH_ALLOCATE_FLAT( ZRSNWCS      , JIU, JJU, JKU, NBLOWSNOW_2D )
-IZRRS_OTHER    = MNH_ALLOCATE_FLAT( ZRRS_OTHER   , JIU, JJU, JKU, SIZE(PRT, 4) )
-IZRSVS_OTHER   = MNH_ALLOCATE_FLAT( ZRSVS_OTHER  , JIU, JJU, JKU, SIZE(PSVT,4) )
-IZRSNWCS_OTHER = MNH_ALLOCATE_FLAT( ZRSNWCS_OTHER, JIU, JJU, JKU, NBLOWSNOW_2D )
-IZRRS_PPM      = MNH_ALLOCATE_FLAT( ZRRS_PPM     , JIU, JJU, JKU, SIZE(PRT, 4) )
-IZRSVS_PPM     = MNH_ALLOCATE_FLAT( ZRSVS_PPM    , JIU, JJU, JKU, SIZE(PSVT,4) )
-IZRSNWCS_PPM   = MNH_ALLOCATE_FLAT( ZRSNWCS_PPM  , JIU, JJU, JKU, NBLOWSNOW_2D )
-IZRHOX1        = MNH_ALLOCATE_FLAT( ZRHOX1       , JIU, JJU, JKU               )
-IZRHOX2        = MNH_ALLOCATE_FLAT( ZRHOX2       , JIU, JJU, JKU               )
-IZRHOY1        = MNH_ALLOCATE_FLAT( ZRHOY1       , JIU, JJU, JKU               )
-IZRHOY2        = MNH_ALLOCATE_FLAT( ZRHOY2       , JIU, JJU, JKU               )
-IZRHOZ1        = MNH_ALLOCATE_FLAT( ZRHOZ1       , JIU, JJU, JKU               )
-IZRHOZ2        = MNH_ALLOCATE_FLAT( ZRHOZ2       , JIU, JJU, JKU               )
-IZT            = MNH_ALLOCATE_FLAT( ZT           , JIU, JJU, JKU               )
-IZEXN          = MNH_ALLOCATE_FLAT( ZEXN         , JIU, JJU, JKU               )
-IZLV           = MNH_ALLOCATE_FLAT( ZLV          , JIU, JJU, JKU               )
-IZLS           = MNH_ALLOCATE_FLAT( ZLS          , JIU, JJU, JKU               )
-IZCPH          = MNH_ALLOCATE_FLAT( ZCPH         , JIU, JJU, JKU                )
+!Pin positions in the pools of MNH memory
+CALL MNH_MEM_POSITION_PIN()
+
+CALL MNH_MEM_GET( ZRUCPPM      , JIU, JJU, JKU               )
+CALL MNH_MEM_GET( ZRVCPPM      , JIU, JJU, JKU               )
+CALL MNH_MEM_GET( ZRWCPPM      , JIU, JJU, JKU               )
+CALL MNH_MEM_GET( ZCFLU        , JIU, JJU, JKU               )
+CALL MNH_MEM_GET( ZCFLV        , JIU, JJU, JKU               )
+CALL MNH_MEM_GET( ZCFLW        , JIU, JJU, JKU               )
+CALL MNH_MEM_GET( ZCFL         , JIU, JJU, JKU               )
+CALL MNH_MEM_GET( ZTH          , JIU, JJU, JKU               )
+CALL MNH_MEM_GET( ZTKE         , JIU, JJU, SIZE(PTKET,3)     )
+CALL MNH_MEM_GET( ZRTHS_OTHER  , JIU, JJU, JKU               )
+CALL MNH_MEM_GET( ZRTKES_OTHER , JIU, JJU, SIZE(PTKET,3)     )
+CALL MNH_MEM_GET( ZRTHS_PPM    , JIU, JJU, JKU               )
+CALL MNH_MEM_GET( ZRTKES_PPM   , JIU, JJU, SIZE(PTKET,3)     )
+CALL MNH_MEM_GET( ZR           , JIU, JJU, JKU, SIZE(PRT, 4) )
+CALL MNH_MEM_GET( ZSV          , JIU, JJU, JKU, SIZE(PSVT,4) )
+CALL MNH_MEM_GET( ZSNWC        , JIU, JJU, JKU, NBLOWSNOW_2D )
+CALL MNH_MEM_GET( ZSNWC_INIT   , JIU, JJU, JKU, NBLOWSNOW_2D )
+CALL MNH_MEM_GET( ZRSNWCS      , JIU, JJU, JKU, NBLOWSNOW_2D )
+CALL MNH_MEM_GET( ZRRS_OTHER   , JIU, JJU, JKU, SIZE(PRT, 4) )
+CALL MNH_MEM_GET( ZRSVS_OTHER  , JIU, JJU, JKU, SIZE(PSVT,4) )
+CALL MNH_MEM_GET( ZRSNWCS_OTHER, JIU, JJU, JKU, NBLOWSNOW_2D )
+CALL MNH_MEM_GET( ZRRS_PPM     , JIU, JJU, JKU, SIZE(PRT, 4) )
+CALL MNH_MEM_GET( ZRSVS_PPM    , JIU, JJU, JKU, SIZE(PSVT,4) )
+CALL MNH_MEM_GET( ZRSNWCS_PPM  , JIU, JJU, JKU, NBLOWSNOW_2D )
+CALL MNH_MEM_GET( ZRHOX1       , JIU, JJU, JKU               )
+CALL MNH_MEM_GET( ZRHOX2       , JIU, JJU, JKU               )
+CALL MNH_MEM_GET( ZRHOY1       , JIU, JJU, JKU               )
+CALL MNH_MEM_GET( ZRHOY2       , JIU, JJU, JKU               )
+CALL MNH_MEM_GET( ZRHOZ1       , JIU, JJU, JKU               )
+CALL MNH_MEM_GET( ZRHOZ2       , JIU, JJU, JKU               )
+CALL MNH_MEM_GET( ZT           , JIU, JJU, JKU               )
+CALL MNH_MEM_GET( ZEXN         , JIU, JJU, JKU               )
+CALL MNH_MEM_GET( ZLV          , JIU, JJU, JKU               )
+CALL MNH_MEM_GET( ZLS          , JIU, JJU, JKU               )
+CALL MNH_MEM_GET( ZCPH         , JIU, JJU, JKU                )
 #endif
 
 !$acc data present( ZRUCPPM, ZRVCPPM, ZRWCPPM, ZCFLU, ZCFLV, ZCFLW, ZCFL, ZTH,                        &
@@ -1115,16 +1097,8 @@ deallocate ( ZRUCPPM, ZRVCPPM, ZRWCPPM, ZCFLU, ZCFLV, ZCFLW, ZCFL, ZTH,
             ZRRS_PPM, ZRSVS_PPM, ZRSNWCS_PPM, ZRHOX1, ZRHOX2, ZRHOY1, ZRHOY2, ZRHOZ1, ZRHOZ2, &
             ZT, ZEXN, ZLV, ZLS, ZCPH                                                          )
 #else
-CALL MNH_RELEASE_FLAT ( IZRHOX1, IZRHOX2, IZRHOY1, IZRHOY2, IZRHOZ1, IZRHOZ2, &
-                        IZT, IZEXN, IZLV, IZLS, IZCPH                         )
-
-CALL MNH_RELEASE_FLAT ( IZR, IZSV, IZSNWC, IZSNWC_INIT, IZRSNWCS, IZRRS_OTHER, IZRSVS_OTHER, &
-                        IZRSNWCS_OTHER, IZRRS_PPM, IZRSVS_PPM, IZRSNWCS_PPM)
-
-CALL MNH_RELEASE_FLAT ( IZRUCPPM, IZRVCPPM, IZRWCPPM, IZCFLU, IZCFLV, IZCFLW, IZCFL, IZTH, &
-                        IZTKE, IZRTHS_OTHER, IZRTKES_OTHER, IZRTHS_PPM, IZRTKES_PPM        )
-
-CALL MNH_CHECK_OUT_ZT3D("ADVECTION_METSV")
+!Release all memory allocated with MNH_MEM_GET calls since last call to MNH_MEM_POSITION_PIN
+CALL MNH_MEM_RELEASE()
 #endif
 
 !$acc end data
diff --git a/src/ZSOLVER/advection_uvw.f90 b/src/ZSOLVER/advection_uvw.f90
index 999dff33aaa46057faddfd824f3a8179ac24455c..6f2e14a80be9b96517b0f0bf704f532c792bdcb7 100644
--- a/src/ZSOLVER/advection_uvw.f90
+++ b/src/ZSOLVER/advection_uvw.f90
@@ -108,7 +108,8 @@ use mode_budget,      only: Budget_store_init, Budget_store_end
 USE MODE_ll
 #ifdef MNH_OPENACC
 USE MODE_DEVICE
-USE MODE_MNH_ZWORK,   ONLY: MNH_ALLOCATE_FLAT, MNH_RELEASE_FLAT, ZT3D, MNH_GET_ZT3D, MNH_REL_ZT3D, MNH_GET_ZT4D, MNH_REL_ZT4D
+USE MODE_MNH_ZWORK,   ONLY: MNH_MEM_GET, MNH_MEM_POSITION_PIN, MNH_MEM_RELEASE, &
+                            MNH_GET_ZT3D, MNH_GET_ZT4D, MNH_REL_ZT3D, MNH_REL_ZT4D, ZT3D
 #endif
 use mode_mppdb
 
@@ -161,9 +162,6 @@ INTEGER             :: IKE       ! indice K End       in z direction
 REAL, DIMENSION(:,:,:), POINTER, CONTIGUOUS :: ZRUT
 REAL, DIMENSION(:,:,:), POINTER, CONTIGUOUS :: ZRVT
 REAL, DIMENSION(:,:,:), POINTER, CONTIGUOUS :: ZRWT
-#ifdef MNH_OPENACC
-INTEGER :: IZRUT,IZRVT,IZRWT
-#endif
                                                   ! cartesian
                                                   ! components of
                                                   ! momentum
@@ -171,24 +169,15 @@ INTEGER :: IZRUT,IZRVT,IZRWT
 REAL, DIMENSION(:,:,:), POINTER, CONTIGUOUS :: ZRUCT
 REAL, DIMENSION(:,:,:), POINTER, CONTIGUOUS :: ZRVCT
 REAL, DIMENSION(:,:,:), POINTER, CONTIGUOUS :: ZRWCT
-#ifdef MNH_OPENACC
-INTEGER :: IZRUCT,IZRVCT,IZRWCT
-#endif
                                                   ! contravariant
                                                   ! components
                                                   ! of momentum
 !
 REAL, DIMENSION(:,:,:), POINTER, CONTIGUOUS :: ZU, ZV, ZW
-#ifdef MNH_OPENACC
-INTEGER :: IZU, IZV, IZW
-#endif
 ! Guesses at the end of the sub time step
 REAL, DIMENSION(:,:,:), POINTER, CONTIGUOUS :: ZRUS_OTHER
 REAL, DIMENSION(:,:,:), POINTER, CONTIGUOUS :: ZRVS_OTHER
 REAL, DIMENSION(:,:,:), POINTER, CONTIGUOUS :: ZRWS_OTHER
-#ifdef MNH_OPENACC
-INTEGER :: IZRUS_OTHER,IZRVS_OTHER,IZRWS_OTHER
-#endif
 ! Contribution of the RK time step
 REAL, DIMENSION(:,:,:), POINTER, CONTIGUOUS :: ZRUS_ADV
 REAL, DIMENSION(:,:,:), POINTER, CONTIGUOUS :: ZRVS_ADV
@@ -196,10 +185,6 @@ REAL, DIMENSION(:,:,:), POINTER, CONTIGUOUS :: ZRWS_ADV
 REAL, DIMENSION(:,:,:), POINTER, CONTIGUOUS :: ZMXM_RHODJ
 REAL, DIMENSION(:,:,:), POINTER, CONTIGUOUS :: ZMYM_RHODJ
 REAL, DIMENSION(:,:,:), POINTER, CONTIGUOUS :: ZMZM_RHODJ
-#ifdef MNH_OPENACC
-INTEGER :: IZRUS_ADV,IZRVS_ADV,IZRWS_ADV
-INTEGER :: IZMXM_RHODJ,IZMYM_RHODJ,IZMZM_RHODJ
-#endif
 !
 ! Momentum tendencies due to advection
 INTEGER :: ISPLIT              ! Number of splitting loops
@@ -270,24 +255,27 @@ ALLOCATE( ZMXM_RHODJ( IIU,IJU,IKU ) )
 ALLOCATE( ZMYM_RHODJ( IIU,IJU,IKU ) )
 ALLOCATE( ZMZM_RHODJ( IIU,IJU,IKU ) )
 #else
-IZRUT       = MNH_ALLOCATE_FLAT( ZRUT,       IIU, IJU, IKU )
-IZRVT       = MNH_ALLOCATE_FLAT( ZRVT,       IIU, IJU, IKU )
-IZRWT       = MNH_ALLOCATE_FLAT( ZRWT,       IIU, IJU, IKU )
-IZRUCT      = MNH_ALLOCATE_FLAT( ZRUCT,      IIU, IJU, IKU )
-IZRVCT      = MNH_ALLOCATE_FLAT( ZRVCT,      IIU, IJU, IKU )
-IZRWCT      = MNH_ALLOCATE_FLAT( ZRWCT,      IIU, IJU, IKU )
-IZU         = MNH_ALLOCATE_FLAT( ZU,         IIU, IJU, IKU )
-IZV         = MNH_ALLOCATE_FLAT( ZV,         IIU, IJU, IKU )
-IZW         = MNH_ALLOCATE_FLAT( ZW,         IIU, IJU, IKU )
-IZRUS_OTHER = MNH_ALLOCATE_FLAT( ZRUS_OTHER, IIU, IJU, IKU )
-IZRVS_OTHER = MNH_ALLOCATE_FLAT( ZRVS_OTHER, IIU, IJU, IKU )
-IZRWS_OTHER = MNH_ALLOCATE_FLAT( ZRWS_OTHER, IIU, IJU, IKU )
-IZRUS_ADV   = MNH_ALLOCATE_FLAT( ZRUS_ADV,   IIU, IJU, IKU )
-IZRVS_ADV   = MNH_ALLOCATE_FLAT( ZRVS_ADV,   IIU, IJU, IKU )
-IZRWS_ADV   = MNH_ALLOCATE_FLAT( ZRWS_ADV,   IIU, IJU, IKU )
-IZMXM_RHODJ = MNH_ALLOCATE_FLAT( ZMXM_RHODJ, IIU, IJU, IKU )
-IZMYM_RHODJ = MNH_ALLOCATE_FLAT( ZMYM_RHODJ, IIU, IJU, IKU )
-IZMZM_RHODJ = MNH_ALLOCATE_FLAT( ZMZM_RHODJ, IIU, IJU, IKU )
+!Pin positions in the pools of MNH memory
+CALL MNH_MEM_POSITION_PIN()
+
+CALL MNH_MEM_GET( ZRUT,       IIU, IJU, IKU )
+CALL MNH_MEM_GET( ZRVT,       IIU, IJU, IKU )
+CALL MNH_MEM_GET( ZRWT,       IIU, IJU, IKU )
+CALL MNH_MEM_GET( ZRUCT,      IIU, IJU, IKU )
+CALL MNH_MEM_GET( ZRVCT,      IIU, IJU, IKU )
+CALL MNH_MEM_GET( ZRWCT,      IIU, IJU, IKU )
+CALL MNH_MEM_GET( ZU,         IIU, IJU, IKU )
+CALL MNH_MEM_GET( ZV,         IIU, IJU, IKU )
+CALL MNH_MEM_GET( ZW,         IIU, IJU, IKU )
+CALL MNH_MEM_GET( ZRUS_OTHER, IIU, IJU, IKU )
+CALL MNH_MEM_GET( ZRVS_OTHER, IIU, IJU, IKU )
+CALL MNH_MEM_GET( ZRWS_OTHER, IIU, IJU, IKU )
+CALL MNH_MEM_GET( ZRUS_ADV,   IIU, IJU, IKU )
+CALL MNH_MEM_GET( ZRVS_ADV,   IIU, IJU, IKU )
+CALL MNH_MEM_GET( ZRWS_ADV,   IIU, IJU, IKU )
+CALL MNH_MEM_GET( ZMXM_RHODJ, IIU, IJU, IKU )
+CALL MNH_MEM_GET( ZMYM_RHODJ, IIU, IJU, IKU )
+CALL MNH_MEM_GET( ZMZM_RHODJ, IIU, IJU, IKU )
 #endif
 
 !$acc data present( zrut, zrvt, zrwt, zruct, zrvct, zrwct, zu, zv, zw,                &
@@ -585,9 +573,8 @@ DEALLOCATE(zrut, zrvt, zrwt, zruct, zrvct, zrwct, zu, zv, zw,                &
            zrus_other, zrvs_other, zrws_other, zrus_adv, zrvs_adv, zrws_adv, &
            zmxm_rhodj, zmym_rhodj, zmzm_rhodj )
 #else
-CALL MNH_RELEASE_FLAT( izmxm_rhodj, izmym_rhodj, izmzm_rhodj )
-CALL MNH_RELEASE_FLAT( izrus_other, izrvs_other, izrws_other, izrus_adv, izrvs_adv, izrws_adv )
-CALL MNH_RELEASE_FLAT( izrut, izrvt, izrwt, izruct, izrvct, izrwct, izu, izv, izw)
+!Release all memory allocated with MNH_MEM_GET calls since last call to MNH_MEM_POSITION_PIN
+CALL MNH_MEM_RELEASE()
 #endif
 
 !$acc end data
diff --git a/src/ZSOLVER/gdiv.f90 b/src/ZSOLVER/gdiv.f90
index c13e3aaa943337e95ab983dd6dbef79db20b7bd7..b82d37e71d0a1aa0aec599634bcd4082918fd47c 100644
--- a/src/ZSOLVER/gdiv.f90
+++ b/src/ZSOLVER/gdiv.f90
@@ -1,4 +1,4 @@
-!MNH_LIC Copyright 1994-2021 CNRS, Meteo-France and Universite Paul Sabatier
+!MNH_LIC Copyright 1994-2022 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.
@@ -107,7 +107,7 @@ USE MODI_CONTRAV
 USE MODE_ll
 !
 #ifdef MNH_OPENACC
-USE MODE_MNH_ZWORK,   ONLY: MNH_ALLOCATE_FLAT, MNH_RELEASE_FLAT
+USE MODE_MNH_ZWORK,   ONLY: MNH_MEM_GET, MNH_MEM_POSITION_PIN, MNH_MEM_RELEASE
 #endif
 !
 IMPLICIT NONE
@@ -139,7 +139,6 @@ REAL, DIMENSION(:,:,:) , POINTER , CONTIGUOUS :: ZUC      ! x
 REAL, DIMENSION(:,:,:) , POINTER , CONTIGUOUS :: ZVC      ! y 
 REAL, DIMENSION(:,:,:) , POINTER , CONTIGUOUS :: ZWC      ! z 
 REAL, DIMENSION(:,:,:) , POINTER , CONTIGUOUS :: Z1,Z2,Z3 !work arrays
-INTEGER :: IZUC,IZVC,IZWC,IZ1,IZ2,IZ3
 !
 INTEGER :: IIB          ! indice I for the first inner mass point along x
 INTEGER :: IIE          ! indice I for the last inner mass point along x
@@ -154,7 +153,6 @@ INTEGER :: IIU,IJU,IKU
 !
 #ifdef MNH_OPENACC
 REAL, DIMENSION(:,:,:) , POINTER , CONTIGUOUS :: ZTMP1,ZTMP2
-INTEGER :: IZTMP1,IZTMP2
 #endif
 !
 LOGICAL :: GWEST,GEAST,GSOUTH,GNORTH
@@ -178,15 +176,18 @@ IKU=SIZE(PU,3)
 ALLOCATE(ZUC(IIU,IJU,IKU),ZVC(IIU,IJU,IKU),ZWC(IIU,IJU,IKU))
 ALLOCATE(Z1(IIU,IJU,IKU),Z2(IIU,IJU,IKU),Z3(IIU,IJU,IKU))
 #else
-IZUC = MNH_ALLOCATE_FLAT( ZUC, IIU, IJU, IKU )
-IZVC = MNH_ALLOCATE_FLAT( ZVC, IIU, IJU, IKU )
-IZWC = MNH_ALLOCATE_FLAT( ZWC, IIU, IJU, IKU )
-IZ1  = MNH_ALLOCATE_FLAT( Z1,  IIU, IJU, IKU )
-IZ2  = MNH_ALLOCATE_FLAT( Z2,  IIU, IJU, IKU )
-IZ3  = MNH_ALLOCATE_FLAT( Z3,  IIU, IJU, IKU )
-!
-IZTMP1 = MNH_ALLOCATE_FLAT( ZTMP1, IIU, IJU, IKU )
-IZTMP2 = MNH_ALLOCATE_FLAT( ZTMP2, IIU, IJU, IKU )
+!Pin positions in the pools of MNH memory
+CALL MNH_MEM_POSITION_PIN()
+
+CALL MNH_MEM_GET( ZUC, IIU, IJU, IKU )
+CALL MNH_MEM_GET( ZVC, IIU, IJU, IKU )
+CALL MNH_MEM_GET( ZWC, IIU, IJU, IKU )
+CALL MNH_MEM_GET( Z1,  IIU, IJU, IKU )
+CALL MNH_MEM_GET( Z2,  IIU, IJU, IKU )
+CALL MNH_MEM_GET( Z3,  IIU, IJU, IKU )
+
+CALL MNH_MEM_GET( ZTMP1, IIU, IJU, IKU )
+CALL MNH_MEM_GET( ZTMP2, IIU, IJU, IKU )
 #endif
 !
 GWEST  = ( HLBCX(1) /= 'CYCL' .AND. LWEST_ll() )
@@ -347,7 +348,8 @@ END IF
 #ifndef MNH_OPENACC
 DEALLOCATE( ZUC, ZVC, ZWC, Z1, Z2, Z3 )
 #else
-CALL MNH_RELEASE_FLAT( IZUC, IZVC, IZWC, IZ1, IZ2, IZ3, IZTMP1, IZTMP2 )
+!Release all memory allocated with MNH_MEM_GET calls since last call to MNH_MEM_POSITION_PIN
+CALL MNH_MEM_RELEASE()
 #endif
 !
 !-------------------------------------------------------------------------------
diff --git a/src/ZSOLVER/modeln.f90 b/src/ZSOLVER/modeln.f90
index 14685ecbf9f1e21708837252e1452fcd54a1a0f1..083d1adad140066fc63d2894a99adda19ffa48e4 100644
--- a/src/ZSOLVER/modeln.f90
+++ b/src/ZSOLVER/modeln.f90
@@ -378,7 +378,7 @@ use mode_menu_diachro,     only: MENU_DIACHRO
 #endif
 USE MODE_MNH_TIMING
 #ifdef MNH_OPENACC
-USE MODE_MNH_ZWORK,      ONLY: MNH_ALLOCATE_FLAT, MNH_RELEASE_FLAT
+USE MODE_MNH_ZWORK,      ONLY: MNH_MEM_GET, MNH_MEM_POSITION_PIN, MNH_MEM_RELEASE
 #endif
 USE MODE_MODELN_HANDLER
 USE MODE_MPPDB
@@ -490,9 +490,6 @@ INTEGER :: ISYNCHRO          ! model synchronic index relative to its father
 INTEGER      :: IMI ! Current model index
 REAL, DIMENSION(:,:), POINTER, CONTIGUOUS :: ZSEA
 REAL, DIMENSION(:,:), POINTER, CONTIGUOUS :: ZTOWN
-#ifdef MNH_OPENACC
-INTEGER :: IZSEA, IZTOWN
-#endif
 ! Dummy pointers needed to correct an ifort Bug
 REAL, DIMENSION(:), POINTER :: DPTR_XZHAT
 REAL, DIMENSION(:), POINTER :: DPTR_XBMX1,DPTR_XBMX2,DPTR_XBMX3,DPTR_XBMX4
@@ -547,14 +544,8 @@ LOGICAL :: KHHONI
 !
 REAL, DIMENSION(:,:,:), ALLOCATABLE :: ZRUS,ZRVS
 REAL, DIMENSION(:,:,:), POINTER, CONTIGUOUS :: ZRWS
-#ifdef MNH_OPENACC
-INTEGER :: IZRWS
-#endif
 REAL, DIMENSION(:,:,:), POINTER, CONTIGUOUS :: ZPABST !To give pressure at t
                                                      ! (and not t+1) to resolved_cloud
-#ifdef MNH_OPENACC
-INTEGER :: IZPABST
-#endif
 REAL, DIMENSION(:,:,:), ALLOCATABLE :: ZJ
 !
 TYPE(LIST_ll), POINTER :: TZFIELDC_ll   ! list of fields to exchange
@@ -579,10 +570,11 @@ allocate( ZRVS  (SIZE(XTHT,1),SIZE(XTHT,2),SIZE(XTHT,3)) )
 allocate( ZRWS  (SIZE(XTHT,1),SIZE(XTHT,2),SIZE(XTHT,3)) )
 allocate( ZPABST(SIZE(XTHT,1),SIZE(XTHT,2),SIZE(XTHT,3)) )
 #else
-IZRWS   = MNH_ALLOCATE_FLAT( ZRWS,   SIZE( XTHT, 1 ), SIZE( XTHT, 2 ), SIZE( XTHT, 3 ) )
-IZPABST = MNH_ALLOCATE_FLAT( ZPABST, SIZE( XTHT, 1 ), SIZE( XTHT, 2 ), SIZE( XTHT, 3 ) )
-IZSEA = -1  !Set to -1 because not (yet) allocated
-IZTOWN = -1 !Set to -1 because not (yet) allocated
+!Pin positions in the pools of MNH memory
+CALL MNH_MEM_POSITION_PIN()
+
+CALL MNH_MEM_GET( ZRWS,   SIZE( XTHT, 1 ), SIZE( XTHT, 2 ), SIZE( XTHT, 3 ) )
+CALL MNH_MEM_GET( ZPABST, SIZE( XTHT, 1 ), SIZE( XTHT, 2 ), SIZE( XTHT, 3 ) )
 #endif
 allocate( ZJ    (SIZE(XTHT,1),SIZE(XTHT,2),SIZE(XTHT,3)) )
 allocate( ZWETDEPAER(SIZE(XRSVS,1), SIZE(XRSVS,2), SIZE(XRSVS,3), NSV_AER) )
@@ -1937,8 +1929,10 @@ IF (CCLOUD /= 'NONE' .AND. CELEC == 'NONE') THEN
     ALLOCATE (ZSEA(SIZE(XRHODJ,1),SIZE(XRHODJ,2)))
     ALLOCATE (ZTOWN(SIZE(XRHODJ,1),SIZE(XRHODJ,2)))
 #else
-    IZSEA  = MNH_ALLOCATE_FLAT( ZSEA,  SIZE( XRHODJ, 1 ), SIZE( XRHODJ, 2 ) )
-    IZTOWN = MNH_ALLOCATE_FLAT( ZTOWN, SIZE( XRHODJ, 1 ), SIZE( XRHODJ, 2 ) )
+    CALL MNH_MEM_GET( ZSEA,  SIZE( XRHODJ, 1 ), SIZE( XRHODJ, 2 ) )
+
+    CALL MNH_MEM_POSITION_PIN()
+    CALL MNH_MEM_GET( ZTOWN, SIZE( XRHODJ, 1 ), SIZE( XRHODJ, 2 ) )
 #endif
     CALL MNHGET_SURF_PARAM_n (PSEA=ZSEA(:,:),PTOWN=ZTOWN(:,:))
 !$acc update device( ZSEA, ZTOWN )
@@ -1965,7 +1959,7 @@ IF (CCLOUD /= 'NONE' .AND. CELEC == 'NONE') THEN
 #ifndef MNH_OPENACC
     DEALLOCATE(ZTOWN)
 #else
-    CALL MNH_RELEASE_FLAT( IZTOWN )
+    CALL MNH_MEM_RELEASE() !Release ZTOWN
 #endif
   ELSE
     CALL RESOLVED_CLOUD ( CCLOUD, CACTCCN, CSCONV, CMF_CLOUD, NRR, NSPLITR,    &
@@ -2052,8 +2046,10 @@ IF (CELEC /= 'NONE' .AND. (CCLOUD(1:3) == 'ICE')) THEN
     ALLOCATE (ZSEA(SIZE(XRHODJ,1),SIZE(XRHODJ,2)))
     ALLOCATE (ZTOWN(SIZE(XRHODJ,1),SIZE(XRHODJ,2)))
 #else
-    IZSEA  = MNH_ALLOCATE_FLAT( ZSEA,  SIZE( XRHODJ, 1 ), SIZE( XRHODJ, 2 ) )
-    IZTOWN = MNH_ALLOCATE_FLAT( ZTOWN, SIZE( XRHODJ, 1 ), SIZE( XRHODJ, 2 ) )
+    CALL MNH_MEM_GET( ZSEA,  SIZE( XRHODJ, 1 ), SIZE( XRHODJ, 2 ) )
+
+    CALL MNH_MEM_POSITION_PIN()
+    CALL MNH_MEM_GET( ZTOWN, SIZE( XRHODJ, 1 ), SIZE( XRHODJ, 2 ) )
 #endif
     CALL MNHGET_SURF_PARAM_n (PSEA=ZSEA(:,:),PTOWN=ZTOWN(:,:))
     CALL RESOLVED_ELEC_n (CCLOUD, CSCONV, CMF_CLOUD,                     &
@@ -2071,7 +2067,7 @@ IF (CELEC /= 'NONE' .AND. (CCLOUD(1:3) == 'ICE')) THEN
 #ifndef MNH_OPENACC
     DEALLOCATE(ZTOWN)
 #else
-    CALL MNH_RELEASE_FLAT( IZTOWN )
+    CALL MNH_MEM_RELEASE() !Release ZTOWN
 #endif
   ELSE
     CALL RESOLVED_ELEC_n (CCLOUD, CSCONV, CMF_CLOUD,                     &
@@ -2404,16 +2400,10 @@ END IF
 
 #ifndef MNH_OPENACC
 IF ( ALLOCATED( ZSEA ) ) DEALLOCATE( ZSEA )
-#else
-IF ( IZSEA /= -1 ) CALL MNH_RELEASE_FLAT( IZSEA )
-#endif
-
-#ifndef MNH_OPENACC
 DEALLOCATE( ZRWS )
 DEALLOCATE( ZPABST )
 #else
-CALL MNH_RELEASE_FLAT( IZPABST )
-CALL MNH_RELEASE_FLAT( IZRWS )
+CALL MNH_MEM_RELEASE()
 #endif
 
 END SUBROUTINE MODEL_n
diff --git a/src/ZSOLVER/p_abs.f90 b/src/ZSOLVER/p_abs.f90
index e2c098887e23260d3a90a3ea10dfcc069bb89155..dac98f5e9e6f37824a980c7cdc21a7d4a2d18b1b 100644
--- a/src/ZSOLVER/p_abs.f90
+++ b/src/ZSOLVER/p_abs.f90
@@ -124,7 +124,7 @@ USE MODE_REPRO_SUM
 USE MODI_BITREP
 #endif
 #ifdef MNH_OPENACC
-USE MODE_MNH_ZWORK,   ONLY: MNH_ALLOCATE_FLAT, MNH_RELEASE_FLAT
+USE MODE_MNH_ZWORK,   ONLY: MNH_MEM_GET, MNH_MEM_POSITION_PIN, MNH_MEM_RELEASE
 #endif
 !  
 IMPLICIT NONE
@@ -227,9 +227,12 @@ ZCVD_O_RD = (XCPD - XRD) / XRD
 #ifndef MNH_OPENACC
 ALLOCATE (ZRTOT(IIU,IJU,IKU), ZRHOREF(IIU,IJU,IKU), ZWORK(IIU,IJU,IKU))
 #else
-IZRTOT   = MNH_ALLOCATE_FLAT( ZRTOT,   IIU, IJU, IKU )
-IZRHOREF = MNH_ALLOCATE_FLAT( ZRHOREF, IIU, IJU, IKU )
-IZWORK   = MNH_ALLOCATE_FLAT( ZWORK,   IIU, IJU, IKU )
+!Pin positions in the pools of MNH memory
+CALL MNH_MEM_POSITION_PIN()
+
+CALL MNH_MEM_GET( ZRTOT,   IIU, IJU, IKU )
+CALL MNH_MEM_GET( ZRHOREF, IIU, IJU, IKU )
+CALL MNH_MEM_GET( ZWORK,   IIU, IJU, IKU )
 #endif
 
 !-------------------------------------------------------------------------------
@@ -445,7 +448,8 @@ END IF
 #ifndef MNH_OPENACC
 DEALLOCATE (ZRTOT, ZRHOREF, ZWORK)
 #else
-CALL MNH_RELEASE_FLAT( IZRTOT, IZRHOREF, IZWORK )
+!Release all memory allocated with MNH_MEM_GET calls since last call to MNH_MEM_POSITION_PIN
+CALL MNH_MEM_RELEASE()
 #endif
 !-------------------------------------------------------------------------------
 !
diff --git a/src/ZSOLVER/pressurez.f90 b/src/ZSOLVER/pressurez.f90
index dd59a84831ad63eb042ff087adb3d75df79e45a8..09c68f1a645addebfca34e9333fcfebbd75a8ad4 100644
--- a/src/ZSOLVER/pressurez.f90
+++ b/src/ZSOLVER/pressurez.f90
@@ -257,7 +257,7 @@ USE MODD_VAR_ll,      ONLY: NMNH_COMM_WORLD , NPROC
 use mode_budget,      only: Budget_store_end
 USE MODE_ll
 #ifdef MNH_OPENACC
-USE MODE_MNH_ZWORK,   ONLY: MNH_ALLOCATE_FLAT, MNH_RELEASE_FLAT
+USE MODE_MNH_ZWORK,   ONLY: MNH_MEM_GET, MNH_MEM_POSITION_PIN, MNH_MEM_RELEASE
 #endif
 USE MODE_MPPDB
 USE MODE_MSG
@@ -379,9 +379,6 @@ REAL, OPTIONAL                     :: PRESIDUAL
 !
 REAL, DIMENSION(:,:,:) , POINTER , CONTIGUOUS :: ZDV_SOURCE
 !                                                   ! divergence of the sources
-#ifdef MNH_OPENACC
-INTEGER :: IZDV_SOURCE
-#endif
 !
 INTEGER :: IIB          ! indice I for the first inner mass point along x
 INTEGER :: IIE          ! indice I for the last inner mass point along x
@@ -397,9 +394,6 @@ REAL, DIMENSION(:,:,:) , POINTER , CONTIGUOUS :: ZTHETAV, &
                                                  ZPHIT
                         ! MAE + DUR => Exner function perturbation
                         ! LHE       => Exner function perturbation * CPD * THVREF
-#ifdef MNH_OPENACC
-INTEGER :: IZTHETAV, IZPHIT
-#endif
 !
 REAL :: ZPHI0
 REAL            :: ZRV_OV_RD !  XRV / XRD
@@ -422,9 +416,7 @@ INTEGER :: IIMAX_ll,IJMAX_ll
 !
 #ifdef MNH_OPENACC
 REAL, DIMENSION(:,:,:) , POINTER , CONTIGUOUS :: ZPRHODJ,ZMXM_PRHODJ,ZMZM_PRHODJ,ZGZ_M_W
-INTEGER :: IZPRHODJ, IZMXM_PRHODJ, IZMZM_PRHODJ, IZGZ_M_W
 REAL, DIMENSION(:,:,:) , POINTER , CONTIGUOUS :: ZMYM_PRHODJ
-INTEGER :: IZMYM_PRHODJ
 #endif
 !
 !
@@ -498,15 +490,18 @@ ALLOCATE( ZDV_SOURCE(IIU, IJU, IKU) )
 ALLOCATE( ZTHETAV   (IIU, IJU, IKU) )
 ALLOCATE( ZPHIT     (IIU, IJU, IKU) )
 #else
-IZDV_SOURCE = MNH_ALLOCATE_FLAT( ZDV_SOURCE, IIU, IJU, IKU )
-IZTHETAV    = MNH_ALLOCATE_FLAT( ZTHETAV,    IIU, IJU, IKU )
-IZPHIT      = MNH_ALLOCATE_FLAT( ZPHIT,      IIU, IJU, IKU )
-!
-IZPRHODJ     = MNH_ALLOCATE_FLAT( ZPRHODJ,     IIU, IJU, IKU )
-IZMXM_PRHODJ = MNH_ALLOCATE_FLAT( ZMXM_PRHODJ, IIU, IJU, IKU )
-IZMZM_PRHODJ = MNH_ALLOCATE_FLAT( ZMZM_PRHODJ, IIU, IJU, IKU )
-IZGZ_M_W     = MNH_ALLOCATE_FLAT( ZGZ_M_W,     IIU, IJU, IKU )
-IZMYM_PRHODJ = MNH_ALLOCATE_FLAT( ZMYM_PRHODJ, IIU, IJU, IKU )
+!Pin positions in the pools of MNH memory
+CALL MNH_MEM_POSITION_PIN()
+
+CALL MNH_MEM_GET( ZDV_SOURCE, IIU, IJU, IKU )
+CALL MNH_MEM_GET( ZTHETAV,    IIU, IJU, IKU )
+CALL MNH_MEM_GET( ZPHIT,      IIU, IJU, IKU )
+
+CALL MNH_MEM_GET( ZPRHODJ,     IIU, IJU, IKU )
+CALL MNH_MEM_GET( ZMXM_PRHODJ, IIU, IJU, IKU )
+CALL MNH_MEM_GET( ZMZM_PRHODJ, IIU, IJU, IKU )
+CALL MNH_MEM_GET( ZGZ_M_W,     IIU, IJU, IKU )
+CALL MNH_MEM_GET( ZMYM_PRHODJ, IIU, IJU, IKU )
 #endif
 !
 IF (GFIRST_CALL_PRESSUREZ) THEN
@@ -1123,8 +1118,8 @@ deallocate( ZDV_SOURCE )
 deallocate( ZTHETAV )
 deallocate( ZPHIT )
 #else
-CALL MNH_RELEASE_FLAT( IZPRHODJ, IZMXM_PRHODJ, IZMZM_PRHODJ, IZGZ_M_W, IZMYM_PRHODJ )
-CALL MNH_RELEASE_FLAT( IZDV_SOURCE, IZTHETAV, IZPHIT )
+!Release all memory allocated with MNH_MEM_GET calls since last call to MNH_MEM_POSITION_PIN
+CALL MNH_MEM_RELEASE()
 #endif
 !-------------------------------------------------------------------------------
 !
diff --git a/src/ZSOLVER/qlap.f90 b/src/ZSOLVER/qlap.f90
index 288ab841f6a93e03ca36c26d2dc21c0285e0b8d3..427fe70a93036ea2363ea4d2f59776a98a453e9d 100644
--- a/src/ZSOLVER/qlap.f90
+++ b/src/ZSOLVER/qlap.f90
@@ -154,7 +154,7 @@ USE MODI_SHUMAN
 !
 USE MODE_MPPDB
 #ifdef MNH_OPENACC
-USE MODE_MNH_ZWORK , ONLY : MNH_ALLOCATE_FLAT , MNH_RELEASE_FLAT
+USE MODE_MNH_ZWORK,   ONLY: MNH_MEM_GET, MNH_MEM_POSITION_PIN, MNH_MEM_RELEASE
 #endif
 !
 USE MODD_IBM_PARAM_n, ONLY: XIBM_LS, LIBM, XIBM_SU
@@ -196,8 +196,6 @@ REAL, DIMENSION(:,:,:) , POINTER , CONTIGUOUS :: ZU ! rho*J*gradient along x
 REAL, DIMENSION(:,:,:) , POINTER , CONTIGUOUS :: ZV ! rho*J*gradient along y
 !
 REAL, DIMENSION(:,:,:) , POINTER , CONTIGUOUS :: ZW ! rho*J*gradient along z
-!
-INTEGER :: IZU,IZV,IZW
 #endif
 !
 INTEGER                          :: IIU,IJU,IKU         ! I,J,K array sizes
@@ -218,9 +216,12 @@ IKE = IKU - JPVEXT
 IKB =   1 + JPVEXT
 !
 #ifdef MNH_OPENACC
-IZU = MNH_ALLOCATE_FLAT( ZU,IIU,IJU,IKU  )
-IZV = MNH_ALLOCATE_FLAT( ZV,IIU,IJU,IKU  )
-IZW = MNH_ALLOCATE_FLAT( ZW,IIU,IJU,IKU  )
+!Pin positions in the pools of MNH memory
+CALL MNH_MEM_POSITION_PIN()
+
+CALL MNH_MEM_GET( ZU,IIU,IJU,IKU  )
+CALL MNH_MEM_GET( ZV,IIU,IJU,IKU  )
+CALL MNH_MEM_GET( ZW,IIU,IJU,IKU  )
 #endif
 !
 ZU = GX_M_U(1,IKU,1,PY,PDXX,PDZZ,PDZX)
@@ -331,7 +332,8 @@ IF (LIBM)  THEN
 ENDIF
 !
 #ifdef MNH_OPENACC
-CALL MNH_RELEASE_FLAT (  IZU,IZV,IZW )
+!Release all memory allocated with MNH_MEM_GET calls since last call to MNH_MEM_POSITION_PIN
+CALL MNH_MEM_RELEASE()
 #endif
 !-------------------------------------------------------------------------------
 !
@@ -426,7 +428,7 @@ USE MODI_SHUMAN_DEVICE
 !
 USE MODE_MPPDB
 !
-USE MODE_MNH_ZWORK,   ONLY: MNH_ALLOCATE_FLAT, MNH_RELEASE_FLAT
+USE MODE_MNH_ZWORK,   ONLY: MNH_MEM_GET, MNH_MEM_POSITION_PIN, MNH_MEM_RELEASE
 !
 USE MODI_GET_HALO
 USE MODD_IBM_PARAM_n, ONLY: XIBM_LS, LIBM, XIBM_SU
@@ -462,8 +464,6 @@ REAL, DIMENSION(:,:,:) , POINTER , CONTIGUOUS :: ZV ! rho*J*gradient along y
 !
 REAL, DIMENSION(:,:,:) , POINTER , CONTIGUOUS :: ZW ! rho*J*gradient along z
 !
-INTEGER :: IZU,IZV,IZW
-!
 INTEGER                          :: IIU,IJU,IKU         ! I,J,K array sizes
 INTEGER                          :: JK,JJ,JI            ! vertical loop index
 TYPE(LIST_ll), POINTER :: TZFIELDS_ll   ! list of fields to exchange
@@ -471,7 +471,6 @@ INTEGER :: IINFO_ll
 INTEGER :: IIB,IIE,IJB,IJE,IKB,IKE
 !
 REAL, DIMENSION(:,:,:), pointer , contiguous :: ZMXM,ZMYM,ZMZM,ZRHODJ,ZGZMW
-INTEGER :: IZMXM,IZMYM,IZMZM,IZRHODJ,IZGZMW
 !
 LOGICAL :: GWEST,GEAST,GSOUTH,GNORTH
 !-------------------------------------------------------------------------------
@@ -491,15 +490,15 @@ GEAST  = ( HLBCX(2) /= 'CYCL' .AND. LEAST_ll() )
 GSOUTH = ( HLBCY(1) /= 'CYCL' .AND. LSOUTH_ll() )
 GNORTH = ( HLBCY(2) /= 'CYCL' .AND. LNORTH_ll() )
 !
-IZU = MNH_ALLOCATE_FLAT( ZU, IIU, IJU, IKU )
-IZV = MNH_ALLOCATE_FLAT( ZV, IIU, IJU, IKU )
-IZW = MNH_ALLOCATE_FLAT( ZW, IIU, IJU, IKU )
+CALL MNH_MEM_GET( ZU, IIU, IJU, IKU )
+CALL MNH_MEM_GET( ZV, IIU, IJU, IKU )
+CALL MNH_MEM_GET( ZW, IIU, IJU, IKU )
 !
-IZMXM   = MNH_ALLOCATE_FLAT( ZMXM,   IIU, IJU, IKU )
-IZMYM   = MNH_ALLOCATE_FLAT( ZMYM,   IIU, IJU, IKU )
-IZMZM   = MNH_ALLOCATE_FLAT( ZMZM,   IIU, IJU, IKU )
-IZRHODJ = MNH_ALLOCATE_FLAT( ZRHODJ, IIU, IJU, IKU )
-IZGZMW  = MNH_ALLOCATE_FLAT( ZGZMW,  IIU, IJU, IKU )
+CALL MNH_MEM_GET( ZMXM,   IIU, IJU, IKU )
+CALL MNH_MEM_GET( ZMYM,   IIU, IJU, IKU )
+CALL MNH_MEM_GET( ZMZM,   IIU, IJU, IKU )
+CALL MNH_MEM_GET( ZRHODJ, IIU, IJU, IKU )
+CALL MNH_MEM_GET( ZGZMW,  IIU, IJU, IKU )
 !
 CALL GX_M_U_DEVICE(1,IKU,1,PY,PDXX,PDZZ,PDZX,ZU)
 CALL MPPDB_CHECK3D(ZU,'QLAP::ZU',PRECISION)
@@ -632,7 +631,8 @@ IF (LIBM)  THEN
    !
 ENDIF
 !
-CALL MNH_RELEASE_FLAT( IZU, IZV, IZW, IZMXM, IZMYM, IZMZM, IZRHODJ, IZGZMW )
+!Release all memory allocated with MNH_MEM_GET calls since last call to MNH_MEM_POSITION_PIN
+CALL MNH_MEM_RELEASE()
 !-------------------------------------------------------------------------------
 !
 END SUBROUTINE QLAP_DEVICE
diff --git a/src/ZSOLVER/tridiag_thermo.f90 b/src/ZSOLVER/tridiag_thermo.f90
index 333047bf3d35aaa8f14c5eb50f703c582d6bffcf..b7c9db58810dfd0b0674b2e65c0fdd10b7e7e18b 100644
--- a/src/ZSOLVER/tridiag_thermo.f90
+++ b/src/ZSOLVER/tridiag_thermo.f90
@@ -158,7 +158,7 @@ USE MODI_BITREP
 #endif
 !
 #ifdef MNH_OPENACC
-USE MODE_MNH_ZWORK , ONLY : MNH_ALLOCATE_FLAT , MNH_RELEASE_FLAT
+USE MODE_MNH_ZWORK, ONLY: MNH_MEM_GET, MNH_MEM_POSITION_PIN, MNH_MEM_RELEASE
 #endif
 !
 IMPLICIT NONE
@@ -186,13 +186,7 @@ REAL, DIMENSION(:,:,:), pointer , contiguous :: ZMZM_RHODJ
 REAL, DIMENSION(:,:,:), pointer , contiguous :: ZA, ZB, ZC
 REAL, DIMENSION(:,:,:), pointer , contiguous :: ZY ,ZGAM
                                          ! RHS of the equation, 3D work array
-#ifdef MNH_OPENACC
-INTEGER :: IZRHODJ_DFDDTDZ_O_DZ2,IZMZM_RHODJ,IZA,IZB,IZC,IZY,IZGAM
-#endif
 REAL, DIMENSION(:,:), pointer , contiguous   :: ZBET
-#ifdef MNH_OPENACC
-INTEGER :: IZBET
-#endif
                                          ! 2D work array
 INTEGER             :: JI,JJ,JK      ! loop counter
 INTEGER             :: IKB,IKE       ! inner vertical limits
@@ -202,7 +196,6 @@ INTEGER             :: IKTB,IKTE    ! start, end of k loops in physical domain
 !
 #ifdef MNH_OPENACC
 REAL, DIMENSION(:,:,:), pointer , contiguous :: ZTMP1_DEVICE
-INTEGER :: IZTMP1_DEVICE
 #endif
 
 INTEGER  :: JIU,JJU,JKU
@@ -234,18 +227,19 @@ allocate( zy                  (JIU,JJU,JKU ) )
 allocate( zgam                (JIU,JJU,JKU ) )
 allocate( zbet                (JIU,JJU ) )
 #else
-izrhodj_dfddtdz_o_dz2 = MNH_ALLOCATE_FLAT( zrhodj_dfddtdz_o_dz2, JIU, JJU, JKU )
-izmzm_rhodj           = MNH_ALLOCATE_FLAT( zmzm_rhodj          , JIU, JJU, JKU )
-iza                   = MNH_ALLOCATE_FLAT( za                  , JIU, JJU, JKU )
-izb                   = MNH_ALLOCATE_FLAT( zb                  , JIU, JJU, JKU )
-izc                   = MNH_ALLOCATE_FLAT( zc                  , JIU, JJU, JKU )
-izy                   = MNH_ALLOCATE_FLAT( zy                  , JIU, JJU, JKU )
-izgam                 = MNH_ALLOCATE_FLAT( zgam                , JIU, JJU, JKU )
-izbet                 = MNH_ALLOCATE_FLAT( zbet                , JIU, JJU )
-#endif
+!Pin positions in the pools of MNH memory
+CALL MNH_MEM_POSITION_PIN()
 
-#ifdef MNH_OPENACC
-iztmp1_device = MNH_ALLOCATE_FLAT( ztmp1_device, JIU, JJU, JKU )
+CALL MNH_MEM_GET( zrhodj_dfddtdz_o_dz2, JIU, JJU, JKU )
+CALL MNH_MEM_GET( zmzm_rhodj          , JIU, JJU, JKU )
+CALL MNH_MEM_GET( za                  , JIU, JJU, JKU )
+CALL MNH_MEM_GET( zb                  , JIU, JJU, JKU )
+CALL MNH_MEM_GET( zc                  , JIU, JJU, JKU )
+CALL MNH_MEM_GET( zy                  , JIU, JJU, JKU )
+CALL MNH_MEM_GET( zgam                , JIU, JJU, JKU )
+CALL MNH_MEM_GET( zbet                , JIU, JJU )
+
+CALL MNH_MEM_GET( ztmp1_device, JIU, JJU, JKU )
 #endif
 
 !$acc data present( zrhodj_dfddtdz_o_dz2, zmzm_rhodj, za, zb, zc, zy, zgam, zbet, ztmp1_device )
@@ -478,8 +472,8 @@ end if
 #ifndef MNH_OPENACC
 deallocate (zrhodj_dfddtdz_o_dz2,zmzm_rhodj,za,zb,zc,zy,zgam,zbet)
 #else
-CALL MNH_RELEASE_FLAT( IZRHODJ_DFDDTDZ_O_DZ2, IZMZM_RHODJ, IZA, IZB, IZC, IZY, IZGAM, &
-                       IZBET, iztmp1_device )
+!Release all memory allocated with MNH_MEM_GET calls since last call to MNH_MEM_POSITION_PIN
+CALL MNH_MEM_RELEASE()
 #endif
 
 !$acc end data
diff --git a/src/ZSOLVER/turb.f90 b/src/ZSOLVER/turb.f90
index 450f91cc169e078e7ce4ab696abda38b0cda1301..717657c05299e2c7626ae1e7fe4b872dd9190d6b 100644
--- a/src/ZSOLVER/turb.f90
+++ b/src/ZSOLVER/turb.f90
@@ -9,7 +9,7 @@ module mode_turb
 
 #ifdef MNH_OPENACC
   use mode_msg
-  USE MODE_MNH_ZWORK, ONLY: MNH_ALLOCATE_FLAT, MNH_RELEASE_FLAT
+  USE MODE_MNH_ZWORK, ONLY: MNH_MEM_GET, MNH_MEM_POSITION_PIN, MNH_MEM_RELEASE
 #endif
 
 #ifdef MNH_BITREP
@@ -418,11 +418,6 @@ REAL, POINTER , CONTIGUOUS, DIMENSION(:,:,:) ::&
           ZMWTH,ZMWR,ZMTH2,ZMR2,ZMTHR,&  ! 3rd order moments
           ZFWTH,ZFWR,ZFTH2,ZFR2,ZFTHR,&  ! opposite of verticale derivate of 3rd order moments
           ZTHLM                          ! initial potential temp.
-#ifdef MNH_OPENACC
-INTEGER :: IZCP,IZEXN,IZT,IZLOCPEXNM,IZLEPS,IZTRH,IZATHETA,IZAMOIST &
-          ,IZCOEF_DISS,IZFRAC_ICE,IZMWTH,IZMWR,IZMTH2,IZMR2,IZMTHR &
-          ,IZFWTH,IZFWR,IZFTH2,IZFR2,IZFTHR,IZTHLM
-#endif
 !
 REAL, POINTER , CONTIGUOUS, DIMENSION(:,:,:,:) ::     &
           ZRM                            ! initial mixing ratio
@@ -441,16 +436,9 @@ REAL, POINTER , CONTIGUOUS, DIMENSION(:,:) ::  ZTAU11M,ZTAU12M,  &
 !
             ! Virtual Potential Temp. used
             ! in the Deardorff mixing length computation
-#ifdef MNH_OPENACC
-INTEGER :: IZRM,IZTAU11M,IZTAU12M,IZTAU22M,IZTAU33M,IZUSLOPE,IZVSLOPE &
-          ,IZCDUEFF,IZUSTAR,IZLMO,IZRVM,IZSFRV
-#endif
 REAL, DIMENSION(:,:,:), POINTER , CONTIGUOUS  :: &
           ZLVOCPEXNM,ZLSOCPEXNM,      &  ! Lv/Cp/EXNREF and Ls/Cp/EXNREF at t-1
           ZATHETA_ICE,ZAMOIST_ICE        ! coefficients for s = f (Thetal,Rnp)
-#ifdef MNH_OPENACC
-INTEGER :: IZLVOCPEXNM,IZLSOCPEXNM,IZATHETA_ICE,IZAMOIST_ICE
-#endif
 !
 REAL                :: ZEXPL        ! 1-PIMPL deg of expl.
 REAL                :: ZRVORD       ! RV/RD
@@ -469,14 +457,10 @@ REAL                :: ZALPHA       ! work coefficient :
 REAL :: ZTIME1, ZTIME2
 REAL, DIMENSION(:,:,:), pointer , contiguous :: ZTT,ZEXNE,ZLV,ZCPH
 REAL, DIMENSION(:,:,:), pointer , contiguous :: ZSHEAR, ZDUDZ, ZDVDZ
-#ifdef MNH_OPENACC
-INTEGER :: IZTT,IZEXNE,IZLV,IZCPH,IZSHEAR, IZDUDZ, IZDVDZ
-#endif
 TYPE(TFIELDDATA) :: TZFIELD
 !
 #ifdef MNH_OPENACC
 REAL, DIMENSION(:,:,:), pointer , contiguous :: ZTMP1_DEVICE,ZTMP2_DEVICE,ZTMP3_DEVICE
-INTEGER :: IZTMP1_DEVICE,IZTMP2_DEVICE,IZTMP3_DEVICE
 #endif
 !
 INTEGER  :: JIU,JJU,JKU
@@ -615,74 +599,74 @@ allocate( zdudz (JIU,JJU, JKU_TURB ) )
 allocate( zdvdz (JIU,JJU, JKU_TURB ) )
 
 #else
-IZCP        = MNH_ALLOCATE_FLAT( ZCP,        JIU, JJU, JKU )
-IZEXN       = MNH_ALLOCATE_FLAT( ZEXN,       JIU, JJU, JKU )
-IZT         = MNH_ALLOCATE_FLAT( ZT,         JIU, JJU, JKU )
-IZLOCPEXNM  = MNH_ALLOCATE_FLAT( ZLOCPEXNM,  JIU, JJU, JKU )
-IZLEPS      = MNH_ALLOCATE_FLAT( ZLEPS,      JIU, JJU, JKU )
-IZTRH       = MNH_ALLOCATE_FLAT( ZTRH,       JIU, JJU, JKU )
-IZATHETA    = MNH_ALLOCATE_FLAT( ZATHETA,    JIU, JJU, JKU )
-IZAMOIST    = MNH_ALLOCATE_FLAT( ZAMOIST,    JIU, JJU, JKU )
-IZCOEF_DISS = MNH_ALLOCATE_FLAT( ZCOEF_DISS, JIU, JJU, JKU )
-IZFRAC_ICE  = MNH_ALLOCATE_FLAT( ZFRAC_ICE,  JIU, JJU, JKU )
-
-IZMWTH = MNH_ALLOCATE_FLAT( ZMWTH, JIU, JJU, JKU )
-IZMWR  = MNH_ALLOCATE_FLAT( ZMWR,  JIU, JJU, JKU )
-IZMTH2 = MNH_ALLOCATE_FLAT( ZMTH2, JIU, JJU, JKU )
-IZMR2  = MNH_ALLOCATE_FLAT( ZMR2,  JIU, JJU, JKU )
-IZMTHR = MNH_ALLOCATE_FLAT( ZMTHR, JIU, JJU, JKU )
-
-IZFWTH = MNH_ALLOCATE_FLAT( ZFWTH, JIU, JJU, JKU )
-IZFWR  = MNH_ALLOCATE_FLAT( ZFWR,  JIU, JJU, JKU )
-IZFTH2 = MNH_ALLOCATE_FLAT( ZFTH2, JIU, JJU, JKU )
-IZFR2  = MNH_ALLOCATE_FLAT( ZFR2,  JIU, JJU, JKU )
-IZFTHR = MNH_ALLOCATE_FLAT( ZFTHR, JIU, JJU, JKU )
-IZTHLM = MNH_ALLOCATE_FLAT( ZTHLM, JIU, JJU, JKU )
+!Pin positions in the pools of MNH memory
+CALL MNH_MEM_POSITION_PIN()
+
+CALL MNH_MEM_GET( ZCP,        JIU, JJU, JKU )
+CALL MNH_MEM_GET( ZEXN,       JIU, JJU, JKU )
+CALL MNH_MEM_GET( ZT,         JIU, JJU, JKU )
+CALL MNH_MEM_GET( ZLOCPEXNM,  JIU, JJU, JKU )
+CALL MNH_MEM_GET( ZLEPS,      JIU, JJU, JKU )
+CALL MNH_MEM_GET( ZTRH,       JIU, JJU, JKU )
+CALL MNH_MEM_GET( ZATHETA,    JIU, JJU, JKU )
+CALL MNH_MEM_GET( ZAMOIST,    JIU, JJU, JKU )
+CALL MNH_MEM_GET( ZCOEF_DISS, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ZFRAC_ICE,  JIU, JJU, JKU )
+
+CALL MNH_MEM_GET( ZMWTH, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ZMWR,  JIU, JJU, JKU )
+CALL MNH_MEM_GET( ZMTH2, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ZMR2,  JIU, JJU, JKU )
+CALL MNH_MEM_GET( ZMTHR, JIU, JJU, JKU )
+
+CALL MNH_MEM_GET( ZFWTH, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ZFWR,  JIU, JJU, JKU )
+CALL MNH_MEM_GET( ZFTH2, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ZFR2,  JIU, JJU, JKU )
+CALL MNH_MEM_GET( ZFTHR, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ZTHLM, JIU, JJU, JKU )
 
 JLU_ZRM = 0 
 IF ( HTURBLEN == 'BL89' .OR. HTURBLEN == 'RM17' .OR. ORMC01 ) JLU_ZRM = SIZE(PRT,4)
-IZRM = MNH_ALLOCATE_FLAT( ZRM, JIU, JJU, JKU, JLU_ZRM )
+CALL MNH_MEM_GET( ZRM, JIU, JJU, JKU, JLU_ZRM )
 
-IZTAU11M = MNH_ALLOCATE_FLAT( ZTAU11M, JIU, JJU )
-IZTAU12M = MNH_ALLOCATE_FLAT( ZTAU12M, JIU, JJU )
-IZTAU22M = MNH_ALLOCATE_FLAT( ZTAU22M, JIU, JJU )
-IZTAU33M = MNH_ALLOCATE_FLAT( ZTAU33M, JIU, JJU )
-IZUSLOPE = MNH_ALLOCATE_FLAT( ZUSLOPE, JIU, JJU )
-IZVSLOPE = MNH_ALLOCATE_FLAT( ZVSLOPE, JIU, JJU )
-IZCDUEFF = MNH_ALLOCATE_FLAT( ZCDUEFF, JIU, JJU )
-IZLMO    = MNH_ALLOCATE_FLAT( ZLMO,    JIU, JJU )
+CALL MNH_MEM_GET( ZTAU11M, JIU, JJU )
+CALL MNH_MEM_GET( ZTAU12M, JIU, JJU )
+CALL MNH_MEM_GET( ZTAU22M, JIU, JJU )
+CALL MNH_MEM_GET( ZTAU33M, JIU, JJU )
+CALL MNH_MEM_GET( ZUSLOPE, JIU, JJU )
+CALL MNH_MEM_GET( ZVSLOPE, JIU, JJU )
+CALL MNH_MEM_GET( ZCDUEFF, JIU, JJU )
+CALL MNH_MEM_GET( ZLMO,    JIU, JJU )
 
 JJU_ORMC01 = 0
 IF (ORMC01) JJU_ORMC01 = SIZE(PTHLT,2)
-IZUSTAR = MNH_ALLOCATE_FLAT( ZUSTAR, JIU, JJU_ORMC01 )
-IZRVM   = MNH_ALLOCATE_FLAT( ZRVM,   JIU, JJU_ORMC01 )
-IZSFRV  = MNH_ALLOCATE_FLAT( ZSFRV,  JIU, JJU_ORMC01 )
+CALL MNH_MEM_GET( ZUSTAR, JIU, JJU_ORMC01 )
+CALL MNH_MEM_GET( ZRVM,   JIU, JJU_ORMC01 )
+CALL MNH_MEM_GET( ZSFRV,  JIU, JJU_ORMC01 )
 
 JKU_CLOUD = 0 
 IF ( HCLOUD == 'KHKO' .OR. HCLOUD == 'C2R2' ) JKU_CLOUD = size( put, 3 )
-iztt   = MNH_ALLOCATE_FLAT( ztt,   JIU, JJU, JKU_CLOUD )
-izexne = MNH_ALLOCATE_FLAT( zexne, JIU, JJU, JKU_CLOUD )
-izlv   = MNH_ALLOCATE_FLAT( zlv,   JIU, JJU, JKU_CLOUD )
-izcph  = MNH_ALLOCATE_FLAT( zcph,  JIU, JJU, JKU_CLOUD )
+CALL MNH_MEM_GET( ztt,   JIU, JJU, JKU_CLOUD )
+CALL MNH_MEM_GET( zexne, JIU, JJU, JKU_CLOUD )
+CALL MNH_MEM_GET( zlv,   JIU, JJU, JKU_CLOUD )
+CALL MNH_MEM_GET( zcph,  JIU, JJU, JKU_CLOUD )
 
 JKU_TURB = 0  
 IF ( HTURBLEN == 'BL89' .OR. HTURBLEN == 'RM17' ) JKU_TURB = size( put, 3 )
-izshear = MNH_ALLOCATE_FLAT( zshear, JIU, JJU, JKU_TURB )
+CALL MNH_MEM_GET( zshear, JIU, JJU, JKU_TURB )
 
 JKU_TURB = 0
 IF ( HTURBLEN == 'RM17' ) JKU_TURB = size( put, 3 )
-izdudz = MNH_ALLOCATE_FLAT( zdudz, JIU, JJU, JKU_TURB )
-izdvdz = MNH_ALLOCATE_FLAT( zdvdz, JIU, JJU, JKU_TURB )
-
-#endif
+CALL MNH_MEM_GET( zdudz, JIU, JJU, JKU_TURB )
+CALL MNH_MEM_GET( zdvdz, JIU, JJU, JKU_TURB )
 
-#ifdef MNH_OPENACC
-iztmp1_device = MNH_ALLOCATE_FLAT( ztmp1_device, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ztmp1_device, JIU, JJU, JKU )
 
 JKU_TURB = 0
 IF (HTURBDIM=="1DIM") JKU_TURB = size( pthlt, 3 )
-iztmp2_device = MNH_ALLOCATE_FLAT( ztmp2_device, JIU, JJU, JKU_TURB )
-iztmp3_device = MNH_ALLOCATE_FLAT( ztmp3_device, JIU, JJU, JKU_TURB )
+CALL MNH_MEM_GET( ztmp2_device, JIU, JJU, JKU_TURB )
+CALL MNH_MEM_GET( ztmp3_device, JIU, JJU, JKU_TURB )
 
 #endif
 
@@ -1605,21 +1589,8 @@ deallocate( zcp, zexn, zt, zlocpexnm, zleps, ztrh,         &
             zustar, zrvm, zsfrv,                           &
             ztt, zexne, zlv, zcph, zshear,  zdudz,  zdvdz  )
 #else
-
-CALL MNH_RELEASE_FLAT( iztt, izexne, izlv, izcph, izshear,  izdudz,  izdvdz, &
-                       iztmp1_device, iztmp2_device, iztmp3_device       )
-
-CALL MNH_RELEASE_FLAT( iztau11m, iztau12m, iztau22m, iztau33m,   &
-                       izuslope, izvslope, izcdueff, izlmo,      &
-                       izustar, izrvm, izsfrv                   )
-
-CALL MNH_RELEASE_FLAT( izrm)
-
-CALL MNH_RELEASE_FLAT( izmwth, izmwr, izmth2, izmr2, izmthr,        &
-                       izfwth, izfwr, izfth2, izfr2, izfthr, izthlm )
-
-CALL MNH_RELEASE_FLAT( izcp, izexn, izt, izlocpexnm, izleps, iztrh, &
-                       izatheta, izamoist, izcoef_diss, izfrac_ice  )
+!Release all memory allocated with MNH_MEM_GET calls since last call to MNH_MEM_POSITION_PIN
+CALL MNH_MEM_RELEASE()
 #endif
 
 !$acc end data
@@ -1775,9 +1746,6 @@ REAL, DIMENSION(:,:,:), INTENT(OUT)   :: PAMOIST,PATHETA
 REAL                :: ZEPS         ! XMV / XMD
 real, dimension(:,:,:), pointer , contiguous :: zrvsat
 real, dimension(:,:,:), pointer , contiguous :: zdrvsatdt
-#ifdef MNH_OPENACC
-INTEGER :: izrvsat, izdrvsatdt
-#endif
 !
 !-------------------------------------------------------------------------------
 
@@ -1794,8 +1762,11 @@ INTEGER :: izrvsat, izdrvsatdt
   allocate( zrvsat   ( size( pexn, 1 ), size( pexn, 2 ), size( pexn, 3 ) ) )
   allocate( zdrvsatdt( size( pexn, 1 ), size( pexn, 2 ), size( pexn, 3 ) ) )
 #else
-izrvsat    = MNH_ALLOCATE_FLAT( zrvsat   , size( pexn, 1 ), size( pexn, 2 ), size( pexn, 3 ) )
-izdrvsatdt = MNH_ALLOCATE_FLAT( zdrvsatdt, size( pexn, 1 ), size( pexn, 2 ), size( pexn, 3 ) )
+!Pin positions in the pools of MNH memory
+CALL MNH_MEM_POSITION_PIN()
+
+CALL MNH_MEM_GET( zrvsat   , size( pexn, 1 ), size( pexn, 2 ), size( pexn, 3 ) )
+CALL MNH_MEM_GET( zdrvsatdt, size( pexn, 1 ), size( pexn, 2 ), size( pexn, 3 ) )
 #endif
 
 !$acc data present( zrvsat, zdrvsatdt )
@@ -1870,7 +1841,8 @@ izdrvsatdt = MNH_ALLOCATE_FLAT( zdrvsatdt, size( pexn, 1 ), size( pexn, 2 ), siz
 #ifndef MNH_OPENACC 
   deallocate( zrvsat, zdrvsatdt )
 #else
-  CALL MNH_RELEASE_FLAT( izrvsat, izdrvsatdt )
+  !Release all memory allocated with MNH_MEM_GET calls since last call to MNH_MEM_POSITION_PIN
+  CALL MNH_MEM_RELEASE()
 #endif
  
 !$acc end data
@@ -2361,13 +2333,9 @@ REAL, DIMENSION(:,:,:), POINTER , CONTIGUOUS ::     &
             ZDTHLDZ,ZDRTDZ,     &!dtheta_l/dz, drt_dz used for computing the stablity
 !                                ! criterion
             ZETHETA,ZEMOIST             !coef ETHETA and EMOIST
-#ifdef MNH_OPENACC
-INTEGER :: IZWORK2D,IZDTHLDZ,IZDRTDZ,IZETHETA,IZEMOIST
-#endif
 !
 #ifdef MNH_OPENACC
 REAL, DIMENSION(:,:,:), POINTER , CONTIGUOUS :: ZTMP1_DEVICE,ZTMP2_DEVICE
-INTEGER :: IZTMP1_DEVICE,IZTMP2_DEVICE
 #endif
 INTEGER  :: JIU,JJU,JKU
 LOGICAL :: GOCEAN !Intermediate variable used to work around a Cray compiler bug (CCE 13.0.0)
@@ -2406,16 +2374,17 @@ allocate( ZDRTDZ (JIU,JJU,JKU) )
 allocate( ZETHETA(JIU,JJU,JKU) )
 allocate( ZEMOIST(JIU,JJU,JKU) )
 #else
-IZWORK2D = MNH_ALLOCATE_FLAT( ZWORK2D, JIU, JJU )
-IZDTHLDZ = MNH_ALLOCATE_FLAT( ZDTHLDZ, JIU, JJU, JKU )
-IZDRTDZ  = MNH_ALLOCATE_FLAT( ZDRTDZ,  JIU, JJU, JKU )
-IZETHETA = MNH_ALLOCATE_FLAT( ZETHETA, JIU, JJU, JKU )
-IZEMOIST = MNH_ALLOCATE_FLAT( ZEMOIST, JIU, JJU, JKU )
-#endif
+!Pin positions in the pools of MNH memory
+CALL MNH_MEM_POSITION_PIN()
 
-#ifdef MNH_OPENACC
-IZTMP1_DEVICE = MNH_ALLOCATE_FLAT( ZTMP1_DEVICE, JIU, JJU, JKU )
-IZTMP2_DEVICE = MNH_ALLOCATE_FLAT( ZTMP2_DEVICE, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ZWORK2D, JIU, JJU )
+CALL MNH_MEM_GET( ZDTHLDZ, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ZDRTDZ,  JIU, JJU, JKU )
+CALL MNH_MEM_GET( ZETHETA, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ZEMOIST, JIU, JJU, JKU )
+
+CALL MNH_MEM_GET( ZTMP1_DEVICE, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ZTMP2_DEVICE, JIU, JJU, JKU )
 #endif
 
 !$acc data present(zwork2d, zdthldz, zdrtdz, zetheta, zemoist, &
@@ -2630,8 +2599,8 @@ end if
 #ifndef MNH_OPENACC
 deallocate(zwork2d, zdthldz, zdrtdz, zetheta, zemoist ) 
 #else
-CALL MNH_RELEASE_FLAT( izwork2d, izdthldz, izdrtdz, izetheta, izemoist, &
-                       iztmp1_device, iztmp2_device )
+!Release all memory allocated with MNH_MEM_GET calls since last call to MNH_MEM_POSITION_PIN
+CALL MNH_MEM_RELEASE()
 #endif
 
 !$acc end data
diff --git a/src/ZSOLVER/turb_hor_dyn_corr.f90 b/src/ZSOLVER/turb_hor_dyn_corr.f90
index 6b74f21fde1b69c049997aed9b1792abe8058c4b..2e0fa87bcfe04d024b88c2201a05fe9d388e00db 100644
--- a/src/ZSOLVER/turb_hor_dyn_corr.f90
+++ b/src/ZSOLVER/turb_hor_dyn_corr.f90
@@ -153,7 +153,7 @@ USE MODD_NSV
 USE MODE_IO_FIELD_WRITE, only: IO_Field_write
 USE MODE_ll
 #ifdef MNH_OPENACC
-USE MODE_MNH_ZWORK,      ONLY: MNH_ALLOCATE_FLAT, MNH_RELEASE_FLAT
+USE MODE_MNH_ZWORK,      ONLY: MNH_MEM_GET, MNH_MEM_POSITION_PIN, MNH_MEM_RELEASE
 #endif
 use mode_mppdb
 !
@@ -235,9 +235,6 @@ REAL, DIMENSION(:,:,:), pointer , contiguous :: ZFLX,ZWORK ! work arrays, PK is
 !
 REAL, DIMENSION(:,:),   pointer , contiguous :: ZDIRSINZW
       ! sinus of the angle between the vertical and the normal to the orography
-#ifdef MNH_OPENACC
-INTEGER :: IZFLX,IZWORK,IZDIRSINZW
-#endif
 INTEGER             :: IKB,IKE
                                     ! Index values for the Beginning and End
                                     ! mass points of the domain  
@@ -248,9 +245,6 @@ REAL, DIMENSION(:,:,:), pointer , contiguous :: GX_U_M_PUM
 REAL, DIMENSION(:,:,:), pointer , contiguous :: GY_V_M_PVM
 REAL, DIMENSION(:,:,:), pointer , contiguous :: GZ_W_M_PWM
 REAL, DIMENSION(:,:,:), pointer , contiguous :: GZ_W_M_ZWP
-#ifdef MNH_OPENACC
-INTEGER :: IGX_U_M_PUM,IGY_V_M_PVM,IGZ_W_M_PWM,IGZ_W_M_ZWP
-#endif
 REAL, DIMENSION(:,:,:), pointer , contiguous :: ZMZF_DZZ   ! MZF(PDZZ)
 REAL, DIMENSION(:,:,:), pointer , contiguous :: ZDFDDWDZ   ! formal derivative of the
 !                                                 ! flux (variable: dW/dz)
@@ -261,10 +255,6 @@ REAL, DIMENSION(:,:,:), pointer , contiguous :: ZDV_DZ_DZS_DY ! dv/dz*dzs/dy sur
 REAL, DIMENSION(:,:,:), pointer , contiguous :: ZDU_DX        ! du/dx        surf
 REAL, DIMENSION(:,:,:), pointer , contiguous :: ZDV_DY        ! dv/dy        surf
 REAL, DIMENSION(:,:,:), pointer , contiguous :: ZDW_DZ        ! dw/dz        surf
-#ifdef MNH_OPENACC
-INTEGER :: IZMZF_DZZ,IZDFDDWDZ,IZWP,IZDU_DZ_DZS_DX,IZDV_DZ_DZS_DY &
-           ,IZDU_DX,IZDV_DY,IZDW_DZ 
-#endif
 !
 INTEGER                :: IINFO_ll      ! return code of parallel routine
 TYPE(LIST_ll), POINTER :: TZFIELDS_ll   ! list of fields to exchange
@@ -275,13 +265,9 @@ REAL :: ZTIME1, ZTIME2
 REAL, DIMENSION(:,:,:), pointer , contiguous :: ZCOEFF , ZDZZ
                                     ! coefficients for the uncentred gradient 
                                     ! computation near the ground
-#ifdef MNH_OPENACC
-INTEGER  :: IZCOEFF , IZDZZ
-#endif
 !
 #ifdef MNH_OPENACC
 REAL, DIMENSION(:,:,:), pointer , contiguous :: ZTMP1_DEVICE, ZTMP2_DEVICE, ZTMP3_DEVICE, ZTMP4_DEVICE
-INTEGER :: IZTMP1_DEVICE, IZTMP2_DEVICE, IZTMP3_DEVICE, IZTMP4_DEVICE
 #endif
 TYPE(TFIELDDATA) :: TZFIELD
 !
@@ -359,34 +345,35 @@ allocate( zdw_dz       (JIU,JJU, 1 ) )
 allocate( zcoeff(JIU,JJU, 1 + jpvext : 3 + jpvext ) )
 allocate( zdzz  (JIU,JJU, 1 + jpvext : 3 + jpvext ) )
 #else
-izflx          = MNH_ALLOCATE_FLAT( zflx,  JIU, JJU, JKU )
-izwork         = MNH_ALLOCATE_FLAT( zwork, JIU, JJU, JKU )
+!Pin positions in the pools of MNH memory
+CALL MNH_MEM_POSITION_PIN()
 
-izdirsinzw     = MNH_ALLOCATE_FLAT( zdirsinzw,JIU,JJU )
+CALL MNH_MEM_GET( zflx,  JIU, JJU, JKU )
+CALL MNH_MEM_GET( zwork, JIU, JJU, JKU )
 
-igx_u_m_pum    = MNH_ALLOCATE_FLAT( gx_u_m_pum, JIU, JJU, JKU )
-igy_v_m_pvm    = MNH_ALLOCATE_FLAT( gy_v_m_pvm, JIU, JJU, JKU )
-igz_w_m_pwm    = MNH_ALLOCATE_FLAT( gz_w_m_pwm, JIU, JJU, JKU )
-igz_w_m_zwp    = MNH_ALLOCATE_FLAT( gz_w_m_zwp, JIU, JJU, JKU )
-izmzf_dzz      = MNH_ALLOCATE_FLAT( zmzf_dzz,   JIU, JJU, JKU )
-izdfddwdz      = MNH_ALLOCATE_FLAT( zdfddwdz,   JIU, JJU, JKU )
-izwp           = MNH_ALLOCATE_FLAT( zwp,        JIU, JJU, JKU )
+CALL MNH_MEM_GET( zdirsinzw,JIU,JJU )
 
-izdu_dz_dzs_dx = MNH_ALLOCATE_FLAT( zdu_dz_dzs_dx,1, JIU, 1, JJU, 1 , 1 )
-izdv_dz_dzs_dy = MNH_ALLOCATE_FLAT( zdv_dz_dzs_dy,1, JIU, 1, JJU, 1 , 1 )
-izdu_dx        = MNH_ALLOCATE_FLAT( zdu_dx,       1, JIU, 1, JJU, 1 , 1 )
-izdv_dy        = MNH_ALLOCATE_FLAT( zdv_dy,       1, JIU, 1, JJU, 1 , 1 )
-izdw_dz        = MNH_ALLOCATE_FLAT( zdw_dz,       1, JIU, 1, JJU, 1 , 1 )
+CALL MNH_MEM_GET( gx_u_m_pum, JIU, JJU, JKU )
+CALL MNH_MEM_GET( gy_v_m_pvm, JIU, JJU, JKU )
+CALL MNH_MEM_GET( gz_w_m_pwm, JIU, JJU, JKU )
+CALL MNH_MEM_GET( gz_w_m_zwp, JIU, JJU, JKU )
+CALL MNH_MEM_GET( zmzf_dzz,   JIU, JJU, JKU )
+CALL MNH_MEM_GET( zdfddwdz,   JIU, JJU, JKU )
+CALL MNH_MEM_GET( zwp,        JIU, JJU, JKU )
 
-izcoeff        = MNH_ALLOCATE_FLAT( zcoeff,1, JIU, 1, JJU, 1 + jpvext, 3 + jpvext )
-izdzz          = MNH_ALLOCATE_FLAT( zdzz,  1, JIU, 1, JJU, 1 + jpvext, 3 + jpvext )
-#endif
+CALL MNH_MEM_GET( zdu_dz_dzs_dx,1, JIU, 1, JJU, 1 , 1 )
+CALL MNH_MEM_GET( zdv_dz_dzs_dy,1, JIU, 1, JJU, 1 , 1 )
+CALL MNH_MEM_GET( zdu_dx,       1, JIU, 1, JJU, 1 , 1 )
+CALL MNH_MEM_GET( zdv_dy,       1, JIU, 1, JJU, 1 , 1 )
+CALL MNH_MEM_GET( zdw_dz,       1, JIU, 1, JJU, 1 , 1 )
 
-#ifdef MNH_OPENACC
-iztmp1_device = MNH_ALLOCATE_FLAT( ztmp1_device, JIU, JJU, JKU )
-iztmp2_device = MNH_ALLOCATE_FLAT( ztmp2_device, JIU, JJU, JKU )
-iztmp3_device = MNH_ALLOCATE_FLAT( ztmp3_device, JIU, JJU, JKU )
-iztmp4_device = MNH_ALLOCATE_FLAT( ztmp4_device, JIU, JJU, JKU )
+CALL MNH_MEM_GET( zcoeff,1, JIU, 1, JJU, 1 + jpvext, 3 + jpvext )
+CALL MNH_MEM_GET( zdzz,  1, JIU, 1, JJU, 1 + jpvext, 3 + jpvext )
+
+CALL MNH_MEM_GET( ztmp1_device, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ztmp2_device, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ztmp3_device, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ztmp4_device, JIU, JJU, JKU )
 #endif
 
 !$acc data present(ZFLX, ZWORK, ZDIRSINZW, ZCOEFF, ZDZZ,                  &
@@ -1337,15 +1324,9 @@ DEALLOCATE (ZFLX, ZWORK, ZDIRSINZW, ZCOEFF, ZDZZ,                  &
             ZMZF_DZZ, ZDFDDWDZ, ZWP,                               &
             ZDU_DZ_DZS_DX, ZDV_DZ_DZS_DY, ZDU_DX, ZDV_DY, ZDW_DZ   )
 #else
-CALL MNH_RELEASE_FLAT( IZTMP1_DEVICE, IZTMP2_DEVICE, IZTMP3_DEVICE, IZTMP4_DEVICE )
-CALL MNH_RELEASE_FLAT( IZFLX, IZWORK, IZDIRSINZW,                                 &
-                       IGX_U_M_PUM, IGY_V_M_PVM, IGZ_W_M_PWM, IGZ_W_M_ZWP,        &
-                       IZMZF_DZZ, IZDFDDWDZ, IZWP,                                &
-                       IZDU_DZ_DZS_DX, IZDV_DZ_DZS_DY, IZDU_DX, IZDV_DY, IZDW_DZ, &
-                       IZCOEFF, IZDZZ                                             )
-
+!Release all memory allocated with MNH_MEM_GET calls since last call to MNH_MEM_POSITION_PIN
+CALL MNH_MEM_RELEASE()
 #endif
-     
 
 !$acc end data
 
diff --git a/src/ZSOLVER/turb_hor_thermo_flux.f90 b/src/ZSOLVER/turb_hor_thermo_flux.f90
index a6b56908f57da52dfbab2c4635802e1806090c3c..dc9982bb854360536fcb48955bb3c6f35433d26b 100644
--- a/src/ZSOLVER/turb_hor_thermo_flux.f90
+++ b/src/ZSOLVER/turb_hor_thermo_flux.f90
@@ -152,7 +152,7 @@ USE MODI_LES_MEAN_SUBGRID
 USE MODI_SECOND_MNH
 !
 #ifdef MNH_OPENACC
-USE MODE_MNH_ZWORK,      ONLY: MNH_ALLOCATE_FLAT, MNH_RELEASE_FLAT
+USE MODE_MNH_ZWORK,      ONLY: MNH_MEM_GET, MNH_MEM_POSITION_PIN, MNH_MEM_RELEASE
 #endif
 !
 IMPLICIT NONE
@@ -215,17 +215,12 @@ INTEGER             :: IKB,IKE,IKU
 REAL, DIMENSION(:,:,:), pointer , contiguous :: ZCOEFF
                                     ! coefficients for the uncentred gradient 
                                     ! computation near the ground
-#ifdef MNH_OPENACC
-INTEGER :: IZFLX,IZFLXC,IZCOEFF
-#endif
 !
 REAL :: ZTIME1, ZTIME2
 !
 #ifdef MNH_OPENACC
 REAL, DIMENSION(:,:,:), pointer , contiguous :: ZTMP1_DEVICE, ZTMP2_DEVICE, ZTMP3_DEVICE, ZTMP4_DEVICE
 REAL, DIMENSION(:,:,:), pointer , contiguous :: ZTMP5_DEVICE, ZTMP6_DEVICE, ZTMP7_DEVICE, ZTMP8_DEVICE
-INTEGER ::  IZTMP1_DEVICE, IZTMP2_DEVICE, IZTMP3_DEVICE, IZTMP4_DEVICE, &
-            IZTMP5_DEVICE, IZTMP6_DEVICE, IZTMP7_DEVICE, IZTMP8_DEVICE
 #endif
 !
 TYPE(TFIELDDATA) :: TZFIELD
@@ -283,23 +278,23 @@ allocate( zflxc(JIU,JJU,JKU) )
 
 allocate( zcoeff(JIU,JJU, 1 + jpvext : 3 + jpvext ) )
 #else
-izflx  = MNH_ALLOCATE_FLAT( zflx,  JIU, JJU, JKU )
-izflxc = MNH_ALLOCATE_FLAT( zflxc, JIU, JJU, JKU )
-! izvptv= MNH_ALLOCATE_FLAT( zvptv, JIU, JJU, JKU )
+!Pin positions in the pools of MNH memory
+CALL MNH_MEM_POSITION_PIN()
 
-izcoeff= MNH_ALLOCATE_FLAT( zcoeff, 1, JIU, 1, JJU, 1 + jpvext, 3 + jpvext )
+CALL MNH_MEM_GET( zflx,  JIU, JJU, JKU )
+CALL MNH_MEM_GET( zflxc, JIU, JJU, JKU )
+! CALL MNH_MEM_GET( zvptv, JIU, JJU, JKU )
 
-#endif
+CALL MNH_MEM_GET( zcoeff, 1, JIU, 1, JJU, 1 + jpvext, 3 + jpvext )
 
-#ifdef MNH_OPENACC
-iztmp1_device = MNH_ALLOCATE_FLAT( ztmp1_device, JIU, JJU, JKU )
-iztmp2_device = MNH_ALLOCATE_FLAT( ztmp2_device, JIU, JJU, JKU )
-iztmp3_device = MNH_ALLOCATE_FLAT( ztmp3_device, JIU, JJU, JKU )
-iztmp4_device = MNH_ALLOCATE_FLAT( ztmp4_device, JIU, JJU, JKU )
-iztmp5_device = MNH_ALLOCATE_FLAT( ztmp5_device, JIU, JJU, JKU )
-iztmp6_device = MNH_ALLOCATE_FLAT( ztmp6_device, JIU, JJU, JKU )
-iztmp7_device = MNH_ALLOCATE_FLAT( ztmp7_device, JIU, JJU, JKU )
-iztmp8_device = MNH_ALLOCATE_FLAT( ztmp8_device, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ztmp1_device, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ztmp2_device, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ztmp3_device, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ztmp4_device, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ztmp5_device, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ztmp6_device, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ztmp7_device, JIU, JJU, JKU )
+CALL MNH_MEM_GET( ztmp8_device, JIU, JJU, JKU )
 #endif
 
 !$acc data present( ZFLX, ZFLXC, ZCOEFF,                                    &
@@ -1844,9 +1839,8 @@ end if
 #ifndef MNH_OPENACC
 deallocate (zflx,zflxc,zcoeff)
 #else
-CALL MNH_RELEASE_FLAT( IZFLX, IZFLXC, IZCOEFF,                                     &
-                       IZTMP1_DEVICE, IZTMP2_DEVICE, IZTMP3_DEVICE, IZTMP4_DEVICE, &
-                       IZTMP5_DEVICE, IZTMP6_DEVICE, IZTMP7_DEVICE, IZTMP8_DEVICE  )
+!Release all memory allocated with MNH_MEM_GET calls since last call to MNH_MEM_POSITION_PIN
+CALL MNH_MEM_RELEASE()
 #endif
 
 !$acc end data
diff --git a/src/ZSOLVER/zsolver.f90 b/src/ZSOLVER/zsolver.f90
index ab198f36eb049c0b6e9eecf224e04f08770feac2..15130e126c3b527659897b3fae7947862222e011 100644
--- a/src/ZSOLVER/zsolver.f90
+++ b/src/ZSOLVER/zsolver.f90
@@ -1,13 +1,8 @@
-!MNH_LIC Copyright 1994-2014 CNRS, Meteo-France and Universite Paul Sabatier
+!MNH_LIC Copyright 1994-2022 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.
 !-----------------------------------------------------------------
-!--------------- special set of characters for RCS information
-!-----------------------------------------------------------------
-! $Source$ $Revision$
-! MASDEV4_7 solver 2006/05/18 13:07:25
-!-----------------------------------------------------------------
 !     ####################
       MODULE MODI_ZSOLVER
 !     ####################
@@ -154,7 +149,7 @@ USE MODI_ZSOLVER_INV
 USE MODI_DOTPROD
 !
 #ifdef MNH_OPENACC
-USE MODE_MNH_ZWORK, ONLY: MNH_ALLOCATE_FLAT, MNH_RELEASE_FLAT
+USE MODE_MNH_ZWORK, ONLY: MNH_MEM_GET, MNH_MEM_POSITION_PIN, MNH_MEM_RELEASE
 #endif
 !
 !
@@ -220,7 +215,6 @@ REAL, DIMENSION(:,:,:), pointer , contiguous :: ZP, ZQ
      ! array containing the auxilary fields P and Q of the CR method
 REAL, DIMENSION(:,:,:), pointer , contiguous :: ZRESIDUE
      ! array containing the error field at each iteration Q(PHI) - Y
-INTEGER :: IZDELTA, IZKSI, IZP, IZQ, IZRESIDUE
 !
 REAL :: ZALPHA, ZLAMBDA      ! amplitude of the descent in the Conjugate
                              ! directions
@@ -240,12 +234,14 @@ JKU =  size(PPHI, 3 )
 #ifndef MNH_OPENACC
 ALLOCATE(ZDELTA(JIU,JJU,JKU),ZKSI(JIU,JJU,JKU),ZP(JIU,JJU,JKU),ZQ(JIU,JJU,JKU),ZRESIDUE(JIU,JJU,JKU))
 #else
-IZDELTA   = MNH_ALLOCATE_FLAT( ZDELTA   , JIU, JJU, JKU )
-IZKSI     = MNH_ALLOCATE_FLAT( ZKSI     , JIU, JJU, JKU )
-IZP       = MNH_ALLOCATE_FLAT( ZP       , JIU, JJU, JKU )
-IZQ       = MNH_ALLOCATE_FLAT( ZQ       , JIU, JJU, JKU )
-IZRESIDUE = MNH_ALLOCATE_FLAT( ZRESIDUE , JIU, JJU, JKU )
+!Pin positions in the pools of MNH memory
+CALL MNH_MEM_POSITION_PIN()
 
+CALL MNH_MEM_GET( ZDELTA   , JIU, JJU, JKU )
+CALL MNH_MEM_GET( ZKSI     , JIU, JJU, JKU )
+CALL MNH_MEM_GET( ZP       , JIU, JJU, JKU )
+CALL MNH_MEM_GET( ZQ       , JIU, JJU, JKU )
+CALL MNH_MEM_GET( ZRESIDUE , JIU, JJU, JKU )
 #endif
 !*       1.1    compute the vector: r^(0) =  Q(PHI) - Y
 !
@@ -333,7 +329,8 @@ END DO              ! end of the loop for the iterative solver
 #ifndef MNH_OPENACC
 DEALLOCATE(ZDELTA,ZKSI,ZP,ZQ,ZRESIDUE)
 #else
-CALL MNH_RELEASE_FLAT( IZDELTA, IZKSI, IZP, IZQ, IZRESIDUE )
+!Release all memory allocated with MNH_MEM_GET calls since last call to MNH_MEM_POSITION_PIN
+CALL MNH_MEM_RELEASE()
 #endif
 !-------------------------------------------------------------------------------
 !
diff --git a/src/ZSOLVER/zsolver_inv.f90 b/src/ZSOLVER/zsolver_inv.f90
index cc4d320253076de49d4bec1298737eef67422290..588cd940c310be4366d71d73949d98030fa33144 100644
--- a/src/ZSOLVER/zsolver_inv.f90
+++ b/src/ZSOLVER/zsolver_inv.f90
@@ -146,7 +146,7 @@ SUBROUTINE ZSOLVER_INV(HLBCX,HLBCY,PDXHATM,PDYHATM,PRHOM,PAF,PBF,PCF, &
   !
   USE mode_mg_main_mnh
 #ifdef MNH_OPENACC
-  USE MODE_MNH_ZWORK,   ONLY: MNH_ALLOCATE_FLAT, MNH_RELEASE_FLAT
+  USE MODE_MNH_ZWORK,   ONLY: MNH_MEM_GET, MNH_MEM_POSITION_PIN, MNH_MEM_RELEASE
 #endif
   !
   IMPLICIT NONE
@@ -191,8 +191,6 @@ SUBROUTINE ZSOLVER_INV(HLBCX,HLBCY,PDXHATM,PDYHATM,PRHOM,PAF,PBF,PCF, &
   !
   REAL, DIMENSION(:,:,:), pointer , contiguous :: ZY ! work array to store 
   !                                                    the RHS of the equation
-  INTEGER :: IZY
-  !   
   INTEGER :: IIB          ! indice I for the first inner mass point along x
   INTEGER :: IIE          ! indice I for the last inner mass point along x
   INTEGER :: IJB          ! indice J for the first inner mass point along y
@@ -219,7 +217,10 @@ SUBROUTINE ZSOLVER_INV(HLBCX,HLBCY,PDXHATM,PDYHATM,PRHOM,PAF,PBF,PCF, &
 #ifndef MNH_OPENACC
   ALLOCATE(ZY(IIU,IJU,IKU))
 #else
-  IZY = MNH_ALLOCATE_FLAT( ZY, IIU, IJU, IKU )
+  !Pin positions in the pools of MNH memory
+  CALL MNH_MEM_POSITION_PIN()
+
+  CALL MNH_MEM_GET( ZY, IIU, IJU, IKU )
 #endif
   !
   !-------------------------------------------------------------------------------
@@ -318,7 +319,8 @@ SUBROUTINE ZSOLVER_INV(HLBCX,HLBCY,PDXHATM,PDYHATM,PRHOM,PAF,PBF,PCF, &
 #ifndef MNH_OPENACC
   DEALLOCATE(ZY)
 #else
-  CALL MNH_RELEASE_FLAT( IZY )
+  !Release all memory allocated with MNH_MEM_GET calls since last call to MNH_MEM_POSITION_PIN
+  CALL MNH_MEM_RELEASE()
 #endif  
   !
 CONTAINS