Index: palm/trunk/SOURCE/surface_mod.f90
===================================================================
--- palm/trunk/SOURCE/surface_mod.f90	(revision 3597)
+++ palm/trunk/SOURCE/surface_mod.f90	(revision 3634)
@@ -26,4 +26,7 @@
 ! -----------------
 ! $Id$
+! OpenACC port for SPEC
+! 
+! 3597 2018-12-04 08:40:18Z maronga
 ! Added pt_2m and renamed t_surf_10cm to pt_10cm. Removed some _eb variables as
 ! they are no longer used.
@@ -608,4 +611,12 @@
     END INTERFACE init_surface_arrays
 
+    INTERFACE enter_surface_arrays
+       MODULE PROCEDURE enter_surface_arrays
+    END INTERFACE
+
+    INTERFACE exit_surface_arrays
+       MODULE PROCEDURE exit_surface_arrays
+    END INTERFACE
+
     INTERFACE surface_rrd_local
        MODULE PROCEDURE surface_rrd_local
@@ -634,6 +645,7 @@
 !-- Public subroutines and functions
     PUBLIC get_topography_top_index, get_topography_top_index_ji, init_bc,     &
-           init_surfaces, init_surface_arrays, surface_rrd_local,              & 
-           surface_restore_elements, surface_wrd_local, surface_last_actions
+           init_surfaces, init_surface_arrays, enter_surface_arrays,           &
+           exit_surface_arrays, surface_rrd_local, surface_restore_elements,   &
+           surface_wrd_local, surface_last_actions
 
 
@@ -1084,4 +1096,92 @@
 
     END SUBROUTINE init_surface_arrays
+
+
+!------------------------------------------------------------------------------!
+! Description:
+! ------------
+!> Enter horizontal and vertical surfaces.
+!------------------------------------------------------------------------------!
+    SUBROUTINE enter_surface_arrays
+
+       IMPLICIT NONE
+
+       INTEGER(iwp) ::  l     !<
+       
+       !$ACC ENTER DATA &
+       !$ACC COPYIN(surf_def_h(0:2)) &
+       !$ACC COPYIN(surf_def_v(0:3)) &
+       !$ACC COPYIN(surf_lsm_h) &
+       !$ACC COPYIN(surf_lsm_v(0:3)) &
+       !$ACC COPYIN(surf_usm_h) &
+       !$ACC COPYIN(surf_usm_v(0:3))
+
+       ! Copy data in surf_def_h(0:2)
+       DO  l = 0, 1
+          CALL enter_surface_attributes_h(surf_def_h(l))
+       ENDDO
+       CALL enter_surface_attributes_h_top(surf_def_h(2))
+       ! Copy data in surf_def_v(0:3)
+       DO  l = 0, 3
+          CALL enter_surface_attributes_v(surf_def_v(l))
+       ENDDO
+       ! Copy data in surf_lsm_h
+       CALL enter_surface_attributes_h(surf_lsm_h)
+       ! Copy data in surf_lsm_v(0:3)
+       DO  l = 0, 3
+          CALL enter_surface_attributes_v(surf_lsm_v(l))
+       ENDDO
+       ! Copy data in surf_usm_h
+       CALL enter_surface_attributes_h(surf_usm_h)
+       ! Copy data in surf_usm_v(0:3)
+       DO  l = 0, 3
+          CALL enter_surface_attributes_v(surf_usm_v(l))
+       ENDDO
+
+    END SUBROUTINE enter_surface_arrays
+
+
+!------------------------------------------------------------------------------!
+! Description:
+! ------------
+!> Exit horizontal and vertical surfaces.
+!------------------------------------------------------------------------------!
+    SUBROUTINE exit_surface_arrays
+
+       IMPLICIT NONE
+
+       INTEGER(iwp) ::  l     !<
+       
+       ! Delete data in surf_def_h(0:2)
+       DO  l = 0, 1
+          CALL exit_surface_attributes_h(surf_def_h(l))
+       ENDDO
+       CALL exit_surface_attributes_h(surf_def_h(2))
+       ! Delete data in surf_def_v(0:3)
+       DO  l = 0, 3
+          CALL exit_surface_attributes_v(surf_def_v(l))
+       ENDDO
+       ! Delete data in surf_lsm_h
+       CALL exit_surface_attributes_h(surf_lsm_h)
+       ! Delete data in surf_lsm_v(0:3)
+       DO  l = 0, 3
+          CALL exit_surface_attributes_v(surf_lsm_v(l))
+       ENDDO
+       ! Delete data in surf_usm_h
+       CALL exit_surface_attributes_h(surf_usm_h)
+       ! Delete data in surf_usm_v(0:3)
+       DO  l = 0, 3
+          CALL exit_surface_attributes_v(surf_usm_v(l))
+       ENDDO
+
+       !$ACC EXIT DATA &
+       !$ACC DELETE(surf_def_h(0:2)) &
+       !$ACC DELETE(surf_def_v(0:3)) &
+       !$ACC DELETE(surf_lsm_h) &
+       !$ACC DELETE(surf_lsm_v(0:3)) &
+       !$ACC DELETE(surf_usm_h) &
+       !$ACC DELETE(surf_usm_v(0:3))
+
+    END SUBROUTINE exit_surface_arrays
 
 
@@ -1328,4 +1428,86 @@
 ! Description:
 ! ------------
