Index: codes/icosagcm/devel/src/dynamics/caldyn_kernels_base.F90
===================================================================
--- codes/icosagcm/devel/src/dynamics/caldyn_kernels_base.F90	(revision 537)
+++ codes/icosagcm/devel/src/dynamics/caldyn_kernels_base.F90	(revision 537)
@@ -0,0 +1,357 @@
+MODULE caldyn_kernels_base_mod
+  USE icosa
+  USE transfert_mod
+  USE disvert_mod
+  USE omp_para
+  USE trace
+  IMPLICIT NONE
+  PRIVATE
+
+  INTEGER, PARAMETER,PUBLIC :: energy=1, enstrophy=2
+  TYPE(t_field),POINTER,PUBLIC :: f_out_u(:), f_qu(:), f_qv(:)
+  REAL(rstd),SAVE,POINTER :: out_u(:,:), p(:,:), qu(:,:)
+  !$OMP THREADPRIVATE(out_u, p, qu)
+
+  ! temporary shared variables for caldyn
+  TYPE(t_field),POINTER,PUBLIC :: f_pk(:),f_wwuu(:),f_planetvel(:)
+
+  INTEGER, PUBLIC :: caldyn_conserv
+  !$OMP THREADPRIVATE(caldyn_conserv) 
+
+  TYPE(t_message),PUBLIC :: req_ps, req_mass, req_theta_rhodz, req_u, req_qu, req_geopot, req_w
+
+  PUBLIC :: compute_geopot, compute_caldyn_vert, compute_caldyn_vert_nh
+
+CONTAINS
+
+  !**************************** Geopotential *****************************
+
+  SUBROUTINE compute_geopot(rhodz,theta, ps,pk,geopot) 
+    REAL(rstd),INTENT(IN)    :: rhodz(iim*jjm,llm)
+    REAL(rstd),INTENT(IN)    :: theta(iim*jjm,llm,nqdyn) ! active scalars : theta/entropy, moisture, ...
+    REAL(rstd),INTENT(INOUT) :: ps(iim*jjm)
+    REAL(rstd),INTENT(OUT)   :: pk(iim*jjm,llm)       ! Exner function (compressible) /Lagrange multiplier (Boussinesq)
+    REAL(rstd),INTENT(INOUT) :: geopot(iim*jjm,llm+1) ! geopotential
+
+    INTEGER :: i,j,ij,l
+    REAL(rstd) :: Rd, p_ik, exner_ik, temp_ik, qv, chi, Rmix, gv
+    INTEGER    :: ij_omp_begin_ext, ij_omp_end_ext
+
+    CALL trace_start("compute_geopot")
+
+!$OMP BARRIER
+
+    CALL distrib_level(ij_end_ext-ij_begin_ext+1,ij_omp_begin_ext,ij_omp_end_ext)
+    ij_omp_begin_ext=ij_omp_begin_ext+ij_begin_ext-1
+    ij_omp_end_ext=ij_omp_end_ext+ij_begin_ext-1
+
+    Rd = kappa*cpp
+
+#ifdef CPP_DYSL
+#include "../kernels/compute_geopot.k90"
+#else
+
+    ! Pressure is computed first top-down (temporarily stored in pk)
+    ! Then Exner pressure and geopotential are computed bottom-up
+    ! Works also when caldyn_eta=eta_mass          
+
+    IF(boussinesq) THEN ! compute geopotential and pk=Lagrange multiplier
+       ! specific volume 1 = dphi/g/rhodz
+       !         IF (is_omp_level_master) THEN ! no openMP on vertical due to dependency
+       DO l = 1,llm
+          !DIR$ SIMD
+          DO ij=ij_omp_begin_ext,ij_omp_end_ext         
+             geopot(ij,l+1) = geopot(ij,l) + g*rhodz(ij,l)
+          ENDDO
+       ENDDO
+       ! use hydrostatic balance with theta*rhodz to find pk (Lagrange multiplier=pressure) 
+       ! uppermost layer
+       !DIR$ SIMD
+       DO ij=ij_begin_ext,ij_end_ext         
+          pk(ij,llm) = ptop + (.5*g)*theta(ij,llm,1)*rhodz(ij,llm)
+       END DO
+       ! other layers
+       DO l = llm-1, 1, -1
+          !          !$OMP DO SCHEDULE(STATIC) 
+          !DIR$ SIMD
+          DO ij=ij_begin_ext,ij_end_ext         
+             pk(ij,l) = pk(ij,l+1) + (.5*g)*(theta(ij,l,1)*rhodz(ij,l)+theta(ij,l+1,1)*rhodz(ij,l+1))
+          END DO
+       END DO
+       ! now pk contains the Lagrange multiplier (pressure)
+    ELSE ! non-Boussinesq, compute pressure, Exner pressure or temperature, then geopotential
+       ! uppermost layer
+       
+       SELECT CASE(caldyn_thermo)
+          CASE(thermo_theta, thermo_entropy)
+             !DIR$ SIMD
+             DO ij=ij_omp_begin_ext,ij_omp_end_ext
+                pk(ij,llm) = ptop + (.5*g)*rhodz(ij,llm)
+             END DO
+             ! other layers
+             DO l = llm-1, 1, -1
+                !DIR$ SIMD
+                DO ij=ij_omp_begin_ext,ij_omp_end_ext         
+                   pk(ij,l) = pk(ij,l+1) + (.5*g)*(rhodz(ij,l)+rhodz(ij,l+1))
+                END DO
+             END DO
+             ! surface pressure (for diagnostics)
+             IF(caldyn_eta==eta_lag) THEN
+                DO ij=ij_omp_begin_ext,ij_omp_end_ext         
+                   ps(ij) = pk(ij,1) + (.5*g)*rhodz(ij,1)
+                END DO
+             END IF
+          CASE(thermo_moist) ! theta(ij,l,2) = qv = mv/md
+             !DIR$ SIMD
+             DO ij=ij_omp_begin_ext,ij_omp_end_ext
+                pk(ij,llm) = ptop + (.5*g)*rhodz(ij,llm)*(1.+theta(ij,l,2))
+             END DO
+             ! other layers
+             DO l = llm-1, 1, -1
+                !DIR$ SIMD
+                DO ij=ij_omp_begin_ext,ij_omp_end_ext         
+                   pk(ij,l) = pk(ij,l+1) + (.5*g)*(          &
+                        rhodz(ij,l)  *(1.+theta(ij,l,2)) +   &
+                        rhodz(ij,l+1)*(1.+theta(ij,l+1,2)) )
+                END DO
+             END DO
+             ! surface pressure (for diagnostics)
+             IF(caldyn_eta==eta_lag) THEN
+                DO ij=ij_omp_begin_ext,ij_omp_end_ext         
+                   ps(ij) = pk(ij,1) + (.5*g)*rhodz(ij,1)*(1.+theta(ij,l,2))
+                END DO
+             END IF
+          END SELECT
+
+       DO l = 1,llm
+          SELECT CASE(caldyn_thermo)
+          CASE(thermo_theta)
+             !DIR$ SIMD
+             DO ij=ij_omp_begin_ext,ij_omp_end_ext
+                p_ik = pk(ij,l)
+                exner_ik = cpp * (p_ik/preff) ** kappa
+                pk(ij,l) = exner_ik
+                ! specific volume v = kappa*theta*pi/p = dphi/g/rhodz
+                geopot(ij,l+1) = geopot(ij,l) + (g*kappa)*rhodz(ij,l)*theta(ij,l,1)*exner_ik/p_ik
+             ENDDO
+          CASE(thermo_entropy) ! theta is in fact entropy = cpp*log(theta/Treff) = cpp*log(T/Treff) - Rd*log(p/preff)
+             !DIR$ SIMD
+             DO ij=ij_omp_begin_ext,ij_omp_end_ext
+                p_ik = pk(ij,l)
+                temp_ik = Treff*exp((theta(ij,l,1) + Rd*log(p_ik/preff))/cpp)
+                pk(ij,l) = temp_ik
+                ! specific volume v = Rd*T/p = dphi/g/rhodz
+                geopot(ij,l+1) = geopot(ij,l) + (g*Rd)*rhodz(ij,l)*temp_ik/p_ik
+             ENDDO
+          CASE(thermo_moist) ! theta is moist pseudo-entropy per dry air mass
+             DO ij=ij_omp_begin_ext,ij_omp_end_ext
+                p_ik = pk(ij,l)
+                qv = theta(ij,l,2) ! water vaper mixing ratio = mv/md
+                Rmix = Rd+qv*Rv
+                chi = ( theta(ij,l,1) + Rmix*log(p_ik/preff) ) / (cpp + qv*cppv) ! log(T/Treff)
+                temp_ik = Treff*exp(chi)
+                pk(ij,l) = temp_ik
+                ! specific volume v = R*T/p = dphi/g/rhodz
+                ! R = (Rd + qv.Rv)/(1+qv)
+                geopot(ij,l+1) = geopot(ij,l) + g*Rmix*rhodz(ij,l)*temp_ik/(p_ik*(1+qv))
+             ENDDO
+          CASE DEFAULT
+             STOP
+          END SELECT
+       ENDDO
+    END IF
+
+#endif
+
+    !ym flush geopot
+    !$OMP BARRIER
+
+    CALL trace_end("compute_geopot")
+
+  END SUBROUTINE compute_geopot
+
+  SUBROUTINE compute_caldyn_vert(u,theta,rhodz,convm, wflux,wwuu, dps,dtheta_rhodz,du)
+    REAL(rstd),INTENT(IN)  :: u(iim*3*jjm,llm)
+    REAL(rstd),INTENT(IN)  :: theta(iim*jjm,llm,nqdyn)
+    REAL(rstd),INTENT(IN)  :: rhodz(iim*jjm,llm)
+    REAL(rstd),INTENT(INOUT)  :: convm(iim*jjm,llm)  ! mass flux convergence
+
+    REAL(rstd),INTENT(INOUT) :: wflux(iim*jjm,llm+1) ! vertical mass flux (kg/m2/s)
+    REAL(rstd),INTENT(INOUT) :: wwuu(iim*3*jjm,llm+1)
+    REAL(rstd),INTENT(INOUT) :: du(iim*3*jjm,llm)
+    REAL(rstd),INTENT(INOUT) :: dtheta_rhodz(iim*jjm,llm,nqdyn)
+    REAL(rstd),INTENT(OUT) :: dps(iim*jjm)
+
+    ! temporary variable    
+    INTEGER :: i,j,ij,l,iq
+    REAL(rstd) :: p_ik, exner_ik
+    INTEGER    :: ij_omp_begin, ij_omp_end
+
+    CALL trace_start("compute_caldyn_vert")
+
+    CALL distrib_level(ij_end-ij_begin+1,ij_omp_begin,ij_omp_end)
+    ij_omp_begin=ij_omp_begin+ij_begin-1
+    ij_omp_end=ij_omp_end+ij_begin-1
+
+    !    REAL(rstd) :: wwuu(iim*3*jjm,llm+1) ! tmp var, don't know why but gain 30% on the whole code in opemp
+    ! need to be understood
+
+    !    wwuu=wwuu_out
+    CALL trace_start("compute_caldyn_vert")
+
+    !$OMP BARRIER   
+!!! cumulate mass flux convergence from top to bottom
+    !  IF (is_omp_level_master) THEN
+    DO  l = llm-1, 1, -1
+       !    IF (caldyn_conserv==energy) CALL test_message(req_qu) 
+
+!!$OMP DO SCHEDULE(STATIC) 
+       !DIR$ SIMD
+       DO ij=ij_omp_begin,ij_omp_end         
+          convm(ij,l) = convm(ij,l) + convm(ij,l+1)
+       ENDDO
+    ENDDO
+    !  ENDIF
+
+    !$OMP BARRIER
+    ! FLUSH on convm
+!!!!!!!!!!!!!!!!!!!!!!!!!
+
+    ! compute dps
+    IF (is_omp_first_level) THEN
+       !DIR$ SIMD
+       DO ij=ij_begin,ij_end         
+          ! dps/dt = -int(div flux)dz
+          dps(ij) = convm(ij,1)
+       ENDDO
+    ENDIF
+
+!!! Compute vertical mass flux (l=1,llm+1 done by caldyn_BC)
+    DO l=ll_beginp1,ll_end
+       !    IF (caldyn_conserv==energy) CALL test_message(req_qu) 
+       !DIR$ SIMD
+       DO ij=ij_begin,ij_end         
+          ! w = int(z,ztop,div(flux)dz) + B(eta)dps/dt
+          ! => w>0 for upward transport
+          wflux( ij, l ) = bp(l) * convm( ij, 1 ) - convm( ij, l ) 
+       ENDDO
+    ENDDO
+
+    !--> flush wflux  
+    !$OMP BARRIER
+
+    DO iq=1,nqdyn
+       DO l=ll_begin,ll_endm1
+       !DIR$ SIMD
+          DO ij=ij_begin,ij_end         
+             dtheta_rhodz(ij, l, iq) = dtheta_rhodz(ij, l, iq)  -   0.5 * &
+                  ( wflux(ij,l+1) * (theta(ij,l,iq) + theta(ij,l+1,iq)))
+          END DO
+       END DO
+       DO l=ll_beginp1,ll_end
+          !DIR$ SIMD
+          DO ij=ij_begin,ij_end         
+             dtheta_rhodz(ij, l, iq) = dtheta_rhodz(ij, l, iq)  +   0.5 * &
+                  ( wflux(ij,l) * (theta(ij,l-1,iq) + theta(ij,l,iq) ) )
+          END DO
+       END DO
+    END DO
+
+    ! Compute vertical transport
+    DO l=ll_beginp1,ll_end
+       !DIR$ SIMD
+       DO ij=ij_begin,ij_end         
+          wwuu(ij+u_right,l) = 0.5*( wflux(ij,l) + wflux(ij+t_right,l)) * (u(ij+u_right,l) - u(ij+u_right,l-1))
+          wwuu(ij+u_lup,l) = 0.5* ( wflux(ij,l) + wflux(ij+t_lup,l)) * (u(ij+u_lup,l) - u(ij+u_lup,l-1))
+          wwuu(ij+u_ldown,l) = 0.5*( wflux(ij,l) + wflux(ij+t_ldown,l)) * (u(ij+u_ldown,l) - u(ij+u_ldown,l-1))
+       ENDDO
+    ENDDO
+
+    !--> flush wwuu  
+    !$OMP BARRIER
+
+    ! Add vertical transport to du
+    DO l=ll_begin,ll_end
+       !DIR$ SIMD
+       DO ij=ij_begin,ij_end         
+          du(ij+u_right, l )   = du(ij+u_right,l)  - (wwuu(ij+u_right,l+1)+ wwuu(ij+u_right,l)) / (rhodz(ij,l)+rhodz(ij+t_right,l))
+          du(ij+u_lup, l )     = du(ij+u_lup,l)    - (wwuu(ij+u_lup,l+1)  + wwuu(ij+u_lup,l))   / (rhodz(ij,l)+rhodz(ij+t_lup,l))
+          du(ij+u_ldown, l )   = du(ij+u_ldown,l)  - (wwuu(ij+u_ldown,l+1)+ wwuu(ij+u_ldown,l)) / (rhodz(ij,l)+rhodz(ij+t_ldown,l))
+       ENDDO
+    ENDDO
+
+    !  DO l=ll_beginp1,ll_end
+    !!DIR$ SIMD
+    !      DO ij=ij_begin,ij_end         
+    !        wwuu_out(ij+u_right,l) = wwuu(ij+u_right,l)
+    !        wwuu_out(ij+u_lup,l)   = wwuu(ij+u_lup,l)
+    !        wwuu_out(ij+u_ldown,l) = wwuu(ij+u_ldown,l)
+    !     ENDDO
+    !   ENDDO
+
+    CALL trace_end("compute_caldyn_vert")
+
+  END SUBROUTINE compute_caldyn_vert
+
+  SUBROUTINE compute_caldyn_vert_NH(mass,geopot,W,wflux, du,dPhi,dW)
+    REAL(rstd),INTENT(IN) :: mass(iim*jjm,llm)
+    REAL(rstd),INTENT(IN) :: geopot(iim*jjm,llm+1)
+    REAL(rstd),INTENT(IN) :: W(iim*jjm,llm+1)
+    REAL(rstd),INTENT(IN) :: wflux(iim*jjm,llm+1)
+    REAL(rstd),INTENT(INOUT) :: du(iim*3*jjm,llm)
+    REAL(rstd),INTENT(INOUT) :: dPhi(iim*jjm,llm+1)
+    REAL(rstd),INTENT(INOUT) :: dW(iim*jjm,llm+1)
+    ! local arrays
+    REAL(rstd) :: eta_dot(iim*jjm) ! eta_dot in full layers
+    REAL(rstd) :: wcov(iim*jjm) ! covariant vertical momentum in full layers
+    REAL(rstd) :: W_etadot(iim*jjm,llm) ! vertical flux of vertical momentum
+    ! indices and temporary values
+    INTEGER    :: ij, l
+    REAL(rstd) :: wflux_ij, w_ij
+
+    CALL trace_start("compute_caldyn_vert_nh")
+
+    DO l=ll_begin,ll_end
+       ! compute the local arrays
+       !DIR$ SIMD
+       DO ij=ij_begin_ext,ij_end_ext
+          wflux_ij = .5*(wflux(ij,l)+wflux(ij,l+1))
+          w_ij = .5*(W(ij,l)+W(ij,l+1))/mass(ij,l)
+          W_etadot(ij,l) = wflux_ij*w_ij
+          eta_dot(ij) = wflux_ij / mass(ij,l)
+          wcov(ij) = w_ij*(geopot(ij,l+1)-geopot(ij,l))
+       ENDDO
+       ! add NH term to du
+      !DIR$ SIMD
+      DO ij=ij_begin,ij_end
+          du(ij+u_right,l) = du(ij+u_right,l) &
+               - .5*(wcov(ij+t_right)+wcov(ij)) &
+               *ne_right*(eta_dot(ij+t_right)-eta_dot(ij))
+          du(ij+u_lup,l) = du(ij+u_lup,l) &
+               - .5*(wcov(ij+t_lup)+wcov(ij)) &
+               *ne_lup*(eta_dot(ij+t_lup)-eta_dot(ij))
+          du(ij+u_ldown,l) = du(ij+u_ldown,l) &
+               - .5*(wcov(ij+t_ldown)+wcov(ij)) &
+               *ne_ldown*(eta_dot(ij+t_ldown)-eta_dot(ij))
+       END DO
+    ENDDO
+    ! add NH terms to dW, dPhi
+    ! FIXME : TODO top and bottom
+    DO l=ll_beginp1,ll_end ! inner interfaces only
+       !DIR$ SIMD
+       DO ij=ij_begin,ij_end
+          dPhi(ij,l) = dPhi(ij,l) - wflux(ij,l) &
+               * (geopot(ij,l+1)-geopot(ij,l-1))/(mass(ij,l-1)+mass(ij,l))
+       END DO
+    END DO
+    DO l=ll_begin,ll_end
+       !DIR$ SIMD
+       DO ij=ij_begin,ij_end
+          dW(ij,l+1) = dW(ij,l+1) + W_etadot(ij,l) ! update inner+top interfaces
+          dW(ij,l)   = dW(ij,l)   - W_etadot(ij,l) ! update bottom+inner interfaces
+       END DO
+    END DO
+    CALL trace_end("compute_caldyn_vert_nh")
+
+  END SUBROUTINE compute_caldyn_vert_NH
+END MODULE caldyn_kernels_base_mod
Index: codes/icosagcm/devel/src/dynamics/caldyn_kernels_base.f90
===================================================================
--- codes/icosagcm/devel/src/dynamics/caldyn_kernels_base.f90	(revision 536)
+++ 	(revision )
@@ -1,351 +1,0 @@
-MODULE caldyn_kernels_base_mod
-  USE icosa
-  USE transfert_mod
-  USE disvert_mod
-  USE omp_para
-  USE trace
-  IMPLICIT NONE
-  PRIVATE
-
-  INTEGER, PARAMETER,PUBLIC :: energy=1, enstrophy=2
-  TYPE(t_field),POINTER,PUBLIC :: f_out_u(:), f_qu(:), f_qv(:)
-  REAL(rstd),SAVE,POINTER :: out_u(:,:), p(:,:), qu(:,:)
-  !$OMP THREADPRIVATE(out_u, p, qu)
-
-  ! temporary shared variables for caldyn
-  TYPE(t_field),POINTER,PUBLIC :: f_pk(:),f_wwuu(:),f_planetvel(:)
-
-  INTEGER, PUBLIC :: caldyn_conserv
-  !$OMP THREADPRIVATE(caldyn_conserv) 
-
-  TYPE(t_message),PUBLIC :: req_ps, req_mass, req_theta_rhodz, req_u, req_qu, req_geopot, req_w
-
-  PUBLIC :: compute_geopot, compute_caldyn_vert, compute_caldyn_vert_nh
-
-CONTAINS
-
-  !**************************** Geopotential *****************************
-
-  SUBROUTINE compute_geopot(rhodz,theta, ps,pk,geopot) 
-    REAL(rstd),INTENT(IN)    :: rhodz(iim*jjm,llm)
-    REAL(rstd),INTENT(IN)    :: theta(iim*jjm,llm,nqdyn) ! active scalars : theta/entropy, moisture, ...
-    REAL(rstd),INTENT(INOUT) :: ps(iim*jjm)
-    REAL(rstd),INTENT(OUT)   :: pk(iim*jjm,llm)       ! Exner function (compressible) /Lagrange multiplier (Boussinesq)
-    REAL(rstd),INTENT(INOUT) :: geopot(iim*jjm,llm+1) ! geopotential
-
-    INTEGER :: i,j,ij,l
-    REAL(rstd) :: Rd, p_ik, exner_ik, temp_ik, qv, chi, Rmix
-    INTEGER    :: ij_omp_begin_ext, ij_omp_end_ext
-
-    CALL trace_start("compute_geopot")
-
-!$OMP BARRIER
-
-    CALL distrib_level(ij_end_ext-ij_begin_ext+1,ij_omp_begin_ext,ij_omp_end_ext)
-    ij_omp_begin_ext=ij_omp_begin_ext+ij_begin_ext-1
-    ij_omp_end_ext=ij_omp_end_ext+ij_begin_ext-1
-
-    Rd = kappa*cpp
-
-    ! Pressure is computed first top-down (temporarily stored in pk)
-    ! Then Exner pressure and geopotential are computed bottom-up
-    ! Works also when caldyn_eta=eta_mass          
-
-    IF(boussinesq) THEN ! compute geopotential and pk=Lagrange multiplier
-       ! specific volume 1 = dphi/g/rhodz
-       !         IF (is_omp_level_master) THEN ! no openMP on vertical due to dependency
-       DO l = 1,llm
-          !DIR$ SIMD
-          DO ij=ij_omp_begin_ext,ij_omp_end_ext         
-             geopot(ij,l+1) = geopot(ij,l) + g*rhodz(ij,l)
-          ENDDO
-       ENDDO
-       ! use hydrostatic balance with theta*rhodz to find pk (Lagrange multiplier=pressure) 
-       ! uppermost layer
-       !DIR$ SIMD
-       DO ij=ij_begin_ext,ij_end_ext         
-          pk(ij,llm) = ptop + (.5*g)*theta(ij,llm,1)*rhodz(ij,llm)
-       END DO
-       ! other layers
-       DO l = llm-1, 1, -1
-          !          !$OMP DO SCHEDULE(STATIC) 
-          !DIR$ SIMD
-          DO ij=ij_begin_ext,ij_end_ext         
-             pk(ij,l) = pk(ij,l+1) + (.5*g)*(theta(ij,l,1)*rhodz(ij,l)+theta(ij,l+1,1)*rhodz(ij,l+1))
-          END DO
-       END DO
-       ! now pk contains the Lagrange multiplier (pressure)
-    ELSE ! non-Boussinesq, compute pressure, Exner pressure or temperature, then geopotential
-       ! uppermost layer
-       
-       SELECT CASE(caldyn_thermo)
-          CASE(thermo_theta, thermo_entropy)
-             !DIR$ SIMD
-             DO ij=ij_omp_begin_ext,ij_omp_end_ext
-                pk(ij,llm) = ptop + (.5*g)*rhodz(ij,llm)
-             END DO
-             ! other layers
-             DO l = llm-1, 1, -1
-                !DIR$ SIMD
-                DO ij=ij_omp_begin_ext,ij_omp_end_ext         
-                   pk(ij,l) = pk(ij,l+1) + (.5*g)*(rhodz(ij,l)+rhodz(ij,l+1))
-                END DO
-             END DO
-             ! surface pressure (for diagnostics)
-             IF(caldyn_eta==eta_lag) THEN
-                DO ij=ij_omp_begin_ext,ij_omp_end_ext         
-                   ps(ij) = pk(ij,1) + (.5*g)*rhodz(ij,1)
-                END DO
-             END IF
-          CASE(thermo_moist) ! theta(ij,l,2) = qv = mv/md
-             !DIR$ SIMD
-             DO ij=ij_omp_begin_ext,ij_omp_end_ext
-                pk(ij,llm) = ptop + (.5*g)*rhodz(ij,llm)*(1.+theta(ij,l,2))
-             END DO
-             ! other layers
-             DO l = llm-1, 1, -1
-                !DIR$ SIMD
-                DO ij=ij_omp_begin_ext,ij_omp_end_ext         
-                   pk(ij,l) = pk(ij,l+1) + (.5*g)*(          &
-                        rhodz(ij,l)  *(1.+theta(ij,l,2)) +   &
-                        rhodz(ij,l+1)*(1.+theta(ij,l+1,2)) )
-                END DO
-             END DO
-             ! surface pressure (for diagnostics)
-             IF(caldyn_eta==eta_lag) THEN
-                DO ij=ij_omp_begin_ext,ij_omp_end_ext         
-                   ps(ij) = pk(ij,1) + (.5*g)*rhodz(ij,1)*(1.+theta(ij,l,2))
-                END DO
-             END IF
-          END SELECT
-
-       DO l = 1,llm
-          SELECT CASE(caldyn_thermo)
-          CASE(thermo_theta)
-             !DIR$ SIMD
-             DO ij=ij_omp_begin_ext,ij_omp_end_ext
-                p_ik = pk(ij,l)
-                exner_ik = cpp * (p_ik/preff) ** kappa
-                pk(ij,l) = exner_ik
-                ! specific volume v = kappa*theta*pi/p = dphi/g/rhodz
-                geopot(ij,l+1) = geopot(ij,l) + (g*kappa)*rhodz(ij,l)*theta(ij,l,1)*exner_ik/p_ik
-             ENDDO
-          CASE(thermo_entropy) ! theta is in fact entropy = cpp*log(theta/Treff) = cpp*log(T/Treff) - Rd*log(p/preff)
-             !DIR$ SIMD
-             DO ij=ij_omp_begin_ext,ij_omp_end_ext
-                p_ik = pk(ij,l)
-                temp_ik = Treff*exp((theta(ij,l,1) + Rd*log(p_ik/preff))/cpp)
-                pk(ij,l) = temp_ik
-                ! specific volume v = Rd*T/p = dphi/g/rhodz
-                geopot(ij,l+1) = geopot(ij,l) + (g*Rd)*rhodz(ij,l)*temp_ik/p_ik
-             ENDDO
-          CASE(thermo_moist) ! theta is moist pseudo-entropy per dry air mass
-             DO ij=ij_omp_begin_ext,ij_omp_end_ext
-                p_ik = pk(ij,l)
-                qv = theta(ij,l,2) ! water vaper mixing ratio = mv/md
-                Rmix = Rd+qv*Rv
-                chi = ( theta(ij,l,1) + Rmix*log(p_ik/preff) ) / (cpp + qv*cppv) ! log(T/Treff)
-                temp_ik = Treff*exp(chi)
-                pk(ij,l) = temp_ik
-                ! specific volume v = R*T/p = dphi/g/rhodz
-                ! R = (Rd + qv.Rv)/(1+qv)
-                geopot(ij,l+1) = geopot(ij,l) + g*Rmix*rhodz(ij,l)*temp_ik/(p_ik*(1+qv))
-             ENDDO
-          CASE DEFAULT
-             STOP
-          END SELECT
-       ENDDO
-    END IF
-
-    !ym flush geopot
-    !$OMP BARRIER
-
-    CALL trace_end("compute_geopot")
-
-  END SUBROUTINE compute_geopot
-
-  SUBROUTINE compute_caldyn_vert(u,theta,rhodz,convm, wflux,wwuu, dps,dtheta_rhodz,du)
-    REAL(rstd),INTENT(IN)  :: u(iim*3*jjm,llm)
-    REAL(rstd),INTENT(IN)  :: theta(iim*jjm,llm,nqdyn)
-    REAL(rstd),INTENT(IN)  :: rhodz(iim*jjm,llm)
-    REAL(rstd),INTENT(INOUT)  :: convm(iim*jjm,llm)  ! mass flux convergence
-
-    REAL(rstd),INTENT(INOUT) :: wflux(iim*jjm,llm+1) ! vertical mass flux (kg/m2/s)
-    REAL(rstd),INTENT(INOUT) :: wwuu(iim*3*jjm,llm+1)
-    REAL(rstd),INTENT(INOUT) :: du(iim*3*jjm,llm)
-    REAL(rstd),INTENT(INOUT) :: dtheta_rhodz(iim*jjm,llm,nqdyn)
-    REAL(rstd),INTENT(OUT) :: dps(iim*jjm)
-
-    ! temporary variable    
-    INTEGER :: i,j,ij,l,iq
-    REAL(rstd) :: p_ik, exner_ik
-    INTEGER    :: ij_omp_begin, ij_omp_end
-
-    CALL trace_start("compute_caldyn_vert")
-
-    CALL distrib_level(ij_end-ij_begin+1,ij_omp_begin,ij_omp_end)
-    ij_omp_begin=ij_omp_begin+ij_begin-1
-    ij_omp_end=ij_omp_end+ij_begin-1
-
-    !    REAL(rstd) :: wwuu(iim*3*jjm,llm+1) ! tmp var, don't know why but gain 30% on the whole code in opemp
-    ! need to be understood
-
-    !    wwuu=wwuu_out
-    CALL trace_start("compute_caldyn_vert")
-
-    !$OMP BARRIER   
-!!! cumulate mass flux convergence from top to bottom
-    !  IF (is_omp_level_master) THEN
-    DO  l = llm-1, 1, -1
-       !    IF (caldyn_conserv==energy) CALL test_message(req_qu) 
-
-!!$OMP DO SCHEDULE(STATIC) 
-       !DIR$ SIMD
-       DO ij=ij_omp_begin,ij_omp_end         
-          convm(ij,l) = convm(ij,l) + convm(ij,l+1)
-       ENDDO
-    ENDDO
-    !  ENDIF
-
-    !$OMP BARRIER
-    ! FLUSH on convm
-!!!!!!!!!!!!!!!!!!!!!!!!!
-
-    ! compute dps
-    IF (is_omp_first_level) THEN
-       !DIR$ SIMD
-       DO ij=ij_begin,ij_end         
-          ! dps/dt = -int(div flux)dz
-          dps(ij) = convm(ij,1)
-       ENDDO
-    ENDIF
-
-!!! Compute vertical mass flux (l=1,llm+1 done by caldyn_BC)
-    DO l=ll_beginp1,ll_end
-       !    IF (caldyn_conserv==energy) CALL test_message(req_qu) 
-       !DIR$ SIMD
-       DO ij=ij_begin,ij_end         
-          ! w = int(z,ztop,div(flux)dz) + B(eta)dps/dt
-          ! => w>0 for upward transport
-          wflux( ij, l ) = bp(l) * convm( ij, 1 ) - convm( ij, l ) 
-       ENDDO
-    ENDDO
-
-    !--> flush wflux  
-    !$OMP BARRIER
-
-    DO iq=1,nqdyn
-       DO l=ll_begin,ll_endm1
-       !DIR$ SIMD
-          DO ij=ij_begin,ij_end         
-             dtheta_rhodz(ij, l, iq) = dtheta_rhodz(ij, l, iq)  -   0.5 * &
-                  ( wflux(ij,l+1) * (theta(ij,l,iq) + theta(ij,l+1,iq)))
-          END DO
-       END DO
-       DO l=ll_beginp1,ll_end
-          !DIR$ SIMD
-          DO ij=ij_begin,ij_end         
-             dtheta_rhodz(ij, l, iq) = dtheta_rhodz(ij, l, iq)  +   0.5 * &
-                  ( wflux(ij,l) * (theta(ij,l-1,iq) + theta(ij,l,iq) ) )
-          END DO
-       END DO
-    END DO
-
-    ! Compute vertical transport
-    DO l=ll_beginp1,ll_end
-       !DIR$ SIMD
-       DO ij=ij_begin,ij_end         
-          wwuu(ij+u_right,l) = 0.5*( wflux(ij,l) + wflux(ij+t_right,l)) * (u(ij+u_right,l) - u(ij+u_right,l-1))
-          wwuu(ij+u_lup,l) = 0.5* ( wflux(ij,l) + wflux(ij+t_lup,l)) * (u(ij+u_lup,l) - u(ij+u_lup,l-1))
-          wwuu(ij+u_ldown,l) = 0.5*( wflux(ij,l) + wflux(ij+t_ldown,l)) * (u(ij+u_ldown,l) - u(ij+u_ldown,l-1))
-       ENDDO
-    ENDDO
-
-    !--> flush wwuu  
-    !$OMP BARRIER
-
-    ! Add vertical transport to du
-    DO l=ll_begin,ll_end
-       !DIR$ SIMD
-       DO ij=ij_begin,ij_end         
-          du(ij+u_right, l )   = du(ij+u_right,l)  - (wwuu(ij+u_right,l+1)+ wwuu(ij+u_right,l)) / (rhodz(ij,l)+rhodz(ij+t_right,l))
-          du(ij+u_lup, l )     = du(ij+u_lup,l)    - (wwuu(ij+u_lup,l+1)  + wwuu(ij+u_lup,l))   / (rhodz(ij,l)+rhodz(ij+t_lup,l))
-          du(ij+u_ldown, l )   = du(ij+u_ldown,l)  - (wwuu(ij+u_ldown,l+1)+ wwuu(ij+u_ldown,l)) / (rhodz(ij,l)+rhodz(ij+t_ldown,l))
-       ENDDO
-    ENDDO
-
-    !  DO l=ll_beginp1,ll_end
-    !!DIR$ SIMD
-    !      DO ij=ij_begin,ij_end         
-    !        wwuu_out(ij+u_right,l) = wwuu(ij+u_right,l)
-    !        wwuu_out(ij+u_lup,l)   = wwuu(ij+u_lup,l)
-    !        wwuu_out(ij+u_ldown,l) = wwuu(ij+u_ldown,l)
-    !     ENDDO
-    !   ENDDO
-
-    CALL trace_end("compute_caldyn_vert")
-
-  END SUBROUTINE compute_caldyn_vert
-
-  SUBROUTINE compute_caldyn_vert_NH(mass,geopot,W,wflux, du,dPhi,dW)
-    REAL(rstd),INTENT(IN) :: mass(iim*jjm,llm)
-    REAL(rstd),INTENT(IN) :: geopot(iim*jjm,llm+1)
-    REAL(rstd),INTENT(IN) :: W(iim*jjm,llm+1)
-    REAL(rstd),INTENT(IN) :: wflux(iim*jjm,llm+1)
-    REAL(rstd),INTENT(INOUT) :: du(iim*3*jjm,llm)
-    REAL(rstd),INTENT(INOUT) :: dPhi(iim*jjm,llm+1)
-    REAL(rstd),INTENT(INOUT) :: dW(iim*jjm,llm+1)
-    ! local arrays
-    REAL(rstd) :: eta_dot(iim*jjm) ! eta_dot in full layers
-    REAL(rstd) :: wcov(iim*jjm) ! covariant vertical momentum in full layers
-    REAL(rstd) :: W_etadot(iim*jjm,llm) ! vertical flux of vertical momentum
-    ! indices and temporary values
-    INTEGER    :: ij, l
-    REAL(rstd) :: wflux_ij, w_ij
-
-    CALL trace_start("compute_caldyn_vert_nh")
-
-    DO l=ll_begin,ll_end
-       ! compute the local arrays
-       !DIR$ SIMD
-       DO ij=ij_begin_ext,ij_end_ext
-          wflux_ij = .5*(wflux(ij,l)+wflux(ij,l+1))
-          w_ij = .5*(W(ij,l)+W(ij,l+1))/mass(ij,l)
-          W_etadot(ij,l) = wflux_ij*w_ij
-          eta_dot(ij) = wflux_ij / mass(ij,l)
-          wcov(ij) = w_ij*(geopot(ij,l+1)-geopot(ij,l))
-       ENDDO
-       ! add NH term to du
-      !DIR$ SIMD
-      DO ij=ij_begin,ij_end
-          du(ij+u_right,l) = du(ij+u_right,l) &
-               - .5*(wcov(ij+t_right)+wcov(ij)) &
-               *ne_right*(eta_dot(ij+t_right)-eta_dot(ij))
-          du(ij+u_lup,l) = du(ij+u_lup,l) &
-               - .5*(wcov(ij+t_lup)+wcov(ij)) &
-               *ne_lup*(eta_dot(ij+t_lup)-eta_dot(ij))
-          du(ij+u_ldown,l) = du(ij+u_ldown,l) &
-               - .5*(wcov(ij+t_ldown)+wcov(ij)) &
-               *ne_ldown*(eta_dot(ij+t_ldown)-eta_dot(ij))
-       END DO
-    ENDDO
-    ! add NH terms to dW, dPhi
-    ! FIXME : TODO top and bottom
-    DO l=ll_beginp1,ll_end ! inner interfaces only
-       !DIR$ SIMD
-       DO ij=ij_begin,ij_end
-          dPhi(ij,l) = dPhi(ij,l) - wflux(ij,l) &
-               * (geopot(ij,l+1)-geopot(ij,l-1))/(mass(ij,l-1)+mass(ij,l))
-       END DO
-    END DO
-    DO l=ll_begin,ll_end
-       !DIR$ SIMD
-       DO ij=ij_begin,ij_end
-          dW(ij,l+1) = dW(ij,l+1) + W_etadot(ij,l) ! update inner+top interfaces
-          dW(ij,l)   = dW(ij,l)   - W_etadot(ij,l) ! update bottom+inner interfaces
-       END DO
-    END DO
-    CALL trace_end("compute_caldyn_vert_nh")
-
-  END SUBROUTINE compute_caldyn_vert_NH
-END MODULE caldyn_kernels_base_mod
Index: codes/icosagcm/devel/src/dynamics/caldyn_kernels_hevi.F90
===================================================================
--- codes/icosagcm/devel/src/dynamics/caldyn_kernels_hevi.F90	(revision 536)
+++ codes/icosagcm/devel/src/dynamics/caldyn_kernels_hevi.F90	(revision 537)
@@ -638,9 +638,15 @@
     REAL(rstd),INTENT(INOUT) :: du(3*iim*jjm,llm)
     
