diff --git a/src/ZSOLVER/SURCOUCHE/mode_exchange2_ll.f90 b/src/ZSOLVER/SURCOUCHE/mode_exchange2_ll.f90
new file mode 100644
index 0000000000000000000000000000000000000000..8d2affca44ef628c6003ff27fbe700901b5bba7e
--- /dev/null
+++ b/src/ZSOLVER/SURCOUCHE/mode_exchange2_ll.f90
@@ -0,0 +1,924 @@
+!MNH_LIC Copyright 1998-2019 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.
+!-----------------------------------------------------------------
+!Modifications:
+!  J. Escobar  15/09/2015: WENO5 & JPHEXT <> 1
+!  P. Wautelet 21/05/2019: use name argument of LIST_ll for MPPDB_CHECK
+!-----------------------------------------------------------------
+
+!     ########################
+      MODULE MODE_EXCHANGE2_ll
+!     ########################
+!!
+!!    Purpose
+!!    -------
+! 
+!     The purpose of this module is the implementation of communication routine
+!     UPDATE_HALO2 that updates the second layer of the halo
+!!
+!!    Glossary
+!!    --------
+!       For short, we will refer as "halo2" the zone corresponding
+!     to the second layer of the halo to be updated.
+!!
+!!    Routines Of The User Interface
+!!    ------------------------------
+! 
+!     SUBROUTINES : UPDATE_HALO2_ll, INIT_HALO2_ll
+! 
+!!    Reference
+!!    ---------
+!
+!     User Interface for Meso-NH parallel package
+!     Ph. Kloos, L. Giraud, R. Guivarch, D. Lugato
+!
+!!    Authors
+!!    -------
+!
+!     R. Guivarch, D. Lugato    * CERFACS *
+!     Ph. Kloos                 * CERFACS - CNRM *
+!
+!!    Implicit Arguments
+!!    ------------------
+!
+!     Module MODD_ARGSLIST_ll
+!      types HALO2LIST_ll, LIST_ll
+!
+!     Module MODD_STRUCTURE_ll
+!       types CRSPD_ll, ZONE_ll
+!
+!     Module MODD_VAR_ll
+!       IP - Number of local processor=subdomain
+!       TCRRT_COMDATA - Current communication data structure for current model
+!                       and local processor
+!       NHALO2_COM - MPI communicator for halo 2
+!       NCOMBUFFSIZE2 - buffer size
+!       MNHREAL_MPI - mpi precision
+!       NNEXTTAG, NMAXTAG - variable to define message tag
+!
+!!    Modifications
+!!    -------------
+!       Original    May 19, 1998
+!       R. Guivarch June 24, 1998 _ll
+!       R. Guivarch June 29, 1998 MNHREAL_MPI
+!       N. Gicquel  October 30, 1998 COPY_CRSPD2
+!       J.Escobar 10/02/2012 : Bug , in MPI_RECV replace 
+!            MPI_STATUSES_IGNORE with MPI_STATUS_IGNORE
+! 
+!-------------------------------------------------------------------------------
+!
+implicit none
+!
+  CONTAINS
+!
+!-----------------------------------------------------------------------
+!
+!     ######################################################################
+      SUBROUTINE INIT_HALO2_ll(TPHALO2LIST, KNBVAR, KDIMX, KDIMY, KDIMZ)
+!     ######################################################################
+!
+!!****  *INIT_HALO2_ll* initialise the second layer of the halo
+!!
+!!
+!!    Purpose
+!!    -------
+!       The purpose of this routine is to allocate and initialise the 
+!     TPHALO2LIST variable which contains the second layer of the
+!     halo for each variable.
+! 
+!!    Implicit Arguments
+!!    ------------------
+!     Module MODD_ARGSLIST_ll
+!       type HALO2LIST_ll
+!!
+!!    Reference
+!!    ---------
+! 
+!!    Author
+!!    ------
+!     P. Kloos                 * CERFACS - CNRM *
+! 
+!-------------------------------------------------------------------------------
+!
+!*       0.    DECLARATIONS
+!              ------------
+!
+  USE MODD_ARGSLIST_ll, ONLY : HALO2LIST_ll
+!
+  IMPLICIT NONE
+!
+!*       0.1   Declarations of dummy arguments :
+!
+  TYPE(HALO2LIST_ll), POINTER :: TPHALO2LIST ! list of HALO2_lls
+  INTEGER                     :: KNBVAR      ! number of HALO2_lls to allocate
+  INTEGER        :: KDIMX, KDIMY, KDIMZ      ! dimensions of the HALO2_lls
+!
+!
+!*       0.2   Declarations of local variables :
+!
+  TYPE(HALO2LIST_ll), POINTER :: TZHALO2LIST
+  INTEGER :: JJ ! loop counter
+
+  REAL , POINTER , CONTIGUOUS , DIMENSION(:,:) :: ZWEST,ZEAST,ZSOUTH,ZNORTH
+!
+!-------------------------------------------------------------------------------
+!
+!*       1.    Allocate the list of HALO2_lls
+!
+  ALLOCATE(TPHALO2LIST)
+  TZHALO2LIST => TPHALO2LIST
+!
+  DO JJ=1, KNBVAR
+!
+!*       1.1   Allocate the current HALO2_ll
+!
+     ALLOCATE(TZHALO2LIST%HALO2)
+     
+    ALLOCATE(TZHALO2LIST%HALO2%WEST(KDIMY, KDIMZ))
+    ALLOCATE(TZHALO2LIST%HALO2%EAST(KDIMY, KDIMZ))
+    ALLOCATE(TZHALO2LIST%HALO2%SOUTH(KDIMX, KDIMZ))
+    ALLOCATE(TZHALO2LIST%HALO2%NORTH(KDIMX, KDIMZ))
+    ZWEST => TZHALO2LIST%HALO2%WEST
+    ZEAST => TZHALO2LIST%HALO2%EAST
+    ZSOUTH => TZHALO2LIST%HALO2%SOUTH
+    ZNORTH => TZHALO2LIST%HALO2%NORTH
+    !$acc enter data create(ZWEST,ZEAST,ZSOUTH,ZNORTH)
+    
+    !$acc kernels
+    ZWEST=0.
+    ZEAST=0.
+    ZSOUTH=0.
+    ZNORTH=0.
+    !$acc end kernels
+
+    ALLOCATE(TZHALO2LIST%NEXT)   
+!
+!*       1.2   Go to the next HALO2_ll, or terminate the list
+!
+    IF (JJ < KNBVAR) THEN
+      TZHALO2LIST => TZHALO2LIST%NEXT
+    ELSE
+      DEALLOCATE(TZHALO2LIST%NEXT)
+      NULLIFY(TZHALO2LIST%NEXT)
+    ENDIF
+  ENDDO
+!
+!-------------------------------------------------------------------------------
+!
+      END SUBROUTINE INIT_HALO2_ll
+!
+!     ######################################################
+      SUBROUTINE UPDATE_HALO2_ll(TPLIST, TPLISTHALO2, KINFO)
+!     ######################################################
+!
+!!****  *UPDATE_HALO2_ll* - routine to update the second layer halo
+!!
+!!    Purpose
+!!    -------
+!       This routine updates the halo with the values computed by the 
+!     neighbor subdomains. The fields to be updated are in the
+!     TPLIST list of fields. Before UPDATE_HALO is called, TPLIST
+!     has been filled with the fields to be communicated
+!
+!!**  Method
+!!    ------
+!       First the processors send their internal halos to their
+!     neighboring processors/subdomains, and then they receive
+!     their external halos from their neighboring processors.
+!
+!!    Implicit Arguments
+!!    ------------------
+!     Module MODD_ARGSLIST_ll
+!       type HALO2LIST_ll, LIST_ll
+!
+!     Module MODD_VAR_ll
+!       TCRRT_COMDATA - Current communication data structure for current model
+!                       and local processor
+!       NHALO2_COM - MPI communicator for halo 2
+! 
+!!    Reference
+!!    ---------
+! 
+!!    Author
+!!    ------
+!     P. Kloos                 * CERFACS - CNRM *
+!!    J.Escobar 21/03/014: add mppd_check for all updated field
+!  P. Wautelet 21/05/2019: use name argument of LIST_ll for MPPDB_CHECK
+!
+!-------------------------------------------------------------------------------!
+!*       0.    DECLARATIONS
+!
+  USE MODD_ARGSLIST_ll, ONLY : LIST_ll, HALO2LIST_ll
+  USE MODD_VAR_ll, ONLY : TCRRT_COMDATA, NHALO2_COM
+!
+  USE MODE_MPPDB
+!
+!*       0.1   declarations of arguments
+!
+  TYPE(LIST_ll), POINTER      :: TPLIST      ! pointer to the list of 
+                                             ! fields to be sent
+  TYPE(HALO2LIST_ll), POINTER :: TPLISTHALO2 ! pointer to the list of
+                                             ! halo2 to be received
+  INTEGER                     :: KINFO       ! return status
+!
+  TYPE(LIST_ll), POINTER :: TZFIELD
+!
+  INTEGER                :: ICOUNT
+  CHARACTER(len=2)       :: YCOUNT
+!
+!-------------------------------------------------------------------------------
+!
+!*       1.   SEND / RECV THE INTERNAL HALO TO/FROM THE NEIGHBORING PROCESSORS
+!             ----------------------------------------------------
+!
+  CALL SEND_RECV_CRSPD2(TCRRT_COMDATA%TSEND_HALO2, TCRRT_COMDATA%TRECV_HALO2, &
+                        TPLIST, TPLISTHALO2, NHALO2_COM, KINFO)
+
+!------------------------------------------------------------------------------
+!
+!*       2.  ZONES TO SEND TO THE PROC ITSELF
+!            --------------------------------
+!
+   CALL COPY_CRSPD2(TCRRT_COMDATA%TSEND_HALO2, TCRRT_COMDATA%TRECV_HALO2, &
+                    TPLIST, TPLISTHALO2, KINFO)
+!
+!JUAN MPP_CHECK2D/3D
+!
+   IF (MPPDB_INITIALIZED) THEN
+      TZFIELD => TPLIST
+      ICOUNT=0
+      DO WHILE (ASSOCIATED(TZFIELD))
+        ICOUNT=ICOUNT+1
+        WRITE(YCOUNT,'(I2)') ICOUNT
+        if (tzfield%l1d) then
+          CALL MPPDB_CHECK(TZFIELD%ARRAY1D,"UPDATE_HALO2_ll::"//tzfield%cname)
+        else if (tzfield%l2d) then
+          CALL MPPDB_CHECK(TZFIELD%ARRAY2D,"UPDATE_HALO2_ll::"//tzfield%cname)
+        else if (tzfield%l3d) then
+          CALL MPPDB_CHECK(TZFIELD%ARRAY3D,"UPDATE_HALO2_ll::"//tzfield%cname)
+        end if
+        TZFIELD => TZFIELD%NEXT
+      END DO
+   END IF
+!
+!----------------------------------------------------------------------
+!
+      END SUBROUTINE UPDATE_HALO2_ll
+!
+!     ##########################################################################
+      SUBROUTINE COPY_CRSPD2(TPSENDCRSPD, TPRECVCRSPD, TPSENDLIST, TPRECVLIST, &
+                             KINFO)
+!     ##########################################################################
+!
+!!****  *COPY_CRSPD2* - routine to copy zones that a proc sends to itself
+!!
+!!    Purpose
+!!    -------
+!!  
+!      Copy the field sendtplist of the zone sendcrspd to the field recvtplist
+!      of the zones recvcrspd.    
+!
+!!**  Method
+!!    ------
+!
+!!    Implicit Arguments
+!!    ------------------
+!     Module MODD_STRUCTURE_ll
+!       type CRSPD_ll
+!
+!     Module MODD_ARGSLIST_ll
+!       type HALO2LIST_ll, LIST_ll
+!
+!     Module MODD_VAR_ll
+!       IP - Number of local processor=subdomain
+! 
+!!    Reference
+!!    ---------
+! 
+!!    Author
+!!    ------
+!     N. Gicquel               * CERFACS - CNRM *
+!
+!-------------------------------------------------------------------------------
+!
+!*       0.    DECLARATIONS
+!
+  USE MODD_STRUCTURE_ll, ONLY : CRSPD_ll
+  USE MODD_ARGSLIST_ll, ONLY : LIST_ll, HALO2LIST_ll
+  USE MODD_VAR_ll, ONLY : IP
+!
+  IMPLICIT NONE
+!
+!*       0.1   declarations of arguments
+!
+  TYPE(CRSPD_ll), POINTER      :: TPSENDCRSPD, TPRECVCRSPD
+  TYPE(LIST_ll), POINTER       :: TPSENDLIST
+  TYPE(HALO2LIST_ll), POINTER  :: TPRECVLIST
+  INTEGER                      :: KINFO
+!
+!*       0.2   declarations of local variables
+!
+  TYPE(CRSPD_ll), POINTER      :: TZSEND, TZRECV
+!
+!------------------------------------------------------------------------------
+!
+  TZSEND => TPSENDCRSPD
+  DO WHILE (ASSOCIATED(TZSEND))
+    IF (TZSEND%TELT%NUMBER == IP) THEN
+      TZRECV => TPRECVCRSPD 
+      DO WHILE (ASSOCIATED(TZRECV))
+        IF (TZRECV%TELT%NUMBER == IP&
+             & .AND.TZSEND%TELT%MSSGTAG == TZRECV%TELT%MSSGTAG) THEN
+          CALL COPY_ZONE2(TZSEND%TELT, TZRECV%TELT, TPSENDLIST, &
+                          TPRECVLIST, KINFO)
+        ENDIF
+        TZRECV => TZRECV%TNEXT
+      ENDDO
+    ENDIF
+    TZSEND => TZSEND%TNEXT
+  ENDDO
+!
+!------------------------------------------------------------------------------
+!
+      END SUBROUTINE COPY_CRSPD2
+!
+!     ####################################################################
+      SUBROUTINE COPY_ZONE2(TPSEND, TPRECV, TPSENDLIST, TPRECVLIST, KINFO)
+!     ####################################################################
+!
+!!****  *COPY_ZONE2* - 
+!!
+!!    Purpose
+!!    -------
+!       This routine copies the values of the fields in the TPSENDLIST to the
+!       halo 2 fields of TPRECVLIST according the TPSEND and TPRECV zones
+!
+!!**  Method
+!!    ------
+!
+!!    Implicit Arguments
+!!    ------------------
+!     Module MODD_STRUCTURE_ll
+!       type ZONE_ll
+!
+!     Module MODD_ARGSLIST_ll
+!       type HALO2LIST_ll, LIST_ll
+!
+!!    Reference
+!!    ---------
+! 
+!!    Author
+!!    ------
+!     P. Kloos                 * CERFACS - CNRM *
+!
+!-------------------------------------------------------------------------------
+!
+!*       0.    DECLARATIONS
+!
+  USE MODD_STRUCTURE_ll, ONLY : ZONE_ll
+  USE MODD_ARGSLIST_ll, ONLY : LIST_ll, HALO2LIST_ll
+!
+  IMPLICIT NONE
+!
+!*       0.1   declarations of arguments
+!
+  TYPE(ZONE_ll)                :: TPSEND, TPRECV 
+  TYPE(LIST_ll), POINTER       :: TPSENDLIST
+  TYPE(HALO2LIST_ll), POINTER  :: TPRECVLIST
+  INTEGER                      :: KINFO
+!
+!*       0.2   declarations of local variables
+!
+  TYPE(LIST_ll), POINTER       :: TZLIST
+  TYPE(HALO2LIST_ll), POINTER  :: TZHALO
+  REAL, DIMENSION(:,:), POINTER :: TZTAB2D 
+  INTEGER :: IIBS, IIES, IJBS, IJES, IIBR, IIER, IJBR, IJER, IKES, IKBS, &
+             IKBR, IKER
+!
+  INTEGER, PARAMETER :: ISENDNORTH=2, &
+                        ISENDWEST=4, &
+                        ISENDSOUTH=6, &
+                        ISENDEAST=8, &
+                        ISENDCYCNORTH=12, &
+                        ISENDCYCWEST=14, &
+                        ISENDCYCSOUTH=16, &
+                        ISENDCYCEAST=18
+!
+!-------------------------------------------------------------------------------
+!
+  IIBS = TPSEND%NXOR
+  IIES = TPSEND%NXEND
+  IJBS = TPSEND%NYOR
+  IJES = TPSEND%NYEND
+  IKBS = TPSEND%NZOR
+  IKES = TPSEND%NZEND
+!
+  IIBR = TPRECV%NXOR
+  IIER = TPRECV%NXEND
+  IJBR = TPRECV%NYOR
+  IJER = TPRECV%NYEND
+  IKBR = TPRECV%NZOR
+  IKER = TPRECV%NZEND
+!
+  TZLIST => TPSENDLIST
+  TZHALO => TPRECVLIST 
+  DO WHILE (ASSOCIATED(TZLIST)) 
+    SELECT CASE(TPSEND%MSSGTAG)
+      CASE(ISENDNORTH, ISENDCYCNORTH)
+        TZTAB2D => TZHALO%HALO2%SOUTH
+        TZTAB2D(IIBR:IIER, IKBR:IKER) = &
+                                     TZLIST%ARRAY3D(IIBS:IIES, IJBS, IKBS:IKES)
+      CASE(ISENDSOUTH, ISENDCYCSOUTH)
+        TZTAB2D => TZHALO%HALO2%NORTH
+        TZTAB2D(IIBR:IIER, IKBR:IKER) = &
+                                     TZLIST%ARRAY3D(IIBS:IIES, IJBS, IKBS:IKES)
+      CASE(ISENDWEST, ISENDCYCWEST)
+        TZTAB2D => TZHALO%HALO2%EAST
+        TZTAB2D(IJBR:IJER, IKBR:IKER) = &
+                                     TZLIST%ARRAY3D(IIBS, IJBS:IJES, IKBS:IKES)
+      CASE(ISENDEAST, ISENDCYCEAST)
+        TZTAB2D => TZHALO%HALO2%WEST
+        TZTAB2D(IJBR:IJER, IKBR:IKER) = &
+                                     TZLIST%ARRAY3D(IIBS, IJBS:IJES, IKBS:IKES)
+    END SELECT    
+    TZLIST => TZLIST%NEXT
+    TZHALO => TZHALO%NEXT
+  ENDDO
+!
+!-------------------------------------------------------------------------------
+!
+      END SUBROUTINE COPY_ZONE2
+!
+!     ######################################################
+      SUBROUTINE FILLOUT_ZONE2(TPHALO2LIST, TPZONE, PBUFFER)
+!     ######################################################
+!
+!!****  *FILLOUT_ZONE2* -
+!!
+!!    Purpose
+!!    -------
+!       This routine receives the data of the fields of the TPHALO2LIST
+!     list of fields situated in the TPZONE ZONE_ll.
+!
+!!**  Method
+!!    ------
+!       First the data are received in a buffer. Then each field
+!     of the TPHALO2LIST list of fields is filled in at the
+!     location pointed by the zone.
+!
+!!    Implicit Arguments
+!!    ------------------
+!     Module MODD_STRUCTURE_ll
+!       type ZONE_ll
+!
+!     Module MODD_ARGSLIST_ll
+!       type HALO2LIST_ll
+!
+!!    Reference
+!!    ---------
+! 
+!!    Author
+!!    ------
+!     P. Kloos                 * CERFACS - CNRM *
+!
+!-------------------------------------------------------------------------------
+!
+!
+!*       0.    DECLARATIONS
+!              ------------
+!
+  USE MODD_STRUCTURE_ll, ONLY : ZONE_ll
+  USE MODD_ARGSLIST_ll, ONLY : HALO2LIST_ll
+  USE MODD_MPIF
+!
+  IMPLICIT NONE
+
+!  INCLUDE 'mpif.h'
+!
+!*       0.1   declarations of arguments
+!
+  TYPE(ZONE_ll)          :: TPZONE      ! ZONE_ll to be received
+  TYPE(HALO2LIST_ll), POINTER :: TPHALO2LIST ! list of halo2 to be received
+  REAL, DIMENSION(:) :: PBUFFER     ! reception buffer for unpacking data
+!
+!  INTEGER, DIMENSION(MPI_STATUS_SIZE) ::  KSTATUS ! status of received message
+!
+!*       0.2   declarations of local variables
+!
+  INTEGER :: JI,JJ,JK,JINC           ! loop counters
+  TYPE(HALO2LIST_ll), POINTER :: TZHALO2  ! temporary list of halo2
+!
+  INTEGER, PARAMETER :: ISENDNORTH=2, &
+             ISENDWEST=4, &
+             ISENDSOUTH=6, &
+             ISENDEAST=8, &
+             ISENDCYCNORTH=12, &
+             ISENDCYCWEST=14, & 
+             ISENDCYCSOUTH=16, &
+             ISENDCYCEAST=18
+!
+!-------------------------------------------------------------------------------
+!
+!*       1.    Set MPI message tags
+!              --------------------
+!  ISENDNORTH = 2
+!  ISENDWEST  = 4
+!  ISENDSOUTH = 6
+!  ISENDEAST  = 8 
+!
+!  ISENDCYCNORTH = 12 ! !  ISENDCYCWEST  = 14 !  | In case of cyclic 
+
+!  ISENDCYCSOUTH = 16 !  | boundary conditions
+!  ISENDCYCEAST  = 18 ! /
+ 
+!
+!*       2.    Store the received message
+!              --------------------------
+!
+!*       2.1   See at which side of the halo the message has to be stored
+!
+  SELECT CASE(TPZONE%MSSGTAG)
+!
+!*       2.1.1 Message is to be put in the south halo
+!
+  CASE(ISENDNORTH, ISENDCYCNORTH) 
+!
+!*       2.1.1.1   Go over the TPHALO2LIST list of halo2
+!
+    TZHALO2 => TPHALO2LIST
+    JINC=0
+    DO WHILE (ASSOCIATED(TZHALO2))
+!
+!*       2.1.1.2   Fill out the buffer in the south part of the halo2
+!
+      DO JK=TPZONE%NZOR, TPZONE%NZEND
+          DO JI=TPZONE%NXOR, TPZONE%NXEND
+!
+            JINC = JINC + 1
+            TZHALO2%HALO2%SOUTH(JI,JK) = PBUFFER(JINC)
+!
+          ENDDO
+      ENDDO
+!
+!*       2.1.1.3   Go to the next halo2 in the list
+!
+      TZHALO2 => TZHALO2%NEXT
+!
+    ENDDO
+!
+!*       2.1.2 Message is coming from the east
+!
+  CASE(ISENDWEST, ISENDCYCWEST)
+!
+!*       2.1.2.1   Go over the TPHALO2LIST list of halo2
+!
+    TZHALO2 => TPHALO2LIST
+    JINC=0
+    DO WHILE (ASSOCIATED(TZHALO2))
+!
+!*       2.1.2.2   Fill out the buffer in the east part of the halo2
+!
+      DO JK=TPZONE%NZOR, TPZONE%NZEND
+        DO JJ=TPZONE%NYOR, TPZONE%NYEND
+!
+            JINC = JINC + 1
+            TZHALO2%HALO2%EAST(JJ,JK) = PBUFFER(JINC)
+!
+        ENDDO
+      ENDDO
+!
+!*       2.1.2.3   Go to the next halo2 in the list
+!
+      TZHALO2 => TZHALO2%NEXT
+!
+    ENDDO
+!
+!*       2.1.3 Message is coming from the north
+!
+  CASE(ISENDSOUTH, ISENDCYCSOUTH)
+!
+!*       2.1.3.1   Go over the TPHALO2LIST list of halo2
+!
+    TZHALO2 => TPHALO2LIST
+    JINC=0
+    DO WHILE (ASSOCIATED(TZHALO2))
+!
+!*       2.1.3.2   Fill out the buffer in the north part of the halo2
+!
+      DO JK=TPZONE%NZOR, TPZONE%NZEND
+          DO JI=TPZONE%NXOR, TPZONE%NXEND
+!
+            JINC = JINC + 1
+            TZHALO2%HALO2%NORTH(JI,JK) = PBUFFER(JINC)
+!
+          ENDDO
+      ENDDO
+!
+!*       2.1.3.3   Go to the next halo2 in the list
+!
+      TZHALO2 => TZHALO2%NEXT
+!
+    ENDDO
+!
+!*       2.1.4 Message is coming from the west
+!
+  CASE(ISENDEAST, ISENDCYCEAST)
+!
+!*       2.1.4.1   Go over the TPHALO2LIST list of halo2
+!
+    TZHALO2 => TPHALO2LIST
+    JINC=0
+    DO WHILE (ASSOCIATED(TZHALO2))
+!
+!*       2.1.4.2   Fill out the buffer in the west part of the halo2
+!
+      DO JK=TPZONE%NZOR, TPZONE%NZEND
+        DO JJ=TPZONE%NYOR, TPZONE%NYEND
+!
+            JINC = JINC + 1
+            TZHALO2%HALO2%WEST(JJ,JK) = PBUFFER(JINC)
+!
+        ENDDO
+      ENDDO
+!
+!*       2.1.4.3   Go to the next halo2 in the list
+!
+      TZHALO2 => TZHALO2%NEXT
+!
+    ENDDO
+!
+  END SELECT
+!
+!-------------------------------------------------------------------------------
+!
+      END SUBROUTINE FILLOUT_ZONE2
+!
+!     ########################################################################
+      SUBROUTINE SEND_RECV_CRSPD2(TPCRSPDSEND, TPCRSPDRECV, TPFIELDLISTSEND, &
+                                  TPFIELDLISTRECV, KMPI_COMM, KINFO)
+!     ########################################################################
+!
+!!****  *SEND_RECV_CRSPD2* -
+!
+!!    Purpose
+!!    -------
+!       This routine sends the data of the TPFIELDLISTSEND list 
+!       to the correspondants of the TPCRSPDSEND list 
+!       and receives the data of the TPFIELDLISTRECV list
+!       from the correspondants  of the TPCRSPDRECV list
+!
+!!**  Method
+!!    ------
+!
+!     This routine is based on the following rule : 
+!        one sent for one received (if it is possible);
+!     The algorithm is the following :
+!
+!     while (there is some messages to send)
+!       OR  (there is some messages to receive)
+!     do
+!       if (there is some messages to send)
+!         send the first of the list
+!       end if
+!       if (there is some messages to receive)
+!         try to receive
+!       end if
+!     done
+!
+!     The receptions are non-blocking and don't follow necessarly
+!     the order of the TPCRSPDRECV list
+!
+!!    Implicit Arguments
+!!    ------------------
+!     Module MODD_STRUCTURE_ll
+!       type CRSPD_ll, ZONE_ll
+!
+!     Module MODD_ARGSLIST_ll
+!       type LIST_ll, HALO2LIST_ll
+!
+!     Module MODD_VAR_ll
+!       IP - Number of local processor=subdomain
+!       NCOMBUFFSIZE2 - buffer size
+!       NNEXTTAG, NMAXTAG - variable to define message tag
+!               
+!!    Reference
+!!    ---------
+! 
+!!    Author
+!!    ------
+!     P. Kloos                 * CERFACS - CNRM *
+!
+!-------------------------------------------------------------------------------
+!
+!*       0.    DECLARATIONS
+!
+  USE MODD_STRUCTURE_ll, ONLY : CRSPD_ll, ZONE_ll
+  USE MODD_ARGSLIST_ll, ONLY : LIST_ll, HALO2LIST_ll
+  use modd_precision, only: MNHREAL_MPI
+  USE MODD_VAR_ll, ONLY : NCOMBUFFSIZE2, IP, NNEXTTAG, NMAXTAG
+  USE MODE_EXCHANGE_ll, ONLY : FILLIN_BUFFERS
+  USE MODD_MPIF
+!JUANZ
+  USE MODD_CONFZ, ONLY : LMNH_MPI_BSEND
+!JUANZ
+!
+  USE MODD_VAR_ll, ONLY : MNH_STATUSES_IGNORE
+!
+  IMPLICIT NONE
+!
+!  INCLUDE 'mpif.h'
+!
+!*       0.1   declarations of arguments
+!
+  TYPE(CRSPD_ll), POINTER :: TPCRSPDSEND, TPCRSPDRECV
+  TYPE(LIST_ll), POINTER :: TPFIELDLISTSEND
+  TYPE(HALO2LIST_ll), POINTER :: TPFIELDLISTRECV 
+  INTEGER :: KMPI_COMM
+  INTEGER :: KINFO
+!
+!*       0.2   declarations of local variables
+!
+  INTEGER :: JINC, JI, JJ, JK  ! Loop and counter variables
+  INTEGER :: FOUND, KERROR
+!
+!JUAN
+!if defined (MNH_MPI_ISEND)
+  REAL, DIMENSION (:,:), ALLOCATABLE,TARGET :: TZBUFFER ! Buffers for info
+                                                      ! received
+!!$#else
+!!$  REAL, DIMENSION (NCOMBUFFSIZE2), TARGET :: TZBUFFER ! Buffers for info
+!!$                                                      ! received
+!!$#endif
+!JUAN
+!
+ ! INTEGER IRECVSTATUS(MPI_STATUS_SIZE) ! Status of completed receive request
+  LOGICAL :: IRECVFLAG, ISENDFLAG
+  INTEGER :: IMSGTAG, ISENDERPROC
+!
+  INTEGER :: IRECVNB, ISENDNB ! Total numbers of receive and send to do
+  INTEGER :: IRECVDONE ! RECEIVE COMPLETED (receive and treated)
+!
+  TYPE(CRSPD_ll), POINTER :: TPMAILSEND, TPMAILRECV
+  TYPE(ZONE_ll), POINTER :: TZZONESEND
+!
+  TYPE(LIST_ll), POINTER :: TZFIELDLISTSEND
+  TYPE(HALO2LIST_ll), POINTER :: TZFIELDLISTRECV
+  INTEGER, SAVE :: ITAGOFFSET = 0
+! JUAN
+!if defined (MNH_MPI_ISEND)
+INTEGER,PARAMETER                                     :: MPI_MAX_REQ = 1024
+!INTEGER,SAVE,DIMENSION(MPI_MAX_REQ)                  :: REQ_TAB
+!INTEGER,SAVE,DIMENSION(MPI_STATUS_SIZE,MPI_MAX_REQ)  :: STATUS_TAB
+INTEGER,ALLOCATABLE,DIMENSION(:)                      :: REQ_TAB
+INTEGER                                               :: NB_REQ,NFIRST_REQ_RECV
+!endif
+! JUAN
+!
+!-------------------------------------------------------------------------------
+!
+!*       1.    INITIALISATIONS
+!              ---------------
+!
+  TZFIELDLISTSEND => TPFIELDLISTSEND
+  TZFIELDLISTRECV => TPFIELDLISTRECV
+!
+  IRECVDONE = 0
+!
+  IF (ASSOCIATED(TPCRSPDRECV)) THEN
+    IRECVNB = TPCRSPDRECV%NCARDDIF
+  ELSE
+    IRECVNB = 0
+  ENDIF
+  IF (ASSOCIATED(TPCRSPDSEND)) THEN
+    ISENDNB = TPCRSPDSEND%NCARDDIF
+  ELSE
+    ISENDNB = 0
+  ENDIF
+
+!JUAN
+!if defined (MNH_MPI_ISEND)
+  IF (LMNH_MPI_BSEND) THEN
+     ALLOCATE(TZBUFFER(NCOMBUFFSIZE2,1))
+  ELSE
+     ALLOCATE(TZBUFFER(NCOMBUFFSIZE2,ISENDNB+IRECVNB))
+     NB_REQ = 0
+     ALLOCATE(REQ_TAB(ISENDNB+IRECVNB))
+  END IF
+!endif
+!JUAN
+! 
+  TPMAILRECV => TPCRSPDRECV
+  TPMAILSEND => TPCRSPDSEND
+!
+!NZJUAN  CALL MPI_BARRIER(KMPI_COMM, KERROR)
+!
+!-------------------------------------------------------------------------------
+!
+!*       2.    MAIN LOOP
+!              ---------
+!
+  DO WHILE (ASSOCIATED(TPMAILSEND))
+!
+!*       2.1  if there is still something to send
+!
+     IF (ASSOCIATED(TPMAILSEND)) THEN
+        TZZONESEND => TPMAILSEND%TELT
+        IF (TZZONESEND%NUMBER /= IP) THEN 
+           JINC = 0
+!JUAN
+!if defined(MNH_MPI_ISEND)
+ IF ( .NOT. LMNH_MPI_BSEND) THEN
+           NB_REQ = NB_REQ + 1
+           CALL FILLIN_BUFFERS(TZFIELDLISTSEND, TZZONESEND, TZBUFFER(:,NB_REQ), JINC)
+ else
+           CALL FILLIN_BUFFERS(TZFIELDLISTSEND, TZZONESEND, TZBUFFER(:,1), JINC)
+ endif
+!JUAN
+!if defined(MNH_MPI_BSEND)
+ IF (LMNH_MPI_BSEND) THEN
+           CALL MPI_BSEND(TZBUFFER, JINC, MNHREAL_MPI, &
+                TZZONESEND%NUMBER - 1, TZZONESEND%MSSGTAG + ITAGOFFSET, &
+                KMPI_COMM, KERROR)
+else
+!JUAN
+!if defined(MNH_MPI_ISEND)
+           CALL MPI_ISEND(TZBUFFER(1,NB_REQ), JINC, MNHREAL_MPI, &
+                TZZONESEND%NUMBER - 1, TZZONESEND%MSSGTAG + ITAGOFFSET, &
+                KMPI_COMM, REQ_TAB(NB_REQ), KERROR)
+
+ endif
+!JUAN 
+
+        ENDIF
+        TPMAILSEND => TPMAILSEND%TNEXT
+     ENDIF
+  ENDDO
+
+!NZJUAN  CALL MPI_BARRIER(KMPI_COMM, KERROR)
+
+! JUAN
+!if defined (MNH_MPI_ISEND)
+  IF ( .NOT. LMNH_MPI_BSEND) THEN
+     NFIRST_REQ_RECV = NB_REQ
+  endif
+  ! JUAN
+
+  DO WHILE (ASSOCIATED(TPMAILRECV)) 
+     IF (TPMAILRECV%TELT%NUMBER  == IP) THEN
+        TPMAILRECV => TPMAILRECV%TNEXT
+     ELSE
+! JUAN
+!if defined (MNH_MPI_ISEND)
+ IF ( .NOT. LMNH_MPI_BSEND) THEN
+        NB_REQ = NB_REQ + 1
+        CALL MPI_IRECV(TZBUFFER(1,NB_REQ), NCOMBUFFSIZE2, MNHREAL_MPI, &
+             TPMAILRECV%TELT%NUMBER-1, &
+             TPMAILRECV%TELT%MSSGTAG + ITAGOFFSET, &
+             KMPI_COMM, REQ_TAB(NB_REQ), KERROR)
+else
+        CALL MPI_RECV(TZBUFFER, NCOMBUFFSIZE2, MNHREAL_MPI, &
+             TPMAILRECV%TELT%NUMBER-1, &
+             TPMAILRECV%TELT%MSSGTAG + ITAGOFFSET, &
+             KMPI_COMM, MPI_STATUS_IGNORE, KERROR)
+        CALL FILLOUT_ZONE2(TZFIELDLISTRECV, TPMAILRECV%TELT, TZBUFFER(:,1))
+endif
+! JUAN
+        TPMAILRECV => TPMAILRECV%TNEXT
+     ENDIF
+     
+  ENDDO
+
+! JUAN
+!if defined (MNH_MPI_ISEND)
+ IF ( .NOT. LMNH_MPI_BSEND) THEN
+    CALL MPI_WAITALL(NB_REQ,REQ_TAB,MNH_STATUSES_IGNORE,KINFO) 
+    
+    TPMAILRECV => TPCRSPDRECV
+    NB_REQ = NFIRST_REQ_RECV
+    
+    DO WHILE (ASSOCIATED(TPMAILRECV)) 
+       IF (TPMAILRECV%TELT%NUMBER  == IP) THEN
+          TPMAILRECV => TPMAILRECV%TNEXT
+       ELSE
+          NB_REQ = NB_REQ + 1
+          CALL FILLOUT_ZONE2(TZFIELDLISTRECV, TPMAILRECV%TELT, TZBUFFER(:,NB_REQ))
+          TPMAILRECV => TPMAILRECV%TNEXT
+       ENDIF
+       
+    ENDDO
+    
+    DEALLOCATE(REQ_TAB)
+ endif
+!JUAN 
+! 
+ DEALLOCATE(TZBUFFER)
+  ITAGOFFSET = MOD((ITAGOFFSET + NNEXTTAG), NMAXTAG)
+!
+!NZJUAN  CALL MPI_BARRIER(KMPI_COMM, KERROR)
+!
+!-------------------------------------------------------------------------------!
+      END SUBROUTINE SEND_RECV_CRSPD2
+!
+END MODULE MODE_EXCHANGE2_ll 
diff --git a/src/ZSOLVER/advection_uvw.f90 b/src/ZSOLVER/advection_uvw.f90
new file mode 100644
index 0000000000000000000000000000000000000000..5c92dba01d1c9910880d4c3c759bf75d12817e6c
--- /dev/null
+++ b/src/ZSOLVER/advection_uvw.f90
@@ -0,0 +1,584 @@
+!MNH_LIC Copyright 1994-2020 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.
+!-----------------------------------------------------------------
+!     #########################
+      MODULE MODI_ADVECTION_UVW
+!     #########################
+!
+INTERFACE
+      SUBROUTINE ADVECTION_UVW (HUVW_ADV_SCHEME,                               &
+                            HTEMP_SCHEME, KWENO_ORDER, OSPLIT_WENO,            &
+                            HLBCX, HLBCY, PTSTEP,                              &
+                            PUT, PVT, PWT,                                     &
+                            PRHODJ, PDXX, PDYY, PDZZ, PDZX, PDZY,              &
+                            PRUS, PRVS, PRWS,                                  &
+                            PRUS_PRES, PRVS_PRES, PRWS_PRES                    )
+!
+CHARACTER(LEN=6),         INTENT(IN)    :: HUVW_ADV_SCHEME     ! to the selected
+CHARACTER(LEN=4),         INTENT(IN)    :: HTEMP_SCHEME   ! Temporal scheme
+!
+INTEGER,                  INTENT(IN)    :: KWENO_ORDER   ! Order of the WENO
+                                                         ! scheme (3 or 5)
+LOGICAL,                  INTENT(IN)   :: OSPLIT_WENO  ! flag to add a time
+                                                       ! splitting to RK for WENO
+!
+CHARACTER(LEN=4),DIMENSION(2),INTENT(IN):: HLBCX, HLBCY  ! X- and Y-direc LBC
+!
+REAL,                     INTENT(IN)    :: PTSTEP
+!
+REAL, DIMENSION(:,:,:),   INTENT(IN)    :: PUT , PVT  , PWT
+                                                  ! Variables at t
+REAL, DIMENSION(:,:,:),   INTENT(IN)    :: PRHODJ
+REAL, DIMENSION(:,:,:),   INTENT(IN)    :: PDXX,PDYY,PDZZ,PDZX,PDZY
+                                                  !  metric coefficients
+REAL, DIMENSION(:,:,:),   INTENT(INOUT) :: PRUS , PRVS, PRWS
+                                                  ! Sources terms 
+REAL, DIMENSION(:,:,:),   INTENT(IN)    :: PRUS_PRES, PRVS_PRES, PRWS_PRES
+!
+END SUBROUTINE ADVECTION_UVW
+!
+END INTERFACE
+!
+END MODULE MODI_ADVECTION_UVW
+!     ##########################################################################
+      SUBROUTINE ADVECTION_UVW (HUVW_ADV_SCHEME,                               &
+                            HTEMP_SCHEME, KWENO_ORDER, OSPLIT_WENO,            &
+                            HLBCX, HLBCY, PTSTEP,                              &
+                            PUT, PVT, PWT,                                     &
+                            PRHODJ, PDXX, PDYY, PDZZ, PDZX, PDZY,              &
+                            PRUS, PRVS, PRWS,                                  &
+                            PRUS_PRES, PRVS_PRES, PRWS_PRES                    )
+!     ##########################################################################
+!
+!!****  *ADVECTION_UVW * - routine to call the specialized advection routines for wind
+!!
+!!    PURPOSE
+!!    -------
+!!
+!!**  METHOD
+!!    ------
+!!
+!!    EXTERNAL
+!!    --------
+!!
+!!    IMPLICIT ARGUMENTS
+!!    ------------------
+!!      NONE
+!!
+!!    REFERENCE
+!!    ---------
+!!      Book1 and book2 ( routine ADVECTION )
+!!
+!!    AUTHOR
+!!    ------
+!!	J.-P. Pinty      * Laboratoire d'Aerologie*
+!!	J.-P. Lafore     * Meteo France *
+!!
+!!    MODIFICATIONS
+!!    -------------
+!!      Original    06/07/94 
+!!                  01/04/95 (Ph. Hereil J. Nicolau) add the model number
+!!                  23/10/95 (J. Vila and JP Lafore) advection schemes scalar
+!!                  16/01/97 (JP Pinty)              change presentation 
+!!                  30/04/98 (J. Stein P Jabouille)  extrapolation for the cyclic
+!!                                                   case and parallelisation
+!!                  24/06/99 (P Jabouille)           case of NHALO>1
+!!                  25/10/05 (JP Pinty)              4th order scheme
+!!                  04/2011  (V. Masson & C. Lac)    splits the routine and adds
+!!                                                   time splitting
+!!                  J.Escobar 21/03/2013: for HALOK comment all NHALO=1 test
+!!                  J.Escobar : 15/09/2015 : WENO5 & JPHEXT <> 1 
+!!                  C.LAC 10/2016 : Add OSPLIT_WENO
+!  P. Wautelet 20/05/2019: add name argument to ADDnFIELD_ll + new ADD4DFIELD_ll subroutine
+!-------------------------------------------------------------------------------
+!
+!*       0.    DECLARATIONS
+!              ------------
+!
+USE MODE_ll
+USE MODD_ARGSLIST_ll, ONLY : LIST_ll, HALO2LIST_ll
+USE MODD_PARAMETERS,  ONLY : JPVEXT
+USE MODD_CONF,        ONLY : NHALO
+USE MODD_BUDGET
+!
+#ifndef MNH_OPENACC
+USE MODI_SHUMAN
+#else
+USE MODI_SHUMAN_DEVICE
+#endif
+USE MODI_CONTRAV
+USE MODI_ADVECUVW_RK
+USE MODI_ADV_BOUNDARIES
+USE MODI_BUDGET
+USE MODI_GET_HALO
+!
+#ifdef MNH_OPENACC
+USE MODE_DEVICE
+USE MODE_MNH_ZWORK, ONLY : ZT3D, MNH_GET_ZT3D , MNH_REL_ZT3D, MNH_GET_ZT4D , MNH_REL_ZT4D, &
+                           MNH_ALLOCATE_ZT3D
+#endif
+use mode_mppdb
+!
+!-------------------------------------------------------------------------------
+!
+IMPLICIT NONE
+!
+!*       0.1   Declarations of dummy arguments :
+!
+CHARACTER(LEN=6),         INTENT(IN)    :: HUVW_ADV_SCHEME     ! to the selected
+CHARACTER(LEN=4),         INTENT(IN)    :: HTEMP_SCHEME   ! Temporal scheme
+!
+INTEGER,                  INTENT(IN)    :: KWENO_ORDER   ! Order of the WENO
+                                                         ! scheme (3 or 5)
+LOGICAL,                  INTENT(IN)   :: OSPLIT_WENO  ! flag to add a time
+                                                       ! splitting to RK for WENO
+!
+CHARACTER(LEN=4),DIMENSION(2),INTENT(IN):: HLBCX, HLBCY  ! X- and Y-direc LBC
+!
+REAL,                     INTENT(IN)    :: PTSTEP
+!
+REAL, DIMENSION(:,:,:),   INTENT(IN)    :: PUT , PVT  , PWT
+                                                  ! Variables at t
+REAL, DIMENSION(:,:,:),   INTENT(IN)    :: PRHODJ               
+REAL, DIMENSION(:,:,:),   INTENT(IN)    :: PDXX,PDYY,PDZZ,PDZX,PDZY
+                                                  !  metric coefficients
+REAL, DIMENSION(:,:,:),   INTENT(INOUT) :: PRUS , PRVS, PRWS
+                                                  ! Sources terms
+REAL, DIMENSION(:,:,:),   INTENT(IN)    :: PRUS_PRES, PRVS_PRES, PRWS_PRES
+!
+!
+!*       0.2   declarations of local variables
+!
+!
+!  
+INTEGER             :: IKE       ! indice K End       in z direction
+!
+REAL, DIMENSION(:,:,:), POINTER, CONTIGUOUS :: ZRUT
+REAL, DIMENSION(:,:,:), POINTER, CONTIGUOUS :: ZRVT
+REAL, DIMENSION(:,:,:), POINTER, CONTIGUOUS :: ZRWT
+INTEGER :: IZRUT,IZRVT,IZRWT
+                                                  ! cartesian
+                                                  ! components of
+                                                  ! momentum
+!
+REAL, DIMENSION(:,:,:), POINTER, CONTIGUOUS :: ZRUCT
+REAL, DIMENSION(:,:,:), POINTER, CONTIGUOUS :: ZRVCT
+REAL, DIMENSION(:,:,:), POINTER, CONTIGUOUS :: ZRWCT
+INTEGER :: IZRUCT,IZRVCT,IZRWCT
+                                                  ! contravariant
+                                                  ! components
+                                                  ! of momentum
+!
+REAL, DIMENSION(:,:,:), POINTER, CONTIGUOUS :: ZU, ZV, ZW
+INTEGER :: IZU, IZV, IZW
+! 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
+INTEGER :: IZRUS_OTHER,IZRVS_OTHER,IZRWS_OTHER
+! Contribution of the RK time step
+REAL, DIMENSION(:,:,:), POINTER, CONTIGUOUS :: ZRUS_ADV
+REAL, DIMENSION(:,:,:), POINTER, CONTIGUOUS :: ZRVS_ADV
+REAL, DIMENSION(:,:,:), POINTER, CONTIGUOUS :: ZRWS_ADV
+REAL, DIMENSION(:,:,:), POINTER, CONTIGUOUS :: ZMXM_RHODJ
+REAL, DIMENSION(:,:,:), POINTER, CONTIGUOUS :: ZMYM_RHODJ
+REAL, DIMENSION(:,:,:), POINTER, CONTIGUOUS :: ZMZM_RHODJ
+INTEGER :: IZRUS_ADV,IZRVS_ADV,IZRWS_ADV
+INTEGER :: IZMXM_RHODJ,IZMYM_RHODJ,IZMZM_RHODJ
+!
+! Momentum tendencies due to advection
+INTEGER :: ISPLIT              ! Number of splitting loops
+INTEGER :: JSPL                ! Loop index
+REAL    :: ZTSTEP              ! Sub Time step 
+!
+INTEGER                     :: IINFO_ll    ! return code of parallel routine
+TYPE(LIST_ll), POINTER      :: TZFIELD_ll  ! list of fields to exchange
+TYPE(LIST_ll), POINTER      :: TZFIELDS_ll ! list of fields to exchange
+TYPE(LIST_ll), POINTER      :: TZFIELDS0_ll ! list of fields to exchange
+!
+#ifdef MNH_OPENACC
+INTEGER :: ISPL, IZUT, IZVT, IZWT, IZ1, IZ2
+INTEGER :: IZRUSB, IZRUSE, IZRVSB, IZRVSE, IZRWSB, IZRWSE
+#endif
+!
+INTEGER :: IIU,IJU,IKU
+!
+!-------------------------------------------------------------------------------
+!
+!*       0.     INITIALIZATION
+!        --------------
+!
+!
+IIU = SIZE(PUT,1)
+IJU = SIZE(PUT,2)
+IKU = SIZE(PUT,3)
+!
+!$acc data present( PUT, PVT, PWT, PRHODJ, PDXX, PDYY, PDZZ, PDZX, PDZY, PRUS, PRVS, PRWS, PRUS_PRES, PRVS_PRES, PRWS_PRES )
+
+IF (MPPDB_INITIALIZED) THEN
+  !Check all IN arrays
+  CALL MPPDB_CHECK(PUT,"ADVECTION_UVW beg:PUT")
+  CALL MPPDB_CHECK(PVT,"ADVECTION_UVW beg:PVT")
+  CALL MPPDB_CHECK(PWT,"ADVECTION_UVW beg:PWT")
+  CALL MPPDB_CHECK(PRHODJ,"ADVECTION_UVW beg:PRHODJ")
+  CALL MPPDB_CHECK(PDXX,"ADVECTION_UVW beg:PDXX")
+  CALL MPPDB_CHECK(PDYY,"ADVECTION_UVW beg:PDYY")
+  CALL MPPDB_CHECK(PDZZ,"ADVECTION_UVW beg:PDZZ")
+  CALL MPPDB_CHECK(PDZX,"ADVECTION_UVW beg:PDZX")
+  CALL MPPDB_CHECK(PDZY,"ADVECTION_UVW beg:PDZY")
+  CALL MPPDB_CHECK(PRUS_PRES,"ADVECTION_UVW beg:PRUS_PRES")
+  CALL MPPDB_CHECK(PRVS_PRES,"ADVECTION_UVW beg:PRVS_PRES")
+  CALL MPPDB_CHECK(PRWS_PRES,"ADVECTION_UVW beg:PRWS_PRES")
+  !Check all INOUT arrays
+  CALL MPPDB_CHECK(PRUS,"ADVECTION_UVW beg:PRUS")
+  CALL MPPDB_CHECK(PRVS,"ADVECTION_UVW beg:PRVS")
+  CALL MPPDB_CHECK(PRWS,"ADVECTION_UVW beg:PRWS")
+END IF
+
+#ifndef MNH_OPENACC
+ALLOCATE( ZRUT      ( IIU,IJU,IKU ) )
+ALLOCATE( ZRVT      ( IIU,IJU,IKU ) )
+ALLOCATE( ZRWT      ( IIU,IJU,IKU ) )
+ALLOCATE( ZRUCT     ( IIU,IJU,IKU ) )
+ALLOCATE( ZRVCT     ( IIU,IJU,IKU ) )
+ALLOCATE( ZRWCT     ( IIU,IJU,IKU ) )
+ALLOCATE( ZU        ( IIU,IJU,IKU ) )
+ALLOCATE( ZV        ( IIU,IJU,IKU ) )
+ALLOCATE( ZW        ( IIU,IJU,IKU ) )
+ALLOCATE( ZRUS_OTHER( IIU,IJU,IKU ) )
+ALLOCATE( ZRVS_OTHER( IIU,IJU,IKU ) )
+ALLOCATE( ZRWS_OTHER( IIU,IJU,IKU ) )
+ALLOCATE( ZRUS_ADV  ( IIU,IJU,IKU ) )
+ALLOCATE( ZRVS_ADV  ( IIU,IJU,IKU ) )
+ALLOCATE( ZRWS_ADV  ( IIU,IJU,IKU ) )
+ALLOCATE( ZMXM_RHODJ( IIU,IJU,IKU ) )
+ALLOCATE( ZMYM_RHODJ( IIU,IJU,IKU ) )
+ALLOCATE( ZMZM_RHODJ( IIU,IJU,IKU ) )
+#else
+IZRUT       = MNH_ALLOCATE_ZT3D( ZRUT      ,IIU,IJU,IKU )
+IZRVT       = MNH_ALLOCATE_ZT3D( ZRVT      ,IIU,IJU,IKU )
+IZRWT       = MNH_ALLOCATE_ZT3D( ZRWT      ,IIU,IJU,IKU )
+IZRUCT      = MNH_ALLOCATE_ZT3D( ZRUCT     ,IIU,IJU,IKU )
+IZRVCT      = MNH_ALLOCATE_ZT3D( ZRVCT     ,IIU,IJU,IKU )
+IZRWCT      = MNH_ALLOCATE_ZT3D( ZRWCT     ,IIU,IJU,IKU )
+IZU         = MNH_ALLOCATE_ZT3D( ZU        ,IIU,IJU,IKU )
+IZV         = MNH_ALLOCATE_ZT3D( ZV        ,IIU,IJU,IKU )
+IZW         = MNH_ALLOCATE_ZT3D( ZW        ,IIU,IJU,IKU )
+IZRUS_OTHER = MNH_ALLOCATE_ZT3D( ZRUS_OTHER,IIU,IJU,IKU )
+IZRVS_OTHER = MNH_ALLOCATE_ZT3D( ZRVS_OTHER,IIU,IJU,IKU )
+IZRWS_OTHER = MNH_ALLOCATE_ZT3D( ZRWS_OTHER,IIU,IJU,IKU )
+IZRUS_ADV   = MNH_ALLOCATE_ZT3D( ZRUS_ADV  ,IIU,IJU,IKU )
+IZRVS_ADV   = MNH_ALLOCATE_ZT3D( ZRVS_ADV  ,IIU,IJU,IKU )
+IZRWS_ADV   = MNH_ALLOCATE_ZT3D( ZRWS_ADV  ,IIU,IJU,IKU )
+IZMXM_RHODJ = MNH_ALLOCATE_ZT3D( ZMXM_RHODJ,IIU,IJU,IKU )
+IZMYM_RHODJ = MNH_ALLOCATE_ZT3D( ZMYM_RHODJ,IIU,IJU,IKU )
+IZMZM_RHODJ = MNH_ALLOCATE_ZT3D( ZMZM_RHODJ,IIU,IJU,IKU )
+#endif
+
+!$acc data present( zrut, zrvt, zrwt, zruct, zrvct, zrwct, zu, zv, zw,                &
+!$acc &            zrus_other, zrvs_other, zrws_other, zrus_adv, zrvs_adv, zrws_adv, &
+!$acc &            zmxm_rhodj, zmym_rhodj, zmzm_rhodj  )
+
+#ifdef MNH_OPENACC
+#if 0
+CALL INIT_ON_HOST_AND_DEVICE(ZRUT,-1e99,'ADVECTION_UVW::ZRUT')
+CALL INIT_ON_HOST_AND_DEVICE(ZRVT,-2e99,'ADVECTION_UVW::ZRVT')
+CALL INIT_ON_HOST_AND_DEVICE(ZRWT,-3e99,'ADVECTION_UVW::ZRWT')
+CALL INIT_ON_HOST_AND_DEVICE(ZRUCT,-1e98,'ADVECTION_UVW::ZRUCT')
+CALL INIT_ON_HOST_AND_DEVICE(ZRVCT,-2e98,'ADVECTION_UVW::ZRVCT')
+CALL INIT_ON_HOST_AND_DEVICE(ZRWCT,-3e98,'ADVECTION_UVW::ZRWCT')
+CALL INIT_ON_HOST_AND_DEVICE(ZU,-1e99,'ADVECTION_UVW::ZU')
+CALL INIT_ON_HOST_AND_DEVICE(ZV,-1e99,'ADVECTION_UVW::ZV')
+CALL INIT_ON_HOST_AND_DEVICE(ZW,-1e99,'ADVECTION_UVW::ZW')
+CALL INIT_ON_HOST_AND_DEVICE(ZRUS_OTHER,-1e99,'ADVECTION_UVW::ZRUS_OTHER')
+CALL INIT_ON_HOST_AND_DEVICE(ZRVS_OTHER,-1e99,'ADVECTION_UVW::ZRVS_OTHER')
+CALL INIT_ON_HOST_AND_DEVICE(ZRWS_OTHER,-1e99,'ADVECTION_UVW::ZRWS_OTHER')
+CALL INIT_ON_HOST_AND_DEVICE(ZRUS_ADV,-1e99,'ADVECTION_UVW::ZRUS_ADV')
+CALL INIT_ON_HOST_AND_DEVICE(ZRVS_ADV,-1e99,'ADVECTION_UVW::ZRVS_ADV')
+CALL INIT_ON_HOST_AND_DEVICE(ZRWS_ADV,-1e99,'ADVECTION_UVW::ZRWS_ADV')
+CALL INIT_ON_HOST_AND_DEVICE(ZMXM_RHODJ,-1e97,'ADVECTION_UVW::ZMXM_RHODJ')
+CALL INIT_ON_HOST_AND_DEVICE(ZMYM_RHODJ,-2e97,'ADVECTION_UVW::ZMYM_RHODJ')
+CALL INIT_ON_HOST_AND_DEVICE(ZMZM_RHODJ,-3e97,'ADVECTION_UVW::ZMZM_RHODJ')
+#endif
+!
+SELECT CASE (HTEMP_SCHEME)
+ CASE('RK11')
+  ISPL = 1
+ CASE('RK21')
+  ISPL = 2
+ CASE('NP32')
+  ISPL = 3
+ CASE('SP32')
+  ISPL = 3
+ CASE('RK33')
+  ISPL = 3
+ CASE('RKC4')
+  ISPL = 4
+ CASE('RK4B')
+  ISPL = 4
+ CASE('RK53')
+  ISPL = 5
+ CASE('RK62')
+  ISPL = 6
+ CASE('RK65')
+  ISPL = 6
+ CASE DEFAULT
+  call Print_msg( NVERB_FATAL, 'GEN', 'ADVECTION_UVW', 'unknown htemp_scheme' )
+END SELECT
+!
+CALL MNH_GET_ZT3D(IZUT, IZVT, IZWT, IZ1, IZ2)
+CALL MNH_GET_ZT4D(ISPL, IZRUSB, IZRUSE)
+CALL MNH_GET_ZT4D(ISPL, IZRVSB, IZRVSE)
+CALL MNH_GET_ZT4D(ISPL, IZRWSB, IZRWSE)
+#endif
+!
+IKE = SIZE(PWT,3) - JPVEXT
+!
+#ifndef MNH_OPENACC
+ZMXM_RHODJ = MXM(PRHODJ)
+ZMYM_RHODJ = MYM(PRHODJ)
+ZMZM_RHODJ = MZM(PRHODJ)
+#else
+CALL MXM_DEVICE(PRHODJ,ZMXM_RHODJ)
+CALL MYM_DEVICE(PRHODJ,ZMYM_RHODJ)
+CALL MZM_DEVICE(PRHODJ,ZMZM_RHODJ)
+#endif
+!
+!-------------------------------------------------------------------------------
+!
+!*       1.     COMPUTES THE CONTRAVARIANT COMPONENTS
+!	        -------------------------------------
+!
+!$acc kernels
+ZRUT(:,:,:) = PUT(:,:,:) * ZMXM_RHODJ(:,:,:)
+ZRVT(:,:,:) = PVT(:,:,:) * ZMYM_RHODJ(:,:,:)
+ZRWT(:,:,:) = PWT(:,:,:) * ZMZM_RHODJ(:,:,:)
+!$acc end kernels
+
+!
+#ifndef MNH_OPENACC
+NULLIFY(TZFIELD_ll)
+!!$IF(NHALO == 1) THEN
+  CALL ADD3DFIELD_ll( TZFIELD_ll, ZRUT, 'ADVECTION_UVW::ZRUT' )
+  CALL ADD3DFIELD_ll( TZFIELD_ll, ZRVT, 'ADVECTION_UVW::ZRVT' )
+  CALL UPDATE_HALO_ll(TZFIELD_ll,IINFO_ll)
+  CALL CLEANLIST_ll(TZFIELD_ll)
+!!$END IF
+#else
+! acc update self(ZRUT,ZRVT)  
+  CALL GET_HALO_D(ZRUT,HNAME='ADVECTION_UVW::ZRUT')
+  CALL GET_HALO_D(ZRVT,HNAME='ADVECTION_UVW::ZRVT')
+! acc update device(ZRUT,ZRVT)
+#endif
+  
+
+!
+#ifndef MNH_OPENACC
+CALL CONTRAV (HLBCX,HLBCY,ZRUT,ZRVT,ZRWT,PDXX,PDYY,PDZZ,PDZX,PDZY,ZRUCT,ZRVCT,ZRWCT,4)
+#else
+CALL CONTRAV_DEVICE (HLBCX,HLBCY,ZRUT,ZRVT,ZRWT,PDXX,PDYY,PDZZ,PDZX,PDZY,ZRUCT,ZRVCT,ZRWCT,4,&
+               ZT3D(:,:,:,IZ1),ZT3D(:,:,:,IZ2),ODATA_ON_DEVICE=.TRUE.)
+!Not necessary: already done in contrav_device !$acc update self(ZRUCT,ZRVCT,ZRWCT)
+#endif
+!
+#ifndef MNH_OPENACC
+  NULLIFY(TZFIELDS_ll)
+!!$IF(NHALO == 1) THEN
+  CALL ADD3DFIELD_ll( TZFIELDS_ll, ZRWCT, 'ADVECTION_UVW::ZRWCT' )
+  CALL ADD3DFIELD_ll( TZFIELDS_ll, ZRUCT, 'ADVECTION_UVW::ZRUCT' )
+  CALL ADD3DFIELD_ll( TZFIELDS_ll, ZRVCT, 'ADVECTION_UVW::ZRVCT' )
+  CALL UPDATE_HALO_ll(TZFIELDS_ll,IINFO_ll)
+  CALL CLEANLIST_ll(TZFIELDS_ll)
+!!$END IF
+#else
+  CALL GET_HALO_D(ZRUCT,HNAME='ADVECTION_UVW::ZRUCT')
+  CALL GET_HALO_D(ZRVCT,HNAME='ADVECTION_UVW::ZRVCT')
+  CALL GET_HALO_D(ZRWCT,HNAME='ADVECTION_UVW::ZRWCT')
+! acc update device(ZRUCT,ZRVCT,ZRWCT) !Needed in advecuvw_weno_k called by advecuvw_rk
+#endif
+  
+
+!
+!-------------------------------------------------------------------------------
+!
+!
+!*       2.     COMPUTES THE TENDENCIES SINCE THE BEGINNING OF THE TIME STEP
+!	        ------------------------------------------------------------
+!
+!$acc kernels
+ZRUS_OTHER(:,:,:) = PRUS(:,:,:) - ZRUT(:,:,:) / PTSTEP + PRUS_PRES(:,:,:)
+ZRVS_OTHER(:,:,:) = PRVS(:,:,:) - ZRVT(:,:,:) / PTSTEP + PRVS_PRES(:,:,:)
+ZRWS_OTHER(:,:,:) = PRWS(:,:,:) - ZRWT(:,:,:) / PTSTEP + PRWS_PRES(:,:,:)
+!$acc end kernels
+!
+! Top and bottom Boundaries 
+!
+#ifndef MNH_OPENACC
+CALL ADV_BOUNDARIES (HLBCX, HLBCY, ZRUS_OTHER)
+CALL ADV_BOUNDARIES (HLBCX, HLBCY, ZRVS_OTHER)
+CALL ADV_BOUNDARIES (HLBCX, HLBCY, ZRWS_OTHER)
+#else
+CALL ADV_BOUNDARIES_DEVICE (HLBCX, HLBCY, ZRUS_OTHER)
+CALL ADV_BOUNDARIES_DEVICE (HLBCX, HLBCY, ZRVS_OTHER)
+CALL ADV_BOUNDARIES_DEVICE (HLBCX, HLBCY, ZRWS_OTHER)
+#endif
+!$acc kernels
+ZRWS_OTHER(:,:,IKE+1) = 0.
+!$acc end kernels
+
+#ifndef MNH_OPENACC
+
+NULLIFY(TZFIELDS0_ll)
+!!$IF(NHALO == 1) THEN
+  CALL ADD3DFIELD_ll( TZFIELDS0_ll, ZRUS_OTHER, 'ADVECTION_UVW::ZRUS_OTHER' )
+  CALL ADD3DFIELD_ll( TZFIELDS0_ll, ZRVS_OTHER, 'ADVECTION_UVW::ZRVS_OTHER' )
+  CALL ADD3DFIELD_ll( TZFIELDS0_ll, ZRWS_OTHER, 'ADVECTION_UVW::ZRWS_OTHER' )
+  CALL UPDATE_HALO_ll(TZFIELDS0_ll,IINFO_ll)
+  CALL CLEANLIST_ll(TZFIELDS0_ll)
+!!$END IF
+#else
+! acc update self(ZRUS_OTHER,ZRVS_OTHER,ZRWS_OTHER)
+  CALL GET_HALO_D(ZRUS_OTHER,HNAME='ADVECTION_UVW::ZRUS_OTHER' )
+  CALL GET_HALO_D(ZRVS_OTHER,HNAME='ADVECTION_UVW::ZRVS_OTHER' )
+  CALL GET_HALO_D(ZRWS_OTHER,HNAME='ADVECTION_UVW::ZRWS_OTHER' )
+! acc update device(ZRUS_OTHER,ZRVS_OTHER,ZRWS_OTHER)
+#endif
+  
+
+!
+!
+!
+!-------------------------------------------------------------------------------
+!
+IF ( HUVW_ADV_SCHEME == 'CEN4TH' ) THEN
+  ISPLIT = 1
+ELSE IF (OSPLIT_WENO) THEN
+  ISPLIT = 2
+ELSE
+  ISPLIT = 1
+END IF
+ZTSTEP = PTSTEP / REAL(ISPLIT)
+!
+!-------------------------------------------------------------------------------
+!
+!$acc kernels
+ZU(:,:,:) = PUT(:,:,:)
+ZV(:,:,:) = PVT(:,:,:)
+ZW(:,:,:) = PWT(:,:,:)
+!$acc end kernels
+!$acc update self(ZU,ZV,ZW)
+!
+!
+!*       3.     TIME SPLITTING
+!	        --------------
+!
+DO JSPL=1,ISPLIT
+!
+  CALL ADVECUVW_RK (HUVW_ADV_SCHEME,                                   &
+                    HTEMP_SCHEME, KWENO_ORDER,                         &
+                    HLBCX, HLBCY, ZTSTEP,                              &
+                    ZU, ZV, ZW,                                        &
+                    PUT, PVT, PWT,                                     &
+                    ZMXM_RHODJ, ZMYM_RHODJ, ZMZM_RHODJ,                &
+                    ZRUCT, ZRVCT, ZRWCT,                               &
+                    ZRUS_ADV, ZRVS_ADV, ZRWS_ADV,                      &
+                    ZRUS_OTHER, ZRVS_OTHER, ZRWS_OTHER                 &
+#ifndef MNH_OPENACC
+                    )
+#else
+                    ,ZT3D(:,:,:,IZUT), ZT3D(:,:,:,IZVT), ZT3D(:,:,:,IZWT), &
+                    ZT3D(:,:,:,IZRUSB:IZRUSE), ZT3D(:,:,:,IZRVSB:IZRVSE), ZT3D(:,:,:,IZRWSB:IZRWSE) )
+#endif
+!
+! Tendencies on wind
+!$acc update device(ZRUS_ADV,ZRVS_ADV,ZRWS_ADV)
+!$acc kernels
+  PRUS(:,:,:) = PRUS(:,:,:) + ZRUS_ADV(:,:,:) / ISPLIT
+  PRVS(:,:,:) = PRVS(:,:,:) + ZRVS_ADV(:,:,:) / ISPLIT
+  PRWS(:,:,:) = PRWS(:,:,:) + ZRWS_ADV(:,:,:) / ISPLIT
+!$acc end kernels  
+!
+  IF (JSPL<ISPLIT) THEN
+!
+! Guesses for next time splitting loop
+  !
+  !$acc kernels   
+  ZU(:,:,:) = ZU(:,:,:) + ZTSTEP / ZMXM_RHODJ *  &
+              (ZRUS_OTHER(:,:,:) + ZRUS_ADV(:,:,:))
+  ZV(:,:,:) = ZV(:,:,:) + ZTSTEP / ZMYM_RHODJ *  &
+              (ZRVS_OTHER(:,:,:) + ZRVS_ADV(:,:,:))
+  ZW(:,:,:) = ZW(:,:,:) + ZTSTEP / ZMZM_RHODJ *  &
+              (ZRWS_OTHER(:,:,:) + ZRWS_ADV(:,:,:))
+  !$acc end kernels
+ END IF
+!
+! Top and bottom Boundaries 
+!
+ IF (JSPL<ISPLIT) THEN
+#ifndef MNH_OPENACC
+  CALL ADV_BOUNDARIES (HLBCX, HLBCY, ZU, PUT, 'U' )
+  CALL ADV_BOUNDARIES (HLBCX, HLBCY, ZV, PVT, 'V' )
+  CALL ADV_BOUNDARIES (HLBCX, HLBCY, ZW, PWT, 'W' )
+#else
+  CALL ADV_BOUNDARIES_DEVICE (HLBCX, HLBCY, ZU, PUT, 'U' )
+  CALL ADV_BOUNDARIES_DEVICE (HLBCX, HLBCY, ZV, PVT, 'V' )
+  CALL ADV_BOUNDARIES_DEVICE (HLBCX, HLBCY, ZW, PWT, 'W' )
+#endif
+!$acc kernels
+  ZW (:,:,IKE+1 ) = 0.
+!$acc end kernels
+!$acc update self(ZU,ZV,ZW)
+  END IF
+!
+! End of the time splitting loop
+END DO
+!
+!
+!*       4.     BUDGETS              
+!	        -------
+!
+IF (LBUDGET_U) THEN
+!$acc update self(PRUS)
+  CALL BUDGET (PRUS,1,'ADV_BU_RU')
+END IF
+IF (LBUDGET_V) THEN
+!$acc update self(PRVS)
+  CALL BUDGET (PRVS,2,'ADV_BU_RV')
+END IF
+IF (LBUDGET_W)  THEN
+!$acc update self(PRWS)
+  CALL BUDGET (PRWS,3,'ADV_BU_RW')
+END IF
+!-------------------------------------------------------------------------------
+!
+#ifdef MNH_OPENACC
+CALL MNH_REL_ZT4D(ISPL, IZRWSB)
+CALL MNH_REL_ZT4D(ISPL, IZRVSB)
+CALL MNH_REL_ZT4D(ISPL, IZRUSB)
+CALL MNH_REL_ZT3D(IZUT, IZVT, IZWT, IZ1, IZ2)
+#endif
+
+IF (MPPDB_INITIALIZED) THEN
+  !Check all INOUT arrays
+  CALL MPPDB_CHECK(PRUS,"ADVECTION_UVW end:PRUS")
+  CALL MPPDB_CHECK(PRVS,"ADVECTION_UVW end:PRVS")
+  CALL MPPDB_CHECK(PRWS,"ADVECTION_UVW end:PRWS")
+END IF
+
+!$acc end data
+
+#ifndef MNH_OPENACC
+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_REL_ZT3D(izmxm_rhodj, izmym_rhodj, izmzm_rhodj )
+CALL MNH_REL_ZT3D(izrus_other, izrvs_other, izrws_other, izrus_adv, izrvs_adv, izrws_adv )
+CALL MNH_REL_ZT3D(izrut, izrvt, izrwt, izruct, izrvct, izrwct, izu, izv, izw)
+#endif
+
+!$acc end data
+
+END SUBROUTINE ADVECTION_UVW
diff --git a/src/ZSOLVER/advecuvw_rk.f90 b/src/ZSOLVER/advecuvw_rk.f90
new file mode 100644
index 0000000000000000000000000000000000000000..6bdfae2fe4342040acd6d061ac9fa988b5f72be6
--- /dev/null
+++ b/src/ZSOLVER/advecuvw_rk.f90
@@ -0,0 +1,581 @@
+!MNH_LIC Copyright 1994-2019 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.
+!-----------------------------------------------------------------
+!     #####################
+      MODULE MODI_ADVECUVW_RK
+!     #####################
+!
+INTERFACE
+      SUBROUTINE ADVECUVW_RK (HUVW_ADV_SCHEME,                         &
+                    HTEMP_SCHEME, KWENO_ORDER,                         &
+                    HLBCX, HLBCY, PTSTEP,                              &
+                    PU, PV, PW,                                        &
+                    PUT, PVT, PWT,                                     &
+                    PMXM_RHODJ, PMYM_RHODJ, PMZM_RHODJ,                &
+                    PRUCT, PRVCT, PRWCT,                               &
+                    PRUS_ADV, PRVS_ADV, PRWS_ADV,                      &
+                    PRUS_OTHER, PRVS_OTHER, PRWS_OTHER                 &
+#ifndef MNH_OPENACC
+                    )
+#else
+                    ,ZUT, ZVT, ZWT, ZRUS, ZRVS, ZRWS)
+#endif
+!
+CHARACTER(LEN=6),         INTENT(IN)    :: HUVW_ADV_SCHEME! to the selected
+CHARACTER(LEN=4),         INTENT(IN)    :: HTEMP_SCHEME   ! Temporal scheme
+!
+INTEGER,                  INTENT(IN)    :: KWENO_ORDER   ! Order of the WENO
+                                                         ! scheme (3 or 5)
+!
+CHARACTER(LEN=4),DIMENSION(2),INTENT(IN):: HLBCX, HLBCY  ! X- and Y-direc LBC
+!
+REAL,                     INTENT(IN)    :: PTSTEP
+!
+REAL, DIMENSION(:,:,:),   INTENT(IN)    :: PU , PV  , PW
+                                                  ! Variables to advect
+REAL, DIMENSION(:,:,:),   INTENT(IN)    :: PUT, PVT , PWT
+                                                  ! Variables at t
+REAL, DIMENSION(:,:,:),   INTENT(IN)    :: PMXM_RHODJ
+REAL, DIMENSION(:,:,:),   INTENT(IN)    :: PMYM_RHODJ
+REAL, DIMENSION(:,:,:),   INTENT(IN)    :: PMZM_RHODJ
+                                                  !  metric coefficients
+REAL, DIMENSION(:,:,:),   INTENT(IN)    :: PRUCT , PRVCT, PRWCT
+                                                  ! Contravariant wind components
+REAL, DIMENSION(:,:,:),   INTENT(OUT)   :: PRUS_ADV , PRVS_ADV, PRWS_ADV
+                                                  ! Tendency due to advection
+REAL, DIMENSION(:,:,:),   INTENT(IN)    :: PRUS_OTHER , PRVS_OTHER, PRWS_OTHER
+!                                                 ! tendencies from other processes
+#ifdef MNH_OPENACC
+! Work arrays
+REAL, DIMENSION(:,:,:) :: ZUT, ZVT, ZWT
+REAL, DIMENSION(:,:,:,:) :: ZRUS,ZRVS,ZRWS
+#endif
+!
+!
+END SUBROUTINE ADVECUVW_RK
+!
+END INTERFACE
+!
+END MODULE MODI_ADVECUVW_RK
+!     ##########################################################################
+      SUBROUTINE ADVECUVW_RK (HUVW_ADV_SCHEME,                         &
+                    HTEMP_SCHEME, KWENO_ORDER,                         &
+                    HLBCX, HLBCY, PTSTEP,                              &
+                    PU, PV, PW,                                        &
+                    PUT, PVT, PWT,                                     &
+                    PMXM_RHODJ, PMYM_RHODJ, PMZM_RHODJ,                &
+                    PRUCT, PRVCT, PRWCT,                               &
+                    PRUS_ADV, PRVS_ADV, PRWS_ADV,                      &
+                    PRUS_OTHER, PRVS_OTHER, PRWS_OTHER                 &
+#ifndef MNH_OPENACC
+                    )
+#else
+                    ,ZUT, ZVT, ZWT, ZRUS, ZRVS, ZRWS)
+#endif
+!     ##########################################################################
+!
+!!****  *ADVECUVW_RK * - routine to call the specialized advection routines for wind
+!!
+!!    PURPOSE
+!!    -------
+!!
+!!**  METHOD
+!!    ------
+!!
+!!    EXTERNAL
+!!    --------
+!!
+!!    IMPLICIT ARGUMENTS
+!!    ------------------
+!!      NONE
+!!
+!!    REFERENCE
+!!    ---------
+!!      Book1 and book2 ( routine ADVECTION )
+!!
+!!    AUTHOR
+!!    ------
+!!	J.-P. Pinty      * Laboratoire d'Aerologie*
+!!	J.-P. Lafore     * Meteo France *
+!!
+!!    MODIFICATIONS
+!!    -------------
+!!      Original    06/07/94 
+!!                  01/04/95 (Ph. Hereil J. Nicolau) add the model number
+!!                  23/10/95 (J. Vila and JP Lafore) advection schemes scalar
+!!                  16/01/97 (JP Pinty)              change presentation 
+!!                  30/04/98 (J. Stein P Jabouille)  extrapolation for the cyclic
+!!                                                   case and parallelisation
+!!                  24/06/99 (P Jabouille)           case of NHALO>1
+!!                  25/10/05 (JP Pinty)              4th order scheme
+!!                  24/04/06 (C.Lac)                 Split scalar and passive
+!!                                                   tracer routines
+!!                  08/06    (T.Maric)               PPM scheme
+!!                  04/2011  (V. Masson & C. Lac)    splits the routine and adds
+!!                                                   time splitting
+!!                  J.Escobar 21/03/2013: for HALOK comment all NHALO=1 test
+!!                  J.Escobar : 15/09/2015 : WENO5 & JPHEXT <> 1
+!!                  F.Auguste and C.Lac : 08/16 : CEN4TH with RKC4
+!!                  C.Lac   10/16 : Correction on RK loop
+!  P. Wautelet 10/04/2019: replace ABORT and STOP calls by Print_msg
+!  P. Wautelet 20/05/2019: add name argument to ADDnFIELD_ll + new ADD4DFIELD_ll subroutine
+!!
+!-------------------------------------------------------------------------------
+!
+!*       0.    DECLARATIONS
+!              ------------
+!
+USE MODD_ARGSLIST_ll, ONLY: LIST_ll, HALO2LIST_ll
+USE MODD_CONF,        ONLY: NHALO
+USE MODD_PARAMETERS,  ONLY: JPVEXT
+!
+USE MODE_ll
+USE MODE_MPPDB
+use mode_msg
+!
+USE MODI_ADV_BOUNDARIES
+USE MODI_ADVECUVW_4TH
+USE MODI_ADVECUVW_WENO_K
+USE MODI_GET_HALO
+USE MODI_SHUMAN
+!
+!
+#ifdef MNH_OPENACC
+USE MODE_DEVICE
+USE MODE_MNH_ZWORK, ONLY : ZT3D, MNH_GET_ZT3D , MNH_REL_ZT3D
+#endif
+!
+!-------------------------------------------------------------------------------
+!
+IMPLICIT NONE
+!
+!*       0.1   Declarations of dummy arguments :
+!
+CHARACTER(LEN=6),         INTENT(IN)    :: HUVW_ADV_SCHEME! to the selected
+CHARACTER(LEN=4),         INTENT(IN)    :: HTEMP_SCHEME   ! Temporal scheme
+!
+INTEGER,                  INTENT(IN)    :: KWENO_ORDER   ! Order of the WENO
+                                                         ! scheme (3 or 5)
+!
+CHARACTER(LEN=4),DIMENSION(2),INTENT(IN):: HLBCX, HLBCY  ! X- and Y-direc LBC
+!
+REAL,                     INTENT(IN)    :: PTSTEP
+!
+REAL, DIMENSION(:,:,:),   INTENT(IN)    :: PU , PV  , PW
+                                                  ! Variables to advect
+REAL, DIMENSION(:,:,:),   INTENT(IN)    :: PUT, PVT , PWT
+                                                  ! Variables at t
+REAL, DIMENSION(:,:,:),   INTENT(IN)    :: PMXM_RHODJ
+REAL, DIMENSION(:,:,:),   INTENT(IN)    :: PMYM_RHODJ
+REAL, DIMENSION(:,:,:),   INTENT(IN)    :: PMZM_RHODJ
+                                                  !  metric coefficients
+REAL, DIMENSION(:,:,:),   INTENT(IN)    :: PRUCT , PRVCT, PRWCT
+                                                  ! Contravariant wind components
+REAL, DIMENSION(:,:,:),   INTENT(OUT)   :: PRUS_ADV , PRVS_ADV, PRWS_ADV
+                                                  ! Tendency due to advection
+REAL, DIMENSION(:,:,:),   INTENT(IN)    :: PRUS_OTHER , PRVS_OTHER, PRWS_OTHER
+!                                                 ! tendencies from other processes
+#ifdef MNH_OPENACC
+REAL, DIMENSION(:,:,:) :: ZUT, ZVT, ZWT
+REAL, DIMENSION(:,:,:,:) :: ZRUS,ZRVS,ZRWS
+#endif
+!
+!
+!
+!*       0.2   declarations of local variables
+!
+!
+!
+character(len=3)    :: ynum
+INTEGER             :: IKE       ! indice K End       in z direction
+!
+#ifndef MNH_OPENACC
+REAL, DIMENSION(:,:,:), ALLOCATABLE :: ZUT, ZVT, ZWT
+! Intermediate Guesses inside the RK loop
+!
+REAL, DIMENSION(:,:,:,:), ALLOCATABLE :: ZRUS,ZRVS,ZRWS
+#endif
+! Momentum tendencies due to advection
+REAL, DIMENSION(:,:), ALLOCATABLE :: ZBUT ! Butcher array coefficients
+                                          ! at the RK sub time step
+REAL, DIMENSION(:),   ALLOCATABLE :: ZBUTS! Butcher array coefficients
+                                          ! at the end of the RK loop
+!JUAN
+TYPE(LIST_ll), POINTER      :: TZFIELDMT_ll ! list of fields to exchange
+TYPE(HALO2LIST_ll), POINTER :: TZHALO2MT_ll ! momentum variables
+TYPE(HALO2LIST_ll), SAVE , POINTER :: TZHALO2_UT,TZHALO2_VT,TZHALO2_WT
+LOGICAL , SAVE :: GFIRST_CALL_ADVECUVW_RK = .TRUE.
+INTEGER                     :: INBVAR
+INTEGER :: IIU, IJU, IKU ! array sizes
+!JUAN
+
+#ifdef MNH_OPENACC
+INTEGER :: IZMEAN, IZWORK
+#endif
+! Momentum tendencies due to advection
+INTEGER :: ISPL                ! Number of RK splitting loops
+INTEGER :: JI, JS              ! Loop index
+!
+INTEGER                     :: IINFO_ll    ! return code of parallel routine
+TYPE(LIST_ll), POINTER      :: TZFIELD_ll  ! list of fields to exchange
+TYPE(LIST_ll), POINTER      :: TZFIELDS_ll ! list of fields to exchange
+TYPE(LIST_ll), POINTER      :: TZFIELDS0_ll ! list of fields to exchange
+TYPE(LIST_ll), POINTER      :: TZFIELDS4_ll ! list of fields to exchange
+!
+!-------------------------------------------------------------------------------
+!$acc data present( PU, PV, PW, PUT, PVT, PWT, PMXM_RHODJ, PMYM_RHODJ, PMZM_RHODJ,      &
+!$acc &             PRUCT, PRVCT, PRWCT, PRUS_ADV, PRVS_ADV, PRWS_ADV,                  &
+!$acc &             PRUS_OTHER, PRVS_OTHER, PRWS_OTHER, ZUT, ZVT, ZWT, ZRUS, ZRVS, ZRWS )
+
+IF (MPPDB_INITIALIZED) THEN
+  !Check all IN arrays
+  CALL MPPDB_CHECK(PU,"ADVECUVW_RK beg:PU")
+  CALL MPPDB_CHECK(PV,"ADVECUVW_RK beg:PV")
+  CALL MPPDB_CHECK(PW,"ADVECUVW_RK beg:PW")
+  CALL MPPDB_CHECK(PUT,"ADVECUVW_RK beg:PUT")
+  CALL MPPDB_CHECK(PVT,"ADVECUVW_RK beg:PVT")
+  CALL MPPDB_CHECK(PWT,"ADVECUVW_RK beg:PWT")
+  CALL MPPDB_CHECK(PMXM_RHODJ,"ADVECUVW_RK beg:PMXM_RHODJ")
+  CALL MPPDB_CHECK(PMYM_RHODJ,"ADVECUVW_RK beg:PMYM_RHODJ")
+  CALL MPPDB_CHECK(PMZM_RHODJ,"ADVECUVW_RK beg:PMZM_RHODJ")
+  CALL MPPDB_CHECK(PRUCT,"ADVECUVW_RK beg:PRUCT")
+  CALL MPPDB_CHECK(PRVCT,"ADVECUVW_RK beg:PRVCT")
+  CALL MPPDB_CHECK(PRWCT,"ADVECUVW_RK beg:PRWCT")
+  CALL MPPDB_CHECK(PRUS_OTHER,"ADVECUVW_RK beg:PRUS_OTHER")
+  CALL MPPDB_CHECK(PRVS_OTHER,"ADVECUVW_RK beg:PRVS_OTHER")
+  CALL MPPDB_CHECK(PRWS_OTHER,"ADVECUVW_RK beg:PRWS_OTHER")
+END IF
+!
+!*       0.     INITIALIZATION                        
+!	        --------------
+!
+#ifndef MNH_OPENACC
+allocate(ZUT(SIZE(PUT,1),SIZE(PUT,2),SIZE(PUT,3)))
+allocate(ZVT(SIZE(PUT,1),SIZE(PUT,2),SIZE(PUT,3)))
+allocate(ZWT(SIZE(PUT,1),SIZE(PUT,2),SIZE(PUT,3)))
+#endif
+
+#ifdef MNH_OPENACC
+CALL INIT_ON_HOST_AND_DEVICE(ZUT,4e99,'ADVECUVW_RK::ZUT')
+CALL INIT_ON_HOST_AND_DEVICE(ZVT,5e99,'ADVECUVW_RK::ZVT')
+CALL INIT_ON_HOST_AND_DEVICE(ZWT,6e99,'ADVECUVW_RK::ZWT')
+!
+CALL MNH_GET_ZT3D(IZMEAN,IZWORK)
+#endif
+!
+IKE = SIZE(PWT,3) - JPVEXT
+IIU=SIZE(PUT,1)
+IJU=SIZE(PUT,2)
+IKU=SIZE(PUT,3)
+!
+SELECT CASE (HTEMP_SCHEME)
+ CASE('RK11')
+  ISPL = 1
+ CASE('RK21')
+  ISPL = 2
+ CASE('NP32')
+  ISPL = 3
+ CASE('SP32')
+  ISPL = 3
+ CASE('RK33')
+  ISPL = 3
+ CASE('RKC4')
+  ISPL = 4
+ CASE('RK4B')
+  ISPL = 4
+ CASE('RK53')
+  ISPL = 5
+ CASE('RK62')
+  ISPL = 6
+ CASE('RK65')
+  ISPL = 6
+ CASE DEFAULT
+  call Print_msg(NVERB_FATAL,'GEN','ADVECUVW_RK','unknown HTEMP_SCHEME')
+END SELECT
+!
+!
+ALLOCATE(ZBUT(ISPL-1,ISPL-1))
+ALLOCATE(ZBUTS(ISPL))
+
+!$acc data create(ZBUT,ZBUTS)
+
+SELECT CASE (HTEMP_SCHEME)
+  CASE('RK11')
+    ZBUTS = (/ 1. /)
+  CASE('RK21')
+    ZBUTS     = (/ 0. , 1. /)
+    ZBUT(1,1)   = 3./4.
+  CASE('RK33')
+    ZBUTS     = (/ 1./6. , 1./6. , 2./3. /)
+    ZBUT(1,1) = 1.
+    ZBUT(1,2) = 0.
+    ZBUT(2,1) = 1./4.
+    ZBUT(2,2) = 1./4.
+  CASE('NP32')
+    ZBUTS     = (/ 1./2. , 0., 1./2. /)
+    ZBUT(1,1) = 1./3.
+    ZBUT(1,2) = 0.
+    ZBUT(2,1) = 0.
+    ZBUT(2,2) = 1.
+  CASE('SP32')
+    ZBUTS     = (/ 1./3. , 1./3. , 1./3. /)
+    ZBUT(1,1) = 1./2.
+    ZBUT(1,2) = 0.
+    ZBUT(2,1) = 1./2.
+    ZBUT(2,2) = 1./2.
+  CASE('RKC4')
+    ZBUTS     = (/ 1./6. , 1./3. , 1./3. , 1./6./)
+    ZBUT      = 0.
+    ZBUT(1,1) = 1./2.
+    ZBUT(2,2) = 1./2.
+    ZBUT(3,3) = 1.
+  CASE('RK4B')
+    ZBUTS     = (/ 1./8. , 3./8. , 3./8. , 1./8./)
+    ZBUT      = 0.
+    ZBUT(1,1) = 1./3.
+    ZBUT(2,1) = -1./3.
+    ZBUT(2,2) = 1.
+    ZBUT(3,1) = 1.
+    ZBUT(3,2) = -1.
+    ZBUT(3,3) = 1.
+  CASE('RK53')
+    ZBUTS     = (/ 1./4. , 0. , 0. , 0. , 3./4. /)
+    ZBUT      = 0.
+    ZBUT(1,1) = 1./7.
+    ZBUT(2,2) = 3./16.
+    ZBUT(3,3) = 1./3.
+    ZBUT(4,4) = 2./3.
+  CASE('RK62')
+    ZBUTS     = (/ 1./6. , 1./6. , 1./6. , 1./6. , 1./6. , 1./6. /)
+    ZBUT      = 0.
+    ZBUT(1,1) = 1./5.
+    ZBUT(2,1) = 1./5.
+    ZBUT(2,2) = 1./5.
+    ZBUT(3,1) = 1./5.
+    ZBUT(3,2) = 1./5.
+    ZBUT(3,3) = 1./5.
+    ZBUT(4,1) = 1./5.
+    ZBUT(4,2) = 1./5.
+    ZBUT(4,3) = 1./5.
+    ZBUT(4,4) = 1./5.
+    ZBUT(5,1) = 1./5.
+    ZBUT(5,2) = 1./5.
+    ZBUT(5,3) = 1./5.
+    ZBUT(5,4) = 1./5.
+    ZBUT(5,5) = 1./5.
+CASE('RK65')
+    ZBUTS= (/ 7./90. , 0. , 16./45. , 2./15. , 16./45. , 7./90. /)
+    ZBUT= 0.
+    ZBUT(1,1) = 1./4.
+    ZBUT(2,1) = 1./8.
+    ZBUT(2,2) = 1./8.
+    ZBUT(3,1) = 0
+    ZBUT(3,2) = -1./2.
+    ZBUT(3,3) = 1
+    ZBUT(4,1) = 3./16.
+    ZBUT(4,2) = 0
+    ZBUT(4,3) = 0
+    ZBUT(4,4) = 9./16.
+    ZBUT(5,1) = -3./7.
+    ZBUT(5,2) = 2./7.
+    ZBUT(5,3) = 12./7.
+    ZBUT(5,4) = -12./7.
+    ZBUT(5,5) = 8./7.
+END SELECT
+!$acc update device(ZBUTS,ZBUT)
+!
+#ifndef MNH_OPENACC
+ALLOCATE(ZRUS(SIZE(PUT,1),SIZE(PUT,2),SIZE(PWT,3),ISPL))
+ALLOCATE(ZRVS(SIZE(PUT,1),SIZE(PUT,2),SIZE(PWT,3),ISPL))
+ALLOCATE(ZRWS(SIZE(PUT,1),SIZE(PUT,2),SIZE(PWT,3),ISPL))
+#endif
+!
+!$acc kernels present(PRUS_ADV,PRVS_ADV,PRWS_ADV) present(ZUT,ZVT,ZWT) present(PU,PV,PW)
+PRUS_ADV = 0.
+PRVS_ADV = 0.
+PRWS_ADV = 0.
+!
+!-------------------------------------------------------------------------------
+!
+!*       2.     Wind guess before RK loop
+!	        -------------------------
+!
+ZUT = PU
+ZVT = PV
+ZWT = PW
+!$acc end kernels
+!
+#ifndef MNH_OPENACC
+CALL ADV_BOUNDARIES (HLBCX, HLBCY, ZUT, PUT, 'U' )
+CALL ADV_BOUNDARIES (HLBCX, HLBCY, ZVT, PVT, 'V' )
+CALL ADV_BOUNDARIES (HLBCX, HLBCY, ZWT, PWT, 'W' )
+#else
+CALL ADV_BOUNDARIES_DEVICE (HLBCX, HLBCY, ZUT, PUT, 'U' )
+CALL ADV_BOUNDARIES_DEVICE (HLBCX, HLBCY, ZVT, PVT, 'V' )
+CALL ADV_BOUNDARIES_DEVICE (HLBCX, HLBCY, ZWT, PWT, 'W' )
+#endif
+!
+NULLIFY(TZFIELDMT_ll)
+CALL ADD3DFIELD_ll( TZFIELDMT_ll, ZUT, 'ADVECUVW_RK::ZUT' )
+CALL ADD3DFIELD_ll( TZFIELDMT_ll, ZVT, 'ADVECUVW_RK::ZVT' )
+CALL ADD3DFIELD_ll( TZFIELDMT_ll, ZWT, 'ADVECUVW_RK::ZWT' )
+INBVAR = 3
+CALL INIT_HALO2_ll(TZHALO2MT_ll,INBVAR,SIZE(PUT,1),SIZE(PUT,2),SIZE(PWT,3))
+!
+!$acc kernels
+ZRUS(:, :, :, : ) = 0.
+ZRVS(:, :, :, : ) = 0.
+ZRWS(:, :, :, : ) = 0.
+!$acc end kernels
+
+!Necessary to work around a PGI bug (19.10)
+!because following update ZRUS(:,:,:,JS) are done on the WHOLE array
+!$acc update self(ZRUS,ZRVS,ZRWS)
+
+!-------------------------------------------------------------------------------
+!
+!*       3.     BEGINNING of Runge-Kutta loop
+!	        -----------------------------
+!
+ DO JS = 1, ISPL
+!
+#ifndef MNH_OPENACC
+      CALL ADV_BOUNDARIES (HLBCX, HLBCY, ZUT, PUT, 'U' )
+      CALL ADV_BOUNDARIES (HLBCX, HLBCY, ZVT, PVT, 'V' )
+      CALL ADV_BOUNDARIES (HLBCX, HLBCY, ZWT, PWT, 'W' )
+#else
+      CALL ADV_BOUNDARIES_DEVICE (HLBCX, HLBCY, ZUT, PUT, 'U' )
+      CALL ADV_BOUNDARIES_DEVICE (HLBCX, HLBCY, ZVT, PVT, 'V' )
+      CALL ADV_BOUNDARIES_DEVICE (HLBCX, HLBCY, ZWT, PWT, 'W' )
+#endif
+      !
+#ifndef MNH_OPENACC      
+        CALL UPDATE_HALO_ll(TZFIELDMT_ll,IINFO_ll)
+        CALL UPDATE_HALO2_ll(TZFIELDMT_ll, TZHALO2MT_ll, IINFO_ll)
+#else
+! acc update self(ZUT,ZVT,ZWT)
+!!$        CALL GET_HALO_D(ZUT,HNAME='ZUT')
+!!$        CALL GET_HALO_D(ZVT,HNAME='ZVT')
+!!$        CALL GET_HALO_D(ZWT,HNAME='ZWT')
+!!$        CALL UPDATE_HALO2_ll(TZFIELDMT_ll, TZHALO2MT_ll, IINFO_ll)
+IF (GFIRST_CALL_ADVECUVW_RK) THEN
+   GFIRST_CALL_ADVECUVW_RK = .FALSE.
+   NULLIFY(TZHALO2_UT,TZHALO2_VT,TZHALO2_WT)
+   CALL INIT_HALO2_ll(TZHALO2_UT,1,IIU,IJU,IKU)
+   CALL INIT_HALO2_ll(TZHALO2_VT,1,IIU,IJU,IKU)
+   CALL INIT_HALO2_ll(TZHALO2_WT,1,IIU,IJU,IKU)
+END IF        
+        CALL GET_HALO2_DF(ZUT,TZHALO2_UT,HNAME='ZUT')
+        CALL GET_HALO2_DF(ZVT,TZHALO2_VT,HNAME='ZVT')
+        CALL GET_HALO2_DF(ZWT,TZHALO2_WT,HNAME='ZWT')               
+! acc update device(ZUT,ZVT,ZWT)       
+#endif
+        
+
+        
+!
+!*       4.     Advection with WENO
+!	        -------------------
+!
+!!$TZHALO2_UT => TZHALO2MT_ll                   ! 1rst add3dfield in model_n
+!!$TZHALO2_VT => TZHALO2MT_ll%NEXT              ! 2nd  add3dfield in model_n
+!!$TZHALO2_WT => TZHALO2MT_ll%NEXT%NEXT         ! 3rst add3dfield in model_n
+        
+  IF (HUVW_ADV_SCHEME=='WENO_K') THEN
+    CALL ADVECUVW_WENO_K (HLBCX, HLBCY, KWENO_ORDER, ZUT, ZVT, ZWT,     &
+                        PRUCT, PRVCT, PRWCT,                            &
+                        ZRUS(:,:,:,JS), ZRVS(:,:,:,JS), ZRWS(:,:,:,JS), &
+                        TZHALO2_UT,TZHALO2_VT,TZHALO2_WT &
+#ifndef MNH_OPENACC
+                        )
+#else
+                        , ZT3D(:,:,:,IZMEAN), ZT3D(:,:,:,IZWORK) )
+#endif
+  ELSE IF ((HUVW_ADV_SCHEME=='CEN4TH') .AND. (HTEMP_SCHEME=='RKC4')) THEN
+    CALL ADVECUVW_4TH (HLBCX, HLBCY, PRUCT, PRVCT, PRWCT,               &
+                       ZUT, ZVT, ZWT,                                   &
+                       ZRUS(:,:,:,JS), ZRVS(:,:,:,JS), ZRWS(:,:,:,JS),  &
+                       TZHALO2MT_ll )
+  ENDIF
+!
+
+!
+    write ( ynum, '( I3 )' ) js
+#ifndef MNH_OPENACC
+    NULLIFY(TZFIELDS4_ll) 
+    CALL ADD3DFIELD_ll( TZFIELDS4_ll, ZRUS(:,:,:,JS), 'ADVECUVW_RK::ZRUS(:,:,:,'//trim( adjustl( ynum ) )//')' )
+    CALL ADD3DFIELD_ll( TZFIELDS4_ll, ZRVS(:,:,:,JS), 'ADVECUVW_RK::ZRVS(:,:,:,'//trim( adjustl( ynum ) )//')' )
+    CALL ADD3DFIELD_ll( TZFIELDS4_ll, ZRWS(:,:,:,JS), 'ADVECUVW_RK::ZRWS(:,:,:,'//trim( adjustl( ynum ) )//')' )
+    CALL UPDATE_HALO_ll(TZFIELDS4_ll,IINFO_ll)
+    CALL CLEANLIST_ll(TZFIELDS4_ll)
+#else
+    CALL GET_HALO_D(ZRUS(:,:,:,JS),HNAME='ADVECUVW_RK::ZRUS(:,:,:,'//trim( adjustl( ynum ) )//')' )
+    CALL GET_HALO_D(ZRVS(:,:,:,JS),HNAME='ADVECUVW_RK::ZRVS(:,:,:,'//trim( adjustl( ynum ) )//')' )
+    CALL GET_HALO_D(ZRWS(:,:,:,JS),HNAME='ADVECUVW_RK::ZRWS(:,:,:,'//trim( adjustl( ynum ) )//')' )
+! acc update device(ZRUS(:,:,:,JS),ZRVS(:,:,:,JS),ZRWS(:,:,:,JS))
+#endif    
+!
+!
+! Guesses at the end of the RK loop
+!
+!$acc kernels present(PRUS_ADV,PRVS_ADV,PRWS_ADV,ZBUTS) present(ZRUS,ZRVS,ZRWS)
+     PRUS_ADV(:,:,:) = PRUS_ADV(:,:,:) + ZBUTS(JS) * ZRUS(:,:,:,JS)
+     PRVS_ADV(:,:,:) = PRVS_ADV(:,:,:) + ZBUTS(JS) * ZRVS(:,:,:,JS)
+     PRWS_ADV(:,:,:) = PRWS_ADV(:,:,:) + ZBUTS(JS) * ZRWS(:,:,:,JS)
+!$acc end kernels
+!
+  IF ( JS < ISPL ) THEN
+!$acc kernels present(ZUT,ZVT,ZWT) present(ZBUT) present(PU,PV,PW)        &
+!$acc & present(ZRUS,ZRVS,ZRWS) present(PRUS_OTHER,PRVS_OTHER,PRWS_OTHER) &
+!$acc & present(PMXM_RHODJ,PMYM_RHODJ,PMZM_RHODJ)
+!
+    ZUT = PU
+    ZVT = PV
+    ZWT = PW
+!
+    DO JI = 1, JS
+!
+! Intermediate guesses inside the RK loop
+!
+      ZUT(:,:,:) = ZUT(:,:,:) + ZBUT(JS,JI) *  PTSTEP *  &
+       ( ZRUS(:,:,:,JI) + PRUS_OTHER(:,:,:) ) / PMXM_RHODJ
+      ZVT(:,:,:) = ZVT(:,:,:) + ZBUT(JS,JI) *  PTSTEP *  &
+       ( ZRVS(:,:,:,JI) + PRVS_OTHER(:,:,:) ) / PMYM_RHODJ
+      ZWT(:,:,:) = ZWT(:,:,:) + ZBUT(JS,JI) *  PTSTEP *  &
+       ( ZRWS(:,:,:,JI) + PRWS_OTHER(:,:,:) ) / PMZM_RHODJ
+!
+    END DO
+!$acc end kernels
+!$acc update self(ZUT,ZVT,ZWT)
+  END IF
+!
+! End of the RK loop
+ END DO
+!
+!
+#ifdef MNH_OPENACC
+CALL MNH_REL_ZT3D(IZMEAN,IZWORK)
+#endif
+!
+CALL CLEANLIST_ll(TZFIELDMT_ll)
+CALL DEL_HALO2_ll(TZHALO2MT_ll)
+!!$CALL DEL_HALO2_ll(TZHALO2_UT)
+!!$CALL DEL_HALO2_ll(TZHALO2_VT)
+!!$CALL DEL_HALO2_ll(TZHALO2_WT)
+!$acc update self(PRUS_ADV,PRVS_ADV,PRWS_ADV)
+!-------------------------------------------------------------------------------
+!
+IF (MPPDB_INITIALIZED) THEN
+  !Check all OUT arrays
+  CALL MPPDB_CHECK(PRUS_ADV,"ADVECUVW_RK end:PRUS_ADV")
+  CALL MPPDB_CHECK(PRVS_ADV,"ADVECUVW_RK end:PRVS_ADV")
+  CALL MPPDB_CHECK(PRWS_ADV,"ADVECUVW_RK end:PRWS_ADV")
+END IF
+
+!$acc end data
+
+!$acc end data
+
+END SUBROUTINE ADVECUVW_RK
diff --git a/src/ZSOLVER/advecuvw_weno_k.f90 b/src/ZSOLVER/advecuvw_weno_k.f90
new file mode 100644
index 0000000000000000000000000000000000000000..f41009ae4ef63792834dff1b2f025e0808f1a2e2
--- /dev/null
+++ b/src/ZSOLVER/advecuvw_weno_k.f90
@@ -0,0 +1,662 @@
+!MNH_LIC Copyright 2013-2020 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.
+!-----------------------------------------------------------------
+!     ###########################
+      MODULE MODI_ADVECUVW_WENO_K
+!     ###########################
+!
+INTERFACE
+!
+      SUBROUTINE ADVECUVW_WENO_K(HLBCX, HLBCY, KWENO_ORDER, PUT, PVT, PWT,       &
+                             PRUCT, PRVCT, PRWCT, PRUS, PRVS, PRWS, & 
+                             TPHALO2_UT,TPHALO2_VT,TPHALO2_WT &
+#ifndef MNH_OPENACC
+                             )
+#else
+                             , ZMEAN, ZWORK)
+#endif
+!
+USE MODD_ARGSLIST_ll, ONLY : HALO2LIST_ll
+!
+CHARACTER (LEN=4), DIMENSION(2), INTENT(IN) :: HLBCX ! X direction LBC type
+CHARACTER (LEN=4), DIMENSION(2), INTENT(IN) :: HLBCY ! Y direction LBC type
+INTEGER,                  INTENT(IN)    :: KWENO_ORDER   ! Order of the WENO
+                                                         ! scheme (3 or 5)
+!
+REAL, DIMENSION(:,:,:),   INTENT(IN)    :: PRUCT ! contravariant
+REAL, DIMENSION(:,:,:),   INTENT(IN)    :: PRVCT !  components
+REAL, DIMENSION(:,:,:),   INTENT(IN)    :: PRWCT ! of momentum
+!
+REAL, DIMENSION(:,:,:),   INTENT(IN) :: PUT, PVT, PWT        ! U,V,W at t
+!
+REAL, DIMENSION(:,:,:),   INTENT(INOUT) :: PRUS, PRVS, PRWS     ! Source terms
+!
+TYPE(HALO2LIST_ll), POINTER :: TPHALO2_UT,TPHALO2_VT,TPHALO2_WT
+!
+#ifdef MNH_OPENACC
+! Work arrays
+REAL, DIMENSION(:,:,:) :: ZMEAN, ZWORK
+#endif
+!
+END SUBROUTINE ADVECUVW_WENO_K
+!
+END INTERFACE
+!
+END MODULE MODI_ADVECUVW_WENO_K
+!
+!     ##########################################################################
+      SUBROUTINE ADVECUVW_WENO_K(HLBCX, HLBCY, KWENO_ORDER, PUT, PVT, PWT,      &
+                             PRUCT, PRVCT, PRWCT, PRUS, PRVS, PRWS, & 
+                             TPHALO2_UT,TPHALO2_VT,TPHALO2_WT &
+#ifndef MNH_OPENACC
+                             )
+#else
+                             , ZMEAN, ZWORK)
+#endif
+!     ##########################################################################
+!
+!!    AUTHOR
+!!    ------
+!!
+!!
+!!    MODIFICATIONS
+!!    ------------- 
+!!      J.Escobar 21/03/2013: for HALOK comment all NHALO=1 tests
+!!		  T.Lunet	 	02/10/2014: add get_halo for WENO 5
+!!					suppress comment of NHALO=1 tests
+!!      J.Escobar : 15/09/2015 : WENO5 & JPHEXT <> 1 
+!!
+!-------------------------------------------------------------------------------
+!
+!*       0.    DECLARATIONS
+!              ------------
+!
+USE MODE_ll
+!
+USE MODD_PARAMETERS
+USE MODD_CONF
+USE MODD_ARGSLIST_ll, ONLY : HALO2LIST_ll
+!
+#ifndef MNH_OPENACC
+USE MODI_SHUMAN
+#else
+USE MODI_SHUMAN_DEVICE
+#endif
+USE MODI_ADVEC_WENO_K_1_AUX
+USE MODI_ADVEC_WENO_K_2_AUX
+USE MODI_ADVEC_WENO_K_3_AUX
+!
+USE MODD_CONF,        ONLY : NHALO
+USE MODE_MPPDB
+USE MODI_GET_HALO
+!
+#ifdef MNH_OPENACC
+USE MODE_DEVICE
+USE MODE_MNH_ZWORK, ONLY : ZT3D, MNH_GET_ZT3D , MNH_REL_ZT3D
+#endif
+!
+IMPLICIT NONE
+!
+!*       0.1   Declarations of dummy arguments :
+!
+CHARACTER (LEN=4), DIMENSION(2), INTENT(IN) :: HLBCX ! X direction LBC type
+CHARACTER (LEN=4), DIMENSION(2), INTENT(IN) :: HLBCY ! Y direction LBC type
+INTEGER,                  INTENT(IN)    :: KWENO_ORDER   ! Order of the WENO
+                                                         ! scheme (3 or 5)
+!
+REAL, DIMENSION(:,:,:),   INTENT(IN) :: PRUCT  ! contravariant
+REAL, DIMENSION(:,:,:),   INTENT(IN) :: PRVCT  !  components
+REAL, DIMENSION(:,:,:),   INTENT(IN) :: PRWCT  ! of momentum
+!
+REAL, DIMENSION(:,:,:),   INTENT(IN) :: PUT, PVT, PWT     ! Variables at t
+!
+REAL, DIMENSION(:,:,:),   INTENT(INOUT) :: PRUS, PRVS, PRWS     ! Source terms
+!
+!
+!*       0.2   Declarations of local variables :
+!
+TYPE(HALO2LIST_ll), POINTER :: TPHALO2_UT,TPHALO2_VT,TPHALO2_WT
+
+INTEGER                     :: IINFO_ll    ! return code of parallel routine
+!
+#ifndef MNH_OPENACC
+REAL, DIMENSION(:,:,:), allocatable :: ZMEAN, ZWORK
+#else
+REAL, DIMENSION(:,:,:) :: ZMEAN, ZWORK
+#endif
+!
+INTEGER :: IKU
+#ifdef MNH_OPENACC
+INTEGER :: IZFPOS1, IZFPOS2, IZFPOS3
+INTEGER :: IZFNEG1, IZFNEG2, IZFNEG3
+INTEGER :: IZBPOS1, IZBPOS2, IZBPOS3
+INTEGER :: IZBNEG1, IZBNEG2, IZBNEG3
+INTEGER :: IZOMP1,  IZOMP2,  IZOMP3
+INTEGER :: IZOMN1,  IZOMN2,  IZOMN3
+#endif
+!
+!$acc data present( PRUCT, PRVCT, PRWCT, PUT, PVT, PWT, PRUS, PRVS, PRWS, ZMEAN, ZWORK )
+!
+IF (MPPDB_INITIALIZED) THEN
+  !Check all IN arrays
+  CALL MPPDB_CHECK(PRUCT,"ADVECUVW_WENO_K beg:PRUCT")
+  CALL MPPDB_CHECK(PRVCT,"ADVECUVW_WENO_K beg:PRVCT")
+  CALL MPPDB_CHECK(PRWCT,"ADVECUVW_WENO_K beg:PRWCT")
+  CALL MPPDB_CHECK(PUT,"ADVECUVW_WENO_K beg:PUT")
+  CALL MPPDB_CHECK(PVT,"ADVECUVW_WENO_K beg:PVT")
+  CALL MPPDB_CHECK(PWT,"ADVECUVW_WENO_K beg:PWT")
+  !Check all INOUT arrays
+  CALL MPPDB_CHECK(PRUS,"ADVECUVW_WENO_K beg:PRUS")
+  CALL MPPDB_CHECK(PRVS,"ADVECUVW_WENO_K beg:PRVS")
+  CALL MPPDB_CHECK(PRWS,"ADVECUVW_WENO_K beg:PRWS")
+END IF
+
+#ifndef MNH_OPENACC
+allocate(ZMEAN(SIZE(PUT,1), SIZE(PUT,2), SIZE(PUT,3)))
+allocate(ZWORK(SIZE(PUT,1), SIZE(PUT,2), SIZE(PUT,3)))
+#endif
+
+#ifdef MNH_OPENACC
+CALL INIT_ON_HOST_AND_DEVICE(ZMEAN,1e90,'ADVECUVW_WENO_K::ZMEAN')
+CALL INIT_ON_HOST_AND_DEVICE(ZWORK,2e90,'ADVECUVW_WENO_K::ZWORK')
+#endif
+!
+!------------------------- ADVECTION OF MOMENTUM ------------------------------
+!
+!
+!!$TPHALO2_UT => TPHALO2LIST                   ! 1rst add3dfield in model_n
+!!$TPHALO2_VT => TPHALO2LIST%NEXT              ! 2nd  add3dfield in model_n
+!!$TPHALO2_WT => TPHALO2LIST%NEXT%NEXT         ! 3rst add3dfield in model_n
+!
+IKU=SIZE(PUT,3)
+!      -------------------------------------------------------
+!
+SELECT CASE(KWENO_ORDER)
+!
+CASE(1) ! WENO 1
+#ifndef MNH_OPENACC
+!
+!  U component
+!
+  PRUS = PRUS - DXM(UP_UX(PUT,MXF(PRUCT)))
+!
+  PRUS = PRUS - DYF(UP_MY(PUT,MXM(PRVCT)))
+!
+  PRUS = PRUS - DZF(UP_MZ(PUT,MXM(PRWCT)))
+!
+! V component
+!
+  PRVS = PRVS - DXF(UP_MX(PVT,MYM(PRUCT)))
+!
+  PRVS = PRVS - DYM(UP_VY(PVT,MYF(PRVCT)))
+!
+  PRVS = PRVS - DZF(UP_MZ(PVT,MYM(PRWCT)))
+!
+! W component
+!
+  PRWS = PRWS - DXF(UP_MX(PWT,MZM(PRUCT)))
+!
+  PRWS = PRWS - DYF(UP_MY(PWT,MZM(PRVCT)))
+!
+  PRWS = PRWS - DZM(UP_WZ(PWT,MZF(PRWCT)))
+#else
+!
+!  U component
+!
+  !PRUS = PRUS - DXM(UP_UX(PUT,MXF(PRUCT)))
+  CALL MXF_DEVICE(PRUCT,ZWORK)
+  CALL UP_UX_DEVICE(PUT,ZWORK,ZMEAN)
+  CALL DXM_DEVICE(ZMEAN,ZWORK)
+!$acc kernels
+  PRUS = PRUS - ZWORK
+!$acc end kernels
+!
+  !PRUS = PRUS - DYF(UP_MY(PUT,MXM(PRVCT)))
+  CALL MXM_DEVICE(PRVCT,ZWORK)
+  CALL UP_MY_DEVICE(PUT,ZWORK,ZMEAN)
+  CALL DYF_DEVICE(ZMEAN,ZWORK)
+!$acc kernels
+  PRUS = PRUS - ZWORK
+!$acc end kernels
+!
+  !PRUS = PRUS - DZF(1,IKU,1,UP_MZ(PUT,MXM(PRWCT)))
+  CALL MXM_DEVICE(PRWCT,ZWORK)
+  CALL UP_MZ_DEVICE(PUT,ZWORK,ZMEAN)
+  CALL DZF_DEVICE(1,IKU,1,ZMEAN,ZWORK)
+!$acc kernels
+  PRUS = PRUS - ZWORK
+!$acc end kernels
+!
+! V component
+!
+  !PRVS = PRVS - DXF(UP_MX(PVT,MYM(PRUCT)))
+  CALL MYM_DEVICE(PRUCT,ZWORK)
+  CALL UP_MX_DEVICE(PVT,ZWORK,ZMEAN)
+  CALL DXF_DEVICE(ZMEAN,ZWORK)
+!$acc kernels
+  PRVS = PRVS - ZWORK
+!$acc end kernels
+!
+  !PRVS = PRVS - DYM(UP_VY(PVT,MYF(PRVCT)))
+  CALL MYF_DEVICE(PRVCT,ZWORK)
+  CALL UP_VY_DEVICE(PVT,ZWORK,ZMEAN)
+  CALL DYM_DEVICE(ZMEAN,ZWORK)
+!$acc kernels
+  PRVS = PRVS - ZWORK
+!$acc end kernels
+!
+  !PRVS = PRVS - DZF(1,IKU,1,UP_MZ(PVT,MYM(PRWCT)))
+  CALL MYM_DEVICE(PRWCT,ZWORK)
+  CALL UP_MZ_DEVICE(PVT,ZWORK,ZMEAN)
+  CALL DZF_DEVICE(1,IKU,1,ZMEAN,ZWORK)
+!$acc kernels
+  PRVS = PRVS - ZWORK
+!$acc end kernels
+!
+! W component
+!
+  !PRWS = PRWS - DXF(UP_MX(PWT,MZM(1,IKU,1,PRUCT)))
+  CALL MZM_DEVICE(PRUCT,ZWORK)
+  CALL UP_MX_DEVICE(PWT,ZWORK,ZMEAN)
+  CALL DXF_DEVICE(ZMEAN,ZWORK)
+!$acc kernels
+  PRWS = PRWS - ZWORK
+!$acc end kernels
+!
+  !PRWS = PRWS - DYF(UP_MY(PWT,MZM(1,IKU,1,PRVCT)))
+  CALL MZM_DEVICE(PRVCT,ZWORK)
+  CALL UP_MY_DEVICE(PWT,ZWORK,ZMEAN)
+  CALL DYF_DEVICE(ZMEAN,ZWORK)
+!$acc kernels
+  PRWS = PRWS - ZWORK
+!$acc end kernels
+!
+  !PRWS = PRWS - DZM(1,IKU,1,UP_WZ(PWT,MZF(1,IKU,1,PRWCT)))
+  CALL MZF_DEVICE(1,IKU,1,PRWCT,ZWORK)
+  CALL UP_WZ_DEVICE(PWT,ZWORK,ZMEAN)
+  CALL DZM_DEVICE(1,IKU,1,ZMEAN,ZWORK)
+!$acc kernels
+  PRWS = PRWS - ZWORK
+!$acc end kernels
+#endif
+!
+!
+CASE(3) ! WENO 3
+#ifndef MNH_OPENACC
+!
+! U component
+!
+  ZWORK = MXF(PRUCT)
+  CALL ADVEC_WENO_K_2_UX(HLBCX, PUT, ZWORK, ZMEAN, TPHALO2_UT%HALO2)
+  PRUS = PRUS - DXM(ZMEAN)
+  
+!   
+  IF (.NOT.L2D) THEN
+    ZWORK = MXM(PRVCT)
+    CALL ADVEC_WENO_K_2_MY(HLBCY, PUT, ZWORK, ZMEAN, TPHALO2_UT%HALO2)
+    PRUS = PRUS - DYF(ZMEAN)
+  END IF
+!
+  PRUS = PRUS - DZF(WENO_K_2_MZ(PUT, MXM(PRWCT)))
+!
+! V component
+!
+  IF (.NOT.L2D) THEN
+    ZWORK = MYM(PRUCT)
+    CALL ADVEC_WENO_K_2_MX(HLBCX, PVT, ZWORK, ZMEAN, TPHALO2_VT%HALO2)
+    PRVS = PRVS - DXF(ZMEAN)
+!   
+    ZWORK = MYF(PRVCT)
+    CALL ADVEC_WENO_K_2_VY(HLBCY, PVT, ZWORK, ZMEAN, TPHALO2_VT%HALO2)
+    PRVS = PRVS - DYM(ZMEAN)
+!
+    PRVS = PRVS - DZF(WENO_K_2_MZ(PVT, MYM(PRWCT)))
+  END IF
+!
+! W component
+!
+  ZWORK = MZM(PRUCT)
+  CALL ADVEC_WENO_K_2_MX(HLBCX, PWT, ZWORK, ZMEAN, TPHALO2_WT%HALO2)
+  PRWS = PRWS - DXF(ZMEAN)
+!
+  IF (.NOT.L2D) THEN
+    ZWORK = MZM(PRVCT)
+    CALL ADVEC_WENO_K_2_MY(HLBCY, PWT, ZWORK, ZMEAN, TPHALO2_WT%HALO2)
+    PRWS = PRWS - DYF(ZMEAN)
+  END IF
+!
+  PRWS = PRWS - DZM(WENO_K_2_WZ(PWT,MZF(PRWCT)))
+#else
+  CALL MNH_GET_ZT3D(IZFPOS1,IZFPOS2,IZFNEG1,IZFNEG2,IZBPOS1,IZBPOS2,IZBNEG1,IZBNEG2,IZOMP1,IZOMP2,IZOMN1,IZOMN2)
+!
+! U component
+!
+  CALL MXF_DEVICE(PRUCT,ZWORK)
+  CALL ADVEC_WENO_K_2_UX(HLBCX, PUT, ZWORK, ZMEAN, TPHALO2_UT%HALO2%WEST, TPHALO2_UT%HALO2%EAST,             &
+                         ZT3D(:,:,:,IZFPOS1), ZT3D(:,:,:,IZFPOS2), ZT3D(:,:,:,IZFNEG1), ZT3D(:,:,:,IZFNEG2), &
+                         ZT3D(:,:,:,IZBPOS1), ZT3D(:,:,:,IZBPOS2), ZT3D(:,:,:,IZBNEG1), ZT3D(:,:,:,IZBNEG2), &
+                         ZT3D(:,:,:,IZOMP1),  ZT3D(:,:,:,IZOMP2),  ZT3D(:,:,:,IZOMN1),  ZT3D(:,:,:,IZOMN2) )
+  CALL DXM_DEVICE(ZMEAN,ZWORK)
+!$acc kernels
+  PRUS = PRUS - ZWORK
+!$acc end kernels
+!   
+  IF (.NOT.L2D) THEN
+    CALL MXM_DEVICE(PRVCT,ZWORK)
+    CALL ADVEC_WENO_K_2_MY(HLBCY, PUT, ZWORK, ZMEAN, TPHALO2_UT%HALO2%NORTH, TPHALO2_UT%HALO2%SOUTH,           &
+                           ZT3D(:,:,:,IZFPOS1), ZT3D(:,:,:,IZFPOS2), ZT3D(:,:,:,IZFNEG1), ZT3D(:,:,:,IZFNEG2), &
+                           ZT3D(:,:,:,IZBPOS1), ZT3D(:,:,:,IZBPOS2), ZT3D(:,:,:,IZBNEG1), ZT3D(:,:,:,IZBNEG2), &
+                           ZT3D(:,:,:,IZOMP1),  ZT3D(:,:,:,IZOMP2),  ZT3D(:,:,:,IZOMN1),  ZT3D(:,:,:,IZOMN2) )
+    CALL DYF_DEVICE(ZMEAN,ZWORK)
+!$acc kernels
+    PRUS = PRUS - ZWORK
+!$acc end kernels
+  END IF
+!
+!  PRUS = PRUS - DZF(1,IKU,1,WENO_K_2_MZ(PUT, MXM(PRWCT)))
+  CALL MXM_DEVICE(PRWCT,ZWORK)
+  CALL WENO_K_2_MZ(PUT, ZWORK, ZMEAN,                                                                  &
+                   ZT3D(:,:,:,IZFPOS1), ZT3D(:,:,:,IZFPOS2), ZT3D(:,:,:,IZFNEG1), ZT3D(:,:,:,IZFNEG2), &
+                   ZT3D(:,:,:,IZBPOS1), ZT3D(:,:,:,IZBPOS2), ZT3D(:,:,:,IZBNEG1), ZT3D(:,:,:,IZBNEG2), &
+                   ZT3D(:,:,:,IZOMP1),  ZT3D(:,:,:,IZOMP2),  ZT3D(:,:,:,IZOMN1),  ZT3D(:,:,:,IZOMN2) )
+  CALL DZF_DEVICE(1,IKU,1,ZMEAN,ZWORK)
+!$acc kernels
+  PRUS = PRUS - ZWORK
+!$acc end kernels
+!
+! V component
+!
+  IF (.NOT.L2D) THEN
+    CALL MYM_DEVICE(PRUCT,ZWORK)
+    CALL ADVEC_WENO_K_2_MX(HLBCX, PVT, ZWORK, ZMEAN, TPHALO2_VT%HALO2%WEST, TPHALO2_VT%HALO2%EAST,             &
+                           ZT3D(:,:,:,IZFPOS1), ZT3D(:,:,:,IZFPOS2), ZT3D(:,:,:,IZFNEG1), ZT3D(:,:,:,IZFNEG2), &
+                           ZT3D(:,:,:,IZBPOS1), ZT3D(:,:,:,IZBPOS2), ZT3D(:,:,:,IZBNEG1), ZT3D(:,:,:,IZBNEG2), &
+                           ZT3D(:,:,:,IZOMP1),  ZT3D(:,:,:,IZOMP2),  ZT3D(:,:,:,IZOMN1),  ZT3D(:,:,:,IZOMN2) )
+    CALL DXF_DEVICE(ZMEAN,ZWORK)
+!$acc kernels
+    PRVS = PRVS - ZWORK
+!$acc end kernels
+!   
+    CALL MYF_DEVICE(PRVCT,ZWORK)
+    CALL ADVEC_WENO_K_2_VY(HLBCY, PVT, ZWORK, ZMEAN, TPHALO2_VT%HALO2%NORTH, TPHALO2_VT%HALO2%SOUTH,           &
+                           ZT3D(:,:,:,IZFPOS1), ZT3D(:,:,:,IZFPOS2), ZT3D(:,:,:,IZFNEG1), ZT3D(:,:,:,IZFNEG2), &
+                           ZT3D(:,:,:,IZBPOS1), ZT3D(:,:,:,IZBPOS2), ZT3D(:,:,:,IZBNEG1), ZT3D(:,:,:,IZBNEG2), &
+                           ZT3D(:,:,:,IZOMP1),  ZT3D(:,:,:,IZOMP2),  ZT3D(:,:,:,IZOMN1),  ZT3D(:,:,:,IZOMN2) )
+    CALL DYM_DEVICE(ZMEAN,ZWORK)
+!$acc kernels
+    PRVS = PRVS - ZWORK
+!$acc end kernels
+!
+!    PRVS = PRVS - DZF(1,IKU,1,WENO_K_2_MZ(PVT, MYM(PRWCT)))
+    CALL MYM_DEVICE(PRWCT,ZWORK)
+    CALL WENO_K_2_MZ(PVT, ZWORK, ZMEAN,                                                                  &
+                     ZT3D(:,:,:,IZFPOS1), ZT3D(:,:,:,IZFPOS2), ZT3D(:,:,:,IZFNEG1), ZT3D(:,:,:,IZFNEG2), &
+                     ZT3D(:,:,:,IZBPOS1), ZT3D(:,:,:,IZBPOS2), ZT3D(:,:,:,IZBNEG1), ZT3D(:,:,:,IZBNEG2), &
+                     ZT3D(:,:,:,IZOMP1),  ZT3D(:,:,:,IZOMP2),  ZT3D(:,:,:,IZOMN1),  ZT3D(:,:,:,IZOMN2) )
+    CALL DZF_DEVICE(1,IKU,1,ZMEAN,ZWORK)
+!$acc kernels
+    PRVS = PRVS - ZWORK
+!$acc end kernels
+  END IF
+!
+! W component
+!
+!  ZWORK = MZM(1,IKU,1,PRUCT)
+  CALL MZM_DEVICE(PRUCT,ZWORK)
+  CALL ADVEC_WENO_K_2_MX(HLBCX, PWT, ZWORK, ZMEAN, TPHALO2_WT%HALO2%WEST, TPHALO2_WT%HALO2%EAST,             &
+                         ZT3D(:,:,:,IZFPOS1), ZT3D(:,:,:,IZFPOS2), ZT3D(:,:,:,IZFNEG1), ZT3D(:,:,:,IZFNEG2), &
+                         ZT3D(:,:,:,IZBPOS1), ZT3D(:,:,:,IZBPOS2), ZT3D(:,:,:,IZBNEG1), ZT3D(:,:,:,IZBNEG2), &
+                         ZT3D(:,:,:,IZOMP1),  ZT3D(:,:,:,IZOMP2),  ZT3D(:,:,:,IZOMN1),  ZT3D(:,:,:,IZOMN2) )
+  CALL DXF_DEVICE(ZMEAN,ZWORK)
+!$acc kernels
+  PRWS = PRWS - ZWORK
+!$acc end kernels
+!
+  IF (.NOT.L2D) THEN
+!    ZWORK = MZM(1,IKU,1,PRVCT)
+    CALL MZM_DEVICE(PRVCT,ZWORK)
+    CALL ADVEC_WENO_K_2_MY(HLBCY, PWT, ZWORK, ZMEAN, TPHALO2_WT%HALO2%NORTH, TPHALO2_WT%HALO2%SOUTH,           &
+                           ZT3D(:,:,:,IZFPOS1), ZT3D(:,:,:,IZFPOS2), ZT3D(:,:,:,IZFNEG1), ZT3D(:,:,:,IZFNEG2), &
+                           ZT3D(:,:,:,IZBPOS1), ZT3D(:,:,:,IZBPOS2), ZT3D(:,:,:,IZBNEG1), ZT3D(:,:,:,IZBNEG2), &
+                           ZT3D(:,:,:,IZOMP1),  ZT3D(:,:,:,IZOMP2),  ZT3D(:,:,:,IZOMN1),  ZT3D(:,:,:,IZOMN2) )
+    CALL DYF_DEVICE(ZMEAN,ZWORK)
+!$acc kernels
+    PRWS = PRWS - ZWORK
+!$acc end kernels
+  END IF
+!
+!  PRWS = PRWS - DZM(1,IKU,1,WENO_K_2_WZ(PWT,MZF(1,IKU,1,PRWCT)))
+  CALL MZF_DEVICE(1,IKU,1,PRWCT,ZWORK)
+  CALL WENO_K_2_WZ(PWT, ZWORK, ZMEAN,                                                                  &
+                   ZT3D(:,:,:,IZFPOS1), ZT3D(:,:,:,IZFPOS2), ZT3D(:,:,:,IZFNEG1), ZT3D(:,:,:,IZFNEG2), &
+                   ZT3D(:,:,:,IZBPOS1), ZT3D(:,:,:,IZBPOS2), ZT3D(:,:,:,IZBNEG1), ZT3D(:,:,:,IZBNEG2), &
+                   ZT3D(:,:,:,IZOMP1),  ZT3D(:,:,:,IZOMP2),  ZT3D(:,:,:,IZOMN1),  ZT3D(:,:,:,IZOMN2) )
+  CALL DZM_DEVICE(1,IKU,1,ZMEAN,ZWORK)
+!$acc kernels
+  PRWS = PRWS - ZWORK
+!$acc end kernels
+!
+  CALL MNH_REL_ZT3D(IZFPOS1,IZFPOS2,IZFNEG1,IZFNEG2,IZBPOS1,IZBPOS2,IZBNEG1,IZBNEG2,IZOMP1,IZOMP2,IZOMN1,IZOMN2)
+#endif
+!
+!
+CASE(5) ! WENO 5
+#ifndef MNH_OPENACC
+!
+! U component
+!
+  ZWORK = MXF(PRUCT)
+  CALL ADVEC_WENO_K_3_UX(HLBCX, PUT, ZWORK, ZMEAN) 
+  CALL GET_HALO(ZMEAN)! Update HALO 
+  PRUS = PRUS - DXM(ZMEAN)
+!
+  IF (.NOT.L2D) THEN! 3D Case
+   ZWORK = MXM(PRVCT)     
+   CALL ADVEC_WENO_K_3_MY(HLBCY, PUT, ZWORK, ZMEAN)
+   CALL GET_HALO(ZMEAN)! Update HALO 
+   PRUS = PRUS - DYF(ZMEAN)
+  END IF
+!
+  ZMEAN = WENO_K_3_MZ(PUT, MXM(PRWCT))
+  CALL GET_HALO(ZMEAN)! Update HALO - maybe not necessary (T.Lunet)
+  PRUS = PRUS - DZF(ZMEAN)
+!
+! V component, only called in 3D case
+!
+  IF (.NOT.L2D) THEN
+!
+    ZWORK = MYM(PRUCT)
+    CALL ADVEC_WENO_K_3_MX(HLBCX, PVT, ZWORK, ZMEAN) 
+    CALL GET_HALO(ZMEAN)! Update HALO 
+    PRVS = PRVS - DXF(ZMEAN)
+!
+    ZWORK = MYF(PRVCT)
+    CALL ADVEC_WENO_K_3_VY(HLBCY, PVT, ZWORK, ZMEAN)
+    CALL GET_HALO(ZMEAN)! Update HALO 
+    PRVS = PRVS - DYM(ZMEAN)
+!
+    ZMEAN = WENO_K_3_MZ(PVT, MYM(PRWCT))
+    CALL GET_HALO(ZMEAN)! Update HALO - maybe not necessary (T.Lunet)
+    PRVS = PRVS - DZF(ZMEAN)
+!
+  END IF
+!
+! W component
+!
+  ZWORK = MZM(PRUCT)
+  CALL ADVEC_WENO_K_3_MX(HLBCX, PWT, ZWORK, ZMEAN)
+  CALL GET_HALO(ZMEAN)! Update HALO
+  PRWS = PRWS - DXF(ZMEAN)
+!
+  IF (.NOT.L2D) THEN! 3D Case
+    ZWORK = MZM(PRVCT)
+    CALL ADVEC_WENO_K_3_MY(HLBCY, PWT, ZWORK, ZMEAN)
+    CALL GET_HALO(ZMEAN)! Update HALO
+    PRWS = PRWS - DYF(ZMEAN)
+  END IF
+!
+  ZMEAN = WENO_K_3_WZ(PWT,MZF(PRWCT))
+  CALL GET_HALO(ZMEAN)! Update HALO - maybe not necessary (T.Lunet)
+  PRWS = PRWS - DZM(ZMEAN)
+#else
+  CALL MNH_GET_ZT3D(IZFPOS1,IZFPOS2,IZFPOS3,IZFNEG1,IZFNEG2,IZFNEG3,IZBPOS1, &
+                    IZBPOS2,IZBPOS3,IZBNEG1,IZBNEG2,IZBNEG3,IZOMP1,IZOMP2,IZOMP3,IZOMN1,IZOMN2,IZOMN3)
+!
+! U component
+!
+  CALL MXF_DEVICE(PRUCT,ZWORK)
+  CALL ADVEC_WENO_K_3_UX(HLBCX, PUT, ZWORK, ZMEAN, &
+                         ZT3D(:,:,:,IZFPOS1), ZT3D(:,:,:,IZFPOS2), ZT3D(:,:,:,IZFPOS3), &
+                         ZT3D(:,:,:,IZFNEG1), ZT3D(:,:,:,IZFNEG2), ZT3D(:,:,:,IZFNEG3), &
+                         ZT3D(:,:,:,IZBPOS1), ZT3D(:,:,:,IZBPOS2), ZT3D(:,:,:,IZBPOS3), &
+                         ZT3D(:,:,:,IZBNEG1), ZT3D(:,:,:,IZBNEG2), ZT3D(:,:,:,IZBNEG3), &
+                         ZT3D(:,:,:,IZOMP1),  ZT3D(:,:,:,IZOMP2),  ZT3D(:,:,:,IZOMP3),  &
+                         ZT3D(:,:,:,IZOMN1),  ZT3D(:,:,:,IZOMN2),  ZT3D(:,:,:,IZOMN3) )
+  CALL GET_HALO_D(ZMEAN)! Update HALO 
+  CALL DXM_DEVICE(ZMEAN,ZWORK)
+!$acc kernels
+  PRUS = PRUS - ZWORK
+!$acc end kernels
+!   
+  IF (.NOT.L2D) THEN
+    CALL MXM_DEVICE(PRVCT,ZWORK)
+    CALL ADVEC_WENO_K_3_MY(HLBCY, PUT, ZWORK, ZMEAN, &
+                           ZT3D(:,:,:,IZFPOS1), ZT3D(:,:,:,IZFPOS2), ZT3D(:,:,:,IZFPOS3), &
+                           ZT3D(:,:,:,IZFNEG1), ZT3D(:,:,:,IZFNEG2), ZT3D(:,:,:,IZFNEG3), &
+                           ZT3D(:,:,:,IZBPOS1), ZT3D(:,:,:,IZBPOS2), ZT3D(:,:,:,IZBPOS3), &
+                           ZT3D(:,:,:,IZBNEG1), ZT3D(:,:,:,IZBNEG2), ZT3D(:,:,:,IZBNEG3), &
+                           ZT3D(:,:,:,IZOMP1),  ZT3D(:,:,:,IZOMP2),  ZT3D(:,:,:,IZOMP3),  &
+                           ZT3D(:,:,:,IZOMN1),  ZT3D(:,:,:,IZOMN2),  ZT3D(:,:,:,IZOMN3) )
+    CALL GET_HALO_D(ZMEAN)! Update HALO 
+    CALL DYF_DEVICE(ZMEAN,ZWORK)
+!$acc kernels
+    PRUS = PRUS - ZWORK
+!$acc end kernels
+  END IF
+!
+  CALL MXM_DEVICE(PRWCT,ZWORK)
+  CALL WENO_K_3_MZ(PUT,ZWORK,ZMEAN, &
+                   ZT3D(:,:,:,IZFPOS1), ZT3D(:,:,:,IZFPOS2), ZT3D(:,:,:,IZFPOS3), &
+                   ZT3D(:,:,:,IZFNEG1), ZT3D(:,:,:,IZFNEG2), ZT3D(:,:,:,IZFNEG3), &
+                   ZT3D(:,:,:,IZBPOS1), ZT3D(:,:,:,IZBPOS2), ZT3D(:,:,:,IZBPOS3), &
+                   ZT3D(:,:,:,IZBNEG1), ZT3D(:,:,:,IZBNEG2), ZT3D(:,:,:,IZBNEG3), &
+                   ZT3D(:,:,:,IZOMP1),  ZT3D(:,:,:,IZOMP2),  ZT3D(:,:,:,IZOMP3),  &
+                   ZT3D(:,:,:,IZOMN1),  ZT3D(:,:,:,IZOMN2),  ZT3D(:,:,:,IZOMN3) )
+  CALL GET_HALO_D(ZMEAN)! Update HALO - maybe not necessary (T.Lunet)
+  CALL DZF_DEVICE(1,IKU,1,ZMEAN,ZWORK)
+!$acc kernels
+  PRUS = PRUS - ZWORK
+!$acc end kernels
+!
+! V component
+!
+  IF (.NOT.L2D) THEN
+    CALL MYM_DEVICE(PRUCT,ZWORK)
+    CALL ADVEC_WENO_K_3_MX(HLBCX, PVT, ZWORK, ZMEAN, &
+                           ZT3D(:,:,:,IZFPOS1), ZT3D(:,:,:,IZFPOS2), ZT3D(:,:,:,IZFPOS3), &
+                           ZT3D(:,:,:,IZFNEG1), ZT3D(:,:,:,IZFNEG2), ZT3D(:,:,:,IZFNEG3), &
+                           ZT3D(:,:,:,IZBPOS1), ZT3D(:,:,:,IZBPOS2), ZT3D(:,:,:,IZBPOS3), &
+                           ZT3D(:,:,:,IZBNEG1), ZT3D(:,:,:,IZBNEG2), ZT3D(:,:,:,IZBNEG3), &
+                           ZT3D(:,:,:,IZOMP1),  ZT3D(:,:,:,IZOMP2),  ZT3D(:,:,:,IZOMP3),  &
+                           ZT3D(:,:,:,IZOMN1),  ZT3D(:,:,:,IZOMN2),  ZT3D(:,:,:,IZOMN3) )
+    CALL GET_HALO_D(ZMEAN)! Update HALO 
+    CALL DXF_DEVICE(ZMEAN,ZWORK)
+!$acc kernels
+    PRVS = PRVS - ZWORK
+!$acc end kernels
+!   
+    CALL MYF_DEVICE(PRVCT,ZWORK)
+    CALL ADVEC_WENO_K_3_VY(HLBCY, PVT, ZWORK, ZMEAN, &
+                           ZT3D(:,:,:,IZFPOS1), ZT3D(:,:,:,IZFPOS2), ZT3D(:,:,:,IZFPOS3), &
+                           ZT3D(:,:,:,IZFNEG1), ZT3D(:,:,:,IZFNEG2), ZT3D(:,:,:,IZFNEG3), &
+                           ZT3D(:,:,:,IZBPOS1), ZT3D(:,:,:,IZBPOS2), ZT3D(:,:,:,IZBPOS3), &
+                           ZT3D(:,:,:,IZBNEG1), ZT3D(:,:,:,IZBNEG2), ZT3D(:,:,:,IZBNEG3), &
+                           ZT3D(:,:,:,IZOMP1),  ZT3D(:,:,:,IZOMP2),  ZT3D(:,:,:,IZOMP3),  &
+                           ZT3D(:,:,:,IZOMN1),  ZT3D(:,:,:,IZOMN2),  ZT3D(:,:,:,IZOMN3) )
+    CALL GET_HALO_D(ZMEAN)! Update HALO 
+    CALL DYM_DEVICE(ZMEAN,ZWORK)
+!$acc kernels
+    PRVS = PRVS - ZWORK
+!$acc end kernels
+!
+    CALL MYM_DEVICE(PRWCT,ZWORK)
+    CALL WENO_K_3_MZ(PVT,ZWORK,ZMEAN, &
+                     ZT3D(:,:,:,IZFPOS1), ZT3D(:,:,:,IZFPOS2), ZT3D(:,:,:,IZFPOS3), &
+                     ZT3D(:,:,:,IZFNEG1), ZT3D(:,:,:,IZFNEG2), ZT3D(:,:,:,IZFNEG3), &
+                     ZT3D(:,:,:,IZBPOS1), ZT3D(:,:,:,IZBPOS2), ZT3D(:,:,:,IZBPOS3), &
+                     ZT3D(:,:,:,IZBNEG1), ZT3D(:,:,:,IZBNEG2), ZT3D(:,:,:,IZBNEG3), &
+                     ZT3D(:,:,:,IZOMP1),  ZT3D(:,:,:,IZOMP2),  ZT3D(:,:,:,IZOMP3),  &
+                     ZT3D(:,:,:,IZOMN1),  ZT3D(:,:,:,IZOMN2),  ZT3D(:,:,:,IZOMN3) )
+    CALL GET_HALO_D(ZMEAN)! Update HALO - maybe not necessary (T.Lunet)
+    CALL DZF_DEVICE(1,IKU,1,ZMEAN,ZWORK)
+!$acc kernels
+    PRVS = PRVS - ZWORK
+!$acc end kernels
+  END IF
+!
+! W component
+!
+  CALL MZM_DEVICE(PRUCT,ZWORK)
+  CALL ADVEC_WENO_K_3_MX(HLBCX, PWT, ZWORK, ZMEAN, &
+                         ZT3D(:,:,:,IZFPOS1), ZT3D(:,:,:,IZFPOS2), ZT3D(:,:,:,IZFPOS3), &
+                         ZT3D(:,:,:,IZFNEG1), ZT3D(:,:,:,IZFNEG2), ZT3D(:,:,:,IZFNEG3), &
+                         ZT3D(:,:,:,IZBPOS1), ZT3D(:,:,:,IZBPOS2), ZT3D(:,:,:,IZBPOS3), &
+                         ZT3D(:,:,:,IZBNEG1), ZT3D(:,:,:,IZBNEG2), ZT3D(:,:,:,IZBNEG3), &
+                         ZT3D(:,:,:,IZOMP1),  ZT3D(:,:,:,IZOMP2),  ZT3D(:,:,:,IZOMP3),  &
+                         ZT3D(:,:,:,IZOMN1),  ZT3D(:,:,:,IZOMN2),  ZT3D(:,:,:,IZOMN3) )
+  CALL GET_HALO_D(ZMEAN)! Update HALO 
+  CALL DXF_DEVICE(ZMEAN,ZWORK)
+!$acc kernels
+  PRWS = PRWS - ZWORK
+!$acc end kernels
+!
+  IF (.NOT.L2D) THEN
+  CALL MZM_DEVICE(PRVCT,ZWORK)
+    CALL ADVEC_WENO_K_3_MY(HLBCY, PWT, ZWORK, ZMEAN, &
+                           ZT3D(:,:,:,IZFPOS1), ZT3D(:,:,:,IZFPOS2), ZT3D(:,:,:,IZFPOS3), &
+                           ZT3D(:,:,:,IZFNEG1), ZT3D(:,:,:,IZFNEG2), ZT3D(:,:,:,IZFNEG3), &
+                           ZT3D(:,:,:,IZBPOS1), ZT3D(:,:,:,IZBPOS2), ZT3D(:,:,:,IZBPOS3), &
+                           ZT3D(:,:,:,IZBNEG1), ZT3D(:,:,:,IZBNEG2), ZT3D(:,:,:,IZBNEG3), &
+                           ZT3D(:,:,:,IZOMP1),  ZT3D(:,:,:,IZOMP2),  ZT3D(:,:,:,IZOMP3),  &
+                           ZT3D(:,:,:,IZOMN1),  ZT3D(:,:,:,IZOMN2),  ZT3D(:,:,:,IZOMN3) )
+    CALL GET_HALO_D(ZMEAN)! Update HALO 
+    CALL DYF_DEVICE(ZMEAN,ZWORK)
+!$acc kernels
+    PRWS = PRWS - ZWORK
+!$acc end kernels
+  END IF
+!
+  CALL MZF_DEVICE(1,IKU,1,PRWCT,ZWORK)
+  CALL WENO_K_3_WZ(PWT,ZWORK,ZMEAN, &
+                   ZT3D(:,:,:,IZFPOS1), ZT3D(:,:,:,IZFPOS2), ZT3D(:,:,:,IZFPOS3), &
+                   ZT3D(:,:,:,IZFNEG1), ZT3D(:,:,:,IZFNEG2), ZT3D(:,:,:,IZFNEG3), &
+                   ZT3D(:,:,:,IZBPOS1), ZT3D(:,:,:,IZBPOS2), ZT3D(:,:,:,IZBPOS3), &
+                   ZT3D(:,:,:,IZBNEG1), ZT3D(:,:,:,IZBNEG2), ZT3D(:,:,:,IZBNEG3), &
+                   ZT3D(:,:,:,IZOMP1),  ZT3D(:,:,:,IZOMP2),  ZT3D(:,:,:,IZOMP3),  &
+                   ZT3D(:,:,:,IZOMN1),  ZT3D(:,:,:,IZOMN2),  ZT3D(:,:,:,IZOMN3) )
+  CALL GET_HALO_D(ZMEAN)! Update HALO - maybe not necessary (T.Lunet)
+  CALL DZM_DEVICE(1,IKU,1,ZMEAN,ZWORK)
+!$acc kernels
+  PRWS = PRWS - ZWORK
+!$acc end kernels
+!
+  CALL MNH_REL_ZT3D(IZFPOS1,IZFPOS2,IZFPOS3,IZFNEG1,IZFNEG2,IZFNEG3,IZBPOS1, &
+                    IZBPOS2,IZBPOS3,IZBNEG1,IZBNEG2,IZBNEG3,IZOMP1,IZOMP2,IZOMP3,IZOMN1,IZOMN2,IZOMN3)
+#endif
+!
+!
+END SELECT
+!             ---------------------------------
+!$acc update self(PRUS,PRVS,PRWS)
+!
+IF (MPPDB_INITIALIZED) THEN
+  CALL MPPDB_CHECK(PRUS,"ADVECUVW_WENO_K end:PRUS")
+  CALL MPPDB_CHECK(PRVS,"ADVECUVW_WENO_K end:PRVS")
+  CALL MPPDB_CHECK(PRWS,"ADVECUVW_WENO_K end:PRWS")
+END IF
+
+!$acc end data
+
+END SUBROUTINE ADVECUVW_WENO_K
diff --git a/src/ZSOLVER/contrav.f90 b/src/ZSOLVER/contrav.f90
index ebef79590bb7b5f6faa48cb6a8a680d0525a4f3e..97df82096f4d57928bc287dce6eaf863ea163fa5 100644
--- a/src/ZSOLVER/contrav.f90
+++ b/src/ZSOLVER/contrav.f90
@@ -567,7 +567,8 @@ LOGICAL                             :: GDATA_ON_DEVICE
 real                                :: ZTMP1, ZTMP2 ! Intermediate work variables
 REAL,   DIMENSION(:,:), POINTER , CONTIGUOUS :: ZU_EAST, ZV_NORTH, ZDZX_EAST, ZDZY_NORTH
 TYPE(LIST_ll),          POINTER     :: TZFIELD_U, TZFIELD_V, TZFIELD_DZX, TZFIELD_DZY
-TYPE(HALO2LIST_ll),     POINTER     :: TZHALO2_U, TZHALO2_V, TZHALO2_DZX, TZHALO2_DZY
+TYPE(HALO2LIST_ll), SAVE, POINTER  :: TZHALO2_U, TZHALO2_V, TZHALO2_DZX, TZHALO2_DZY
+LOGICAL , SAVE :: GFIRST_CALL_CONTRAV_DEVICE = .TRUE.
 !
 LOGICAL :: GWEST,GEAST,GSOUTH,GNORTH
 !
@@ -634,23 +635,26 @@ IF (KADV_ORDER == 4 ) THEN
 !!$  NULLIFY(TZFIELD_DZY)
 !!$  CALL ADD3DFIELD_ll( TZFIELD_DZX, PDZX, 'CONTRAV::PDZX' )
 !!$  CALL ADD3DFIELD_ll( TZFIELD_DZY, PDZY, 'CONTRAV::PDZY' )
-!!$  NULLIFY(TZHALO2_U)
-!!$  NULLIFY(TZHALO2_V)
-!!$  NULLIFY(TZHALO2_DZX)
-!!$  NULLIFY(TZHALO2_DZY)
-!!$  CALL INIT_HALO2_ll(TZHALO2_U,1,IIU,IJU,IKU)
-!!$  CALL INIT_HALO2_ll(TZHALO2_V,1,IIU,IJU,IKU)
-!!$  CALL INIT_HALO2_ll(TZHALO2_DZX,1,IIU,IJU,IKU)
-!!$  CALL INIT_HALO2_ll(TZHALO2_DZY,1,IIU,IJU,IKU)
+    IF ( GFIRST_CALL_CONTRAV_DEVICE ) THEN
+       GFIRST_CALL_CONTRAV_DEVICE = .FALSE.
+       NULLIFY(TZHALO2_U)
+       NULLIFY(TZHALO2_V)
+       NULLIFY(TZHALO2_DZX)
+       NULLIFY(TZHALO2_DZY)
+       CALL INIT_HALO2_ll(TZHALO2_U,1,IIU,IJU,IKU)
+       CALL INIT_HALO2_ll(TZHALO2_V,1,IIU,IJU,IKU)
+       CALL INIT_HALO2_ll(TZHALO2_DZX,1,IIU,IJU,IKU)
+       CALL INIT_HALO2_ll(TZHALO2_DZY,1,IIU,IJU,IKU)
+    END IF
 !!$  CALL UPDATE_HALO2_ll(TZFIELD_U, TZHALO2_U, IINFO_ll)
 !!$  CALL UPDATE_HALO2_ll(TZFIELD_V, TZHALO2_V, IINFO_ll)
 !!$  CALL UPDATE_HALO2_ll(TZFIELD_DZX, TZHALO2_DZX, IINFO_ll)
 !!$  CALL UPDATE_HALO2_ll(TZFIELD_DZY, TZHALO2_DZY, IINFO_ll)
   !
-  CALL GET_HALO2_D(PRUCT,TZHALO2_U,'CONTRAV::PRUCT')
-  CALL GET_HALO2_D(PRVCT,TZHALO2_V,'CONTRAV::PRVCT')
-  CALL GET_HALO2_D(PDZX,TZHALO2_DZX,'CONTRAV::PDZX')
-  CALL GET_HALO2_D(PDZY,TZHALO2_DZY,'CONTRAV::PDZY')
+  CALL GET_HALO2_DF(PRUCT,TZHALO2_U,'CONTRAV::PRUCT')
+  CALL GET_HALO2_DF(PRVCT,TZHALO2_V,'CONTRAV::PRVCT')
+  CALL GET_HALO2_DF(PDZX,TZHALO2_DZX,'CONTRAV::PDZX')
+  CALL GET_HALO2_DF(PDZY,TZHALO2_DZY,'CONTRAV::PDZY')
   
 !!$!$acc update device(PRUCT,PRVCT)
 !!$ !!$ END IF
@@ -874,10 +878,10 @@ IF (KADV_ORDER == 4 ) THEN
 !!$ !!$  IF (NHALO==1) THEN
 !!$    CALL CLEANLIST_ll(TZFIELD_DZX)
 !!$    CALL CLEANLIST_ll(TZFIELD_DZY)
-    CALL DEL_HALO2_ll(TZHALO2_U)
-    CALL DEL_HALO2_ll(TZHALO2_V)
-    CALL DEL_HALO2_ll(TZHALO2_DZX)
-    CALL DEL_HALO2_ll(TZHALO2_DZY)
+!!$    CALL DEL_HALO2_ll(TZHALO2_U)
+!!$    CALL DEL_HALO2_ll(TZHALO2_V)
+!!$    CALL DEL_HALO2_ll(TZHALO2_DZX)
+!!$    CALL DEL_HALO2_ll(TZHALO2_DZY)
 !!$ !!$  END IF
 END IF
 
diff --git a/src/ZSOLVER/get_halo.f90 b/src/ZSOLVER/get_halo.f90
index 784b664f64a3842ce6a230d8fad1f047258b2fa3..7dec4456cba761f8600a66e3bdf78a86b3c860de 100644
--- a/src/ZSOLVER/get_halo.f90
+++ b/src/ZSOLVER/get_halo.f90
@@ -63,6 +63,19 @@ INTERFACE
      !
    END SUBROUTINE GET_HALO2_DD
 END INTERFACE
+INTERFACE
+   SUBROUTINE GET_HALO2_DF(PSRC, TP_PSRC_HALO2_ll, HNAME)
+     !
+     USE MODD_ARGSLIST_ll, ONLY : HALO2LIST_ll
+     !
+     IMPLICIT NONE
+     !
+     REAL, DIMENSION(:,:,:), INTENT(INOUT)  :: PSRC    ! variable at t
+     TYPE(HALO2LIST_ll), POINTER         :: TP_PSRC_HALO2_ll          ! halo2 for SRC
+     character(len=*), optional, intent(in) :: HNAME ! Name of the field to be added
+     !
+   END SUBROUTINE GET_HALO2_DF
+END INTERFACE
 INTERFACE
    SUBROUTINE GET_HALO_D(PSRC, HDIR, HNAME)
      IMPLICIT NONE
@@ -104,6 +117,36 @@ INTERFACE
      !
    END SUBROUTINE GET_HALO_DD
 END INTERFACE
+INTERFACE
+   SUBROUTINE GET_HALO_DDC(PSRC, HDIR, HNAME)
+     IMPLICIT NONE
+     !
+     REAL, DIMENSION(:,:,:), INTENT(INOUT)   :: PSRC    ! variable at t
+     CHARACTER(len=4), OPTIONAL :: HDIR ! to send only halo on X or Y direction
+     character(len=*), optional, intent(in) :: HNAME ! Name of the field to be added
+     !
+   END SUBROUTINE GET_HALO_DDC
+END INTERFACE
+INTERFACE
+   SUBROUTINE GET_2D_HALO_DD(PSRC, HDIR, HNAME)
+     IMPLICIT NONE
+     !
+     REAL, DIMENSION(:,:), INTENT(INOUT)   :: PSRC    ! variable at t
+     CHARACTER(len=4), OPTIONAL :: HDIR ! to send only halo on X or Y direction
+     character(len=*), optional, intent(in) :: HNAME ! Name of the field to be added
+     !
+   END SUBROUTINE GET_2D_HALO_DD
+END INTERFACE
+INTERFACE
+   SUBROUTINE GET_2D_HALO_DDC(PSRC, HDIR, HNAME)
+     IMPLICIT NONE
+     !
+     REAL, DIMENSION(:,:), INTENT(INOUT)   :: PSRC    ! variable at t
+     CHARACTER(len=4), OPTIONAL :: HDIR ! to send only halo on X or Y direction
+     character(len=*), optional, intent(in) :: HNAME ! Name of the field to be added
+     !
+   END SUBROUTINE GET_2D_HALO_DDC
+END INTERFACE
 #endif
 !
 INTERFACE
@@ -202,14 +245,27 @@ MODULE MODD_HALO_D
   REAL, SAVE , ALLOCATABLE, DIMENSION(:,:,:)  :: ZNORTH_IN, ZSOUTH_IN, ZWEST_IN, ZEAST_IN
   REAL, SAVE , ALLOCATABLE, DIMENSION(:,:,:)  :: ZNORTH_OUT, ZSOUTH_OUT, ZWEST_OUT, ZEAST_OUT
 
+  REAL, SAVE , ALLOCATABLE, DIMENSION(:,:,:)  :: ZNORTHC_IN, ZSOUTHC_IN, ZWESTC_IN, ZEASTC_IN
+  REAL, SAVE , ALLOCATABLE, DIMENSION(:,:,:)  :: ZNORTHC_OUT, ZSOUTHC_OUT, ZWESTC_OUT, ZEASTC_OUT 
+
   REAL, SAVE , ALLOCATABLE, DIMENSION(:,:)  :: ZNORTH2_IN, ZSOUTH2_IN, ZWEST2_IN, ZEAST2_IN
   REAL, SAVE , ALLOCATABLE, DIMENSION(:,:)  :: ZNORTH2_OUT, ZSOUTH2_OUT, ZWEST2_OUT, ZEAST2_OUT
-  
+
+  REAL, SAVE , ALLOCATABLE, DIMENSION(:,:)  :: ZNORTH_2D_IN, ZSOUTH_2D_IN, ZWEST_2D_IN, ZEAST_2D_IN
+  REAL, SAVE , ALLOCATABLE, DIMENSION(:,:)  :: ZNORTH_2D_OUT, ZSOUTH_2D_OUT, ZWEST_2D_OUT, ZEAST_2D_OUT
+
+  REAL, SAVE , ALLOCATABLE, DIMENSION(:,:)  :: ZNORTHC_2D_IN, ZSOUTHC_2D_IN, ZWESTC_2D_IN, ZEASTC_2D_IN
+  REAL, SAVE , ALLOCATABLE, DIMENSION(:,:)  :: ZNORTHC_2D_OUT, ZSOUTHC_2D_OUT, ZWESTC_2D_OUT, ZEASTC_2D_OUT
+
+  REAL, SAVE , ALLOCATABLE, DIMENSION(:,:,:)  :: ZNORTH2F_IN, ZSOUTH2F_IN, ZWEST2F_IN, ZEAST2F_IN
+  REAL, SAVE , ALLOCATABLE, DIMENSION(:,:,:)  :: ZNORTH2F_OUT, ZSOUTH2F_OUT, ZWEST2F_OUT, ZEAST2F_OUT  
+    
   LOGICAL, SAVE                               :: GFIRST_GET_HALO_D = .TRUE.
   
   LOGICAL, SAVE     :: GFIRST_INIT_HALO_D = .TRUE.
   INTEGER, SAVE     :: IHALO_1  
   INTEGER, SAVE     :: NP_NORTH,NP_SOUTH,NP_WEST,NP_EAST
+  INTEGER, SAVE     :: IHALO2,IHALO2_1
 
 CONTAINS
   
@@ -227,7 +283,9 @@ CONTAINS
 
     IF (GFIRST_INIT_HALO_D) THEN 
        !
-       IHALO_1 = NHALO-1
+       IHALO_1  = NHALO-1
+       IHALO2   = MAX(2,NHALO)
+       IHALO2_1 = IHALO2-1
        !
        !  Init HALO
        !
@@ -243,6 +301,20 @@ CONTAINS
        ALLOCATE  ( ZEAST_OUT  ( IIE+1:IIU ,   IJB:IJE   , IKU ) )
        !$acc enter data create (ZNORTH_OUT, ZSOUTH_OUT, ZWEST_OUT, ZEAST_OUT)
        !
+       !  Init HALO with Corner
+       !
+       ALLOCATE  ( ZSOUTHC_IN (   1:IIU   , IJB:IJB+IHALO_1   , IKU ) )
+       ALLOCATE  ( ZNORTHC_IN (   1:IIU   , IJE-IHALO_1:IJE   , IKU ) )
+       ALLOCATE  ( ZWESTC_IN  ( IIB:IIB+IHALO_1   , IJB:IJE   , IKU ) )
+       ALLOCATE  ( ZEASTC_IN  ( IIE-IHALO_1:IIE   , IJB:IJE   , IKU ) )
+       !$acc enter data create (ZNORTHC_IN, ZSOUTHC_IN, ZWESTC_IN, ZEASTC_IN)
+       !
+       ALLOCATE  ( ZSOUTHC_OUT (   1:IIU   , 1:IJB-1 , IKU ) )
+       ALLOCATE  ( ZNORTHC_OUT (   1:IIU   , IJE+1:IJU , IKU ) )
+       ALLOCATE  ( ZWESTC_OUT  ( 1:IIB-1 ,   IJB:IJE   , IKU ) )
+       ALLOCATE  ( ZEASTC_OUT  ( IIE+1:IIU ,   IJB:IJE   , IKU ) )
+       !$acc enter data create (ZNORTHC_OUT, ZSOUTHC_OUT, ZWESTC_OUT, ZEASTC_OUT)       
+       !
        !  Init HALO2
        !
        ALLOCATE  ( ZSOUTH2_IN ( IIU , IKU ) )
@@ -255,8 +327,50 @@ CONTAINS
        ALLOCATE  ( ZNORTH2_OUT ( IIU , IKU ) )
        ALLOCATE  ( ZWEST2_OUT  ( IJU , IKU ) )
        ALLOCATE  ( ZEAST2_OUT  ( IJU , IKU ) )
-       !$acc enter data create (ZNORTH2_OUT, ZSOUTH2_OUT, ZWEST2_OUT, ZEAST2_OUT)       
-
+       !$acc enter data create (ZNORTH2_OUT, ZSOUTH2_OUT, ZWEST2_OUT, ZEAST2_OUT)
+       !
+       !  Init HALO_2D
+       !
+       ALLOCATE  ( ZSOUTH_2D_IN ( IIB:IIE   , IJB:IJB+IHALO_1  ) )
+       ALLOCATE  ( ZNORTH_2D_IN ( IIB:IIE   , IJE-IHALO_1:IJE  ) )
+       ALLOCATE  ( ZWEST_2D_IN  ( IIB:IIB+IHALO_1   , IJB:IJE  ) )
+       ALLOCATE  ( ZEAST_2D_IN  ( IIE-IHALO_1:IIE   , IJB:IJE  ) )
+       !$acc enter data create (ZNORTH_2D_IN, ZSOUTH_2D_IN, ZWEST_2D_IN, ZEAST_2D_IN)
+       !
+       ALLOCATE  ( ZSOUTH_2D_OUT (   IIB:IIE   , 1:IJB-1) )
+       ALLOCATE  ( ZNORTH_2D_OUT (   IIB:IIE   , IJE+1:IJU) )
+       ALLOCATE  ( ZWEST_2D_OUT  ( 1:IIB-1 ,   IJB:IJE  ) )
+       ALLOCATE  ( ZEAST_2D_OUT  ( IIE+1:IIU ,   IJB:IJE  ) )
+       !$acc enter data create (ZNORTH_2D_OUT, ZSOUTH_2D_OUT, ZWEST_2D_OUT, ZEAST_2D_OUT)
+       !
+       !  Init HALO 2D with Corner
+       !
+       ALLOCATE  ( ZSOUTHC_2D_IN (   1:IIU   , IJB:IJB+IHALO_1   ) )
+       ALLOCATE  ( ZNORTHC_2D_IN (   1:IIU   , IJE-IHALO_1:IJE   ) )
+       ALLOCATE  ( ZWESTC_2D_IN  ( IIB:IIB+IHALO_1   , IJB:IJE   ) )
+       ALLOCATE  ( ZEASTC_2D_IN  ( IIE-IHALO_1:IIE   , IJB:IJE   ) )
+       !$acc enter data create (ZNORTHC_2D_IN, ZSOUTHC_2D_IN, ZWESTC_2D_IN, ZEASTC_2D_IN)
+       !
+       ALLOCATE  ( ZSOUTHC_2D_OUT (   1:IIU   , 1:IJB-1 ) )
+       ALLOCATE  ( ZNORTHC_2D_OUT (   1:IIU   , IJE+1:IJU ) )
+       ALLOCATE  ( ZWESTC_2D_OUT  ( 1:IIB-1 ,   IJB:IJE   ) )
+       ALLOCATE  ( ZEASTC_2D_OUT  ( IIE+1:IIU ,   IJB:IJE   ) )
+       !$acc enter data create (ZNORTHC_2D_OUT, ZSOUTHC_2D_OUT, ZWESTC_2D_OUT, ZEASTC_2D_OUT)
+       !
+       !  Init HALO2 for Full update in 1 time <-> GET_HALO + GET_HALO2 
+       !
+       ALLOCATE  ( ZSOUTH2F_IN ( IIB:IIE   , IJB:IJB+IHALO2_1   , IKU ) )
+       ALLOCATE  ( ZNORTH2F_IN ( IIB:IIE   , IJE-IHALO2_1:IJE   , IKU ) )
+       ALLOCATE  ( ZWEST2F_IN  ( IIB:IIB+IHALO2_1   , IJB:IJE   , IKU ) )
+       ALLOCATE  ( ZEAST2F_IN  ( IIE-IHALO2_1:IIE   , IJB:IJE   , IKU ) )
+       !$acc enter data create (ZNORTH2F_IN, ZSOUTH2F_IN, ZWEST2F_IN, ZEAST2F_IN)
+       !
+       ALLOCATE  ( ZSOUTH2F_OUT (   IIB:IIE   , IJB-IHALO2:IJB-1 , IKU ) )
+       ALLOCATE  ( ZNORTH2F_OUT (   IIB:IIE   , IJE+1:IJE+IHALO2 , IKU ) )
+       ALLOCATE  ( ZWEST2F_OUT  ( IIB-IHALO2:IIB-1 ,   IJB:IJE   , IKU ) )
+       ALLOCATE  ( ZEAST2F_OUT  ( IIE+1:IIE+IHALO2 ,   IJB:IJE   , IKU ) )
+       !$acc enter data create (ZNORTH2F_OUT, ZSOUTH2F_OUT, ZWEST2F_OUT, ZEAST2F_OUT)
+       
        IF (.NOT. GWEST ) THEN
           NP_WEST = ( IP-1 -1 ) + 1
        ELSE
@@ -891,10 +1005,8 @@ END IF
 !$acc end data
 
 END SUBROUTINE GET_HALO_DD
-
-!-------------------------------------------------------------------------------
 !     ########################################
-      SUBROUTINE GET_HALO2_DD(PSRC, TP_PSRC_HALO2_ll, HNAME)
+      SUBROUTINE GET_2D_HALO_DD(PSRC, HDIR, HNAME)
 !     ########################################
 #define MNH_GPUDIRECT
 !
@@ -905,25 +1017,27 @@ USE MODD_PARAMETERS, ONLY : JPHEXT
 !
 USE MODD_IO,        ONLY : GSMONOPROC
 USE MODE_MNH_ZWORK, ONLY : GWEST , GEAST, GSOUTH , GNORTH
-USE MODE_MNH_ZWORK, ONLY : IIU,IJU,IKU
-USE MODE_MNH_ZWORK, ONLY : IIB,IJB ,IIE,IJE
 !
 USE MODD_CONF, ONLY : NHALO
 USE MODE_DEVICE
 USE MODE_MPPDB
-!
-USE MODD_VAR_ll,     ONLY : IP,NPROC,NP1,NP2
-USE MODD_VAR_ll,     ONLY : NMNH_COMM_WORLD
-USE MODD_MPIF,       ONLY : MPI_STATUSES_IGNORE
+
+USE MODD_VAR_ll, ONLY    : IP,NPROC,NP1,NP2
+USE MODD_VAR_ll, ONLY : NMNH_COMM_WORLD
+USE MODD_MPIF,    ONLY : MPI_STATUSES_IGNORE
 USE MODD_PRECISION,  ONLY : MNHREAL_MPI
 !
+USE MODE_MNH_ZWORK, ONLY : IIU,IJU,IKU
+USE MODE_MNH_ZWORK, ONLY : IIB,IJB ,IIE,IJE 
+!
 IMPLICIT NONE
 !
-REAL, DIMENSION(:,:,:), INTENT(INOUT) :: PSRC    ! variable at t
-TYPE(HALO2LIST_ll), POINTER  :: TP_PSRC_HALO2_ll  ! halo2 for SRC
+REAL, DIMENSION(:,:), INTENT(INOUT) :: PSRC    ! variable at t
+CHARACTER(len=4), OPTIONAL :: HDIR ! to send only halo on X or Y direction
 character(len=*), optional, intent(in) :: HNAME ! Name of the field to be added
 !
 character(len=:), allocatable    :: yname
+TYPE(LIST_ll)     , POINTER      :: TZ_PSRC_ll               ! halo
 INTEGER                          :: IERROR                 ! error return code 
 
 INTEGER,PARAMETER :: IS_WEST=1 , IS_EAST=2, IS_SOUTH=3, IS_NORTH=4
@@ -933,44 +1047,62 @@ LOGICAL      :: LX , LY
 INTEGER      :: INB_REQ , IREQ(8)
 INTEGER      :: IERR
 
-REAL , DIMENSION(:,:) , POINTER , CONTIGUOUS :: ZH2_EAST,ZH2_WEST,ZH2_NORTH,ZH2_SOUTH
-
 if ( NPROC == 1 ) RETURN
 
-!$acc data present ( PSRC ) &
-!$acc present (ZNORTH2_IN, ZSOUTH2_IN, ZWEST2_IN, ZEAST2_IN) &
-!$acc present (ZNORTH2_OUT, ZSOUTH2_OUT, ZWEST2_OUT, ZEAST2_OUT)
+CALL INIT_HALO_D()
+
+!$acc data present ( PSRC )
+
+NULLIFY( TZ_PSRC_ll)
 !
+
 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
+LX = .FALSE.
+LY = .FALSE. 
+
+IF (.NOT. PRESENT(HDIR) ) THEN
 LX = .TRUE.
 LY = .TRUE.
+ELSE
+   !
+   !  Problem of reproductibility in ppm_s0_x/y if only S0_X or S0_Y
+   !  so add S0_X + S0_Y for ppm_s0*
+   !
+!!$LX = ( HDIR == "01_X" .OR. HDIR == "S0_X" )
+!!$LY = ( HDIR == "01_Y" .OR. HDIR == "S0_Y" )
+LX = ( HDIR == "01_X" .OR. HDIR == "S0_X" .OR. HDIR == "S0_Y" )
+LY = ( HDIR == "01_Y" .OR. HDIR == "S0_Y" .OR. HDIR == "S0_X" )
+END IF
+
+!!$LX = .TRUE.
+!!$LY = .TRUE.
 
 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
 INB_REQ = 0
 
 !
-! Post the recieve of Zxxxx_IN buffer first via MPI(Gpu_direct)
+! Post the recieve of Zxxxx_2D_OUT buffer first via MPI(Gpu_direct)
 !
 
 IF (LX) THEN
    IF (.NOT. GWEST) THEN
 #ifdef MNH_GPUDIRECT
-      !$acc host_data use_device(ZWEST2_OUT)
+      !$acc host_data use_device(ZWEST_2D_OUT)
 #endif
       INB_REQ = INB_REQ + 1
-      CALL MPI_IRECV(ZWEST2_OUT,SIZE(ZWEST2_OUT),MNHREAL_MPI,NP_WEST-1,1000+IS_EAST,NMNH_COMM_WORLD,IREQ(INB_REQ),IERR)
+      CALL MPI_IRECV(ZWEST_2D_OUT,SIZE(ZWEST_2D_OUT),MNHREAL_MPI,NP_WEST-1,1000+IS_EAST,NMNH_COMM_WORLD,IREQ(INB_REQ),IERR)
 #ifdef MNH_GPUDIRECT
       !$acc end host_data
 #endif
    END IF
    IF (.NOT.GEAST) THEN 
 #ifdef MNH_GPUDIRECT
-      !$acc host_data use_device(ZEAST2_OUT)
+      !$acc host_data use_device(ZEAST_2D_OUT)
 #endif
       INB_REQ = INB_REQ + 1
-      CALL MPI_IRECV(ZEAST2_OUT,SIZE(ZEAST2_OUT),MNHREAL_MPI,NP_EAST-1,1000+IS_WEST,NMNH_COMM_WORLD,IREQ(INB_REQ),IERR)
+      CALL MPI_IRECV(ZEAST_2D_OUT,SIZE(ZEAST_2D_OUT),MNHREAL_MPI,NP_EAST-1,1000+IS_WEST,NMNH_COMM_WORLD,IREQ(INB_REQ),IERR)
 #ifdef MNH_GPUDIRECT
       !$acc end host_data
 #endif
@@ -980,20 +1112,20 @@ END IF
 IF (LY) THEN
    IF (.NOT.GSOUTH) THEN
 #ifdef MNH_GPUDIRECT
-      !$acc host_data use_device(ZSOUTH2_OUT)
+      !$acc host_data use_device(ZSOUTH_2D_OUT)
 #endif
       INB_REQ = INB_REQ + 1
-      CALL MPI_IRECV(ZSOUTH2_OUT,SIZE(ZSOUTH2_OUT),MNHREAL_MPI,NP_SOUTH-1,1000+IS_NORTH,NMNH_COMM_WORLD,IREQ(INB_REQ),IERR)
+      CALL MPI_IRECV(ZSOUTH_2D_OUT,SIZE(ZSOUTH_2D_OUT),MNHREAL_MPI,NP_SOUTH-1,1000+IS_NORTH,NMNH_COMM_WORLD,IREQ(INB_REQ),IERR)
 #ifdef MNH_GPUDIRECT
       !$acc end host_data
 #endif
    ENDIF
    IF (.NOT.GNORTH) THEN
 #ifdef MNH_GPUDIRECT
-      !$acc host_data use_device(ZNORTH2_OUT)
+      !$acc host_data use_device(ZNORTH_2D_OUT)
 #endif
       INB_REQ = INB_REQ + 1
-      CALL MPI_IRECV(ZNORTH2_OUT,SIZE(ZNORTH2_OUT),MNHREAL_MPI,NP_NORTH-1,1000+IS_SOUTH,NMNH_COMM_WORLD,IREQ(INB_REQ),IERR)
+      CALL MPI_IRECV(ZNORTH_2D_OUT,SIZE(ZNORTH_2D_OUT),MNHREAL_MPI,NP_NORTH-1,1000+IS_SOUTH,NMNH_COMM_WORLD,IREQ(INB_REQ),IERR)
 #ifdef MNH_GPUDIRECT
       !$acc end host_data
 #endif
@@ -1002,33 +1134,29 @@ END IF
 
 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
-!Copy the halo on the device PSRC to Zxxxx_IN
+!Copy the halo on the device PSRC to Zxxxx_2D_IN
 
 IF (LX) THEN
    IF (.NOT. GWEST) THEN
    !$acc kernels async(IS_WEST)
-!!$      ZWEST2_IN ( IIB:IIB+IHALO_1  ,    IJB:IJE  , : )  = PSRC( IIB:IIB+IHALO_1  ,  IJB:IJE  , : )
-      ZWEST2_IN ( : , : )  = PSRC( IIB+1  , : , : )
+   ZWEST_2D_IN ( IIB:IIB+IHALO_1  ,    IJB:IJE )  = PSRC( IIB:IIB+IHALO_1  ,  IJB:IJE )
    !$acc end kernels
       END IF
    IF (.NOT.GEAST) THEN
    !$acc kernels async(IS_EAST)
-!!$      ZEAST2_IN ( IIE-IHALO_1:IIE  ,    IJB:IJE  , : )  = PSRC( IIE-IHALO_1:IIE  ,  IJB:IJE  , : )
-      ZEAST2_IN ( : , : )  = PSRC( IIE-1 ,  :  , : )
+   ZEAST_2D_IN ( IIE-IHALO_1:IIE  ,    IJB:IJE )  = PSRC( IIE-IHALO_1:IIE  ,  IJB:IJE )
    !$acc end kernels
       ENDIF
 END IF
 IF (LY) THEN
    IF (.NOT.GSOUTH) THEN
    !$acc kernels async(IS_SOUTH)
-!!$   ZSOUTH2_IN ( IIB:IIE  ,    IJB:IJB+IHALO_1  , : ) = PSRC( IIB:IIE  ,    IJB:IJB+IHALO_1  , : )
-      ZSOUTH2_IN ( : , : ) = PSRC( : , IJB+1 , : )
+   ZSOUTH_2D_IN ( IIB:IIE  ,    IJB:IJB+IHALO_1 ) = PSRC( IIB:IIE  ,    IJB:IJB+IHALO_1 )
    !$acc end kernels
       ENDIF
    IF (.NOT.GNORTH) THEN
    !$acc kernels async(IS_NORTH)
-!!$      ZNORTH2_IN ( IIB:IIE  ,    IJE-IHALO_1:IJE  , : ) = PSRC( IIB:IIE  ,    IJE-IHALO_1:IJE  , : )
-      ZNORTH2_IN ( : , : ) = PSRC( : , IJE-1  , : )      
+   ZNORTH_2D_IN ( IIB:IIE  ,    IJE-IHALO_1:IJE ) = PSRC( IIB:IIE  ,    IJE-IHALO_1:IJE )
    !$acc end kernels
    ENDIF
 ENDIF
@@ -1036,29 +1164,29 @@ ENDIF
 
 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 !
-! Send  Zxxxx2_IN buffer via MPI(Gpu_direct) or copy to host
+! Send  Zxxxx_2D_IN buffer via MPI(Gpu_direct) or copy to host
 !
 IF (LX) THEN
    IF (.NOT. GWEST) THEN
 #ifdef MNH_GPUDIRECT
-      !$acc host_data use_device(ZWEST2_IN)
+      !$acc host_data use_device(ZWEST_2D_IN)
 #else
-      !$acc update host(ZWEST2_IN)
+      !$acc update host(ZWEST_2D_IN)
 #endif
       INB_REQ = INB_REQ + 1
-      CALL MPI_ISEND(ZWEST2_IN,SIZE(ZWEST2_IN)  ,MNHREAL_MPI,NP_WEST-1,1000+IS_WEST,NMNH_COMM_WORLD,IREQ(INB_REQ),IERR)
+      CALL MPI_ISEND(ZWEST_2D_IN,SIZE(ZWEST_2D_IN)  ,MNHREAL_MPI,NP_WEST-1,1000+IS_WEST,NMNH_COMM_WORLD,IREQ(INB_REQ),IERR)
 #ifdef MNH_GPUDIRECT
       !$acc end host_data
 #endif
    END IF
    IF (.NOT.GEAST) THEN
 #ifdef MNH_GPUDIRECT
-      !$acc host_data use_device(ZEAST2_IN)
+      !$acc host_data use_device(ZEAST_2D_IN)
 #else
-      !$acc update host(ZEAST2_IN)
+      !$acc update host(ZEAST_2D_IN)
 #endif
       INB_REQ = INB_REQ + 1
-      CALL MPI_ISEND(ZEAST2_IN,SIZE(ZEAST2_IN)  ,MNHREAL_MPI,NP_EAST-1,1000+IS_EAST,NMNH_COMM_WORLD,IREQ(INB_REQ),IERR)
+      CALL MPI_ISEND(ZEAST_2D_IN,SIZE(ZEAST_2D_IN)  ,MNHREAL_MPI,NP_EAST-1,1000+IS_EAST,NMNH_COMM_WORLD,IREQ(INB_REQ),IERR)
 #ifdef MNH_GPUDIRECT
       !$acc end host_data
 #endif
@@ -1068,24 +1196,24 @@ END IF
 IF (LY) THEN
    IF (.NOT.GSOUTH) THEN
 #ifdef MNH_GPUDIRECT
-      !$acc host_data use_device(ZSOUTH2_IN)
+      !$acc host_data use_device(ZSOUTH_2D_IN)
 #else
-      !$acc update host(ZSOUTH2_IN)
+      !$acc update host(ZSOUTH_2D_IN)
 #endif
       INB_REQ = INB_REQ + 1
-      CALL MPI_ISEND(ZSOUTH2_IN,SIZE(ZSOUTH2_IN)  ,MNHREAL_MPI,NP_SOUTH-1,1000+IS_SOUTH,NMNH_COMM_WORLD,IREQ(INB_REQ),IERR)
+      CALL MPI_ISEND(ZSOUTH_2D_IN,SIZE(ZSOUTH_2D_IN)  ,MNHREAL_MPI,NP_SOUTH-1,1000+IS_SOUTH,NMNH_COMM_WORLD,IREQ(INB_REQ),IERR)
 #ifdef MNH_GPUDIRECT
       !$acc end host_data
 #endif
    ENDIF
    IF (.NOT.GNORTH) THEN
 #ifdef MNH_GPUDIRECT
-      !$acc host_data use_device(ZNORTH2_IN)
+      !$acc host_data use_device(ZNORTH_2D_IN)
 #else
-      !$acc update host(ZNORTH2_IN)
+      !$acc update host(ZNORTH_2D_IN)
 #endif
       INB_REQ = INB_REQ + 1
-      CALL MPI_ISEND(ZNORTH2_IN,SIZE(ZNORTH2_IN)  ,MNHREAL_MPI,NP_NORTH-1,1000+IS_NORTH,NMNH_COMM_WORLD,IREQ(INB_REQ),IERR)
+      CALL MPI_ISEND(ZNORTH_2D_IN,SIZE(ZNORTH_2D_IN)  ,MNHREAL_MPI,NP_NORTH-1,1000+IS_NORTH,NMNH_COMM_WORLD,IREQ(INB_REQ),IERR)
 #ifdef MNH_GPUDIRECT
       !$acc end host_data
 #endif
@@ -1108,44 +1236,36 @@ END IF
 IF (LX) THEN
    IF (.NOT.GWEST) THEN
 #ifndef MNH_GPUDIRECT
-   !$acc update device(ZWEST2_OUT) async(IS_WEST)
+   !$acc update device(ZWEST_2D_OUT) async(IS_WEST)
 #endif
-   ZH2_WEST => TP_PSRC_HALO2_ll%HALO2%WEST  
    !$acc kernels async(IS_WEST)
-!!$      PSRC( 1:IIB-1  ,      IJB:IJE      , : ) = ZWEST2_OUT( 1:IIB-1  ,   IJB:IJE    , : )
-      ZH2_WEST( : , : ) = ZWEST2_OUT( : , : )      
+   PSRC( 1:IIB-1  ,      IJB:IJE     ) = ZWEST_2D_OUT( 1:IIB-1  ,   IJB:IJE   )
    !$acc end kernels
    ENDIF
    IF (.NOT.GEAST) THEN
 #ifndef MNH_GPUDIRECT
-   !$acc update device(ZEAST2_OUT) async(IS_EAST)
+   !$acc update device(ZEAST_2D_OUT) async(IS_EAST)
 #endif
-      ZH2_EAST => TP_PSRC_HALO2_ll%HALO2%EAST
    !$acc kernels async(IS_EAST)
-!!$      PSRC( IIE+1:IIU  ,      IJB:IJE      , : ) = ZEAST2_OUT( IIE+1:IIU  ,   IJB:IJE    , : )
-      ZH2_EAST( : , : ) = ZEAST2_OUT( : , : )
+   PSRC( IIE+1:IIU  ,      IJB:IJE     ) = ZEAST_2D_OUT( IIE+1:IIU  ,   IJB:IJE   )  
    !$acc end kernels
    ENDIF
 END IF
 IF (LY) THEN
    IF (.NOT.GSOUTH) THEN
 #ifndef MNH_GPUDIRECT
-   !$acc update device(ZSOUTH2_OUT) async(IS_SOUTH)
+   !$acc update device(ZSOUTH_2D_OUT) async(IS_SOUTH)
 #endif
-   ZH2_SOUTH => TP_PSRC_HALO2_ll%HALO2%SOUTH    
    !$acc kernels async(IS_SOUTH)
-!!$      PSRC(      IIB:IIE       ,  1:IJB-1 , : ) = ZSOUTH2_OUT(  IIB:IIE     , 1:IJB-1  , : )
-     ZH2_SOUTH( : , : ) = ZSOUTH2_OUT( : , : )  
+   PSRC(      IIB:IIE       ,  1:IJB-1) = ZSOUTH_2D_OUT(  IIB:IIE     , 1:IJB-1 )
    !$acc end kernels
    ENDIF
    IF (.NOT.GNORTH) THEN
 #ifndef MNH_GPUDIRECT
-   !$acc update device(ZNORTH2_OUT) async(IS_NORTH)
+   !$acc update device(ZNORTH_2D_OUT) async(IS_NORTH)
 #endif
-   ZH2_NORTH => TP_PSRC_HALO2_ll%HALO2%NORTH
    !$acc kernels async(IS_NORTH)
-!!$      PSRC(      IIB:IIE       , IJE+1:IJU , : ) = ZNORTH2_OUT (  IIB:IIE     , IJE+1:IJU  , : )
-     ZH2_NORTH( : , : ) = ZNORTH2_OUT ( : , : )      
+   PSRC(      IIB:IIE       , IJE+1:IJU) = ZNORTH_2D_OUT (  IIB:IIE     , IJE+1:IJU  )
    !$acc end kernels
    ENDIF
 END IF
@@ -1153,47 +1273,1169 @@ END IF
 
 !$acc end data
 
-END SUBROUTINE GET_HALO2_DD
-!
-!     ###################################################
-      SUBROUTINE GET_HALO2_D(PSRC, TP_PSRC_HALO2_ll, HNAME)
-!     ###################################################
+END SUBROUTINE GET_2D_HALO_DD
+!-------------------------------------------------------------------------------
+!     ########################################
+      SUBROUTINE GET_HALO_DDC(PSRC, HDIR, HNAME)
+!     ########################################
+#define MNH_GPUDIRECT
 !
+USE MODD_HALO_D
 USE MODE_ll
-USE MODD_ARGSLIST_ll, ONLY : LIST_ll, HALO2LIST_ll
-USE MODI_GET_HALO, ONLY : GET_HALO_D,GET_HALO_DD,GET_HALO2_DD
+USE MODD_ARGSLIST_ll, ONLY : LIST_ll
+USE MODD_PARAMETERS, ONLY : JPHEXT
+!
+USE MODD_IO,        ONLY : GSMONOPROC
+USE MODE_MNH_ZWORK, ONLY : GWEST , GEAST, GSOUTH , GNORTH
+!
+USE MODD_CONF, ONLY : NHALO
+USE MODE_DEVICE
+USE MODE_MPPDB
+
+USE MODD_VAR_ll, ONLY    : IP,NPROC,NP1,NP2
+USE MODD_VAR_ll, ONLY : NMNH_COMM_WORLD
+USE MODD_MPIF,    ONLY : MPI_STATUSES_IGNORE
+USE MODD_PRECISION,  ONLY : MNHREAL_MPI
+!
+USE MODE_MNH_ZWORK, ONLY : IIU,IJU,IKU
+USE MODE_MNH_ZWORK, ONLY : IIB,IJB ,IIE,IJE 
 !
 IMPLICIT NONE
 !
-REAL, DIMENSION(:,:,:), INTENT(INOUT)  :: PSRC    ! variable at t
-TYPE(HALO2LIST_ll), POINTER         :: TP_PSRC_HALO2_ll          ! halo2 for SRC
+REAL, DIMENSION(:,:,:), INTENT(INOUT) :: PSRC    ! variable at t
+CHARACTER(len=4), OPTIONAL :: HDIR ! to send only halo on X or Y direction
 character(len=*), optional, intent(in) :: HNAME ! Name of the field to be added
 !
 character(len=:), allocatable    :: yname
-INTEGER                          :: IIU,IJU,IKU            ! domain sizes
 TYPE(LIST_ll)     , POINTER      :: TZ_PSRC_ll               ! halo
 INTEGER                          :: IERROR                 ! error return code 
+
+INTEGER,PARAMETER :: IS_WEST=1 , IS_EAST=2, IS_SOUTH=3, IS_NORTH=4
+
+LOGICAL      :: LX , LY
+
+INTEGER      :: INB_REQEW , IREQEW(4)
+INTEGER      :: INB_REQNS , IREQNS(4)
+INTEGER      :: IERR
+
+if ( NPROC == 1 ) RETURN
+
+CALL INIT_HALO_D()
+
+!$acc data present ( PSRC )
+
+NULLIFY( TZ_PSRC_ll)
 !
-IIU = SIZE(PSRC,1)
-IJU = SIZE(PSRC,2)
-IKU = SIZE(PSRC,3)
 
-if ( present ( hname ) ) then
-  yname = hname
-else
-  yname = 'PSRC'
-end if
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
-CALL GET_HALO_DD(PSRC,HNAME=yname)
+LX = .FALSE.
+LY = .FALSE. 
 
-!!$NULLIFY( TZ_PSRC_ll,TP_PSRC_HALO2_ll)
-CALL INIT_HALO2_ll(TP_PSRC_HALO2_ll,1,IIU,IJU,IKU)
+IF (.NOT. PRESENT(HDIR) ) THEN
+LX = .TRUE.
+LY = .TRUE.
+ELSE
+   !
+   !  Problem of reproductibility in ppm_s0_x/y if only S0_X or S0_Y
+   !  so add S0_X + S0_Y for ppm_s0*
+   !
+!!$LX = ( HDIR == "01_X" .OR. HDIR == "S0_X" )
+!!$LY = ( HDIR == "01_Y" .OR. HDIR == "S0_Y" )
+LX = ( HDIR == "01_X" .OR. HDIR == "S0_X" .OR. HDIR == "S0_Y" )
+LY = ( HDIR == "01_Y" .OR. HDIR == "S0_Y" .OR. HDIR == "S0_X" )
+END IF
+
+!!$LX = .TRUE.
+!!$LY = .TRUE.
+
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 !
-!!$CALL ADD3DFIELD_ll( TZ_PSRC_ll, PSRC, 'GET_HALO2_D::'//trim( yname ) )
-!!$CALL UPDATE_HALO2_ll(TZ_PSRC_ll,TP_PSRC_HALO2_ll,IERROR)
-CALL GET_HALO2_DD(PSRC,TP_PSRC_HALO2_ll,'GET_HALO2_DD::'//trim( yname ) )
+! Post first the recieve of ZxxxxC_OUT buffer via MPI(Gpu_direct)
 !
-!   clean local halo list
+!-------------------------------------------------------------------------------!
+!  IRecv  E/W                                                                   !
+!-------------------------------------------------------------------------------!
+INB_REQEW = 0
+IF (LX) THEN
+   IF (.NOT. GWEST) THEN
+#ifdef MNH_GPUDIRECT
+      !$acc host_data use_device(ZWESTC_OUT)
+#endif
+      INB_REQEW = INB_REQEW + 1
+      CALL MPI_IRECV(ZWESTC_OUT,SIZE(ZWESTC_OUT),MNHREAL_MPI,NP_WEST-1,1000+IS_EAST,NMNH_COMM_WORLD,IREQEW(INB_REQEW),IERR)
+#ifdef MNH_GPUDIRECT
+      !$acc end host_data
+#endif
+   END IF
+   IF (.NOT.GEAST) THEN 
+#ifdef MNH_GPUDIRECT
+      !$acc host_data use_device(ZEASTC_OUT)
+#endif
+      INB_REQEW = INB_REQEW + 1
+      CALL MPI_IRECV(ZEASTC_OUT,SIZE(ZEASTC_OUT),MNHREAL_MPI,NP_EAST-1,1000+IS_WEST,NMNH_COMM_WORLD,IREQEW(INB_REQEW),IERR)
+#ifdef MNH_GPUDIRECT
+      !$acc end host_data
+#endif
+   ENDIF
+END IF
+
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+!Copy the halo E/W on the device PSRC to ZxxxxC_IN
+
+IF (LX) THEN
+   IF (.NOT. GWEST) THEN
+   !$acc kernels async(IS_WEST)
+   ZWESTC_IN ( IIB:IIB+IHALO_1  ,    IJB:IJE  , : )  = PSRC( IIB:IIB+IHALO_1  ,  IJB:IJE  , : )
+   !$acc end kernels
+   END IF
+   IF (.NOT.GEAST) THEN
+   !$acc kernels async(IS_EAST)
+   ZEASTC_IN ( IIE-IHALO_1:IIE  ,    IJB:IJE  , : )  = PSRC( IIE-IHALO_1:IIE  ,  IJB:IJE  , : )
+   !$acc end kernels
+   ENDIF
+   !$acc wait
+END IF
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!
+! Send  E/W ZxxxxC_IN buffer via MPI(Gpu_direct) or copy to host
+!
+IF (LX) THEN
+   IF (.NOT. GWEST) THEN
+#ifdef MNH_GPUDIRECT
+      !$acc host_data use_device(ZWESTC_IN)
+#else
+      !$acc update host(ZWESTC_IN)
+#endif
+      INB_REQEW = INB_REQEW + 1
+      CALL MPI_ISEND(ZWESTC_IN,SIZE(ZWESTC_IN)  ,MNHREAL_MPI,NP_WEST-1,1000+IS_WEST,NMNH_COMM_WORLD,IREQEW(INB_REQEW),IERR)
+#ifdef MNH_GPUDIRECT
+      !$acc end host_data
+#endif
+   END IF
+   IF (.NOT.GEAST) THEN
+#ifdef MNH_GPUDIRECT
+      !$acc host_data use_device(ZEASTC_IN)
+#else
+      !$acc update host(ZEASTC_IN)
+#endif
+      INB_REQEW = INB_REQEW + 1
+      CALL MPI_ISEND(ZEASTC_IN,SIZE(ZEASTC_IN)  ,MNHREAL_MPI,NP_EAST-1,1000+IS_EAST,NMNH_COMM_WORLD,IREQEW(INB_REQEW),IERR)
+#ifdef MNH_GPUDIRECT
+      !$acc end host_data
+#endif
+   ENDIF
+END IF
+
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+IF ( INB_REQEW > 0 ) THEN
+   CALL MPI_WAITALL(INB_REQEW,IREQEW,MPI_STATUSES_IGNORE,IERR)
+END IF
+
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+! Update halo E/W from buffer to PSRC
+
+IF (LX) THEN
+   IF (.NOT.GWEST) THEN
+#ifndef MNH_GPUDIRECT
+   !$acc update device(ZWESTC_OUT) async(IS_WEST)
+#endif
+   !$acc kernels async(IS_WEST)
+   PSRC( 1:IIB-1  ,      IJB:IJE      , : ) = ZWESTC_OUT( 1:IIB-1  ,   IJB:IJE    , : )
+   !$acc end kernels
+   ENDIF
+   IF (.NOT.GEAST) THEN
+#ifndef MNH_GPUDIRECT
+   !$acc update device(ZEASTC_OUT) async(IS_EAST)
+#endif
+   !$acc kernels async(IS_EAST)
+   PSRC( IIE+1:IIU  ,      IJB:IJE      , : ) = ZEASTC_OUT( IIE+1:IIU  ,   IJB:IJE    , : )  
+   !$acc end kernels
+   ENDIF
+   !$acc wait
+END IF
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!
+! Post first the recieve of N/S ZxxxxC_OUT buffer via MPI(Gpu_direct)
+!
+!-------------------------------------------------------------------------------!
+!  IRecv  N/S                                                                   !
+!-------------------------------------------------------------------------------!
+INB_REQNS = 0
+IF (LY) THEN
+   IF (.NOT.GSOUTH) THEN
+#ifdef MNH_GPUDIRECT
+      !$acc host_data use_device(ZSOUTHC_OUT)
+#endif
+      INB_REQNS = INB_REQNS + 1
+      CALL MPI_IRECV(ZSOUTHC_OUT,SIZE(ZSOUTHC_OUT),MNHREAL_MPI,NP_SOUTH-1,1000+IS_NORTH,NMNH_COMM_WORLD,IREQNS(INB_REQNS),IERR)
+#ifdef MNH_GPUDIRECT
+      !$acc end host_data
+#endif
+   ENDIF
+   IF (.NOT.GNORTH) THEN
+#ifdef MNH_GPUDIRECT
+      !$acc host_data use_device(ZNORTHC_OUT)
+#endif
+      INB_REQNS = INB_REQNS + 1
+      CALL MPI_IRECV(ZNORTHC_OUT,SIZE(ZNORTHC_OUT),MNHREAL_MPI,NP_NORTH-1,1000+IS_SOUTH,NMNH_COMM_WORLD,IREQNS(INB_REQNS),IERR)
+#ifdef MNH_GPUDIRECT
+      !$acc end host_data
+#endif
+   ENDIF
+END IF
+
+!
+!Copy the halo N/S on the device PSRC to ZxxxxC_IN
+!
+IF (LY) THEN
+   IF (.NOT.GSOUTH) THEN
+   !$acc kernels async(IS_SOUTH)
+   ZSOUTHC_IN ( 1:IIU  ,    IJB:IJB+IHALO_1  , : ) = PSRC( 1:IIU  ,    IJB:IJB+IHALO_1  , : )
+   !$acc end kernels
+      ENDIF
+   IF (.NOT.GNORTH) THEN
+   !$acc kernels async(IS_NORTH)
+   ZNORTHC_IN ( 1:IIU  ,    IJE-IHALO_1:IJE  , : ) = PSRC( 1:IIU  ,    IJE-IHALO_1:IJE  , : )
+   !$acc end kernels
+   ENDIF
+   !$acc wait
+ENDIF
+
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!
+! Send N/S ZxxxxC_IN buffer via MPI(Gpu_direct) or copy to host
+!
+IF (LY) THEN
+   IF (.NOT.GSOUTH) THEN
+#ifdef MNH_GPUDIRECT
+      !$acc host_data use_device(ZSOUTHC_IN)
+#else
+      !$acc update host(ZSOUTHC_IN)
+#endif
+      INB_REQNS = INB_REQNS + 1
+      CALL MPI_ISEND(ZSOUTHC_IN,SIZE(ZSOUTHC_IN)  ,MNHREAL_MPI,NP_SOUTH-1,1000+IS_SOUTH,NMNH_COMM_WORLD,IREQNS(INB_REQNS),IERR)
+#ifdef MNH_GPUDIRECT
+      !$acc end host_data
+#endif
+   ENDIF
+   IF (.NOT.GNORTH) THEN
+#ifdef MNH_GPUDIRECT
+      !$acc host_data use_device(ZNORTHC_IN)
+#else
+      !$acc update host(ZNORTHC_IN)
+#endif
+      INB_REQNS = INB_REQNS + 1
+      CALL MPI_ISEND(ZNORTHC_IN,SIZE(ZNORTHC_IN)  ,MNHREAL_MPI,NP_NORTH-1,1000+IS_NORTH,NMNH_COMM_WORLD,IREQNS(INB_REQNS),IERR)
+#ifdef MNH_GPUDIRECT
+      !$acc end host_data
+#endif
+   ENDIF   
+ENDIF
+
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+IF ( INB_REQNS > 0 ) THEN
+   CALL MPI_WAITALL(INB_REQNS,IREQNS,MPI_STATUSES_IGNORE,IERR)
+END IF
+
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+! Update halo N/S
+
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+! Update halo N/S/W from buffer to PSRC
+
+IF (LY) THEN
+   IF (.NOT.GSOUTH) THEN
+#ifndef MNH_GPUDIRECT
+   !$acc update device(ZSOUTHC_OUT) async(IS_SOUTH)
+#endif
+   !$acc kernels async(IS_SOUTH)
+   PSRC(      1:IIU       ,  1:IJB-1 , : ) = ZSOUTHC_OUT(  1:IIU     , 1:IJB-1  , : )
+   !$acc end kernels
+   ENDIF
+   IF (.NOT.GNORTH) THEN
+#ifndef MNH_GPUDIRECT
+   !$acc update device(ZNORTHC_OUT) async(IS_NORTH)
+#endif
+   !$acc kernels async(IS_NORTH)
+   PSRC(      1:IIU       , IJE+1:IJU , : ) = ZNORTHC_OUT (  1:IIU     , IJE+1:IJU  , : )
+   !$acc end kernels
+   ENDIF
+   !$acc wait
+END IF
+
+!$acc end data
+
+END SUBROUTINE GET_HALO_DDC
+!-------------------------------------------------------------------------------
+!     ########################################
+      SUBROUTINE GET_2D_HALO_DDC(PSRC, HDIR, HNAME)
+!     ########################################
+#define MNH_GPUDIRECT
+!
+USE MODD_HALO_D
+USE MODE_ll
+USE MODD_ARGSLIST_ll, ONLY : LIST_ll
+USE MODD_PARAMETERS, ONLY : JPHEXT
+!
+USE MODD_IO,        ONLY : GSMONOPROC
+USE MODE_MNH_ZWORK, ONLY : GWEST , GEAST, GSOUTH , GNORTH
+!
+USE MODD_CONF, ONLY : NHALO
+USE MODE_DEVICE
+USE MODE_MPPDB
+
+USE MODD_VAR_ll, ONLY    : IP,NPROC,NP1,NP2
+USE MODD_VAR_ll, ONLY : NMNH_COMM_WORLD
+USE MODD_MPIF,    ONLY : MPI_STATUSES_IGNORE
+USE MODD_PRECISION,  ONLY : MNHREAL_MPI
+!
+USE MODE_MNH_ZWORK, ONLY : IIU,IJU,IKU
+USE MODE_MNH_ZWORK, ONLY : IIB,IJB ,IIE,IJE 
+!
+IMPLICIT NONE
+!
+REAL, DIMENSION(:,:), INTENT(INOUT) :: PSRC    ! variable at t
+CHARACTER(len=4), OPTIONAL :: HDIR ! to send only halo on X or Y direction
+character(len=*), optional, intent(in) :: HNAME ! Name of the field to be added
+!
+character(len=:), allocatable    :: yname
+TYPE(LIST_ll)     , POINTER      :: TZ_PSRC_ll               ! halo
+INTEGER                          :: IERROR                 ! error return code 
+
+INTEGER,PARAMETER :: IS_WEST=1 , IS_EAST=2, IS_SOUTH=3, IS_NORTH=4
+
+LOGICAL      :: LX , LY
+
+INTEGER      :: INB_REQEW , IREQEW(4)
+INTEGER      :: INB_REQNS , IREQNS(4)
+INTEGER      :: IERR
+
+if ( NPROC == 1 ) RETURN
+
+CALL INIT_HALO_D()
+
+!$acc data present ( PSRC )
+
+NULLIFY( TZ_PSRC_ll)
+!
+
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+LX = .FALSE.
+LY = .FALSE. 
+
+IF (.NOT. PRESENT(HDIR) ) THEN
+LX = .TRUE.
+LY = .TRUE.
+ELSE
+   !
+   !  Problem of reproductibility in ppm_s0_x/y if only S0_X or S0_Y
+   !  so add S0_X + S0_Y for ppm_s0*
+   !
+!!$LX = ( HDIR == "01_X" .OR. HDIR == "S0_X" )
+!!$LY = ( HDIR == "01_Y" .OR. HDIR == "S0_Y" )
+LX = ( HDIR == "01_X" .OR. HDIR == "S0_X" .OR. HDIR == "S0_Y" )
+LY = ( HDIR == "01_Y" .OR. HDIR == "S0_Y" .OR. HDIR == "S0_X" )
+END IF
+
+!!$LX = .TRUE.
+!!$LY = .TRUE.
+
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!
+! Post first the recieve of ZxxxxC_2D_OUT buffer via MPI(Gpu_direct)
+!
+!-------------------------------------------------------------------------------!
+!  IRecv  E/W                                                                   !
+!-------------------------------------------------------------------------------!
+INB_REQEW = 0
+IF (LX) THEN
+   IF (.NOT. GWEST) THEN
+#ifdef MNH_GPUDIRECT
+      !$acc host_data use_device(ZWESTC_2D_OUT)
+#endif
+      INB_REQEW = INB_REQEW + 1
+      CALL MPI_IRECV(ZWESTC_2D_OUT,SIZE(ZWESTC_2D_OUT),MNHREAL_MPI,NP_WEST-1,1000+IS_EAST,NMNH_COMM_WORLD,IREQEW(INB_REQEW),IERR)
+#ifdef MNH_GPUDIRECT
+      !$acc end host_data
+#endif
+   END IF
+   IF (.NOT.GEAST) THEN 
+#ifdef MNH_GPUDIRECT
+      !$acc host_data use_device(ZEASTC_2D_OUT)
+#endif
+      INB_REQEW = INB_REQEW + 1
+      CALL MPI_IRECV(ZEASTC_2D_OUT,SIZE(ZEASTC_2D_OUT),MNHREAL_MPI,NP_EAST-1,1000+IS_WEST,NMNH_COMM_WORLD,IREQEW(INB_REQEW),IERR)
+#ifdef MNH_GPUDIRECT
+      !$acc end host_data
+#endif
+   ENDIF
+END IF
+
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+!Copy the halo E/W on the device PSRC to ZxxxxC_2D_IN
+
+IF (LX) THEN
+   IF (.NOT. GWEST) THEN
+   !$acc kernels async(IS_WEST)
+   ZWESTC_2D_IN ( IIB:IIB+IHALO_1  ,    IJB:IJE )  = PSRC( IIB:IIB+IHALO_1  ,  IJB:IJE )
+   !$acc end kernels
+   END IF
+   IF (.NOT.GEAST) THEN
+   !$acc kernels async(IS_EAST)
+   ZEASTC_2D_IN ( IIE-IHALO_1:IIE  ,    IJB:IJE )  = PSRC( IIE-IHALO_1:IIE  ,  IJB:IJE )
+   !$acc end kernels
+   ENDIF
+   !$acc wait
+END IF
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!
+! Send  E/W ZxxxxC_2D_IN buffer via MPI(Gpu_direct) or copy to host
+!
+IF (LX) THEN
+   IF (.NOT. GWEST) THEN
+#ifdef MNH_GPUDIRECT
+      !$acc host_data use_device(ZWESTC_2D_IN)
+#else
+      !$acc update host(ZWESTC_2D_IN)
+#endif
+      INB_REQEW = INB_REQEW + 1
+      CALL MPI_ISEND(ZWESTC_2D_IN,SIZE(ZWESTC_2D_IN)  ,MNHREAL_MPI,NP_WEST-1,1000+IS_WEST,NMNH_COMM_WORLD,IREQEW(INB_REQEW),IERR)
+#ifdef MNH_GPUDIRECT
+      !$acc end host_data
+#endif
+   END IF
+   IF (.NOT.GEAST) THEN
+#ifdef MNH_GPUDIRECT
+      !$acc host_data use_device(ZEASTC_2D_IN)
+#else
+      !$acc update host(ZEASTC_2D_IN)
+#endif
+      INB_REQEW = INB_REQEW + 1
+      CALL MPI_ISEND(ZEASTC_2D_IN,SIZE(ZEASTC_2D_IN)  ,MNHREAL_MPI,NP_EAST-1,1000+IS_EAST,NMNH_COMM_WORLD,IREQEW(INB_REQEW),IERR)
+#ifdef MNH_GPUDIRECT
+      !$acc end host_data
+#endif
+   ENDIF
+END IF
+
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+IF ( INB_REQEW > 0 ) THEN
+   CALL MPI_WAITALL(INB_REQEW,IREQEW,MPI_STATUSES_IGNORE,IERR)
+END IF
+
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+! Update halo E/W from buffer to PSRC
+
+IF (LX) THEN
+   IF (.NOT.GWEST) THEN
+#ifndef MNH_GPUDIRECT
+   !$acc update device(ZWESTC_2D_OUT) async(IS_WEST)
+#endif
+   !$acc kernels async(IS_WEST)
+   PSRC( 1:IIB-1  ,      IJB:IJE     ) = ZWESTC_2D_OUT( 1:IIB-1  ,   IJB:IJE   )
+   !$acc end kernels
+   ENDIF
+   IF (.NOT.GEAST) THEN
+#ifndef MNH_GPUDIRECT
+   !$acc update device(ZEASTC_2D_OUT) async(IS_EAST)
+#endif
+   !$acc kernels async(IS_EAST)
+   PSRC( IIE+1:IIU  ,      IJB:IJE     ) = ZEASTC_2D_OUT( IIE+1:IIU  ,   IJB:IJE   )  
+   !$acc end kernels
+   ENDIF
+   !$acc wait
+END IF
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!
+! Post first the recieve of N/S ZxxxxC_2D_OUT buffer via MPI(Gpu_direct)
+!
+!-------------------------------------------------------------------------------!
+!  IRecv  N/S                                                                   !
+!-------------------------------------------------------------------------------!
+INB_REQNS = 0
+IF (LY) THEN
+   IF (.NOT.GSOUTH) THEN
+#ifdef MNH_GPUDIRECT
+      !$acc host_data use_device(ZSOUTHC_2D_OUT)
+#endif
+      INB_REQNS = INB_REQNS + 1
+      CALL MPI_IRECV(ZSOUTHC_2D_OUT,SIZE(ZSOUTHC_2D_OUT),MNHREAL_MPI,NP_SOUTH-1,1000+IS_NORTH,NMNH_COMM_WORLD,IREQNS(INB_REQNS),IERR)
+#ifdef MNH_GPUDIRECT
+      !$acc end host_data
+#endif
+   ENDIF
+   IF (.NOT.GNORTH) THEN
+#ifdef MNH_GPUDIRECT
+      !$acc host_data use_device(ZNORTHC_2D_OUT)
+#endif
+      INB_REQNS = INB_REQNS + 1
+      CALL MPI_IRECV(ZNORTHC_2D_OUT,SIZE(ZNORTHC_2D_OUT),MNHREAL_MPI,NP_NORTH-1,1000+IS_SOUTH,NMNH_COMM_WORLD,IREQNS(INB_REQNS),IERR)
+#ifdef MNH_GPUDIRECT
+      !$acc end host_data
+#endif
+   ENDIF
+END IF
+
+!
+!Copy the halo N/S on the device PSRC to ZxxxxC_2D_IN
+!
+IF (LY) THEN
+   IF (.NOT.GSOUTH) THEN
+   !$acc kernels async(IS_SOUTH)
+   ZSOUTHC_2D_IN ( 1:IIU  ,    IJB:IJB+IHALO_1 ) = PSRC( 1:IIU  ,    IJB:IJB+IHALO_1 )
+   !$acc end kernels
+      ENDIF
+   IF (.NOT.GNORTH) THEN
+   !$acc kernels async(IS_NORTH)
+   ZNORTHC_2D_IN ( 1:IIU  ,    IJE-IHALO_1:IJE ) = PSRC( 1:IIU  ,    IJE-IHALO_1:IJE )
+   !$acc end kernels
+   ENDIF
+   !$acc wait
+ENDIF
+
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!
+! Send N/S ZxxxxC_2D_IN buffer via MPI(Gpu_direct) or copy to host
+!
+IF (LY) THEN
+   IF (.NOT.GSOUTH) THEN
+#ifdef MNH_GPUDIRECT
+      !$acc host_data use_device(ZSOUTHC_2D_IN)
+#else
+      !$acc update host(ZSOUTHC_2D_IN)
+#endif
+      INB_REQNS = INB_REQNS + 1
+      CALL MPI_ISEND(ZSOUTHC_2D_IN,SIZE(ZSOUTHC_2D_IN)  ,MNHREAL_MPI,NP_SOUTH-1,1000+IS_SOUTH,NMNH_COMM_WORLD,IREQNS(INB_REQNS),IERR)
+#ifdef MNH_GPUDIRECT
+      !$acc end host_data
+#endif
+   ENDIF
+   IF (.NOT.GNORTH) THEN
+#ifdef MNH_GPUDIRECT
+      !$acc host_data use_device(ZNORTHC_2D_IN)
+#else
+      !$acc update host(ZNORTHC_2D_IN)
+#endif
+      INB_REQNS = INB_REQNS + 1
+      CALL MPI_ISEND(ZNORTHC_2D_IN,SIZE(ZNORTHC_2D_IN)  ,MNHREAL_MPI,NP_NORTH-1,1000+IS_NORTH,NMNH_COMM_WORLD,IREQNS(INB_REQNS),IERR)
+#ifdef MNH_GPUDIRECT
+      !$acc end host_data
+#endif
+   ENDIF   
+ENDIF
+
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+IF ( INB_REQNS > 0 ) THEN
+   CALL MPI_WAITALL(INB_REQNS,IREQNS,MPI_STATUSES_IGNORE,IERR)
+END IF
+
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+! Update halo N/S
+
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+! Update halo N/S/W from buffer to PSRC
+
+IF (LY) THEN
+   IF (.NOT.GSOUTH) THEN
+#ifndef MNH_GPUDIRECT
+   !$acc update device(ZSOUTHC_2D_OUT) async(IS_SOUTH)
+#endif
+   !$acc kernels async(IS_SOUTH)
+   PSRC(      1:IIU       ,  1:IJB-1) = ZSOUTHC_2D_OUT(  1:IIU     , 1:IJB-1 )
+   !$acc end kernels
+   ENDIF
+   IF (.NOT.GNORTH) THEN
+#ifndef MNH_GPUDIRECT
+   !$acc update device(ZNORTHC_2D_OUT) async(IS_NORTH)
+#endif
+   !$acc kernels async(IS_NORTH)
+   PSRC(      1:IIU       , IJE+1:IJU) = ZNORTHC_2D_OUT (  1:IIU     , IJE+1:IJU )
+   !$acc end kernels
+   ENDIF
+   !$acc wait
+END IF
+
+!$acc end data
+
+END SUBROUTINE GET_2D_HALO_DDC
+!-------------------------------------------------------------------------------
+!     ########################################
+      SUBROUTINE GET_HALO2_DD(PSRC, TP_PSRC_HALO2_ll, HNAME)
+!     ########################################
+#define MNH_GPUDIRECT
+!
+USE MODD_HALO_D
+USE MODE_ll
+USE MODD_ARGSLIST_ll, ONLY : LIST_ll
+USE MODD_PARAMETERS, ONLY : JPHEXT
+!
+USE MODD_IO,        ONLY : GSMONOPROC
+USE MODE_MNH_ZWORK, ONLY : GWEST , GEAST, GSOUTH , GNORTH
+USE MODE_MNH_ZWORK, ONLY : IIU,IJU,IKU
+USE MODE_MNH_ZWORK, ONLY : IIB,IJB ,IIE,IJE
+!
+USE MODD_CONF, ONLY : NHALO
+USE MODE_DEVICE
+USE MODE_MPPDB
+!
+USE MODD_VAR_ll,     ONLY : IP,NPROC,NP1,NP2
+USE MODD_VAR_ll,     ONLY : NMNH_COMM_WORLD
+USE MODD_MPIF,       ONLY : MPI_STATUSES_IGNORE
+USE MODD_PRECISION,  ONLY : MNHREAL_MPI
+!
+IMPLICIT NONE
+!
+REAL, DIMENSION(:,:,:), INTENT(INOUT) :: PSRC    ! variable at t
+TYPE(HALO2LIST_ll), POINTER  :: TP_PSRC_HALO2_ll  ! halo2 for SRC
+character(len=*), optional, intent(in) :: HNAME ! Name of the field to be added
+!
+character(len=:), allocatable    :: yname
+INTEGER                          :: IERROR                 ! error return code 
+
+INTEGER,PARAMETER :: IS_WEST=1 , IS_EAST=2, IS_SOUTH=3, IS_NORTH=4
+
+LOGICAL      :: LX , LY
+
+INTEGER      :: INB_REQ , IREQ(8)
+INTEGER      :: IERR
+
+REAL , DIMENSION(:,:) , POINTER , CONTIGUOUS :: ZH2_EAST,ZH2_WEST,ZH2_NORTH,ZH2_SOUTH
+
+if ( NPROC == 1 ) RETURN
+
+!$acc data present ( PSRC ) &
+!$acc present (ZNORTH2_IN, ZSOUTH2_IN, ZWEST2_IN, ZEAST2_IN) &
+!$acc present (ZNORTH2_OUT, ZSOUTH2_OUT, ZWEST2_OUT, ZEAST2_OUT)
+!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+LX = .TRUE.
+LY = .TRUE.
+
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+INB_REQ = 0
+
+!
+! Post the recieve of Zxxxx_IN buffer first via MPI(Gpu_direct)
+!
+
+IF (LX) THEN
+   IF (.NOT. GWEST) THEN
+#ifdef MNH_GPUDIRECT
+      !$acc host_data use_device(ZWEST2_OUT)
+#endif
+      INB_REQ = INB_REQ + 1
+      CALL MPI_IRECV(ZWEST2_OUT,SIZE(ZWEST2_OUT),MNHREAL_MPI,NP_WEST-1,1000+IS_EAST,NMNH_COMM_WORLD,IREQ(INB_REQ),IERR)
+#ifdef MNH_GPUDIRECT
+      !$acc end host_data
+#endif
+   END IF
+   IF (.NOT.GEAST) THEN 
+#ifdef MNH_GPUDIRECT
+      !$acc host_data use_device(ZEAST2_OUT)
+#endif
+      INB_REQ = INB_REQ + 1
+      CALL MPI_IRECV(ZEAST2_OUT,SIZE(ZEAST2_OUT),MNHREAL_MPI,NP_EAST-1,1000+IS_WEST,NMNH_COMM_WORLD,IREQ(INB_REQ),IERR)
+#ifdef MNH_GPUDIRECT
+      !$acc end host_data
+#endif
+   ENDIF
+END IF
+
+IF (LY) THEN
+   IF (.NOT.GSOUTH) THEN
+#ifdef MNH_GPUDIRECT
+      !$acc host_data use_device(ZSOUTH2_OUT)
+#endif
+      INB_REQ = INB_REQ + 1
+      CALL MPI_IRECV(ZSOUTH2_OUT,SIZE(ZSOUTH2_OUT),MNHREAL_MPI,NP_SOUTH-1,1000+IS_NORTH,NMNH_COMM_WORLD,IREQ(INB_REQ),IERR)
+#ifdef MNH_GPUDIRECT
+      !$acc end host_data
+#endif
+   ENDIF
+   IF (.NOT.GNORTH) THEN
+#ifdef MNH_GPUDIRECT
+      !$acc host_data use_device(ZNORTH2_OUT)
+#endif
+      INB_REQ = INB_REQ + 1
+      CALL MPI_IRECV(ZNORTH2_OUT,SIZE(ZNORTH2_OUT),MNHREAL_MPI,NP_NORTH-1,1000+IS_SOUTH,NMNH_COMM_WORLD,IREQ(INB_REQ),IERR)
+#ifdef MNH_GPUDIRECT
+      !$acc end host_data
+#endif
+   ENDIF
+END IF
+
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+!Copy the halo on the device PSRC to Zxxxx_IN
+
+IF (LX) THEN
+   IF (.NOT. GWEST) THEN
+   !$acc kernels async(IS_WEST)
+!!$      ZWEST2_IN ( IIB:IIB+IHALO_1  ,    IJB:IJE  , : )  = PSRC( IIB:IIB+IHALO_1  ,  IJB:IJE  , : )
+      ZWEST2_IN ( : , : )  = PSRC( IIB+1  , : , : )
+   !$acc end kernels
+      END IF
+   IF (.NOT.GEAST) THEN
+   !$acc kernels async(IS_EAST)
+!!$      ZEAST2_IN ( IIE-IHALO_1:IIE  ,    IJB:IJE  , : )  = PSRC( IIE-IHALO_1:IIE  ,  IJB:IJE  , : )
+      ZEAST2_IN ( : , : )  = PSRC( IIE-1 ,  :  , : )
+   !$acc end kernels
+      ENDIF
+END IF
+IF (LY) THEN
+   IF (.NOT.GSOUTH) THEN
+   !$acc kernels async(IS_SOUTH)
+!!$   ZSOUTH2_IN ( IIB:IIE  ,    IJB:IJB+IHALO_1  , : ) = PSRC( IIB:IIE  ,    IJB:IJB+IHALO_1  , : )
+      ZSOUTH2_IN ( : , : ) = PSRC( : , IJB+1 , : )
+   !$acc end kernels
+      ENDIF
+   IF (.NOT.GNORTH) THEN
+   !$acc kernels async(IS_NORTH)
+!!$      ZNORTH2_IN ( IIB:IIE  ,    IJE-IHALO_1:IJE  , : ) = PSRC( IIB:IIE  ,    IJE-IHALO_1:IJE  , : )
+      ZNORTH2_IN ( : , : ) = PSRC( : , IJE-1  , : )      
+   !$acc end kernels
+   ENDIF
+ENDIF
+!$acc wait
+
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!
+! Send  Zxxxx2_IN buffer via MPI(Gpu_direct) or copy to host
+!
+IF (LX) THEN
+   IF (.NOT. GWEST) THEN
+#ifdef MNH_GPUDIRECT
+      !$acc host_data use_device(ZWEST2_IN)
+#else
+      !$acc update host(ZWEST2_IN)
+#endif
+      INB_REQ = INB_REQ + 1
+      CALL MPI_ISEND(ZWEST2_IN,SIZE(ZWEST2_IN)  ,MNHREAL_MPI,NP_WEST-1,1000+IS_WEST,NMNH_COMM_WORLD,IREQ(INB_REQ),IERR)
+#ifdef MNH_GPUDIRECT
+      !$acc end host_data
+#endif
+   END IF
+   IF (.NOT.GEAST) THEN
+#ifdef MNH_GPUDIRECT
+      !$acc host_data use_device(ZEAST2_IN)
+#else
+      !$acc update host(ZEAST2_IN)
+#endif
+      INB_REQ = INB_REQ + 1
+      CALL MPI_ISEND(ZEAST2_IN,SIZE(ZEAST2_IN)  ,MNHREAL_MPI,NP_EAST-1,1000+IS_EAST,NMNH_COMM_WORLD,IREQ(INB_REQ),IERR)
+#ifdef MNH_GPUDIRECT
+      !$acc end host_data
+#endif
+   ENDIF
+END IF
+
+IF (LY) THEN
+   IF (.NOT.GSOUTH) THEN
+#ifdef MNH_GPUDIRECT
+      !$acc host_data use_device(ZSOUTH2_IN)
+#else
+      !$acc update host(ZSOUTH2_IN)
+#endif
+      INB_REQ = INB_REQ + 1
+      CALL MPI_ISEND(ZSOUTH2_IN,SIZE(ZSOUTH2_IN)  ,MNHREAL_MPI,NP_SOUTH-1,1000+IS_SOUTH,NMNH_COMM_WORLD,IREQ(INB_REQ),IERR)
+#ifdef MNH_GPUDIRECT
+      !$acc end host_data
+#endif
+   ENDIF
+   IF (.NOT.GNORTH) THEN
+#ifdef MNH_GPUDIRECT
+      !$acc host_data use_device(ZNORTH2_IN)
+#else
+      !$acc update host(ZNORTH2_IN)
+#endif
+      INB_REQ = INB_REQ + 1
+      CALL MPI_ISEND(ZNORTH2_IN,SIZE(ZNORTH2_IN)  ,MNHREAL_MPI,NP_NORTH-1,1000+IS_NORTH,NMNH_COMM_WORLD,IREQ(INB_REQ),IERR)
+#ifdef MNH_GPUDIRECT
+      !$acc end host_data
+#endif
+   ENDIF   
+ENDIF
+
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+IF ( INB_REQ > 0 ) THEN
+   CALL MPI_WAITALL(INB_REQ,IREQ,MPI_STATUSES_IGNORE,IERR)
+END IF
+
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+! Is update halo
+
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+
+IF (LX) THEN
+   IF (.NOT.GWEST) THEN
+#ifndef MNH_GPUDIRECT
+   !$acc update device(ZWEST2_OUT) async(IS_WEST)
+#endif
+   ZH2_WEST => TP_PSRC_HALO2_ll%HALO2%WEST  
+   !$acc kernels async(IS_WEST)
+!!$      PSRC( 1:IIB-1  ,      IJB:IJE      , : ) = ZWEST2_OUT( 1:IIB-1  ,   IJB:IJE    , : )
+      ZH2_WEST( : , : ) = ZWEST2_OUT( : , : )      
+   !$acc end kernels
+   ENDIF
+   IF (.NOT.GEAST) THEN
+#ifndef MNH_GPUDIRECT
+   !$acc update device(ZEAST2_OUT) async(IS_EAST)
+#endif
+      ZH2_EAST => TP_PSRC_HALO2_ll%HALO2%EAST
+   !$acc kernels async(IS_EAST)
+!!$      PSRC( IIE+1:IIU  ,      IJB:IJE      , : ) = ZEAST2_OUT( IIE+1:IIU  ,   IJB:IJE    , : )
+      ZH2_EAST( : , : ) = ZEAST2_OUT( : , : )
+   !$acc end kernels
+   ENDIF
+END IF
+IF (LY) THEN
+   IF (.NOT.GSOUTH) THEN
+#ifndef MNH_GPUDIRECT
+   !$acc update device(ZSOUTH2_OUT) async(IS_SOUTH)
+#endif
+   ZH2_SOUTH => TP_PSRC_HALO2_ll%HALO2%SOUTH    
+   !$acc kernels async(IS_SOUTH)
+!!$      PSRC(      IIB:IIE       ,  1:IJB-1 , : ) = ZSOUTH2_OUT(  IIB:IIE     , 1:IJB-1  , : )
+     ZH2_SOUTH( : , : ) = ZSOUTH2_OUT( : , : )  
+   !$acc end kernels
+   ENDIF
+   IF (.NOT.GNORTH) THEN
+#ifndef MNH_GPUDIRECT
+   !$acc update device(ZNORTH2_OUT) async(IS_NORTH)
+#endif
+   ZH2_NORTH => TP_PSRC_HALO2_ll%HALO2%NORTH
+   !$acc kernels async(IS_NORTH)
+!!$      PSRC(      IIB:IIE       , IJE+1:IJU , : ) = ZNORTH2_OUT (  IIB:IIE     , IJE+1:IJU  , : )
+     ZH2_NORTH( : , : ) = ZNORTH2_OUT ( : , : )      
+   !$acc end kernels
+   ENDIF
+END IF
+!$acc wait
+
+!$acc end data
+
+END SUBROUTINE GET_HALO2_DD
+!-------------------------------------------------------------------------------
+!     ########################################
+      SUBROUTINE GET_HALO2_DF(PSRC, TP_PSRC_HALO2F_ll, HNAME)
+!     ########################################
+#define MNH_GPUDIRECT
+!
+USE MODD_HALO_D
+USE MODE_ll
+USE MODD_ARGSLIST_ll, ONLY : LIST_ll
+USE MODD_PARAMETERS, ONLY : JPHEXT
+!
+USE MODD_IO,        ONLY : GSMONOPROC
+USE MODE_MNH_ZWORK, ONLY : GWEST , GEAST, GSOUTH , GNORTH
+USE MODE_MNH_ZWORK, ONLY : IIU,IJU,IKU
+USE MODE_MNH_ZWORK, ONLY : IIB,IJB ,IIE,IJE
+!
+USE MODD_CONF, ONLY : NHALO
+USE MODE_DEVICE
+USE MODE_MPPDB
+!
+USE MODD_VAR_ll,     ONLY : IP,NPROC,NP1,NP2
+USE MODD_VAR_ll,     ONLY : NMNH_COMM_WORLD
+USE MODD_MPIF,       ONLY : MPI_STATUSES_IGNORE
+USE MODD_PRECISION,  ONLY : MNHREAL_MPI
+!
+IMPLICIT NONE
+!
+REAL, DIMENSION(:,:,:), INTENT(INOUT) :: PSRC    ! variable at t
+TYPE(HALO2LIST_ll), POINTER  :: TP_PSRC_HALO2F_ll  ! halo2 for SRC
+character(len=*), optional, intent(in) :: HNAME ! Name of the field to be added
+!
+character(len=:), allocatable    :: yname
+INTEGER                          :: IERROR                 ! error return code 
+
+INTEGER,PARAMETER :: IS_WEST=1 , IS_EAST=2, IS_SOUTH=3, IS_NORTH=4
+
+LOGICAL      :: LX , LY
+
+INTEGER      :: INB_REQ , IREQ(8)
+INTEGER      :: IERR
+
+REAL , DIMENSION(:,:) , POINTER , CONTIGUOUS :: ZH2F_EAST,ZH2F_WEST,ZH2F_NORTH,ZH2F_SOUTH
+
+if ( NPROC == 1 ) RETURN
+
+!$acc data present ( PSRC ) &
+!$acc present (ZNORTH2F_IN, ZSOUTH2F_IN, ZWEST2F_IN, ZEAST2F_IN) &
+!$acc present (ZNORTH2F_OUT, ZSOUTH2F_OUT, ZWEST2F_OUT, ZEAST2F_OUT)
+!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+LX = .TRUE.
+LY = .TRUE.
+
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+INB_REQ = 0
+
+!
+! Post the recieve of Zxxxx_IN buffer first via MPI(Gpu_direct)
+!
+
+IF (LX) THEN
+   IF (.NOT. GWEST) THEN
+#ifdef MNH_GPUDIRECT
+      !$acc host_data use_device(ZWEST2F_OUT)
+#endif
+      INB_REQ = INB_REQ + 1
+      CALL MPI_IRECV(ZWEST2F_OUT,SIZE(ZWEST2F_OUT),MNHREAL_MPI,NP_WEST-1,1000+IS_EAST,NMNH_COMM_WORLD,IREQ(INB_REQ),IERR)
+#ifdef MNH_GPUDIRECT
+      !$acc end host_data
+#endif
+   END IF
+   IF (.NOT.GEAST) THEN 
+#ifdef MNH_GPUDIRECT
+      !$acc host_data use_device(ZEAST2F_OUT)
+#endif
+      INB_REQ = INB_REQ + 1
+      CALL MPI_IRECV(ZEAST2F_OUT,SIZE(ZEAST2F_OUT),MNHREAL_MPI,NP_EAST-1,1000+IS_WEST,NMNH_COMM_WORLD,IREQ(INB_REQ),IERR)
+#ifdef MNH_GPUDIRECT
+      !$acc end host_data
+#endif
+   ENDIF
+END IF
+
+IF (LY) THEN
+   IF (.NOT.GSOUTH) THEN
+#ifdef MNH_GPUDIRECT
+      !$acc host_data use_device(ZSOUTH2F_OUT)
+#endif
+      INB_REQ = INB_REQ + 1
+      CALL MPI_IRECV(ZSOUTH2F_OUT,SIZE(ZSOUTH2F_OUT),MNHREAL_MPI,NP_SOUTH-1,1000+IS_NORTH,NMNH_COMM_WORLD,IREQ(INB_REQ),IERR)
+#ifdef MNH_GPUDIRECT
+      !$acc end host_data
+#endif
+   ENDIF
+   IF (.NOT.GNORTH) THEN
+#ifdef MNH_GPUDIRECT
+      !$acc host_data use_device(ZNORTH2F_OUT)
+#endif
+      INB_REQ = INB_REQ + 1
+      CALL MPI_IRECV(ZNORTH2F_OUT,SIZE(ZNORTH2F_OUT),MNHREAL_MPI,NP_NORTH-1,1000+IS_SOUTH,NMNH_COMM_WORLD,IREQ(INB_REQ),IERR)
+#ifdef MNH_GPUDIRECT
+      !$acc end host_data
+#endif
+   ENDIF
+END IF
+
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+!Copy the halo on the device PSRC to Zxxxx_IN
+
+IF (LX) THEN
+   IF (.NOT. GWEST) THEN
+   !$acc kernels async(IS_WEST)
+      ZWEST2F_IN ( IIB:IIB+IHALO2_1  ,    IJB:IJE  , : )  = PSRC( IIB:IIB+IHALO2_1  ,  IJB:IJE  , : )
+!!$      ZWEST2F_IN ( : , : )  = PSRC( IIB+1  , : , : )
+   !$acc end kernels
+      END IF
+   IF (.NOT.GEAST) THEN
+   !$acc kernels async(IS_EAST)
+      ZEAST2F_IN ( IIE-IHALO2_1:IIE  ,    IJB:IJE  , : )  = PSRC( IIE-IHALO2_1:IIE  ,  IJB:IJE  , : )
+!!$      ZEAST2F_IN ( : , : )  = PSRC( IIE-1 ,  :  , : )
+   !$acc end kernels
+      ENDIF
+END IF
+IF (LY) THEN
+   IF (.NOT.GSOUTH) THEN
+   !$acc kernels async(IS_SOUTH)
+   ZSOUTH2F_IN ( IIB:IIE  ,    IJB:IJB+IHALO2_1  , : ) = PSRC( IIB:IIE  ,    IJB:IJB+IHALO2_1  , : )
+!!$      ZSOUTH2F_IN ( : , : ) = PSRC( : , IJB+1 , : )
+   !$acc end kernels
+      ENDIF
+   IF (.NOT.GNORTH) THEN
+   !$acc kernels async(IS_NORTH)
+      ZNORTH2F_IN ( IIB:IIE  ,    IJE-IHALO2_1:IJE  , : ) = PSRC( IIB:IIE  ,    IJE-IHALO2_1:IJE  , : )
+!!$      ZNORTH2F_IN ( : , : ) = PSRC( : , IJE-1  , : )      
+   !$acc end kernels
+   ENDIF
+ENDIF
+!$acc wait
+
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!
+! Send  Zxxxx2F_IN buffer via MPI(Gpu_direct) or copy to host
+!
+IF (LX) THEN
+   IF (.NOT. GWEST) THEN
+#ifdef MNH_GPUDIRECT
+      !$acc host_data use_device(ZWEST2F_IN)
+#else
+      !$acc update host(ZWEST2F_IN)
+#endif
+      INB_REQ = INB_REQ + 1
+      CALL MPI_ISEND(ZWEST2F_IN,SIZE(ZWEST2F_IN)  ,MNHREAL_MPI,NP_WEST-1,1000+IS_WEST,NMNH_COMM_WORLD,IREQ(INB_REQ),IERR)
+#ifdef MNH_GPUDIRECT
+      !$acc end host_data
+#endif
+   END IF
+   IF (.NOT.GEAST) THEN
+#ifdef MNH_GPUDIRECT
+      !$acc host_data use_device(ZEAST2F_IN)
+#else
+      !$acc update host(ZEAST2F_IN)
+#endif
+      INB_REQ = INB_REQ + 1
+      CALL MPI_ISEND(ZEAST2F_IN,SIZE(ZEAST2F_IN)  ,MNHREAL_MPI,NP_EAST-1,1000+IS_EAST,NMNH_COMM_WORLD,IREQ(INB_REQ),IERR)
+#ifdef MNH_GPUDIRECT
+      !$acc end host_data
+#endif
+   ENDIF
+END IF
+
+IF (LY) THEN
+   IF (.NOT.GSOUTH) THEN
+#ifdef MNH_GPUDIRECT
+      !$acc host_data use_device(ZSOUTH2F_IN)
+#else
+      !$acc update host(ZSOUTH2F_IN)
+#endif
+      INB_REQ = INB_REQ + 1
+      CALL MPI_ISEND(ZSOUTH2F_IN,SIZE(ZSOUTH2F_IN)  ,MNHREAL_MPI,NP_SOUTH-1,1000+IS_SOUTH,NMNH_COMM_WORLD,IREQ(INB_REQ),IERR)
+#ifdef MNH_GPUDIRECT
+      !$acc end host_data
+#endif
+   ENDIF
+   IF (.NOT.GNORTH) THEN
+#ifdef MNH_GPUDIRECT
+      !$acc host_data use_device(ZNORTH2F_IN)
+#else
+      !$acc update host(ZNORTH2F_IN)
+#endif
+      INB_REQ = INB_REQ + 1
+      CALL MPI_ISEND(ZNORTH2F_IN,SIZE(ZNORTH2F_IN)  ,MNHREAL_MPI,NP_NORTH-1,1000+IS_NORTH,NMNH_COMM_WORLD,IREQ(INB_REQ),IERR)
+#ifdef MNH_GPUDIRECT
+      !$acc end host_data
+#endif
+   ENDIF   
+ENDIF
+
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+IF ( INB_REQ > 0 ) THEN
+   CALL MPI_WAITALL(INB_REQ,IREQ,MPI_STATUSES_IGNORE,IERR)
+END IF
+
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+! Update halo in PSRC + %HALO2 
+
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+
+IF (LX) THEN
+   IF (.NOT.GWEST) THEN
+#ifndef MNH_GPUDIRECT
+   !$acc update device(ZWEST2F_OUT) async(IS_WEST)
+#endif
+   ZH2F_WEST => TP_PSRC_HALO2F_ll%HALO2%WEST  
+   !$acc kernels async(IS_WEST)
+   PSRC( 1:IIB-1  ,      IJB:IJE      , : ) = ZWEST2F_OUT( 1:IIB-1  ,   IJB:IJE    , : )
+   ZH2F_WEST( IJB:IJE , : ) = ZWEST2F_OUT( IIB-2, IJB:IJE , : )      
+   !$acc end kernels
+   ENDIF
+   IF (.NOT.GEAST) THEN
+#ifndef MNH_GPUDIRECT
+   !$acc update device(ZEAST2F_OUT) async(IS_EAST)
+#endif
+   ZH2F_EAST => TP_PSRC_HALO2F_ll%HALO2%EAST
+   !$acc kernels async(IS_EAST)
+   PSRC( IIE+1:IIU  ,      IJB:IJE      , : ) = ZEAST2F_OUT( IIE+1:IIU  ,   IJB:IJE    , : )
+   ZH2F_EAST( IJB:IJE , : ) = ZEAST2F_OUT( IIE+2 , IJB:IJE , : )
+   !$acc end kernels
+   ENDIF
+END IF
+IF (LY) THEN
+   IF (.NOT.GSOUTH) THEN
+#ifndef MNH_GPUDIRECT
+   !$acc update device(ZSOUTH2F_OUT) async(IS_SOUTH)
+#endif
+   ZH2F_SOUTH => TP_PSRC_HALO2F_ll%HALO2%SOUTH    
+   !$acc kernels async(IS_SOUTH)
+   PSRC(      IIB:IIE       ,  1:IJB-1 , : ) = ZSOUTH2F_OUT(  IIB:IIE     , 1:IJB-1  , : )
+   ZH2F_SOUTH( IIB:IIE , : ) = ZSOUTH2F_OUT( IIB:IIE , IJB-2 , : )  
+   !$acc end kernels
+   ENDIF
+   IF (.NOT.GNORTH) THEN
+#ifndef MNH_GPUDIRECT
+   !$acc update device(ZNORTH2F_OUT) async(IS_NORTH)
+#endif
+   ZH2F_NORTH => TP_PSRC_HALO2F_ll%HALO2%NORTH
+   !$acc kernels async(IS_NORTH)
+   PSRC(      IIB:IIE       , IJE+1:IJU , : ) = ZNORTH2F_OUT (  IIB:IIE     , IJE+1:IJU  , : )
+   ZH2F_NORTH( IIB:IIE , : ) = ZNORTH2F_OUT ( IIB:IIE , IJE+2 , : )      
+   !$acc end kernels
+   ENDIF
+END IF
+!$acc wait
+
+!$acc end data
+
+END SUBROUTINE GET_HALO2_DF
+!
+!     ###################################################
+      SUBROUTINE GET_HALO2_D(PSRC, TP_PSRC_HALO2_ll, HNAME)
+!     ###################################################
+!
+USE MODE_ll
+USE MODD_ARGSLIST_ll, ONLY : LIST_ll, HALO2LIST_ll
+USE MODI_GET_HALO, ONLY : GET_HALO_D,GET_HALO_DD,GET_HALO2_DD
+!
+IMPLICIT NONE
+!
+REAL, DIMENSION(:,:,:), INTENT(INOUT)  :: PSRC    ! variable at t
+TYPE(HALO2LIST_ll), POINTER         :: TP_PSRC_HALO2_ll          ! halo2 for SRC
+character(len=*), optional, intent(in) :: HNAME ! Name of the field to be added
+!
+character(len=:), allocatable    :: yname
+INTEGER                          :: IIU,IJU,IKU            ! domain sizes
+TYPE(LIST_ll)     , POINTER      :: TZ_PSRC_ll               ! halo
+INTEGER                          :: IERROR                 ! error return code 
+!
+IIU = SIZE(PSRC,1)
+IJU = SIZE(PSRC,2)
+IKU = SIZE(PSRC,3)
+
+if ( present ( hname ) ) then
+  yname = hname
+else
+  yname = 'PSRC'
+end if
+
+CALL GET_HALO_DD(PSRC,HNAME=yname)
+
+!!$NULLIFY( TZ_PSRC_ll,TP_PSRC_HALO2_ll)
+!!$CALL INIT_HALO2_ll(TP_PSRC_HALO2_ll,1,IIU,IJU,IKU)
+!
+CALL GET_HALO2_DD(PSRC,TP_PSRC_HALO2_ll,'GET_HALO2_DD::'//trim( yname ) )
+!
+!   clean local halo list , must be done outside
 !
 !!$CALL CLEANLIST_ll(TZ_PSRC_ll)
 !
diff --git a/src/ZSOLVER/ini_modeln.f90 b/src/ZSOLVER/ini_modeln.f90
index 8203f0ada7d3d47b9a065697b8587553b551aa77..7fa50a868f56b4f03f92f506a153227281417929 100644
--- a/src/ZSOLVER/ini_modeln.f90
+++ b/src/ZSOLVER/ini_modeln.f90
@@ -786,6 +786,7 @@ ALLOCATE(XTHT(IIU,IJU,IKU))     ; XTHT = 0.0
 ALLOCATE(XRUS(IIU,IJU,IKU))     ; XRUS = 0.0
 ALLOCATE(XRVS(IIU,IJU,IKU))     ; XRVS = 0.0
 ALLOCATE(XRWS(IIU,IJU,IKU))     ; XRWS = 0.0
+!$acc enter data copyin(XRUS,XRVS,XRWS)
 ALLOCATE(XRUS_PRES(IIU,IJU,IKU)); XRUS_PRES = 0.0
 ALLOCATE(XRVS_PRES(IIU,IJU,IKU)); XRVS_PRES = 0.0
 ALLOCATE(XRWS_PRES(IIU,IJU,IKU)); XRWS_PRES = 0.0
diff --git a/src/ZSOLVER/mass_leak.f90 b/src/ZSOLVER/mass_leak.f90
index 9ffe52c67bd2b3bceed6459854309e30d6eb4468..6a6b7206dc5a60d53ac683957f3e8c672ef06732 100644
--- a/src/ZSOLVER/mass_leak.f90
+++ b/src/ZSOLVER/mass_leak.f90
@@ -132,7 +132,7 @@ REAL, DIMENSION(:,:,:),        INTENT(INOUT) :: PRVS ! momentum  tendencies
 !
 !JUAN16
 REAL                               :: ZLEAK     ! total leak of mass
-REAL, ALLOCATABLE, DIMENSION (:,:) :: ZLEAK_W_2D , ZLEAK_E_2D , ZLEAK_S_2D , ZLEAK_N_2D
+REAL, SAVE , ALLOCATABLE, DIMENSION (:,:) :: ZLEAK_W_2D , ZLEAK_E_2D , ZLEAK_S_2D , ZLEAK_N_2D
 !JUAN16
 
 REAL                :: ZUSTOP     ! wind correction!
@@ -151,6 +151,7 @@ INTEGER             :: IINFO_ll   ! return code of parallel routine
 LOGICAL :: GWEST,GEAST,GSOUTH,GNORTH
 REAL    :: ZLEAK_W,ZLEAK_E,ZLEAK_S,ZLEAK_N
 !
+LOGICAL , SAVE :: GFIRST_CALL_MASS_LEAK = .TRUE.
 !-------------------------------------------------------------------------------
 !
 !*       1.    COMPUTE DIMENSIONS OF ARRAYS AND OTHER INDICES:
@@ -177,9 +178,19 @@ ZLEAK_W=0.
 ZLEAK_S=0.
 ZLEAK_N=0.
 !
-IF( HLBCY(1) /= 'CYCL' ) THEN
-   ALLOCATE( ZLEAK_W_2D(IIB:IIB,IJB:IJE))
-   ALLOCATE( ZLEAK_E_2D(IIE+1:IIE+1,IJB:IJE))   
+IF (GFIRST_CALL_MASS_LEAK) THEN
+   GFIRST_CALL_MASS_LEAK = .FALSE.
+   IF( HLBCX(1) /= 'CYCL' ) THEN
+      ALLOCATE( ZLEAK_W_2D(IIB:IIB,IJB:IJE))
+      ALLOCATE( ZLEAK_E_2D(IIE+1:IIE+1,IJB:IJE))
+   END IF
+   IF( HLBCY(1) /= 'CYCL' ) THEN
+      ALLOCATE( ZLEAK_S_2D(IIB:IIE,IJB:IJB))
+      ALLOCATE( ZLEAK_N_2D(IIB:IIE,IJE+1:IJE+1))
+   END IF
+END IF
+!
+IF( HLBCX(1) /= 'CYCL' ) THEN
    !$acc kernels async
    ZLEAK_W_2D = 0.0   
    IF( GWEST ) THEN
@@ -209,8 +220,6 @@ IF( HLBCY(1) /= 'CYCL' ) THEN
 END IF
 !
 IF( HLBCY(1) /= 'CYCL' ) THEN
-   ALLOCATE( ZLEAK_S_2D(IIB:IIE,IJB:IJB))
-   ALLOCATE( ZLEAK_N_2D(IIB:IIE,IJE+1:IJE+1))
    !
    !$acc kernels async
    ZLEAK_S_2D = 0.0 
@@ -242,10 +251,6 @@ IF( HLBCY(1) /= 'CYCL' ) THEN
 END IF
 !
 ZLEAK = ZLEAK_E + ZLEAK_W + ZLEAK_S + ZLEAK_N
-!!$ZLEAK = ZLEAK_E
-!!$ZLEAK = ZLEAK + ZLEAK_W
-!!$ZLEAK = ZLEAK + ZLEAK_S
-!!$ZLEAK = ZLEAK + ZLEAK_N
 !
 !CALL REDUCESUM_ll(ZLEAK,IINFO_ll)	! we do the reducesum_ll in SUM_DD_R2_ll so we do not do it here
 !
diff --git a/src/ZSOLVER/p_abs.f90 b/src/ZSOLVER/p_abs.f90
new file mode 100644
index 0000000000000000000000000000000000000000..adfa745cb1665ad351177b31e3b00abef6d583b3
--- /dev/null
+++ b/src/ZSOLVER/p_abs.f90
@@ -0,0 +1,439 @@
+!MNH_LIC Copyright 1994-2014 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_P_ABS
+!     #################
+!
+INTERFACE
+!
+      SUBROUTINE P_ABS (KRR, KRRL, KRRI, PDRYMASST, PREFMASS, PMASS_O_PHI0, &
+                        PTHT, PRT, PRHODJ, PRHODREF, PTHETAV, PTHVREF,      &
+                        PRVREF, PEXNREF, PPHIT )
+!  
+IMPLICIT NONE
+!
+INTEGER,                  INTENT(IN)    :: KRR  ! Total number of water var.
+INTEGER,                  INTENT(IN)    :: KRRL ! Number of liquid water var.
+INTEGER,                  INTENT(IN)    :: KRRI ! Number of ice water var.
+!
+REAL,                     INTENT(IN)    :: PDRYMASST   ! Mass of dry air and of
+REAL,                     INTENT(IN)    :: PREFMASS    ! the ref. atmosphere
+                                          !  contained in the simulation domain
+REAL,                     INTENT(IN)    :: PMASS_O_PHI0 !    Mass / Phi0 
+!
+REAL, DIMENSION(:,:,:),   INTENT(IN)    :: PTHT        ! Temperature and water
+REAL, DIMENSION(:,:,:,:), INTENT(IN)    :: PRT         !  variables at time t
+!
+REAL, DIMENSION(:,:,:),   INTENT(IN)    :: PRHODJ      ! dry Density * Jacobian
+REAL, DIMENSION(:,:,:),   INTENT(IN)    :: PTHETAV     ! virtual potential temp.
+REAL, DIMENSION(:,:,:),   INTENT(IN)    :: PRHODREF    ! dry Density
+REAL, DIMENSION(:,:,:),   INTENT(IN)    :: PTHVREF     ! Virtual Temperature
+                                                  ! of the reference state
+REAL, DIMENSION(:,:,:),   INTENT(IN)    :: PRVREF ! vapor mixing ratio 
+                                       ! for the reference state 
+REAL, DIMENSION(:,:,:),   INTENT(IN)    :: PEXNREF! Exner function of the
+                                                  ! reference state
+!
+REAL, DIMENSION(:,:,:),   INTENT(INOUT) :: PPHIT  ! Perturbation of
+               ! either the Exner function Pi or Pi * Cpd * THvref
+!
+!
+END SUBROUTINE P_ABS
+!
+END INTERFACE
+!
+END MODULE MODI_P_ABS
+!     #######################################################################
+      SUBROUTINE P_ABS (KRR, KRRL, KRRI, PDRYMASST, PREFMASS, PMASS_O_PHI0, &
+		                PTHT, PRT, PRHODJ, PRHODREF, PTHETAV, PTHVREF,      &
+                        PRVREF, PEXNREF, PPHIT )
+!     #######################################################################
+!
+!!****  *P_ABS * - routine to compute the absolute Exner pressure deviation PHI
+!!
+!!    PURPOSE
+!!    -------
+!!      The purpose of this routine is to compute the absolute Exner
+!!      pressure Pi ( or Pi multiplied by Cpd*Thetavref) deviation PHI, 
+!!      which is not determined for an anelatic system. 
+!!      It also diagnozes the total mass of water Mw.
+!!
+!!     
+!!**  METHOD
+!!    ------
+!!      The knowledge of the total mass of dry air Md and of water Mw 
+!!    (including all water categories), allowed to diagnoze the absolute  
+!!    Exner pressure PHI. The equation of state is not anymore linearized.
+!!
+!!    EXTERNAL
+!!    --------
+!!      none
+!!
+!!    IMPLICIT ARGUMENTS
+!!    ------------------
+!!      Module MODD_CST 
+!!           XRD,XRV      Gaz constant for dry air Rd and wator vapor Rv
+!!           XCPD         Specific heat at constant pressure for dry air Cp
+!!           XP00         Reference pressure  
+!!
+!!      Module MODD_PARAMETERS : contains parameters commun to all models
+!!        JPHEXT : Horizontal EXTernal points number (JPHEXT=1 for this version)
+!!        JPVEXT : Vertical   EXTernal points number (JPVEXT=1 for this version)
+!!      Module MODD_CONF  :
+!!        CEQNSYS
+!!
+!!    REFERENCE
+!!    ---------
+!!      Book1 and book2 of documentation ( routine P_ABS )
+!!
+!!    AUTHOR
+!!    ------
+!!	J.-P. Lafore     * Meteo France *
+!!
+!!    MODIFICATIONS
+!!    -------------
+!!      Original    30/12/94 
+!!      J.P. Lafore 10/02/95   Bug correction in ZMASSGUESS
+!!      J. Stein    16/03/95   Remove R from the historical variables
+!!      J.P. Lafore 14/01/97   Introduction of 2 anelastic systems:
+!!                              Modified Anelastic Equation and one derived 
+!!                              from Durran (1989), MAE and DUR respectively
+!!                  15/06/98  (D.Lugato, R.Guivarch) Parallelisation
+!!      J. Colin       07/13  Add LBOUSS
+!-------------------------------------------------------------------------------
+!
+!*       0.    DECLARATIONS 
+!              ------------
+!
+USE MODD_CST
+USE MODD_CONF
+USE MODD_PARAMETERS
+USE MODD_REF, ONLY : LBOUSS
+!
+USE MODE_ll
+!JUAN
+USE MODE_REPRO_SUM
+!JUAN
+!
+#ifdef MNH_BITREP
+USE MODI_BITREP
+#endif
+#ifdef MNH_OPENACC
+USE MODE_MNH_ZWORK , ONLY : MNH_ALLOCATE_ZT3D , MNH_REL_ZT3D
+#endif
+!  
+IMPLICIT NONE
+!  
+!*       0.1   Declarations of dummy arguments :
+!
+!
+INTEGER,                  INTENT(IN)    :: KRR  ! Total number of water var.
+INTEGER,                  INTENT(IN)    :: KRRL ! Number of liquid water var.
+INTEGER,                  INTENT(IN)    :: KRRI ! Number of ice water var.
+!
+REAL,                     INTENT(IN)    :: PDRYMASST   ! Mass of dry air and of
+REAL,                     INTENT(IN)    :: PREFMASS    ! the ref. atmosphere
+                                          !  contained in the simulation domain
+REAL,                     INTENT(IN)    :: PMASS_O_PHI0 !    Mass / Phi0 
+!
+REAL, DIMENSION(:,:,:),   INTENT(IN)    :: PTHT        ! Temperature and water
+REAL, DIMENSION(:,:,:,:), INTENT(IN)    :: PRT         !  variables at time t
+!
+REAL, DIMENSION(:,:,:),   INTENT(IN)    :: PRHODJ      ! dry Density * Jacobian
+REAL, DIMENSION(:,:,:),   INTENT(IN)    :: PTHETAV     ! virtual potential temp.
+REAL, DIMENSION(:,:,:),   INTENT(IN)    :: PRHODREF    ! dry Density
+REAL, DIMENSION(:,:,:),   INTENT(IN)    :: PTHVREF     ! Virtual Temperature
+                                                  ! of the reference state
+REAL, DIMENSION(:,:,:),   INTENT(IN)    :: PRVREF ! vapor mixing ratio 
+                                       ! for the reference state 
+REAL, DIMENSION(:,:,:),   INTENT(IN)    :: PEXNREF! Exner function of the
+                                                  ! reference state
+!
+REAL, DIMENSION(:,:,:),   INTENT(INOUT) :: PPHIT  ! Perturbation of
+               ! either the Exner function Pi or Pi * Cpd * THvref
+!
+!
+!*       0.2   Declarations of local variables :
+!
+INTEGER             :: IKU       ! Upper dimension in z direction
+INTEGER             :: IIB       ! indice I Beginning in x direction
+INTEGER             :: IJB       ! indice J Beginning in y direction
+INTEGER             :: IKB       ! indice K Beginning in z direction
+INTEGER             :: IIE       ! indice I End       in x direction 
+INTEGER             :: IJE       ! indice J End       in y direction 
+INTEGER             :: IKE       ! indice K End       in z direction 
+INTEGER             :: JI        ! Loop index in x direction
+INTEGER             :: JJ        ! Loop index in y direction      
+INTEGER             :: JK        ! Loop index in z direction       
+REAL     ::  ZP00_O_RD     ! = P00 /  Rd
+REAL     ::  ZCVD_O_RD     ! = Cvd /  Rd
+REAL     ::   ZRV_O_RD     ! = Rv  /  Rd
+REAL     ::  ZCVD_O_RDCPD  ! = Cvd / (Rd * Cpd)
+REAL     ::  ZMASS_O_PI    !    Mass / Pi0 
+REAL     ::  ZMASSGUESS    ! guess of mass resulting of the pressure function
+                                       ! provided by the pressure solveur, to an arbitary constant
+REAL     ::  ZWATERMASST   ! Total mass of water Mw
+!JUAN16
+REAL, SAVE , ALLOCATABLE, DIMENSION(:,:)     :: ZMASS_O_PI_2D,ZMASSGUESS_2D,ZWATERMASST_2D
+!JUAN16
+REAL     ::  ZPI0          ! constant to retrieve the absolute Exner pressure
+INTEGER  ::  JWATER        ! loop index on the different types of water
+REAL,  DIMENSION(:,:,:) , POINTER , CONTIGUOUS &
+         ::  ZRTOT, ZRHOREF, ZWORK
+INTEGER :: IZRTOT, IZRHOREF, IZWORK
+REAL     ::  ZPHI0
+!
+INTEGER  :: IINFO_ll
+!
+LOGICAL :: GPRVREF0
+!
+INTEGER         :: IIU,IJU
+!
+LOGICAL, SAVE :: GFIRST_CALL_P_ABS = .TRUE.
+!
+!-------------------------------------------------------------------------------
+!
+!*       1.    COMPUTE DIMENSIONS OF ARRAYS AND OTHER INDICES:
+!              ----------------------------------------------
+!
+IIU = SIZE(PTHT,1)
+IJU = SIZE(PTHT,2)
+IKU = SIZE(PTHT,3)
+IKB = 1 + JPVEXT
+IKE = IKU - JPVEXT
+!
+CALL GET_INDICE_ll(IIB,IJB,IIE,IJE)
+!
+GPRVREF0 =  ( SIZE(PRVREF,1) == 0 )
+!
+IF (GFIRST_CALL_P_ABS) THEN
+   GFIRST_CALL_P_ABS = .FALSE. 
+   ALLOCATE(ZMASS_O_PI_2D(IIB:IIE,IJB:IJE))
+   ALLOCATE(ZMASSGUESS_2D(IIB:IIE,IJB:IJE))
+   ALLOCATE(ZWATERMASST_2D(IIB:IIE,IJB:IJE))
+END IF
+!
+ZP00_O_RD = XP00 / XRD
+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_ZT3D(ZRTOT,IIU,IJU,IKU  )
+IZRHOREF = MNH_ALLOCATE_ZT3D(ZRHOREF,IIU,IJU,IKU  )
+IZWORK   = MNH_ALLOCATE_ZT3D(ZWORK,IIU,IJU,IKU  )
+#endif
+
+!-------------------------------------------------------------------------------
+!
+!
+!*       2.     COMPUTES THE ABSOLUTE EXNER FUNCTION (MAE+ DUR) 
+!	        -----------------------------------------------
+!
+!       
+!
+IF ( CEQNSYS=='DUR' .OR. CEQNSYS=='MAE' ) THEN
+  !
+  !$acc kernels  
+  IF(KRR > 0) THEN
+  !
+  !   compute the mixing ratio of the total water (ZRTOT)
+    ZRTOT(:,:,:) = PRT(:,:,:,1)
+    !$acc loop seq 
+    DO JWATER = 2 , 1+KRRL+KRRI                
+      ZRTOT(:,:,:) = ZRTOT(:,:,:) + PRT(:,:,:,JWATER)
+    END DO
+  ELSE
+    ZRTOT(:,:,:) = 0.
+  END IF
+  !
+  ZMASSGUESS_2D  = 0.  
+  ZMASS_O_PI_2D  = 0.      
+  ZWATERMASST_2D = 0.
+  !$acc end kernels
+!
+  IF ( CEQNSYS == 'DUR' ) THEN
+    !$acc kernels 
+    ! compute the Jacobian in ZWORK
+    IF ( GPRVREF0 ) THEN
+      ZWORK(:,:,:)=  PRHODJ * XTH00  / ( PRHODREF * PTHVREF )
+    ELSE
+      ZWORK(:,:,:)=PRHODJ * XTH00  &
+           / ( PRHODREF * PTHVREF * (1. + PRVREF) )
+    END IF
+    !
+    !$acc loop seq
+    DO JK = IKB,IKE
+      !$acc loop independent collapse(2) 
+      DO JJ = IJB,IJE
+        DO JI = IIB,IIE
+           ZMASSGUESS_2D(JI,JJ)  = ZMASSGUESS_2D(JI,JJ) +                          &
+#ifndef MNH_OPENACC
+                (PEXNREF(JI,JJ,JK)+PPHIT(JI,JJ,JK))**ZCVD_O_RD   &
+#else
+                BR_POW((PEXNREF(JI,JJ,JK)+PPHIT(JI,JJ,JK)),ZCVD_O_RD) &
+#endif
+             * ZWORK(JI,JJ,JK) / PTHETAV(JI,JJ,JK)
+          ZMASS_O_PI_2D(JI,JJ)  = ZMASS_O_PI_2D(JI,JJ) + ZWORK(JI,JJ,JK) / PTHETAV(JI,JJ,JK)
+          ZWATERMASST_2D(JI,JJ) = ZWATERMASST_2D(JI,JJ) +       &
+            ZRTOT(JI,JJ,JK) * ZWORK(JI,JJ,JK) * PRHODREF(JI,JJ,JK)
+        END DO
+      END DO
+    END DO
+    !$acc end kernels
+    !
+  ELSE
+    DO JK = IKB,IKE
+      DO JJ = IJB,IJE
+        DO JI = IIB,IIE
+          ZMASSGUESS_2D(JI,JJ)  = ZMASSGUESS_2D(JI,JJ) +                               &
+             (PEXNREF(JI,JJ,JK)+PPHIT(JI,JJ,JK))**ZCVD_O_RD        &
+            * PRHODJ(JI,JJ,JK) / PRHODREF(JI,JJ,JK)                &
+            / PTHETAV(JI,JJ,JK)
+          ZMASS_O_PI_2D(JI,JJ)  = ZMASS_O_PI_2D(JI,JJ) +                               &
+            PRHODJ(JI,JJ,JK) / PRHODREF(JI,JJ,JK) / PTHETAV(JI,JJ,JK)
+          ZWATERMASST_2D(JI,JJ) = ZWATERMASST_2D(JI,JJ) + ZRTOT(JI,JJ,JK) * PRHODJ(JI,JJ,JK) 
+        END DO
+      END DO
+    END DO
+  END IF
+!
+  !
+  ZMASSGUESS  = SUM_DD_R2_ll(ZMASSGUESS_2D)
+  ZMASS_O_PI  = SUM_DD_R2_ll(ZMASS_O_PI_2D)
+  ZWATERMASST = SUM_DD_R2_ll(ZWATERMASST_2D)
+  !
+  ZMASS_O_PI  = ZMASS_O_PI*ZP00_O_RD*ZCVD_O_RD
+  ZPI0 = (PDRYMASST + ZWATERMASST - ZP00_O_RD*ZMASSGUESS ) / ZMASS_O_PI
+  !$acc kernels
+  PPHIT(:,:,:) = PPHIT(:,:,:) + ZPI0
+  !$acc end kernels
+!
+!
+  !
+  !          Second iteration
+  !
+  !$acc kernels
+  ZMASSGUESS_2D  = 0.
+  !$acc end kernels
+  IF ( CEQNSYS == 'DUR' ) THEN
+     !$acc kernels
+     !$acc loop seq 
+     DO JK = IKB,IKE
+        !$acc loop independent collapse(2)  
+        DO JJ = IJB,IJE
+           DO JI = IIB,IIE
+              ZMASSGUESS_2D(JI,JJ)  = ZMASSGUESS_2D(JI,JJ) +                               &
+                   (PEXNREF(JI,JJ,JK)+PPHIT(JI,JJ,JK))**ZCVD_O_RD          &
+                   * ZWORK(JI,JJ,JK) / PTHETAV(JI,JJ,JK)
+           END DO
+        END DO
+     END DO
+     !$acc end kernels
+  ELSE
+    DO JK = IKB,IKE
+      DO JJ = IJB,IJE
+        DO JI = IIB,IIE
+          ZMASSGUESS_2D(JI,JJ)  = ZMASSGUESS_2D(JI,JJ) +                                &
+            (PEXNREF(JI,JJ,JK)+PPHIT(JI,JJ,JK))**ZCVD_O_RD          &
+           * PRHODJ(JI,JJ,JK) / PRHODREF(JI,JJ,JK) / PTHETAV(JI,JJ,JK)
+        END DO
+      END DO
+    END DO
+  END IF
+!
+
+  ZMASSGUESS  = SUM_DD_R2_ll(ZMASSGUESS_2D)
+  !
+  ZPI0 = (PDRYMASST + ZWATERMASST - ZP00_O_RD*ZMASSGUESS ) / ZMASS_O_PI
+  !$acc kernels
+  PPHIT(:,:,:) = PPHIT(:,:,:) + ZPI0
+  !$acc end kernels
+!
+!
+ELSEIF( CEQNSYS == 'LHE' ) THEN
+!
+!-------------------------------------------------------------------------------
+!
+!
+!*       3.     COMPUTES THE ABSOLUTE PRESSURE FUNCTION (LHE) 
+!	        ---------------------------------------------
+!
+  !               compute the reference moist density
+  !
+  ZCVD_O_RDCPD = ZCVD_O_RD / XCPD
+  ZCVD_O_RD = (XCPD - XRD) / XRD
+  !
+  IF (LBOUSS) THEN
+    ZRHOREF(:,:,:) = PRHODREF(:,:,:)
+  ELSE
+    ZRHOREF(:,:,:) = PEXNREF(:,:,:) ** ZCVD_O_RD    &
+                  * XP00 / ( XRD * PTHVREF(:,:,:) )
+  ENDIF        
+  !
+  !
+  !               compute the virtual potential temperature 
+  !
+  !
+  IF(KRR > 0) THEN
+  !
+  !   compute the mixing ratio of the total water (ZRRTOT)
+    ZRV_O_RD = XRV / XRD
+    ZRTOT(:,:,:) = PRT(:,:,:,1)
+    !$acc loop seq
+    DO JWATER = 2 , 1+KRRL+KRRI                
+      ZRTOT(:,:,:) = ZRTOT(:,:,:) + PRT(:,:,:,JWATER)
+    END DO
+  !   compute the virtual potential temperature in ZWORK                 
+    ZWORK(:,:,:) = PTHT(:,:,:) * (1. + PRT(:,:,:,1) * ZRV_O_RD)  &
+                                / (1. + ZRTOT(:,:,:))
+  ELSE
+  !   compute the virtual potential temperature when water is absent
+    ZWORK(:,:,:)  = PTHT(:,:,:)
+    ZRTOT(:,:,:) = 0.
+  END IF
+  !
+  !
+  !               compute the absolute pressure function 
+  !
+  !
+  !
+  ZMASSGUESS_2D  = 0. 
+  ZWATERMASST_2D = 0.
+!
+  DO JK = IKB,IKE
+    DO JJ = IJB,IJE
+      DO JI = IIB,IIE
+        ZMASSGUESS_2D(JI,JJ)  = ZMASSGUESS_2D(JI,JJ) + ZRHOREF(JI,JJ,JK) /  PTHVREF(JI,JJ,JK) *   &
+                     (  ZWORK(JI,JJ,JK)                                       &
+                      - ZCVD_O_RDCPD * PPHIT(JI,JJ,JK) / PEXNREF(JI,JJ,JK)    &
+                     ) * PRHODJ(JI,JJ,JK) /  PRHODREF(JI,JJ,JK)
+        ZWATERMASST_2D(JI,JJ) = ZWATERMASST_2D(JI,JJ) + ZRTOT(JI,JJ,JK) * PRHODJ(JI,JJ,JK)
+      END DO
+    END DO
+  END DO
+  !
+  ZMASSGUESS  = SUM_DD_R2_ll(ZMASSGUESS_2D)
+  ZWATERMASST =  SUM_DD_R2_ll(ZWATERMASST_2D)
+  !
+  ZPHI0 = (PDRYMASST + ZWATERMASST - 2. * PREFMASS + ZMASSGUESS ) / PMASS_O_PHI0
+  PPHIT(:,:,:) = PPHIT(:,:,:) + ZPHI0
+  !
+END IF
+!
+#ifndef MNH_OPENACC
+DEALLOCATE (ZRTOT, ZRHOREF, ZWORK)
+#else
+CALL MNH_REL_ZT3D ( IZRTOT, IZRHOREF, IZWORK )
+#endif
+!-------------------------------------------------------------------------------
+!
+END SUBROUTINE P_ABS
diff --git a/src/ZSOLVER/ppm.f90 b/src/ZSOLVER/ppm.f90
new file mode 100644
index 0000000000000000000000000000000000000000..6c80487d465aecf2a6ddbc78f07daae49da0017f
--- /dev/null
+++ b/src/ZSOLVER/ppm.f90
@@ -0,0 +1,4897 @@
+!MNH_LIC Copyright 1994-2020 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.
+!-----------------------------------------------------------------
+! Modifications:
+!  P. Wautelet 05/2016-04/2018: new data structures and calls for I/O
+!  P. Wautelet 20/06/2019: OpenACC: correct intent of some dummy variables
+!  P. Wautelet 01/07/2019: OpenACC: optimisation of ppm_s0_x/y/z_d for GPU
+!  P. Wautelet 18/07/2019: OpenACC: remove use of macros for dif2x/y/z
+!-----------------------------------------------------------------
+#ifdef MNH_OPENACC
+!
+! inline shuman with macro
+! 
+!#define dxf(PDXF,PA) PDXF(1:IIU-1,:,:) = PA(2:IIU,:,:) - PA(1:IIU-1,:,:) ; PDXF(IIU,:,:)    = PDXF(2*JPHEXT,:,:) ! DXF(PDXF,PA)
+!#define  dyf(PDYF,PA) PDYF(:,1:IJU-1,:) = PA(:,2:IJU,:) - PA(:,1:IJU-1,:); PDYF(:,IJU,:) = PDYF(:,2*JPHEXT,:) !   DYF(PDYF,PA)
+!!#define dyf(PDYF,PA) PDYF(1:IIU,1:IJU-1,IKB:IKE) = PA(1:IIU,2:IJU,IKB:IKE) - PA(1:IIU,1:IJU-1,IKB:IKE); ! PDYF(1:IIU,IJU,IKB:IKE) = PDYF(1:IIU,2*JPHEXT,IKB:IKE) !   DYF(PDYF,PA)
+!#define dzf(PDZF,PA) PDZF(:,:,1:IKU-1) = PA(:,:,2:IKU) - PA(:,:,1:IKU-1) ; PDZF(:,:,IKU) = -999. ! DZF(PDZF,PA)
+!
+!#define mxm(PMXM,PA) PMXM(2:IIU,:,:) = 0.5*( PA(2:IIU,:,:)+PA(1:IIU-1,:,:) ) ; PMXM(1,:,:) = PMXM(IIU-2*JPHEXT+1,:,:) !  MXM(PMXM,PA)
+!!#define mym(PMYM,PA) PMYM(1:IIU,2:IJU,IKB:IKE) = 0.5*( PA(1:IIU,2:IJU,IKB:IKE)+PA(1:IIU,1:IJU-1,IKB:IKE) ) ; ! PMYM(1:IIU,1,IKB:IKE) = PMYM(1:IIU,IJU-2*JPHEXT+1,IKB:IKE) !  MYM(PMYM,PA)
+!#define mzm(PMZM,PA) PMZM(:,:,2:IKU) = 0.5*( PA(:,:,2:IKU)+PA(:,:,1:IKU-1) ) ; PMZM(:,:,1)    = -999. !  MZM(PMZM,PA)
+!#define mym(PMYM,PA) PMYM(:,2:IJU,:) = 0.5*( PA(:,2:IJU,:)+PA(:,1:IJU-1,:) ) ; PMYM(:,1,:) = PMYM(:,IJU-2*JPHEXT+1,:) !  MYM(PMYM,PA)
+!
+! #define dif2x(DQ,PQ) DQ(IIB:IIE,:,:)=0.5*(PQ(IIB+1:IIE+1,:,:)-PQ(IIB-1:IIE-1,:,:));\
+! DQ(IIB-1,:,:)=0.5*(PQ(IIB,:,:)-PQ(IIE-1,:,:));\
+! DQ(IIE+1,:,:)=0.5*(PQ(IIB+1,:,:)-PQ(IIE,:,:)) ! DIF2X(DQ,PQ)
+!
+! #define dif2y(DQ,PQ) DQ(1:IIU,IJB:IJE,IKB:IKE) = 0.5*(PQ(1:IIU,IJB+1:IJE+1,IKB:IKE) - PQ(1:IIU,IJB-1:IJE-1,IKB:IKE)) ; !
+! ! DQ(1:IIU,IJB-1,IKB:IKE) = 0.5*(PQ(1:IIU,IJB,IKB:IKE) - PQ(1:IIU,IJE-1,IKB:IKE)) ; \
+! DQ(1:IIU,IJE+1,IKB:IKE) = 0.5*(PQ(1:IIU,IJB+1,IKB:IKE) - PQ(1:IIU,IJE,IKB:IKE)) ! DIF2Y(DQ,PQ)
+!
+! #define dif2z(DQ,PQ) DQ(:,:,IKB:IKE) = 0.5*(PQ(:,:,IKB+1:IKE+1) - PQ(:,:,IKB-1:IKE-1)) ; \
+! DQ(:,:,IKB-1) = -DQ(:,:,IKB) ;\
+! DQ(:,:,IKE+1) = -DQ(:,:,IKE) ! DIF2Z(DQ,PQ)
+!
+#endif
+!     ###############
+      MODULE MODI_PPM
+!     ###############
+!
+INTERFACE
+!
+#ifndef MNH_OPENACC
+FUNCTION PPM_01_X(HLBCX, KGRID, PSRC, PCR, PRHO, PTSTEP) &
+               RESULT(PR)
+#else
+SUBROUTINE PPM_01_X(HLBCX, KGRID, PSRC, PCR, PRHO, PTSTEP, PR)
+#endif
+CHARACTER (LEN=4), DIMENSION(2), INTENT(IN) :: HLBCX  ! X direction LBC type
+!
+INTEGER,                INTENT(IN)  :: KGRID   ! C grid localisation
+!
+REAL, DIMENSION(:,:,:), INTENT(INOUT)  :: PSRC    ! variable at t
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PCR     ! Courant number
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PRHO  ! density
+REAL,                   INTENT(IN)  :: PTSTEP  ! Time step 
+!
+! output source term
+#ifndef MNH_OPENACC
+REAL, DIMENSION(SIZE(PCR,1),SIZE(PCR,2),SIZE(PCR,3)) :: PR
+#else
+REAL, DIMENSION(:,:,:), INTENT(OUT) :: PR
+#endif
+!
+#ifndef MNH_OPENACC
+END FUNCTION PPM_01_X
+#else
+END SUBROUTINE PPM_01_X
+#endif
+!
+!
+#ifndef MNH_OPENACC
+FUNCTION PPM_01_Y(HLBCY, KGRID, PSRC, PCR, PRHO, PTSTEP) &
+               RESULT(PR)
+#else
+SUBROUTINE PPM_01_Y(HLBCY, KGRID, PSRC, PCR, PRHO, PTSTEP, PR)
+#endif
+CHARACTER (LEN=4), DIMENSION(2), INTENT(IN) :: HLBCY  ! Y direction LBC type
+!
+INTEGER,                INTENT(IN)  :: KGRID   ! C grid localisation
+!
+REAL, DIMENSION(:,:,:), INTENT(INOUT)  :: PSRC    ! variable at t
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PCR     ! Courant number
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PRHO  ! density
+REAL,                   INTENT(IN)  :: PTSTEP  ! Time step 
+!
+! output source term
+#ifndef MNH_OPENACC
+REAL, DIMENSION(SIZE(PCR,1),SIZE(PCR,2),SIZE(PCR,3)) :: PR
+#else
+REAL, DIMENSION(:,:,:), INTENT(OUT) :: PR
+#endif
+!
+#ifndef MNH_OPENACC
+END FUNCTION PPM_01_Y
+#else
+END SUBROUTINE PPM_01_Y
+#endif
+!
+#ifndef MNH_OPENACC
+FUNCTION PPM_01_Z(KGRID, PSRC, PCR, PRHO, PTSTEP) RESULT(PR)
+#else
+SUBROUTINE PPM_01_Z(KGRID, PSRC, PCR, PRHO, PTSTEP, PR)
+#endif
+!
+INTEGER,                INTENT(IN)  :: KGRID   ! C grid localisation
+!
+#ifndef MNH_OPENACC
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PSRC    ! variable at t
+#else
+REAL, DIMENSION(:,:,:), INTENT(INOUT)  :: PSRC    ! variable at t
+#endif
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PCR     ! Courant number
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PRHO  ! density
+REAL,                   INTENT(IN)  :: PTSTEP  ! Time step 
+!
+! output source term
+#ifndef MNH_OPENACC
+REAL, DIMENSION(SIZE(PCR,1),SIZE(PCR,2),SIZE(PCR,3)) :: PR
+#else
+REAL, DIMENSION(:,:,:), INTENT(OUT) :: PR
+#endif
+!
+#ifndef MNH_OPENACC
+END FUNCTION PPM_01_Z
+#else
+END SUBROUTINE PPM_01_Z
+#endif
+!
+#ifndef MNH_OPENACC
+FUNCTION PPM_S0_X(HLBCX, KGRID, PSRC, PCR, PRHO, PTSTEP) &
+               RESULT(PR)
+#else
+SUBROUTINE PPM_S0_X(HLBCX, KGRID, PSRC, PCR, PRHO, PTSTEP &
+                   , PR)
+#endif
+CHARACTER (LEN=4), DIMENSION(2), INTENT(IN) :: HLBCX  ! X direction LBC type
+!
+INTEGER,                INTENT(IN)  :: KGRID   ! C grid localisation
+!
+REAL, DIMENSION(:,:,:), INTENT(INOUT)  :: PSRC    ! variable at t
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PCR     ! Courant number
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PRHO  ! density
+REAL,                   INTENT(IN)  :: PTSTEP  ! Time step 
+!
+! output source term
+#ifndef MNH_OPENACC
+REAL, DIMENSION(SIZE(PCR,1),SIZE(PCR,2),SIZE(PCR,3)) :: PR
+#else
+REAL, DIMENSION(:,:,:), INTENT(OUT) :: PR
+#endif
+!
+#ifndef MNH_OPENACC
+END FUNCTION PPM_S0_X
+#else
+END SUBROUTINE PPM_S0_X
+#endif
+!
+#ifndef MNH_OPENACC
+FUNCTION PPM_S0_Y(HLBCY, KGRID, PSRC, PCR, PRHO, PTSTEP) &
+               RESULT(PR)
+#else
+SUBROUTINE PPM_S0_Y(HLBCY, KGRID, PSRC, PCR, PRHO, PTSTEP &
+                   , PR)
+#endif
+!
+CHARACTER (LEN=4), DIMENSION(2), INTENT(IN) :: HLBCY ! Y direction LBC type
+!
+INTEGER,                INTENT(IN)  :: KGRID   ! C grid localisation
+!
+REAL, DIMENSION(:,:,:), INTENT(INOUT)  :: PSRC    ! variable at t
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PCR     ! Courant number
+!
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PRHO  ! density
+REAL,                   INTENT(IN)  :: PTSTEP  ! Time step 
+!
+! output source term
+#ifndef MNH_OPENACC
+REAL, DIMENSION(SIZE(PCR,1),SIZE(PCR,2),SIZE(PCR,3)) :: PR
+#else
+REAL, DIMENSION(:,:,:), INTENT(OUT) :: PR
+#endif
+!
+#ifndef MNH_OPENACC
+END FUNCTION PPM_S0_Y
+#else
+END SUBROUTINE PPM_S0_Y
+#endif
+!
+#ifndef MNH_OPENACC
+FUNCTION PPM_S0_Z(KGRID, PSRC, PCR, PRHO, PTSTEP) &
+               RESULT(PR)
+#else
+SUBROUTINE PPM_S0_Z(KGRID, PSRC, PCR, PRHO, PTSTEP &
+                   , PR)
+#endif
+!
+INTEGER,                INTENT(IN)  :: KGRID   ! C grid localisation
+!
+REAL, DIMENSION(:,:,:), INTENT(INOUT)  :: PSRC    ! variable at t
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PCR     ! Courant number
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PRHO  ! density
+REAL,                   INTENT(IN)  :: PTSTEP  ! Time step 
+!
+! output source term
+#ifndef MNH_OPENACC
+REAL, DIMENSION(SIZE(PCR,1),SIZE(PCR,2),SIZE(PCR,3)) :: PR
+#else
+REAL, DIMENSION(:,:,:), INTENT(OUT) :: PR
+#endif
+!
+#ifndef MNH_OPENACC
+END FUNCTION PPM_S0_Z
+#else
+END SUBROUTINE PPM_S0_Z
+#endif
+!
+#ifndef MNH_OPENACC
+FUNCTION PPM_S1_X(HLBCX, KGRID, PSRC, PCR, PRHO, PRHOT, &
+                        PTSTEP) RESULT(PR)
+#else
+SUBROUTINE PPM_S1_X(HLBCX, KGRID, PSRC, PCR, PRHO, PRHOT, &
+                        PTSTEP, PR)
+#endif
+!
+CHARACTER (LEN=4), DIMENSION(2), INTENT(IN) :: HLBCX  ! X direction LBC type
+!
+INTEGER,                INTENT(IN)  :: KGRID   ! C grid localisation
+!
+REAL, DIMENSION(:,:,:), INTENT(INOUT)  :: PSRC    ! variable at t
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PCR     ! Courant number
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PRHO  ! density
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PRHOT ! density at t+dt
+REAL,                   INTENT(IN)  :: PTSTEP  ! Time step 
+!
+! output source term
+#ifndef MNH_OPENACC
+REAL, DIMENSION(SIZE(PCR,1),SIZE(PCR,2),SIZE(PCR,3)) :: PR
+#else
+REAL, DIMENSION(:,:,:), INTENT(OUT) :: PR
+#endif
+!
+#ifndef MNH_OPENACC
+END FUNCTION PPM_S1_X
+#else
+END SUBROUTINE PPM_S1_X
+#endif
+!
+#ifndef MNH_OPENACC
+FUNCTION PPM_S1_Y(HLBCY, KGRID, PSRC, PCR, PRHO, PRHOT, &
+                        PTSTEP) RESULT(PR)
+#else
+SUBROUTINE PPM_S1_Y(HLBCY, KGRID, PSRC, PCR, PRHO, PRHOT, &
+                        PTSTEP, PR)
+#endif
+!
+CHARACTER (LEN=4), DIMENSION(2), INTENT(IN) :: HLBCY  ! X direction LBC type
+!
+INTEGER,                INTENT(IN)  :: KGRID   ! C grid localisation
+!
+REAL, DIMENSION(:,:,:), INTENT(INOUT)  :: PSRC    ! variable at t
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PCR     ! Courant number
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PRHO  ! density
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PRHOT ! density at t+dt
+REAL,                   INTENT(IN)  :: PTSTEP  ! Time step 
+!
+! output source term
+#ifndef MNH_OPENACC
+REAL, DIMENSION(SIZE(PCR,1),SIZE(PCR,2),SIZE(PCR,3)) :: PR
+#else
+REAL, DIMENSION(:,:,:), INTENT(OUT) :: PR
+#endif
+!
+#ifndef MNH_OPENACC
+END FUNCTION PPM_S1_Y
+#else
+END SUBROUTINE PPM_S1_Y
+#endif
+!
+#ifndef MNH_OPENACC
+FUNCTION PPM_S1_Z(KGRID, PSRC, PCR, PRHO, PRHOT, PTSTEP) &
+                        RESULT(PR)
+#else
+SUBROUTINE PPM_S1_Z(KGRID, PSRC, PCR, PRHO, PRHOT, PTSTEP, &
+                    PR)
+#endif
+!
+INTEGER,                INTENT(IN)  :: KGRID   ! C grid localisation
+!
+#ifndef MNH_OPENACC
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PSRC    ! variable at t
+#else
+REAL, DIMENSION(:,:,:), INTENT(INOUT)  :: PSRC    ! variable at t
+#endif
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PCR     ! Courant number
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PRHO  ! density
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PRHOT ! density at t+dt
+REAL,                   INTENT(IN)  :: PTSTEP  ! Time step 
+!
+! output source term
+#ifndef MNH_OPENACC
+REAL, DIMENSION(SIZE(PCR,1),SIZE(PCR,2),SIZE(PCR,3)) :: PR
+#else
+REAL, DIMENSION(:,:,:), INTENT(OUT) :: PR
+#endif
+!
+#ifndef MNH_OPENACC
+END FUNCTION PPM_S1_Z
+#else
+END SUBROUTINE PPM_S1_Z
+#endif
+!
+END INTERFACE
+!
+END MODULE MODI_PPM
+!
+!
+!-------------------------------------------------------------------------------
+!
+#ifdef MNH_OPENACC
+!     ########################################################################
+!!$      FUNCTION PPM_01_X(HLBCX, KGRID, PSRC, PCR, PRHO, PTSTEP) &
+!!$               RESULT(PR)
+      SUBROUTINE  PPM_01_X(HLBCX, KGRID, PSRC, PCR, PRHO, PTSTEP, PR)
+!     ########################################################################
+
+  USE MODE_MNH_ZWORK, ONLY : ZT3D, MNH_GET_ZT3D , MNH_REL_ZT3D
+  USE MODE_MNH_ZWORK, ONLY : IIU,IJU,IKU
+
+  IMPLICIT NONE
+!
+!*       0.1   Declarations of dummy arguments :
+!
+CHARACTER (LEN=4), DIMENSION(2), INTENT(IN) :: HLBCX  ! X direction LBC type
+!
+INTEGER,                INTENT(IN)  :: KGRID   ! C grid localisation
+!
+REAL, DIMENSION(:,:,:), INTENT(INOUT) :: PSRC    ! variable at t
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PCR     ! Courant number
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PRHO  ! density
+REAL,                   INTENT(IN)  :: PTSTEP  ! Time step 
+!
+! output source term
+REAL, DIMENSION(:,:,:), INTENT(OUT) :: PR
+
+INTEGER :: IZQL,IZQR,IZDQ,IZQ6,IZDMQ,IZQL0,IZQR0,IZQ60,IZFPOS,IZFNEG
+
+!$acc data present( PSRC, PCR, PRHO, PR )
+
+        CALL  MNH_GET_ZT3D(IZQL,IZQR,IZDQ,IZQ6,IZDMQ,IZQL0,IZQR0,IZQ60,IZFPOS,IZFNEG)
+
+        CALL  PPM_01_X_D(IIU,IJU,IKU,HLBCX, KGRID, &
+                     & PSRC, PCR, PRHO, PTSTEP, PR, &
+                     & ZT3D(:,:,:,IZQL),ZT3D(:,:,:,IZQR),ZT3D(:,:,:,IZDQ),ZT3D(:,:,:,IZQ6), &
+                     & ZT3D(:,:,:,IZDMQ),ZT3D(:,:,:,IZQL0),ZT3D(:,:,:,IZQR0), ZT3D(:,:,:,IZQ60), &
+                     & ZT3D(:,:,:,IZFPOS),ZT3D(:,:,:,IZFNEG) )
+
+        CALL  MNH_REL_ZT3D(IZQL,IZQR,IZDQ,IZQ6,IZDMQ,IZQL0,IZQR0,IZQ60,IZFPOS,IZFNEG)
+
+!$acc end data
+!
+CONTAINS
+!
+!     ########################################################################
+        SUBROUTINE  PPM_01_X_D(IIU,IJU,IKU,HLBCX, KGRID, &
+                     & PSRC, PCR, PRHO, PTSTEP, PR, &
+                     & ZQL,ZQR,ZDQ,ZQ6,ZDMQ,ZQL0,ZQR0,ZQ60,ZFPOS,ZFNEG)
+
+!     ########################################################################
+#else
+!     ########################################################################
+      FUNCTION PPM_01_X(HLBCX, KGRID, PSRC, PCR, PRHO, PTSTEP) &
+               RESULT(PR)
+!     ########################################################################
+#endif
+!!
+!!****  PPM_01_X - PPM_01 fully monotonic PPM advection scheme in X direction
+!!                 Colella notation
+!!
+!!    MODIFICATIONS
+!!    -------------
+!!    
+!!    11.5.2006.  T. Maric - original version
+!!      J.Escobar 21/03/2013: for HALOK comment all NHALO=1 test
+!!      J.Escobar 28/06/2018: limit computation on TAB(:,IJS:IJN,:) to avoid unneeded NaN
+!!      J.Escobr  16/07/2018: still NaN pb => reintroduce initialization of temporary local array
+!!
+!-------------------------------------------------------------------------------
+!
+USE MODD_CONF
+
+USE MODE_ll
+use mode_mppdb
+#ifdef MNH_OPENACC
+use mode_msg
+#endif
+
+#ifdef MNH_BITREP
+USE MODI_BITREP
+#endif
+USE MODI_GET_HALO
+#ifndef MNH_OPENACC
+USE MODI_SHUMAN
+#else
+USE MODI_SHUMAN_DEVICE
+#endif
+!
+IMPLICIT NONE
+!
+!*       0.1   Declarations of dummy arguments :
+!
+#ifdef MNH_OPENACC
+INTEGER                        , INTENT(IN) :: IIU,IJU,IKU
+#endif
+CHARACTER (LEN=4), DIMENSION(2), INTENT(IN) :: HLBCX  ! X direction LBC type
+!
+INTEGER,                INTENT(IN)  :: KGRID   ! C grid localisation
+!
+REAL, DIMENSION(:,:,:), INTENT(INOUT)  :: PSRC    ! variable at t
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PCR     ! Courant number
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PRHO  ! density
+REAL,                   INTENT(IN)  :: PTSTEP  ! Time step 
+!
+! output source term
+#ifndef MNH_OPENACC
+REAL, DIMENSION(SIZE(PCR,1),SIZE(PCR,2),SIZE(PCR,3)) :: PR
+#else
+REAL, DIMENSION(IIU,IJU,IKU), INTENT(OUT) :: PR
+#endif
+!
+!*       0.2   Declarations of local variables :
+!
+INTEGER:: IIB,IJB    ! Begining useful area in x,y,z directions
+INTEGER:: IIE,IJE    ! End useful area in x,y,z directions
+!
+integer :: ji, jj, jk
+#ifndef MNH_OPENACC
+integer :: iiu, iju, iku
+! terms used in parabolic interpolation, dmq, qL, qR, dq, q6
+REAL, DIMENSION(SIZE(PCR,1),SIZE(PCR,2),SIZE(PCR,3)) :: ZQL,ZQR
+REAL, DIMENSION(SIZE(PCR,1),SIZE(PCR,2),SIZE(PCR,3)) :: ZDQ,ZQ6
+REAL, DIMENSION(SIZE(PCR,1),SIZE(PCR,2),SIZE(PCR,3)) :: ZDMQ
+!
+! extra variables for the initial guess of parabolae parameters
+REAL, DIMENSION(SIZE(PCR,1),SIZE(PCR,2),SIZE(PCR,3)) :: ZQL0,ZQR0,ZQ60
+!
+! advection fluxes
+REAL, DIMENSION(SIZE(PCR,1),SIZE(PCR,2),SIZE(PCR,3)) :: ZFPOS, ZFNEG
+!
+!BEG JUAN PPM_LL
+INTEGER                          :: IJS,IJN
+!END JUAN PPM_LL
+#else
+INTEGER                          :: I,J,K 
+!
+!!$!
+!!$! terms used in parabolic interpolation, dmq, qL, qR, dq, q6
+REAL , DIMENSION(IIU,IJU,IKU) :: &
+  ZQL,ZQR, ZDQ,ZQ6, ZDMQ &
+!!$!
+!!$! extra variables for the initial guess of parabolae parameters
+  , ZQL0,ZQR0,ZQ60 &
+!!$!
+!!$! advection fluxes
+  , ZFPOS, ZFNEG
+!
+INTEGER                :: IJS,IJN
+#endif
+LOGICAL                :: GWEST , GEAST
+!-------------------------------------------------------------------------------
+
+!$acc data present( PSRC, PCR, PRHO, PR , &
+!$acc &             ZQL, ZQR, ZDQ, ZQ6, ZDMQ, ZQL0, ZQR0, ZQ60, ZFPOS, ZFNEG )
+
+IF (MPPDB_INITIALIZED) THEN
+  !Check all IN arrays
+  CALL MPPDB_CHECK(PCR, "PPM_01_X beg:PCR")
+  CALL MPPDB_CHECK(PRHO,"PPM_01_X beg:PRHO")
+  !Check all INOUT arrays
+  CALL MPPDB_CHECK(PSRC,"PPM_01_X beg:PSRC")
+END IF
+!
+!*       0.3.     COMPUTES THE DOMAIN DIMENSIONS
+!                 ------------------------------
+!
+CALL GET_INDICE_ll(IIB,IJB,IIE,IJE)
+IJS=IJB
+IJN=IJE
+!
+GWEST = LWEST_ll()
+GEAST = LEAST_ll()
+!
+!BEG JUAN PPM_LL
+!
+!*              initialise & update halo & halo2 for PSRC
+!
+#ifndef MNH_OPENACC
+iiu = size( PSRC, 1 )
+iju = size( PSRC, 2 )
+iku = size( PSRC, 3 )
+
+CALL GET_HALO(PSRC, HNAME='PSRC')
+!
+PR   (:,:,:) = PSRC(:,:,:)
+ZQL  (:,:,:) = PSRC(:,:,:)
+ZQR  (:,:,:) = PSRC(:,:,:)
+ZDQ  (:,:,:) = PSRC(:,:,:)
+ZQ6  (:,:,:) = PSRC(:,:,:)
+ZDMQ (:,:,:) = PSRC(:,:,:)
+ZQL0 (:,:,:) = PSRC(:,:,:)
+ZQR0 (:,:,:) = PSRC(:,:,:)
+ZQ60 (:,:,:) = PSRC(:,:,:)
+ZFPOS(:,:,:) = PSRC(:,:,:)
+ZFNEG(:,:,:) = PSRC(:,:,:)
+#else
+CALL GET_HALO_D(PSRC,HDIR="01_X", HNAME='PSRC')
+!
+!$acc kernels 
+!$acc loop independent collapse(3)
+  do jk = 1, iku
+    do jj = 1, iju
+      do ji = 1, iiu
+        PR   (ji, jj, jk ) = PSRC(ji, jj, jk )
+        ZQL  (ji, jj, jk ) = PSRC(ji, jj, jk )
+        ZQR  (ji, jj, jk ) = PSRC(ji, jj, jk )
+        ZDQ  (ji, jj, jk ) = PSRC(ji, jj, jk )
+        ZQ6  (ji, jj, jk ) = PSRC(ji, jj, jk )
+        ZDMQ (ji, jj, jk ) = PSRC(ji, jj, jk )
+        ZQL0 (ji, jj, jk ) = PSRC(ji, jj, jk )
+        ZQR0 (ji, jj, jk ) = PSRC(ji, jj, jk )
+        ZQ60 (ji, jj, jk ) = PSRC(ji, jj, jk )
+    end do
+  end do
+end do
+!
+#if 0
+ZFPOS(:,1:IJS,:)=PSRC(:,1:IJS,:)
+ZFNEG(:,1:IJS,:)=PSRC(:,1:IJS,:)
+ZFPOS(:,IJN:,:)=PSRC(:,IJN:,:)
+ZFNEG(:,IJN:,:)=PSRC(:,IJN:,:)
+#else
+ZFPOS(:,:,:) = PSRC(:,:,:)
+ZFNEG(:,:,:) = PSRC(:,:,:)
+#endif
+!$acc end kernels
+#endif
+!
+!-------------------------------------------------------------------------------
+!
+SELECT CASE ( HLBCX(1) ) ! X direction LBC type: (1) for left side
+!
+!        1.1   CYCLIC BOUNDARY CONDITIONS IN X DIRECTION
+!              -----------------------------------------
+!
+CASE ('CYCL','WALL')          ! In that case one must have HLBCX(1) == HLBCX(2)
+#ifdef MNH_OPENACC
+  call Print_msg( NVERB_ERROR, 'GEN', 'PPM_01_X', 'OpenACC: CYCL/WALL boundaries not yet implemented' )
+#endif
+!
+! calculate dmq
+   ZDMQ = DIF2X(PSRC)
+!
+! monotonize the difference followinq eq. 5 in Lin94
+!
+!BEG JUAN PPM_LL01
+!
+!  ZDMQ(i) = Fct[ ZDMQ(i),PSRC(i),PSRC(i-1),PSRC(i+1) ]
+!
+   ZDMQ(IIB:IIE,IJS:IJN,:) = &
+        SIGN( (MIN( ABS(ZDMQ(IIB:IIE,IJS:IJN,:)),2.0*(PSRC(IIB:IIE,IJS:IJN,:) - &
+        MIN(PSRC(IIB-1:IIE-1,IJS:IJN,:),PSRC(IIB:IIE,IJS:IJN,:),PSRC(IIB+1:IIE+1,IJS:IJN,:))),    &
+        2.0*(MAX(PSRC(IIB-1:IIE-1,IJS:IJN,:),PSRC(IIB:IIE,IJS:IJN,:),PSRC(IIB+1:IIE+1,IJS:IJN,:)) - &
+        PSRC(IIB:IIE,IJS:IJN,:)) )), ZDMQ(IIB:IIE,IJS:IJN,:) )
+!
+!  WEST BOUND
+!
+!!$   ZDMQ(IIB-1,:,:) = & 
+!!$        SIGN( (MIN( ABS(ZDMQ(IIB-1,:,:)), 2.0*(PSRC(IIB-1,:,:) - &
+!!$        MIN(PSRC(IIE-1,:,:),PSRC(IIB-1,:,:),PSRC(IIB,:,:))),   &
+!!$        2.0*(MAX(PSRC(IIE-1,:,:),PSRC(IIB-1,:,:),PSRC(IIB,:,:)) - &
+!!$        PSRC(IIB-1,:,:)) )), ZDMQ(IIB-1,:,:) )
+!
+!  EAST BOUND
+!
+!!$   ZDMQ(IIE+1,:,:) = &
+!!$        SIGN( (MIN( ABS(ZDMQ(IIE+1,:,:)), 2.0*(PSRC(IIE+1,:,:) - &
+!!$        MIN(PSRC(IIE,:,:),PSRC(IIE+1,:,:),PSRC(IIB+1,:,:))),  &
+!!$        2.0*(MAX(PSRC(IIE,:,:),PSRC(IIE+1,:,:),PSRC(IIB+1,:,:)) - &
+!!$        PSRC(IIE+1,:,:)) )), ZDMQ(IIE+1,:,:) )
+!
+!  update ZDMQ HALO before next/further  utilisation 
+!
+   CALL  GET_HALO(ZDMQ, HNAME='ZDMQ')
+!
+! calculate qL and qR with the modified dmq
+!
+!  ZQL0(i) = Fct[ PSRC(i),PSRC(i-1),ZDMQ(i),ZDMQ(i-1) ]
+!
+   ZQL0(IIB:IIE+1,IJS:IJN,:) = 0.5*(PSRC(IIB:IIE+1,IJS:IJN,:) + PSRC(IIB-1:IIE,IJS:IJN,:)) - &
+        (ZDMQ(IIB:IIE+1,IJS:IJN,:) - ZDMQ(IIB-1:IIE,IJS:IJN,:))/6.0
+!
+   CALL  GET_HALO(ZQL0, HNAME='ZQL0')
+!  
+!  WEST BOUND
+!
+!!$   ZQL0(IIB-1,:,:) = ZQL0(IIE,:,:) JUAN PPMLL01
+!
+   ZQR0(IIB-1:IIE,IJS:IJN,:) = ZQL0(IIB:IIE+1,IJS:IJN,:)
+!
+   CALL  GET_HALO(ZQR0, HNAME='ZQR0')
+!
+!  EAST BOUND
+!
+!!$   ZQR0(IIE+1,:,:) = ZQR0(IIB,:,:) JUAN PPMLL01
+!
+! determine initial coefficients of the parabolae
+!
+   ZDQ(:,IJS:IJN,:) = ZQR0(:,IJS:IJN,:) - ZQL0(:,IJS:IJN,:)
+   ZQ60(:,IJS:IJN,:) = 6.0*(PSRC(:,IJS:IJN,:) - 0.5*(ZQL0(:,IJS:IJN,:) + ZQR0(:,IJS:IJN,:)))
+!
+! initialize final parabolae parameters
+!
+   ZQL(:,IJS:IJN,:) = ZQL0(:,IJS:IJN,:)
+   ZQR(:,IJS:IJN,:) = ZQR0(:,IJS:IJN,:)
+   ZQ6(:,IJS:IJN,:) = ZQ60(:,IJS:IJN,:) 
+!
+! eliminate over and undershoots and create qL and qR as in Lin96
+!
+   WHERE ( ZDMQ(:,IJS:IJN,:) == 0.0 )
+      ZQL(:,IJS:IJN,:) = PSRC(:,IJS:IJN,:)
+      ZQR(:,IJS:IJN,:) = PSRC(:,IJS:IJN,:)
+      ZQ6(:,IJS:IJN,:) = 0.0
+#ifndef MNH_BITREP
+   ELSEWHERE ( ZQ60(:,IJS:IJN,:)*ZDQ(:,IJS:IJN,:) < -(ZDQ(:,IJS:IJN,:))**2 )
+#else
+   ELSEWHERE ( ZQ60(:,IJS:IJN,:)*ZDQ(:,IJS:IJN,:) < -BR_P2(ZDQ(:,IJS:IJN,:)) )
+#endif
+      ZQ6(:,IJS:IJN,:) = 3.0*(ZQL0(:,IJS:IJN,:) - PSRC(:,IJS:IJN,:))
+      ZQR(:,IJS:IJN,:) = ZQL0(:,IJS:IJN,:) - ZQ6(:,IJS:IJN,:)
+      ZQL(:,IJS:IJN,:) = ZQL0(:,IJS:IJN,:)
+#ifndef MNH_BITREP
+   ELSEWHERE ( ZQ60(:,IJS:IJN,:)*ZDQ(:,IJS:IJN,:) > (ZDQ(:,IJS:IJN,:))**2 )
+#else
+   ELSEWHERE ( ZQ60(:,IJS:IJN,:)*ZDQ(:,IJS:IJN,:) > BR_P2(ZDQ(:,IJS:IJN,:)) )
+#endif
+      ZQ6(:,IJS:IJN,:) = 3.0*(ZQR0(:,IJS:IJN,:) - PSRC(:,IJS:IJN,:))
+      ZQL(:,IJS:IJN,:) = ZQR0(:,IJS:IJN,:) - ZQ6(:,IJS:IJN,:)
+      ZQR(:,IJS:IJN,:) = ZQR0(:,IJS:IJN,:)
+   END WHERE
+!
+! recalculate coefficients of the parabolae
+!
+   ZDQ(:,IJS:IJN,:) = ZQR(:,IJS:IJN,:) - ZQL(:,IJS:IJN,:)
+!
+! and finally calculate fluxes for the advection
+!
+!  ZFPOS(i) = Fct[ ZQR(i-1),PCR(i),ZDQ(i-1),ZQ6(i-1) ]
+!
+   ZFPOS(IIB:IIE+1,IJS:IJN,:) = ZQR(IIB-1:IIE,IJS:IJN,:) - 0.5*PCR(IIB:IIE+1,IJS:IJN,:) * &
+        (ZDQ(IIB-1:IIE,IJS:IJN,:) - (1.0 - 2.0*PCR(IIB:IIE+1,IJS:IJN,:)/3.0)        &
+        * ZQ6(IIB-1:IIE,IJS:IJN,:))
+!
+   CALL GET_HALO(ZFPOS, HNAME='ZFPOS')
+!
+!  WEST BOUND
+!
+! PPOSX(IIB-1,:,:) is not important for the calc of advection so 
+! we set it to 0
+!!$   ZFPOS(IIB-1,:,:) = 0.0 JUANPPMLL01
+!
+   ZFNEG(:,IJS:IJN,:) = ZQL(:,IJS:IJN,:) - 0.5*PCR(:,IJS:IJN,:) *      &            
+        ( ZDQ(:,IJS:IJN,:) + (1.0 + 2.0*PCR(:,IJS:IJN,:)/3.0) * ZQ6(:,IJS:IJN,:) )
+!
+   CALL GET_HALO(ZFNEG, HNAME='ZFNEG')
+!
+! advect the actual field in X direction by U*dt
+!
+#ifndef MNH_OPENACC
+   PR = DXF( PCR*MXM(PRHO)*( ZFPOS*(0.5+SIGN(0.5,PCR)) + & 
+                             ZFNEG*(0.5-SIGN(0.5,PCR)) ) )
+#else
+  call Print_msg( NVERB_ERROR, 'GEN', 'PPM_01_X', 'OpenACC: CYCL/WALL boundaries not yet implemented' )
+#endif
+   CALL GET_HALO(PR, HNAME='PR')
+!
+!
+!*       1.2    NON-CYCLIC BOUNDARY CONDITIONS IN THE X DIRECTION 
+!               -------------------------------------------------
+!
+CASE('OPEN')
+!
+! calculate dmq
+!
+#ifndef  MNH_OPENACC  
+   ZDMQ = DIF2X(PSRC)
+#else
+   CALL DIF2X_DEVICE(ZDMQ,PSRC)
+#endif
+   
+!$acc kernels
+!
+! overwrite the values on the boundary to get second order difference
+! for qL and qR at the boundary
+!
+!  WEST BOUND
+!
+  IF (GWEST) THEN
+   ZDMQ(IIB-1,IJS:IJN,:) = -ZDMQ(IIB,IJS:IJN,:)
+  ENDIF
+!
+!  EAST BOUND
+!
+  IF (GEAST) THEN 
+   ZDMQ(IIE+1,IJS:IJN,:) = -ZDMQ(IIE,IJS:IJN,:)
+  ENDIF
+!
+! monotonize the difference followinq eq. 5 in Lin94
+!
+!  ZDMQ(i) = Fct[ ZDMQ(i),PSRC(i),PSRC(i-1),PSRC(i+1) ]
+!
+!$acc loop independent collapse(3)
+  do jk = 1, iku
+    do jj = ijs, ijn
+      do ji = iib, iie
+        ZDMQ(ji, jj, jk ) = SIGN(                                                                  &
+            MIN( ABS(ZDMQ(ji, jj, jk )),                                                           &
+                 2.0 * ( PSRC(ji, jj, jk )                                                         &
+                         - MIN(PSRC(ji - 1, jj, jk ),PSRC(ji, jj, jk ),PSRC(ji + 1, jj, jk )) ),   &
+                 2.0 * (-PSRC(ji, jj, jk )                                                         &
+                        + MAX(PSRC(ji - 1, jj, jk ),PSRC(ji, jj, jk ),PSRC(ji + 1, jj, jk )) )  ), &
+            ZDMQ(ji, jj, jk ) )
+      end do
+    end do
+  end do
+!
+!  WEST BOUND
+!
+!!$   ZDMQ(IIB-1,:,:) = & 
+!!$        SIGN( (MIN( ABS(ZDMQ(IIB-1,:,:)), 2.0*(PSRC(IIB-1,:,:) - &
+!!$        MIN(PSRC(IIE-1,:,:),PSRC(IIB-1,:,:),PSRC(IIB,:,:))),   &
+!!$        2.0*(MAX(PSRC(IIE-1,:,:),PSRC(IIB-1,:,:),PSRC(IIB,:,:)) - &
+!!$        PSRC(IIB-1,:,:)) )), ZDMQ(IIB-1,:,:) )
+!
+!  EAST BOUND
+!
+!!$   ZDMQ(IIE+1,:,:) = &
+!!$        SIGN( (MIN( ABS(ZDMQ(IIE+1,:,:)), 2.0*(PSRC(IIE+1,:,:) - &
+!!$        MIN(PSRC(IIE,:,:),PSRC(IIE+1,:,:),PSRC(IIB+1,:,:))),  &
+!!$        2.0*(MAX(PSRC(IIE,:,:),PSRC(IIE+1,:,:),PSRC(IIB+1,:,:)) - &
+!!$        PSRC(IIE+1,:,:)) )), ZDMQ(IIE+1,:,:) )
+!
+!
+!  update ZDMQ HALO before next/further  utilisation 
+!
+#ifndef MNH_OPENACC
+   CALL  GET_HALO(ZDMQ, HNAME='ZDMQ')
+#else
+!$acc end kernels
+   CALL  GET_HALO_D(ZDMQ, HDIR="01_X", HNAME='ZDMQ')
+#endif
+!$acc kernels
+!
+! calculate qL and qR
+!
+!  ZQL0(i) = Fct[ PSRC(i),PSRC(i-1),ZDMQ(i),ZDMQ(i-1) ]
+!
+!$acc loop independent collapse(3)
+  do jk = 1, iku
+    do jj = ijs, ijn
+      do ji = iib, iie + 1
+        ZQL0(ji, jj, jk ) = 0.5 * ( PSRC(ji, jj, jk ) + PSRC(ji-1, jj, jk ) ) - ( ZDMQ(ji, jj, jk ) - ZDMQ(ji-1, jj, jk ) ) / 6.0
+      end do
+    end do
+  end do
+!
+#ifndef MNH_OPENACC
+   CALL  GET_HALO(ZQL0, HNAME='ZQL0')
+#else
+!$acc end kernels
+   CALL  GET_HALO_D(ZQL0,HDIR="01_X", HNAME='ZQL0')
+!$acc kernels
+#endif
+!  
+!  WEST BOUND
+!
+  IF (GWEST) THEN
+   ZQL0(IIB-1,IJS:IJN,:) = ZQL0(IIB,IJS:IJN,:)
+  ENDIF
+!
+   ZQR0(IIB-1:IIE,IJS:IJN,:) = ZQL0(IIB:IIE+1,IJS:IJN,:)
+!
+#ifndef MNH_OPENACC
+   CALL  GET_HALO(ZQR0, HNAME='ZQR0')
+#else
+!$acc end kernels
+   CALL  GET_HALO_D(ZQR0, HDIR="01_X", HNAME='ZQR0')
+!$acc kernels
+#endif
+!
+!  EAST BOUND
+!
+  IF (GEAST) THEN
+   ZQR0(IIE+1,IJS:IJN,:) = ZQR0(IIE,IJS:IJN,:)
+  ENDIF
+#ifndef MNH_OPENACC
+!
+! determine initial coefficients of the parabolae
+!
+   ZDQ(:,IJS:IJN,:) = ZQR0(:,IJS:IJN,:) - ZQL0(:,IJS:IJN,:)
+   ZQ60(:,IJS:IJN,:) = 6.0*(PSRC(:,IJS:IJN,:) - 0.5*(ZQL0(:,IJS:IJN,:) + ZQR0(:,IJS:IJN,:)))
+!
+! initialize final parabolae parameters
+!
+   ZQL(:,IJS:IJN,:) = ZQL0(:,IJS:IJN,:)
+   ZQR(:,IJS:IJN,:) = ZQR0(:,IJS:IJN,:)
+   ZQ6(:,IJS:IJN,:) = ZQ60(:,IJS:IJN,:)
+!
+! eliminate over and undershoots and create qL and qR as in Lin96
+!
+   WHERE ( ZDMQ(:,IJS:IJN,:) == 0.0 )
+      ZQL(:,IJS:IJN,:) = PSRC(:,IJS:IJN,:)
+      ZQR(:,IJS:IJN,:) = PSRC(:,IJS:IJN,:)
+      ZQ6(:,IJS:IJN,:) = 0.0
+   ELSEWHERE ( ZQ60(:,IJS:IJN,:)*ZDQ(:,IJS:IJN,:) < -ZDQ(:,IJS:IJN,:)*ZDQ(:,IJS:IJN,:) )
+      ZQ6(:,IJS:IJN,:) = 3.0*(ZQL0(:,IJS:IJN,:) - PSRC(:,IJS:IJN,:))
+      ZQR(:,IJS:IJN,:) = ZQL0(:,IJS:IJN,:) - ZQ6(:,IJS:IJN,:)
+      ZQL(:,IJS:IJN,:) = ZQL0(:,IJS:IJN,:)
+   ELSEWHERE ( ZQ60(:,IJS:IJN,:)*ZDQ(:,IJS:IJN,:) > ZDQ(:,IJS:IJN,:)*ZDQ(:,IJS:IJN,:) )
+      ZQ6(:,IJS:IJN,:) = 3.0*(ZQR0(:,IJS:IJN,:) - PSRC(:,IJS:IJN,:))
+      ZQL(:,IJS:IJN,:) = ZQR0(:,IJS:IJN,:) - ZQ6(:,IJS:IJN,:)
+      ZQR(:,IJS:IJN,:) = ZQR0(:,IJS:IJN,:)
+   END WHERE
+!
+! recalculate coefficients of the parabolae
+!
+   ZDQ(:,IJS:IJN,:) = ZQR(:,IJS:IJN,:) - ZQL(:,IJS:IJN,:)
+#else
+!$acc loop independent collapse(3)
+DO K=1,IKU 
+ DO J = IJS,IJN
+    ! acc loop vector(24)
+   DO I=1,IIU
+!
+! determine initial coefficients of the parabolae
+!
+   ZDQ (I,J,K)= ZQR0(I,J,K) - ZQL0(I,J,K)
+   ZQ60(I,J,K) = 6.0*(PSRC(I,J,K) - 0.5*(ZQL0(I,J,K) + ZQR0(I,J,K)))
+!
+! initialize final parabolae parameters
+!
+   ZQL(I,J,K) = ZQL0(I,J,K)
+   ZQR(I,J,K) = ZQR0(I,J,K)
+   ZQ6(I,J,K) = ZQ60(I,J,K)
+!
+! eliminate over and undershoots and create qL and qR as in Lin96
+!
+   IF ( ZDMQ(I,J,K) == 0.0 ) THEN
+      ZQL(I,J,K) = PSRC(I,J,K)
+      ZQR(I,J,K) = PSRC(I,J,K)
+      ZQ6(I,J,K) = 0.0
+   ELSEIF ( ZQ60(I,J,K)*ZDQ(I,J,K) < -ZDQ(I,J,K)*ZDQ(I,J,K) ) THEN
+      ZQ6(I,J,K) = 3.0*(ZQL0(I,J,K) - PSRC(I,J,K))
+      ZQR(I,J,K) = ZQL0(I,J,K) - ZQ6(I,J,K)
+      ZQL(I,J,K) = ZQL0(I,J,K)
+   ELSEIF ( ZQ60(I,J,K)*ZDQ(I,J,K) > ZDQ(I,J,K)*ZDQ(I,J,K) ) THEN
+      ZQ6(I,J,K) = 3.0*(ZQR0(I,J,K) - PSRC(I,J,K))
+      ZQL(I,J,K) = ZQR0(I,J,K) - ZQ6(I,J,K)
+      ZQR(I,J,K) = ZQR0(I,J,K)
+   ENDIF
+!
+! recalculate coefficients of the parabolae
+!
+   ZDQ(I,J,K) = ZQR(I,J,K) - ZQL(I,J,K)
+ENDDO ; ENDDO ; ENDDO
+#endif
+!
+! and finally calculate fluxes for the advection
+!
+!
+!  ZFPOS(i) = Fct[ ZQR(i-1),PCR(i),ZDQ(i-1),ZQ6(i-1) ]
+!
+!!$   ZFPOS(IIB+1:IIE+1,:,:) = ZQR(IIB:IIE,:,:) - 0.5*PCR(IIB+1:IIE+1,:,:) * &            
+!!$        (ZDQ(IIB:IIE,:,:) - (1.0 - 2.0*PCR(IIB+1:IIE+1,:,:)/3.0)          &
+!!$        * ZQ6(IIB:IIE,:,:))
+!$acc loop independent collapse(3)
+  do jk = 1, iku
+    do jj = ijs, ijn
+      do ji = iib, iie + 1
+        ZFPOS(ji, jj, jk ) = ZQR(ji - 1, jj, jk ) - 0.5 * PCR(ji, jj, jk )                  &
+                            * ( ZDQ(ji - 1, jj, jk) - (1.0 - 2.0 * PCR(ji, jj, jk ) / 3.0 ) &
+                            * ZQ6(ji - 1, jj, jk) )
+      end do
+    end do
+  end do
+!
+!
+#ifndef MNH_OPENACC
+   CALL GET_HALO(ZFPOS, HNAME='ZFPOS')
+#else
+!$acc end kernels
+   CALL GET_HALO_D(ZFPOS, HDIR="01_X", HNAME='ZFPOS')
+!$acc kernels
+#endif
+!
+!
+!  WEST BOUND
+!
+! advection flux at open boundary when u(IIB) > 0
+! 
+  IF (GWEST) THEN
+   ZFPOS(IIB,IJS:IJN,:) = (PSRC(IIB-1,IJS:IJN,:) - ZQR(IIB-1,IJS:IJN,:))*PCR(IIB,IJS:IJN,:) + &
+                    ZQR(IIB-1,IJS:IJN,:)
+! PPOSX(IIB-1,:,:) is not important for the calc of advection so 
+! we set it to 0
+!!$   ZFPOS(IIB-1,:,:) = 0.0
+   ENDIF
+!
+!!$   ZFNEG(IIB-1:IIE,:,:) = ZQL(IIB-1:IIE,:,:) - 0.5*PCR(IIB-1:IIE,:,:) *  &            
+!!$        (ZDQ(IIB-1:IIE,:,:) + (1.0 + 2.0*PCR(IIB-1:IIE,:,:)/3.0)         &
+!!$        * ZQ6(IIB-1:IIE,:,:))
+!$acc loop independent collapse(3)
+  do jk = 1, iku
+    do jj = ijs, ijn
+      do ji = 1, iiu
+   ZFNEG(ji, jj, jk ) = ZQL(ji, jj, jk ) - 0.5*PCR(ji, jj, jk ) *      &
+        ( ZDQ(ji, jj, jk ) + (1.0 + 2.0*PCR(ji, jj, jk )/3.0) * ZQ6(ji, jj, jk ) )
+      end do
+    end do
+  end do
+!
+#ifndef MNH_OPENACC
+   CALL GET_HALO(ZFNEG, HNAME='ZFNEG')
+#else
+!$acc end kernels
+   CALL GET_HALO_D(ZFNEG, HDIR="01_X", HNAME='ZFNEG')
+!$acc kernels
+#endif
+!
+!  EAST BOUND
+!
+! advection flux at open boundary when u(IIE+1) < 0
+  IF (GEAST) THEN
+   ZFNEG(IIE+1,IJS:IJN,:) = (ZQR(IIE,IJS:IJN,:)-PSRC(IIE+1,IJS:IJN,:))*PCR(IIE+1,IJS:IJN,:) + &
+                      ZQR(IIE,IJS:IJN,:)
+  ENDIF
+!
+! advect the actual field in X direction by U*dt
+!
+#ifndef MNH_OPENACC
+   PR = DXF( PCR*MXM(PRHO)*( ZFPOS*(0.5+SIGN(0.5,PCR)) + & 
+                             ZFNEG*(0.5-SIGN(0.5,PCR)) ) )
+   CALL GET_HALO(PR, HNAME='PR')
+#else
+   !mxm(ZQL,PRHO)
+!$acc end kernels
+   CALL MXM_DEVICE(PRHO,ZQL)
+!$acc kernels
+   where ( PCR(:,:,:) > 0. )
+     ZQR(:,:,:) = PCR(:,:,:) * ZQL(:,:,:) * ZFPOS(:,:,:)
+   elsewhere
+     ZQR(:,:,:) = PCR(:,:,:) * ZQL(:,:,:) * ZFNEG(:,:,:)
+   end where
+    !dxf(PR,ZQR)
+!$acc end kernels
+   CALL DXF_DEVICE(ZQR,PR)
+   CALL GET_HALO_D(PR, HDIR="01_X", HNAME='PR')
+#endif
+!
+END SELECT
+!
+IF (MPPDB_INITIALIZED) THEN
+  !Check all INOUT arrays
+  CALL MPPDB_CHECK(PSRC,"PPM_01_X end:PSRC")
+  !Check all OUT arrays
+  CALL MPPDB_CHECK(PR,"PPM_01_X end:PR")
+END IF
+
+!$acc end data
+
+#ifndef MNH_OPENACC
+CONTAINS
+#else
+END SUBROUTINE PPM_01_X_D
+#endif
+!
+!-------------------------------------------------------------------------------
+!-------------------------------------------------------------------------------
+!
+!     ########################################################################
+      FUNCTION DIF2X(PQ) RESULT(DQ)
+!     ########################################################################
+!!
+!!****  DIF2X - leap-frog difference operator in X direction
+!!
+!!    Calculates the difference assuming periodic BC (CYCL). 
+!!
+!!    DQ(I) = 0.5 * (PQ(I+1) - PQ(I-1))
+!!
+!!    MODIFICATIONS
+!!    -------------
+!!    
+!!    18.3.2006.  T. Maric - original version
+!!    07/2010     J.Escobar : Correction for reproducility
+!!    04/2017     J.Escobar : initialize realistic value in all HALO pts
+!-------------------------------------------------------------------------------
+!
+!
+USE MODE_ll
+!
+IMPLICIT NONE
+! 
+!*       0.1   Declarations of dummy arguments :
+!   
+REAL, DIMENSION(:,:,:), INTENT(IN)                :: PQ
+REAL, DIMENSION(SIZE(PQ,1),SIZE(PQ,2),SIZE(PQ,3)) :: DQ
+!
+!*       0.2   Declarations of local variables :
+!   
+INTEGER :: IIB,IJB        ! Begining useful area in x,y directions
+INTEGER :: IIE,IJE        ! End useful area in x,y directions
+!
+!-------------------------------------------------------------------------------
+
+!$acc data present( PQ, DQ )
+!
+!*       1.0.     COMPUTE THE DOMAIN DIMENSIONS
+!                 -----------------------------
+!
+!!$CALL GET_INDICE_ll(IIB,IJB,IIE,IJE)
+IIB=2 ; IIE = SIZE(PQ,1) -1
+IJB=2 ; IJE = SIZE(PQ,2) -1
+!
+!-------------------------------------------------------------------------------
+!
+!*       2.0.     COMPUTE THE DIFFERENCE
+!                 ----------------------
+!
+!$acc kernels
+DQ(IIB:IIE,:,:) = PQ(IIB+1:IIE+1,:,:) - PQ(IIB-1:IIE-1,:,:)
+DQ(IIB-1,:,:) = PQ(IIB,:,:) - PQ(IIE-1,:,:)
+DQ(IIE+1,:,:) = PQ(IIB+1,:,:) - PQ(IIE,:,:)  
+DQ = 0.5*DQ
+!$acc end kernels
+
+!$acc end data
+
+END FUNCTION DIF2X
+!-------------------------------------------------------------------------------
+!
+!     ########################################################################
+      SUBROUTINE DIF2X_DEVICE(DQ,PQ)
+!     ########################################################################
+!!
+!!****  DIF2X - leap-frog difference operator in X direction
+!!
+!!    Calculates the difference assuming periodic BC (CYCL). 
+!!
+!!    DQ(I) = 0.5 * (PQ(I+1) - PQ(I-1))
+!!
+!!    MODIFICATIONS
+!!    -------------
+!!    
+!!    18.3.2006.  T. Maric - original version
+!!    07/2010     J.Escobar : Correction for reproducility
+!!    04/2017     J.Escobar : initialize realistic value in all HALO pts
+!-------------------------------------------------------------------------------
+!
+!
+USE MODE_ll
+!
+IMPLICIT NONE
+! 
+!*       0.1   Declarations of dummy arguments :
+!   
+REAL, DIMENSION(:,:,:), INTENT(IN)                :: PQ
+REAL, DIMENSION(:,:,:)                            :: DQ
+!
+!*       0.2   Declarations of local variables :
+!   
+INTEGER :: IIB,IJB        ! Begining useful area in x,y directions
+INTEGER :: IIE,IJE        ! End useful area in x,y directions
+!
+!-------------------------------------------------------------------------------
+
+!$acc data present( PQ, DQ )
+!
+!*       1.0.     COMPUTE THE DOMAIN DIMENSIONS
+!                 -----------------------------
+!
+!!$CALL GET_INDICE_ll(IIB,IJB,IIE,IJE)
+IIB=2 ; IIE = SIZE(PQ,1) -1
+IJB=2 ; IJE = SIZE(PQ,2) -1
+!
+!-------------------------------------------------------------------------------
+!
+!*       2.0.     COMPUTE THE DIFFERENCE
+!                 ----------------------
+!
+!$acc kernels
+DQ(IIB:IIE,:,:) = PQ(IIB+1:IIE+1,:,:) - PQ(IIB-1:IIE-1,:,:)
+DQ(IIB-1,:,:) = PQ(IIB,:,:) - PQ(IIE-1,:,:)
+DQ(IIE+1,:,:) = PQ(IIB+1,:,:) - PQ(IIE,:,:)  
+DQ = 0.5*DQ
+!$acc end kernels
+
+!$acc end data
+
+END SUBROUTINE DIF2X_DEVICE
+!
+#ifdef MNH_OPENACC
+END SUBROUTINE PPM_01_X
+#else
+END FUNCTION PPM_01_X
+#endif
+!
+!
+!-------------------------------------------------------------------------------
+!-------------------------------------------------------------------------------
+!
+#ifdef MNH_OPENACC
+!     ########################################################################
+!!$      FUNCTION PPM_01_Y(HLBCY, KGRID, PSRC, PCR, PRHO, PTSTEP) &
+!!$               RESULT(PR)
+      SUBROUTINE PPM_01_Y(HLBCY, KGRID, PSRC, PCR, PRHO, PTSTEP, PR)
+!     ########################################################################
+
+        USE MODE_MNH_ZWORK, ONLY : ZT3D, MNH_GET_ZT3D , MNH_REL_ZT3D
+        USE MODE_MNH_ZWORK, ONLY : IIU,IJU,IKU
+
+IMPLICIT NONE
+!
+!*       0.1   Declarations of dummy arguments :
+!
+CHARACTER (LEN=4), DIMENSION(2), INTENT(IN) :: HLBCY  ! Y direction LBC type
+!
+INTEGER,                INTENT(IN)  :: KGRID   ! C grid localisation
+REAL,                   INTENT(IN)  :: PTSTEP   ! Time step 
+!
+REAL, DIMENSION(:,:,:), INTENT(INOUT):: PSRC ! variable at t
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PCR   &  ! Courant number
+                                     , PRHO     ! density
+!
+! output source term
+REAL, DIMENSION(:,:,:), INTENT(OUT) :: PR
+
+INTEGER :: IZQL,IZQR,IZDQ,IZQ6,IZDMQ,IZQL0,IZQR0,IZQ60,IZFPOS,IZFNEG
+
+!$acc data present( PSRC, PCR, PRHO, PR )
+
+        CALL  MNH_GET_ZT3D(IZQL,IZQR,IZDQ,IZQ6,IZDMQ,IZQL0,IZQR0,IZQ60,IZFPOS,IZFNEG)
+
+        CALL  PPM_01_Y_D(IIU,IJU,IKU,HLBCY, KGRID, &
+                     & PSRC, PCR, PRHO, PTSTEP, PR, &
+                     & ZT3D(:,:,:,IZQL),ZT3D(:,:,:,IZQR),ZT3D(:,:,:,IZDQ),ZT3D(:,:,:,IZQ6), &
+                     & ZT3D(:,:,:,IZDMQ),ZT3D(:,:,:,IZQL0),ZT3D(:,:,:,IZQR0), ZT3D(:,:,:,IZQ60), &
+                     & ZT3D(:,:,:,IZFPOS),ZT3D(:,:,:,IZFNEG) )
+
+        CALL  MNH_REL_ZT3D(IZQL,IZQR,IZDQ,IZQ6,IZDMQ,IZQL0,IZQR0,IZQ60,IZFPOS,IZFNEG)
+
+!$acc end data
+
+CONTAINS
+!
+!     ########################################################################
+        SUBROUTINE  PPM_01_Y_D(IIU,IJU,IKU,HLBCY, KGRID, &
+                     & PSRC, PCR, PRHO, PTSTEP, PR, &
+                     & ZQL,ZQR,ZDQ,ZQ6,ZDMQ,ZQL0,ZQR0,ZQ60,ZFPOS,ZFNEG)
+
+!     ########################################################################
+#else
+!     ########################################################################
+      FUNCTION PPM_01_Y(HLBCY, KGRID, PSRC, PCR, PRHO, PTSTEP) &
+               RESULT(PR)
+!     ########################################################################
+#endif
+!!
+!!****  PPM_01_Y - PPM_01 fully monotonic PPM advection scheme in Y direction
+!!                 Colella notation
+!!
+!!    MODIFICATIONS
+!!    -------------
+!!    
+!!    11.5.2006.  T. Maric - original version
+!!      J.Escobar 21/03/2013: for HALOK comment all NHALO=1 test
+!!      J.Escobar 28/06/2018: limit computation on TAB(IIW:IIA,:,:) to avoid unneeded NaN 
+!!      J.Escobr  16/07/2018: still NaN pb => reintroduce initialization of temporary local array
+!!
+!-------------------------------------------------------------------------------
+!
+USE MODD_CONF
+
+USE MODE_ll
+#ifdef MNH_OPENACC
+use mode_msg
+#endif
+use mode_mppdb
+
+#ifdef MNH_BITREP
+USE MODI_BITREP
+#endif
+USE MODI_GET_HALO
+#ifndef MNH_OPENACC
+USE MODI_SHUMAN
+#else
+USE MODI_SHUMAN_DEVICE
+#endif
+!
+IMPLICIT NONE
+!
+!*       0.1   Declarations of dummy arguments :
+!
+#ifdef MNH_OPENACC
+integer, intent(in) :: iiu, iju, iku
+#endif
+CHARACTER (LEN=4), DIMENSION(2), INTENT(IN) :: HLBCY  ! Y direction LBC type
+!
+INTEGER,                INTENT(IN)  :: KGRID   ! C grid localisation
+!
+REAL, DIMENSION(:,:,:), INTENT(INOUT)  :: PSRC    ! variable at t
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PCR     ! Courant number
+!
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PRHO  ! density
+REAL,                   INTENT(IN)  :: PTSTEP  ! Time step 
+!
+! output source term
+#ifndef MNH_OPENACC
+REAL, DIMENSION(SIZE(PCR,1),SIZE(PCR,2),SIZE(PCR,3)) :: PR
+#else
+REAL, DIMENSION(IIU,IJU,IKU), INTENT(OUT) :: PR
+#endif
+!
+!*       0.2   Declarations of local variables :
+!
+INTEGER:: IIB,IJB    ! Begining useful area in x,y,z directions
+INTEGER:: IIE,IJE    ! End useful area in x,y,z directions
+!
+INTEGER                          :: IIW,IIA
+!
+LOGICAL                          :: GSOUTH , GNORTH
+#ifndef MNH_OPENACC
+integer ::  iiu, iju, iku
+!
+! terms used in parabolic interpolation, dmq, qL, qR, dq, q6
+REAL, DIMENSION(SIZE(PCR,1),SIZE(PCR,2),SIZE(PCR,3)) :: ZQL,ZQR
+REAL, DIMENSION(SIZE(PCR,1),SIZE(PCR,2),SIZE(PCR,3)) :: ZDQ,ZQ6
+REAL, DIMENSION(SIZE(PCR,1),SIZE(PCR,2),SIZE(PCR,3)) :: ZDMQ
+!
+! extra variables for the initial guess of parabolae parameters
+REAL, DIMENSION(SIZE(PCR,1),SIZE(PCR,2),SIZE(PCR,3)) :: ZQL0,ZQR0,ZQ60
+!
+! advection fluxes
+REAL, DIMENSION(SIZE(PCR,1),SIZE(PCR,2),SIZE(PCR,3)) :: ZFPOS, ZFNEG
+!
+#else
+! terms used in parabolic interpolation, dmq, qL, qR, dq, q6
+REAL, DIMENSION(IIU,IJU,IKU) :: &
+     ZQL,ZQR , ZDQ,ZQ6 , ZDMQ &
+! extra variables for the initial guess of parabolae parameters
+   , ZQL0,ZQR0,ZQ60 &
+! advection fluxes
+   , ZFPOS, ZFNEG
+
+!
+!JUAN ACC
+INTEGER                          :: I,J,K
+!
+INTEGER                          :: IKB,IKE
+INTEGER                          :: IJN,IJS
+!JUAN ACC
+#endif
+integer :: ji, jj, jk
+!-------------------------------------------------------------------------------
+
+!$acc data present( PSRC, PCR, PRHO, PR, &
+!$acc &             ZQL, ZQR, ZDQ, ZQ6, ZDMQ, ZQL0, ZQR0, ZQ60, ZFPOS, ZFNEG )
+
+IF (MPPDB_INITIALIZED) THEN
+  !Check all IN arrays
+  CALL MPPDB_CHECK(PCR, "PPM_01_Y beg:PCR")
+  CALL MPPDB_CHECK(PRHO,"PPM_01_Y beg:PRHO")
+  !Check all INOUT arrays
+  CALL MPPDB_CHECK(PSRC,"PPM_01_Y beg:PSRC")
+END IF
+!
+!*       0.3.     COMPUTES THE DOMAIN DIMENSIONS
+!                 ------------------------------
+!
+CALL GET_INDICE_ll(IIB,IJB,IIE,IJE)
+IIW=IIB
+IIA=IIE
+!
+GSOUTH=LSOUTH_ll()
+GNORTH=LNORTH_ll()
+!
+#ifndef MNH_OPENACC
+iiu = size( PSRC, 1 )
+iju = size( PSRC, 2 )
+iku = size( PSRC, 3 )
+
+CALL GET_HALO(PSRC, HNAME='PSRC')
+#else
+IJS=1
+IJN=IJU
+IKB=1
+IKE=IKU
+!
+! For HALO >=2 all possible domaine computed
+!
+!IJB=2
+!IJE=IJU-1
+!IIB=2
+!IIE=IIU-1
+!
+CALL GET_HALO_D(PSRC, HDIR="01_Y", HNAME='PSRC')
+#endif
+!
+!-------------------------------------------------------------------------------
+!
+!
+!$acc kernels
+!$acc loop independent collapse(3)
+  do jk = 1, iku
+    do jj = 1, iju
+      do ji = 1, iiu
+        PR   (ji, jj, jk ) = PSRC(ji, jj, jk )
+        ZQL  (ji, jj, jk ) = PSRC(ji, jj, jk )
+        ZQR  (ji, jj, jk ) = PSRC(ji, jj, jk )
+        ZDQ  (ji, jj, jk ) = PSRC(ji, jj, jk )
+        ZQ6  (ji, jj, jk ) = PSRC(ji, jj, jk )
+        ZDMQ (ji, jj, jk ) = PSRC(ji, jj, jk )
+        ZQL0 (ji, jj, jk ) = PSRC(ji, jj, jk )
+        ZQR0 (ji, jj, jk ) = PSRC(ji, jj, jk )
+        ZQ60 (ji, jj, jk ) = PSRC(ji, jj, jk )
+    end do
+  end do
+end do
+#ifndef MNH_OPENACC
+ZFPOS=PSRC
+ZFNEG=PSRC
+#else
+#if 0
+ZFPOS(1:IIW,:,IKB:IKE)=PSRC(1:IIW,:,IKB:IKE)
+ZFNEG(1:IIW,:,IKB:IKE)=PSRC(1:IIW,:,IKB:IKE)
+ZFPOS(IIA:,:,IKB:IKE)=PSRC(IIA:,:,IKB:IKE)
+ZFNEG(IIA:,:,IKB:IKE)=PSRC(IIA:,:,IKB:IKE)
+#else
+ZFPOS(:,:,:) = PSRC(:,:,:)
+ZFNEG(:,:,:) = PSRC(:,:,:)
+#endif
+#endif
+!$acc end kernels
+!
+SELECT CASE ( HLBCY(1) ) ! Y direction LBC type: (1) for left side
+!
+!*       2.1    CYCLIC BOUNDARY CONDITIONS IN THE Y DIRECTION
+!               ---------------------------------------------
+!
+CASE ('CYCL','WALL')          ! In that case one must have HLBCY(1) == HLBCY(2)
+!
+! calculate dmq
+   ZDMQ = DIF2Y(PSRC)
+!
+! monotonize the difference followinq eq. 5 in Lin94
+!BEG JUAN PPM_LL01
+!
+!  ZDMQ(j) = Fct[ ZDMQ(j),PSRC(j),PSRC(j-1),PSRC(j+1) ]
+!
+!$acc kernels
+   ZDMQ(IIW:IIA,IJB:IJE,:) = &
+        SIGN( (MIN( ABS(ZDMQ(IIW:IIA,IJB:IJE,:)),2.0*(PSRC(IIW:IIA,IJB:IJE,:) - &
+        MIN(PSRC(IIW:IIA,IJB-1:IJE-1,:),PSRC(IIW:IIA,IJB:IJE,:),PSRC(IIW:IIA,IJB+1:IJE+1,:))),    &
+        2.0*(MAX(PSRC(IIW:IIA,IJB-1:IJE-1,:),PSRC(IIW:IIA,IJB:IJE,:),PSRC(IIW:IIA,IJB+1:IJE+1,:)) - &
+        PSRC(IIW:IIA,IJB:IJE,:)) )), ZDMQ(IIW:IIA,IJB:IJE,:) )
+!
+!  SOUTH BOUND
+!
+!!$   ZDMQ(:,IJB-1,:) = & 
+!!$        SIGN( (MIN( ABS(ZDMQ(:,IJB-1,:)), 2.0*(PSRC(:,IJB-1,:) - &
+!!$        MIN(PSRC(:,IJE-1,:),PSRC(:,IJB-1,:),PSRC(:,IJB,:))),   &
+!!$        2.0*(MAX(PSRC(:,IJE-1,:),PSRC(:,IJB-1,:),PSRC(:,IJB,:)) - &
+!!$        PSRC(:,IJB-1,:)) )), ZDMQ(:,IJB-1,:) )
+!
+!  NORTH BOUND
+!
+!!$   ZDMQ(:,IJE+1,:) = &
+!!$        SIGN( (MIN( ABS(ZDMQ(:,IJE+1,:)), 2.0*(PSRC(:,IJE+1,:) - &
+!!$        MIN(PSRC(:,IJE,:),PSRC(:,IJE+1,:),PSRC(:,IJB+1,:))),  &
+!!$        2.0*(MAX(PSRC(:,IJE,:),PSRC(:,IJE+1,:),PSRC(:,IJB+1,:)) - &
+!!$        PSRC(:,IJE+1,:)) )), ZDMQ(:,IJE+1,:) )   
+!
+!  update ZDMQ HALO before next/further  utilisation 
+!
+#ifndef MNH_OPENACC
+   CALL GET_HALO(ZDMQ, HNAME='ZDMQ')
+#else
+!$acc end kernels
+   CALL GET_HALO_D(ZDMQ,HDIR="01_Y", HNAME='ZDMQ')
+!$acc kernels
+#endif
+!
+! calculate qL and qR with the modified dmq
+!
+!    ZQL0(IIW:IIA,IJB:IJE+1,:) = 0.5*(PSRC(IIW:IIA,IJB:IJE+1,:) + PSRC(IIW:IIA,IJB-1:IJE,:)) - &
+!         (ZDMQ(IIW:IIA,IJB:IJE+1,:) - ZDMQ(IIW:IIA,IJB-1:IJE,:))/6.0
+!$acc loop independent collapse(3)
+  do jk = 1, iku
+    do jj = ijb, ije + 1
+      do ji = iiw, iia
+        ZQL0(ji, jj, jk ) = 0.5 * ( PSRC(ji, jj, jk ) + PSRC(ji, jj-1, jk )) - ( ZDMQ(ji, jj, jk ) - ZDMQ(ji, jj-1, jk ) ) / 6.0
+      end do
+    end do
+  end do
+!
+#ifndef MNH_OPENACC
+   CALL GET_HALO(ZQL0, HNAME='ZQL0')
+#else
+!$acc end kernels
+  CALL GET_HALO_D(ZQL0,HDIR="01_Y", HNAME='ZQL0')
+!$acc kernels
+#endif
+!
+!  SOUTH BOUND
+!
+!!$   ZQL0(:,IJB-1,:) = ZQL0(:,IJE,:) JUAN PPMLL01
+!
+   ZQR0(IIW:IIA,IJB-1:IJE,:) = ZQL0(IIW:IIA,IJB:IJE+1,:)
+!
+#ifndef MNH_OPENACC
+   CALL GET_HALO(ZQR0, HNAME='ZQR0')
+#else
+!$acc end kernels
+  CALL GET_HALO_D(ZQR0,HDIR="01_Y", HNAME='ZQR0')
+!$acc kernels
+#endif
+!
+!  NORTH BOUND
+!
+!!$   ZQR0(:,IJE+1,:) = ZQR0(:,IJB,:) JUAN PPMLL01
+#ifndef MNH_OPENACC
+!
+! determine initial coefficients of the parabolae
+!
+   ZDQ(IIW:IIA,:,:) = ZQR0(IIW:IIA,:,:) - ZQL0(IIW:IIA,:,:)
+   ZQ60(IIW:IIA,:,:) = 6.0*(PSRC(IIW:IIA,:,:) - 0.5*(ZQL0(IIW:IIA,:,:) + ZQR0(IIW:IIA,:,:)))
+!
+! initialize final parabolae parameters
+!
+   ZQL(IIW:IIA,:,:) = ZQL0(IIW:IIA,:,:)
+   ZQR(IIW:IIA,:,:) = ZQR0(IIW:IIA,:,:)
+   ZQ6(IIW:IIA,:,:) = ZQ60(IIW:IIA,:,:) 
+!
+! eliminate over and undershoots and create qL and qR as in Lin96
+!
+   WHERE ( ZDMQ(IIW:IIA,:,:) == 0.0 )
+      ZQL(IIW:IIA,:,:) = PSRC(IIW:IIA,:,:)
+      ZQR(IIW:IIA,:,:) = PSRC(IIW:IIA,:,:)
+      ZQ6(IIW:IIA,:,:) = 0.0
+   ELSEWHERE ( ZQ60(IIW:IIA,:,:)*ZDQ(IIW:IIA,:,:) < -ZDQ(IIW:IIA,:,:)*ZDQ(IIW:IIA,:,:) )
+      ZQ6(IIW:IIA,:,:) = 3.0*(ZQL0(IIW:IIA,:,:) - PSRC(IIW:IIA,:,:))
+      ZQR(IIW:IIA,:,:) = ZQL0(IIW:IIA,:,:) - ZQ6(IIW:IIA,:,:)
+      ZQL(IIW:IIA,:,:) = ZQL0(IIW:IIA,:,:)
+   ELSEWHERE ( ZQ60(IIW:IIA,:,:)*ZDQ(IIW:IIA,:,:) > ZDQ(IIW:IIA,:,:)*ZDQ(IIW:IIA,:,:) )
+      ZQ6(IIW:IIA,:,:) = 3.0*(ZQR0(IIW:IIA,:,:) - PSRC(IIW:IIA,:,:))
+      ZQL(IIW:IIA,:,:) = ZQR0(IIW:IIA,:,:) - ZQ6(IIW:IIA,:,:)
+      ZQR(IIW:IIA,:,:) = ZQR0(IIW:IIA,:,:)
+   END WHERE
+!
+! recalculate coefficients of the parabolae
+!
+   ZDQ(IIW:IIA,:,:) = ZQR(IIW:IIA,:,:) - ZQL(IIW:IIA,:,:)
+#else
+!$acc loop independent collapse(3)
+   DO K=IKB,IKE
+      DO J=IJS,IJN
+         DO I=1,IIU
+            !
+            ! determine initial coefficients of the parabolae
+            !
+            ZDQ(I,J,K) = ZQR0(I,J,K) - ZQL0(I,J,K)
+            ZQ60(I,J,K) = 6.0*(PSRC(I,J,K) - 0.5*(ZQL0(I,J,K) + ZQR0(I,J,K)))
+            !
+            ! initialize final parabolae parameters
+            !
+            ZQL(I,J,K) = ZQL0(I,J,K)
+            ZQR(I,J,K) = ZQR0(I,J,K)
+            ZQ6(I,J,K) = ZQ60(I,J,K)
+            !
+            ! eliminate over and undershoots and create qL and qR as in Lin96
+            !
+            IF ( ZDMQ(I,J,K) == 0.0 ) THEN
+               ZQL(I,J,K) = PSRC(I,J,K)
+               ZQR(I,J,K) = PSRC(I,J,K)
+               ZQ6(I,J,K) = 0.0
+            ELSE IF ( ZQ60(I,J,K)*ZDQ(I,J,K) < -ZDQ(I,J,K)*ZDQ(I,J,K) ) THEN
+               ZQ6(I,J,K) = 3.0*(ZQL0(I,J,K) - PSRC(I,J,K))
+               ZQR(I,J,K) = ZQL0(I,J,K) - ZQ6(I,J,K)
+               ZQL(I,J,K) = ZQL0(I,J,K)
+            ELSE IF ( ZQ60(I,J,K)*ZDQ(I,J,K) > ZDQ(I,J,K)*ZDQ(I,J,K) ) THEN
+               ZQ6(I,J,K) = 3.0*(ZQR0(I,J,K) - PSRC(I,J,K))
+               ZQL(I,J,K) = ZQR0(I,J,K) - ZQ6(I,J,K)
+               ZQR(I,J,K) = ZQR0(I,J,K)
+            END IF
+            !
+            ! recalculate coefficients of the parabolae
+            !
+            ZDQ(I,J,K) = ZQR(I,J,K) - ZQL(I,J,K)
+            !
+         END DO
+      END DO
+   END DO
+#endif
+!
+! and finally calculate fluxes for the advection
+!
+!  ZFPOS(j) = Fct[ ZQR(j-1),PCR(i),ZDQ(j-1),ZQ6(j-1) ]
+!
+   ZFPOS(IIW:IIA,IJB:IJE+1,:) = ZQR(IIW:IIA,IJB-1:IJE,:) - 0.5*PCR(IIW:IIA,IJB:IJE+1,:) * &            
+        (ZDQ(IIW:IIA,IJB-1:IJE,:) - (1.0 - 2.0*PCR(IIW:IIA,IJB:IJE+1,:)/3.0)        &
+        * ZQ6(IIW:IIA,IJB-1:IJE,:))
+!
+#ifndef MNH_OPENACC
+  CALL GET_HALO(ZFPOS, HNAME='ZFPOS')
+#else
+!$acc end kernels
+  CALL GET_HALO_D(ZFPOS,HDIR="01_Y", HNAME='ZFPOS')
+!$acc kernels
+#endif
+!
+! SOUTH BOUND
+!
+! PPOSX(:,IJB-1,:) is not important for the calc of advection so 
+! we set it to 0
+!!$   ZFPOS(:,IJB-1,:) = 0.0 JUANPPMLL01
+!
+   ZFNEG(IIW:IIA,:,:) = ZQL(IIW:IIA,:,:) - 0.5*PCR(IIW:IIA,:,:) *      &            
+        ( ZDQ(IIW:IIA,:,:) + (1.0 + 2.0*PCR(IIW:IIA,:,:)/3.0) * ZQ6(IIW:IIA,:,:) )
+!
+#ifndef MNH_OPENACC
+  CALL GET_HALO(ZFNEG, HNAME='ZFNEG')
+#else
+!$acc end kernels
+  CALL GET_HALO_D(ZFNEG,HDIR="01_Y", HNAME='ZFNEG')
+!$acc kernels
+#endif
+!
+! advect the actual field in Y direction by V*dt
+!
+#ifndef MNH_OPENACC
+   PR = DYF( PCR*MYM(PRHO)*( ZFPOS*(0.5+SIGN(0.5,PCR)) + & 
+                             ZFNEG*(0.5-SIGN(0.5,PCR)) ) )
+#else
+!$acc end kernels
+   CALL MYM_DEVICE(PRHO,ZQL)
+!$acc kernels
+!$acc loop independent collapse(3)
+   DO K=IKB,IKE
+      DO J=IJS,IJN
+         DO I=1,IIU
+          if ( PCR(I,J,K) > 0. ) then
+            ZQR(I,J,K) =  PCR(I,J,K)* ZQL(I,J,K) * ZFPOS(I,J,K)
+          else
+            ZQR(I,J,K) =  PCR(I,J,K)* ZQL(I,J,K) * ZFNEG(I,J,K)
+          end if
+         END DO
+      END DO
+   END DO
+!$acc end kernels
+   CALL DYF_DEVICE(ZQR,PR)
+#endif
+#ifndef MNH_OPENACC
+  CALL GET_HALO(PR, HNAME='PR')
+#else
+  CALL GET_HALO_D(PR,HDIR="01_Y", HNAME='PR')
+#endif
+!
+!*       2.2    NON-CYCLIC BOUNDARY CONDITIONS IN THE Y DIRECTION
+!               -------------------------------------------------
+!
+CASE('OPEN')
+!
+! calculate dmq
+#ifndef  MNH_OPENACC   
+   ZDMQ = DIF2Y(PSRC)
+#else
+   CALL DIF2Y_DEVICE(ZDMQ,PSRC)
+#endif   
+!$acc kernels
+! overwrite the values on the boundary to get second order difference
+! for qL and qR at the boundary
+!
+!  SOUTH BOUND
+!
+   IF (GSOUTH) THEN
+    ZDMQ(IIW:IIA,IJB-1,:) = -ZDMQ(IIW:IIA,IJB,:)
+   ENDIF
+!
+!  NORTH BOUND
+!
+   IF (GNORTH) THEN
+    ZDMQ(IIW:IIA,IJE+1,:) = -ZDMQ(IIW:IIA,IJE,:)
+   ENDIF
+!
+! monotonize the difference followinq eq. 5 in Lin94
+!$acc loop independent collapse(3)
+  do jk = 1, iku
+    do jj = ijb, ije
+      do ji = iiw, iia
+        ZDMQ(ji, jj, jk ) = SIGN( &
+        MIN( ABS( ZDMQ(ji, jj, jk ) ),                                                                             &
+             2.0 * (   PSRC(ji, jj, jk ) - MIN( PSRC(ji, jj-1, jk ), PSRC(ji, jj, jk ), PSRC(ji, jj+1, jk ) ) ),   &
+             2.0 * ( - PSRC(ji, jj, jk ) + MAX( PSRC(ji, jj-1, jk ), PSRC(ji, jj, jk ), PSRC(ji, jj+1, jk ) ) ) ), &
+        ZDMQ(ji, jj, jk ) )
+    end do
+  end do
+end do
+!!$   ZDMQ(:,IJB-1,:) = &
+!!$        SIGN( (MIN( ABS(ZDMQ(:,IJB-1,:)), 2.0*(PSRC(:,IJB-1,:) - &
+!!$        MIN(PSRC(:,IJE-1,:),PSRC(:,IJB-1,:),PSRC(:,IJB,:))),   &
+!!$        2.0*(MAX(PSRC(:,IJE-1,:),PSRC(:,IJB-1,:),PSRC(:,IJB,:)) - &
+!!$        PSRC(:,IJB-1,:)) )), ZDMQ(:,IJB-1,:) )
+!!$   ZDMQ(:,IJE+1,:) = &
+!!$        SIGN( (MIN( ABS(ZDMQ(:,IJE+1,:)), 2.0*(PSRC(:,IJE+1,:) - &
+!!$        MIN(PSRC(:,IJE,:),PSRC(:,IJE+1,:),PSRC(:,IJB+1,:))),  &
+!!$        2.0*(MAX(PSRC(:,IJE,:),PSRC(:,IJE+1,:),PSRC(:,IJB+1,:)) - &
+!!$        PSRC(:,IJE+1,:)) )), ZDMQ(:,IJE+1,:) ) 
+!
+!  update ZDMQ HALO before next/further  utilisation 
+!
+#ifndef MNH_OPENACC
+   CALL  GET_HALO(ZDMQ, HNAME='ZDMQ')
+#else
+!$acc end kernels
+   CALL  GET_HALO_D(ZDMQ,HDIR="01_Y", HNAME='ZDMQ')
+!$acc kernels
+#endif
+!
+! calculate qL and qR with the modified dmq
+!
+!$acc loop independent collapse(3)
+  do jk = 1, iku
+    do jj = ijb, ije + 1
+      do ji = iiw, iia
+        ZQL0(ji, jj, jk ) = 0.5 * ( PSRC(ji, jj, jk ) + PSRC(ji, jj-1, jk )) - ( ZDMQ(ji, jj, jk ) - ZDMQ(ji, jj-1, jk ) ) / 6.0
+      end do
+    end do
+  end do
+!
+#ifndef MNH_OPENACC
+   CALL  GET_HALO(ZQL0, HNAME='ZQL0')
+#else
+!$acc end kernels
+CALL  GET_HALO_D(ZQL0,HDIR="01_Y", HNAME='ZQL0')
+!$acc kernels
+#endif
+!
+!  SOUTH BOUND
+!
+   IF (GSOUTH) THEN
+    ZQL0(IIW:IIA,IJB-1,:) = ZQL0(IIW:IIA,IJB,:)
+   ENDIF
+!
+!$acc loop independent collapse(3)
+  do jk = 1, iku
+    do jj = ijb - 1, ije
+      do ji = iiw, iia
+        ZQR0(ji, jj, jk ) = ZQL0(ji, jj+1, jk )
+      end do
+    end do
+  end do
+!
+!  NORTH BOUND
+!
+   IF (GNORTH) THEN
+    ZQR0(IIW:IIA,IJE+1,:) = ZQR0(IIW:IIA,IJE,:)
+   ENDIF
+#ifndef MNH_OPENACC
+!
+! determine initial coefficients of the parabolae
+!
+   ZDQ(IIW:IIA,:,:) = ZQR0(IIW:IIA,:,:) - ZQL0(IIW:IIA,:,:)
+   ZQ60(IIW:IIA,:,:) = 6.0*(PSRC(IIW:IIA,:,:) - 0.5*(ZQL0(IIW:IIA,:,:) + ZQR0(IIW:IIA,:,:)))
+!
+! initialize final parabolae parameters
+!
+   ZQL(IIW:IIA,:,:) = ZQL0(IIW:IIA,:,:)
+   ZQR(IIW:IIA,:,:) = ZQR0(IIW:IIA,:,:)
+   ZQ6(IIW:IIA,:,:) = ZQ60(IIW:IIA,:,:) 
+!
+! eliminate over and undershoots and create qL and qR as in Lin96
+!
+   WHERE ( ZDMQ(IIW:IIA,:,:) == 0.0 )
+      ZQL(IIW:IIA,:,:) = PSRC(IIW:IIA,:,:)
+      ZQR(IIW:IIA,:,:) = PSRC(IIW:IIA,:,:)
+      ZQ6(IIW:IIA,:,:) = 0.0
+   ELSEWHERE ( ZQ60(IIW:IIA,:,:)*ZDQ(IIW:IIA,:,:) < -ZDQ(IIW:IIA,:,:)*ZDQ(IIW:IIA,:,:) )
+      ZQ6(IIW:IIA,:,:) = 3.0*(ZQL0(IIW:IIA,:,:) - PSRC(IIW:IIA,:,:))
+      ZQR(IIW:IIA,:,:) = ZQL0(IIW:IIA,:,:) - ZQ6(IIW:IIA,:,:)
+      ZQL(IIW:IIA,:,:) = ZQL0(IIW:IIA,:,:)
+   ELSEWHERE ( ZQ60(IIW:IIA,:,:)*ZDQ(IIW:IIA,:,:) > ZDQ(IIW:IIA,:,:)*ZDQ(IIW:IIA,:,:) )
+      ZQ6(IIW:IIA,:,:) = 3.0*(ZQR0(IIW:IIA,:,:) - PSRC(IIW:IIA,:,:))
+      ZQL(IIW:IIA,:,:) = ZQR0(IIW:IIA,:,:) - ZQ6(IIW:IIA,:,:)
+      ZQR(IIW:IIA,:,:) = ZQR0(IIW:IIA,:,:)
+   END WHERE
+!
+! recalculate coefficients of the parabolae
+!
+   ZDQ(IIW:IIA,:,:) = ZQR(IIW:IIA,:,:) - ZQL(IIW:IIA,:,:)
+!
+#else
+!$acc loop independent collapse(3)
+   DO K=IKB,IKE
+      DO J=IJS,IJN
+         DO I=1,IIU
+            !
+            ! determine initial coefficients of the parabolae
+            !
+            ZDQ(I,J,K) = ZQR0(I,J,K) - ZQL0(I,J,K)
+            ZQ60(I,J,K) = 6.0*(PSRC(I,J,K) - 0.5*(ZQL0(I,J,K) + ZQR0(I,J,K)))
+            !
+            ! initialize final parabolae parameters
+            !
+            ZQL(I,J,K) = ZQL0(I,J,K)
+            ZQR(I,J,K) = ZQR0(I,J,K)
+            ZQ6(I,J,K) = ZQ60(I,J,K) 
+            !
+            ! eliminate over and undershoots and create qL and qR as in Lin96
+            !
+            IF ( ZDMQ(I,J,K) == 0.0 ) THEN
+               ZQL(I,J,K) = PSRC(I,J,K)
+               ZQR(I,J,K) = PSRC(I,J,K)
+               ZQ6(I,J,K) = 0.0
+            ELSE IF ( ZQ60(I,J,K)*ZDQ(I,J,K) < -ZDQ(I,J,K)*ZDQ(I,J,K) ) THEN
+               ZQ6(I,J,K) = 3.0*(ZQL0(I,J,K) - PSRC(I,J,K))
+               ZQR(I,J,K) = ZQL0(I,J,K) - ZQ6(I,J,K)
+               ZQL(I,J,K) = ZQL0(I,J,K)
+            ELSE IF ( ZQ60(I,J,K)*ZDQ(I,J,K) > ZDQ(I,J,K)*ZDQ(I,J,K) ) THEN
+               ZQ6(I,J,K) = 3.0*(ZQR0(I,J,K) - PSRC(I,J,K))
+               ZQL(I,J,K) = ZQR0(I,J,K) - ZQ6(I,J,K)
+               ZQR(I,J,K) = ZQR0(I,J,K)
+            END IF
+            !
+            ! recalculate coefficients of the parabolae
+            !
+            ZDQ(I,J,K) = ZQR(I,J,K) - ZQL(I,J,K)
+            !
+         END DO
+      END DO
+   END DO
+#endif
+!
+! and finally calculate fluxes for the advection
+!
+!!$   ZFPOS(:,IJB+1:IJE+1,:) = ZQR(:,IJB:IJE,:) - 0.5*PCR(:,IJB+1:IJE+1,:) * &            
+!!$        (ZDQ(:,IJB:IJE,:) - (1.0 - 2.0*PCR(:,IJB+1:IJE+1,:)/3.0)        &
+!!$        * ZQ6(:,IJB:IJE,:))
+!$acc loop independent collapse(3)
+  do jk = 1, iku
+    do jj = ijb, ije + 1
+      do ji = iiw, iia
+        ZFPOS(ji, jj, jk ) = ZQR(ji, jj-1, jk ) - 0.5 * PCR(ji, jj, jk )   &
+                                      * ( ZDQ(ji, jj-1, jk ) - ( 1.0 - 2.0 * PCR(ji, jj, jk ) / 3.0 ) * ZQ6(ji, jj-1, jk ) )
+      end do
+    end do
+  end do
+!
+#ifndef MNH_OPENACC
+  CALL GET_HALO(ZFPOS, HNAME='ZFPOS')
+#else
+!$acc end kernels
+  CALL GET_HALO_D(ZFPOS,HDIR="01_Y", HNAME='ZFPOS')
+!$acc kernels
+#endif
+!
+!
+! advection flux at open boundary when u(IJB) > 0
+!  
+!  SOUTH BOUND
+!
+   IF (GSOUTH) THEN
+    ZFPOS(IIW:IIA,IJB,:) = (PSRC(IIW:IIA,IJB-1,:) - ZQR(IIW:IIA,IJB-1,:))*PCR(IIW:IIA,IJB,:) + &
+                      ZQR(IIW:IIA,IJB-1,:)
+   ENDIF
+!
+! PPOSX(:,IJB-1,:) is not important for the calc of advection so 
+! we set it to 0
+!!$   ZFPOS(:,IJB-1,:) = 0.0 ! JUAN PPMLL01
+!
+!!$   ZFNEG(:,IJB-1:IJE,:) = ZQL(:,IJB-1:IJE,:) - 0.5*PCR(:,IJB-1:IJE,:) * &            
+!!$        ( ZDQ(:,IJB-1:IJE,:) + (1.0 + 2.0*PCR(:,IJB-1:IJE,:)/3.0) * &
+!!$        ZQ6(:,IJB-1:IJE,:) )
+!$acc loop independent collapse(3)
+  do jk = 1, iku
+    do jj = 1, iju
+      do ji = iiw, iia
+        ZFNEG(ji, jj, jk ) = ZQL(ji, jj, jk ) - 0.5 * PCR(ji, jj, jk )      &
+                                     * ( ZDQ(ji, jj, jk ) + ( 1.0 + 2.0 * PCR(ji, jj, jk ) / 3.0 ) * ZQ6(ji, jj, jk ) )
+      end do
+    end do
+  end do
+!
+#ifndef MNH_OPENACC
+  CALL GET_HALO(ZFNEG, HNAME='ZFNEG')
+#else
+!$acc end kernels
+  CALL GET_HALO_D(ZFNEG,HDIR="01_Y", HNAME='ZFNEG')
+!$acc kernels
+#endif
+!
+! advection flux at open boundary when u(IJE+1) < 0
+!
+!  NORTH BOUND
+!
+   IF (GNORTH) THEN
+    ZFNEG(IIW:IIA,IJE+1,:) = (ZQR(IIW:IIA,IJE,:)-PSRC(IIW:IIA,IJE+1,:))*PCR(IIW:IIA,IJE+1,:) + &
+                        ZQR(IIW:IIA,IJE,:)
+   ENDIF
+#ifndef MNH_OPENACC
+!
+! advect the actual field in X direction by U*dt
+!
+   PR = DYF( PCR*MYM(PRHO)*( ZFPOS*(0.5+SIGN(0.5,PCR)) + & 
+                             ZFNEG*(0.5-SIGN(0.5,PCR)) ) )
+!
+#else
+!$acc end kernels
+   CALL MYM_DEVICE(PRHO,ZQL)
+!$acc kernels
+!$acc loop independent collapse(3)
+   DO K=IKB,IKE
+      DO J=IJS,IJN
+         DO I=1,IIU
+          if ( PCR(I,J,K) > 0. ) then
+            ZQR(I,J,K) =  PCR(I,J,K)* ZQL(I,J,K) * ZFPOS(I,J,K)
+          else
+            ZQR(I,J,K) =  PCR(I,J,K)* ZQL(I,J,K) * ZFNEG(I,J,K)
+          end if
+         END DO
+      END DO
+   END DO
+!$acc end kernels
+   CALL DYF_DEVICE(ZQR,PR)
+#endif
+!
+#ifndef MNH_OPENACC
+  CALL GET_HALO(PR, HNAME='PR')
+#else
+  CALL GET_HALO_D(PR,HDIR="01_Y", HNAME='PR')
+#endif
+!
+!
+END SELECT
+!
+IF (MPPDB_INITIALIZED) THEN
+  !Check all INOUT arrays
+  CALL MPPDB_CHECK(PSRC,"PPM_01_Y end:PSRC")
+  !Check all OUT arrays
+  CALL MPPDB_CHECK(PR,"PPM_01_Y end:PR")
+END IF
+
+!$acc end data
+
+#ifndef MNH_OPENACC
+CONTAINS
+#else
+END SUBROUTINE PPM_01_Y_D
+#endif
+!
+!-------------------------------------------------------------------------------
+!-------------------------------------------------------------------------------
+!
+!     ########################################################################
+      FUNCTION DIF2Y(PQ) RESULT(DQ)
+!     ########################################################################
+!!
+!!****  DIF2Y - leap-frog difference operator in Y direction
+!!
+!!    Calculates the difference assuming periodic BC (CYCL). 
+!!
+!!    DQ(J) = 0.5 * (PQ(J+1) - PQ(J-1))
+!!
+!!
+!!    MODIFICATIONS
+!!    -------------
+!!    
+!!    18.3.2006.  T. Maric - original version, works only for periodic boundary
+!!                           conditions and on one domain
+!!    04/2017     J.Escobar : initialize realistic value in all HALO pts
+!!
+!-------------------------------------------------------------------------------
+!
+!
+USE MODE_ll
+!
+IMPLICIT NONE
+! 
+!*       0.1   Declarations of dummy arguments :
+!   
+REAL, DIMENSION(:,:,:), INTENT(IN)                :: PQ
+REAL, DIMENSION(SIZE(PQ,1),SIZE(PQ,2),SIZE(PQ,3)) :: DQ
+!
+!*       0.2   Declarations of local variables :
+!   
+INTEGER :: IIB,IJB        ! Begining useful area in x,y directions
+INTEGER :: IIE,IJE        ! End useful area in x,y directions
+!
+!-------------------------------------------------------------------------------
+
+!$acc data present(PQ, DQ)
+!
+!*       1.0.     COMPUTE THE DOMAIN DIMENSIONS
+!                 -----------------------------
+!
+!!$CALL GET_INDICE_ll(IIB,IJB,IIE,IJE)
+IIB=2 ; IIE = SIZE(PQ,1) -1
+IJB=2 ; IJE = SIZE(PQ,2) -1
+!
+!-------------------------------------------------------------------------------
+!
+!*       2.0.     COMPUTE THE DIFFERENCE
+!                 ----------------------
+!
+!$acc kernels
+DQ(:,IJB:IJE,:) = PQ(:,IJB+1:IJE+1,:) - PQ(:,IJB-1:IJE-1,:)
+DQ(:,IJB-1,:) = PQ(:,IJB,:) - PQ(:,IJE-1,:)
+DQ(:,IJE+1,:) = PQ(:,IJB+1,:) - PQ(:,IJE,:) 
+DQ = 0.5 * DQ
+!$acc end kernels
+
+!$acc end data
+
+END FUNCTION DIF2Y
+!-------------------------------------------------------------------------------
+!
+!     ########################################################################
+      SUBROUTINE DIF2Y_DEVICE(DQ,PQ)
+!     ########################################################################
+!!
+!!****  DIF2Y - leap-frog difference operator in Y direction
+!!
+!!    Calculates the difference assuming periodic BC (CYCL). 
+!!
+!!    DQ(J) = 0.5 * (PQ(J+1) - PQ(J-1))
+!!
+!!
+!!    MODIFICATIONS
+!!    -------------
+!!    
+!!    18.3.2006.  T. Maric - original version, works only for periodic boundary
+!!                           conditions and on one domain
+!!    04/2017     J.Escobar : initialize realistic value in all HALO pts
+!!
+!-------------------------------------------------------------------------------
+!
+!
+USE MODE_ll
+!
+IMPLICIT NONE
+! 
+!*       0.1   Declarations of dummy arguments :
+!   
+REAL, DIMENSION(:,:,:), INTENT(IN)                :: PQ
+REAL, DIMENSION(:,:,:)                            :: DQ
+!
+!*       0.2   Declarations of local variables :
+!   
+INTEGER :: IIB,IJB        ! Begining useful area in x,y directions
+INTEGER :: IIE,IJE        ! End useful area in x,y directions
+!
+!-------------------------------------------------------------------------------
+
+!$acc data present(PQ, DQ)
+!
+!*       1.0.     COMPUTE THE DOMAIN DIMENSIONS
+!                 -----------------------------
+!
+!!$CALL GET_INDICE_ll(IIB,IJB,IIE,IJE)
+IIB=2 ; IIE = SIZE(PQ,1) -1
+IJB=2 ; IJE = SIZE(PQ,2) -1
+!
+!-------------------------------------------------------------------------------
+!
+!*       2.0.     COMPUTE THE DIFFERENCE
+!                 ----------------------
+!
+!$acc kernels
+DQ(:,IJB:IJE,:) = PQ(:,IJB+1:IJE+1,:) - PQ(:,IJB-1:IJE-1,:)
+DQ(:,IJB-1,:) = PQ(:,IJB,:) - PQ(:,IJE-1,:)
+DQ(:,IJE+1,:) = PQ(:,IJB+1,:) - PQ(:,IJE,:) 
+DQ = 0.5 * DQ
+!$acc end kernels
+
+!$acc end data
+
+END SUBROUTINE DIF2Y_DEVICE
+! #endif
+!
+#ifdef MNH_OPENACC
+! END SUBROUTINE PPM_01_Y_D
+
+END SUBROUTINE PPM_01_Y
+#else
+END FUNCTION PPM_01_Y
+#endif
+!
+!
+!-------------------------------------------------------------------------------
+!-------------------------------------------------------------------------------
+!
+#ifdef MNH_OPENACC
+!     ########################################################################
+!!$      FUNCTION PPM_01_Z(KGRID, PSRC, PCR, PRHO, PTSTEP) RESULT(PR)
+      SUBROUTINE PPM_01_Z(KGRID, PSRC, PCR, PRHO, PTSTEP, PR)
+!     ########################################################################
+
+  USE MODE_MNH_ZWORK, ONLY : ZT3D, MNH_GET_ZT3D , MNH_REL_ZT3D
+  USE MODE_MNH_ZWORK, ONLY : IIU,IJU,IKU
+
+  IMPLICIT NONE
+!
+!*       0.1   Declarations of dummy arguments :
+!
+INTEGER,                INTENT(IN)  :: KGRID   ! C grid localisation
+REAL,                   INTENT(IN)  :: PTSTEP  ! Time step 
+!
+REAL, DIMENSION(:,:,:), INTENT(INOUT) :: PSRC    ! variable at t
+REAL, DIMENSION(:,:,:), INTENT(IN)    :: PCR &    ! Courant number
+                                      ,  PRHO  ! density
+!
+! output source term
+REAL, DIMENSION(:,:,:), INTENT(OUT) :: PR
+
+INTEGER :: IZQL,IZQR,IZDQ,IZQ6,IZDMQ,IZQL0,IZQR0,IZQ60,IZFPOS,IZFNEG
+
+!$acc data present( PSRC, PCR, PRHO, PR )
+
+        CALL  MNH_GET_ZT3D(IZQL,IZQR,IZDQ,IZQ6,IZDMQ,IZQL0,IZQR0,IZQ60,IZFPOS,IZFNEG)
+
+        CALL  PPM_01_Z_D(IIU,IJU,IKU, KGRID, &
+                     & PSRC, PCR, PRHO, PTSTEP, PR, &
+                     & ZT3D(:,:,:,IZQL),ZT3D(:,:,:,IZQR),ZT3D(:,:,:,IZDQ),ZT3D(:,:,:,IZQ6), &
+                     & ZT3D(:,:,:,IZDMQ),ZT3D(:,:,:,IZQL0),ZT3D(:,:,:,IZQR0), ZT3D(:,:,:,IZQ60), &
+                     & ZT3D(:,:,:,IZFPOS),ZT3D(:,:,:,IZFNEG) )
+
+        CALL  MNH_REL_ZT3D(IZQL,IZQR,IZDQ,IZQ6,IZDMQ,IZQL0,IZQR0,IZQ60,IZFPOS,IZFNEG)
+
+!$acc end data
+
+CONTAINS
+!
+!     ########################################################################
+        SUBROUTINE  PPM_01_Z_D(IIU,IJU,IKU,KGRID, &
+                     & PSRC, PCR, PRHO, PTSTEP, PR, &
+                     & ZQL,ZQR,ZDQ,ZQ6,ZDMQ,ZQL0,ZQR0,ZQ60,ZFPOS,ZFNEG)
+!     ########################################################################
+#else
+!     ########################################################################
+      FUNCTION PPM_01_Z(KGRID, PSRC, PCR, PRHO, PTSTEP) RESULT(PR)
+!     ########################################################################
+#endif
+!!
+!!****  PPM_01_Z - PPM_01 fully monotonic PPM advection scheme in Z direction
+!!                 Colella notation
+!!
+!!    MODIFICATIONS
+!!    -------------
+!!    
+!!    11.5.2006.  T. Maric - original version
+!!
+!-------------------------------------------------------------------------------
+!
+USE MODE_ll
+
+#ifndef MNH_OPENACC
+USE MODI_SHUMAN
+#else
+USE MODI_SHUMAN_DEVICE
+#endif
+USE MODI_GET_HALO
+#ifdef MNH_BITREP
+USE MODI_BITREP
+#endif
+!
+USE MODD_CONF
+USE MODD_PARAMETERS
+!USE MODD_ARGSLIST_ll, ONLY : HALO2LIST_ll
+USE MODE_MPPDB
+!
+IMPLICIT NONE
+!
+!*       0.1   Declarations of dummy arguments :
+!
+#ifdef MNH_OPENACC
+integer,                intent(in)    :: iiu, iju, iku
+#endif
+INTEGER,                INTENT(IN)  :: KGRID   ! C grid localisation
+!
+#ifndef MNH_OPENACC
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PSRC    ! variable at t
+#else
+REAL, DIMENSION(:,:,:), INTENT(INOUT)  :: PSRC    ! variable at t
+#endif
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PCR     ! Courant number
+!
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PRHO  ! density
+REAL,                   INTENT(IN)  :: PTSTEP  ! Time step 
+!
+! output source term
+#ifndef MNH_OPENACC
+REAL, DIMENSION(SIZE(PCR,1),SIZE(PCR,2),SIZE(PCR,3)) :: PR
+#else
+REAL, DIMENSION(IIU,IJU,IKU), INTENT(OUT) :: PR
+#endif
+!
+!*       0.2   Declarations of local variables :
+!
+#ifndef MNH_OPENACC
+INTEGER :: IIU, IJU, IKU
+INTEGER:: IKB    ! Begining useful area in x,y,z directions
+INTEGER:: IKE    ! End useful area in x,y,z directions
+!
+! terms used in parabolic interpolation, dmq, qL, qR, dq, q6
+REAL, DIMENSION(SIZE(PCR,1),SIZE(PCR,2),SIZE(PCR,3)) :: ZQL,ZQR
+REAL, DIMENSION(SIZE(PCR,1),SIZE(PCR,2),SIZE(PCR,3)) :: ZDQ,ZQ6
+REAL, DIMENSION(SIZE(PCR,1),SIZE(PCR,2),SIZE(PCR,3)) :: ZDMQ
+!
+! extra variables for the initial guess of parabolae parameters
+REAL, DIMENSION(SIZE(PCR,1),SIZE(PCR,2),SIZE(PCR,3)) :: ZQL0,ZQR0,ZQ60
+!
+! advection fluxes
+REAL, DIMENSION(SIZE(PCR,1),SIZE(PCR,2),SIZE(PCR,3)) :: ZFPOS, ZFNEG
+#else
+! terms used in parabolic interpolation, dmq, qL, qR, dq, q6
+REAL, DIMENSION(IIU,IJU,IKU) :: &
+                                                      ZQL, ZQR, ZDQ, ZQ6, ZDMQ &
+!
+! extra variables for the initial guess of parabolae parameters
+                                                     , ZQL0,ZQR0,ZQ60 &
+!
+! advection fluxes
+                                                     , ZFPOS, ZFNEG
+!
+INTEGER:: IKB    ! Begining useful area in x,y,z directions
+INTEGER:: IKE    ! End useful area in x,y,z directions
+!
+INTEGER                          :: I,J,K 
+#endif
+integer                          :: ji, jj, jk
+!
+!-------------------------------------------------------------------------------
+
+!$acc data present( PSRC, PCR, PRHO, PR, &
+!$acc &             ZQL, ZQR, ZDQ, ZQ6, ZDMQ, ZQL0, ZQR0, ZQ60, ZFPOS, ZFNEG )
+IF (MPPDB_INITIALIZED) THEN
+  !Check all IN arrays
+  CALL MPPDB_CHECK(PCR, "PPM_01_Z beg:PCR")
+  CALL MPPDB_CHECK(PRHO,"PPM_01_Z beg:PRHO")
+  !Check all INOUT arrays
+  CALL MPPDB_CHECK(PSRC,"PPM_01_Z beg:PSRC")
+END IF
+!
+!*       0.3.     COMPUTES THE DOMAIN DIMENSIONS
+!                 ------------------------------
+!
+IKB = 1 + JPVEXT
+IKE = SIZE(PSRC,3) - JPVEXT
+#ifndef MNH_OPENACC
+iiu = size( PSRC, 1 )
+iju = size( PSRC, 2 )
+iku = size( PSRC, 3 )
+#endif
+
+!$acc kernels
+!$acc loop independent collapse(3)
+  do jk = 1, iku
+    do jj = 1, iju
+      do ji = 1, iiu
+        PR   (ji, jj, jk ) = PSRC(ji, jj, jk )
+        ZQL  (ji, jj, jk ) = PSRC(ji, jj, jk )
+        ZQR  (ji, jj, jk ) = PSRC(ji, jj, jk )
+        ZDQ  (ji, jj, jk ) = PSRC(ji, jj, jk )
+        ZQ6  (ji, jj, jk ) = PSRC(ji, jj, jk )
+        ZDMQ (ji, jj, jk ) = PSRC(ji, jj, jk )
+        ZQL0 (ji, jj, jk ) = PSRC(ji, jj, jk )
+        ZQR0 (ji, jj, jk ) = PSRC(ji, jj, jk )
+        ZQ60 (ji, jj, jk ) = PSRC(ji, jj, jk )
+    end do
+  end do
+end do
+#ifndef MNH_OPENACC
+ZFPOS=PSRC
+ZFNEG=PSRC
+#else
+#if 0
+ZFPOS(1:IIW,:,IKB:IKE)=PSRC(1:IIW,:,IKB:IKE)
+ZFNEG(1:IIW,:,IKB:IKE)=PSRC(1:IIW,:,IKB:IKE)
+ZFPOS(IIA:,:,IKB:IKE)=PSRC(IIA:,:,IKB:IKE)
+ZFNEG(IIA:,:,IKB:IKE)=PSRC(IIA:,:,IKB:IKE)
+#else
+ZFPOS(:,:,:) = PSRC(:,:,:)
+ZFNEG(:,:,:) = PSRC(:,:,:)
+#endif
+#endif
+!$acc end kernels
+!
+!-------------------------------------------------------------------------------
+!
+!*       3.     PPM ADVECTION IN THE Z DIRECTION
+!               --------------------------------
+! 
+! calculate dmq
+#ifndef  MNH_OPENACC
+ZDMQ = DIF2Z(PSRC)
+#else
+CALL DIF2Z_DEVICE(ZDMQ,PSRC)
+#endif
+!$acc kernels
+!
+! monotonize the difference followinq eq. 5 in Lin94
+! use the periodic BC here, it doesn't matter for vertical (hopefully) 
+!
+!$acc loop independent collapse(3)
+do jk = ikb, ike
+  do jj = 1, iju
+    do ji = 1, iiu
+      ZDMQ(ji, jj, jk ) = SIGN(                                                                                    &
+        MIN( ABS( ZDMQ(ji, jj, jk ) ),                                                                             &
+             2.0 * (   PSRC(ji, jj, jk ) - MIN( PSRC(ji, jj, jk-1 ), PSRC(ji, jj, jk ), PSRC(ji, jj, jk+1 ) ) ) ,  &
+             2.0 * ( - PSRC(ji, jj, jk ) + MAX( PSRC(ji, jj, jk-1 ), PSRC(ji, jj, jk ), PSRC(ji, jj, jk+1 ) ) ) ), &
+        ZDMQ(ji, jj, jk ) )
+    end do
+  end do
+end do
+ZDMQ(:,:,IKB-1) = &
+     SIGN( (MIN( ABS(ZDMQ(:,:,IKB-1)), 2.0*(PSRC(:,:,IKB-1) - &
+     MIN(PSRC(:,:,IKE-1),PSRC(:,:,IKB-1),PSRC(:,:,IKB))),   &
+     2.0*(MAX(PSRC(:,:,IKE-1),PSRC(:,:,IKB-1),PSRC(:,:,IKB)) - &
+     PSRC(:,:,IKB-1)) )), ZDMQ(:,:,IKB-1) )
+ZDMQ(:,:,IKE+1) = &
+     SIGN( (MIN( ABS(ZDMQ(:,:,IKE+1)), 2.0*(PSRC(:,:,IKE+1) - &
+     MIN(PSRC(:,:,IKE),PSRC(:,:,IKE+1),PSRC(:,:,IKB+1))),  &
+     2.0*(MAX(PSRC(:,:,IKE),PSRC(:,:,IKE+1),PSRC(:,:,IKB+1)) - &
+     PSRC(:,:,IKE+1)) )), ZDMQ(:,:,IKE+1) )
+!
+! calculate qL and qR with the modified dmq
+!
+!$acc loop independent collapse(3)
+do jk = ikb, ike + 1
+  do jj = 1, iju
+    do ji = 1, iiu
+      ZQL0(ji, jj, jk ) = 0.5 * ( PSRC(ji, jj, jk ) + PSRC(ji, jj, jk-1 ) ) - ( ZDMQ(ji, jj, jk ) - ZDMQ(ji, jj, jk-1 ) ) / 6.0
+    end do
+  end do
+end do
+ZQL0(:,:,IKB-1) = ZQL0(:,:,IKE)
+!
+!$acc loop independent collapse(3)
+do jk = ikb - 1, ike
+  do jj = 1, iju
+    do ji = 1, iiu
+      ZQR0(ji, jj, jk ) = ZQL0(ji, jj, jk+1 )
+    end do
+  end do
+end do
+ZQR0(:,:,IKE+1) = ZQR0(:,:,IKB)
+#ifndef MNH_OPENACC
+!
+! determine initial coefficients of the parabolae
+!
+!Note: do loop on jk is done from 1 to iku to prevent problems with unitialized value
+!      in the next "where"
+! do jk = ikb - 1, ike
+do jk = 1, iku
+  do jj = 1, iju
+    do ji = 1, iiu
+      ZDQ (ji, jj, jk ) = ZQR0(ji, jj, jk ) - ZQL0(ji, jj, jk )
+      ZQ60(ji, jj, jk ) = 6.0 * ( PSRC(ji, jj, jk ) - 0.5 * ( ZQL0(ji, jj, jk ) + ZQR0(ji, jj, jk ) ) )
+    end do
+  end do
+end do
+!
+! initialize final parabolae parameters
+!
+ZQL = ZQL0
+ZQR = ZQR0
+ZQ6 = ZQ60 
+!
+! eliminate over and undershoots and create qL and qR as in Lin96
+!
+WHERE ( ZDMQ == 0.0 )
+   ZQL = PSRC
+   ZQR = PSRC
+   ZQ6 = 0.0
+#ifndef MNH_BITREP
+ELSEWHERE ( ZQ60*ZDQ < -(ZDQ)**2 )
+#else
+ELSEWHERE ( ZQ60*ZDQ < -BR_P2(ZDQ) )
+#endif
+   ZQ6 = 3.0*(ZQL0 - PSRC)
+   ZQR = ZQL0 - ZQ6
+   ZQL = ZQL0
+#ifndef MNH_BITREP
+ELSEWHERE ( ZQ60*ZDQ > (ZDQ)**2 ) 
+#else
+ELSEWHERE ( ZQ60*ZDQ > BR_P2(ZDQ) ) 
+#endif
+   ZQ6 = 3.0*(ZQR0 - PSRC)
+   ZQL = ZQR0 - ZQ6
+   ZQR = ZQR0
+END WHERE
+!
+! recalculate coefficients of the parabolae
+!
+ZDQ = ZQR - ZQL
+#else
+!!!
+!!! initialize final parabolae parameters
+!!!
+!!ZQL = ZQL0
+!!ZQR = ZQR0
+!!ZQ6 = ZQ60 
+!!!
+!!! eliminate over and undershoots and create qL and qR as in Lin96
+!!!
+!!!PW: BUG: done like that because if using PGI (tested up to 16.10)
+!!! will cause crashes at run (address not mapped)
+!!! and problems at compilation
+!!$WHERE ( ZDMQ == 0.0 )
+!!$   ZQL = PSRC
+!!$   ZQR = PSRC
+!!$   ZQ6 = 0.0
+!!$END WHERE
+!!#ifndef MNH_BITREP
+!!$WHERE ( ( ZDMQ /= 0.0 ) .AND. ( ZQ60*ZDQ < -ZDQ**2 ) )
+!!#else
+!!$WHERE ( ( ZDMQ /= 0.0 ) .AND. ( ZQ60*ZDQ < -BR_P2(ZDQ) ) )
+!!#endif
+!!$WHERE ( ( ZDMQ /= 0.0 ) .AND. ( ZQ60*ZDQ < -BR_P2(ZDQ) ) )
+!!$   ZQ6 = 3.0*(ZQL0 - PSRC)
+!!$   ZQR = ZQL0 - ZQ6
+!!$   ZQL = ZQL0
+!!$END WHERE
+!!#ifndef MNH_BITREP
+!!$WHERE ( ( ZDMQ /= 0.0 ) .AND. ( ZQ60*ZDQ > ZDQ**2 ) )
+!!#else
+!!$WHERE ( ( ZDMQ /= 0.0 ) .AND. ( ZQ60*ZDQ > BR_P2(ZDQ) ) )
+!!#endif
+!!$WHERE ( ( ZDMQ /= 0.0 ) .AND. ( ZQ60*ZDQ > BR_P2(ZDQ) ) )
+!!$   ZQ6 = 3.0*(ZQR0 - PSRC)
+!!$   ZQL = ZQR0 - ZQ6
+!!$   ZQR = ZQR0
+!!$END WHERE
+!!!
+!!! recalculate coefficients of the parabolae
+!!!
+!!ZDQ = ZQR - ZQL
+!$acc loop independent collapse(3)
+   DO K=1,IKU
+      DO J=1,IJU
+         DO I=1,IIU
+            !
+            ! determine initial coefficients of the parabolae
+            !
+            ZDQ(I,J,K) = ZQR0(I,J,K) - ZQL0(I,J,K)
+            ZQ60(I,J,K) = 6.0*(PSRC(I,J,K) - 0.5*(ZQL0(I,J,K) + ZQR0(I,J,K)))
+            !
+            ! initialize final parabolae parameters
+            !
+            ZQL(I,J,K) = ZQL0(I,J,K)
+            ZQR(I,J,K) = ZQR0(I,J,K)
+            ZQ6(I,J,K) = ZQ60(I,J,K) 
+            !
+            ! eliminate over and undershoots and create qL and qR as in Lin96
+            !
+            IF ( ZDMQ(I,J,K) == 0.0 ) THEN
+               ZQL(I,J,K) = PSRC(I,J,K)
+               ZQR(I,J,K) = PSRC(I,J,K)
+               ZQ6(I,J,K) = 0.0
+            ELSE IF ( ZQ60(I,J,K)*ZDQ(I,J,K) < -ZDQ(I,J,K)*ZDQ(I,J,K) ) THEN
+               ZQ6(I,J,K) = 3.0*(ZQL0(I,J,K) - PSRC(I,J,K))
+               ZQR(I,J,K) = ZQL0(I,J,K) - ZQ6(I,J,K)
+               ZQL(I,J,K) = ZQL0(I,J,K)
+            ELSE IF ( ZQ60(I,J,K)*ZDQ(I,J,K) > ZDQ(I,J,K)*ZDQ(I,J,K) ) THEN
+               ZQ6(I,J,K) = 3.0*(ZQR0(I,J,K) - PSRC(I,J,K))
+               ZQL(I,J,K) = ZQR0(I,J,K) - ZQ6(I,J,K)
+               ZQR(I,J,K) = ZQR0(I,J,K)
+            END IF
+            !
+            ! recalculate coefficients of the parabolae
+            !
+            ZDQ(I,J,K) = ZQR(I,J,K) - ZQL(I,J,K)
+            !
+         END DO
+      END DO
+   END DO
+#endif
+!
+! and finally calculate fluxes for the advection
+!
+!$acc loop independent collapse(3)
+do jk = ikb + 1, ike + 1
+  do jj = 1, iju
+    do ji = 1, iiu
+      ZFPOS(ji, jj, jk ) = ZQR(ji, jj, jk-1 ) - 0.5 * PCR(ji, jj, jk ) &
+                                   * ( ZDQ(ji, jj, jk-1 ) - ( 1.0 - 2.0 * PCR(ji, jj, jk ) / 3.0) * ZQ6(ji, jj, jk-1 ) )
+    end do
+  end do
+end do
+!
+! advection flux at open boundary when u(IKB) > 0
+ZFPOS(:,:,IKB) = (PSRC(:,:,IKB-1) - ZQR(:,:,IKB-1))*PCR(:,:,IKB) + &
+                 ZQR(:,:,IKB-1)
+!
+! PPOSX(IKB-1) is not important for the calc of advection so 
+! we set it to 0
+ZFPOS(:,:,IKB-1) = 0.0
+!
+!$acc loop independent collapse(3)
+do jk = ikb - 1, ike
+  do jj = 1, iju
+    do ji = 1, iiu
+      ZFNEG(ji, jj, jk ) = ZQL(ji, jj, jk ) - 0.5 * PCR(ji, jj, jk ) &
+                                   * ( ZDQ(ji, jj, jk ) + ( 1.0 + 2.0 * PCR(ji, jj, jk ) / 3.0) * ZQ6(ji, jj, jk ) )
+    end do
+  end do
+end do
+!
+! advection flux at open boundary when u(IKE+1) < 0
+ZFNEG(:,:,IKE+1) = (ZQR(:,:,IKE)-PSRC(:,:,IKE+1))*PCR(:,:,IKE+1) + &
+                   ZQR(:,:,IKE)
+!
+! advect the actual field in Z direction by W*dt
+!
+#ifndef MNH_OPENACC
+PR = DZF( PCR*MZM(PRHO)*( ZFPOS*(0.5+SIGN(0.5,PCR)) + &
+                          ZFNEG*(0.5-SIGN(0.5,PCR)) ) )
+#else
+!$acc end kernels 
+    CALL MZM_DEVICE(PRHO,ZQL)
+!$acc kernels 
+!$acc loop independent collapse(3)
+do jk = 1, iku
+  do jj = 1, iju
+    do ji = 1, iiu
+      if ( PCR(ji, jj, jk ) > 0. ) then
+        ZQR(ji, jj, jk ) =  PCR(ji, jj, jk ) * ZQL(ji, jj, jk ) * ZFPOS(ji, jj, jk )
+      else
+        ZQR(ji, jj, jk ) =  PCR(ji, jj, jk ) * ZQL(ji, jj, jk ) * ZFNEG(ji, jj, jk )
+      end if
+    end do
+  end do
+end do
+    !dzf(PR,ZQR)
+!$acc end kernels
+    CALL DZF_DEVICE(1,1,1,ZQR,PR)
+#endif
+!
+#ifndef MNH_OPENACC
+!Unnecessary CALL GET_HALO(PR)
+#else
+!Unnecessary CALL GET_HALO_D(PR)
+#endif
+!
+IF (MPPDB_INITIALIZED) THEN
+  !Check all INOUT arrays
+  CALL MPPDB_CHECK(PSRC,"PPM_01_Z end:PSRC")
+  !Check all OUT arrays
+  CALL MPPDB_CHECK(PR,"PPM_01_Z end:PR")
+END IF
+
+!$acc end data
+
+#ifndef MNH_OPENACC
+CONTAINS
+#else
+END SUBROUTINE PPM_01_Z_D
+#endif
+!
+!-------------------------------------------------------------------------------
+!-------------------------------------------------------------------------------
+!
+!     ########################################################################
+      FUNCTION DIF2Z(PQ) RESULT(DQ)
+!     ########################################################################
+!!
+!!****  DIF2Z - leap-frog difference operator in Z direction
+!!
+!!    Calculates the difference assuming periodic BC (CYCL). 
+!!
+!!    DQ(K) = 0.5 * (PQ(K+1) - PQ(K-1))
+!!
+!!
+!!    MODIFICATIONS
+!!    -------------
+!!    
+!!    18.3.2006.  T. Maric - original version
+!!
+!-------------------------------------------------------------------------------
+!
+!
+USE MODE_ll
+USE MODD_CONF
+USE MODD_PARAMETERS
+!
+IMPLICIT NONE
+! 
+!*       0.1   Declarations of dummy arguments :
+!   
+REAL, DIMENSION(:,:,:), INTENT(IN)                :: PQ
+REAL, DIMENSION(SIZE(PQ,1),SIZE(PQ,2),SIZE(PQ,3)) :: DQ
+!
+!*       0.2   Declarations of local variables :
+!   
+INTEGER :: IKB    ! Begining useful area in z directions
+INTEGER :: IKE    ! End useful area in z directions
+!
+!-------------------------------------------------------------------------------
+
+!$acc data present( PQ, DQ )
+!
+!*       1.0.     COMPUTE THE DOMAIN DIMENSIONS
+!                 -----------------------------
+!
+!CALL GET_INDICE_ll(IIB,IJB,IIE,IJE)
+IKB = 1 + JPVEXT
+IKE = SIZE(PQ,3) - JPVEXT
+!
+!-------------------------------------------------------------------------------
+!
+!*       2.0.     COMPUTE THE DIFFERENCE
+!                 ----------------------
+!
+!$acc kernels
+DQ(:,:,IKB:IKE) = PQ(:,:,IKB+1:IKE+1) - PQ(:,:,IKB-1:IKE-1)
+DQ(:,:,IKB-1) = -DQ(:,:,IKB)
+DQ(:,:,IKE+1) = -DQ(:,:,IKE)
+DQ = 0.5 * DQ
+!$acc end kernels
+
+!$acc end data
+
+END FUNCTION DIF2Z
+!-------------------------------------------------------------------------------
+!
+!     ########################################################################
+      SUBROUTINE DIF2Z_DEVICE(DQ,PQ)
+!     ########################################################################
+!!
+!!****  DIF2Z - leap-frog difference operator in Z direction
+!!
+!!    Calculates the difference assuming periodic BC (CYCL). 
+!!
+!!    DQ(K) = 0.5 * (PQ(K+1) - PQ(K-1))
+!!
+!!
+!!    MODIFICATIONS
+!!    -------------
+!!    
+!!    18.3.2006.  T. Maric - original version
+!!
+!-------------------------------------------------------------------------------
+!
+!
+USE MODE_ll
+USE MODD_CONF
+USE MODD_PARAMETERS
+!
+IMPLICIT NONE
+! 
+!*       0.1   Declarations of dummy arguments :
+!   
+REAL, DIMENSION(:,:,:), INTENT(IN)                :: PQ
+REAL, DIMENSION(:,:,:)                            :: DQ
+!
+!*       0.2   Declarations of local variables :
+!   
+INTEGER :: IKB    ! Begining useful area in z directions
+INTEGER :: IKE    ! End useful area in z directions
+!
+!-------------------------------------------------------------------------------
+
+!$acc data present( PQ, DQ )
+!
+!*       1.0.     COMPUTE THE DOMAIN DIMENSIONS
+!                 -----------------------------
+!
+!CALL GET_INDICE_ll(IIB,IJB,IIE,IJE)
+IKB = 1 + JPVEXT
+IKE = SIZE(PQ,3) - JPVEXT
+!
+!-------------------------------------------------------------------------------
+!
+!*       2.0.     COMPUTE THE DIFFERENCE
+!                 ----------------------
+!
+!$acc kernels
+DQ(:,:,IKB:IKE) = PQ(:,:,IKB+1:IKE+1) - PQ(:,:,IKB-1:IKE-1)
+DQ(:,:,IKB-1) = -DQ(:,:,IKB)
+DQ(:,:,IKE+1) = -DQ(:,:,IKE)
+DQ = 0.5 * DQ
+!$acc end kernels
+
+!$acc end data
+
+END SUBROUTINE DIF2Z_DEVICE
+
+! #endif
+!
+#ifdef MNH_OPENACC
+! END SUBROUTINE PPM_01_Z_D
+!
+END SUBROUTINE PPM_01_Z
+#else
+END FUNCTION PPM_01_Z
+#endif
+!
+!
+!-------------------------------------------------------------------------------
+!-------------------------------------------------------------------------------
+!
+#ifdef MNH_OPENACC
+!     ########################################################################
+!!$      FUNCTION PPM_S0_X(HLBCX, KGRID, PSRC, PCR, PRHO, PTSTEP) &
+!!$               RESULT(PR)
+SUBROUTINE PPM_S0_X(HLBCX, KGRID, PSRC, PCR, PRHO, PTSTEP , PR)
+
+  USE MODE_MNH_ZWORK, ONLY : ZT3D, MNH_GET_ZT3D , MNH_REL_ZT3D
+  USE MODE_MNH_ZWORK, ONLY : ZPSRC_HALO2_WEST
+
+  IMPLICIT NONE
+  !
+  !*       0.1   Declarations of dummy arguments :
+  !
+  CHARACTER (LEN=4), DIMENSION(2), INTENT(IN) :: HLBCX  ! X direction LBC type
+  !
+  INTEGER,                INTENT(IN)  :: KGRID   ! C grid localisation
+  !
+  REAL, DIMENSION(:,:,:), INTENT(INOUT)  :: PSRC    ! variable at t
+  REAL, DIMENSION(:,:,:), INTENT(IN)  :: PCR     ! Courant number
+  REAL, DIMENSION(:,:,:), INTENT(IN)  :: PRHO  ! density
+  REAL,                   INTENT(IN)  :: PTSTEP  ! Time step 
+  !
+  ! output source term
+  REAL, DIMENSION(:,:,:), INTENT(OUT) :: PR
+
+  INTEGER     :: IZFPOS,IZFNEG,IZPHAT,IZRHO_MXM,IZCR_MXM,IZCR_DXF
+
+!$acc data present( PSRC, PCR, PRHO, PR )
+
+  CALL MNH_GET_ZT3D(IZFPOS,IZFNEG,IZPHAT,IZRHO_MXM,IZCR_MXM,IZCR_DXF)
+
+  CALL PPM_S0_X_D(HLBCX, KGRID, PSRC, PCR, PRHO, PTSTEP , PR,  &
+               &  ZT3D(:,:,:,IZFPOS),ZT3D(:,:,:,IZFNEG),ZT3D(:,:,:,IZPHAT),ZT3D(:,:,:,IZRHO_MXM), &
+               &  ZT3D(:,:,:,IZCR_MXM),ZT3D(:,:,:,IZCR_DXF),ZPSRC_HALO2_WEST  )
+
+  CALL MNH_REL_ZT3D(IZFPOS,IZFNEG,IZPHAT,IZRHO_MXM,IZCR_MXM,IZCR_DXF)
+
+!$acc end data
+
+CONTAINS
+!
+!     ########################################################################
+      SUBROUTINE PPM_S0_X_D(HLBCX, KGRID, PSRC, PCR, PRHO, PTSTEP , PR &
+                         & ,ZFPOS,ZPHAT,ZFNEG &
+                         & ,ZRHO_MXM,ZCR_MXM,ZCR_DXF,ZPSRC_HALO2_WEST )
+
+!     ########################################################################
+#else
+!     ########################################################################
+      FUNCTION PPM_S0_X(HLBCX, KGRID, PSRC, PCR, PRHO, PTSTEP) &
+               RESULT(PR)
+!     ########################################################################
+#endif
+!!
+!!****  PPM_S0_X - PPM  advection scheme in X direction in Skamarock 2006 
+!!                 notation - NO CONSTRAINTS
+!!
+!!    MODIFICATIONS
+!!    -------------
+!!    
+!!    20.6.2006.  T. Maric - original version
+!!      J.Escobar 21/03/2013: for HALOK comment all NHALO=1 test
+!!
+!-------------------------------------------------------------------------------
+!
+USE MODD_ARGSLIST_ll, ONLY : HALO2LIST_ll
+USE MODD_CONF
+
+USE MODE_ll
+#ifdef MNH_OPENACC
+use mode_msg
+#endif
+
+USE MODI_GET_HALO
+#ifndef MNH_OPENACC
+USE MODI_SHUMAN
+#else
+USE MODI_SHUMAN_DEVICE
+#endif
+!
+#ifdef MNH_OPENACC
+USE MODD_PARAMETERS, ONLY : JPHEXT
+!
+USE MODE_MNH_ZWORK, ONLY : IIB,IIE, IIU,IJU,IKU , IJS,IJN, GWEST,GEAST
+!
+USE MODD_IO,   ONLY : GSMONOPROC
+#endif
+USE MODE_MPPDB
+!
+IMPLICIT NONE
+!
+!*       0.1   Declarations of dummy arguments :
+!
+CHARACTER (LEN=4), DIMENSION(2), INTENT(IN) :: HLBCX  ! X direction LBC type
+!
+INTEGER,                INTENT(IN)  :: KGRID   ! C grid localisation
+!
+REAL, DIMENSION(:,:,:), INTENT(INOUT)  :: PSRC    ! variable at t
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PCR     ! Courant number
+!
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PRHO  ! density
+REAL,                   INTENT(IN)  :: PTSTEP  ! Time step 
+!
+! output source term
+#ifndef MNH_OPENACC
+REAL, DIMENSION(SIZE(PCR,1),SIZE(PCR,2),SIZE(PCR,3)) :: PR
+#else
+REAL, DIMENSION(:,:,:), INTENT(OUT) :: PR
+#endif
+!
+!*       0.2   Declarations of local variables :
+!
+#ifndef MNH_OPENACC
+INTEGER:: IIB,IJB    ! Begining useful area in x,y,z directions
+INTEGER:: IIE,IJE    ! End useful area in x,y,z directions
+INTEGER                          :: IJS,IJN
+!
+LOGICAL :: GWEST, GEAST
+
+! advection fluxes
+REAL, DIMENSION(SIZE(PCR,1),SIZE(PCR,2),SIZE(PCR,3)) :: ZFPOS, ZFNEG
+!
+! variable at cell edges
+REAL, DIMENSION(SIZE(PCR,1),SIZE(PCR,2),SIZE(PCR,3)) :: ZPHAT
+!
+REAL, DIMENSION(SIZE(PCR,2),SIZE(PCR,3))             :: ZPSRC_HALO2_WEST
+#else
+! advection fluxes
+REAL, DIMENSION(:,:,:) :: ZFPOS, ZFNEG
+!
+! variable at cell edges
+REAL, DIMENSION(:,:,:) :: ZPHAT
+!
+REAL, DIMENSION(:,:,:) :: ZRHO_MXM, ZCR_MXM  , ZCR_DXF
+INTEGER                          :: I,J,K
+!
+REAL, DIMENSION(:,:)             :: ZPSRC_HALO2_WEST
+#endif
+
+TYPE(HALO2LIST_ll), SAVE , POINTER      :: TZ_PSRC_HALO2_ll         ! halo2 for PSRC
+LOGICAL, SAVE :: GFIRST_CALL_PPM_S0_X = .TRUE.
+!
+REAL , POINTER , CONTIGUOUS , DIMENSION(:,:) :: ZWEST
+
+!-------------------------------------------------------------------------------
+
+!$acc data present( PSRC, PCR, PRHO, PR , &
+!$acc &             ZFPOS, ZFNEG, ZPHAT, ZRHO_MXM, ZCR_MXM, ZCR_DXF, ZPSRC_HALO2_WEST )
+
+IF (MPPDB_INITIALIZED) THEN
+  !Check all IN arrays
+  CALL MPPDB_CHECK(PCR, "PPM_S0_X beg:PCR")
+  CALL MPPDB_CHECK(PRHO,"PPM_S0_X beg:PRHO")
+  !Check all INOUT arrays
+  CALL MPPDB_CHECK(PSRC,"PPM_S0_X beg:PSRC")
+END IF
+!
+!*       0.3.     COMPUTES THE DOMAIN DIMENSIONS
+!                 ------------------------------
+!
+#ifndef MNH_OPENACC
+CALL GET_INDICE_ll(IIB,IJB,IIE,IJE)
+IJS=IJB
+IJN=IJE
+!!$IJS=IJB-1
+!!$IJN=IJE+1
+!
+GWEST = LWEST_ll()
+GEAST = LEAST_ll()
+#endif
+!
+!BEG JUAN PPM_LL
+!
+!*              initialise & update halo & halo2 for PSRC
+!
+!!$CALL GET_HALO2(PSRC, TZ_PSRC_HALO2_ll, HNAME='PSRC')
+!!$ZPSRC_HALO2_WEST(:,:) = TZ_PSRC_HALO2_ll%HALO2%WEST(:,:)
+!!$!$acc update device (ZPSRC_HALO2_WEST)
+IF (GFIRST_CALL_PPM_S0_X) THEN
+   GFIRST_CALL_PPM_S0_X = .FALSE.
+   NULLIFY(TZ_PSRC_HALO2_ll)
+   CALL INIT_HALO2_ll(TZ_PSRC_HALO2_ll,1,IIU,IJU,IKU)
+END IF
+CALL GET_HALO2_DF(PSRC, TZ_PSRC_HALO2_ll, HNAME='PSRC')
+ZWEST => TZ_PSRC_HALO2_ll%HALO2%WEST
+!$acc kernels
+ZPSRC_HALO2_WEST(:,:) = ZWEST(:,:)
+ZPHAT=PSRC
+ZFPOS=PSRC
+ZFNEG=PSRC
+PR=PSRC
+!
+!END JUAN PPM_LL
+!-------------------------------------------------------------------------------
+!
+! calculate 4th order fluxes at cell edges  
+!
+!BEG JUAN PPM_LL
+!
+!   i=IIB+1:IIE  (  inner domain IIB exclude )
+!          ZPATH(i)   = Fct[ PSRC(i)  ,PSRC(i-1),PSRC(i+1),PSRC(i-2) ]    
+!
+! doc MNH  ZPATH(i+1) = Fct[ PSRC(i+1),PSRC(i)  ,PSRC(i+2),PSRC(i-1) ] 
+!      
+!
+ZPHAT(IIB+1:IIE,IJS:IJN,:) = ( 7.0 * &
+                       ( PSRC(IIB+1:IIE  ,IJS:IJN,:) + PSRC(IIB  :IIE-1,IJS:IJN,:) ) - &
+                       ( PSRC(IIB+2:IIE+1,IJS:IJN,:) + PSRC(IIB-1:IIE-2,IJS:IJN,:) ) ) / 12.0
+!$acc end kernels
+!
+SELECT CASE ( HLBCX(1) ) ! X direction LBC type: (1) for left side
+CASE ('CYCL','WALL')            ! In that case one must have HLBCX(1) == HLBCX(2)
+#ifdef MNH_OPENACC
+  call Print_msg( NVERB_ERROR, 'GEN', 'PPM_S0_X', 'OpenACC: CYCL/WALL boundaries not yet implemented' )
+#endif
+!
+!!$   ZPHAT(IIB,:,:) = (7.0 * &
+!!$                    (PSRC(IIB,:,:) + PSRC(IIB-1,:,:)) - &
+!!$                    (PSRC(IIB+1,:,:) + PSRC(IIE-1,:,:))) / 12.0
+!!$
+!!$!
+!!$   ZPHAT(IIE+1,:,:) = ZPHAT(IIB,:,:)
+!!$   ZPHAT(IIB-1,:,:) = ZPHAT(IIE,:,:)
+!
+!  WEST BOUND 
+!
+   ZPHAT(IIB  ,IJS:IJN,:) = ( 7.0 * &
+                      ( PSRC(IIB  ,IJS:IJN,:) + PSRC(IIB-1,IJS:IJN,:)                  ) - &
+                      ( PSRC(IIB+1,IJS:IJN,:) + TZ_PSRC_HALO2_ll%HALO2%WEST(IJS:IJN,:) ) ) / 12.0
+! <=>  WEST BOUND     ( PSRC(IIB+1,IJS:IJN,:) + PSRC(IIB-2,IJS:IJN,:)                  ) ) / 12.0
+!
+!  The ZPHAT(IIB-1,:,:) doesn't matter only define an realistic value
+!
+!!$   ZPHAT(IIB-1,:,:) = ZPHAT(IIB,:,:) ! JUANTEST1
+!
+! EAST BOUND
+!
+!  The ZPHAT(IIE+1,:,:) doesn't matter only define an realistic value
+!
+!!$   ZPHAT(IIE+1,:,:) = ZPHAT(IIE,:,:) ! JUANTEST1
+!
+!
+!   update ZPHAT HALO before next/further  utilisation 
+!
+CALL  GET_HALO(ZPHAT, HNAME='ZPHAT')
+!
+   ZFPOS(IIB:IIE+1,IJS:IJN,:) = ZPHAT(IIB:IIE+1,IJS:IJN,:) - & 
+        PCR(IIB:IIE+1,IJS:IJN,:)*(ZPHAT(IIB:IIE+1,IJS:IJN,:) - PSRC(IIB-1:IIE,IJS:IJN,:)) - &
+        PCR(IIB:IIE+1,IJS:IJN,:)*(1.0 - PCR(IIB:IIE+1,IJS:IJN,:)) * &
+        (ZPHAT(IIB-1:IIE,IJS:IJN,:) - 2.0*PSRC(IIB-1:IIE,IJS:IJN,:) + ZPHAT(IIB:IIE+1,IJS:IJN,:))
+!
+!!$   ZFPOS(IIB-1,:,:) = ZFPOS(IIE,:,:) !JUAN
+CALL GET_HALO(ZFPOS, HNAME='ZFPOS') ! JUAN
+!
+   ZFNEG(IIB-1:IIE,IJS:IJN,:) = ZPHAT(IIB-1:IIE,IJS:IJN,:) + & 
+        PCR(IIB-1:IIE,IJS:IJN,:)*(ZPHAT(IIB-1:IIE,IJS:IJN,:) - PSRC(IIB-1:IIE,IJS:IJN,:)) + &
+        PCR(IIB-1:IIE,IJS:IJN,:)*(1.0 + PCR(IIB-1:IIE,IJS:IJN,:)) * &
+        (ZPHAT(IIB-1:IIE,IJS:IJN,:) - 2.0*PSRC(IIB-1:IIE,IJS:IJN,:) + ZPHAT(IIB:IIE+1,IJS:IJN,:))
+!
+! define fluxes for CYCL BC outside physical domain
+!!$   ZFNEG(IIE+1,:,:) = ZFNEG(IIB,:,:) !JUAN
+CALL GET_HALO(ZFNEG, HNAME='ZFNEG') ! JUAN
+
+!
+! calculate the advection
+!
+#ifndef MNH_OPENACC
+   PR = PSRC * PRHO - &
+        DXF( PCR*MXM(PRHO)*( ZFPOS*(0.5+SIGN(0.5,PCR)) + & 
+                             ZFNEG*(0.5-SIGN(0.5,PCR)) ) )
+#else
+  call Print_msg( NVERB_ERROR, 'GEN', 'PPM_S0_X', 'OpenACC: CYCL/WALL boundaries not yet implemented' )
+#endif
+   CALL GET_HALO(PR, HNAME='PR') ! JUAN
+!
+CASE ('OPEN')
+!$acc kernels
+!
+!!$   ZPHAT(IIB,:,:) = 0.5*(PSRC(IIB-1,:,:) + PSRC(IIB,:,:))
+!!$   ZPHAT(IIB-1,:,:) = ZPHAT(IIB,:,:)   ! not used
+!!$   ZPHAT(IIE+1,:,:) = 0.5*(PSRC(IIE,:,:) + PSRC(IIE+1,:,:))
+!
+!  WEST BOUND 
+!
+IF (.NOT. GWEST) THEN
+   ZPHAT(IIB  ,IJS:IJN,:) = ( 7.0 * &
+                      ( PSRC(IIB  ,IJS:IJN,:) + PSRC(IIB-1,IJS:IJN,:)                  ) - &
+                      ( PSRC(IIB+1,IJS:IJN,:) + ZPSRC_HALO2_WEST(IJS:IJN,:)            ) ) / 12.0
+! <=>  WEST BOUND     ( PSRC(IIB+1,IJS:IJN,:) + PSRC(IIB-2,IJS:IJN,:)                  ) ) / 12.0
+ENDIF
+!$acc end kernels
+!
+!   update ZPHAT HALO before next/further  utilisation 
+!
+#ifndef MNH_OPENACC
+CALL  GET_HALO(ZPHAT, HNAME='ZPHAT')
+#else
+! acc update self(ZPHAT)
+!CALL GET_HALO_D(ZPHAT(:,:,:), HDIR="Z0_X", HNAME='ZPHAT')
+! acc update device(ZPHAT)
+#endif
+!
+!$acc kernels
+  IF (GWEST) THEN
+   ZPHAT(IIB  ,IJS:IJN,:) = 0.5*(PSRC(IIB-1,IJS:IJN,:) + PSRC(IIB,IJS:IJN,:))
+   ZPHAT(IIB-1,IJS:IJN,:) = ZPHAT(IIB,IJS:IJN,:)
+  ENDIF
+!
+!
+! EAST BOUND
+!
+  IF (GEAST) THEN
+   ZPHAT(IIE+1,IJS:IJN,:) = 0.5*(PSRC(IIE,IJS:IJN,:) + PSRC(IIE+1,IJS:IJN,:))
+  ENDIF
+!
+! update ZPHAT HALO before next/further  utilisation
+!
+!!$CALL  GET_HALO(ZPHAT)
+!
+!!$   ZFPOS(IIB+1:IIE+1,:,:) = ZPHAT(IIB+1:IIE+1,:,:) - & 
+!!$        PCR(IIB+1:IIE+1,:,:)*(ZPHAT(IIB+1:IIE+1,:,:) - PSRC(IIB:IIE,:,:)) - &
+!!$        PCR(IIB+1:IIE+1,:,:)*(1.0 - PCR(IIB+1:IIE+1,:,:)) * &
+!!$        (ZPHAT(IIB:IIE,:,:) - 2.0*PSRC(IIB:IIE,:,:) + ZPHAT(IIB+1:IIE+1,:,:))
+   ZFPOS(IIB:IIE+1,IJS:IJN,:) = ZPHAT(IIB:IIE+1,IJS:IJN,:) - & 
+        PCR(IIB:IIE+1,IJS:IJN,:)*(ZPHAT(IIB:IIE+1,IJS:IJN,:) - PSRC(IIB-1:IIE,IJS:IJN,:)) - &
+        PCR(IIB:IIE+1,IJS:IJN,:)*(1.0 - PCR(IIB:IIE+1,IJS:IJN,:)) * &
+        (ZPHAT(IIB-1:IIE,IJS:IJN,:) - 2.0*PSRC(IIB-1:IIE,IJS:IJN,:) + ZPHAT(IIB:IIE+1,IJS:IJN,:))
+!$acc end kernels
+!
+#ifndef MNH_OPENACC
+CALL GET_HALO(ZFPOS, HNAME='ZFPOS') ! JUAN
+#else
+! acc update self(ZFPOS)
+!CALL GET_HALO_D(ZFPOS(:,:,:), HDIR="Z0_X", HNAME='ZFPOS') ! JUAN
+! acc update device(ZFPOS)
+#endif
+!
+!$acc kernels
+! positive flux on the WEST boundary
+  IF (GWEST) THEN
+   ZFPOS(IIB,IJS:IJN,:) = (PSRC(IIB-1,IJS:IJN,:) - ZPHAT(IIB,IJS:IJN,:))*PCR(IIB,IJS:IJN,:) + &
+                     ZPHAT(IIB,IJS:IJN,:) 
+! this is not used
+   ZFPOS(IIB-1,IJS:IJN,:) = 0.0
+  ENDIF
+!
+! negative fluxes
+!!$   ZFNEG(IIB:IIE,:,:) = ZPHAT(IIB:IIE,:,:) + & 
+!!$        PCR(IIB:IIE,:,:)*(ZPHAT(IIB:IIE,:,:) - PSRC(IIB:IIE,:,:)) + &
+!!$        PCR(IIB:IIE,:,:)*(1.0 + PCR(IIB:IIE,:,:)) * &
+!!$        (ZPHAT(IIB:IIE,:,:) - 2.0*PSRC(IIB:IIE,:,:) + ZPHAT(IIB+1:IIE+1,:,:))
+   ZFNEG(IIB-1:IIE,IJS:IJN,:) = ZPHAT(IIB-1:IIE,IJS:IJN,:) + & 
+        PCR(IIB-1:IIE,IJS:IJN,:)*(ZPHAT(IIB-1:IIE,IJS:IJN,:) - PSRC(IIB-1:IIE,IJS:IJN,:)) + &
+        PCR(IIB-1:IIE,IJS:IJN,:)*(1.0 + PCR(IIB-1:IIE,IJS:IJN,:)) * &
+        (ZPHAT(IIB-1:IIE,IJS:IJN,:) - 2.0*PSRC(IIB-1:IIE,IJS:IJN,:) + ZPHAT(IIB:IIE+1,IJS:IJN,:))
+!$acc end kernels
+!
+#ifndef MNH_OPENACC
+   CALL GET_HALO(ZFNEG, HNAME='ZFNEG') ! JUAN
+#else
+! acc update self(ZFNEG)
+!CALL GET_HALO_D(ZFNEG, HDIR="Z0_X", HNAME='ZFNEG') ! JUAN
+! acc update device(ZFNEG)
+#endif
+!
+!$acc kernels
+  IF (GEAST) THEN
+!
+! in OPEN case PCR(IIB-1) is not used, so we also set ZFNEG(IIB-1) = 0
+!
+   ZFNEG(IIB-1,IJS:IJN,:) = 0.0
+!
+! modified negative flux on EAST boundary. We use linear function instead of a
+! parabola to represent the tracer field, so it simplifies the flux expresion
+!
+   ZFNEG(IIE+1,IJS:IJN,:) = (ZPHAT(IIE+1,IJS:IJN,:) - PSRC(IIE+1,IJS:IJN,:))*PCR(IIE+1,IJS:IJN,:) + &
+                       ZPHAT(IIE+1,IJS:IJN,:)
+  ENDIF
+!
+! calculate the advection
+!
+#ifndef MNH_OPENACC
+   PR = PSRC * PRHO - &
+        DXF( PCR*MXM(PRHO)*( ZFPOS*(0.5+SIGN(0.5,PCR)) + & 
+                             ZFNEG*(0.5-SIGN(0.5,PCR)) ) )
+#else
+!$acc end kernels
+   CALL MXM_DEVICE(PRHO,ZRHO_MXM)
+!$acc kernels
+   ZCR_MXM =  PCR * ZRHO_MXM * ( ZFPOS*(0.5+SIGN(0.5,PCR)) + ZFNEG*(0.5-SIGN(0.5,PCR)) ) 
+!$acc end kernels
+   CALL DXF_DEVICE(ZCR_MXM,ZCR_DXF)
+!$acc kernels
+   PR = PSRC * PRHO - ZCR_DXF
+#endif
+!
+! in OPEN case fix boundary conditions
+!
+  IF (GWEST) THEN
+   WHERE ( PCR(IIB,IJS:IJN,:) <= 0. ) !  OUTFLOW condition
+      PR(IIB-1,IJS:IJN,:) = 2.*PR(IIB,IJS:IJN,:) - PR(IIB+1,IJS:IJN,:)
+   ELSEWHERE
+      PR(IIB-1,IJS:IJN,:) = PR(IIB,IJS:IJN,:)
+   END WHERE
+  ENDIF
+!
+  IF (GEAST) THEN 
+   WHERE ( PCR(IIE,IJS:IJN,:) >= 0. ) !  OUTFLOW condition
+      PR(IIE+1,IJS:IJN,:) = 2.*PR(IIE,IJS:IJN,:) - PR(IIE-1,IJS:IJN,:)
+   ELSEWHERE
+      PR(IIE+1,IJS:IJN,:) = PR(IIE,IJS:IJN,:)
+   END WHERE
+  ENDIF
+!
+!$acc end kernels 
+!
+!
+END SELECT
+!
+#ifndef MNH_OPENACC
+CALL GET_HALO(PR, HNAME='PR')
+#else
+CALL GET_HALO_D(PR, HDIR="S0_X", HNAME='PR')
+#endif
+!-------------------------------------------------------------------------------
+!!$CALL  DEL_HALO2_ll(TZ_PSRC_HALO2_ll)
+
+IF (MPPDB_INITIALIZED) THEN
+  !Check all INOUT arrays
+  CALL MPPDB_CHECK(PSRC,"PPM_S0_X end:PSRC")
+  !Check all OUT arrays
+  CALL MPPDB_CHECK(PR,"PPM_S0_X end:PR")
+END IF
+
+!$acc end data
+
+#ifdef MNH_OPENACC
+END SUBROUTINE PPM_S0_X_D
+
+END SUBROUTINE PPM_S0_X
+#else
+END FUNCTION PPM_S0_X
+#endif
+!
+!-------------------------------------------------------------------------------
+!-------------------------------------------------------------------------------
+!
+#ifdef MNH_OPENACC
+!     ########################################################################
+!!$      FUNCTION PPM_S0_Y(HLBCY, KGRID, PSRC, PCR, PRHO, PTSTEP) &
+!!$               RESULT(PR)
+         SUBROUTINE PPM_S0_Y(HLBCY, KGRID, PSRC, PCR, PRHO, PTSTEP, PR)
+
+  USE MODE_MNH_ZWORK, ONLY : ZT3D, MNH_GET_ZT3D , MNH_REL_ZT3D
+  USE MODE_MNH_ZWORK, ONLY : ZPSRC_HALO2_SOUTH
+
+  IMPLICIT NONE
+!
+!*       0.1   Declarations of dummy arguments :
+!
+CHARACTER (LEN=4), DIMENSION(2), INTENT(IN) :: HLBCY ! Y direction LBC type
+!
+INTEGER,                INTENT(IN)  :: KGRID   ! C grid localisation
+!
+REAL, DIMENSION(:,:,:), INTENT(INOUT)  :: PSRC    ! variable at t
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PCR     ! Courant number
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PRHO  ! density
+REAL,                   INTENT(IN)  :: PTSTEP  ! Time step 
+!
+! output source term
+REAL, DIMENSION(:,:,:), INTENT(OUT) :: PR
+
+  INTEGER     :: IZFPOS,IZPHAT,IZFNEG,IZRHO_MYM,IZCR_MYM,IZCR_DYF
+
+!$acc data present( PSRC, PCR, PRHO, PR )
+
+  CALL MNH_GET_ZT3D(IZFPOS,IZFNEG,IZPHAT,IZRHO_MYM,IZCR_MYM,IZCR_DYF)
+
+  CALL PPM_S0_Y_D(HLBCY, KGRID, PSRC, PCR, PRHO, PTSTEP , PR,  &
+               &  ZT3D(:,:,:,IZFPOS),ZT3D(:,:,:,IZFNEG),ZT3D(:,:,:,IZPHAT),ZT3D(:,:,:,IZRHO_MYM), &
+               &  ZT3D(:,:,:,IZCR_MYM),ZT3D(:,:,:,IZCR_DYF),ZPSRC_HALO2_SOUTH  )
+
+  CALL MNH_REL_ZT3D(IZFPOS,IZFNEG,IZPHAT,IZRHO_MYM,IZCR_MYM,IZCR_DYF)
+
+!$acc end data
+
+CONTAINS
+!
+!     ########################################################################
+      SUBROUTINE PPM_S0_Y_D(HLBCY, KGRID, PSRC, PCR, PRHO, PTSTEP , PR &
+                         & ,ZFPOS,ZPHAT,ZFNEG &
+                         & ,ZRHO_MYM,ZCR_MYM,ZCR_DYF,ZPSRC_HALO2_SOUTH )
+
+!     ########################################################################
+#else
+!     ########################################################################
+      FUNCTION PPM_S0_Y(HLBCY, KGRID, PSRC, PCR, PRHO, PTSTEP) &
+               RESULT(PR)
+!     ########################################################################
+#endif
+!!
+!!****  PPM_S0_Y - PPM  advection scheme in Y direction in Skamarock 2006 
+!!                 notation - NO CONSTRAINTS
+!!
+!!    MODIFICATIONS
+!!    -------------
+!!    
+!!    20.6.2006.  T. Maric - original version
+!!
+!-------------------------------------------------------------------------------
+!
+USE MODD_CONF
+
+USE MODE_ll
+#ifdef MNH_OPENACC
+use mode_msg
+#endif
+
+USE MODI_GET_HALO
+#ifndef MNH_OPENACC
+USE MODI_SHUMAN
+#else
+USE MODI_SHUMAN_DEVICE
+#endif
+!
+#ifdef MNH_OPENACC
+USE MODD_ARGSLIST_ll, ONLY : HALO2LIST_ll
+USE MODD_PARAMETERS, ONLY : JPHEXT
+!
+USE MODE_MNH_ZWORK, ONLY : IJB,IJE, IIU,IJU,IKU , IIW,IIA, GSOUTH , GNORTH
+!
+USE MODD_IO,   ONLY : GSMONOPROC
+#endif
+USE MODE_MPPDB
+!
+IMPLICIT NONE
+!
+!*       0.1   Declarations of dummy arguments :
+!
+CHARACTER (LEN=4), DIMENSION(2), INTENT(IN) :: HLBCY ! Y direction LBC type
+!
+INTEGER,                INTENT(IN)  :: KGRID   ! C grid localisation
+!
+REAL, DIMENSION(:,:,:), INTENT(INOUT)  :: PSRC    ! variable at t
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PCR     ! Courant number
+!
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PRHO  ! density
+REAL,                   INTENT(IN)  :: PTSTEP  ! Time step 
+!
+! output source term
+#ifndef MNH_OPENACC
+REAL, DIMENSION(SIZE(PCR,1),SIZE(PCR,2),SIZE(PCR,3)) :: PR
+#else
+REAL, DIMENSION(:,:,:), INTENT(OUT) :: PR
+#endif
+!
+!*       0.2   Declarations of local variables :
+!
+#ifndef MNH_OPENACC
+INTEGER:: IIB,IJB    ! Begining useful area in x,y,z directions
+INTEGER:: IIE,IJE    ! End useful area in x,y,z directions
+INTEGER                          :: IJS,IJN
+INTEGER                          :: IIW,IIA
+!
+LOGICAL :: GNORTH, GSOUTH
+!
+! advection fluxes
+REAL, DIMENSION(SIZE(PCR,1),SIZE(PCR,2),SIZE(PCR,3)) :: ZFPOS, ZFNEG
+!
+! variable at cell edges
+REAL, DIMENSION(SIZE(PCR,1),SIZE(PCR,2),SIZE(PCR,3)) :: ZPHAT
+!
+TYPE(HALO2LIST_ll), POINTER      :: TZ_PSRC_HALO2_ll         ! halo2 for PSRC
+TYPE(HALO2LIST_ll), POINTER      :: TZ_PHAT_HALO2_ll         ! halo2 for ZPHAT
+!
+REAL, DIMENSION(SIZE(PCR,1),SIZE(PCR,3))             :: ZPSRC_HALO2_SOUTH
+#else
+!
+! advection fluxes
+REAL, DIMENSION(:,:,:) :: ZFPOS, ZFNEG
+!
+! variable at cell edges
+REAL, DIMENSION(:,:,:) :: ZPHAT
+!
+TYPE(HALO2LIST_ll), SAVE ,POINTER      :: TZ_PSRC_HALO2_ll         ! halo2 for PSRC
+LOGICAL, SAVE :: GFIRST_CALL_PPM_S0_Y = .TRUE.
+
+TYPE(HALO2LIST_ll), POINTER      :: TZ_PHAT_HALO2_ll         ! halo2 for ZPHAT
+!
+REAL, DIMENSION(:,:,:) :: ZRHO_MYM , ZCR_MYM , ZCR_DYF
+!
+INTEGER                          :: I,J,K
+!
+REAL, DIMENSION(:,:)             :: ZPSRC_HALO2_SOUTH
+#endif
+!
+REAL , POINTER , CONTIGUOUS , DIMENSION(:,:) :: ZSOUTH
+!
+!-------------------------------------------------------------------------------
+
+!$acc data present( PSRC, PCR, PRHO, PR , &
+!$acc &             ZFPOS, ZFNEG, ZPHAT, ZRHO_MYM, ZCR_MYM, ZCR_DYF, ZPSRC_HALO2_SOUTH )
+
+IF (MPPDB_INITIALIZED) THEN
+  !Check all IN arrays
+  CALL MPPDB_CHECK(PCR, "PPM_S0_Y beg:PCR")
+  CALL MPPDB_CHECK(PRHO,"PPM_S0_Y beg:PRHO")
+  !Check all INOUT arrays
+  CALL MPPDB_CHECK(PSRC,"PPM_S0_Y beg:PSRC")
+END IF
+!
+!*       0.3.     COMPUTES THE DOMAIN DIMENSIONS
+!                 ------------------------------
+!
+#ifndef MNH_OPENACC
+CALL GET_INDICE_ll(IIB,IJB,IIE,IJE)
+IIW=IIB
+IIA=IIE
+!!$IIW=IIB-1
+!!$IIA=IIE+1
+!
+GNORTH = LNORTH_ll()
+GSOUTH = LSOUTH_ll()
+#endif
+!
+!-------------------------------------------------------------------------------
+!
+IF ( L2D ) THEN
+!$acc kernels
+  PR(:, :, : ) = PSRC(:, :, : ) * PRHO(:, :, : )
+!$acc end kernels
+
+  !Check all OUT arrays
+  CALL MPPDB_CHECK(PR,"PPM_S0_Y end:PR")
+!   RETURN
+ELSE !not L2D
+   !   
+!!$CALL GET_HALO2(PSRC, TZ_PSRC_HALO2_ll, HNAME='PSRC')
+!!$ZPSRC_HALO2_SOUTH(:,:) = TZ_PSRC_HALO2_ll%HALO2%SOUTH(:,:)
+!!$!$acc update device (ZPSRC_HALO2_SOUTH)
+IF (GFIRST_CALL_PPM_S0_Y) THEN
+   GFIRST_CALL_PPM_S0_Y = .FALSE.
+   NULLIFY(TZ_PSRC_HALO2_ll)
+   CALL INIT_HALO2_ll(TZ_PSRC_HALO2_ll,1,IIU,IJU,IKU)
+END IF   
+CALL GET_HALO2_DF(PSRC, TZ_PSRC_HALO2_ll, HNAME='PSRC')
+ZSOUTH => TZ_PSRC_HALO2_ll%HALO2%SOUTH(:,:)
+!
+! Initialize with relalistic value all work array 
+!
+!$acc kernels
+ZPSRC_HALO2_SOUTH(:,:) = ZSOUTH(:,:) 
+ZPHAT=PSRC
+ZFPOS=PSRC
+ZFNEG=PSRC
+PR=PSRC
+!
+!-------------------------------------------------------------------------------
+!
+! calculate 4th order fluxes at cell edges in the inner domain
+!
+ZPHAT(IIW:IIA,IJB+1:IJE,:) = (7.0 * &
+                       (PSRC(IIW:IIA,IJB+1:IJE,:) + PSRC(IIW:IIA,IJB:IJE-1,:)) - &
+                       (PSRC(IIW:IIA,IJB+2:IJE+1,:) + PSRC(IIW:IIA,IJB-1:IJE-2,:))) / 12.0
+!$acc end kernels 
+!
+SELECT CASE ( HLBCY(1) ) ! Y direction LBC type: (1) for left side
+CASE ('CYCL','WALL')            ! In that case one must have HLBCY(1) == HLBCY(2)
+#ifdef MNH_OPENACC
+  call Print_msg( NVERB_ERROR, 'GEN', 'PPM_S0_Y', 'OpenACC: CYCL/WALL boundaries not yet implemented' )
+#endif
+!
+!!$   ZPHAT(:,IJB,:) = (7.0 * &
+!!$                    (PSRC(:,IJB,:) + PSRC(:,IJB-1,:)) - &
+!!$                    (PSRC(:,IJB+1,:) + PSRC(:,IJE-1,:))) / 12.0
+!!$!
+!!$   ZPHAT(:,IJE+1,:) = ZPHAT(:,IJB,:)
+!!$   ZPHAT(:,IJB-1,:) = ZPHAT(:,IJE,:)
+!
+!  SOUTH BOUND 
+!
+   ZPHAT(IIW:IIA,IJB,:) = ( 7.0 * &
+                    ( PSRC(IIW:IIA,IJB  ,:) + PSRC(IIW:IIA,IJB-1,:) ) - &
+                    ( PSRC(IIW:IIA,IJB+1,:) + TZ_PSRC_HALO2_ll%HALO2%SOUTH(IIW:IIA,:) ) ) / 12.0
+! <=> SOUTH B       ( PSRC(IIW:IIA,IJB+1,:) +    PSRC(IIW:IIA,IJB-2,:)                ) ) / 12.0
+!
+!  The ZPHAT(:,IJB-1,:) doesn't matter only define an realistic value
+!
+!!$   ZPHAT(:,IJB-1,:) = ZPHAT(:,IJB,:)
+!
+!  NORTH BOUND
+!
+!  The ZPHAT(:IJE+1,:) doesn't matter only define an realistic value
+!
+!!$   ZPHAT(:,IJE+1,:) = ZPHAT(:,IJE,:)
+!
+!   update ZPHAT HALO before next/further  utilisation 
+!
+CALL  GET_HALO(ZPHAT, HNAME='ZPHAT')
+!
+! calculate the fluxes:
+!
+   ZFPOS(IIW:IIA,IJB:IJE+1,:) = ZPHAT(IIW:IIA,IJB:IJE+1,:) - & 
+        PCR(IIW:IIA,IJB:IJE+1,:)*(ZPHAT(IIW:IIA,IJB:IJE+1,:) - PSRC(IIW:IIA,IJB-1:IJE,:)) - &
+        PCR(IIW:IIA,IJB:IJE+1,:)*(1.0 - PCR(IIW:IIA,IJB:IJE+1,:)) * &
+        (ZPHAT(IIW:IIA,IJB-1:IJE,:) - 2.0*PSRC(IIW:IIA,IJB-1:IJE,:) + ZPHAT(IIW:IIA,IJB:IJE+1,:))
+!
+!!$   ZFPOS(:,IJB-1,:) = ZFPOS(:,IJE,:)
+CALL GET_HALO(ZFPOS, HNAME='ZFPOS') ! JUAN
+!
+   ZFNEG(IIW:IIA,IJB-1:IJE,:) = ZPHAT(IIW:IIA,IJB-1:IJE,:) + & 
+        PCR(IIW:IIA,IJB-1:IJE,:)*(ZPHAT(IIW:IIA,IJB-1:IJE,:) - PSRC(IIW:IIA,IJB-1:IJE,:)) + &
+        PCR(IIW:IIA,IJB-1:IJE,:)*(1.0 + PCR(IIW:IIA,IJB-1:IJE,:)) * &
+        (ZPHAT(IIW:IIA,IJB-1:IJE,:) - 2.0*PSRC(IIW:IIA,IJB-1:IJE,:) +ZPHAT(IIW:IIA,IJB:IJE+1,:))
+!
+
+!
+! define fluxes for CYCL BC outside physical domain
+!!$   ZFNEG(:,IJE+1,:) = ZFNEG(:,IJB,:)
+CALL GET_HALO(ZFNEG, HNAME='ZFNEG') ! JUAN
+!
+! calculate the advection
+!
+#ifndef MNH_OPENACC
+   PR = PSRC * PRHO - &
+        DYF( PCR*MYM(PRHO)*( ZFPOS*(0.5+SIGN(0.5,PCR)) + & 
+                             ZFNEG*(0.5-SIGN(0.5,PCR)) ) )
+#else
+  call Print_msg( NVERB_ERROR, 'GEN', 'PPM_S0_Y', 'OpenACC: CYCL/WALL boundaries not yet implemented' )
+#endif
+!
+CASE ('OPEN')
+!$acc kernels 
+!
+!!$   ZPHAT(:,IJB,:) = 0.5*(PSRC(:,IJB-1,:) + PSRC(:,IJB,:))
+!!$   ZPHAT(:,IJB-1,:) = ZPHAT(:,IJB,:)   ! not used
+!!$   ZPHAT(:,IJE+1,:) = 0.5*(PSRC(:,IJE,:) + PSRC(:,IJE+1,:))
+!
+!
+!  SOUTH BOUND 
+!
+  IF ( .NOT. GSOUTH) THEN
+   ZPHAT(IIW:IIA,IJB  ,:) = (7.0 * &
+                      (PSRC(IIW:IIA,IJB  ,:) + PSRC(IIW:IIA,IJB-1,:)) - &
+                      (PSRC(IIW:IIA,IJB+1,:) + ZPSRC_HALO2_SOUTH(IIW:IIA,:)            )) / 12.0
+!                     (PSRC(IIW:IIA,IJB+1,:) + TZ_PSRC_HALO2_ll%HALO2%SOUTH(IIW:IIA,:) )) / 12.0
+! <=> SOUTH BOUND     (PSRC(IIW:IIA,IJB+1,:) + PSRC(IIW:IIA,IJB-2,:)                   )) / 12.0
+  ENDIF
+!
+!TEMPO_JUAN  
+!$acc end kernels
+!
+#ifndef MNH_OPENACC
+CALL  GET_HALO(ZPHAT, HNAME='ZPHAT')
+#else
+! acc update self(ZPHAT)
+!CALL  GET_HALO_D(ZPHAT(:,:,:), HDIR="Z0_Y", HNAME='ZPHAT')
+! acc update device(ZPHAT)
+#endif
+!
+!$acc kernels
+  IF (GSOUTH) THEN
+   ZPHAT(IIW:IIA,IJB  ,:) = 0.5*(PSRC(IIW:IIA,IJB-1,:) + PSRC(IIW:IIA,IJB,:))
+   ZPHAT(IIW:IIA,IJB-1,:) = ZPHAT(IIW:IIA,IJB,:)
+  ENDIF
+!
+! NORTH BOUND
+!
+  IF (GNORTH) THEN
+   ZPHAT(IIW:IIA,IJE+1,:) =  0.5*(PSRC(IIW:IIA,IJE,:) + PSRC(IIW:IIA,IJE+1,:))
+  ENDIF
+!
+!
+!   update ZPHAT HALO before next/further  utilisation 
+!
+!!$CALL  GET_HALO(ZPHAT)
+!
+! calculate the fluxes:
+! positive fluxes
+!!$   ZFPOS(:,IJB+1:IJE+1,:) = ZPHAT(:,IJB+1:IJE+1,:) - & 
+!!$        PCR(:,IJB+1:IJE+1,:)*(ZPHAT(:,IJB+1:IJE+1,:) - PSRC(:,IJB:IJE,:)) - &
+!!$        PCR(:,IJB+1:IJE+1,:)*(1.0 - PCR(:,IJB+1:IJE+1,:)) * &
+!!$        (ZPHAT(:,IJB:IJE,:) - 2.0*PSRC(:,IJB:IJE,:) + ZPHAT(:,IJB+1:IJE+1,:))
+   ZFPOS(IIW:IIA,IJB:IJE+1,:) = ZPHAT(IIW:IIA,IJB:IJE+1,:) - & 
+        PCR(IIW:IIA,IJB:IJE+1,:)*( ZPHAT(IIW:IIA,IJB:IJE+1,:) - PSRC(IIW:IIA,IJB-1:IJE  ,:) ) - &
+        PCR(IIW:IIA,IJB:IJE+1,:)*( 1.0                  -  PCR(IIW:IIA,IJB  :IJE+1,:) ) * &
+        (ZPHAT(IIW:IIA,IJB-1:IJE,:) - 2.0*PSRC(IIW:IIA,IJB-1:IJE,:) + ZPHAT(IIW:IIA,IJB:IJE+1,:))
+!$acc end kernels
+!
+#ifndef MNH_OPENACC
+CALL GET_HALO(ZFPOS, HNAME='ZFPOS') ! JUAN
+#else
+! acc update self(ZFPOS)
+!CALL GET_HALO_D(ZFPOS(:,:,:), HDIR="Z0_Y", HNAME='ZFPOS') ! JUAN
+! acc update device(ZFPOS)
+#endif
+!
+!$acc kernels
+! positive flux on the SOUTH boundary
+  IF (GSOUTH) THEN
+   ZFPOS(IIW:IIA,IJB,:) = (PSRC(IIW:IIA,IJB-1,:) - ZPHAT(IIW:IIA,IJB,:))*PCR(IIW:IIA,IJB,:) + &
+                     ZPHAT(IIW:IIA,IJB,:)
+!
+! this is not used
+   ZFPOS(IIW:IIA,IJB-1,:) = 0.0
+  ENDIF
+! 
+! negative fluxes
+!!$   ZFNEG(:,IJB:IJE,:) = ZPHAT(:,IJB:IJE,:) + & 
+!!$        PCR(:,IJB:IJE,:)*(ZPHAT(:,IJB:IJE,:) - PSRC(:,IJB:IJE,:)) + &
+!!$        PCR(:,IJB:IJE,:)*(1.0 + PCR(:,IJB:IJE,:)) * &
+!!$        (ZPHAT(:,IJB:IJE,:) - 2.0*PSRC(:,IJB:IJE,:) +ZPHAT(:,IJB+1:IJE+1,:))
+   ZFNEG(IIW:IIA,IJB-1:IJE,:) = ZPHAT(IIW:IIA,IJB-1:IJE,:) + & 
+        PCR(IIW:IIA,IJB-1:IJE,:)*(ZPHAT(IIW:IIA,IJB-1:IJE,:) - PSRC(IIW:IIA,IJB-1:IJE,:)) + &
+        PCR(IIW:IIA,IJB-1:IJE,:)*(1.0 + PCR(IIW:IIA,IJB-1:IJE,:)) * &
+        (ZPHAT(IIW:IIA,IJB-1:IJE,:) - 2.0*PSRC(IIW:IIA,IJB-1:IJE,:) +ZPHAT(IIW:IIA,IJB:IJE+1,:))
+!$acc end kernels
+!
+#ifndef MNH_OPENACC
+   CALL GET_HALO(ZFNEG, HNAME='ZFNEG') ! JUAN
+#else
+! acc update self(ZFNEG)
+!   CALL GET_HALO_D(ZFNEG, HDIR="Z0_Y", HNAME='ZFNEG') ! JUAN
+! acc update device(ZFNEG)
+#endif
+!
+!$acc kernels
+  IF (GNORTH) THEN
+! this is not used
+   ZFNEG(IIW:IIA,IJB-1,:) = 0.0
+!
+! negative flux on the NORTH boundary
+   ZFNEG(IIW:IIA,IJE+1,:) = (ZPHAT(IIW:IIA,IJE+1,:) - PSRC(IIW:IIA,IJE+1,:))*PCR(IIW:IIA,IJE+1,:) + &
+                       ZPHAT(IIW:IIA,IJE+1,:)
+  ENDIF
+!
+! calculate the advection
+!
+#ifndef MNH_OPENACC
+   PR = PSRC * PRHO - &
+        DYF( PCR*MYM(PRHO)*( ZFPOS*(0.5+SIGN(0.5,PCR)) + & 
+                             ZFNEG*(0.5-SIGN(0.5,PCR)) ) )
+#else
+!$acc end kernels
+   CALL MYM_DEVICE(PRHO,ZRHO_MYM)
+!$acc kernels
+   ZCR_MYM =  PCR* ZRHO_MYM*( ZFPOS(:,:,:)*(0.5+SIGN(0.5,PCR)) + ZFNEG*(0.5-SIGN(0.5,PCR)) ) 
+!$acc end kernels
+   CALL DYF_DEVICE(ZCR_MYM,ZCR_DYF)
+!$acc kernels
+   PR = PSRC * PRHO - ZCR_DYF
+#endif
+!
+! in OPEN case fix boundary conditions
+!
+  IF (GSOUTH) THEN
+   WHERE ( PCR(IIW:IIA,IJB,:) <= 0. ) !  OUTFLOW condition
+      PR(IIW:IIA,IJB-1,:) = 1.0 * 2.*PR(IIW:IIA,IJB,:) - PR(IIW:IIA,IJB+1,:)
+   ELSEWHERE
+      PR(IIW:IIA,IJB-1,:) = PR(IIW:IIA,IJB,:) 
+   END WHERE
+  ENDIF
+!
+  IF (GNORTH) THEN
+   WHERE ( PCR(IIW:IIA,IJE,:) >= 0. ) !  OUTFLOW condition
+      PR(IIW:IIA,IJE+1,:) = 1.0 * 2.*PR(IIW:IIA,IJE,:) - PR(IIW:IIA,IJE-1,:)
+   ELSEWHERE
+      PR(IIW:IIA,IJE+1,:) = PR(IIW:IIA,IJE,:) 
+   END WHERE
+  ENDIF
+!
+!$acc end kernels 
+!
+!
+END SELECT
+!
+#ifndef MNH_OPENACC
+CALL GET_HALO(PR, HNAME='PR')
+#else
+CALL GET_HALO_D(PR, HDIR="S0_Y", HNAME='PR')
+#endif
+!
+!!$CALL  DEL_HALO2_ll(TZ_PSRC_HALO2_ll)
+!
+IF (MPPDB_INITIALIZED) THEN
+  !Check all INOUT arrays
+  CALL MPPDB_CHECK(PSRC,"PPM_S0_Y end:PSRC")
+  !Check all OUT arrays
+  CALL MPPDB_CHECK(PR,"PPM_S0_Y end:PR")
+END IF
+
+END IF !not L2D
+!$acc end data
+
+#ifdef MNH_OPENACC
+END SUBROUTINE PPM_S0_Y_D
+
+END SUBROUTINE PPM_S0_Y
+#else
+END FUNCTION PPM_S0_Y
+#endif
+!
+!
+!-------------------------------------------------------------------------------
+!-------------------------------------------------------------------------------
+!
+#ifdef MNH_OPENACC
+!     ########################################################################
+!!$      FUNCTION PPM_S0_Z(KGRID, PSRC, PCR, PRHO, PTSTEP) &
+!!$               RESULT(PR)
+SUBROUTINE PPM_S0_Z(KGRID, PSRC, PCR, PRHO, PTSTEP, PR)
+
+  USE MODE_MNH_ZWORK, ONLY : ZT3D, MNH_GET_ZT3D , MNH_REL_ZT3D
+
+  IMPLICIT NONE
+!
+!*       0.1   Declarations of dummy arguments :
+!
+INTEGER,                INTENT(IN)  :: KGRID   ! C grid localisation
+!
+REAL, DIMENSION(:,:,:), INTENT(INOUT)  :: PSRC    ! variable at t
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PCR     ! Courant number
+!
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PRHO  ! density
+REAL,                   INTENT(IN)  :: PTSTEP  ! Time step 
+!
+! output source term
+REAL, DIMENSION(:,:,:),INTENT(OUT):: PR
+
+
+  INTEGER     :: IZFPOS,IZPHAT,IZFNEG,IZRHO_MZM,IZCR_MZM,IZCR_DZF
+
+!$acc data present ( PSRC, PCR, PRHO, PR )
+
+  CALL MNH_GET_ZT3D(IZFPOS,IZFNEG,IZPHAT,IZRHO_MZM,IZCR_MZM,IZCR_DZF)
+
+  CALL PPM_S0_Z_D(KGRID, PSRC, PCR, PRHO, PTSTEP , PR,  &
+               &  ZT3D(:,:,:,IZFPOS),  ZT3D(:,:,:,IZFNEG),  ZT3D(:,:,:,IZPHAT), &
+               &  ZT3D(:,:,:,IZRHO_MZM),ZT3D(:,:,:,IZCR_MZM),ZT3D(:,:,:,IZCR_DZF)  )
+
+  CALL MNH_REL_ZT3D(IZFPOS,IZFNEG,IZPHAT,IZRHO_MZM,IZCR_MZM,IZCR_DZF)
+
+!$acc end data
+
+CONTAINS
+!
+!     ########################################################################
+SUBROUTINE PPM_S0_Z_D(KGRID, PSRC, PCR, PRHO, PTSTEP , PR  &
+                   & ,ZFPOS,ZFNEG,ZPHAT  &
+                   & ,ZRHO_MZM,ZCR_MZM,ZCR_DZF )
+
+!     ########################################################################
+#else
+!     ########################################################################
+      FUNCTION PPM_S0_Z(KGRID, PSRC, PCR, PRHO, PTSTEP) &
+               RESULT(PR)
+!     ########################################################################
+#endif
+!!
+!!****  PPM_S0_Z - PPM  advection scheme in Z direction in Skamarock 2006 
+!!                 notation - NO CONSTRAINTS
+!!
+!!    MODIFICATIONS
+!!    -------------
+!!    
+!!    20.6.2006.  T. Maric - original version
+!!
+!-------------------------------------------------------------------------------
+!
+USE MODE_ll
+#ifndef MNH_OPENACC
+USE MODI_SHUMAN
+#else
+USE MODI_SHUMAN_DEVICE
+#endif
+USE MODI_GET_HALO
+!
+USE MODD_CONF
+USE MODD_PARAMETERS
+USE MODE_MPPDB
+!
+#ifdef MNH_OPENACC
+USE MODE_MNH_ZWORK, ONLY : IKB,IKE, IKU
+#endif
+!
+IMPLICIT NONE
+!
+!*       0.1   Declarations of dummy arguments :
+!
+INTEGER,                INTENT(IN)  :: KGRID   ! C grid localisation
+!
+REAL, DIMENSION(:,:,:), INTENT(INOUT)  :: PSRC    ! variable at t
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PCR     ! Courant number
+!
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PRHO  ! density
+REAL,                   INTENT(IN)  :: PTSTEP  ! Time step 
+!
+! output source term
+#ifndef MNH_OPENACC
+REAL, DIMENSION(SIZE(PCR,1),SIZE(PCR,2),SIZE(PCR,3)) :: PR
+#else
+REAL, DIMENSION(:,:,:),INTENT(OUT):: PR
+#endif
+!
+!*       0.2   Declarations of local variables :
+!
+#ifndef MNH_OPENACC
+INTEGER:: IKB    ! Begining useful area in x,y,z directions
+INTEGER:: IKE    ! End useful area in x,y,z directions
+!
+! advection fluxes
+REAL, DIMENSION(SIZE(PCR,1),SIZE(PCR,2),SIZE(PCR,3)) :: ZFPOS, ZFNEG
+!
+! interpolated variable at cell edges
+REAL, DIMENSION(SIZE(PCR,1),SIZE(PCR,2),SIZE(PCR,3)) :: ZPHAT
+#else
+! advection fluxes
+REAL, DIMENSION(:,:,:),INTENT(OUT):: ZFPOS, ZFNEG &
+!
+! interpolated variable at cell edges
+  &                                                   , ZPHAT &
+  &                                                   , ZRHO_MZM ,ZCR_MZM,ZCR_DZF
+#endif
+!
+!-------------------------------------------------------------------------------
+
+!$acc data present ( PSRC, PCR, PRHO, PR , &
+!$acc &              ZFPOS, ZFNEG, ZPHAT, ZRHO_MZM, ZCR_MZM, ZCR_DZF )
+
+IF (MPPDB_INITIALIZED) THEN
+  !Check all IN arrays
+  CALL MPPDB_CHECK(PCR, "PPM_S0_Z beg:PCR")
+  CALL MPPDB_CHECK(PRHO,"PPM_S0_Z beg:PRHO")
+  !Check all INOUT arrays
+  CALL MPPDB_CHECK(PSRC,"PPM_S0_Z beg:PSRC")
+END IF
+!
+!*       0.3.     COMPUTES THE DOMAIN DIMENSIONS
+!                 ------------------------------
+!
+#ifndef MNH_OPENACC
+IKB = 1 + JPVEXT
+IKE = SIZE(PSRC,3) - JPVEXT
+#endif
+!
+!-------------------------------------------------------------------------------
+!
+! calculate 4th order fluxes at cell edges in the inner domain
+!
+#ifndef MNH_OPENACC
+   CALL GET_HALO(PSRC, HNAME='PSRC')
+#else
+   CALL GET_HALO_D(PSRC, HNAME='PSRC')
+#endif
+!
+#ifdef MNH_OPENACC
+!$acc kernels
+#endif
+!
+ZPHAT(:,:,IKB+1:IKE) = (7.0 * &
+                       (PSRC(:,:,IKB+1:IKE) + PSRC(:,:,IKB:IKE-1)) - &
+                       (PSRC(:,:,IKB+2:IKE+1) + PSRC(:,:,IKB-1:IKE-2))) / 12.0
+!
+! set OPEN BC at the top and bottom
+ZPHAT(:,:,IKB) = 0.5*(PSRC(:,:,IKB-1) + PSRC(:,:,IKB))
+ZPHAT(:,:,IKB-1) = ZPHAT(:,:,IKB)  ! not used
+ZPHAT(:,:,IKE+1) = 0.5*(PSRC(:,:,IKE) + PSRC(:,:,IKE+1))
+!
+!!$CALL  GET_HALO(ZPHAT(:,:,:))
+!
+! calculate fluxes through cell edges for positive and negative Courant numbers
+! (for inflow or outflow situation)
+!
+ZFPOS(:,:,IKB+1:IKE+1) = ZPHAT(:,:,IKB+1:IKE+1) - & 
+     PCR(:,:,IKB+1:IKE+1)*(ZPHAT(:,:,IKB+1:IKE+1) - PSRC(:,:,IKB:IKE)) - &
+     PCR(:,:,IKB+1:IKE+1)*(1.0 - PCR(:,:,IKB+1:IKE+1)) * &
+     (ZPHAT(:,:,IKB:IKE) - 2.0*PSRC(:,:,IKB:IKE) + ZPHAT(:,:,IKB+1:IKE+1))
+!
+!!$CALL GET_HALO(ZFPOS(:,:,:)) ! JUAN
+!
+! positive flux on the BOTTOM boundary
+ZFPOS(:,:,IKB) = (PSRC(:,:,IKB-1) - ZPHAT(:,:,IKB))*PCR(:,:,IKB) + &
+                  ZPHAT(:,:,IKB)
+!
+! below bottom flux - not used
+ZFPOS(:,:,IKB-1) = 0.0
+!
+! negative fluxes:
+!
+ZFNEG(:,:,IKB:IKE) = ZPHAT(:,:,IKB:IKE) + & 
+     PCR(:,:,IKB:IKE)*(ZPHAT(:,:,IKB:IKE) - PSRC(:,:,IKB:IKE)) + &
+     PCR(:,:,IKB:IKE)*(1.0 + PCR(:,:,IKB:IKE)) * &
+     (ZPHAT(:,:,IKB:IKE) - 2.0*PSRC(:,:,IKB:IKE) +ZPHAT(:,:,IKB+1:IKE+1))
+!
+!!$   CALL GET_HALO(ZFNEG) ! JUAN
+!
+! set bottom negative flux to 0
+ZFNEG(:,:,IKB-1) = 0.0 
+!
+! negative flux at the TOP
+ZFNEG(:,:,IKE+1) = (ZPHAT(:,:,IKE+1) - PSRC(:,:,IKE+1))*PCR(:,:,IKE+1) + &
+                    ZPHAT(:,:,IKE+1) 
+!
+! calculate the advection
+!
+#ifndef MNH_OPENACC
+PR = PSRC * PRHO - &
+     DZF( PCR*MZM(PRHO)*( ZFPOS(:,:,:)*(0.5+SIGN(0.5,PCR)) + &
+                          ZFNEG*(0.5-SIGN(0.5,PCR)) ) )
+#else
+!$acc end kernels
+   CALL MZM_DEVICE(PRHO,ZRHO_MZM)
+!$acc kernels
+   ZCR_MZM =  PCR* ZRHO_MZM*( ZFPOS(:,:,:)*(0.5+SIGN(0.5,PCR)) + ZFNEG*(0.5-SIGN(0.5,PCR)) ) 
+   !dzf(ZCR_DZF,ZCR_MZM)
+!$acc end kernels
+   CALL DZF_DEVICE(1,1,1,ZCR_MZM,ZCR_DZF)
+!$acc kernels
+   PR = PSRC * PRHO - ZCR_DZF
+#endif
+!
+! in OPEN case fix boundary conditions
+!
+      PR(:,:,IKB-1) = PR(:,:,IKB)
+      PR(:,:,IKE+1) = PR(:,:,IKE)
+!
+!$acc end kernels 
+!
+#ifndef MNH_OPENACC
+   CALL GET_HALO(PR, HNAME='PR')
+#else
+   CALL GET_HALO_D(PR, HNAME='PR')
+#endif
+IF (MPPDB_INITIALIZED) THEN
+  !Check all INOUT arrays
+  CALL MPPDB_CHECK(PSRC,"PPM_S0_Z end:PSRC")
+  !Check all OUT arrays
+  CALL MPPDB_CHECK(PR,"PPM_S0_Z end:PR")
+END IF
+
+!$acc end data
+
+#ifdef MNH_OPENACC
+END SUBROUTINE PPM_S0_Z_D
+
+END SUBROUTINE PPM_S0_Z
+#else
+END FUNCTION PPM_S0_Z
+#endif
+!
+!-------------------------------------------------------------------------------
+!-------------------------------------------------------------------------------
+!
+#ifdef MNH_OPENACC
+!     ########################################################################
+!      FUNCTION PPM_S1_X(HLBCX, KGRID, PSRC, PCR, PRHO, PRHOT, &
+!                        PTSTEP) RESULT(PR)
+      SUBROUTINE PPM_S1_X(HLBCX, KGRID, PSRC, PCR, PRHO, PRHOT, &
+                          PTSTEP, PR)
+!     ########################################################################
+USE MODE_ll
+use mode_msg
+USE MODE_IO
+USE MODI_SHUMAN_DEVICE
+!
+USE MODD_CONF
+USE MODD_LUNIT
+USE MODD_PARAMETERS
+!
+USE MODE_MNH_ZWORK, ONLY : ZT3D, MNH_GET_ZT3D , MNH_REL_ZT3D
+!
+IMPLICIT NONE
+!
+!*       0.1   Declarations of dummy arguments :
+!
+CHARACTER (LEN=4), DIMENSION(2), INTENT(IN) :: HLBCX  ! X direction LBC type
+!
+INTEGER,                INTENT(IN)  :: KGRID   ! C grid localisation
+!
+REAL, DIMENSION(:,:,:), INTENT(INOUT)  :: PSRC    ! variable at t
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PCR     ! Courant number
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PRHO  ! density
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PRHOT ! density at t+dt
+REAL,                   INTENT(IN)  :: PTSTEP  ! Time step
+!
+! output source term
+REAL, DIMENSION(SIZE(PCR,1),SIZE(PCR,2),SIZE(PCR,3)) :: PR
+
+INTEGER :: IZPHAT,IZRUT,IZFUP,IZFCOR,IZRPOS,IZRNEG
+
+!$acc data present( PSRC, PCR, PRHO, PRHOT, PR )
+
+  call Print_msg( NVERB_ERROR, 'GEN', 'PPM_S1_X', 'OpenACC: not yet implemented' )
+
+    CALL  MNH_GET_ZT3D(IZPHAT,IZRUT,IZFUP,IZFCOR,IZRPOS,IZRNEG)
+
+    CALL PPM_S1_X_D(HLBCX, KGRID, PSRC, PCR, PRHO, PRHOT, PTSTEP, PR, &
+                    ZT3D(:,:,:,IZPHAT),ZT3D(:,:,:,IZRUT),ZT3D(:,:,:,IZFUP), &
+                    ZT3D(:,:,:,IZFCOR),ZT3D(:,:,:,IZRPOS),ZT3D(:,:,:,IZRNEG) )
+
+    CALL  MNH_REL_ZT3D(IZPHAT,IZRUT,IZFUP,IZFCOR,IZRPOS,IZRNEG)
+
+!$acc end data
+
+  CONTAINS
+!
+!     ########################################################################
+!      FUNCTION PPM_S1_X_D(HLBCX, KGRID, PSRC, PCR, PRHO, PRHOT, &
+!                        PTSTEP) RESULT(PR)
+      SUBROUTINE PPM_S1_X_D(HLBCX, KGRID, PSRC, PCR, PRHO, PRHOT, &
+                          PTSTEP, PR, ZPHAT,ZRUT,ZFUP,ZFCOR,ZRPOS,ZRNEG)
+!     ########################################################################
+#else
+!     ########################################################################
+      FUNCTION PPM_S1_X(HLBCX, KGRID, PSRC, PCR, PRHO, PRHOT, &
+                        PTSTEP) RESULT(PR)
+!     ########################################################################
+#endif
+!!
+!!****  PPM_S1_X - PPM  advection scheme in X direction in Skamarock 2006 
+!!                 notation - with flux limiting for monotonicity
+!!
+!!    MODIFICATIONS
+!!    -------------
+!!    
+!!    23.6.2006.  T. Maric - original version
+!!
+!-------------------------------------------------------------------------------
+!
+USE MODE_ll
+use mode_mppdb
+
+#ifndef MNH_OPENACC
+USE MODI_SHUMAN
+#else
+USE MODI_SHUMAN
+USE MODI_SHUMAN_DEVICE
+#endif
+!
+USE MODD_CONF
+USE MODD_PARAMETERS
+!USE MODD_ARGSLIST_ll, ONLY : HALO2LIST_ll
+!
+IMPLICIT NONE
+!
+!*       0.1   Declarations of dummy arguments :
+!
+CHARACTER (LEN=4), DIMENSION(2), INTENT(IN) :: HLBCX  ! X direction LBC type
+!
+INTEGER,                INTENT(IN)  :: KGRID   ! C grid localisation
+!
+#ifndef MNH_OPENACC
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PSRC    ! variable at t
+#else
+REAL, DIMENSION(:,:,:), INTENT(INOUT)  :: PSRC    ! variable at t
+#endif
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PCR     ! Courant number
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PRHO  ! density
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PRHOT ! density at t+dt
+REAL,                   INTENT(IN)  :: PTSTEP  ! Time step 
+!
+! output source term
+#ifndef MNH_OPENACC
+REAL, DIMENSION(SIZE(PCR,1),SIZE(PCR,2),SIZE(PCR,3)) :: PR
+#else
+REAL, DIMENSION(:,:,:), INTENT(OUT) :: PR
+#endif
+!
+!*       0.2   Declarations of local variables :
+!
+INTEGER:: IIB,IJB,IKB    ! Begining useful area in x,y,z directions
+INTEGER:: IIE,IJE,IKE    ! End useful area in x,y,z directions
+!
+! variable at cell edges
+REAL, DIMENSION(SIZE(PCR,1),SIZE(PCR,2),SIZE(PCR,3)) :: ZPHAT, ZRUT
+!
+! advection fluxes, upwind and correction
+REAL, DIMENSION(SIZE(PCR,1),SIZE(PCR,2),SIZE(PCR,3)) :: ZFUP, ZFCOR
+!
+! ratios for limiting the correction flux
+REAL, DIMENSION(SIZE(PCR,1),SIZE(PCR,2),SIZE(PCR,3)) :: ZRPOS, ZRNEG
+!
+! variables for limiting the correction flux
+REAL :: ZSRCMAX, ZSRCMIN, ZFIN, ZFOUT
+!
+REAL, PARAMETER :: ZEPS = 1.0E-16
+!
+INTEGER :: II, IJ, IK
+INTEGER                          :: IRESP             ! for prints
+!
+!-------------------------------------------------------------------------------
+
+!$acc data present( PSRC, PCR, PRHO, PRHOT, PR, &
+!$acc &             ZPHAT, ZRUT, ZFUP, ZFCOR, ZRPOS, ZRNEG )
+
+IF (MPPDB_INITIALIZED) THEN
+  !Check all IN arrays
+  CALL MPPDB_CHECK(PCR,  "PPM_S1_X beg:PCR")
+  CALL MPPDB_CHECK(PRHO, "PPM_S1_X beg:PRHO")
+  CALL MPPDB_CHECK(PRHOT,"PPM_S1_X beg:PRHOT")
+  !Check all INOUT arrays
+  CALL MPPDB_CHECK(PSRC, "PPM_S1_X beg:PSRC")
+END IF
+!
+!*       0.3.     COMPUTES THE DOMAIN DIMENSIONS
+!                 ------------------------------
+!
+CALL GET_INDICE_ll(IIB,IJB,IIE,IJE)
+IKB = 1 + JPVEXT
+IKE = SIZE(PSRC,3) - JPVEXT
+!
+!-------------------------------------------------------------------------------
+!
+! Calculate contravariant component rho*u/dx
+!
+ZRUT = PCR/PTSTEP * MXM(PRHO)
+!
+! calculate 4th order fluxes at cell edges in the inner domain
+!
+ZPHAT(IIB+1:IIE,:,:) = (7.0 * &
+                       (PSRC(IIB+1:IIE,:,:) + PSRC(IIB:IIE-1,:,:)) - &
+                       (PSRC(IIB+2:IIE+1,:,:) + PSRC(IIB-1:IIE-2,:,:))) / 12.0
+!
+SELECT CASE ( HLBCX(1) ) ! X direction LBC type: (1) for left side
+CASE ('CYCL','WALL')            ! In that case one must have HLBCX(1) == HLBCX(2)
+!
+   ZPHAT(IIB,:,:) = (7.0 * &
+                    (PSRC(IIB,:,:) + PSRC(IIB-1,:,:)) - &
+                    (PSRC(IIB+1,:,:) + PSRC(IIE-1,:,:))) / 12.0
+!
+   ZPHAT(IIE+1,:,:) = ZPHAT(IIB,:,:)
+   ZPHAT(IIB-1,:,:) = ZPHAT(IIE,:,:)
+!
+CASE ('OPEN')
+!
+   ZPHAT(IIB,:,:) = 0.5*(PSRC(IIB-1,:,:) + PSRC(IIB,:,:))
+   ZPHAT(IIB-1,:,:) = ZPHAT(IIB,:,:)
+   ZPHAT(IIE+1,:,:) = 0.5*(PSRC(IIE,:,:) + PSRC(IIE+1,:,:))
+!
+!
+END SELECT
+!
+! calculate upwind and correction fluxes. upwind flux is upstream value of the
+! scalar variable, and correction flux is the correction to the upstream flux
+! that makes it equivalent to the PPM flux
+! flux_ppm = flux_up + flux_corr
+!
+WHERE ( PCR(IIB:IIE,:,:) .GT. 0.0 )
+   ZFUP(IIB:IIE,:,:) = ZRUT(IIB:IIE,:,:) * PSRC(IIB-1:IIE-1,:,:)
+   ZFCOR(IIB:IIE,:,:) = ZRUT(IIB:IIE,:,:) * &
+        (1.0 - PCR(IIB:IIE,:,:)) * &
+        (ZPHAT(IIB:IIE,:,:) - PSRC(IIB-1:IIE-1,:,:) - PCR(IIB:IIE,:,:) * &
+        (ZPHAT(IIB-1:IIE-1,:,:) - 2.0*PSRC(IIB-1:IIE-1,:,:)+ZPHAT(IIB:IIE,:,:)))
+ELSEWHERE
+   ZFUP(IIB:IIE,:,:) = ZRUT(IIB:IIE,:,:) * PSRC(IIB:IIE,:,:)
+   ZFCOR(IIB:IIE,:,:) = ZRUT(IIB:IIE,:,:) * &
+        (1.0 + PCR(IIB:IIE,:,:)) * &
+        (ZPHAT(IIB:IIE,:,:) - PSRC(IIB:IIE,:,:) + PCR(IIB:IIE,:,:) * &
+        (ZPHAT(IIB:IIE,:,:) - 2.0*PSRC(IIB:IIE,:,:) + ZPHAT(IIB+1:IIE+1,:,:)))
+END WHERE
+!
+! set boundaries to CYCL
+!
+WHERE ( PCR(IIB-1,:,:) .GT. 0.0 )
+   ZFUP(IIB-1,:,:) = ZRUT(IIB-1,:,:) * PSRC(IIE-1,:,:)
+   ZFCOR(IIB-1,:,:) =  ZRUT(IIB-1,:,:) * &
+        (1.0 - PCR(IIB-1,:,:)) * &
+        (ZPHAT(IIB-1,:,:) - PSRC(IIE-1,:,:) - PCR(IIB-1,:,:) * &
+        (ZPHAT(IIE-1,:,:) - 2.0*PSRC(IIE-1,:,:) + ZPHAT(IIB-1,:,:)))
+ELSEWHERE
+   ZFUP(IIB-1,:,:) = ZRUT(IIB-1,:,:) * PSRC(IIB-1,:,:)
+   ZFCOR(IIB-1,:,:) =  ZRUT(IIB-1,:,:) * &
+        (1.0 + PCR(IIB-1,:,:)) * &
+        (ZPHAT(IIB-1,:,:) - PSRC(IIB-1,:,:) + PCR(IIB-1,:,:) * &
+        (ZPHAT(IIB-1,:,:) - 2.0*PSRC(IIB-1,:,:) + ZPHAT(IIB,:,:)))
+END WHERE
+!
+WHERE ( PCR(IIE+1,:,:) .GT. 0.0 )
+   ZFUP(IIE+1,:,:) = ZRUT(IIE+1,:,:) * PSRC(IIE,:,:)
+   ZFCOR(IIE+1,:,:) =  ZRUT(IIE+1,:,:) * &
+        (1.0 - PCR(IIE+1,:,:)) * &
+        (ZPHAT(IIE+1,:,:) - PSRC(IIE,:,:) - PCR(IIE+1,:,:) * &
+        (ZPHAT(IIE,:,:) - 2.0*PSRC(IIE,:,:) + ZPHAT(IIE+1,:,:)))
+ELSEWHERE
+   ZFUP(IIE+1,:,:) = ZRUT(IIE+1,:,:) * PSRC(IIE+1,:,:)
+   ZFCOR(IIE+1,:,:) =  ZRUT(IIE+1,:,:) * &
+        (1.0 + PCR(IIE+1,:,:)) * &
+        (ZPHAT(IIE+1,:,:) - PSRC(IIE+1,:,:) + PCR(IIE+1,:,:) * &
+        (ZPHAT(IIE+1,:,:) - 2.0*PSRC(IIE+1,:,:) + ZPHAT(IIB+1,:,:)))
+END WHERE
+!
+! Perform limiting of the fluxes
+!
+! 1. calculate upwind tendency of the source
+!
+PR = PSRC*PRHO - PTSTEP*DXF(ZFUP)
+!
+!-------------------------------------------------------------------------------
+! compute and apply the limiters
+!
+DO II = IIB,IIE
+   DO IJ = IJB-1,IJE+1
+      DO IK = IKB-1,IKE+1         
+!
+! 2. find local extrema in the source 
+!
+         ZSRCMAX = MAX( PSRC(II-1,IJ,IK),PSRC(II,IJ,IK),PSRC(II+1,IJ,IK) )
+         ZSRCMIN = MIN( PSRC(II-1,IJ,IK),PSRC(II,IJ,IK),PSRC(II+1,IJ,IK) )
+!
+! 3. compute incoming and outgoing fluxes for this cell
+!
+         ZFOUT = MAX(ZEPS,MAX(0.,ZFCOR(II+1,IJ,IK)) - MIN(0.,ZFCOR(II,IJ,IK)))
+         ZFIN  = MAX(ZEPS,MAX(0.,ZFCOR(II,IJ,IK)) - MIN(0.,ZFCOR(II+1,IJ,IK)))
+!
+! 4. calculate fraction of outgoing and incoming flux which will drive scalar
+!    values outside the local extrema
+!
+         ZRNEG(II,IJ,IK) = MAX(0.,MIN(1., &
+              (PR(II,IJ,IK) - PRHOT(II,IJ,IK)*ZSRCMIN) &
+              / PTSTEP / ZFOUT))
+!
+         ZRPOS(II,IJ,IK) = MAX(0.,MIN(1., &
+              (PRHOT(II,IJ,IK)*ZSRCMAX - PR(II,IJ,IK)) &
+              / PTSTEP / ZFIN))
+      END DO
+   END DO
+END DO
+!
+! set CYCL boundaries
+!
+DO IJ = IJB-1,IJE+1
+   DO IK = IKB-1,IKE+1         
+!
+      ZSRCMAX = MAX( PSRC(IIE-1,IJ,IK),PSRC(IIB-1,IJ,IK),PSRC(IIB,IJ,IK) )
+      ZSRCMIN = MIN( PSRC(IIE-1,IJ,IK),PSRC(IIB-1,IJ,IK),PSRC(IIB,IJ,IK) )
+!
+      ZFOUT = MAX(ZEPS,MAX(0.,ZFCOR(IIB,IJ,IK)) - MIN(0.,ZFCOR(IIB-1,IJ,IK)))
+      ZFIN  = MAX(ZEPS,MAX(0.,ZFCOR(IIB-1,IJ,IK)) - MIN(0.,ZFCOR(IIB,IJ,IK)))
+!
+      ZRNEG(IIB-1,IJ,IK) = MAX(0.,MIN(1., &
+           (PR(IIB-1,IJ,IK) - PRHOT(IIB-1,IJ,IK)*ZSRCMIN) &
+           / PTSTEP / ZFOUT))
+!
+      ZRPOS(IIB-1,IJ,IK) = MAX(0.,MIN(1., &
+           (PRHOT(IIB-1,IJ,IK)*ZSRCMAX - PR(IIB-1,IJ,IK)) &
+           / PTSTEP / ZFIN))
+!
+! 
+      ZSRCMAX = MAX( PSRC(IIE,IJ,IK),PSRC(IIE+1,IJ,IK),PSRC(IIB+1,IJ,IK) )
+      ZSRCMIN = MIN( PSRC(IIE,IJ,IK),PSRC(IIE+1,IJ,IK),PSRC(IIB+1,IJ,IK) )
+!
+      ZFOUT = MAX(ZEPS,MAX(0.,ZFCOR(IIB+1,IJ,IK)) - MIN(0.,ZFCOR(IIE+1,IJ,IK)))
+      ZFIN  = MAX(ZEPS,MAX(0.,ZFCOR(IIE+1,IJ,IK)) - MIN(0.,ZFCOR(IIB+1,IJ,IK)))
+!
+      ZRNEG(IIE+1,IJ,IK) = MAX(0.,MIN(1., &
+           (PR(IIE+1,IJ,IK) - PRHOT(IIE+1,IJ,IK)*ZSRCMIN) &
+           / PTSTEP / ZFOUT))
+!
+      ZRPOS(IIE+1,IJ,IK) = MAX(0.,MIN(1., &
+           (PRHOT(IIE+1,IJ,IK)*ZSRCMAX - PR(IIE+1,IJ,IK)) &
+           / PTSTEP / ZFIN))
+!
+   END DO
+END DO
+!
+! 5. apply the limit to the fluxes where needed
+!
+ZFCOR(IIB:IIE+1,:,:) = MAX( &
+     MIN(ZRNEG(IIB:IIE+1,:,:),ZRPOS(IIB-1:IIE,:,:)) * ZFCOR(IIB:IIE+1,:,:), &
+     ZFCOR(IIB:IIE+1,:,:) )
+ZFCOR(IIB-1,:,:) = MAX( &
+     MIN(ZRNEG(IIB-1,:,:),ZRPOS(IIE-1,:,:))*ZFCOR(IIB-1,:,:),ZFCOR(IIB-1,:,:))
+!ZFCOR(IIB-1,:,:) = MAX( ZRNEG(IIB-1,:,:)*ZFCOR(IIB-1,:,:), ZFCOR(IIB-1,:,:) )
+!
+ZFCOR(IIB:IIE+1,:,:) = MIN( &
+     MIN(ZRPOS(IIB:IIE+1,:,:),ZRNEG(IIB-1:IIE,:,:)) * ZFCOR(IIB:IIE+1,:,:), &
+     ZFCOR(IIB:IIE+1,:,:) )
+ZFCOR(IIB-1,:,:) = MIN( &
+     MIN(ZRPOS(IIB-1,:,:),ZRNEG(IIE-1,:,:))*ZFCOR(IIB-1,:,:),ZFCOR(IIB-1,:,:))
+!ZFCOR(IIB-1,:,:) = MIN( ZRPOS(IIB-1,:,:)*ZFCOR(IIB-1,:,:), ZFCOR(IIB-1,:,:) )
+
+!-------------------------------------------------------------------------------
+! 6. apply the limited flux correction to scalar field
+!
+PR = PR - PTSTEP*DXF(ZFCOR)
+!
+IF (MPPDB_INITIALIZED) THEN
+  !Check all INOUT arrays
+  CALL MPPDB_CHECK(PSRC,"PPM_S1_X end:PSRC")
+  !Check all OUT arrays
+  CALL MPPDB_CHECK(PR,"PPM_S1_X end:PR")
+END IF
+
+!$acc end data
+
+#ifdef MNH_OPENACC
+  END SUBROUTINE PPM_S1_X_D
+END SUBROUTINE PPM_S1_X
+#else
+END FUNCTION PPM_S1_X
+#endif
+!
+!-------------------------------------------------------------------------------
+!-------------------------------------------------------------------------------
+!
+#ifdef MNH_OPENACC
+!     ########################################################################
+!      FUNCTION PPM_S1_Y(HLBCX, KGRID, PSRC, PCR, PRHO, PRHOT, &
+!                        PTSTEP) RESULT(PR)
+      SUBROUTINE PPM_S1_Y(HLBCX, KGRID, PSRC, PCR, PRHO, PRHOT, &
+                          PTSTEP, PR)
+!     ########################################################################
+USE MODE_ll
+USE MODE_IO
+use mode_msg
+USE MODI_SHUMAN_DEVICE
+!
+USE MODD_CONF
+USE MODD_LUNIT
+USE MODD_PARAMETERS
+!
+USE MODE_MNH_ZWORK, ONLY : ZT3D, MNH_GET_ZT3D , MNH_REL_ZT3D
+!
+IMPLICIT NONE
+!
+!*       0.1   Declarations of dummy arguments :
+!
+CHARACTER (LEN=4), DIMENSION(2), INTENT(IN) :: HLBCX  ! X direction LBC type
+!
+INTEGER,                INTENT(IN)  :: KGRID   ! C grid localisation
+!
+REAL, DIMENSION(:,:,:), INTENT(INOUT)  :: PSRC    ! variable at t
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PCR     ! Courant number
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PRHO  ! density
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PRHOT ! density at t+dt
+REAL,                   INTENT(IN)  :: PTSTEP  ! Time step
+!
+! output source term
+REAL, DIMENSION(SIZE(PCR,1),SIZE(PCR,2),SIZE(PCR,3)) :: PR
+
+INTEGER :: IZPHAT,IZRVT,IZFUP,IZFCOR,IZRPOS,IZRNEG
+
+!$acc data present( PSRC, PCR, PRHO, PRHOT, PR )
+
+  call Print_msg( NVERB_ERROR, 'GEN', 'PPM_S1_Y', 'OpenACC: not yet implemented' )
+
+    CALL  MNH_GET_ZT3D(IZPHAT,IZRVT,IZFUP,IZFCOR,IZRPOS,IZRNEG)
+
+    CALL PPM_S1_Y_D(HLBCX, KGRID, PSRC, PCR, PRHO, PRHOT, PTSTEP, PR, &
+                    ZT3D(:,:,:,IZPHAT),ZT3D(:,:,:,IZRVT),ZT3D(:,:,:,IZFUP), &
+                    ZT3D(:,:,:,IZFCOR),ZT3D(:,:,:,IZRPOS),ZT3D(:,:,:,IZRNEG) )
+
+    CALL  MNH_REL_ZT3D(IZPHAT,IZRVT,IZFUP,IZFCOR,IZRPOS,IZRNEG)
+
+!$acc end data
+
+  CONTAINS
+!
+!     ########################################################################
+!      FUNCTION PPM_S1_Y_D(HLBCY, KGRID, PSRC, PCR, PRHO, PRHOT, &
+!                        PTSTEP) RESULT(PR)
+      SUBROUTINE PPM_S1_Y_D(HLBCY, KGRID, PSRC, PCR, PRHO, PRHOT, &
+                          PTSTEP, PR, ZPHAT,ZRVT,ZFUP,ZFCOR,ZRPOS,ZRNEG)
+!     ########################################################################
+#else
+!     ########################################################################
+      FUNCTION PPM_S1_Y(HLBCY, KGRID, PSRC, PCR, PRHO, PRHOT, &
+                        PTSTEP) RESULT(PR)
+!     ########################################################################
+#endif
+!!
+!!****  PPM_S1_Y - PPM  advection scheme in Y direction in Skamarock 2006 
+!!                 notation - with flux limiting for monotonicity
+!!
+!!    MODIFICATIONS
+!!    -------------
+!!    
+!!    23.6.2006.  T. Maric - original version
+!!
+!-------------------------------------------------------------------------------
+!
+USE MODE_ll
+use mode_mppdb
+
+#ifndef MNH_OPENACC
+USE MODI_SHUMAN
+#else
+USE MODI_SHUMAN
+USE MODI_SHUMAN_DEVICE
+#endif
+!
+USE MODD_CONF
+USE MODD_PARAMETERS
+!USE MODD_ARGSLIST_ll, ONLY : HALO2LIST_ll
+#ifdef MNH_OPENACC
+USE MODE_MNH_ZWORK, ONLY : ZT3D, MNH_GET_ZT3D , MNH_REL_ZT3D
+#endif
+!
+IMPLICIT NONE
+!
+!*       0.1   Declarations of dummy arguments :
+!
+CHARACTER (LEN=4), DIMENSION(2), INTENT(IN) :: HLBCY  ! X direction LBC type
+!
+INTEGER,                INTENT(IN)  :: KGRID   ! C grid localisation
+!
+#ifndef MNH_OPENACC
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PSRC    ! variable at t
+#else
+REAL, DIMENSION(:,:,:), INTENT(INOUT)  :: PSRC    ! variable at t
+#endif
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PCR     ! Courant number
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PRHO  ! density
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PRHOT ! density at t+dt
+REAL,                   INTENT(IN)  :: PTSTEP  ! Time step 
+!
+! output source term
+#ifndef MNH_OPENACC
+REAL, DIMENSION(SIZE(PCR,1),SIZE(PCR,2),SIZE(PCR,3)) :: PR
+#else
+REAL, DIMENSION(:,:,:), INTENT(OUT) :: PR
+#endif
+!
+!*       0.2   Declarations of local variables :
+!
+INTEGER:: IIB,IJB,IKB   ! Begining useful area in x,y,z directions
+INTEGER:: IIE,IJE,IKE   ! End useful area in x,y,z directions
+!
+! variable at cell edges
+REAL, DIMENSION(SIZE(PCR,1),SIZE(PCR,2),SIZE(PCR,3)) :: ZPHAT, ZRVT
+!
+! advection fluxes, upwind and correction
+REAL, DIMENSION(SIZE(PCR,1),SIZE(PCR,2),SIZE(PCR,3)) :: ZFUP, ZFCOR
+!
+! ratios for limiting the correction flux
+REAL, DIMENSION(SIZE(PCR,1),SIZE(PCR,2),SIZE(PCR,3)) :: ZRPOS, ZRNEG
+!
+! variables for limiting the correction flux
+REAL :: ZSRCMAX, ZSRCMIN, ZFIN, ZFOUT
+!
+!
+REAL, PARAMETER :: ZEPS = 1.0E-16
+!
+INTEGER :: II, IJ, IK
+INTEGER  :: IRESP   ! Return code of FM-routines
+!
+!-------------------------------------------------------------------------------
+
+!$acc data present( PSRC, PCR, PRHO, PRHOT, PR , &
+!$acc &             ZPHAT, ZRVT, ZFUP, ZFCOR, ZRPOS, ZRNEG )
+
+IF (MPPDB_INITIALIZED) THEN
+  !Check all IN arrays
+  CALL MPPDB_CHECK(PCR,  "PPM_S1_Y beg:PCR")
+  CALL MPPDB_CHECK(PRHO, "PPM_S1_Y beg:PRHO")
+  CALL MPPDB_CHECK(PRHOT,"PPM_S1_Y beg:PRHOT")
+  !Check all INOUT arrays
+  CALL MPPDB_CHECK(PSRC, "PPM_S1_Y beg:PSRC")
+END IF
+
+!
+IF ( L2D ) THEN
+   PR = PSRC*PRHO
+   !RETURN
+ELSE
+!
+!-------------------------------------------------------------------------------
+!
+!*       0.3.     COMPUTES THE DOMAIN DIMENSIONS
+!                 ------------------------------
+!
+CALL GET_INDICE_ll(IIB,IJB,IIE,IJE)
+IKB = 1 + JPVEXT
+IKE = SIZE(PSRC,3) - JPVEXT
+!
+!-------------------------------------------------------------------------------
+!
+ZRVT = PCR/PTSTEP * MYM(PRHO)
+!
+! calculate 4th order fluxes at cell edges in the inner domain !
+ZPHAT(:,IJB+1:IJE,:) = (7.0 * &
+                       (PSRC(:,IJB+1:IJE,:) + PSRC(:,IJB:IJE-1,:)) - &
+                       (PSRC(:,IJB+2:IJE+1,:) + PSRC(:,IJB-1:IJE-2,:))) / 12.0
+!
+SELECT CASE ( HLBCY(1) ) ! X direction LBC type: (1) for left side
+CASE ('CYCL','WALL')            ! In that case one must have HLBCY(1) == HLBCY(2)
+!
+   ZPHAT(:,IJB,:) = (7.0 * &
+                    (PSRC(:,IJB,:) + PSRC(:,IJB-1,:)) - &
+                    (PSRC(:,IJB+1,:) + PSRC(:,IJE-1,:))) / 12.0
+!
+   ZPHAT(:,IJE+1,:) = ZPHAT(:,IJB,:)
+   ZPHAT(:,IJB-1,:) = ZPHAT(:,IJE,:)
+!
+CASE ('OPEN')
+!
+   ZPHAT(:,IJB,:) = 0.5*(PSRC(:,IJB-1,:) + PSRC(:,IJB,:))
+   ZPHAT(:,IJB-1,:) = ZPHAT(:,IJB,:)
+   ZPHAT(:,IJE+1,:) = 0.5*(PSRC(:,IJE,:) + PSRC(:,IJE+1,:))
+!
+!
+END SELECT
+!
+! calculate upwind and correction fluxes. upwind flux is upstream value of the
+! scalar variable, and correction flux is the correction to the upstream flux
+! that makes it equivalent to the PPM flux
+! flux_ppm = flux_up + flux_corr
+!
+WHERE ( PCR(:,IJB:IJE,:) .GT. 0.0 )
+   ZFUP(:,IJB:IJE,:) = ZRVT(:,IJB:IJE,:) * PSRC(:,IJB-1:IJE-1,:)
+   ZFCOR(:,IJB:IJE,:) = ZRVT(:,IJB:IJE,:) * &
+        (1.0 - PCR(:,IJB:IJE,:)) * &
+        (ZPHAT(:,IJB:IJE,:) - PSRC(:,IJB-1:IJE-1,:) - PCR(:,IJB:IJE,:) * &
+        (ZPHAT(:,IJB-1:IJE-1,:) - 2.0*PSRC(:,IJB-1:IJE-1,:)+ZPHAT(:,IJB:IJE,:)))
+ELSEWHERE
+   ZFUP(:,IJB:IJE,:) = ZRVT(:,IJB:IJE,:) * PSRC(:,IJB:IJE,:)
+   ZFCOR(:,IJB:IJE,:) = ZRVT(:,IJB:IJE,:) * &
+        (1.0 + PCR(:,IJB:IJE,:)) * &
+        (ZPHAT(:,IJB:IJE,:) - PSRC(:,IJB:IJE,:) + PCR(:,IJB:IJE,:) * &
+        (ZPHAT(:,IJB:IJE,:) - 2.0*PSRC(:,IJB:IJE,:) + ZPHAT(:,IJB+1:IJE+1,:)))
+END WHERE
+!
+! set boundaries to CYCL
+!
+WHERE ( PCR(:,IJB-1,:) .GT. 0.0 )
+   ZFUP(:,IJB-1,:) = ZRVT(:,IJB-1,:) * PSRC(:,IJE-1,:)
+   ZFCOR(:,IJB-1,:) =  ZRVT(:,IJB-1,:) * &
+        (1.0 - PCR(:,IJB-1,:)) * &
+        (ZPHAT(:,IJB-1,:) - PSRC(:,IJE-1,:) - PCR(:,IJB-1,:) * &
+        (ZPHAT(:,IJE-1,:) - 2.0*PSRC(:,IJE-1,:) + ZPHAT(:,IJB-1,:)))
+ELSEWHERE
+   ZFUP(:,IJB-1,:) = ZRVT(:,IJB-1,:) * PSRC(:,IJB-1,:)
+   ZFCOR(:,IJB-1,:) =  ZRVT(:,IJB-1,:) * &
+        (1.0 + PCR(:,IJB-1,:)) * &
+        (ZPHAT(:,IJB-1,:) - PSRC(:,IJB-1,:) + PCR(:,IJB-1,:) * &
+        (ZPHAT(:,IJB-1,:) - 2.0*PSRC(:,IJB-1,:) + ZPHAT(:,IJB,:)))
+END WHERE
+!
+WHERE ( PCR(:,IJE+1,:) .GT. 0.0 )
+   ZFUP(:,IJE+1,:) = ZRVT(:,IJE+1,:) * PSRC(:,IJE,:)
+   ZFCOR(:,IJE+1,:) =  ZRVT(:,IJE+1,:) * &
+        (1.0 - PCR(:,IJE+1,:)) * &
+        (ZPHAT(:,IJE+1,:) - PSRC(:,IJE,:) - PCR(:,IJE+1,:) * &
+        (ZPHAT(:,IJE,:) - 2.0*PSRC(:,IJE,:) + ZPHAT(:,IJE+1,:)))
+ELSEWHERE
+   ZFUP(:,IJE+1,:) = ZRVT(:,IJE+1,:) * PSRC(:,IJE+1,:)
+   ZFCOR(:,IJE+1,:) =  ZRVT(:,IJE+1,:) * &
+        (1.0 + PCR(:,IJE+1,:)) * &
+        (ZPHAT(:,IJE+1,:) - PSRC(:,IJE+1,:) + PCR(:,IJE+1,:) * &
+        (ZPHAT(:,IJE+1,:) - 2.0*PSRC(:,IJE+1,:) + ZPHAT(:,IJB+1,:)))
+END WHERE
+!
+! Perform limiting of the fluxes
+!
+! 1. calculate upwind tendency of the source
+!
+PR = PSRC*PRHO - PTSTEP*DYF(ZFUP)
+!
+!-------------------------------------------------------------------------------
+! compute and apply the limiters
+!
+DO II = IIB-1,IIE+1
+   DO IJ = IJB,IJE
+      DO IK = IKB-1,IKE+1         
+!
+! 2. find local extrema in the source 
+!
+         ZSRCMAX = MAX( PSRC(II,IJ-1,IK),PSRC(II,IJ,IK),PSRC(II,IJ+1,IK) )
+         ZSRCMIN = MIN( PSRC(II,IJ-1,IK),PSRC(II,IJ,IK),PSRC(II,IJ+1,IK) )
+!
+! 3. compute incoming and outgoing fluxes for this cell
+!
+         ZFOUT = MAX(ZEPS,MAX(0.,ZFCOR(II,IJ+1,IK)) - MIN(0.,ZFCOR(II,IJ,IK)))
+         ZFIN  = MAX(ZEPS,MAX(0.,ZFCOR(II,IJ,IK)) - MIN(0.,ZFCOR(II,IJ+1,IK)))
+!
+! 4. calculate fraction of outgoing and incoming flux which will drive scalar
+!    values outside the local extrema
+!
+         ZRNEG(II,IJ,IK) = MAX(0.,MIN(1., &
+              (PR(II,IJ,IK) - PRHOT(II,IJ,IK)*ZSRCMIN) &
+              / PTSTEP / ZFOUT))
+!
+         ZRPOS(II,IJ,IK) = MAX(0.,MIN(1., &
+              (PRHOT(II,IJ,IK)*ZSRCMAX - PR(II,IJ,IK)) &
+              / PTSTEP / ZFIN))
+      END DO
+   END DO
+END DO
+!
+! set CYCL boundaries
+!
+DO II = IIB-1,IIE+1
+   DO IK = IKB-1,IKE+1         
+!
+      ZSRCMAX = MAX( PSRC(II,IJE-1,IK),PSRC(II,IJB-1,IK),PSRC(II,IJB,IK) )
+      ZSRCMIN = MIN( PSRC(II,IJE-1,IK),PSRC(II,IJB-1,IK),PSRC(II,IJB,IK) )
+!
+      ZFOUT = MAX(ZEPS,MAX(0.,ZFCOR(II,IJB,IK)) - MIN(0.,ZFCOR(II,IJB-1,IK)))
+      ZFIN  = MAX(ZEPS,MAX(0.,ZFCOR(II,IJB-1,IK)) - MIN(0.,ZFCOR(II,IJB,IK)))
+!
+      ZRNEG(II,IJB-1,IK) = MAX(0.,MIN(1., &
+           (PR(II,IJB-1,IK) - PRHOT(II,IJB-1,IK)*ZSRCMIN) &
+           / PTSTEP / ZFOUT))
+!
+      ZRPOS(II,IJB-1,IK) = MAX(0.,MIN(1., &
+           (PRHOT(II,IJB-1,IK)*ZSRCMAX - PR(II,IJB-1,IK)) &
+           / PTSTEP / ZFIN))
+!
+! 
+      ZSRCMAX = MAX( PSRC(II,IJE,IK),PSRC(II,IJE+1,IK),PSRC(II,IJB+1,IK) )
+      ZSRCMIN = MIN( PSRC(II,IJE,IK),PSRC(II,IJE+1,IK),PSRC(II,IJB+1,IK) )
+!
+      ZFOUT = MAX(ZEPS,MAX(0.,ZFCOR(II,IJB+1,IK)) - MIN(0.,ZFCOR(II,IJE+1,IK)))
+      ZFIN  = MAX(ZEPS,MAX(0.,ZFCOR(II,IJE+1,IK)) - MIN(0.,ZFCOR(II,IJB+1,IK)))
+!
+      ZRNEG(II,IJE+1,IK) = MAX(0.,MIN(1., &
+           (PR(II,IJE+1,IK) - PRHOT(II,IJE+1,IK)*ZSRCMIN) &
+           / PTSTEP / ZFOUT))
+!
+      ZRPOS(II,IJE+1,IK) = MAX(0.,MIN(1., &
+           (PRHOT(II,IJE+1,IK)*ZSRCMAX - PR(II,IJE+1,IK)) &
+           / PTSTEP / ZFIN))
+!
+   END DO
+END DO
+!
+! 5. apply the limit to the fluxes where needed
+!
+ZFCOR(:,IJB:IJE+1,:) = MAX( &
+     MIN(ZRNEG(:,IJB:IJE+1,:),ZRPOS(:,IJB-1:IJE,:)) * ZFCOR(:,IJB:IJE+1,:), &
+     ZFCOR(:,IJB:IJE+1,:) )
+ZFCOR(:,IJB-1,:) = MAX( &
+     MIN(ZRNEG(:,IJB-1,:),ZRPOS(:,IJE-1,:))*ZFCOR(:,IJB-1,:),ZFCOR(:,IJB-1,:))
+!
+ZFCOR(:,IJB:IJE+1,:) = MIN( &
+     MIN(ZRPOS(:,IJB:IJE+1,:),ZRNEG(:,IJB-1:IJE,:)) * ZFCOR(:,IJB:IJE+1,:), &
+     ZFCOR(:,IJB:IJE+1,:) )
+ZFCOR(:,IJB-1,:) = MIN( &
+     MIN(ZRPOS(:,IJB-1,:),ZRNEG(:,IJE-1,:))*ZFCOR(:,IJB-1,:),ZFCOR(:,IJB-1,:))
+!
+!-------------------------------------------------------------------------------
+! 6. apply the limited flux correction to scalar field
+!
+PR = PR - PTSTEP*DYF(ZFCOR)
+!
+IF (MPPDB_INITIALIZED) THEN
+  !Check all INOUT arrays
+  CALL MPPDB_CHECK(PSRC,"PPM_S1_Y end:PSRC")
+  !Check all OUT arrays
+  CALL MPPDB_CHECK(PR,"PPM_S1_Y end:PR")
+END IF
+
+END IF !not L2D
+
+!$acc end data
+
+#ifdef MNH_OPENACC
+  END SUBROUTINE PPM_S1_Y_D
+END SUBROUTINE PPM_S1_Y
+#else
+END FUNCTION PPM_S1_Y
+#endif
+!
+!-------------------------------------------------------------------------------
+!-------------------------------------------------------------------------------
+!
+#ifdef MNH_OPENACC
+!
+!     ########################################################################
+!      FUNCTION PPM_S1_Z(KGRID, PSRC, PCR, PRHO, PRHOT, &
+!                        PTSTEP) RESULT(PR)
+      SUBROUTINE PPM_S1_Z(KGRID, PSRC, PCR, PRHO, PRHOT, &
+                          PTSTEP, PR)
+!     ########################################################################
+USE MODE_ll
+USE MODE_IO
+use mode_msg
+
+USE MODI_SHUMAN_DEVICE
+!
+USE MODD_CONF
+USE MODD_LUNIT
+USE MODD_PARAMETERS
+!
+USE MODE_MNH_ZWORK, ONLY : ZT3D, MNH_GET_ZT3D , MNH_REL_ZT3D
+!
+IMPLICIT NONE
+!
+!*       0.1   Declarations of dummy arguments :
+!
+INTEGER,                INTENT(IN)  :: KGRID   ! C grid localisation
+!
+REAL, DIMENSION(:,:,:), INTENT(INOUT)  :: PSRC    ! variable at t
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PCR     ! Courant number
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PRHO  ! density
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PRHOT ! density at t+dt
+REAL,                   INTENT(IN)  :: PTSTEP  ! Time step
+!
+! output source term
+REAL, DIMENSION(SIZE(PCR,1),SIZE(PCR,2),SIZE(PCR,3)) :: PR
+
+INTEGER :: IZPHAT,IZRVT,IZFUP,IZFCOR,IZRPOS,IZRNEG
+
+!$acc data present( PSRC, PCR, PRHO, PRHOT, PR )
+
+  call Print_msg( NVERB_ERROR, 'GEN', 'PPM_S1_Z', 'OpenACC: not yet implemented' )
+
+    CALL  MNH_GET_ZT3D(IZPHAT,IZRVT,IZFUP,IZFCOR,IZRPOS,IZRNEG)
+
+    CALL PPM_S1_Z_D(KGRID, PSRC, PCR, PRHO, PRHOT, PTSTEP, PR, &
+                    ZT3D(:,:,:,IZPHAT),ZT3D(:,:,:,IZRVT),ZT3D(:,:,:,IZFUP), &
+                    ZT3D(:,:,:,IZFCOR),ZT3D(:,:,:,IZRPOS),ZT3D(:,:,:,IZRNEG) )
+
+    CALL  MNH_REL_ZT3D(IZPHAT,IZRVT,IZFUP,IZFCOR,IZRPOS,IZRNEG)
+
+!$acc end data
+
+  CONTAINS
+!     ########################################################################
+      SUBROUTINE PPM_S1_Z_D(KGRID, PSRC, PCR, PRHO, PRHOT, PTSTEP, &
+                          PR, ZPHAT,ZRVT,ZFUP,ZFCOR,ZRPOS,ZRNEG)
+!     ########################################################################
+#else
+!     ########################################################################
+      FUNCTION PPM_S1_Z(KGRID, PSRC, PCR, PRHO, PRHOT, PTSTEP) &
+                        RESULT(PR)
+!     ########################################################################
+#endif
+!!
+!!****  PPM_S1_Z - PPM  advection scheme in Z direction in Skamarock 2006 
+!!                 notation - with flux limiting for monotonicity
+!!
+!!    MODIFICATIONS
+!!    -------------
+!!    
+!!    23.6.2006.  T. Maric - original version
+!!
+!-------------------------------------------------------------------------------
+!
+USE MODE_ll
+use mode_mppdb
+
+#ifndef MNH_OPENACC
+USE MODI_SHUMAN
+#else
+USE MODI_SHUMAN
+USE MODI_SHUMAN_DEVICE
+#endif
+!
+USE MODD_CONF
+USE MODD_PARAMETERS
+!USE MODD_ARGSLIST_ll, ONLY : HALO2LIST_ll
+#ifdef MNH_OPENACC
+USE MODE_MNH_ZWORK, ONLY : ZT3D, MNH_GET_ZT3D , MNH_REL_ZT3D
+#endif
+!
+IMPLICIT NONE
+!
+!*       0.1   Declarations of dummy arguments :
+!
+INTEGER,                INTENT(IN)  :: KGRID   ! C grid localisation
+!
+#ifndef MNH_OPENACC
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PSRC    ! variable at t
+#else
+REAL, DIMENSION(:,:,:), INTENT(INOUT)  :: PSRC    ! variable at t
+#endif
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PCR     ! Courant number
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PRHO  ! density
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PRHOT ! density at t+dt
+REAL,                   INTENT(IN)  :: PTSTEP  ! Time step 
+!
+! output source term
+#ifndef MNH_OPENACC
+REAL, DIMENSION(SIZE(PCR,1),SIZE(PCR,2),SIZE(PCR,3)) :: PR
+#else
+REAL, DIMENSION(:,:,:), INTENT(OUT) :: PR
+#endif
+!
+!*       0.2   Declarations of local variables :
+!
+INTEGER:: IIB,IJB,IKB   ! Begining useful area in x,y,z directions
+INTEGER:: IIE,IJE,IKE   ! End useful area in x,y,z directions
+!
+! variable at cell edges
+REAL, DIMENSION(SIZE(PCR,1),SIZE(PCR,2),SIZE(PCR,3)) :: ZPHAT, ZRVT
+!
+! advection fluxes, upwind and correction
+REAL, DIMENSION(SIZE(PCR,1),SIZE(PCR,2),SIZE(PCR,3)) :: ZFUP, ZFCOR
+!
+! ratios for limiting the correction flux
+REAL, DIMENSION(SIZE(PCR,1),SIZE(PCR,2),SIZE(PCR,3)) :: ZRPOS, ZRNEG
+!
+! variables for limiting the correction flux
+REAL :: ZSRCMAX, ZSRCMIN, ZFIN, ZFOUT
+!
+REAL, PARAMETER :: ZEPS = 1.0E-16
+!
+INTEGER :: II, IJ, IK
+!
+!-------------------------------------------------------------------------------
+
+!$acc data present( PSRC, PCR, PRHO, PRHOT, PR, &
+!$acc &             ZPHAT, ZRVT, ZFUP, ZFCOR, ZRPOS, ZRNEG )
+
+IF (MPPDB_INITIALIZED) THEN
+  !Check all IN arrays
+  CALL MPPDB_CHECK(PCR,  "PPM_S1_Z beg:PCR")
+  CALL MPPDB_CHECK(PRHO, "PPM_S1_Z beg:PRHO")
+  CALL MPPDB_CHECK(PRHOT,"PPM_S1_Z beg:PRHOT")
+  !Check all INOUT arrays
+  CALL MPPDB_CHECK(PSRC, "PPM_S1_Z beg:PSRC")
+END IF
+
+!
+!*       0.3.     COMPUTES THE DOMAIN DIMENSIONS
+!                 ------------------------------
+!
+CALL GET_INDICE_ll(IIB,IJB,IIE,IJE)
+IKB = 1 + JPVEXT
+IKE = SIZE(PSRC,3) - JPVEXT
+!
+!-------------------------------------------------------------------------------
+!
+ZRVT = PCR/PTSTEP * MZM(PRHO)
+!
+! calculate 4th order fluxes at cell edges in the inner domain !
+ZPHAT(:,:,IKB+1:IKE) = (7.0 * &
+                       (PSRC(:,:,IKB+1:IKE) + PSRC(:,:,IKB:IKE-1)) - &
+                       (PSRC(:,:,IKB+2:IKE+1) + PSRC(:,:,IKB-1:IKE-2))) / 12.0
+!
+! set BC to WALL
+!
+ZPHAT(:,:,IKB) = (7.0 * &
+                 (PSRC(:,:,IKB) + PSRC(:,:,IKB+1)) - &
+                 (PSRC(:,:,IKB+1) + PSRC(:,:,IKB+2))) / 12.0
+ZPHAT(:,:,IKB-1) = ZPHAT(:,:,IKB+1)
+ZPHAT(:,:,IKE+1) = (7.0 * &
+                   (PSRC(:,:,IKE+1) + PSRC(:,:,IKE)) - &
+                   (PSRC(:,:,IKE) + PSRC(:,:,IKE-1))) / 12.0
+!
+! set BC to OPEN
+!
+!!$ZPHAT(:,:,IKB) = 0.5*(PSRC(:,:,IKB-1) + PSRC(:,:,IKB))
+!!$ZPHAT(:,:,IKB-1) = ZPHAT(:,:,IKB)
+!!$ZPHAT(:,:,IKE+1) = 0.5*(PSRC(:,:,IKE) + PSRC(:,:,IKE+1))
+!
+! calculate upwind and correction fluxes. upwind flux is upstream value of the
+! scalar variable, and correction flux is the correction to the upstream flux
+! that makes it equivalent to the PPM flux
+! flux_ppm = flux_up + flux_corr
+!
+WHERE ( PCR(:,:,IKB:IKE) .GT. 0.0 )
+   ZFUP(:,:,IKB:IKE) = ZRVT(:,:,IKB:IKE) * PSRC(:,:,IKB-1:IKE-1)
+   ZFCOR(:,:,IKB:IKE) = ZRVT(:,:,IKB:IKE) * &
+        (1.0 - PCR(:,:,IKB:IKE)) * &
+        (ZPHAT(:,:,IKB:IKE) - PSRC(:,:,IKB-1:IKE-1) - PCR(:,:,IKB:IKE) * &
+        (ZPHAT(:,:,IKB-1:IKE-1) - 2.0*PSRC(:,:,IKB-1:IKE-1)+ZPHAT(:,:,IKB:IKE)))
+ELSEWHERE
+   ZFUP(:,:,IKB:IKE) = ZRVT(:,:,IKB:IKE) * PSRC(:,:,IKB:IKE)
+   ZFCOR(:,:,IKB:IKE) = ZRVT(:,:,IKB:IKE) * &
+        (1.0 + PCR(:,:,IKB:IKE)) * &
+        (ZPHAT(:,:,IKB:IKE) - PSRC(:,:,IKB:IKE) + PCR(:,:,IKB:IKE) * &
+        (ZPHAT(:,:,IKB:IKE) - 2.0*PSRC(:,:,IKB:IKE) + ZPHAT(:,:,IKB+1:IKE+1)))
+END WHERE
+!
+! set BC to WALL
+!
+WHERE ( PCR(:,:,IKB-1) .GT. 0.0 )
+   ZFUP(:,:,IKB-1) = ZRVT(:,:,IKB-1) * PSRC(:,:,IKB+2)
+   ZFCOR(:,:,IKB-1) =  ZRVT(:,:,IKB-1) * &
+        (1.0 - PCR(:,:,IKB-1)) * &
+        (ZPHAT(:,:,IKB+1) - PSRC(:,:,IKB+2) - PCR(:,:,IKB+1) * &
+        (ZPHAT(:,:,IKB+2) - 2.0*PSRC(:,:,IKB+2) + ZPHAT(:,:,IKB+1)))
+ELSEWHERE
+   ZFUP(:,:,IKB-1) = ZRVT(:,:,IKB-1) * PSRC(:,:,IKB+1)
+   ZFCOR(:,:,IKB-1) =  ZRVT(:,:,IKB-1) * &
+        (1.0 + PCR(:,:,IKB-1)) * &
+        (ZPHAT(:,:,IKB+1) - PSRC(:,:,IKB+1) + PCR(:,:,IKB+1) * &
+        (ZPHAT(:,:,IKB+1) - 2.0*PSRC(:,:,IKB+1) + ZPHAT(:,:,IKB)))
+END WHERE
+!
+WHERE ( PCR(:,:,IKE+1) .GT. 0.0 )
+   ZFUP(:,:,IKE+1) = ZRVT(:,:,IKE+1) * PSRC(:,:,IKE)
+   ZFCOR(:,:,IKE+1) =  ZRVT(:,:,IKE+1) * &
+        (1.0 - PCR(:,:,IKE+1)) * &
+        (ZPHAT(:,:,IKE+1) - PSRC(:,:,IKE) - PCR(:,:,IKE+1) * &
+        (ZPHAT(:,:,IKE) - 2.0*PSRC(:,:,IKE) + ZPHAT(:,:,IKE+1)))
+ELSEWHERE
+   ZFUP(:,:,IKE+1) = ZRVT(:,:,IKE+1) * PSRC(:,:,IKE+1)
+   ZFCOR(:,:,IKE+1) =  ZRVT(:,:,IKE+1) * &
+        (1.0 + PCR(:,:,IKE+1)) * &
+        (ZPHAT(:,:,IKE+1) - PSRC(:,:,IKE+1) + PCR(:,:,IKE+1) * &
+        (ZPHAT(:,:,IKE+1) - 2.0*PSRC(:,:,IKE+1) + ZPHAT(:,:,IKE)))
+END WHERE
+!
+!
+!!$! set boundaries to CYCL
+!!$!
+!!$WHERE ( PCR(:,:,IKB-1) .GT. 0.0 )
+!!$   ZFUP(:,:,IKB-1) = ZRVT(:,:,IKB-1) * PSRC(:,:,IKE-1)
+!!$   ZFCOR(:,:,IKB-1) =  ZRVT(:,:,IKB-1) * &
+!!$        (1.0 - PCR(:,:,IKB-1)) * &
+!!$        (ZPHAT(:,:,IKB-1) - PSRC(:,:,IKE-1) - PCR(:,:,IKB-1) * &
+!!$        (ZPHAT(:,:,IKE-1) - 2.0*PSRC(:,:,IKE-1) + ZPHAT(:,:,IKB-1)))
+!!$ELSEWHERE
+!!$   ZFUP(:,:,IKB-1) = ZRVT(:,:,IKB-1) * PSRC(:,:,IKB-1)
+!!$   ZFCOR(:,:,IKB-1) =  ZRVT(:,:,IKB-1) * &
+!!$        (1.0 + PCR(:,:,IKB-1)) * &
+!!$        (ZPHAT(:,:,IKB-1) - PSRC(:,:,IKB-1) + PCR(:,:,IKB-1) * &
+!!$        (ZPHAT(:,:,IKB-1) - 2.0*PSRC(:,:,IKB-1) + ZPHAT(:,:,IKB)))
+!!$END WHERE
+!!$!
+!!$WHERE ( PCR(:,:,IKE+1) .GT. 0.0 )
+!!$   ZFUP(:,:,IKE+1) = ZRVT(:,:,IKE+1) * PSRC(:,:,IKE)
+!!$   ZFCOR(:,:,IKE+1) =  ZRVT(:,:,IKE+1) * &
+!!$        (1.0 - PCR(:,:,IKE+1)) * &
+!!$        (ZPHAT(:,:,IKE+1) - PSRC(:,:,IKE) - PCR(:,:,IKE+1) * &
+!!$        (ZPHAT(:,:,IKE) - 2.0*PSRC(:,:,IKE) + ZPHAT(:,:,IKE+1)))
+!!$ELSEWHERE
+!!$   ZFUP(:,:,IKE+1) = ZRVT(:,:,IKE+1) * PSRC(:,:,IKE+1)
+!!$   ZFCOR(:,:,IKE+1) =  ZRVT(:,:,IKE+1) * &
+!!$        (1.0 + PCR(:,:,IKE+1)) * &
+!!$        (ZPHAT(:,:,IKE+1) - PSRC(:,:,IKE+1) + PCR(:,:,IKE+1) * &
+!!$        (ZPHAT(:,:,IKE+1) - 2.0*PSRC(:,:,IKE+1) + ZPHAT(:,:,IKB+1)))
+!!$END WHERE
+!
+! Perform limiting of the fluxes
+!
+! 1. calculate upwind tendency of the source
+!
+PR = PSRC*PRHO - PTSTEP*DZF(ZFUP)
+!
+!-------------------------------------------------------------------------------
+! compute and apply the limiters
+!
+DO II = IIB-1,IIE+1
+   DO IJ = IJB-1,IJE+1
+      DO IK = IKB,IKE         
+!
+! 2. find local extrema in the source 
+!
+         ZSRCMAX = MAX( PSRC(II,IJ,IK-1),PSRC(II,IJ,IK),PSRC(II,IJ,IK+1) )
+         ZSRCMIN = MIN( PSRC(II,IJ,IK-1),PSRC(II,IJ,IK),PSRC(II,IJ,IK+1) )
+!
+! 3. compute incoming and outgoing fluxes for this cell
+!
+         ZFOUT = MAX(ZEPS,MAX(0.,ZFCOR(II,IJ,IK+1)) - MIN(0.,ZFCOR(II,IJ,IK)))
+         ZFIN  = MAX(ZEPS,MAX(0.,ZFCOR(II,IJ,IK)) - MIN(0.,ZFCOR(II,IJ,IK+1)))
+!
+! 4. calculate fraction of outgoing and incoming flux which will drive scalar
+!    values outside the local extrema
+!
+         ZRNEG(II,IJ,IK) = MAX(0.,MIN(1., &
+              (PR(II,IJ,IK) - PRHOT(II,IJ,IK)*ZSRCMIN) &
+              / PTSTEP / ZFOUT))
+!
+         ZRPOS(II,IJ,IK) = MAX(0.,MIN(1., &
+              (PRHOT(II,IJ,IK)*ZSRCMAX - PR(II,IJ,IK)) &
+              / PTSTEP / ZFIN))
+      END DO
+   END DO
+END DO
+!
+! set WALL boundaries
+!
+DO II = IIB-1,IIE+1
+   DO IJ = IJB-1,IJE+1         
+!
+      ZSRCMAX = MAX( PSRC(II,IJ,IKB+1),PSRC(II,IJ,IKB) )
+      ZSRCMIN = MIN( PSRC(II,IJ,IKB+1),PSRC(II,IJ,IKB) )
+!
+      ZFOUT = MAX(ZEPS,MAX(0.,ZFCOR(II,IJ,IKB)) - MIN(0.,ZFCOR(II,IJ,IKB-1)))
+      ZFIN  = MAX(ZEPS,MAX(0.,ZFCOR(II,IJ,IKB-1)) - MIN(0.,ZFCOR(II,IJ,IKB)))
+!
+      ZRNEG(II,IJ,IKB-1) = MAX(0.,MIN(1., &
+           (PR(II,IJ,IKB-1) - PRHOT(II,IJ,IKB-1)*ZSRCMIN) &
+           / PTSTEP / ZFOUT))
+!
+      ZRPOS(II,IJ,IKB-1) = MAX(0.,MIN(1., &
+           (PRHOT(II,IJ,IKB-1)*ZSRCMAX - PR(II,IJ,IKB-1)) &
+           / PTSTEP / ZFIN))
+!
+! 
+      ZSRCMAX = MAX( PSRC(II,IJ,IKE),PSRC(II,IJ,IKE+1) )
+      ZSRCMIN = MIN( PSRC(II,IJ,IKE),PSRC(II,IJ,IKE+1) )
+!
+      ZFOUT = MAX(ZEPS,MAX(0.,ZFCOR(II,IJ,IKE)) - MIN(0.,ZFCOR(II,IJ,IKE+1)))
+      ZFIN  = MAX(ZEPS,MAX(0.,ZFCOR(II,IJ,IKE+1)) - MIN(0.,ZFCOR(II,IJ,IKE)))
+!
+      ZRNEG(II,IJ,IKE+1) = MAX(0.,MIN(1., &
+           (PR(II,IJ,IKE+1) - PRHOT(II,IJ,IKE+1)*ZSRCMIN) &
+           / PTSTEP / ZFOUT))
+!
+      ZRPOS(II,IJ,IKE+1) = MAX(0.,MIN(1., &
+           (PRHOT(II,IJ,IKE+1)*ZSRCMAX - PR(II,IJ,IKE+1)) &
+           / PTSTEP / ZFIN))
+!
+   END DO
+END DO
+!
+! set CYCL boundaries
+!
+!!$DO II = IIB-1,IIE+1
+!!$   DO IJ = IJB-1,IJE+1         
+!!$!
+!!$      ZSRCMAX = MAX( PSRC(II,IJ,IKE-1),PSRC(II,IJ,IKB-1),PSRC(II,IJ,IKB) )
+!!$      ZSRCMIN = MIN( PSRC(II,IJ,IKE-1),PSRC(II,IJ,IKB-1),PSRC(II,IJ,IKB) )
+!!$!
+!!$      ZFOUT = MAX(ZEPS,MAX(0.,ZFCOR(II,IJ,IKB)) - MIN(0.,ZFCOR(II,IJ,IKB-1)))
+!!$      ZFIN  = MAX(ZEPS,MAX(0.,ZFCOR(II,IJ,IKB-1)) - MIN(0.,ZFCOR(II,IJ,IKB)))
+!!$!
+!!$      ZRNEG(II,IJ,IKB-1) = MAX(0.,MIN(1., &
+!!$           (PR(II,IJ,IKB-1) - PRHOT(II,IJ,IKB-1)*ZSRCMIN) &
+!!$           / PTSTEP / ZFOUT))
+!!$!
+!!$      ZRPOS(II,IJ,IKB-1) = MAX(0.,MIN(1., &
+!!$           (PRHOT(II,IJ,IKB-1)*ZSRCMAX - PR(II,IJ,IKB-1)) &
+!!$           / PTSTEP / ZFIN))
+!!$!
+!!$! 
+!!$      ZSRCMAX = MAX( PSRC(II,IJ,IKE),PSRC(II,IJ,IKE+1),PSRC(II,IJ,IKB+1) )
+!!$      ZSRCMIN = MIN( PSRC(II,IJ,IKE),PSRC(II,IJ,IKE+1),PSRC(II,IJ,IKB+1) )
+!!$!
+!!$      ZFOUT = MAX(ZEPS,MAX(0.,ZFCOR(II,IJ,IKB+1)) - MIN(0.,ZFCOR(II,IJ,IKE+1)))
+!!$      ZFIN  = MAX(ZEPS,MAX(0.,ZFCOR(II,IJ,IKE+1)) - MIN(0.,ZFCOR(II,IJ,IKB+1)))
+!!$!
+!!$      ZRNEG(II,IJ,IKE+1) = MAX(0.,MIN(1., &
+!!$           (PR(II,IJ,IKE+1) - PRHOT(II,IJ,IKE+1)*ZSRCMIN) &
+!!$           / PTSTEP / ZFOUT))
+!!$!
+!!$      ZRPOS(II,IJ,IKE+1) = MAX(0.,MIN(1., &
+!!$           (PRHOT(II,IJ,IKE+1)*ZSRCMAX - PR(II,IJ,IKE+1)) &
+!!$           / PTSTEP / ZFIN))
+!!$!
+!!$   END DO
+!!$END DO
+!
+! 5. apply the limit to the fluxes where needed
+!
+ZFCOR(:,:,IKB:IKE+1) = MAX( &
+     MIN(ZRNEG(:,:,IKB:IKE+1),ZRPOS(:,:,IKB-1:IKE)) * ZFCOR(:,:,IKB:IKE+1), &
+     ZFCOR(:,:,IKB:IKE+1) )
+ZFCOR(:,:,IKB-1) = MAX( &
+     MIN(ZRNEG(:,:,IKB-1),ZRPOS(:,:,IKB+2))*ZFCOR(:,:,IKB-1),ZFCOR(:,:,IKB-1))
+!!$ZFCOR(:,:,IKB-1) = MAX( &
+!!$     MIN(ZRNEG(:,:,IKB-1),ZRPOS(:,:,IKE-1))*ZFCOR(:,:,IKB-1),ZFCOR(:,:,IKB-1))
+!
+ZFCOR(:,:,IKB:IKE+1) = MIN( &
+     MIN(ZRPOS(:,:,IKB:IKE+1),ZRNEG(:,:,IKB-1:IKE)) * ZFCOR(:,:,IKB:IKE+1), &
+     ZFCOR(:,:,IKB:IKE+1) )
+ZFCOR(:,:,IKB-1) = MIN( &
+     MIN(ZRPOS(:,:,IKB-1),ZRNEG(:,:,IKB+2))*ZFCOR(:,:,IKB-1),ZFCOR(:,:,IKB-1))
+!!$ZFCOR(:,:,IKB-1) = MIN( &
+!!$     MIN(ZRPOS(:,:,IKB-1),ZRNEG(:,:,IKE-1))*ZFCOR(:,:,IKB-1),ZFCOR(:,:,IKB-1))
+!
+!-------------------------------------------------------------------------------
+! 6. apply the limited flux correction to scalar field
+!
+PR = PR - PTSTEP*DZF(ZFCOR)
+!
+IF (MPPDB_INITIALIZED) THEN
+  !Check all INOUT arrays
+  CALL MPPDB_CHECK(PSRC,"PPM_S1_Z end:PSRC")
+  !Check all OUT arrays
+  CALL MPPDB_CHECK(PR,"PPM_S1_Z end:PR")
+END IF
+
+!$acc end data
+
+#ifdef MNH_OPENACC
+  END SUBROUTINE PPM_S1_Z_D
+END SUBROUTINE PPM_S1_Z
+#else
+END FUNCTION PPM_S1_Z
+#endif
diff --git a/src/ZSOLVER/pressurez.f90 b/src/ZSOLVER/pressurez.f90
index a637645ae4e9cd3df13f6ec93fbff5a551d4338b..b7221fa4acb1ab350c0658a531032e553d8f22b5 100644
--- a/src/ZSOLVER/pressurez.f90
+++ b/src/ZSOLVER/pressurez.f90
@@ -366,8 +366,9 @@ REAL, OPTIONAL                     :: PRESIDUAL
 !
 !                                                           Metric coefficients:
 !
-REAL, DIMENSION(SIZE(PPABST,1),SIZE(PPABST,2),SIZE(PPABST,3)) :: ZDV_SOURCE
+REAL, DIMENSION(:,:,:) , POINTER , CONTIGUOUS :: ZDV_SOURCE
 !                                                   ! divergence of the sources
+INTEGER :: IZDV_SOURCE
 !
 INTEGER :: IIB          ! indice I for the first inner mass point along x
 INTEGER :: IIE          ! indice I for the last inner mass point along x
@@ -378,11 +379,12 @@ INTEGER :: IKE          ! indice K for the last inner mass point along z
 INTEGER :: ILUOUT       ! Logical unit of output listing
 INTEGER :: IRESP        ! Return code of FM routines
 !
-REAL, DIMENSION(SIZE(PPABST,1),SIZE(PPABST,2),SIZE(PPABST,3)) :: ZTHETAV, &
+REAL, DIMENSION(:,:,:) , POINTER , CONTIGUOUS :: ZTHETAV, &
                         ! virtual potential temperature
-                                                                 ZPHIT
+                                                 ZPHIT
                         ! MAE + DUR => Exner function perturbation
                         ! LHE       => Exner function perturbation * CPD * THVREF
+INTEGER :: IZTHETAV,IZPHIT
 !
 REAL            :: ZRV_OV_RD !  XRV / XRD
 REAL                  :: ZMAXVAL, ZMAXRES, ZMAX,ZMAX_ll ! for print
@@ -392,10 +394,10 @@ INTEGER         :: IIU,IJU,IKU     ! array sizes in I,J,K
 INTEGER         :: JK              ! loop index on the vertical levels
 INTEGER         :: JI,JJ
 !
-REAL, DIMENSION(SIZE(PDXX,1),SIZE(PDXX,3)) :: ZPABS_S ! local pressure on southern side
-REAL, DIMENSION(SIZE(PDXX,1),SIZE(PDXX,3)) :: ZPABS_N ! local pressure on northern side
-REAL, DIMENSION(SIZE(PDYY,2),SIZE(PDXX,3)) :: ZPABS_E ! local pressure on eastern side
-REAL, DIMENSION(SIZE(PDYY,2),SIZE(PDXX,3)) :: ZPABS_W ! local pressure on western side
+REAL, SAVE , ALLOCATABLE , DIMENSION(:,:) :: ZPABS_S ! local pressure on southern side
+REAL, SAVE , ALLOCATABLE , DIMENSION(:,:) :: ZPABS_N ! local pressure on northern side
+REAL, SAVE , ALLOCATABLE , DIMENSION(:,:) :: ZPABS_E ! local pressure on eastern side
+REAL, SAVE , ALLOCATABLE , DIMENSION(:,:) :: ZPABS_W ! local pressure on western side
 INTEGER :: IINFO_ll,KINFO
 TYPE(LIST_ll), POINTER :: TZFIELDS_ll, TZFIELDS2_ll  ! list of fields to exchange
 !
@@ -411,6 +413,8 @@ INTEGER :: IZMYM_PRHODJ
 LOGICAL :: GWEST,GEAST,GSOUTH,GNORTH
 LOGICAL :: GSOUTH2D,GNORTH2D,GPRVREF0
 !
+LOGICAL, SAVE :: GFIRST_CALL_PRESSUREZ = .TRUE.
+!
 !------------------------------------------------------------------------------
 !-------------------------------------------------------------------------------
 !
@@ -442,12 +446,20 @@ GNORTH2D = ( L2D .AND. LNORTH_ll() )
 !
 GPRVREF0 =  ( SIZE(PRVREF,1) == 0 )
 !
+IZDV_SOURCE = MNH_ALLOCATE_ZT3D(ZDV_SOURCE ,IIU,IJU,IKU  )
+IZTHETAV    = MNH_ALLOCATE_ZT3D(ZTHETAV ,IIU,IJU,IKU  )
+IZPHIT      = MNH_ALLOCATE_ZT3D(ZPHIT ,IIU,IJU,IKU  )
+!
 IZPRHODJ     = MNH_ALLOCATE_ZT3D( ZPRHODJ,IIU,IJU,IKU  )
 IZMXM_PRHODJ = MNH_ALLOCATE_ZT3D( ZMXM_PRHODJ,IIU,IJU,IKU  )
 IZMZM_PRHODJ = MNH_ALLOCATE_ZT3D( ZMZM_PRHODJ,IIU,IJU,IKU  )
 IZGZ_M_W     = MNH_ALLOCATE_ZT3D( ZGZ_M_W,IIU,IJU,IKU  )
 IZMYM_PRHODJ = MNH_ALLOCATE_ZT3D( ZMYM_PRHODJ,IIU,IJU,IKU  )
 !
+IF (GFIRST_CALL_PRESSUREZ) THEN
+   GFIRST_CALL_PRESSUREZ = .FALSE.
+   ALLOCATE ( ZPABS_S(IIU,IKU),ZPABS_N(IIU,IKU),ZPABS_E(IJU,IKU),ZPABS_W(IJU,IKU))
+END IF
 !$acc kernels
 ZPABS_S(:,:) = 0.
 ZPABS_N(:,:) = 0.
@@ -532,6 +544,7 @@ IF(CEQNSYS=='MAE' .OR. CEQNSYS=='DUR') THEN
   !   compute the ratio : 1 + total water mass / dry air mass
     ZRV_OV_RD = XRV / XRD
     ZTHETAV(:,:,:) = 1. + PRT(:,:,:,1)
+    !$acc loop seq
     DO JWATER = 2 , 1+KRRL+KRRI
       ZTHETAV(:,:,:) = ZTHETAV(:,:,:) + PRT(:,:,:,JWATER)
     END DO
@@ -548,7 +561,9 @@ IF(CEQNSYS=='MAE' .OR. CEQNSYS=='DUR') THEN
   ZPHIT(:,:,:)=(PPABST(:,:,:)/XP00)**(XRD/XCPD)-PEXNREF(:,:,:)
 #else
   !$acc kernels
-  ZPHIT(:,:,:)=BR_POW((PPABST(:,:,:)/XP00),(XRD/XCPD))-PEXNREF(:,:,:)
+  DO CONCURRENT ( JI=1:IIU,JJ=1:IJU,JK=1:IKU )
+     ZPHIT(JI,JJ,JK)=BR_POW((PPABST(JI,JJ,JK)/XP00),(XRD/XCPD))-PEXNREF(JI,JJ,JK)
+  END DO
   !$acc end kernels
 #endif  
   !
@@ -654,32 +669,33 @@ CALL GX_M_U_DEVICE(1,IKU,1,ZPHIT,PDXX,PDZZ,PDZX,ZDV_SOURCE)
 IF ( GWEST ) THEN
 !!!!!!!!!!!!!!!!  FUJI  compiler directive !!!!!!!!!!
 !!!!!!!!!!!!!!!!  FUJI  compiler directive !!!!!!!!!!
-   !$acc kernels
-    DO JK=2,IKU-1
-      ZDV_SOURCE(IIB,:,JK)=                                                    &
-       (ZPHIT(IIB,:,JK) - ZPHIT(IIB-1,:,JK) - 0.5 * (                              &
-        PDZX(IIB,:,JK)   * (ZPHIT(IIB,:,JK)-ZPHIT(IIB,:,JK-1)) / PDZZ(IIB,:,JK)      &
-       +PDZX(IIB,:,JK+1) * (ZPHIT(IIB,:,JK+1)-ZPHIT(IIB,:,JK)) / PDZZ(IIB,:,JK+1)    &
+   !$acc kernels loop independent collapse(2) async
+   DO CONCURRENT (JJ=1:IJU , JK=2:IKU-1)
+      ZDV_SOURCE(IIB,JJ,JK)=                                                    &
+       (ZPHIT(IIB,JJ,JK) - ZPHIT(IIB-1,JJ,JK) - 0.5 * (                              &
+        PDZX(IIB,JJ,JK)   * (ZPHIT(IIB,JJ,JK)-ZPHIT(IIB,JJ,JK-1)) / PDZZ(IIB,JJ,JK)      &
+       +PDZX(IIB,JJ,JK+1) * (ZPHIT(IIB,JJ,JK+1)-ZPHIT(IIB,JJ,JK)) / PDZZ(IIB,JJ,JK+1)    &
                                               )                              &
-       ) / PDXX(IIB,:,JK)
+       ) / PDXX(IIB,JJ,JK)
    END DO
    !$acc end kernels
 ENDIF
   !
 IF( GEAST ) THEN
-   !$acc kernels
-    DO JK=2,IKU-1
-      ZDV_SOURCE(IIE+1,:,JK)=                                                   &
-        (ZPHIT(IIE+1,:,JK) - ZPHIT(IIE+1-1,:,JK) - 0.5 * (                        &
-         PDZX(IIE+1,:,JK)   * (ZPHIT(IIE+1-1,:,JK)-ZPHIT(IIE+1-1,:,JK-1))           &
-                          / PDZZ(IIE+1-1,:,JK)                                  &
-        +PDZX(IIE+1,:,JK+1) * (ZPHIT(IIE+1-1,:,JK+1)-ZPHIT(IIE+1-1,:,JK))           &
-                          / PDZZ(IIE+1-1,:,JK+1)                                &
+   !$acc kernels loop independent collapse(2) async
+   DO CONCURRENT (JJ=1:IJU , JK=2:IKU-1)
+      ZDV_SOURCE(IIE+1,JJ,JK)=                                                   &
+        (ZPHIT(IIE+1,JJ,JK) - ZPHIT(IIE+1-1,JJ,JK) - 0.5 * (                        &
+         PDZX(IIE+1,JJ,JK)   * (ZPHIT(IIE+1-1,JJ,JK)-ZPHIT(IIE+1-1,JJ,JK-1))           &
+                          / PDZZ(IIE+1-1,JJ,JK)                                  &
+        +PDZX(IIE+1,JJ,JK+1) * (ZPHIT(IIE+1-1,JJ,JK+1)-ZPHIT(IIE+1-1,JJ,JK))           &
+                          / PDZZ(IIE+1-1,JJ,JK+1)                                &
                                                      )                        &
-        ) / PDXX(IIE+1,:,JK)
+        ) / PDXX(IIE+1,JJ,JK)
    END DO
    !$acc end kernels
 END IF
+!$acc wait
 !
 CALL MPPDB_CHECK3DM("before MXM PRESSUREZ :PRU/V/WS",PRECISION,PRUS,PRVS,PRWS)
 IF(CEQNSYS=='MAE' .OR. CEQNSYS=='DUR') THEN  
@@ -711,31 +727,31 @@ IF(.NOT. L2D) THEN
    IF ( GSOUTH ) THEN
 !!!!!!!!!!!!!!!!  FUJI  compiler directive !!!!!!!!!!
 !!!!!!!!!!!!!!!!  FUJI  compiler directive !!!!!!!!!!
-      !$acc kernels async
-      DO JK=2,IKU-1
-        ZDV_SOURCE(:,IJB,JK)=                                                  &
-         (ZPHIT(:,IJB,JK) - ZPHIT(:,IJB-1,JK) - 0.5 * (                            &
-          PDZY(:,IJB,JK)   * (ZPHIT(:,IJB,JK)-ZPHIT(:,IJB,JK-1)) / PDZZ(:,IJB,JK)    &
-         +PDZY(:,IJB,JK+1) * (ZPHIT(:,IJB,JK+1)-ZPHIT(:,IJB,JK)) / PDZZ(:,IJB,JK+1)  &
-                                                )                            &
-         ) / PDYY(:,IJB,JK)
-     END DO
-     !$acc end kernels
-    END IF
-    !
-    IF ( GNORTH ) THEN
-      !$acc kernels async
-      DO JK=2,IKU-1
-        ZDV_SOURCE(:,IJE+1,JK)=                                                &
-         (ZPHIT(:,IJE+1,JK) - ZPHIT(:,IJE+1-1,JK) - 0.5 * (                      &
-          PDZY(:,IJE+1,JK)   * (ZPHIT(:,IJE+1-1,JK)-ZPHIT(:,IJE+1-1,JK-1))         &
-                           / PDZZ(:,IJE+1-1,JK)                                &
-         +PDZY(:,IJE+1,JK+1) * (ZPHIT(:,IJE+1-1,JK+1)-ZPHIT(:,IJE+1-1,JK))         &
-                           / PDZZ(:,IJE+1-1,JK+1)                              &
-                                                      )                      &
-        ) / PDYY(:,IJE+1,JK)
-     END DO
-     !$acc end kernels
+      !$acc kernels loop independent collapse(2) async
+      DO CONCURRENT (JI=1:IIU , JK=2:IKU-1)
+         ZDV_SOURCE(JI,IJB,JK)=                                                  &
+              (ZPHIT(JI,IJB,JK) - ZPHIT(JI,IJB-1,JK) - 0.5 * (                            &
+              PDZY(JI,IJB,JK)   * (ZPHIT(JI,IJB,JK)-ZPHIT(JI,IJB,JK-1)) / PDZZ(JI,IJB,JK)    &
+              +PDZY(JI,IJB,JK+1) * (ZPHIT(JI,IJB,JK+1)-ZPHIT(JI,IJB,JK)) / PDZZ(JI,IJB,JK+1)  &
+              )                            &
+              ) / PDYY(JI,IJB,JK)
+      END DO
+      !$acc end kernels
+   END IF
+   !
+   IF ( GNORTH ) THEN
+      !$acc kernels loop independent collapse(2) async
+      DO CONCURRENT (JI=1:IIU , JK=2:IKU-1) 
+         ZDV_SOURCE(JI,IJE+1,JK)=                                                &
+              (ZPHIT(JI,IJE+1,JK) - ZPHIT(JI,IJE+1-1,JK) - 0.5 * (                      &
+              PDZY(JI,IJE+1,JK)   * (ZPHIT(JI,IJE+1-1,JK)-ZPHIT(JI,IJE+1-1,JK-1))         &
+              / PDZZ(JI,IJE+1-1,JK)                                &
+              +PDZY(JI,IJE+1,JK+1) * (ZPHIT(JI,IJE+1-1,JK+1)-ZPHIT(JI,IJE+1-1,JK))         &
+              / PDZZ(JI,IJE+1-1,JK+1)                              &
+              )                      &
+              ) / PDYY(JI,IJE+1,JK)
+      END DO
+      !$acc end kernels
   END IF
 !$acc wait  
 !
@@ -922,6 +938,7 @@ END IF
 !
 #ifdef MNH_OPENACC
 CALL MNH_REL_ZT3D ( IZPRHODJ,IZMXM_PRHODJ,IZMZM_PRHODJ,IZGZ_M_W,IZMYM_PRHODJ )
+CALL MNH_REL_ZT3D ( IZDV_SOURCE,IZTHETAV,IZPHIT)
 #endif
 !-------------------------------------------------------------------------------
 !
diff --git a/src/ZSOLVER/tensorproductmultigrid_Source/communication.f90 b/src/ZSOLVER/tensorproductmultigrid_Source/communication.f90
index 794ac3a6f7c58f7c1bfdfb1baf02ed5b37386273..d95cde8d430bd5d5e0b35646118f3fd73e3cf1e3 100644
--- a/src/ZSOLVER/tensorproductmultigrid_Source/communication.f90
+++ b/src/ZSOLVER/tensorproductmultigrid_Source/communication.f90
@@ -547,12 +547,14 @@ contains
         end if
         if (LUseT) then
            local_sumt = 0.0_rl
+           za_st => a%st
+           zb_st => b%st
            !$acc kernels loop collapse(3)
            do iz=0,nz+1
               do iy=a%icompy_min,a%icompy_max
                  do ix=a%icompx_min,a%icompx_max
                     local_sumt = local_sumt &
-                         + a%st(ix,iy,iz)*b%st(ix,iy,iz)
+                         + za_st(ix,iy,iz)*zb_st(ix,iy,iz)
                  end do
               end do
            end do
@@ -1056,6 +1058,10 @@ contains
     real , pointer , contiguous , dimension(:,:,:) :: ztab_halo_nt_haloTout,ztab_halo_st_haloTout
     real , pointer , contiguous , dimension(:,:,:) :: ztab_halo_wt_haloTout,ztab_halo_et_haloTout
 
+    INTEGER,PARAMETER :: IS_WEST=1 , IS_EAST=2, IS_SOUTH=3, IS_NORTH=4
+
+    LOGICAL :: Gneighbour_s,Gneighbour_n,Gneighbour_e,Gneighbour_w
+
     halo_size = comm_param%halo_size
 
     ! Do nothing if we are only using one processor
@@ -1092,35 +1098,48 @@ contains
         !
         zst => a%st
         !
+        Gneighbour_s = (neighbour_s_rank >= 0)
+        Gneighbour_n = (neighbour_n_rank >= 0)
+        Gneighbour_e = (neighbour_e_rank >= 0)
+        Gneighbour_w = (neighbour_w_rank >= 0)        
+        !
 #ifdef MNH_GPUDIRECT
         if (LUseT) then
            !
            ! Copy send buffer async to GPU
            !
            ! Send to south
+           if (Gneighbour_s) then
            ztab_halo_st_haloTin => tab_halo_st(level,m)%haloTin
-           !$acc parallel loop collapse(3) async(1)
+           !$acc parallel loop collapse(3) async(IS_SOUTH)
            do concurrent ( ii=1:a_n,ij=1:halo_size,ik=1:nz+2 )
               ztab_halo_st_haloTin(ii,ij,ik) = zst(ii,ij+a_n-halo_size,ik-1)
            end do
+           end if
            ! Send to north
+           if (Gneighbour_n) then
            ztab_halo_nt_haloTin => tab_halo_nt(level,m)%haloTin
-           !$acc parallel loop collapse(3) async(1)
+           !$acc parallel loop collapse(3) async(IS_NORTH) 
            do concurrent ( ii=1:a_n,ij=1:halo_size,ik=1:nz+2 )           
               ztab_halo_nt_haloTin(ii,ij,ik) = zst(ii,ij,ik-1)
            end do
+           end if
            ! Send to east
+           if (Gneighbour_e) then
            ztab_halo_et_haloTin => tab_halo_et(level,m)%haloTin
-           !$acc parallel loop collapse(3) async(1)
+           !$acc parallel loop collapse(3) async(IS_EAST)
            do concurrent ( ii=1:halo_size,ij=1:a_n+2*halo_size,ik=1:nz+2 ) 
               ztab_halo_et_haloTin(ii,ij,ik) = zst(ii+a_n-halo_size,ij-halo_size,ik-1)
            end do
+           end if
            ! Send to west
+           if (Gneighbour_w) then
            ztab_halo_wt_haloTin => tab_halo_wt(level,m)%haloTin
-           !$acc parallel loop collapse(3) async(1)
+           !$acc parallel loop collapse(3) async(IS_WEST)
            do concurrent ( ii=1:halo_size,ij=1:a_n+2*halo_size,ik=1:nz+2 ) 
               ztab_halo_wt_haloTin(ii,ij,ik) = zst(ii,ij-halo_size,ik-1)
-           end do           
+           end do
+           end if
         end if
 #endif
         ! Receive from north
@@ -1131,12 +1150,15 @@ contains
         recvtag = 1012
         if (LUseT) then
 #ifdef MNH_GPUDIRECT
+           if (Gneighbour_n) then
            ztab_halo_nt_haloTout => tab_halo_nt(level,m)%haloTout
            !$acc host_data use_device(ztab_halo_nt_haloTout)
            call mpi_irecv(ztab_halo_nt_haloTout,size(ztab_halo_nt_haloTout),      &
                        MPI_DOUBLE_PRECISION,neighbour_n_rank,recvtag,  &
                        MPI_COMM_HORIZ, requests_nsT(1), ierr)
            !$acc end host_data
+           end if
+           !print*,"mpi_irecv(ztab_halo_nt_haloTout,neighbour_n_rank=",neighbour_n_rank
 #else
            call mpi_irecv(a%st(1,0-(halo_size-1),0),1,      &
                        halo_nst(level,m),neighbour_n_rank,recvtag,  &
@@ -1151,12 +1173,15 @@ contains
         recvtag = 1013
         if (LUseT) then
 #ifdef MNH_GPUDIRECT
+           if (Gneighbour_s) then
            ztab_halo_st_haloTout => tab_halo_st(level,m)%haloTout
            !$acc host_data use_device (ztab_halo_st_haloTout)
            call mpi_irecv(ztab_halo_st_haloTout,size(ztab_halo_st_haloTout),  &
                        MPI_DOUBLE_PRECISION,neighbour_s_rank,recvtag,  &
                        MPI_COMM_HORIZ, requests_nsT(2), ierr)
            !$acc end host_data
+           end if
+           !print*,"mpi_irecv(ztab_halo_st_haloTout,neighbour_s_rank=",neighbour_s_rank
 #else
            call mpi_irecv(a%st(1,a_n+1,0),1,                &
                        halo_nst(level,m),neighbour_s_rank,recvtag,  &
@@ -1166,7 +1191,7 @@ contains
 #ifdef MNH_GPUDIRECT
         if (LUseT) then
            ! wait for async copy of send buffer to GPU
-           !$acc wait(1)
+           call acc_wait_haloswap_mnh()           
         end if
 #endif        
         ! Send to south
@@ -1177,11 +1202,14 @@ contains
         sendtag = 1012
         if (LUseT) then
 #ifdef MNH_GPUDIRECT
+           if (Gneighbour_s) then
            !$acc host_data use_device(ztab_halo_st_haloTin)
            call mpi_isend(ztab_halo_st_haloTin,size(ztab_halo_st_haloTin),    &
                        MPI_DOUBLE_PRECISION,neighbour_s_rank,sendtag,  &
                        MPI_COMM_HORIZ, requests_nsT(3), ierr)
            !$acc end host_data
+           end if
+           !print*,"mpi_isend(ztab_halo_st_haloTin,neighbour_s_rank=",neighbour_s_rank
 #else   
            call mpi_isend(a%st(1,a_n-(halo_size-1),0),1,    &
                        halo_nst(level,m),neighbour_s_rank,sendtag,  &
@@ -1196,11 +1224,14 @@ contains
         sendtag = 1013
         if (LUseT) then
 #ifdef MNH_GPUDIRECT
+           if (Gneighbour_n) then
            !$acc host_data use_device(ztab_halo_nt_haloTin)
            call mpi_isend(ztab_halo_nt_haloTin,size(ztab_halo_nt_haloTin),   &
                        MPI_DOUBLE_PRECISION,neighbour_n_rank,sendtag,  &
                        MPI_COMM_HORIZ, requests_nsT(4), ierr)
            !$acc end host_data
+           end if
+           !print*,"mpi_isend(ztab_halo_nt_haloTin,neighbour_n_rank=",neighbour_n_rank
 #else
            call mpi_isend(a%st(1,1,0),1,                    &
                        halo_nst(level,m),neighbour_n_rank,sendtag,  &
@@ -1220,12 +1251,15 @@ contains
         recvtag = 1010
         if (LUseT) then
 #ifdef MNH_GPUDIRECT
+           if (Gneighbour_w) then
            ztab_halo_wt_haloTout => tab_halo_wt(level,m)%haloTout
            !$acc host_data use_device(ztab_halo_wt_haloTout)
            call mpi_irecv(ztab_halo_wt_haloTout,size(ztab_halo_wt_haloTout),  &
                        MPI_DOUBLE_PRECISION,neighbour_w_rank,recvtag, &
                        MPI_COMM_HORIZ, requests_ewT(1), ierr)
            !$acc end host_data
+           end if
+           !print*,"mpi_irecv(ztab_halo_wt_haloTout,neighbour_w_rank=",neighbour_w_rank
 #else
            call mpi_irecv(a%st(0-(halo_size-1),0,0),1,  &
                        halo_wet(level,m),neighbour_w_rank,recvtag, &
@@ -1240,12 +1274,15 @@ contains
         sendtag = 1011
         if (LUseT) then
 #ifdef MNH_GPUDIRECT
+           if (Gneighbour_e) then
            ztab_halo_et_haloTout => tab_halo_et(level,m)%haloTout
            !$acc host_data use_device(ztab_halo_et_haloTout)
            call mpi_irecv(ztab_halo_et_haloTout,size(ztab_halo_et_haloTout),  &
                        MPI_DOUBLE_PRECISION,neighbour_e_rank,recvtag, &
                        MPI_COMM_HORIZ, requests_ewT(2), ierr)
            !$acc end host_data
+           end if
+           !print*,"mpi_irecv(ztab_halo_et_haloTout,neighbour_e_rank=",neighbour_e_rank
 #else
            call mpi_irecv(a%st(a_n+1,0,0),1,          &
                        halo_wet(level,m),neighbour_e_rank,recvtag, &
@@ -1261,11 +1298,14 @@ contains
         sendtag = 1010
         if (LUseT) then
 #ifdef MNH_GPUDIRECT
+           if (Gneighbour_e) then
            !$acc host_data use_device(ztab_halo_et_haloTin)
            call mpi_isend(ztab_halo_et_haloTin,size(ztab_halo_et_haloTin),  &
                        MPI_DOUBLE_PRECISION,neighbour_e_rank,sendtag, &
                        MPI_COMM_HORIZ, requests_ewT(3), ierr)
            !$acc end host_data
+           end if
+           !print*,"mpi_isend(ztab_halo_et_haloTin,neighbour_e_rank=",neighbour_e_rank
 #else
            call mpi_isend(a%st(a_n-(halo_size-1),0,0),1,  &
                        halo_wet(level,m),neighbour_e_rank,sendtag, &
@@ -1280,11 +1320,14 @@ contains
         recvtag = 1011
         if (LUseT) then
 #ifdef MNH_GPUDIRECT
+           if (Gneighbour_w) then
            !$acc host_data use_device(ztab_halo_wt_haloTin)
            call mpi_isend(ztab_halo_wt_haloTin,size(ztab_halo_wt_haloTin),  &
                        MPI_DOUBLE_PRECISION,neighbour_w_rank,sendtag,   &
                        MPI_COMM_HORIZ, requests_ewT(4), ierr)
            !$acc end host_data
+           end if
+           !print*,"mpi_isend(ztab_halo_wt_haloTin,neighbour_w_rank=",neighbour_w_rank
 #else
            call mpi_isend(a%st(1,0,0),1,                &
                        halo_wet(level,m),neighbour_w_rank,sendtag,   &
@@ -1301,27 +1344,36 @@ contains
         if (LUseT) call mpi_waitall(4,requests_ewT, MPI_STATUSES_IGNORE, ierr)
 #ifdef MNH_GPUDIRECT
         if (LUseT) then
+           if (Gneighbour_n) then
            ! copy north halo for GPU managed
-           !$acc parallel loop collapse(3) async(3)
+           !$acc parallel loop collapse(3) async(IS_NORTH)
            do concurrent ( ii=1:a_n,ij=1:halo_size,ik=1:nz+2 )
               zst(ii,ij-halo_size,ik-1) = ztab_halo_nt_haloTout(ii,ij,ik)
            end do
+           end if
+           if (Gneighbour_s) then
            ! copy south halo for GPU managed
-           !$acc parallel loop collapse(3) async(3)
+           !$acc parallel loop collapse(3) async(IS_SOUTH)
            do concurrent ( ii=1:a_n,ij=1:halo_size,ik=1:nz+2 )
               zst(ii,ij+a_n,ik-1) = ztab_halo_st_haloTout(ii,ij,ik)
            end do          
+           end if
+           if (Gneighbour_w) then
            ! copy west halo for GPU managed
-           !$acc parallel loop collapse(3) async(3)
+           !$acc parallel loop collapse(3) async(IS_WEST)
            do concurrent ( ii=1:halo_size,ij=1:a_n+2*halo_size,ik=1:nz+2 )
               zst(ii-halo_size,ij-halo_size,ik-1) = ztab_halo_wt_haloTout(ii,ij,ik)
            end do
+           end if
+           if (Gneighbour_e) then
            ! copy east halo for GPU managed
-           !$acc parallel loop collapse(3) async(3)
+           !$acc parallel loop collapse(3) async(IS_EAST)
            do concurrent ( ii=1:halo_size,ij=1:a_n+2*halo_size,ik=1:nz+2 )
               zst(ii+a_n,ij-halo_size,ik-1) = ztab_halo_et_haloTout(ii,ij,ik)
            end do
-           !$acc wait(3)
+           end if 
+           ! wait for async copy of send buffer to GPU
+           call acc_wait_haloswap_mnh()           
         end if 
 #endif
       end if!  (stepsize == 1) ...
@@ -1330,6 +1382,22 @@ contains
       end if
     end if
 
+  contains
+    subroutine acc_wait_haloswap_mnh()
+      if (Gneighbour_s) then
+         !$acc wait(IS_SOUTH)
+      endif
+      if (Gneighbour_n) then
+         !$acc wait(IS_NORTH)
+      endif
+      if (Gneighbour_e) then
+         !$acc wait(IS_EAST)
+      endif
+      if (Gneighbour_w) then
+         !$acc wait(IS_WEST)
+      endif
+    end subroutine acc_wait_haloswap_mnh
+    
   end subroutine haloswap_mnh
 !==================================================================
   subroutine haloswap(level,m, &  ! multigrid- and processor- level
diff --git a/src/ZSOLVER/tensorproductmultigrid_Source/conjugategradient.f90 b/src/ZSOLVER/tensorproductmultigrid_Source/conjugategradient.f90
index 30277d8625ad6735444ad7335b761ab6ed369b7a..34eacb6b86a7cf47e41a6b14a08ea2685e8c7206 100644
--- a/src/ZSOLVER/tensorproductmultigrid_Source/conjugategradient.f90
+++ b/src/ZSOLVER/tensorproductmultigrid_Source/conjugategradient.f90
@@ -206,10 +206,13 @@ contains
     allocate(Ap%st(1-halo_size:nlocal+halo_size,   &
                    1-halo_size:nlocal+halo_size,   &
                    0:nz+1) )
+    !$acc enter data create (r%st,z%st,p%st,Ap%st)
+    !$acc kernels
     r%st = 0.0_rl
     z%st = 0.0_rl
     p%st = 0.0_rl
     Ap%st = 0.0_rl
+    !$acc end kernels
     endif
 
 
@@ -307,6 +310,7 @@ contains
     end if
 
     if (LUseT) then
+    !$acc exit data delete(r%st,z%st,p%st,Ap%st)
     deallocate(r%st)
     deallocate(z%st)
     deallocate(p%st)
@@ -419,10 +423,13 @@ contains
     allocate(Ap%st(1-halo_size:nlocal+halo_size,  &
                    1-halo_size:nlocal+halo_size,  &
                    0:nz+1) )
+    !$acc enter data create (r%st,z%st,p%st,Ap%st)
+    !$acc kernels
     r%st = 0.0_rl
     z%st = 0.0_rl
     p%st = 0.0_rl
     Ap%st = 0.0_rl
+    !$acc end kernels
     end if
 
     ! Initialise
@@ -518,6 +525,7 @@ contains
     deallocate(Ap%s)
     end if
     if (LUseT) then
+    !$acc exit data delete(r%st,z%st,p%st,Ap%st)
     deallocate(r%st)
     deallocate(z%st)
     deallocate(p%st)
diff --git a/src/ZSOLVER/tensorproductmultigrid_Source/datatypes.f90 b/src/ZSOLVER/tensorproductmultigrid_Source/datatypes.f90
index d0ddee6daae5fa031349db044389cb510c92b144..e4c2a370395eca6f76468299e4b9d01213ab4862 100644
--- a/src/ZSOLVER/tensorproductmultigrid_Source/datatypes.f90
+++ b/src/ZSOLVER/tensorproductmultigrid_Source/datatypes.f90
@@ -195,6 +195,7 @@ private
     allocate(zphi_st(1-halo_size:nlocal+halo_size, &
                     1-halo_size:nlocal+halo_size, &
                     0:grid_param%nz+1))
+    !$acc enter data create (zphi_st)
     phi%st => zphi_st
     !$acc kernels
     zphi_st(:,:,:) = 0.0_rl
@@ -211,7 +212,10 @@ private
     type(scalar3d), intent(inout) :: phi
 
     if (LUseO) deallocate(phi%s)
-    if (LUseT) deallocate(phi%st)
+    if (LUseT) then
+       !$acc exit data delete(phi%st)
+       deallocate(phi%st)
+    end if
 
   end subroutine destroy_scalar3d
 
diff --git a/src/ZSOLVER/tensorproductmultigrid_Source/dblas.f90 b/src/ZSOLVER/tensorproductmultigrid_Source/dblas.f90
index 48d5dcdce4f328566fd6e968cd8ba21311c5dd30..a8363fa2fe153344ab182da8f86ed4a0d587ddfd 100644
--- a/src/ZSOLVER/tensorproductmultigrid_Source/dblas.f90
+++ b/src/ZSOLVER/tensorproductmultigrid_Source/dblas.f90
@@ -10,7 +10,15 @@ subroutine dcopy(n,sx,incx,sy,incy)
       integer i,incx,incy,ix,iy,m,mp1,n
 !
       if(n.le.0)return
-      if(incx.eq.1.and.incy.eq.1)go to 20
+!!$      if(incx.eq.1.and.incy.eq.1)go to 20
+      !
+      ! Juan Simplifaction for incx=1 & incy=1
+      !
+      if(incx.ne.1.or.incy.ne.1) STOP "DCOPY incx.ne.1.or.incy.ne.1 "
+      !$acc kernels
+      sy(1:n) = sx(1:n)
+      !$acc end kernels
+      return
 !
 !        code for unequal increments or equal increments
 !          not equal to 1
@@ -84,7 +92,11 @@ SUBROUTINE DAXPY( N, SA, SX, INCX, SY, INCY )
 	       SY(I) = SY(I) + SA * SX(I)
    10     CONTINUE
 
-	ELSE IF ( INCX.EQ.INCY .AND. INCX.EQ.1 )  THEN
+            ELSE IF ( INCX.EQ.INCY .AND. INCX.EQ.1 )  THEN
+            !$acc kernels   
+            SY(1:N) = SY(1:N) + SA * SX(1:N)
+            !$acc end kernels
+            return
 
 !                                        ** EQUAL, UNIT INCREMENTS
 	   M = MOD(N,4)
diff --git a/src/ZSOLVER/tensorproductmultigrid_Source/discretisation.f90 b/src/ZSOLVER/tensorproductmultigrid_Source/discretisation.f90
index 70d9063b2494dce63cf65cb43ce68cd9a379199b..1bd6d51d85bcd52b6a93103136e06caf8881a182 100644
--- a/src/ZSOLVER/tensorproductmultigrid_Source/discretisation.f90
+++ b/src/ZSOLVER/tensorproductmultigrid_Source/discretisation.f90
@@ -204,6 +204,7 @@ contains
     allocate(vert_coeff%c(grid_param%nz))
     allocate(vert_coeff%d(grid_param%nz))
     call construct_vertical_coeff_mnh(PA_K,PB_K,PC_K,PD_K)
+    !$acc enter data copyin(vert_coeff%a,vert_coeff%b,vert_coeff%c,vert_coeff%d)
   end subroutine discretisation_initialise_mnh
 
   subroutine discretisation_initialise(grid_param_in, &
@@ -817,6 +818,7 @@ end subroutine construct_vertical_coeff
        allocate(r%st(1-halo_size:nlocal+halo_size, &
                      1-halo_size:nlocal+halo_size, &
                      0:nz+1))
+       !$acc enter data create (r%st)
     end if
 
     call calculate_residual(level,m,b,u,r)
@@ -843,7 +845,10 @@ end subroutine construct_vertical_coeff
                             + (log_res_final - log_res_initial)
     nsmooth_total(level) = nsmooth_total(level) + nsmooth
     if (LUseO) deallocate(r%s)
-    if (LUseT) deallocate(r%st)
+    if (LUseT) then
+       !$acc exit data delete(r%st)
+       deallocate(r%st)       
+    end if
 #endif
   end subroutine smooth_mnh
 !==================================================================
@@ -888,6 +893,7 @@ end subroutine construct_vertical_coeff
     allocate(r%st(1-halo_size:nlocal+halo_size,   &
                   1-halo_size:nlocal+halo_size,   &
                   0:nz+1) )
+    !$acc enter data create (r%st)
     endif
     log_res_initial = log(l2norm(r))
 #endif
@@ -912,7 +918,10 @@ end subroutine construct_vertical_coeff
                             + (log_res_final - log_res_initial)
     nsmooth_total(level) = nsmooth_total(level) + nsmooth
     if (LUseO) deallocate(r%s)
-    if (LUseT) deallocate(r%st)
+    if (LUseT) then
+       !$acc exit data delete(r%st)
+       deallocate(r%st)
+    end if
 #endif
   end subroutine smooth
 !==================================================================
@@ -1882,8 +1891,8 @@ end subroutine line_Jacobi_mnh
 
     !local 
     !real(kind=rl), dimension(5) :: alpha_T
-    real(kind=rl) :: Tij
-    real(kind=rl) :: alpha_div_Tij ! b_k_tmp, c_k_tmp
+    real(kind=rl) ,pointer :: Tij
+    real(kind=rl) ,pointer :: alpha_div_Tij ! b_k_tmp, c_k_tmp
     integer :: iz, nz
 
     real, dimension(:,:,:) , pointer, contiguous :: zSr_st , zb_st , zSu_in_st , zSu_out_st
@@ -1898,20 +1907,17 @@ end subroutine line_Jacobi_mnh
     
     type Temp_tridiag_mnh
        real, dimension(:), pointer, contiguous :: tmp_k,c_k
+       real, pointer  :: Tij , alpha_div_Tij
     end type Temp_tridiag_mnh
 
     type(Temp_tridiag_mnh) , save , dimension(max_lev) :: Ttridiag_mnh
 
     if (LUseT ) then
+
+      ! Calculate r_i = b_i - A_{ij} u_i
        
-       nz = b%grid_param%nz
-       
-       !call construct_alpha_T_cst_mnh(b%grid_param,alpha_T,Tij)
-       Tij = ( b%grid_param%L/b%grid_param%n ) ** 2
-       alpha_div_Tij = 4.0_rl / Tij
-       !print*,"level=",level," Tij=",Tij," alpha_div_Tij=",alpha_div_Tij
-       ! Calculate r_i = b_i - A_{ij} u_i
-    
+      nz = b%grid_param%nz
+           
       zSr_st => Sr%st
       zb_st  => b%st
       zSu_in_st => Su_in%st
@@ -1923,6 +1929,18 @@ end subroutine line_Jacobi_mnh
 
       if ( Lfirst_call_level_tridiag_mnhallT(level) ) then
          Lfirst_call_level_tridiag_mnhallT(level) = .false.
+
+         allocate(Ttridiag_mnh(level)%Tij)
+         allocate(Ttridiag_mnh(level)%alpha_div_Tij)
+
+         Tij=>Ttridiag_mnh(level)%Tij
+         alpha_div_Tij=>Ttridiag_mnh(level)%alpha_div_Tij
+         !call construct_alpha_T_cst_mnh(b%grid_param,alpha_T,Tij)
+         Tij = ( b%grid_param%L/b%grid_param%n ) ** 2
+         alpha_div_Tij = 4.0_rl / Tij
+         !$acc enter data copyin(Tij,alpha_div_Tij)
+         !print*,"level=",level," Tij=",Tij," alpha_div_Tij=",alpha_div_Tij
+
          allocate(Ttridiag_mnh(level)%tmp_k(size(zb_k)))
          allocate(Ttridiag_mnh(level)%c_k(size(zb_k)))
          
@@ -1948,6 +1966,9 @@ end subroutine line_Jacobi_mnh
          !$acc enter data copyin(tmp_k,c_k)
          
       endif
+
+      Tij=>Ttridiag_mnh(level)%Tij
+      alpha_div_Tij=>Ttridiag_mnh(level)%alpha_div_Tij
       
       tmp_k => Ttridiag_mnh(level)%tmp_k
       c_k => Ttridiag_mnh(level)%c_k
diff --git a/src/ZSOLVER/tensorproductmultigrid_Source/multigrid.f90 b/src/ZSOLVER/tensorproductmultigrid_Source/multigrid.f90
index bb1a7d3f7ea79fe25eba3090a39a93cf9d9415b9..b43fa68dd42e6783c41cae69e3396b0f145fdbb7 100644
--- a/src/ZSOLVER/tensorproductmultigrid_Source/multigrid.f90
+++ b/src/ZSOLVER/tensorproductmultigrid_Source/multigrid.f90
@@ -275,18 +275,20 @@ contains
          allocate(zxu_mg_st(1-halo_size:nlocal+halo_size, &
               1-halo_size:nlocal+halo_size, &
               0:nz+1))
+         !$acc enter data create (zxu_mg_st)
          xu_mg(level,m)%st => zxu_mg_st
          
          allocate(zxb_mg_st(1-halo_size:nlocal+halo_size, &
               1-halo_size:nlocal+halo_size, &
               0:nz+1))
+         !$acc enter data create (zxb_mg_st)
          xb_mg(level,m)%st => zxb_mg_st
          
          allocate(zxr_mg_st(1-halo_size:nlocal+halo_size, &
               1-halo_size:nlocal+halo_size, &
               0:nz+1))
-          xr_mg(level,m)%st => zxr_mg_st
-
+         !$acc enter data create (zxr_mg_st)
+         xr_mg(level,m)%st => zxr_mg_st
       
       !$acc kernels
       zxu_mg_st(:,:,:) = 0.0_rl
@@ -429,9 +431,14 @@ contains
       endif
 
       if (LUseT) then
-      deallocate(xu_mg(level,m)%st)
-      deallocate(xb_mg(level,m)%st)
-      deallocate(xr_mg(level,m)%st)
+         !$acc exit data delete(xu_mg(level,m)%st)  
+         deallocate(xu_mg(level,m)%st)
+         !
+         !$acc exit data delete(xb_mg(level,m)%st)
+         deallocate(xb_mg(level,m)%st)
+         !
+         !$acc exit data delete(xr_mg(level,m)%st)
+         deallocate(xr_mg(level,m)%st)
       endif
 
       ! If we are below L_split, split data
@@ -466,7 +473,7 @@ contains
     type(scalar3d), intent(inout) :: phicoarse
     ! local var
     integer :: ix,iy,iz
-    integer :: ix_min, ix_max, iy_min, iy_max, n
+    integer :: ix_min, ix_max, iy_min, iy_max, n ,nz
     real(kind=rl) :: xn,xs,xw,xe
 
     real , dimension(:,:,:) , pointer , contiguous :: zphifine_st , zphicoarse_st
@@ -476,13 +483,14 @@ contains
     ix_max = phicoarse%icompx_max
     iy_min = phicoarse%icompy_min
     iy_max = phicoarse%icompy_max
+    nz     = phicoarse%grid_param%nz
     ! three dimensional cell average
     if (mg_param%restriction == REST_CELLAVERAGE) then
       ! Do not coarsen in z-direction
       if (LUseO) then 
       do ix=ix_min,ix_max
         do iy=iy_min,iy_max
-          do iz=1,phicoarse%grid_param%nz
+          do iz=1,nz
             phicoarse%s(iz,iy,ix) =  &
               phifine%s(iz  ,2*iy  ,2*ix  ) + &
               phifine%s(iz  ,2*iy-1,2*ix  ) + &
@@ -496,7 +504,7 @@ contains
          zphifine_st => phifine%st
          zphicoarse_st => phicoarse%st
          !$acc kernels loop independent  collapse(3)
-         do iz=1,phicoarse%grid_param%nz
+         do iz=1,nz
             do iy=iy_min,iy_max
                do ix=ix_min,ix_max
                   zphicoarse_st(ix,iy,iz) =  &
@@ -522,7 +530,7 @@ contains
                xn=1.0
                if (iy==1) xs=0.0
                if (iy==n) xn=0.0
-               do iz=1,phicoarse%grid_param%nz
+               do iz=1,nz
                   phicoarse%s(iz,iy,ix) = 0.25_rl *         ( &
                        phifine%s(iz,2*iy+1,2*ix-1) * xn        + &
                        phifine%s(iz,2*iy+1,2*ix  ) * xn        + &
@@ -541,7 +549,7 @@ contains
          end do
       end if
       if (LUseT) then 
-         do iz=1,phicoarse%grid_param%nz
+         do iz=1,nz
             do iy=iy_min,iy_max
                xs=1.0
                xn=1.0
@@ -580,19 +588,21 @@ contains
     type(scalar3d), intent(in)    :: phifine
     type(scalar3d), intent(inout) :: phicoarse
     integer :: ix,iy,iz
-    integer :: ix_min, ix_max, iy_min, iy_max
+    integer :: ix_min, ix_max, iy_min, iy_max , nz
 
     ix_min = phicoarse%icompx_min
     ix_max = phicoarse%icompx_max
     iy_min = phicoarse%icompy_min
     iy_max = phicoarse%icompy_max
+    nz     = phicoarse%grid_param%nz
+    
     ! three dimensional cell average
     if (mg_param%restriction == REST_CELLAVERAGE) then
       ! Do not coarsen in z-direction
       if (LUseO) then
          do ix=ix_min,ix_max
             do iy=iy_min,iy_max
-               do iz=1,phicoarse%grid_param%nz
+               do iz=1,nz
                   phicoarse%s(iz,iy,ix) =  &
                        phifine%s(iz  ,2*iy  ,2*ix  ) + &
                        phifine%s(iz  ,2*iy-1,2*ix  ) + &
@@ -603,7 +613,7 @@ contains
          end do
       end if
       if (LUseT) then 
-         do iz=1,phicoarse%grid_param%nz
+         do iz=1,nz
             do iy=iy_min,iy_max
                do ix=ix_min,ix_max
                   phicoarse%st(ix,iy,iz) =  &
@@ -748,14 +758,16 @@ contains
     subroutine loop_over_grid_constant_mnh(iblock)
       implicit none
       integer, intent(in) :: iblock
-      integer :: ix,iy,iz
+      integer :: ix,iy,iz, nz
+
+      nz = phicoarse%grid_param%nz
       
       if (LUseO) then
          do ix=ixmin(iblock),ixmax(iblock)
             do iy=iymin(iblock),iymax(iblock)
                do dix = -1,0
                   do diy = -1,0
-                     do iz=1,phicoarse%grid_param%nz
+                     do iz=1,nz
                         phifine%s(iz,2*iy+diy,2*ix+dix) = phicoarse%s(iz,iy,ix)
                      end do
                   end do
@@ -768,7 +780,7 @@ contains
             do iy=iymin(iblock),iymax(iblock)
                do dix = -1,0
                   do diy = -1,0
-                     do iz=1,phicoarse%grid_param%nz
+                     do iz=1,nz
                         phifine%st(2*ix+dix,2*iy+diy,iz) = phicoarse%st(ix,iy,iz)
                      end do
                   end do
@@ -790,6 +802,10 @@ contains
 
       real , dimension(:,:,:) , pointer , contiguous :: zphifine_st , zphicoarse_st
 
+      integer :: nz
+
+      nz = phicoarse%grid_param%nz
+      
       ! optimisation for newman MNH case : all coef constant
       rhox = 0.25_rl
       rhoy = 0.25_rl
@@ -798,7 +814,7 @@ contains
          do ix=ixmin(iblock),ixmax(iblock)
             do iy=iymin(iblock),iymax(iblock)
                ! Piecewise linear interpolation
-               do iz=1,phicoarse%grid_param%nz
+               do iz=1,nz
                   do dix = -1,0
                      do diy = -1,0
                         phifine%s(iz,2*iy+diy,2*ix+dix) =      &
@@ -820,7 +836,7 @@ contains
          zphicoarse_st => phicoarse%st
 
          !$acc kernels loop independent  collapse(5)
-         do iz=1,phicoarse%grid_param%nz 
+         do iz=1,nz 
             do diy = -1,0
                do dix = -1,0
                   do iy=iymin(iblock),iymax(iblock)
@@ -974,7 +990,7 @@ contains
         do iy=iymin(iblock),iymax(iblock)
           do dix = -1,0
             do diy = -1,0
-              do iz=1,phicoarse%grid_param%nz
+              do iz=1,nz
                 phifine%s(iz,2*iy+diy,2*ix+dix) = phicoarse%s(iz,iy,ix)
               end do
             end do
@@ -994,7 +1010,7 @@ contains
         do iy=iymin(iblock),iymax(iblock)
 #ifdef PIECEWISELINEAR
           ! Piecewise linear interpolation
-          do iz=1,phicoarse%grid_param%nz
+          do iz=1,nz
             do dix = -1,0
               do diy = -1,0
                 if ( (ix+(2*dix+1)+phicoarse%ix_min-1  < 1 ) .or. &
@@ -1098,7 +1114,7 @@ contains
           end do
           ! invert A
           call invertA(A)
-          do iz=1,phicoarse%grid_param%nz
+          do iz=1,nz
             ! Calculate gradient on each level
             dxu(1:2) = dx(1,1:2)*phicoarse%s(iz,iy  ,ix-1) &
                      + dx(2,1:2)*phicoarse%s(iz,iy  ,ix+1) &
@@ -1491,6 +1507,7 @@ contains
     real(kind=rl) :: alpha, beta, pq, rz, rz_old
     integer :: ierr
     real(kind=rl) , pointer , contiguous , dimension(:,:,:) :: z_one_st
+    integer :: icompx_max, icompy_max, nz
 
     solvertype = solver_param%solvertype
     resreduction = solver_param%resreduction
@@ -1517,22 +1534,27 @@ contains
     !
     ! Init 1 vector = z_one
     call create_scalar3d(MPI_COMM_HORIZ,bRHS%grid_param,halo_size,z_one)
+    !
+    icompx_max = z_one%icompx_max
+    icompy_max = z_one%icompy_max
+    nz         = z_one%grid_param%nz
+    !
     if (LUseO) then
        z_one%s(:,:,:) = 0.0_rl
-       z_one%s(1:z_one%grid_param%nz,1:z_one%icompy_max,1:z_one%icompx_max) = 1.0_rl
+       z_one%s(1:nz,1:icompy_max,1:icompx_max) = 1.0_rl
     end if
     if (LUseT) then       
        z_one_st => z_one%st
        !$acc kernels
        z_one_st(:,:,:) = 0.0_rl
-       z_one_st(1:z_one%icompx_max,1:z_one%icompy_max,1:z_one%grid_param%nz) = 1.0_rl
+       z_one_st(1:icompx_max,1:icompy_max,1:nz) = 1.0_rl
        !$acc end kernels
     end if
     !   Mean / Norm of B
     call scalarprod_mnh(pproc,z_one,z_one, mean_initial ) 
     call scalarprod_mnh(pproc,z_one,bRHS, mean_initial ) 
     norm_initial =  l2norm_mnh(bRHS,.true.)
-    mean_initial =  mean_initial / (( z_one%grid_param%nz ) * ( z_one%grid_param%n )**2)
+    mean_initial =  mean_initial / (( nz ) * ( z_one%grid_param%n )**2)
     norm_initial =  mean_initial / norm_initial
     if (LMean) then
        ! b <- b -mean_initial * z_one
@@ -1709,7 +1731,7 @@ contains
     call print_elapsed(t_l2norm,.True.,1.0_rl)
     call print_elapsed(t_scalprod,.True.,1.0_rl)
     call print_elapsed(t_mainloop,.True.,1.0_rl)
-    if (i_am_master_mpi) write(STDOUT,'("")')
+!!$    if (i_am_master_mpi) write(STDOUT,'("")')
   end subroutine mg_solve_mnh
 
   subroutine mg_solve(bRHS,usolution,solver_param)
diff --git a/src/ZSOLVER/tensorproductmultigrid_Source/profiles.f90 b/src/ZSOLVER/tensorproductmultigrid_Source/profiles.f90
index 72338e703e1ab7a938de88d82c72d8b43c2ac763..70e7508d52411b9bd9e9c28b5dd81054d9f7a86f 100644
--- a/src/ZSOLVER/tensorproductmultigrid_Source/profiles.f90
+++ b/src/ZSOLVER/tensorproductmultigrid_Source/profiles.f90
@@ -58,7 +58,7 @@ private
     type(grid_parameters), intent(in) :: grid_param
     type(model_parameters), intent(in) :: model_param
     type(scalar3d), intent(inout) :: u
-    integer :: ix, iy, iz, ix_min, ix_max, iy_min, iy_max
+    integer :: ix, iy, iz, ix_min, ix_max, iy_min, iy_max, nz
     real(kind=rl) :: x, y, z
     real(kind=rl) :: rho, sigma, theta, phi, r, b_low, b_up, pi
 
@@ -71,12 +71,14 @@ private
     ix_max = u%ix_max
     iy_min = u%iy_min
     iy_max = u%iy_max
+    nz     = u%grid_param%nz
+    
     IF (.NOT. PRESENT(KIB) ) THEN
        ! Initialise RHS
         if (LUseO) then
            do ix=ix_min, ix_max
               do iy=iy_min, iy_max
-                 do iz=1,u%grid_param%nz
+                 do iz=1,nz
                     
                     u%s(iz,iy-iy_min+1,ix-ix_min+1) = 0.0_rl
                     
@@ -87,7 +89,7 @@ private
         if (LUseT) then
            zu_st => u%st
            !$acc kernels loop independent collapse(3)
-           do iz=1,u%grid_param%nz
+           do iz=1,nz
               do iy=iy_min, iy_max
                  do ix=ix_min, ix_max
                     
@@ -103,7 +105,7 @@ private
        if (LUseO) then
           do ix=ix_min, ix_max
              do iy=iy_min, iy_max
-                do iz=1,u%grid_param%nz
+                do iz=1,nz
                    u%s(iz,iy-iy_min+1,ix-ix_min+1) = PU(IX-ix_min+KIB,IY-iy_min+KJB,IZ)
                 end do
              end do
@@ -112,7 +114,7 @@ private
        if (LUseT) then
           zu_st => u%st
           !$acc kernels loop independent collapse(3)
-          do iz=1,u%grid_param%nz
+          do iz=1,nz
              do iy=iy_min, iy_max
                 do ix=ix_min, ix_max
                    zu_st(ix-ix_min+1,iy-iy_min+1,iz) = PU(IX-ix_min+KIB,IY-iy_min+KJB,IZ)
@@ -131,7 +133,7 @@ private
     type(grid_parameters), intent(in) :: grid_param
     type(model_parameters), intent(in) :: model_param
     type(scalar3d), intent(inout) :: u
-    integer :: ix, iy, iz, ix_min, ix_max, iy_min, iy_max
+    integer :: ix, iy, iz, ix_min, ix_max, iy_min, iy_max, nz
     real(kind=rl) :: x, y, z
     real(kind=rl) :: rho, sigma, theta, phi, r, b_low, b_up, pi
 
@@ -144,6 +146,8 @@ private
     ix_max = u%ix_max
     iy_min = u%iy_min
     iy_max = u%iy_max
+    nz     = u%grid_param%nz
+    
     IF (.NOT. PRESENT(KIB) ) THEN
     ! 
     ELSE
@@ -151,7 +155,7 @@ private
        if (LUseO) then
           do ix=ix_min, ix_max
              do iy=iy_min, iy_max
-                do iz=1,u%grid_param%nz
+                do iz=1,nz
                    PU(IX-ix_min+KIB,IY-iy_min+KJB,IZ) =  u%s(iz,iy-iy_min+1,ix-ix_min+1)
                 end do
              end do
@@ -159,7 +163,7 @@ private
        else
           zu_st => u%st
           !$acc kernels loop independent collapse(3)
-          do iz=1,u%grid_param%nz
+          do iz=1,nz
              do iy=iy_min, iy_max
                 do ix=ix_min, ix_max
                    PU(IX-ix_min+KIB,IY-iy_min+KJB,IZ) = zu_st(ix-ix_min+1,iy-iy_min+1,iz)
@@ -178,7 +182,7 @@ private
     type(grid_parameters), intent(in) :: grid_param
     type(model_parameters), intent(in) :: model_param
     type(scalar3d), intent(inout) :: b
-    integer :: ix, iy, iz, ix_min, ix_max, iy_min, iy_max
+    integer :: ix, iy, iz, ix_min, ix_max, iy_min, iy_max, nz, n
     real(kind=rl) :: x, y, z
     real(kind=rl) :: rho, sigma, theta, phi, r, b_low, b_up, pi
 
@@ -191,15 +195,18 @@ private
     ix_max = b%ix_max
     iy_min = b%iy_min
     iy_max = b%iy_max
+    nz     = b%grid_param%nz
+    n      = b%grid_param%n
+    !
     IF (.NOT. PRESENT(KIB) ) THEN
     ! Initialise RHS
        if (LUseO) then   
           do ix=ix_min, ix_max
              do iy=iy_min, iy_max
-                do iz=1,b%grid_param%nz
-                   x = 1.0_rl*((ix-0.5_rl)/(1.0_rl*b%grid_param%n))
-                   y = 1.0_rl*((iy-0.5_rl)/(1.0_rl*b%grid_param%n))
-                   z = 1.0_rl*((iz-0.5_rl)/(1.0_rl*b%grid_param%nz))
+                do iz=1,nz
+                   x = 1.0_rl*((ix-0.5_rl)/(1.0_rl*n))
+                   y = 1.0_rl*((iy-0.5_rl)/(1.0_rl*n))
+                   z = 1.0_rl*((iz-0.5_rl)/(1.0_rl*nz))
                    
                    b%s(iz,iy-iy_min+1,ix-ix_min+1) = 0.0_rl
                    
@@ -219,12 +226,12 @@ private
        if (LUseT) then
           zb_st => b%st
           !$acc kernels loop independent collapse(3)
-          do iz=1,b%grid_param%nz
+          do iz=1,nz
              do iy=iy_min, iy_max
                 do ix=ix_min, ix_max
-                   x = 1.0_rl*((ix-0.5_rl)/(1.0_rl*b%grid_param%n))
-                   y = 1.0_rl*((iy-0.5_rl)/(1.0_rl*b%grid_param%n))
-                   z = 1.0_rl*((iz-0.5_rl)/(1.0_rl*b%grid_param%nz))
+                   x = 1.0_rl*((ix-0.5_rl)/(1.0_rl*n))
+                   y = 1.0_rl*((iy-0.5_rl)/(1.0_rl*n))
+                   z = 1.0_rl*((iz-0.5_rl)/(1.0_rl*nz))
                    
                    zb_st(ix-ix_min+1,iy-iy_min+1,iz) = 0.0_rl
                    
@@ -247,7 +254,7 @@ private
        if (LUseO) then    
           do ix=ix_min, ix_max
              do iy=iy_min, iy_max
-                do iz=1,b%grid_param%nz
+                do iz=1,nz
                    b%s(iz,iy-iy_min+1,ix-ix_min+1) = PY(IX-ix_min+KIB,IY-iy_min+KJB,IZ)
                 end do
              end do
@@ -256,7 +263,7 @@ private
        if (LUseT) then
           zb_st => b%st
           !$acc kernels loop independent collapse(3)
-          do iz=1,b%grid_param%nz 
+          do iz=1,nz 
              do iy=iy_min, iy_max
                 do ix=ix_min, ix_max
                    zb_st(ix-ix_min+1,iy-iy_min+1,iz) = PY(IX-ix_min+KIB,IY-iy_min+KJB,IZ)
@@ -275,7 +282,7 @@ private
     type(grid_parameters), intent(in) :: grid_param
     type(model_parameters), intent(in) :: model_param
     type(scalar3d), intent(inout) :: b
-    integer :: ix, iy, iz, ix_min, ix_max, iy_min, iy_max
+    integer :: ix, iy, iz, ix_min, ix_max, iy_min, iy_max, nz, n
     real(kind=rl) :: x, y, z
     real(kind=rl) :: rho, sigma, theta, phi, r, b_low, b_up, pi
 
@@ -287,16 +294,18 @@ private
     ix_max = b%ix_max
     iy_min = b%iy_min
     iy_max = b%iy_max
+    nz     = b%grid_param%nz
+    n      = b%grid_param%n
     b_low = 1.0_rl+0.25*b%grid_param%H
     b_up = 1.0_rl+0.75*b%grid_param%H
     pi = 4.0_rl*atan2(1.0_rl,1.0_rl)
     ! Initialise RHS
     do ix=ix_min, ix_max
       do iy=iy_min, iy_max
-        do iz=1,b%grid_param%nz
-          x = 1.0_rl*((ix-0.5_rl)/(1.0_rl*b%grid_param%n))
-          y = 1.0_rl*((iy-0.5_rl)/(1.0_rl*b%grid_param%n))
-          z = 1.0_rl*((iz-0.5_rl)/(1.0_rl*b%grid_param%nz))
+        do iz=1,nz
+          x = 1.0_rl*((ix-0.5_rl)/(1.0_rl*n))
+          y = 1.0_rl*((iy-0.5_rl)/(1.0_rl*n))
+          z = 1.0_rl*((iz-0.5_rl)/(1.0_rl*nz))
 #ifdef TESTCONVERGENCE
           ! RHS for analytical solution x*(1-x)*y*(1-y)*z*(1-z)
           if (grid_param%vertbc == VERTBC_DIRICHLET) then
@@ -359,21 +368,23 @@ private
     implicit none
     type(grid_parameters), intent(in) :: grid_param
     type(scalar3d), intent(inout) :: u
-    integer :: ix, iy, iz, ix_min, ix_max, iy_min, iy_max
+    integer :: ix, iy, iz, ix_min, ix_max, iy_min, iy_max, nz, n
     real(kind=rl) :: x, y, z
 
     ix_min = u%ix_min
     ix_max = u%ix_max
     iy_min = u%iy_min
     iy_max = u%iy_max
+    nz     = u%grid_param%nz
+    n      = u%grid_param%n
 
     ! Initialise RHS
     do ix=ix_min, ix_max
       do iy=iy_min, iy_max
-        do iz=1,u%grid_param%nz
-          x = u%grid_param%L*((ix-0.5_rl)/(1.0_rl*u%grid_param%n))
-          y = u%grid_param%L*((iy-0.5_rl)/(1.0_rl*u%grid_param%n))
-          z = u%grid_param%H*((iz-0.5_rl)/(1.0_rl*u%grid_param%nz))
+        do iz=1,nz
+          x = u%grid_param%L*((ix-0.5_rl)/(1.0_rl*n))
+          y = u%grid_param%L*((iy-0.5_rl)/(1.0_rl*n))
+          z = u%grid_param%H*((iz-0.5_rl)/(1.0_rl*nz))
           if (grid_param%vertbc == VERTBC_DIRICHLET) then
             u%s(iz,iy-iy_min+1,ix-ix_min+1) &
               = x*(1.0_rl-x) &
diff --git a/src/ZSOLVER/tridiag_thermo.f90 b/src/ZSOLVER/tridiag_thermo.f90
new file mode 100644
index 0000000000000000000000000000000000000000..7ba28585cf889c05a029487228b15e8dcdc5a908
--- /dev/null
+++ b/src/ZSOLVER/tridiag_thermo.f90
@@ -0,0 +1,460 @@
+!MNH_LIC Copyright 2003-2020 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.
+!-----------------------------------------------------------------
+!     ###################
+      MODULE MODI_TRIDIAG_THERMO
+!     ###################
+!        
+INTERFACE
+!        
+       SUBROUTINE TRIDIAG_THERMO(KKA,KKU,KKL,PVARM,PF,PDFDDTDZ,PTSTEP,PIMPL,  &
+                                 PDZZ,PRHODJ,PVARP             )
+!
+INTEGER,                INTENT(IN)   :: KKA           !near ground array index  
+INTEGER,                INTENT(IN)   :: KKU           !uppest atmosphere array index
+INTEGER,                INTENT(IN)   :: KKL           !vert. levels type 1=MNH -1=AR
+REAL, DIMENSION(:,:,:), INTENT(IN) :: PVARM   ! variable at t-1      at mass point
+REAL, DIMENSION(:,:,:), INTENT(IN) :: PF      ! flux in dT/dt=-dF/dz at flux point
+REAL, DIMENSION(:,:,:), INTENT(IN) :: PDFDDTDZ! dF/d(dT/dz)          at flux point
+REAL,                   INTENT(IN) :: PTSTEP  ! Double time step
+REAL,                   INTENT(IN) :: PIMPL   ! implicit weight
+REAL, DIMENSION(:,:,:), INTENT(IN) :: PDZZ    ! Dz                   at flux point
+REAL, DIMENSION(:,:,:), INTENT(IN) :: PRHODJ  ! (dry rho)*J          at mass point
+!
+REAL, DIMENSION(:,:,:), INTENT(OUT):: PVARP   ! variable at t+1      at mass point
+!
+END SUBROUTINE TRIDIAG_THERMO
+!
+END INTERFACE
+!
+END MODULE MODI_TRIDIAG_THERMO 
+!
+!      #################################################
+       SUBROUTINE TRIDIAG_THERMO(KKA,KKU,KKL,PVARM,PF,PDFDDTDZ,PTSTEP,PIMPL,  &
+                                 PDZZ,PRHODJ,PVARP             )
+!      #################################################
+!
+!
+!!****   *TRIDIAG_THERMO* - routine to solve a time implicit scheme
+!!
+!!
+!!     PURPOSE
+!!     -------
+!        The purpose of this routine is to give a field PVARP at t+1, by 
+!      solving an implicit TRIDIAGonal system obtained by the 
+!      discretization of the vertical turbulent diffusion. It should be noted 
+!      that the degree of implicitness can be varied (PIMPL parameter) and that
+!      the function of F(dT/dz) must have been linearized.
+!      PVARP is localized at a mass point.
+!
+!!**   METHOD
+!!     ------
+!!
+!!        [T(+) - T(-)]/2Dt = -d{ F + dF/d(dT/dz) * [impl*dT/dz(+) + expl* dT/dz(-)] }/dz
+!!
+!!     It is discretized as follows:
+!!
+!!    PRHODJ(k)*PVARP(k)/PTSTEP
+!!              = 
+!!    PRHODJ(k)*PVARM(k)/PTSTEP 
+!!  - (PRHODJ(k+1)+PRHODJ(k)  )/2. * PF(k+1)/PDZZ(k+1)
+!!  + (PRHODJ(k)  +PRHODJ(k-1))/2. * PF(k)  /PDZZ(k)
+!!  + (PRHODJ(k+1)+PRHODJ(k)  )/2. * ZEXPL* PDFDDTDZ(k+1) * PVARM(k+1)/PDZZ(k+1)**2
+!!  - (PRHODJ(k+1)+PRHODJ(k)  )/2. * PIMPL* PDFDDTDZ(k+1) * PVARP(k+1)/PDZZ(k+1)**2
+!!  - (PRHODJ(k+1)+PRHODJ(k)  )/2. * ZEXPL* PDFDDTDZ(k+1) * PVARM(k)  /PDZZ(k+1)**2
+!!  + (PRHODJ(k+1)+PRHODJ(k)  )/2. * PIMPL* PDFDDTDZ(k+1) * PVARP(k)  /PDZZ(k+1)**2
+!!  - (PRHODJ(k)  +PRHODJ(k-1))/2. * ZEXPL* PDFDDTDZ(k)   * PVARM(k)  /PDZZ(k)**2
+!!  + (PRHODJ(k)  +PRHODJ(k-1))/2. * PIMPL* PDFDDTDZ(k)   * PVARP(k)  /PDZZ(k)**2
+!!  + (PRHODJ(k)  +PRHODJ(k-1))/2. * ZEXPL* PDFDDTDZ(k)   * PVARM(k-1)/PDZZ(k)**2
+!!  - (PRHODJ(k)  +PRHODJ(k-1))/2. * PIMPL* PDFDDTDZ(k)   * PVARP(k-1)/PDZZ(k)**2
+!!
+!!
+!!    The system to solve is:
+!!
+!!      A*PVARP(k-1) + B*PVARP(k) + C*PVARP(k+1) = Y(k)
+!!
+!!
+!!    The RHS of the linear system in PVARP writes:
+!!
+!! y(k)    = PRHODJ(k)*PVARM(k)/PTSTEP
+!!  - (PRHODJ(k+1)+PRHODJ(k)  )/2. * PF(k+1)/PDZZ(k+1)
+!!  + (PRHODJ(k)  +PRHODJ(k-1))/2. * PF(k)  /PDZZ(k)
+!!  + (PRHODJ(k+1)+PRHODJ(k)  )/2. * ZEXPL* PDFDDTDZ(k+1) * PVARM(k+1)/PDZZ(k+1)**2
+!!  - (PRHODJ(k+1)+PRHODJ(k)  )/2. * ZEXPL* PDFDDTDZ(k+1) * PVARM(k)  /PDZZ(k+1)**2
+!!  - (PRHODJ(k)  +PRHODJ(k-1))/2. * ZEXPL* PDFDDTDZ(k)   * PVARM(k)  /PDZZ(k)**2
+!!  + (PRHODJ(k)  +PRHODJ(k-1))/2. * ZEXPL* PDFDDTDZ(k)   * PVARM(k-1)/PDZZ(k)**2
+!!
+!!                      
+!!        Then, the classical TRIDIAGonal algorithm is used to invert the 
+!!     implicit operator. Its matrix is given by:
+!!
+!!     ( b(ikb)   c(ikb)      0        0        0         0        0        0  )
+!!     (   0      a(ikb+1) b(ikb+1) c(ikb+1)    0  ...    0        0        0  ) 
+!!     (   0         0     a(ikb+2) b(ikb+2) c(ikb+2).    0        0        0  ) 
+!!      .......................................................................
+!!     (   0   ...   0     a(k)     b(k)     c(k)         0   ...  0        0  ) 
+!!      .......................................................................
+!!     (   0         0        0        0        0 ...a(ike-1) b(ike-1) c(ike-1))
+!!     (   0         0        0        0        0 ...     0   a(ike)   b(ike)  )
+!!
+!!     ikb and ike represent the first and the last inner mass levels of the
+!!     model. The coefficients are:
+!!         
+!! a(k) = + (PRHODJ(k)  +PRHODJ(k-1))/2. * PIMPL* PDFDDTDZ(k)  /PDZZ(k)**2
+!! b(k) =    PRHODJ(k) / PTSTEP
+!!        - (PRHODJ(k+1)+PRHODJ(k)  )/2. * PIMPL* PDFDDTDZ(k+1)/PDZZ(k+1)**2
+!!        - (PRHODJ(k)  +PRHODJ(k-1))/2. * PIMPL* PDFDDTDZ(k)  /PDZZ(k)**2
+!! c(k) = + (PRHODJ(k+1)+PRHODJ(k)  )/2. * PIMPL* PDFDDTDZ(k+1)/PDZZ(k+1)**2
+!!
+!!          for all k /= ikb or ike
+!!
+!!
+!! b(ikb) =  PRHODJ(ikb) / PTSTEP
+!!          -(PRHODJ(ikb+1)+PRHODJ(ikb))/2.*PIMPL*PDFDDTDZ(ikb+1)/PDZZ(ikb+1)**2
+!! c(ikb) = +(PRHODJ(ikb+1)+PRHODJ(ikb))/2.*PIMPL*PDFDDTDZ(ikb+1)/PDZZ(ikb+1)**2
+!!
+!! b(ike) =  PRHODJ(ike) / PTSTEP
+!!          -(PRHODJ(ike)+PRHODJ(ike-1))/2.*PIMPL*PDFDDTDZ(ike)/PDZZ(ike)**2
+!! a(ike) = +(PRHODJ(ike)+PRHODJ(ike-1))/2.*PIMPL*PDFDDTDZ(ike)/PDZZ(ike)**2
+!!
+!!
+!!     EXTERNAL
+!!     --------
+!!
+!!       NONE
+!!
+!!     IMPLICIT ARGUMENTS
+!!     ------------------
+!!
+!!     REFERENCE
+!!     ---------
+!!       Press et al: Numerical recipes (1986) Cambridge Univ. Press
+!!
+!!     AUTHOR
+!!     ------
+!!       V. Masson         * Meteo-France *   
+!! 
+!!     MODIFICATIONS
+!!     -------------
+!!       Original        04/2003 (from tridiag.f90)
+!!       M.Moge          04/2016 Use openACC directives to port the TURB part of Meso-NH on GPU
+!! ---------------------------------------------------------------------
+!
+!*       0. DECLARATIONS
+!
+USE MODD_PARAMETERS, ONLY : JPVEXT_TURB
+
+use mode_mppdb
+
+#ifndef MNH_OPENACC
+USE MODI_SHUMAN
+#else
+USE MODI_SHUMAN_DEVICE
+#endif
+#ifdef MNH_BITREP
+USE MODI_BITREP
+#endif
+!
+#ifdef MNH_OPENACC
+USE MODE_MNH_ZWORK , ONLY : MNH_ALLOCATE_ZT3D , MNH_REL_ZT3D , MNH_ALLOCATE_ZT2D, &
+                            MNH_CHECK_IN_ZT3D,MNH_CHECK_OUT_ZT3D
+#endif
+!
+IMPLICIT NONE
+!
+!
+!*       0.1 declarations of arguments
+!
+INTEGER,              INTENT(IN)   :: KKA     !near ground array index  
+INTEGER,              INTENT(IN)   :: KKU     !uppest atmosphere array index
+INTEGER,              INTENT(IN)   :: KKL     !vert. levels type 1=MNH -1=ARO
+REAL, DIMENSION(:,:,:), INTENT(IN) :: PVARM   ! variable at t-1      at mass point
+REAL, DIMENSION(:,:,:), INTENT(IN) :: PF      ! flux in dT/dt=-dF/dz at flux point
+REAL, DIMENSION(:,:,:), INTENT(IN) :: PDFDDTDZ! dF/d(dT/dz)          at flux point
+REAL,                   INTENT(IN) :: PTSTEP  ! Double time step
+REAL,                   INTENT(IN) :: PIMPL   ! implicit weight
+REAL, DIMENSION(:,:,:), INTENT(IN) :: PDZZ    ! Dz                   at flux point
+REAL, DIMENSION(:,:,:), INTENT(IN) :: PRHODJ  ! (dry rho)*J          at mass point
+!
+REAL, DIMENSION(:,:,:), INTENT(OUT):: PVARP   ! variable at t+1      at mass point
+!
+!*       0.2 declarations of local variables
+!
+REAL, DIMENSION(:,:,:), pointer , contiguous :: ZRHODJ_DFDDTDZ_O_DZ2
+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
+INTEGER :: IZRHODJ_DFDDTDZ_O_DZ2,IZMZM_RHODJ,IZA,IZB,IZC,IZY,IZGAM
+REAL, DIMENSION(:,:), pointer , contiguous   :: ZBET
+INTEGER :: IZBET
+                                         ! 2D work array
+INTEGER             :: JI,JJ,JK      ! loop counter
+INTEGER             :: IKB,IKE       ! inner vertical limits
+INTEGER             :: IKT          ! array size in k direction
+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
+
+! ---------------------------------------------------------------------------
+
+!$acc data present( PVARM, PF, PDFDDTDZ, PDZZ, PRHODJ, PVARP )
+
+if ( mppdb_initialized ) then
+  !Check all in arrays
+  call Mppdb_check( pvarm,    "Tridiag_thermo beg:pvarm"    )
+  call Mppdb_check( pf,       "Tridiag_thermo beg:pf"       )
+  call Mppdb_check( pdfddtdz, "Tridiag_thermo beg:pdfddtdz" )
+  call Mppdb_check( pdzz,     "Tridiag_thermo beg:pdzz"     )
+  call Mppdb_check( prhodj,   "Tridiag_thermo beg:prhodj"   )
+end if
+
+JIU =  size( pvarm, 1 )
+JJU =  size( pvarm, 2 )
+JKU =  size( pvarm, 3 )
+
+#ifndef MNH_OPENACC
+allocate( zrhodj_dfddtdz_o_dz2(JIU,JJU,JKU ) )
+allocate( zmzm_rhodj          (JIU,JJU,JKU ) )
+allocate( za                  (JIU,JJU,JKU ) )
+allocate( zb                  (JIU,JJU,JKU ) )
+allocate( zc                  (JIU,JJU,JKU ) )
+allocate( zy                  (JIU,JJU,JKU ) )
+allocate( zgam                (JIU,JJU,JKU ) )
+allocate( zbet                (JIU,JJU ) )
+#else
+CALL MNH_CHECK_IN_ZT3D("TRIDIAG_THERMO")
+izrhodj_dfddtdz_o_dz2 = MNH_ALLOCATE_ZT3D( zrhodj_dfddtdz_o_dz2,JIU,JJU,JKU )
+izmzm_rhodj           = MNH_ALLOCATE_ZT3D( zmzm_rhodj          ,JIU,JJU,JKU )
+iza                   = MNH_ALLOCATE_ZT3D( za                  ,JIU,JJU,JKU )
+izb                   = MNH_ALLOCATE_ZT3D( zb                  ,JIU,JJU,JKU )
+izc                   = MNH_ALLOCATE_ZT3D( zc                  ,JIU,JJU,JKU )
+izy                   = MNH_ALLOCATE_ZT3D( zy                  ,JIU,JJU,JKU )
+izgam                 = MNH_ALLOCATE_ZT3D( zgam                ,JIU,JJU,JKU )
+izbet                 = MNH_ALLOCATE_ZT2D( zbet                ,JIU,JJU )
+#endif
+
+#ifdef MNH_OPENACC
+iztmp1_device = MNH_ALLOCATE_ZT3D( ztmp1_device,JIU,JJU,JKU )
+#endif
+
+!$acc data present( zrhodj_dfddtdz_o_dz2, zmzm_rhodj, za, zb, zc, zy, zgam, zbet, ztmp1_device )
+!
+!*      1.  Preliminaries
+!           -------------
+!
+IKT=SIZE(PVARM,3)          
+IKTB=1+JPVEXT_TURB              
+IKTE=IKT-JPVEXT_TURB
+IKB=KKA+JPVEXT_TURB*KKL
+IKE=KKU-JPVEXT_TURB*KKL
+!
+#ifndef MNH_OPENACC
+ZMZM_RHODJ = MZM(PRHODJ)
+#else
+CALL MZM_DEVICE(PRHODJ,ZMZM_RHODJ)
+#endif
+!$acc kernels ! async
+#ifndef MNH_BITREP
+ZRHODJ_DFDDTDZ_O_DZ2 = ZMZM_RHODJ*PDFDDTDZ/PDZZ**2
+#else
+!$acc loop independent collapse(3)
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU) 
+   ZRHODJ_DFDDTDZ_O_DZ2(JI,JJ,JK) = ZMZM_RHODJ(JI,JJ,JK)*PDFDDTDZ(JI,JJ,JK)/BR_P2(PDZZ(JI,JJ,JK))
+END DO !CONCURRENT   
+#endif
+!$acc end kernels
+!
+!$acc kernels ! async
+ZA=0.
+ZB=0.
+ZC=0.
+ZY=0.
+!$acc end kernels
+! acc wait
+!
+!
+!*      2.  COMPUTE THE RIGHT HAND SIDE
+!           ---------------------------
+!
+!$acc kernels ! async
+!$acc loop independent collapse(2)
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU)
+ZY(JI,JJ,IKB) = PRHODJ(JI,JJ,IKB)*PVARM(JI,JJ,IKB)/PTSTEP                  &
+    - ZMZM_RHODJ(JI,JJ,IKB+KKL) * PF(JI,JJ,IKB+KKL)/PDZZ(JI,JJ,IKB+KKL)    &
+    + ZMZM_RHODJ(JI,JJ,IKB  ) * PF(JI,JJ,IKB  )/PDZZ(JI,JJ,IKB  )          &
+    + ZRHODJ_DFDDTDZ_O_DZ2(JI,JJ,IKB+KKL) * PIMPL * PVARM(JI,JJ,IKB+KKL) &
+    - ZRHODJ_DFDDTDZ_O_DZ2(JI,JJ,IKB+KKL) * PIMPL * PVARM(JI,JJ,IKB  )
+END DO !CONCURRENT
+!$acc end kernels
+!
+!$acc kernels ! async
+!$acc loop independent collapse(3)
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=IKTB+1:IKTE-1)
+  ZY(JI,JJ,JK) = PRHODJ(JI,JJ,JK)*PVARM(JI,JJ,JK)/PTSTEP                 &
+    - ZMZM_RHODJ(JI,JJ,JK+KKL) * PF(JI,JJ,JK+KKL)/PDZZ(JI,JJ,JK+KKL)     &
+    + ZMZM_RHODJ(JI,JJ,JK  ) * PF(JI,JJ,JK  )/PDZZ(JI,JJ,JK  )           &
+    + ZRHODJ_DFDDTDZ_O_DZ2(JI,JJ,JK+KKL) * PIMPL * PVARM(JI,JJ,JK+KKL) &
+    - ZRHODJ_DFDDTDZ_O_DZ2(JI,JJ,JK+KKL) * PIMPL * PVARM(JI,JJ,JK  )   &
+    - ZRHODJ_DFDDTDZ_O_DZ2(JI,JJ,JK    ) * PIMPL * PVARM(JI,JJ,JK  )   &
+    + ZRHODJ_DFDDTDZ_O_DZ2(JI,JJ,JK    ) * PIMPL * PVARM(JI,JJ,JK-KKL)
+END DO !CONCURRENT
+!$acc end kernels
+! 
+!$acc kernels ! async
+!$acc loop independent collapse(2)
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU)
+ZY(JI,JJ,IKE) = PRHODJ(JI,JJ,IKE)*PVARM(JI,JJ,IKE)/PTSTEP               &
+    - ZMZM_RHODJ(JI,JJ,IKE+KKL) * PF(JI,JJ,IKE+KKL)/PDZZ(JI,JJ,IKE+KKL) &
+    + ZMZM_RHODJ(JI,JJ,IKE  ) * PF(JI,JJ,IKE  )/PDZZ(JI,JJ,IKE  )       &
+    - ZRHODJ_DFDDTDZ_O_DZ2(JI,JJ,IKE ) * PIMPL * PVARM(JI,JJ,IKE  )   &
+    + ZRHODJ_DFDDTDZ_O_DZ2(JI,JJ,IKE ) * PIMPL * PVARM(JI,JJ,IKE-KKL)
+END DO !CONCURRENT
+!$acc end kernels
+!
+! acc wait
+!
+!*       3.  INVERSION OF THE TRIDIAGONAL SYSTEM
+!            -----------------------------------
+!
+IF ( PIMPL > 1.E-10 ) THEN
+!
+!*       3.1 arrays A, B, C
+!            --------------
+!
+!$acc kernels ! async
+!$acc loop independent collapse(2)   
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU)   
+  ZB(JI,JJ,IKB) =   PRHODJ(JI,JJ,IKB)/PTSTEP                   &
+                - ZRHODJ_DFDDTDZ_O_DZ2(JI,JJ,IKB+KKL) * PIMPL
+END DO !CONCURRENT 
+!$acc end kernels
+!
+!$acc kernels ! async
+!$acc loop independent collapse(2)
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU)
+  ZC(JI,JJ,IKB) =   ZRHODJ_DFDDTDZ_O_DZ2(JI,JJ,IKB+KKL) * PIMPL
+END DO !CONCURRENT
+!$acc end kernels
+!
+!$acc kernels ! async
+!$acc loop independent collapse(3)
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=IKTB+1:IKTE-1)
+  ZA(JI,JJ,JK) =   ZRHODJ_DFDDTDZ_O_DZ2(JI,JJ,JK) * PIMPL
+  ZB(JI,JJ,JK) =   PRHODJ(JI,JJ,JK)/PTSTEP                        &
+                          - ZRHODJ_DFDDTDZ_O_DZ2(JI,JJ,JK+KKL) * PIMPL &
+                          - ZRHODJ_DFDDTDZ_O_DZ2(JI,JJ,JK) * PIMPL
+  ZC(JI,JJ,JK) =   ZRHODJ_DFDDTDZ_O_DZ2(JI,JJ,JK+KKL) * PIMPL
+END DO !CONCURRENT
+!$acc end kernels
+!
+!$acc kernels ! async
+!$acc loop independent collapse(2)
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU)
+  ZA(JI,JJ,IKE) =   ZRHODJ_DFDDTDZ_O_DZ2(JI,JJ,IKE  ) * PIMPL
+  ZB(JI,JJ,IKE) =   PRHODJ(JI,JJ,IKE)/PTSTEP                   &
+                - ZRHODJ_DFDDTDZ_O_DZ2(JI,JJ,IKE  ) * PIMPL
+END DO !CONCURRENT
+!$acc end kernels
+!
+! acc wait
+!
+!
+!*       3.2 going up
+!            --------
+!
+!$acc kernels
+!$acc loop independent collapse(2)
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU)
+  ZBET(JI,JJ) = ZB(JI,JJ,IKB)  ! bet = b(ikb)
+  PVARP(JI,JJ,IKB) = ZY(JI,JJ,IKB) / ZBET(JI,JJ)
+END DO !CONCURRENT
+!
+!$acc loop seq
+DO JK = IKB+KKL,IKE-KKL,KKL
+   ! gang+vector needed or parallisation vector only
+   !$acc loop independent gang, vector collapse(2)   
+   DO CONCURRENT ( JI=1:JIU,JJ=1:JJU)
+      ZGAM(JI,JJ,JK) = ZC(JI,JJ,JK-KKL) / ZBET(JI,JJ)  
+      ! gam(k) = c(k-1) / bet
+      ZBET(JI,JJ)    = ZB(JI,JJ,JK) - ZA(JI,JJ,JK) * ZGAM(JI,JJ,JK)
+      ! bet = b(k) - a(k)* gam(k)  
+      PVARP(JI,JJ,JK)= ( ZY(JI,JJ,JK) - ZA(JI,JJ,JK) * PVARP(JI,JJ,JK-KKL) ) / ZBET(JI,JJ)
+      ! res(k) = (y(k) -a(k)*res(k-1))/ bet
+   END DO !CONCURRENT 
+END DO
+! special treatment for the last level
+!$acc loop independent collapse(2)
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU)
+      ZGAM(JI,JJ,IKE) = ZC(JI,JJ,IKE-KKL) / ZBET(JI,JJ) 
+      ! gam(k) = c(k-1) / bet
+      ZBET(JI,JJ)     = ZB(JI,JJ,IKE) - ZA(JI,JJ,IKE) * ZGAM(JI,JJ,IKE)
+      ! bet = b(k) - a(k)* gam(k)  
+      PVARP(JI,JJ,IKE)= ( ZY(JI,JJ,IKE) - ZA(JI,JJ,IKE) * PVARP(JI,JJ,IKE-KKL) ) / ZBET(JI,JJ)
+      ! res(k) = (y(k) -a(k)*res(k-1))/ bet 
+END DO !CONCURRENT
+!
+!*       3.3 going down
+!            ----------
+!
+!$acc loop seq
+DO JK = IKE-KKL,IKB,-1*KKL
+   ! gang+vector needed or parallisation vector only
+   !$acc loop independent gang, vector collapse(2)
+   DO CONCURRENT ( JI=1:JIU,JJ=1:JJU)
+      PVARP(JI,JJ,JK) = PVARP(JI,JJ,JK) - ZGAM(JI,JJ,JK+KKL) * PVARP(JI,JJ,JK+KKL)
+   END DO !CONCURRENT
+END DO
+!$acc end kernels
+!
+ELSE
+! 
+!$acc kernels
+!$acc loop independent collapse(3)   
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=IKTB:IKTE)   
+   PVARP(JI,JJ,JK) = ZY(JI,JJ,JK) * PTSTEP / PRHODJ(JI,JJ,JK)
+END DO !CONCURRENT
+!$acc end kernels
+!
+END IF 
+!
+!
+!*       4.  FILL THE UPPER AND LOWER EXTERNAL VALUES
+!            ----------------------------------------
+!
+!$acc kernels
+!$acc loop independent collapse(2)
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU)
+   PVARP(JI,JJ,KKA)=PVARP(JI,JJ,IKB)
+   PVARP(JI,JJ,KKU)=PVARP(JI,JJ,IKE)
+END DO !CONCURRENT
+!$acc end kernels
+
+if ( mppdb_initialized ) then
+  !Check all out arrays
+  call Mppdb_check( pvarp, "Tridiag_thermo end:pvarp" )
+end if
+
+!$acc end data
+
+#ifndef MNH_OPENACC
+deallocate (zrhodj_dfddtdz_o_dz2,zmzm_rhodj,za,zb,zc,zy,zgam,zbet)
+#else
+CALL MNH_REL_ZT3D(IZRHODJ_DFDDTDZ_O_DZ2,IZMZM_RHODJ,IZA,IZB,IZC,IZY,IZGAM,&
+                  IZBET,iztmp1_device)
+CALL MNH_CHECK_OUT_ZT3D("TRIDIAG_THERMO")
+#endif
+
+!$acc end data
+
+!-------------------------------------------------------------------------------
+!
+END SUBROUTINE TRIDIAG_THERMO
diff --git a/src/ZSOLVER/turb.f90 b/src/ZSOLVER/turb.f90
new file mode 100644
index 0000000000000000000000000000000000000000..9d5f3bfa99c5c9e6b916e628f882e8bb9f8e6d7c
--- /dev/null
+++ b/src/ZSOLVER/turb.f90
@@ -0,0 +1,2461 @@
+!MNH_LIC Copyright 1994-2020 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.
+!-----------------------------------------------------------------
+!###############
+module mode_turb
+!###############
+
+#ifdef MNH_OPENACC
+  use mode_msg
+  USE MODE_MNH_ZWORK , ONLY : MNH_ALLOCATE_ZT3D , MNH_REL_ZT3D, MNH_ALLOCATE_ZT3DP , MNH_ALLOCATE_ZT2D, &
+       MNH_ALLOCATE_ZT4D , MNH_REL_ZT4D , &
+       MNH_CHECK_IN_ZT3D,MNH_CHECK_OUT_ZT3D
+#endif
+
+#ifdef MNH_BITREP
+use modi_bitrep
+#endif
+
+implicit none
+
+private
+
+public :: turb
+
+contains
+
+!     #################################################################
+SUBROUTINE TURB(KKA,KKU,KKL,KMI,KRR,KRRL,KRRI,HLBCX,HLBCY,KSPLIT,KMODEL_CL, &
+                OCLOSE_OUT,OTURB_FLX,OTURB_DIAG,OSUBG_COND,ORMC01,    &
+                HTURBDIM,HTURBLEN,HTOM,HTURBLEN_CL,HCLOUD,PIMPL,      &
+                PTSTEP,TPFILE,PDXX,PDYY,PDZZ,PDZX,PDZY,PZZ,           &
+                PDIRCOSXW,PDIRCOSYW,PDIRCOSZW,PCOSSLOPE,PSINSLOPE,    &
+                PRHODJ,PTHVREF,                                       &
+                PSFTH,PSFRV,PSFSV,PSFU,PSFV,                          &
+                PPABST,PUT,PVT,PWT,PTKET,PSVT,PSRCT,                  &
+                PBL_DEPTH,PSBL_DEPTH,                                 &
+                PCEI,PCEI_MIN,PCEI_MAX,PCOEF_AMPL_SAT,                &
+                PTHLT,PRT,                                            &
+                PRUS,PRVS,PRWS,PRTHLS,PRRS,PRSVS,PRTKES,PRTKEMS,PSIGS,&
+                PFLXZTHVMF,PWTH,PWRC,PWSV,PDYP,PTHP,PTR,PDISS,PLEM    )
+!     #################################################################
+!
+!
+!!****  *TURB* - computes the turbulent source terms for the prognostic
+!!               variables. 
+!!
+!!    PURPOSE
+!!    -------
+!!****  The purpose of this routine is to compute the source terms in 
+!!    the evolution equations due to the turbulent mixing. 
+!!      The source term is computed as the divergence of the turbulent fluxes.
+!!    The cartesian fluxes are obtained by a one and a half order closure, based
+!!    on a prognostic equation for the Turbulence Kinetic Energy( TKE ). The 
+!!    system is closed by prescribing a turbulent mixing length. Different 
+!!    choices are available for this length. 
+!
+!!**  METHOD
+!!    ------
+!!    
+!!      The dimensionality of the turbulence parameterization can be chosen by
+!!    means of the parameter HTURBDIM:
+!!           * HTURBDIM='1DIM' the parameterization is 1D but can be used in
+!!    3D , 2D or 1D simulations. Only the sources associated to the vertical
+!!    turbulent fluxes are taken into account.
+!!           *  HTURBDIM='3DIM' the parameterization is fully 2D or 3D depending
+!!    on the model  dimensionality. Of course, it does not make any sense to
+!!    activate this option with a 1D model. 
+!!
+!!      The following steps are made:
+!!      1- Preliminary computations.
+!!      2- The metric coefficients are recovered from the grid knowledge.
+!!      3- The mixing length is computed according to its choice:
+!!           * HTURBLEN='BL89' the Bougeault and Lacarrere algorithm is used.
+!!             The mixing length is given by the vertical displacement from its
+!!             original level of an air particule having an initial internal
+!!             energy equal to its TKE and stopped by the buoyancy forces.
+!!             The discrete formulation is second order accurate.
+!!           * HTURBLEN='DELT' the mixing length is given by the mesh size 
+!!             depending on the model dimensionality, this length is limited 
+!!             with the ground distance.
+!!           * HTURBLEN='DEAR' the mixing length is given by the mesh size 
+!!             depending on the model dimensionality, this length is limited 
+!!             with the ground distance and also by the Deardorff mixing length
+!!             pertinent in the stable cases.
+!!           * HTURBLEN='KEPS' the mixing length is deduced from the TKE 
+!!             dissipation, which becomes a prognostic variable of the model (
+!!             Duynkerke formulation).   
+!!      3'- The cloud mixing length is computed according to HTURBLEN_CLOUD
+!!             and emphasized following the CEI index
+!!      4- The conservative variables are computed along with Lv/Cp.
+!!      5- The turbulent Prandtl numbers are computed from the resolved fields
+!!         and TKE 
+!!      6- The sources associated to the vertical turbulent fluxes are computed
+!!      with a temporal scheme allowing a degree of implicitness given by 
+!!      PIMPL, varying from PIMPL=0. ( purely explicit scheme) to PIMPL=1.
+!!      ( purely implicit scheme)
+!!      The sources associated to the horizontal fluxes are computed with a
+!!      purely explicit temporal scheme. These sources are only computed when
+!!      the turbulence parameterization is 2D or 3D( HTURBDIM='3DIM' ).
+!!      7- The sources for TKE are computed, along with the dissipation of TKE 
+!!      if HTURBLEN='KEPS'.
+!!      8- Some turbulence-related quantities are stored in the synchronous 
+!!      FM-file.
+!!      9- The non-conservative variables are retrieved.  
+!!    
+!!      
+!!      The saving of the fields in the synchronous FM-file is controlled by:
+!!        * OTURB_FLX => saves all the turbulent fluxes and correlations
+!!        * OTURB_DIAG=> saves the turbulent Prandtl and Schmidt numbers, the
+!!                       source terms of TKE and dissipation of TKE 
+!!
+!!    EXTERNAL
+!!    --------
+!!      SUBROUTINE PRANDTL   : computes the turbulent Prandtl number
+!!      SUBROUTINE TURB_VER  : computes the sources from the vertical fluxes
+!!      SUBROUTINE TURB_HOR  : computes the sources from the horizontal fluxes
+!!      SUBROUTINE TKE_EPS_SOURCES : computes the sources for  TKE and its
+!!                                   dissipation
+!!      SUBROUTINE BUDGET    : computes and stores the budgets
+!!
+!!    IMPLICIT ARGUMENTS
+!!    ------------------
+!!
+!!       MODD_PARAMETERS : JPVEXT  number of marginal vertical points
+!!
+!!       MODD_CONF      : CCONF model configuration (start/restart)
+!!                        L1D   switch for 1D model version
+!!                        L2D   switch for 2D model version
+!!
+!!       MODD_CST  : contains physical constants
+!!                    XG   gravity constant
+!!                    XRD  Gas constant for dry air
+!!                    XRV  Gas constant for vapor
+!!
+!!       MODD_CTURB : contains turbulence scheme constants
+!!                    XCMFS,XCED       to compute the dissipation mixing length
+!!                    XTKEMIN  minimum values for the TKE 
+!!                    XLINI,XLINF      to compute Bougeault-Lacarrere mixing 
+!!                                     length
+!!      Module MODD_BUDGET:
+!!         NBUMOD  
+!!         CBUTYPE 
+!!         NBUPROCCTR 
+!!         LBU_RU     
+!!         LBU_RV     
+!!         LBU_RW     
+!!         LBU_RTH    
+!!         LBU_RSV1   
+!!         LBU_RRV    
+!!         LBU_RRC    
+!!         LBU_RRR    
+!!         LBU_RRI    
+!!         LBU_RRS    
+!!         LBU_RRG    
+!!         LBU_RRH    
+!!
+!!    REFERENCE
+!!    ---------
+!!      Book 2 of documentation (routine TURB)
+!!      Book 1 of documentation (Chapter: Turbulence)
+!!
+!!    AUTHOR
+!!    ------
+!!      Joan Cuxart             * INM and Meteo-France *
+!!
+!!    MODIFICATIONS
+!!    -------------
+!!      Original         05/10/94
+!!      Modifications: Feb 14, 1995 (J.Cuxart and J.Stein) 
+!!                                  Doctorization and Optimization
+!!      Modifications: March 21, 1995 (J.M. Carriere) 
+!!                                  Introduction of cloud water
+!!      Modifications: June   1, 1995 (J.Cuxart     ) 
+!!                                  take min(Kz,delta)
+!!      Modifications: June   1, 1995 (J.Stein J.Cuxart)
+!!                                  remove unnecessary arrays and change Prandtl
+!!                                  and Schmidt numbers localizations
+!!      Modifications: July  20, 1995 (J.Stein) remove MODI_ground_ocean +
+!!                                TZDTCUR + MODD_TIME because they are not used
+!!                                change RW in RNP for the outputs
+!!      Modifications: August 21, 1995 (Ph. Bougeault)   
+!!                                  take min(K(z-zsol),delta)
+!!      Modifications: Sept 14, 1995 (Ph Bougeault, J. Cuxart)
+!!         second order BL89 mixing length computations + add Deardorff length 
+!!         in the Delta case for stable cases
+!!      Modifications: Sept 19, 1995 (J. Stein, J. Cuxart)
+!!         define a DEAR case for the mixing length, add MODI_BUDGET and change
+!!         some BUDGET calls, add LES tools
+!!      Modifications: Oct  16, 1995 (J. Stein) change the budget calls
+!!      Modifications: Feb  28, 1996 (J. Stein) optimization + 
+!!                                              remove min(K(z-zsol),delta)+
+!!                                              bug in the tangential fluxes 
+!!      Modifications: Oct  16, 1996 (J. Stein) change the subgrid condensation
+!!                                              scheme + temporal discretization
+!!      Modifications: Dec  19, 1996 (J.-P. Pinty) update the budget calls
+!!                     Jun  22, 1997 (J. Stein) use the absolute pressure and
+!!                                  change the Deardorf length at the surface
+!!      Modifications: Apr  27, 1997 (V. Masson) BL89 mix. length computed in
+!!                                               a separate routine
+!!                     Oct  13, 1999 (J. Stein)  switch for the tgt fluxes
+!!                     Jun  24, 1999 (P Jabouille)  Add routine UPDATE_ROTATE_WIND
+!!                     Feb  15, 2001 (J. Stein)  remove tgt fluxes
+!!                     Mar 8,  2001 (V. Masson) forces the same behaviour near the surface
+!!                                              for all mixing lengths
+!!                     Nov 06, 2002 (V. Masson) LES budgets
+!!                     Nov,    2002 (V. Masson) implement modifications of
+!!                                              mixing and dissipative lengths
+!!                                              near the surface (according
+!!                                              Redelsperger et al 2001)
+!!                     Apr,    2003 (V. Masson) bug in Blackadar length
+!!                                              bug in LES in 1DIM case
+!!                     Feb 20, 2003 (J.-P. Pinty) Add reversible ice processes
+!!                     May,26  2004 (P Jabouille) coef for computing dissipative heating
+!!                     Sept 2004 (M.Tomasini) Cloud Mixing length modification
+!!                                            following the instability 
+!!                                            criterium CEI calculated in modeln
+!!                     May   2006    Remove KEPS
+!!                     Sept.2006 (I.Sandu): Modification of the stability criterion for
+!!                                 DEAR (theta_v -> theta_l)
+!!                     Oct 2007 (J.Pergaud) Add MF contribution for vert. turb. transport
+!!                     Oct.2009  (C.Lac) Introduction of different PTSTEP according to the
+!!                              advection schemes
+!!                     October 2009 (G. Tanguy) add ILENCH=LEN(YCOMMENT) after
+!!                                              change of YCOMMENT
+!!                     06/2011 (J.escobar ) Bypass Bug with ifort11/12 on  HLBCX,HLBC
+!!                     2012-02 Y. Seity,  add possibility to run with reversed
+!!                                          vertical levels
+!!                     10/2012 (J. Colin) Correct bug in DearDoff for dry simulations
+!!                     10/2012 J.Escobar Bypass PGI bug , redefine some allocatable array inplace of automatic
+!!                     04/2016  (C.Lac) correction of negativity for KHKO
+!!  Philippe Wautelet: 05/2016-04/2018: new data structures and calls for I/O
+!!                     01/2018 (Q.Rodier) Introduction of RM17
+!  P. Wautelet 20/05/2019: add name argument to ADDnFIELD_ll + new ADD4DFIELD_ll subroutine
+!  P. Wautelet 20/06/2019: take DELT and DEAR subroutines out of the TURB one (PGI compiler bug workaround) + transform into a mode_ module
+!! --------------------------------------------------------------------------
+!       
+!*      0. DECLARATIONS
+!          ------------
+!
+USE MODD_PARAMETERS, ONLY: JPVEXT_TURB
+USE MODD_CST
+USE MODD_CTURB
+USE MODD_CONF
+USE MODD_BUDGET
+USE MODD_IO, ONLY: TFILEDATA
+USE MODD_LES
+USE MODD_NSV
+!
+USE MODI_GRADIENT_M
+USE MODI_GRADIENT_U
+USE MODI_GRADIENT_V
+USE MODI_BL89
+USE MODI_TURB_VER
+USE MODI_ROTATE_WIND
+USE MODI_TURB_HOR_SPLT 
+USE MODI_TKE_EPS_SOURCES
+#ifndef MNH_OPENACC
+USE MODI_SHUMAN
+#else
+!PW: TODO: remove use modi_shuman
+USE MODI_SHUMAN
+USE MODI_SHUMAN_DEVICE
+#endif
+USE MODI_GRADIENT_M
+USE MODI_BUDGET
+USE MODI_LES_MEAN_SUBGRID
+USE MODI_RMC01
+USE MODI_GRADIENT_W
+USE MODI_TM06
+USE MODI_UPDATE_LM
+USE MODI_GET_HALO
+!
+USE MODE_FIELD,          ONLY: TFIELDDATA, TYPEREAL
+USE MODE_IO_FIELD_WRITE, only: IO_Field_write
+USE MODE_SBL
+!
+USE MODI_EMOIST
+USE MODI_ETHETA
+!
+USE MODI_SECOND_MNH
+!
+USE MODE_MPPDB
+!
+!!  use, intrinsic :: ISO_C_BINDING
+!
+IMPLICIT NONE
+!
+!
+!*      0.1  declarations of arguments
+!
+!
+!
+INTEGER,                INTENT(IN)   :: KKA           !near ground array index  
+INTEGER,                INTENT(IN)   :: KKU           !uppest atmosphere array index
+INTEGER,                INTENT(IN)   :: KKL           !vert. levels type 1=MNH -1=ARO
+INTEGER,                INTENT(IN)   :: KMI           ! model index number  
+INTEGER,                INTENT(IN)   :: KRR           ! number of moist var.
+INTEGER,                INTENT(IN)   :: KRRL          ! number of liquid water var.
+INTEGER,                INTENT(IN)   :: KRRI          ! number of ice water var.
+CHARACTER(LEN=*),DIMENSION(:),INTENT(IN):: HLBCX, HLBCY  ! X- and Y-direc LBC
+INTEGER,                INTENT(IN)   :: KSPLIT        ! number of time-splitting
+INTEGER,                INTENT(IN)   :: KMODEL_CL     ! model number for cloud mixing length
+LOGICAL,                INTENT(IN)   ::  OCLOSE_OUT   ! switch for syncronous
+                                                      ! file opening
+LOGICAL,                INTENT(IN)   ::  OTURB_FLX    ! switch to write the
+                                 ! turbulent fluxes in the syncronous FM-file
+LOGICAL,                INTENT(IN)   ::  OTURB_DIAG   ! switch to write some
+                                 ! diagnostic fields in the syncronous FM-file
+LOGICAL,                INTENT(IN)   ::  OSUBG_COND   ! switch for SUBGrid 
+                                 ! CONDensation
+LOGICAL,                INTENT(IN)   ::  ORMC01       ! switch for RMC01 lengths in SBL
+CHARACTER(len=4),       INTENT(IN)   ::  HTURBDIM     ! dimensionality of the
+                                                      ! turbulence scheme
+CHARACTER(len=4),       INTENT(IN)   ::  HTURBLEN     ! kind of mixing length
+CHARACTER(len=4),       INTENT(IN)   ::  HTOM         ! kind of Third Order Moment
+CHARACTER(len=4),       INTENT(IN)   ::  HTURBLEN_CL  ! kind of cloud mixing length
+REAL,                   INTENT(IN)   ::  PIMPL        ! degree of implicitness
+CHARACTER (LEN=4),      INTENT(IN)   ::  HCLOUD       ! Kind of microphysical scheme
+REAL,                   INTENT(IN)   ::  PTSTEP       ! timestep 
+TYPE(TFILEDATA),        INTENT(IN)   ::  TPFILE       ! Output file
+!
+REAL, DIMENSION(:,:,:), INTENT(IN)   :: PDXX,PDYY,PDZZ,PDZX,PDZY
+                                        ! metric coefficients
+REAL, DIMENSION(:,:,:), INTENT(IN)   :: PZZ       !  physical distance 
+! between 2 succesive grid points along the K direction
+REAL, DIMENSION(:,:),   INTENT(IN)      ::  PDIRCOSXW, PDIRCOSYW, PDIRCOSZW
+! Director Cosinus along x, y and z directions at surface w-point
+REAL, DIMENSION(:,:),   INTENT(IN)   ::  PCOSSLOPE       ! cosinus of the angle
+                                 ! between i and the slope vector
+REAL, DIMENSION(:,:),   INTENT(IN)   ::  PSINSLOPE       ! sinus of the angle
+                                 ! between i and the slope vector
+REAL, DIMENSION(:,:,:), INTENT(IN)      ::  PRHODJ    ! dry density * Grid size
+REAL, DIMENSION(:,:,:), INTENT(IN)      ::  PTHVREF   ! Virtual Potential
+                                        ! Temperature of the reference state
+!
+REAL, DIMENSION(:,:),   INTENT(IN)      ::  PSFTH,PSFRV,   &
+! normal surface fluxes of theta and Rv 
+                                            PSFU,PSFV
+! normal surface fluxes of (u,v) parallel to the orography
+REAL, DIMENSION(:,:,:), INTENT(IN)      ::  PSFSV
+! normal surface fluxes of Scalar var. 
+!
+!    prognostic variables at t- deltat
+REAL, DIMENSION(:,:,:),   INTENT(IN) ::  PPABST      ! Pressure at time t
+REAL, DIMENSION(:,:,:),   INTENT(IN) ::  PUT,PVT,PWT ! wind components
+REAL, DIMENSION(:,:,:),   INTENT(IN) ::  PTKET       ! TKE
+REAL, DIMENSION(:,:,:,:), INTENT(IN) ::  PSVT        ! passive scal. var.
+REAL, DIMENSION(:,:,:),   INTENT(IN) ::  PSRCT       ! Second-order flux
+                      ! s'rc'/2Sigma_s2 at time t-1 multiplied by Lambda_3
+REAL, DIMENSION(:,:),     INTENT(INOUT) :: PBL_DEPTH  ! BL height for TOMS
+REAL, DIMENSION(:,:),     INTENT(INOUT) :: PSBL_DEPTH ! SBL depth for RMC01
+!
+!    variables for cloud mixing length
+REAL, DIMENSION(:,:,:), INTENT(IN)      ::  PCEI ! Cloud Entrainment instability
+                                                 ! index to emphasize localy 
+                                                 ! turbulent fluxes
+REAL, INTENT(IN)      ::  PCEI_MIN ! minimum threshold for the instability index CEI
+REAL, INTENT(IN)      ::  PCEI_MAX ! maximum threshold for the instability index CEI
+REAL, INTENT(IN)      ::  PCOEF_AMPL_SAT ! saturation of the amplification coefficient
+!
+!   thermodynamical variables which are transformed in conservative var.
+REAL, DIMENSION(:,:,:),   INTENT(INOUT) ::  PTHLT       ! conservative pot. temp.
+REAL, DIMENSION(:,:,:,:), INTENT(INOUT) ::  PRT         ! water var.  where 
+                             ! PRT(:,:,:,1) is the conservative mixing ratio        
+! sources of momentum, conservative potential temperature, Turb. Kin. Energy, 
+! TKE dissipation
+REAL, DIMENSION(:,:,:),   INTENT(INOUT) ::  PRUS,PRVS,PRWS,PRTHLS,PRTKES
+! Source terms for all water kinds, PRRS(:,:,:,1) is used for the conservative
+! mixing ratio
+REAL, DIMENSION(:,:,:),   INTENT(IN)    ::  PRTKEMS
+REAL, DIMENSION(:,:,:,:), INTENT(INOUT) ::  PRRS 
+! Source terms for all passive scalar variables
+REAL, DIMENSION(:,:,:,:), INTENT(INOUT) ::  PRSVS
+! Sigma_s at time t+1 : square root of the variance of the deviation to the 
+! saturation
+REAL, DIMENSION(:,:,:), INTENT(OUT)     ::  PSIGS
+REAL, DIMENSION(:,:,:), INTENT(IN)      ::  PFLXZTHVMF 
+!                                           MF contribution for vert. turb. transport
+!                                           used in the buoy. prod. of TKE
+REAL, DIMENSION(:,:,:), INTENT(OUT)  :: PWTH       ! heat flux
+REAL, DIMENSION(:,:,:), INTENT(OUT)  :: PWRC       ! cloud water flux
+REAL, DIMENSION(:,:,:,:),INTENT(OUT) :: PWSV       ! scalar flux
+REAL, DIMENSION(:,:,:), INTENT(OUT)  :: PDYP  ! Dynamical production of TKE
+REAL, DIMENSION(:,:,:), INTENT(OUT)  :: PTHP  ! Thermal production of TKE
+REAL, DIMENSION(:,:,:), INTENT(OUT)  :: PTR   ! Transport production of TKE
+REAL, DIMENSION(:,:,:), INTENT(OUT)  :: PDISS ! Dissipation of TKE
+REAL, DIMENSION(:,:,:), INTENT(OUT)  :: PLEM  ! Mixing length
+!
+!-------------------------------------------------------------------------------
+!
+!       0.2  declaration of local variables
+!
+REAL, POINTER , CONTIGUOUS, DIMENSION(:,:,:) ::&
+          ZCP,                        &  ! Cp at t-1
+          ZEXN,                       &  ! EXN at t-1
+          ZT,                         &  ! T at t-1
+          ZLOCPEXNM,                  &  ! Lv/Cp/EXNREF at t-1
+          ZLEPS,                      &  ! Dissipative length
+          ZTRH,                       &  ! Dynamic and Thermal Production of TKE
+          ZATHETA,ZAMOIST,            &  ! coefficients for s = f (Thetal,Rnp)
+          ZCOEF_DISS,                 &  ! 1/(Cph*Exner) for dissipative heating
+          ZFRAC_ICE,                  &  ! ri fraction of rc+ri
+          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.
+INTEGER :: IZCP,IZEXN,IZT,IZLOCPEXNM,IZLEPS,IZTRH,IZATHETA,IZAMOIST &
+          ,IZCOEF_DISS,IZFRAC_ICE,IZMWTH,IZMWR,IZMTH2,IZMR2,IZMTHR &
+          ,IZFWTH,IZFWR,IZFTH2,IZFR2,IZFTHR,IZTHLM
+!
+REAL, POINTER , CONTIGUOUS, DIMENSION(:,:,:,:) ::     &
+          ZRM                            ! initial mixing ratio
+REAL, POINTER , CONTIGUOUS, DIMENSION(:,:) ::  ZTAU11M,ZTAU12M,  &
+                                                 ZTAU22M,ZTAU33M,  &
+            ! tangential surface fluxes in the axes following the orography
+                                                 ZUSLOPE,ZVSLOPE,  &
+            ! wind components at the first mass level parallel
+            ! to the orography
+                                                 ZCDUEFF,          &
+            ! - Cd*||u|| where ||u|| is the module of the wind tangential to
+            ! orography (ZUSLOPE,ZVSLOPE) at the surface.
+                                                 ZUSTAR, ZLMO,     &
+                                                 ZRVM, ZSFRV
+            ! friction velocity, Monin Obuhkov length, work arrays for vapor
+!
+            ! Virtual Potential Temp. used
+            ! in the Deardorff mixing length computation
+INTEGER :: IZRM,IZTAU11M,IZTAU12M,IZTAU22M,IZTAU33M,IZUSLOPE,IZVSLOPE &
+          ,IZCDUEFF,IZUSTAR,IZLMO,IZRVM,IZSFRV
+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)
+INTEGER :: IZLVOCPEXNM,IZLSOCPEXNM,IZATHETA_ICE,IZAMOIST_ICE
+!
+REAL                :: ZEXPL        ! 1-PIMPL deg of expl.
+REAL                :: ZRVORD       ! RV/RD
+!
+INTEGER             :: IKB,IKE      ! index value for the
+! Beginning and the End of the physical domain for the mass points
+INTEGER             :: IKT          ! array size in k direction
+INTEGER             :: IKTB,IKTE    ! start, end of k loops in physical domain 
+INTEGER             :: JRR,JK,JSV   ! loop counters
+INTEGER             :: JI,JJ        ! loop counters
+REAL                :: ZL0          ! Max. Mixing Length in Blakadar formula
+REAL                :: ZALPHA       ! proportionnality constant between Dz/2 and 
+!                                   ! BL89 mixing length near the surface
+!
+REAL :: ZTIME1, ZTIME2
+REAL, DIMENSION(:,:,:), pointer , contiguous :: ZTT,ZEXNE,ZLV,ZCPH
+REAL, DIMENSION(:,:,:), pointer , contiguous :: ZSHEAR, ZDUDZ, ZDVDZ
+INTEGER :: IZTT,IZEXNE,IZLV,IZCPH,IZSHEAR, IZDUDZ, IZDVDZ
+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
+INTEGER  :: JLU_ZRM, JLU_TURB, JJU_ORMC01, JKU_CLOUD, JKU_TURB
+!
+!------------------------------------------------------------------------------------------
+!
+! IN variables
+!
+!$acc data present( PDXX, PDYY, PDZZ, PDZX, PDZY, PRHODJ)                                  &
+!$acc &    copyin ( PZZ, PDIRCOSXW,  PDIRCOSYW,  PDIRCOSZW,                                &
+!$acc &             PCOSSLOPE, PSINSLOPE, PTHVREF, PSFTH, PSFRV, PSFU, PSFV, PSFSV,        &
+!$acc &             PPABST, PUT, PVT, PWT, PTKET, PSVT, PSRCT, PCEI, PRTKEMS, PFLXZTHVMF ) &
+!
+! INOUT variables
+!
+!$acc &    create ( PBL_DEPTH, PSBL_DEPTH, PTHLT, PRT,                                     &
+!$acc &             PRUS, PRVS, PRWS, PRTHLS, PRTKES, PRRS, PRSVS )                        &
+!
+! OUT variables
+!
+!$acc &    create ( PSIGS, PWTH, PWRC, PWSV, PDYP, PTHP, PTR, PDISS, PLEM )
+!
+! Local variables
+!
+! !$acc &    create ( ZSHEAR )
+
+if ( mppdb_initialized ) then
+  !Check all in arrays
+  call Mppdb_check( pdxx,       "Turb beg:pdxx"       )
+  call Mppdb_check( pdyy,       "Turb beg:pdyy"       )
+  call Mppdb_check( pdzz,       "Turb beg:pdzz"       )
+  call Mppdb_check( pdzx,       "Turb beg:pdzx"       )
+  call Mppdb_check( pdzy,       "Turb beg:pdzy"       )
+  call Mppdb_check( prhodj,     "Turb beg:prhodj"     )
+  call Mppdb_check( pzz,        "Turb beg:pzz"        )
+  call Mppdb_check( pdircosxw,  "Turb beg:pdircosxw"  )
+  call Mppdb_check( pdircosyw,  "Turb beg:pdircosyw"  )
+  call Mppdb_check( pdircoszw,  "Turb beg:pdircoszw"  )
+  call Mppdb_check( pcosslope,  "Turb beg:pcosslope"  )
+  call Mppdb_check( psinslope,  "Turb beg:psinslope"  )
+  call Mppdb_check( pthvref,    "Turb beg:pthvref"    )
+  call Mppdb_check( psfth,      "Turb beg:psfth"      )
+  call Mppdb_check( psfrv,      "Turb beg:psfrv"      )
+  call Mppdb_check( psfu,       "Turb beg:psfu"       )
+  call Mppdb_check( psfv,       "Turb beg:psfv"       )
+  call Mppdb_check( psfsv,      "Turb beg:psfsv"      )
+  call Mppdb_check( ppabst,     "Turb beg:ppabst"     )
+  call Mppdb_check( put,        "Turb beg:put"        )
+  call Mppdb_check( pvt,        "Turb beg:pvt"        )
+  call Mppdb_check( pwt,        "Turb beg:pwt"        )
+  call Mppdb_check( ptket,      "Turb beg:ptket"      )
+  call Mppdb_check( psvt,       "Turb beg:psvt"       )
+  call Mppdb_check( psrct,      "Turb beg:psrct"      )
+  call Mppdb_check( pcei,       "Turb beg:pcei"       )
+  call Mppdb_check( prtkems,    "Turb beg:prtkems"    )
+  call Mppdb_check( pflxzthvmf, "Turb beg:pflxzthvmf" )
+  !check all inout arrays
+  call Mppdb_check( pbl_depth,  "Turb beg:pbl_depth"  )
+  call Mppdb_check( psbl_depth, "Turb beg:psbl_depth" )
+  call Mppdb_check( pthlt,      "Turb beg:pthlt"      )
+  call Mppdb_check( prt,        "Turb beg:prt"        )
+  call Mppdb_check( prus,       "Turb beg:prus"       )
+  call Mppdb_check( prvs,       "Turb beg:prvs"       )
+  call Mppdb_check( prws,       "Turb beg:prws"       )
+  call Mppdb_check( prthls,     "Turb beg:prthls"     )
+  call Mppdb_check( prtkes,     "Turb beg:prtkes"     )
+  call Mppdb_check( prrs,       "Turb beg:prrs"       )
+  call Mppdb_check( prsvs,      "Turb beg:prsvs"      )
+end if
+
+JIU =  size(pthlt, 1 )
+JJU =  size(pthlt, 2 )
+JKU =  size(pthlt, 3 )
+
+#ifndef MNH_OPENACC
+ALLOCATE (ZCP       (JIU,JJU,JKU) )
+ALLOCATE (ZEXN      (JIU,JJU,JKU) )
+ALLOCATE (ZT        (JIU,JJU,JKU) )
+ALLOCATE (ZLOCPEXNM (JIU,JJU,JKU) )
+ALLOCATE (ZLEPS     (JIU,JJU,JKU) )
+ALLOCATE (ZTRH      (JIU,JJU,JKU) )
+ALLOCATE (ZATHETA   (JIU,JJU,JKU) )
+ALLOCATE (ZAMOIST   (JIU,JJU,JKU) )
+ALLOCATE (ZCOEF_DISS(JIU,JJU,JKU) )
+ALLOCATE (ZFRAC_ICE (JIU,JJU,JKU) )
+
+ALLOCATE (ZMWTH     (JIU,JJU,JKU) )
+ALLOCATE (ZMWR      (JIU,JJU,JKU) )
+ALLOCATE (ZMTH2     (JIU,JJU,JKU) )
+ALLOCATE (ZMR2      (JIU,JJU,JKU) )
+ALLOCATE (ZMTHR     (JIU,JJU,JKU) )
+
+ALLOCATE (ZFWTH     (JIU,JJU,JKU) )
+ALLOCATE (ZFWR      (JIU,JJU,JKU) )
+ALLOCATE (ZFTH2     (JIU,JJU,JKU) )
+ALLOCATE (ZFR2      (JIU,JJU,JKU) )
+ALLOCATE (ZFTHR     (JIU,JJU,JKU) )
+ALLOCATE (ZTHLM     (JIU,JJU,JKU) )
+
+JLU_TURB = 0 
+IF ( HTURBLEN == 'BL89' .OR. HTURBLEN == 'RM17' .OR. ORMC01 ) JLU_TURB = SIZE(PRT,4)
+ALLOCATE ( ZRM(JIU,JJU,JKU, JLU_TURB ) )
+
+ALLOCATE ( ZTAU11M(JIU,JJU) )
+ALLOCATE ( ZTAU12M(JIU,JJU) )
+ALLOCATE ( ZTAU22M(JIU,JJU) )
+ALLOCATE ( ZTAU33M(JIU,JJU) )
+ALLOCATE ( ZUSLOPE(JIU,JJU) )
+ALLOCATE ( ZVSLOPE(JIU,JJU) )
+ALLOCATE ( ZCDUEFF(JIU,JJU) )
+ALLOCATE ( ZLMO   (JIU,JJU) )
+
+JJU_ORMC01 = 0
+IF (ORMC01) JJU_ORMC01 = SIZE(PTHLT,2)
+ALLOCATE ( ZUSTAR (JIU,JJU_ORMC01) )
+ALLOCATE ( ZRVM   (JIU,JJU_ORMC01) )
+ALLOCATE ( ZSFRV  (JIU,JJU_ORMC01) )
+
+JKU_CLOUD = 0 
+IF ( HCLOUD == 'KHKO' .OR. HCLOUD == 'C2R2' ) JKU_CLOUD = size( put, 3 )
+allocate( ztt   (JIU,JJU, JKU_CLOUD ) )
+allocate( zexne (JIU,JJU, JKU_CLOUD ) )
+allocate( zlv   (JIU,JJU, JKU_CLOUD ) )
+allocate( zcph  (JIU,JJU, JKU_CLOUD ) )
+
+JKU_TURB = 0  
+IF ( HTURBLEN == 'BL89' .OR. HTURBLEN == 'RM17' ) JKU_TURB = size( put, 3 )
+allocate( zshear(JIU,JJU, JKU_TURB ) )
+
+JKU_TURB = 0
+IF ( HTURBLEN == 'RM17' ) JKU_TURB = size( put, 3 )
+allocate( zdudz (JIU,JJU, JKU_TURB ) )
+allocate( zdvdz (JIU,JJU, JKU_TURB ) )
+
+#else
+CALL MNH_CHECK_IN_ZT3D("TURB")
+IZCP =  MNH_ALLOCATE_ZT3D (ZCP       ,JIU,JJU,JKU )
+IZEXN =  MNH_ALLOCATE_ZT3D (ZEXN      ,JIU,JJU,JKU )
+IZT =  MNH_ALLOCATE_ZT3D (ZT        ,JIU,JJU,JKU )
+IZLOCPEXNM =  MNH_ALLOCATE_ZT3D (ZLOCPEXNM ,JIU,JJU,JKU )
+IZLEPS =  MNH_ALLOCATE_ZT3D (ZLEPS     ,JIU,JJU,JKU )
+IZTRH =  MNH_ALLOCATE_ZT3D (ZTRH      ,JIU,JJU,JKU )
+IZATHETA =  MNH_ALLOCATE_ZT3D (ZATHETA   ,JIU,JJU,JKU )
+IZAMOIST =  MNH_ALLOCATE_ZT3D (ZAMOIST   ,JIU,JJU,JKU )
+IZCOEF_DISS =  MNH_ALLOCATE_ZT3D (ZCOEF_DISS,JIU,JJU,JKU )
+IZFRAC_ICE =  MNH_ALLOCATE_ZT3D (ZFRAC_ICE ,JIU,JJU,JKU )
+
+IZMWTH =  MNH_ALLOCATE_ZT3D (ZMWTH     ,JIU,JJU,JKU )
+IZMWR =  MNH_ALLOCATE_ZT3D (ZMWR      ,JIU,JJU,JKU )
+IZMTH2 =  MNH_ALLOCATE_ZT3D (ZMTH2     ,JIU,JJU,JKU )
+IZMR2 =  MNH_ALLOCATE_ZT3D (ZMR2      ,JIU,JJU,JKU )
+IZMTHR =  MNH_ALLOCATE_ZT3D (ZMTHR     ,JIU,JJU,JKU )
+
+IZFWTH =  MNH_ALLOCATE_ZT3D (ZFWTH     ,JIU,JJU,JKU )
+IZFWR =  MNH_ALLOCATE_ZT3D (ZFWR      ,JIU,JJU,JKU )
+IZFTH2 =  MNH_ALLOCATE_ZT3D (ZFTH2     ,JIU,JJU,JKU )
+IZFR2 =  MNH_ALLOCATE_ZT3D (ZFR2      ,JIU,JJU,JKU )
+IZFTHR =  MNH_ALLOCATE_ZT3D (ZFTHR     ,JIU,JJU,JKU )
+IZTHLM =  MNH_ALLOCATE_ZT3D (ZTHLM     ,JIU,JJU,JKU )
+
+JLU_ZRM = 0 
+IF ( HTURBLEN == 'BL89' .OR. HTURBLEN == 'RM17' .OR. ORMC01 ) JLU_ZRM = SIZE(PRT,4)
+IZRM =  MNH_ALLOCATE_ZT4D ( ZRM,JIU,JJU,JKU, JLU_ZRM  )
+
+IZTAU11M =  MNH_ALLOCATE_ZT2D ( ZTAU11M,JIU,JJU )
+IZTAU12M =  MNH_ALLOCATE_ZT2D ( ZTAU12M,JIU,JJU )
+IZTAU22M =  MNH_ALLOCATE_ZT2D ( ZTAU22M,JIU,JJU )
+IZTAU33M =  MNH_ALLOCATE_ZT2D ( ZTAU33M,JIU,JJU )
+IZUSLOPE =  MNH_ALLOCATE_ZT2D ( ZUSLOPE,JIU,JJU )
+IZVSLOPE =  MNH_ALLOCATE_ZT2D ( ZVSLOPE,JIU,JJU )
+IZCDUEFF =  MNH_ALLOCATE_ZT2D ( ZCDUEFF,JIU,JJU )
+IZLMO =  MNH_ALLOCATE_ZT2D ( ZLMO   ,JIU,JJU )
+
+JJU_ORMC01 = 0
+IF (ORMC01) JJU_ORMC01 = SIZE(PTHLT,2)
+IZUSTAR =  MNH_ALLOCATE_ZT2D ( ZUSTAR ,JIU,JJU_ORMC01 )
+IZRVM =  MNH_ALLOCATE_ZT2D ( ZRVM   ,JIU,JJU_ORMC01 )
+IZSFRV =  MNH_ALLOCATE_ZT2D ( ZSFRV  ,JIU,JJU_ORMC01 )
+
+JKU_CLOUD = 0 
+IF ( HCLOUD == 'KHKO' .OR. HCLOUD == 'C2R2' ) JKU_CLOUD = size( put, 3 )
+iztt =  MNH_ALLOCATE_ZT3D( ztt   ,JIU,JJU,JKU_CLOUD )
+izexne =  MNH_ALLOCATE_ZT3D( zexne ,JIU,JJU,JKU_CLOUD )
+izlv =  MNH_ALLOCATE_ZT3D( zlv   ,JIU,JJU,JKU_CLOUD )
+izcph =  MNH_ALLOCATE_ZT3D( zcph  ,JIU,JJU,JKU_CLOUD )
+
+JKU_TURB = 0  
+IF ( HTURBLEN == 'BL89' .OR. HTURBLEN == 'RM17' ) JKU_TURB = size( put, 3 )
+izshear =  MNH_ALLOCATE_ZT3D( zshear,JIU,JJU, JKU_TURB )
+
+JKU_TURB = 0
+IF ( HTURBLEN == 'RM17' ) JKU_TURB = size( put, 3 )
+izdudz =  MNH_ALLOCATE_ZT3D( zdudz ,JIU,JJU, JKU_TURB )
+izdvdz =  MNH_ALLOCATE_ZT3D( zdvdz ,JIU,JJU, JKU_TURB )
+
+#endif
+
+#ifdef MNH_OPENACC
+iztmp1_device =  MNH_ALLOCATE_ZT3D( ztmp1_device,JIU,JJU,JKU )
+
+JKU_TURB = 0
+IF (HTURBDIM=="1DIM") JKU_TURB = size( pthlt, 3 )
+iztmp2_device =  MNH_ALLOCATE_ZT3D( ztmp2_device,JIU,JJU, JKU_TURB )
+iztmp3_device =  MNH_ALLOCATE_ZT3D( ztmp3_device,JIU,JJU, JKU_TURB )
+
+#endif
+
+!$acc data present( zcp, zexn, zt, zlocpexnm, zleps, ztrh,         &
+!$acc &            zatheta, zamoist, zcoef_diss, zfrac_ice,       &
+!$acc &            zmwth, zmwr, zmth2, zmr2, zmthr,               &
+!$acc &            zfwth, zfwr, zfth2, zfr2, zfthr, zthlm,        &
+!$acc &            zrm,                                           &
+!$acc &            ztau11m, ztau12m, ztau22m, ztau33m,            &
+!$acc &            zuslope, zvslope, zcdueff, zlmo,               &
+!$acc &            zustar, zrvm, zsfrv,                           &
+!$acc &            ztt, zexne, zlv, zcph, zshear,  zdudz,  zdvdz, &
+!$acc &            ztmp1_device, ztmp2_device, ztmp3_device       )
+
+!------------------------------------------------------------------------------------------
+!
+!*      1.PRELIMINARIES
+!         -------------
+!
+!*      1.1 Set the internal domains, ZEXPL 
+!
+!
+IKT=SIZE(PTHLT,3)          
+IKTB=1+JPVEXT_TURB              
+IKTE=IKT-JPVEXT_TURB
+IKB=KKA+JPVEXT_TURB*KKL
+IKE=KKU-JPVEXT_TURB*KKL
+!
+ZEXPL = 1.- PIMPL
+ZRVORD= XRV / XRD
+!
+!
+!$acc update device(PTHLT,PRT)
+!$acc kernels
+!Copy data into ZTHLM and ZRM only if needed
+IF (HTURBLEN=='BL89' .OR. HTURBLEN=='RM17' .OR. ORMC01) THEN
+  ZTHLM(:,:,:) = PTHLT(:,:,:)
+  ZRM(:,:,:,:) = PRT(:,:,:,:)
+END IF
+!
+ZTRH(:, :, : ) = XUNDEF
+!
+!----------------------------------------------------------------------------
+!
+!*      2. COMPUTE CONSERVATIVE VARIABLES AND RELATED QUANTITIES
+!          -----------------------------------------------------
+!
+!*      2.1 Cph at t
+!
+ZCP(:,:,:)=XCPD
+!
+IF (KRR > 0) ZCP(:,:,:) = ZCP(:,:,:) + XCPV * PRT(:,:,:,1)
+! PGI20.5 BUG or reproductibility problem , with pointer this loop on JRR parallelize whitout reduction 
+!$acc loop seq
+DO JRR = 2,1+KRRL                          ! loop on the liquid components  
+  ZCP(:,:,:)  = ZCP(:,:,:) + XCL * PRT(:,:,:,JRR)
+END DO
+!
+!$acc loop seq
+DO JRR = 2+KRRL,1+KRRL+KRRI                ! loop on the solid components   
+  ZCP(:,:,:)  = ZCP(:,:,:)  + XCI * PRT(:,:,:,JRR)
+END DO
+!
+!*      2.2 Exner function at t
+!
+!PW: "BUG" PGI : results different on CPU and GPU due to the power function
+!See http://www.pgroup.com/userforum/viewtopic.php?t=5364&sid=ec7b762b17fb9bb3332a47f0db57af55
+!Use of own functions allows bit-reproducible results
+#ifndef MNH_BITREP
+ZEXN(:,:,:) = (PPABST(:,:,:)/XP00) ** (XRD/XCPD)
+#else
+ZEXN(:,:,:) = BR_POW(PPABST(:,:,:)/XP00,XRD/XCPD)
+#endif
+!
+!*      2.3 dissipative heating coeff a t
+!
+ZCOEF_DISS(:,:,:) = 1/(ZCP(:,:,:) * ZEXN(:,:,:)) 
+!
+!
+ZFRAC_ICE(:,:,:) = 0.0
+ZATHETA(:,:,:) = 0.0
+ZAMOIST(:,:,:) = 0.0
+!$acc end kernels
+!
+IF (KRRL >=1) THEN
+!
+!*      2.4 Temperature at t
+!
+!$acc kernels
+  ZT(:,:,:) =  PTHLT(:,:,:) * ZEXN(:,:,:)
+!$acc end kernels
+!
+!*       2.5 Lv/Cph/Exn
+!
+  IF ( KRRI >= 1 ) THEN 
+    ALLOCATE(ZLVOCPEXNM(JIU,JJU,JKU))
+    ALLOCATE(ZLSOCPEXNM(JIU,JJU,JKU))
+    ALLOCATE(ZAMOIST_ICE(JIU,JJU,JKU))
+    ALLOCATE(ZATHETA_ICE(JIU,JJU,JKU))
+
+!$acc enter data create( zlvocpexnm, zlsocpexnm )
+!$acc data create( zamoist_ice, zatheta_ice )
+
+    CALL COMPUTE_FUNCTION_THERMO(XALPW,XBETAW,XGAMW,XLVTT,XCL,ZT,ZEXN,ZCP, &
+                                 ZLVOCPEXNM,ZAMOIST,ZATHETA)
+    CALL COMPUTE_FUNCTION_THERMO(XALPI,XBETAI,XGAMI,XLSTT,XCI,ZT,ZEXN,ZCP, &
+                                 ZLSOCPEXNM,ZAMOIST_ICE,ZATHETA_ICE)
+!
+!$acc kernels 
+    WHERE(PRT(:,:,:,2)+PRT(:,:,:,4)>0.0)
+      ZFRAC_ICE(:,:,:) = PRT(:,:,:,4) / ( PRT(:,:,:,2)+PRT(:,:,:,4) )
+    END WHERE
+!
+    ZLOCPEXNM(:,:,:) = (1.0-ZFRAC_ICE(:,:,:))*ZLVOCPEXNM(:,:,:) &
+                           +ZFRAC_ICE(:,:,:) *ZLSOCPEXNM(:,:,:)
+    ZAMOIST(:,:,:) = (1.0-ZFRAC_ICE(:,:,:))*ZAMOIST(:,:,:) &
+                         +ZFRAC_ICE(:,:,:) *ZAMOIST_ICE(:,:,:)
+    ZATHETA(:,:,:) = (1.0-ZFRAC_ICE(:,:,:))*ZATHETA(:,:,:) &
+                         +ZFRAC_ICE(:,:,:) *ZATHETA_ICE(:,:,:)
+!$acc end kernels
+
+!$acc end data
+    DEALLOCATE(ZAMOIST_ICE)
+    DEALLOCATE(ZATHETA_ICE)
+  ELSE
+    CALL COMPUTE_FUNCTION_THERMO(XALPW,XBETAW,XGAMW,XLVTT,XCL,ZT,ZEXN,ZCP, &
+                                 ZLOCPEXNM,ZAMOIST,ZATHETA)
+  END IF
+!
+!
+  IF (OCLOSE_OUT .AND. OTURB_DIAG) THEN
+!$acc update self(ZAMOIST,ZATHETA)
+    TZFIELD%CMNHNAME   = 'ATHETA'
+    TZFIELD%CSTDNAME   = ''
+    TZFIELD%CLONGNAME  = 'ATHETA'
+    TZFIELD%CUNITS     = 'm'
+    TZFIELD%CDIR       = 'XY'
+    TZFIELD%CCOMMENT   = 'X_Y_Z_ATHETA'
+    TZFIELD%NGRID      = 1
+    TZFIELD%NTYPE      = TYPEREAL
+    TZFIELD%NDIMS      = 3
+    TZFIELD%LTIMEDEP   = .TRUE.
+    CALL IO_Field_write(TPFILE,TZFIELD,ZATHETA)
+! 
+    TZFIELD%CMNHNAME   = 'AMOIST'
+    TZFIELD%CSTDNAME   = ''
+    TZFIELD%CLONGNAME  = 'AMOIST'
+    TZFIELD%CUNITS     = 'm'
+    TZFIELD%CDIR       = 'XY'
+    TZFIELD%CCOMMENT   = 'X_Y_Z_AMOIST'
+    TZFIELD%NGRID      = 1
+    TZFIELD%NTYPE      = TYPEREAL
+    TZFIELD%NDIMS      = 3
+    TZFIELD%LTIMEDEP   = .TRUE.
+    CALL IO_Field_write(TPFILE,TZFIELD,ZAMOIST)
+  END IF
+!
+ELSE
+!$acc kernels
+  ZLOCPEXNM=0.
+!$acc end kernels
+END IF              ! loop end on KRRL >= 1
+!
+! computes conservative variables
+!
+!$acc update device(PRRS,PRTHLS)
+IF ( KRRL >= 1 ) THEN
+!$acc kernels
+  IF ( KRRI >= 1 ) THEN
+    ! Rnp at t
+    PRT(:,:,:,1)  = PRT(:,:,:,1)  + PRT(:,:,:,2)  + PRT(:,:,:,4)
+    PRRS(:,:,:,1) = PRRS(:,:,:,1) + PRRS(:,:,:,2) + PRRS(:,:,:,4)
+    ! Theta_l at t
+    PTHLT(:,:,:)  = PTHLT(:,:,:)  - ZLVOCPEXNM(:,:,:) * PRT(:,:,:,2) &
+                                  - ZLSOCPEXNM(:,:,:) * PRT(:,:,:,4)
+    PRTHLS(:,:,:) = PRTHLS(:,:,:) - ZLVOCPEXNM(:,:,:) * PRRS(:,:,:,2) &
+                                  - ZLSOCPEXNM(:,:,:) * PRRS(:,:,:,4)
+  ELSE
+    ! Rnp at t
+    PRT(:,:,:,1)  = PRT(:,:,:,1)  + PRT(:,:,:,2) 
+    PRRS(:,:,:,1) = PRRS(:,:,:,1) + PRRS(:,:,:,2)
+    ! Theta_l at t
+    PTHLT(:,:,:)  = PTHLT(:,:,:)  - ZLOCPEXNM(:,:,:) * PRT(:,:,:,2)
+    PRTHLS(:,:,:) = PRTHLS(:,:,:) - ZLOCPEXNM(:,:,:) * PRRS(:,:,:,2)
+  END IF
+!$acc end kernels
+END IF
+!
+!----------------------------------------------------------------------------
+!
+!*      3. MIXING LENGTH : SELECTION AND COMPUTATION
+!          -----------------------------------------
+!
+!
+SELECT CASE (HTURBLEN)
+!
+!*      3.1 BL89 mixing length
+!           ------------------
+
+  CASE ('BL89')
+!$acc kernels
+    ZSHEAR(:, :, : ) = 0.
+!$acc end kernels
+    CALL BL89(KKA,KKU,KKL,PZZ,PDZZ,PTHVREF,ZTHLM,KRR,ZRM,PTKET,ZSHEAR,PLEM)
+!
+!*      3.2 RM17 mixing length
+!           ------------------
+
+  CASE ('RM17')
+#ifdef MNH_OPENACC
+    call Print_msg( NVERB_FATAL, 'GEN', 'TURB', 'OpenACC: HTURBLEN=RM17 not yet implemented' )
+#endif
+    ZDUDZ = MXF(MZF(GZ_U_UW(PUT,PDZZ)))
+    ZDVDZ = MYF(MZF(GZ_V_VW(PVT,PDZZ)))
+    ZSHEAR = SQRT(ZDUDZ*ZDUDZ + ZDVDZ*ZDVDZ)
+    CALL BL89(KKA,KKU,KKL,PZZ,PDZZ,PTHVREF,ZTHLM,KRR,ZRM,PTKET,ZSHEAR,PLEM)
+!
+!*      3.3 Delta mixing length
+!           -------------------
+!
+  CASE ('DELT')
+    CALL DELT(KKA,KKU,KKL,IKB, IKE,IKTB, IKTE,ORMC01,HTURBDIM,PDXX, PDYY,PZZ,PDIRCOSZW,PLEM)
+!
+!*      3.4 Deardorff mixing length
+!           -----------------------
+!
+  CASE ('DEAR')
+    CALL DEAR(KKA,KKU,KKL,KRR, KRRI, IKB, IKE,IKTB, IKTE, &
+                ORMC01,HTURBDIM,PDXX, PDYY, PDZZ,PZZ,PDIRCOSZW,PTHLT,PTHVREF,PTKET,PSRCT,PRT,&
+                ZLOCPEXNM,ZATHETA, ZAMOIST, PLEM)
+!*      3.5 Blackadar mixing length
+!           -----------------------
+!
+  CASE ('BLKR')
+#ifdef MNH_OPENACC
+    call Print_msg( NVERB_FATAL, 'GEN', 'TURB', 'OpenACC: HTURBLEN=BLKR not yet implemented' )
+#endif
+   ZL0 = 100.
+   PLEM(:,:,:) = ZL0
+
+   ZALPHA=0.5**(-1.5)
+   !
+   DO JK=IKTB,IKTE
+     PLEM(:,:,JK) = ( 0.5*(PZZ(:,:,JK)+PZZ(:,:,JK+KKL)) - &
+     & PZZ(:,:,KKA+JPVEXT_TURB*KKL) ) * PDIRCOSZW(:,:)
+     PLEM(:,:,JK) = ZALPHA  * PLEM(:,:,JK) * ZL0 / ( ZL0 + ZALPHA*PLEM(:,:,JK) )
+   END DO
+!
+   PLEM(:,:,IKTB-1) = PLEM(:,:,IKTB)
+   PLEM(:,:,IKTE+1) = PLEM(:,:,IKTE)
+!
+!
+!
+END SELECT
+!
+!
+!
+!*      3.5 Mixing length modification for cloud
+!           -----------------------
+IF (KMODEL_CL==KMI .AND. HTURBLEN_CL/='NONE') THEN
+#ifdef MNH_OPENACC
+    call Print_msg( NVERB_FATAL, 'GEN', 'TURB', 'OpenACC: CLOUD_MODIF_LM not yet implemented' )
+#endif
+  CALL CLOUD_MODIF_LM
+END IF
+
+!
+!*      3.6 Dissipative length
+!           ------------------
+!
+!$acc kernels
+ZLEPS(:,:,:)=PLEM(:,:,:)
+!
+!*      3.7 Correction in the Surface Boundary Layer (Redelsperger 2001)
+!           ----------------------------------------
+!
+ZLMO=XUNDEF
+!$acc end kernels
+IF (ORMC01) THEN
+!$acc update self(PLEM,ZLEPS)
+#ifdef MNH_OPENACC
+  call Print_msg( NVERB_FATAL, 'GEN', 'TURB', 'OpenACC: ORMC01 not yet implemented' )
+#endif
+#ifndef MNH_BITREP
+  ZUSTAR=(PSFU**2+PSFV**2)**(0.25)
+#else
+  ZUSTAR=BR_POW(BR_P2(PSFU)+BR_P2(PSFV),0.25)
+#endif
+  IF (KRR>0) THEN
+    ZLMO=LMO(ZUSTAR,ZTHLM(:,:,IKB),ZRM(:,:,IKB,1),PSFTH,PSFRV)
+  ELSE
+    ZRVM=0.
+    ZSFRV=0.
+    ZLMO=LMO(ZUSTAR,ZTHLM(:,:,IKB),ZRVM,PSFTH,ZSFRV)
+  END IF
+  CALL RMC01(HTURBLEN,KKA,KKU,KKL,PZZ,PDXX,PDYY,PDZZ,PDIRCOSZW,PSBL_DEPTH,ZLMO,PLEM,ZLEPS)
+!$acc update device(PLEM,ZLEPS)
+END IF
+!
+!*      3.8 Mixing length in external points (used if HTURBDIM="3DIM")
+!           ----------------------------------------------------------
+!
+IF (HTURBDIM=="3DIM") THEN
+  CALL UPDATE_LM(HLBCX,HLBCY,PLEM,ZLEPS)
+END IF
+!----------------------------------------------------------------------------
+!
+!*      4. GO INTO THE AXES FOLLOWING THE SURFACE
+!          --------------------------------------
+!
+!
+!*      4.1 rotate the wind at time t
+!
+!
+!
+  IF (CPROGRAM/='AROME ') THEN
+    CALL ROTATE_WIND(PUT,PVT,PWT,                       &
+                     PDIRCOSXW, PDIRCOSYW, PDIRCOSZW,   &
+                     PCOSSLOPE,PSINSLOPE,               &
+                     PDXX,PDYY,PDZZ,                    &
+                     ZUSLOPE,ZVSLOPE                    )
+!
+    CALL UPDATE_ROTATE_WIND(ZUSLOPE,ZVSLOPE)
+  ELSE
+!$acc kernels
+    ZUSLOPE=PUT(:,:,KKA)
+    ZVSLOPE=PVT(:,:,KKA)
+!$acc end kernels
+  END IF
+!
+!
+!*      4.2 compute the proportionality coefficient between wind and stress
+!
+!$acc kernels
+#ifndef MNH_BITREP
+  ZCDUEFF(:,:) =-SQRT ( (PSFU(:,:)**2 + PSFV(:,:)**2) /                  &
+                        (XMNH_TINY + ZUSLOPE(:,:)**2 + ZVSLOPE(:,:)**2 ) )
+#else
+  !$acc loop independent collapse(2)
+  DO CONCURRENT ( JI=1:JIU,JJ=1:JJU )
+     ZCDUEFF(JI,JJ) =-SQRT ( (BR_P2(PSFU(JI,JJ)) + BR_P2(PSFV(JI,JJ))) /                  &
+                    (XMNH_TINY + BR_P2(ZUSLOPE(JI,JJ)) + BR_P2(ZVSLOPE(JI,JJ)) ) )
+  END DO
+#endif
+!$acc end kernels
+!
+!*       4.6 compute the surface tangential fluxes
+!
+!$acc kernels
+ZTAU11M(:,:) =2./3.*(  (1.+ (PZZ (:,:,IKB+KKL)-PZZ (:,:,IKB))  &
+                           /(PDZZ(:,:,IKB+KKL)+PDZZ(:,:,IKB))  &
+                       )   *PTKET(:,:,IKB)                   &
+                     -0.5  *PTKET(:,:,IKB+KKL)                 &
+                    )
+ZTAU12M(:,:) =0.0
+ZTAU22M(:,:) =ZTAU11M(:,:)
+ZTAU33M(:,:) =ZTAU11M(:,:)
+!
+!*       4.7 third order terms in temperature and water fluxes and correlations
+!            ------------------------------------------------------------------
+!
+!
+ZMWTH = 0.     ! w'2th'
+ZMWR  = 0.     ! w'2r'
+ZMTH2 = 0.     ! w'th'2
+ZMR2  = 0.     ! w'r'2
+ZMTHR = 0.     ! w'th'r'
+!$acc end kernels
+
+IF (HTOM=='TM06') THEN
+#ifndef MNH_OPENACC
+  CALL TM06(KKA,KKU,KKL,PTHVREF,PBL_DEPTH,PZZ,PSFTH,ZMWTH,ZMTH2)
+!
+  ZFWTH = -GZ_M_W(KKA,KKU,KKL,ZMWTH,PDZZ)    ! -d(w'2th' )/dz
+  !ZFWR  = -GZ_M_W(KKA,KKU,KKL,ZMWR, PDZZ)    ! -d(w'2r'  )/dz
+  ZFTH2 = -GZ_W_M(ZMTH2,PDZZ)    ! -d(w'th'2 )/dz
+  !ZFR2  = -GZ_W_M(ZMR2, PDZZ)    ! -d(w'r'2  )/dz
+  !ZFTHR = -GZ_W_M(ZMTHR,PDZZ)    ! -d(w'th'r')/dz
+#else
+  call Print_msg( NVERB_FATAL, 'GEN', 'TURB', 'OpenACC: TM06 not yet implemented' )
+  CALL TM06(KKA,KKU,KKL,PTHVREF,PBL_DEPTH,PZZ,PSFTH,ZMWTH,ZMTH2)
+!
+  CALL GZ_M_W_DEVICE(KKA,KKU,KKL,ZMWTH,PDZZ,ZFWTH)    ! -d(w'2th' )/dz
+  !CALL GZ_M_W_DEVICE(KKA,KKU,KKL,ZMWR, PDZZ,ZFWR)     ! -d(w'2r'  )/dz
+  CALL GZ_W_M_DEVICE(KKA,KKU,KKL,ZMTH2,PDZZ,ZFTH2)    ! -d(w'th'2 )/dz
+  !CALL GZ_W_M_DEVICE(KKA,KKU,KKL,ZMR2, PDZZ,ZFR2)     ! -d(w'r'2  )/dz
+  !CALL GZ_W_M_DEVICE(KKA,KKU,KKL,ZMTHR,PDZZ,ZFTHR)    ! -d(w'th'r')/dz
+!$acc kernels
+  ZFWTH = -ZFWTH
+  !ZFWR  = -ZFWR
+  ZFTH2 = -ZFTH2
+  !ZFR2  = -ZFR2
+  !ZFTHR = -ZFTHR
+#endif
+!
+  ZFWTH(:,:,IKTE:) = 0.
+  ZFWTH(:,:,:IKTB) = 0.
+  !ZFWR (:,:,IKTE:) = 0.
+  !ZFWR (:,:,:IKTB) = 0.
+  ZFWR  = 0.
+  ZFTH2(:,:,IKTE:) = 0.
+  ZFTH2(:,:,:IKTB) = 0.
+  !ZFR2 (:,:,IKTE:) = 0.
+  !ZFR2 (:,:,:IKTB) = 0.
+  ZFR2  = 0.
+  !ZFTHR(:,:,IKTE:) = 0.
+  !ZFTHR(:,:,:IKTB) = 0.
+  ZFTHR = 0.
+!$acc end kernels
+ELSE
+!$acc kernels
+  ZFWTH = 0.
+  ZFWR  = 0.
+  ZFTH2 = 0.
+  ZFR2  = 0.
+  ZFTHR = 0.
+!$acc end kernels
+ENDIF
+!
+!----------------------------------------------------------------------------
+!
+!*      5. TURBULENT SOURCES
+!          -----------------
+!
+!$acc update device(PRHODJ)
+!$acc update device(PRUS,PRVS,PRWS,PRSVS)
+CALL TURB_VER(KKA,KKU,KKL,KRR, KRRL, KRRI,               &
+          OCLOSE_OUT,OTURB_FLX,                          &
+          HTURBDIM,HTOM,PIMPL,ZEXPL,                     &
+          PTSTEP,TPFILE,                                 &
+          PDXX,PDYY,PDZZ,PDZX,PDZY,PDIRCOSZW,PZZ,        &
+          PCOSSLOPE,PSINSLOPE,                           &
+          PRHODJ,PTHVREF,                                &
+          PSFTH,PSFRV,PSFSV,PSFTH,PSFRV,PSFSV,           &
+          ZCDUEFF,ZTAU11M,ZTAU12M,ZTAU33M,               &
+          PUT,PVT,PWT,ZUSLOPE,ZVSLOPE,PTHLT,PRT,PSVT,    &
+          PTKET,PLEM,ZLEPS,                              &
+          ZLOCPEXNM,ZATHETA,ZAMOIST,PSRCT,ZFRAC_ICE,     &
+          ZFWTH,ZFWR,ZFTH2,ZFR2,ZFTHR,PBL_DEPTH,         &
+          PSBL_DEPTH,ZLMO,                               &
+          PRUS,PRVS,PRWS,PRTHLS,PRRS,PRSVS,              &
+          PDYP,PTHP,PSIGS,PWTH,PWRC,PWSV                 )
+!$acc update self(PWTH,PWRC,PWSV)
+!
+#ifdef MNH_OPENACC
+IF (  ( LBUDGET_TH .AND. ( ( KRRI >= 1 .AND. KRRL >= 1 ) .OR. ( KRRL >= 1 ) ) ) .OR. &
+      LBUDGET_RV .OR. LBUDGET_RC .OR. LBUDGET_RI ) THEN
+!$acc update self(PRRS)
+ENDIF
+#endif
+!
+IF (LBUDGET_U) THEN
+!$acc update self(PRUS)
+  CALL BUDGET (PRUS,1,'VTURB_BU_RU')
+END IF
+IF (LBUDGET_V) THEN
+!$acc update self(PRVS)
+  CALL BUDGET (PRVS,2,'VTURB_BU_RV')
+END IF
+IF (LBUDGET_W) THEN
+!$acc update self(PRWS)
+  CALL BUDGET (PRWS,3,'VTURB_BU_RW')
+END IF
+IF (LBUDGET_TH)  THEN
+!$acc update self(PRTHLS)
+  IF ( KRRI >= 1 .AND. KRRL >= 1 ) THEN
+!$acc update self(ZLVOCPEXNM,ZLSOCPEXNM)
+    CALL BUDGET (PRTHLS+ ZLVOCPEXNM * PRRS(:,:,:,2) + ZLSOCPEXNM * PRRS(:,:,:,4),4,'VTURB_BU_RTH')
+  ELSE IF ( KRRL >= 1 ) THEN
+!$acc update self(ZLOCPEXNM)
+    CALL BUDGET (PRTHLS+ ZLOCPEXNM * PRRS(:,:,:,2),4,'VTURB_BU_RTH')
+  ELSE
+    CALL BUDGET (PRTHLS,4,'VTURB_BU_RTH')
+  END IF
+END IF
+IF (LBUDGET_SV) THEN
+!$acc update self(PRSVS)
+  DO JSV = 1,NSV
+    CALL BUDGET (PRSVS(:,:,:,JSV),JSV+12,'VTURB_BU_RSV')
+  END DO
+END IF
+IF (LBUDGET_RV) THEN
+  IF ( KRRI >= 1 .AND. KRRL >= 1) THEN
+    CALL BUDGET (PRRS(:,:,:,1)-PRRS(:,:,:,2)-PRRS(:,:,:,4),6,'VTURB_BU_RRV')
+  ELSE IF ( KRRL >= 1 ) THEN
+    CALL BUDGET (PRRS(:,:,:,1)-PRRS(:,:,:,2),6,'VTURB_BU_RRV')
+  ELSE 
+    CALL BUDGET (PRRS(:,:,:,1),6,'VTURB_BU_RRV')
+  END IF
+END IF  
+IF (LBUDGET_RC) CALL BUDGET (PRRS(:,:,:,2),7,'VTURB_BU_RRC')
+IF (LBUDGET_RI) CALL BUDGET (PRRS(:,:,:,4),9,'VTURB_BU_RRI')
+!
+!
+IF (HTURBDIM=='3DIM') THEN
+    CALL TURB_HOR_SPLT(KSPLIT, KRR, KRRL, KRRI, PTSTEP,        &
+          HLBCX,HLBCY,OCLOSE_OUT,OTURB_FLX,OSUBG_COND,         &
+          TPFILE,                                              &
+          PDXX,PDYY,PDZZ,PDZX,PDZY,PZZ,                        &
+          PDIRCOSXW,PDIRCOSYW,PDIRCOSZW,                       &
+          PCOSSLOPE,PSINSLOPE,                                 &
+          PRHODJ,PTHVREF,                                      &
+          PSFTH,PSFRV,PSFSV,                                   &
+          ZCDUEFF,ZTAU11M,ZTAU12M,ZTAU22M,ZTAU33M,             &
+          PUT,PVT,PWT,ZUSLOPE,ZVSLOPE,PTHLT,PRT,PSVT,          &
+          PTKET,PLEM,ZLEPS,                                    &
+          ZLOCPEXNM,ZATHETA,ZAMOIST,PSRCT,ZFRAC_ICE,           &
+          PDYP,PTHP,PSIGS,                                     &
+          ZTRH,                                                &
+          PRUS,PRVS,PRWS,PRTHLS,PRRS,PRSVS                     )
+END IF
+!$acc update self(PSIGS,PRUS,PRVS,PRWS,PRSVS)
+!
+!
+#ifdef MNH_OPENACC
+IF (  ( LBUDGET_TH .AND. ( ( KRRI >= 1 .AND. KRRL >= 1 ) .OR. ( KRRL >= 1 ) ) ) .OR. &
+      LBUDGET_RV .OR. LBUDGET_RC .OR. LBUDGET_RI ) THEN
+!$acc update self(PRRS)
+ENDIF
+#endif
+!
+IF (LBUDGET_U) CALL BUDGET (PRUS,1,'HTURB_BU_RU')
+IF (LBUDGET_V) CALL BUDGET (PRVS,2,'HTURB_BU_RV')
+IF (LBUDGET_W) CALL BUDGET (PRWS,3,'HTURB_BU_RW')
+IF (LBUDGET_TH)  THEN
+!$acc update self(PRTHLS)
+  IF ( KRRI >= 1 .AND. KRRL >= 1 ) THEN
+    CALL BUDGET (PRTHLS+ZLVOCPEXNM*PRRS(:,:,:,2)+ZLSOCPEXNM*PRRS(:,:,:,4) &
+                                                  ,4,'HTURB_BU_RTH')
+  ELSE IF ( KRRL >= 1 ) THEN
+    CALL BUDGET (PRTHLS+ ZLOCPEXNM * PRRS(:,:,:,2),4,'HTURB_BU_RTH')
+  ELSE
+    CALL BUDGET (PRTHLS,4,'HTURB_BU_RTH')
+  END IF
+END IF
+IF (LBUDGET_SV) THEN
+  DO JSV = 1,NSV
+    CALL BUDGET (PRSVS(:,:,:,JSV),JSV+12,'HTURB_BU_RSV')
+  END DO
+END IF
+IF (LBUDGET_RV) THEN
+  IF ( KRRI >= 1 .AND. KRRL >= 1) THEN
+    CALL BUDGET (PRRS(:,:,:,1)-PRRS(:,:,:,2)-PRRS(:,:,:,4),6,'HTURB_BU_RRV')
+  ELSE IF ( KRRL >= 1 ) THEN
+    CALL BUDGET (PRRS(:,:,:,1)-PRRS(:,:,:,2),6,'HTURB_BU_RRV')
+  ELSE 
+    CALL BUDGET (PRRS(:,:,:,1),6,'HTURB_BU_RRV')
+  END IF
+END IF  
+IF (LBUDGET_RC) CALL BUDGET (PRRS(:,:,:,2),7,'HTURB_BU_RRC')
+IF (LBUDGET_RI) CALL BUDGET (PRRS(:,:,:,4),9,'HTURB_BU_RRI')
+!
+!----------------------------------------------------------------------------
+!
+!*      6. EVOLUTION OF THE TKE AND ITS DISSIPATION 
+!          ----------------------------------------
+!
+!  6.1 Contribution of mass-flux in the TKE buoyancy production if 
+!      cloud computation is not statistical 
+#ifndef MNH_OPENACC
+       PTHP = PTHP + XG / PTHVREF * MZF( PFLXZTHVMF )
+#else
+      CALL MZF_DEVICE(KKA,KKU,KKL,PFLXZTHVMF,ZTMP1_DEVICE)
+!$acc kernels
+      PTHP(:,:,:) = PTHP(:,:,:) + XG / PTHVREF(:,:,:) * ZTMP1_DEVICE(:,:,:)
+!$acc end kernels
+#endif
+
+!  6.2 TKE evolution equation
+!$acc update device(PRTKES)
+CALL TKE_EPS_SOURCES(KKA,KKU,KKL,KMI,PTKET,PLEM,ZLEPS,PDYP,ZTRH,     &
+                     PRHODJ,PDZZ,PDXX,PDYY,PDZX,PDZY,PZZ,            &
+                     PTSTEP,PIMPL,ZEXPL,                             &
+                     HTURBLEN,HTURBDIM,                              &
+                     TPFILE,OCLOSE_OUT,OTURB_DIAG,                   &
+                     PTHP,PRTKES,PRTKEMS,PRTHLS,ZCOEF_DISS,PTR,PDISS )
+!
+!$acc update self(PTR,PDISS)
+!$acc update self(PDYP,PTHP)
+!
+!$acc update self(PRTKES)
+IF (LBUDGET_TH)  THEN
+!$acc update self(PRTHLS)
+  IF ( KRRI >= 1 .AND. KRRL >= 1 ) THEN
+    CALL BUDGET (PRTHLS+ZLVOCPEXNM*PRRS(:,:,:,2)+ZLSOCPEXNM*PRRS(:,:,:,4) &
+                                                ,4,'DISSH_BU_RTH')
+  ELSE IF ( KRRL >= 1 ) THEN
+    CALL BUDGET (PRTHLS+ZLOCPEXNM* PRRS(:,:,:,2),4,'DISSH_BU_RTH')
+  ELSE
+    CALL BUDGET (PRTHLS,4,'DISSH_BU_RTH')
+  END IF
+END IF
+!
+!----------------------------------------------------------------------------
+!
+!*      7. STORES SOME INFORMATIONS RELATED TO THE TURBULENCE SCHEME
+!          ---------------------------------------------------------
+!
+!$acc update self(PLEM)
+!
+IF ( OTURB_DIAG .AND. OCLOSE_OUT ) THEN
+! 
+! stores the mixing length
+! 
+  TZFIELD%CMNHNAME   = 'LM'
+  TZFIELD%CSTDNAME   = ''
+  TZFIELD%CLONGNAME  = 'LM'
+  TZFIELD%CUNITS     = 'm'
+  TZFIELD%CDIR       = 'XY'
+  TZFIELD%CCOMMENT   = 'Mixing length'
+  TZFIELD%NGRID      = 1
+  TZFIELD%NTYPE      = TYPEREAL
+  TZFIELD%NDIMS      = 3
+  TZFIELD%LTIMEDEP   = .TRUE.
+  CALL IO_Field_write(TPFILE,TZFIELD,PLEM)
+!
+  IF (KRR /= 0) THEN
+!
+! stores the conservative potential temperature
+!
+    TZFIELD%CMNHNAME   = 'THLM'
+    TZFIELD%CSTDNAME   = ''
+    TZFIELD%CLONGNAME  = 'THLM'
+    TZFIELD%CUNITS     = 'K'
+    TZFIELD%CDIR       = 'XY'
+    TZFIELD%CCOMMENT   = 'Conservative potential temperature'
+    TZFIELD%NGRID      = 1
+    TZFIELD%NTYPE      = TYPEREAL
+    TZFIELD%NDIMS      = 3
+    TZFIELD%LTIMEDEP   = .TRUE.
+!$acc update self(PTHLT)
+    CALL IO_Field_write(TPFILE,TZFIELD,PTHLT)
+!
+! stores the conservative mixing ratio
+!
+    TZFIELD%CMNHNAME   = 'RNPM'
+    TZFIELD%CSTDNAME   = ''
+    TZFIELD%CLONGNAME  = 'RNPM'
+    TZFIELD%CUNITS     = 'kg kg-1'
+    TZFIELD%CDIR       = 'XY'
+    TZFIELD%CCOMMENT   = 'Conservative mixing ratio'
+    TZFIELD%NGRID      = 1
+    TZFIELD%NTYPE      = TYPEREAL
+    TZFIELD%NDIMS      = 3
+    TZFIELD%LTIMEDEP   = .TRUE.
+!$acc update self(PRT)
+    CALL IO_Field_write(TPFILE,TZFIELD,PRT(:,:,:,1))
+   END IF
+END IF
+!
+!----------------------------------------------------------------------------
+!
+!*      8. RETRIEVE NON-CONSERVATIVE VARIABLES
+!          -----------------------------------
+!
+IF ( KRRL >= 1 ) THEN
+  IF ( KRRI >= 1 ) THEN
+!$acc kernels
+    PRT(:,:,:,1)  = PRT(:,:,:,1)  - PRT(:,:,:,2)  - PRT(:,:,:,4)
+    PRRS(:,:,:,1) = PRRS(:,:,:,1) - PRRS(:,:,:,2) - PRRS(:,:,:,4)
+    PTHLT(:,:,:)  = PTHLT(:,:,:)  + ZLVOCPEXNM(:,:,:) * PRT(:,:,:,2) &
+                                  + ZLSOCPEXNM(:,:,:) * PRT(:,:,:,4)
+    PRTHLS(:,:,:) = PRTHLS(:,:,:) + ZLVOCPEXNM(:,:,:) * PRRS(:,:,:,2) &
+                                  + ZLSOCPEXNM(:,:,:) * PRRS(:,:,:,4)
+!$acc end kernels
+!$acc update self(PRT(:,:,:,1))
+!
+!$acc exit data delete( zlvocpexnm, zlsocpexnm )
+    DEALLOCATE(ZLVOCPEXNM)
+    DEALLOCATE(ZLSOCPEXNM)
+  ELSE
+!$acc kernels
+    PRT(:,:,:,1)  = PRT(:,:,:,1)  - PRT(:,:,:,2) 
+    PRRS(:,:,:,1) = PRRS(:,:,:,1) - PRRS(:,:,:,2)
+    PTHLT(:,:,:)  = PTHLT(:,:,:)  + ZLOCPEXNM(:,:,:) * PRT(:,:,:,2)
+    PRTHLS(:,:,:) = PRTHLS(:,:,:) + ZLOCPEXNM(:,:,:) * PRRS(:,:,:,2)
+!$acc end kernels
+!$acc update self(PRT(:,:,:,1))
+  END IF
+END IF
+!$acc update self(PRRS,PTHLT,PRTHLS)
+!
+IF ((HCLOUD == 'KHKO') .OR. (HCLOUD == 'C2R2')) THEN
+#ifdef MNH_OPENACC
+  call Print_msg( NVERB_FATAL, 'GEN', 'TURB', 'OpenACC: HCLOUD=KHKO or C2R2 not yet implemented' )
+#endif
+ ZEXNE(:,:,:)= (PPABST(:,:,:)/XP00)**(XRD/XCPD)
+ ZTT(:,:,:)= PTHLT(:,:,:)*ZEXNE(:,:,:)
+ ZLV(:,:,:)=XLVTT +(XCPV-XCL) *(ZTT(:,:,:)-XTT)
+ ZCPH(:,:,:)=XCPD +XCPV*PRT(:,:,:,1)
+! CALL GET_HALO(PRRS(:,:,:,2))
+! CALL GET_HALO(PRSVS(:,:,:,2))
+! CALL GET_HALO(PRSVS(:,:,:,3))
+ WHERE (PRRS(:,:,:,2) < 0. .OR. PRSVS(:,:,:,2) < 0.)
+      PRSVS(:,:,:,1) = 0.0
+ END WHERE
+ DO JSV = 2, 3
+  WHERE (PRRS(:,:,:,JSV) < 0. .OR. PRSVS(:,:,:,JSV) < 0.)
+      PRRS(:,:,:,1) = PRRS(:,:,:,1) + PRRS(:,:,:,JSV)
+      PRTHLS(:,:,:) = PRTHLS(:,:,:) - PRRS(:,:,:,JSV) * ZLV(:,:,:) /  &
+             ZCPH(:,:,:) / ZEXNE(:,:,:)
+      PRRS(:,:,:,JSV)  = 0.0
+      PRSVS(:,:,:,JSV) = 0.0
+  END WHERE
+ END DO
+!
+ IF (LBUDGET_TH) CALL BUDGET (PRTHLS(:,:,:), 4,'NETUR_BU_RTH')
+ IF (LBUDGET_RV) CALL BUDGET (PRRS(:,:,:,1), 6,'NETUR_BU_RRV')
+ IF (LBUDGET_RC) CALL BUDGET (PRRS(:,:,:,2), 7,'NETUR_BU_RRC')
+END IF
+!
+!----------------------------------------------------------------------------
+!
+!*      9. LES averaged surface fluxes
+!          ---------------------------
+!
+IF (LLES_CALL) THEN
+  CALL SECOND_MNH(ZTIME1)
+!$acc data copy(X_LES_Q0,X_LES_E0,X_LES_SV0,X_LES_UW0,X_LES_VW0,X_LES_USTAR)
+  CALL LES_MEAN_SUBGRID(PSFTH,X_LES_Q0)
+  CALL LES_MEAN_SUBGRID(PSFRV,X_LES_E0)
+  DO JSV=1,NSV
+    CALL LES_MEAN_SUBGRID(PSFSV(:,:,JSV),X_LES_SV0(:,JSV))
+  END DO
+  CALL LES_MEAN_SUBGRID(PSFU,X_LES_UW0)
+  CALL LES_MEAN_SUBGRID(PSFV,X_LES_VW0)
+#ifndef MNH_OPENACC
+  CALL LES_MEAN_SUBGRID((PSFU*PSFU+PSFV*PSFV)**0.25,X_LES_USTAR)
+#else
+!$acc kernels
+  ZTMP1_DEVICE(:,:,1) = (PSFU*PSFU+PSFV*PSFV)**0.25
+!$acc end kernels
+  CALL LES_MEAN_SUBGRID(ZTMP1_DEVICE(:,:,1),X_LES_USTAR)
+#endif
+!$acc end data
+!----------------------------------------------------------------------------
+!
+!*     10. LES for 3rd order moments
+!          -------------------------
+!
+!$acc data copy(X_LES_SUBGRID_W2Thl,X_LES_SUBGRID_WThl2)
+  CALL LES_MEAN_SUBGRID(ZMWTH,X_LES_SUBGRID_W2Thl)
+  CALL LES_MEAN_SUBGRID(ZMTH2,X_LES_SUBGRID_WThl2)
+!$acc end data
+  IF (KRR>0) THEN
+!$acc data copy(X_LES_SUBGRID_W2Rt,X_LES_SUBGRID_WThlRt,X_LES_SUBGRID_WRt2)
+    CALL LES_MEAN_SUBGRID(ZMWR,X_LES_SUBGRID_W2Rt)
+    CALL LES_MEAN_SUBGRID(ZMTHR,X_LES_SUBGRID_WThlRt)
+    CALL LES_MEAN_SUBGRID(ZMR2,X_LES_SUBGRID_WRt2)
+!$acc end data
+  END IF
+!
+!----------------------------------------------------------------------------
+!
+!*     11. LES quantities depending on <w'2> in "1DIM" mode
+!          ------------------------------------------------
+!
+#ifndef MNH_OPENACC
+  IF (HTURBDIM=="1DIM") THEN
+    CALL LES_MEAN_SUBGRID(2./3.*PTKET,X_LES_SUBGRID_U2)
+    X_LES_SUBGRID_V2 = X_LES_SUBGRID_U2
+    X_LES_SUBGRID_W2 = X_LES_SUBGRID_U2
+    CALL LES_MEAN_SUBGRID(2./3.*PTKET*MZF(&
+               & GZ_M_W(KKA,KKU,KKL,PTHLT,PDZZ)),X_LES_RES_ddz_Thl_SBG_W2)
+    IF (KRR>=1) &
+    CALL LES_MEAN_SUBGRID(2./3.*PTKET*MZF(&
+               & GZ_M_W(KKA,KKU,KKL,PRT(:,:,:,1),PDZZ)),X_LES_RES_ddz_Rt_SBG_W2)
+    DO JSV=1,NSV
+      CALL LES_MEAN_SUBGRID(2./3.*PTKET*MZF(&
+ & GZ_M_W(KKA,KKU,KKL,PSVT(:,:,:,JSV),PDZZ)),X_LES_RES_ddz_Sv_SBG_W2(:,:,:,JSV))
+    END DO
+  END IF
+#else
+  IF (HTURBDIM=="1DIM") THEN
+!$acc data copy(X_LES_SUBGRID_U2,X_LES_SUBGRID_V2,X_LES_SUBGRID_W2,X_LES_RES_ddz_Thl_SBG_W2)
+!$acc kernels
+    ZTMP1_DEVICE = 2./3.*PTKET
+!$acc end kernels
+    CALL LES_MEAN_SUBGRID(ZTMP1_DEVICE,X_LES_SUBGRID_U2)
+!$acc kernels
+    X_LES_SUBGRID_V2 = X_LES_SUBGRID_U2
+    X_LES_SUBGRID_W2 = X_LES_SUBGRID_U2
+!$acc end kernels
+    CALL GZ_M_W_DEVICE(KKA,KKU,KKL,PTHLT,PDZZ,ZTMP2_DEVICE)
+    CALL MZF_DEVICE(KKA,KKU,KKL,ZTMP2_DEVICE,ZTMP3_DEVICE)
+!$acc kernels
+      ZTMP2_DEVICE = ZTMP1_DEVICE*ZTMP3_DEVICE
+!$acc end kernels
+    CALL LES_MEAN_SUBGRID(ZTMP2_DEVICE,X_LES_RES_ddz_Thl_SBG_W2)
+!$acc end data
+    IF (KRR>=1) THEN
+!$acc data copy(X_LES_RES_ddz_Rt_SBG_W2)
+      CALL GZ_M_W_DEVICE(KKA,KKU,KKL,PRT(:,:,:,1),PDZZ,ZTMP2_DEVICE)
+      CALL MZF_DEVICE(KKA,KKU,KKL,ZTMP2_DEVICE,ZTMP3_DEVICE)
+!$acc kernels
+      ZTMP2_DEVICE = ZTMP1_DEVICE*PTKET*ZTMP3_DEVICE
+!$acc end kernels
+      CALL LES_MEAN_SUBGRID(ZTMP2_DEVICE,X_LES_RES_ddz_Rt_SBG_W2)
+!$acc end data
+    END IF
+!$acc data copy(X_LES_RES_ddz_Sv_SBG_W2(:,:,:,1:NSV))
+    DO JSV=1,NSV
+      CALL GZ_M_W_DEVICE(KKA,KKU,KKL,PSVT(:,:,:,JSV),PDZZ,ZTMP2_DEVICE)
+      CALL MZF_DEVICE(KKA,KKU,KKL,ZTMP2_DEVICE,ZTMP3_DEVICE)
+!$acc kernels
+      ZTMP2_DEVICE = ZTMP1_DEVICE*PTKET*ZTMP3_DEVICE
+!$acc end kernels
+      CALL LES_MEAN_SUBGRID(ZTMP2_DEVICE,X_LES_RES_ddz_Sv_SBG_W2(:,:,:,JSV))
+    END DO
+!$acc end data
+  END IF
+#endif
+!----------------------------------------------------------------------------
+!
+!*     12. LES mixing end dissipative lengths, presso-correlations
+!          -------------------------------------------------------
+!
+!$acc data copy(X_LES_SUBGRID_LMix,X_LES_SUBGRID_LDiss,X_LES_SUBGRID_WP)
+  CALL LES_MEAN_SUBGRID(PLEM,X_LES_SUBGRID_LMix)
+  CALL LES_MEAN_SUBGRID(ZLEPS,X_LES_SUBGRID_LDiss)
+!
+!* presso-correlations for subgrid Tke are equal to zero.
+!
+!$acc kernels
+  ZLEPS = 0. !ZLEPS is used as a work array (not used anymore)
+!$acc end kernels
+  CALL LES_MEAN_SUBGRID(ZLEPS,X_LES_SUBGRID_WP)
+!$acc end data
+!
+  CALL SECOND_MNH(ZTIME2)
+  XTIME_LES = XTIME_LES + ZTIME2 - ZTIME1
+END IF
+
+if ( mppdb_initialized ) then
+  !Check all inout arrays
+  call Mppdb_check( pbl_depth,  "Turb end:pbl_depth"  )
+  call Mppdb_check( psbl_depth, "Turb end:psbl_depth" )
+  call Mppdb_check( pthlt,      "Turb end:pthlt"      )
+  call Mppdb_check( prt,        "Turb end:prt"        )
+  call Mppdb_check( prus,       "Turb end:prus"       )
+  call Mppdb_check( prvs,       "Turb end:prvs"       )
+  call Mppdb_check( prws,       "Turb end:prws"       )
+  call Mppdb_check( prthls,     "Turb end:prthls"     )
+  call Mppdb_check( prtkes,     "Turb end:prtkes"     )
+  call Mppdb_check( prrs,       "Turb end:prrs"       )
+  call Mppdb_check( prsvs,      "Turb end:prsvs"      )
+  !check all out arrays
+  call Mppdb_check( psigs,      "Turb end:psigs"      )
+  call Mppdb_check( pwth,       "Turb end:pwth"       )
+  call Mppdb_check( pwrc,       "Turb end:pwrc"       )
+  call Mppdb_check( pwsv,       "Turb end:pwsv"       )
+  call Mppdb_check( pdyp,       "Turb end:pdyp"       )
+  call Mppdb_check( pthp,       "Turb end:pthp"       )
+  call Mppdb_check( ptr,        "Turb end:ptr"        )
+  call Mppdb_check( pdiss,      "Turb end:pdiss"      )
+  call Mppdb_check( plem,       "Turb end:plem"       )
+end if
+
+!$acc end data
+
+#ifndef MNH_OPENACC
+deallocate( zcp, zexn, zt, zlocpexnm, zleps, ztrh,         &
+            zatheta, zamoist, zcoef_diss, zfrac_ice,       &
+            zmwth, zmwr, zmth2, zmr2, zmthr,               &
+            zfwth, zfwr, zfth2, zfr2, zfthr, zthlm,        &
+            zrm,                                           &
+            ztau11m, ztau12m, ztau22m, ztau33m,            &
+            zuslope, zvslope, zcdueff, zlmo,               &
+            zustar, zrvm, zsfrv,                           &
+            ztt, zexne, zlv, zcph, zshear,  zdudz,  zdvdz  )
+#else
+
+CALL MNH_REL_ZT3D ( iztt, izexne, izlv, izcph, izshear,  izdudz,  izdvdz, &
+     iztmp1_device, iztmp2_device, iztmp3_device       )
+
+CALL MNH_REL_ZT3D ( iztau11m, iztau12m, iztau22m, iztau33m,   &
+                    izuslope, izvslope, izcdueff, izlmo,      &
+                    izustar, izrvm, izsfrv                   )
+
+CALL MNH_REL_ZT3D ( izrm)
+
+CALL MNH_REL_ZT3D ( izmwth, izmwr, izmth2, izmr2, izmthr,        &
+                    izfwth, izfwr, izfth2, izfr2, izfthr, izthlm )
+
+CALL MNH_REL_ZT3D ( izcp, izexn, izt, izlocpexnm, izleps, iztrh, &
+                    izatheta, izamoist, izcoef_diss, izfrac_ice  )
+
+CALL MNH_CHECK_OUT_ZT3D("TURB")
+#endif
+
+!$acc end data
+
+!----------------------------------------------------------------------------
+!
+CONTAINS
+!
+!
+!     ##############################################
+      SUBROUTINE UPDATE_ROTATE_WIND(PUSLOPE,PVSLOPE)
+!     ##############################################
+!!
+!!****  *UPDATE_ROTATE_WIND* routine to set rotate wind values at the border
+!
+!!    AUTHOR
+!!    ------
+!!
+!!     P Jabouille   *CNRM METEO-FRANCE
+!!
+!!    MODIFICATIONS
+!!    -------------
+!!      Original   24/06/99
+!!      J.Escobar 21/03/2013: for HALOK comment all NHALO=1 test
+!!
+!-------------------------------------------------------------------------------
+!
+!*       0.    DECLARATIONS
+!              ------------
+USE MODE_ll
+USE MODD_ARGSLIST_ll, ONLY : LIST_ll
+USE MODD_CONF
+!
+USE MODI_GET_HALO
+!
+IMPLICIT NONE
+!
+!*       0.1   Declarations of dummy arguments :
+!
+REAL, DIMENSION(:,:), INTENT(INOUT) :: PUSLOPE,PVSLOPE
+! tangential surface fluxes in the axes following the orography
+!
+!*       0.2   Declarations of local variables :
+!
+INTEGER             :: IIB,IIE,IJB,IJE ! index values for the physical subdomain
+TYPE(LIST_ll), POINTER :: TZFIELDS_ll  ! list of fields to exchange
+INTEGER                :: IINFO_ll     ! return code of parallel routine
+logical                :: gwest, geast, gnorth, gsouth
+!
+!*        1  PROLOGUE
+!
+!$acc data present( PUSLOPE, PVSLOPE )
+
+if ( mppdb_initialized ) then
+  !Check all inout arrays
+  call Mppdb_check( puslope, "Update_rotate_wind beg:puslope" )
+  call Mppdb_check( pvslope, "Update_rotate_wind beg:pvslope" )
+end if
+
+NULLIFY(TZFIELDS_ll)
+!
+CALL GET_INDICE_ll (IIB,IJB,IIE,IJE)
+!
+!         2 Update halo if necessary
+!
+!!$IF (NHALO == 1) THEN
+!!$!$acc update self(PUSLOPE,PVSLOPE)
+!!$  CALL ADD2DFIELD_ll( TZFIELDS_ll, PUSLOPE, 'UPDATE_ROTATE_WIND::PUSLOPE' )
+!!$  CALL ADD2DFIELD_ll( TZFIELDS_ll, PVSLOPE, 'UPDATE_ROTATE_WIND::PVSLOPE' )
+!!$  CALL UPDATE_HALO_ll(TZFIELDS_ll,IINFO_ll)
+!!$  CALL CLEANLIST_ll(TZFIELDS_ll)
+!!$!$acc update device(PUSLOPE,PVSLOPE)
+!
+!  /!\ warning conner needed -> GET_HALO...C
+!
+CALL GET_2D_HALO_DDC( PUSLOPE, HNAME='UPDATE_ROTATE_WIND::PUSLOPE' )
+CALL GET_2D_HALO_DDC( PVSLOPE, HNAME='UPDATE_ROTATE_WIND::PVSLOPE' )
+!!$ENDIF
+!
+!        3 Boundary conditions for non cyclic case
+!
+gwest  = HLBCX(1) /= "CYCL" .AND. LWEST_ll()
+geast  = HLBCX(2) /= "CYCL" .AND. LEAST_ll()
+gsouth = HLBCY(1) /= "CYCL" .AND. LSOUTH_ll()
+gnorth = HLBCY(2) /= "CYCL" .AND. LNORTH_ll()
+
+!$acc kernels
+IF ( gwest ) THEN
+  PUSLOPE(IIB-1,:)=PUSLOPE(IIB,:)
+  PVSLOPE(IIB-1,:)=PVSLOPE(IIB,:)
+END IF
+IF ( geast ) THEN
+  PUSLOPE(IIE+1,:)=PUSLOPE(IIE,:)
+  PVSLOPE(IIE+1,:)=PVSLOPE(IIE,:)
+END IF
+IF ( gsouth ) THEN
+  PUSLOPE(:,IJB-1)=PUSLOPE(:,IJB)
+  PVSLOPE(:,IJB-1)=PVSLOPE(:,IJB)
+END IF
+IF ( gnorth ) THEN
+  PUSLOPE(:,IJE+1)=PUSLOPE(:,IJE)
+  PVSLOPE(:,IJE+1)=PVSLOPE(:,IJE)
+END IF
+!$acc end kernels
+
+if ( mppdb_initialized ) then
+  !Check all inout arrays
+  call Mppdb_check( puslope, "Update_rotate_wind end:puslope" )
+  call Mppdb_check( pvslope, "Update_rotate_wind end:pvslope" )
+end if
+
+!$acc end data
+
+END SUBROUTINE UPDATE_ROTATE_WIND
+!
+!     ########################################################################
+      SUBROUTINE COMPUTE_FUNCTION_THERMO(PALP,PBETA,PGAM,PLTT,PC,PT,PEXN,PCP,&
+                                         PLOCPEXN,PAMOIST,PATHETA            )
+!     ########################################################################
+!!
+!!****  *COMPUTE_FUNCTION_THERMO* routine to compute several thermo functions
+!
+!!    AUTHOR
+!!    ------
+!!
+!!     JP Pinty      *LA*
+!!
+!!    MODIFICATIONS
+!!    -------------
+!!      Original   24/02/03
+!!
+!-------------------------------------------------------------------------------
+!
+!*       0.    DECLARATIONS
+!              ------------
+USE MODD_CST
+!
+IMPLICIT NONE
+!
+!*       0.1   Declarations of dummy arguments 
+!
+REAL,                   INTENT(IN)    :: PALP,PBETA,PGAM,PLTT,PC
+REAL, DIMENSION(:,:,:), INTENT(IN)    :: PT,PEXN,PCP
+!
+REAL, DIMENSION(:,:,:), INTENT(OUT)   :: PLOCPEXN
+REAL, DIMENSION(:,:,:), INTENT(OUT)   :: PAMOIST,PATHETA
+!
+!*       0.2   Declarations of local variables
+!
+REAL                :: ZEPS         ! XMV / XMD
+real, dimension(:,:,:), pointer , contiguous :: zrvsat
+real, dimension(:,:,:), pointer , contiguous :: zdrvsatdt
+INTEGER :: izrvsat, izdrvsatdt
+!
+!-------------------------------------------------------------------------------
+
+!$acc data present( PT, PEXN, PCP, PLOCPEXN, PAMOIST, PATHETA )
+
+  if ( mppdb_initialized ) then
+    !Check all in arrays
+    call Mppdb_check( pt,   "Compute_function_thermo beg:pt"   )
+    call Mppdb_check( pexn, "Compute_function_thermo beg:pexn" )
+    call Mppdb_check( pcp,  "Compute_function_thermo beg:pcp"  )
+  end if
+
+#ifndef MNH_OPENACC  
+  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_ZT3D( zrvsat   , size( pexn, 1 ), size( pexn, 2 ), size( pexn, 3 ) ) 
+izdrvsatdt = MNH_ALLOCATE_ZT3D( zdrvsatdt, size( pexn, 1 ), size( pexn, 2 ), size( pexn, 3 ) )
+#endif
+
+!$acc data present( zrvsat, zdrvsatdt )
+
+  ZEPS = XMV / XMD
+!
+!*       1.1 Lv/Cph at  t
+!
+!$acc kernels
+  PLOCPEXN(:,:,:) = ( PLTT + (XCPV-PC) *  (PT(:,:,:)-XTT) ) / PCP(:,:,:)
+!
+!*      1.2 Saturation vapor pressure at t
+!
+!PW: "BUG" PGI : results different on CPU and GPU due to the EXP and LOG functions
+!See http://www.pgroup.com/userforum/viewtopic.php?t=5364&sid=ec7b762b17fb9bb3332a47f0db57af55
+!Use of own functions allows bit-reproducible results
+#ifndef MNH_BITREP
+  ZRVSAT(:,:,:) =  EXP( PALP - PBETA/PT(:,:,:) - PGAM*ALOG( PT(:,:,:) ) )
+#else
+  DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+     ZRVSAT(JI,JJ,JK) =  BR_EXP( PALP - PBETA/PT(JI,JJ,JK) - PGAM*BR_LOG( PT(JI,JJ,JK) ) )
+  END DO
+#endif
+!
+!*      1.3 saturation  mixing ratio at t
+!
+  ZRVSAT(:,:,:) =  ZRVSAT(:,:,:) * ZEPS / ( PPABST(:,:,:) - ZRVSAT(:,:,:) )
+!
+!*      1.4 compute the saturation mixing ratio derivative (rvs')
+!
+  ZDRVSATDT(:,:,:) = ( PBETA / PT(:,:,:)  - PGAM ) / PT(:,:,:)   &
+                 * ZRVSAT(:,:,:) * ( 1. + ZRVSAT(:,:,:) / ZEPS )
+!
+!*      1.5 compute Amoist
+!
+  PAMOIST(:,:,:)=  0.5 / ( 1.0 + ZDRVSATDT(:,:,:) * PLOCPEXN(:,:,:) )
+!
+!*      1.6 compute Atheta
+!
+  PATHETA(:,:,:)= PAMOIST(:,:,:) * PEXN(:,:,:) *                             &
+        ( ( ZRVSAT(:,:,:) - PRT(:,:,:,1) ) * PLOCPEXN(:,:,:) /               &
+          ( 1. + ZDRVSATDT(:,:,:) * PLOCPEXN(:,:,:) )        *               &
+          (                                                                  &
+           ZRVSAT(:,:,:) * (1. + ZRVSAT(:,:,:)/ZEPS)                         &
+#ifndef MNH_BITREP
+                        * ( -2.*PBETA/PT(:,:,:) + PGAM ) / PT(:,:,:)**2      &
+#else
+                        * ( -2.*PBETA/PT(:,:,:) + PGAM ) / BR_P2(PT(:,:,:))  &
+#endif
+          +ZDRVSATDT(:,:,:) * (1. + 2. * ZRVSAT(:,:,:)/ZEPS)                 &
+                        * ( PBETA/PT(:,:,:) - PGAM ) / PT(:,:,:)             &
+          )                                                                  &
+         - ZDRVSATDT(:,:,:)                                                  &
+        )
+!
+!*      1.7 Lv/Cph/Exner at t-1
+!
+  PLOCPEXN(:,:,:) = PLOCPEXN(:,:,:) / PEXN(:,:,:)
+!$acc end kernels
+
+
+
+  if ( mppdb_initialized ) then
+    !Check all out arrays
+    call Mppdb_check( plocpexn, "Compute_function_thermo end:plocpexn" )
+    call Mppdb_check( pamoist,  "Compute_function_thermo end:pamoist"  )
+    call Mppdb_check( patheta,  "Compute_function_thermo end:patheta"  )
+  end if
+
+!$acc end data
+
+#ifndef MNH_OPENACC 
+  deallocate( zrvsat, zdrvsatdt )
+#else
+  CALL MNH_REL_ZT3D(izrvsat, izdrvsatdt )
+#endif
+ 
+!$acc end data
+
+END SUBROUTINE COMPUTE_FUNCTION_THERMO
+!
+!
+!     #########################
+      SUBROUTINE CLOUD_MODIF_LM
+!     #########################
+!!
+!!*****CLOUD_MODIF_LM routine to:
+!!       1/ change the mixing length in the clouds
+!!       2/ emphasize the mixing length in the cloud
+!!           by the coefficient ZCOEF_AMPL calculated here
+!!             when the CEI index is above ZCEI_MIN.
+!!
+!!
+!!      ZCOEF_AMPL ^
+!!                 |
+!!                 |
+!!  ZCOEF_AMPL_SAT -                       ---------- Saturation
+!!    (XDUMMY1)    |                      -
+!!                 |                     -
+!!                 |                    -
+!!                 |                   -
+!!                 |                  - Amplification
+!!                 |                 - straight
+!!                 |                - line
+!!                 |               -
+!!                 |              -
+!!                 |             -
+!!                 |            -
+!!                 |           -
+!!               1 ------------
+!!                 |
+!!                 |
+!!               0 -----------|------------|----------> PCEI
+!!                 0      ZCEI_MIN     ZCEI_MAX
+!!                        (XDUMMY2)    (XDUMMY3)
+!!
+!!
+!!
+!!    AUTHOR
+!!    ------
+!!     M. Tomasini   *CNRM METEO-FRANCE
+!!
+!!    MODIFICATIONS
+!!    -------------
+!!     Original   09/07/04
+!!
+!-------------------------------------------------------------------------------
+!
+!*       0.    DECLARATIONS
+!              ------------
+!
+IMPLICIT NONE
+!
+REAL :: ZPENTE            ! Slope of the amplification straight line
+REAL :: ZCOEF_AMPL_CEI_NUL! Ordonnate at the origin of the
+                          ! amplification straight line
+real, dimension(:,:,:), pointer , contiguous :: zcoef_ampl
+                          ! Amplification coefficient of the mixing length
+                          ! when the instability criterium is verified 
+real, dimension(:,:,:), pointer , contiguous :: zlm_cloud
+                          ! Turbulent mixing length in the clouds
+!
+!-------------------------------------------------------------------------------
+#ifdef MNH_OPENACC
+call Print_msg( NVERB_FATAL, 'GEN', 'TURB', 'OpenACC: CLOUD_MODIF_LM not yet implemented' )
+#endif
+
+allocate( zcoef_ampl(size( put, 1 ), size( put, 2 ), size( put, 3) ) )
+allocate( zlm_cloud (size( put, 1 ), size( put, 2 ), size( put, 3) ) )
+!
+!*       1.    INITIALISATION
+!              --------------
+!
+ZPENTE = ( PCOEF_AMPL_SAT - 1. ) / ( PCEI_MAX - PCEI_MIN ) 
+ZCOEF_AMPL_CEI_NUL = 1. - ZPENTE * PCEI_MIN
+!
+ZCOEF_AMPL(:,:,:) = 1.
+!
+!*       2.    CALCULATION OF THE AMPLIFICATION COEFFICIENT
+!              --------------------------------------------
+!
+! Saturation
+!
+WHERE ( PCEI(:,:,:)>=PCEI_MAX ) ZCOEF_AMPL(:,:,:)=PCOEF_AMPL_SAT
+!
+! Between the min and max limits of CEI index, linear variation of the
+! amplification coefficient ZCOEF_AMPL as a function of CEI
+!
+WHERE ( PCEI(:,:,:) <  PCEI_MAX .AND.                                        &
+        PCEI(:,:,:) >  PCEI_MIN      )                                       &
+        ZCOEF_AMPL(:,:,:) = ZPENTE * PCEI(:,:,:) + ZCOEF_AMPL_CEI_NUL  
+!
+!
+!*       3.    CALCULATION OF THE MIXING LENGTH IN CLOUDS
+!              ------------------------------------------
+!
+IF (HTURBLEN_CL == HTURBLEN) THEN
+  ZLM_CLOUD(:,:,:) = PLEM(:,:,:)
+ELSE
+  SELECT CASE (HTURBLEN_CL)
+!
+!*         3.1 BL89 mixing length
+!           ------------------
+  CASE ('BL89','RM17')
+!$acc kernels
+    ZSHEAR(:, :, : ) = 0.
+!$acc end kernels
+    CALL BL89(KKA,KKU,KKL,PZZ,PDZZ,PTHVREF,ZTHLM,KRR,ZRM,PTKET,ZSHEAR,ZLM_CLOUD)
+!
+!*         3.2 Delta mixing length
+!           -------------------
+  CASE ('DELT')
+    CALL DELT(KKA,KKU,KKL,IKB, IKE,IKTB, IKTE,ORMC01,HTURBDIM,PDXX, PDYY,PZZ,PDIRCOSZW,ZLM_CLOUD)
+!
+!*         3.3 Deardorff mixing length
+!           -----------------------
+  CASE ('DEAR')
+    CALL DEAR(KKA,KKU,KKL,KRR, KRRI, IKB, IKE,IKTB, IKTE, &
+                ORMC01,HTURBDIM,PDXX, PDYY, PDZZ,PZZ,PDIRCOSZW,PTHLT,PTHVREF,PTKET,PSRCT,PRT,&
+                ZLOCPEXNM,ZATHETA, ZAMOIST, ZLM_CLOUD)
+!
+  END SELECT
+ENDIF
+!
+!*       4.    MODIFICATION OF THE MIXING LENGTH IN THE CLOUDS
+!              -----------------------------------------------
+!
+! Impression before modification of the mixing length
+IF ( OTURB_DIAG .AND. OCLOSE_OUT ) THEN
+  TZFIELD%CMNHNAME   = 'LM_CLEAR_SKY'
+  TZFIELD%CSTDNAME   = ''
+  TZFIELD%CLONGNAME  = 'LM_CLEAR_SKY'
+  TZFIELD%CUNITS     = 'm'
+  TZFIELD%CDIR       = 'XY'
+  TZFIELD%CCOMMENT   = 'X_Y_Z_LM CLEAR SKY'
+  TZFIELD%NGRID      = 1
+  TZFIELD%NTYPE      = TYPEREAL
+  TZFIELD%NDIMS      = 3
+  TZFIELD%LTIMEDEP   = .TRUE.
+  CALL IO_Field_write(TPFILE,TZFIELD,PLEM)
+ENDIF
+!
+! Amplification of the mixing length when the criteria are verified
+!
+WHERE (ZCOEF_AMPL(:,:,:) /= 1.) PLEM(:,:,:) = ZCOEF_AMPL(:,:,:)*ZLM_CLOUD(:,:,:)
+!
+! Cloud mixing length in the clouds at the points which do not verified the CEI
+!
+WHERE (PCEI(:,:,:) == -1.) PLEM(:,:,:) = ZLM_CLOUD(:,:,:)
+!
+!
+!*       5.    IMPRESSION
+!              ----------
+!
+IF ( OTURB_DIAG .AND. OCLOSE_OUT ) THEN
+  TZFIELD%CMNHNAME   = 'COEF_AMPL'
+  TZFIELD%CSTDNAME   = ''
+  TZFIELD%CLONGNAME  = 'COEF_AMPL'
+  TZFIELD%CUNITS     = '1'
+  TZFIELD%CDIR       = 'XY'
+  TZFIELD%CCOMMENT   = 'X_Y_Z_COEF AMPL'
+  TZFIELD%NGRID      = 1
+  TZFIELD%NTYPE      = TYPEREAL
+  TZFIELD%NDIMS      = 3
+  TZFIELD%LTIMEDEP   = .TRUE.
+  CALL IO_Field_write(TPFILE,TZFIELD,ZCOEF_AMPL)
+  !
+  TZFIELD%CMNHNAME   = 'LM_CLOUD'
+  TZFIELD%CSTDNAME   = ''
+  TZFIELD%CLONGNAME  = 'LM_CLOUD'
+  TZFIELD%CUNITS     = 'm'
+  TZFIELD%CDIR       = 'XY'
+  TZFIELD%CCOMMENT   = 'X_Y_Z_LM CLOUD'
+  TZFIELD%NGRID      = 1
+  TZFIELD%NTYPE      = TYPEREAL
+  TZFIELD%NDIMS      = 3
+  CALL IO_Field_write(TPFILE,TZFIELD,ZLM_CLOUD)
+  !
+ENDIF
+
+deallocate( zcoef_ampl, zlm_cloud )
+
+END SUBROUTINE CLOUD_MODIF_LM
+!
+END SUBROUTINE TURB
+
+
+
+!###################
+SUBROUTINE DELT(KKA,KKU,KKL,KKB, KKE,KKTB, KKTE,ORMC01,HTURBDIM,PDXX, PDYY,PZZ,PDIRCOSZW,PLM)
+!###################
+!!
+!!****  *DELT* routine to compute mixing length for DELT case
+!
+!!    AUTHOR
+!!    ------
+!!
+!!     M Tomasini      *Meteo-France
+!!
+!!    MODIFICATIONS
+!!    -------------
+!!      Original   01/05
+!!
+!  P. Wautelet 18/07/2019: add OpenACC directives
+!-------------------------------------------------------------------------------
+!
+!*       0.    DECLARATIONS
+!              ------------
+use modd_conf, only: l2d
+
+use mode_mppdb
+
+#ifndef MNH_OPENACC
+USE MODI_SHUMAN
+#else
+USE MODI_SHUMAN_DEVICE
+#endif
+
+implicit none
+!
+!*       0.1   Declarations of dummy arguments
+!
+INTEGER,                INTENT(IN)   :: KKA           !near ground array index
+INTEGER,                INTENT(IN)   :: KKU           !uppest atmosphere array index
+INTEGER,                INTENT(IN)   :: KKL           !vert. levels type 1=MNH -1=ARO
+INTEGER,  intent(in)             :: KKB, KKE      ! index value for the
+! Beginning and the End of the physical domain for the mass points
+INTEGER, intent(in)  :: KKTB, KKTE    ! start, end of k loops in physical domain
+LOGICAL,                INTENT(IN)   ::  ORMC01       ! switch for RMC01 lengths in SBL
+CHARACTER(len=4),       INTENT(IN)   ::  HTURBDIM     ! dimensionality of the
+                                                      ! turbulence scheme
+REAL, DIMENSION(:,:,:), INTENT(IN)   :: PDXX, PDYY
+                                        ! metric coefficients
+REAL, DIMENSION(:,:,:), INTENT(IN)   :: PZZ       !  physical distance
+! between 2 succesive grid points along the K direction
+REAL, DIMENSION(:,:),   INTENT(IN)      ::  PDIRCOSZW
+! Director Cosinus along x, y and z directions at surface w-point
+REAL, DIMENSION(:,:,:), INTENT(OUT)   :: PLM
+!
+!
+!*       0.2   Declarations of local variables
+!
+
+integer :: ji, jj, jk
+REAL                :: ZALPHA       ! proportionnality constant between Dz/2 and
+!                                   ! BL89 mixing length near the surface
+REAL                :: ZD           ! distance to the surface
+#ifdef MNH_OPENACC
+real, dimension(:,:,:), pointer , contiguous :: ztmp1_device, ztmp2_device
+#endif
+!
+!-------------------------------------------------------------------------------
+
+!$acc data present( PDXX, PDYY, PZZ, PDIRCOSZW, PLM )
+
+if ( mppdb_initialized ) then
+  !Check all in arrays
+  call Mppdb_check( pdxx,      "Delt beg:pdxx"      )
+  call Mppdb_check( pdyy,      "Delt beg:pdyy"      )
+  call Mppdb_check( pzz,       "Delt beg:pzz"       )
+  call Mppdb_check( pdircoszw, "Delt beg:pdircoszw" )
+end if
+
+#ifdef MNH_OPENACC
+allocate( ztmp1_device( size( pdxx, 1 ), size( pdxx, 2 ), size( pdxx, 3 ) ) )
+allocate( ztmp2_device( size( pdxx, 1 ), size( pdxx, 2 ), size( pdxx, 3 ) ) )
+#endif
+
+!$acc data create( ztmp1_device, ztmp2_device )
+
+!$acc kernels
+DO JK = KKTB,KKTE ! 1D turbulence scheme
+  PLM(:,:,JK) = PZZ(:,:,JK+KKL) - PZZ(:,:,JK)
+END DO
+PLM(:,:,KKU) = PLM(:,:,KKE)
+PLM(:,:,KKA) = PZZ(:,:,KKB) - PZZ(:,:,KKA)
+!$acc end kernels
+IF ( HTURBDIM /= '1DIM' ) THEN  ! 3D turbulence scheme
+  IF ( L2D ) THEN
+#ifndef MNH_OPENACC
+    PLM(:,:,:) = SQRT( PLM(:,:,:)*MXF(PDXX(:,:,:)) )
+#else
+    CALL MXF_DEVICE( PDXX, ZTMP1_DEVICE )
+!$acc kernels
+    PLM(:,:,:) = SQRT( PLM(:,:,:) * ZTMP1_DEVICE )
+!$acc end kernels
+#endif
+  ELSE
+#ifndef MNH_OPENACC
+#ifndef MNH_BITREP
+    PLM(:,:,:) = (PLM(:,:,:)*MXF(PDXX(:,:,:))*MYF(PDYY(:,:,:)) ) ** (1./3.)
+#else
+    PLM(:,:,:) = BR_POW( PLM(:, :, : ) * MXF( PDXX(:, :, : ) ) * MYF( PDYY(:, :, : ) ), 1. / 3. )
+#endif
+#else
+    CALL MXF_DEVICE( PDXX, ZTMP1_DEVICE )
+    CALL MYF_DEVICE( PDYY, ZTMP2_DEVICE )
+!$acc kernels
+#ifndef MNH_BITREP
+    PLM(:,:,:) = ( PLM(:,:,:) * ZTMP1_DEVICE * ZTMP2_DEVICE ) ** (1./3.)
+#else
+    PLM(:,:,:) = BR_POW( PLM(:,:,:) * ZTMP1_DEVICE * ZTMP2_DEVICE, 1./3. )
+#endif
+!$acc end kernels
+#endif
+  END IF
+END IF
+!
+!  mixing length limited by the distance normal to the surface
+!  (with the same factor as for BL89)
+!
+!$acc kernels
+IF (.NOT. ORMC01) THEN
+#ifndef MNH_BITREP
+  ZALPHA = 0.5**(-1.5)
+#else
+  ZALPHA = BR_POW( 0.5, -1.5 )
+#endif
+  !
+  DO JJ=1,SIZE(PLM,2)
+    DO JI=1,SIZE(PLM,1)
+      DO JK=KKTB,KKTE
+        ZD = ZALPHA * ( 0.5 * ( PZZ(JI, JJ, JK ) + PZZ(JI, JJ, JK+KKL ) ) - PZZ(JI, JJ, KKB ) ) * PDIRCOSZW(JI, JJ )
+        IF ( PLM(JI,JJ,JK) > ZD ) THEN
+          PLM(JI,JJ,JK) = ZD
+        ELSE
+          EXIT
+        ENDIF
+      END DO
+    END DO
+  END DO
+END IF
+!
+PLM(:,:,KKA) = PLM(:,:,KKB  )
+PLM(:,:,KKU  ) = PLM(:,:,KKE)
+!$acc end kernels
+
+if ( mppdb_initialized ) then
+  !Check all out arrays
+  call Mppdb_check( plm, "Delt end:plm" )
+end if
+
+!$acc end data
+
+!$acc end data
+
+END SUBROUTINE DELT
+
+
+
+!###################
+SUBROUTINE DEAR(KKA,KKU,KKL,KRR, KRRI, KKB, KKE,KKTB, KKTE, &
+                ORMC01,HTURBDIM,PDXX, PDYY, PDZZ,PZZ,PDIRCOSZW,PTHLT,PTHVREF,PTKET,PSRCT,PRT,&
+                PLOCPEXNM,PATHETA, PAMOIST, PLM)
+!###################
+!!
+!!****  *DEAR* routine to compute mixing length for DEARdorff case
+!
+!!    AUTHOR
+!!    ------
+!!
+!!     M Tomasini      *Meteo-France
+!!
+!!    MODIFICATIONS
+!!    -------------
+!!      Original   01/05
+!!      I.Sandu (Sept.2006) : Modification of the stability criterion
+!!                            (theta_v -> theta_l)
+!!
+!-------------------------------------------------------------------------------
+!
+!*       0.    DECLARATIONS
+!              ------------
+use modd_conf, only: l2d
+use modd_cst,  only: XG, XMNH_EPSILON
+
+use mode_mppdb
+
+USE MODI_EMOIST
+USE MODI_ETHETA
+#ifndef MNH_OPENACC
+USE MODI_SHUMAN
+#else
+USE MODI_SHUMAN_DEVICE
+#endif
+
+implicit none
+!
+!*       0.1   Declarations of dummy arguments
+!
+INTEGER,                INTENT(IN)   :: KKA           !near ground array index
+INTEGER,                INTENT(IN)   :: KKU           !uppest atmosphere array index
+INTEGER,                INTENT(IN)   :: KKL           !vert. levels type 1=MNH -1=ARO
+INTEGER,                INTENT(IN)   :: KRR           ! number of moist var.
+INTEGER,                INTENT(IN)   :: KRRI          ! number of ice water var.
+INTEGER,  intent(in)             :: KKB, KKE      ! index value for the
+! Beginning and the End of the physical domain for the mass points
+INTEGER, intent(in)  :: KKTB, KKTE    ! start, end of k loops in physical domain
+LOGICAL,                INTENT(IN)   ::  ORMC01       ! switch for RMC01 lengths in SBL
+CHARACTER(len=4),       INTENT(IN)   ::  HTURBDIM     ! dimensionality of the
+                                                      ! turbulence scheme
+REAL, DIMENSION(:,:,:), INTENT(IN)   :: PDXX, PDYY, PDZZ
+                                        ! metric coefficients
+REAL, DIMENSION(:,:,:), INTENT(IN)   :: PZZ       !  physical distance
+! between 2 succesive grid points along the K direction
+REAL, DIMENSION(:,:),   INTENT(IN)      ::  PDIRCOSZW
+! Director Cosinus along x, y and z directions at surface w-point
+REAL, DIMENSION(:,:,:),   INTENT(IN) ::  PTHLT       ! conservative pot. temp.
+REAL, DIMENSION(:,:,:), INTENT(IN)      ::  PTHVREF   ! Virtual Potential
+                                        ! Temperature of the reference state
+REAL, DIMENSION(:,:,:),   INTENT(IN) ::  PTKET       ! TKE
+REAL, DIMENSION(:,:,:),   INTENT(IN) ::  PSRCT       ! Second-order flux
+                      ! s'rc'/2Sigma_s2 at time t-1 multiplied by Lambda_3
+REAL, DIMENSION(:,:,:,:), INTENT(IN) ::  PRT         ! water var.  where
+                             ! PRT(:,:,:,1) is the conservative mixing ratio
+REAL, DIMENSION(:,:,:),   INTENT(IN) :: PLOCPEXNM  ! Lv/Cp/EXNREF at t-1
+REAL, DIMENSION(:,:,:),   INTENT(IN) :: PATHETA, PAMOIST  ! coefficients for s = f (Thetal,Rnp)
+REAL, DIMENSION(:,:,:), INTENT(OUT)   :: PLM
+!
+!*       0.2   Declarations of local variables
+!
+integer :: ji, jj, jk
+REAL                :: ZALPHA       ! proportionnality constant between Dz/2 and
+!                                   ! BL89 mixing length near the surface
+REAL                :: ZD           ! distance to the surface
+REAL                :: ZVAR         ! Intermediary variable
+REAL, DIMENSION(:,:), POINTER , CONTIGUOUS ::   ZWORK2D
+!
+REAL, DIMENSION(:,:,:), POINTER , CONTIGUOUS ::     &
+            ZDTHLDZ,ZDRTDZ,     &!dtheta_l/dz, drt_dz used for computing the stablity
+!                                ! criterion
+            ZETHETA,ZEMOIST             !coef ETHETA and EMOIST
+INTEGER :: IZWORK2D,IZDTHLDZ,IZDRTDZ,IZETHETA,IZEMOIST
+!
+#ifdef MNH_OPENACC
+REAL, DIMENSION(:,:,:), POINTER , CONTIGUOUS :: ZTMP1_DEVICE,ZTMP2_DEVICE
+INTEGER :: IZTMP1_DEVICE,IZTMP2_DEVICE
+#endif
+INTEGER  :: JIU,JJU,JKU
+!----------------------------------------------------------------------------
+
+!$acc data present( PDXX, PDYY, PDZZ, PZZ, PDIRCOSZW, PTHLT, PTHVREF, PTKET, PSRCT, PRT, PLOCPEXNM, PATHETA, PAMOIST, PLM )
+
+if ( mppdb_initialized ) then
+  !Check all in arrays
+  call Mppdb_check( pdxx,      "Dear beg:pdxx"      )
+  call Mppdb_check( pdyy,      "Dear beg:pdyy"      )
+  call Mppdb_check( pdzz,      "Dear beg:pdzz"      )
+  call Mppdb_check( pzz,       "Dear beg:pzz"       )
+  call Mppdb_check( pdircoszw, "Dear beg:pdircoszw" )
+  call Mppdb_check( pthlt,     "Dear beg:pthlt"     )
+  call Mppdb_check( pthvref,   "Dear beg:pthvref"   )
+  call Mppdb_check( ptket,     "Dear beg:ptket"     )
+  call Mppdb_check( psrct,     "Dear beg:psrct"     )
+  call Mppdb_check( prt,       "Dear beg:prt"       )
+  call Mppdb_check( plocpexnm, "Dear beg:plocpexnm" )
+  call Mppdb_check( patheta,   "Dear beg:patheta"   )
+  call Mppdb_check( pamoist,   "Dear beg:pamoist"   )
+end if
+
+JIU =  size(pthlt, 1 )
+JJU =  size(pthlt, 2 )
+JKU =  size(pthlt, 3 )
+
+!-------------------------------------------------------------------------------
+#ifndef MNH_OPENACC
+allocate( ZWORK2D(JIU,JJU) )
+allocate( ZDTHLDZ(JIU,JJU,JKU) )
+allocate( ZDRTDZ (JIU,JJU,JKU) )
+allocate( ZETHETA(JIU,JJU,JKU) )
+allocate( ZEMOIST(JIU,JJU,JKU) )
+#else
+IZWORK2D = MNH_ALLOCATE_ZT2D( ZWORK2D,JIU,JJU)
+IZDTHLDZ = MNH_ALLOCATE_ZT3D( ZDTHLDZ,JIU,JJU,JKU)
+IZDRTDZ  = MNH_ALLOCATE_ZT3D( ZDRTDZ ,JIU,JJU,JKU)
+IZETHETA = MNH_ALLOCATE_ZT3D( ZETHETA,JIU,JJU,JKU)
+IZEMOIST = MNH_ALLOCATE_ZT3D( ZEMOIST,JIU,JJU,JKU)
+#endif
+
+#ifdef MNH_OPENACC
+IZTMP1_DEVICE = MNH_ALLOCATE_ZT3D( ZTMP1_DEVICE,JIU,JJU,JKU)
+IZTMP2_DEVICE = MNH_ALLOCATE_ZT3D( ZTMP2_DEVICE,JIU,JJU,JKU)
+#endif
+
+!$acc data present(zwork2d, zdthldz, zdrtdz, zetheta, zemoist, &
+!$acc &            ztmp1_device, ztmp2_device )
+
+!
+!   initialize the mixing length with the mesh grid
+!$acc kernels
+! 1D turbulence scheme
+PLM(:,:,KKTB:KKTE) = PZZ(:,:,KKTB+KKL:KKTE+KKL) - PZZ(:,:,KKTB:KKTE)
+PLM(:,:,KKU) = PLM(:,:,KKE)
+PLM(:,:,KKA) = PZZ(:,:,KKB) - PZZ(:,:,KKA)
+!$acc end kernels
+IF ( HTURBDIM /= '1DIM' ) THEN  ! 3D turbulence scheme
+  IF ( L2D) THEN
+#ifndef MNH_OPENACC
+    PLM(:,:,:) = SQRT( PLM(:,:,:)*MXF(PDXX(:,:,:)) )
+#else
+    CALL MXF_DEVICE(PDXX,ZTMP1_DEVICE)
+!$acc kernels
+    PLM(:,:,:) = SQRT( PLM(:,:,:)*ZTMP1_DEVICE )
+!$acc end kernels
+    if ( mppdb_initialized ) then
+       call Mppdb_check( ZTMP1_DEVICE , "Dear mid: ZTMP1_DEVICE=Mxf" )
+       call Mppdb_check( plm, "Dear mid:plm" )
+    end if
+#endif
+  ELSE
+!PW: "BUG" PGI : results different on CPU and GPU due to the power function
+!See http://www.pgroup.com/userforum/viewtopic.php?t=5364&sid=ec7b762b17fb9bb3332a47f0db57af55
+!Use of own functions allows bit-reproducible results
+#ifndef MNH_BITREP
+!
+#ifndef MNH_OPENACC
+    PLM(:,:,:) = (PLM(:,:,:)*MXF(PDXX(:,:,:))*MYF(PDYY(:,:,:)) ) ** (1./3.)
+#else
+    CALL MXF_DEVICE(PDXX,ZTMP1_DEVICE)
+    CALL MYF_DEVICE(PDYY,ZTMP2_DEVICE)
+!$acc kernels
+    PLM(:,:,:) = (PLM(:,:,:)*ZTMP1_DEVICE*ZTMP2_DEVICE ) ** (1./3.)
+!$acc end kernels
+    if ( mppdb_initialized ) then
+       call Mppdb_check( ZTMP1_DEVICE , "Dear mid: ZTMP1_DEVICE=Mxf" )
+       call Mppdb_check( ZTMP2_DEVICE , "Dear mid: ZTMP2_DEVICE=Myf" )
+       call Mppdb_check( plm, "Dear mid:plm" )
+    end if
+#endif
+!
+#else
+!
+#ifndef MNH_OPENACC
+    PLM(:,:,:) = BR_POW( PLM(:,:,:)*MXF(PDXX(:,:,:))*MYF(PDYY(:,:,:)) , 1./3. )
+#else
+    CALL MXF_DEVICE(PDXX,ZTMP1_DEVICE)
+    CALL MYF_DEVICE(PDYY,ZTMP2_DEVICE)
+    if ( mppdb_initialized ) then
+       call Mppdb_check( ZTMP1_DEVICE , "Dear mid: ZTMP1_DEVICE=Mxf" )
+       call Mppdb_check( ZTMP2_DEVICE , "Dear mid: ZTMP2_DEVICE=Myf" )
+       call Mppdb_check( plm, "Dear mid1:plm" )
+    end if
+!$acc kernels
+    PLM(:,:,:) = BR_POW( PLM(:,:,:)*ZTMP1_DEVICE    *ZTMP2_DEVICE     , 1./3. )
+!$acc end kernels
+    if ( mppdb_initialized ) then
+       call Mppdb_check( plm, "Dear mid2:plm" )
+    end if
+#endif
+#endif
+  END IF
+END IF
+!   compute a mixing length limited by the stability
+!
+#ifndef MNH_OPENACC
+ZETHETA(:,:,:) = ETHETA(KRR,KRRI,PTHLT,PRT,PLOCPEXNM,PATHETA,PSRCT)
+ZEMOIST(:,:,:) = EMOIST(KRR,KRRI,PTHLT,PRT,PLOCPEXNM,PAMOIST,PSRCT)
+#else
+CALL ETHETA(KRR,KRRI,PTHLT,PRT,PLOCPEXNM,PATHETA,PSRCT,ZETHETA)
+CALL EMOIST(KRR,KRRI,PTHLT,PRT,PLOCPEXNM,PAMOIST,PSRCT,ZEMOIST)
+#endif
+!
+!$acc kernels
+! For dry simulations
+IF (KRR>0) THEN
+!$acc loop independent collapse(3) private(ZVAR)
+  DO JK = KKTB+1,KKTE-1
+    DO JJ=1,SIZE(PLM,2)
+      DO JI=1,SIZE(PLM,1)
+        ZDTHLDZ(JI,JJ,JK)= 0.5*((PTHLT(JI,JJ,JK+KKL)-PTHLT(JI,JJ,JK    ))/PDZZ(JI,JJ,JK+KKL)+ &
+                                (PTHLT(JI,JJ,JK    )-PTHLT(JI,JJ,JK-KKL))/PDZZ(JI,JJ,JK    ))
+        ZDRTDZ(JI,JJ,JK) = 0.5*((PRT(JI,JJ,JK+KKL,1)-PRT(JI,JJ,JK    ,1))/PDZZ(JI,JJ,JK+KKL)+ &
+                                (PRT(JI,JJ,JK    ,1)-PRT(JI,JJ,JK-KKL,1))/PDZZ(JI,JJ,JK    ))
+        ZVAR=XG/PTHVREF(JI,JJ,JK)*                                                  &
+             (ZETHETA(JI,JJ,JK)*ZDTHLDZ(JI,JJ,JK)+ZEMOIST(JI,JJ,JK)*ZDRTDZ(JI,JJ,JK))
+        !
+        IF (ZVAR>0.) THEN
+          PLM(JI,JJ,JK)=MAX(XMNH_EPSILON,MIN(PLM(JI,JJ,JK), &
+                        0.76* SQRT(PTKET(JI,JJ,JK)/ZVAR)))
+        END IF
+      END DO
+    END DO
+  END DO
+ELSE
+!$acc loop independent collapse(3) private(ZVAR)
+  DO JK = KKTB+1,KKTE-1
+    DO JJ=1,SIZE(PLM,2)
+      DO JI=1,SIZE(PLM,1)
+        ZDTHLDZ(JI,JJ,JK)= 0.5*((PTHLT(JI,JJ,JK+KKL)-PTHLT(JI,JJ,JK    ))/PDZZ(JI,JJ,JK+KKL)+ &
+                                (PTHLT(JI,JJ,JK    )-PTHLT(JI,JJ,JK-KKL))/PDZZ(JI,JJ,JK    ))
+        ZVAR=XG/PTHVREF(JI,JJ,JK)*ZETHETA(JI,JJ,JK)*ZDTHLDZ(JI,JJ,JK)
+        !
+        IF (ZVAR>0.) THEN
+          PLM(JI,JJ,JK)=MAX(XMNH_EPSILON,MIN(PLM(JI,JJ,JK), &
+                        0.76* SQRT(PTKET(JI,JJ,JK)/ZVAR)))
+        END IF
+      END DO
+    END DO
+  END DO
+END IF
+!  special case near the surface
+ZDTHLDZ(:,:,KKB)=(PTHLT(:,:,KKB+KKL)-PTHLT(:,:,KKB))/PDZZ(:,:,KKB+KKL)
+! For dry simulations
+IF (KRR>0) THEN
+  ZDRTDZ(:,:,KKB)=(PRT(:,:,KKB+KKL,1)-PRT(:,:,KKB,1))/PDZZ(:,:,KKB+KKL)
+ELSE
+  ZDRTDZ(:,:,KKB)=0
+ENDIF
+!
+ZWORK2D(:,:)=XG/PTHVREF(:,:,KKB)*                                           &
+            (ZETHETA(:,:,KKB)*ZDTHLDZ(:,:,KKB)+ZEMOIST(:,:,KKB)*ZDRTDZ(:,:,KKB))
+WHERE(ZWORK2D(:,:)>0.)
+  PLM(:,:,KKB)=MAX(XMNH_EPSILON,MIN( PLM(:,:,KKB),                 &
+                    0.76* SQRT(PTKET(:,:,KKB)/ZWORK2D(:,:))))
+END WHERE
+!
+!  mixing length limited by the distance normal to the surface (with the same factor as for BL89)
+!
+IF (.NOT. ORMC01) THEN
+  ZALPHA=0.5**(-1.5)
+  !
+  DO JJ=1,SIZE(PLM,2)
+    DO JI=1,SIZE(PLM,1)
+      DO JK=KKTB,KKTE
+        ZD=ZALPHA*(0.5*(PZZ(JI,JJ,JK)+PZZ(JI,JJ,JK+KKL))-PZZ(JI,JJ,KKB)) &
+          *PDIRCOSZW(JI,JJ)
+        IF ( PLM(JI,JJ,JK)>ZD) THEN
+          PLM(JI,JJ,JK)=ZD
+        ELSE
+          EXIT
+        ENDIF
+      END DO
+    END DO
+  END DO
+END IF
+!
+PLM(:,:,KKA) = PLM(:,:,KKB  )
+PLM(:,:,KKE  ) = PLM(:,:,KKE-KKL)
+PLM(:,:,KKU  ) = PLM(:,:,KKU-KKL)
+!$acc end kernels
+
+if ( mppdb_initialized ) then
+  !Check all out arrays
+  call Mppdb_check( plm, "Dear end:plm" )
+end if
+
+!$acc end data
+
+#ifndef MNH_OPENACC
+deallocate(zwork2d, zdthldz, zdrtdz, zetheta, zemoist ) 
+#else
+CALL MNH_REL_ZT3D(izwork2d, izdthldz, izdrtdz, izetheta, izemoist, &
+                iztmp1_device, iztmp2_device )
+#endif
+
+!$acc end data
+
+END SUBROUTINE DEAR
+
+end module mode_turb
diff --git a/src/ZSOLVER/turb_hor_dyn_corr.f90 b/src/ZSOLVER/turb_hor_dyn_corr.f90
new file mode 100644
index 0000000000000000000000000000000000000000..b59a3dfaa26314a1a3360157b626ff755290bc70
--- /dev/null
+++ b/src/ZSOLVER/turb_hor_dyn_corr.f90
@@ -0,0 +1,1300 @@
+!MNH_LIC Copyright 1994-2020 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.
+!-----------------------------------------------------------------
+MODULE MODI_TURB_HOR_DYN_CORR
+!
+INTERFACE
+!
+      SUBROUTINE TURB_HOR_DYN_CORR(KSPLT, PTSTEP,                    &
+                      OCLOSE_OUT,OTURB_FLX,KRR,                      &
+                      TPFILE,                                        &
+                      PK,PINV_PDZZ,                                  &
+                      PDXX,PDYY,PDZZ,PDZX,PDZY,PZZ,                  &
+                      PDIRCOSZW,                                     &
+                      PCOSSLOPE,PSINSLOPE,                           &
+                      PRHODJ,                                        &
+                      PCDUEFF,PTAU11M,PTAU12M,PTAU22M,PTAU33M,       &
+                      PUM,PVM,PWM,PUSLOPEM,PVSLOPEM,                 &
+                      PTHLM,PRM,PSVM,                                &
+                      PTKEM,PLM,                                     &
+                      PDP,PTP,                                       &
+                      PRUS,PRVS,PRWS                                 )
+!
+USE MODD_IO, ONLY: TFILEDATA
+!
+INTEGER,                  INTENT(IN)    ::  KSPLT        ! split process index
+REAL,                     INTENT(IN)    ::  PTSTEP       ! timestep
+LOGICAL,                  INTENT(IN)    ::  OCLOSE_OUT   ! switch for syncronous
+                                                         ! file opening       
+LOGICAL,                  INTENT(IN)    ::  OTURB_FLX    ! switch to write the
+                                 ! turbulent fluxes in the syncronous FM-file
+INTEGER,                  INTENT(IN)    ::  KRR          ! number of moist var.
+TYPE(TFILEDATA),          INTENT(IN)    ::  TPFILE       ! Output file
+!
+REAL, DIMENSION(:,:,:),   INTENT(IN)    ::  PK          ! Turbulent diffusion doef.
+                                                        ! PK = PLM * SQRT(PTKEM)
+REAL, DIMENSION(:,:,:),   INTENT(IN)    ::  PINV_PDZZ   ! 1./PDZZ
+REAL, DIMENSION(:,:,:),   INTENT(IN)    ::  PDXX, PDYY, PDZZ, PDZX, PDZY 
+                                                         ! Metric coefficients
+REAL, DIMENSION(:,:,:),   INTENT(IN)    ::  PZZ          ! vertical grid
+REAL, DIMENSION(:,:),     INTENT(IN)    ::  PDIRCOSZW
+! Director Cosinus along z directions at surface w-point
+REAL, DIMENSION(:,:),   INTENT(IN)   ::  PCOSSLOPE       ! cosinus of the angle 
+                                      ! between i and the slope vector
+REAL, DIMENSION(:,:),   INTENT(IN)   ::  PSINSLOPE       ! sinus of the angle 
+                                      ! between i and the slope vector
+REAL, DIMENSION(:,:,:),   INTENT(IN)    ::  PRHODJ       ! density * grid volume
+!
+REAL, DIMENSION(:,:),   INTENT(IN)   ::  PCDUEFF      ! Cd * || u || at time t
+REAL, DIMENSION(:,:),   INTENT(IN)   ::  PTAU11M      ! <uu> in the axes linked 
+       ! to the maximum slope direction and the surface normal and the binormal 
+       ! at time t - dt
+REAL, DIMENSION(:,:),   INTENT(IN)   ::  PTAU12M      ! <uv> in the same axes
+REAL, DIMENSION(:,:),   INTENT(IN)   ::  PTAU22M      ! <vv> in the same axes
+REAL, DIMENSION(:,:),   INTENT(IN)   ::  PTAU33M      ! <ww> in the same axes
+!
+! Variables at t-1
+REAL, DIMENSION(:,:,:),   INTENT(IN)    ::  PUM,PVM,PWM,PTHLM
+REAL, DIMENSION(:,:,:,:), INTENT(IN)    ::  PRM
+REAL, DIMENSION(:,:,:,:), INTENT(IN)    ::  PSVM
+REAL, DIMENSION(:,:),      INTENT(IN)   ::  PUSLOPEM     ! wind component along the 
+                                     ! maximum slope direction
+REAL, DIMENSION(:,:),      INTENT(IN)   ::  PVSLOPEM     ! wind component along the 
+                                     ! direction normal to the maximum slope one
+!
+REAL, DIMENSION(:,:,:),   INTENT(IN)    ::  PTKEM        ! TKE at time t- dt
+REAL, DIMENSION(:,:,:),   INTENT(IN)    ::  PLM          ! Turb. mixing length
+!
+REAL, DIMENSION(:,:,:),   INTENT(INOUT) ::  PRUS, PRVS, PRWS
+REAL, DIMENSION(:,:,:),   INTENT(INOUT) ::  PDP,PTP      ! TKE production terms
+!
+END SUBROUTINE TURB_HOR_DYN_CORR
+!
+END INTERFACE
+!
+END MODULE MODI_TURB_HOR_DYN_CORR
+!     ################################################################
+      SUBROUTINE TURB_HOR_DYN_CORR(KSPLT, PTSTEP,                    &
+                      OCLOSE_OUT,OTURB_FLX,KRR,                      &
+                      TPFILE,                                        &
+                      PK,PINV_PDZZ,                                  &
+                      PDXX,PDYY,PDZZ,PDZX,PDZY,PZZ,                  &
+                      PDIRCOSZW,                                     &
+                      PCOSSLOPE,PSINSLOPE,                           &
+                      PRHODJ,                                        &
+                      PCDUEFF,PTAU11M,PTAU12M,PTAU22M,PTAU33M,       &
+                      PUM,PVM,PWM,PUSLOPEM,PVSLOPEM,                 &
+                      PTHLM,PRM,PSVM,                                &
+                      PTKEM,PLM,                                     &
+                      PDP,PTP,                                       &
+                      PRUS,PRVS,PRWS                                 )
+!     ################################################################
+!
+!!****  *TURB_HOR* -routine to compute the source terms in the meso-NH
+!!               model equations due to the non-vertical turbulent fluxes.
+!!
+!!    PURPOSE
+!!    -------
+!!
+!!     see TURB_HOR
+!!
+!!**  METHOD
+!!    ------
+!!
+!!    EXTERNAL
+!!    --------
+!!
+!!    IMPLICIT ARGUMENTS
+!!    ------------------
+!!
+!!    REFERENCE
+!!    ---------
+!!
+!!    AUTHOR
+!!    ------
+!!
+!!      Joan Cuxart             * INM and Meteo-France *
+!!
+!!    MODIFICATIONS
+!!    -------------
+!!                     Aug    , 1997 (V. Saravane) spliting of TURB_HOR
+!!                     Nov  27, 1997 (V. Masson) clearing of the routine
+!!                     Oct  18, 2000 (V. Masson) LES computations + LFLAT switch
+!!                     Feb  15, 2001 (J. Stein)  remove the use of w=0 at the
+!!                                               ground   
+!!                     Mar  12, 2001 (V. Masson and J. Stein) major bugs 
+!!                                 + change of discretization at the surface
+!!                     Nov  06, 2002 (V. Masson) LES budgets
+!!                     October 2009 (G. Tanguy) add ILENCH=LEN(YCOMMENT) after
+!!                                              change of YCOMMENT
+!!                     July 2012     (V.Masson) Implicitness of W
+!!                     March 2014    (V.Masson) tridiag_w : bug between
+!!                                               mass and flux position
+!!                     J.Escobar : 15/09/2015 : WENO5 & JPHEXT <> 1
+!!                      M.Moge  04/2016 Use openACC directives to port the TURB part of Meso-NH on GPU
+!!  Philippe Wautelet: 05/2016-04/2018: new data structures and calls for I/O
+!  P. Wautelet 20/05/2019: add name argument to ADDnFIELD_ll + new ADD4DFIELD_ll subroutine
+!  J.Escobar 13/08/2020: PGI/NVHPC BUG , extend DO CONCURRENT to 3D indexes        
+!! --------------------------------------------------------------------------
+!
+!*      0. DECLARATIONS
+!          ------------
+!
+USE MODD_ARGSLIST_ll,    ONLY: LIST_ll
+USE MODD_CST
+USE MODD_CONF
+USE MODD_CTURB
+USE MODD_IO,             ONLY: TFILEDATA
+USE MODD_PARAMETERS
+USE MODD_LES
+USE MODD_NSV
+!
+USE MODE_ll
+USE MODE_FIELD,          ONLY: TFIELDDATA, TYPEREAL
+USE MODE_IO_FIELD_WRITE, only: IO_Field_write
+use mode_mppdb
+!
+USE MODI_GRADIENT_M
+USE MODI_GRADIENT_U
+USE MODI_GRADIENT_V
+USE MODI_GRADIENT_W
+#ifndef MNH_OPENACC
+USE MODI_SHUMAN
+#else
+USE MODI_SHUMAN_DEVICE
+#endif
+USE MODI_COEFJ
+USE MODI_LES_MEAN_SUBGRID
+USE MODI_TRIDIAG_W
+!
+USE MODI_SECOND_MNH
+USE MODE_MPPDB
+#ifdef MNH_BITREP
+USE MODI_BITREP
+#endif
+#ifdef MNH_OPENACC
+USE MODE_MNH_ZWORK , ONLY : MNH_ALLOCATE_ZT3D , MNH_REL_ZT3D, MNH_ALLOCATE_ZT3DP , MNH_ALLOCATE_ZT2D
+#endif
+USE MODI_GET_HALO
+!
+IMPLICIT NONE
+!
+!
+!*       0.1  declaration of arguments
+!
+!
+!
+INTEGER,                  INTENT(IN)    ::  KSPLT        ! split process index
+REAL,                     INTENT(IN)    ::  PTSTEP       ! timestep
+LOGICAL,                  INTENT(IN)    ::  OCLOSE_OUT   ! switch for syncronous
+                                                         ! file opening       
+LOGICAL,                  INTENT(IN)    ::  OTURB_FLX    ! switch to write the
+                                 ! turbulent fluxes in the syncronous FM-file
+INTEGER,                  INTENT(IN)    ::  KRR          ! number of moist var.
+TYPE(TFILEDATA),          INTENT(IN)    ::  TPFILE       ! Output file
+!
+REAL, DIMENSION(:,:,:),   INTENT(IN)    ::  PK          ! Turbulent diffusion doef.
+                                                        ! PK = PLM * SQRT(PTKEM)
+REAL, DIMENSION(:,:,:),   INTENT(IN)    ::  PINV_PDZZ   ! 1./PDZZ
+REAL, DIMENSION(:,:,:),   INTENT(IN)    ::  PDXX, PDYY, PDZZ, PDZX, PDZY 
+                                                         ! Metric coefficients
+REAL, DIMENSION(:,:,:),   INTENT(IN)    ::  PZZ          ! vertical grid
+REAL, DIMENSION(:,:),     INTENT(IN)    ::  PDIRCOSZW
+! Director Cosinus along z directions at surface w-point
+REAL, DIMENSION(:,:),   INTENT(IN)   ::  PCOSSLOPE       ! cosinus of the angle 
+                                      ! between i and the slope vector
+REAL, DIMENSION(:,:),   INTENT(IN)   ::  PSINSLOPE       ! sinus of the angle 
+                                      ! between i and the slope vector
+REAL, DIMENSION(:,:,:),   INTENT(IN)    ::  PRHODJ       ! density * grid volume
+!
+REAL, DIMENSION(:,:),   INTENT(IN)   ::  PCDUEFF      ! Cd * || u || at time t
+REAL, DIMENSION(:,:),   INTENT(IN)   ::  PTAU11M      ! <uu> in the axes linked 
+       ! to the maximum slope direction and the surface normal and the binormal 
+       ! at time t - dt
+REAL, DIMENSION(:,:),   INTENT(IN)   ::  PTAU12M      ! <uv> in the same axes
+REAL, DIMENSION(:,:),   INTENT(IN)   ::  PTAU22M      ! <vv> in the same axes
+REAL, DIMENSION(:,:),   INTENT(IN)   ::  PTAU33M      ! <ww> in the same axes
+!
+! Variables at t-1
+REAL, DIMENSION(:,:,:),   INTENT(IN)    ::  PUM,PVM,PWM,PTHLM
+REAL, DIMENSION(:,:,:,:), INTENT(IN)    ::  PRM
+REAL, DIMENSION(:,:,:,:), INTENT(IN)    ::  PSVM
+REAL, DIMENSION(:,:),      INTENT(IN)   ::  PUSLOPEM     ! wind component along the 
+                                     ! maximum slope direction
+REAL, DIMENSION(:,:),      INTENT(IN)   ::  PVSLOPEM     ! wind component along the 
+                                     ! direction normal to the maximum slope one
+!
+REAL, DIMENSION(:,:,:),   INTENT(IN)    ::  PTKEM        ! TKE at time t- dt
+REAL, DIMENSION(:,:,:),   INTENT(IN)    ::  PLM          ! Turb. mixing length
+!
+REAL, DIMENSION(:,:,:),   INTENT(INOUT) ::  PRUS, PRVS, PRWS
+REAL, DIMENSION(:,:,:),   INTENT(INOUT) ::  PDP,PTP      ! TKE production terms
+!
+!*       0.2  declaration of local variables
+!
+REAL, DIMENSION(:,:,:), pointer , contiguous :: ZFLX,ZWORK ! work arrays, PK is the turb. mixing coef.
+!
+REAL, DIMENSION(:,:),   pointer , contiguous :: ZDIRSINZW
+INTEGER :: IZFLX,IZWORK,IZDIRSINZW
+      ! sinus of the angle between the vertical and the normal to the orography
+INTEGER             :: IKB,IKE
+                                    ! Index values for the Beginning and End
+                                    ! mass points of the domain  
+INTEGER             :: IKU                                   
+INTEGER             :: JSV          ! scalar loop counter
+!
+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
+INTEGER :: IGX_U_M_PUM,IGY_V_M_PVM,IGZ_W_M_PWM,IGZ_W_M_ZWP
+REAL, DIMENSION(:,:,:), pointer , contiguous :: ZMZF_DZZ   ! MZF(PDZZ)
+REAL, DIMENSION(:,:,:), pointer , contiguous :: ZDFDDWDZ   ! formal derivative of the
+!                                                 ! flux (variable: dW/dz)
+REAL, DIMENSION(:,:,:), pointer , contiguous :: ZWP        ! W at future   time-step
+!
+REAL, DIMENSION(:,:,:), pointer , contiguous :: ZDU_DZ_DZS_DX ! du/dz*dzs/dx surf
+REAL, DIMENSION(:,:,:), pointer , contiguous :: ZDV_DZ_DZS_DY ! dv/dz*dzs/dy surf
+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
+INTEGER :: IZMZF_DZZ,IZDFDDWDZ,IZWP,IZDU_DZ_DZS_DX,IZDV_DZ_DZS_DY &
+           ,IZDU_DX,IZDV_DY,IZDW_DZ 
+!
+INTEGER                :: IINFO_ll      ! return code of parallel routine
+TYPE(LIST_ll), POINTER :: TZFIELDS_ll   ! list of fields to exchange
+
+REAL :: ZTIME1, ZTIME2
+
+
+REAL, DIMENSION(:,:,:), pointer , contiguous :: ZCOEFF , ZDZZ
+                                    ! coefficients for the uncentred gradient 
+                                    ! computation near the ground
+INTEGER  :: IZCOEFF , IZDZZ
+!
+#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
+!
+INTEGER  :: JIU,JJU,JKU
+INTEGER  :: JI,JJ,JK
+! --------------------------------------------------------------------------
+
+!$acc data present( PK, PINV_PDZZ, PDXX, PDYY, PDZZ, PDZX, PDZY, PZZ, PDIRCOSZW,     &
+!$acc &             PCOSSLOPE, PSINSLOPE, PRHODJ, PCDUEFF,                           &
+!$acc &             PTAU11M, PTAU12M, PTAU22M, PTAU33M,                              &
+!$acc &             PUM, PVM, PWM, PTHLM, PRM, PSVM, PUSLOPEM, PVSLOPEM, PTKEM, PLM, &
+!$acc &             PRUS, PRVS, PRWS, PDP, PTP )
+
+if ( mppdb_initialized ) then
+  !Check all in arrays
+  call Mppdb_check( pk,          "Turb_hor_dyn_corr beg:pk"          )
+  call Mppdb_check( pinv_pdzz,   "Turb_hor_dyn_corr beg:pinv_pdzz"   )
+  call Mppdb_check( pdxx,        "Turb_hor_dyn_corr beg:pdxx"        )
+  call Mppdb_check( pdyy,        "Turb_hor_dyn_corr beg:pdyy"        )
+  call Mppdb_check( pdzz,        "Turb_hor_dyn_corr beg:pdzz"        )
+  call Mppdb_check( pdzx,        "Turb_hor_dyn_corr beg:pdzx"        )
+  call Mppdb_check( pdzy,        "Turb_hor_dyn_corr beg:pdzy"        )
+  call Mppdb_check( pzz,         "Turb_hor_dyn_corr beg:pzz"         )
+  call Mppdb_check( pdircoszw,   "Turb_hor_dyn_corr beg:pdircoszw"   )
+  call Mppdb_check( pcosslope,   "Turb_hor_dyn_corr beg:pcosslope"   )
+  call Mppdb_check( psinslope,   "Turb_hor_dyn_corr beg:psinslope"   )
+  call Mppdb_check( prhodj,      "Turb_hor_dyn_corr beg:prhodj"      )
+  call Mppdb_check( pcdueff,     "Turb_hor_dyn_corr beg:pcdueff"     )
+  call Mppdb_check( ptau11m,     "Turb_hor_dyn_corr beg:ptau11m"     )
+  call Mppdb_check( ptau12m,     "Turb_hor_dyn_corr beg:ptau12m"     )
+  call Mppdb_check( ptau22m,     "Turb_hor_dyn_corr beg:ptau22m"     )
+  call Mppdb_check( ptau33m,     "Turb_hor_dyn_corr beg:ptau33m"     )
+  call Mppdb_check( pum,         "Turb_hor_dyn_corr beg:pum"         )
+  call Mppdb_check( pvm,         "Turb_hor_dyn_corr beg:pvm"         )
+  call Mppdb_check( pwm,         "Turb_hor_dyn_corr beg:pwm"         )
+  call Mppdb_check( pthlm,       "Turb_hor_dyn_corr beg:pthlm"       )
+  call Mppdb_check( prm,         "Turb_hor_dyn_corr beg:prm"         )
+  call Mppdb_check( psvm,        "Turb_hor_dyn_corr beg:psvm"        )
+  call Mppdb_check( puslopem,    "Turb_hor_dyn_corr beg:puslopem"    )
+  call Mppdb_check( pvslopem,    "Turb_hor_dyn_corr beg:pvslopem"    )
+  call Mppdb_check( ptkem,       "Turb_hor_dyn_corr beg:ptkem"       )
+  call Mppdb_check( plm,         "Turb_hor_dyn_corr beg:plm"         )
+  !Check all inout arrays
+  call Mppdb_check( prus,   "Turb_hor_dyn_corr beg:prus"   )
+  call Mppdb_check( prvs,   "Turb_hor_dyn_corr beg:prvs"   )
+  call Mppdb_check( prws,   "Turb_hor_dyn_corr beg:prws"   )
+  call Mppdb_check( pdp,    "Turb_hor_dyn_corr beg:pdp"    )
+  call Mppdb_check( ptp,    "Turb_hor_dyn_corr beg:ptp"    )
+end if
+
+JIU =  size(pum, 1 )
+JJU =  size(pum, 2 )
+JKU =  size(pum, 3 )
+
+#ifndef MNH_OPENACC
+allocate( zflx (JIU,JJU,JKU ) )
+allocate( zwork(JIU,JJU,JKU ) )
+
+allocate( zdirsinzw(JIU,JJU ) )
+
+allocate( gx_u_m_pum(JIU,JJU,JKU ) )
+allocate( gy_v_m_pvm(JIU,JJU,JKU ) )
+allocate( gz_w_m_pwm(JIU,JJU,JKU ) )
+allocate( gz_w_m_zwp(JIU,JJU,JKU ) )
+allocate( zmzf_dzz  (JIU,JJU,JKU ) )
+allocate( zdfddwdz  (JIU,JJU,JKU ) )
+allocate( zwp       (JIU,JJU,JKU ) )
+
+allocate( zdu_dz_dzs_dx(JIU,JJU, 1 ) )
+allocate( zdv_dz_dzs_dy(JIU,JJU, 1 ) )
+allocate( zdu_dx       (JIU,JJU, 1 ) )
+allocate( zdv_dy       (JIU,JJU, 1 ) )
+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_ZT3D( zflx ,JIU,JJU,JKU )
+izwork         = MNH_ALLOCATE_ZT3D( zwork,JIU,JJU,JKU )
+
+izdirsinzw     = MNH_ALLOCATE_ZT2D( zdirsinzw,JIU,JJU )
+
+igx_u_m_pum    = MNH_ALLOCATE_ZT3D( gx_u_m_pum,JIU,JJU,JKU )
+igy_v_m_pvm    = MNH_ALLOCATE_ZT3D( gy_v_m_pvm,JIU,JJU,JKU )
+igz_w_m_pwm    = MNH_ALLOCATE_ZT3D( gz_w_m_pwm,JIU,JJU,JKU )
+igz_w_m_zwp    = MNH_ALLOCATE_ZT3D( gz_w_m_zwp,JIU,JJU,JKU )
+izmzf_dzz      = MNH_ALLOCATE_ZT3D( zmzf_dzz  ,JIU,JJU,JKU )
+izdfddwdz      = MNH_ALLOCATE_ZT3D( zdfddwdz  ,JIU,JJU,JKU )
+izwp           = MNH_ALLOCATE_ZT3D( zwp       ,JIU,JJU,JKU )
+
+izdu_dz_dzs_dx = MNH_ALLOCATE_ZT3DP( zdu_dz_dzs_dx,JIU,JJU, 1 , 1 )
+izdv_dz_dzs_dy = MNH_ALLOCATE_ZT3DP( zdv_dz_dzs_dy,JIU,JJU, 1 , 1 )
+izdu_dx        = MNH_ALLOCATE_ZT3DP( zdu_dx       ,JIU,JJU, 1 , 1 )
+izdv_dy        = MNH_ALLOCATE_ZT3DP( zdv_dy       ,JIU,JJU, 1 , 1 )
+izdw_dz        = MNH_ALLOCATE_ZT3DP( zdw_dz       ,JIU,JJU, 1 , 1 )
+
+izcoeff        = MNH_ALLOCATE_ZT3DP( zcoeff,JIU,JJU, 1 + jpvext , 3 + jpvext )
+izdzz          = MNH_ALLOCATE_ZT3DP( zdzz  ,JIU,JJU, 1 + jpvext , 3 + jpvext )
+#endif
+
+#ifdef MNH_OPENACC
+iztmp1_device = MNH_ALLOCATE_ZT3D( ztmp1_device,JIU,JJU,JKU )
+iztmp2_device = MNH_ALLOCATE_ZT3D( ztmp2_device,JIU,JJU,JKU )
+iztmp3_device = MNH_ALLOCATE_ZT3D( ztmp3_device,JIU,JJU,JKU )
+iztmp4_device = MNH_ALLOCATE_ZT3D( ztmp4_device,JIU,JJU,JKU )
+#endif
+
+!$acc data present(ZFLX, ZWORK, ZDIRSINZW, ZCOEFF, ZDZZ,                  &
+!$acc &            GX_U_M_PUM, GY_V_M_PVM, GZ_W_M_PWM, GZ_W_M_ZWP,        &
+!$acc &            ZMZF_DZZ, ZDFDDWDZ, ZWP,                               &
+!$acc &            ZDU_DZ_DZS_DX, ZDV_DZ_DZS_DY, ZDU_DX, ZDV_DY, ZDW_DZ,  &
+!$acc &            ZTMP1_DEVICE, ZTMP2_DEVICE, ZTMP3_DEVICE, ZTMP4_DEVICE )
+
+!
+!*       1.   PRELIMINARY COMPUTATIONS
+!             ------------------------
+NULLIFY(TZFIELDS_ll)
+!
+IKB = 1+JPVEXT               
+IKE = SIZE(PUM,3)-JPVEXT    
+IKU = SIZE(PUM,3)
+!
+!
+!$acc kernels async(1)
+#ifndef MNH_BITREP
+ZDIRSINZW(:,:) = SQRT( 1. - PDIRCOSZW(:,:)**2 )
+#else
+!$acc loop independent collapse(2)
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU )
+   ZDIRSINZW(JI,JJ) = SQRT( 1. - BR_P2(PDIRCOSZW(JI,JJ)) )
+END DO
+#endif
+!$acc end kernels
+!
+#ifndef MNH_OPENACC
+GX_U_M_PUM = GX_U_M(PUM,PDXX,PDZZ,PDZX)
+IF (.NOT. L2D) THEN
+  GY_V_M_PVM = GY_V_M(PVM,PDYY,PDZZ,PDZY)
+END IF
+GZ_W_M_PWM = GZ_W_M(PWM,PDZZ)
+!
+ZMZF_DZZ = MZF(PDZZ)
+#else
+CALL GX_U_M_DEVICE(1,IKU,1,PUM,PDXX,PDZZ,PDZX,GX_U_M_PUM)
+IF (.NOT. L2D) THEN
+  CALL GY_V_M_DEVICE(1,IKU,1,PVM,PDYY,PDZZ,PDZY,GY_V_M_PVM)
+END IF
+CALL GZ_W_M_DEVICE(1,IKU,1,PWM,PDZZ,GZ_W_M_PWM)
+!
+CALL MZF_DEVICE(1,IKU,1,PDZZ,ZMZF_DZZ)
+#endif
+!
+CALL ADD3DFIELD_ll( TZFIELDS_ll, ZFLX, 'TURB_HOR_DYN_CORR::ZFLX' )
+
+
+!  compute the coefficients for the uncentred gradient computation near the 
+!  ground
+!
+!*       9.   < U'U'>
+!             -------
+!
+! Computes the U variance
+IF (.NOT. L2D) THEN
+   !$acc kernels async(2)
+   !$acc loop independent collapse(3)
+   DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+      ZFLX(JI,JJ,JK)= (2./3.) * PTKEM(JI,JJ,JK)                            &
+           - XCMFS * PK(JI,JJ,JK) *( (4./3.) * GX_U_M_PUM(JI,JJ,JK)        &
+           -(2./3.) * ( GY_V_M_PVM(JI,JJ,JK)                     &
+           +GZ_W_M_PWM(JI,JJ,JK)                ) )
+   END DO !CONCURRENT
+   !$acc end kernels
+   !!  &   to be tested later
+  !!  + XCMFB *  PLM / SQRT(PTKEM) * (-2./3.) * PTP 
+ELSE
+  !$acc kernels async(2)
+  ZFLX(:,:,:)= (2./3.) * PTKEM                                  &
+    - XCMFS * PK *( (4./3.) * GX_U_M_PUM                        &
+                   -(2./3.) * ( GZ_W_M_PWM                ) ) 
+  !$acc end kernels
+  !!  &   to be tested later
+  !!  + XCMFB *  PLM / SQRT(PTKEM) * (-2./3.) * PTP 
+END IF
+!
+!$acc kernels async(2)
+ZFLX(:,:,IKE+1) = ZFLX(:,:,IKE) 
+!$acc end kernels
+!
+!* prescription of du/dz and dv/dz with uncentered gradient at the surface
+!  prescription of dw/dz at Dz/2 above ground using the continuity equation
+!  using a Boussinesq hypothesis to remove the z dependance of rhod_ref
+!  (div u = 0)
+!
+#ifndef MNH_OPENACC
+ZDZZ(:,:,:) = MXM(PDZZ(:,:,IKB:IKB+2))
+#else
+CALL MXM_DEVICE(PDZZ(:,:,IKB:IKB+2),ZDZZ(:,:,:))
+#endif
+!$acc kernels async(3)
+ZCOEFF(:,:,IKB+2)= - ZDZZ(:,:,2) /      &
+       ( (ZDZZ(:,:,3)+ZDZZ(:,:,2)) * ZDZZ(:,:,3) )
+ZCOEFF(:,:,IKB+1)=   (ZDZZ(:,:,3)+ZDZZ(:,:,2)) /      &
+       ( ZDZZ(:,:,2) * ZDZZ(:,:,3) )
+ZCOEFF(:,:,IKB)= - (ZDZZ(:,:,3)+2.*ZDZZ(:,:,2)) /      &
+       ( (ZDZZ(:,:,3)+ZDZZ(:,:,2)) * ZDZZ(:,:,2) )
+!$acc end kernels
+!
+#ifndef MNH_OPENACC
+ZDU_DZ_DZS_DX(:,:,:)=MXF ((ZCOEFF(:,:,IKB+2:IKB+2)*PUM(:,:,IKB+2:IKB+2)       &
+                          +ZCOEFF(:,:,IKB+1:IKB+1)*PUM(:,:,IKB+1:IKB+1)       &
+                          +ZCOEFF(:,:,IKB  :IKB  )*PUM(:,:,IKB  :IKB  )       &
+                          )* 0.5 * ( PDZX(:,:,IKB+1:IKB+1)+PDZX(:,:,IKB:IKB)) &
+                         )/ MXF(PDXX(:,:,IKB:IKB))
+!
+ZDZZ(:,:,:) = MYM(PDZZ(:,:,IKB:IKB+2))
+#else
+!$acc kernels async(3)
+ZTMP1_DEVICE(:,:,1) = (ZCOEFF(:,:,IKB+2)*PUM(:,:,IKB+2)       &
+                          +ZCOEFF(:,:,IKB+1)*PUM(:,:,IKB+1)       &
+                          +ZCOEFF(:,:,IKB )*PUM(:,:,IKB)       &
+                          )* 0.5 * ( PDZX(:,:,IKB+1)+PDZX(:,:,IKB))
+!$acc end kernels
+!
+!!! wait for the computation of ZCOEFF and ZTMP1_DEVICE
+!$acc wait(3)
+!
+CALL MXF_DEVICE(ZTMP1_DEVICE(:,:,1:1), ZTMP2_DEVICE(:,:,1:1))
+CALL MXF_DEVICE(PDXX(:,:,IKB:IKB), ZTMP1_DEVICE(:,:,1:1))
+!$acc kernels async(3)
+ZDU_DZ_DZS_DX(:,:,1) = ZTMP2_DEVICE(:,:,1) / ZTMP1_DEVICE(:,:,1)
+!$acc end kernels
+!
+CALL MYM_DEVICE(PDZZ(:,:,IKB:IKB+2),ZDZZ(:,:,:))
+#endif
+!$acc kernels async(4)
+ZCOEFF(:,:,IKB+2)= - ZDZZ(:,:,2) /      &
+       ( (ZDZZ(:,:,3)+ZDZZ(:,:,2)) * ZDZZ(:,:,3) )
+ZCOEFF(:,:,IKB+1)=   (ZDZZ(:,:,3)+ZDZZ(:,:,2)) /      &
+       ( ZDZZ(:,:,2) * ZDZZ(:,:,3) )
+ZCOEFF(:,:,IKB)= - (ZDZZ(:,:,3)+2.*ZDZZ(:,:,2)) /      &
+       ( (ZDZZ(:,:,3)+ZDZZ(:,:,2)) * ZDZZ(:,:,2) )
+!$acc end kernels
+!
+#ifndef MNH_OPENACC
+ZDV_DZ_DZS_DY(:,:,:)=MYF ((ZCOEFF(:,:,IKB+2:IKB+2)*PVM(:,:,IKB+2:IKB+2)       &
+                          +ZCOEFF(:,:,IKB+1:IKB+1)*PVM(:,:,IKB+1:IKB+1)       &
+                          +ZCOEFF(:,:,IKB  :IKB  )*PVM(:,:,IKB  :IKB  )       &
+                          )* 0.5 * ( PDZY(:,:,IKB+1:IKB+1)+PDZY(:,:,IKB:IKB)) &
+                         )/ MYF(PDYY(:,:,IKB:IKB))
+#else
+!$acc kernels async(4)
+ZTMP3_DEVICE(:,:,1) = (ZCOEFF(:,:,IKB+2)*PVM(:,:,IKB+2)       &
+                          +ZCOEFF(:,:,IKB+1)*PVM(:,:,IKB+1)       &
+                          +ZCOEFF(:,:,IKB)*PVM(:,:,IKB)       &
+                          )* 0.5 * ( PDZY(:,:,IKB+1)+PDZY(:,:,IKB))
+!$acc end kernels
+!
+!!! wait for the computation of ZCOEFF and ZTMP3_DEVICE
+!$acc wait(4)
+#endif
+!
+#ifndef MNH_OPENACC
+ZDU_DX(:,:,:)=  DXF(PUM(:,:,IKB:IKB)) / MXF(PDXX(:,:,IKB:IKB))  &
+              - ZDU_DZ_DZS_DX(:,:,:)
+
+ZDV_DY(:,:,:)=  DYF(PVM(:,:,IKB:IKB)) / MYF(PDYY(:,:,IKB:IKB)) &
+              - ZDV_DZ_DZS_DY(:,:,:)
+#else
+CALL MYF_DEVICE(ZTMP3_DEVICE(:,:,1:1), ZTMP4_DEVICE(:,:,1:1))
+CALL MYF_DEVICE(PDYY(:,:,IKB:IKB), ZTMP3_DEVICE(:,:,1:1))
+!$acc kernels async(4)
+ZDV_DZ_DZS_DY(:,:,1)= ZTMP4_DEVICE(:,:,1) / ZTMP3_DEVICE(:,:,1)
+!$acc end kernels
+!
+!
+!!! wait for the computation of ZDU_DZ_DZS_DX
+!$acc wait(3)
+!
+CALL DXF_DEVICE(PUM(:,:,IKB:IKB),ZTMP1_DEVICE(:,:,1:1))
+CALL MXF_DEVICE(PDXX(:,:,IKB:IKB),ZTMP2_DEVICE(:,:,1:1))
+!$acc kernels async(3)
+ZDU_DX(:,:,1)=  ZTMP1_DEVICE(:,:,1) / ZTMP2_DEVICE(:,:,1) - ZDU_DZ_DZS_DX(:,:,1)
+!$acc end kernels
+
+!!! wait for the computation of ZDV_DZ_DZS_DY
+!$acc wait(4)
+!
+CALL DYF_DEVICE(PVM(:,:,IKB:IKB),ZTMP3_DEVICE(:,:,1:1))
+CALL MYF_DEVICE(PDYY(:,:,IKB:IKB),ZTMP4_DEVICE(:,:,1:1))
+!$acc kernels! async(4)
+ZDV_DY(:,:,1)=  ZTMP3_DEVICE(:,:,1) / ZTMP4_DEVICE(:,:,1) - ZDV_DZ_DZS_DY(:,:,1)
+!$acc end kernels
+!
+!
+!!! wait for the computation of ZDU_DX and ZDV_DY
+!$acc wait(3) async(4)
+#endif
+!
+!$acc kernels async(4)
+ZDW_DZ(:,:,:)=-ZDU_DX(:,:,:)-ZDV_DY(:,:,:)
+!$acc end kernels
+!
+!* computation 
+!
+!!! wait for the computation of ZFLX
+!$acc wait(2) async(4)
+!!! wait for the computation of ZDW_DZ
+!$acc wait(4)
+!
+! ! !!! we can launch the update of ZFLX on the part that has already been computed
+! ! !$acc update self(ZFLX(:,:,IKB+1:)) async(10)
+!attention !!!!! je ne comprends pas pourquoi mais ce update plante à l'execution...
+! du coup je ne peux pas faire de update self asynchrone...
+!
+!$acc kernels async(3)
+ZFLX(:,:,IKB)   = (2./3.) * PTKEM(:,:,IKB)                           &
+  - XCMFS * PK(:,:,IKB) * 2. * ZDU_DX(:,:,1)
+!$acc end kernels
+
+
+!!  &  to be tested later
+!! + XCMFB * PLM(:,:,IKB:IKB) /SQRT(PTKEM(:,:,IKB:IKB)) *        &
+!!   (-2./3.) * PTP(:,:,IKB:IKB)
+!
+! extrapolates this flux under the ground with the surface flux
+!
+!
+!!! wait for the computation of ZDIRSINZW
+!$acc wait(1)
+!
+!$acc kernels async(4)
+#ifndef MNH_BITREP
+ZFLX(:,:,IKB-1) =                                                            &
+        PTAU11M(:,:) * PCOSSLOPE(:,:)**2 * PDIRCOSZW(:,:)**2                 &
+  -2. * PTAU12M(:,:) * PCOSSLOPE(:,:)* PSINSLOPE(:,:) * PDIRCOSZW(:,:)       &
+  +     PTAU22M(:,:) * PSINSLOPE(:,:)**2                                     &
+  +     PTAU33M(:,:) * PCOSSLOPE(:,:)**2 * ZDIRSINZW(:,:)**2                 &
+  +2. * PCDUEFF(:,:) *      (                                                &
+      PVSLOPEM(:,:) * PCOSSLOPE(:,:)    * PSINSLOPE(:,:) * ZDIRSINZW(:,:)    &
+    - PUSLOPEM(:,:) * PCOSSLOPE(:,:)**2 * ZDIRSINZW(:,:) * PDIRCOSZW(:,:)    )
+#else
+!$acc loop independent collapse(2)   
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU )
+ZFLX(JI,JJ,IKB-1) =                                                             &
+        PTAU11M(JI,JJ) * BR_P2(PCOSSLOPE(JI,JJ)) * BR_P2(PDIRCOSZW(JI,JJ))          &
+  -2. * PTAU12M(JI,JJ) * PCOSSLOPE(JI,JJ)* PSINSLOPE(JI,JJ) * PDIRCOSZW(JI,JJ)        &
+  +     PTAU22M(JI,JJ) * BR_P2(PSINSLOPE(JI,JJ))                                  &
+  +     PTAU33M(JI,JJ) * BR_P2(PCOSSLOPE(JI,JJ)) * BR_P2(ZDIRSINZW(JI,JJ))          &
+  +2. * PCDUEFF(JI,JJ) *      (                                                 &
+      PVSLOPEM(JI,JJ) * PCOSSLOPE(JI,JJ)    * PSINSLOPE(JI,JJ) * ZDIRSINZW(JI,JJ)     &
+      - PUSLOPEM(JI,JJ) * BR_P2(PCOSSLOPE(JI,JJ)) * ZDIRSINZW(JI,JJ) * PDIRCOSZW(JI,JJ) )
+END DO ! CONCURRENT
+#endif
+!$acc end kernels
+! 
+!!! wait for the computation of ZFLX(:,:,IKB) and ZFLX(:,:,IKB-1)
+!$acc wait(3) async(4)
+!
+!$acc kernels async(4)
+ZFLX(:,:,IKB-1) = 2. * ZFLX(:,:,IKB-1) -  ZFLX(:,:,IKB)
+!$acc end kernels
+!
+!
+!!! wait for the computation of ZFLX(:,:,IKB-1)
+!$acc wait(4)
+!
+
+
+! ! !!! we can launch the update of ZFLX on the rest
+! ! !$acc update self(ZFLX(:,:,1:IKB)) async(11)
+! ! !
+! ! !!! and wait for the update self(ZFLX(...)) to complete
+! ! !$acc wait(10)
+! ! !$acc wait(11)
+!attention !!!!! je ne comprends pas pourquoi mais le update self(ZFLX(:,:,IKB+1:)) plante à l'execution...
+! du coup je ne peux pas faire de update self asynchrone...
+
+
+!
+!!! at this point there are no more async operations running
+!!! to be absolutely sure, we do a wait
+!$acc wait
+!
+!!$!$acc update self(ZFLX)
+!!$CALL UPDATE_HALO_ll(TZFIELDS_ll, IINFO_ll)
+!!$!$acc update device(ZFLX) async(10)
+CALL GET_HALO_D(ZFLX)
+!
+IF ( OCLOSE_OUT .AND. OTURB_FLX ) THEN
+  ! stores <U U>  
+  TZFIELD%CMNHNAME   = 'U_VAR'
+  TZFIELD%CSTDNAME   = ''
+  TZFIELD%CLONGNAME  = 'U_VAR'
+  TZFIELD%CUNITS     = 'm2 s-2'
+  TZFIELD%CDIR       = 'XY'
+  TZFIELD%CCOMMENT   = 'X_Y_Z_U_VAR'
+  TZFIELD%NGRID      = 1
+  TZFIELD%NTYPE      = TYPEREAL
+  TZFIELD%NDIMS      = 3
+  TZFIELD%LTIMEDEP   = .TRUE.
+  CALL IO_Field_write(TPFILE,TZFIELD,ZFLX)
+END IF
+!
+! Complete the U tendency
+#ifndef MNH_OPENACC
+IF (.NOT. LFLAT) THEN
+  PRUS(:,:,:)=PRUS                                            &
+              -DXM(PRHODJ * ZFLX / MXF(PDXX) )                &
+              +DZF( PDZX / MZM(PDXX) * MXM( MZM(PRHODJ*ZFLX) * PINV_PDZZ ) )
+ELSE
+  PRUS(:,:,:)=PRUS -DXM(PRHODJ * ZFLX / MXF(PDXX) )
+END IF
+#else
+CALL MXF_DEVICE(PDXX, ZTMP1_DEVICE)
+!$acc kernels async(10)
+!$acc loop independent collapse(3)
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+   ZTMP2_DEVICE(JI,JJ,JK) = PRHODJ(JI,JJ,JK) * ZFLX(JI,JJ,JK) / ZTMP1_DEVICE(JI,JJ,JK)
+END DO !CONCURRENT
+!$acc end kernels
+!
+!!! wait for the computation of ZTMP2_DEVICE and the update of ZFLX
+!$acc wait(10)
+!
+CALL DXM_DEVICE(ZTMP2_DEVICE, ZTMP3_DEVICE)
+IF (.NOT. LFLAT) THEN
+  CALL MZM_DEVICE(PDXX,ZTMP1_DEVICE)
+  !$acc kernels
+  !$acc loop independent collapse(3)
+  DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+     ZTMP2_DEVICE(JI,JJ,JK) = PRHODJ(JI,JJ,JK) * ZFLX(JI,JJ,JK)
+  END DO !CONCURRENT
+  !$acc end kernels
+  CALL MZM_DEVICE(ZTMP2_DEVICE,ZTMP4_DEVICE)
+  !$acc kernels
+  !$acc loop independent collapse(3)
+  DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+     ZTMP2_DEVICE(JI,JJ,JK) = ZTMP4_DEVICE(JI,JJ,JK) * PINV_PDZZ(JI,JJ,JK)
+  END DO !CONCURRENT   
+  !$acc end kernels
+  CALL MXM_DEVICE( ZTMP2_DEVICE, ZTMP4_DEVICE )
+  !$acc kernels
+  !$acc loop independent collapse(3)
+  DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+     ZTMP2_DEVICE(JI,JJ,JK) = PDZX(JI,JJ,JK) / ZTMP1_DEVICE(JI,JJ,JK) * ZTMP4_DEVICE(JI,JJ,JK)
+  END DO !CONCURRENT   
+  !$acc end kernels
+  CALL DZF_DEVICE(1,IKU,1,ZTMP2_DEVICE,ZTMP1_DEVICE)
+  !$acc kernels async(1)
+  PRUS(:,:,:)=PRUS(:,:,:)                                           &
+              -ZTMP3_DEVICE(:,:,:)                &
+              +ZTMP1_DEVICE(:,:,:)
+  !$acc end kernels
+ELSE
+  !$acc kernels async(1)
+  PRUS(:,:,:)=PRUS(:,:,:) - ZTMP3_DEVICE(:,:,:)
+  !$acc end kernels
+END IF
+#endif
+!
+IF (KSPLT==1) THEN
+  ! Contribution to the dynamic production of TKE:
+   !$acc kernels async(2)
+   !$acc loop independent collapse(3)
+   DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+      ZWORK(JI,JJ,JK)     = - ZFLX(JI,JJ,JK) * GX_U_M_PUM(JI,JJ,JK)
+   END DO !CONCURRENT
+  !$acc end kernels
+  !
+  ! evaluate the dynamic production at w(IKB+1) in PDP(IKB)
+  !
+  !$acc kernels async(2)
+  ZWORK(:,:,IKB) = 0.5* ( -ZFLX(:,:,IKB)*ZDU_DX(:,:,1) + ZWORK(:,:,IKB+1) )
+  !$acc end kernels
+  !
+  !$acc kernels async(2)
+  PDP(:,:,:) = PDP(:,:,:) + ZWORK(:,:,:)
+  !$acc end kernels
+END IF
+!
+! Storage in the LES configuration
+!
+IF (LLES_CALL .AND. KSPLT==1) THEN
+  CALL SECOND_MNH(ZTIME1)
+!$acc data copy(X_LES_SUBGRID_U2,X_LES_RES_ddxa_U_SBG_UaU)
+  CALL LES_MEAN_SUBGRID( ZFLX, X_LES_SUBGRID_U2 ) 
+#ifndef MNH_OPENACC
+  CALL LES_MEAN_SUBGRID( -ZWORK, X_LES_RES_ddxa_U_SBG_UaU , .TRUE.)
+#else
+  !
+  !!! wait for the computation of ZWORK and PDP
+  !$acc wait(2)
+  !
+  !$acc kernels
+  ZTMP1_DEVICE = -ZWORK
+  !$acc end kernels
+  CALL LES_MEAN_SUBGRID( ZTMP1_DEVICE, X_LES_RES_ddxa_U_SBG_UaU , .TRUE.)
+  !
+#endif
+!$acc end data
+  CALL SECOND_MNH(ZTIME2)
+  XTIME_LES = XTIME_LES + ZTIME2 - ZTIME1
+END IF
+
+!
+!*      10.   < V'V'>
+!             -------
+!
+!!! wait for the computation of ZWORK and PDP (that uses ZFLX)
+!$acc wait(2)
+!
+! Computes the V variance
+IF (.NOT. L2D) THEN
+   !$acc kernels async(3)
+   !$acc loop independent collapse(3)
+   DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+      ZFLX(JI,JJ,JK)= (2./3.) * PTKEM(JI,JJ,JK)                                  &
+           - XCMFS * PK(JI,JJ,JK) *( (4./3.) * GY_V_M_PVM(JI,JJ,JK)                        &
+           -(2./3.) * ( GX_U_M_PUM(JI,JJ,JK)                      &
+           +GZ_W_M_PWM(JI,JJ,JK)                ) )
+   END DO !CONCURRENT
+   !$acc end kernels
+  !! &  to be tested
+  !!  + XCMFB *  PLM / SQRT(PTKEM) * (-2./3.) * PTP 
+  !
+ELSE
+  !$acc kernels async(3)
+  ZFLX(:,:,:)= (2./3.) * PTKEM                                  &
+    - XCMFS * PK *(-(2./3.) * ( GX_U_M_PUM                      &
+                               +GZ_W_M_PWM                ) )  
+  !$acc end kernels
+  !! &  to be tested
+  !!  + XCMFB *  PLM / SQRT(PTKEM) * (-2./3.) * PTP 
+  !
+END IF
+!
+!$acc kernels async(3)
+ZFLX(:,:,IKE+1) = ZFLX(:,:,IKE) 
+!$acc end kernels
+!
+! ! !!! wait for the computation of ZFLX to begin the update
+! ! !$acc wait(3)
+! ! !$acc update self(ZFLX(:,:,IKB+1:)) async(10)
+!
+!$acc kernels async(3)
+ZFLX(:,:,IKB)   = (2./3.) * PTKEM(:,:,IKB)                           &
+  - XCMFS * PK(:,:,IKB) * 2. * ZDV_DY(:,:,1)
+!$acc end kernels
+
+!!           & to be tested
+!! + XCMFB * PLM(:,:,IKB:IKB) /SQRT(PTKEM(:,:,IKB:IKB)) *         &
+!!   (-2./3.) * PTP(:,:,IKB:IKB)
+!
+! extrapolates this flux under the ground with the surface flux
+!$acc kernels async(3)
+#ifndef MNH_BITREP
+ZFLX(:,:,IKB-1) =                                                            &
+        PTAU11M(:,:) * PSINSLOPE(:,:)**2 * PDIRCOSZW(:,:)**2                 &         
+  +2. * PTAU12M(:,:) * PCOSSLOPE(:,:)* PSINSLOPE(:,:) * PDIRCOSZW(:,:)       &
+  +     PTAU22M(:,:) * PCOSSLOPE(:,:)**2                                     &
+  +     PTAU33M(:,:) * PSINSLOPE(:,:)**2 * ZDIRSINZW(:,:)**2                 &
+  -2. * PCDUEFF(:,:)*       (                                                &
+      PUSLOPEM(:,:) * PSINSLOPE(:,:)**2 * ZDIRSINZW(:,:) * PDIRCOSZW(:,:)    &
+    + PVSLOPEM(:,:) * PCOSSLOPE(:,:)    * PSINSLOPE(:,:) * ZDIRSINZW(:,:)    )
+#else
+!$acc loop independent collapse(2)   
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU )
+ZFLX(JI,JJ,IKB-1) =                                                             &
+        PTAU11M(JI,JJ) * BR_P2(PSINSLOPE(JI,JJ)) * BR_P2(PDIRCOSZW(JI,JJ))          &
+  +2. * PTAU12M(JI,JJ) * PCOSSLOPE(JI,JJ)* PSINSLOPE(JI,JJ) * PDIRCOSZW(JI,JJ)        &
+  +     PTAU22M(JI,JJ) * BR_P2(PCOSSLOPE(JI,JJ))                                  &
+  +     PTAU33M(JI,JJ) * BR_P2(PSINSLOPE(JI,JJ)) * BR_P2(ZDIRSINZW(JI,JJ))          &
+  -2. * PCDUEFF(JI,JJ)*       (                                                 &
+      PUSLOPEM(JI,JJ) * BR_P2(PSINSLOPE(JI,JJ)) * ZDIRSINZW(JI,JJ) * PDIRCOSZW(JI,JJ) &
+      + PVSLOPEM(JI,JJ) * PCOSSLOPE(JI,JJ)    * PSINSLOPE(JI,JJ) * ZDIRSINZW(JI,JJ)     )
+END DO ! CONCURRENT
+#endif
+!$acc end kernels
+! 
+!$acc kernels async(3)
+ZFLX(:,:,IKB-1) = 2. * ZFLX(:,:,IKB-1) -  ZFLX(:,:,IKB)
+!$acc end kernels
+!
+!
+! ! !!! wait for the computation of ZFLX(:,:,1:IKB) to begin the update
+! ! !$acc update self(ZFLX(:,:,IKB+1:)) async(3)
+! ! !
+! ! !!! and wait for the update self(ZFLX(...)) to complete
+! ! !$acc wait(10)
+! ! !$acc wait(3)
+!
+!$acc wait(3)
+!!$!$acc update self(ZFLX)
+!!$CALL UPDATE_HALO_ll(TZFIELDS_ll, IINFO_ll)
+!!$!$acc update device(ZFLX) async(10)
+CALL GET_HALO_D(ZFLX)
+!
+IF ( OCLOSE_OUT .AND. OTURB_FLX ) THEN
+  ! stores <V V>  
+  TZFIELD%CMNHNAME   = 'V_VAR'
+  TZFIELD%CSTDNAME   = ''
+  TZFIELD%CLONGNAME  = 'V_VAR'
+  TZFIELD%CUNITS     = 'm2 s-2'
+  TZFIELD%CDIR       = 'XY'
+  TZFIELD%CCOMMENT   = 'X_Y_Z_V_VAR'
+  TZFIELD%NGRID      = 1
+  TZFIELD%NTYPE      = TYPEREAL
+  TZFIELD%NDIMS      = 3
+  TZFIELD%LTIMEDEP   = .TRUE.
+  CALL IO_Field_write(TPFILE,TZFIELD,ZFLX)
+END IF
+!
+!!! wait for the computation of PRUS (that uses ZTMP1_DEVICE and ZTMP3_DEVICE)
+!$acc wait(1)
+!
+!
+!
+! Complete the V tendency
+IF (.NOT. L2D) THEN
+#ifndef MNH_OPENACC
+  IF (.NOT. LFLAT) THEN
+    PRVS(:,:,:)=PRVS                                          &
+                -DYM(PRHODJ * ZFLX / MYF(PDYY) )              &
+                +DZF( PDZY / MZM(PDYY) *                      &
+                MYM( MZM(PRHODJ*ZFLX) * PINV_PDZZ ) )
+  ELSE
+    PRVS(:,:,:)=PRVS -DYM(PRHODJ * ZFLX / MYF(PDYY) )
+  END IF
+!
+! Contribution to the dynamic production of TKE:
+  IF (KSPLT==1) ZWORK(:,:,:)     = - ZFLX(:,:,:) * GY_V_M_PVM
+#else
+  CALL MYF_DEVICE(PDYY, ZTMP1_DEVICE)
+  !$acc kernels async(10)
+  !$acc loop independent collapse(3)
+  DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+     ZTMP2_DEVICE(JI,JJ,JK) = PRHODJ(JI,JJ,JK) * ZFLX(JI,JJ,JK) / ZTMP1_DEVICE(JI,JJ,JK)
+  END DO !CONCURRENT   
+  !$acc end kernels
+  !
+  !!! wait for the computation of ZTMP2_DEVICE and the update of ZFLX
+  !$acc wait(10)
+  !
+  CALL DYM_DEVICE( ZTMP2_DEVICE,ZTMP3_DEVICE )
+  IF (.NOT. LFLAT) THEN
+    CALL MZM_DEVICE(PDYY,ZTMP1_DEVICE)
+    !$acc kernels
+    !$acc loop independent collapse(3)
+    DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+       ZTMP2_DEVICE(JI,JJ,JK) = PRHODJ(JI,JJ,JK) * ZFLX(JI,JJ,JK)
+    END DO !CONCURRENT   
+    !$acc end kernels
+    CALL MZM_DEVICE(ZTMP2_DEVICE,ZTMP4_DEVICE)
+    !$acc kernels
+    !$acc loop independent collapse(3)
+    DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+       ZTMP2_DEVICE(JI,JJ,JK) = ZTMP4_DEVICE(JI,JJ,JK) * PINV_PDZZ(JI,JJ,JK)
+    END DO !CONCURRENT   
+    !$acc end kernels
+    CALL MYM_DEVICE( ZTMP2_DEVICE,ZTMP4_DEVICE )
+    !$acc kernels
+    !$acc loop independent collapse(3)
+    DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+       ZTMP2_DEVICE(JI,JJ,JK) = PDZY(JI,JJ,JK) / ZTMP1_DEVICE(JI,JJ,JK) * ZTMP4_DEVICE(JI,JJ,JK)
+    END DO !CONCURRENT   
+    !$acc end kernels
+    CALL DZF_DEVICE(1,IKU,1,ZTMP2_DEVICE,ZTMP4_DEVICE )
+    !$acc kernels async(1)
+    PRVS(:,:,:)=PRVS(:,:,:)                                          &
+                -ZTMP3_DEVICE(:,:,:)              &
+                +ZTMP4_DEVICE(:,:,:)
+    !$acc end kernels
+  ELSE
+     !$acc kernels async(1)
+     !$acc loop independent collapse(3)
+     DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+        PRVS(JI,JJ,JK)=PRVS(JI,JJ,JK) - ZTMP3_DEVICE(JI,JJ,JK)
+     END DO !CONCURRENT    
+    !$acc end kernels
+  END IF
+! Contribution to the dynamic production of TKE:
+  IF (KSPLT==1) THEN
+     !$acc kernels async(2)
+     !$acc loop independent collapse(3)
+     DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+        ZWORK(JI,JJ,JK) = - ZFLX(JI,JJ,JK) * GY_V_M_PVM(JI,JJ,JK)
+     END DO !CONCURRENT   
+    !$acc end kernels
+  ENDIF
+#endif
+ELSE
+  !$acc kernels async(2)
+  ZWORK(:,:,:)     = 0.
+  !$acc end kernels
+END IF
+!
+IF (KSPLT==1) THEN
+  !
+  ! evaluate the dynamic production at w(IKB+1) in PDP(IKB)
+  !
+  !$acc kernels async(2)
+  ZWORK(:,:,IKB) = 0.5* ( -ZFLX(:,:,IKB)*ZDV_DY(:,:,1) + ZWORK(:,:,IKB+1) )
+  !$acc end kernels
+  !
+  !$acc kernels async(2)
+  PDP(:,:,:) = PDP(:,:,:) + ZWORK(:,:,:)
+  !$acc end kernels
+END IF
+!
+! Storage in the LES configuration
+!
+IF (LLES_CALL .AND. KSPLT==1) THEN
+  CALL SECOND_MNH(ZTIME1)
+!$acc data copy(X_LES_SUBGRID_V2,X_LES_RES_ddxa_V_SBG_UaV)
+  CALL LES_MEAN_SUBGRID( ZFLX, X_LES_SUBGRID_V2 ) 
+#ifndef MNH_OPENACC
+  CALL LES_MEAN_SUBGRID( -ZWORK, X_LES_RES_ddxa_V_SBG_UaV , .TRUE.)
+#else
+  !
+  !!! wait for the computation of ZWORK and PDP
+  !$acc wait(2)
+  !
+  !$acc kernels
+  ZTMP1_DEVICE = -ZWORK
+  !$acc end kernels
+  CALL LES_MEAN_SUBGRID( ZTMP1_DEVICE, X_LES_RES_ddxa_V_SBG_UaV , .TRUE.)
+  !
+#endif
+!$acc end data
+  CALL SECOND_MNH(ZTIME2)
+  XTIME_LES = XTIME_LES + ZTIME2 - ZTIME1
+END IF
+!
+!*      11.   < W'W'>
+!             -------
+!
+! Computes the W variance
+IF (.NOT. L2D) THEN
+   !$acc kernels async(2)
+   !$acc loop independent collapse(3)
+   DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+      ZFLX(JI,JJ,JK) = (2./3.) * PTKEM(JI,JJ,JK)                                  &
+           - XCMFS * PK(JI,JJ,JK) *( (4./3.) * GZ_W_M_PWM(JI,JJ,JK)                        &
+           -(2./3.) * ( GX_U_M_PUM(JI,JJ,JK)                      &
+           +GY_V_M_PVM(JI,JJ,JK)                ) )
+   END DO !CONCURRENT
+  !$acc end kernels
+  !!  &  to be tested
+  !!    -2.* XCMFB *  PLM / SQRT(PTKEM) * (-2./3.) * PTP 
+ELSE
+  !$acc kernels async(2)
+  ZFLX(:,:,:)= (2./3.) * PTKEM                                  &
+    - XCMFS * PK *( (4./3.) * GZ_W_M_PWM                        &
+                   -(2./3.) * ( GX_U_M_PUM                ) ) 
+  !$acc end kernels
+  !!  &  to be tested
+  !!    -2.* XCMFB *  PLM / SQRT(PTKEM) * (-2./3.) * PTP 
+END IF
+!
+!$acc kernels async(2)
+ZFLX(:,:,IKE+1)= ZFLX(:,:,IKE)
+!$acc end kernels
+!
+!!! wait for the computation of ZWORK, PDP and ZFLX
+!$acc wait(2)
+!
+!
+!$acc kernels async(2)
+ZFLX(:,:,IKB)   = (2./3.) * PTKEM(:,:,IKB)                           &
+  - XCMFS * PK(:,:,IKB) * 2. * ZDW_DZ(:,:,1)
+!$acc end kernels
+!
+
+!             &  to be tested
+!   - 2.* XCMFB * PLM(:,:,IKB:IKB) /SQRT(PTKEM(:,:,IKB:IKB)) *             &
+!  (-2./3.) * PTP(:,:,IKB:IKB)
+! extrapolates this flux under the ground with the surface flux
+!$acc kernels async(3)
+#ifndef MNH_BITREP
+ZFLX(:,:,IKB-1) = &    
+        PTAU11M(:,:) * ZDIRSINZW(:,:)**2                                &
+  +     PTAU33M(:,:) * PDIRCOSZW(:,:)**2                                &
+  +2. * PCDUEFF(:,:)* PUSLOPEM(:,:)  * ZDIRSINZW(:,:) * PDIRCOSZW(:,:)
+#else
+!$acc loop independent collapse(2)
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU )        
+ZFLX(JI,JJ,IKB-1) = &
+        PTAU11M(JI,JJ) * BR_P2(ZDIRSINZW(JI,JJ))                                &
+  +     PTAU33M(JI,JJ) * BR_P2(PDIRCOSZW(JI,JJ))                                &
+  +2. * PCDUEFF(JI,JJ)* PUSLOPEM(JI,JJ)  * ZDIRSINZW(JI,JJ) * PDIRCOSZW(JI,JJ)
+END DO ! CONCURRENT        
+#endif
+!$acc end kernels
+  ! 
+!
+!!! wait for the computation of ZFLX(:,:,IKB-1) and ZFLX(:,:,IKB)
+!$acc wait(2) async(3)
+!
+!$acc kernels async(3)
+ZFLX(:,:,IKB-1) = 2. * ZFLX(:,:,IKB-1) - ZFLX(:,:,IKB)
+!$acc end kernels
+!
+IF ( OCLOSE_OUT .AND. OTURB_FLX ) THEN
+  !$acc wait(3)
+  !$acc update self(ZFLX)
+  ! stores <W W>  
+  TZFIELD%CMNHNAME   = 'W_VAR'
+  TZFIELD%CSTDNAME   = ''
+  TZFIELD%CLONGNAME  = 'W_VAR'
+  TZFIELD%CUNITS     = 'm2 s-2'
+  TZFIELD%CDIR       = 'XY'
+  TZFIELD%CCOMMENT   = 'X_Y_Z_W_VAR'
+  TZFIELD%NGRID      = 1
+  TZFIELD%NTYPE      = TYPEREAL
+  TZFIELD%NDIMS      = 3
+  TZFIELD%LTIMEDEP   = .TRUE.
+  CALL IO_Field_write(TPFILE,TZFIELD,ZFLX)
+END IF
+!
+!
+!!! wait for the computation of PRVS (that uses ZTMP1_DEVICE and ZTMP3_DEVICE)
+!$acc wait(1)
+!
+
+!
+! Complete the W tendency
+!
+!PRWS(:,:,:)=PRWS(:,:,:) - DZM( PRHODJ*ZFLX/MZF(PDZZ) )
+!$acc kernels async(2)
+ZDFDDWDZ(:,:,:)    = - XCMFS * PK(:,:,:) * (4./3.)
+!$acc end kernels
+!$acc kernels async(2)
+ZDFDDWDZ(:,:,:IKB) = 0.
+!$acc end kernels
+!
+!!! wait for the computation of ZFLX(:,:,IKB-1) and ZDFDDWDZ
+!$acc wait(3) async(2)
+!$acc wait(2)
+!
+CALL TRIDIAG_W(PWM,ZFLX,ZDFDDWDZ,PTSTEP,ZMZF_DZZ,PRHODJ,ZWP)
+!
+#ifndef MNH_OPENACC
+PRWS = PRWS(:,:,:) + MZM(PRHODJ(:,:,:))*(ZWP(:,:,:)-PWM(:,:,:))/PTSTEP
+#else
+CALL MZM_DEVICE(PRHODJ(:,:,:),ZTMP1_DEVICE)
+!$acc kernels async(1)
+PRWS = PRWS(:,:,:) + ZTMP1_DEVICE *(ZWP(:,:,:)-PWM(:,:,:))/PTSTEP
+!$acc end kernels
+#endif
+!
+!* recomputes flux using guess of W
+!
+#ifndef MNH_OPENACC
+GZ_W_M_ZWP = GZ_W_M(ZWP,PDZZ)
+#else
+CALL GZ_W_M_DEVICE(1,IKU,1,ZWP,PDZZ,GZ_W_M_ZWP)
+#endif
+!$acc kernels async(2)
+!$acc loop independent collapse(3)
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=IKB+1:JKU)
+   ZFLX(JI,JJ,JK)=ZFLX(JI,JJ,JK) &
+        - XCMFS * PK(JI,JJ,JK) * (4./3.) * (GZ_W_M_ZWP(JI,JJ,JK) - GZ_W_M_PWM(JI,JJ,JK))
+END DO !CONCURRENT
+!$acc end kernels
+!
+IF (KSPLT==1) THEN
+   !Contribution to the dynamic production of TKE:
+   !$acc kernels async(2)
+   !$acc loop independent collapse(3)
+   DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+      ZWORK(JI,JJ,JK) = - ZFLX(JI,JJ,JK) * GZ_W_M_ZWP(JI,JJ,JK)
+   END DO !CONCURRENT   
+   !$acc end kernels
+  !
+  ! evaluate the dynamic production at w(IKB+1) in PDP(IKB)
+  !
+  !$acc kernels async(2)
+  ZWORK(:,:,IKB) = 0.5* ( -ZFLX(:,:,IKB)*ZDW_DZ(:,:,1) + ZWORK(:,:,IKB+1) )
+  !$acc end kernels
+  !
+  !$acc kernels async(2)
+  PDP(:,:,:) = PDP(:,:,:) + ZWORK(:,:,:)
+  !$acc end kernels
+END IF
+!
+! Storage in the LES configuration
+!
+!
+IF (LLES_CALL .AND. KSPLT==1) THEN
+  CALL SECOND_MNH(ZTIME1)
+#ifndef MNH_OPENACC
+  CALL LES_MEAN_SUBGRID( ZFLX, X_LES_SUBGRID_W2 ) 
+  CALL LES_MEAN_SUBGRID( -ZWORK, X_LES_RES_ddxa_W_SBG_UaW , .TRUE.)
+  CALL LES_MEAN_SUBGRID( GZ_M_M(PTHLM,PDZZ)*ZFLX, X_LES_RES_ddxa_Thl_SBG_UaW , .TRUE.)
+  CALL LES_MEAN_SUBGRID(ZFLX*MZF(GZ_M_W(1,IKU,1,PTHLM,PDZZ)),X_LES_RES_ddz_Thl_SBG_W2)
+  IF (KRR>=1) THEN
+    CALL LES_MEAN_SUBGRID( GZ_M_M(PRM(:,:,:,1),PDZZ)*ZFLX, &
+                           X_LES_RES_ddxa_Rt_SBG_UaW , .TRUE.)
+    CALL LES_MEAN_SUBGRID(ZFLX*MZF(GZ_M_W(1,IKU,1,PRM(:,:,:,1),PDZZ)), &
+                           X_LES_RES_ddz_Rt_SBG_W2)
+  END IF
+  DO JSV=1,NSV
+    CALL LES_MEAN_SUBGRID( GZ_M_M(PSVM(:,:,:,JSV),PDZZ)*ZFLX, &
+                           X_LES_RES_ddxa_Sv_SBG_UaW(:,:,:,JSV) , .TRUE.)
+    CALL LES_MEAN_SUBGRID(ZFLX*MZF(GZ_M_W(1,IKU,1,PSVM(:,:,:,JSV),PDZZ)), &
+                           X_LES_RES_ddz_Sv_SBG_W2(:,:,:,JSV))
+  END DO
+#else
+!$acc data copy(X_LES_SUBGRID_W2,X_LES_RES_ddxa_W_SBG_UaW,X_LES_RES_ddxa_Thl_SBG_UaW,X_LES_RES_ddz_Thl_SBG_W2)
+  !
+  CALL LES_MEAN_SUBGRID( ZFLX, X_LES_SUBGRID_W2 ) 
+  !
+  !
+  !!! wait for the computation of ZFLX, ZDP and ZWORK
+  !$acc wait(2)
+  !
+  !$acc kernels
+  ZTMP1_DEVICE = -ZWORK
+  !$acc end kernels
+  CALL LES_MEAN_SUBGRID( ZTMP1_DEVICE, X_LES_RES_ddxa_W_SBG_UaW , .TRUE.)
+  !
+  CALL GZ_M_M_DEVICE(1,IKU,1,PTHLM,PDZZ,ZTMP1_DEVICE)
+  !$acc kernels
+  ZTMP2_DEVICE = ZTMP1_DEVICE * ZFLX
+  !$acc end kernels
+  CALL LES_MEAN_SUBGRID( ZTMP2_DEVICE, X_LES_RES_ddxa_Thl_SBG_UaW , .TRUE.)
+  !
+  CALL GZ_M_W_DEVICE(1,IKU,1,PTHLM,PDZZ,ZTMP1_DEVICE)
+  CALL MZF_DEVICE(1,IKU,1,ZTMP1_DEVICE,ZTMP2_DEVICE)
+  !$acc kernels
+  ZTMP3_DEVICE = ZFLX*ZTMP2_DEVICE
+  !$acc end kernels
+  CALL LES_MEAN_SUBGRID(ZTMP3_DEVICE,X_LES_RES_ddz_Thl_SBG_W2)
+  !
+!$acc end data
+  !
+  IF (KRR>=1) THEN
+!$acc data copy(X_LES_RES_ddxa_Rt_SBG_UaW,X_LES_RES_ddz_Rt_SBG_W2)
+    !
+    CALL GZ_M_M_DEVICE(1,IKU,1,PRM(:,:,:,1),PDZZ,ZTMP1_DEVICE)
+    !$acc kernels
+    ZTMP2_DEVICE = ZTMP1_DEVICE*ZFLX
+    !$acc end kernels
+    CALL LES_MEAN_SUBGRID( ZTMP2_DEVICE, X_LES_RES_ddxa_Rt_SBG_UaW , .TRUE.)
+    !
+    CALL GZ_M_W_DEVICE(1,IKU,1,PRM(:,:,:,1),PDZZ,ZTMP1_DEVICE)
+    CALL MZF_DEVICE(1,IKU,1,ZTMP1_DEVICE,ZTMP2_DEVICE)
+    !$acc kernels
+    ZTMP3_DEVICE = ZFLX*ZTMP2_DEVICE
+    !$acc end kernels
+    CALL LES_MEAN_SUBGRID(ZTMP3_DEVICE, X_LES_RES_ddz_Rt_SBG_W2)
+    !
+!$acc end data
+  END IF
+!$acc data copy(X_LES_RES_ddxa_Sv_SBG_UaW,X_LES_RES_ddz_Sv_SBG_W2)
+  DO JSV=1,NSV
+    !
+    !
+    CALL GZ_M_M_DEVICE(1,IKU,1,PSVM(:,:,:,JSV),PDZZ,ZTMP1_DEVICE)
+    !$acc kernels
+    ZTMP2_DEVICE = ZTMP1_DEVICE*ZFLX
+    !$acc end kernels
+    CALL LES_MEAN_SUBGRID( ZTMP2_DEVICE, &
+                           X_LES_RES_ddxa_Sv_SBG_UaW(:,:,:,JSV) , .TRUE.)
+    !
+    CALL GZ_M_W_DEVICE(1,IKU,1,PSVM(:,:,:,JSV),PDZZ,ZTMP1_DEVICE)
+    CALL MZF_DEVICE(1,IKU,1,ZTMP1_DEVICE,ZTMP2_DEVICE)
+    !$acc kernels
+    ZTMP3_DEVICE = ZFLX*ZTMP2_DEVICE
+    !$acc end kernels
+    CALL LES_MEAN_SUBGRID(ZTMP3_DEVICE, X_LES_RES_ddz_Sv_SBG_W2(:,:,:,JSV))
+    !
+    !
+  END DO
+!$acc end data
+#endif
+  CALL SECOND_MNH(ZTIME2)
+  XTIME_LES = XTIME_LES + ZTIME2 - ZTIME1
+END IF
+!
+!
+!!! wait for the computation of ZFLX, ZDP and ZWORK
+!$acc wait(2)
+!!! wait for the computation of PRWS
+!$acc wait(1)
+!
+!!! et un dernier wait pour etre sur
+!$acc wait
+!
+CALL CLEANLIST_ll(TZFIELDS_ll)
+
+if ( mppdb_initialized ) then
+  !Check all inout arrays
+  call Mppdb_check( prus,   "Turb_hor_dyn_corr end:prus"   )
+  call Mppdb_check( prvs,   "Turb_hor_dyn_corr end:prvs"   )
+  call Mppdb_check( prws,   "Turb_hor_dyn_corr end:prws"   )
+  call Mppdb_check( pdp,    "Turb_hor_dyn_corr end:pdp"    )
+  call Mppdb_check( ptp,    "Turb_hor_dyn_corr end:ptp"    )
+end if
+
+!$acc end data
+
+#ifndef MNH_OPENACC
+DEALLOCATE (ZFLX, ZWORK, ZDIRSINZW, ZCOEFF, ZDZZ,                  &
+            GX_U_M_PUM, GY_V_M_PVM, GZ_W_M_PWM, GZ_W_M_ZWP,        &
+            ZMZF_DZZ, ZDFDDWDZ, ZWP,                               &
+            ZDU_DZ_DZS_DX, ZDV_DZ_DZS_DY, ZDU_DX, ZDV_DY, ZDW_DZ   )
+#else
+CALL MNH_REL_ZT3D(IZTMP1_DEVICE, IZTMP2_DEVICE, IZTMP3_DEVICE, IZTMP4_DEVICE )
+CALL MNH_REL_ZT3D(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             )
+
+#endif
+     
+
+!$acc end data
+
+END SUBROUTINE TURB_HOR_DYN_CORR
diff --git a/src/ZSOLVER/turb_hor_thermo_flux.f90 b/src/ZSOLVER/turb_hor_thermo_flux.f90
new file mode 100644
index 0000000000000000000000000000000000000000..76a1d60c284b3896f10722e6bf4f6a0112c2f37c
--- /dev/null
+++ b/src/ZSOLVER/turb_hor_thermo_flux.f90
@@ -0,0 +1,1814 @@
+!MNH_LIC Copyright 1994-2020 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.
+!-----------------------------------------------------------------
+!    ################################ 
+     MODULE MODI_TURB_HOR_THERMO_FLUX
+!    ################################ 
+!
+INTERFACE  
+!
+      SUBROUTINE TURB_HOR_THERMO_FLUX(KSPLT, KRR, KRRL, KRRI,        &
+                      OCLOSE_OUT,OTURB_FLX,OSUBG_COND,               &
+                      TPFILE,                                        &
+                      PK,PINV_PDXX,PINV_PDYY,PINV_PDZZ,PMZM_PRHODJ,  &
+                      PDXX,PDYY,PDZZ,PDZX,PDZY,                      &
+                      PDIRCOSXW,PDIRCOSYW,                           &
+                      PRHODJ,                                        &
+                      PSFTHM,PSFRM,                                  &
+                      PWM,PTHLM,PRM,                                 &
+                      PATHETA,PAMOIST,PSRCM,PFRAC_ICE,               &
+                      PRTHLS,PRRS                                    )
+!
+USE MODD_IO, ONLY: TFILEDATA
+!
+INTEGER,                  INTENT(IN)    :: KSPLT         ! split process index
+INTEGER,                  INTENT(IN)    :: KRR           ! number of moist var.
+INTEGER,                  INTENT(IN)    :: KRRL          ! number of liquid water var.
+INTEGER,                  INTENT(IN)    :: KRRI          ! number of ice water var.
+LOGICAL,                  INTENT(IN)    ::  OCLOSE_OUT   ! switch for syncronous
+                                                         ! file opening       
+LOGICAL,                  INTENT(IN)    ::  OTURB_FLX    ! switch to write the
+                                 ! turbulent fluxes in the syncronous FM-file
+LOGICAL,                 INTENT(IN)  ::   OSUBG_COND ! Switch for sub-grid 
+!                                                    condensation
+TYPE(TFILEDATA),          INTENT(IN)    ::  TPFILE       ! Output file
+!
+REAL, DIMENSION(:,:,:),   INTENT(IN)    ::  PK          ! Turbulent diffusion doef.
+                                                        ! PK = PLM * SQRT(PTKEM)
+REAL, DIMENSION(:,:,:),   INTENT(IN)    ::  PINV_PDXX   ! 1./PDXX
+REAL, DIMENSION(:,:,:),   INTENT(IN)    ::  PINV_PDYY   ! 1./PDYY
+REAL, DIMENSION(:,:,:),   INTENT(IN)    ::  PINV_PDZZ   ! 1./PDZZ
+REAL, DIMENSION(:,:,:),   INTENT(IN)    ::  PMZM_PRHODJ ! MZM(PRHODJ)
+REAL, DIMENSION(:,:,:),   INTENT(IN)    ::  PDXX, PDYY, PDZZ, PDZX, PDZY 
+                                                         ! Metric coefficients
+REAL, DIMENSION(:,:),     INTENT(IN)    ::  PDIRCOSXW, PDIRCOSYW
+! Director Cosinus along x, y and z directions at surface w-point
+REAL, DIMENSION(:,:,:),   INTENT(IN)    ::  PRHODJ       ! density * grid volume
+!
+REAL, DIMENSION(:,:),     INTENT(IN)    ::  PSFTHM,PSFRM
+!
+! Variables at t-1
+REAL, DIMENSION(:,:,:),   INTENT(IN)    ::  PWM 
+REAL, DIMENSION(:,:,:),   INTENT(IN)    ::  PTHLM 
+REAL, DIMENSION(:,:,:,:), INTENT(IN)    ::  PRM          ! mixing ratios at t-1,
+                              !  where PRM(:,:,:,1) = conservative mixing ratio
+!
+REAL, DIMENSION(:,:,:),   INTENT(IN)    ::  PATHETA      ! coefficients between 
+REAL, DIMENSION(:,:,:),   INTENT(IN)    ::  PAMOIST      ! s and Thetal and Rnp
+
+REAL, DIMENSION(:,:,:),   INTENT(IN)    ::  PSRCM
+                                  ! normalized 2nd-order flux
+                                  ! s'r'c/2Sigma_s2 at t-1 multiplied by Lambda_3
+!
+REAL, DIMENSION(:,:,:),   INTENT(IN)    ::  PFRAC_ICE    ! ri fraction of rc+ri
+!
+REAL, DIMENSION(:,:,:),   INTENT(INOUT) ::  PRTHLS
+REAL, DIMENSION(:,:,:,:), INTENT(INOUT) ::  PRRS         ! var. at t+1 -split-
+!
+END SUBROUTINE TURB_HOR_THERMO_FLUX
+!
+END INTERFACE
+!
+END MODULE MODI_TURB_HOR_THERMO_FLUX
+!     ################################################################
+      SUBROUTINE TURB_HOR_THERMO_FLUX(KSPLT, KRR, KRRL, KRRI,        &
+                      OCLOSE_OUT,OTURB_FLX,OSUBG_COND,               &
+                      TPFILE,                                        &
+                      PK,PINV_PDXX,PINV_PDYY,PINV_PDZZ,PMZM_PRHODJ,  &
+                      PDXX,PDYY,PDZZ,PDZX,PDZY,                      &
+                      PDIRCOSXW,PDIRCOSYW,                           &
+                      PRHODJ,                                        &
+                      PSFTHM,PSFRM,                                  &
+                      PWM,PTHLM,PRM,                                 &
+                      PATHETA,PAMOIST,PSRCM,PFRAC_ICE,               &
+                      PRTHLS,PRRS                                    )
+!     ################################################################
+!
+!
+!!****  *TURB_HOR* -routine to compute the source terms in the meso-NH
+!!               model equations due to the non-vertical turbulent fluxes.
+!!
+!!    PURPOSE
+!!    -------
+!!
+!!     see TURB_HOR
+!!
+!!**  METHOD
+!!    ------
+!!
+!!    EXTERNAL
+!!    --------
+!!
+!!    IMPLICIT ARGUMENTS
+!!    ------------------
+!!
+!!    REFERENCE
+!!    ---------
+!!
+!!    AUTHOR
+!!    ------
+!!
+!!      Joan Cuxart             * INM and Meteo-France *
+!!
+!!    MODIFICATIONS
+!!    -------------
+!!                     Aug    , 1997 (V. Saravane) spliting of TURB_HOR
+!!                     Nov  27, 1997 (V. Masson) clearing of the routine
+!!                     Feb. 18, 1998 (J. Stein) bug for v'RC'
+!!                     Oct  18, 2000 (V. Masson) LES computations + LFLAT switch
+!!                     Nov  06, 2002 (V. Masson) LES budgets
+!!                     Feb  20, 2003 (JP Pinty)  Add PFRAC_ICE
+!!                     October 2009 (G. Tanguy) add ILENCH=LEN(YCOMMENT) after
+!!                                              change of YCOMMENT
+!!                     04/2016 (M.Moge) Use openACC directives to port the TURB part of Meso-NH on GPU
+!!  Philippe Wautelet: 05/2016-04/2018: new data structures and calls for I/O
+!! --------------------------------------------------------------------------
+!       
+!*      0. DECLARATIONS
+!          ------------
+!
+USE MODD_CST
+USE MODD_CONF
+USE MODD_CTURB
+USE MODD_IO,             ONLY: TFILEDATA
+USE MODD_PARAMETERS
+USE MODD_LES
+!
+USE MODE_FIELD,          ONLY: TFIELDDATA, TYPEREAL
+USE MODE_IO_FIELD_WRITE, only: IO_Field_write
+use mode_mppdb
+!
+USE MODI_GRADIENT_M
+USE MODI_GRADIENT_U
+USE MODI_GRADIENT_V
+USE MODI_GRADIENT_W
+#ifndef MNH_OPENACC
+USE MODI_SHUMAN
+#else
+USE MODI_SHUMAN_DEVICE
+#endif
+USE MODI_LES_MEAN_SUBGRID
+!
+USE MODI_SECOND_MNH
+!
+#ifdef MNH_OPENACC
+USE MODE_MNH_ZWORK , ONLY : MNH_ALLOCATE_ZT3D , MNH_REL_ZT3D, MNH_ALLOCATE_ZT3DP , MNH_ALLOCATE_ZT2D, &
+     MNH_ALLOCATE_ZT4D , MNH_REL_ZT4D, &
+     MNH_CHECK_IN_ZT3D,MNH_CHECK_OUT_ZT3D
+#endif
+!
+IMPLICIT NONE
+!
+!
+!*       0.1  declaration of arguments
+!
+!
+!
+INTEGER,                  INTENT(IN)    :: KSPLT         ! split process index
+INTEGER,                  INTENT(IN)    :: KRR           ! number of moist var.
+INTEGER,                  INTENT(IN)    :: KRRL          ! number of liquid water var.
+INTEGER,                  INTENT(IN)    :: KRRI          ! number of ice water var.
+LOGICAL,                  INTENT(IN)    ::  OCLOSE_OUT   ! switch for syncronous
+                                                         ! file opening       
+LOGICAL,                  INTENT(IN)    ::  OTURB_FLX    ! switch to write the
+                                 ! turbulent fluxes in the syncronous FM-file
+LOGICAL,                 INTENT(IN)  ::   OSUBG_COND ! Switch for sub-grid 
+!                                                    condensation
+TYPE(TFILEDATA),          INTENT(IN)    ::  TPFILE       ! Output file
+!
+REAL, DIMENSION(:,:,:),   INTENT(IN)    ::  PK          ! Turbulent diffusion doef.
+                                                        ! PK = PLM * SQRT(PTKEM)
+REAL, DIMENSION(:,:,:),   INTENT(IN)    ::  PINV_PDXX   ! 1./PDXX
+REAL, DIMENSION(:,:,:),   INTENT(IN)    ::  PINV_PDYY   ! 1./PDYY
+REAL, DIMENSION(:,:,:),   INTENT(IN)    ::  PINV_PDZZ   ! 1./PDZZ
+REAL, DIMENSION(:,:,:),   INTENT(IN)    ::  PMZM_PRHODJ ! MZM(PRHODJ)
+REAL, DIMENSION(:,:,:),   INTENT(IN)    ::  PDXX, PDYY, PDZZ, PDZX, PDZY 
+                                                         ! Metric coefficients
+REAL, DIMENSION(:,:),     INTENT(IN)    ::  PDIRCOSXW, PDIRCOSYW
+! Director Cosinus along x, y and z directions at surface w-point
+REAL, DIMENSION(:,:,:),   INTENT(IN)    ::  PRHODJ       ! density * grid volume
+!
+REAL, DIMENSION(:,:),     INTENT(IN)    ::  PSFTHM,PSFRM
+!
+! Variables at t-1
+REAL, DIMENSION(:,:,:),   INTENT(IN)    ::  PWM 
+REAL, DIMENSION(:,:,:),   INTENT(IN)    ::  PTHLM
+REAL, DIMENSION(:,:,:,:), INTENT(IN)    ::  PRM          ! mixing ratios at t-1,
+                              !  where PRM(:,:,:,1) = conservative mixing ratio
+!
+REAL, DIMENSION(:,:,:),   INTENT(IN)    ::  PATHETA      ! coefficients between 
+REAL, DIMENSION(:,:,:),   INTENT(IN)    ::  PAMOIST      ! s and Thetal and Rnp
+
+REAL, DIMENSION(:,:,:),   INTENT(IN)    ::  PSRCM
+                                  ! normalized 2nd-order flux
+                                  ! s'r'c/2Sigma_s2 at t-1 multiplied by Lambda_3
+!
+REAL, DIMENSION(:,:,:),   INTENT(IN)    ::  PFRAC_ICE    ! ri fraction of rc+ri
+!
+REAL, DIMENSION(:,:,:),   INTENT(INOUT) ::  PRTHLS
+REAL, DIMENSION(:,:,:,:), INTENT(INOUT) ::  PRRS         ! var. at t+1 -split-
+!
+!
+!*       0.2  declaration of local variables
+!
+REAL, DIMENSION(:,:,:), pointer , contiguous :: ZFLX,ZFLXC ! work arrays
+!! REAL, DIMENSION(:,:,:), pointer , contiguous :: ZVPTV
+INTEGER             :: IKB,IKE,IKU
+                                    ! Index values for the Beginning and End
+                                    ! mass points of the domain  
+REAL, DIMENSION(:,:,:), pointer , contiguous :: ZCOEFF
+                                    ! coefficients for the uncentred gradient 
+                                    ! computation near the ground
+INTEGER :: IZFLX,IZFLXC,IZCOEFF
+!
+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
+!
+INTEGER  :: JIU,JJU,JKU
+INTEGER  :: JI,JJ,JK
+!
+! ---------------------------------------------------------------------------
+
+!$acc data present( PK, PINV_PDXX, PINV_PDYY, PINV_PDZZ, PMZM_PRHODJ, &
+!$acc &             PDXX, PDYY, PDZZ, PDZX, PDZY,                     &
+!$acc &             PDIRCOSXW, PDIRCOSYW,                             &
+!$acc &             PRHODJ,                                           &
+!$acc &             PSFTHM, PSFRM,                                    &
+!$acc &             PWM, PTHLM, PRM,                                  &
+!$acc &             PATHETA, PAMOIST, PSRCM, PFRAC_ICE,               &
+!$acc &             PRTHLS, PRRS                                      )
+
+if ( mppdb_initialized ) then
+  !Check all in arrays
+  call Mppdb_check( pinv_pdxx,   "Turb_hor_thermo_flux beg:pinv_pdxx"   )
+  call Mppdb_check( pinv_pdyy,   "Turb_hor_thermo_flux beg:pinv_pdyy"   )
+  call Mppdb_check( pinv_pdzz,   "Turb_hor_thermo_flux beg:pinv_pdzz"   )
+  call Mppdb_check( pmzm_prhodj, "Turb_hor_thermo_flux beg:pmzm_prhodj" )
+  call Mppdb_check( pdxx,        "Turb_hor_thermo_flux beg:pdxx"        )
+  call Mppdb_check( pdyy,        "Turb_hor_thermo_flux beg:pdyy"        )
+  call Mppdb_check( pdzz,        "Turb_hor_thermo_flux beg:pdzz"        )
+  call Mppdb_check( pdzx,        "Turb_hor_thermo_flux beg:pdzx"        )
+  call Mppdb_check( pdzy,        "Turb_hor_thermo_flux beg:pdzy"        )
+  call Mppdb_check( pdircosxw,   "Turb_hor_thermo_flux beg:pdircosxw"   )
+  call Mppdb_check( pdircosyw,   "Turb_hor_thermo_flux beg:pdircosyw"   )
+  call Mppdb_check( prhodj,      "Turb_hor_thermo_flux beg:prhodj"      )
+  call Mppdb_check( psfthm,      "Turb_hor_thermo_flux beg:psfthm"      )
+  call Mppdb_check( psfrm,       "Turb_hor_thermo_flux beg:psfrm"       )
+  call Mppdb_check( pwm,         "Turb_hor_thermo_flux beg:pwm"         )
+  call Mppdb_check( pthlm,       "Turb_hor_thermo_flux beg:pthlm"       )
+  call Mppdb_check( prm,         "Turb_hor_thermo_flux beg:prm"         )
+  call Mppdb_check( patheta,     "Turb_hor_thermo_flux beg:patheta"     )
+  call Mppdb_check( pamoist,     "Turb_hor_thermo_flux beg:pamoist"     )
+  call Mppdb_check( psrcm,       "Turb_hor_thermo_flux beg:psrcm"       )
+  call Mppdb_check( pfrac_ice,   "Turb_hor_thermo_flux beg:pfrac_ice"   )
+  !Check all inout arrays
+  call Mppdb_check( prthls, "Turb_hor_thermo_flux beg:prthls" )
+  call Mppdb_check( prrs,   "Turb_hor_thermo_flux beg:prrs"   )
+end if
+
+JIU =  size(pthlm, 1 )
+JJU =  size(pthlm, 2 )
+JKU =  size(pthlm, 3 )
+
+#ifndef MNH_OPENACC
+allocate( zflx (JIU,JJU,JKU) )
+allocate( zflxc(JIU,JJU,JKU) )
+! allocate( zvptv(JIU,JJU,JKU) )
+
+allocate( zcoeff(JIU,JJU, 1 + jpvext : 3 + jpvext ) )
+#else
+CALL  MNH_CHECK_IN_ZT3D("TURB_HOR_THERMO_FLUX")
+izflx  = MNH_ALLOCATE_ZT3D( zflx ,JIU,JJU,JKU )
+izflxc = MNH_ALLOCATE_ZT3D( zflxc,JIU,JJU,JKU )
+! izvptv= MNH_ALLOCATE_ZT3D( zvptv,JIU,JJU,JKU )
+
+izcoeff= MNH_ALLOCATE_ZT3DP( zcoeff,JIU,JJU, 1 + jpvext , 3 + jpvext )
+
+#endif
+
+#ifdef MNH_OPENACC
+iztmp1_device= MNH_ALLOCATE_ZT3D( ztmp1_device,JIU,JJU,JKU  )
+iztmp2_device= MNH_ALLOCATE_ZT3D( ztmp2_device,JIU,JJU,JKU  )
+iztmp3_device= MNH_ALLOCATE_ZT3D( ztmp3_device,JIU,JJU,JKU  )
+iztmp4_device= MNH_ALLOCATE_ZT3D( ztmp4_device,JIU,JJU,JKU  )
+iztmp5_device= MNH_ALLOCATE_ZT3D( ztmp5_device,JIU,JJU,JKU  )
+iztmp6_device= MNH_ALLOCATE_ZT3D( ztmp6_device,JIU,JJU,JKU  )
+iztmp7_device= MNH_ALLOCATE_ZT3D( ztmp7_device,JIU,JJU,JKU  )
+iztmp8_device= MNH_ALLOCATE_ZT3D( ztmp8_device,JIU,JJU,JKU  )
+#endif
+
+!$acc data present( ZFLX, ZFLXC, ZCOEFF,                                    &
+!$acc &            ZTMP1_DEVICE, ZTMP2_DEVICE, ZTMP3_DEVICE, ZTMP4_DEVICE, &
+!$acc &            ZTMP5_DEVICE, ZTMP6_DEVICE, ZTMP7_DEVICE, ZTMP8_DEVICE  )
+
+!
+!*       1.   PRELIMINARY COMPUTATIONS
+!             ------------------------
+!
+IKB = 1+JPVEXT               
+IKE = SIZE(PTHLM,3)-JPVEXT    
+IKU = SIZE(PTHLM,3)
+!
+!
+!  compute the coefficients for the uncentred gradient computation near the 
+!  ground
+!$acc kernels
+ZCOEFF(:,:,IKB+2)= - PDZZ(:,:,IKB+1) /      &
+       ( (PDZZ(:,:,IKB+2)+PDZZ(:,:,IKB+1)) * PDZZ(:,:,IKB+2) )
+ZCOEFF(:,:,IKB+1)=   (PDZZ(:,:,IKB+2)+PDZZ(:,:,IKB+1)) /      &
+       ( PDZZ(:,:,IKB+1) * PDZZ(:,:,IKB+2) )
+ZCOEFF(:,:,IKB)= - (PDZZ(:,:,IKB+2)+2.*PDZZ(:,:,IKB+1)) /      &
+       ( (PDZZ(:,:,IKB+2)+PDZZ(:,:,IKB+1)) * PDZZ(:,:,IKB+1) )
+!$acc end kernels
+!
+!*       2.   < U' THETA'l >
+!             --------------
+!
+! 
+#ifndef MNH_OPENACC
+ZFLX(:,:,:)     = -XCSHF * MXM( PK ) * GX_M_U(1,IKU,1,PTHLM,PDXX,PDZZ,PDZX)
+ZFLX(:,:,IKE+1) = ZFLX(:,:,IKE) 
+#else
+CALL MXM_DEVICE( PK, ZTMP1_DEVICE )
+CALL GX_M_U_DEVICE(1,IKU,1,PTHLM,PDXX,PDZZ,PDZX,ZTMP2_DEVICE)
+!$acc kernels
+!$acc loop independent collapse(3)
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+   ZFLX(JI,JJ,JK)     = -XCSHF * ZTMP1_DEVICE(JI,JJ,JK) * ZTMP2_DEVICE(JI,JJ,JK)
+END DO
+ZFLX(:,:,IKE+1) = ZFLX(:,:,IKE) 
+!$acc end kernels
+#endif
+!
+! Compute the flux at the first inner U-point with an uncentred vertical  
+! gradient
+#ifndef MNH_OPENACC
+ZFLX(:,:,IKB:IKB) = -XCSHF * MXM( PK(:,:,IKB:IKB) ) *          &
+  ( DXM(PTHLM(:,:,IKB:IKB)) * PINV_PDXX(:,:,IKB:IKB)           &
+   -MXM( ZCOEFF(:,:,IKB+2:IKB+2)*PTHLM(:,:,IKB+2:IKB+2)        &
+         +ZCOEFF(:,:,IKB+1:IKB+1)*PTHLM(:,:,IKB+1:IKB+1)       &
+         +ZCOEFF(:,:,IKB  :IKB  )*PTHLM(:,:,IKB  :IKB  ))      &
+        *0.5* ( PDZX(:,:,IKB+1:IKB+1)+PDZX(:,:,IKB:IKB))       &
+        * PINV_PDXX(:,:,IKB:IKB) )
+#else
+CALL MXM_DEVICE( PK(:,:,IKB:IKB), ZTMP1_DEVICE(:,:,1:1) )
+CALL DXM_DEVICE( PTHLM(:,:,IKB:IKB), ZTMP2_DEVICE(:,:,1:1) )
+!$acc kernels
+ZTMP3_DEVICE(:,:,1) = ZCOEFF(:,:,IKB+2)*PTHLM(:,:,IKB+2)        &
+         +ZCOEFF(:,:,IKB+1)*PTHLM(:,:,IKB+1)       &
+         +ZCOEFF(:,:,IKB  )*PTHLM(:,:,IKB  )
+!$acc end kernels
+CALL MXM_DEVICE( ZTMP3_DEVICE(:,:,1:1), ZTMP4_DEVICE(:,:,1:1)) 
+!$acc kernels
+ZFLX(:,:,IKB) = -XCSHF * ZTMP1_DEVICE(:,:,1) *          &
+  ( ZTMP2_DEVICE(:,:,1) * PINV_PDXX(:,:,IKB) - ZTMP4_DEVICE(:,:,1)      &
+        *0.5* ( PDZX(:,:,IKB+1)+PDZX(:,:,IKB))       &
+        * PINV_PDXX(:,:,IKB) )
+! acc end kernels
+#endif
+! extrapolates the flux under the ground so that the vertical average with 
+! the IKB flux gives the ground value  ( warning the tangential surface
+! flux has been set to 0 for the moment !!  to be improved )
+#ifndef MNH_OPENACC
+ZFLX(:,:,IKB-1:IKB-1) = 2. * MXM(  SPREAD( PSFTHM(:,:)* PDIRCOSXW(:,:), 3,1) )  &
+                       - ZFLX(:,:,IKB:IKB)
+#else
+! acc kernels
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU )
+   ZTMP1_DEVICE(JI,JJ,1) = PSFTHM(JI,JJ)* PDIRCOSXW(JI,JJ)
+END DO
+!$acc end kernels
+  CALL MXM_DEVICE( ZTMP1_DEVICE(:,:,1:1), ZTMP2_DEVICE(:,:,1:1) )
+!$acc kernels
+  ZFLX(:,:,IKB-1) = 2. * ZTMP2_DEVICE(:,:,1) - ZFLX(:,:,IKB)
+!$acc end kernels
+#endif
+!
+! Add this source to the Theta_l sources
+!
+#ifndef MNH_OPENACC
+IF (.NOT. LFLAT) THEN
+  PRTHLS(:,:,:) =  PRTHLS(:,:,:)                                                   &
+                - DXF( MXM(PRHODJ) * ZFLX(:,:,:) * PINV_PDXX(:,:,:) )                          &
+                + DZF( PMZM_PRHODJ(:,:,:) *MXF(PDZX*(MZM(ZFLX(:,:,:) * PINV_PDXX(:,:,:)))) * PINV_PDZZ(:,:,:) )
+ELSE
+  PRTHLS(:,:,:) =  PRTHLS(:,:,:) - DXF( MXM(PRHODJ) * ZFLX(:,:,:) * PINV_PDXX(:,:,:) )
+END IF
+#else
+IF (.NOT. LFLAT) THEN
+  CALL MXM_DEVICE(PRHODJ, ZTMP1_DEVICE)
+  !$acc kernels
+  !$acc loop independent collapse(3)
+  DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+     ZTMP2_DEVICE(JI,JJ,JK) = ZTMP1_DEVICE(JI,JJ,JK) * ZFLX(JI,JJ,JK) * PINV_PDXX(JI,JJ,JK)
+  END DO
+  !$acc end kernels
+  CALL DXF_DEVICE(ZTMP2_DEVICE, ZTMP3_DEVICE)
+  !$acc kernels
+  !$acc loop independent collapse(3)
+  DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+     ZTMP2_DEVICE(JI,JJ,JK) = ZFLX(JI,JJ,JK) * PINV_PDXX(JI,JJ,JK)
+  END DO
+  !$acc end kernels
+  CALL MZM_DEVICE(ZTMP2_DEVICE,ZTMP4_DEVICE)
+  !$acc kernels
+  !$acc loop independent collapse(3)
+  DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)  
+     ZTMP2_DEVICE(JI,JJ,JK) = PDZX(JI,JJ,JK)*ZTMP4_DEVICE(JI,JJ,JK)
+  END DO
+!$acc end kernels
+  CALL MXF_DEVICE(ZTMP2_DEVICE, ZTMP4_DEVICE)
+!$acc kernels
+!$acc loop independent collapse(3)  
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+   ZTMP2_DEVICE(JI,JJ,JK) = PMZM_PRHODJ(JI,JJ,JK) * ZTMP4_DEVICE(JI,JJ,JK) * PINV_PDZZ(JI,JJ,JK)
+END DO
+!$acc end kernels
+  CALL DZF_DEVICE(1,IKU,1,ZTMP2_DEVICE,ZTMP4_DEVICE )
+!$acc kernels
+  PRTHLS(:,:,:) = PRTHLS(:,:,:) - ZTMP3_DEVICE(:,:,:) + ZTMP4_DEVICE(:,:,:)
+!$acc end kernels
+ELSE
+  CALL MXM_DEVICE(PRHODJ, ZTMP1_DEVICE)
+!$acc kernels
+  ZTMP2_DEVICE(:,:,:) = ZTMP1_DEVICE(:,:,:) * ZFLX(:,:,:) * PINV_PDXX(:,:,:)
+!$acc end kernels
+  CALL DXF_DEVICE(ZTMP2_DEVICE, ZTMP3_DEVICE)
+!$acc kernels
+  PRTHLS(:,:,:) =  PRTHLS(:,:,:) - ZTMP3_DEVICE(:,:,:)
+!$acc end kernels
+END IF
+#endif
+!
+! Compute the equivalent tendancy for Rc and Ri
+!
+#ifndef MNH_OPENACC
+IF ( KRRL >= 1 ) THEN
+  IF (.NOT. LFLAT) THEN
+    ZFLXC(:,:,:) = 2.*( MXF( MXM( PRHODJ(:,:,:)*PATHETA(:,:,:)*PSRCM(:,:,:) )*ZFLX(:,:,:) )                       &
+                +MZF( MZM( PRHODJ(:,:,:)*PATHETA(:,:,:)*PSRCM(:,:,:) )*MXF(                         &
+                                               PDZX*(MZM( ZFLX(:,:,:)*PINV_PDXX(:,:,:) )) ) )&
+               )
+    IF ( KRRI >= 1 ) THEN
+      PRRS(:,:,:,2) = PRRS(:,:,:,2) +  2. *                                    &
+        (- DXF( MXM( PRHODJ(:,:,:)*PATHETA(:,:,:)*PSRCM(:,:,:) )*ZFLX(:,:,:)*PINV_PDXX(:,:,:) )                   &
+         + DZF( MZM( PRHODJ(:,:,:)*PATHETA(:,:,:)*PSRCM(:,:,:) )* &
+           MXF( PDZX*(MZM( ZFLX(:,:,:)*PINV_PDXX(:,:,:) )) )&
+                                           *PINV_PDZZ(:,:,:) )                        &
+        )*(1.0-PFRAC_ICE(:,:,:))
+      PRRS(:,:,:,4) = PRRS(:,:,:,4) +  2. *                                    &
+        (- DXF( MXM( PRHODJ(:,:,:)*PATHETA(:,:,:)*PSRCM(:,:,:) )*ZFLX(:,:,:)*PINV_PDXX(:,:,:) )                   &
+         + DZF( MZM( PRHODJ(:,:,:)*PATHETA(:,:,:)*PSRCM(:,:,:) )* &
+           MXF( PDZX*(MZM( ZFLX(:,:,:)*PINV_PDXX(:,:,:) )) )&
+                                           *PINV_PDZZ(:,:,:) )                        &
+        )*PFRAC_ICE(:,:,:)
+    ELSE
+      PRRS(:,:,:,2) = PRRS(:,:,:,2) +  2. *                                    &
+        (- DXF( MXM( PRHODJ(:,:,:)*PATHETA(:,:,:)*PSRCM(:,:,:) )*ZFLX(:,:,:)*PINV_PDXX(:,:,:) )                   &
+         + DZF( MZM( PRHODJ(:,:,:)*PATHETA(:,:,:)*PSRCM(:,:,:) )* &
+           MXF( PDZX*(MZM( ZFLX(:,:,:)*PINV_PDXX(:,:,:) )) )&
+                                           *PINV_PDZZ(:,:,:) )                        &
+        )
+    END IF
+  ELSE
+    ZFLXC(:,:,:) = 2.*MXF( MXM( PRHODJ(:,:,:)*PATHETA(:,:,:)*PSRCM(:,:,:) )*ZFLX )
+    IF ( KRRI >= 1 ) THEN
+      PRRS(:,:,:,2) = PRRS(:,:,:,2) -  2. *                                    &
+        DXF( MXM( PRHODJ(:,:,:)*PATHETA(:,:,:)*PSRCM(:,:,:) )*ZFLX(:,:,:)*PINV_PDXX(:,:,:) )*(1.0-PFRAC_ICE(:,:,:))
+      PRRS(:,:,:,4) = PRRS(:,:,:,4) -  2. *                                    &
+        DXF( MXM( PRHODJ(:,:,:)*PATHETA(:,:,:)*PSRCM(:,:,:) )*ZFLX(:,:,:)*PINV_PDXX(:,:,:) )*PFRAC_ICE(:,:,:)
+    ELSE
+      PRRS(:,:,:,2) = PRRS(:,:,:,2) -  2. *                                    &
+        DXF( MXM( PRHODJ(:,:,:)*PATHETA(:,:,:)*PSRCM(:,:,:) )*ZFLX(:,:,:)*PINV_PDXX(:,:,:) )
+    END IF
+  END IF
+END IF
+#else
+IF ( KRRL >= 1 ) THEN
+  IF (.NOT. LFLAT) THEN
+    !$acc kernels
+    ZTMP1_DEVICE(:,:,:) = PRHODJ(:,:,:)*PATHETA(:,:,:)*PSRCM(:,:,:)
+    !$acc end kernels
+    CALL MZM_DEVICE( ZTMP1_DEVICE, ZTMP4_DEVICE )
+    CALL MXM_DEVICE( ZTMP1_DEVICE, ZTMP2_DEVICE )
+    !$acc kernels
+    ZTMP1_DEVICE(:,:,:) = ZTMP2_DEVICE(:,:,:) *ZFLX(:,:,:)
+    !$acc end kernels
+    CALL MXF_DEVICE( ZTMP1_DEVICE, ZTMP2_DEVICE)
+    !$acc kernels
+    ZTMP1_DEVICE(:,:,:) = ZFLX(:,:,:)*PINV_PDXX(:,:,:)
+    !$acc end kernels
+    CALL MZM_DEVICE( ZTMP1_DEVICE, ZTMP5_DEVICE )
+    !$acc kernels
+    ZTMP6_DEVICE(:,:,:) = PDZX(:,:,:)*ZTMP5_DEVICE(:,:,:)
+    !$acc end kernels
+    CALL MXF_DEVICE( ZTMP6_DEVICE, ZTMP5_DEVICE )
+    !$acc kernels
+    ZTMP6_DEVICE(:,:,:) =  ZTMP4_DEVICE(:,:,:)*ZTMP5_DEVICE(:,:,:)
+    !$acc end kernels
+    CALL MZF_DEVICE(1,IKU,1, ZTMP6_DEVICE,ZTMP7_DEVICE )
+    !$acc kernels
+    ZFLXC(:,:,:) = 2.*( ZTMP2_DEVICE(:,:,:) +ZTMP7_DEVICE(:,:,:) )
+    !$acc end kernels
+    IF ( KRRI >= 1 ) THEN
+      !$acc kernels
+      ZTMP1_DEVICE(:,:,:) = PRHODJ(:,:,:)*PATHETA(:,:,:)*PSRCM(:,:,:)
+      !$acc end kernels
+      CALL MXM_DEVICE( ZTMP1_DEVICE, ZTMP2_DEVICE ) 
+      !$acc kernels
+      ZTMP6_DEVICE(:,:,:) = ZTMP2_DEVICE(:,:,:)*ZFLX(:,:,:)*PINV_PDXX(:,:,:)
+      !$acc end kernels
+      CALL DXF_DEVICE( ZTMP6_DEVICE, ZTMP2_DEVICE)
+      !$acc kernels
+      ZTMP3_DEVICE(:,:,:) = ZTMP4_DEVICE(:,:,:)*ZTMP5_DEVICE(:,:,:)*PINV_PDZZ(:,:,:)
+      !$acc end kernels
+      CALL DZF_DEVICE(1,IKU,1, ZTMP3_DEVICE, ZTMP4_DEVICE )
+!$acc kernels
+      PRRS(:,:,:,2) = PRRS(:,:,:,2) +  2. * (- ZTMP2_DEVICE(:,:,:) + ZTMP4_DEVICE(:,:,:) )*(1.0-PFRAC_ICE(:,:,:))
+      PRRS(:,:,:,4) = PRRS(:,:,:,4) +  2. * (- ZTMP2_DEVICE(:,:,:) + ZTMP4_DEVICE(:,:,:) )*PFRAC_ICE(:,:,:)
+!$acc end kernels
+    ELSE
+      !$acc kernels
+      ZTMP1_DEVICE(:,:,:) = PRHODJ(:,:,:)*PATHETA(:,:,:)*PSRCM(:,:,:)
+      !$acc end kernels
+      CALL MXM_DEVICE( ZTMP1_DEVICE, ZTMP2_DEVICE )
+      !$acc kernels
+      ZTMP1_DEVICE(:,:,:) = ZTMP2_DEVICE(:,:,:) *ZFLX(:,:,:)*PINV_PDXX(:,:,:)
+      !$acc end kernels
+      CALL DXF_DEVICE( ZTMP6_DEVICE, ZTMP2_DEVICE)
+      !$acc kernels
+      ZTMP3_DEVICE(:,:,:) = ZTMP4_DEVICE(:,:,:)*ZTMP5_DEVICE(:,:,:)*PINV_PDZZ(:,:,:)
+      !$acc end kernels
+      CALL DZF_DEVICE(1,IKU,1, ZTMP3_DEVICE, ZTMP4_DEVICE )
+!$acc kernels
+      PRRS(:,:,:,2) = PRRS(:,:,:,2) + 2. * (- ZTMP2_DEVICE(:,:,:) + ZTMP4_DEVICE(:,:,:) )
+!$acc end kernels
+    END IF
+  ELSE
+    !$acc kernels
+    ZTMP1_DEVICE(:,:,:) = PRHODJ(:,:,:)*PATHETA(:,:,:)*PSRCM(:,:,:)
+    !$acc end kernels
+    CALL MXM_DEVICE( ZTMP1_DEVICE,ZTMP2_DEVICE )
+    !$acc kernels
+    ZTMP3_DEVICE(:,:,:) = ZTMP2_DEVICE(:,:,:)*ZFLX(:,:,:)
+    !$acc end kernels
+    CALL MXF_DEVICE( ZTMP3_DEVICE, ZTMP4_DEVICE )
+    !$acc kernels
+    ZFLXC(:,:,:) = 2.*ZTMP4_DEVICE(:,:,:)
+    !$acc end kernels
+    IF ( KRRI >= 1 ) THEN
+      !$acc kernels
+      ZTMP1_DEVICE(:,:,:) =  ZTMP2_DEVICE(:,:,:)*ZFLX(:,:,:)*PINV_PDXX(:,:,:)
+      !$acc end kernels
+      CALL DXF_DEVICE( ZTMP1_DEVICE, ZTMP2_DEVICE )
+      !$acc kernels
+      PRRS(:,:,:,2) = PRRS(:,:,:,2) - 2. * ZTMP2_DEVICE(:,:,:)*(1.0-PFRAC_ICE(:,:,:))
+      PRRS(:,:,:,4) = PRRS(:,:,:,4) - 2. * ZTMP2_DEVICE(:,:,:)*PFRAC_ICE(:,:,:)
+      !$acc end kernels
+    ELSE
+      !$acc kernels
+      ZTMP1_DEVICE(:,:,:) =  ZTMP2_DEVICE(:,:,:)*ZFLX(:,:,:)*PINV_PDXX(:,:,:)
+      !$acc end kernels
+      CALL DXF_DEVICE( ZTMP1_DEVICE, ZTMP2_DEVICE )
+      !$acc kernels
+      PRRS(:,:,:,2) = PRRS(:,:,:,2) - 2. * ZTMP2_DEVICE(:,:,:)
+      !$acc end kernels
+    END IF
+  END IF
+END IF
+#endif
+!
+!! stores this flux in ZWORK to compute later <U' VPT'>
+!!ZWORK(:,:,:) = ZFLX(:,:,:) 
+!
+! stores the horizontal  <U THl>
+IF ( OCLOSE_OUT .AND. OTURB_FLX ) THEN
+  TZFIELD%CMNHNAME   = 'UTHL_FLX'
+  TZFIELD%CSTDNAME   = ''
+  TZFIELD%CLONGNAME  = 'UTHL_FLX'
+  TZFIELD%CUNITS     = 'K m s-1'
+  TZFIELD%CDIR       = 'XY'
+  TZFIELD%CCOMMENT   = 'X_Y_Z_UTHL_FLX'
+  TZFIELD%NGRID      = 2
+  TZFIELD%NTYPE      = TYPEREAL
+  TZFIELD%NDIMS      = 3
+  TZFIELD%LTIMEDEP   = .TRUE.
+!$acc update self(ZFLX)
+  CALL IO_Field_write(TPFILE,TZFIELD,ZFLX(:,:,:))
+END IF
+!
+IF (KSPLT==1 .AND. LLES_CALL) THEN
+  CALL SECOND_MNH(ZTIME1)
+#ifndef MNH_OPENACC
+  CALL LES_MEAN_SUBGRID( MXF(ZFLX), X_LES_SUBGRID_UThl ) 
+  CALL LES_MEAN_SUBGRID( MZF(MXF(GX_W_UW(PWM,PDXX,PDZZ,PDZX)*MZM(ZFLX))),&
+                         X_LES_RES_ddxa_W_SBG_UaThl , .TRUE. )
+  CALL LES_MEAN_SUBGRID( GX_M_M(PTHLM,PDXX,PDZZ,PDZX)*MXF(ZFLX),&
+                         X_LES_RES_ddxa_Thl_SBG_UaThl , .TRUE. )
+  IF (KRR>=1) THEN
+    CALL LES_MEAN_SUBGRID( GX_M_M(PRM(:,:,:,1),PDXX,PDZZ,PDZX)*MXF(ZFLX), &
+                           X_LES_RES_ddxa_Rt_SBG_UaThl , .TRUE. )
+  END IF
+#else
+!$acc data copy(X_LES_SUBGRID_UThl,X_LES_RES_ddxa_W_SBG_UaThl, &
+!$acc &         X_LES_RES_ddxa_Thl_SBG_UaThl,X_LES_RES_ddxa_Rt_SBG_UaThl)
+  !
+  CALL MXF_DEVICE(ZFLX,ZTMP1_DEVICE)
+  CALL LES_MEAN_SUBGRID( ZTMP1_DEVICE, X_LES_SUBGRID_UThl ) 
+  !
+  CALL GX_W_UW_DEVICE(1,IKU,1,PWM,PDXX,PDZZ,PDZX,ZTMP1_DEVICE)
+  CALL MZM_DEVICE(ZFLX,ZTMP2_DEVICE)
+  !$acc kernels
+  ZTMP3_DEVICE(:,:,:) = ZTMP1_DEVICE(:,:,:)*ZTMP2_DEVICE(:,:,:)
+  !$acc end kernels
+  CALL MXF_DEVICE(ZTMP3_DEVICE,ZTMP1_DEVICE)
+  CALL MZF_DEVICE(1,IKU,1,ZTMP1_DEVICE,ZTMP2_DEVICE)
+  CALL LES_MEAN_SUBGRID( ZTMP2_DEVICE,X_LES_RES_ddxa_W_SBG_UaThl , .TRUE. )
+  !
+  CALL GX_M_M_DEVICE(1,IKU,1,PTHLM,PDXX,PDZZ,PDZX,ZTMP1_DEVICE)
+  CALL MXF_DEVICE(ZFLX,ZTMP2_DEVICE)
+  !$acc kernels
+  ZTMP3_DEVICE(:,:,:) = ZTMP1_DEVICE(:,:,:) * ZTMP2_DEVICE(:,:,:)
+  !$acc end kernels
+  CALL LES_MEAN_SUBGRID( ZTMP3_DEVICE,X_LES_RES_ddxa_Thl_SBG_UaThl , .TRUE. )
+  !
+  IF (KRR>=1) THEN
+    CALL GX_M_M_DEVICE(1,IKU,1,PRM(:,:,:,1),PDXX,PDZZ,PDZX,ZTMP1_DEVICE)
+    !$acc kernels
+    ZTMP3_DEVICE(:,:,:) = ZTMP1_DEVICE(:,:,:) * ZTMP2_DEVICE(:,:,:)
+    !$acc end kernels
+    CALL LES_MEAN_SUBGRID( ZTMP3_DEVICE,X_LES_RES_ddxa_Rt_SBG_UaThl , .TRUE. )
+  END IF
+!$acc end data
+ 
+#endif
+
+  CALL SECOND_MNH(ZTIME2)
+  XTIME_LES = XTIME_LES + ZTIME2 - ZTIME1
+END IF
+!
+!*       3.   < U' R'np >
+!             -----------
+IF (KRR/=0) THEN
+  !
+#ifndef MNH_OPENACC
+  ZFLX(:,:,:)     = -XCHF * MXM( PK ) * GX_M_U(1,IKU,1,PRM(:,:,:,1),PDXX,PDZZ,PDZX)
+  ZFLX(:,:,IKE+1) = ZFLX(:,:,IKE) 
+!
+! Compute the flux at the first inner U-point with an uncentred vertical  
+! gradient
+  ZFLX(:,:,IKB:IKB) = -XCHF * MXM( PK(:,:,IKB:IKB) ) *           &
+    ( DXM(PRM(:,:,IKB:IKB,1)) * PINV_PDXX(:,:,IKB:IKB)           &
+     -MXM( ZCOEFF(:,:,IKB+2:IKB+2)*PRM(:,:,IKB+2:IKB+2,1)        &
+           +ZCOEFF(:,:,IKB+1:IKB+1)*PRM(:,:,IKB+1:IKB+1,1)       &
+           +ZCOEFF(:,:,IKB  :IKB  )*PRM(:,:,IKB  :IKB  ,1))      &
+          *0.5* ( PDZX(:,:,IKB+1:IKB+1)+PDZX(:,:,IKB:IKB))       &
+          * PINV_PDXX(:,:,IKB:IKB) )
+! extrapolates the flux under the ground so that the vertical average with 
+! the IKB flux gives the ground value  ( warning the tangential surface
+! flux has been set to 0 for the moment !!  to be improved )
+  ZFLX(:,:,IKB-1:IKB-1) = 2. * MXM(  SPREAD( PSFRM(:,:)* PDIRCOSXW(:,:), 3,1) ) &
+                       - ZFLX(:,:,IKB:IKB)
+  !
+  ! Add this source to the conservative mixing ratio sources
+  !
+  IF (.NOT. LFLAT) THEN
+    PRRS(:,:,:,1) = PRRS(:,:,:,1)                                             &
+                  - DXF( MXM(PRHODJ) * ZFLX(:,:,:) * PINV_PDXX(:,:,:) )                          &
+                  + DZF( PMZM_PRHODJ(:,:,:) *MXF(PDZX*(MZM(ZFLX * PINV_PDXX(:,:,:)))) * PINV_PDZZ(:,:,:) )
+  ELSE
+    PRRS(:,:,:,1) = PRRS(:,:,:,1) - DXF( MXM(PRHODJ) * ZFLX(:,:,:) * PINV_PDXX(:,:,:) )
+  END IF
+  !
+  ! Compute the equivalent tendancy for Rc and Ri
+  !
+  IF ( KRRL >= 1 ) THEN
+    IF (.NOT. LFLAT) THEN
+      ZFLXC(:,:,:) = ZFLXC(:,:,:)            &
+            + 2.*( MXF( MXM( PRHODJ(:,:,:)*PAMOIST(:,:,:)*PSRCM(:,:,:) )*ZFLX(:,:,:) )                     &
+                  +MZF( MZM( PRHODJ(:,:,:)*PAMOIST(:,:,:)*PSRCM(:,:,:) )*MXF(                       &
+                                               PDZX(:,:,:)*(MZM( ZFLX(:,:,:)*PINV_PDXX(:,:,:) )) ) )&
+                 )
+      IF ( KRRI >= 1 ) THEN
+        PRRS(:,:,:,2) = PRRS(:,:,:,2) +  2. *                                  &
+        (- DXF( MXM( PRHODJ(:,:,:)*PAMOIST(:,:,:)*PSRCM(:,:,:) )*ZFLX(:,:,:)*PINV_PDXX(:,:,:) )                   &
+         + DZF( MZM( PRHODJ(:,:,:)*PAMOIST(:,:,:)*PSRCM(:,:,:) )*MXF( PDZX(:,:,:)* &
+           (MZM( ZFLX(:,:,:)*PINV_PDXX(:,:,:) )) )&
+                                           *PINV_PDZZ(:,:,:) )                        &
+        )*(1.0-PFRAC_ICE(:,:,:))
+        PRRS(:,:,:,2) = PRRS(:,:,:,2) +  2. *                                  &
+        (- DXF( MXM( PRHODJ(:,:,:)*PAMOIST(:,:,:)*PSRCM(:,:,:) )*ZFLX(:,:,:)*PINV_PDXX(:,:,:) )                   &
+         + DZF( MZM( PRHODJ(:,:,:)*PAMOIST(:,:,:)*PSRCM(:,:,:) )*MXF( PDZX(:,:,:)* &
+           (MZM( ZFLX(:,:,:)*PINV_PDXX(:,:,:) )) )&
+                                           *PINV_PDZZ(:,:,:) )                        &
+        )*PFRAC_ICE(:,:,:)
+      ELSE
+        PRRS(:,:,:,2) = PRRS(:,:,:,2) +  2. *                                  &
+        (- DXF( MXM( PRHODJ(:,:,:)*PAMOIST(:,:,:)*PSRCM(:,:,:) )*ZFLX(:,:,:)*PINV_PDXX(:,:,:) )                   &
+         + DZF( MZM( PRHODJ(:,:,:)*PAMOIST(:,:,:)*PSRCM(:,:,:) )*MXF( PDZX(:,:,:)* &
+           (MZM( ZFLX(:,:,:)*PINV_PDXX(:,:,:) )) )&
+                                           *PINV_PDZZ(:,:,:) )                        &
+        )
+      END IF
+    ELSE
+      ZFLXC(:,:,:) = ZFLXC(:,:,:) + 2.*MXF( MXM( PRHODJ(:,:,:)*PAMOIST(:,:,:)*PSRCM(:,:,:) )*ZFLX(:,:,:) )
+      IF ( KRRI >= 1 ) THEN
+        PRRS(:,:,:,2) = PRRS(:,:,:,2) -  2. *                                  &
+        DXF( MXM( PRHODJ(:,:,:)*PAMOIST(:,:,:)*PSRCM(:,:,:) )*ZFLX(:,:,:)*PINV_PDXX(:,:,:) )*(1.0-PFRAC_ICE(:,:,:))
+        PRRS(:,:,:,4) = PRRS(:,:,:,4) -  2. *                                  &
+        DXF( MXM( PRHODJ(:,:,:)*PAMOIST(:,:,:)*PSRCM(:,:,:) )*ZFLX(:,:,:)*PINV_PDXX(:,:,:) )*PFRAC_ICE(:,:,:)
+      ELSE
+        PRRS(:,:,:,2) = PRRS(:,:,:,2) -  2. *                                  &
+        DXF( MXM( PRHODJ(:,:,:)*PAMOIST(:,:,:)*PSRCM(:,:,:) )*ZFLX(:,:,:)*PINV_PDXX(:,:,:) )
+      END IF
+    END IF
+  END IF
+  !
+  ! stores the horizontal  <U Rnp>
+  IF ( OCLOSE_OUT .AND. OTURB_FLX ) THEN
+    TZFIELD%CMNHNAME   = 'UR_FLX'
+    TZFIELD%CSTDNAME   = ''
+    TZFIELD%CLONGNAME  = 'UR_FLX'
+    TZFIELD%CUNITS     = 'kg kg-1 m s-1'
+    TZFIELD%CDIR       = 'XY'
+    TZFIELD%CCOMMENT   = 'X_Y_Z_UR_FLX'
+    TZFIELD%NGRID      = 2
+    TZFIELD%NTYPE      = TYPEREAL
+    TZFIELD%NDIMS      = 3
+    TZFIELD%LTIMEDEP   = .TRUE.
+    CALL IO_Field_write(TPFILE,TZFIELD,ZFLX(:,:,:))
+  END IF
+  !
+  IF (KSPLT==1 .AND. LLES_CALL) THEN
+    CALL SECOND_MNH(ZTIME1)
+    CALL LES_MEAN_SUBGRID( MXF(ZFLX), X_LES_SUBGRID_URt ) 
+    CALL LES_MEAN_SUBGRID( MZF(MXF(GX_W_UW(PWM,PDXX,PDZZ,PDZX)*MZM(ZFLX))),&
+                           X_LES_RES_ddxa_W_SBG_UaRt , .TRUE. )
+    CALL LES_MEAN_SUBGRID( GX_M_M(PTHLM,PDXX,PDZZ,PDZX)*MXF(ZFLX),&
+                           X_LES_RES_ddxa_Thl_SBG_UaRt , .TRUE. )
+    CALL LES_MEAN_SUBGRID( GX_M_M(PRM(:,:,:,1),PDXX,PDZZ,PDZX)*MXF(ZFLX),&
+                           X_LES_RES_ddxa_Rt_SBG_UaRt , .TRUE. )
+    CALL SECOND_MNH(ZTIME2)
+    XTIME_LES = XTIME_LES + ZTIME2 - ZTIME1
+  END IF
+!
+  !
+  IF (KRRL>0 .AND. KSPLT==1 .AND. LLES_CALL) THEN
+    CALL SECOND_MNH(ZTIME1)
+    CALL LES_MEAN_SUBGRID(MXF(ZFLXC), X_LES_SUBGRID_URc )
+    CALL SECOND_MNH(ZTIME2)
+    XTIME_LES = XTIME_LES + ZTIME2 - ZTIME1
+  END IF
+!
+END IF 
+#else
+  CALL MXM_DEVICE( PK, ZTMP1_DEVICE )
+  CALL GX_M_U_DEVICE(1,IKU,1,PRM(:,:,:,1),PDXX,PDZZ,PDZX,ZTMP2_DEVICE)
+!$acc kernels
+!$acc loop independent collapse(3)
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+   ZFLX(JI,JJ,JK)     = -XCHF * ZTMP1_DEVICE(JI,JJ,JK) * ZTMP2_DEVICE(JI,JJ,JK)
+END DO
+  ZFLX(:,:,IKE+1) = ZFLX(:,:,IKE) 
+!$acc end kernels
+!
+! Compute the flux at the first inner U-point with an uncentred vertical  
+! gradient
+  CALL MXM_DEVICE( PK(:,:,IKB:IKB), ZTMP1_DEVICE(:,:,1:1) )
+  CALL DXM_DEVICE(PRM(:,:,IKB:IKB,1), ZTMP2_DEVICE(:,:,1:1))
+!$acc kernels
+  ZTMP3_DEVICE(:,:,1) = ZCOEFF(:,:,IKB+2)*PRM(:,:,IKB+2,1) &
+                    +ZCOEFF(:,:,IKB+1)*PRM(:,:,IKB+1,1) &
+                    +ZCOEFF(:,:,IKB  )*PRM(:,:,IKB  ,1)
+!$acc end kernels
+  CALL MXM_DEVICE(ZTMP3_DEVICE(:,:,1:1),ZTMP4_DEVICE(:,:,1:1))
+!$acc kernels
+  ZFLX(:,:,IKB) = -XCHF * ZTMP1_DEVICE(:,:,1) *              &
+                  ( ZTMP2_DEVICE(:,:,1) * PINV_PDXX(:,:,IKB) &
+                  -ZTMP4_DEVICE(:,:,1)                       &
+                  *0.5* ( PDZX(:,:,IKB+1)+PDZX(:,:,IKB))  &
+                  * PINV_PDXX(:,:,IKB) )
+! extrapolates the flux under the ground so that the vertical average with 
+! the IKB flux gives the ground value  ( warning the tangential surface
+! flux has been set to 0 for the moment !!  to be improved )
+  ZTMP1_DEVICE(:,:,1) =  PSFRM(:,:)* PDIRCOSXW(:,:)
+!$acc end kernels
+  CALL MXM_DEVICE(ZTMP1_DEVICE(:,:,1:1),ZTMP2_DEVICE(:,:,1:1))
+  !$acc kernels
+  ZFLX(:,:,IKB-1) = 2. * ZTMP2_DEVICE(:,:,1) - ZFLX(:,:,IKB)
+  !$acc end kernels
+
+  !
+  ! Add this source to the conservative mixing ratio sources
+  !
+  IF (.NOT. LFLAT) THEN
+    CALL MXM_DEVICE(PRHODJ,ZTMP1_DEVICE)
+    !$acc kernels
+    !$acc loop independent collapse(3)
+    DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+       ZTMP2_DEVICE(JI,JJ,JK) = ZTMP1_DEVICE(JI,JJ,JK) * ZFLX(JI,JJ,JK) * PINV_PDXX(JI,JJ,JK)
+    END DO
+    !$acc end kernels
+    CALL DXF_DEVICE( ZTMP2_DEVICE, ZTMP3_DEVICE )
+    !$acc kernels
+    !$acc loop independent collapse(3)
+    DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+       ZTMP2_DEVICE(JI,JJ,JK) = ZFLX(JI,JJ,JK) * PINV_PDXX(JI,JJ,JK)
+    END DO
+    !$acc end kernels
+    CALL MZM_DEVICE(ZTMP2_DEVICE,ZTMP4_DEVICE)
+    !$acc kernels
+    !$acc loop independent collapse(3)
+    DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+       ZTMP2_DEVICE(JI,JJ,JK) = PDZX(JI,JJ,JK)*ZTMP4_DEVICE(JI,JJ,JK)
+    END DO
+    !$acc end kernels
+    CALL MXF_DEVICE(ZTMP2_DEVICE,ZTMP4_DEVICE)
+    !$acc kernels
+    !$acc loop independent collapse(3)
+    DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+       ZTMP2_DEVICE(JI,JJ,JK) = PMZM_PRHODJ(JI,JJ,JK) * ZTMP4_DEVICE(JI,JJ,JK) * PINV_PDZZ(JI,JJ,JK)
+    END DO
+    !$acc end kernels
+    CALL DZF_DEVICE(1,IKU,1, ZTMP2_DEVICE, ZTMP4_DEVICE)
+    !$acc kernels
+    !$acc loop independent collapse(3)
+    DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)    
+       PRRS(JI,JJ,JK,1) = PRRS(JI,JJ,JK,1) - ZTMP3_DEVICE(JI,JJ,JK) + ZTMP4_DEVICE(JI,JJ,JK)
+    END DO
+    !$acc end kernels
+  ELSE
+    CALL MXM_DEVICE(PRHODJ,ZTMP1_DEVICE)
+    !$acc kernels
+    ZTMP2_DEVICE(:,:,:) = ZTMP1_DEVICE(:,:,:) * ZFLX(:,:,:) * PINV_PDXX(:,:,:)
+    !$acc end kernels
+    CALL DXF_DEVICE( ZTMP2_DEVICE, ZTMP3_DEVICE )
+    !$acc kernels
+    PRRS(:,:,:,1) = PRRS(:,:,:,1) - ZTMP3_DEVICE(:,:,:)
+    !$acc end kernels
+  END IF
+  !
+  ! Compute the equivalent tendancy for Rc and Ri
+  !
+  IF ( KRRL >= 1 ) THEN
+    !$acc kernels
+    ZTMP1_DEVICE(:,:,:) = PRHODJ(:,:,:)*PAMOIST(:,:,:)*PSRCM(:,:,:)
+    ZTMP2_DEVICE(:,:,:) = ZFLX(:,:,:)*PINV_PDXX(:,:,:)
+    !$acc end kernels
+    CALL MXM_DEVICE( ZTMP1_DEVICE, ZTMP8_DEVICE )
+    IF (.NOT. LFLAT) THEN
+      !$acc kernels
+      ZTMP4_DEVICE(:,:,:) = ZTMP8_DEVICE(:,:,:) * ZFLX(:,:,:)
+      !$acc end kernels
+      CALL MXF_DEVICE( ZTMP4_DEVICE, ZTMP3_DEVICE )
+      CALL MZM_DEVICE( ZTMP1_DEVICE, ZTMP4_DEVICE )
+      CALL MZM_DEVICE( ZTMP2_DEVICE, ZTMP5_DEVICE )
+      !$acc kernels
+      ZTMP6_DEVICE(:,:,:) = PDZX(:,:,:)*ZTMP5_DEVICE(:,:,:)
+      !$acc end kernels
+      CALL MXF_DEVICE( ZTMP6_DEVICE, ZTMP5_DEVICE )
+      !$acc kernels
+      ZTMP6_DEVICE(:,:,:) = ZTMP4_DEVICE(:,:,:)*ZTMP5_DEVICE(:,:,:)
+      !$acc end kernels
+      CALL MZF_DEVICE(1,IKU,1, ZTMP6_DEVICE, ZTMP7_DEVICE )
+      !$acc kernels
+      ZFLXC(:,:,:) = ZFLXC(:,:,:) + 2.*( ZTMP3_DEVICE(:,:,:) + ZTMP7_DEVICE(:,:,:) )
+      !
+      ZTMP6_DEVICE(:,:,:) = ZTMP4_DEVICE(:,:,:)*ZTMP5_DEVICE(:,:,:)*PINV_PDZZ(:,:,:)
+      !$acc end kernels
+      CALL DZF_DEVICE(1,IKU,1, ZTMP6_DEVICE, ZTMP3_DEVICE )
+      !$acc kernels
+      ZTMP4_DEVICE(:,:,:) = ZTMP8_DEVICE(:,:,:) * ZFLX(:,:,:)*PINV_PDXX(:,:,:)
+      !$acc end kernels
+      CALL DXF_DEVICE(ZTMP4_DEVICE, ZTMP5_DEVICE)
+      !
+      IF ( KRRI >= 1 ) THEN
+        !$acc kernels
+        PRRS(:,:,:,2) = PRRS(:,:,:,2) +  2. * (- ZTMP5_DEVICE(:,:,:)+ ZTMP3_DEVICE(:,:,:))*(1.0-PFRAC_ICE(:,:,:))
+        PRRS(:,:,:,2) = PRRS(:,:,:,2) +  2. * (- ZTMP5_DEVICE(:,:,:)+ ZTMP3_DEVICE(:,:,:))*PFRAC_ICE(:,:,:)
+        !$acc end kernels
+      ELSE
+        !$acc kernels
+        PRRS(:,:,:,2) = PRRS(:,:,:,2) +  2. * (- ZTMP5_DEVICE(:,:,:) + ZTMP3_DEVICE(:,:,:))
+        !$acc end kernels
+      END IF
+    ELSE
+      !$acc kernels
+      ZTMP4_DEVICE(:,:,:) = ZTMP8_DEVICE(:,:,:)*ZTMP2_DEVICE(:,:,:)
+      !$acc end kernels
+      CALL DXF_DEVICE(ZTMP4_DEVICE, ZTMP5_DEVICE)
+      !$acc kernels
+      ZTMP3_DEVICE(:,:,:) = ZTMP8_DEVICE(:,:,:)*ZFLX(:,:,:)
+      !$acc end kernels
+      CALL MXF_DEVICE( ZTMP3_DEVICE, ZTMP4_DEVICE )
+      !$acc kernels
+      ZFLXC(:,:,:) = ZFLXC(:,:,:) + 2.*ZTMP4_DEVICE(:,:,:)
+      !$acc end kernels
+      IF ( KRRI >= 1 ) THEN
+        !$acc kernels
+        PRRS(:,:,:,2) = PRRS(:,:,:,2) -  2. * ZTMP5_DEVICE(:,:,:)*(1.0-PFRAC_ICE(:,:,:))
+        PRRS(:,:,:,4) = PRRS(:,:,:,4) -  2. * ZTMP5_DEVICE(:,:,:)*PFRAC_ICE(:,:,:)
+        !$acc end kernels
+      ELSE
+        !$acc kernels
+        PRRS(:,:,:,2) = PRRS(:,:,:,2) -  2. * ZTMP5_DEVICE(:,:,:)
+        !$acc end kernels
+      END IF
+    END IF
+  END IF
+  !
+  ! stores the horizontal  <U Rnp>
+  IF ( OCLOSE_OUT .AND. OTURB_FLX ) THEN
+!$acc update self(ZFLX)
+    TZFIELD%CMNHNAME   = 'UR_FLX'
+    TZFIELD%CSTDNAME   = ''
+    TZFIELD%CLONGNAME  = 'UR_FLX'
+    TZFIELD%CUNITS     = 'kg kg-1 m s-1'
+    TZFIELD%CDIR       = 'XY'
+    TZFIELD%CCOMMENT   = 'X_Y_Z_UR_FLX'
+    TZFIELD%NGRID      = 2
+    TZFIELD%NTYPE      = TYPEREAL
+    TZFIELD%NDIMS      = 3
+    TZFIELD%LTIMEDEP   = .TRUE.
+    CALL IO_Field_write(TPFILE,TZFIELD,ZFLX(:,:,:))
+  END IF
+  !
+  IF (KSPLT==1 .AND. LLES_CALL) THEN
+    CALL SECOND_MNH(ZTIME1)
+    !
+!$acc data copy(X_LES_SUBGRID_URt,X_LES_RES_ddxa_W_SBG_UaRt, &
+!$acc &         X_LES_RES_ddxa_Thl_SBG_UaRt,X_LES_RES_ddxa_Rt_SBG_UaRt)
+    !
+    CALL MXF_DEVICE(ZFLX,ZTMP1_DEVICE)
+    CALL LES_MEAN_SUBGRID( ZTMP1_DEVICE, X_LES_SUBGRID_URt ) 
+    !
+    CALL GX_W_UW_DEVICE(1,IKU,1,PWM,PDXX,PDZZ,PDZX,ZTMP1_DEVICE)
+    CALL MZM_DEVICE(ZFLX,ZTMP2_DEVICE)
+    !$acc kernels
+    ZTMP3_DEVICE(:,:,:) = ZTMP1_DEVICE(:,:,:)*ZTMP2_DEVICE(:,:,:)
+    !$acc end kernels
+    CALL MXF_DEVICE(ZTMP3_DEVICE,ZTMP4_DEVICE)
+    CALL MZF_DEVICE(1,IKU,1,ZTMP4_DEVICE,ZTMP3_DEVICE)
+    CALL LES_MEAN_SUBGRID( ZTMP3_DEVICE, X_LES_RES_ddxa_W_SBG_UaRt , .TRUE. )
+    !
+    CALL GX_M_M_DEVICE(1,IKU,1,PTHLM,PDXX,PDZZ,PDZX,ZTMP1_DEVICE)
+    CALL MXF_DEVICE(ZFLX,ZTMP2_DEVICE)
+    !$acc kernels
+    ZTMP3_DEVICE(:,:,:) = ZTMP1_DEVICE(:,:,:)*ZTMP2_DEVICE(:,:,:)
+    !$acc end kernels
+    CALL LES_MEAN_SUBGRID( ZTMP3_DEVICE, X_LES_RES_ddxa_Thl_SBG_UaRt , .TRUE. )
+    !
+    CALL GX_M_M_DEVICE(1,IKU,1,PRM(:,:,:,1),PDXX,PDZZ,PDZX,ZTMP1_DEVICE)
+    CALL MXF_DEVICE(ZFLX,ZTMP2_DEVICE)
+    !$acc kernels
+    ZTMP3_DEVICE(:,:,:) = ZTMP1_DEVICE(:,:,:)*ZTMP2_DEVICE(:,:,:)
+    !$acc end kernels
+    CALL LES_MEAN_SUBGRID( ZTMP3_DEVICE, X_LES_RES_ddxa_Rt_SBG_UaRt , .TRUE. )
+    !
+!$acc end data
+    !
+    CALL SECOND_MNH(ZTIME2)
+    XTIME_LES = XTIME_LES + ZTIME2 - ZTIME1
+  END IF
+!
+  !
+  IF (KRRL>0 .AND. KSPLT==1 .AND. LLES_CALL) THEN
+    CALL SECOND_MNH(ZTIME1)
+    !
+    !$acc data copy(X_LES_SUBGRID_URc)
+    !
+    CALL MXF_DEVICE(ZFLXC,ZTMP1_DEVICE)
+    CALL LES_MEAN_SUBGRID(ZTMP1_DEVICE, X_LES_SUBGRID_URc )
+    !
+    !$acc end data
+    !
+    CALL SECOND_MNH(ZTIME2)
+    XTIME_LES = XTIME_LES + ZTIME2 - ZTIME1
+  END IF
+!
+END IF 
+#endif
+!
+!*       4.   < U' TPV' >
+!             -----------
+!
+!! to be tested later
+!!IF (KRR/=0) THEN
+!!  ! here ZFLX= <U'Rnp'> and ZWORK= <U'Thetal'>
+!!  !
+!!  ZVPTU(:,:,:) =                                                        &
+!!    ZWORK(:,:,:)*MXM(ETHETA(KRR,KRRI,PTHLT,PEXNREF,PRT,PLOCPT,PSRCM)) +       &
+!!     ZFLX(:,:,:)*MXM(EMOIST(KRR,KRRI,PTHLT,PEXNREF,PRT,PLOCPT,PSRCM))
+!!  !
+!!  ! stores the horizontal  <U VPT>
+!!  IF ( OCLOSE_OUT .AND. OTURB_FLX ) THEN
+!!    TZFIELD%CMNHNAME   = 'UVPT_FLX'
+!!    TZFIELD%CSTDNAME   = ''
+!!    TZFIELD%CLONGNAME  = 'UVPT_FLX'
+!!    TZFIELD%CUNITS     = 'K m s-1'
+!!    TZFIELD%CDIR       = 'XY'
+!!    TZFIELD%CCOMMENT   = 'X_Y_Z_UVPT_FLX'
+!!    TZFIELD%NGRID      = 2
+!!    TZFIELD%NTYPE      = TYPEREAL
+!!    TZFIELD%NDIMS      = 3
+!!    TZFIELD%LTIMEDEP   = .TRUE.
+!!    CALL IO_Field_write(TPFILE,TZFIELD,ZVPTU)
+!!  END IF
+!!!
+!!ELSE
+!!  ZVPTU(:,:,:)=ZWORK(:,:,:)
+!!END IF
+!
+!
+!*       5.   < V' THETA'l >
+!             --------------
+!
+!
+IF (.NOT. L2D) THEN
+#ifndef MNH_OPENACC
+  ZFLX(:,:,:)     = -XCSHF * MYM( PK ) * GY_M_V(1,IKU,1,PTHLM,PDYY,PDZZ,PDZY)
+  ZFLX(:,:,IKE+1) = ZFLX(:,:,IKE) 
+ELSE
+  ZFLX(:,:,:)     = 0.
+END IF
+!
+!
+! Compute the flux at the first inner U-point with an uncentred vertical  
+! gradient
+ZFLX(:,:,IKB:IKB) = -XCSHF * MYM( PK(:,:,IKB:IKB) ) *          &
+  ( DYM(PTHLM(:,:,IKB:IKB)) * PINV_PDYY(:,:,IKB:IKB)           &
+   -MYM( ZCOEFF(:,:,IKB+2:IKB+2)*PTHLM(:,:,IKB+2:IKB+2)        &
+         +ZCOEFF(:,:,IKB+1:IKB+1)*PTHLM(:,:,IKB+1:IKB+1)       &
+         +ZCOEFF(:,:,IKB  :IKB  )*PTHLM(:,:,IKB  :IKB  ) )     &
+        *0.5* ( PDZY(:,:,IKB+1:IKB+1)+PDZY(:,:,IKB:IKB))       &
+        * PINV_PDYY(:,:,IKB:IKB) )
+! extrapolates the flux under the ground so that the vertical average with 
+! the IKB flux gives the ground value  ( warning the tangential surface
+! flux has been set to 0 for the moment !!  to be improved )
+ZFLX(:,:,IKB-1:IKB-1) = 2. * MYM(  SPREAD( PSFTHM(:,:)* PDIRCOSYW(:,:), 3,1) ) &
+                       - ZFLX(:,:,IKB:IKB)
+!
+! Add this source to the Theta_l sources
+!
+IF (.NOT. L2D) THEN 
+  IF (.NOT. LFLAT) THEN
+    PRTHLS(:,:,:) =  PRTHLS(:,:,:)                                                         &
+                  - DYF( MYM(PRHODJ) * ZFLX(:,:,:) * PINV_PDYY(:,:,:) )                           &
+                  + DZF( PMZM_PRHODJ *MYF(PDZY(:,:,:)*(MZM(ZFLX(:,:,:) * PINV_PDYY(:,:,:)))) * PINV_PDZZ(:,:,:) )
+  ELSE
+    PRTHLS(:,:,:) =  PRTHLS(:,:,:) - DYF( MYM(PRHODJ) * ZFLX(:,:,:) * PINV_PDYY(:,:,:) )
+  END IF
+END IF
+!
+! Compute the equivalent tendancy for Rc and Ri
+!
+!IF ( OSUBG_COND .AND. KRRL > 0 .AND. .NOT. L2D) THEN
+IF ( KRRL >= 1 .AND. .NOT. L2D) THEN
+  IF (.NOT. LFLAT) THEN
+    ZFLXC(:,:,:) = 2.*( MYF( MYM( PRHODJ(:,:,:)*PATHETA(:,:,:)*PSRCM(:,:,:) )*ZFLX(:,:,:) )                       &
+                +MZF( MZM( PRHODJ(:,:,:)*PATHETA(:,:,:)*PSRCM(:,:,:) )*MYF(                         &
+                                               PDZY(:,:,:)*(MZM( ZFLX(:,:,:)*PINV_PDYY(:,:,:) )) ) )&
+               )
+    IF ( KRRI >= 1 ) THEN
+      PRRS(:,:,:,2) = PRRS(:,:,:,2) + 2. *                                     &
+        (- DYF( MYM( PRHODJ(:,:,:)*PATHETA(:,:,:)*PSRCM(:,:,:) )*ZFLX(:,:,:)*PINV_PDYY(:,:,:) )                   &
+         + DZF( MZM( PRHODJ(:,:,:)*PATHETA(:,:,:)*PSRCM(:,:,:) )*MYF( PDZY(:,:,:)* &
+           (MZM( ZFLX(:,:,:)*PINV_PDYY(:,:,:) )) )&
+                                           *PINV_PDZZ(:,:,:) )                        &
+        )*(1.0-PFRAC_ICE(:,:,:))
+      PRRS(:,:,:,4) = PRRS(:,:,:,4) + 2. *                                     &
+        (- DYF( MYM( PRHODJ(:,:,:)*PATHETA(:,:,:)*PSRCM(:,:,:) )*ZFLX(:,:,:)*PINV_PDYY(:,:,:) )                   &
+         + DZF( MZM( PRHODJ(:,:,:)*PATHETA(:,:,:)*PSRCM(:,:,:) )*MYF( PDZY(:,:,:)* &
+           (MZM( ZFLX(:,:,:)*PINV_PDYY(:,:,:) )) )&
+                                           *PINV_PDZZ(:,:,:) )                        &
+        )*PFRAC_ICE(:,:,:)
+    ELSE
+      PRRS(:,:,:,2) = PRRS(:,:,:,2) + 2. *                                     &
+        (- DYF( MYM( PRHODJ(:,:,:)*PATHETA(:,:,:)*PSRCM(:,:,:) )*ZFLX(:,:,:)*PINV_PDYY(:,:,:) )                   &
+         + DZF( MZM( PRHODJ(:,:,:)*PATHETA(:,:,:)*PSRCM(:,:,:) )*MYF( PDZY(:,:,:)* &
+           (MZM( ZFLX(:,:,:)*PINV_PDYY(:,:,:) )) )&
+                                           *PINV_PDZZ(:,:,:) )                        &
+        )
+    END IF
+  ELSE
+    ZFLXC(:,:,:) = 2.*MYF( MYM( PRHODJ(:,:,:)*PATHETA(:,:,:)*PSRCM(:,:,:) )*ZFLX(:,:,:) )
+    IF ( KRRI >= 1 ) THEN
+      PRRS(:,:,:,2) = PRRS(:,:,:,2) - 2. *                                     &
+        DYF( MYM( PRHODJ(:,:,:)*PATHETA(:,:,:)*PSRCM(:,:,:) )*ZFLX(:,:,:)*PINV_PDYY(:,:,:) )*(1.0-PFRAC_ICE(:,:,:))
+      PRRS(:,:,:,4) = PRRS(:,:,:,4) - 2. *                                     &
+        DYF( MYM( PRHODJ(:,:,:)*PATHETA(:,:,:)*PSRCM(:,:,:) )*ZFLX(:,:,:)*PINV_PDYY(:,:,:) )*PFRAC_ICE(:,:,:)
+    ELSE
+      PRRS(:,:,:,2) = PRRS(:,:,:,2) - 2. *                                     &
+        DYF( MYM( PRHODJ(:,:,:)*PATHETA(:,:,:)*PSRCM(:,:,:) )*ZFLX(:,:,:)*PINV_PDYY(:,:,:) )
+    END IF
+  END IF
+END IF
+!
+!! stores this flux in ZWORK to compute later <V' VPT'>
+!!ZWORK(:,:,:) = ZFLX(:,:,:) 
+!
+! stores the horizontal  <V THl>
+IF ( OCLOSE_OUT .AND. OTURB_FLX ) THEN
+  TZFIELD%CMNHNAME   = 'VTHL_FLX'
+  TZFIELD%CSTDNAME   = ''
+  TZFIELD%CLONGNAME  = 'VTHL_FLX'
+  TZFIELD%CUNITS     = 'K m s-1'
+  TZFIELD%CDIR       = 'XY'
+  TZFIELD%CCOMMENT   = 'X_Y_Z_VTHL_FLX'
+  TZFIELD%NGRID      = 3
+  TZFIELD%NTYPE      = TYPEREAL
+  TZFIELD%NDIMS      = 3
+  TZFIELD%LTIMEDEP   = .TRUE.
+  CALL IO_Field_write(TPFILE,TZFIELD,ZFLX(:,:,:))
+END IF
+!
+IF (KSPLT==1 .AND. LLES_CALL) THEN
+  CALL SECOND_MNH(ZTIME1)
+  CALL LES_MEAN_SUBGRID( MYF(ZFLX), X_LES_SUBGRID_VThl ) 
+  CALL LES_MEAN_SUBGRID( MZF(MYF(GY_W_VW(PWM,PDYY,PDZZ,PDZY)*MZM(ZFLX))),&
+                         X_LES_RES_ddxa_W_SBG_UaThl , .TRUE. )
+  CALL LES_MEAN_SUBGRID( GY_M_M(PTHLM,PDYY,PDZZ,PDZY)*MYF(ZFLX),&
+                         X_LES_RES_ddxa_Thl_SBG_UaThl , .TRUE. )
+  IF (KRR>=1) THEN
+    CALL LES_MEAN_SUBGRID( GY_M_M(PRM(:,:,:,1),PDYY,PDZZ,PDZY)*MYF(ZFLX),&
+                           X_LES_RES_ddxa_Rt_SBG_UaThl , .TRUE. )
+  END IF
+  CALL SECOND_MNH(ZTIME2)
+  XTIME_LES = XTIME_LES + ZTIME2 - ZTIME1
+END IF
+#else
+  CALL MYM_DEVICE( PK, ZTMP1_DEVICE )
+  CALL GY_M_V_DEVICE(1,IKU,1,PTHLM,PDYY,PDZZ,PDZY,ZTMP2_DEVICE)
+  !$acc kernels
+  !$acc loop independent collapse(3)
+  DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+     ZFLX(JI,JJ,JK)     = -XCSHF * ZTMP1_DEVICE(JI,JJ,JK) * ZTMP2_DEVICE(JI,JJ,JK)
+  END DO
+  ZFLX(:,:,IKE+1) = ZFLX(:,:,IKE) 
+  !$acc end kernels
+ELSE
+  !$acc kernels
+  ZFLX(:,:,:)     = 0.
+  !$acc end kernels
+END IF
+!
+!
+! Compute the flux at the first inner U-point with an uncentred vertical  
+! gradient
+CALL MYM_DEVICE( PK(:,:,IKB:IKB), ZTMP1_DEVICE(:,:,1:1) )
+CALL DYM_DEVICE(PTHLM(:,:,IKB:IKB), ZTMP2_DEVICE(:,:,1:1) )
+!$acc kernels
+ZTMP3_DEVICE(:,:,1) = ZCOEFF(:,:,IKB+2)*PTHLM(:,:,IKB+2) &
+                  +ZCOEFF(:,:,IKB+1)*PTHLM(:,:,IKB+1) &
+                  +ZCOEFF(:,:,IKB  )*PTHLM(:,:,IKB  )
+!$acc end kernels
+CALL MYM_DEVICE( ZTMP3_DEVICE(:,:,1:1), ZTMP4_DEVICE(:,:,1:1) ) 
+!$acc kernels
+ZFLX(:,:,IKB) = -XCSHF * ZTMP1_DEVICE(:,:,1) *             &
+                ( ZTMP2_DEVICE(:,:,1) * PINV_PDYY(:,:,IKB) &
+                - ZTMP4_DEVICE(:,:,1)                      &
+                *0.5* ( PDZY(:,:,IKB+1)+PDZY(:,:,IKB))  &
+                * PINV_PDYY(:,:,IKB) )
+!$acc end kernels
+! extrapolates the flux under the ground so that the vertical average with 
+! the IKB flux gives the ground value  ( warning the tangential surface
+! flux has been set to 0 for the moment !!  to be improved )
+!$acc kernels
+ZTMP1_DEVICE(:,:,1) = PSFTHM(:,:)* PDIRCOSYW(:,:)
+!$acc end kernels
+CALL MYM_DEVICE( ZTMP1_DEVICE(:,:,1:1), ZTMP2_DEVICE(:,:,1:1) )
+!$acc kernels
+ZFLX(:,:,IKB-1) = 2. * ZTMP2_DEVICE(:,:,1) - ZFLX(:,:,IKB)
+!$acc end kernels
+!
+! Add this source to the Theta_l sources
+!
+IF (.NOT. L2D) THEN 
+  IF (.NOT. LFLAT) THEN
+    CALL MYM_DEVICE(PRHODJ, ZTMP1_DEVICE)
+    !$acc kernels
+    !$acc loop independent collapse(3)
+    DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+       ZTMP2_DEVICE(JI,JJ,JK) = ZTMP1_DEVICE(JI,JJ,JK) * ZFLX(JI,JJ,JK) * PINV_PDYY(JI,JJ,JK)
+    END DO
+    !$acc end kernels
+    CALL DYF_DEVICE( ZTMP2_DEVICE, ZTMP3_DEVICE )
+    !$acc kernels
+    !$acc loop independent collapse(3)
+    DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+       ZTMP1_DEVICE(JI,JJ,JK) = ZFLX(JI,JJ,JK) * PINV_PDYY(JI,JJ,JK)
+    END DO
+    !$acc end kernels
+    CALL MZM_DEVICE(ZTMP1_DEVICE, ZTMP2_DEVICE)
+    !$acc kernels
+    !$acc loop independent collapse(3)
+    DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+       ZTMP1_DEVICE(JI,JJ,JK) = PDZY(JI,JJ,JK)*ZTMP2_DEVICE(JI,JJ,JK)
+    END DO
+    !$acc end kernels
+    CALL MYF_DEVICE(ZTMP1_DEVICE, ZTMP2_DEVICE)
+    !$acc kernels
+    !$acc loop independent collapse(3)
+    DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+       ZTMP1_DEVICE(JI,JJ,JK) = PMZM_PRHODJ(JI,JJ,JK) * ZTMP2_DEVICE(JI,JJ,JK) * PINV_PDZZ(JI,JJ,JK)
+    END DO
+    !$acc end kernels
+    CALL DZF_DEVICE(1,IKU,1, ZTMP1_DEVICE, ZTMP2_DEVICE )
+    !$acc kernels
+    !$acc loop independent collapse(3)
+    DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+       PRTHLS(JI,JJ,JK) = PRTHLS(JI,JJ,JK) - ZTMP3_DEVICE(JI,JJ,JK) + ZTMP2_DEVICE(JI,JJ,JK)
+    END DO
+    !$acc end kernels
+  ELSE
+    CALL MYM_DEVICE(PRHODJ, ZTMP1_DEVICE)
+    !$acc kernels
+    ZTMP2_DEVICE(:,:,:) = ZTMP1_DEVICE(:,:,:) * ZFLX(:,:,:) * PINV_PDYY(:,:,:)
+    !$acc end kernels
+    CALL DYF_DEVICE( ZTMP2_DEVICE, ZTMP3_DEVICE )
+    !$acc kernels
+    PRTHLS(:,:,:) =  PRTHLS(:,:,:) - ZTMP3_DEVICE(:,:,:)
+    !$acc end kernels
+  END IF
+END IF
+!
+! Compute the equivalent tendancy for Rc and Ri
+!
+!IF ( OSUBG_COND .AND. KRRL > 0 .AND. .NOT. L2D) THEN
+IF ( KRRL >= 1 .AND. .NOT. L2D) THEN
+  IF (.NOT. LFLAT) THEN
+    !$acc kernels
+    ZTMP1_DEVICE(:,:,:) = PRHODJ(:,:,:)*PATHETA(:,:,:)*PSRCM(:,:,:)
+    !$acc end kernels
+    CALL MYM_DEVICE( ZTMP1_DEVICE, ZTMP2_DEVICE )
+    !$acc kernels
+    ZTMP4_DEVICE(:,:,:) = ZTMP2_DEVICE(:,:,:)*ZFLX(:,:,:)
+    !$acc end kernels
+    CALL MYF_DEVICE( ZTMP4_DEVICE, ZTMP3_DEVICE )
+    !$acc kernels
+    ZTMP4_DEVICE(:,:,:) = ZFLX(:,:,:)*PINV_PDYY(:,:,:)
+    !$acc end kernels
+    CALL MZM_DEVICE( ZTMP4_DEVICE, ZTMP5_DEVICE )
+    !$acc kernels
+    ZTMP4_DEVICE(:,:,:) = PDZY(:,:,:)*ZTMP5_DEVICE(:,:,:)
+    !$acc end kernels
+    CALL MYF_DEVICE( ZTMP4_DEVICE, ZTMP5_DEVICE)
+    CALL MZM_DEVICE( ZTMP1_DEVICE, ZTMP4_DEVICE )
+    !$acc kernels
+    ZTMP6_DEVICE(:,:,:) = ZTMP4_DEVICE(:,:,:)*ZTMP5_DEVICE(:,:,:)
+    !$acc end kernels
+    CALL MZF_DEVICE(1,IKU,1, ZTMP6_DEVICE, ZTMP4_DEVICE )
+    !$acc kernels
+    ZFLXC(:,:,:) = 2.*( ZTMP3_DEVICE(:,:,:) + ZTMP4_DEVICE(:,:,:) )
+    !$acc end kernels
+    IF ( KRRI >= 1 ) THEN
+      !$acc kernels
+      ZTMP3_DEVICE(:,:,:) = ZTMP2_DEVICE(:,:,:)*ZFLX(:,:,:)*PINV_PDYY(:,:,:)
+      !$acc end kernels
+      CALL DYF_DEVICE( ZTMP3_DEVICE, ZTMP4_DEVICE )
+      !$acc kernels
+      ZTMP3_DEVICE(:,:,:) = ZTMP6_DEVICE(:,:,:)*PINV_PDZZ(:,:,:)
+      !$acc end kernels
+      CALL DZF_DEVICE(1,IKU,1, ZTMP3_DEVICE, ZTMP5_DEVICE )
+      !$acc kernels
+      PRRS(:,:,:,2) = PRRS(:,:,:,2) + 2. * (- ZTMP4_DEVICE(:,:,:) + ZTMP5_DEVICE(:,:,:) )*(1.0-PFRAC_ICE(:,:,:))
+      PRRS(:,:,:,4) = PRRS(:,:,:,4) + 2. * (- ZTMP4_DEVICE(:,:,:) + ZTMP5_DEVICE(:,:,:) )*PFRAC_ICE(:,:,:)
+      !$acc end kernels
+    ELSE
+      !$acc kernels
+      ZTMP3_DEVICE(:,:,:) = ZTMP2_DEVICE(:,:,:)*ZFLX(:,:,:)*PINV_PDYY(:,:,:)
+      !$acc end kernels
+      CALL DYF_DEVICE( ZTMP3_DEVICE, ZTMP4_DEVICE )
+      !$acc kernels
+      ZTMP3_DEVICE(:,:,:) = ZTMP6_DEVICE(:,:,:)*PINV_PDZZ(:,:,:)
+      !$acc end kernels
+      CALL DZF_DEVICE(1,IKU,1, ZTMP3_DEVICE, ZTMP5_DEVICE )
+      !$acc kernels
+      PRRS(:,:,:,2) = PRRS(:,:,:,2) + 2. * (- ZTMP4_DEVICE(:,:,:) + ZTMP5_DEVICE(:,:,:) )
+      !$acc end kernels
+    END IF
+  ELSE
+    !$acc kernels
+    ZTMP1_DEVICE(:,:,:) = PRHODJ(:,:,:)*PATHETA(:,:,:)*PSRCM(:,:,:)
+    !$acc end kernels
+    CALL MYM_DEVICE( ZTMP1_DEVICE, ZTMP2_DEVICE )
+    !$acc kernels
+    ZTMP1_DEVICE(:,:,:) = ZTMP2_DEVICE(:,:,:)*ZFLX(:,:,:)
+    !$acc end kernels
+    CALL MYF_DEVICE( ZTMP1_DEVICE, ZTMP3_DEVICE )
+    !$acc kernels
+    ZFLXC(:,:,:) = 2.*ZTMP3_DEVICE(:,:,:)
+    !$acc end kernels
+    !
+    !$acc kernels
+    ZTMP1_DEVICE(:,:,:) = ZTMP2_DEVICE(:,:,:)*ZFLX(:,:,:)*PINV_PDYY(:,:,:)
+    !$acc end kernels
+    CALL DYF_DEVICE( ZTMP1_DEVICE, ZTMP2_DEVICE )
+    IF ( KRRI >= 1 ) THEN
+      !$acc kernels
+      PRRS(:,:,:,2) = PRRS(:,:,:,2) - 2. * ZTMP2_DEVICE(:,:,:)*(1.0-PFRAC_ICE(:,:,:))
+      PRRS(:,:,:,4) = PRRS(:,:,:,4) - 2. * ZTMP2_DEVICE(:,:,:)*PFRAC_ICE(:,:,:)
+      !$acc end kernels
+    ELSE
+      !$acc kernels
+      PRRS(:,:,:,2) = PRRS(:,:,:,2) - 2. * ZTMP2_DEVICE(:,:,:)
+      !$acc end kernels
+    END IF
+  END IF
+END IF
+!! stores this flux in ZWORK to compute later <V' VPT'>
+!!ZWORK(:,:,:) = ZFLX(:,:,:) 
+!
+! stores the horizontal  <V THl>
+IF ( OCLOSE_OUT .AND. OTURB_FLX ) THEN
+!$acc update self(ZFLX)
+  TZFIELD%CMNHNAME   = 'VTHL_FLX'
+  TZFIELD%CSTDNAME   = ''
+  TZFIELD%CLONGNAME  = 'VTHL_FLX'
+  TZFIELD%CUNITS     = 'K m s-1'
+  TZFIELD%CDIR       = 'XY'
+  TZFIELD%CCOMMENT   = 'X_Y_Z_VTHL_FLX'
+  TZFIELD%NGRID      = 3
+  TZFIELD%NTYPE      = TYPEREAL
+  TZFIELD%NDIMS      = 3
+  TZFIELD%LTIMEDEP   = .TRUE.
+  CALL IO_Field_write(TPFILE,TZFIELD,ZFLX(:,:,:))
+END IF
+!
+IF (KSPLT==1 .AND. LLES_CALL) THEN
+  CALL SECOND_MNH(ZTIME1)
+  !
+!$acc data copy(X_LES_SUBGRID_VThl,X_LES_RES_ddxa_W_SBG_UaThl,X_LES_RES_ddxa_Thl_SBG_UaThl)
+  !
+  CALL MYF_DEVICE(ZFLX, ZTMP1_DEVICE)
+  CALL LES_MEAN_SUBGRID( ZTMP1_DEVICE, X_LES_SUBGRID_VThl ) 
+  !
+  CALL GY_W_VW_DEVICE(1,IKU,1,PWM,PDYY,PDZZ,PDZY,ZTMP1_DEVICE)
+  CALL MZM_DEVICE(ZFLX,ZTMP2_DEVICE)
+  !$acc kernels
+  ZTMP3_DEVICE(:,:,:) = ZTMP1_DEVICE(:,:,:) * ZTMP2_DEVICE(:,:,:)
+  !$acc end kernels
+  CALL MYF_DEVICE(ZTMP3_DEVICE, ZTMP4_DEVICE)
+  CALL MZF_DEVICE(1,IKU,1,ZTMP4_DEVICE, ZTMP1_DEVICE)
+  CALL LES_MEAN_SUBGRID( ZTMP1_DEVICE, X_LES_RES_ddxa_W_SBG_UaThl , .TRUE. )
+  !
+  CALL GY_M_M_DEVICE(1,IKU,1,PTHLM,PDYY,PDZZ,PDZY,ZTMP1_DEVICE)
+  CALL MYF_DEVICE(ZFLX,ZTMP2_DEVICE)
+  !$acc kernels
+  ZTMP3_DEVICE(:,:,:) = ZTMP1_DEVICE(:,:,:) * ZTMP2_DEVICE(:,:,:)
+  !$acc end kernels
+  CALL LES_MEAN_SUBGRID( ZTMP3_DEVICE, X_LES_RES_ddxa_Thl_SBG_UaThl , .TRUE. )
+                         !
+!$acc end data
+  !
+  IF (KRR>=1) THEN
+!$acc data copy(X_LES_RES_ddxa_Rt_SBG_UaThl)
+    CALL GY_M_M_DEVICE(1,IKU,1,PRM(:,:,:,1),PDYY,PDZZ,PDZY,ZTMP1_DEVICE)
+    CALL MYF_DEVICE(ZFLX,ZTMP2_DEVICE)
+    !$acc kernels
+    ZTMP3_DEVICE(:,:,:) = ZTMP1_DEVICE(:,:,:) * ZTMP2_DEVICE(:,:,:)
+    !$acc end kernels
+    CALL LES_MEAN_SUBGRID( ZTMP3_DEVICE,X_LES_RES_ddxa_Rt_SBG_UaThl , .TRUE. )
+!$acc end data
+  END IF
+  !
+  CALL SECOND_MNH(ZTIME2)
+  XTIME_LES = XTIME_LES + ZTIME2 - ZTIME1
+END IF
+#endif
+!
+!
+!*       6.   < V' R'np >
+!             -----------
+!
+#ifndef MNH_OPENACC
+IF (KRR/=0) THEN
+  !
+  IF (.NOT. L2D) THEN
+    ZFLX(:,:,:)     = -XCHF * MYM( PK ) * GY_M_V(1,IKU,1,PRM(:,:,:,1),PDYY,PDZZ,PDZY)
+    ZFLX(:,:,IKE+1) = ZFLX(:,:,IKE) 
+  ELSE
+    ZFLX(:,:,:)     = 0.
+  END IF
+!
+! Compute the flux at the first inner U-point with an uncentred vertical  
+! gradient
+  ZFLX(:,:,IKB:IKB) = -XCHF * MYM( PK(:,:,IKB:IKB) ) *           &
+    ( DYM(PRM(:,:,IKB:IKB,1)) * PINV_PDYY(:,:,IKB:IKB)           &
+     -MYM( ZCOEFF(:,:,IKB+2:IKB+2)*PRM(:,:,IKB+2:IKB+2,1)        &
+           +ZCOEFF(:,:,IKB+1:IKB+1)*PRM(:,:,IKB+1:IKB+1,1)       &
+           +ZCOEFF(:,:,IKB  :IKB  )*PRM(:,:,IKB  :IKB  ,1) )     &
+           *0.5* ( PDZY(:,:,IKB+1:IKB+1)+PDZY(:,:,IKB:IKB))      &
+          * PINV_PDYY(:,:,IKB:IKB) )
+! extrapolates the flux under the ground so that the vertical average with 
+! the IKB flux gives the ground value  ( warning the tangential surface
+! flux has been set to 0 for the moment !!  to be improved )
+  ZFLX(:,:,IKB-1:IKB-1) = 2. * MYM(  SPREAD( PSFRM(:,:)* PDIRCOSYW(:,:), 3,1) ) &
+                       - ZFLX(:,:,IKB:IKB)
+  !
+  ! Add this source to the conservative mixing ratio sources
+  !
+  IF (.NOT. L2D) THEN 
+    IF (.NOT. LFLAT) THEN
+      PRRS(:,:,:,1) = PRRS(:,:,:,1)                                              &
+                    - DYF( MYM(PRHODJ) * ZFLX(:,:,:) * PINV_PDYY(:,:,:) )                           &
+                    + DZF( PMZM_PRHODJ(:,:,:) *MYF(PDZY(:,:,:)* &
+                      (MZM(ZFLX(:,:,:) * PINV_PDYY(:,:,:)))) * PINV_PDZZ(:,:,:) )
+    ELSE
+      PRRS(:,:,:,1) = PRRS(:,:,:,1) - DYF( MYM(PRHODJ) * ZFLX(:,:,:) * PINV_PDYY(:,:,:) )
+    END IF
+  END IF
+  !
+  ! Compute the equivalent tendancy for Rc and Ri
+  !
+  IF ( KRRL >= 1 .AND. .NOT. L2D) THEN   ! Sub-grid condensation
+    IF (.NOT. LFLAT) THEN
+      ZFLXC(:,:,:) = ZFLXC(:,:,:)            &
+            + 2.*( MXF( MYM( PRHODJ(:,:,:)*PAMOIST(:,:,:)*PSRCM(:,:,:) )*ZFLX(:,:,:) )                     &
+                +  MZF( MZM( PRHODJ(:,:,:)*PAMOIST(:,:,:)*PSRCM(:,:,:) )*MYF(                       &
+                                               PDZY(:,:,:)*(MZM( ZFLX(:,:,:)*PINV_PDYY(:,:,:) )) ) )&
+                 )
+      IF ( KRRI >= 1 ) THEN
+        PRRS(:,:,:,2) = PRRS(:,:,:,2) +  2. *                                  &
+        (- DYF( MYM( PRHODJ(:,:,:)*PAMOIST(:,:,:)*PSRCM(:,:,:) )*ZFLX(:,:,:)/PDYY )                        &
+         + DZF( MZM( PRHODJ(:,:,:)*PAMOIST(:,:,:)*PSRCM(:,:,:) )*MYF( PDZY(:,:,:)* &
+           (MZM( ZFLX(:,:,:)*PINV_PDYY(:,:,:) )) )&
+                                           * PINV_PDZZ(:,:,:) )                       &
+        )*(1.0-PFRAC_ICE(:,:,:))
+        PRRS(:,:,:,4) = PRRS(:,:,:,4) +  2. *                                  &
+        (- DYF( MYM( PRHODJ(:,:,:)*PAMOIST(:,:,:)*PSRCM(:,:,:) )*ZFLX(:,:,:)/PDYY )                        &
+         + DZF( MZM( PRHODJ(:,:,:)*PAMOIST(:,:,:)*PSRCM(:,:,:) )*MYF( PDZY(:,:,:)* &
+           (MZM( ZFLX(:,:,:)*PINV_PDYY(:,:,:) )) )&
+                                           * PINV_PDZZ(:,:,:) )                       &
+        )*PFRAC_ICE(:,:,:)
+      ELSE
+        PRRS(:,:,:,2) = PRRS(:,:,:,2) +  2. *                                  &
+        (- DYF( MYM( PRHODJ(:,:,:)*PAMOIST(:,:,:)*PSRCM(:,:,:) )*ZFLX(:,:,:)/PDYY )                        &
+         + DZF( MZM( PRHODJ(:,:,:)*PAMOIST(:,:,:)*PSRCM(:,:,:) )*MYF( PDZY(:,:,:)* &
+           (MZM( ZFLX(:,:,:)*PINV_PDYY(:,:,:) )) )&
+                                           * PINV_PDZZ(:,:,:) )                       &
+        )
+      END IF
+    ELSE
+      ZFLXC(:,:,:) = ZFLXC(:,:,:) + 2.*MXF( MYM( PRHODJ(:,:,:)*PAMOIST(:,:,:)*PSRCM(:,:,:) )*ZFLX )
+      IF ( KRRI >= 1 ) THEN
+        PRRS(:,:,:,2) = PRRS(:,:,:,2) - 2. *                                   &
+        DYF( MYM( PRHODJ(:,:,:)*PAMOIST(:,:,:)*PSRCM(:,:,:) )*ZFLX(:,:,:)/PDYY )*(1.0-PFRAC_ICE(:,:,:))
+        PRRS(:,:,:,4) = PRRS(:,:,:,4) - 2. *                                   &
+        DYF( MYM( PRHODJ(:,:,:)*PAMOIST(:,:,:)*PSRCM(:,:,:) )*ZFLX(:,:,:)/PDYY )*PFRAC_ICE(:,:,:)
+      ELSE
+        PRRS(:,:,:,2) = PRRS(:,:,:,2) - 2. *                                   &
+        DYF( MYM( PRHODJ(:,:,:)*PAMOIST(:,:,:)*PSRCM(:,:,:) )*ZFLX(:,:,:)/PDYY )
+      END IF
+    END IF
+  END IF
+  !
+  ! stores the horizontal  <V Rnp>
+  IF ( OCLOSE_OUT .AND. OTURB_FLX ) THEN
+    TZFIELD%CMNHNAME   = 'VR_FLX'
+    TZFIELD%CSTDNAME   = ''
+    TZFIELD%CLONGNAME  = 'VR_FLX'
+    TZFIELD%CUNITS     = 'kg kg-1 m s-1'
+    TZFIELD%CDIR       = 'XY'
+    TZFIELD%CCOMMENT   = 'X_Y_Z_VR_FLX'
+    TZFIELD%NGRID      = 3
+    TZFIELD%NTYPE      = TYPEREAL
+    TZFIELD%NDIMS      = 3
+    TZFIELD%LTIMEDEP   = .TRUE.
+    CALL IO_Field_write(TPFILE,TZFIELD,ZFLX(:,:,:))
+  END IF
+  !
+  IF (KSPLT==1 .AND. LLES_CALL) THEN
+    CALL SECOND_MNH(ZTIME1)
+    CALL LES_MEAN_SUBGRID( MYF(ZFLX), X_LES_SUBGRID_VRt ) 
+    CALL LES_MEAN_SUBGRID( MZF(MYF(GY_W_VW(PWM,PDYY,PDZZ,PDZY)*MZM(ZFLX))),&
+                           X_LES_RES_ddxa_W_SBG_UaRt , .TRUE. )
+    CALL LES_MEAN_SUBGRID( GY_M_M(PTHLM,PDYY,PDZZ,PDZY)*MYF(ZFLX), &
+                           X_LES_RES_ddxa_Thl_SBG_UaRt , .TRUE. )
+    CALL LES_MEAN_SUBGRID( GY_M_M(PRM(:,:,:,1),PDYY,PDZZ,PDZY)*MYF(ZFLX), &
+                           X_LES_RES_ddxa_Rt_SBG_UaRt , .TRUE. )
+    CALL SECOND_MNH(ZTIME2)
+    XTIME_LES = XTIME_LES + ZTIME2 - ZTIME1
+  END IF
+!
+  !
+  IF (KRRL>0 .AND. KSPLT==1 .AND. LLES_CALL) THEN
+    CALL SECOND_MNH(ZTIME1)
+    CALL LES_MEAN_SUBGRID(MYF(ZFLXC), X_LES_SUBGRID_VRc )
+    CALL SECOND_MNH(ZTIME2)
+    XTIME_LES = XTIME_LES + ZTIME2 - ZTIME1
+  END IF
+  !
+END IF
+#else
+IF (KRR/=0) THEN
+  !
+  IF (.NOT. L2D) THEN
+    CALL MYM_DEVICE( PK, ZTMP1_DEVICE )
+    CALL GY_M_V_DEVICE(1,IKU,1,PRM(:,:,:,1),PDYY,PDZZ,PDZY, ZTMP2_DEVICE)
+    !$acc kernels
+    !$acc loop independent collapse(3)
+    DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+       ZFLX(JI,JJ,JK)     = -XCHF * ZTMP1_DEVICE(JI,JJ,JK) * ZTMP2_DEVICE(JI,JJ,JK)
+    END DO !CONCURRENT
+    ZFLX(:,:,IKE+1) = ZFLX(:,:,IKE) 
+    !$acc end kernels
+  ELSE
+    !$acc kernels
+    ZFLX(:,:,:)     = 0.
+    !$acc end kernels
+  END IF
+!
+! Compute the flux at the first inner U-point with an uncentred vertical  
+! gradient
+  CALL MYM_DEVICE( PK(:,:,IKB:IKB), ZTMP1_DEVICE(:,:,1:1) )
+  CALL DYM_DEVICE(PRM(:,:,IKB:IKB,1), ZTMP2_DEVICE(:,:,1:1))
+  !$acc kernels
+  ZTMP3_DEVICE(:,:,1) = ZCOEFF(:,:,IKB+2)*PRM(:,:,IKB+2,1) &
+                    +ZCOEFF(:,:,IKB+1)*PRM(:,:,IKB+1,1) &
+                    +ZCOEFF(:,:,IKB  )*PRM(:,:,IKB  ,1)
+  !$acc end kernels
+  CALL MYM_DEVICE( ZTMP3_DEVICE(:,:,1:1), ZTMP4_DEVICE(:,:,1:1) )
+  !$acc kernels
+  ZFLX(:,:,IKB) = -XCHF * ZTMP1_DEVICE(:,:,1) *             &
+                 ( ZTMP2_DEVICE(:,:,1) * PINV_PDYY(:,:,IKB) &
+                 - ZTMP4_DEVICE(:,:,1)                      &
+                 *0.5* ( PDZY(:,:,IKB+1)+PDZY(:,:,IKB))  &
+                 * PINV_PDYY(:,:,IKB) )
+  !$acc end kernels
+! extrapolates the flux under the ground so that the vertical average with 
+! the IKB flux gives the ground value  ( warning the tangential surface
+! flux has been set to 0 for the moment !!  to be improved )
+  !$acc kernels
+  ZTMP1_DEVICE(:,:,1) = PSFRM(:,:)* PDIRCOSYW(:,:)
+  !$acc end kernels
+  CALL MYM_DEVICE( ZTMP1_DEVICE(:,:,1:1), ZTMP2_DEVICE(:,:,1:1) )
+  !$acc kernels
+  ZFLX(:,:,IKB-1) = 2. * ZTMP2_DEVICE(:,:,1) - ZFLX(:,:,IKB)
+  !$acc end kernels
+  !
+  ! Add this source to the conservative mixing ratio sources
+  !
+  IF (.NOT. L2D) THEN 
+    IF (.NOT. LFLAT) THEN
+      CALL MYM_DEVICE(PRHODJ, ZTMP1_DEVICE)
+      !$acc kernels
+      !$acc loop independent collapse(3)
+      DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+         ZTMP2_DEVICE(JI,JJ,JK) = ZTMP1_DEVICE(JI,JJ,JK) * ZFLX(JI,JJ,JK) * PINV_PDYY(JI,JJ,JK)
+      END DO
+      !$acc end kernels
+      CALL DYF_DEVICE( ZTMP2_DEVICE, ZTMP3_DEVICE )
+      !
+      !$acc kernels
+      !$acc loop independent collapse(3)
+      DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+         ZTMP1_DEVICE(JI,JJ,JK) = ZFLX(JI,JJ,JK) * PINV_PDYY(JI,JJ,JK)
+      END DO
+      !$acc end kernels
+      CALL MZM_DEVICE(ZTMP1_DEVICE,ZTMP2_DEVICE)
+      !$acc kernels
+      !$acc loop independent collapse(3)
+      DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+         ZTMP1_DEVICE(JI,JJ,JK) = PDZY(JI,JJ,JK)*ZTMP2_DEVICE(JI,JJ,JK)
+      END DO
+      !$acc end kernels
+      CALL MYF_DEVICE(ZTMP1_DEVICE,ZTMP2_DEVICE)
+      !$acc kernels
+      !$acc loop independent collapse(3)
+      DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+         ZTMP1_DEVICE(JI,JJ,JK) = PMZM_PRHODJ(JI,JJ,JK) * ZTMP2_DEVICE(JI,JJ,JK) * PINV_PDZZ(JI,JJ,JK)
+      END DO
+      !$acc end kernels
+      CALL DZF_DEVICE(1,IKU,1,ZTMP1_DEVICE,ZTMP2_DEVICE )
+      !
+      !$acc kernels
+      !$acc loop independent collapse(3)
+      DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+         PRRS(JI,JJ,JK,1) = PRRS(JI,JJ,JK,1) - ZTMP3_DEVICE(JI,JJ,JK) + ZTMP2_DEVICE(JI,JJ,JK)
+      END DO
+      !$acc end kernels
+    ELSE
+      CALL MYM_DEVICE(PRHODJ, ZTMP1_DEVICE)
+      !$acc kernels
+      ZTMP2_DEVICE(:,:,:) = ZTMP1_DEVICE(:,:,:) * ZFLX(:,:,:) * PINV_PDYY(:,:,:)
+      !$acc end kernels
+      CALL DYF_DEVICE( ZTMP2_DEVICE, ZTMP3_DEVICE )
+      !$acc kernels
+      PRRS(:,:,:,1) = PRRS(:,:,:,1) - ZTMP3_DEVICE(:,:,:)
+      !$acc end kernels
+    END IF
+  END IF
+  !
+  ! Compute the equivalent tendancy for Rc and Ri
+  !
+  IF ( KRRL >= 1 .AND. .NOT. L2D) THEN   ! Sub-grid condensation
+    IF (.NOT. LFLAT) THEN
+      !$acc kernels
+      ZTMP1_DEVICE(:,:,:) = PRHODJ(:,:,:)*PAMOIST(:,:,:)*PSRCM(:,:,:)
+      !$acc end kernels
+      CALL MYM_DEVICE( ZTMP1_DEVICE, ZTMP2_DEVICE )
+      !$acc kernels
+      ZTMP3_DEVICE(:,:,:) = ZTMP2_DEVICE(:,:,:)*ZFLX(:,:,:)
+      !$acc end kernels
+      CALL MXF_DEVICE( ZTMP3_DEVICE, ZTMP4_DEVICE )
+      CALL MZM_DEVICE( ZTMP1_DEVICE, ZTMP5_DEVICE )
+      !$acc kernels
+      ZTMP1_DEVICE(:,:,:) = ZFLX(:,:,:)*PINV_PDYY(:,:,:)
+      !$acc end kernels
+      CALL MZM_DEVICE( ZTMP1_DEVICE, ZTMP2_DEVICE )
+      !$acc kernels
+      ZTMP1_DEVICE(:,:,:) = PDZY(:,:,:)*ZTMP2_DEVICE(:,:,:)
+      !$acc end kernels
+      CALL MYF_DEVICE( ZTMP1_DEVICE, ZTMP2_DEVICE )
+      !$acc kernels
+      ZTMP1_DEVICE(:,:,:) = ZTMP5_DEVICE(:,:,:)*ZTMP2_DEVICE(:,:,:)
+      !$acc end kernels
+      CALL MZF_DEVICE(1,IKU,1, ZTMP1_DEVICE, ZTMP2_DEVICE )
+      !$acc kernels
+      ZFLXC(:,:,:) = ZFLXC(:,:,:) + 2.*( ZTMP4_DEVICE(:,:,:) + ZTMP2_DEVICE(:,:,:) )
+      !$acc end kernels
+      IF ( KRRI >= 1 ) THEN
+        !$acc kernels
+        ZTMP2_DEVICE(:,:,:) = ZTMP3_DEVICE(:,:,:) * PINV_PDYY(:,:,:)
+        !$acc end kernels
+        CALL DYF_DEVICE( ZTMP2_DEVICE, ZTMP3_DEVICE )
+        !$acc kernels
+        ZTMP2_DEVICE(:,:,:) = ZTMP1_DEVICE(:,:,:)* PINV_PDZZ(:,:,:)
+        !$acc end kernels
+        CALL DZF_DEVICE(1,IKU,1, ZTMP2_DEVICE, ZTMP4_DEVICE )
+        !$acc kernels
+        PRRS(:,:,:,2) = PRRS(:,:,:,2) +  2. * (- ZTMP3_DEVICE(:,:,:) + ZTMP4_DEVICE(:,:,:) )*(1.0-PFRAC_ICE(:,:,:))
+        PRRS(:,:,:,4) = PRRS(:,:,:,4) +  2. * (- ZTMP3_DEVICE(:,:,:) + ZTMP4_DEVICE(:,:,:) )*PFRAC_ICE(:,:,:)
+        !$acc end kernels
+      ELSE
+        !$acc kernels
+        PRRS(:,:,:,2) = PRRS(:,:,:,2) +  2. * (- ZTMP3_DEVICE(:,:,:) + ZTMP4_DEVICE(:,:,:) )
+        !$acc end kernels
+      END IF
+    ELSE
+      !$acc kernels
+      ZTMP1_DEVICE(:,:,:) = PRHODJ(:,:,:)*PAMOIST(:,:,:)*PSRCM(:,:,:)
+      !$acc end kernels
+      CALL MYM_DEVICE( ZTMP1_DEVICE, ZTMP2_DEVICE )
+      !$acc kernels
+      ZTMP3_DEVICE(:,:,:) = ZTMP2_DEVICE(:,:,:)*ZFLX(:,:,:)
+      !$acc end kernels
+      CALL MXF_DEVICE( ZTMP3_DEVICE, ZTMP4_DEVICE )
+      !$acc kernels
+      ZFLXC(:,:,:) = ZFLXC(:,:,:) + 2.*ZTMP4_DEVICE(:,:,:)
+      !$acc end kernels
+      !
+      !$acc kernels
+      ZTMP1_DEVICE(:,:,:) = ZTMP3_DEVICE(:,:,:)* PINV_PDYY(:,:,:)
+      !$acc end kernels
+      CALL DYF_DEVICE( ZTMP1_DEVICE, ZTMP2_DEVICE )
+      IF ( KRRI >= 1 ) THEN
+        !$acc kernels
+        PRRS(:,:,:,2) = PRRS(:,:,:,2) - 2. * ZTMP2_DEVICE(:,:,:)*(1.0-PFRAC_ICE(:,:,:))
+        PRRS(:,:,:,4) = PRRS(:,:,:,4) - 2. * ZTMP2_DEVICE(:,:,:)*PFRAC_ICE(:,:,:)
+        !$acc end kernels
+      ELSE
+        !$acc kernels
+        PRRS(:,:,:,2) = PRRS(:,:,:,2) - 2. * ZTMP2_DEVICE(:,:,:)
+        !$acc end kernels
+      END IF
+    END IF
+  END IF
+  !
+  ! stores the horizontal  <V Rnp>
+  IF ( OCLOSE_OUT .AND. OTURB_FLX ) THEN
+    !$acc update self(ZFLX)
+    TZFIELD%CMNHNAME   = 'VR_FLX'
+    TZFIELD%CSTDNAME   = ''
+    TZFIELD%CLONGNAME  = 'VR_FLX'
+    TZFIELD%CUNITS     = 'kg kg-1 m s-1'
+    TZFIELD%CDIR       = 'XY'
+    TZFIELD%CCOMMENT   = 'X_Y_Z_VR_FLX'
+    TZFIELD%NGRID      = 3
+    TZFIELD%NTYPE      = TYPEREAL
+    TZFIELD%NDIMS      = 3
+    TZFIELD%LTIMEDEP   = .TRUE.
+    CALL IO_Field_write(TPFILE,TZFIELD,ZFLX(:,:,:))
+  END IF
+  !
+  IF (KSPLT==1 .AND. LLES_CALL) THEN
+    CALL SECOND_MNH(ZTIME1)
+    !
+!$acc data copy(X_LES_SUBGRID_VRt,X_LES_RES_ddxa_W_SBG_UaRt, &
+!$acc &         X_LES_RES_ddxa_Thl_SBG_UaRt,X_LES_RES_ddxa_Rt_SBG_UaRt)
+    !
+    CALL MYF_DEVICE(ZFLX,ZTMP1_DEVICE)
+    CALL LES_MEAN_SUBGRID( ZTMP1_DEVICE, X_LES_SUBGRID_VRt ) 
+    !
+    CALL GY_W_VW_DEVICE(1,IKU,1,PWM,PDYY,PDZZ,PDZY,ZTMP1_DEVICE)
+    CALL MZM_DEVICE(ZFLX,ZTMP2_DEVICE)
+    !$acc kernels
+    ZTMP3_DEVICE(:,:,:) = ZTMP1_DEVICE(:,:,:) * ZTMP2_DEVICE(:,:,:)
+    !$acc end kernels
+    CALL MYF_DEVICE(ZTMP3_DEVICE, ZTMP4_DEVICE)
+    CALL MZF_DEVICE(1,IKU,1,ZTMP4_DEVICE,ZTMP1_DEVICE)
+    CALL LES_MEAN_SUBGRID( ZTMP1_DEVICE,X_LES_RES_ddxa_W_SBG_UaRt , .TRUE. )
+    !
+    CALL GY_M_M_DEVICE(1,IKU,1,PTHLM,PDYY,PDZZ,PDZY,ZTMP1_DEVICE)
+    CALL MYF_DEVICE(ZFLX,ZTMP2_DEVICE)
+    !$acc kernels
+    ZTMP3_DEVICE(:,:,:) = ZTMP1_DEVICE(:,:,:) * ZTMP2_DEVICE(:,:,:)
+    !$acc end kernels
+    CALL LES_MEAN_SUBGRID( ZTMP3_DEVICE, X_LES_RES_ddxa_Thl_SBG_UaRt , .TRUE. )
+    !
+    CALL GY_M_M_DEVICE(1,IKU,1,PRM(:,:,:,1),PDYY,PDZZ,PDZY,ZTMP1_DEVICE)
+    CALL MYF_DEVICE(ZFLX,ZTMP2_DEVICE)
+    !$acc kernels
+    ZTMP3_DEVICE(:,:,:) = ZTMP1_DEVICE(:,:,:) * ZTMP2_DEVICE(:,:,:)
+    !$acc end kernels
+    CALL LES_MEAN_SUBGRID( ZTMP3_DEVICE, X_LES_RES_ddxa_Rt_SBG_UaRt , .TRUE. )
+    !
+!$acc end data
+    !
+    CALL SECOND_MNH(ZTIME2)
+    XTIME_LES = XTIME_LES + ZTIME2 - ZTIME1
+  END IF
+!
+  !
+  IF (KRRL>0 .AND. KSPLT==1 .AND. LLES_CALL) THEN
+    CALL SECOND_MNH(ZTIME1)
+    !
+!$acc data copy(X_LES_SUBGRID_VRc)
+    !
+    CALL MYF_DEVICE(ZFLXC,ZTMP1_DEVICE)
+    CALL LES_MEAN_SUBGRID(ZTMP1_DEVICE, X_LES_SUBGRID_VRc )
+    !
+!$acc end data
+    !
+    CALL SECOND_MNH(ZTIME2)
+    XTIME_LES = XTIME_LES + ZTIME2 - ZTIME1
+  END IF
+  !
+END IF
+#endif
+!
+!*       7.   < V' TPV' >
+!             -----------
+!
+!! to be tested later
+!!IF (KRR/=0) THEN
+!!  ! here ZFLX= <V'R'np> and ZWORK= <V'Theta'l>
+!!  !
+!!  IF (.NOT. L2D) THEN        &
+!!    ZVPTV(:,:,:) =                                                         &
+!!        ZWORK(:,:,:)*MYM(ETHETA(KRR,KRRI,PTHLT,PEXNREF,PRT,PLOCPT,PSRCM)) +       &
+!!         ZFLX(:,:,:)*MYM(EMOIST(KRR,KRRI,PTHLT,PEXNREF,PRT,PLOCPT,PSRCM))
+!!  ELSE
+!!    ZVPTV(:,:,:) = 0.
+!!  END IF
+!!  !
+!!  ! stores the horizontal  <V VPT>
+!!  IF ( OCLOSE_OUT .AND. OTURB_FLX ) THEN
+!!    TZFIELD%CMNHNAME   = 'VVPT_FLX'
+!!    TZFIELD%CSTDNAME   = ''
+!!    TZFIELD%CLONGNAME  = 'VVPT_FLX'
+!!    TZFIELD%CUNITS     = 'K m s-1'
+!!    TZFIELD%CDIR       = 'XY'
+!!    TZFIELD%CCOMMENT   = 'X_Y_Z_VVPT_FLX'
+!!    TZFIELD%NGRID      = 3
+!!    TZFIELD%NTYPE      = TYPEREAL
+!!    TZFIELD%NDIMS      = 3
+!!    TZFIELD%LTIMEDEP   = .TRUE.
+!!    CALL IO_Field_write(TPFILE,TZFIELD,ZVPTV)
+!!  END IF
+!!!
+!!ELSE
+!!  ZVPTV(:,:,:)=ZWORK(:,:,:)
+!!END IF
+
+if ( mppdb_initialized ) then
+  !Check all inout arrays
+  call Mppdb_check( prthls, "Turb_hor_thermo_flux end:prthls" )
+  call Mppdb_check( prrs,   "Turb_hor_thermo_flux end:prrs"   )
+end if
+
+!$acc end data
+
+#ifndef MNH_OPENACC
+deallocate (zflx,zflxc,zcoeff)
+#else
+CALL MNH_REL_ZT3D ( IZFLX, IZFLXC, IZCOEFF,                                    &
+                    IZTMP1_DEVICE, IZTMP2_DEVICE, IZTMP3_DEVICE, IZTMP4_DEVICE, &
+                    IZTMP5_DEVICE, IZTMP6_DEVICE, IZTMP7_DEVICE, IZTMP8_DEVICE  )
+CALL MNH_CHECK_OUT_ZT3D("TURB_HOR_THERMO_FLUX")
+#endif
+
+!$acc end data
+
+END SUBROUTINE TURB_HOR_THERMO_FLUX
diff --git a/src/ZSOLVER/update_lm.f90 b/src/ZSOLVER/update_lm.f90
new file mode 100644
index 0000000000000000000000000000000000000000..7b82c64c7d766f33f34af358abd3c5c5cb3b37ae
--- /dev/null
+++ b/src/ZSOLVER/update_lm.f90
@@ -0,0 +1,173 @@
+!MNH_LIC Copyright 2006-2019 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.
+!-----------------------------------------------------------------
+!     ###################
+      MODULE MODI_UPDATE_LM
+!     ###################
+INTERFACE
+!
+SUBROUTINE UPDATE_LM(HLBCX,HLBCY,PLM,PLEPS)
+!
+CHARACTER(LEN=4), DIMENSION(2), INTENT(IN) :: HLBCX ! X boundary type
+CHARACTER(LEN=4), DIMENSION(2), INTENT(IN) :: HLBCY ! Y boundary type
+!
+REAL, DIMENSION(:,:,:), INTENT(INOUT) :: PLM   ! mixing length
+REAL, DIMENSION(:,:,:), INTENT(INOUT) :: PLEPS ! dissipative length
+!
+END SUBROUTINE UPDATE_LM
+!
+END INTERFACE
+!
+END MODULE MODI_UPDATE_LM
+!
+!
+!
+!     #################################################################
+      SUBROUTINE UPDATE_LM(HLBCX,HLBCY,PLM,PLEPS)
+!     #################################################################
+!
+!!****  *UPDATE_LM* - routine to set external points for mixing length
+!!
+!!    PURPOSE
+!!    -------
+!
+!!**  METHOD
+!!    ------
+!!   
+!!    EXTERNAL
+!!    --------   
+!!
+!!    IMPLICIT ARGUMENTS
+!!    ------------------ 
+!!        
+!!    REFERENCE
+!!    ---------
+!!      Book2 of documentation (routine UPDATE_LM)
+!!
+!!    AUTHOR
+!!    ------
+!!	V. Masson        * Meteo France *
+!!
+!!    MODIFICATIONS
+!!    -------------
+!!      Original    april 2006
+!!       V.Masson : Exchange of East and North sides
+!!   J.Escobar : 15/09/2015 : WENO5 & JPHEXT <> 1 
+!  P. Wautelet 20/05/2019: add name argument to ADDnFIELD_ll + new ADD4DFIELD_ll subroutine
+!-------------------------------------------------------------------------------
+!
+!*       0.    DECLARATIONS
+!         
+USE MODD_ARGSLIST_ll, ONLY : LIST_ll
+USE MODD_CONF
+USE MODD_PARAMETERS
+!
+USE MODE_ll
+use mode_mppdb
+USE MODI_GET_HALO
+!
+IMPLICIT NONE
+!
+!
+!*       0.1   declarations of arguments
+!
+CHARACTER(LEN=4), DIMENSION(2), INTENT(IN) :: HLBCX ! X boundary type
+CHARACTER(LEN=4), DIMENSION(2), INTENT(IN) :: HLBCY ! Y boundary type
+!
+REAL, DIMENSION(:,:,:), INTENT(INOUT) :: PLM   ! mixing length
+REAL, DIMENSION(:,:,:), INTENT(INOUT) :: PLEPS ! dissipative length
+!
+!*       0.2   declarations of local variables
+!
+INTEGER             :: IIB      ! First physical index in x direction
+INTEGER             :: IJB      ! First physical index in y direction
+INTEGER             :: IIE      ! last  physical index in x direction
+INTEGER             :: IJE      ! last  physical index in y direction
+INTEGER             :: JI       ! loop index
+!
+TYPE(LIST_ll), POINTER :: TZLM_ll   ! list of fields to exchange
+INTEGER                :: IINFO_ll       ! return code of parallel routine
+!
+!-------------------------------------------------------------------------------
+
+!$acc data present(PLM,PLEPS)
+
+if ( mppdb_initialized ) then
+  !Check all inout arrays
+  call Mppdb_check( plm,   "Update_lm beg:plm"   )
+  call Mppdb_check( pleps, "Update_lm beg:pleps" )
+end if
+!
+!*       1.    COMPUTE DIMENSIONS OF ARRAYS :
+!              ----------------------------
+CALL GET_INDICE_ll (IIB,IJB,IIE,IJE)
+!!$NULLIFY(TZLM_ll)
+!
+!-------------------------------------------------------------------------------
+!
+!*       2.  UPDATE HALOs :
+!            -------------
+!
+!
+!!$IF(NHALO == 1) THEN
+!!$!$acc update self(PLM,PLEPS)
+!!$  CALL ADD3DFIELD_ll( TZLM_ll, PLM,   'UPDATE_LM::PLM'   )
+!!$  CALL ADD3DFIELD_ll( TZLM_ll, PLEPS, 'UPDATE_LM::PLEPS' )
+!!$  CALL UPDATE_HALO_ll(TZLM_ll,IINFO_ll)
+!!$  CALL CLEANLIST_ll(TZLM_ll)
+!!$!$acc update device(PLM,PLEPS)
+!
+! /!\ Corner update needed ! -> GET_HALO_DDC
+!
+CALL GET_HALO_DDC( PLM,   HNAME='UPDATE_LM::PLM'   )
+CALL GET_HALO_DDC( PLEPS, HNAME='UPDATE_LM::PLEPS' )
+!!$END IF
+!
+!-------------------------------------------------------------------------------
+!
+!*       3.  UPDATE EXTERNAL POINTS OF GLOBAL DOMAIN:
+!            ---------------------------------------
+!
+
+IF ( HLBCX(1) /= "CYCL" .AND. LWEST_ll()) THEN
+  !$acc kernels async
+  PLM  (IIB-1,:,:) = PLM  (IIB,:,:)
+  PLEPS(IIB-1,:,:) = PLEPS(IIB,:,:)
+  !$acc end kernels
+END IF
+IF ( HLBCX(2) /= "CYCL" .AND. LEAST_ll()) THEN
+  !$acc kernels async
+  PLM  (IIE+1,:,:) = PLM  (IIE,:,:)
+  PLEPS(IIE+1,:,:) = PLEPS(IIE,:,:)
+  !$acc end kernels
+END IF
+IF ( HLBCY(1) /= "CYCL" .AND. LSOUTH_ll()) THEN
+   !$acc kernels async 
+   DO JI=1,SIZE(PLM,1)
+      PLM  (JI,IJB-1,:) = PLM  (JI,IJB,:)
+      PLEPS(JI,IJB-1,:) = PLEPS(JI,IJB,:)
+   END DO
+   !$acc end kernels
+END IF
+IF ( HLBCY(2) /= "CYCL" .AND. LNORTH_ll()) THEN
+   !$acc kernels async
+   DO JI=1,SIZE(PLM,1)
+      PLM  (JI,IJE+1,:) = PLM  (JI,IJE,:)
+      PLEPS(JI,IJE+1,:) = PLEPS(JI,IJE,:)
+   END DO
+   !$acc end kernels
+END IF
+!$acc wait
+
+if ( mppdb_initialized ) then
+  !Check all inout arrays
+  call Mppdb_check( plm,   "Update_lm end:plm"   )
+  call Mppdb_check( pleps, "Update_lm end:pleps" )
+end if
+
+!$acc end data
+
+!-----------------------------------------------------------------------------
+END SUBROUTINE UPDATE_LM
diff --git a/src/ZSOLVER/zsolver.f90 b/src/ZSOLVER/zsolver.f90
index 779a6b5685912b69249552d79b93337d17edd1bf..846c7fb7761cab5ef0b8caec2d474fd7a202a6d6 100644
--- a/src/ZSOLVER/zsolver.f90
+++ b/src/ZSOLVER/zsolver.f90
@@ -153,6 +153,11 @@ USE MODI_FLAT_INV
 USE MODI_ZSOLVER_INV
 USE MODI_DOTPROD
 !
+#ifdef MNH_OPENACC
+USE MODE_MNH_ZWORK , ONLY : MNH_ALLOCATE_ZT3D , MNH_REL_ZT3D
+#endif
+!
+!
 IMPLICIT NONE
 !
 !*      0.1    declarations of arguments
@@ -209,23 +214,39 @@ REAL, DIMENSION(:)    , INTENT(IN) :: A_K,B_K,C_K,D_K
 !
 INTEGER :: JM                                    ! loop index   
 !
-REAL, DIMENSION(SIZE(PPHI,1),SIZE(PPHI,2),SIZE(PPHI,3)) :: ZDELTA, ZKSI  
+REAL, DIMENSION(:,:,:), pointer , contiguous :: ZDELTA, ZKSI
      ! array containing the auxilary fields DELTA and KSI of the CR method
-REAL, DIMENSION(SIZE(PPHI,1),SIZE(PPHI,2),SIZE(PPHI,3)) :: ZP, ZQ  
+REAL, DIMENSION(:,:,:), pointer , contiguous :: ZP, ZQ  
      ! array containing the auxilary fields P and Q of the CR method
-REAL, DIMENSION(SIZE(PPHI,1),SIZE(PPHI,2),SIZE(PPHI,3)) :: ZRESIDUE
+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
 REAL :: ZDOT_DELTA           ! dot product of ZDELTA by itself
 !
+INTEGER  :: JIU,JJU,JKU
+INTEGER  :: JI,JJ,JK
 !-------------------------------------------------------------------------------
 !
 !*       1.    INITIALIZATIONS
 !              ---------------
 !
-!                             
+JIU =  size(PPHI, 1 )
+JJU =  size(PPHI, 2 )
+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_ZT3D(ZDELTA   ,JIU,JJU,JKU )
+IZKSI     = MNH_ALLOCATE_ZT3D(ZKSI     ,JIU,JJU,JKU )
+IZP       = MNH_ALLOCATE_ZT3D(ZP       ,JIU,JJU,JKU )
+IZQ       = MNH_ALLOCATE_ZT3D(ZQ       ,JIU,JJU,JKU )
+IZRESIDUE = MNH_ALLOCATE_ZT3D(ZRESIDUE ,JIU,JJU,JKU )
+
+#endif
 !*       1.1    compute the vector: r^(0) =  Q(PHI) - Y
 !
 #ifndef MNH_OPENACC
@@ -308,7 +329,12 @@ DO JM = 1,KITR
 !
 END DO              ! end of the loop for the iterative solver
 !
-!  
+!
+#ifndef MNH_OPENACC
+DEALLOCATE(ZDELTA,ZKSI,ZP,ZQ,ZRESIDUE)
+#else
+CALL MNH_REL_ZT3D(IZDELTA,IZKSI,IZP,IZQ,IZRESIDUE)
+#endif
 !-------------------------------------------------------------------------------
 !
 END SUBROUTINE ZSOLVER
diff --git a/src/ZSOLVER/zsolver_inv.f90 b/src/ZSOLVER/zsolver_inv.f90
index e6cfc214eef4a48d8064037fd25c42d35fee1078..29965951e8ee7546dad9e2e27d6f93e6a1cd3e1e 100644
--- a/src/ZSOLVER/zsolver_inv.f90
+++ b/src/ZSOLVER/zsolver_inv.f90
@@ -150,6 +150,9 @@ SUBROUTINE ZSOLVER_INV(HLBCX,HLBCY,PDXHATM,PDYHATM,PRHOM,PAF,PBF,PCF, &
   USE MODI_DOTPROD
   !
   USE mode_mg_main_mnh
+#ifdef MNH_OPENACC
+  USE MODE_MNH_ZWORK , ONLY : MNH_ALLOCATE_ZT3D , MNH_REL_ZT3D
+#endif
   !
   IMPLICIT NONE
   !
@@ -191,14 +194,10 @@ SUBROUTINE ZSOLVER_INV(HLBCX,HLBCY,PDXHATM,PDYHATM,PRHOM,PAF,PBF,PCF, &
   !
   !*       0.2   declaration of local variables
   !
-  REAL, DIMENSION(SIZE(PY,1),SIZE(PY,2),SIZE(PY,3)) :: ZY ! work array to store 
-  ! the RHS of the equation
-  !
-  !REAL, DIMENSION(SIZE(PY,1),SIZE(PY,2),SIZE(PY,3)) :: ZWORK ! work array used by 
-  ! the FFT. It has been enlarged in order to be sufficient for 2D and 3D cases
-  !
-  REAL, DIMENSION(SIZE(PBF,1),SIZE(PBF,2),SIZE(PBF,3)) :: ZAF ! work array to
-  !                                                        ! expand PAF
+  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
@@ -222,6 +221,11 @@ SUBROUTINE ZSOLVER_INV(HLBCX,HLBCY,PDXHATM,PDYHATM,PRHOM,PAF,PBF,PCF, &
   IKB=1+JPVEXT
   IKE=IKU - JPVEXT
   !
+#ifndef MNH_OPENACC
+  ALLOCATE(ZY(IIU,IJU,IKU))
+#else
+  IZY = MNH_ALLOCATE_ZT3D(ZY ,IIU,IJU,IKU )
+#endif
   !
   !-------------------------------------------------------------------------------
   !
@@ -308,10 +312,15 @@ SUBROUTINE ZSOLVER_INV(HLBCX,HLBCY,PDXHATM,PDYHATM,PRHOM,PAF,PBF,PCF, &
   !
   !  WARNING WITH GET_HALO_D not BITREPROD !!!
   !
-  CALL GET_HALO(PF_1_Y)
+  CALL GET_HALO_DDC(PF_1_Y)
   !
   CALL PF_1_Y_BOUND(PF_1_Y)  
   !-------------------------------------------------------------------------------
+#ifndef MNH_OPENACC
+  DEALLOCATE(ZY)
+#else
+  CALL MNH_REL_ZT3D(IZY)
+#endif  
   !
 CONTAINS