+!> Exit memory for upward and downward-facing horizontal surface types,
+!> except for top fluxes.
+!------------------------------------------------------------------------------!
+    SUBROUTINE exit_surface_attributes_h( surfaces )
+
+       IMPLICIT NONE
+   
+       TYPE(surf_type) ::  surfaces  !< respective surface type
+   
+       !$ACC EXIT DATA &
+       !$ACC DELETE(surfaces%start_index(nys:nyn,nxl:nxr)) &
+       !$ACC DELETE(surfaces%end_index(nys:nyn,nxl:nxr)) &
+       !$ACC DELETE(surfaces%i(1:surfaces%ns)) &
+       !$ACC DELETE(surfaces%j(1:surfaces%ns)) &
+       !$ACC DELETE(surfaces%k(1:surfaces%ns)) &
+       !$ACC DELETE(surfaces%z_mo(1:surfaces%ns)) &
+       !$ACC DELETE(surfaces%uvw_abs(1:surfaces%ns)) &
+       !$ACC DELETE(surfaces%z0(1:surfaces%ns)) &
+       !$ACC COPYOUT(surfaces%us(1:surfaces%ns)) &
+       !$ACC COPYOUT(surfaces%ol(1:surfaces%ns)) &
+       !$ACC DELETE(surfaces%rib(1:surfaces%ns)) &
+       !$ACC COPYOUT(surfaces%usws(1:surfaces%ns)) &
+       !$ACC COPYOUT(surfaces%vsws(1:surfaces%ns)) &
+       !$ACC COPYOUT(surfaces%ts(1:surfaces%ns)) &
+       !$ACC COPYOUT(surfaces%shf(1:surfaces%ns)) &
+       !$ACC DELETE(surfaces%pt_surface(1:surfaces%ns)) &
+       !$ACC DELETE(surfaces%pt1(1:surfaces%ns)) &
+       !$ACC DELETE(surfaces%qv1(1:surfaces%ns))
+
+       IF ( .NOT. constant_diffusion )  THEN
+          !$ACC EXIT DATA &
+          !$ACC DELETE(surfaces%u_0(1:surfaces%ns)) &
+          !$ACC DELETE(surfaces%v_0(1:surfaces%ns))
+       ENDIF
+   
+    END SUBROUTINE exit_surface_attributes_h
+
+
+!------------------------------------------------------------------------------!
+! Description:
+! ------------
+!> Enter memory for upward and downward-facing horizontal surface types,
+!> except for top fluxes.
+!------------------------------------------------------------------------------!
+    SUBROUTINE enter_surface_attributes_h( surfaces )
+
+       IMPLICIT NONE
+
+       TYPE(surf_type) ::  surfaces  !< respective surface type
+
+       !$ACC ENTER DATA &
+       !$ACC COPYIN(surfaces%start_index(nys:nyn,nxl:nxr)) &
+       !$ACC COPYIN(surfaces%end_index(nys:nyn,nxl:nxr)) &
+       !$ACC COPYIN(surfaces%i(1:surfaces%ns)) &
+       !$ACC COPYIN(surfaces%j(1:surfaces%ns)) &
+       !$ACC COPYIN(surfaces%k(1:surfaces%ns)) &
+       !$ACC COPYIN(surfaces%z_mo(1:surfaces%ns)) &
+       !$ACC COPYIN(surfaces%uvw_abs(1:surfaces%ns)) &
+       !$ACC COPYIN(surfaces%z0(1:surfaces%ns)) &
+       !$ACC COPYIN(surfaces%us(1:surfaces%ns)) &
+       !$ACC COPYIN(surfaces%ol(1:surfaces%ns)) &
+       !$ACC COPYIN(surfaces%rib(1:surfaces%ns)) &
+       !$ACC COPYIN(surfaces%usws(1:surfaces%ns)) &
+       !$ACC COPYIN(surfaces%vsws(1:surfaces%ns)) &
+       !$ACC COPYIN(surfaces%ts(1:surfaces%ns)) &
+       !$ACC COPYIN(surfaces%shf(1:surfaces%ns)) &
+       !$ACC COPYIN(surfaces%pt1(1:surfaces%ns)) &
+       !$ACC COPYIN(surfaces%qv1(1:surfaces%ns)) &
+       !$ACC COPYIN(surfaces%pt_surface(1:surfaces%ns))
+
+       IF ( .NOT. constant_diffusion )  THEN
+          !$ACC ENTER DATA &
+          !$ACC COPYIN(surfaces%u_0(1:surfaces%ns)) &
+          !$ACC COPYIN(surfaces%v_0(1:surfaces%ns))
+       ENDIF
+
+    END SUBROUTINE enter_surface_attributes_h
+
+
+!------------------------------------------------------------------------------!
+! Description:
+! ------------
 !> Deallocating memory for model-top fluxes  
 !------------------------------------------------------------------------------!