-    REAL(rstd) :: berni(iim*jjm)  ! Bernoulli function
-    REAL(rstd) :: uu_right, uu_lup, uu_ldown
+    REAL(rstd) :: berni(iim*jjm,llm)  ! Bernoulli function
+    REAL(rstd) :: uu_right, uu_lup, uu_ldown, ke, uu
     INTEGER :: ij,l
 
     CALL trace_start("compute_caldyn_slow_hydro")
+
+#ifdef CPP_DYSL
+#define BERNI(ij,l) berni(ij,l)
+#include "../kernels/caldyn_slow_hydro.k90"
+#else
+#define BERNI(ij) berni(ij,1)
 
     DO l = ll_begin, ll_end
@@ -662,5 +668,5 @@
        !DIR$ SIMD
        DO ij=ij_begin,ij_end         
-          berni(ij) = &
+          BERNI(ij) = &
                1/(4*Ai(ij))*(le_de(ij+u_right)*u(ij+u_right,l)**2 +    &
                le_de(ij+u_rup)*u(ij+u_rup,l)**2 +          &
@@ -674,7 +680,7 @@
           !DIR$ SIMD
           DO ij=ij_begin,ij_end
-             du(ij+u_right,l) = ne_right*(berni(ij)-berni(ij+t_right))
-             du(ij+u_lup,l)   = ne_lup*(berni(ij)-berni(ij+t_lup))
-             du(ij+u_ldown,l) = ne_ldown*(berni(ij)-berni(ij+t_ldown))
+             du(ij+u_right,l) = ne_right*(BERNI(ij)-BERNI(ij+t_right))
+             du(ij+u_lup,l)   = ne_lup*(BERNI(ij)-BERNI(ij+t_lup))
+             du(ij+u_ldown,l) = ne_ldown*(BERNI(ij)-BERNI(ij+t_ldown))
           END DO
        ELSE
@@ -682,12 +688,14 @@
           DO ij=ij_begin,ij_end
              du(ij+u_right,l) = du(ij+u_right,l) + &
-                  ne_right*(berni(ij)-berni(ij+t_right))
+                  ne_right*(BERNI(ij)-BERNI(ij+t_right))
              du(ij+u_lup,l)   = du(ij+u_lup,l) + &
-                  ne_lup*(berni(ij)-berni(ij+t_lup))
+                  ne_lup*(BERNI(ij)-BERNI(ij+t_lup))
              du(ij+u_ldown,l) = du(ij+u_ldown,l) + &
-                  ne_ldown*(berni(ij)-berni(ij+t_ldown))
+                  ne_ldown*(BERNI(ij)-BERNI(ij+t_ldown))
           END DO
        END IF
     END DO
+#endif
+#undef BERNI
     CALL trace_end("compute_caldyn_slow_hydro")    
   END SUBROUTINE compute_caldyn_slow_hydro