@@ -1460,4 +1642,64 @@
 
     END SUBROUTINE allocate_surface_attributes_h_top
+
+
+!------------------------------------------------------------------------------!
+! Description:
+! ------------
+!> Exit memory for model-top fluxes.
+!------------------------------------------------------------------------------!
+    SUBROUTINE exit_surface_attributes_h_top( surfaces )
+
+       IMPLICIT NONE
+   
+       TYPE(surf_type) ::  surfaces  !< respective surface type
+   
+       !$ACC EXIT DATA &
+       !$ACC DELETE(surfaces%start_index(nys:nyn,nxl:nxr)) &
+       !$ACC DELETE(surfaces%end_index(nys:nyn,nxl:nxr)) &
+       !$ACC DELETE(surfaces%i(1:surfaces%ns)) &
+       !$ACC DELETE(surfaces%j(1:surfaces%ns)) &
+       !$ACC DELETE(surfaces%k(1:surfaces%ns)) &
+       !$ACC DELETE(surfaces%usws(1:surfaces%ns)) &
+       !$ACC DELETE(surfaces%vsws(1:surfaces%ns)) &
+       !$ACC DELETE(surfaces%shf(1:surfaces%ns))
+
+       IF ( .NOT. constant_diffusion )  THEN
+          !$ACC EXIT DATA &
+          !$ACC DELETE(surfaces%u_0(1:surfaces%ns)) &
+          !$ACC DELETE(surfaces%v_0(1:surfaces%ns))
+       ENDIF
+   
+    END SUBROUTINE exit_surface_attributes_h_top
+
+
+!------------------------------------------------------------------------------!
+! Description:
+! ------------
+!> Enter memory for model-top fluxes.
+!------------------------------------------------------------------------------!
+    SUBROUTINE enter_surface_attributes_h_top( surfaces )
+
+       IMPLICIT NONE
+
+       TYPE(surf_type) ::  surfaces  !< respective surface type
+
+       !$ACC ENTER DATA &
+       !$ACC COPYIN(surfaces%start_index(nys:nyn,nxl:nxr)) &
+       !$ACC COPYIN(surfaces%end_index(nys:nyn,nxl:nxr)) &
+       !$ACC COPYIN(surfaces%i(1:surfaces%ns)) &
+       !$ACC COPYIN(surfaces%j(1:surfaces%ns)) &
+       !$ACC COPYIN(surfaces%k(1:surfaces%ns)) &
+       !$ACC COPYIN(surfaces%usws(1:surfaces%ns)) &
+       !$ACC COPYIN(surfaces%vsws(1:surfaces%ns)) &
+       !$ACC COPYIN(surfaces%shf(1:surfaces%ns))
+
+       IF ( .NOT. constant_diffusion )  THEN
+          !$ACC ENTER DATA &
+          !$ACC COPYIN(surfaces%u_0(1:surfaces%ns)) &
+          !$ACC COPYIN(surfaces%v_0(1:surfaces%ns))
+       ENDIF
+
+    END SUBROUTINE enter_surface_attributes_h_top
 
 
@@ -1703,4 +1945,66 @@
 
     END SUBROUTINE allocate_surface_attributes_v
+
+
+!------------------------------------------------------------------------------!
+! Description:
+! ------------
+!> Exit memory for vertical surface types. 
+!------------------------------------------------------------------------------!
+    SUBROUTINE exit_surface_attributes_v( surfaces )
+
+       IMPLICIT NONE
+
+       TYPE(surf_type) ::  surfaces  !< respective surface type
+
+       !$ACC EXIT DATA &
+       !$ACC DELETE(surfaces%start_index(nys:nyn,nxl:nxr)) &
+       !$ACC DELETE(surfaces%end_index(nys:nyn,nxl:nxr)) &
+       !$ACC DELETE(surfaces%i(1:surfaces%ns)) &
+       !$ACC DELETE(surfaces%j(1:surfaces%ns)) &
+       !$ACC DELETE(surfaces%k(1:surfaces%ns)) &
+       !$ACC DELETE(surfaces%uvw_abs(1:surfaces%ns)) &
+       !$ACC DELETE(surfaces%z0(1:surfaces%ns)) &
+       !$ACC DELETE(surfaces%rib(1:surfaces%ns)) &
+       !$ACC DELETE(surfaces%mom_flux_uv(1:surfaces%ns)) &
+       !$ACC DELETE(surfaces%mom_flux_w(1:surfaces%ns)) &
+       !$ACC DELETE(surfaces%mom_flux_tke(0:1,1:surfaces%ns)) &
+       !$ACC DELETE(surfaces%ts(1:surfaces%ns)) &
+       !$ACC DELETE(surfaces%shf(1:surfaces%ns)) &
+       !$ACC DELETE(surfaces%pt1(1:surfaces%ns)) &
+       !$ACC DELETE(surfaces%qv1(1:surfaces%ns))
+
+    END SUBROUTINE exit_surface_attributes_v
+
+
+!------------------------------------------------------------------------------!
+! Description:
+! ------------
+!> Enter memory for vertical surface types. 
+!------------------------------------------------------------------------------!
+    SUBROUTINE enter_surface_attributes_v( surfaces )
+   
+       IMPLICIT NONE
+   
+       TYPE(surf_type) ::  surfaces  !< respective surface type
+   
+       !$ACC ENTER DATA &
+       !$ACC COPYIN(surfaces%start_index(nys:nyn,nxl:nxr)) &
+       !$ACC COPYIN(surfaces%end_index(nys:nyn,nxl:nxr)) &
+       !$ACC COPYIN(surfaces%i(1:surfaces%ns)) &
+       !$ACC COPYIN(surfaces%j(1:surfaces%ns)) &
+       !$ACC COPYIN(surfaces%k(1:surfaces%ns)) &
+       !$ACC COPYIN(surfaces%uvw_abs(1:surfaces%ns)) &
+       !$ACC COPYIN(surfaces%z0(1:surfaces%ns)) &
+       !$ACC COPYIN(surfaces%rib(1:surfaces%ns)) &
+       !$ACC COPYIN(surfaces%mom_flux_uv(1:surfaces%ns)) &
+       !$ACC COPYIN(surfaces%mom_flux_w(1:surfaces%ns)) &
+       !$ACC COPYIN(surfaces%mom_flux_tke(0:1,1:surfaces%ns)) &
+       !$ACC COPYIN(surfaces%ts(1:surfaces%ns)) &
+       !$ACC COPYIN(surfaces%shf(1:surfaces%ns)) &
+       !$ACC COPYIN(surfaces%pt1(1:surfaces%ns)) &
+       !$ACC COPYIN(surfaces%qv1(1:surfaces%ns))
+   
+    END SUBROUTINE enter_surface_attributes_v
 
 
