Index: /palm/trunk/SOURCE/Makefile
===================================================================
--- /palm/trunk/SOURCE/Makefile	(revision 2231)
+++ /palm/trunk/SOURCE/Makefile	(revision 2232)
@@ -20,5 +20,6 @@
 # Current revisions:
 # ------------------
-# 
+# +dependencies for surface_mod
+# -wall_fluxes
 # 
 # Former revisions:
@@ -351,5 +352,5 @@
 	read_3d_binary.f90 read_var_list.f90 run_control.f90 \
 	set_slicer_attributes_dvrp.f90 singleton_mod.f90 sor.f90 spectra_mod.f90 \
-	subsidence_mod.f90 sum_up_3d_data.f90 \
+	subsidence_mod.f90 sum_up_3d_data.f90 surface_mod.f90 \
 	surface_coupler.f90 surface_layer_fluxes_mod.f90 swap_timelevel.f90 temperton_fft_mod.f90 \
 	time_integration.f90 time_to_string.f90 timestep.f90 \
@@ -369,5 +370,5 @@
 	user_lpm_init.f90 user_lpm_set_attributes.f90 user_module.f90 \
 	user_parin.f90 user_read_restart_data.f90 \
-	user_spectra.f90 user_statistics.f90 virtual_flight_mod.f90 wall_fluxes.f90 \
+	user_spectra.f90 user_statistics.f90 virtual_flight_mod.f90 \
 	wind_turbine_model_mod.f90 write_3d_binary.f90 write_var_list.f90
 
@@ -413,7 +414,7 @@
 advec_w_pw.o: modules.o mod_kinds.o
 advec_w_up.o: modules.o mod_kinds.o
-average_3d_data.o: modules.o cpulog_mod.o mod_kinds.o land_surface_model_mod.o \
+average_3d_data.o: modules.o cpulog_mod.o mod_kinds.o exchange_horiz_2d.o land_surface_model_mod.o \
 	radiation_model_mod.o urban_surface_mod.o
-boundary_conds.o: modules.o mod_kinds.o pmc_interface_mod.o
+boundary_conds.o: modules.o mod_kinds.o pmc_interface_mod.o surface_mod.o
 buoyancy.o: modules.o mod_kinds.o
 calc_mean_profile.o: modules.o mod_kinds.o
@@ -445,23 +446,23 @@
 data_output_2d.o: modules.o cpulog_mod.o mod_kinds.o mod_particle_attributes.o \
    netcdf_interface_mod.o land_surface_model_mod.o radiation_model_mod.o \
-   urban_surface_mod.o
+   surface_mod.o urban_surface_mod.o
 data_output_3d.o: modules.o cpulog_mod.o mod_kinds.o mod_particle_attributes.o \
    netcdf_interface_mod.o land_surface_model_mod.o urban_surface_mod.o
 diffusion_e.o: modules.o mod_kinds.o microphysics_mod.o \
-   mod_particle_attributes.o
-diffusion_s.o: modules.o mod_kinds.o
-diffusion_u.o: modules.o mod_kinds.o wall_fluxes.o
-diffusion_v.o: modules.o mod_kinds.o wall_fluxes.o
-diffusion_w.o: modules.o mod_kinds.o wall_fluxes.o
-diffusivities.o: modules.o mod_kinds.o
+   mod_particle_attributes.o surface_mod.o
+diffusion_s.o: modules.o mod_kinds.o surface_mod.o
+diffusion_u.o: modules.o mod_kinds.o surface_mod.o
+diffusion_v.o: modules.o mod_kinds.o surface_mod.o
+diffusion_w.o: modules.o mod_kinds.o surface_mod.o
+diffusivities.o: modules.o mod_kinds.o surface_mod.o
 disturb_field.o: modules.o cpulog_mod.o mod_kinds.o random_function_mod.o \
                  random_generator_parallel_mod.o
-disturb_heatflux.o: modules.o cpulog_mod.o mod_kinds.o
-eqn_state_seawater.o: modules.o mod_kinds.o
+disturb_heatflux.o: modules.o cpulog_mod.o mod_kinds.o random_generator_parallel_mod.o surface_mod.o
+eqn_state_seawater.o: modules.o mod_kinds.o surface_mod.o
 exchange_horiz.o: modules.o cpulog_mod.o mod_kinds.o
 exchange_horiz_2d.o: modules.o cpulog_mod.o mod_kinds.o pmc_interface_mod.o
 fft_xy_mod.o: modules.o mod_kinds.o singleton_mod.o temperton_fft_mod.o
 flow_statistics.o: modules.o cpulog_mod.o mod_kinds.o land_surface_model_mod.o \
-   netcdf_interface_mod.o radiation_model_mod.o
+   netcdf_interface_mod.o radiation_model_mod.o surface_mod.o
 global_min_max.o: modules.o mod_kinds.o
 header.o: modules.o cpulog_mod.o mod_kinds.o netcdf_interface_mod.o land_surface_model_mod.o\
@@ -470,14 +471,14 @@
 inflow_turbulence.o: modules.o cpulog_mod.o mod_kinds.o
 init_1d_model.o: modules.o mod_kinds.o
-init_3d_model.o: modules.o mod_kinds.o advec_ws.o cpulog_mod.o land_surface_model_mod.o \
+init_3d_model.o: modules.o mod_kinds.o advec_ws.o cpulog_mod.o disturb_heatflux.o land_surface_model_mod.o \
    lpm_init.o ls_forcing_mod.o netcdf_interface_mod.o plant_canopy_model_mod.o \
    radiation_model_mod.o random_function_mod.o random_generator_parallel_mod.o \
-   surface_layer_fluxes_mod.o microphysics_mod.o mod_particle_attributes.o \
-   urban_surface_mod.o virtual_flight_mod.o wind_turbine_model_mod.o 
+   microphysics_mod.o mod_particle_attributes.o surface_layer_fluxes_mod.o \
+   urban_surface_mod.o virtual_flight_mod.o surface_mod.o wind_turbine_model_mod.o 
 init_advec.o: modules.o mod_kinds.o
 init_cloud_physics.o: modules.o mod_kinds.o
 init_coupling.o: modules.o mod_kinds.o
 init_dvrp.o: modules.o mod_kinds.o
-init_grid.o: modules.o mod_kinds.o advec_ws.o
+init_grid.o: modules.o mod_kinds.o advec_ws.o netcdf_interface_mod.o surface_mod.o
 init_masks.o: modules.o mod_kinds.o netcdf_interface_mod.o
 init_ocean.o: modules.o eqn_state_seawater.o mod_kinds.o
@@ -487,5 +488,5 @@
 init_slope.o: modules.o mod_kinds.o
 interaction_droplets_ptq.o: modules.o mod_kinds.o
-land_surface_model_mod.o: modules.o mod_kinds.o radiation_model_mod.o
+land_surface_model_mod.o: modules.o mod_kinds.o radiation_model_mod.o surface_mod.o
 local_stop.o: modules.o mod_kinds.o pmc_interface_mod.o
 local_tremain.o: modules.o cpulog_mod.o mod_kinds.o
@@ -519,5 +520,5 @@
 ls_forcing_mod.o: modules.o cpulog_mod.o mod_kinds.o
 message.o: modules.o mod_kinds.o pmc_interface_mod.o
-microphysics_mod.o: modules.o cpulog_mod.o mod_kinds.o
+microphysics_mod.o: modules.o cpulog_mod.o mod_kinds.o surface_mod.o
 modules.o: modules.f90 mod_kinds.o
 mod_kinds.o: mod_kinds.f90
@@ -546,7 +547,8 @@
 poismg_noopt.o: modules.o cpulog_mod.o mod_kinds.o
 posix_calls_from_fortran.o: posix_calls_from_fortran.f90
-pres.o: modules.o cpulog_mod.o mod_kinds.o poisfft_mod.o poismg_mod.o pmc_interface_mod.o
+pres.o: modules.o cpulog_mod.o mod_kinds.o poisfft_mod.o poismg_mod.o pmc_interface_mod.o \
+   surface_mod.o
 print_1d.o: modules.o cpulog_mod.o mod_kinds.o
-production_e.o: modules.o mod_kinds.o wall_fluxes.o
+production_e.o: modules.o mod_kinds.o surface_mod.o
 prognostic_equations.o: modules.o advec_s_pw.o advec_s_up.o advec_s_bc.o advec_u_pw.o \
 	advec_u_up.o advec_v_pw.o advec_v_up.o advec_w_pw.o advec_w_up.o \
@@ -555,5 +557,5 @@
 	eqn_state_seawater.o mod_kinds.o microphysics_mod.o \
 	nudging_mod.o plant_canopy_model_mod.o production_e.o radiation_model_mod.o \
-	subsidence_mod.o urban_surface_mod.o user_actions.o wind_turbine_model_mod.o
+	subsidence_mod.o surface_mod.o user_actions.o wind_turbine_model_mod.o
 progress_bar_mod.o: modules.o mod_kinds.o
 radiation_model_mod.o : modules.o mod_particle_attributes.o microphysics_mod.o
@@ -563,5 +565,5 @@
 read_3d_binary.o: modules.o cpulog_mod.o mod_kinds.o \
    land_surface_model_mod.o radiation_model_mod.o random_function_mod.o random_generator_parallel_mod.o \
-   spectra_mod.o
+   spectra_mod.o surface_mod.o
 read_var_list.o: modules.o mod_kinds.o netcdf_interface_mod.o plant_canopy_model_mod.o \
    spectra_mod.o microphysics_mod.o urban_surface_mod.o virtual_flight_mod.o
@@ -573,16 +575,17 @@
 subsidence_mod.o: modules.o mod_kinds.o
 sum_up_3d_data.o: modules.o cpulog_mod.o mod_kinds.o land_surface_model_mod.o \
-                  radiation_model_mod.o urban_surface_mod.o
+                  radiation_model_mod.o surface_mod.o urban_surface_mod.o
 surface_coupler.o: modules.o cpulog_mod.o mod_kinds.o
-surface_layer_fluxes_mod.o: modules.o mod_kinds.o land_surface_model_mod.o \
-	urban_surface_mod.o
+surface_layer_fluxes_mod.o: modules.o mod_kinds.o exchange_horiz_2d.o land_surface_model_mod.o \
+	urban_surface_mod.o surface_mod.o
+surface_mod.o: modules.o mod_kinds.o init_pegrid.o
 swap_timelevel.o: modules.o cpulog_mod.o mod_kinds.o land_surface_model_mod.o \
    pmc_interface_mod.o urban_surface_mod.o
 temperton_fft_mod.o: modules.o mod_kinds.o
 time_integration.o: modules.o advec_ws.o buoyancy.o calc_mean_profile.o \
-	cpulog_mod.o data_output_flight.o interaction_droplets_ptq.o land_surface_model_mod.o \
+	cpulog_mod.o data_output_flight.o disturb_heatflux.o interaction_droplets_ptq.o land_surface_model_mod.o \
 	ls_forcing_mod.o mod_kinds.o nudging_mod.o pmc_interface_mod.o production_e.o \
 	prognostic_equations.o progress_bar_mod.o radiation_model_mod.o \
-	spectra_mod.o user_actions.o surface_layer_fluxes_mod.o microphysics_mod.o \
+	spectra_mod.o user_actions.o microphysics_mod.o surface_layer_fluxes_mod.o surface_mod.o \
 	urban_surface_mod.o virtual_flight_mod.o wind_turbine_model_mod.o
 time_to_string.o: mod_kinds.o
@@ -600,5 +603,5 @@
    netcdf_interface_mod.o
 user_check_parameters.o: modules.o mod_kinds.o user_module.o
-user_data_output_2d.o: modules.o mod_kinds.o user_module.o
+user_data_output_2d.o: modules.o mod_kinds.o surface_mod.o user_module.o
 user_data_output_3d.o: modules.o mod_kinds.o user_module.o
 user_data_output_mask.o: modules.o mod_kinds.o user_module.o
@@ -609,11 +612,11 @@
 user_header.o: modules.o mod_kinds.o user_module.o
 user_init.o: modules.o mod_kinds.o netcdf_interface_mod.o user_module.o
-user_init_3d_model.o: modules.o mod_kinds.o user_module.o
+user_init_3d_model.o: modules.o mod_kinds.o surface_mod.o user_module.o
 user_init_flight.o: modules.o mod_kinds.o netcdf_interface_mod.o user_module.o
 user_init_grid.o: modules.o mod_kinds.o user_module.o
-user_init_land_surface.o: modules.o mod_kinds.o user_module.o land_surface_model_mod.o netcdf_interface_mod.o
+user_init_land_surface.o: modules.o mod_kinds.o surface_mod.o user_module.o land_surface_model_mod.o netcdf_interface_mod.o
 user_init_plant_canopy.o: modules.o mod_kinds.o user_module.o plant_canopy_model_mod.o
 user_init_radiation.o: modules.o mod_kinds.o user_module.o radiation_model_mod.o
-user_init_urban_surface.o: modules.o mod_kinds.o user_module.o urban_surface_mod.o
+user_init_urban_surface.o: modules.o mod_kinds.o surface_mod.o user_module.o urban_surface_mod.o
 user_last_actions.o: modules.o mod_kinds.o user_module.o
 user_lpm_advec.o: modules.o mod_kinds.o user_module.o
@@ -626,9 +629,8 @@
 user_statistics.o: modules.o mod_kinds.o netcdf_interface_mod.o user_module.o
 virtual_flight_mod.o: modules.o cpulog_mod.o mod_kinds.o netcdf_interface_mod.o user_init_flight.o user_flight.o
-wall_fluxes.o: modules.o mod_kinds.o
 wind_turbine_model_mod.o: modules.o cpulog_mod.o mod_kinds.o
 write_3d_binary.o: modules.o cpulog_mod.o mod_kinds.o \
 	radiation_model_mod.o random_function_mod.o random_generator_parallel_mod.o \
-	spectra_mod.o
+	spectra_mod.o surface_mod.o
 write_var_list.o: modules.o mod_kinds.o netcdf_interface_mod.o plant_canopy_model_mod.o\
    spectra_mod.o microphysics_mod.o urban_surface_mod.o virtual_flight_mod.o
Index: /palm/trunk/SOURCE/advec_s_pw.f90
===================================================================
--- /palm/trunk/SOURCE/advec_s_pw.f90	(revision 2231)
+++ /palm/trunk/SOURCE/advec_s_pw.f90	(revision 2232)
@@ -20,5 +20,5 @@
 ! Current revisions:
 ! -----------------
-! 
+! topography representation via flags
 ! 
 ! Former revisions:
@@ -104,6 +104,6 @@
 
        USE indices,                                                            &
-           ONLY:  nxl, nxlg, nxr, nxrg, nyn, nyng, nys, nysg, nzb, nzb_s_inner,&
-                  nzt
+           ONLY:  nxl, nxlg, nxr, nxrg, nyn, nyng, nys, nysg, nzb,             &
+                  nzt, wall_flags_0
 
        USE kinds
@@ -125,7 +125,7 @@
        DO  i = nxl, nxr
           DO  j = nys, nyn
-             DO  k = nzb_s_inner(j,i)+1, nzt
-                tend(k,j,i) = tend(k,j,i)                                      &
-              -0.5_wp * ( ( u(k,j,i+1) - u_gtrans ) * ( sk(k,j,i+1) - sk(k,j,i) ) &
+             DO  k = nzb+1, nzt
+                tend(k,j,i) = tend(k,j,i) +                                       &
+            ( -0.5_wp * ( ( u(k,j,i+1) - u_gtrans ) * ( sk(k,j,i+1) - sk(k,j,i) ) &
                         - ( u(k,j,i)   - u_gtrans ) * ( sk(k,j,i-1) - sk(k,j,i) ) &
                         ) * ddx                                                   &
@@ -135,5 +135,6 @@
               -         (   w(k,j,i)                * ( sk(k+1,j,i) - sk(k,j,i) ) &
                         -   w(k-1,j,i)              * ( sk(k-1,j,i) - sk(k,j,i) ) &
-                        ) * dd2zu(k)
+                        ) * dd2zu(k)                                              &
+            ) * MERGE( 1.0_wp, 0.0_wp, BTEST( wall_flags_0(k,j,i), 0 ) )
              ENDDO
           ENDDO
@@ -160,5 +161,5 @@
 
        USE indices,                                                            &
-           ONLY:  nxlg, nxrg, nyng, nysg, nzb, nzb_s_inner, nzt
+           ONLY:  nxlg, nxrg, nyng, nysg, nzb, nzt, wall_flags_0
 
        USE kinds
@@ -178,7 +179,7 @@
 
 
-       DO  k = nzb_s_inner(j,i)+1, nzt
-          tend(k,j,i) = tend(k,j,i)                                            &
-              -0.5_wp * ( ( u(k,j,i+1) - u_gtrans ) * ( sk(k,j,i+1) - sk(k,j,i) ) &
+       DO  k = nzb+1, nzt
+          tend(k,j,i) = tend(k,j,i) +                                             &
+            ( -0.5_wp * ( ( u(k,j,i+1) - u_gtrans ) * ( sk(k,j,i+1) - sk(k,j,i) ) &
                         - ( u(k,j,i)   - u_gtrans ) * ( sk(k,j,i-1) - sk(k,j,i) ) &
                         ) * ddx                                                   &
@@ -188,5 +189,6 @@
               -         (   w(k,j,i)                * ( sk(k+1,j,i) - sk(k,j,i) ) &
                         -   w(k-1,j,i)              * ( sk(k-1,j,i) - sk(k,j,i) ) &
-                        ) * dd2zu(k)
+                        ) * dd2zu(k)                                              &
+            ) * MERGE( 1.0_wp, 0.0_wp, BTEST( wall_flags_0(k,j,i), 0 ) )
        ENDDO
 
Index: /palm/trunk/SOURCE/advec_s_up.f90
===================================================================
--- /palm/trunk/SOURCE/advec_s_up.f90	(revision 2231)
+++ /palm/trunk/SOURCE/advec_s_up.f90	(revision 2232)
@@ -20,5 +20,5 @@
 ! Current revisions:
 ! -----------------
-! 
+! topography representation via flags
 ! 
 ! Former revisions:
@@ -104,6 +104,6 @@
 
        USE indices,                                                            &
-           ONLY:  nxl, nxlg, nxr, nxrg, nyn, nyng, nys, nysg, nzb, nzb_s_inner,&
-                  nzt
+           ONLY:  nxl, nxlg, nxr, nxrg, nyn, nyng, nys, nysg, nzb, nzt,        &
+                  wall_flags_0
 
        USE kinds
@@ -128,5 +128,5 @@
        DO  i = nxl, nxr
           DO  j = nys, nyn
-             DO  k = nzb_s_inner(j,i)+1, nzt
+             DO  k = nzb+1, nzt
 !
 !--             x-direction
@@ -134,8 +134,12 @@
                 IF ( ukomp > 0.0_wp )  THEN
                    tend(k,j,i) = tend(k,j,i) - ukomp *                         &
-                                         ( sk(k,j,i) - sk(k,j,i-1) ) * ddx
+                                         ( sk(k,j,i) - sk(k,j,i-1) ) * ddx     &
+                                      * MERGE( 1.0_wp, 0.0_wp,                 &
+                                               BTEST( wall_flags_0(k,j,i), 0 ) )
                 ELSE
                    tend(k,j,i) = tend(k,j,i) - ukomp *                         &
-                                         ( sk(k,j,i+1) - sk(k,j,i) ) * ddx
+                                         ( sk(k,j,i+1) - sk(k,j,i) ) * ddx     &
+                                      * MERGE( 1.0_wp, 0.0_wp,                 &
+                                               BTEST( wall_flags_0(k,j,i), 0 ) )
                 ENDIF
 !
@@ -144,8 +148,12 @@
                 IF ( vkomp > 0.0_wp )  THEN
                    tend(k,j,i) = tend(k,j,i) - vkomp *                         &
-                                         ( sk(k,j,i) - sk(k,j-1,i) ) * ddy
+                                         ( sk(k,j,i) - sk(k,j-1,i) ) * ddy     &
+                                      * MERGE( 1.0_wp, 0.0_wp,                 &
+                                               BTEST( wall_flags_0(k,j,i), 0 ) )
                 ELSE
                    tend(k,j,i) = tend(k,j,i) - vkomp *                         &
-                                         ( sk(k,j+1,i) - sk(k,j,i) ) * ddy
+                                         ( sk(k,j+1,i) - sk(k,j,i) ) * ddy     &
+                                      * MERGE( 1.0_wp, 0.0_wp,                 &
+                                               BTEST( wall_flags_0(k,j,i), 0 ) )
                 ENDIF
 !
@@ -154,8 +162,12 @@
                 IF ( wkomp > 0.0_wp )  THEN
                    tend(k,j,i) = tend(k,j,i) - wkomp *                         &
-                                         ( sk(k,j,i) - sk(k-1,j,i) ) * ddzu(k)
+                                         ( sk(k,j,i) - sk(k-1,j,i) ) * ddzu(k) &
+                                      * MERGE( 1.0_wp, 0.0_wp,                 &
+                                               BTEST( wall_flags_0(k,j,i), 0 ) )
                 ELSE
                    tend(k,j,i) = tend(k,j,i) - wkomp *                         &
-                                         ( sk(k+1,j,i)-sk(k,j,i) ) * ddzu(k+1)
+                                         ( sk(k+1,j,i)-sk(k,j,i) ) * ddzu(k+1) &
+                                      * MERGE( 1.0_wp, 0.0_wp,                 &
+                                               BTEST( wall_flags_0(k,j,i), 0 ) )
                 ENDIF
 
@@ -184,5 +196,5 @@
 
        USE indices,                                                            &
-           ONLY:  nxlg, nxrg, nyng, nysg, nzb, nzb_s_inner, nzt
+           ONLY:  nxlg, nxrg, nyng, nysg, nzb, nzt, wall_flags_0
 
        USE kinds
@@ -206,5 +218,5 @@
 
 
-       DO  k = nzb_s_inner(j,i)+1, nzt
+       DO  k = nzb+1, nzt
 !
 !--       x-direction
@@ -212,8 +224,12 @@
           IF ( ukomp > 0.0_wp )  THEN
              tend(k,j,i) = tend(k,j,i) - ukomp *                               &
-                                         ( sk(k,j,i) - sk(k,j,i-1) ) * ddx
+                                         ( sk(k,j,i) - sk(k,j,i-1) ) * ddx     &
+                                      * MERGE( 1.0_wp, 0.0_wp,                 &
+                                               BTEST( wall_flags_0(k,j,i), 0 ) )
           ELSE
              tend(k,j,i) = tend(k,j,i) - ukomp *                               &
-                                         ( sk(k,j,i+1) - sk(k,j,i) ) * ddx
+                                         ( sk(k,j,i+1) - sk(k,j,i) ) * ddx     &
+                                      * MERGE( 1.0_wp, 0.0_wp,                 &
+                                               BTEST( wall_flags_0(k,j,i), 0 ) )
           ENDIF
 !
@@ -222,8 +238,12 @@
           IF ( vkomp > 0.0_wp )  THEN
              tend(k,j,i) = tend(k,j,i) - vkomp *                               &
-                                         ( sk(k,j,i) - sk(k,j-1,i) ) * ddy
+                                         ( sk(k,j,i) - sk(k,j-1,i) ) * ddy     &
+                                      * MERGE( 1.0_wp, 0.0_wp,                 &
+                                               BTEST( wall_flags_0(k,j,i), 0 ) )
           ELSE
              tend(k,j,i) = tend(k,j,i) - vkomp *                               &
-                                         ( sk(k,j+1,i) - sk(k,j,i) ) * ddy
+                                         ( sk(k,j+1,i) - sk(k,j,i) ) * ddy     &
+                                      * MERGE( 1.0_wp, 0.0_wp,                 &
+                                               BTEST( wall_flags_0(k,j,i), 0 ) )
           ENDIF
 !
@@ -232,8 +252,12 @@
           IF ( wkomp > 0.0_wp )  THEN
              tend(k,j,i) = tend(k,j,i) - wkomp *                               &
-                                         ( sk(k,j,i) - sk(k-1,j,i) ) * ddzu(k)
+                                         ( sk(k,j,i) - sk(k-1,j,i) ) * ddzu(k) &
+                                      * MERGE( 1.0_wp, 0.0_wp,                 &
+                                               BTEST( wall_flags_0(k,j,i), 0 ) )
           ELSE
              tend(k,j,i) = tend(k,j,i) - wkomp *                               &
-                                         ( sk(k+1,j,i)-sk(k,j,i) ) * ddzu(k+1)
+                                         ( sk(k+1,j,i)-sk(k,j,i) ) * ddzu(k+1) &
+                                      * MERGE( 1.0_wp, 0.0_wp,                 &
+                                               BTEST( wall_flags_0(k,j,i), 0 ) )
           ENDIF
 
Index: /palm/trunk/SOURCE/advec_u_pw.f90
===================================================================
--- /palm/trunk/SOURCE/advec_u_pw.f90	(revision 2231)
+++ /palm/trunk/SOURCE/advec_u_pw.f90	(revision 2232)
@@ -20,5 +20,5 @@
 ! Current revisions:
 ! -----------------
-! 
+! topography representation via flags
 ! 
 ! Former revisions:
@@ -96,5 +96,5 @@
 
        USE indices,                                                            &
-           ONLY:  nxlu, nxr, nyn, nys, nzb_u_inner, nzt
+           ONLY:  nxlu, nxr, nyn, nys, nzb, nzt, wall_flags_0
 
        USE kinds
@@ -114,5 +114,5 @@
        DO  i = nxlu, nxr
           DO  j = nys, nyn
-             DO  k = nzb_u_inner(j,i)+1, nzt
+             DO  k = nzb+1, nzt
                 tend(k,j,i) = tend(k,j,i) - 0.25_wp * (                        &
                          ( u(k,j,i+1) * ( u(k,j,i+1) + u(k,j,i) - gu )         &
@@ -123,5 +123,7 @@
                          - u(k-1,j,i) * ( w(k-1,j,i) + w(k-1,j,i-1) ) )        &
                                                                   * ddzw(k)    &
-                                                      )
+                                                      )                        &
+                                      * MERGE( 1.0_wp, 0.0_wp,                 &
+                                               BTEST( wall_flags_0(k,j,i), 1 ) )
              ENDDO
           ENDDO
@@ -148,5 +150,5 @@
 
        USE indices,                                                            &
-           ONLY:  nzb_u_inner, nzt
+           ONLY:  nzb, nzt, wall_flags_0
 
        USE kinds
@@ -164,5 +166,5 @@
        gu = 2.0_wp * u_gtrans
        gv = 2.0_wp * v_gtrans
-       DO  k = nzb_u_inner(j,i)+1, nzt
+       DO  k = nzb+1, nzt
           tend(k,j,i) = tend(k,j,i) - 0.25_wp * (                              &
                          ( u(k,j,i+1) * ( u(k,j,i+1) + u(k,j,i) - gu )         &
@@ -173,5 +175,7 @@
                          - u(k-1,j,i) * ( w(k-1,j,i) + w(k-1,j,i-1) ) )        &
                                                                   * ddzw(k)    &
-                                                )
+                                                )                              &
+                                      * MERGE( 1.0_wp, 0.0_wp,                 &
+                                               BTEST( wall_flags_0(k,j,i), 1 ) )
        ENDDO
 
Index: /palm/trunk/SOURCE/advec_u_up.f90
===================================================================
--- /palm/trunk/SOURCE/advec_u_up.f90	(revision 2231)
+++ /palm/trunk/SOURCE/advec_u_up.f90	(revision 2232)
@@ -20,5 +20,5 @@
 ! Current revisions:
 ! -----------------
-! 
+! topography representation via flags
 ! 
 ! Former revisions:
@@ -95,5 +95,5 @@
 
        USE indices,                                                            &
-           ONLY:  nxlu, nxr, nyn, nys, nzb_u_inner, nzt
+           ONLY:  nxlu, nxr, nyn, nys, nzb, nzt, wall_flags_0
 
        USE kinds
@@ -113,5 +113,5 @@
        DO  i = nxlu, nxr
           DO  j = nys, nyn
-             DO  k = nzb_u_inner(j,i)+1, nzt
+             DO  k = nzb+1, nzt
 !
 !--             x-direction
@@ -119,8 +119,12 @@
                 IF ( ukomp > 0.0_wp )  THEN
                    tend(k,j,i) = tend(k,j,i) - ukomp *                         &
-                                         ( u(k,j,i) - u(k,j,i-1) ) * ddx
+                                         ( u(k,j,i) - u(k,j,i-1) ) * ddx       &
+                                      * MERGE( 1.0_wp, 0.0_wp,                 &
+                                               BTEST( wall_flags_0(k,j,i), 1 ) )
                 ELSE
                    tend(k,j,i) = tend(k,j,i) - ukomp *                         &
-                                          ( u(k,j,i+1) - u(k,j,i) ) * ddx
+                                          ( u(k,j,i+1) - u(k,j,i) ) * ddx      &
+                                      * MERGE( 1.0_wp, 0.0_wp,                 &
+                                               BTEST( wall_flags_0(k,j,i), 1 ) )
                 ENDIF
 !
@@ -130,8 +134,12 @@
                 IF ( vkomp > 0.0_wp )  THEN
                    tend(k,j,i) = tend(k,j,i) - vkomp *                         &
-                                         ( u(k,j,i) - u(k,j-1,i) ) * ddy
+                                         ( u(k,j,i) - u(k,j-1,i) ) * ddy       &
+                                      * MERGE( 1.0_wp, 0.0_wp,                 &
+                                               BTEST( wall_flags_0(k,j,i), 1 ) )
                 ELSE
                    tend(k,j,i) = tend(k,j,i) - vkomp *                         &
-                                         ( u(k,j+1,i) - u(k,j,i) ) * ddy
+                                         ( u(k,j+1,i) - u(k,j,i) ) * ddy       &
+                                      * MERGE( 1.0_wp, 0.0_wp,                 &
+                                               BTEST( wall_flags_0(k,j,i), 1 ) )
                 ENDIF
 !
@@ -141,8 +149,12 @@
                 IF ( wkomp > 0.0_wp )  THEN
                    tend(k,j,i) = tend(k,j,i) - wkomp *                         &
-                                         ( u(k,j,i) - u(k-1,j,i) ) * ddzu(k)
+                                         ( u(k,j,i) - u(k-1,j,i) ) * ddzu(k)   &
+                                      * MERGE( 1.0_wp, 0.0_wp,                 &
+                                               BTEST( wall_flags_0(k,j,i), 1 ) )
                 ELSE
                    tend(k,j,i) = tend(k,j,i) - wkomp *                         &
-                                         ( u(k+1,j,i) - u(k,j,i) ) * ddzu(k+1)
+                                         ( u(k+1,j,i) - u(k,j,i) ) * ddzu(k+1) &
+                                      * MERGE( 1.0_wp, 0.0_wp,                 &
+                                               BTEST( wall_flags_0(k,j,i), 1 ) )
                 ENDIF
 
@@ -171,5 +183,5 @@
 
        USE indices,                                                            &
-           ONLY:  nzb_u_inner, nzt
+           ONLY:  nzb, nzt, wall_flags_0
 
        USE kinds
@@ -187,5 +199,5 @@
 
 
-       DO  k = nzb_u_inner(j,i)+1, nzt
+       DO  k = nzb+1, nzt
 !
 !--       x-direction
@@ -193,8 +205,12 @@
           IF ( ukomp > 0.0_wp )  THEN
              tend(k,j,i) = tend(k,j,i) - ukomp *                               &
-                                         ( u(k,j,i) - u(k,j,i-1) ) * ddx
+                                         ( u(k,j,i) - u(k,j,i-1) ) * ddx       &
+                                      * MERGE( 1.0_wp, 0.0_wp,                 &
+                                               BTEST( wall_flags_0(k,j,i), 1 ) )
           ELSE
              tend(k,j,i) = tend(k,j,i) - ukomp *                               &
-                                         ( u(k,j,i+1) - u(k,j,i) ) * ddx
+                                         ( u(k,j,i+1) - u(k,j,i) ) * ddx       &
+                                      * MERGE( 1.0_wp, 0.0_wp,                 &
+                                               BTEST( wall_flags_0(k,j,i), 1 ) )
           ENDIF
 !
@@ -204,8 +220,12 @@
           IF ( vkomp > 0.0_wp )  THEN
              tend(k,j,i) = tend(k,j,i) - vkomp *                               &
-                                         ( u(k,j,i) - u(k,j-1,i) ) * ddy
+                                         ( u(k,j,i) - u(k,j-1,i) ) * ddy       &
+                                      * MERGE( 1.0_wp, 0.0_wp,                 &
+                                               BTEST( wall_flags_0(k,j,i), 1 ) )
           ELSE
              tend(k,j,i) = tend(k,j,i) - vkomp *                               &
-                                         ( u(k,j+1,i) - u(k,j,i) ) * ddy
+                                         ( u(k,j+1,i) - u(k,j,i) ) * ddy       &
+                                      * MERGE( 1.0_wp, 0.0_wp,                 &
+                                               BTEST( wall_flags_0(k,j,i), 1 ) )
           ENDIF
 !
@@ -214,8 +234,12 @@
           IF ( wkomp > 0.0_wp )  THEN
              tend(k,j,i) = tend(k,j,i) - wkomp *                               &
-                                         ( u(k,j,i) - u(k-1,j,i) ) * ddzu(k)
+                                         ( u(k,j,i) - u(k-1,j,i) ) * ddzu(k)   &
+                                      * MERGE( 1.0_wp, 0.0_wp,                 &
+                                               BTEST( wall_flags_0(k,j,i), 1 ) )
           ELSE
              tend(k,j,i) = tend(k,j,i) - wkomp *                               &
-                                         ( u(k+1,j,i) - u(k,j,i) ) * ddzu(k+1)
+                                         ( u(k+1,j,i) - u(k,j,i) ) * ddzu(k+1) &
+                                      * MERGE( 1.0_wp, 0.0_wp,                 &
+                                               BTEST( wall_flags_0(k,j,i), 1 ) )
           ENDIF
 
Index: /palm/trunk/SOURCE/advec_v_pw.f90
===================================================================
--- /palm/trunk/SOURCE/advec_v_pw.f90	(revision 2231)
+++ /palm/trunk/SOURCE/advec_v_pw.f90	(revision 2232)
@@ -20,5 +20,5 @@
 ! Current revisions:
 ! -----------------
-! 
+! topography representation via flags
 ! 
 ! Former revisions:
@@ -96,5 +96,5 @@
 
        USE indices,                                                            &
-           ONLY:  nxl, nxr, nyn, nysv, nzb_v_inner, nzt
+           ONLY:  nxl, nxr, nyn, nysv, nzb, nzt, wall_flags_0
 
        USE kinds
@@ -115,5 +115,5 @@
        DO  i = nxl, nxr
           DO  j = nysv, nyn
-             DO  k = nzb_v_inner(j,i)+1, nzt
+             DO  k = nzb+1, nzt
                 tend(k,j,i) = tend(k,j,i) - 0.25_wp * (                        &
                          ( v(k,j,i+1) * ( u(k,j-1,i+1) + u(k,j,i+1) - gu )     &
@@ -124,5 +124,7 @@
                          - v(k-1,j,i) * ( w(k-1,j-1,i) + w(k-1,j,i) ) )        &
                                                                   * ddzw(k)    &
-                                                      )
+                                                      )                        &
+                                      * MERGE( 1.0_wp, 0.0_wp,                 &
+                                               BTEST( wall_flags_0(k,j,i), 2 ) )
              ENDDO
           ENDDO
@@ -149,5 +151,5 @@
 
        USE indices,                                                            &
-           ONLY:  nzb_v_inner, nzt
+           ONLY:  nzb, nzt, wall_flags_0
 
        USE kinds
@@ -166,5 +168,5 @@
        gu = 2.0_wp * u_gtrans
        gv = 2.0_wp * v_gtrans
-       DO  k = nzb_v_inner(j,i)+1, nzt
+       DO  k = nzb+1, nzt
           tend(k,j,i) = tend(k,j,i) - 0.25_wp * (                              &
                          ( v(k,j,i+1) * ( u(k,j-1,i+1) + u(k,j,i+1) - gu )     &
@@ -175,5 +177,7 @@
                          - v(k-1,j,i) * ( w(k-1,j-1,i) + w(k-1,j,i) ) )        &
                                                                   * ddzw(k)    &
-                                                )
+                                                )                              &
+                                      * MERGE( 1.0_wp, 0.0_wp,                 &
+                                               BTEST( wall_flags_0(k,j,i), 2 ) )
        ENDDO
  
Index: /palm/trunk/SOURCE/advec_v_up.f90
===================================================================
--- /palm/trunk/SOURCE/advec_v_up.f90	(revision 2231)
+++ /palm/trunk/SOURCE/advec_v_up.f90	(revision 2232)
@@ -20,5 +20,5 @@
 ! Current revisions:
 ! -----------------
-! 
+! topography representation via flags
 ! 
 ! Former revisions:
@@ -95,5 +95,5 @@
 
        USE indices,                                                            &
-           ONLY:  nxl, nxr, nyn, nysv, nzb_v_inner, nzt
+           ONLY:  nxl, nxr, nyn, nysv, nzb, nzt, wall_flags_0
 
        USE kinds
@@ -113,5 +113,5 @@
        DO  i = nxl, nxr
           DO  j = nysv, nyn
-             DO  k = nzb_v_inner(j,i)+1, nzt
+             DO  k = nzb+1, nzt
 !
 !--             x-direction
@@ -120,8 +120,12 @@
                 IF ( ukomp > 0.0_wp )  THEN
                    tend(k,j,i) = tend(k,j,i) - ukomp *                         &
-                                         ( v(k,j,i) - v(k,j,i-1) ) * ddx
+                                         ( v(k,j,i) - v(k,j,i-1) ) * ddx       &
+                                      * MERGE( 1.0_wp, 0.0_wp,                 &
+                                               BTEST( wall_flags_0(k,j,i), 2 ) )
                 ELSE
                    tend(k,j,i) = tend(k,j,i) - ukomp *                         &
-                                         ( v(k,j,i+1) - v(k,j,i) ) * ddx
+                                         ( v(k,j,i+1) - v(k,j,i) ) * ddx       &
+                                      * MERGE( 1.0_wp, 0.0_wp,                 &
+                                               BTEST( wall_flags_0(k,j,i), 2 ) )
                 ENDIF
 !
@@ -130,8 +134,12 @@
                 IF ( vkomp > 0.0_wp )  THEN
                    tend(k,j,i) = tend(k,j,i) - vkomp *                         &
-                                         ( v(k,j,i) - v(k,j-1,i) ) * ddy
+                                         ( v(k,j,i) - v(k,j-1,i) ) * ddy       &
+                                      * MERGE( 1.0_wp, 0.0_wp,                 &
+                                               BTEST( wall_flags_0(k,j,i), 2 ) )
                 ELSE
                    tend(k,j,i) = tend(k,j,i) - vkomp *                         &
-                                         ( v(k,j+1,i) - v(k,j,i) ) * ddy
+                                         ( v(k,j+1,i) - v(k,j,i) ) * ddy       &
+                                      * MERGE( 1.0_wp, 0.0_wp,                 &
+                                               BTEST( wall_flags_0(k,j,i), 2 ) )
                 ENDIF
 !
@@ -141,8 +149,12 @@
                 IF ( wkomp > 0.0_wp )  THEN
                    tend(k,j,i) = tend(k,j,i) - wkomp *                         &
-                                         ( v(k,j,i) - v(k-1,j,i) ) * ddzu(k)
+                                         ( v(k,j,i) - v(k-1,j,i) ) * ddzu(k)   &
+                                      * MERGE( 1.0_wp, 0.0_wp,                 &
+                                               BTEST( wall_flags_0(k,j,i), 2 ) )
                 ELSE
                    tend(k,j,i) = tend(k,j,i) - wkomp *                         &
-                                         ( v(k+1,j,i) - v(k,j,i) ) * ddzu(k+1)
+                                         ( v(k+1,j,i) - v(k,j,i) ) * ddzu(k+1) &
+                                      * MERGE( 1.0_wp, 0.0_wp,                 &
+                                               BTEST( wall_flags_0(k,j,i), 2 ) )
                 ENDIF
 
@@ -171,5 +183,5 @@
 
        USE indices,                                                            &
-           ONLY:  nzb_v_inner, nzt
+           ONLY:  nzb, nzt, wall_flags_0
 
        USE kinds
@@ -187,5 +199,5 @@
 
 
-       DO  k = nzb_v_inner(j,i)+1, nzt
+       DO  k = nzb+1, nzt
 !
 !--       x-direction
@@ -194,8 +206,12 @@
           IF ( ukomp > 0.0_wp )  THEN
              tend(k,j,i) = tend(k,j,i) - ukomp *                               &
-                                         ( v(k,j,i) - v(k,j,i-1) ) * ddx
+                                         ( v(k,j,i) - v(k,j,i-1) ) * ddx       &
+                                      * MERGE( 1.0_wp, 0.0_wp,                 &
+                                               BTEST( wall_flags_0(k,j,i), 2 ) )
           ELSE
              tend(k,j,i) = tend(k,j,i) - ukomp *                               &
-                                         ( v(k,j,i+1) - v(k,j,i) ) * ddx
+                                         ( v(k,j,i+1) - v(k,j,i) ) * ddx       &
+                                      * MERGE( 1.0_wp, 0.0_wp,                 &
+                                               BTEST( wall_flags_0(k,j,i), 2 ) )
           ENDIF
 !
@@ -204,8 +220,12 @@
           IF ( vkomp > 0.0_wp )  THEN
              tend(k,j,i) = tend(k,j,i) - vkomp *                               &
-                                         ( v(k,j,i) - v(k,j-1,i) ) * ddy
+                                         ( v(k,j,i) - v(k,j-1,i) ) * ddy       &
+                                      * MERGE( 1.0_wp, 0.0_wp,                 &
+                                               BTEST( wall_flags_0(k,j,i), 2 ) )
           ELSE
              tend(k,j,i) = tend(k,j,i) - vkomp *                               &
-                                         ( v(k,j+1,i) - v(k,j,i) ) * ddy
+                                         ( v(k,j+1,i) - v(k,j,i) ) * ddy       &
+                                      * MERGE( 1.0_wp, 0.0_wp,                 &
+                                               BTEST( wall_flags_0(k,j,i), 2 ) )
           ENDIF
 !
@@ -214,8 +234,12 @@
           IF ( wkomp > 0.0_wp )  THEN
              tend(k,j,i) = tend(k,j,i) - wkomp *                               &
-                                         ( v(k,j,i) - v(k-1,j,i) ) * ddzu(k)
+                                         ( v(k,j,i) - v(k-1,j,i) ) * ddzu(k)   &
+                                      * MERGE( 1.0_wp, 0.0_wp,                 &
+                                               BTEST( wall_flags_0(k,j,i), 2 ) )
           ELSE
              tend(k,j,i) = tend(k,j,i) - wkomp *                               &
-                                         ( v(k+1,j,i) - v(k,j,i) ) * ddzu(k+1)
+                                         ( v(k+1,j,i) - v(k,j,i) ) * ddzu(k+1) &
+                                      * MERGE( 1.0_wp, 0.0_wp,                 &
+                                               BTEST( wall_flags_0(k,j,i), 2 ) )
           ENDIF
 
Index: /palm/trunk/SOURCE/advec_w_pw.f90
===================================================================
--- /palm/trunk/SOURCE/advec_w_pw.f90	(revision 2231)
+++ /palm/trunk/SOURCE/advec_w_pw.f90	(revision 2232)
@@ -20,5 +20,5 @@
 ! Current revisions:
 ! -----------------
-! 
+! topography representation via flags
 ! 
 ! Former revisions:
@@ -96,5 +96,5 @@
 
        USE indices,                                                            &
-           ONLY:  nxl, nxr, nyn, nys, nzb_w_inner, nzt
+           ONLY:  nxl, nxr, nyn, nys, nzb, nzt, wall_flags_0
 
        USE kinds
@@ -115,5 +115,5 @@
        DO  i = nxl, nxr
           DO  j = nys, nyn
-             DO  k = nzb_w_inner(j,i)+1, nzt
+             DO  k = nzb+1, nzt
                 tend(k,j,i) = tend(k,j,i) - 0.25_wp * (                        &
                          ( w(k,j,i+1) * ( u(k+1,j,i+1) + u(k,j,i+1) - gu )     &
@@ -124,5 +124,7 @@
                          - w(k-1,j,i) * ( w(k,j,i) + w(k-1,j,i) ) )            &
                                                                   * ddzu(k+1)  &
-                                                      )
+                                                      )                        &
+                                      * MERGE( 1.0_wp, 0.0_wp,                 &
+                                               BTEST( wall_flags_0(k,j,i), 3 ) )
              ENDDO
           ENDDO
@@ -149,5 +151,5 @@
 
        USE indices,                                                            &
-           ONLY:  nzb_w_inner, nzt
+           ONLY:  nzb, nzt, wall_flags_0
 
        USE kinds
@@ -165,5 +167,5 @@
        gu = 2.0_wp * u_gtrans
        gv = 2.0_wp * v_gtrans
-       DO  k = nzb_w_inner(j,i)+1, nzt
+       DO  k = nzb+1, nzt
           tend(k,j,i) = tend(k,j,i) - 0.25_wp * (                              &
                          ( w(k,j,i+1) * ( u(k+1,j,i+1) + u(k,j,i+1) - gu )     &
@@ -174,5 +176,7 @@
                          - w(k-1,j,i) * ( w(k,j,i) + w(k-1,j,i) ) )            &
                                                                   * ddzu(k+1)  &
-                                                )
+                                                )                              &
+                                      * MERGE( 1.0_wp, 0.0_wp,                 &
+                                               BTEST( wall_flags_0(k,j,i), 3 ) )
        ENDDO
     END SUBROUTINE advec_w_pw_ij
Index: /palm/trunk/SOURCE/advec_w_up.f90
===================================================================
--- /palm/trunk/SOURCE/advec_w_up.f90	(revision 2231)
+++ /palm/trunk/SOURCE/advec_w_up.f90	(revision 2232)
@@ -20,5 +20,5 @@
 ! Current revisions:
 ! -----------------
-! 
+! topography representation via flags
 ! 
 ! Former revisions:
@@ -95,5 +95,5 @@
 
        USE indices,                                                            &
-           ONLY:  nxl, nxr, nyn, nys, nzb_w_inner, nzt
+           ONLY:  nxl, nxr, nyn, nys, nzb, nzt, wall_flags_0
 
        USE kinds
@@ -112,5 +112,5 @@
        DO  i = nxl, nxr
           DO  j = nys, nyn
-             DO  k = nzb_w_inner(j,i)+1, nzt-1
+             DO  k = nzb+1, nzt-1
 !
 !--             x-direction
@@ -119,8 +119,12 @@
                 IF ( ukomp > 0.0_wp )  THEN
                    tend(k,j,i) = tend(k,j,i) - ukomp *                         &
-                                         ( w(k,j,i) - w(k,j,i-1) ) * ddx
+                                         ( w(k,j,i) - w(k,j,i-1) ) * ddx       &
+                                      * MERGE( 1.0_wp, 0.0_wp,                 &
+                                               BTEST( wall_flags_0(k,j,i), 3 ) )
                 ELSE
                    tend(k,j,i) = tend(k,j,i) - ukomp *                         &
-                                         ( w(k,j,i+1) - w(k,j,i) ) * ddx
+                                         ( w(k,j,i+1) - w(k,j,i) ) * ddx       &
+                                      * MERGE( 1.0_wp, 0.0_wp,                 &
+                                               BTEST( wall_flags_0(k,j,i), 3 ) )
                 ENDIF
 !
@@ -130,8 +134,12 @@
                 IF ( vkomp > 0.0_wp )  THEN
                    tend(k,j,i) = tend(k,j,i) - vkomp *                         &
-                                         ( w(k,j,i) - w(k,j-1,i) ) * ddy
+                                         ( w(k,j,i) - w(k,j-1,i) ) * ddy       &
+                                      * MERGE( 1.0_wp, 0.0_wp,                 &
+                                               BTEST( wall_flags_0(k,j,i), 3 ) )
                 ELSE
                    tend(k,j,i) = tend(k,j,i) - vkomp *                         &
-                                         ( w(k,j+1,i) - w(k,j,i) ) * ddy
+                                         ( w(k,j+1,i) - w(k,j,i) ) * ddy       &
+                                      * MERGE( 1.0_wp, 0.0_wp,                 &
+                                               BTEST( wall_flags_0(k,j,i), 3 ) )
                 ENDIF
 !
@@ -139,8 +147,12 @@
                 IF ( w(k,j,i) > 0.0_wp )  THEN
                    tend(k,j,i) = tend(k,j,i) - w(k,j,i) *                      &
-                                         ( w(k,j,i) - w(k-1,j,i) ) * ddzw(k)
+                                         ( w(k,j,i) - w(k-1,j,i) ) * ddzw(k)   &
+                                      * MERGE( 1.0_wp, 0.0_wp,                 &
+                                               BTEST( wall_flags_0(k,j,i), 3 ) )
                 ELSE
                    tend(k,j,i) = tend(k,j,i) - w(k,j,i) *                      &
-                                         ( w(k+1,j,i) - w(k,j,i) ) * ddzw(k+1)
+                                         ( w(k+1,j,i) - w(k,j,i) ) * ddzw(k+1) &
+                                      * MERGE( 1.0_wp, 0.0_wp,                 &
+                                               BTEST( wall_flags_0(k,j,i), 3 ) )
                 ENDIF
 
@@ -169,5 +181,5 @@
 
        USE indices,                                                            &
-           ONLY:  nzb_w_inner, nzt
+           ONLY:  nzb, nzt, wall_flags_0
 
        USE kinds
@@ -184,5 +196,5 @@
 
 
-       DO  k = nzb_w_inner(j,i)+1, nzt-1
+       DO  k = nzb+1, nzt-1
 !
 !--       x-direction
Index: /palm/trunk/SOURCE/advec_ws.f90
===================================================================
--- /palm/trunk/SOURCE/advec_ws.f90	(revision 2231)
+++ /palm/trunk/SOURCE/advec_ws.f90	(revision 2232)
@@ -20,5 +20,8 @@
 ! Current revisions:
 ! ------------------
-! 
+! Rename wall_flags_0 and wall_flags_00 into advc_flags_1 and advc_flags_2, 
+! respectively.
+! Set advc_flags_1/2 on basis of wall_flags_0/00 instead of nzb_s/u/v/w_inner.
+! Setting advc_flags_1/2 also for downward-facing walls
 ! 
 ! Former revisions:
@@ -147,5 +150,5 @@
 ! vector version.
 ! Degradation of the applied order of scheme is now steered by multiplying with
-! Integer wall_flags_0. 2nd order scheme, WS3 and WS5 are calculated on each
+! Integer advc_flags_1. 2nd order scheme, WS3 and WS5 are calculated on each
 ! grid point and mulitplied with the appropriate flag.
 ! 2nd order numerical dissipation term changed. Now the appropriate 2nd order
@@ -406,7 +409,6 @@
 
        USE indices,                                                            &
-           ONLY:  nbgp, nxl, nxlu, nxr, nyn, nys, nysv, nzb, nzb_s_inner,      &
-                  nzb_u_inner, nzb_v_inner, nzb_w_inner, nzt, wall_flags_0,    &
-                  wall_flags_00
+           ONLY:  advc_flags_1, advc_flags_2, nbgp, nxl, nxlu, nxr, nyn, nys,  &
+                  nysv, nzb, nzt, wall_flags_0
 
        USE kinds
@@ -414,8 +416,11 @@
        IMPLICIT NONE
 
-       INTEGER(iwp) ::  i  !< index variable along x
-       INTEGER(iwp) ::  j  !< index variable along y
-       INTEGER(iwp) ::  k  !< index variable along z
-
+       INTEGER(iwp) ::  i     !< index variable along x
+       INTEGER(iwp) ::  j     !< index variable along y
+       INTEGER(iwp) ::  k     !< index variable along z
+       INTEGER(iwp) ::  k_mm  !< dummy index along z
+       INTEGER(iwp) ::  k_pp  !< dummy index along z
+       INTEGER(iwp) ::  k_ppp !< dummy index along z
+       
        LOGICAL      ::  flag_set !< steering variable for advection flags
    
@@ -425,90 +430,134 @@
 !--       Set flags to steer the degradation of the advection scheme in advec_ws
 !--       near topography, inflow- and outflow boundaries as well as bottom and
-!--       top of model domain. wall_flags_0 remains zero for all non-prognostic
+!--       top of model domain. advc_flags_1 remains zero for all non-prognostic
 !--       grid points.
           DO  i = nxl, nxr
              DO  j = nys, nyn
-                DO  k = nzb_s_inner(j,i)+1, nzt
+                DO  k = nzb+1, nzt
 !
 !--                scalar - x-direction
 !--                WS1 (0), WS3 (1), WS5 (2)
-                   IF ( ( k <= nzb_s_inner(j,i+1) .OR. k <= nzb_s_inner(j,i+2) &   
-                     .OR. k <= nzb_s_inner(j,i-1) )                            &
-                       .OR. ( ( inflow_l .OR. outflow_l .OR. nest_bound_l )    &
-                              .AND. i == nxl   )    .OR.                       &
+                   IF ( ( .NOT. BTEST(wall_flags_0(k,j,i+1),0)                 &
+                    .OR.  .NOT. BTEST(wall_flags_0(k,j,i+2),0)                 &   
+                    .OR.  .NOT. BTEST(wall_flags_0(k,j,i-1),0) )               &
+                      .OR.  ( ( inflow_l .OR. outflow_l .OR. nest_bound_l )    &
+                            .AND.  i == nxl   )                                &
+                      .OR.  ( ( inflow_r .OR. outflow_r .OR. nest_bound_r )    &
+                            .AND.  i == nxr   ) )                              &
+                   THEN
+                      advc_flags_1(k,j,i) = IBSET( advc_flags_1(k,j,i), 0 )
+                   ELSEIF ( ( .NOT. BTEST(wall_flags_0(k,j,i+3),0)             &
+                       .AND.        BTEST(wall_flags_0(k,j,i+1),0)             &
+                       .AND.        BTEST(wall_flags_0(k,j,i+2),0)             &
+                       .AND.        BTEST(wall_flags_0(k,j,i-1),0)             &
+                            )                       .OR.                       &
+                            ( .NOT. BTEST(wall_flags_0(k,j,i-2),0)             &
+                       .AND.        BTEST(wall_flags_0(k,j,i+1),0)             &
+                       .AND.        BTEST(wall_flags_0(k,j,i+2),0)             &
+                       .AND.        BTEST(wall_flags_0(k,j,i-1),0)             &
+                            )                                                  &
+                                                    .OR.                       &
                             ( ( inflow_r .OR. outflow_r .OR. nest_bound_r )    &
-                              .AND. i == nxr   ) )                             &
+                              .AND. i == nxr-1 )    .OR.                       &
+                            ( ( inflow_l .OR. outflow_l .OR. nest_bound_l )    &
+                              .AND. i == nxlu  ) )                             &
                    THEN
-                      wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i), 0 )
-                   ELSEIF ( ( k <= nzb_s_inner(j,i+3) .AND. k > nzb_s_inner(j,i+1)&
-                                                      .AND. k > nzb_s_inner(j,i+2)&
-                                                      .AND. k > nzb_s_inner(j,i-1)&
-                            )                       .OR.                          &
-                            ( k <= nzb_s_inner(j,i-2) .AND. k > nzb_s_inner(j,i+1)&
-                                                      .AND. k > nzb_s_inner(j,i+2)&
-                                                      .AND. k > nzb_s_inner(j,i-1)&
-                            )                                                     &
-                                                    .OR.                          &
-                            ( ( inflow_r .OR. outflow_r .OR. nest_bound_r )       &
-                              .AND. i == nxr-1 )    .OR.                          &
-                            ( ( inflow_l .OR. outflow_l .OR. nest_bound_l )       &
-                              .AND. i == nxlu  ) )                                &
-                   THEN
-                      wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i), 1 )
-                   ELSEIF ( k > nzb_s_inner(j,i+1) .AND. k > nzb_s_inner(j,i+2)&
-                      .AND. k > nzb_s_inner(j,i+3) .AND. k > nzb_s_inner(j,i-1)&
-                      .AND. k > nzb_s_inner(j,i-2) )                           &
+                      advc_flags_1(k,j,i) = IBSET( advc_flags_1(k,j,i), 1 )
+                   ELSEIF ( BTEST(wall_flags_0(k,j,i+1),0)                     &
+                      .AND. BTEST(wall_flags_0(k,j,i+2),0)                     &
+                      .AND. BTEST(wall_flags_0(k,j,i+3),0)                     &
+                      .AND. BTEST(wall_flags_0(k,j,i-1),0)                     &
+                      .AND. BTEST(wall_flags_0(k,j,i-2),0) )                   &
                    THEN 
-                      wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i), 2 )
+                      advc_flags_1(k,j,i) = IBSET( advc_flags_1(k,j,i), 2 )
                    ENDIF
 !
 !--                scalar - y-direction
 !--                WS1 (3), WS3 (4), WS5 (5)
-                   IF ( ( k <= nzb_s_inner(j+1,i)  .OR. k <= nzb_s_inner(j+2,i)   &   
-                                                   .OR. k <= nzb_s_inner(j-1,i) ) &
-                                                    .OR.                          &
-                            ( ( inflow_s .OR. outflow_s .OR. nest_bound_s )       &
-                              .AND. j == nys   )    .OR.                          &
-                            ( ( inflow_n .OR. outflow_n .OR. nest_bound_n )       &
-                              .AND. j == nyn   ) )                                &
+                   IF ( ( .NOT. BTEST(wall_flags_0(k,j+1,i),0)                 &
+                    .OR.  .NOT. BTEST(wall_flags_0(k,j+2,i),0)                 &   
+                    .OR.  .NOT. BTEST(wall_flags_0(k,j-1,i),0))                &
+                      .OR.  ( ( inflow_s .OR. outflow_s .OR. nest_bound_s )    &
+                            .AND.  j == nys   )                                &
+                      .OR.  ( ( inflow_n .OR. outflow_n .OR. nest_bound_n )    &
+                            .AND.  j == nyn   ) )                              &
                    THEN
-                      wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i), 3 )
+                      advc_flags_1(k,j,i) = IBSET( advc_flags_1(k,j,i), 3 )
 !
 !--                WS3
-                   ELSEIF ( ( k <= nzb_s_inner(j+3,i) .AND. k > nzb_s_inner(j+1,i)&
-                                                      .AND. k > nzb_s_inner(j+2,i)&
-                                                      .AND. k > nzb_s_inner(j-1,i)&
-                            )                           .OR.                      &
-                            ( k <= nzb_s_inner(j-2,i) .AND. k > nzb_s_inner(j+1,i)&
-                                                      .AND. k > nzb_s_inner(j+2,i)&
-                                                      .AND. k > nzb_s_inner(j-1,i)&
-                            )                                                     &
-                                                        .OR.                      &
-                            ( ( inflow_s .OR. outflow_s .OR. nest_bound_s )       &
-                              .AND. j == nysv  )    .OR.                          &
-                            ( ( inflow_n .OR. outflow_n .OR. nest_bound_n )       &
-                              .AND. j == nyn-1 ) )                                &
+                   ELSEIF ( ( .NOT. BTEST(wall_flags_0(k,j+3,i),0)             &
+                       .AND.        BTEST(wall_flags_0(k,j+1,i),0)             &
+                       .AND.        BTEST(wall_flags_0(k,j+2,i),0)             &
+                       .AND.        BTEST(wall_flags_0(k,j-1,i),0)             &
+                            )                       .OR.                       &
+                            ( .NOT. BTEST(wall_flags_0(k,j-2,i),0)             &
+                       .AND.        BTEST(wall_flags_0(k,j+1,i),0)             &
+                       .AND.        BTEST(wall_flags_0(k,j+2,i),0)             &
+                       .AND.        BTEST(wall_flags_0(k,j-1,i),0)             &
+                            )                                                  &
+                                                    .OR.                       &
+                            ( ( inflow_s .OR. outflow_s .OR. nest_bound_s )    &
+                              .AND. j == nysv  )    .OR.                       &
+                            ( ( inflow_n .OR. outflow_n .OR. nest_bound_n )    &
+                              .AND. j == nyn-1 ) )                             &          
                    THEN
-                      wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i), 4 )
+                      advc_flags_1(k,j,i) = IBSET( advc_flags_1(k,j,i), 4 )
 !
 !--                WS5
-                   ELSEIF ( k > nzb_s_inner(j+1,i) .AND. k > nzb_s_inner(j+2,i)&
-                      .AND. k > nzb_s_inner(j+3,i) .AND. k > nzb_s_inner(j-1,i)&
-                      .AND. k > nzb_s_inner(j-2,i) )                           &
+                   ELSEIF ( BTEST(wall_flags_0(k,j+1,i),0)                     &
+                      .AND. BTEST(wall_flags_0(k,j+2,i),0)                     &
+                      .AND. BTEST(wall_flags_0(k,j+3,i),0)                     &
+                      .AND. BTEST(wall_flags_0(k,j-1,i),0)                     &
+                      .AND. BTEST(wall_flags_0(k,j-2,i),0) )                   &
                    THEN 
-                      wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i), 5 )
+                      advc_flags_1(k,j,i) = IBSET( advc_flags_1(k,j,i), 5 )
                    ENDIF
 ! 
 !--                scalar - z-direction
 !--                WS1 (6), WS3 (7), WS5 (8)
+                   IF ( k == nzb+1 )  THEN
+                      k_mm = nzb
+                   ELSE 
+                      k_mm = k - 2
+                   ENDIF
+                   IF ( k > nzt-1 )  THEN
+                      k_pp = nzt+1
+                   ELSE 
+                      k_pp = k + 2
+                   ENDIF
+                   IF ( k > nzt-2 )  THEN
+                      k_ppp = nzt+1
+                   ELSE 
+                      k_ppp = k + 3
+                   ENDIF
+
                    flag_set = .FALSE.
-                   IF ( k == nzb_s_inner(j,i) + 1 .OR. k == nzt )  THEN
-                      wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i), 6 )
+                   IF ( .NOT. BTEST(wall_flags_0(k-1,j,i),0)  .AND.            &
+                              BTEST(wall_flags_0(k,j,i),0)    .OR.             &
+                        .NOT. BTEST(wall_flags_0(k_pp,j,i),0) .AND.            &                              
+                              BTEST(wall_flags_0(k,j,i),0)    .OR.             &
+                        k == nzt )                                             &
+                   THEN
+                      advc_flags_1(k,j,i) = IBSET( advc_flags_1(k,j,i), 6 )
                       flag_set = .TRUE.
-                   ELSEIF ( k == nzb_s_inner(j,i) + 2 .OR. k == nzt - 1 )  THEN
-                      wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i), 7 )
+                   ELSEIF ( ( .NOT. BTEST(wall_flags_0(k_mm,j,i),0)    .OR.    &
+                              .NOT. BTEST(wall_flags_0(k_ppp,j,i),0) ) .AND.   & 
+                                  BTEST(wall_flags_0(k-1,j,i),0)  .AND.        &
+                                  BTEST(wall_flags_0(k,j,i),0)    .AND.        &
+                                  BTEST(wall_flags_0(k+1,j,i),0)  .AND.        &
+                                  BTEST(wall_flags_0(k_pp,j,i),0) .OR.         &    
+                            k == nzt - 1 )                                     &
+                   THEN
+                      advc_flags_1(k,j,i) = IBSET( advc_flags_1(k,j,i), 7 )
                       flag_set = .TRUE.
-                   ELSEIF ( k > nzb_s_inner(j,i) .AND. .NOT. flag_set )  THEN
-                      wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i), 8 )
+                   ELSEIF ( BTEST(wall_flags_0(k_mm,j,i),0)                    &
+                     .AND.  BTEST(wall_flags_0(k-1,j,i),0)                     &
+                     .AND.  BTEST(wall_flags_0(k,j,i),0)                       &
+                     .AND.  BTEST(wall_flags_0(k+1,j,i),0)                     &
+                     .AND.  BTEST(wall_flags_0(k_pp,j,i),0)                    &
+                     .AND.  BTEST(wall_flags_0(k_ppp,j,i),0)                   &
+                     .AND. .NOT. flag_set )                                    &
+                   THEN
+                      advc_flags_1(k,j,i) = IBSET( advc_flags_1(k,j,i), 8 )
                    ENDIF
 
@@ -520,7 +569,7 @@
        IF ( momentum_advec == 'ws-scheme' )  THEN
 !
-!--       Set wall_flags_0 to steer the degradation of the advection scheme in advec_ws
+!--       Set advc_flags_1 to steer the degradation of the advection scheme in advec_ws
 !--       near topography, inflow- and outflow boundaries as well as bottom and
-!--       top of model domain. wall_flags_0 remains zero for all non-prognostic
+!--       top of model domain. advc_flags_1 remains zero for all non-prognostic
 !--       grid points.
           DO  i = nxl, nxr
@@ -532,10 +581,10 @@
 !--                in order to handle the left/south flux.
 !--                near vertical walls. 
-                   wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i), 9 )
-                   wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i), 12 )
+                   advc_flags_1(k,j,i) = IBSET( advc_flags_1(k,j,i), 9 )
+                   advc_flags_1(k,j,i) = IBSET( advc_flags_1(k,j,i), 12 )
 !
 !--                u component - x-direction
 !--                WS1 (9), WS3 (10), WS5 (11)
-                   IF ( k <= nzb_u_inner(j,i+1)     .OR.                       &
+                   IF ( .NOT. BTEST(wall_flags_0(k,j,i+1),1)  .OR.             &
                             ( ( inflow_l .OR. outflow_l .OR. nest_bound_l )    &
                               .AND. i <= nxlu  )    .OR.                       &
@@ -543,8 +592,8 @@
                               .AND. i == nxr   ) )                             &
                    THEN
-                       wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i), 9 )
-                   ELSEIF ( ( k <= nzb_u_inner(j,i+2) .AND.                    &
-                              k >  nzb_u_inner(j,i+1) ) .OR.                   &
-                              k <= nzb_u_inner(j,i-1)                          &
+                       advc_flags_1(k,j,i) = IBSET( advc_flags_1(k,j,i), 9 )
+                   ELSEIF ( ( .NOT. BTEST(wall_flags_0(k,j,i+2),1)  .AND.      &
+                                    BTEST(wall_flags_0(k,j,i+1),1)  .OR.       &
+                              .NOT. BTEST(wall_flags_0(k,j,i-1),1) )           &
                                                         .OR.                   &
                             ( ( inflow_r .OR. outflow_r .OR. nest_bound_r )    &
@@ -553,20 +602,21 @@
                               .AND. i == nxlu+1) )                             &
                    THEN
-                      wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i), 10 )
+                      advc_flags_1(k,j,i) = IBSET( advc_flags_1(k,j,i), 10 )
 !
 !--                   Clear flag for WS1
-                      wall_flags_0(k,j,i) = IBCLR( wall_flags_0(k,j,i), 9 )
-                   ELSEIF ( k > nzb_u_inner(j,i+1) .AND. k > nzb_u_inner(j,i+2)   &
-                                                   .AND. k > nzb_u_inner(j,i-1) ) &
+                      advc_flags_1(k,j,i) = IBCLR( advc_flags_1(k,j,i), 9 )
+                   ELSEIF ( BTEST(wall_flags_0(k,j,i+1),1)  .AND.              &
+                            BTEST(wall_flags_0(k,j,i+2),1)  .AND.              &
+                            BTEST(wall_flags_0(k,j,i-1),1) )                   &
                    THEN    
-                      wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i), 11 )
+                      advc_flags_1(k,j,i) = IBSET( advc_flags_1(k,j,i), 11 )
 !
 !--                   Clear flag for WS1
-                      wall_flags_0(k,j,i) = IBCLR( wall_flags_0(k,j,i), 9 )
+                      advc_flags_1(k,j,i) = IBCLR( advc_flags_1(k,j,i), 9 )
                    ENDIF
 !
 !--                u component - y-direction
 !--                WS1 (12), WS3 (13), WS5 (14)
-                   IF ( k <= nzb_u_inner(j+1,i) .OR.                           &
+                   IF ( .NOT. BTEST(wall_flags_0(k,j+1,i),1)   .OR.            &
                             ( ( inflow_s .OR. outflow_s .OR. nest_bound_s )    &
                               .AND. j == nys   )    .OR.                       &
@@ -574,8 +624,8 @@
                               .AND. j == nyn   ) )                             &
                    THEN
-                      wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i), 12 )
-                   ELSEIF ( ( k <= nzb_u_inner(j+2,i) .AND.                    &
-                              k >  nzb_u_inner(j+1,i) ) .OR.                   &
-                              k <= nzb_u_inner(j-1,i)                          &
+                      advc_flags_1(k,j,i) = IBSET( advc_flags_1(k,j,i), 12 )
+                   ELSEIF ( ( .NOT. BTEST(wall_flags_0(k,j+2,i),1)  .AND.      &
+                                    BTEST(wall_flags_0(k,j+1,i),1)  .OR.       &
+                              .NOT. BTEST(wall_flags_0(k,j-1,i),1) )           &
                                                         .OR.                   &
                             ( ( inflow_s .OR. outflow_s .OR. nest_bound_s )    &
@@ -584,28 +634,64 @@
                               .AND. j == nyn-1 ) )                             &
                    THEN
-                      wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i), 13 )
+                      advc_flags_1(k,j,i) = IBSET( advc_flags_1(k,j,i), 13 )
 !
 !--                   Clear flag for WS1
-                      wall_flags_0(k,j,i) = IBCLR( wall_flags_0(k,j,i), 12 )
-                   ELSEIF ( k > nzb_u_inner(j+1,i) .AND. k > nzb_u_inner(j+2,i)   &
-                                                   .AND. k > nzb_u_inner(j-1,i) ) &
+                      advc_flags_1(k,j,i) = IBCLR( advc_flags_1(k,j,i), 12 )
+                   ELSEIF ( BTEST(wall_flags_0(k,j+1,i),1)  .AND.              &
+                            BTEST(wall_flags_0(k,j+2,i),1)  .AND.              &
+                            BTEST(wall_flags_0(k,j-1,i),1) )                   &
                    THEN
-                      wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i), 14 )
+                      advc_flags_1(k,j,i) = IBSET( advc_flags_1(k,j,i), 14 )
 !
 !--                   Clear flag for WS1
-                      wall_flags_0(k,j,i) = IBCLR( wall_flags_0(k,j,i), 12 )
+                      advc_flags_1(k,j,i) = IBCLR( advc_flags_1(k,j,i), 12 )
                    ENDIF
 !
 !--                u component - z-direction
 !--                WS1 (15), WS3 (16), WS5 (17)
+                   IF ( k == nzb+1 )  THEN
+                      k_mm = nzb
+                   ELSE 
+                      k_mm = k - 2
+                   ENDIF
+                   IF ( k > nzt-1 )  THEN
+                      k_pp = nzt+1
+                   ELSE 
+                      k_pp = k + 2
+                   ENDIF
+                   IF ( k > nzt-2 )  THEN
+                      k_ppp = nzt+1
+                   ELSE 
+                      k_ppp = k + 3
+                   ENDIF                   
+
                    flag_set = .FALSE.
-                   IF ( k == nzb_u_inner(j,i) + 1 .OR. k == nzt )  THEN
-                      wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i), 15 )
+                   IF ( .NOT. BTEST(wall_flags_0(k-1,j,i),1)  .AND.            &
+                              BTEST(wall_flags_0(k,j,i),1)    .OR.             &
+                        .NOT. BTEST(wall_flags_0(k_pp,j,i),1) .AND.            &                              
+                              BTEST(wall_flags_0(k,j,i),1)    .OR.             &
+                        k == nzt )                                             &
+                   THEN
+                      advc_flags_1(k,j,i) = IBSET( advc_flags_1(k,j,i), 15 )
+                      flag_set = .TRUE.                      
+                   ELSEIF ( ( .NOT. BTEST(wall_flags_0(k_mm,j,i),1)    .OR.    &
+                              .NOT. BTEST(wall_flags_0(k_ppp,j,i),1) ) .AND.   & 
+                                  BTEST(wall_flags_0(k-1,j,i),1)  .AND.        &
+                                  BTEST(wall_flags_0(k,j,i),1)    .AND.        &
+                                  BTEST(wall_flags_0(k+1,j,i),1)  .AND.        &
+                                  BTEST(wall_flags_0(k_pp,j,i),1) .OR.         &
+                                  k == nzt - 1 )                               &
+                   THEN
+                      advc_flags_1(k,j,i) = IBSET( advc_flags_1(k,j,i), 16 )
                       flag_set = .TRUE.
-                   ELSEIF ( k == nzb_u_inner(j,i) + 2 .OR. k == nzt - 1 )  THEN
-                      wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i), 16 )
-                      flag_set = .TRUE.
-                   ELSEIF ( k > nzb_u_inner(j,i) .AND. .NOT. flag_set )  THEN
-                      wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i), 17 )
+                   ELSEIF ( BTEST(wall_flags_0(k_mm,j,i),1)  .AND.             &
+                            BTEST(wall_flags_0(k-1,j,i),1)   .AND.             &
+                            BTEST(wall_flags_0(k,j,i),1)     .AND.             &
+                            BTEST(wall_flags_0(k+1,j,i),1)   .AND.             &
+                            BTEST(wall_flags_0(k_pp,j,i),1)  .AND.             &
+                            BTEST(wall_flags_0(k_ppp,j,i),1) .AND.             &
+                            .NOT. flag_set )                                   &
+                   THEN
+                      advc_flags_1(k,j,i) = IBSET( advc_flags_1(k,j,i), 17 )
                    ENDIF
 
@@ -621,10 +707,10 @@
 !--                Since fluxes are swapped in advec_ws.f90, this is necessary to 
 !--                in order to handle the left/south flux.
-                   wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i), 18 )
-                   wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i), 21 )
+                   advc_flags_1(k,j,i) = IBSET( advc_flags_1(k,j,i), 18 )
+                   advc_flags_1(k,j,i) = IBSET( advc_flags_1(k,j,i), 21 )
 !
 !--                v component - x-direction
 !--                WS1 (18), WS3 (19), WS5 (20)
-                   IF ( k <= nzb_v_inner(j,i+1) .OR.                           &
+                   IF ( .NOT. BTEST(wall_flags_0(k,j,i+1),2)  .OR.             &
                             ( ( inflow_l .OR. outflow_l .OR. nest_bound_l )    &
                               .AND. i == nxl   )    .OR.                       &
@@ -632,10 +718,10 @@
                               .AND. i == nxr   ) )                             &
                   THEN
-                      wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i), 18 )
+                      advc_flags_1(k,j,i) = IBSET( advc_flags_1(k,j,i), 18 )
 !
 !--                WS3
-                   ELSEIF ( ( k <= nzb_v_inner(j,i+2) .AND.                    &
-                              k >  nzb_v_inner(j,i+1) ) .OR.                   &
-                              k <= nzb_v_inner(j,i-1)                          &
+                   ELSEIF ( ( .NOT. BTEST(wall_flags_0(k,j,i+2),2)   .AND.     &
+                                    BTEST(wall_flags_0(k,j,i+1),2) ) .OR.      &
+                              .NOT. BTEST(wall_flags_0(k,j,i-1),2)             &
                                                     .OR.                       &
                             ( ( inflow_r .OR. outflow_r .OR. nest_bound_r )    &
@@ -644,20 +730,21 @@
                               .AND. i == nxlu  ) )                             &
                    THEN
-                      wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i), 19 )
+                      advc_flags_1(k,j,i) = IBSET( advc_flags_1(k,j,i), 19 )
 !
 !--                   Clear flag for WS1
-                      wall_flags_0(k,j,i) = IBCLR( wall_flags_0(k,j,i), 18 )
-                   ELSEIF ( k > nzb_v_inner(j,i+1) .AND. k > nzb_v_inner(j,i+2)   &
-                                                   .AND. k > nzb_v_inner(j,i-1) ) &
+                      advc_flags_1(k,j,i) = IBCLR( advc_flags_1(k,j,i), 18 )
+                   ELSEIF ( BTEST(wall_flags_0(k,j,i+1),2)  .AND.              &
+                            BTEST(wall_flags_0(k,j,i+2),2)  .AND.              &
+                            BTEST(wall_flags_0(k,j,i-1),2) )                   &
                    THEN
-                      wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i), 20 )
+                      advc_flags_1(k,j,i) = IBSET( advc_flags_1(k,j,i), 20 )
 !
 !--                   Clear flag for WS1
-                      wall_flags_0(k,j,i) = IBCLR( wall_flags_0(k,j,i), 18 )
+                      advc_flags_1(k,j,i) = IBCLR( advc_flags_1(k,j,i), 18 )
                    ENDIF
 !
 !--                v component - y-direction
 !--                WS1 (21), WS3 (22), WS5 (23)
-                   IF ( k <= nzb_v_inner(j+1,i) .OR.                           &
+                   IF ( .NOT. BTEST(wall_flags_0(k,j+1,i),2) .OR.              &
                             ( ( inflow_s .OR. outflow_s .OR. nest_bound_s )    &
                               .AND. j <= nysv  )    .OR.                       &
@@ -665,8 +752,8 @@
                               .AND. j == nyn   ) )                             &
                    THEN
-                      wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i), 21 )
-                   ELSEIF ( ( k <= nzb_v_inner(j+2,i) .AND.                    &
-                              k >  nzb_v_inner(j+1,i) ) .OR.                   &
-                              k <= nzb_v_inner(j-1,i)                          &
+                      advc_flags_1(k,j,i) = IBSET( advc_flags_1(k,j,i), 21 )
+                   ELSEIF ( ( .NOT. BTEST(wall_flags_0(k,j+2,i),2)  .AND.      &
+                                    BTEST(wall_flags_0(k,j+1,i),2)  .OR.       &
+                              .NOT. BTEST(wall_flags_0(k,j-1,i),2) )           &
                                                         .OR.                   &
                             ( ( inflow_s .OR. outflow_s .OR. nest_bound_s )    &
@@ -675,28 +762,64 @@
                               .AND. j == nyn-1 ) )                             &
                    THEN
-                      wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i), 22 )
+                      advc_flags_1(k,j,i) = IBSET( advc_flags_1(k,j,i), 22 )
 !
 !--                   Clear flag for WS1
-                      wall_flags_0(k,j,i) = IBCLR( wall_flags_0(k,j,i), 21 )
-                   ELSEIF ( k > nzb_v_inner(j+1,i) .AND. k > nzb_v_inner(j+2,i)   &
-                                                   .AND. k > nzb_v_inner(j-1,i) ) &
+                      advc_flags_1(k,j,i) = IBCLR( advc_flags_1(k,j,i), 21 )
+                   ELSEIF ( BTEST(wall_flags_0(k,j+1,i),2)  .AND.              &
+                            BTEST(wall_flags_0(k,j+2,i),2)  .AND.              &
+                            BTEST(wall_flags_0(k,j-1,i),2) )                   & 
                    THEN
-                      wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i), 23 )
+                      advc_flags_1(k,j,i) = IBSET( advc_flags_1(k,j,i), 23 )
 !
 !--                   Clear flag for WS1
-                      wall_flags_0(k,j,i) = IBCLR( wall_flags_0(k,j,i), 21 )
+                      advc_flags_1(k,j,i) = IBCLR( advc_flags_1(k,j,i), 21 )
                    ENDIF
 !
 !--                v component - z-direction
 !--                WS1 (24), WS3 (25), WS5 (26)
+                   IF ( k == nzb+1 )  THEN
+                      k_mm = nzb
+                   ELSE 
+                      k_mm = k - 2
+                   ENDIF
+                   IF ( k > nzt-1 )  THEN
+                      k_pp = nzt+1
+                   ELSE 
+                      k_pp = k + 2
+                   ENDIF
+                   IF ( k > nzt-2 )  THEN
+                      k_ppp = nzt+1
+                   ELSE 
+                      k_ppp = k + 3
+                   ENDIF  
+                   
                    flag_set = .FALSE.
-                   IF ( k == nzb_v_inner(j,i) + 1 .OR. k == nzt )  THEN
-                      wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i), 24 )
+                   IF ( .NOT. BTEST(wall_flags_0(k-1,j,i),2)  .AND.            &
+                              BTEST(wall_flags_0(k,j,i),2)    .OR.             &
+                        .NOT. BTEST(wall_flags_0(k_pp,j,i),2) .AND.            &                              
+                              BTEST(wall_flags_0(k,j,i),2)    .OR.             &
+                        k == nzt )                                             &
+                   THEN
+                      advc_flags_1(k,j,i) = IBSET( advc_flags_1(k,j,i), 24 )
                       flag_set = .TRUE.
-                   ELSEIF ( k == nzb_v_inner(j,i) + 2 .OR. k == nzt - 1 )  THEN
-                      wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i), 25 )
+                   ELSEIF ( ( .NOT. BTEST(wall_flags_0(k_mm,j,i),2)    .OR.    &
+                              .NOT. BTEST(wall_flags_0(k_ppp,j,i),2) ) .AND.   & 
+                                  BTEST(wall_flags_0(k-1,j,i),2)  .AND.        &
+                                  BTEST(wall_flags_0(k,j,i),2)    .AND.        &
+                                  BTEST(wall_flags_0(k+1,j,i),2)  .AND.        &
+                                  BTEST(wall_flags_0(k_pp,j,i),2)  .OR.        &
+                                  k == nzt - 1 )                               &
+                   THEN
+                      advc_flags_1(k,j,i) = IBSET( advc_flags_1(k,j,i), 25 )
                       flag_set = .TRUE.
-                   ELSEIF ( k > nzb_v_inner(j,i) .AND. .NOT. flag_set )  THEN
-                      wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i), 26 )
+                   ELSEIF ( BTEST(wall_flags_0(k_mm,j,i),2)  .AND.             &
+                            BTEST(wall_flags_0(k-1,j,i),2)   .AND.             &
+                            BTEST(wall_flags_0(k,j,i),2)     .AND.             &
+                            BTEST(wall_flags_0(k+1,j,i),2)   .AND.             &
+                            BTEST(wall_flags_0(k_pp,j,i),2)  .AND.             &
+                            BTEST(wall_flags_0(k_ppp,j,i),2) .AND.             &
+                            .NOT. flag_set )                                   &
+                   THEN
+                      advc_flags_1(k,j,i) = IBSET( advc_flags_1(k,j,i), 26 )
                    ENDIF
 
@@ -711,10 +834,10 @@
 !--                Since fluxes are swapped in advec_ws.f90, this is necessary to 
 !--                in order to handle the left/south flux.
-                   wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i), 27 )
-                   wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i), 30 )
+                   advc_flags_1(k,j,i) = IBSET( advc_flags_1(k,j,i), 27 )
+                   advc_flags_1(k,j,i) = IBSET( advc_flags_1(k,j,i), 30 )
 !
 !--                w component - x-direction
 !--                WS1 (27), WS3 (28), WS5 (29)
-                   IF ( k <= nzb_w_inner(j,i+1) .OR.                           &
+                   IF ( .NOT. BTEST(wall_flags_0(k,j,i+1),3) .OR.              &
                             ( ( inflow_l .OR. outflow_l .OR. nest_bound_l )    &
                               .AND. i == nxl   )    .OR.                       &
@@ -722,8 +845,8 @@
                               .AND. i == nxr   ) )                             &
                    THEN
-                      wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i), 27 )
-                   ELSEIF ( ( k <= nzb_w_inner(j,i+2) .AND.                    &
-                              k >  nzb_w_inner(j,i+1) ) .OR.                   &
-                              k <= nzb_w_inner(j,i-1)                          &
+                      advc_flags_1(k,j,i) = IBSET( advc_flags_1(k,j,i), 27 )
+                   ELSEIF ( ( .NOT. BTEST(wall_flags_0(k,j,i+2),3)  .AND.      &
+                                    BTEST(wall_flags_0(k,j,i+1),3)  .OR.       &
+                              .NOT. BTEST(wall_flags_0(k,j,i-1),3) )           &
                                                         .OR.                   &
                             ( ( inflow_r .OR. outflow_r .OR. nest_bound_r )    &
@@ -732,20 +855,21 @@
                               .AND. i == nxlu  ) )                             &
                    THEN
-                      wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i), 28 )
+                      advc_flags_1(k,j,i) = IBSET( advc_flags_1(k,j,i), 28 )
 !   
 !--                   Clear flag for WS1
-                      wall_flags_0(k,j,i) = IBCLR( wall_flags_0(k,j,i), 27 )
-                   ELSEIF ( k > nzb_w_inner(j,i+1) .AND. k > nzb_w_inner(j,i+2)   &
-                                                   .AND. k > nzb_w_inner(j,i-1) ) &
+                      advc_flags_1(k,j,i) = IBCLR( advc_flags_1(k,j,i), 27 )
+                   ELSEIF ( BTEST(wall_flags_0(k,j,i+1),3)  .AND.              &
+                            BTEST(wall_flags_0(k,j,i+2),3)  .AND.              &
+                            BTEST(wall_flags_0(k,j,i-1),3) )                   &
                    THEN
-                      wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i),29 )
+                      advc_flags_1(k,j,i) = IBSET( advc_flags_1(k,j,i),29 )
 !   
 !--                   Clear flag for WS1
-                      wall_flags_0(k,j,i) = IBCLR( wall_flags_0(k,j,i), 27 )
+                      advc_flags_1(k,j,i) = IBCLR( advc_flags_1(k,j,i), 27 )
                    ENDIF
 !
 !--                w component - y-direction
 !--                WS1 (30), WS3 (31), WS5 (32)
-                   IF ( k <= nzb_w_inner(j+1,i) .OR.                           &
+                   IF ( .NOT. BTEST(wall_flags_0(k,j+1,i),3) .OR.              &
                             ( ( inflow_s .OR. outflow_s .OR. nest_bound_s )    &
                               .AND. j == nys   )    .OR.                       &
@@ -753,8 +877,8 @@
                               .AND. j == nyn   ) )                             &
                    THEN
-                      wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i), 30 )
-                   ELSEIF ( ( k <= nzb_w_inner(j+2,i) .AND.                    &
-                              k >  nzb_w_inner(j+1,i) ) .OR.                   &
-                               k <= nzb_w_inner(j-1,i)                         &
+                      advc_flags_1(k,j,i) = IBSET( advc_flags_1(k,j,i), 30 )
+                   ELSEIF ( ( .NOT. BTEST(wall_flags_0(k,j+2,i),3)  .AND.      &
+                                    BTEST(wall_flags_0(k,j+1,i),3)  .OR.       &
+                              .NOT. BTEST(wall_flags_0(k,j-1,i),3) )           &
                                                         .OR.                   &
                             ( ( inflow_s .OR. outflow_s .OR. nest_bound_s )    &
@@ -763,15 +887,16 @@
                               .AND. j == nyn-1 ) )                             &
                    THEN
-                      wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i), 31 )
+                      advc_flags_1(k,j,i) = IBSET( advc_flags_1(k,j,i), 31 )
 !
 !--                   Clear flag for WS1
-                      wall_flags_0(k,j,i) = IBCLR( wall_flags_0(k,j,i), 30 )
-                   ELSEIF ( k > nzb_w_inner(j+1,i) .AND. k > nzb_w_inner(j+2,i)   &
-                                                   .AND. k > nzb_w_inner(j-1,i) ) &
+                      advc_flags_1(k,j,i) = IBCLR( advc_flags_1(k,j,i), 30 )
+                   ELSEIF ( BTEST(wall_flags_0(k,j+1,i),3)  .AND.              &
+                            BTEST(wall_flags_0(k,j+2,i),3)  .AND.              &
+                            BTEST(wall_flags_0(k,j-1,i),3) )                   &
                    THEN
-                      wall_flags_00(k,j,i) = IBSET( wall_flags_00(k,j,i), 0 )
+                      advc_flags_2(k,j,i) = IBSET( advc_flags_2(k,j,i), 0 )
 !
 !--                   Clear flag for WS1
-                      wall_flags_0(k,j,i) = IBCLR( wall_flags_0(k,j,i), 30 )
+                      advc_flags_1(k,j,i) = IBCLR( advc_flags_1(k,j,i), 30 )
                    ENDIF
 !
@@ -779,6 +904,29 @@
 !--                WS1 (33), WS3 (34), WS5 (35)
                    flag_set = .FALSE.
-                   IF ( k == nzb_w_inner(j,i) .OR. k == nzb_w_inner(j,i) + 1   &
-                                              .OR. k == nzt )  THEN
+                   IF ( k == nzb+1 )  THEN
+                      k_mm = nzb
+                   ELSE
+                      k_mm = k - 2
+                   ENDIF
+                   IF ( k > nzt-1 )  THEN
+                      k_pp = nzt+1
+                   ELSE 
+                      k_pp = k + 2
+                   ENDIF
+                   IF ( k > nzt-2 )  THEN
+                      k_ppp = nzt+1
+                   ELSE 
+                      k_ppp = k + 3
+                   ENDIF  
+                   
+                   IF ( ( .NOT. BTEST(wall_flags_0(k-1,j,i),3)  .AND.          &
+                          .NOT. BTEST(wall_flags_0(k,j,i),3)    .AND.          &
+                                BTEST(wall_flags_0(k+1,j,i),3) )  .OR.         &
+                        ( .NOT. BTEST(wall_flags_0(k-1,j,i),3)  .AND.          &
+                                BTEST(wall_flags_0(k,j,i),3) )  .OR.           &
+                        ( .NOT. BTEST(wall_flags_0(k+1,j,i),3)  .AND.          &
+                                BTEST(wall_flags_0(k,j,i),3) )  .OR.           &        
+                        k == nzt )                                             &
+                   THEN
 !
 !--                   Please note, at k == nzb_w_inner(j,i) a flag is explictely
@@ -787,11 +935,24 @@
 !--                   because flux_t(nzb_w_inner(j,i)) is used for the tendency
 !--                   at k == nzb_w_inner(j,i)+1.
-                      wall_flags_00(k,j,i) = IBSET( wall_flags_00(k,j,i), 1 )
+                      advc_flags_2(k,j,i) = IBSET( advc_flags_2(k,j,i), 1 )
                       flag_set = .TRUE.
-                   ELSEIF ( k == nzb_w_inner(j,i) + 2 .OR. k == nzt - 1 )  THEN
-                      wall_flags_00(k,j,i) = IBSET( wall_flags_00(k,j,i), 2 )
+                   ELSEIF ( ( .NOT. BTEST(wall_flags_0(k_mm,j,i),3)     .OR.   &
+                              .NOT. BTEST(wall_flags_0(k_ppp,j,i),3) ) .AND.   &
+                                    BTEST(wall_flags_0(k-1,j,i),3)  .AND.      &
+                                    BTEST(wall_flags_0(k,j,i),3)    .AND.      &
+                                    BTEST(wall_flags_0(k+1,j,i),3)  .OR.       &
+                            k == nzt - 1 )                                     &
+                   THEN
+                      advc_flags_2(k,j,i) = IBSET( advc_flags_2(k,j,i), 2 )
                       flag_set = .TRUE.
-                   ELSEIF ( k > nzb_w_inner(j,i) .AND. .NOT. flag_set )  THEN
-                      wall_flags_00(k,j,i) = IBSET( wall_flags_00(k,j,i), 3 )
+                   ELSEIF ( BTEST(wall_flags_0(k_mm,j,i),3)  .AND.             &
+                            BTEST(wall_flags_0(k-1,j,i),3)   .AND.             &
+                            BTEST(wall_flags_0(k,j,i),3)     .AND.             &
+                            BTEST(wall_flags_0(k+1,j,i),3)   .AND.             &
+                            BTEST(wall_flags_0(k_pp,j,i),3)  .AND.             &
+                            BTEST(wall_flags_0(k_ppp,j,i),3) .AND.             &
+                            .NOT. flag_set )                                   &
+                   THEN
+                      advc_flags_2(k,j,i) = IBSET( advc_flags_2(k,j,i), 3 )
                    ENDIF
 
@@ -809,27 +970,27 @@
 !
 !--       Exchange ghost points for advection flags
-          CALL exchange_horiz_int( wall_flags_0,  nbgp )
-          CALL exchange_horiz_int( wall_flags_00, nbgp )
+          CALL exchange_horiz_int( advc_flags_1, nbgp )
+          CALL exchange_horiz_int( advc_flags_2, nbgp )
 !
 !--       Set boundary flags at inflow and outflow boundary in case of 
 !--       non-cyclic boundary conditions.
          IF ( inflow_l .OR. outflow_l .OR. nest_bound_l )  THEN
-             wall_flags_0(:,:,nxl-1)  = wall_flags_0(:,:,nxl)
-             wall_flags_00(:,:,nxl-1) = wall_flags_00(:,:,nxl)
+             advc_flags_1(:,:,nxl-1) = advc_flags_1(:,:,nxl)
+             advc_flags_2(:,:,nxl-1) = advc_flags_2(:,:,nxl)
          ENDIF
 
          IF ( inflow_r .OR. outflow_r .OR. nest_bound_r )  THEN
-            wall_flags_0(:,:,nxr+1)  = wall_flags_0(:,:,nxr)
-            wall_flags_00(:,:,nxr+1) = wall_flags_00(:,:,nxr)
+            advc_flags_1(:,:,nxr+1) = advc_flags_1(:,:,nxr)
+            advc_flags_2(:,:,nxr+1) = advc_flags_2(:,:,nxr)
           ENDIF
 
           IF ( inflow_n .OR. outflow_n .OR. nest_bound_n )  THEN
-             wall_flags_0(:,nyn+1,:)  = wall_flags_0(:,nyn,:)
-             wall_flags_00(:,nyn+1,:) = wall_flags_00(:,nyn,:)
+             advc_flags_1(:,nyn+1,:) = advc_flags_1(:,nyn,:)
+             advc_flags_2(:,nyn+1,:) = advc_flags_2(:,nyn,:)
           ENDIF
 
           IF ( inflow_s .OR. outflow_s  .OR. nest_bound_s )  THEN
-             wall_flags_0(:,nys-1,:)  = wall_flags_0(:,nys,:)
-             wall_flags_00(:,nys-1,:) = wall_flags_00(:,nys,:)
+             advc_flags_1(:,nys-1,:) = advc_flags_1(:,nys,:)
+             advc_flags_2(:,nys-1,:) = advc_flags_2(:,nys,:)
           ENDIF
   
@@ -910,5 +1071,5 @@
        USE indices,                                                            &
            ONLY:  nxl, nxlg, nxr, nxrg, nyn, nyng, nys, nysg, nzb, nzb_max,    &
-                  nzt, wall_flags_0
+                  nzt, advc_flags_1
 
        USE kinds
@@ -976,7 +1137,7 @@
           DO  k = nzb+1, nzb_max
 
-             ibit5 = IBITS(wall_flags_0(k,j-1,i),5,1)
-             ibit4 = IBITS(wall_flags_0(k,j-1,i),4,1)
-             ibit3 = IBITS(wall_flags_0(k,j-1,i),3,1)
+             ibit5 = IBITS(advc_flags_1(k,j-1,i),5,1)
+             ibit4 = IBITS(advc_flags_1(k,j-1,i),4,1)
+             ibit3 = IBITS(advc_flags_1(k,j-1,i),3,1)
 
              v_comp                  = v(k,j,i) - v_gtrans
@@ -1037,7 +1198,7 @@
           DO  k = nzb+1, nzb_max
 
-             ibit2 = IBITS(wall_flags_0(k,j,i-1),2,1)
-             ibit1 = IBITS(wall_flags_0(k,j,i-1),1,1)
-             ibit0 = IBITS(wall_flags_0(k,j,i-1),0,1)
+             ibit2 = IBITS(advc_flags_1(k,j,i-1),2,1)
+             ibit1 = IBITS(advc_flags_1(k,j,i-1),1,1)
+             ibit0 = IBITS(advc_flags_1(k,j,i-1),0,1)
 
              u_comp                     = u(k,j,i) - u_gtrans
@@ -1106,7 +1267,7 @@
 !--       flux at the end. 
 
-          ibit2 = IBITS(wall_flags_0(k,j,i),2,1)
-          ibit1 = IBITS(wall_flags_0(k,j,i),1,1)
-          ibit0 = IBITS(wall_flags_0(k,j,i),0,1)
+          ibit2 = IBITS(advc_flags_1(k,j,i),2,1)
+          ibit1 = IBITS(advc_flags_1(k,j,i),1,1)
+          ibit0 = IBITS(advc_flags_1(k,j,i),0,1)
 
           u_comp    = u(k,j,i+1) - u_gtrans
@@ -1141,7 +1302,7 @@
                                        )
 
-          ibit5 = IBITS(wall_flags_0(k,j,i),5,1)
-          ibit4 = IBITS(wall_flags_0(k,j,i),4,1)
-          ibit3 = IBITS(wall_flags_0(k,j,i),3,1)
+          ibit5 = IBITS(advc_flags_1(k,j,i),5,1)
+          ibit4 = IBITS(advc_flags_1(k,j,i),4,1)
+          ibit3 = IBITS(advc_flags_1(k,j,i),3,1)
 
           v_comp    = v(k,j+1,i) - v_gtrans
@@ -1178,7 +1339,7 @@
 !--       k index has to be modified near bottom and top, else array
 !--       subscripts will be exceeded.
-          ibit8 = IBITS(wall_flags_0(k,j,i),8,1)
-          ibit7 = IBITS(wall_flags_0(k,j,i),7,1)
-          ibit6 = IBITS(wall_flags_0(k,j,i),6,1)
+          ibit8 = IBITS(advc_flags_1(k,j,i),8,1)
+          ibit7 = IBITS(advc_flags_1(k,j,i),7,1)
+          ibit6 = IBITS(advc_flags_1(k,j,i),6,1)
 
           k_ppp = k + 3 * ibit8
@@ -1220,13 +1381,13 @@
 !--       by a not sufficient reduction of divergences near topography. 
           div         =   ( u(k,j,i+1) * ( ibit0 + ibit1 + ibit2 )             &
-                          - u(k,j,i)   * ( IBITS(wall_flags_0(k,j,i-1),0,1)    &
-                                         + IBITS(wall_flags_0(k,j,i-1),1,1)    &
-                                         + IBITS(wall_flags_0(k,j,i-1),2,1)    &
+                          - u(k,j,i)   * ( IBITS(advc_flags_1(k,j,i-1),0,1)    &
+                                         + IBITS(advc_flags_1(k,j,i-1),1,1)    &
+                                         + IBITS(advc_flags_1(k,j,i-1),2,1)    &
                                          )                                     &
                           ) * rho_air(k) * ddx                                 &
                         + ( v(k,j+1,i) * ( ibit3 + ibit4 + ibit5 )             &
-                          - v(k,j,i)   * ( IBITS(wall_flags_0(k,j-1,i),3,1)    &
-                                         + IBITS(wall_flags_0(k,j-1,i),4,1)    &
-                                         + IBITS(wall_flags_0(k,j-1,i),5,1)    &
+                          - v(k,j,i)   * ( IBITS(advc_flags_1(k,j-1,i),3,1)    &
+                                         + IBITS(advc_flags_1(k,j-1,i),4,1)    &
+                                         + IBITS(advc_flags_1(k,j-1,i),5,1)    &
                                          )                                     &
                           ) * rho_air(k) * ddy                                 &
@@ -1234,7 +1395,7 @@
                                          ( ibit6 + ibit7 + ibit8 )             &
                           - w(k-1,j,i) * rho_air_zw(k-1) *                     &
-                                         ( IBITS(wall_flags_0(k-1,j,i),6,1)    &
-                                         + IBITS(wall_flags_0(k-1,j,i),7,1)    &
-                                         + IBITS(wall_flags_0(k-1,j,i),8,1)    &
+                                         ( IBITS(advc_flags_1(k-1,j,i),6,1)    &
+                                         + IBITS(advc_flags_1(k-1,j,i),7,1)    &
+                                         + IBITS(advc_flags_1(k-1,j,i),8,1)    &
                                          )                                     &      
                           ) * ddzw(k)
@@ -1287,7 +1448,7 @@
 !--       k index has to be modified near bottom and top, else array
 !--       subscripts will be exceeded.
-          ibit8 = IBITS(wall_flags_0(k,j,i),8,1)
-          ibit7 = IBITS(wall_flags_0(k,j,i),7,1)
-          ibit6 = IBITS(wall_flags_0(k,j,i),6,1)
+          ibit8 = IBITS(advc_flags_1(k,j,i),8,1)
+          ibit7 = IBITS(advc_flags_1(k,j,i),7,1)
+          ibit6 = IBITS(advc_flags_1(k,j,i),6,1)
 
           k_ppp = k + 3 * ibit8
@@ -1450,5 +1611,5 @@
 
        USE indices,                                                           &
-           ONLY:  nxl, nxr, nyn, nys, nzb, nzb_max, nzt, wall_flags_0
+           ONLY:  nxl, nxr, nyn, nys, nzb, nzb_max, nzt, advc_flags_1
 
        USE kinds
@@ -1502,7 +1663,7 @@
           DO  k = nzb+1, nzb_max
 
-             ibit14 = IBITS(wall_flags_0(k,j-1,i),14,1)
-             ibit13 = IBITS(wall_flags_0(k,j-1,i),13,1)
-             ibit12 = IBITS(wall_flags_0(k,j-1,i),12,1)
+             ibit14 = IBITS(advc_flags_1(k,j-1,i),14,1)
+             ibit13 = IBITS(advc_flags_1(k,j-1,i),13,1)
+             ibit12 = IBITS(advc_flags_1(k,j-1,i),12,1)
 
              v_comp      = v(k,j,i) + v(k,j,i-1) - gv
@@ -1560,7 +1721,7 @@
           DO  k = nzb+1, nzb_max
 
-             ibit11 = IBITS(wall_flags_0(k,j,i-1),11,1)
-             ibit10 = IBITS(wall_flags_0(k,j,i-1),10,1)
-             ibit9  = IBITS(wall_flags_0(k,j,i-1),9,1)
+             ibit11 = IBITS(advc_flags_1(k,j,i-1),11,1)
+             ibit10 = IBITS(advc_flags_1(k,j,i-1),10,1)
+             ibit9  = IBITS(advc_flags_1(k,j,i-1),9,1)
 
              u_comp_l         = u(k,j,i) + u(k,j,i-1) - gu
@@ -1622,7 +1783,7 @@
        DO  k = nzb+1, nzb_max
 
-          ibit11 = IBITS(wall_flags_0(k,j,i),11,1)
-          ibit10 = IBITS(wall_flags_0(k,j,i),10,1)
-          ibit9  = IBITS(wall_flags_0(k,j,i),9,1)
+          ibit11 = IBITS(advc_flags_1(k,j,i),11,1)
+          ibit10 = IBITS(advc_flags_1(k,j,i),10,1)
+          ibit9  = IBITS(advc_flags_1(k,j,i),9,1)
 
           u_comp(k) = u(k,j,i+1) + u(k,j,i)
@@ -1657,7 +1818,7 @@
                                                 )
 
-          ibit14 = IBITS(wall_flags_0(k,j,i),14,1)
-          ibit13 = IBITS(wall_flags_0(k,j,i),13,1)
-          ibit12 = IBITS(wall_flags_0(k,j,i),12,1)
+          ibit14 = IBITS(advc_flags_1(k,j,i),14,1)
+          ibit13 = IBITS(advc_flags_1(k,j,i),13,1)
+          ibit12 = IBITS(advc_flags_1(k,j,i),12,1)
 
           v_comp    = v(k,j+1,i) + v(k,j+1,i-1) - gv
@@ -1694,7 +1855,7 @@
 !--       k index has to be modified near bottom and top, else array
 !--       subscripts will be exceeded.
-          ibit17 = IBITS(wall_flags_0(k,j,i),17,1)
-          ibit16 = IBITS(wall_flags_0(k,j,i),16,1)
-          ibit15 = IBITS(wall_flags_0(k,j,i),15,1)
+          ibit17 = IBITS(advc_flags_1(k,j,i),17,1)
+          ibit16 = IBITS(advc_flags_1(k,j,i),16,1)
+          ibit15 = IBITS(advc_flags_1(k,j,i),15,1)
 
           k_ppp = k + 3 * ibit17
@@ -1738,21 +1899,21 @@
           div = ( ( u_comp(k)       * ( ibit9 + ibit10 + ibit11 )             &
                 - ( u(k,j,i)   + u(k,j,i-1)   )                               &
-                                    * ( IBITS(wall_flags_0(k,j,i-1),9,1)      &
-                                      + IBITS(wall_flags_0(k,j,i-1),10,1)     &
-                                      + IBITS(wall_flags_0(k,j,i-1),11,1)     &
+                                    * ( IBITS(advc_flags_1(k,j,i-1),9,1)      &
+                                      + IBITS(advc_flags_1(k,j,i-1),10,1)     &
+                                      + IBITS(advc_flags_1(k,j,i-1),11,1)     &
                                       )                                       &
                   ) * rho_air(k) * ddx                                        &
                +  ( ( v_comp + gv ) * ( ibit12 + ibit13 + ibit14 )            &
                   - ( v(k,j,i)   + v(k,j,i-1 )  )                             &
-                                    * ( IBITS(wall_flags_0(k,j-1,i),12,1)     &
-                                      + IBITS(wall_flags_0(k,j-1,i),13,1)     &
-                                      + IBITS(wall_flags_0(k,j-1,i),14,1)     &
+                                    * ( IBITS(advc_flags_1(k,j-1,i),12,1)     &
+                                      + IBITS(advc_flags_1(k,j-1,i),13,1)     &
+                                      + IBITS(advc_flags_1(k,j-1,i),14,1)     &
                                       )                                       &
                   ) * rho_air(k) * ddy                                        &
                +  ( w_comp * rho_air_zw(k) * ( ibit15 + ibit16 + ibit17 )     &
                 - ( w(k-1,j,i) + w(k-1,j,i-1) ) * rho_air_zw(k-1)             &
-                                    * ( IBITS(wall_flags_0(k-1,j,i),15,1)     &
-                                      + IBITS(wall_flags_0(k-1,j,i),16,1)     &
-                                      + IBITS(wall_flags_0(k-1,j,i),17,1)     &
+                                    * ( IBITS(advc_flags_1(k-1,j,i),15,1)     &
+                                      + IBITS(advc_flags_1(k-1,j,i),16,1)     &
+                                      + IBITS(advc_flags_1(k-1,j,i),17,1)     &
                                       )                                       &  
                   ) * ddzw(k)   &
@@ -1823,7 +1984,7 @@
 !--       k index has to be modified near bottom and top, else array
 !--       subscripts will be exceeded.
-          ibit17 = IBITS(wall_flags_0(k,j,i),17,1)
-          ibit16 = IBITS(wall_flags_0(k,j,i),16,1)
-          ibit15 = IBITS(wall_flags_0(k,j,i),15,1)
+          ibit17 = IBITS(advc_flags_1(k,j,i),17,1)
+          ibit16 = IBITS(advc_flags_1(k,j,i),16,1)
+          ibit15 = IBITS(advc_flags_1(k,j,i),15,1)
 
           k_ppp = k + 3 * ibit17
@@ -1942,5 +2103,5 @@
 
        USE indices,                                                            &
-           ONLY:  nxl, nxr, nyn, nys, nysv, nzb, nzb_max, nzt, wall_flags_0
+           ONLY:  nxl, nxr, nyn, nys, nysv, nzb, nzb_max, nzt, advc_flags_1
 
        USE kinds
@@ -1995,7 +2156,7 @@
           DO  k = nzb+1, nzb_max
 
-             ibit20 = IBITS(wall_flags_0(k,j,i-1),20,1)
-             ibit19 = IBITS(wall_flags_0(k,j,i-1),19,1)
-             ibit18 = IBITS(wall_flags_0(k,j,i-1),18,1)
+             ibit20 = IBITS(advc_flags_1(k,j,i-1),20,1)
+             ibit19 = IBITS(advc_flags_1(k,j,i-1),19,1)
+             ibit18 = IBITS(advc_flags_1(k,j,i-1),18,1)
 
              u_comp           = u(k,j-1,i) + u(k,j,i) - gu
@@ -2053,7 +2214,7 @@
           DO  k = nzb+1, nzb_max
 
-             ibit23 = IBITS(wall_flags_0(k,j-1,i),23,1)
-             ibit22 = IBITS(wall_flags_0(k,j-1,i),22,1)
-             ibit21 = IBITS(wall_flags_0(k,j-1,i),21,1)
+             ibit23 = IBITS(advc_flags_1(k,j-1,i),23,1)
+             ibit22 = IBITS(advc_flags_1(k,j-1,i),22,1)
+             ibit21 = IBITS(advc_flags_1(k,j-1,i),21,1)
 
              v_comp_l       = v(k,j,i) + v(k,j-1,i) - gv
@@ -2115,7 +2276,7 @@
        DO  k = nzb+1, nzb_max
 
-          ibit20 = IBITS(wall_flags_0(k,j,i),20,1)
-          ibit19 = IBITS(wall_flags_0(k,j,i),19,1)
-          ibit18 = IBITS(wall_flags_0(k,j,i),18,1)
+          ibit20 = IBITS(advc_flags_1(k,j,i),20,1)
+          ibit19 = IBITS(advc_flags_1(k,j,i),19,1)
+          ibit18 = IBITS(advc_flags_1(k,j,i),18,1)
  
           u_comp    = u(k,j-1,i+1) + u(k,j,i+1) - gu
@@ -2150,7 +2311,7 @@
                                         )
 
-          ibit23 = IBITS(wall_flags_0(k,j,i),23,1)
-          ibit22 = IBITS(wall_flags_0(k,j,i),22,1)
-          ibit21 = IBITS(wall_flags_0(k,j,i),21,1)
+          ibit23 = IBITS(advc_flags_1(k,j,i),23,1)
+          ibit22 = IBITS(advc_flags_1(k,j,i),22,1)
+          ibit21 = IBITS(advc_flags_1(k,j,i),21,1)
 
 
@@ -2188,7 +2349,7 @@
 !--       k index has to be modified near bottom and top, else array
 !--       subscripts will be exceeded.
-          ibit26 = IBITS(wall_flags_0(k,j,i),26,1)
-          ibit25 = IBITS(wall_flags_0(k,j,i),25,1)
-          ibit24 = IBITS(wall_flags_0(k,j,i),24,1)
+          ibit26 = IBITS(advc_flags_1(k,j,i),26,1)
+          ibit25 = IBITS(advc_flags_1(k,j,i),25,1)
+          ibit24 = IBITS(advc_flags_1(k,j,i),24,1)
 
           k_ppp = k + 3 * ibit26
@@ -2233,7 +2394,7 @@
                                        * ( ibit18 + ibit19 + ibit20 )         &
                   - ( u(k,j-1,i) + u(k,j,i) )                                 &
-                                       * ( IBITS(wall_flags_0(k,j,i-1),18,1)  &
-                                         + IBITS(wall_flags_0(k,j,i-1),19,1)  &
-                                         + IBITS(wall_flags_0(k,j,i-1),20,1)  &
+                                       * ( IBITS(advc_flags_1(k,j,i-1),18,1)  &
+                                         + IBITS(advc_flags_1(k,j,i-1),19,1)  &
+                                         + IBITS(advc_flags_1(k,j,i-1),20,1)  &
                                          )                                    &
                   ) * rho_air(k) * ddx                                        &
@@ -2241,14 +2402,14 @@
                                        * ( ibit21 + ibit22 + ibit23 )         &
                 - ( v(k,j,i)     + v(k,j-1,i) )                               &
-                                       * ( IBITS(wall_flags_0(k,j-1,i),21,1)  &
-                                         + IBITS(wall_flags_0(k,j-1,i),22,1)  &
-                                         + IBITS(wall_flags_0(k,j-1,i),23,1)  &
+                                       * ( IBITS(advc_flags_1(k,j-1,i),21,1)  &
+                                         + IBITS(advc_flags_1(k,j-1,i),22,1)  &
+                                         + IBITS(advc_flags_1(k,j-1,i),23,1)  &
                                          )                                    &
                   ) * rho_air(k) * ddy                                        &
                +  ( w_comp * rho_air_zw(k) * ( ibit24 + ibit25 + ibit26 )     &
                 - ( w(k-1,j-1,i) + w(k-1,j,i) ) * rho_air_zw(k-1)             &
-                                       * ( IBITS(wall_flags_0(k-1,j,i),24,1)  &
-                                         + IBITS(wall_flags_0(k-1,j,i),25,1)  &
-                                         + IBITS(wall_flags_0(k-1,j,i),26,1)  &
+                                       * ( IBITS(advc_flags_1(k-1,j,i),24,1)  &
+                                         + IBITS(advc_flags_1(k-1,j,i),25,1)  &
+                                         + IBITS(advc_flags_1(k-1,j,i),26,1)  &
                                          )                                    &
                    ) * ddzw(k)   &
@@ -2324,7 +2485,7 @@
 !--       k index has to be modified near bottom and top, else array
 !--       subscripts will be exceeded.
-          ibit26 = IBITS(wall_flags_0(k,j,i),26,1)
-          ibit25 = IBITS(wall_flags_0(k,j,i),25,1)
-          ibit24 = IBITS(wall_flags_0(k,j,i),24,1)
+          ibit26 = IBITS(advc_flags_1(k,j,i),26,1)
+          ibit25 = IBITS(advc_flags_1(k,j,i),25,1)
+          ibit24 = IBITS(advc_flags_1(k,j,i),24,1)
 
           k_ppp = k + 3 * ibit26
@@ -2443,6 +2604,6 @@
 
        USE indices,                                                           &
-           ONLY:  nxl, nxr, nyn, nys, nzb, nzb_max, nzt, wall_flags_0,        &
-                  wall_flags_00
+           ONLY:  nxl, nxr, nyn, nys, nzb, nzb_max, nzt, advc_flags_1,        &
+                  advc_flags_2
 
        USE kinds
@@ -2495,7 +2656,7 @@
 
           DO  k = nzb+1, nzb_max
-             ibit32 = IBITS(wall_flags_00(k,j-1,i),0,1)
-             ibit31 = IBITS(wall_flags_0(k,j-1,i),31,1)
-             ibit30 = IBITS(wall_flags_0(k,j-1,i),30,1)
+             ibit32 = IBITS(advc_flags_2(k,j-1,i),0,1)
+             ibit31 = IBITS(advc_flags_1(k,j-1,i),31,1)
+             ibit30 = IBITS(advc_flags_1(k,j-1,i),30,1)
 
              v_comp         = v(k+1,j,i) + v(k,j,i) - gv
@@ -2553,7 +2714,7 @@
           DO  k = nzb+1, nzb_max
 
-             ibit29 = IBITS(wall_flags_0(k,j,i-1),29,1)
-             ibit28 = IBITS(wall_flags_0(k,j,i-1),28,1)
-             ibit27 = IBITS(wall_flags_0(k,j,i-1),27,1)
+             ibit29 = IBITS(advc_flags_1(k,j,i-1),29,1)
+             ibit28 = IBITS(advc_flags_1(k,j,i-1),28,1)
+             ibit27 = IBITS(advc_flags_1(k,j,i-1),27,1)
 
              u_comp           = u(k+1,j,i) + u(k,j,i) - gu
@@ -2608,5 +2769,5 @@
 !--    The lower flux has to be calculated explicetely for the tendency at
 !--    the first w-level. For topography wall this is done implicitely by
-!--    wall_flags_0.
+!--    advc_flags_1.
        k         = nzb + 1
        w_comp    = w(k,j,i) + w(k-1,j,i)
@@ -2620,7 +2781,7 @@
        DO  k = nzb+1, nzb_max
 
-          ibit29 = IBITS(wall_flags_0(k,j,i),29,1)
-          ibit28 = IBITS(wall_flags_0(k,j,i),28,1)
-          ibit27 = IBITS(wall_flags_0(k,j,i),27,1)
+          ibit29 = IBITS(advc_flags_1(k,j,i),29,1)
+          ibit28 = IBITS(advc_flags_1(k,j,i),28,1)
+          ibit27 = IBITS(advc_flags_1(k,j,i),27,1)
 
           u_comp    = u(k+1,j,i+1) + u(k,j,i+1) - gu
@@ -2655,7 +2816,7 @@
                                         )
 
-          ibit32 = IBITS(wall_flags_00(k,j,i),0,1)
-          ibit31 = IBITS(wall_flags_0(k,j,i),31,1)
-          ibit30 = IBITS(wall_flags_0(k,j,i),30,1)
+          ibit32 = IBITS(advc_flags_2(k,j,i),0,1)
+          ibit31 = IBITS(advc_flags_1(k,j,i),31,1)
+          ibit30 = IBITS(advc_flags_1(k,j,i),30,1)
 
           v_comp    = v(k+1,j+1,i) + v(k,j+1,i) - gv
@@ -2692,7 +2853,7 @@
 !--       k index has to be modified near bottom and top, else array
 !--       subscripts will be exceeded.
-          ibit35 = IBITS(wall_flags_00(k,j,i),3,1)
-          ibit34 = IBITS(wall_flags_00(k,j,i),2,1)
-          ibit33 = IBITS(wall_flags_00(k,j,i),1,1)
+          ibit35 = IBITS(advc_flags_2(k,j,i),3,1)
+          ibit34 = IBITS(advc_flags_2(k,j,i),2,1)
+          ibit33 = IBITS(advc_flags_2(k,j,i),1,1)
 
           k_ppp = k + 3 * ibit35
@@ -2737,21 +2898,21 @@
           div = ( ( ( u_comp + gu ) * ( ibit27 + ibit28 + ibit29 )            &
                   - ( u(k+1,j,i) + u(k,j,i)   )                               & 
-                                    * ( IBITS(wall_flags_0(k,j,i-1),27,1)     &
-                                      + IBITS(wall_flags_0(k,j,i-1),28,1)     &
-                                      + IBITS(wall_flags_0(k,j,i-1),29,1)     &
+                                    * ( IBITS(advc_flags_1(k,j,i-1),27,1)     &
+                                      + IBITS(advc_flags_1(k,j,i-1),28,1)     &
+                                      + IBITS(advc_flags_1(k,j,i-1),29,1)     &
                                       )                                       &
                   ) * rho_air_zw(k) * ddx                                     &
               +   ( ( v_comp + gv ) * ( ibit30 + ibit31 + ibit32 )            & 
                   - ( v(k+1,j,i) + v(k,j,i)   )                               &
-                                    * ( IBITS(wall_flags_0(k,j-1,i),30,1)     &
-                                      + IBITS(wall_flags_0(k,j-1,i),31,1)     &
-                                      + IBITS(wall_flags_00(k,j-1,i),0,1)     &
+                                    * ( IBITS(advc_flags_1(k,j-1,i),30,1)     &
+                                      + IBITS(advc_flags_1(k,j-1,i),31,1)     &
+                                      + IBITS(advc_flags_2(k,j-1,i),0,1)      &
                                       )                                       &
                   ) * rho_air_zw(k) * ddy                                     &
               +   ( w_comp * rho_air(k+1) * ( ibit33 + ibit34 + ibit35 )      &
                 - ( w(k,j,i)   + w(k-1,j,i)   ) * rho_air(k)                  &
-                                    * ( IBITS(wall_flags_00(k-1,j,i),1,1)     &
-                                      + IBITS(wall_flags_00(k-1,j,i),2,1)     &
-                                      + IBITS(wall_flags_00(k-1,j,i),3,1)     &
+                                    * ( IBITS(advc_flags_2(k-1,j,i),1,1)      &
+                                      + IBITS(advc_flags_2(k-1,j,i),2,1)      &
+                                      + IBITS(advc_flags_2(k-1,j,i),3,1)      &
                                       )                                       & 
                   ) * ddzu(k+1)   &
@@ -2814,7 +2975,7 @@
 !--       k index has to be modified near bottom and top, else array
 !--       subscripts will be exceeded.
-          ibit35 = IBITS(wall_flags_00(k,j,i),3,1)
-          ibit34 = IBITS(wall_flags_00(k,j,i),2,1)
-          ibit33 = IBITS(wall_flags_00(k,j,i),1,1)
+          ibit35 = IBITS(advc_flags_2(k,j,i),3,1)
+          ibit34 = IBITS(advc_flags_2(k,j,i),2,1)
+          ibit33 = IBITS(advc_flags_2(k,j,i),1,1)
 
           k_ppp = k + 3 * ibit35
@@ -2919,5 +3080,5 @@
        USE indices,                                                           &
            ONLY:  nxl, nxlg, nxr, nxrg, nyn, nyng, nys, nysg, nzb, nzb_max,   &
-                  nzt, wall_flags_0
+                  nzt, advc_flags_1
            
        USE kinds
@@ -2983,7 +3144,7 @@
           DO  k = nzb+1, nzb_max
 
-             ibit2 = IBITS(wall_flags_0(k,j,i-1),2,1)
-             ibit1 = IBITS(wall_flags_0(k,j,i-1),1,1)
-             ibit0 = IBITS(wall_flags_0(k,j,i-1),0,1)
+             ibit2 = IBITS(advc_flags_1(k,j,i-1),2,1)
+             ibit1 = IBITS(advc_flags_1(k,j,i-1),1,1)
+             ibit0 = IBITS(advc_flags_1(k,j,i-1),0,1)
 
              u_comp                 = u(k,j,i) - u_gtrans
@@ -3044,7 +3205,7 @@
           DO  k = nzb+1, nzb_max
 
-             ibit5 = IBITS(wall_flags_0(k,j-1,i),5,1)
-             ibit4 = IBITS(wall_flags_0(k,j-1,i),4,1)
-             ibit3 = IBITS(wall_flags_0(k,j-1,i),3,1)
+             ibit5 = IBITS(advc_flags_1(k,j-1,i),5,1)
+             ibit4 = IBITS(advc_flags_1(k,j-1,i),4,1)
+             ibit3 = IBITS(advc_flags_1(k,j-1,i),3,1)
 
              v_comp               = v(k,j,i) - v_gtrans
@@ -3107,7 +3268,7 @@
              DO  k = nzb+1, nzb_max
 
-                ibit2 = IBITS(wall_flags_0(k,j,i),2,1)
-                ibit1 = IBITS(wall_flags_0(k,j,i),1,1)
-                ibit0 = IBITS(wall_flags_0(k,j,i),0,1)
+                ibit2 = IBITS(advc_flags_1(k,j,i),2,1)
+                ibit1 = IBITS(advc_flags_1(k,j,i),1,1)
+                ibit0 = IBITS(advc_flags_1(k,j,i),0,1)
 
                 u_comp    = u(k,j,i+1) - u_gtrans
@@ -3142,7 +3303,7 @@
                                              )
 
-                ibit5 = IBITS(wall_flags_0(k,j,i),5,1)
-                ibit4 = IBITS(wall_flags_0(k,j,i),4,1)
-                ibit3 = IBITS(wall_flags_0(k,j,i),3,1)
+                ibit5 = IBITS(advc_flags_1(k,j,i),5,1)
+                ibit4 = IBITS(advc_flags_1(k,j,i),4,1)
+                ibit3 = IBITS(advc_flags_1(k,j,i),3,1)
 
                 v_comp    = v(k,j+1,i) - v_gtrans
@@ -3179,7 +3340,7 @@
 !--             k index has to be modified near bottom and top, else array
 !--             subscripts will be exceeded.
-                ibit8 = IBITS(wall_flags_0(k,j,i),8,1)
-                ibit7 = IBITS(wall_flags_0(k,j,i),7,1)
-                ibit6 = IBITS(wall_flags_0(k,j,i),6,1)
+                ibit8 = IBITS(advc_flags_1(k,j,i),8,1)
+                ibit7 = IBITS(advc_flags_1(k,j,i),7,1)
+                ibit6 = IBITS(advc_flags_1(k,j,i),6,1)
 
                 k_ppp = k + 3 * ibit8
@@ -3221,13 +3382,13 @@
 !--             by a not sufficient reduction of divergences near topography.
                 div   =   ( u(k,j,i+1) * ( ibit0 + ibit1 + ibit2 )             &
-                          - u(k,j,i)   * ( IBITS(wall_flags_0(k,j,i-1),0,1)    &
-                                         + IBITS(wall_flags_0(k,j,i-1),1,1)    &
-                                         + IBITS(wall_flags_0(k,j,i-1),2,1)    &
+                          - u(k,j,i)   * ( IBITS(advc_flags_1(k,j,i-1),0,1)    &
+                                         + IBITS(advc_flags_1(k,j,i-1),1,1)    &
+                                         + IBITS(advc_flags_1(k,j,i-1),2,1)    &
                                          )                                     &
                           ) * rho_air(k) * ddx                                 &
                         + ( v(k,j+1,i) * ( ibit3 + ibit4 + ibit5 )             &
-                          - v(k,j,i)   * ( IBITS(wall_flags_0(k,j-1,i),3,1)    &
-                                         + IBITS(wall_flags_0(k,j-1,i),4,1)    &
-                                         + IBITS(wall_flags_0(k,j-1,i),5,1)    &
+                          - v(k,j,i)   * ( IBITS(advc_flags_1(k,j-1,i),3,1)    &
+                                         + IBITS(advc_flags_1(k,j-1,i),4,1)    &
+                                         + IBITS(advc_flags_1(k,j-1,i),5,1)    &
                                          )                                     &
                           ) * rho_air(k) * ddy                                 &
@@ -3235,7 +3396,7 @@
                                          ( ibit6 + ibit7 + ibit8 )             &
                           - w(k-1,j,i) * rho_air_zw(k-1) *                     &
-                                         ( IBITS(wall_flags_0(k-1,j,i),6,1)    &
-                                         + IBITS(wall_flags_0(k-1,j,i),7,1)    &
-                                         + IBITS(wall_flags_0(k-1,j,i),8,1)    &
+                                         ( IBITS(advc_flags_1(k-1,j,i),6,1)    &
+                                         + IBITS(advc_flags_1(k-1,j,i),7,1)    &
+                                         + IBITS(advc_flags_1(k-1,j,i),8,1)    &
                                          )                                     &      
                           ) * ddzw(k)
@@ -3285,7 +3446,7 @@
 !--             k index has to be modified near bottom and top, else array
 !--             subscripts will be exceeded.
-                ibit8 = IBITS(wall_flags_0(k,j,i),8,1)
-                ibit7 = IBITS(wall_flags_0(k,j,i),7,1)
-                ibit6 = IBITS(wall_flags_0(k,j,i),6,1)
+                ibit8 = IBITS(advc_flags_1(k,j,i),8,1)
+                ibit7 = IBITS(advc_flags_1(k,j,i),7,1)
+                ibit6 = IBITS(advc_flags_1(k,j,i),6,1)
 
                 k_ppp = k + 3 * ibit8
@@ -3429,5 +3590,4 @@
 
 
-
 !------------------------------------------------------------------------------!
 ! Description:
@@ -3450,5 +3610,5 @@
 
        USE indices,                                                            &
-           ONLY:  nxl, nxlu, nxr, nyn, nys, nzb, nzb_max, nzt, wall_flags_0
+           ONLY:  nxl, nxlu, nxr, nyn, nys, nzb, nzb_max, nzt, advc_flags_1
            
        USE kinds
@@ -3507,7 +3667,7 @@
           DO  k = nzb+1, nzb_max
 
-             ibit11 = IBITS(wall_flags_0(k,j,i-1),11,1)
-             ibit10 = IBITS(wall_flags_0(k,j,i-1),10,1)
-             ibit9  = IBITS(wall_flags_0(k,j,i-1),9,1)
+             ibit11 = IBITS(advc_flags_1(k,j,i-1),11,1)
+             ibit10 = IBITS(advc_flags_1(k,j,i-1),10,1)
+             ibit9  = IBITS(advc_flags_1(k,j,i-1),9,1)
 
              u_comp(k)                = u(k,j,i) + u(k,j,i-1) - gu
@@ -3565,7 +3725,7 @@
           DO  k = nzb+1, nzb_max
 
-             ibit14 = IBITS(wall_flags_0(k,j-1,i),14,1)
-             ibit13 = IBITS(wall_flags_0(k,j-1,i),13,1)
-             ibit12 = IBITS(wall_flags_0(k,j-1,i),12,1)
+             ibit14 = IBITS(advc_flags_1(k,j-1,i),14,1)
+             ibit13 = IBITS(advc_flags_1(k,j-1,i),13,1)
+             ibit12 = IBITS(advc_flags_1(k,j-1,i),12,1)
 
              v_comp                 = v(k,j,i) + v(k,j,i-1) - gv
@@ -3626,7 +3786,7 @@
              DO  k = nzb+1, nzb_max
 
-                ibit11 = IBITS(wall_flags_0(k,j,i),11,1)
-                ibit10 = IBITS(wall_flags_0(k,j,i),10,1)
-                ibit9  = IBITS(wall_flags_0(k,j,i),9,1)
+                ibit11 = IBITS(advc_flags_1(k,j,i),11,1)
+                ibit10 = IBITS(advc_flags_1(k,j,i),10,1)
+                ibit9  = IBITS(advc_flags_1(k,j,i),9,1)
 
                 u_comp(k) = u(k,j,i+1) + u(k,j,i)
@@ -3661,7 +3821,7 @@
                                                      )
 
-                ibit14 = IBITS(wall_flags_0(k,j,i),14,1)
-                ibit13 = IBITS(wall_flags_0(k,j,i),13,1)
-                ibit12 = IBITS(wall_flags_0(k,j,i),12,1)
+                ibit14 = IBITS(advc_flags_1(k,j,i),14,1)
+                ibit13 = IBITS(advc_flags_1(k,j,i),13,1)
+                ibit12 = IBITS(advc_flags_1(k,j,i),12,1)
 
                 v_comp    = v(k,j+1,i) + v(k,j+1,i-1) - gv
@@ -3698,7 +3858,7 @@
 !--             k index has to be modified near bottom and top, else array
 !--             subscripts will be exceeded.
-                ibit17 = IBITS(wall_flags_0(k,j,i),17,1)
-                ibit16 = IBITS(wall_flags_0(k,j,i),16,1)
-                ibit15 = IBITS(wall_flags_0(k,j,i),15,1)
+                ibit17 = IBITS(advc_flags_1(k,j,i),17,1)
+                ibit16 = IBITS(advc_flags_1(k,j,i),16,1)
+                ibit15 = IBITS(advc_flags_1(k,j,i),15,1)
 
                 k_ppp = k + 3 * ibit17
@@ -3742,21 +3902,21 @@
                 div = ( ( u_comp(k) * ( ibit9 + ibit10 + ibit11 )             &
                 - ( u(k,j,i)   + u(k,j,i-1)   )                               &
-                                    * ( IBITS(wall_flags_0(k,j,i-1),9,1)      &
-                                      + IBITS(wall_flags_0(k,j,i-1),10,1)     &
-                                      + IBITS(wall_flags_0(k,j,i-1),11,1)     &
+                                    * ( IBITS(advc_flags_1(k,j,i-1),9,1)      &
+                                      + IBITS(advc_flags_1(k,j,i-1),10,1)     &
+                                      + IBITS(advc_flags_1(k,j,i-1),11,1)     &
                                       )                                       &
                   ) * rho_air(k) * ddx                                        &
                +  ( ( v_comp + gv ) * ( ibit12 + ibit13 + ibit14 )            &
                   - ( v(k,j,i)   + v(k,j,i-1 )  )                             &
-                                    * ( IBITS(wall_flags_0(k,j-1,i),12,1)     &
-                                      + IBITS(wall_flags_0(k,j-1,i),13,1)     &
-                                      + IBITS(wall_flags_0(k,j-1,i),14,1)     &
+                                    * ( IBITS(advc_flags_1(k,j-1,i),12,1)     &
+                                      + IBITS(advc_flags_1(k,j-1,i),13,1)     &
+                                      + IBITS(advc_flags_1(k,j-1,i),14,1)     &
                                       )                                       &
                   ) * rho_air(k) * ddy                                        &
                +  ( w_comp * rho_air_zw(k) * ( ibit15 + ibit16 + ibit17 )     &
                 - ( w(k-1,j,i) + w(k-1,j,i-1) ) * rho_air_zw(k-1)             &
-                                    * ( IBITS(wall_flags_0(k-1,j,i),15,1)     &
-                                      + IBITS(wall_flags_0(k-1,j,i),16,1)     &
-                                      + IBITS(wall_flags_0(k-1,j,i),17,1)     &
+                                    * ( IBITS(advc_flags_1(k-1,j,i),15,1)     &
+                                      + IBITS(advc_flags_1(k-1,j,i),16,1)     &
+                                      + IBITS(advc_flags_1(k-1,j,i),17,1)     &
                                       )                                       &  
                   ) * ddzw(k)   &
@@ -3829,7 +3989,7 @@
 !--             k index has to be modified near bottom and top, else array
 !--             subscripts will be exceeded.
-                ibit17 = IBITS(wall_flags_0(k,j,i),17,1)
-                ibit16 = IBITS(wall_flags_0(k,j,i),16,1)
-                ibit15 = IBITS(wall_flags_0(k,j,i),15,1)
+                ibit17 = IBITS(advc_flags_1(k,j,i),17,1)
+                ibit16 = IBITS(advc_flags_1(k,j,i),16,1)
+                ibit15 = IBITS(advc_flags_1(k,j,i),15,1)
 
                 k_ppp = k + 3 * ibit17
@@ -3925,5 +4085,5 @@
     END SUBROUTINE advec_u_ws
     
-    
+
 !------------------------------------------------------------------------------!
 ! Description:
@@ -3946,5 +4106,5 @@
 
        USE indices,                                                            &
-           ONLY:  nxl, nxr, nyn, nys, nysv, nzb, nzb_max, nzt, wall_flags_0
+           ONLY:  nxl, nxr, nyn, nys, nysv, nzb, nzb_max, nzt, advc_flags_1
 
        USE kinds
@@ -4003,7 +4163,7 @@
           DO  k = nzb+1, nzb_max
 
-             ibit20 = IBITS(wall_flags_0(k,j,i-1),20,1)
-             ibit19 = IBITS(wall_flags_0(k,j,i-1),19,1)
-             ibit18 = IBITS(wall_flags_0(k,j,i-1),18,1)
+             ibit20 = IBITS(advc_flags_1(k,j,i-1),20,1)
+             ibit19 = IBITS(advc_flags_1(k,j,i-1),19,1)
+             ibit18 = IBITS(advc_flags_1(k,j,i-1),18,1)
 
              u_comp                   = u(k,j-1,i) + u(k,j,i) - gu
@@ -4061,7 +4221,7 @@
           DO  k = nzb+1, nzb_max
 
-             ibit23 = IBITS(wall_flags_0(k,j-1,i),23,1)
-             ibit22 = IBITS(wall_flags_0(k,j-1,i),22,1)
-             ibit21 = IBITS(wall_flags_0(k,j-1,i),21,1)
+             ibit23 = IBITS(advc_flags_1(k,j-1,i),23,1)
+             ibit22 = IBITS(advc_flags_1(k,j-1,i),22,1)
+             ibit21 = IBITS(advc_flags_1(k,j-1,i),21,1)
 
              v_comp(k)              = v(k,j,i) + v(k,j-1,i) - gv
@@ -4121,7 +4281,7 @@
              DO  k = nzb+1, nzb_max
 
-                ibit20 = IBITS(wall_flags_0(k,j,i),20,1)
-                ibit19 = IBITS(wall_flags_0(k,j,i),19,1)
-                ibit18 = IBITS(wall_flags_0(k,j,i),18,1)
+                ibit20 = IBITS(advc_flags_1(k,j,i),20,1)
+                ibit19 = IBITS(advc_flags_1(k,j,i),19,1)
+                ibit18 = IBITS(advc_flags_1(k,j,i),18,1)
 
                 u_comp    = u(k,j-1,i+1) + u(k,j,i+1) - gu
@@ -4156,7 +4316,7 @@
                                               )
 
-                ibit23 = IBITS(wall_flags_0(k,j,i),23,1)
-                ibit22 = IBITS(wall_flags_0(k,j,i),22,1)
-                ibit21 = IBITS(wall_flags_0(k,j,i),21,1)
+                ibit23 = IBITS(advc_flags_1(k,j,i),23,1)
+                ibit22 = IBITS(advc_flags_1(k,j,i),22,1)
+                ibit21 = IBITS(advc_flags_1(k,j,i),21,1)
 
                 v_comp(k) = v(k,j+1,i) + v(k,j,i)
@@ -4193,7 +4353,7 @@
 !--             k index has to be modified near bottom and top, else array
 !--             subscripts will be exceeded.
-                ibit26 = IBITS(wall_flags_0(k,j,i),26,1)
-                ibit25 = IBITS(wall_flags_0(k,j,i),25,1)
-                ibit24 = IBITS(wall_flags_0(k,j,i),24,1)
+                ibit26 = IBITS(advc_flags_1(k,j,i),26,1)
+                ibit25 = IBITS(advc_flags_1(k,j,i),25,1)
+                ibit24 = IBITS(advc_flags_1(k,j,i),24,1)
 
                 k_ppp = k + 3 * ibit26
@@ -4238,7 +4398,7 @@
                                        * ( ibit18 + ibit19 + ibit20 )         &
                 - ( u(k,j-1,i)   + u(k,j,i) )                                 &
-                                       * ( IBITS(wall_flags_0(k,j,i-1),18,1)  &
-                                         + IBITS(wall_flags_0(k,j,i-1),19,1)  &
-                                         + IBITS(wall_flags_0(k,j,i-1),20,1)  &
+                                       * ( IBITS(advc_flags_1(k,j,i-1),18,1)  &
+                                         + IBITS(advc_flags_1(k,j,i-1),19,1)  &
+                                         + IBITS(advc_flags_1(k,j,i-1),20,1)  &
                                          )                                    &
                   ) * rho_air(k) * ddx                                        &
@@ -4246,7 +4406,7 @@
                                        * ( ibit21 + ibit22 + ibit23 )         &
                 - ( v(k,j,i)     + v(k,j-1,i) )                               &
-                                       * ( IBITS(wall_flags_0(k,j-1,i),21,1)  &
-                                         + IBITS(wall_flags_0(k,j-1,i),22,1)  &
-                                         + IBITS(wall_flags_0(k,j-1,i),23,1)  &
+                                       * ( IBITS(advc_flags_1(k,j-1,i),21,1)  &
+                                         + IBITS(advc_flags_1(k,j-1,i),22,1)  &
+                                         + IBITS(advc_flags_1(k,j-1,i),23,1)  &
                                          )                                    &
                   ) * rho_air(k) * ddy                                        &
@@ -4254,7 +4414,7 @@
                                        * ( ibit24 + ibit25 + ibit26 )         &
                 - ( w(k-1,j-1,i) + w(k-1,j,i) ) * rho_air_zw(k-1)             &
-                                       * ( IBITS(wall_flags_0(k-1,j,i),24,1)  &
-                                         + IBITS(wall_flags_0(k-1,j,i),25,1)  &
-                                         + IBITS(wall_flags_0(k-1,j,i),26,1)  &
+                                       * ( IBITS(advc_flags_1(k-1,j,i),24,1)  &
+                                         + IBITS(advc_flags_1(k-1,j,i),25,1)  &
+                                         + IBITS(advc_flags_1(k-1,j,i),26,1)  &
                                          )                                    &
                    ) * ddzw(k)   &
@@ -4332,7 +4492,7 @@
 !--             k index has to be modified near bottom and top, else array
 !--             subscripts will be exceeded.
-                ibit26 = IBITS(wall_flags_0(k,j,i),26,1)
-                ibit25 = IBITS(wall_flags_0(k,j,i),25,1)
-                ibit24 = IBITS(wall_flags_0(k,j,i),24,1)
+                ibit26 = IBITS(advc_flags_1(k,j,i),26,1)
+                ibit25 = IBITS(advc_flags_1(k,j,i),25,1)
+                ibit24 = IBITS(advc_flags_1(k,j,i),24,1)
 
                 k_ppp = k + 3 * ibit26
@@ -4433,6 +4593,4 @@
     
     
-    
-    
 !------------------------------------------------------------------------------!
 ! Description:
@@ -4455,6 +4613,6 @@
 
        USE indices,                                                            &
-           ONLY:  nxl, nxr, nyn, nys, nzb, nzb_max, nzt, wall_flags_0,         &
-                  wall_flags_00
+           ONLY:  nxl, nxr, nyn, nys, nzb, nzb_max, nzt, advc_flags_1,         &
+                  advc_flags_2
 
        USE kinds
@@ -4512,7 +4670,7 @@
           DO  k = nzb+1, nzb_max
 
-             ibit29 = IBITS(wall_flags_0(k,j,i-1),29,1)
-             ibit28 = IBITS(wall_flags_0(k,j,i-1),28,1)
-             ibit27 = IBITS(wall_flags_0(k,j,i-1),27,1)
+             ibit29 = IBITS(advc_flags_1(k,j,i-1),29,1)
+             ibit28 = IBITS(advc_flags_1(k,j,i-1),28,1)
+             ibit27 = IBITS(advc_flags_1(k,j,i-1),27,1)
 
              u_comp                   = u(k+1,j,i) + u(k,j,i) - gu
@@ -4570,7 +4728,7 @@
           DO  k = nzb+1, nzb_max
 
-             ibit32 = IBITS(wall_flags_00(k,j-1,i),0,1)
-             ibit31 = IBITS(wall_flags_0(k,j-1,i),31,1)
-             ibit30 = IBITS(wall_flags_0(k,j-1,i),30,1)
+             ibit32 = IBITS(advc_flags_2(k,j-1,i),0,1)
+             ibit31 = IBITS(advc_flags_1(k,j-1,i),31,1)
+             ibit30 = IBITS(advc_flags_1(k,j-1,i),30,1)
 
              v_comp                 = v(k+1,j,i) + v(k,j,i) - gv
@@ -4626,5 +4784,5 @@
 !--          The lower flux has to be calculated explicetely for the tendency
 !--          at the first w-level. For topography wall this is done implicitely
-!--          by wall_flags_0.
+!--          by advc_flags_1.
              k         = nzb + 1
              w_comp    = w(k,j,i) + w(k-1,j,i)
@@ -4636,7 +4794,7 @@
              DO  k = nzb+1, nzb_max
 
-                ibit29 = IBITS(wall_flags_0(k,j,i),29,1)
-                ibit28 = IBITS(wall_flags_0(k,j,i),28,1)
-                ibit27 = IBITS(wall_flags_0(k,j,i),27,1)
+                ibit29 = IBITS(advc_flags_1(k,j,i),29,1)
+                ibit28 = IBITS(advc_flags_1(k,j,i),28,1)
+                ibit27 = IBITS(advc_flags_1(k,j,i),27,1)
 
                 u_comp    = u(k+1,j,i+1) + u(k,j,i+1) - gu
@@ -4671,7 +4829,7 @@
                                               )
 
-                ibit32 = IBITS(wall_flags_00(k,j,i),0,1)
-                ibit31 = IBITS(wall_flags_0(k,j,i),31,1)
-                ibit30 = IBITS(wall_flags_0(k,j,i),30,1)
+                ibit32 = IBITS(advc_flags_2(k,j,i),0,1)
+                ibit31 = IBITS(advc_flags_1(k,j,i),31,1)
+                ibit30 = IBITS(advc_flags_1(k,j,i),30,1)
 
                 v_comp    = v(k+1,j+1,i) + v(k,j+1,i) - gv
@@ -4708,7 +4866,7 @@
 !--             k index has to be modified near bottom and top, else array
 !--             subscripts will be exceeded.
-                ibit35 = IBITS(wall_flags_00(k,j,i),3,1)
-                ibit34 = IBITS(wall_flags_00(k,j,i),2,1)
-                ibit33 = IBITS(wall_flags_00(k,j,i),1,1)
+                ibit35 = IBITS(advc_flags_2(k,j,i),3,1)
+                ibit34 = IBITS(advc_flags_2(k,j,i),2,1)
+                ibit33 = IBITS(advc_flags_2(k,j,i),1,1)
 
                 k_ppp = k + 3 * ibit35
@@ -4752,21 +4910,21 @@
                 div = ( ( ( u_comp + gu ) * ( ibit27 + ibit28 + ibit29 )      &
                   - ( u(k+1,j,i) + u(k,j,i)   )                               & 
-                                    * ( IBITS(wall_flags_0(k,j,i-1),27,1)     &
-                                      + IBITS(wall_flags_0(k,j,i-1),28,1)     &
-                                      + IBITS(wall_flags_0(k,j,i-1),29,1)     &
+                                    * ( IBITS(advc_flags_1(k,j,i-1),27,1)     &
+                                      + IBITS(advc_flags_1(k,j,i-1),28,1)     &
+                                      + IBITS(advc_flags_1(k,j,i-1),29,1)     &
                                       )                                       &
                   ) * rho_air_zw(k) * ddx                                     &
               +   ( ( v_comp + gv ) * ( ibit30 + ibit31 + ibit32 )            &
                   - ( v(k+1,j,i) + v(k,j,i)   )                               &
-                                    * ( IBITS(wall_flags_0(k,j-1,i),30,1)     &
-                                      + IBITS(wall_flags_0(k,j-1,i),31,1)     &
-                                      + IBITS(wall_flags_00(k,j-1,i),0,1)     &
+                                    * ( IBITS(advc_flags_1(k,j-1,i),30,1)     &
+                                      + IBITS(advc_flags_1(k,j-1,i),31,1)     &
+                                      + IBITS(advc_flags_2(k,j-1,i),0,1)      &
                                       )                                       &
                   ) * rho_air_zw(k) * ddy                                     &
               +   ( w_comp * rho_air(k+1) * ( ibit33 + ibit34 + ibit35 )      &
                 - ( w(k,j,i)   + w(k-1,j,i)   ) * rho_air(k)                  &
-                                    * ( IBITS(wall_flags_00(k-1,j,i),1,1)     &
-                                      + IBITS(wall_flags_00(k-1,j,i),2,1)     &
-                                      + IBITS(wall_flags_00(k-1,j,i),3,1)     &
+                                    * ( IBITS(advc_flags_2(k-1,j,i),1,1)      &
+                                      + IBITS(advc_flags_2(k-1,j,i),2,1)      &
+                                      + IBITS(advc_flags_2(k-1,j,i),3,1)      &
                                       )                                       & 
                   ) * ddzu(k+1)   &
@@ -4831,7 +4989,7 @@
 !--             k index has to be modified near bottom and top, else array
 !--             subscripts will be exceeded.
-                ibit35 = IBITS(wall_flags_00(k,j,i),3,1)
-                ibit34 = IBITS(wall_flags_00(k,j,i),2,1)
-                ibit33 = IBITS(wall_flags_00(k,j,i),1,1)
+                ibit35 = IBITS(advc_flags_2(k,j,i),3,1)
+                ibit34 = IBITS(advc_flags_2(k,j,i),2,1)
+                ibit33 = IBITS(advc_flags_2(k,j,i),1,1)
 
                 k_ppp = k + 3 * ibit35
@@ -4916,4 +5074,3 @@
     END SUBROUTINE advec_w_ws
 
-
  END MODULE advec_ws
Index: /palm/trunk/SOURCE/average_3d_data.f90
===================================================================
--- /palm/trunk/SOURCE/average_3d_data.f90	(revision 2231)
+++ /palm/trunk/SOURCE/average_3d_data.f90	(revision 2232)
@@ -20,5 +20,6 @@
 ! Current revisions:
 ! -----------------
-! 
+! Adjustments to new surface concept - additional ghost point exchange 
+! of surface variable required
 ! 
 ! Former revisions:
@@ -104,5 +105,6 @@
 
     USE control_parameters,                                                    &
-        ONLY:  average_count_3d, doav, doav_n, urban_surface, varnamelength
+        ONLY:  average_count_3d, doav, doav_n, land_surface, urban_surface,    &
+               varnamelength
 
     USE cpulog,                                                                &
@@ -110,10 +112,10 @@
 
     USE indices,                                                               &
-        ONLY:  nxl, nxlg, nxr, nxrg, nyn, nyng, nys, nysg, nzb, nzt
+        ONLY:  nbgp, nxl, nxlg, nxr, nxrg, nyn, nyng, nys, nysg, nzb, nzt
 
     USE kinds
 
     USE land_surface_model_mod,                                                &
-        ONLY:  land_surface, lsm_3d_data_averaging
+        ONLY:  lsm_3d_data_averaging
 
     USE radiation_model_mod,                                                   &
@@ -171,4 +173,5 @@
                 ENDDO
              ENDDO
+             CALL exchange_horiz_2d( qsws_av, nbgp )
 
           CASE ( 'lpt' )
@@ -203,4 +206,5 @@
                 ENDDO
              ENDDO
+             CALL exchange_horiz_2d( ol_av, nbgp )
 
           CASE ( 'p' )
@@ -354,4 +358,5 @@
                 ENDDO
              ENDDO
+             CALL exchange_horiz_2d( shf_av, nbgp )
 
           CASE ( 'ssws*' )
@@ -361,4 +366,5 @@
                 ENDDO
              ENDDO
+             CALL exchange_horiz_2d( ssws_av, nbgp )
 
           CASE ( 't*' )
@@ -368,4 +374,5 @@
                 ENDDO
              ENDDO
+             CALL exchange_horiz_2d( ts_av, nbgp )
 
           CASE ( 'u' )
@@ -384,4 +391,5 @@
                 ENDDO
              ENDDO
+             CALL exchange_horiz_2d( us_av, nbgp )
 
           CASE ( 'v' )
@@ -418,4 +426,5 @@
                 ENDDO
              ENDDO
+             CALL exchange_horiz_2d( z0_av, nbgp )
 
           CASE ( 'z0h*' )
@@ -425,4 +434,5 @@
                 ENDDO
              ENDDO
+             CALL exchange_horiz_2d( z0h_av, nbgp )
 !             
 !--       Block of urban surface model outputs   
Index: /palm/trunk/SOURCE/boundary_conds.f90
===================================================================
--- /palm/trunk/SOURCE/boundary_conds.f90	(revision 2231)
+++ /palm/trunk/SOURCE/boundary_conds.f90	(revision 2232)
@@ -20,5 +20,5 @@
 ! Current revisions:
 ! -----------------
-! 
+! Set boundary conditions on topography top using flag method.
 ! 
 ! Former revisions:
@@ -168,5 +168,5 @@
     USE indices,                                                               &
         ONLY:  nx, nxl, nxlg, nxr, nxrg, ny, nyn, nyng, nys, nysg,             &
-               nzb, nzb_s_inner, nzb_w_inner, nzt
+               nzb, nzt, wall_flags_0
 
     USE kinds
@@ -177,10 +177,15 @@
         ONLY : nesting_mode
 
+    USE surface_mod,                                                           &
+        ONLY :  bc_h
 
     IMPLICIT NONE
 
-    INTEGER(iwp) ::  i !<
-    INTEGER(iwp) ::  j !<
-    INTEGER(iwp) ::  k !<
+    INTEGER(iwp) ::  i  !< grid index x direction
+    INTEGER(iwp) ::  j  !< grid index y direction
+    INTEGER(iwp) ::  k  !< grid index z direction
+    INTEGER(iwp) ::  kb !< variable to set respective boundary value, depends on facing. 
+    INTEGER(iwp) ::  l  !< running index boundary type, for up- and downward-facing walls
+    INTEGER(iwp) ::  m  !< running index surface elements
 
     REAL(wp)    ::  c_max !<
@@ -194,8 +199,18 @@
        v_p(nzb,:,:) = v_p(nzb+1,:,:)
     ENDIF
-
-    DO  i = nxlg, nxrg
-       DO  j = nysg, nyng
-          w_p(nzb_w_inner(j,i),j,i) = 0.0_wp
+!
+!-- Set zero vertical velocity at topography top (l=0), or bottom (l=1) in case
+!-- of downward-facing surfaces. 
+    DO  l = 0, 1
+!
+!--    Set kb, for upward-facing surfaces value at topography top (k-1) is set,
+!--    for downward-facing surfaces at topography bottom (k+1). 
+       kb = MERGE( -1, 1, l == 0 )
+       !$OMP PARALLEL DO PRIVATE( i, j, k )
+       DO  m = 1, bc_h(l)%ns
+          i = bc_h(l)%i(m)            
+          j = bc_h(l)%j(m)
+          k = bc_h(l)%k(m)
+          w_p(k+kb,j,i) = 0.0_wp
        ENDDO
     ENDDO
@@ -216,17 +231,36 @@
 
 !
-!-- Temperature at bottom boundary.
+!-- Temperature at bottom and top boundary.
 !-- In case of coupled runs (ibc_pt_b = 2) the temperature is given by
 !-- the sea surface temperature of the coupled ocean model.
+!-- Dirichlet
     IF ( ibc_pt_b == 0 )  THEN
-       DO  i = nxlg, nxrg
-          DO  j = nysg, nyng
-             pt_p(nzb_s_inner(j,i),j,i) = pt(nzb_s_inner(j,i),j,i)
+       DO  l = 0, 1
+!
+!--       Set kb, for upward-facing surfaces value at topography top (k-1) is set,
+!--       for downward-facing surfaces at topography bottom (k+1). 
+          kb = MERGE( -1, 1, l == 0 )
+          !$OMP PARALLEL DO PRIVATE( i, j, k )
+          DO  m = 1, bc_h(l)%ns
+             i = bc_h(l)%i(m)            
+             j = bc_h(l)%j(m)
+             k = bc_h(l)%k(m)
+             pt_p(k+kb,j,i) = pt(k+kb,j,i)
           ENDDO
        ENDDO
+!
+!-- Neumann, zero-gradient
     ELSEIF ( ibc_pt_b == 1 )  THEN
-       DO  i = nxlg, nxrg
-          DO  j = nysg, nyng
-             pt_p(nzb_s_inner(j,i),j,i) = pt_p(nzb_s_inner(j,i)+1,j,i)
+       DO  l = 0, 1
+!
+!--       Set kb, for upward-facing surfaces value at topography top (k-1) is set,
+!--       for downward-facing surfaces at topography bottom (k+1). 
+          kb = MERGE( -1, 1, l == 0 )
+          !$OMP PARALLEL DO PRIVATE( i, j, k )
+          DO  m = 1, bc_h(l)%ns
+             i = bc_h(l)%i(m)            
+             j = bc_h(l)%j(m)
+             k = bc_h(l)%k(m)
+             pt_p(k+kb,j,i) = pt_p(k,j,i)
           ENDDO
        ENDDO
@@ -253,9 +287,19 @@
 !-- Generally Neumann conditions with de/dz=0 are assumed
     IF ( .NOT. constant_diffusion )  THEN
-       DO  i = nxlg, nxrg
-          DO  j = nysg, nyng
-             e_p(nzb_s_inner(j,i),j,i) = e_p(nzb_s_inner(j,i)+1,j,i)
+
+       DO  l = 0, 1
+!
+!--       Set kb, for upward-facing surfaces value at topography top (k-1) is set,
+!--       for downward-facing surfaces at topography bottom (k+1). 
+          kb = MERGE( -1, 1, l == 0 )
+          !$OMP PARALLEL DO PRIVATE( i, j, k )
+          DO  m = 1, bc_h(l)%ns
+             i = bc_h(l)%i(m)            
+             j = bc_h(l)%j(m)
+             k = bc_h(l)%k(m)
+             e_p(k+kb,j,i) = e_p(k,j,i)
           ENDDO
        ENDDO
+
        IF ( .NOT. nest_domain )  THEN
           e_p(nzt+1,:,:) = e_p(nzt,:,:)
@@ -268,11 +312,18 @@
 !
 !--    Bottom boundary: Neumann condition because salinity flux is always
-!--    given
-       DO  i = nxlg, nxrg
-          DO  j = nysg, nyng
-             sa_p(nzb_s_inner(j,i),j,i) = sa_p(nzb_s_inner(j,i)+1,j,i)
+!--    given.
+       DO  l = 0, 1
+!
+!--       Set kb, for upward-facing surfaces value at topography top (k-1) is set,
+!--       for downward-facing surfaces at topography bottom (k+1). 
+          kb = MERGE( -1, 1, l == 0 )
+          !$OMP PARALLEL DO PRIVATE( i, j, k )
+          DO  m = 1, bc_h(l)%ns
+             i = bc_h(l)%i(m)            
+             j = bc_h(l)%j(m)
+             k = bc_h(l)%k(m)
+             sa_p(k+kb,j,i) = sa_p(k,j,i)
           ENDDO
        ENDDO
-
 !
 !--    Top boundary: Dirichlet or Neumann
@@ -291,14 +342,43 @@
 !
 !--    Surface conditions for constant_humidity_flux
+!--    Run loop over all non-natural and natural walls. Note, in wall-datatype
+!--    the k coordinate belongs to the atmospheric grid point, therefore, set
+!--    q_p at k-1
        IF ( ibc_q_b == 0 ) THEN
-          DO  i = nxlg, nxrg
-             DO  j = nysg, nyng
-                q_p(nzb_s_inner(j,i),j,i) = q(nzb_s_inner(j,i),j,i)
+
+          DO  l = 0, 1
+!
+!--          Set kb, for upward-facing surfaces value at topography top (k-1) is set,
+!--          for downward-facing surfaces at topography bottom (k+1). 
+             kb = MERGE( -1, 1, l == 0 )
+             !$OMP PARALLEL DO PRIVATE( i, j, k )
+             DO  m = 1, bc_h(l)%ns
+                i = bc_h(l)%i(m)            
+                j = bc_h(l)%j(m)
+                k = bc_h(l)%k(m)
+                q_p(k+kb,j,i) = q(k+kb,j,i)
              ENDDO
           ENDDO
+          
        ELSE
-          DO  i = nxlg, nxrg
-             DO  j = nysg, nyng
-                q_p(nzb_s_inner(j,i),j,i) = q_p(nzb_s_inner(j,i)+1,j,i)
+          !$OMP PARALLEL DO PRIVATE( i, j, k )
+          DO  m = 1, bc_h(0)%ns
+             i = bc_h(0)%i(m)            
+             j = bc_h(0)%j(m)
+             k = bc_h(0)%k(m)
+             q_p(k-1,j,i) = q_p(k,j,i)
+          ENDDO
+          
+          DO  l = 0, 1
+!
+!--          Set kb, for upward-facing surfaces value at topography top (k-1) is set,
+!--          for downward-facing surfaces at topography bottom (k+1). 
+             kb = MERGE( -1, 1, l == 0 )
+             !$OMP PARALLEL DO PRIVATE( i, j, k )
+             DO  m = 1, bc_h(l)%ns
+                i = bc_h(l)%i(m)            
+                j = bc_h(l)%j(m)
+                k = bc_h(l)%k(m)
+                q_p(k+kb,j,i) = q_p(k,j,i)
              ENDDO
           ENDDO
@@ -315,9 +395,14 @@
 !             
 !--       Surface conditions rain water (Dirichlet)
-          DO  i = nxlg, nxrg
-             DO  j = nysg, nyng
-                qr_p(nzb_s_inner(j,i),j,i) = 0.0_wp
-                nr_p(nzb_s_inner(j,i),j,i) = 0.0_wp
-             ENDDO
+!--       Run loop over all non-natural and natural walls. Note, in wall-datatype
+!--       the k coordinate belongs to the atmospheric grid point, therefore, set
+!--       qr_p and nr_p at k-1
+          !$OMP PARALLEL DO PRIVATE( i, j, k )
+          DO  m = 1, bc_h(0)%ns
+             i = bc_h(0)%i(m)            
+             j = bc_h(0)%j(m)
+             k = bc_h(0)%k(m)
+             qr_p(k-1,j,i) = 0.0_wp
+             nr_p(k-1,j,i) = 0.0_wp
           ENDDO
 !
@@ -334,14 +419,43 @@
 !
 !--    Surface conditions for constant_humidity_flux
+!--    Run loop over all non-natural and natural walls. Note, in wall-datatype
+!--    the k coordinate belongs to the atmospheric grid point, therefore, set
+!--    s_p at k-1
        IF ( ibc_s_b == 0 ) THEN
-          DO  i = nxlg, nxrg
-             DO  j = nysg, nyng
-                s_p(nzb_s_inner(j,i),j,i) = s(nzb_s_inner(j,i),j,i)
+          
+          DO  l = 0, 1
+!
+!--          Set kb, for upward-facing surfaces value at topography top (k-1) is set,
+!--          for downward-facing surfaces at topography bottom (k+1). 
+             kb = MERGE( -1, 1, l == 0 )
+             !$OMP PARALLEL DO PRIVATE( i, j, k )
+             DO  m = 1, bc_h(l)%ns
+                i = bc_h(l)%i(m)            
+                j = bc_h(l)%j(m)
+                k = bc_h(l)%k(m)
+                s_p(k+kb,j,i) = s(k+kb,j,i)
              ENDDO
           ENDDO
+          
        ELSE
-          DO  i = nxlg, nxrg
-             DO  j = nysg, nyng
-                s_p(nzb_s_inner(j,i),j,i) = s_p(nzb_s_inner(j,i)+1,j,i)
+          !$OMP PARALLEL DO PRIVATE( i, j, k )
+          DO  m = 1, bc_h(0)%ns
+             i = bc_h(0)%i(m)            
+             j = bc_h(0)%j(m)
+             k = bc_h(0)%k(m)
+             s_p(k-1,j,i) = s_p(k,j,i)
+          ENDDO
+          
+          DO  l = 0, 1
+!
+!--          Set kb, for upward-facing surfaces value at topography top (k-1) is set,
+!--          for downward-facing surfaces at topography bottom (k+1). 
+             kb = MERGE( -1, 1, l == 0 )
+             !$OMP PARALLEL DO PRIVATE( i, j, k )
+             DO  m = 1, bc_h(l)%ns
+                i = bc_h(l)%i(m)            
+                j = bc_h(l)%j(m)
+                k = bc_h(l)%k(m)
+                s_p(k+kb,j,i) = s_p(k,j,i)
              ENDDO
           ENDDO
@@ -394,5 +508,5 @@
     IF ( outflow_s )  THEN
        pt_p(:,nys-1,:)     = pt_p(:,nys,:)
-       IF ( .NOT. constant_diffusion     )  e_p(:,nys-1,:) = e_p(:,nys,:)
+       IF ( .NOT. constant_diffusion )  e_p(:,nys-1,:) = e_p(:,nys,:)
        IF ( humidity )  THEN
           q_p(:,nys-1,:) = q_p(:,nys,:)
Index: /palm/trunk/SOURCE/buoyancy.f90
===================================================================
--- /palm/trunk/SOURCE/buoyancy.f90	(revision 2231)
+++ /palm/trunk/SOURCE/buoyancy.f90	(revision 2232)
@@ -20,5 +20,5 @@
 ! Current revisions:
 ! ------------------
-! 
+! Adjustments to new topography concept
 ! 
 ! Former revisions:
@@ -131,5 +131,5 @@
        USE indices,                                                            &
            ONLY:  nxl, nxlg, nxlu, nxr, nxrg, nyn, nyng, nys, nysg, nzb,       &
-                  nzb_s_inner, nzt
+                  nzt, wall_flags_0
 
        USE kinds
@@ -157,10 +157,11 @@
           DO  i = nxl, nxr
              DO  j = nys, nyn
-                DO  k = nzb_s_inner(j,i)+1, nzt-1
-                   tend(k,j,i) = tend(k,j,i) + atmos_ocean_sign * g * 0.5_wp * &
-                          (                                                    &
+                DO  k = nzb+1, nzt-1
+                   tend(k,j,i) = tend(k,j,i) + atmos_ocean_sign * g * 0.5_wp *  &
+                          (                                                     &
                              ( var(k,j,i)   - ref_state(k) )   / ref_state(k) + &
                              ( var(k+1,j,i) - ref_state(k+1) ) / ref_state(k+1) &
-                          )
+                          ) * MERGE( 1.0_wp, 0.0_wp,                            &
+                                     BTEST( wall_flags_0(k,j,i), 0 ) )
                 ENDDO
              ENDDO
@@ -178,9 +179,11 @@
              DO  i = nxlu, nxr
                 DO  j = nys, nyn
-                   DO  k = nzb_s_inner(j,i)+1, nzt-1
-                      tend(k,j,i) = tend(k,j,i) + g * sin_alpha_surface *      &
+                   DO  k = nzb+1, nzt-1
+                      tend(k,j,i) = tend(k,j,i) + g * sin_alpha_surface *         &
                            0.5_wp * ( ( pt(k,j,i-1)         + pt(k,j,i)         ) &
                                     - ( pt_slope_ref(k,i-1) + pt_slope_ref(k,i) ) &
-                                    ) / pt_surface
+                                    ) / pt_surface                                &
+                                      * MERGE( 1.0_wp, 0.0_wp,                    &
+                                               BTEST( wall_flags_0(k,j,i), 0 ) )
                    ENDDO
                 ENDDO
@@ -191,9 +194,11 @@
              DO  i = nxl, nxr
                 DO  j = nys, nyn
-                   DO  k = nzb_s_inner(j,i)+1, nzt-1
-                      tend(k,j,i) = tend(k,j,i) + g * cos_alpha_surface *      &
+                   DO  k = nzb+1, nzt-1
+                      tend(k,j,i) = tend(k,j,i) + g * cos_alpha_surface *         &
                            0.5_wp * ( ( pt(k,j,i)         + pt(k+1,j,i)         ) &
                                     - ( pt_slope_ref(k,i) + pt_slope_ref(k+1,i) ) &
-                                    ) / pt_surface
+                                    ) / pt_surface                                &
+                                      * MERGE( 1.0_wp, 0.0_wp,                    &
+                                               BTEST( wall_flags_0(k,j,i), 0 ) )
                    ENDDO
                 ENDDO
@@ -231,5 +236,5 @@
 
        USE indices,                                                            &
-           ONLY:  nxlg, nxrg, nyng, nysg, nzb, nzb_s_inner, nzt
+           ONLY:  nxlg, nxrg, nyng, nysg, nzb, nzt, wall_flags_0
 
        USE kinds
@@ -256,9 +261,11 @@
 !
 !--       Normal case: horizontal surface
-          DO  k = nzb_s_inner(j,i)+1, nzt-1
+          DO  k = nzb+1, nzt-1
               tend(k,j,i) = tend(k,j,i) + atmos_ocean_sign * g * 0.5_wp * (    &
                         ( var(k,j,i)   - ref_state(k)   ) / ref_state(k)   +   &
                         ( var(k+1,j,i) - ref_state(k+1) ) / ref_state(k+1)     &
-                                                                          )
+                                                                          )    &
+                                      * MERGE( 1.0_wp, 0.0_wp,                 &
+                                               BTEST( wall_flags_0(k,j,i), 0 ) )
           ENDDO
 
@@ -272,18 +279,22 @@
           IF ( wind_component == 1 )  THEN
 
-             DO  k = nzb_s_inner(j,i)+1, nzt-1
-                tend(k,j,i) = tend(k,j,i) + g * sin_alpha_surface *            &
+             DO  k = nzb+1, nzt-1
+                tend(k,j,i) = tend(k,j,i) + g * sin_alpha_surface *               &
                            0.5_wp * ( ( pt(k,j,i-1)         + pt(k,j,i)         ) &
                                     - ( pt_slope_ref(k,i-1) + pt_slope_ref(k,i) ) &
-                                    ) / pt_surface
+                                    ) / pt_surface                                &
+                                      * MERGE( 1.0_wp, 0.0_wp,                    &
+                                               BTEST( wall_flags_0(k,j,i), 0 ) )
              ENDDO
 
           ELSEIF ( wind_component == 3 )  THEN
 
-             DO  k = nzb_s_inner(j,i)+1, nzt-1
-                tend(k,j,i) = tend(k,j,i) + g * cos_alpha_surface *            &
+             DO  k = nzb+1, nzt-1
+                tend(k,j,i) = tend(k,j,i) + g * cos_alpha_surface *               &
                            0.5_wp * ( ( pt(k,j,i)         + pt(k+1,j,i)         ) &
                                     - ( pt_slope_ref(k,i) + pt_slope_ref(k+1,i) ) &
-                                    ) / pt_surface
+                                    ) / pt_surface                                &
+                                      * MERGE( 1.0_wp, 0.0_wp,                    &
+                                               BTEST( wall_flags_0(k,j,i), 0 ) )
              ENDDO
 
Index: /palm/trunk/SOURCE/calc_liquid_water_content.f90
===================================================================
--- /palm/trunk/SOURCE/calc_liquid_water_content.f90	(revision 2231)
+++ /palm/trunk/SOURCE/calc_liquid_water_content.f90	(revision 2232)
@@ -20,5 +20,5 @@
 ! Current revisions:
 ! -----------------
-! 
+! Adjustments to new topography concept
 ! 
 ! Former revisions:
@@ -83,5 +83,5 @@
 
     USE indices,                                                               &
-        ONLY:  nxlg, nxrg, nyng, nysg, nzb_s_inner, nzt
+        ONLY:  nxlg, nxrg, nyng, nysg, nzb, nzt, wall_flags_0
 
     USE kinds
@@ -103,5 +103,5 @@
     DO  i = nxlg, nxrg
        DO  j = nysg, nyng
-          DO  k = nzb_s_inner(j,i)+1, nzt
+          DO  k = nzb+1, nzt
 
 !
@@ -131,15 +131,25 @@
              IF ( microphysics_seifert )  THEN
                 IF ( ( q(k,j,i) - q_s - qr(k,j,i) ) > 0.0_wp ) THEN
-                   qc(k,j,i) = q(k,j,i) - q_s - qr(k,j,i)
-                   ql(k,j,i) = qc(k,j,i) + qr(k,j,i)
+                   qc(k,j,i) = ( q(k,j,i) - q_s - qr(k,j,i) )                  &
+                                      * MERGE( 1.0_wp, 0.0_wp,                 &
+                                               BTEST( wall_flags_0(k,j,i), 0 ) )
+                   ql(k,j,i) = ( qc(k,j,i) + qr(k,j,i) )                       &
+                                      * MERGE( 1.0_wp, 0.0_wp,                 &
+                                               BTEST( wall_flags_0(k,j,i), 0 ) )
                 ELSE
                    IF ( q(k,j,i) < qr(k,j,i) )  q(k,j,i) = qr(k,j,i)
                    qc(k,j,i) = 0.0_wp 
-                   ql(k,j,i) = qr(k,j,i)
+                   ql(k,j,i) = qr(k,j,i)                                       &
+                                      * MERGE( 1.0_wp, 0.0_wp,                 &
+                                               BTEST( wall_flags_0(k,j,i), 0 ) )
                 ENDIF
              ELSE
                 IF ( ( q(k,j,i) - q_s ) > 0.0_wp ) THEN
-                   qc(k,j,i) = q(k,j,i) - q_s
-                   ql(k,j,i) = qc(k,j,i)
+                   qc(k,j,i) = ( q(k,j,i) - q_s )                              &
+                                      * MERGE( 1.0_wp, 0.0_wp,                 &
+                                               BTEST( wall_flags_0(k,j,i), 0 ) )
+                   ql(k,j,i) = qc(k,j,i)                                       &
+                                      * MERGE( 1.0_wp, 0.0_wp,                 &
+                                               BTEST( wall_flags_0(k,j,i), 0 ) )
                 ELSE
                    qc(k,j,i) = 0.0_wp
Index: /palm/trunk/SOURCE/calc_mean_profile.f90
===================================================================
--- /palm/trunk/SOURCE/calc_mean_profile.f90	(revision 2231)
+++ /palm/trunk/SOURCE/calc_mean_profile.f90	(revision 2232)
@@ -20,5 +20,5 @@
 ! Current revisions:
 ! -----------------
-! 
+! Adjustments to new topography concept
 ! 
 ! Former revisions:
@@ -75,5 +75,6 @@
 
        USE indices,                                                            &
-           ONLY:  ngp_2dh_s_inner, nxl, nxr, nyn, nys, nzb, nzb_s_inner, nzt
+           ONLY:  ngp_2dh_s_inner, nxl, nxr, nyn, nys, nzb, nzb, nzt,          &
+                  wall_flags_0
 
        USE kinds
@@ -118,6 +119,8 @@
           DO  i = nxl, nxr
              DO  j =  nys, nyn
-                DO  k = nzb_s_inner(j,i), nzt+1
-                   sums_l(k,pr,tn) = sums_l(k,pr,tn) + var(k,j,i)
+                DO  k = nzb, nzt+1
+                   sums_l(k,pr,tn) = sums_l(k,pr,tn) + var(k,j,i)              &
+                                     * MERGE( 1.0_wp, 0.0_wp,                  &
+                                              BTEST( wall_flags_0(k,j,i), 22 ) )
                 ENDDO
              ENDDO
Index: /palm/trunk/SOURCE/calc_radiation.f90
===================================================================
--- /palm/trunk/SOURCE/calc_radiation.f90	(revision 2231)
+++ /palm/trunk/SOURCE/calc_radiation.f90	(revision 2232)
@@ -20,5 +20,5 @@
 ! Current revisions:
 ! -----------------
-! 
+! Adjustments to new topography concept
 ! 
 ! Former revisions:
@@ -105,5 +105,5 @@
 
        USE indices,                                                            &
-           ONLY:  nxl, nxr, nyn, nys, nzb, nzb_s_inner, nzt
+           ONLY:  nxl, nxr, nyn, nys, nzb, nzt, wall_flags_0
 
        USE kinds
@@ -153,5 +153,5 @@
              blackbody_emission(nzb) = sigma * temperature**4
 
-             DO  k = nzb_s_inner(j,i)+1, nzt
+             DO  k = nzb+1, nzt
 
                 k_help = ( nzt+nzb+1 ) - k
@@ -163,5 +163,7 @@
 
                 temperature     = pt(k,j,i) * t_d_pt(k) + l_d_cp * ql(k,j,i)
-                blackbody_emission(k) = sigma * temperature**4
+                blackbody_emission(k) = sigma * temperature**4                 &
+                                      * MERGE( 1.0_wp, 0.0_wp,                 &
+                                               BTEST( wall_flags_0(k,j,i), 0 ) )
 
              ENDDO
@@ -179,5 +181,5 @@
              impinging_flux_at_top = blackbody_emission(nzb) - 100.0_wp
 
-             DO  k = nzb_s_inner(j,i)+1, nzt
+             DO  k = nzb+1, nzt
 !
 !--             Save some computational time, but this may cause load
@@ -222,5 +224,7 @@
                    tend(k,j,i) = tend(k,j,i) -                                 &
                                 ( pt_d_t(k) / ( rho_surface * cp ) *           &
-                                  ( df_p - df_m ) / dzw(k) )
+                                  ( df_p - df_m ) / dzw(k) )                   &
+                                      * MERGE( 1.0_wp, 0.0_wp,                 &
+                                               BTEST( wall_flags_0(k,j,i), 0 ) )
 
                 ENDIF
@@ -250,5 +254,5 @@
 
        USE indices,                                                            &
-           ONLY:  nzb, nzb_s_inner, nzt
+           ONLY:  nzb, nzt, wall_flags_0
 
        USE kinds
@@ -295,5 +299,5 @@
        blackbody_emission(nzb) = sigma * temperature**4
 
-       DO  k = nzb_s_inner(j,i)+1, nzt
+       DO  k = nzb+1, nzt
           k_help = ( nzt+nzb+1 ) - k
           lwp_ground(k)   = lwp_ground(k-1) + rho_surface * ql(k,j,i) * dzw(k)
@@ -303,5 +307,7 @@
 
           temperature     = pt(k,j,i) * t_d_pt(k) + l_d_cp * ql(k,j,i)
-          blackbody_emission(k) = sigma * temperature**4
+          blackbody_emission(k) = sigma * temperature**4                       &
+                                      * MERGE( 1.0_wp, 0.0_wp,                 &
+                                               BTEST( wall_flags_0(k,j,i), 0 ) )
 
        ENDDO
@@ -318,5 +324,5 @@
        impinging_flux_at_top = blackbody_emission(nzb) - 100.0_wp
 
-       DO  k = nzb_s_inner(j,i)+1, nzt
+       DO  k = nzb+1, nzt
 !
 !--       Store some computational time,
@@ -356,5 +362,7 @@
 !--          Compute tendency term         
              tend(k,j,i) = tend(k,j,i) - ( pt_d_t(k) / ( rho_surface * cp ) *  &
-                                         ( df_p - df_m ) / dzw(k) )
+                                         ( df_p - df_m ) / dzw(k) )            &
+                                      * MERGE( 1.0_wp, 0.0_wp,                 &
+                                               BTEST( wall_flags_0(k,j,i), 0 ) )
 
           ENDIF
Index: /palm/trunk/SOURCE/check_parameters.f90
===================================================================
--- /palm/trunk/SOURCE/check_parameters.f90	(revision 2231)
+++ /palm/trunk/SOURCE/check_parameters.f90	(revision 2232)
@@ -466,5 +466,5 @@
     USE indices
     USE land_surface_model_mod,                                                &
-        ONLY: land_surface, lsm_check_data_output, lsm_check_data_output_pr,   &
+        ONLY: lsm_check_data_output, lsm_check_data_output_pr,                 &
               lsm_check_parameters
 
@@ -859,4 +859,12 @@
                         'momentum_advec = "ws-scheme"'
        CALL message( 'check_parameters', 'PA0447', 1, 2, 0, 6, 0 )
+    ENDIF
+    IF ( TRIM( approximation ) == 'anelastic'   .AND.   &
+         TRIM( psolver ) == 'multigrid' )  THEN
+       message_string = 'Anelastic approximation currently only supports: ' // &
+                        'psolver = "poisfft", ' // &
+                        'psolver = "sor" and ' // &
+                        'psolver = "multigrid_noopt"'
+       CALL message( 'check_parameters', 'PA0448', 1, 2, 0, 6, 0 )
     ENDIF
     IF ( TRIM( approximation ) == 'anelastic'   .AND.   &
Index: /palm/trunk/SOURCE/coriolis.f90
===================================================================
--- /palm/trunk/SOURCE/coriolis.f90	(revision 2231)
+++ /palm/trunk/SOURCE/coriolis.f90	(revision 2232)
@@ -20,5 +20,5 @@
 ! Current revisions:
 ! -----------------
-! 
+! Adjustments to new topography concept
 ! 
 ! Former revisions:
@@ -102,6 +102,5 @@
            
        USE indices,                                                            &
-           ONLY:  nxl, nxlu, nxr, nyn, nys, nysv, nzb_u_inner, nzb_v_inner,    &
-                  nzb_w_inner, nzt
+           ONLY:  nxl, nxlu, nxr, nyn, nys, nysv, nzb, nzt, wall_flags_0
                    
        USE kinds
@@ -110,9 +109,9 @@
 
        INTEGER(iwp) ::  component  !< 
-       INTEGER(iwp) ::  i          !< 
-       INTEGER(iwp) ::  j          !< 
-       INTEGER(iwp) ::  k          !< 
-
-
+       INTEGER(iwp) ::  i          !< running index x direction 
+       INTEGER(iwp) ::  j          !< running index y direction 
+       INTEGER(iwp) ::  k          !< running index z direction 
+
+       REAL(wp)     ::  flag       !< flag to mask topography
 !
 !--    Compute Coriolis terms for the three velocity components
@@ -124,12 +123,17 @@
              DO  i = nxlu, nxr
                 DO  j = nys, nyn
-                   DO  k = nzb_u_inner(j,i)+1, nzt
+                   DO  k = nzb+1, nzt
+!
+!--                    Predetermine flag to mask topography
+                      flag = MERGE( 1.0_wp, 0.0_wp,                            &
+                                    BTEST( wall_flags_0(k,j,i), 1 ) )
+
                       tend(k,j,i) = tend(k,j,i) + f  *    ( 0.25_wp *          &
                                    ( v(k,j,i-1) + v(k,j,i) + v(k,j+1,i-1) +    &
-                                     v(k,j+1,i) ) - vg(k) )                    &
+                                     v(k,j+1,i) ) - vg(k)   ) * flag           &
                                                 - fs *    ( 0.25_wp *          &
                                    ( w(k-1,j,i-1) + w(k-1,j,i) + w(k,j,i-1) +  &
-                                     w(k,j,i)   ) &
-                                                          )
+                                     w(k,j,i)   )                              &
+                                                          )   * flag
                    ENDDO
                 ENDDO
@@ -141,8 +145,10 @@
              DO  i = nxl, nxr
                 DO  j = nysv, nyn
-                   DO  k = nzb_v_inner(j,i)+1, nzt
+                   DO  k = nzb+1, nzt
                       tend(k,j,i) = tend(k,j,i) - f *     ( 0.25_wp *          &
                                    ( u(k,j-1,i) + u(k,j,i) + u(k,j-1,i+1) +    &
-                                     u(k,j,i+1) ) - ug(k) )
+                                     u(k,j,i+1) ) - ug(k) ) *                  &
+                                      MERGE( 1.0_wp, 0.0_wp,                   &
+                                             BTEST( wall_flags_0(k,j,i), 2 ) )
                    ENDDO
                 ENDDO
@@ -154,8 +160,10 @@
              DO  i = nxl, nxr
                 DO  j = nys, nyn
-                   DO  k = nzb_w_inner(j,i)+1, nzt
+                   DO  k = nzb+1, nzt
                       tend(k,j,i) = tend(k,j,i) + fs * 0.25_wp *               &
                                    ( u(k,j,i) + u(k+1,j,i) + u(k,j,i+1) +      &
-                                     u(k+1,j,i+1) )
+                                     u(k+1,j,i+1) ) *                          &
+                                      MERGE( 1.0_wp, 0.0_wp,                   &
+                                             BTEST( wall_flags_0(k,j,i), 3 ) )
                    ENDDO
                 ENDDO
@@ -186,5 +194,5 @@
            
        USE indices,                                                            &
-           ONLY:  nzb_u_inner, nzb_v_inner, nzb_w_inner, nzt
+           ONLY:  nzb, nzt, wall_flags_0
            
        USE kinds
@@ -193,7 +201,9 @@
 
        INTEGER(iwp) ::  component  !< 
-       INTEGER(iwp) ::  i          !<
-       INTEGER(iwp) ::  j          !< 
-       INTEGER(iwp) ::  k          !<
+       INTEGER(iwp) ::  i          !< running index x direction 
+       INTEGER(iwp) ::  j          !< running index y direction 
+       INTEGER(iwp) ::  k          !< running index z direction 
+
+       REAL(wp)     ::  flag       !< flag to mask topography
 
 !
@@ -204,11 +214,15 @@
 !--       u-component
           CASE ( 1 )
-             DO  k = nzb_u_inner(j,i)+1, nzt
-                tend(k,j,i) = tend(k,j,i) + f  *    ( 0.25_wp *                &
+             DO  k = nzb+1, nzt
+!
+!--             Predetermine flag to mask topography
+                flag = MERGE( 1.0_wp, 0.0_wp, BTEST( wall_flags_0(k,j,i), 1 ) )
+
+                tend(k,j,i) = tend(k,j,i) + f  *     ( 0.25_wp *               &
                                 ( v(k,j,i-1) + v(k,j,i) + v(k,j+1,i-1) +       &
-                                  v(k,j+1,i) ) - vg(k) )                       &
+                                  v(k,j+1,i) ) - vg(k) ) * flag                &
                                           - fs *    ( 0.25_wp *                &
                                 ( w(k-1,j,i-1) + w(k-1,j,i) + w(k,j,i-1) +     &
-                                  w(k,j,i)   ) )
+                                  w(k,j,i)   )      ) * flag
              ENDDO
 
@@ -216,8 +230,10 @@
 !--       v-component
           CASE ( 2 )
-             DO  k = nzb_v_inner(j,i)+1, nzt
-                tend(k,j,i) = tend(k,j,i) - f *     ( 0.25_wp *                &
+             DO  k = nzb+1, nzt
+                tend(k,j,i) = tend(k,j,i) - f *        ( 0.25_wp *             &
                                 ( u(k,j-1,i) + u(k,j,i) + u(k,j-1,i+1) +       &
-                                  u(k,j,i+1) ) - ug(k) )
+                                  u(k,j,i+1) ) - ug(k) ) *                     &
+                                      MERGE( 1.0_wp, 0.0_wp,                   &
+                                             BTEST( wall_flags_0(k,j,i), 2 ) )
              ENDDO
 
@@ -225,8 +241,10 @@
 !--       w-component
           CASE ( 3 )
-             DO  k = nzb_w_inner(j,i)+1, nzt
+             DO  k = nzb+1, nzt
                 tend(k,j,i) = tend(k,j,i) + fs * 0.25_wp *                     &
                                 ( u(k,j,i) + u(k+1,j,i) + u(k,j,i+1) +         &
-                                  u(k+1,j,i+1) )
+                                  u(k+1,j,i+1) ) *                             &
+                                      MERGE( 1.0_wp, 0.0_wp,                   &
+                                             BTEST( wall_flags_0(k,j,i), 3 ) )
              ENDDO
 
Index: /palm/trunk/SOURCE/data_output_2d.f90
===================================================================
--- /palm/trunk/SOURCE/data_output_2d.f90	(revision 2231)
+++ /palm/trunk/SOURCE/data_output_2d.f90	(revision 2232)
@@ -20,4 +20,5 @@
 ! Current revisions:
 ! -----------------
+! Adjustments to new surface concept
 ! 
 !
@@ -162,7 +163,7 @@
 
     USE arrays_3d,                                                             &
-        ONLY:  dzw, e, nr, ol, p, pt, precipitation_amount, precipitation_rate,&
-               prr,q, qc, ql, ql_c, ql_v, ql_vp, qr, qsws, rho_ocean, s, sa, shf,    &
-               ssws, tend, ts, u, us, v, vpt, w, z0, z0h, z0q, zu, zw
+        ONLY:  dzw, e, nr, p, pt, precipitation_amount, precipitation_rate,    &
+               prr, q, qc, ql, ql_c, ql_v, ql_vp, qr, rho_ocean, s, sa,        &
+               tend, u, v, vpt, w, zu, zw
         
     USE averaging
@@ -177,5 +178,5 @@
                do2d_xz_last_time, do2d_xz_n, do2d_xz_time_count,               &
                do2d_yz_last_time, do2d_yz_n, do2d_yz_time_count,               &
-               ibc_uv_b, io_blocks, io_group, message_string,                  &
+               ibc_uv_b, io_blocks, io_group, land_surface, message_string,    &
                ntdim_2d_xy, ntdim_2d_xz, ntdim_2d_yz,                          &
                psolver, section, simulated_time, simulated_time_chr,           &
@@ -195,5 +196,5 @@
     
     USE land_surface_model_mod,                                                &
-        ONLY:  land_surface, lsm_data_output_2d, zs
+        ONLY:  lsm_data_output_2d, zs
     
 #if defined( __netcdf )
@@ -214,4 +215,7 @@
     USE radiation_model_mod,                                                   &
         ONLY:  radiation, radiation_data_output_2d
+
+    USE surface_mod,                                                           &
+        ONLY:  surf_def_h, surf_lsm_h, surf_usm_h
 
     IMPLICIT NONE
@@ -234,4 +238,5 @@
     INTEGER(iwp) ::  l         !< 
     INTEGER(iwp) ::  layer_xy  !< 
+    INTEGER(iwp) ::  m         !<
     INTEGER(iwp) ::  n         !< 
     INTEGER(iwp) ::  nis       !<
@@ -255,4 +260,6 @@
     REAL(wp), DIMENSION(:,:), ALLOCATABLE   ::  local_2d            !<
     REAL(wp), DIMENSION(:,:), ALLOCATABLE   ::  local_2d_l          !<
+    REAL(wp), DIMENSION(:,:), ALLOCATABLE   ::  tmp_2d              !< temporary field used to exchange surface-related quantities
+
     REAL(wp), DIMENSION(:,:,:), ALLOCATABLE ::  local_pf            !<
     REAL(wp), DIMENSION(:,:,:), ALLOCATABLE ::  local_2d_sections   !<
@@ -417,4 +424,9 @@
 !-- Allocate a temporary array for resorting (kji -> ijk).
     ALLOCATE( local_pf(nxlg:nxrg,nysg:nyng,nzb:nzt+1) )
+    local_pf = 0.0
+!
+!-- Allocate temporary array used for exchanging ghoist points of surface-data
+    ALLOCATE( tmp_2d(nysg:nyng,nxlg:nxrg) )
+    tmp_2d = 0.0
 
 !
@@ -485,9 +497,28 @@
              CASE ( 'ol*_xy' )        ! 2d-array
                 IF ( av == 0 ) THEN
-                   DO  i = nxlg, nxrg
-                      DO  j = nysg, nyng
-                         local_pf(i,j,nzb+1) = ol(j,i)
-                      ENDDO
-                   ENDDO
+                   DO  m = 1, surf_def_h(0)%ns
+                      i = surf_def_h(0)%i(m)
+                      j = surf_def_h(0)%j(m)
+                      tmp_2d(j,i) = surf_def_h(0)%ol(m)
+                   ENDDO
+                   DO  m = 1, surf_lsm_h%ns
+                      i = surf_lsm_h%i(m)
+                      j = surf_lsm_h%j(m)
+                      tmp_2d(j,i) = surf_lsm_h%ol(m)
+                   ENDDO
+                   DO  m = 1, surf_usm_h%ns
+                      i = surf_usm_h%i(m)
+                      j = surf_usm_h%j(m)
+                      tmp_2d(j,i) = surf_usm_h%ol(m)
+                   ENDDO
+
+                   CALL exchange_horiz_2d( tmp_2d, nbgp )
+
+                   DO  i = nxlg, nxrg
+                      DO  j = nysg, nyng
+                         local_pf(i,j,nzb+1) = tmp_2d(j,i)
+                      ENDDO
+                   ENDDO
+
                 ELSE
                    DO  i = nxlg, nxrg
@@ -740,7 +771,25 @@
              CASE ( 'qsws*_xy' )        ! 2d-array
                 IF ( av == 0 ) THEN
-                   DO  i = nxlg, nxrg
-                      DO  j = nysg, nyng
-                         local_pf(i,j,nzb+1) =  qsws(j,i)
+                   DO  m = 1, surf_def_h(0)%ns
+                      i = surf_def_h(0)%i(m)
+                      j = surf_def_h(0)%j(m)
+                      tmp_2d(j,i) = surf_def_h(0)%qsws(m)
+                   ENDDO
+                   DO  m = 1, surf_lsm_h%ns
+                      i = surf_lsm_h%i(m)
+                      j = surf_lsm_h%j(m)
+                      tmp_2d(j,i) = surf_lsm_h%qsws(m)
+                   ENDDO
+                   DO  m = 1, surf_usm_h%ns
+                      i = surf_usm_h%i(m)
+                      j = surf_usm_h%j(m)
+                      tmp_2d(j,i) = surf_usm_h%qsws(m)
+                   ENDDO
+
+                   CALL exchange_horiz_2d( tmp_2d, nbgp )
+
+                   DO  i = nxlg, nxrg
+                      DO  j = nysg, nyng
+                         local_pf(i,j,nzb+1) = tmp_2d(j,i)
                       ENDDO
                    ENDDO
@@ -796,7 +845,25 @@
              CASE ( 'shf*_xy' )        ! 2d-array
                 IF ( av == 0 ) THEN
-                   DO  i = nxlg, nxrg
-                      DO  j = nysg, nyng
-                         local_pf(i,j,nzb+1) =  shf(j,i)
+                   DO  m = 1, surf_def_h(0)%ns
+                      i = surf_def_h(0)%i(m)
+                      j = surf_def_h(0)%j(m)
+                      tmp_2d(j,i) = surf_def_h(0)%shf(m)
+                   ENDDO
+                   DO  m = 1, surf_lsm_h%ns
+                      i = surf_lsm_h%i(m)
+                      j = surf_lsm_h%j(m)
+                      tmp_2d(j,i) = surf_lsm_h%shf(m)
+                   ENDDO
+                   DO  m = 1, surf_usm_h%ns
+                      i = surf_usm_h%i(m)
+                      j = surf_usm_h%j(m)
+                      tmp_2d(j,i) = surf_usm_h%shf(m)
+                   ENDDO
+
+                   CALL exchange_horiz_2d( tmp_2d, nbgp )
+
+                   DO  i = nxlg, nxrg
+                      DO  j = nysg, nyng
+                         local_pf(i,j,nzb+1) = tmp_2d(j,i)
                       ENDDO
                    ENDDO
@@ -814,7 +881,25 @@
              CASE ( 'ssws*_xy' )        ! 2d-array
                 IF ( av == 0 ) THEN
-                   DO  i = nxlg, nxrg
-                      DO  j = nysg, nyng
-                         local_pf(i,j,nzb+1) =  ssws(j,i)
+                   DO  m = 1, surf_def_h(0)%ns
+                      i = surf_def_h(0)%i(m)
+                      j = surf_def_h(0)%j(m)
+                      tmp_2d(j,i) = surf_def_h(0)%ssws(m)
+                   ENDDO
+                   DO  m = 1, surf_lsm_h%ns
+                      i = surf_lsm_h%i(m)
+                      j = surf_lsm_h%j(m)
+                      tmp_2d(j,i) = surf_lsm_h%ssws(m)
+                   ENDDO
+                   DO  m = 1, surf_usm_h%ns
+                      i = surf_usm_h%i(m)
+                      j = surf_usm_h%j(m)
+                      tmp_2d(j,i) = surf_usm_h%ssws(m)
+                   ENDDO
+
+                   CALL exchange_horiz_2d( tmp_2d, nbgp )
+
+                   DO  i = nxlg, nxrg
+                      DO  j = nysg, nyng
+                         local_pf(i,j,nzb+1) = tmp_2d(j,i)
                       ENDDO
                    ENDDO
@@ -832,9 +917,28 @@
              CASE ( 't*_xy' )        ! 2d-array
                 IF ( av == 0 )  THEN
-                   DO  i = nxlg, nxrg
-                      DO  j = nysg, nyng
-                         local_pf(i,j,nzb+1) = ts(j,i)
-                      ENDDO
-                   ENDDO
+                   DO  m = 1, surf_def_h(0)%ns
+                      i = surf_def_h(0)%i(m)
+                      j = surf_def_h(0)%j(m)
+                      tmp_2d(j,i) = surf_def_h(0)%ts(m)
+                   ENDDO
+                   DO  m = 1, surf_lsm_h%ns
+                      i = surf_lsm_h%i(m)
+                      j = surf_lsm_h%j(m)
+                      tmp_2d(j,i) = surf_lsm_h%ts(m)
+                   ENDDO
+                   DO  m = 1, surf_usm_h%ns
+                      i = surf_usm_h%i(m)
+                      j = surf_usm_h%j(m)
+                      tmp_2d(j,i) = surf_usm_h%ts(m)
+                   ENDDO
+
+                   CALL exchange_horiz_2d( tmp_2d, nbgp )
+
+                   DO  i = nxlg, nxrg
+                      DO  j = nysg, nyng
+                         local_pf(i,j,nzb+1) = tmp_2d(j,i)
+                      ENDDO
+                   ENDDO
+
                 ELSE
                    DO  i = nxlg, nxrg
@@ -864,7 +968,25 @@
              CASE ( 'u*_xy' )        ! 2d-array
                 IF ( av == 0 )  THEN
-                   DO  i = nxlg, nxrg
-                      DO  j = nysg, nyng
-                         local_pf(i,j,nzb+1) = us(j,i)
+                   DO  m = 1, surf_def_h(0)%ns
+                      i = surf_def_h(0)%i(m)
+                      j = surf_def_h(0)%j(m)
+                      tmp_2d(j,i) = surf_def_h(0)%us(m)
+                   ENDDO
+                   DO  m = 1, surf_lsm_h%ns
+                      i = surf_lsm_h%i(m)
+                      j = surf_lsm_h%j(m)
+                      tmp_2d(j,i) = surf_lsm_h%us(m)
+                   ENDDO
+                   DO  m = 1, surf_usm_h%ns
+                      i = surf_usm_h%i(m)
+                      j = surf_usm_h%j(m)
+                      tmp_2d(j,i) = surf_usm_h%us(m)
+                   ENDDO
+
+                   CALL exchange_horiz_2d( tmp_2d, nbgp )
+
+                   DO  i = nxlg, nxrg
+                      DO  j = nysg, nyng
+                         local_pf(i,j,nzb+1) = tmp_2d(j,i)
                       ENDDO
                    ENDDO
@@ -912,9 +1034,28 @@
              CASE ( 'z0*_xy' )        ! 2d-array
                 IF ( av == 0 ) THEN
-                   DO  i = nxlg, nxrg
-                      DO  j = nysg, nyng
-                         local_pf(i,j,nzb+1) =  z0(j,i)
-                      ENDDO
-                   ENDDO
+                   DO  m = 1, surf_def_h(0)%ns
+                      i = surf_def_h(0)%i(m)
+                      j = surf_def_h(0)%j(m)
+                      tmp_2d(j,i) = surf_def_h(0)%z0(m)
+                   ENDDO
+                   DO  m = 1, surf_lsm_h%ns
+                      i = surf_lsm_h%i(m)
+                      j = surf_lsm_h%j(m)
+                      tmp_2d(j,i) = surf_lsm_h%z0(m)
+                   ENDDO
+                   DO  m = 1, surf_usm_h%ns
+                      i = surf_usm_h%i(m)
+                      j = surf_usm_h%j(m)
+                      tmp_2d(j,i) = surf_usm_h%z0(m)
+                   ENDDO
+
+                   CALL exchange_horiz_2d( tmp_2d, nbgp )
+
+                   DO  i = nxlg, nxrg
+                      DO  j = nysg, nyng
+                         local_pf(i,j,nzb+1) = tmp_2d(j,i)
+                      ENDDO
+                   ENDDO
+
                 ELSE
                    DO  i = nxlg, nxrg
@@ -930,7 +1071,25 @@
              CASE ( 'z0h*_xy' )        ! 2d-array
                 IF ( av == 0 ) THEN
-                   DO  i = nxlg, nxrg
-                      DO  j = nysg, nyng
-                         local_pf(i,j,nzb+1) =  z0h(j,i)
+                   DO  m = 1, surf_def_h(0)%ns
+                      i = surf_def_h(0)%i(m)
+                      j = surf_def_h(0)%j(m)
+                      tmp_2d(j,i) = surf_def_h(0)%z0h(m)
+                   ENDDO
+                   DO  m = 1, surf_lsm_h%ns
+                      i = surf_lsm_h%i(m)
+                      j = surf_lsm_h%j(m)
+                      tmp_2d(j,i) = surf_lsm_h%z0h(m)
+                   ENDDO
+                   DO  m = 1, surf_usm_h%ns
+                      i = surf_usm_h%i(m)
+                      j = surf_usm_h%j(m)
+                      tmp_2d(j,i) = surf_usm_h%z0h(m)
+                   ENDDO
+
+                   CALL exchange_horiz_2d( tmp_2d, nbgp )
+
+                   DO  i = nxlg, nxrg
+                      DO  j = nysg, nyng
+                         local_pf(i,j,nzb+1) = tmp_2d(j,i)
                       ENDDO
                    ENDDO
@@ -948,7 +1107,25 @@
              CASE ( 'z0q*_xy' )        ! 2d-array
                 IF ( av == 0 ) THEN
-                   DO  i = nxlg, nxrg
-                      DO  j = nysg, nyng
-                         local_pf(i,j,nzb+1) =  z0q(j,i)
+                   DO  m = 1, surf_def_h(0)%ns
+                      i = surf_def_h(0)%i(m)
+                      j = surf_def_h(0)%j(m)
+                      tmp_2d(j,i) = surf_def_h(0)%z0q(m)
+                   ENDDO
+                   DO  m = 1, surf_lsm_h%ns
+                      i = surf_lsm_h%i(m)
+                      j = surf_lsm_h%j(m)
+                      tmp_2d(j,i) = surf_lsm_h%z0q(m)
+                   ENDDO
+                   DO  m = 1, surf_usm_h%ns
+                      i = surf_usm_h%i(m)
+                      j = surf_usm_h%j(m)
+                      tmp_2d(j,i) = surf_usm_h%z0q(m)
+                   ENDDO
+
+                   CALL exchange_horiz_2d( tmp_2d, nbgp )
+
+                   DO  i = nxlg, nxrg
+                      DO  j = nysg, nyng
+                         local_pf(i,j,nzb+1) = tmp_2d(j,i)
                       ENDDO
                    ENDDO
Index: /palm/trunk/SOURCE/data_output_3d.f90
===================================================================
--- /palm/trunk/SOURCE/data_output_3d.f90	(revision 2231)
+++ /palm/trunk/SOURCE/data_output_3d.f90	(revision 2232)
@@ -20,5 +20,5 @@
 ! Current revisions:
 ! ------------------
-! 
+! Adjustments to new topography concept
 ! 
 ! Former revisions:
@@ -152,6 +152,6 @@
 
     USE arrays_3d,                                                             &
-        ONLY:  e, nr, p, pt, prr, q, qc, ql, ql_c, ql_v, qr, rho_ocean, s, sa, tend, &
-               u, v, vpt, w
+        ONLY:  e, nr, p, pt, prr, q, qc, ql, ql_c, ql_v, qr, rho_ocean, s, sa, &
+               tend, u, v, vpt, w
         
     USE averaging
@@ -162,7 +162,7 @@
     USE control_parameters,                                                    &
         ONLY:  cloud_physics, do3d, do3d_no, do3d_time_count, io_blocks,       &
-               io_group, message_string, ntdim_3d, nz_do3d, psolver,           &
-               simulated_time, time_since_reference_point, urban_surface,      &
-               varnamelength
+               io_group, land_surface, message_string, ntdim_3d, nz_do3d,      &
+               psolver, simulated_time, time_since_reference_point,            &
+               urban_surface, varnamelength
         
     USE cpulog,                                                                &
@@ -175,5 +175,5 @@
     
     USE land_surface_model_mod,                                                &
-        ONLY: land_surface, lsm_data_output_3d, nzb_soil, nzt_soil
+        ONLY: lsm_data_output_3d, nzb_soil, nzt_soil
 
 #if defined( __netcdf )
Index: /palm/trunk/SOURCE/diffusion_e.f90
===================================================================
--- /palm/trunk/SOURCE/diffusion_e.f90	(revision 2231)
+++ /palm/trunk/SOURCE/diffusion_e.f90	(revision 2232)
@@ -20,5 +20,5 @@
 ! Current revisions:
 ! -----------------
-! 
+! Adjustments to new topography and surface concept
 ! 
 ! Former revisions:
@@ -129,5 +129,5 @@
 
        USE arrays_3d,                                                          &
-           ONLY:  dd2zu, ddzu, ddzw, diss, e, km, l_grid, tend, zu, zw,        &
+           ONLY:  dd2zu, ddzu, ddzw, diss, e, km, l_grid, l_wall, tend, zu, zw,&
                   drho_air, rho_air_zw
            
@@ -140,6 +140,6 @@
            
        USE indices,                                                            &
-           ONLY:  nxl, nxlg, nxr, nxrg, nyn, nyng, nys, nysg, nzb, nzb_s_inner,&
-                  nzt
+           ONLY:  nxl, nxlg, nxr, nxrg, nyn, nyng, nys, nysg, nzb, nzb_max,    &
+                  nzt, wall_flags_0
            
        USE kinds
@@ -151,10 +151,16 @@
            ONLY:  use_sgs_for_particles, wang_kernel
 
+       USE surface_mod,                                                        &
+          ONLY :  bc_h
+
        IMPLICIT NONE
 
-       INTEGER(iwp) ::  i              !< 
-       INTEGER(iwp) ::  j              !< 
-       INTEGER(iwp) ::  k              !< 
+       INTEGER(iwp) ::  i              !< running index x direction
+       INTEGER(iwp) ::  j              !< running index y direction
+       INTEGER(iwp) ::  k              !< running index z direction
+       INTEGER(iwp) ::  m              !< running index surface elements
+ 
        REAL(wp)     ::  dvar_dz        !< 
+       REAL(wp)     ::  flag           !< flag to mask topography
        REAL(wp)     ::  l_stable       !< 
        REAL(wp)     ::  var_reference  !< 
@@ -177,5 +183,5 @@
           DO  i = nxl, nxr
              DO  j = nys, nyn
-                DO  k = nzb_s_inner(j,i)+1, nzt
+                DO  k = nzb+1, nzt
 !
 !--                Calculate the mixing length (for dissipation)
@@ -191,9 +197,7 @@
 !--                Adjustment of the mixing length
                    IF ( wall_adjustment )  THEN
-                      l(k,j)  = MIN( wall_adjustment_factor *          &
-                                     ( zu(k) - zw(nzb_s_inner(j,i)) ), &
+                      l(k,j)  = MIN( wall_adjustment_factor * l_wall(k,j,i),   &
                                      l_grid(k), l_stable )
-                      ll(k,j) = MIN( wall_adjustment_factor *          &
-                                     ( zu(k) - zw(nzb_s_inner(j,i)) ), &
+                      ll(k,j) = MIN( wall_adjustment_factor * l_wall(k,j,i),   &
                                      l_grid(k) )
                    ELSE
@@ -208,18 +212,21 @@
 !--          Calculate the tendency terms
              DO  j = nys, nyn
-                DO  k = nzb_s_inner(j,i)+1, nzt
-
-                    dissipation(k,j) = ( 0.19_wp + 0.74_wp * l(k,j) / ll(k,j) ) * &
+                DO  k = nzb+1, nzt
+!
+!--                Predetermine flag to mask topography
+                   flag = MERGE( 1.0_wp, 0.0_wp, BTEST( wall_flags_0(k,j,i), 0 ) )
+
+                   dissipation(k,j) = ( 0.19_wp + 0.74_wp * l(k,j) / ll(k,j) ) * &
                                        e(k,j,i) * SQRT( e(k,j,i) ) / l(k,j)
 
-                    tend(k,j,i) = tend(k,j,i)                                  &
+                   tend(k,j,i) = tend(k,j,i)                                   &
                                         + (                                    &
                           ( km(k,j,i)+km(k,j,i+1) ) * ( e(k,j,i+1)-e(k,j,i) )  &
                         - ( km(k,j,i)+km(k,j,i-1) ) * ( e(k,j,i)-e(k,j,i-1) )  &
-                                          ) * ddx2                             &
+                                          ) * ddx2  * flag                     &
                                         + (                                    &
                           ( km(k,j,i)+km(k,j+1,i) ) * ( e(k,j+1,i)-e(k,j,i) )  &
                         - ( km(k,j,i)+km(k,j-1,i) ) * ( e(k,j,i)-e(k,j-1,i) )  &
-                                          ) * ddy2                             &
+                                          ) * ddy2  * flag                     &
                                         + (                                    &
                ( km(k,j,i)+km(k+1,j,i) ) * ( e(k+1,j,i)-e(k,j,i) ) * ddzu(k+1) &
@@ -227,6 +234,6 @@
              - ( km(k,j,i)+km(k-1,j,i) ) * ( e(k,j,i)-e(k-1,j,i) ) * ddzu(k)   &
                                                              * rho_air_zw(k-1) &
-                                          ) * ddzw(k) * drho_air(k)            &
-                             - dissipation(k,j)
+                                          ) * ddzw(k) * drho_air(k) * flag     &
+                             - dissipation(k,j) * flag
 
                 ENDDO
@@ -239,6 +246,8 @@
                   collision_turbulence )  THEN
                 DO  j = nys, nyn
-                   DO  k = nzb_s_inner(j,i)+1, nzt
-                      diss(k,j,i) = dissipation(k,j)
+                   DO  k = nzb+1, nzt
+                      diss(k,j,i) = dissipation(k,j) *                         &
+                                        MERGE( 1.0_wp, 0.0_wp,                 &
+                                               BTEST( wall_flags_0(k,j,i), 0 ) )
                    ENDDO
                 ENDDO
@@ -251,5 +260,5 @@
           DO  i = nxl, nxr
              DO  j = nys, nyn
-                DO  k = nzb_s_inner(j,i)+1, nzt
+                DO  k = nzb+1, nzt
 !
 !--                Calculate the mixing length (for dissipation)
@@ -265,9 +274,7 @@
 !--                Adjustment of the mixing length
                    IF ( wall_adjustment )  THEN
-                      l(k,j)  = MIN( wall_adjustment_factor *          &
-                                     ( zu(k) - zw(nzb_s_inner(j,i)) ), &
+                      l(k,j)  = MIN( wall_adjustment_factor * l_wall(k,j,i),   &
                                      l_grid(k), l_stable )
-                      ll(k,j) = MIN( wall_adjustment_factor *          &
-                                     ( zu(k) - zw(nzb_s_inner(j,i)) ), &
+                      ll(k,j) = MIN( wall_adjustment_factor * l_wall(k,j,i),   &
                                      l_grid(k) )
                    ELSE
@@ -282,18 +289,21 @@
 !--          Calculate the tendency terms
              DO  j = nys, nyn
-                DO  k = nzb_s_inner(j,i)+1, nzt
-
-                    dissipation(k,j) = ( 0.19_wp + 0.74_wp * l(k,j) / ll(k,j) ) * &
+                DO  k = nzb+1, nzt
+!
+!--                Predetermine flag to mask topography
+                   flag = MERGE( 1.0_wp, 0.0_wp, BTEST( wall_flags_0(k,j,i), 0 ) )
+
+                   dissipation(k,j) = ( 0.19_wp + 0.74_wp * l(k,j) / ll(k,j) )   *&
                                              e(k,j,i) * SQRT( e(k,j,i) ) / l(k,j)
 
-                    tend(k,j,i) = tend(k,j,i)                                  &
+                   tend(k,j,i) = tend(k,j,i)                                   &
                                         + (                                    &
                           ( km(k,j,i)+km(k,j,i+1) ) * ( e(k,j,i+1)-e(k,j,i) )  &
                         - ( km(k,j,i)+km(k,j,i-1) ) * ( e(k,j,i)-e(k,j,i-1) )  &
-                                          ) * ddx2                             &
+                                          ) * ddx2  * flag                     &
                                         + (                                    &
                           ( km(k,j,i)+km(k,j+1,i) ) * ( e(k,j+1,i)-e(k,j,i) )  &
                         - ( km(k,j,i)+km(k,j-1,i) ) * ( e(k,j,i)-e(k,j-1,i) )  &
-                                          ) * ddy2                             &
+                                          ) * ddy2  * flag                     &
                                         + (                                    &
                ( km(k,j,i)+km(k+1,j,i) ) * ( e(k+1,j,i)-e(k,j,i) ) * ddzu(k+1) &
@@ -301,6 +311,6 @@
              - ( km(k,j,i)+km(k-1,j,i) ) * ( e(k,j,i)-e(k-1,j,i) ) * ddzu(k)   &
                                                              * rho_air_zw(k-1) &
-                                          ) * ddzw(k) * drho_air(k)            &
-                             - dissipation(k,j)
+                                          ) * ddzw(k) * drho_air(k) * flag     &
+                             - dissipation(k,j) * flag
 
                 ENDDO
@@ -313,6 +323,8 @@
                   collision_turbulence )  THEN
                 DO  j = nys, nyn
-                   DO  k = nzb_s_inner(j,i)+1, nzt
-                      diss(k,j,i) = dissipation(k,j)
+                   DO  k = nzb+1, nzt
+                      diss(k,j,i) = dissipation(k,j) *                         &
+                                        MERGE( 1.0_wp, 0.0_wp,                 &
+                                               BTEST( wall_flags_0(k,j,i), 0 ) )
                    ENDDO
                 ENDDO
@@ -324,12 +336,24 @@
 
 !
-!--    Boundary condition for dissipation
+!--    Neumann boundary condition for dissipation diss(nzb,:,:) = diss(nzb+1,:,:)
        IF ( use_sgs_for_particles  .OR.  wang_kernel  .OR.  &
             collision_turbulence )  THEN
-          DO  i = nxl, nxr
-             DO  j = nys, nyn
-                diss(nzb_s_inner(j,i),j,i) = diss(nzb_s_inner(j,i)+1,j,i)
-             ENDDO
-          ENDDO
+!
+!--       Upward facing surfaces
+          DO  m = 1, bc_h(0)%ns
+             i = bc_h(0)%i(m)            
+             j = bc_h(0)%j(m)
+             k = bc_h(0)%k(m)
+             diss(k-1,j,i) = diss(k,j,i)
+          ENDDO
+!
+!--       Downward facing surfaces
+          DO  m = 1, bc_h(1)%ns
+             i = bc_h(1)%i(m)            
+             j = bc_h(1)%j(m)
+             k = bc_h(1)%k(m)
+             diss(k+1,j,i) = diss(k,j,i)
+          ENDDO
+
        ENDIF
 
@@ -345,5 +369,5 @@
 
        USE arrays_3d,                                                          &
-           ONLY:  dd2zu, ddzu, ddzw, diss, e, km, l_grid, tend, zu, zw,        &
+           ONLY:  dd2zu, ddzu, ddzw, diss, e, km, l_grid, l_wall, tend, zu, zw,&
                   drho_air, rho_air_zw
           
@@ -356,5 +380,5 @@
            
        USE indices,                                                            &
-           ONLY:  nxlg, nxrg, nyng, nysg, nzb, nzb_s_inner, nzt
+           ONLY:  nxlg, nxrg, nyng, nysg, nzb, nzb_max, nzt, wall_flags_0
            
        USE kinds
@@ -366,10 +390,18 @@
            ONLY:  use_sgs_for_particles, wang_kernel
 
+       USE surface_mod,                                                        &
+          ONLY :  bc_h
+
        IMPLICIT NONE
 
-       INTEGER(iwp) ::  i              !< 
-       INTEGER(iwp) ::  j              !< 
-       INTEGER(iwp) ::  k              !< 
+       INTEGER(iwp) ::  i              !< running index x direction
+       INTEGER(iwp) ::  j              !< running index y direction
+       INTEGER(iwp) ::  k              !< running index z direction
+       INTEGER(iwp) ::  m              !< running index surface elements
+       INTEGER(iwp) ::  surf_e         !< End index of surface elements at (j,i)-gridpoint
+       INTEGER(iwp) ::  surf_s         !< Start index of surface elements at (j,i)-gridpoint
+
        REAL(wp)     ::  dvar_dz        !< 
+       REAL(wp)     ::  flag           !< flag to mask topography
        REAL(wp)     ::  l_stable       !<
        REAL(wp)     ::  var_reference  !<
@@ -384,8 +416,11 @@
        REAL(wp), DIMENSION(nzb+1:nzt) ::  ll           !<
 
-
 !
 !--    Calculate the mixing length (for dissipation)
-       DO  k = nzb_s_inner(j,i)+1, nzt
+       DO  k = nzb+1, nzt
+!
+!--       Predetermine flag to mask topography
+          flag = MERGE( 1.0_wp, 0.0_wp, BTEST( wall_flags_0(k,j,i), 0 ) )
+
           dvar_dz = atmos_ocean_sign * &
                     ( var(k+1,j,i) - var(k-1,j,i) ) * dd2zu(k)
@@ -404,9 +439,7 @@
 !--       Adjustment of the mixing length
           IF ( wall_adjustment )  THEN
-             l(k)  = MIN( wall_adjustment_factor *                     &
-                          ( zu(k) - zw(nzb_s_inner(j,i)) ), l_grid(k), &
-                          l_stable )
-             ll(k) = MIN( wall_adjustment_factor *                     &
-                          ( zu(k) - zw(nzb_s_inner(j,i)) ), l_grid(k) )
+             l(k)  = MIN( wall_adjustment_factor * l_wall(k,j,i),              &
+                          l_grid(k), l_stable )
+             ll(k) = MIN( wall_adjustment_factor * l_wall(k,j,i), l_grid(k) )
           ELSE
              l(k)  = MIN( l_grid(k), l_stable )
@@ -415,23 +448,23 @@
 !
 !--       Calculate the tendency term
-          dissipation(k) = ( 0.19_wp + 0.74_wp * l(k) / ll(k) ) * e(k,j,i) * &
+          dissipation(k) = ( 0.19_wp + 0.74_wp * l(k) / ll(k) ) * e(k,j,i) *   &
                                  SQRT( e(k,j,i) ) / l(k)
 
-          tend(k,j,i) = tend(k,j,i)                                           &
-                                       + (                                    &
-                         ( km(k,j,i)+km(k,j,i+1) ) * ( e(k,j,i+1)-e(k,j,i) )  &
-                       - ( km(k,j,i)+km(k,j,i-1) ) * ( e(k,j,i)-e(k,j,i-1) )  &
-                                         ) * ddx2                             &
-                                       + (                                    &
-                         ( km(k,j,i)+km(k,j+1,i) ) * ( e(k,j+1,i)-e(k,j,i) )  &
-                       - ( km(k,j,i)+km(k,j-1,i) ) * ( e(k,j,i)-e(k,j-1,i) )  &
-                                         ) * ddy2                             &
-                                       + (                                    &
-              ( km(k,j,i)+km(k+1,j,i) ) * ( e(k+1,j,i)-e(k,j,i) ) * ddzu(k+1) &
-                                                            * rho_air_zw(k)   &
-            - ( km(k,j,i)+km(k-1,j,i) ) * ( e(k,j,i)-e(k-1,j,i) ) * ddzu(k)   &
-                                                            * rho_air_zw(k-1) &
-                                         ) * ddzw(k) * drho_air(k)            &
-                                       - dissipation(k)
+          tend(k,j,i) = tend(k,j,i)                                            &
+                                       + (                                     &
+                         ( km(k,j,i)+km(k,j,i+1) ) * ( e(k,j,i+1)-e(k,j,i) )   &
+                       - ( km(k,j,i)+km(k,j,i-1) ) * ( e(k,j,i)-e(k,j,i-1) )   &
+                                         ) * ddx2  * flag                      &
+                                       + (                                     &
+                         ( km(k,j,i)+km(k,j+1,i) ) * ( e(k,j+1,i)-e(k,j,i) )   &
+                       - ( km(k,j,i)+km(k,j-1,i) ) * ( e(k,j,i)-e(k,j-1,i) )   &
+                                         ) * ddy2  * flag                      &
+                                       + (                                     &
+              ( km(k,j,i)+km(k+1,j,i) ) * ( e(k+1,j,i)-e(k,j,i) ) * ddzu(k+1)  &
+                                                            * rho_air_zw(k)    &
+            - ( km(k,j,i)+km(k-1,j,i) ) * ( e(k,j,i)-e(k-1,j,i) ) * ddzu(k)    &
+                                                            * rho_air_zw(k-1)  &
+                                         ) * ddzw(k) * drho_air(k) * flag      &
+                                       - dissipation(k) * flag
 
        ENDDO
@@ -441,10 +474,27 @@
        IF ( use_sgs_for_particles  .OR.  wang_kernel  .OR.                     &
             collision_turbulence )  THEN
-          DO  k = nzb_s_inner(j,i)+1, nzt
-             diss(k,j,i) = dissipation(k)
-          ENDDO
-!
-!--       Boundary condition for dissipation
-          diss(nzb_s_inner(j,i),j,i) = diss(nzb_s_inner(j,i)+1,j,i)
+          DO  k = nzb+1, nzt
+             diss(k,j,i) = dissipation(k) *                                    &
+                                        MERGE( 1.0_wp, 0.0_wp,                 &
+                                               BTEST( wall_flags_0(k,j,i), 0 ) )
+          ENDDO
+!
+!--       Neumann boundary condition for dissipation diss(nzb,:,:) = diss(nzb+1,:,:)
+!--       For each surface type determine start and end index (in case of elevated
+!--       toopography several up/downward facing surfaces may exist.
+          surf_s = bc_h(0)%start_index(j,i)   
+          surf_e = bc_h(0)%end_index(j,i)   
+          DO  m = surf_s, surf_e
+             k             = bc_h(0)%k(m)
+             diss(k-1,j,i) = diss(k,j,i)
+          ENDDO
+!
+!--       Downward facing surfaces
+          surf_s = bc_h(1)%start_index(j,i)   
+          surf_e = bc_h(1)%end_index(j,i)   
+          DO  m = surf_s, surf_e
+             k             = bc_h(1)%k(m)
+             diss(k+1,j,i) = diss(k,j,i)
+          ENDDO
        ENDIF
 
Index: /palm/trunk/SOURCE/diffusion_s.f90
===================================================================
--- /palm/trunk/SOURCE/diffusion_s.f90	(revision 2231)
+++ /palm/trunk/SOURCE/diffusion_s.f90	(revision 2232)
@@ -20,5 +20,5 @@
 ! Current revisions:
 ! ------------------
-! 
+! Adjustments to new topography and surface concept
 ! 
 ! Former revisions:
@@ -110,5 +110,13 @@
 !> Call for all grid points
 !------------------------------------------------------------------------------!
-    SUBROUTINE diffusion_s( s, s_flux_b, s_flux_t, wall_s_flux )
+    SUBROUTINE diffusion_s( s, s_flux_def_h_up,    s_flux_def_h_down,          &
+                               s_flux_t,                                       &
+                               s_flux_lsm_h_up,    s_flux_usm_h_up,            &
+                               s_flux_def_v_north, s_flux_def_v_south,         &
+                               s_flux_def_v_east,  s_flux_def_v_west,          &
+                               s_flux_lsm_v_north, s_flux_lsm_v_south,         &
+                               s_flux_lsm_v_east,  s_flux_lsm_v_west,          &
+                               s_flux_usm_v_north, s_flux_usm_v_south,         &
+                               s_flux_usm_v_east,  s_flux_usm_v_west )
 
        USE arrays_3d,                                                          &
@@ -119,19 +127,50 @@
        
        USE grid_variables,                                                     &
-           ONLY:  ddx2, ddy2, fwxm, fwxp, fwym, fwyp, wall_w_x, wall_w_y
+           ONLY:  ddx2, ddy2
        
        USE indices,                                                            &
            ONLY:  nxl, nxlg, nxr, nxrg, nyn, nyng, nys, nysg, nzb,             &
-                  nzb_diff_s_inner, nzb_s_inner, nzb_s_outer, nzt, nzt_diff
+                  nzt, wall_flags_0
        
        USE kinds
 
+       USE surface_mod,                                                        &
+           ONLY :  surf_def_h, surf_def_v, surf_lsm_h, surf_lsm_v, surf_usm_h, &
+                   surf_usm_v 
+
        IMPLICIT NONE
 
-       INTEGER(iwp) ::  i                 !< 
-       INTEGER(iwp) ::  j                 !< 
-       INTEGER(iwp) ::  k                 !< 
-       REAL(wp)     ::  wall_s_flux(0:4)  !< 
-       REAL(wp), DIMENSION(nysg:nyng,nxlg:nxrg) ::  s_flux_b, s_flux_t !<
+       INTEGER(iwp) ::  i             !< running index x direction
+       INTEGER(iwp) ::  j             !< running index y direction
+       INTEGER(iwp) ::  k             !< running index z direction
+       INTEGER(iwp) ::  m             !< running index surface elements
+       INTEGER(iwp) ::  surf_e        !< End index of surface elements at (j,i)-gridpoint
+       INTEGER(iwp) ::  surf_s        !< Start index of surface elements at (j,i)-gridpoint
+
+       REAL(wp) ::  flag              !< flag to mask topography grid points
+       REAL(wp) ::  mask_bottom       !< flag to mask vertical upward-facing surface     
+       REAL(wp) ::  mask_east         !< flag to mask vertical surface east of the grid point 
+       REAL(wp) ::  mask_north        !< flag to mask vertical surface north of the grid point
+       REAL(wp) ::  mask_south        !< flag to mask vertical surface south of the grid point 
+       REAL(wp) ::  mask_west         !< flag to mask vertical surface west of the grid point
+       REAL(wp) ::  mask_top          !< flag to mask vertical downward-facing surface  
+
+       REAL(wp), DIMENSION(1:surf_def_v(0)%ns) ::  s_flux_def_v_north !< flux at north-facing vertical default-type surfaces
+       REAL(wp), DIMENSION(1:surf_def_v(1)%ns) ::  s_flux_def_v_south !< flux at south-facing vertical default-type surfaces
+       REAL(wp), DIMENSION(1:surf_def_v(2)%ns) ::  s_flux_def_v_east  !< flux at east-facing vertical default-type surfaces
+       REAL(wp), DIMENSION(1:surf_def_v(3)%ns) ::  s_flux_def_v_west  !< flux at west-facing vertical default-type surfaces
+       REAL(wp), DIMENSION(1:surf_def_h(0)%ns) ::  s_flux_def_h_up    !< flux at horizontal upward-facing default-type surfaces
+       REAL(wp), DIMENSION(1:surf_def_h(1)%ns) ::  s_flux_def_h_down  !< flux at horizontal donwward-facing default-type surfaces 
+       REAL(wp), DIMENSION(1:surf_lsm_h%ns)    ::  s_flux_lsm_h_up    !< flux at horizontal upward-facing natural-type surfaces
+       REAL(wp), DIMENSION(1:surf_lsm_v(0)%ns) ::  s_flux_lsm_v_north !< flux at north-facing vertical natural-type surfaces
+       REAL(wp), DIMENSION(1:surf_lsm_v(1)%ns) ::  s_flux_lsm_v_south !< flux at south-facing vertical natural-type surfaces
+       REAL(wp), DIMENSION(1:surf_lsm_v(2)%ns) ::  s_flux_lsm_v_east  !< flux at east-facing vertical natural-type surfaces
+       REAL(wp), DIMENSION(1:surf_lsm_v(3)%ns) ::  s_flux_lsm_v_west  !< flux at west-facing vertical natural-type surfaces
+       REAL(wp), DIMENSION(1:surf_usm_h%ns)    ::  s_flux_usm_h_up    !< flux at horizontal upward-facing urban-type surfaces
+       REAL(wp), DIMENSION(1:surf_usm_v(0)%ns) ::  s_flux_usm_v_north !< flux at north-facing vertical urban-type surfaces
+       REAL(wp), DIMENSION(1:surf_usm_v(1)%ns) ::  s_flux_usm_v_south !< flux at south-facing vertical urban-type surfaces
+       REAL(wp), DIMENSION(1:surf_usm_v(2)%ns) ::  s_flux_usm_v_east  !< flux at east-facing vertical urban-type surfaces
+       REAL(wp), DIMENSION(1:surf_usm_v(3)%ns) ::  s_flux_usm_v_west  !< flux at west-facing vertical urban-type surfaces
+       REAL(wp), DIMENSION(1:surf_def_h(2)%ns) ::  s_flux_t           !< flux at model top
 #if defined( __nopointer )
        REAL(wp), DIMENSION(nzb:nzt+1,nysg:nyng,nxlg:nxrg) ::  s  !< 
@@ -144,95 +183,236 @@
 !
 !--          Compute horizontal diffusion
-             DO  k = nzb_s_outer(j,i)+1, nzt
+             DO  k = nzb+1, nzt
+!
+!--             Predetermine flag to mask topography and wall-bounded grid points
+                flag = MERGE( 1.0_wp, 0.0_wp, BTEST( wall_flags_0(k,j,i), 0 ) ) 
+!
+!--             Predetermine flag to mask wall-bounded grid points, equivalent to
+!--             former s_outer array
+                mask_west  = MERGE( 1.0_wp, 0.0_wp, BTEST( wall_flags_0(k,j,i-1), 0 ) )
+                mask_east  = MERGE( 1.0_wp, 0.0_wp, BTEST( wall_flags_0(k,j,i+1), 0 ) )
+                mask_south = MERGE( 1.0_wp, 0.0_wp, BTEST( wall_flags_0(k,j-1,i), 0 ) )
+                mask_north = MERGE( 1.0_wp, 0.0_wp, BTEST( wall_flags_0(k,j+1,i), 0 ) )
 
                 tend(k,j,i) = tend(k,j,i)                                      &
                                           + 0.5_wp * (                         &
-                        ( kh(k,j,i) + kh(k,j,i+1) ) * ( s(k,j,i+1)-s(k,j,i) )  &
-                      - ( kh(k,j,i) + kh(k,j,i-1) ) * ( s(k,j,i)-s(k,j,i-1) )  &
-                                                     ) * ddx2                  &
+                        mask_east  * ( kh(k,j,i) + kh(k,j,i+1) )               &
+                                   * ( s(k,j,i+1) - s(k,j,i)   )               &
+                      - mask_west  * ( kh(k,j,i) + kh(k,j,i-1) )               &
+                                   * ( s(k,j,i)   - s(k,j,i-1) )               &
+                                                     ) * ddx2 * flag           &
                                           + 0.5_wp * (                         &
-                        ( kh(k,j,i) + kh(k,j+1,i) ) * ( s(k,j+1,i)-s(k,j,i) )  &
-                      - ( kh(k,j,i) + kh(k,j-1,i) ) * ( s(k,j,i)-s(k,j-1,i) )  &
-                                                     ) * ddy2
-             ENDDO
-
-!
-!--          Apply prescribed horizontal wall heatflux where necessary
-             IF ( ( wall_w_x(j,i) /= 0.0_wp ) .OR. ( wall_w_y(j,i) /= 0.0_wp ) &
-                )  THEN
-                DO  k = nzb_s_inner(j,i)+1, nzb_s_outer(j,i)
-
+                        mask_north * ( kh(k,j,i) + kh(k,j+1,i) )               &
+                                   * ( s(k,j+1,i) - s(k,j,i)   )               &
+                      - mask_south * ( kh(k,j,i) + kh(k,j-1,i) )               &
+                                   * ( s(k,j,i)   - s(k,j-1,i) )               &
+                                                     ) * ddy2 * flag
+             ENDDO
+
+!
+!--          Apply prescribed horizontal wall heatflux where necessary. First,
+!--          determine start and end index for respective (j,i)-index. Please
+!--          note, in the flat case following loop will not be entered, as
+!--          surf_s=1 and surf_e=0. Furtermore, note, no vertical natural surfaces
+!--          so far. 
+!--          First, for default-type surfaces 
+!--          North-facing vertical default-type surfaces
+             surf_s = surf_def_v(0)%start_index(j,i)
+             surf_e = surf_def_v(0)%end_index(j,i)
+             DO  m = surf_s, surf_e
+                k           = surf_def_v(0)%k(m)
+                tend(k,j,i) = tend(k,j,i) + s_flux_def_v_north(m) * ddy2
+             ENDDO
+!
+!--          South-facing vertical default-type surfaces
+             surf_s = surf_def_v(1)%start_index(j,i)
+             surf_e = surf_def_v(1)%end_index(j,i)
+             DO  m = surf_s, surf_e
+                k           = surf_def_v(1)%k(m)
+                tend(k,j,i) = tend(k,j,i) + s_flux_def_v_south(m) * ddy2
+             ENDDO
+!
+!--          East-facing vertical default-type surfaces
+             surf_s = surf_def_v(2)%start_index(j,i)
+             surf_e = surf_def_v(2)%end_index(j,i)
+             DO  m = surf_s, surf_e
+                k           = surf_def_v(2)%k(m)
+                tend(k,j,i) = tend(k,j,i) + s_flux_def_v_east(m) * ddx2
+             ENDDO
+!
+!--          West-facing vertical default-type surfaces
+             surf_s = surf_def_v(3)%start_index(j,i)
+             surf_e = surf_def_v(3)%end_index(j,i)
+             DO  m = surf_s, surf_e
+                k           = surf_def_v(3)%k(m)
+                tend(k,j,i) = tend(k,j,i) + s_flux_def_v_west(m) * ddx2
+             ENDDO
+!
+!--          Now, for natural-type surfaces.
+!--          North-facing
+             surf_s = surf_lsm_v(0)%start_index(j,i)
+             surf_e = surf_lsm_v(0)%end_index(j,i)
+             DO  m = surf_s, surf_e
+                k           = surf_lsm_v(0)%k(m)
+                tend(k,j,i) = tend(k,j,i) + s_flux_lsm_v_north(m) * ddy2
+             ENDDO
+!
+!--          South-facing
+             surf_s = surf_lsm_v(1)%start_index(j,i)
+             surf_e = surf_lsm_v(1)%end_index(j,i)
+             DO  m = surf_s, surf_e
+                k           = surf_lsm_v(1)%k(m)
+                tend(k,j,i) = tend(k,j,i) + s_flux_lsm_v_south(m) * ddy2
+             ENDDO
+!
+!--          East-facing
+             surf_s = surf_lsm_v(2)%start_index(j,i)
+             surf_e = surf_lsm_v(2)%end_index(j,i)
+             DO  m = surf_s, surf_e
+                k           = surf_lsm_v(2)%k(m)
+                tend(k,j,i) = tend(k,j,i) + s_flux_lsm_v_east(m) * ddx2
+             ENDDO
+!
+!--          West-facing
+             surf_s = surf_lsm_v(3)%start_index(j,i)
+             surf_e = surf_lsm_v(3)%end_index(j,i)
+             DO  m = surf_s, surf_e
+                k           = surf_lsm_v(3)%k(m)
+                tend(k,j,i) = tend(k,j,i) + s_flux_lsm_v_west(m) * ddx2
+             ENDDO
+!
+!--          Now, for urban-type surfaces.
+!--          North-facing
+             surf_s = surf_usm_v(0)%start_index(j,i)
+             surf_e = surf_usm_v(0)%end_index(j,i)
+             DO  m = surf_s, surf_e
+                k           = surf_usm_v(0)%k(m)
+                tend(k,j,i) = tend(k,j,i) + s_flux_usm_v_north(m) * ddy2
+             ENDDO
+!
+!--          South-facing
+             surf_s = surf_usm_v(1)%start_index(j,i)
+             surf_e = surf_usm_v(1)%end_index(j,i)
+             DO  m = surf_s, surf_e
+                k           = surf_usm_v(1)%k(m)
+                tend(k,j,i) = tend(k,j,i) + s_flux_usm_v_south(m) * ddy2
+             ENDDO
+!
+!--          East-facing
+             surf_s = surf_usm_v(2)%start_index(j,i)
+             surf_e = surf_usm_v(2)%end_index(j,i)
+             DO  m = surf_s, surf_e
+                k           = surf_usm_v(2)%k(m)
+                tend(k,j,i) = tend(k,j,i) + s_flux_usm_v_east(m) * ddx2
+             ENDDO
+!
+!--          West-facing
+             surf_s = surf_usm_v(3)%start_index(j,i)
+             surf_e = surf_usm_v(3)%end_index(j,i)
+             DO  m = surf_s, surf_e
+                k           = surf_usm_v(3)%k(m)
+                tend(k,j,i) = tend(k,j,i) + s_flux_usm_v_west(m) * ddx2
+             ENDDO
+
+!
+!--          Compute vertical diffusion. In case that surface fluxes have been
+!--          prescribed or computed at bottom and/or top, index k starts/ends at
+!--          nzb+2 or nzt-1, respectively. Model top is also mask if top flux
+!--          is given.
+             DO  k = nzb+1, nzt
+!
+!--             Determine flags to mask topography below and above. Flag 0 is 
+!--             used to mask topography in general, and flag 8 implies 
+!--             information about use_surface_fluxes. Flag 9 is used to control 
+!--             flux at model top. 
+                mask_bottom = MERGE( 1.0_wp, 0.0_wp,                           &
+                                     BTEST( wall_flags_0(k-1,j,i), 8 ) ) 
+                mask_top    = MERGE( 1.0_wp, 0.0_wp,                           &
+                                     BTEST( wall_flags_0(k+1,j,i), 8 ) ) *     &
+                              MERGE( 1.0_wp, 0.0_wp,                           &
+                                     BTEST( wall_flags_0(k+1,j,i), 9 ) ) 
+                flag        = MERGE( 1.0_wp, 0.0_wp,                           &
+                                     BTEST( wall_flags_0(k,j,i), 0 ) )
+
+                tend(k,j,i) = tend(k,j,i)                                      &
+                                       + 0.5_wp * (                            &
+                                      ( kh(k,j,i) + kh(k+1,j,i) ) *            &
+                                          ( s(k+1,j,i)-s(k,j,i) ) * ddzu(k+1)  &
+                                                            * rho_air_zw(k)    &
+                                                            * mask_top         &
+                                    - ( kh(k,j,i) + kh(k-1,j,i) ) *            &
+                                          ( s(k,j,i)-s(k-1,j,i) ) * ddzu(k)    &
+                                                            * rho_air_zw(k-1)  &
+                                                            * mask_bottom      &
+                                                  ) * ddzw(k) * drho_air(k)    &
+                                                              * flag
+             ENDDO
+
+!
+!--          Vertical diffusion at horizontal walls.
+             IF ( use_surface_fluxes )  THEN
+!
+!--             Default-type surfaces, upward-facing               
+                surf_s = surf_def_h(0)%start_index(j,i)
+                surf_e = surf_def_h(0)%end_index(j,i)
+                DO  m = surf_s, surf_e
+
+                   k   = surf_def_h(0)%k(m)
+                   tend(k,j,i) = tend(k,j,i) + s_flux_def_h_up(m)              &
+                                       * ddzw(k) * drho_air(k)
+
+                ENDDO
+!
+!--             Default-type surfaces, downward-facing               
+                surf_s = surf_def_h(1)%start_index(j,i)
+                surf_e = surf_def_h(1)%end_index(j,i)
+                DO  m = surf_s, surf_e
+
+                   k   = surf_def_h(1)%k(m)
+                   tend(k,j,i) = tend(k,j,i) + s_flux_def_h_down(m)            &
+                                       * ddzw(k) * drho_air(k)
+
+                ENDDO
+!
+!--             Natural-type surfaces, upward-facing  
+                surf_s = surf_lsm_h%start_index(j,i)
+                surf_e = surf_lsm_h%end_index(j,i)
+                DO  m = surf_s, surf_e
+
+                   k   = surf_lsm_h%k(m)
+                   tend(k,j,i) = tend(k,j,i) + s_flux_lsm_h_up(m)              &
+                                       * ddzw(k) * drho_air(k)
+
+                ENDDO
+!
+!--             Urban-type surfaces, upward-facing     
+                surf_s = surf_usm_h%start_index(j,i)
+                surf_e = surf_usm_h%end_index(j,i)
+                DO  m = surf_s, surf_e
+
+                   k   = surf_usm_h%k(m)
+                   tend(k,j,i) = tend(k,j,i) + s_flux_usm_h_up(m)              &
+                                       * ddzw(k) * drho_air(k)
+
+                ENDDO
+
+             ENDIF
+!
+!--          Vertical diffusion at the last computational gridpoint along z-direction
+             IF ( use_top_fluxes )  THEN
+                surf_s = surf_def_h(2)%start_index(j,i)
+                surf_e = surf_def_h(2)%end_index(j,i)
+                DO  m = surf_s, surf_e
+
+                   k   = surf_def_h(2)%k(m)
                    tend(k,j,i) = tend(k,j,i)                                   &
-                                                + ( fwxp(j,i) * 0.5_wp *       &
-                        ( kh(k,j,i) + kh(k,j,i+1) ) * ( s(k,j,i+1)-s(k,j,i) )  &
-                        + ( 1.0_wp - fwxp(j,i) ) * wall_s_flux(1)              &
-                                                   -fwxm(j,i) * 0.5_wp *       &
-                        ( kh(k,j,i) + kh(k,j,i-1) ) * ( s(k,j,i)-s(k,j,i-1) )  &
-                        + ( 1.0_wp - fwxm(j,i) ) * wall_s_flux(2)              &
-                                                  ) * ddx2                     &
-                                                + ( fwyp(j,i) * 0.5_wp *       &
-                        ( kh(k,j,i) + kh(k,j+1,i) ) * ( s(k,j+1,i)-s(k,j,i) )  &
-                        + ( 1.0_wp - fwyp(j,i) ) * wall_s_flux(3)              &
-                                                   -fwym(j,i) * 0.5_wp *       &
-                        ( kh(k,j,i) + kh(k,j-1,i) ) * ( s(k,j,i)-s(k,j-1,i) )  &
-                        + ( 1.0_wp - fwym(j,i) ) * wall_s_flux(4)              &
-                                                  ) * ddy2
+                           + ( - s_flux_t(m) ) * ddzw(k) * drho_air(k)
                 ENDDO
              ENDIF
 
-!
-!--          Compute vertical diffusion. In case that surface fluxes have been
-!--          prescribed or computed at bottom and/or top, index k starts/ends at
-!--          nzb+2 or nzt-1, respectively.
-             DO  k = nzb_diff_s_inner(j,i), nzt_diff
-
-                tend(k,j,i) = tend(k,j,i)                                      &
-                                       + 0.5_wp * (                            &
-            ( kh(k,j,i) + kh(k+1,j,i) ) * ( s(k+1,j,i)-s(k,j,i) ) * ddzu(k+1)  &
-                                                            * rho_air_zw(k)    &
-          - ( kh(k,j,i) + kh(k-1,j,i) ) * ( s(k,j,i)-s(k-1,j,i) ) * ddzu(k)    &
-                                                            * rho_air_zw(k-1)  &
-                                                  ) * ddzw(k) * drho_air(k)
-             ENDDO
-
-!
-!--          Vertical diffusion at the first computational gridpoint along
-!--          z-direction
-             IF ( use_surface_fluxes )  THEN
-
-                k = nzb_s_inner(j,i)+1
-
-                tend(k,j,i) = tend(k,j,i)                                      &
-                                       + ( 0.5_wp * ( kh(k,j,i)+kh(k+1,j,i) )  &
-                                                  * ( s(k+1,j,i)-s(k,j,i) )    &
-                                                  * ddzu(k+1)                  &
-                                                  * rho_air_zw(k)              &
-                                           + s_flux_b(j,i)                     &
-                                         ) * ddzw(k) * drho_air(k)
-
-             ENDIF
-
-!
-!--          Vertical diffusion at the last computational gridpoint along
-!--          z-direction
-             IF ( use_top_fluxes )  THEN
-
-                k = nzt
-
-                tend(k,j,i) = tend(k,j,i)                                      &
-                                       + ( - s_flux_t(j,i)                     &
-                                           - 0.5_wp * ( kh(k-1,j,i)+kh(k,j,i) )&
-                                                    * ( s(k,j,i)-s(k-1,j,i) )  &
-                                                    * ddzu(k)                  &
-                                                    * rho_air_zw(k-1)          &
-                                         ) * ddzw(k) * drho_air(k)
-
-             ENDIF
-
           ENDDO
        ENDDO
 
     END SUBROUTINE diffusion_s
-
 
 !------------------------------------------------------------------------------!
@@ -241,5 +421,14 @@
 !> Call for grid point i,j
 !------------------------------------------------------------------------------!
-    SUBROUTINE diffusion_s_ij( i, j, s, s_flux_b, s_flux_t, wall_s_flux )
+    SUBROUTINE diffusion_s_ij( i, j, s,                                        &
+                               s_flux_def_h_up,    s_flux_def_h_down,          &
+                               s_flux_t,                                       &
+                               s_flux_lsm_h_up,    s_flux_usm_h_up,            &
+                               s_flux_def_v_north, s_flux_def_v_south,         &
+                               s_flux_def_v_east,  s_flux_def_v_west,          &
+                               s_flux_lsm_v_north, s_flux_lsm_v_south,         &
+                               s_flux_lsm_v_east,  s_flux_lsm_v_west,          &
+                               s_flux_usm_v_north, s_flux_usm_v_south,         &
+                               s_flux_usm_v_east,  s_flux_usm_v_west )       
 
        USE arrays_3d,                                                          &
@@ -250,20 +439,49 @@
        
        USE grid_variables,                                                     &
-           ONLY:  ddx2, ddy2, fwxm, fwxp, fwym, fwyp, wall_w_x, wall_w_y
+           ONLY:  ddx2, ddy2
        
        USE indices,                                                            &
-           ONLY:  nxlg, nxrg, nyng, nysg, nzb, nzb_diff_s_inner, nzb_s_inner,  &
-                  nzb_s_outer, nzt, nzt_diff
+           ONLY:  nxlg, nxrg, nyng, nysg, nzb, nzt, wall_flags_0
        
        USE kinds
 
+       USE surface_mod,                                                        &
+           ONLY :  surf_def_h, surf_def_v, surf_lsm_h, surf_lsm_v, surf_usm_h, &
+                   surf_usm_v 
+
        IMPLICIT NONE
 
-       INTEGER(iwp) ::  i                 !< 
-       INTEGER(iwp) ::  j                 !< 
-       INTEGER(iwp) ::  k                 !< 
-       REAL(wp)     ::  wall_s_flux(0:4)  !< 
-       REAL(wp), DIMENSION(nysg:nyng,nxlg:nxrg) ::  s_flux_b  !< 
-       REAL(wp), DIMENSION(nysg:nyng,nxlg:nxrg) ::  s_flux_t  !< 
+       INTEGER(iwp) ::  i             !< running index x direction
+       INTEGER(iwp) ::  j             !< running index y direction
+       INTEGER(iwp) ::  k             !< running index z direction
+       INTEGER(iwp) ::  m             !< running index surface elements
+       INTEGER(iwp) ::  surf_e        !< End index of surface elements at (j,i)-gridpoint
+       INTEGER(iwp) ::  surf_s        !< Start index of surface elements at (j,i)-gridpoint
+
+       REAL(wp) ::  flag              !< flag to mask topography grid points
+       REAL(wp) ::  mask_bottom       !< flag to mask vertical upward-facing surface     
+       REAL(wp) ::  mask_east         !< flag to mask vertical surface east of the grid point 
+       REAL(wp) ::  mask_north        !< flag to mask vertical surface north of the grid point
+       REAL(wp) ::  mask_south        !< flag to mask vertical surface south of the grid point 
+       REAL(wp) ::  mask_west         !< flag to mask vertical surface west of the grid point
+       REAL(wp) ::  mask_top          !< flag to mask vertical downward-facing surface  
+
+       REAL(wp), DIMENSION(1:surf_def_v(0)%ns) ::  s_flux_def_v_north !< flux at north-facing vertical default-type surfaces
+       REAL(wp), DIMENSION(1:surf_def_v(1)%ns) ::  s_flux_def_v_south !< flux at south-facing vertical default-type surfaces
+       REAL(wp), DIMENSION(1:surf_def_v(2)%ns) ::  s_flux_def_v_east  !< flux at east-facing vertical default-type surfaces
+       REAL(wp), DIMENSION(1:surf_def_v(3)%ns) ::  s_flux_def_v_west  !< flux at west-facing vertical default-type surfaces
+       REAL(wp), DIMENSION(1:surf_def_h(0)%ns) ::  s_flux_def_h_up    !< flux at horizontal upward-facing default-type surfaces
+       REAL(wp), DIMENSION(1:surf_def_h(1)%ns) ::  s_flux_def_h_down  !< flux at horizontal donwward-facing default-type surfaces 
+       REAL(wp), DIMENSION(1:surf_lsm_h%ns)    ::  s_flux_lsm_h_up    !< flux at horizontal upward-facing natural-type surfaces
+       REAL(wp), DIMENSION(1:surf_lsm_v(0)%ns) ::  s_flux_lsm_v_north !< flux at north-facing vertical urban-type surfaces
+       REAL(wp), DIMENSION(1:surf_lsm_v(1)%ns) ::  s_flux_lsm_v_south !< flux at south-facing vertical urban-type surfaces
+       REAL(wp), DIMENSION(1:surf_lsm_v(2)%ns) ::  s_flux_lsm_v_east  !< flux at east-facing vertical urban-type surfaces
+       REAL(wp), DIMENSION(1:surf_lsm_v(3)%ns) ::  s_flux_lsm_v_west  !< flux at west-facing vertical urban-type surfaces
+       REAL(wp), DIMENSION(1:surf_usm_h%ns)    ::  s_flux_usm_h_up    !< flux at horizontal upward-facing urban-type surfaces
+       REAL(wp), DIMENSION(1:surf_usm_v(0)%ns) ::  s_flux_usm_v_north !< flux at north-facing vertical urban-type surfaces
+       REAL(wp), DIMENSION(1:surf_usm_v(1)%ns) ::  s_flux_usm_v_south !< flux at south-facing vertical urban-type surfaces
+       REAL(wp), DIMENSION(1:surf_usm_v(2)%ns) ::  s_flux_usm_v_east  !< flux at east-facing vertical urban-type surfaces
+       REAL(wp), DIMENSION(1:surf_usm_v(3)%ns) ::  s_flux_usm_v_west  !< flux at west-facing vertical urban-type surfaces
+       REAL(wp), DIMENSION(1:surf_def_h(2)%ns) ::  s_flux_t           !< flux at model top
 #if defined( __nopointer )
        REAL(wp), DIMENSION(nzb:nzt+1,nysg:nyng,nxlg:nxrg) ::  s !< 
@@ -274,84 +492,232 @@
 !
 !--    Compute horizontal diffusion
-       DO  k = nzb_s_outer(j,i)+1, nzt
+       DO  k = nzb+1, nzt
+!
+!--       Predetermine flag to mask topography and wall-bounded grid points
+          flag = MERGE( 1.0_wp, 0.0_wp, BTEST( wall_flags_0(k,j,i), 0 ) ) 
+!
+!--       Predetermine flag to mask wall-bounded grid points, equivalent to
+!--       former s_outer array
+          mask_west  = MERGE( 1.0_wp, 0.0_wp, BTEST( wall_flags_0(k,j,i-1), 0 ) )
+          mask_east  = MERGE( 1.0_wp, 0.0_wp, BTEST( wall_flags_0(k,j,i+1), 0 ) )
+          mask_south = MERGE( 1.0_wp, 0.0_wp, BTEST( wall_flags_0(k,j-1,i), 0 ) )
+          mask_north = MERGE( 1.0_wp, 0.0_wp, BTEST( wall_flags_0(k,j+1,i), 0 ) )
+!
+!--       Finally, determine flag to mask both topography itself as well
+!--       as wall-bounded grid points, which will be treated further below
 
           tend(k,j,i) = tend(k,j,i)                                            &
                                           + 0.5_wp * (                         &
-                        ( kh(k,j,i) + kh(k,j,i+1) ) * ( s(k,j,i+1)-s(k,j,i) )  &
-                      - ( kh(k,j,i) + kh(k,j,i-1) ) * ( s(k,j,i)-s(k,j,i-1) )  &
-                                                     ) * ddx2                  &
+                            mask_east  * ( kh(k,j,i) + kh(k,j,i+1) )           &
+                                       * ( s(k,j,i+1) - s(k,j,i)   )           &
+                          - mask_west  * ( kh(k,j,i) + kh(k,j,i-1) )           &
+                                       * ( s(k,j,i)   - s(k,j,i-1) )           &
+                                                     ) * ddx2 * flag           &
                                           + 0.5_wp * (                         &
-                        ( kh(k,j,i) + kh(k,j+1,i) ) * ( s(k,j+1,i)-s(k,j,i) )  &
-                      - ( kh(k,j,i) + kh(k,j-1,i) ) * ( s(k,j,i)-s(k,j-1,i) )  &
-                                                     ) * ddy2
-       ENDDO
-
-!
-!--    Apply prescribed horizontal wall heatflux where necessary
-       IF ( ( wall_w_x(j,i) /= 0.0_wp ) .OR. ( wall_w_y(j,i) /= 0.0_wp ) )     &
-       THEN
-          DO  k = nzb_s_inner(j,i)+1, nzb_s_outer(j,i)
-
-             tend(k,j,i) = tend(k,j,i)                                         &
-                                                + ( fwxp(j,i) * 0.5_wp *       &
-                        ( kh(k,j,i) + kh(k,j,i+1) ) * ( s(k,j,i+1)-s(k,j,i) )  &
-                        + ( 1.0_wp - fwxp(j,i) ) * wall_s_flux(1)              &
-                                                   -fwxm(j,i) * 0.5_wp *       &
-                        ( kh(k,j,i) + kh(k,j,i-1) ) * ( s(k,j,i)-s(k,j,i-1) )  &
-                        + ( 1.0_wp - fwxm(j,i) ) * wall_s_flux(2)              &
-                                                  ) * ddx2                     &
-                                                + ( fwyp(j,i) * 0.5_wp *       &
-                        ( kh(k,j,i) + kh(k,j+1,i) ) * ( s(k,j+1,i)-s(k,j,i) )  &
-                        + ( 1.0_wp - fwyp(j,i) ) * wall_s_flux(3)              &
-                                                   -fwym(j,i) * 0.5_wp *       &
-                        ( kh(k,j,i) + kh(k,j-1,i) ) * ( s(k,j,i)-s(k,j-1,i) )  &
-                        + ( 1.0_wp - fwym(j,i) ) * wall_s_flux(4)              &
-                                                  ) * ddy2
+                            mask_north * ( kh(k,j,i) + kh(k,j+1,i) )           &
+                                       * ( s(k,j+1,i) - s(k,j,i)   )           &
+                          - mask_south * ( kh(k,j,i) + kh(k,j-1,i) )           &
+                                       * ( s(k,j,i)  - s(k,j-1,i)  )           &
+                                                     ) * ddy2 * flag
+       ENDDO
+
+!
+!--    Apply prescribed horizontal wall heatflux where necessary. First,
+!--    determine start and end index for respective (j,i)-index. Please
+!--    note, in the flat case following loops will not be entered, as
+!--    surf_s=1 and surf_e=0. Furtermore, note, no vertical natural surfaces
+!--    so far. 
+!--    First, for default-type surfaces
+!--    North-facing vertical default-type surfaces
+       surf_s = surf_def_v(0)%start_index(j,i)
+       surf_e = surf_def_v(0)%end_index(j,i)
+       DO  m = surf_s, surf_e
+          k           = surf_def_v(0)%k(m)
+          tend(k,j,i) = tend(k,j,i) + s_flux_def_v_north(m) * ddy2
+       ENDDO
+!
+!--    South-facing vertical default-type surfaces
+       surf_s = surf_def_v(1)%start_index(j,i)
+       surf_e = surf_def_v(1)%end_index(j,i)
+       DO  m = surf_s, surf_e
+          k           = surf_def_v(1)%k(m)
+          tend(k,j,i) = tend(k,j,i) + s_flux_def_v_south(m) * ddy2
+       ENDDO
+!
+!--    East-facing vertical default-type surfaces
+       surf_s = surf_def_v(2)%start_index(j,i)
+       surf_e = surf_def_v(2)%end_index(j,i)
+       DO  m = surf_s, surf_e
+          k           = surf_def_v(2)%k(m)
+          tend(k,j,i) = tend(k,j,i) + s_flux_def_v_east(m) * ddx2
+       ENDDO
+!
+!--    West-facing vertical default-type surfaces
+       surf_s = surf_def_v(3)%start_index(j,i)
+       surf_e = surf_def_v(3)%end_index(j,i)
+       DO  m = surf_s, surf_e
+          k           = surf_def_v(3)%k(m)
+          tend(k,j,i) = tend(k,j,i) + s_flux_def_v_west(m) * ddx2
+       ENDDO
+!
+!--    Now, for natural-type surfaces
+!--    North-facing
+       surf_s = surf_lsm_v(0)%start_index(j,i)
+       surf_e = surf_lsm_v(0)%end_index(j,i)
+       DO  m = surf_s, surf_e
+          k           = surf_lsm_v(0)%k(m)
+          tend(k,j,i) = tend(k,j,i) + s_flux_lsm_v_north(m) * ddy2
+       ENDDO
+!
+!--    South-facing
+       surf_s = surf_lsm_v(1)%start_index(j,i)
+       surf_e = surf_lsm_v(1)%end_index(j,i)
+       DO  m = surf_s, surf_e
+          k           = surf_lsm_v(1)%k(m)
+          tend(k,j,i) = tend(k,j,i) + s_flux_lsm_v_south(m) * ddy2
+       ENDDO
+!
+!--    East-facing
+       surf_s = surf_lsm_v(2)%start_index(j,i)
+       surf_e = surf_lsm_v(2)%end_index(j,i)
+       DO  m = surf_s, surf_e
+          k           = surf_lsm_v(2)%k(m)
+          tend(k,j,i) = tend(k,j,i) + s_flux_lsm_v_east(m) * ddx2
+       ENDDO
+!
+!--    West-facing
+       surf_s = surf_lsm_v(3)%start_index(j,i)
+       surf_e = surf_lsm_v(3)%end_index(j,i)
+       DO  m = surf_s, surf_e
+          k           = surf_lsm_v(3)%k(m)
+          tend(k,j,i) = tend(k,j,i) + s_flux_lsm_v_west(m) * ddx2
+       ENDDO
+!
+!--    Now, for urban-type surfaces
+!--    North-facing
+       surf_s = surf_usm_v(0)%start_index(j,i)
+       surf_e = surf_usm_v(0)%end_index(j,i)
+       DO  m = surf_s, surf_e
+          k           = surf_usm_v(0)%k(m)
+          tend(k,j,i) = tend(k,j,i) + s_flux_usm_v_north(m) * ddy2
+       ENDDO
+!
+!--    South-facing
+       surf_s = surf_usm_v(1)%start_index(j,i)
+       surf_e = surf_usm_v(1)%end_index(j,i)
+       DO  m = surf_s, surf_e
+          k           = surf_usm_v(1)%k(m)
+          tend(k,j,i) = tend(k,j,i) + s_flux_usm_v_south(m) * ddy2
+       ENDDO
+!
+!--    East-facing
+       surf_s = surf_usm_v(2)%start_index(j,i)
+       surf_e = surf_usm_v(2)%end_index(j,i)
+       DO  m = surf_s, surf_e
+          k           = surf_usm_v(2)%k(m)
+          tend(k,j,i) = tend(k,j,i) + s_flux_usm_v_east(m) * ddx2
+       ENDDO
+!
+!--    West-facing
+       surf_s = surf_usm_v(3)%start_index(j,i)
+       surf_e = surf_usm_v(3)%end_index(j,i)
+       DO  m = surf_s, surf_e
+          k           = surf_usm_v(3)%k(m)
+          tend(k,j,i) = tend(k,j,i) + s_flux_usm_v_west(m) * ddx2
+       ENDDO
+
+
+!
+!--    Compute vertical diffusion. In case that surface fluxes have been
+!--    prescribed or computed at bottom and/or top, index k starts/ends at
+!--    nzb+2 or nzt-1, respectively. Model top is also mask if top flux 
+!--    is given. 
+       DO  k = nzb+1, nzt
+!
+!--       Determine flags to mask topography below and above. Flag 0 is 
+!--       used to mask topography in general, and flag 8 implies 
+!--       information about use_surface_fluxes. Flag 9 is used to control 
+!--       flux at model top.   
+          mask_bottom = MERGE( 1.0_wp, 0.0_wp,                                 &
+                               BTEST( wall_flags_0(k-1,j,i), 8 ) ) 
+          mask_top    = MERGE( 1.0_wp, 0.0_wp,                                 &
+                               BTEST( wall_flags_0(k+1,j,i), 8 ) )  *          &
+                        MERGE( 1.0_wp, 0.0_wp,                                 &
+                               BTEST( wall_flags_0(k+1,j,i), 9 ) )
+          flag        = MERGE( 1.0_wp, 0.0_wp,                                 &
+                               BTEST( wall_flags_0(k,j,i), 0 ) )
+
+          tend(k,j,i) = tend(k,j,i)                                            &
+                                       + 0.5_wp * (                            &
+                                      ( kh(k,j,i) + kh(k+1,j,i) ) *            &
+                                          ( s(k+1,j,i)-s(k,j,i) ) * ddzu(k+1)  &
+                                                            * rho_air_zw(k)    &
+                                                            * mask_top         &
+                                    - ( kh(k,j,i) + kh(k-1,j,i) ) *            &
+                                          ( s(k,j,i)-s(k-1,j,i) ) * ddzu(k)    &
+                                                            * rho_air_zw(k-1)  &
+                                                            * mask_bottom      &
+                                                  ) * ddzw(k) * drho_air(k)    &
+                                                              * flag
+       ENDDO
+
+!
+!--    Vertical diffusion at horizontal walls.
+!--    TO DO: Adjust for downward facing walls and mask already in main loop
+       IF ( use_surface_fluxes )  THEN
+!
+!--       Default-type surfaces, upward-facing
+          surf_s = surf_def_h(0)%start_index(j,i)
+          surf_e = surf_def_h(0)%end_index(j,i)
+          DO  m = surf_s, surf_e
+
+             k   = surf_def_h(0)%k(m)
+
+             tend(k,j,i) = tend(k,j,i) + s_flux_def_h_up(m)                    &
+                                       * ddzw(k) * drho_air(k)
+          ENDDO
+!
+!--       Default-type surfaces, downward-facing
+          surf_s = surf_def_h(1)%start_index(j,i)
+          surf_e = surf_def_h(1)%end_index(j,i)
+          DO  m = surf_s, surf_e
+
+             k   = surf_def_h(1)%k(m)
+
+             tend(k,j,i) = tend(k,j,i) + s_flux_def_h_down(m)                  &
+                                       * ddzw(k) * drho_air(k)
+          ENDDO
+!
+!--       Natural-type surfaces, upward-facing
+          surf_s = surf_lsm_h%start_index(j,i)
+          surf_e = surf_lsm_h%end_index(j,i)
+          DO  m = surf_s, surf_e
+             k   = surf_lsm_h%k(m)
+
+             tend(k,j,i) = tend(k,j,i) + s_flux_lsm_h_up(m)                    &
+                                       * ddzw(k) * drho_air(k)
+          ENDDO
+!
+!--       Urban-type surfaces, upward-facing
+          surf_s = surf_usm_h%start_index(j,i)
+          surf_e = surf_usm_h%end_index(j,i)
+          DO  m = surf_s, surf_e
+             k   = surf_usm_h%k(m)
+
+             tend(k,j,i) = tend(k,j,i) + s_flux_usm_h_up(m)                    &
+                                       * ddzw(k) * drho_air(k)
           ENDDO
        ENDIF
-
-!
-!--    Compute vertical diffusion. In case that surface fluxes have been
-!--    prescribed or computed at bottom and/or top, index k starts/ends at
-!--    nzb+2 or nzt-1, respectively.
-       DO  k = nzb_diff_s_inner(j,i), nzt_diff
-
-          tend(k,j,i) = tend(k,j,i)                                            &
-                                       + 0.5_wp * (                            &
-            ( kh(k,j,i) + kh(k+1,j,i) ) * ( s(k+1,j,i)-s(k,j,i) ) * ddzu(k+1)  &
-                                                            * rho_air_zw(k)    &
-          - ( kh(k,j,i) + kh(k-1,j,i) ) * ( s(k,j,i)-s(k-1,j,i) ) * ddzu(k)    &
-                                                            * rho_air_zw(k-1)  &
-                                                  ) * ddzw(k) * drho_air(k)
-       ENDDO
-
-!
-!--    Vertical diffusion at the first computational gridpoint along z-direction
-       IF ( use_surface_fluxes )  THEN
-
-          k = nzb_s_inner(j,i)+1
-
-          tend(k,j,i) = tend(k,j,i) + ( 0.5_wp * ( kh(k,j,i)+kh(k+1,j,i) )     &
-                                               * ( s(k+1,j,i)-s(k,j,i) )       &
-                                               * ddzu(k+1)                     &
-                                               * rho_air_zw(k)                 &
-                                        + s_flux_b(j,i)                        &
-                                      ) * ddzw(k) * drho_air(k)
-
-       ENDIF
-
 !
 !--    Vertical diffusion at the last computational gridpoint along z-direction
        IF ( use_top_fluxes )  THEN
-
-          k = nzt
-
-          tend(k,j,i) = tend(k,j,i) + ( - s_flux_t(j,i)                        &
-                                      - 0.5_wp * ( kh(k-1,j,i)+kh(k,j,i) )     &
-                                               * ( s(k,j,i)-s(k-1,j,i) )       &
-                                               * ddzu(k)                       &
-                                               * rho_air_zw(k-1)               &
-                                      ) * ddzw(k) * drho_air(k)
-
+          surf_s = surf_def_h(2)%start_index(j,i)
+          surf_e = surf_def_h(2)%end_index(j,i)
+          DO  m = surf_s, surf_e
+
+             k   = surf_def_h(2)%k(m)
+             tend(k,j,i) = tend(k,j,i)                                         &
+                           + ( - s_flux_t(m) ) * ddzw(k) * drho_air(k)
+          ENDDO
        ENDIF
 
Index: /palm/trunk/SOURCE/diffusion_u.f90
===================================================================
--- /palm/trunk/SOURCE/diffusion_u.f90	(revision 2231)
+++ /palm/trunk/SOURCE/diffusion_u.f90	(revision 2232)
@@ -20,5 +20,5 @@
 ! Current revisions:
 ! -----------------
-! 
+! Adjustments to new topography and surface concept
 ! 
 ! Former revisions:
@@ -95,6 +95,4 @@
  
 
-    USE wall_fluxes_mod
-
     PRIVATE
     PUBLIC diffusion_u
@@ -116,39 +114,43 @@
 
        USE arrays_3d,                                                          &
-           ONLY:  ddzu, ddzw, km, tend, u, usws, uswst, v, w,                  &
-                  drho_air, rho_air_zw
+           ONLY:  ddzu, ddzw, km, tend, u, v, w, drho_air, rho_air_zw
        
        USE control_parameters,                                                 &
-           ONLY:  constant_top_momentumflux, topography, use_surface_fluxes,   &
+           ONLY:  constant_top_momentumflux, use_surface_fluxes,               &
                   use_top_fluxes
        
        USE grid_variables,                                                     &
-           ONLY:  ddx, ddx2, ddy, fym, fyp, wall_u
+           ONLY:  ddx, ddx2, ddy
        
        USE indices,                                                            &
-           ONLY:  nxl, nxlu, nxr, nyn, nys, nzb, nzb_diff_u, nzb_u_inner,      &
-                  nzb_u_outer, nzt, nzt_diff
-       
+           ONLY:  nxl, nxlu, nxr, nyn, nys, nzb, nzt, wall_flags_0
+     
        USE kinds
 
+       USE surface_mod,                                                        &
+           ONLY :  surf_def_h, surf_def_v, surf_lsm_h, surf_lsm_v, surf_usm_h, &
+                   surf_usm_v
+
        IMPLICIT NONE
 
-       INTEGER(iwp) ::  i     !< 
-       INTEGER(iwp) ::  j     !< 
-       INTEGER(iwp) ::  k     !< 
-       REAL(wp)     ::  kmym  !<
-       REAL(wp)     ::  kmyp  !<
-       REAL(wp)     ::  kmzm  !<
-       REAL(wp)     ::  kmzp  !<
-
-       REAL(wp), DIMENSION(nzb:nzt+1,nys:nyn,nxl:nxr) ::  usvs  !< 
-
-!
-!--    First calculate horizontal momentum flux u'v' at vertical walls,
-!--    if neccessary
-       IF ( topography /= 'flat' )  THEN
-          CALL wall_fluxes( usvs, 1.0_wp, 0.0_wp, 0.0_wp, 0.0_wp, nzb_u_inner, &
-                            nzb_u_outer, wall_u )
-       ENDIF
+       INTEGER(iwp) ::  i             !< running index x direction
+       INTEGER(iwp) ::  j             !< running index y direction
+       INTEGER(iwp) ::  k             !< running index z direction
+       INTEGER(iwp) ::  l             !< running index of surface type, south- or north-facing wall
+       INTEGER(iwp) ::  m             !< running index surface elements
+       INTEGER(iwp) ::  surf_e        !< End index of surface elements at (j,i)-gridpoint
+       INTEGER(iwp) ::  surf_s        !< Start index of surface elements at (j,i)-gridpoint
+
+       REAL(wp)     ::  flag          !< flag to mask topography grid points
+       REAL(wp)     ::  kmym          !< 
+       REAL(wp)     ::  kmyp          !<
+       REAL(wp)     ::  kmzm          !<
+       REAL(wp)     ::  kmzp          !<
+       REAL(wp)     ::  mask_bottom   !< flag to mask vertical upward-facing surface       
+       REAL(wp)     ::  mask_north    !< flag to mask vertical surface north of the grid point 
+       REAL(wp)     ::  mask_south    !< flag to mask vertical surface south of the grid point 
+       REAL(wp)     ::  mask_top      !< flag to mask vertical downward-facing surface 
+
+
 
        DO  i = nxlu, nxr
@@ -156,5 +158,12 @@
 !
 !--          Compute horizontal diffusion
-             DO  k = nzb_u_outer(j,i)+1, nzt
+             DO  k = nzb+1, nzt
+!
+!--             Predetermine flag to mask topography and wall-bounded grid points. 
+!--             It is sufficient to masked only north- and south-facing surfaces, which
+!--             need special treatment for the u-component. 
+                flag       = MERGE( 1.0_wp, 0.0_wp, BTEST( wall_flags_0(k,j,i),   1 ) ) 
+                mask_south = MERGE( 1.0_wp, 0.0_wp, BTEST( wall_flags_0(k,j-1,i), 1 ) )
+                mask_north = MERGE( 1.0_wp, 0.0_wp, BTEST( wall_flags_0(k,j+1,i), 1 ) )
 !
 !--             Interpolate eddy diffusivities on staggered gridpoints
@@ -165,47 +174,75 @@
 
                 tend(k,j,i) = tend(k,j,i)                                      &
-                      & + 2.0_wp * (                                           &
-                      &           km(k,j,i)   * ( u(k,j,i+1) - u(k,j,i)   )    &
-                      &         - km(k,j,i-1) * ( u(k,j,i)   - u(k,j,i-1) )    &
-                      &            ) * ddx2                                    &
-                      & + ( kmyp * ( u(k,j+1,i) - u(k,j,i)     ) * ddy         &
-                      &   + kmyp * ( v(k,j+1,i) - v(k,j+1,i-1) ) * ddx         &
-                      &   - kmym * ( u(k,j,i) - u(k,j-1,i) ) * ddy             &
-                      &   - kmym * ( v(k,j,i) - v(k,j,i-1) ) * ddx             &
-                      &   ) * ddy
+                        + 2.0_wp * (                                           &
+                                  km(k,j,i)   * ( u(k,j,i+1) - u(k,j,i)   )    &
+                                - km(k,j,i-1) * ( u(k,j,i)   - u(k,j,i-1) )    &
+                                   ) * ddx2 * flag                             &
+                        +          ( mask_north * (                            &
+                            kmyp * ( u(k,j+1,i) - u(k,j,i)     ) * ddy         &
+                          + kmyp * ( v(k,j+1,i) - v(k,j+1,i-1) ) * ddx         &
+                                                  )                            &
+                                   - mask_south * (                            &
+                            kmym * ( u(k,j,i) - u(k,j-1,i) ) * ddy             &
+                          + kmym * ( v(k,j,i) - v(k,j,i-1) ) * ddx             &
+                                                  )                            &
+                                   ) * ddy  * flag                             
              ENDDO
-
-!
-!--          Wall functions at the north and south walls, respectively
-             IF ( wall_u(j,i) /= 0.0_wp )  THEN
-
-                DO  k = nzb_u_inner(j,i)+1, nzb_u_outer(j,i)
-                   kmyp = 0.25_wp *                                            &
-                          ( km(k,j,i)+km(k,j+1,i)+km(k,j,i-1)+km(k,j+1,i-1) )
-                   kmym = 0.25_wp *                                            &
-                          ( km(k,j,i)+km(k,j-1,i)+km(k,j,i-1)+km(k,j-1,i-1) )
-
-                   tend(k,j,i) = tend(k,j,i)                                   &
-                                 + 2.0_wp * (                                  &
-                                       km(k,j,i)   * ( u(k,j,i+1) - u(k,j,i) ) &
-                                     - km(k,j,i-1) * ( u(k,j,i) - u(k,j,i-1) ) &
-                                            ) * ddx2                           &
-                                 + (   fyp(j,i) * (                            &
-                                  kmyp * ( u(k,j+1,i) - u(k,j,i)     ) * ddy   &
-                                + kmyp * ( v(k,j+1,i) - v(k,j+1,i-1) ) * ddx   &
-                                                  )                            &
-                                     - fym(j,i) * (                            &
-                                  kmym * ( u(k,j,i) - u(k,j-1,i) ) * ddy       &
-                                + kmym * ( v(k,j,i) - v(k,j,i-1) ) * ddx       &
-                                                  )                            &
-                                     + wall_u(j,i) * usvs(k,j,i)               &
-                                   ) * ddy
-                ENDDO
-             ENDIF
-
-!
-!--          Compute vertical diffusion. In case of simulating a Prandtl layer,
-!--          index k starts at nzb_u_inner+2.
-             DO  k = nzb_diff_u(j,i), nzt_diff
+!
+!--          Add horizontal momentum flux u'v' at north- (l=0) and south-facing (l=1)
+!--          surfaces. Note, in the the flat case, loops won't be entered as 
+!--          start_index > end_index. Furtermore, note, no vertical natural surfaces
+!--          so far.           
+!--          Default-type surfaces
+             DO  l = 0, 1
+                surf_s = surf_def_v(l)%start_index(j,i)
+                surf_e = surf_def_v(l)%end_index(j,i)
+                DO  m = surf_s, surf_e
+                   k           = surf_def_v(l)%k(m)
+                   tend(k,j,i) = tend(k,j,i) +                                 &                    
+                                    surf_def_v(l)%mom_flux_uv(m) * ddy
+                ENDDO   
+             ENDDO
+!
+!--          Natural-type surfaces
+             DO  l = 0, 1
+                surf_s = surf_lsm_v(l)%start_index(j,i)
+                surf_e = surf_lsm_v(l)%end_index(j,i)
+                DO  m = surf_s, surf_e
+                   k           = surf_lsm_v(l)%k(m)
+                   tend(k,j,i) = tend(k,j,i) +                                 &                    
+                                    surf_lsm_v(l)%mom_flux_uv(m) * ddy
+                ENDDO   
+             ENDDO
+!
+!--          Urban-type surfaces
+             DO  l = 0, 1
+                surf_s = surf_usm_v(l)%start_index(j,i)
+                surf_e = surf_usm_v(l)%end_index(j,i)
+                DO  m = surf_s, surf_e
+                   k           = surf_usm_v(l)%k(m)
+                   tend(k,j,i) = tend(k,j,i) +                                 &                    
+                                    surf_usm_v(l)%mom_flux_uv(m) * ddy
+                ENDDO   
+             ENDDO
+
+!
+!--          Compute vertical diffusion. In case of simulating a surface layer,
+!--          respective grid diffusive fluxes are masked (flag 8) within this 
+!--          loop, and added further below, else, simple gradient approach is
+!--          applied. Model top is also mask if top-momentum flux is given. 
+             DO  k = nzb+1, nzt
+!
+!--             Determine flags to mask topography below and above. Flag 1 is 
+!--             used to mask topography in general, and flag 8 implies 
+!--             information about use_surface_fluxes. Flag 9 is used to control 
+!--             momentum flux at model top.  
+                mask_bottom = MERGE( 1.0_wp, 0.0_wp,                           &
+                                     BTEST( wall_flags_0(k-1,j,i), 8 ) ) 
+                mask_top    = MERGE( 1.0_wp, 0.0_wp,                           &
+                                     BTEST( wall_flags_0(k+1,j,i), 8 ) ) *     &
+                              MERGE( 1.0_wp, 0.0_wp,                           &
+                                     BTEST( wall_flags_0(k+1,j,i), 9 ) ) 
+                flag        = MERGE( 1.0_wp, 0.0_wp,                           &
+                                     BTEST( wall_flags_0(k,j,i), 1 ) ) 
 !
 !--             Interpolate eddy diffusivities on staggered gridpoints
@@ -216,11 +253,11 @@
 
                 tend(k,j,i) = tend(k,j,i)                                      &
-                      & + ( kmzp * ( ( u(k+1,j,i) - u(k,j,i)   ) * ddzu(k+1)   &
-                      &            + ( w(k,j,i)   - w(k,j,i-1) ) * ddx         &
-                      &            ) * rho_air_zw(k)                           &
-                      &   - kmzm * ( ( u(k,j,i)   - u(k-1,j,i)   ) * ddzu(k)   &
-                      &            + ( w(k-1,j,i) - w(k-1,j,i-1) ) * ddx       &
-                      &            ) * rho_air_zw(k-1)                         &
-                      &   ) * ddzw(k) * drho_air(k)
+                        + ( kmzp * ( ( u(k+1,j,i) - u(k,j,i)   ) * ddzu(k+1)   &
+                                   + ( w(k,j,i)   - w(k,j,i-1) ) * ddx         &
+                                   ) * rho_air_zw(k)   * mask_top              &
+                          - kmzm * ( ( u(k,j,i)   - u(k-1,j,i)   ) * ddzu(k)   &
+                                   + ( w(k-1,j,i) - w(k-1,j,i-1) ) * ddx       &
+                                   ) * rho_air_zw(k-1) * mask_bottom           &
+                          ) * ddzw(k) * drho_air(k) * flag
              ENDDO
 
@@ -236,34 +273,66 @@
 !--          because the vertical velocity is assumed to be zero at the surface.
              IF ( use_surface_fluxes )  THEN
-                k = nzb_u_inner(j,i)+1
-!
-!--             Interpolate eddy diffusivities on staggered gridpoints
-                kmzp = 0.25_wp *                                               &
-                      ( km(k,j,i)+km(k+1,j,i)+km(k,j,i-1)+km(k+1,j,i-1) )
-
-                tend(k,j,i) = tend(k,j,i)                                      &
-                      & + ( kmzp * ( ( u(k+1,j,i) - u(k,j,i)   ) * ddzu(k+1)   &
-                      &            + ( w(k,j,i)   - w(k,j,i-1) ) * ddx         &
-                      &            ) * rho_air_zw(k)                           &
-                      &   - ( -usws(j,i) )                                     &
-                      &   ) * ddzw(k) * drho_air(k)
+!
+!--             Default-type surfaces, upward-facing
+                surf_s = surf_def_h(0)%start_index(j,i)
+                surf_e = surf_def_h(0)%end_index(j,i)
+                DO  m = surf_s, surf_e
+
+                   k   = surf_def_h(0)%k(m)
+
+                   tend(k,j,i) = tend(k,j,i)                                   &
+                        + ( - ( - surf_def_h(0)%usws(m) )                      &
+                          ) * ddzw(k) * drho_air(k)
+                ENDDO
+!
+!--             Default-type surfaces, dowward-facing
+                surf_s = surf_def_h(1)%start_index(j,i)
+                surf_e = surf_def_h(1)%end_index(j,i)
+                DO  m = surf_s, surf_e
+
+                   k   = surf_def_h(1)%k(m)
+
+                   tend(k,j,i) = tend(k,j,i)                                   &
+                        + ( - surf_def_h(1)%usws(m)                            &
+                          ) * ddzw(k) * drho_air(k)
+                ENDDO
+!
+!--             Natural-type surfaces, upward-facing
+                surf_s = surf_lsm_h%start_index(j,i)
+                surf_e = surf_lsm_h%end_index(j,i)
+                DO  m = surf_s, surf_e
+
+                   k   = surf_lsm_h%k(m)
+
+                   tend(k,j,i) = tend(k,j,i)                                   &
+                        + ( - ( - surf_lsm_h%usws(m) )                         &
+                          ) * ddzw(k) * drho_air(k)
+                ENDDO
+!
+!--             Urban-type surfaces, upward-facing
+                surf_s = surf_usm_h%start_index(j,i)
+                surf_e = surf_usm_h%end_index(j,i)
+                DO  m = surf_s, surf_e
+
+                   k   = surf_usm_h%k(m)
+
+                   tend(k,j,i) = tend(k,j,i)                                   &
+                       + ( - ( - surf_usm_h%usws(m) )                          &
+                         ) * ddzw(k) * drho_air(k)
+                ENDDO
+
              ENDIF
-
-!
-!--          Vertical diffusion at the first gridpoint below the top boundary,
-!--          if the momentum flux at the top is prescribed by the user
-             IF ( use_top_fluxes  .AND.  constant_top_momentumflux )  THEN
-                k = nzt
-!
-!--             Interpolate eddy diffusivities on staggered gridpoints
-                kmzm = 0.25_wp *                                               &
-                       ( km(k,j,i)+km(k-1,j,i)+km(k,j,i-1)+km(k-1,j,i-1) )
-
-                tend(k,j,i) = tend(k,j,i)                                      &
-                      & + ( ( -uswst(j,i) )                                    &
-                      &   - kmzm * ( ( u(k,j,i)   - u(k-1,j,i)   ) * ddzu(k)   &
-                      &            + ( w(k-1,j,i) - w(k-1,j,i-1) ) * ddx       &
-                      &            ) * rho_air_zw(k-1)                         &
-                      &   ) * ddzw(k) * drho_air(k)
+!
+!--          Add momentum flux at model top
+             IF ( use_top_fluxes )  THEN
+                surf_s = surf_def_h(2)%start_index(j,i)
+                surf_e = surf_def_h(2)%end_index(j,i)
+                DO  m = surf_s, surf_e
+
+                   k   = surf_def_h(2)%k(m)
+
+                   tend(k,j,i) = tend(k,j,i)                                   &
+                        + ( - surf_def_h(2)%usws(m) ) * ddzw(k) * drho_air(k)
+                ENDDO
              ENDIF
 
@@ -282,33 +351,51 @@
 
        USE arrays_3d,                                                          &
-           ONLY:  ddzu, ddzw, km, tend, u, usws, uswst, v, w,                  &
-                  drho_air, rho_air_zw
+           ONLY:  ddzu, ddzw, km, tend, u, v, w, drho_air, rho_air_zw
        
        USE control_parameters,                                                 &
-           ONLY:  constant_top_momentumflux, use_surface_fluxes, use_top_fluxes
+           ONLY:  constant_top_momentumflux, use_surface_fluxes,               &
+                  use_top_fluxes
        
        USE grid_variables,                                                     &
-           ONLY:  ddx, ddx2, ddy, fym, fyp, wall_u
+           ONLY:  ddx, ddx2, ddy
        
        USE indices,                                                            &
-           ONLY:  nzb, nzb_diff_u, nzb_u_inner, nzb_u_outer, nzt, nzt_diff
-       
+           ONLY:  nzb, nzt, wall_flags_0
+      
        USE kinds
 
+       USE surface_mod,                                                        &
+           ONLY :  surf_def_h, surf_def_v, surf_lsm_h, surf_lsm_v, surf_usm_h, &
+                   surf_usm_v
+
        IMPLICIT NONE
 
-       INTEGER(iwp) ::  i     !< 
-       INTEGER(iwp) ::  j     !< 
-       INTEGER(iwp) ::  k     !< 
-       REAL(wp)     ::  kmym  !<
-       REAL(wp)     ::  kmyp  !<
-       REAL(wp)     ::  kmzm  !<
-       REAL(wp)     ::  kmzp  !<
-
-       REAL(wp), DIMENSION(nzb:nzt+1) ::  usvs  !< 
-
-!
+       INTEGER(iwp) ::  i             !< running index x direction
+       INTEGER(iwp) ::  j             !< running index y direction
+       INTEGER(iwp) ::  k             !< running index z direction
+       INTEGER(iwp) ::  l             !< running index of surface type, south- or north-facing wall
+       INTEGER(iwp) ::  m             !< running index surface elements
+       INTEGER(iwp) ::  surf_e        !< End index of surface elements at (j,i)-gridpoint
+       INTEGER(iwp) ::  surf_s        !< Start index of surface elements at (j,i)-gridpoint
+
+       REAL(wp)     ::  flag          !< flag to mask topography grid points
+       REAL(wp)     ::  kmym          !< 
+       REAL(wp)     ::  kmyp          !<
+       REAL(wp)     ::  kmzm          !<
+       REAL(wp)     ::  kmzp          !<
+       REAL(wp)     ::  mask_bottom   !< flag to mask vertical upward-facing surface       
+       REAL(wp)     ::  mask_north    !< flag to mask vertical surface north of the grid point 
+       REAL(wp)     ::  mask_south    !< flag to mask vertical surface south of the grid point 
+       REAL(wp)     ::  mask_top      !< flag to mask vertical downward-facing surface 
+! 
 !--    Compute horizontal diffusion
-       DO  k = nzb_u_outer(j,i)+1, nzt
+       DO  k = nzb+1, nzt
+!
+!--       Predetermine flag to mask topography and wall-bounded grid points. 
+!--       It is sufficient to masked only north- and south-facing surfaces, which
+!--       need special treatment for the u-component. 
+          flag       = MERGE( 1.0_wp, 0.0_wp, BTEST( wall_flags_0(k,j,i),   1 ) ) 
+          mask_south = MERGE( 1.0_wp, 0.0_wp, BTEST( wall_flags_0(k,j-1,i), 1 ) )
+          mask_north = MERGE( 1.0_wp, 0.0_wp, BTEST( wall_flags_0(k,j+1,i), 1 ) )
 !
 !--       Interpolate eddy diffusivities on staggered gridpoints
@@ -317,50 +404,71 @@
 
           tend(k,j,i) = tend(k,j,i)                                            &
-                      & + 2.0_wp * (                                           &
-                      &           km(k,j,i)   * ( u(k,j,i+1) - u(k,j,i)   )    &
-                      &         - km(k,j,i-1) * ( u(k,j,i)   - u(k,j,i-1) )    &
-                      &            ) * ddx2                                    &
-                      & + ( kmyp * ( u(k,j+1,i) - u(k,j,i)     ) * ddy         &
-                      &   + kmyp * ( v(k,j+1,i) - v(k,j+1,i-1) ) * ddx         &
-                      &   - kmym * ( u(k,j,i) - u(k,j-1,i) ) * ddy             &
-                      &   - kmym * ( v(k,j,i) - v(k,j,i-1) ) * ddx             &
-                      &   ) * ddy
+                       + 2.0_wp * (                                            &
+                                 km(k,j,i)   * ( u(k,j,i+1) - u(k,j,i)   )     &
+                               - km(k,j,i-1) * ( u(k,j,i)   - u(k,j,i-1) )     &
+                                   ) * ddx2 * flag                             &
+                                 + (                                           &
+                  mask_north * kmyp * ( ( u(k,j+1,i) - u(k,j,i)     ) * ddy    &
+                                      + ( v(k,j+1,i) - v(k,j+1,i-1) ) * ddx    &
+                                      )                                        &
+                - mask_south * kmym * ( ( u(k,j,i)   - u(k,j-1,i)   ) * ddy    &
+                                      + ( v(k,j,i)   - v(k,j,i-1)   ) * ddx    &
+                                      )                                        &
+                                   ) * ddy  * flag
        ENDDO
 
 !
-!--    Wall functions at the north and south walls, respectively
-       IF ( wall_u(j,i) /= 0.0_wp )  THEN
-
-!
-!--       Calculate the horizontal momentum flux u'v'
-          CALL wall_fluxes( i, j, nzb_u_inner(j,i)+1, nzb_u_outer(j,i),        &
-                            usvs, 1.0_wp, 0.0_wp, 0.0_wp, 0.0_wp )
-
-          DO  k = nzb_u_inner(j,i)+1, nzb_u_outer(j,i)
-             kmyp = 0.25_wp * ( km(k,j,i)+km(k,j+1,i)+km(k,j,i-1)+km(k,j+1,i-1) )
-             kmym = 0.25_wp * ( km(k,j,i)+km(k,j-1,i)+km(k,j,i-1)+km(k,j-1,i-1) )
-
-             tend(k,j,i) = tend(k,j,i)                                         &
-                                 + 2.0_wp * (                                  &
-                                       km(k,j,i)   * ( u(k,j,i+1) - u(k,j,i) ) &
-                                     - km(k,j,i-1) * ( u(k,j,i) - u(k,j,i-1) ) &
-                                            ) * ddx2                           &
-                                 + (   fyp(j,i) * (                            &
-                                  kmyp * ( u(k,j+1,i) - u(k,j,i)     ) * ddy   &
-                                + kmyp * ( v(k,j+1,i) - v(k,j+1,i-1) ) * ddx   &
-                                                  )                            &
-                                     - fym(j,i) * (                            &
-                                  kmym * ( u(k,j,i) - u(k,j-1,i) ) * ddy       &
-                                + kmym * ( v(k,j,i) - v(k,j,i-1) ) * ddx       &
-                                                  )                            &
-                                     + wall_u(j,i) * usvs(k)                   &
-                                   ) * ddy
-          ENDDO
-       ENDIF
-
-!
-!--    Compute vertical diffusion. In case of simulating a Prandtl layer,
-!--    index k starts at nzb_u_inner+2.
-       DO  k = nzb_diff_u(j,i), nzt_diff
+!--    Add horizontal momentum flux u'v' at north- (l=0) and south-facing (l=1)
+!--    surfaces. Note, in the the flat case, loops won't be entered as 
+!--    start_index > end_index. Furtermore, note, no vertical natural surfaces
+!--    so far.           
+!--    Default-type surfaces
+       DO  l = 0, 1
+          surf_s = surf_def_v(l)%start_index(j,i)
+          surf_e = surf_def_v(l)%end_index(j,i)
+          DO  m = surf_s, surf_e
+             k           = surf_def_v(l)%k(m)
+             tend(k,j,i) = tend(k,j,i) + surf_def_v(l)%mom_flux_uv(m) * ddy
+          ENDDO   
+       ENDDO
+!
+!--    Natural-type surfaces
+       DO  l = 0, 1
+          surf_s = surf_lsm_v(l)%start_index(j,i)
+          surf_e = surf_lsm_v(l)%end_index(j,i)
+          DO  m = surf_s, surf_e
+             k           = surf_lsm_v(l)%k(m)
+             tend(k,j,i) = tend(k,j,i) + surf_lsm_v(l)%mom_flux_uv(m) * ddy
+          ENDDO   
+       ENDDO
+!
+!--    Urban-type surfaces
+       DO  l = 0, 1
+          surf_s = surf_usm_v(l)%start_index(j,i)
+          surf_e = surf_usm_v(l)%end_index(j,i)
+          DO  m = surf_s, surf_e
+             k           = surf_usm_v(l)%k(m)
+             tend(k,j,i) = tend(k,j,i) + surf_usm_v(l)%mom_flux_uv(m) * ddy
+          ENDDO   
+       ENDDO
+!
+!--    Compute vertical diffusion. In case of simulating a surface layer,
+!--    respective grid diffusive fluxes are masked (flag 8) within this 
+!--    loop, and added further below, else, simple gradient approach is
+!--    applied. Model top is also mask if top-momentum flux is given.
+       DO  k = nzb+1, nzt
+!
+!--       Determine flags to mask topography below and above. Flag 1 is 
+!--       used to mask topography in general, and flag 8 implies 
+!--       information about use_surface_fluxes. Flag 9 is used to control 
+!--       momentum flux at model top. 
+          mask_bottom = MERGE( 1.0_wp, 0.0_wp,                                 &
+                               BTEST( wall_flags_0(k-1,j,i), 8 ) ) 
+          mask_top    = MERGE( 1.0_wp, 0.0_wp,                                 &
+                               BTEST( wall_flags_0(k+1,j,i), 8 ) ) *           &
+                        MERGE( 1.0_wp, 0.0_wp,                                 &
+                               BTEST( wall_flags_0(k+1,j,i), 9 ) )
+          flag        = MERGE( 1.0_wp, 0.0_wp,                                 &
+                               BTEST( wall_flags_0(k,j,i), 1 ) ) 
 !
 !--       Interpolate eddy diffusivities on staggered gridpoints
@@ -369,15 +477,15 @@
 
           tend(k,j,i) = tend(k,j,i)                                            &
-                      & + ( kmzp * ( ( u(k+1,j,i) - u(k,j,i)   ) * ddzu(k+1)   &
-                      &            + ( w(k,j,i)   - w(k,j,i-1) ) * ddx         &
-                      &            ) * rho_air_zw(k)                           &
-                      &   - kmzm * ( ( u(k,j,i)   - u(k-1,j,i)   ) * ddzu(k)   &
-                      &            + ( w(k-1,j,i) - w(k-1,j,i-1) ) * ddx       &
-                      &            ) * rho_air_zw(k-1)                         &
-                      &   ) * ddzw(k) * drho_air(k)
+                        + ( kmzp * ( ( u(k+1,j,i) - u(k,j,i)   ) * ddzu(k+1)   &
+                                   + ( w(k,j,i)   - w(k,j,i-1) ) * ddx         &
+                                   ) * rho_air_zw(k)   * mask_top              &
+                          - kmzm * ( ( u(k,j,i)   - u(k-1,j,i)   ) * ddzu(k)   &
+                                   + ( w(k-1,j,i) - w(k-1,j,i-1) ) * ddx       &
+                                   ) * rho_air_zw(k-1) * mask_bottom           &
+                          ) * ddzw(k) * drho_air(k) * flag
        ENDDO
 
 !
-!--    Vertical diffusion at the first grid point above the surface, if the
+!--    Vertical diffusion at the first surface grid points, if the
 !--    momentum flux at the bottom is given by the Prandtl law or if it is
 !--    prescribed by the user.
@@ -386,37 +494,70 @@
 !--    other (LES) models showed that the values of the momentum flux becomes
 !--    too large in this case.
-!--    The term containing w(k-1,..) (see above equation) is removed here
-!--    because the vertical velocity is assumed to be zero at the surface.
        IF ( use_surface_fluxes )  THEN
-          k = nzb_u_inner(j,i)+1
-!
-!--       Interpolate eddy diffusivities on staggered gridpoints
-          kmzp = 0.25_wp * ( km(k,j,i)+km(k+1,j,i)+km(k,j,i-1)+km(k+1,j,i-1) )
-
-          tend(k,j,i) = tend(k,j,i)                                            &
-                      & + ( kmzp * ( ( u(k+1,j,i) - u(k,j,i)   ) * ddzu(k+1)   &
-                      &            + ( w(k,j,i)   - w(k,j,i-1) ) * ddx         &
-                      &            ) * rho_air_zw(k)                           &
-                      &   - ( -usws(j,i) )                                     &
-                      &   ) * ddzw(k) * drho_air(k)
+!
+!--       Default-type surfaces, upward-facing
+          surf_s = surf_def_h(0)%start_index(j,i)
+          surf_e = surf_def_h(0)%end_index(j,i)
+          DO  m = surf_s, surf_e
+
+             k   = surf_def_h(0)%k(m)
+
+             tend(k,j,i) = tend(k,j,i)                                         &
+                        + ( - ( - surf_def_h(0)%usws(m) )                      &
+                          ) * ddzw(k) * drho_air(k)
+          ENDDO
+!
+!--       Default-type surfaces, dowward-facing (except for model-top fluxes)
+          surf_s = surf_def_h(1)%start_index(j,i)
+          surf_e = surf_def_h(1)%end_index(j,i)
+          DO  m = surf_s, surf_e
+
+             k   = surf_def_h(1)%k(m)
+
+             tend(k,j,i) = tend(k,j,i)                                         &
+                        + ( - surf_def_h(1)%usws(m)                            &
+                          ) * ddzw(k) * drho_air(k)
+          ENDDO
+!
+!--       Natural-type surfaces, upward-facing
+          surf_s = surf_lsm_h%start_index(j,i)
+          surf_e = surf_lsm_h%end_index(j,i)
+          DO  m = surf_s, surf_e
+
+             k   = surf_lsm_h%k(m)
+
+             tend(k,j,i) = tend(k,j,i)                                         &
+                        + ( - ( - surf_lsm_h%usws(m) )                         &
+                          ) * ddzw(k) * drho_air(k)
+          ENDDO
+!
+!--       Urban-type surfaces, upward-facing
+          surf_s = surf_usm_h%start_index(j,i)
+          surf_e = surf_usm_h%end_index(j,i)
+          DO  m = surf_s, surf_e
+
+             k   = surf_usm_h%k(m)
+
+             tend(k,j,i) = tend(k,j,i)                                         &
+                       + ( - ( - surf_usm_h%usws(m) )                          &
+                         ) * ddzw(k) * drho_air(k)
+          ENDDO
+
        ENDIF
-
-!
-!--    Vertical diffusion at the first gridpoint below the top boundary,
-!--    if the momentum flux at the top is prescribed by the user
-       IF ( use_top_fluxes  .AND.  constant_top_momentumflux )  THEN
-          k = nzt
-!
-!--       Interpolate eddy diffusivities on staggered gridpoints
-          kmzm = 0.25_wp * ( km(k,j,i)+km(k-1,j,i)+km(k,j,i-1)+km(k-1,j,i-1) )
-
-          tend(k,j,i) = tend(k,j,i)                                            &
-                      & + ( ( -uswst(j,i) )                                    &
-                      &   - kmzm * ( ( u(k,j,i)   - u(k-1,j,i)   ) * ddzu(k)   &
-                      &            + ( w(k-1,j,i) - w(k-1,j,i-1) ) * ddx       &
-                      &            ) * rho_air_zw(k-1)                         &
-                      &   ) * ddzw(k) * drho_air(k)
+!
+!--    Add momentum flux at model top
+       IF ( use_top_fluxes )  THEN
+          surf_s = surf_def_h(2)%start_index(j,i)
+          surf_e = surf_def_h(2)%end_index(j,i)
+          DO  m = surf_s, surf_e
+
+             k   = surf_def_h(2)%k(m)
+
+             tend(k,j,i) = tend(k,j,i)                                         &
+                           + ( - surf_def_h(2)%usws(m) ) * ddzw(k) * drho_air(k)
+          ENDDO
        ENDIF
 
+
     END SUBROUTINE diffusion_u_ij
 
Index: /palm/trunk/SOURCE/diffusion_v.f90
===================================================================
--- /palm/trunk/SOURCE/diffusion_v.f90	(revision 2231)
+++ /palm/trunk/SOURCE/diffusion_v.f90	(revision 2232)
@@ -20,5 +20,5 @@
 ! Current revisions:
 ! -----------------
-! 
+! Adjustments to new topography and surface concept
 ! 
 ! Former revisions:
@@ -90,6 +90,4 @@
  
 
-    USE wall_fluxes_mod
-
     PRIVATE
     PUBLIC diffusion_v
@@ -111,39 +109,41 @@
 
        USE arrays_3d,                                                          &
-           ONLY:  ddzu, ddzw, km, tend, u, v, vsws, vswst, w,                  &
-                  drho_air, rho_air_zw
+           ONLY:  ddzu, ddzw, km, tend, u, v, w, drho_air, rho_air_zw
        
        USE control_parameters,                                                 &
-           ONLY:  constant_top_momentumflux, topography, use_surface_fluxes,   &
+           ONLY:  constant_top_momentumflux, use_surface_fluxes,               &
                   use_top_fluxes
        
        USE grid_variables,                                                     &
-           ONLY:  ddx, ddy, ddy2, fxm, fxp, wall_v
+           ONLY:  ddx, ddy, ddy2
        
        USE indices,                                                            &
-           ONLY:  nxl, nxr, nyn, nys, nysv, nzb, nzb_diff_v, nzb_v_inner,      &
-                  nzb_v_outer, nzt, nzt_diff
+           ONLY:  nxl, nxr, nyn, nys, nysv, nzb, nzt, wall_flags_0
        
        USE kinds
 
+       USE surface_mod,                                                        &
+           ONLY :  surf_def_h, surf_def_v, surf_lsm_h, surf_lsm_v, surf_usm_h, &
+                   surf_usm_v
+
        IMPLICIT NONE
 
-       INTEGER(iwp) ::  i     !< 
-       INTEGER(iwp) ::  j     !< 
-       INTEGER(iwp) ::  k     !< 
-       REAL(wp)     ::  kmxm  !< 
-       REAL(wp)     ::  kmxp  !< 
-       REAL(wp)     ::  kmzm  !< 
-       REAL(wp)     ::  kmzp  !< 
-
-       REAL(wp), DIMENSION(nzb:nzt+1,nys:nyn,nxl:nxr) ::  vsus  !< 
-
-!
-!--    First calculate horizontal momentum flux v'u' at vertical walls,
-!--    if neccessary
-       IF ( topography /= 'flat' )  THEN
-          CALL wall_fluxes( vsus, 0.0_wp, 1.0_wp, 0.0_wp, 0.0_wp, nzb_v_inner, &
-                            nzb_v_outer, wall_v )
-       ENDIF
+       INTEGER(iwp) ::  i             !< running index x direction
+       INTEGER(iwp) ::  j             !< running index y direction
+       INTEGER(iwp) ::  k             !< running index z direction
+       INTEGER(iwp) ::  l             !< running index of surface type, south- or north-facing wall
+       INTEGER(iwp) ::  m             !< running index surface elements
+       INTEGER(iwp) ::  surf_e        !< End index of surface elements at (j,i)-gridpoint
+       INTEGER(iwp) ::  surf_s        !< Start index of surface elements at (j,i)-gridpoint
+
+       REAL(wp)     ::  flag          !< flag to mask topography grid points
+       REAL(wp)     ::  kmxm          !< 
+       REAL(wp)     ::  kmxp          !< 
+       REAL(wp)     ::  kmzm          !< 
+       REAL(wp)     ::  kmzp          !< 
+       REAL(wp)     ::  mask_bottom   !< flag to mask vertical upward-facing surface  
+       REAL(wp)     ::  mask_east     !< flag to mask vertical surface south of the grid point 
+       REAL(wp)     ::  mask_west     !< flag to mask vertical surface north of the grid point 
+       REAL(wp)     ::  mask_top      !< flag to mask vertical downward-facing surface      
 
        DO  i = nxl, nxr
@@ -151,56 +151,91 @@
 !
 !--          Compute horizontal diffusion
-             DO  k = nzb_v_outer(j,i)+1, nzt
+             DO  k = nzb+1, nzt
+
+!
+!--             Predetermine flag to mask topography and wall-bounded grid points. 
+!--             It is sufficient to masked only east- and west-facing surfaces, which
+!--             need special treatment for the v-component. 
+                flag      = MERGE( 1.0_wp, 0.0_wp, BTEST( wall_flags_0(k,j,i),   2 ) ) 
+                mask_east = MERGE( 1.0_wp, 0.0_wp, BTEST( wall_flags_0(k,j,i+1), 2 ) )
+                mask_west = MERGE( 1.0_wp, 0.0_wp, BTEST( wall_flags_0(k,j,i-1), 2 ) )
 !
 !--             Interpolate eddy diffusivities on staggered gridpoints
-                kmxp = 0.25_wp * &
-                       ( km(k,j,i)+km(k,j,i+1)+km(k,j-1,i)+km(k,j-1,i+1) )
-                kmxm = 0.25_wp * &
-                       ( km(k,j,i)+km(k,j,i-1)+km(k,j-1,i)+km(k,j-1,i-1) )
-
-                tend(k,j,i) = tend(k,j,i)                                      &
-                      & + ( kmxp * ( v(k,j,i+1) - v(k,j,i)     ) * ddx         &
-                      &   + kmxp * ( u(k,j,i+1) - u(k,j-1,i+1) ) * ddy         &
-                      &   - kmxm * ( v(k,j,i) - v(k,j,i-1) ) * ddx             &
-                      &   - kmxm * ( u(k,j,i) - u(k,j-1,i) ) * ddy             &
-                      &   ) * ddx                                              &
-                      & + 2.0_wp * (                                           &
-                      &           km(k,j,i)   * ( v(k,j+1,i) - v(k,j,i) )      &
-                      &         - km(k,j-1,i) * ( v(k,j,i) - v(k,j-1,i) )      &
-                      &            ) * ddy2
+                kmxp = 0.25_wp * ( km(k,j,i)+km(k,j,i+1)+km(k,j-1,i)+km(k,j-1,i+1) )
+                kmxm = 0.25_wp * ( km(k,j,i)+km(k,j,i-1)+km(k,j-1,i)+km(k,j-1,i-1) )
+
+                tend(k,j,i) = tend(k,j,i) +    (                             &
+                          mask_east * kmxp * (                               &
+                                 ( v(k,j,i+1) - v(k,j,i)     ) * ddx         &
+                               + ( u(k,j,i+1) - u(k,j-1,i+1) ) * ddy         &
+                                             )                               &
+                        - mask_west * kmxm * (                               &
+                                 ( v(k,j,i) - v(k,j,i-1) ) * ddx             &
+                               + ( u(k,j,i) - u(k,j-1,i) ) * ddy             &
+                                             )                               &
+                                               ) * ddx  * flag               &
+                                    + 2.0_wp * (                             &
+                                  km(k,j,i)   * ( v(k,j+1,i) - v(k,j,i)   )  &
+                                - km(k,j-1,i) * ( v(k,j,i)   - v(k,j-1,i) )  &
+                                               ) * ddy2 * flag
+
              ENDDO
 
 !
-!--          Wall functions at the left and right walls, respectively
-             IF ( wall_v(j,i) /= 0.0_wp )  THEN
-
-                DO  k = nzb_v_inner(j,i)+1, nzb_v_outer(j,i)
-                   kmxp = 0.25_wp *                                            &
-                          ( km(k,j,i)+km(k,j,i+1)+km(k,j-1,i)+km(k,j-1,i+1) )
-                   kmxm = 0.25_wp *                                            &
-                          ( km(k,j,i)+km(k,j,i-1)+km(k,j-1,i)+km(k,j-1,i-1) )
-                   
-                   tend(k,j,i) = tend(k,j,i)                                   &
-                                 + 2.0_wp * (                                  &
-                                       km(k,j,i)   * ( v(k,j+1,i) - v(k,j,i) ) &
-                                     - km(k,j-1,i) * ( v(k,j,i) - v(k,j-1,i) ) &
-                                            ) * ddy2                           &
-                                 + (   fxp(j,i) * (                            &
-                                  kmxp * ( v(k,j,i+1) - v(k,j,i)     ) * ddx   &
-                                + kmxp * ( u(k,j,i+1) - u(k,j-1,i+1) ) * ddy   &
-                                                  )                            &
-                                     - fxm(j,i) * (                            &
-                                  kmxm * ( v(k,j,i) - v(k,j,i-1) ) * ddx       &
-                                + kmxm * ( u(k,j,i) - u(k,j-1,i) ) * ddy       &
-                                                  )                            &
-                                     + wall_v(j,i) * vsus(k,j,i)               &
-                                   ) * ddx
-                ENDDO
-             ENDIF
-
-!
-!--          Compute vertical diffusion. In case of simulating a Prandtl
-!--          layer, index k starts at nzb_v_inner+2.
-             DO  k = nzb_diff_v(j,i), nzt_diff
+!--          Add horizontal momentum flux v'u' at east- (l=2) and west-facing (l=3)
+!--          surfaces. Note, in the the flat case, loops won't be entered as 
+!--          start_index > end_index. Furtermore, note, no vertical natural surfaces
+!--          so far.           
+!--          Default-type surfaces
+             DO  l = 2, 3
+                surf_s = surf_def_v(l)%start_index(j,i)
+                surf_e = surf_def_v(l)%end_index(j,i)
+                DO  m = surf_s, surf_e
+                   k           = surf_def_v(l)%k(m)
+                   tend(k,j,i) = tend(k,j,i) +                                 &
+                                    surf_def_v(l)%mom_flux_uv(m) * ddx
+                ENDDO   
+             ENDDO
+!
+!--          Natural-type surfaces
+             DO  l = 2, 3
+                surf_s = surf_lsm_v(l)%start_index(j,i)
+                surf_e = surf_lsm_v(l)%end_index(j,i)
+                DO  m = surf_s, surf_e
+                   k           = surf_lsm_v(l)%k(m)
+                   tend(k,j,i) = tend(k,j,i) +                                 &
+                                    surf_lsm_v(l)%mom_flux_uv(m) * ddx
+                ENDDO   
+             ENDDO
+!
+!--          Urban-type surfaces
+             DO  l = 2, 3
+                surf_s = surf_usm_v(l)%start_index(j,i)
+                surf_e = surf_usm_v(l)%end_index(j,i)
+                DO  m = surf_s, surf_e
+                   k           = surf_usm_v(l)%k(m)
+                   tend(k,j,i) = tend(k,j,i) +                                 &
+                                    surf_usm_v(l)%mom_flux_uv(m) * ddx
+                ENDDO   
+             ENDDO
+!
+!--          Compute vertical diffusion. In case of simulating a surface layer,
+!--          respective grid diffusive fluxes are masked (flag 10) within this 
+!--          loop, and added further below, else, simple gradient approach is
+!--          applied. Model top is also mask if top-momentum flux is given. 
+             DO  k = nzb+1, nzt
+!
+!--             Determine flags to mask topography below and above. Flag 2 is 
+!--             used to mask topography in general, while flag 8 implies also
+!--             information about use_surface_fluxes. Flag 9 is used to control 
+!--             momentum flux at model top.  
+                mask_bottom = MERGE( 1.0_wp, 0.0_wp,                           &
+                                     BTEST( wall_flags_0(k-1,j,i), 8 ) ) 
+                mask_top    = MERGE( 1.0_wp, 0.0_wp,                           &
+                                     BTEST( wall_flags_0(k+1,j,i), 8 ) ) *     &
+                              MERGE( 1.0_wp, 0.0_wp,                           &
+                                     BTEST( wall_flags_0(k+1,j,i), 9 ) ) 
+                flag        = MERGE( 1.0_wp, 0.0_wp,                           &
+                                     BTEST( wall_flags_0(k,j,i), 2 ) ) 
 !
 !--             Interpolate eddy diffusivities on staggered gridpoints
@@ -213,9 +248,9 @@
                       & + ( kmzp * ( ( v(k+1,j,i) - v(k,j,i) ) * ddzu(k+1)     &
                       &            + ( w(k,j,i) - w(k,j-1,i) ) * ddy           &
-                      &            ) * rho_air_zw(k)                           &
+                      &            ) * rho_air_zw(k)   * mask_top              &
                       &   - kmzm * ( ( v(k,j,i)   - v(k-1,j,i)   ) * ddzu(k)   &
                       &            + ( w(k-1,j,i) - w(k-1,j-1,i) ) * ddy       &
-                      &            ) * rho_air_zw(k-1)                         &
-                      &   ) * ddzw(k) * drho_air(k)
+                      &            ) * rho_air_zw(k-1) * mask_bottom           &
+                      &   ) * ddzw(k) * drho_air(k) * flag
              ENDDO
 
@@ -228,37 +263,64 @@
 !--          comparison with other (LES) models showed that the values of
 !--          the momentum flux becomes too large in this case.
-!--          The term containing w(k-1,..) (see above equation) is removed here
-!--          because the vertical velocity is assumed to be zero at the surface.
              IF ( use_surface_fluxes )  THEN
-                k = nzb_v_inner(j,i)+1
-!
-!--             Interpolate eddy diffusivities on staggered gridpoints
-                kmzp = 0.25_wp *                                               &
-                       ( km(k,j,i)+km(k+1,j,i)+km(k,j-1,i)+km(k+1,j-1,i) )
-
-                tend(k,j,i) = tend(k,j,i)                                      &
-                      & + ( kmzp * ( ( v(k+1,j,i) - v(k,j,i)   ) * ddzu(k+1)   &
-                      &            + ( w(k,j,i)   - w(k,j-1,i) ) * ddy         &
-                      &            ) * rho_air_zw(k)                           &
-                      &   - ( -vsws(j,i) )                                     &
-                      &   ) * ddzw(k) * drho_air(k)
+!
+!--             Default-type surfaces, upward-facing
+                surf_s = surf_def_h(0)%start_index(j,i)
+                surf_e = surf_def_h(0)%end_index(j,i)
+                DO  m = surf_s, surf_e
+                   k   = surf_def_h(0)%k(m)
+
+                   tend(k,j,i) = tend(k,j,i)                                   &
+                        + ( - ( - surf_def_h(0)%vsws(m) )                      &
+                          ) * ddzw(k) * drho_air(k)
+                ENDDO
+!
+!--             Default-type surfaces, dowward-facing
+                surf_s = surf_def_h(1)%start_index(j,i)
+                surf_e = surf_def_h(1)%end_index(j,i)
+                DO  m = surf_s, surf_e
+                   k   = surf_def_h(1)%k(m)
+
+                   tend(k,j,i) = tend(k,j,i)                                   &
+                        + ( - surf_def_h(1)%vsws(m)                            &
+                          ) * ddzw(k) * drho_air(k)
+                ENDDO
+!
+!--             Natural-type surfaces, upward-facing
+                surf_s = surf_lsm_h%start_index(j,i)
+                surf_e = surf_lsm_h%end_index(j,i)
+                DO  m = surf_s, surf_e
+                   k   = surf_lsm_h%k(m)
+
+                   tend(k,j,i) = tend(k,j,i)                                   &
+                        + ( - ( - surf_lsm_h%vsws(m) )                         &
+                          ) * ddzw(k) * drho_air(k)
+
+                ENDDO
+!
+!--             Urban-type surfaces, upward-facing
+                surf_s = surf_usm_h%start_index(j,i)
+                surf_e = surf_usm_h%end_index(j,i)
+                DO  m = surf_s, surf_e
+                   k   = surf_usm_h%k(m)
+
+                   tend(k,j,i) = tend(k,j,i)                                   &
+                        + ( - ( - surf_usm_h%vsws(m) )                         &
+                          ) * ddzw(k) * drho_air(k)
+
+                ENDDO
              ENDIF
-
-!
-!--          Vertical diffusion at the first gridpoint below the top boundary,
-!--          if the momentum flux at the top is prescribed by the user
-             IF ( use_top_fluxes  .AND.  constant_top_momentumflux )  THEN
-                k = nzt
-!
-!--             Interpolate eddy diffusivities on staggered gridpoints
-                kmzm = 0.25_wp *                                               &
-                       ( km(k,j,i)+km(k-1,j,i)+km(k,j-1,i)+km(k-1,j-1,i) )
-
-                tend(k,j,i) = tend(k,j,i)                                      &
-                      & + ( ( -vswst(j,i) )                                    &
-                      &   - kmzm * ( ( v(k,j,i)   - v(k-1,j,i)   ) * ddzu(k)   &
-                      &            + ( w(k-1,j,i) - w(k-1,j-1,i) ) * ddy       &
-                      &            ) * rho_air_zw(k-1)                         &
-                      &   ) * ddzw(k) * drho_air(k)
+!
+!--          Add momentum flux at model top
+             IF ( use_top_fluxes )  THEN
+                surf_s = surf_def_h(2)%start_index(j,i)
+                surf_e = surf_def_h(2)%end_index(j,i)
+                DO  m = surf_s, surf_e
+
+                   k   = surf_def_h(2)%k(m)
+
+                   tend(k,j,i) = tend(k,j,i)                                   &
+                           + ( - surf_def_h(2)%vsws(m) ) * ddzw(k) * drho_air(k)
+                ENDDO
              ENDIF
 
@@ -277,33 +339,53 @@
 
        USE arrays_3d,                                                          &
-           ONLY:  ddzu, ddzw, km, tend, u, v, vsws, vswst, w,                  &
-                  drho_air, rho_air_zw
+           ONLY:  ddzu, ddzw, km, tend, u, v, w, drho_air, rho_air_zw
        
        USE control_parameters,                                                 &
-           ONLY:  constant_top_momentumflux, use_surface_fluxes, use_top_fluxes
+           ONLY:  constant_top_momentumflux, use_surface_fluxes,               &
+                  use_top_fluxes
        
        USE grid_variables,                                                     &
-           ONLY:  ddx, ddy, ddy2, fxm, fxp, wall_v
+           ONLY:  ddx, ddy, ddy2
        
        USE indices,                                                            &
-           ONLY:  nzb, nzb_diff_v, nzb_v_inner, nzb_v_outer, nzt, nzt_diff
+           ONLY:  nzb, nzt, wall_flags_0
        
        USE kinds
 
+       USE surface_mod,                                                        &
+           ONLY :  surf_def_h, surf_def_v, surf_lsm_h, surf_lsm_v, surf_usm_h, &
+                   surf_usm_v
+
        IMPLICIT NONE
 
-       INTEGER(iwp) ::  i     !< 
-       INTEGER(iwp) ::  j     !< 
-       INTEGER(iwp) ::  k     !< 
-       REAL(wp)     ::  kmxm  !< 
-       REAL(wp)     ::  kmxp  !< 
-       REAL(wp)     ::  kmzm  !< 
-       REAL(wp)     ::  kmzp  !< 
-
-       REAL(wp), DIMENSION(nzb:nzt+1) ::  vsus  !< 
+
+       INTEGER(iwp) ::  i             !< running index x direction
+       INTEGER(iwp) ::  j             !< running index y direction
+       INTEGER(iwp) ::  k             !< running index z direction
+       INTEGER(iwp) ::  l             !< running index of surface type, south- or north-facing wall
+       INTEGER(iwp) ::  m             !< running index surface elements
+       INTEGER(iwp) ::  surf_e        !< End index of surface elements at (j,i)-gridpoint
+       INTEGER(iwp) ::  surf_s        !< Start index of surface elements at (j,i)-gridpoint
+
+       REAL(wp)     ::  flag          !< flag to mask topography grid points
+       REAL(wp)     ::  kmxm          !< 
+       REAL(wp)     ::  kmxp          !< 
+       REAL(wp)     ::  kmzm          !< 
+       REAL(wp)     ::  kmzp          !< 
+       REAL(wp)     ::  mask_bottom   !< flag to mask vertical upward-facing surface  
+       REAL(wp)     ::  mask_east     !< flag to mask vertical surface south of the grid point 
+       REAL(wp)     ::  mask_west     !< flag to mask vertical surface north of the grid point 
+       REAL(wp)     ::  mask_top      !< flag to mask vertical downward-facing surface
 
 !
 !--    Compute horizontal diffusion
-       DO  k = nzb_v_outer(j,i)+1, nzt
+       DO  k = nzb+1, nzt
+!
+!--       Predetermine flag to mask topography and wall-bounded grid points. 
+!--       It is sufficient to masked only east- and west-facing surfaces, which
+!--       need special treatment for the v-component. 
+          flag      = MERGE( 1.0_wp, 0.0_wp, BTEST( wall_flags_0(k,j,i),   2 ) ) 
+          mask_east = MERGE( 1.0_wp, 0.0_wp, BTEST( wall_flags_0(k,j,i+1), 2 ) )
+          mask_west = MERGE( 1.0_wp, 0.0_wp, BTEST( wall_flags_0(k,j,i-1), 2 ) )
 !
 !--       Interpolate eddy diffusivities on staggered gridpoints
@@ -311,53 +393,73 @@
           kmxm = 0.25_wp * ( km(k,j,i)+km(k,j,i-1)+km(k,j-1,i)+km(k,j-1,i-1) )
 
-          tend(k,j,i) = tend(k,j,i)                                            &
-                      & + ( kmxp * ( v(k,j,i+1) - v(k,j,i)     ) * ddx         &
-                      &   + kmxp * ( u(k,j,i+1) - u(k,j-1,i+1) ) * ddy         &
-                      &   - kmxm * ( v(k,j,i) - v(k,j,i-1) ) * ddx             &
-                      &   - kmxm * ( u(k,j,i) - u(k,j-1,i) ) * ddy             &
-                      &   ) * ddx                                              &
-                      & + 2.0_wp * (                                           &
-                      &           km(k,j,i)   * ( v(k,j+1,i) - v(k,j,i) )      &
-                      &         - km(k,j-1,i) * ( v(k,j,i) - v(k,j-1,i) )      &
-                      &            ) * ddy2
+          tend(k,j,i) = tend(k,j,i) +          (                             &
+                          mask_east * kmxp * (                               &
+                                 ( v(k,j,i+1) - v(k,j,i)     ) * ddx         &
+                               + ( u(k,j,i+1) - u(k,j-1,i+1) ) * ddy         &
+                                             )                               &
+                        - mask_west * kmxm * (                               &
+                                 ( v(k,j,i) - v(k,j,i-1) ) * ddx             &
+                               + ( u(k,j,i) - u(k,j-1,i) ) * ddy             &
+                                             )                               &
+                                               ) * ddx  * flag               &
+                                    + 2.0_wp * (                             &
+                                  km(k,j,i)   * ( v(k,j+1,i) - v(k,j,i)   )  &
+                                - km(k,j-1,i) * ( v(k,j,i)   - v(k,j-1,i) )  &
+                                               ) * ddy2 * flag
        ENDDO
 
 !
-!--    Wall functions at the left and right walls, respectively
-       IF ( wall_v(j,i) /= 0.0_wp )  THEN
-
-!
-!--       Calculate the horizontal momentum flux v'u'
-          CALL wall_fluxes( i, j, nzb_v_inner(j,i)+1, nzb_v_outer(j,i),        &
-                            vsus, 0.0_wp, 1.0_wp, 0.0_wp, 0.0_wp )
-
-          DO  k = nzb_v_inner(j,i)+1, nzb_v_outer(j,i)
-             kmxp = 0.25_wp *                                                  &
-                    ( km(k,j,i)+km(k,j,i+1)+km(k,j-1,i)+km(k,j-1,i+1) )
-             kmxm = 0.25_wp *                                                  &
-                    ( km(k,j,i)+km(k,j,i-1)+km(k,j-1,i)+km(k,j-1,i-1) )
-
-             tend(k,j,i) = tend(k,j,i)                                         &
-                                 + 2.0_wp * (                                  &
-                                       km(k,j,i)   * ( v(k,j+1,i) - v(k,j,i) ) &
-                                     - km(k,j-1,i) * ( v(k,j,i) - v(k,j-1,i) ) &
-                                            ) * ddy2                           &
-                                 + (   fxp(j,i) * (                            &
-                                  kmxp * ( v(k,j,i+1) - v(k,j,i)     ) * ddx   &
-                                + kmxp * ( u(k,j,i+1) - u(k,j-1,i+1) ) * ddy   &
-                                                  )                            &
-                                     - fxm(j,i) * (                            &
-                                  kmxm * ( v(k,j,i) - v(k,j,i-1) ) * ddx       &
-                                + kmxm * ( u(k,j,i) - u(k,j-1,i) ) * ddy       &
-                                                  )                            &
-                                     + wall_v(j,i) * vsus(k)                   &
-                                   ) * ddx
-          ENDDO
-       ENDIF
-
-!
-!--    Compute vertical diffusion. In case of simulating a Prandtl layer,
-!--    index k starts at nzb_v_inner+2.
-       DO  k = nzb_diff_v(j,i), nzt_diff
+!--    Add horizontal momentum flux v'u' at east- (l=2) and west-facing (l=3)
+!--    surfaces. Note, in the the flat case, loops won't be entered as 
+!--    start_index > end_index. Furtermore, note, no vertical natural surfaces
+!--    so far.           
+!--    Default-type surfaces
+       DO  l = 2, 3
+          surf_s = surf_def_v(l)%start_index(j,i)
+          surf_e = surf_def_v(l)%end_index(j,i)
+          DO  m = surf_s, surf_e
+             k           = surf_def_v(l)%k(m)
+             tend(k,j,i) = tend(k,j,i) + surf_def_v(l)%mom_flux_uv(m) * ddx
+          ENDDO   
+       ENDDO
+!
+!--    Natural-type surfaces
+       DO  l = 2, 3
+          surf_s = surf_lsm_v(l)%start_index(j,i)
+          surf_e = surf_lsm_v(l)%end_index(j,i)
+          DO  m = surf_s, surf_e
+             k           = surf_lsm_v(l)%k(m)
+             tend(k,j,i) = tend(k,j,i) + surf_lsm_v(l)%mom_flux_uv(m) * ddx
+          ENDDO   
+       ENDDO
+!
+!--    Urban-type surfaces
+       DO  l = 2, 3
+          surf_s = surf_usm_v(l)%start_index(j,i)
+          surf_e = surf_usm_v(l)%end_index(j,i)
+          DO  m = surf_s, surf_e
+             k           = surf_usm_v(l)%k(m)
+             tend(k,j,i) = tend(k,j,i) + surf_usm_v(l)%mom_flux_uv(m) * ddx
+          ENDDO   
+       ENDDO
+!
+!--    Compute vertical diffusion. In case of simulating a surface layer,
+!--    respective grid diffusive fluxes are masked (flag 8) within this 
+!--    loop, and added further below, else, simple gradient approach is
+!--    applied. Model top is also mask if top-momentum flux is given.
+       DO  k = nzb+1, nzt
+!
+!--       Determine flags to mask topography below and above. Flag 2 is 
+!--       used to mask topography in general, while flag 10 implies also
+!--       information about use_surface_fluxes. Flag 9 is used to control 
+!--       momentum flux at model top.  
+          mask_bottom = MERGE( 1.0_wp, 0.0_wp,                                 &
+                               BTEST( wall_flags_0(k-1,j,i), 8 ) ) 
+          mask_top    = MERGE( 1.0_wp, 0.0_wp,                                 &
+                               BTEST( wall_flags_0(k+1,j,i), 8 ) ) *           &
+                        MERGE( 1.0_wp, 0.0_wp,                                 &
+                               BTEST( wall_flags_0(k+1,j,i), 9 ) ) 
+          flag        = MERGE( 1.0_wp, 0.0_wp,                                 &
+                               BTEST( wall_flags_0(k,j,i), 2 ) )
 !
 !--       Interpolate eddy diffusivities on staggered gridpoints
@@ -368,9 +470,9 @@
                       & + ( kmzp * ( ( v(k+1,j,i) - v(k,j,i) ) * ddzu(k+1)     &
                       &            + ( w(k,j,i) - w(k,j-1,i) ) * ddy           &
-                      &            ) * rho_air_zw(k)                           &
+                      &            ) * rho_air_zw(k)   * mask_top              &
                       &   - kmzm * ( ( v(k,j,i)   - v(k-1,j,i)   ) * ddzu(k)   &
                       &            + ( w(k-1,j,i) - w(k-1,j-1,i) ) * ddy       &
-                      &            ) * rho_air_zw(k-1)                         &
-                      &   ) * ddzw(k) * drho_air(k)
+                      &            ) * rho_air_zw(k-1) * mask_bottom           &
+                      &   ) * ddzw(k) * drho_air(k) * flag
        ENDDO
 
@@ -383,35 +485,64 @@
 !--    other (LES) models showed that the values of the momentum flux becomes
 !--    too large in this case.
-!--    The term containing w(k-1,..) (see above equation) is removed here
-!--    because the vertical velocity is assumed to be zero at the surface.
        IF ( use_surface_fluxes )  THEN
-          k = nzb_v_inner(j,i)+1
-!
-!--       Interpolate eddy diffusivities on staggered gridpoints
-          kmzp = 0.25_wp * ( km(k,j,i)+km(k+1,j,i)+km(k,j-1,i)+km(k+1,j-1,i) )
-
-          tend(k,j,i) = tend(k,j,i)                                            &
-                      & + ( kmzp * ( ( v(k+1,j,i) - v(k,j,i)   ) * ddzu(k+1)   &
-                      &            + ( w(k,j,i)   - w(k,j-1,i) ) * ddy         &
-                      &            ) * rho_air_zw(k)                           &
-                      &   - ( -vsws(j,i) )                                     &
-                      &   ) * ddzw(k) * drho_air(k)
+!
+!--       Default-type surfaces, upward-facing
+          surf_s = surf_def_h(0)%start_index(j,i)
+          surf_e = surf_def_h(0)%end_index(j,i)
+          DO  m = surf_s, surf_e
+             k   = surf_def_h(0)%k(m)
+
+             tend(k,j,i) = tend(k,j,i)                                         &
+                        + ( - ( - surf_def_h(0)%vsws(m) )                      &
+                          ) * ddzw(k) * drho_air(k)
+          ENDDO
+!
+!--       Default-type surfaces, dowward-facing
+          surf_s = surf_def_h(1)%start_index(j,i)
+          surf_e = surf_def_h(1)%end_index(j,i)
+          DO  m = surf_s, surf_e
+             k   = surf_def_h(1)%k(m)
+
+             tend(k,j,i) = tend(k,j,i)                                         &
+                        + ( - surf_def_h(1)%vsws(m)                            &
+                          ) * ddzw(k) * drho_air(k)
+          ENDDO
+!
+!--       Natural-type surfaces, upward-facing
+          surf_s = surf_lsm_h%start_index(j,i)
+          surf_e = surf_lsm_h%end_index(j,i)
+          DO  m = surf_s, surf_e
+             k   = surf_lsm_h%k(m)
+
+             tend(k,j,i) = tend(k,j,i)                                         &
+                        + ( - ( - surf_lsm_h%vsws(m) )                         &
+                          ) * ddzw(k) * drho_air(k)
+
+          ENDDO
+!
+!--       Urban-type surfaces, upward-facing
+          surf_s = surf_usm_h%start_index(j,i)
+          surf_e = surf_usm_h%end_index(j,i)
+          DO  m = surf_s, surf_e
+             k   = surf_usm_h%k(m)
+
+             tend(k,j,i) = tend(k,j,i)                                         &
+                        + ( - ( - surf_usm_h%vsws(m) )                         &
+                          ) * ddzw(k) * drho_air(k)
+
+          ENDDO
        ENDIF
-
-!
-!--    Vertical diffusion at the first gridpoint below the top boundary,
-!--    if the momentum flux at the top is prescribed by the user
-       IF ( use_top_fluxes  .AND.  constant_top_momentumflux )  THEN
-          k = nzt
-!
-!--       Interpolate eddy diffusivities on staggered gridpoints
-          kmzm = 0.25_wp * ( km(k,j,i)+km(k-1,j,i)+km(k,j-1,i)+km(k-1,j-1,i) )
-
-          tend(k,j,i) = tend(k,j,i)                                            &
-                      & + ( ( -vswst(j,i) )                                    &
-                      &   - kmzm * ( ( v(k,j,i)   - v(k-1,j,i)   ) * ddzu(k)   &
-                      &            + ( w(k-1,j,i) - w(k-1,j-1,i) ) * ddy       &
-                      &            ) * rho_air_zw(k-1)                         &
-                      &   ) * ddzw(k) * drho_air(k)
+!
+!--    Add momentum flux at model top
+       IF ( use_top_fluxes )  THEN
+          surf_s = surf_def_h(2)%start_index(j,i)
+          surf_e = surf_def_h(2)%end_index(j,i)
+          DO  m = surf_s, surf_e
+
+             k   = surf_def_h(2)%k(m)
+
+             tend(k,j,i) = tend(k,j,i)                                         &
+                           + ( - surf_def_h(2)%vsws(m) ) * ddzw(k) * drho_air(k)
+          ENDDO
        ENDIF
 
Index: /palm/trunk/SOURCE/diffusion_w.f90
===================================================================
--- /palm/trunk/SOURCE/diffusion_w.f90	(revision 2231)
+++ /palm/trunk/SOURCE/diffusion_w.f90	(revision 2232)
@@ -20,5 +20,5 @@
 ! Current revisions:
 ! -----------------
-! 
+! Adjustments to new topography and surface concept
 ! 
 ! Former revisions:
@@ -97,7 +97,4 @@
  
 
-    USE wall_fluxes_mod,                                                       &
-        ONLY :  wall_fluxes
-
     PRIVATE
     PUBLIC diffusion_w
@@ -125,114 +122,161 @@
            
        USE grid_variables,                                                     &     
-           ONLY :  ddx, ddy, fwxm, fwxp, fwym, fwyp, wall_w_x, wall_w_y
+           ONLY :  ddx, ddy
            
        USE indices,                                                            &            
-           ONLY :  nxl, nxr, nyn, nys, nzb, nzb_w_inner, nzb_w_outer, nzt
+           ONLY :  nxl, nxr, nyn, nys, nzb, nzt, wall_flags_0
            
        USE kinds
 
+       USE surface_mod,                                                        &
+           ONLY :  surf_def_v, surf_lsm_v, surf_usm_v
+
        IMPLICIT NONE
 
-       INTEGER(iwp) ::  i     !<
-       INTEGER(iwp) ::  j     !<
-       INTEGER(iwp) ::  k     !<
+       INTEGER(iwp) ::  i             !< running index x direction
+       INTEGER(iwp) ::  j             !< running index y direction
+       INTEGER(iwp) ::  k             !< running index z direction
+       INTEGER(iwp) ::  l             !< running index of surface type, south- or north-facing wall
+       INTEGER(iwp) ::  m             !< running index surface elements
+       INTEGER(iwp) ::  surf_e        !< End index of surface elements at (j,i)-gridpoint
+       INTEGER(iwp) ::  surf_s        !< Start index of surface elements at (j,i)-gridpoint
        
-       REAL(wp) ::  kmxm  !<
-       REAL(wp) ::  kmxp  !<
-       REAL(wp) ::  kmym  !<
-       REAL(wp) ::  kmyp  !< 
-
-       REAL(wp), DIMENSION(nzb:nzt+1,nys:nyn,nxl:nxr) ::  wsus  !<
-       REAL(wp), DIMENSION(nzb:nzt+1,nys:nyn,nxl:nxr) ::  wsvs  !<
-
-
-!
-!--    First calculate horizontal momentum flux w'u' and/or w'v' at vertical
-!--    walls, if neccessary
-       IF ( topography /= 'flat' )  THEN
-          CALL wall_fluxes( wsus, 0.0_wp, 0.0_wp, 0.0_wp, 1.0_wp, nzb_w_inner,             &
-                            nzb_w_outer, wall_w_x )
-          CALL wall_fluxes( wsvs, 0.0_wp, 0.0_wp, 1.0_wp, 0.0_wp, nzb_w_inner,             &
-                            nzb_w_outer, wall_w_y )
-       ENDIF
+       REAL(wp) ::  flag              !< flag to mask topography grid points
+       REAL(wp) ::  kmxm              !<
+       REAL(wp) ::  kmxp              !<
+       REAL(wp) ::  kmym              !<
+       REAL(wp) ::  kmyp              !< 
+       REAL(wp) ::  mask_west         !< flag to mask vertical wall west of the grid point
+       REAL(wp) ::  mask_east         !< flag to mask vertical wall east of the grid point 
+       REAL(wp) ::  mask_south        !< flag to mask vertical wall south of the grid point 
+       REAL(wp) ::  mask_north        !< flag to mask vertical wall north of the grid point 
+
+
 
        DO  i = nxl, nxr
           DO  j = nys, nyn
-             DO  k = nzb_w_outer(j,i)+1, nzt-1
+             DO  k = nzb+1, nzt-1
+!
+!--             Predetermine flag to mask topography and wall-bounded grid points. 
+                flag       = MERGE( 1.0_wp, 0.0_wp,                            &
+                                    BTEST( wall_flags_0(k,j,i),   3 ) ) 
+                mask_east  = MERGE( 1.0_wp, 0.0_wp,                            &
+                                    BTEST( wall_flags_0(k,j,i+1), 3 ) )
+                mask_west  = MERGE( 1.0_wp, 0.0_wp,                            &
+                                    BTEST( wall_flags_0(k,j,i-1), 3 ) )
+                mask_south = MERGE( 1.0_wp, 0.0_wp,                            &
+                                    BTEST( wall_flags_0(k,j-1,i), 3 ) )
+                mask_north = MERGE( 1.0_wp, 0.0_wp,                            &
+                                    BTEST( wall_flags_0(k,j+1,i), 3 ) )
 !
 !--             Interpolate eddy diffusivities on staggered gridpoints
-                kmxp = 0.25_wp *                                               &
-                       ( km(k,j,i)+km(k,j,i+1)+km(k+1,j,i)+km(k+1,j,i+1) )
-                kmxm = 0.25_wp *                                               &
-                       ( km(k,j,i)+km(k,j,i-1)+km(k+1,j,i)+km(k+1,j,i-1) )
-                kmyp = 0.25_wp *                                               &
-                       ( km(k,j,i)+km(k+1,j,i)+km(k,j+1,i)+km(k+1,j+1,i) )
-                kmym = 0.25_wp *                                               &
-                       ( km(k,j,i)+km(k+1,j,i)+km(k,j-1,i)+km(k+1,j-1,i) )
+                kmxp = 0.25_wp * ( km(k,j,i)   +   km(k,j,i+1) +               &
+                                   km(k+1,j,i) + km(k+1,j,i+1) )
+                kmxm = 0.25_wp * ( km(k,j,i)   + km(k,j,i-1)   +               &
+                                   km(k+1,j,i) + km(k+1,j,i-1) )
+                kmyp = 0.25_wp * ( km(k,j,i)   + km(k+1,j,i)   +               &
+                                   km(k,j+1,i) + km(k+1,j+1,i) )
+                kmym = 0.25_wp * ( km(k,j,i)   + km(k+1,j,i)   +               &
+                                   km(k,j-1,i) + km(k+1,j-1,i) )
 
                 tend(k,j,i) = tend(k,j,i)                                      &
-                      & + ( kmxp * ( w(k,j,i+1)   - w(k,j,i)   ) * ddx         &
-                      &   + kmxp * ( u(k+1,j,i+1) - u(k,j,i+1) ) * ddzu(k+1)   &
-                      &   - kmxm * ( w(k,j,i)   - w(k,j,i-1) ) * ddx           &
-                      &   - kmxm * ( u(k+1,j,i) - u(k,j,i)   ) * ddzu(k+1)     &
-                      &   ) * ddx                                              &
-                      & + ( kmyp * ( w(k,j+1,i)   - w(k,j,i)   ) * ddy         &
-                      &   + kmyp * ( v(k+1,j+1,i) - v(k,j+1,i) ) * ddzu(k+1)   &
-                      &   - kmym * ( w(k,j,i)   - w(k,j-1,i) ) * ddy           &
-                      &   - kmym * ( v(k+1,j,i) - v(k,j,i)   ) * ddzu(k+1)     &
-                      &   ) * ddy                                              &
-                      & + 2.0_wp * (                                           &
-                      &   km(k+1,j,i) * ( w(k+1,j,i) - w(k,j,i) ) * ddzw(k+1)  &
-                      &               * rho_air(k+1)                           &
-                      & - km(k,j,i)   * ( w(k,j,i)   - w(k-1,j,i) ) * ddzw(k)  &
-                      &               * rho_air(k)                             &
-                      &            ) * ddzu(k+1) * drho_air_zw(k)
-             ENDDO
-
-!
-!--          Wall functions at all vertical walls, where necessary
-             IF ( wall_w_x(j,i) /= 0.0_wp  .OR.  wall_w_y(j,i) /= 0.0_wp )  THEN
-
-                DO  k = nzb_w_inner(j,i)+1, nzb_w_outer(j,i)
-!
-!--                Interpolate eddy diffusivities on staggered gridpoints
-                   kmxp = 0.25_wp *                                            &
-                          ( km(k,j,i)+km(k,j,i+1)+km(k+1,j,i)+km(k+1,j,i+1) )
-                   kmxm = 0.25_wp *                                            &
-                          ( km(k,j,i)+km(k,j,i-1)+km(k+1,j,i)+km(k+1,j,i-1) )
-                   kmyp = 0.25_wp *                                            &
-                          ( km(k,j,i)+km(k+1,j,i)+km(k,j+1,i)+km(k+1,j+1,i) )
-                   kmym = 0.25_wp *                                            &
-                          ( km(k,j,i)+km(k+1,j,i)+km(k,j-1,i)+km(k+1,j-1,i) )
-
-                   tend(k,j,i) = tend(k,j,i)                                   &
-                                 + (   fwxp(j,i) * (                           &
-                            kmxp * ( w(k,j,i+1)   - w(k,j,i)   ) * ddx         &
-                          + kmxp * ( u(k+1,j,i+1) - u(k,j,i+1) ) * ddzu(k+1)   &
-                                                   )                           &
-                                     - fwxm(j,i) * (                           &
-                            kmxm * ( w(k,j,i)     - w(k,j,i-1) ) * ddx         &
-                          + kmxm * ( u(k+1,j,i)   - u(k,j,i)   ) * ddzu(k+1)   &
-                                                   )                           &
-                                     + wall_w_x(j,i) * wsus(k,j,i)             &
-                                   ) * ddx                                     &
-                                 + (   fwyp(j,i) * (                           &
-                            kmyp * ( w(k,j+1,i)   - w(k,j,i)   ) * ddy         &
-                          + kmyp * ( v(k+1,j+1,i) - v(k,j+1,i) ) * ddzu(k+1)   &
-                                                   )                           &
-                                     - fwym(j,i) * (                           &
-                            kmym * ( w(k,j,i)     - w(k,j-1,i) ) * ddy         &
-                          + kmym * ( v(k+1,j,i)   - v(k,j,i)   ) * ddzu(k+1)   &
-                                                   )                           &
-                                     + wall_w_y(j,i) * wsvs(k,j,i)             &
-                                   ) * ddy                                     &
-                                 + 2.0_wp * (                                  &
-                           km(k+1,j,i) * ( w(k+1,j,i) - w(k,j,i) ) * ddzw(k+1) &
-                                       * rho_air(k+1)                          &
-                         - km(k,j,i)   * ( w(k,j,i)   - w(k-1,j,i) ) * ddzw(k) &
-                                       * rho_air(k)                            &
-                                            ) * ddzu(k+1) * drho_air_zw(k)
-                ENDDO
-             ENDIF
+                       + ( mask_east *  kmxp * (                               &
+                                   ( w(k,j,i+1)   - w(k,j,i)   ) * ddx         &
+                                 + ( u(k+1,j,i+1) - u(k,j,i+1) ) * ddzu(k+1)   &
+                                               )                               &
+                         - mask_west * kmxm *  (                               &
+                                   ( w(k,j,i)     - w(k,j,i-1) ) * ddx         &
+                                 + ( u(k+1,j,i)   - u(k,j,i)   ) * ddzu(k+1)   &
+                                               )                               &
+                         ) * ddx                                 * flag        &
+                       + ( mask_north * kmyp * (                               &
+                                   ( w(k,j+1,i)   - w(k,j,i)   ) * ddy         &
+                                 + ( v(k+1,j+1,i) - v(k,j+1,i) ) * ddzu(k+1)   &
+                                               )                               &
+                         - mask_south * kmym * (                               &
+                                   ( w(k,j,i)     - w(k,j-1,i) ) * ddy         &
+                                 + ( v(k+1,j,i)   - v(k,j,i)   ) * ddzu(k+1)   &
+                                               )                               &
+                         ) * ddy                                 * flag        &
+                       + 2.0_wp * (                                            &
+                         km(k+1,j,i) * ( w(k+1,j,i) - w(k,j,i) )   * ddzw(k+1) &
+                                     * rho_air(k+1)                            &
+                       - km(k,j,i)   * ( w(k,j,i)   - w(k-1,j,i) ) * ddzw(k)   &
+                                     * rho_air(k)                              &
+                                  ) * ddzu(k+1) * drho_air_zw(k) * flag
+             ENDDO
+
+!
+!--          Add horizontal momentum flux v'w' at north- (l=0) and south-facing (l=1)
+!--          surfaces. Note, in the the flat case, loops won't be entered as 
+!--          start_index > end_index. Furtermore, note, no vertical natural surfaces
+!--          so far.           
+!--          Default-type surfaces
+             DO  l = 0, 1
+                surf_s = surf_def_v(l)%start_index(j,i)
+                surf_e = surf_def_v(l)%end_index(j,i)
+                DO  m = surf_s, surf_e
+                   k           = surf_def_v(l)%k(m)
+                   tend(k,j,i) = tend(k,j,i) +                                 &
+                                     surf_def_v(l)%mom_flux_w(m) * ddy
+                ENDDO   
+             ENDDO
+!
+!--          Natural-type surfaces
+             DO  l = 0, 1
+                surf_s = surf_lsm_v(l)%start_index(j,i)
+                surf_e = surf_lsm_v(l)%end_index(j,i)
+                DO  m = surf_s, surf_e
+                   k           = surf_lsm_v(l)%k(m)
+                   tend(k,j,i) = tend(k,j,i) +                                 &
+                                     surf_lsm_v(l)%mom_flux_w(m) * ddy
+                ENDDO   
+             ENDDO
+!
+!--          Urban-type surfaces
+             DO  l = 0, 1
+                surf_s = surf_usm_v(l)%start_index(j,i)
+                surf_e = surf_usm_v(l)%end_index(j,i)
+                DO  m = surf_s, surf_e
+                   k           = surf_usm_v(l)%k(m)
+                   tend(k,j,i) = tend(k,j,i) +                                 &
+                                     surf_usm_v(l)%mom_flux_w(m) * ddy
+                ENDDO   
+             ENDDO
+!
+!--          Add horizontal momentum flux u'w' at east- (l=2) and west-facing (l=3)
+!--          surface.
+!--          Default-type surfaces
+             DO  l = 2, 3
+                surf_s = surf_def_v(l)%start_index(j,i)
+                surf_e = surf_def_v(l)%end_index(j,i)
+                DO  m = surf_s, surf_e
+                   k           = surf_def_v(l)%k(m)
+                   tend(k,j,i) = tend(k,j,i) +                                 &
+                                     surf_def_v(l)%mom_flux_w(m) * ddx
+                ENDDO   
+             ENDDO
+!
+!--          Natural-type surfaces
+             DO  l = 2, 3
+                surf_s = surf_lsm_v(l)%start_index(j,i)
+                surf_e = surf_lsm_v(l)%end_index(j,i)
+                DO  m = surf_s, surf_e
+                   k           = surf_lsm_v(l)%k(m)
+                   tend(k,j,i) = tend(k,j,i) +                                 &
+                                     surf_lsm_v(l)%mom_flux_w(m) * ddx
+                ENDDO   
+             ENDDO
+!
+!--          Urban-type surfaces
+             DO  l = 2, 3
+                surf_s = surf_usm_v(l)%start_index(j,i)
+                surf_e = surf_usm_v(l)%end_index(j,i)
+                DO  m = surf_s, surf_e
+                   k           = surf_usm_v(l)%k(m)
+                   tend(k,j,i) = tend(k,j,i) +                                 &
+                                     surf_usm_v(l)%mom_flux_w(m) * ddx
+                ENDDO   
+             ENDDO
 
           ENDDO
@@ -256,27 +300,44 @@
            
        USE grid_variables,                                                     &     
-           ONLY :  ddx, ddy, fwxm, fwxp, fwym, fwyp, wall_w_x, wall_w_y
+           ONLY :  ddx, ddy
            
        USE indices,                                                            &            
-           ONLY :  nxl, nxr, nyn, nys, nzb, nzb_w_inner, nzb_w_outer, nzt
+           ONLY :  nxl, nxr, nyn, nys, nzb, nzt, wall_flags_0
            
        USE kinds
 
+       USE surface_mod,                                                        &
+           ONLY :  surf_def_v, surf_lsm_v, surf_usm_v
+
        IMPLICIT NONE
 
-       INTEGER(iwp) ::  i     !<
-       INTEGER(iwp) ::  j     !<
-       INTEGER(iwp) ::  k     !<
+
+       INTEGER(iwp) ::  i             !< running index x direction
+       INTEGER(iwp) ::  j             !< running index y direction
+       INTEGER(iwp) ::  k             !< running index z direction
+       INTEGER(iwp) ::  l             !< running index of surface type, south- or north-facing wall
+       INTEGER(iwp) ::  m             !< running index surface elements
+       INTEGER(iwp) ::  surf_e        !< End index of surface elements at (j,i)-gridpoint
+       INTEGER(iwp) ::  surf_s        !< Start index of surface elements at (j,i)-gridpoint
        
-       REAL(wp) ::  kmxm  !<
-       REAL(wp) ::  kmxp  !<
-       REAL(wp) ::  kmym  !<
-       REAL(wp) ::  kmyp  !< 
-
-       REAL(wp), DIMENSION(nzb:nzt+1) ::  wsus
-       REAL(wp), DIMENSION(nzb:nzt+1) ::  wsvs
-
-
-       DO  k = nzb_w_outer(j,i)+1, nzt-1
+       REAL(wp) ::  flag              !< flag to mask topography grid points
+       REAL(wp) ::  kmxm              !<
+       REAL(wp) ::  kmxp              !<
+       REAL(wp) ::  kmym              !<
+       REAL(wp) ::  kmyp              !< 
+       REAL(wp) ::  mask_west         !< flag to mask vertical wall west of the grid point
+       REAL(wp) ::  mask_east         !< flag to mask vertical wall east of the grid point 
+       REAL(wp) ::  mask_south        !< flag to mask vertical wall south of the grid point 
+       REAL(wp) ::  mask_north        !< flag to mask vertical wall north of the grid point 
+
+
+       DO  k = nzb+1, nzt-1
+!
+!--       Predetermine flag to mask topography and wall-bounded grid points. 
+          flag       = MERGE( 1.0_wp, 0.0_wp, BTEST( wall_flags_0(k,j,i),   3 ) ) 
+          mask_east  = MERGE( 1.0_wp, 0.0_wp, BTEST( wall_flags_0(k,j,i+1), 3 ) )
+          mask_west  = MERGE( 1.0_wp, 0.0_wp, BTEST( wall_flags_0(k,j,i-1), 3 ) )
+          mask_south = MERGE( 1.0_wp, 0.0_wp, BTEST( wall_flags_0(k,j-1,i), 3 ) )
+          mask_north = MERGE( 1.0_wp, 0.0_wp, BTEST( wall_flags_0(k,j+1,i), 3 ) )
 !
 !--       Interpolate eddy diffusivities on staggered gridpoints
@@ -287,79 +348,102 @@
 
           tend(k,j,i) = tend(k,j,i)                                            &
-                      & + ( kmxp * ( w(k,j,i+1)   - w(k,j,i)   ) * ddx         &
-                      &   + kmxp * ( u(k+1,j,i+1) - u(k,j,i+1) ) * ddzu(k+1)   &
-                      &   - kmxm * ( w(k,j,i)   - w(k,j,i-1) ) * ddx           &
-                      &   - kmxm * ( u(k+1,j,i) - u(k,j,i)   ) * ddzu(k+1)     &
-                      &   ) * ddx                                              &
-                      & + ( kmyp * ( w(k,j+1,i)   - w(k,j,i)   ) * ddy         &
-                      &   + kmyp * ( v(k+1,j+1,i) - v(k,j+1,i) ) * ddzu(k+1)   &
-                      &   - kmym * ( w(k,j,i)   - w(k,j-1,i) ) * ddy           &
-                      &   - kmym * ( v(k+1,j,i) - v(k,j,i)   ) * ddzu(k+1)     &
-                      &   ) * ddy                                              &
-                      & + 2.0_wp * (                                           &
-                      &   km(k+1,j,i) * ( w(k+1,j,i) - w(k,j,i) ) * ddzw(k+1)  &
-                      &               * rho_air(k+1)                           &
-                      & - km(k,j,i)   * ( w(k,j,i)   - w(k-1,j,i) ) * ddzw(k)  &
-                      &               * rho_air(k)                             &
-                      &            ) * ddzu(k+1) * drho_air_zw(k)
-       ENDDO
-
-!
-!--    Wall functions at all vertical walls, where necessary
-       IF ( wall_w_x(j,i) /= 0.0_wp  .OR.  wall_w_y(j,i) /= 0.0_wp )  THEN
-
-!
-!--       Calculate the horizontal momentum fluxes w'u' and/or w'v'
-          IF ( wall_w_x(j,i) /= 0.0_wp )  THEN
-             CALL wall_fluxes( i, j, nzb_w_inner(j,i)+1, nzb_w_outer(j,i),     &
-                               wsus, 0.0_wp, 0.0_wp, 0.0_wp, 1.0_wp )
-          ELSE
-             wsus = 0.0_wp
-          ENDIF
-
-          IF ( wall_w_y(j,i) /= 0.0_wp )  THEN
-             CALL wall_fluxes( i, j, nzb_w_inner(j,i)+1, nzb_w_outer(j,i),     &
-                               wsvs, 0.0_wp, 0.0_wp, 1.0_wp, 0.0_wp )
-          ELSE
-             wsvs = 0.0_wp
-          ENDIF
-
-          DO  k = nzb_w_inner(j,i)+1, nzb_w_outer(j,i)
-!
-!--          Interpolate eddy diffusivities on staggered gridpoints
-             kmxp = 0.25_wp * ( km(k,j,i)+km(k,j,i+1)+km(k+1,j,i)+km(k+1,j,i+1) )
-             kmxm = 0.25_wp * ( km(k,j,i)+km(k,j,i-1)+km(k+1,j,i)+km(k+1,j,i-1) )
-             kmyp = 0.25_wp * ( km(k,j,i)+km(k+1,j,i)+km(k,j+1,i)+km(k+1,j+1,i) )
-             kmym = 0.25_wp * ( km(k,j,i)+km(k+1,j,i)+km(k,j-1,i)+km(k+1,j-1,i) )
-
-             tend(k,j,i) = tend(k,j,i)                                         &
-                                 + (   fwxp(j,i) * (                           &
-                            kmxp * ( w(k,j,i+1)   - w(k,j,i)   ) * ddx         &
-                          + kmxp * ( u(k+1,j,i+1) - u(k,j,i+1) ) * ddzu(k+1)   &
-                                                   )                           &
-                                     - fwxm(j,i) * (                           &
-                            kmxm * ( w(k,j,i)     - w(k,j,i-1) ) * ddx         &
-                          + kmxm * ( u(k+1,j,i)   - u(k,j,i)   ) * ddzu(k+1)   &
-                                                   )                           &
-                                     + wall_w_x(j,i) * wsus(k)                 &
-                                   ) * ddx                                     &
-                                 + (   fwyp(j,i) * (                           &
-                            kmyp * ( w(k,j+1,i)   - w(k,j,i)   ) * ddy         &
-                          + kmyp * ( v(k+1,j+1,i) - v(k,j+1,i) ) * ddzu(k+1)   &
-                                                   )                           &
-                                     - fwym(j,i) * (                           &
-                            kmym * ( w(k,j,i)     - w(k,j-1,i) ) * ddy         &
-                          + kmym * ( v(k+1,j,i)   - v(k,j,i)   ) * ddzu(k+1)   &
-                                                   )                           &
-                                     + wall_w_y(j,i) * wsvs(k)                 &
-                                   ) * ddy                                     &
-                                 + 2.0_wp * (                                  &
-                           km(k+1,j,i) * ( w(k+1,j,i) - w(k,j,i) ) * ddzw(k+1) &
-                                       * rho_air(k+1)                          &
-                         - km(k,j,i)   * ( w(k,j,i)   - w(k-1,j,i) ) * ddzw(k) &
-                                       * rho_air(k)                            &
-                                            ) * ddzu(k+1) * drho_air_zw(k)
-          ENDDO
-       ENDIF
+                       + ( mask_east *  kmxp * (                               &
+                                   ( w(k,j,i+1)   - w(k,j,i)   ) * ddx         &
+                                 + ( u(k+1,j,i+1) - u(k,j,i+1) ) * ddzu(k+1)   &
+                                               )                               &
+                         - mask_west * kmxm *  (                               &
+                                   ( w(k,j,i)     - w(k,j,i-1) ) * ddx         &
+                                 + ( u(k+1,j,i)   - u(k,j,i)   ) * ddzu(k+1)   &
+                                               )                               &
+                         ) * ddx                                 * flag        &
+                       + ( mask_north * kmyp * (                               &
+                                   ( w(k,j+1,i)   - w(k,j,i)   ) * ddy         &
+                                 + ( v(k+1,j+1,i) - v(k,j+1,i) ) * ddzu(k+1)   &
+                                               )                               &
+                         - mask_south * kmym * (                               &
+                                   ( w(k,j,i)     - w(k,j-1,i) ) * ddy         &
+                                 + ( v(k+1,j,i)   - v(k,j,i)   ) * ddzu(k+1)   &
+                                               )                               &
+                         ) * ddy                                 * flag        &
+                       + 2.0_wp * (                                            &
+                         km(k+1,j,i) * ( w(k+1,j,i) - w(k,j,i) ) * ddzw(k+1)   &
+                                     * rho_air(k+1)                            &
+                       - km(k,j,i)   * ( w(k,j,i)   - w(k-1,j,i) ) * ddzw(k)   &
+                                     * rho_air(k)                              &
+                                  ) * ddzu(k+1) * drho_air_zw(k) * flag
+       ENDDO
+!
+!--    Add horizontal momentum flux v'w' at north- (l=0) and south-facing (l=1)
+!--    surfaces. Note, in the the flat case, loops won't be entered as 
+!--    start_index > end_index. Furtermore, note, no vertical natural surfaces
+!--    so far.           
+!--    Default-type surfaces
+       DO  l = 0, 1
+          surf_s = surf_def_v(l)%start_index(j,i)
+          surf_e = surf_def_v(l)%end_index(j,i)
+          DO  m = surf_s, surf_e
+             k           = surf_def_v(l)%k(m)
+             tend(k,j,i) = tend(k,j,i) +                                       &
+                                     surf_def_v(l)%mom_flux_w(m) * ddy
+          ENDDO   
+       ENDDO
+!
+!--    Natural-type surfaces
+       DO  l = 0, 1
+          surf_s = surf_lsm_v(l)%start_index(j,i)
+          surf_e = surf_lsm_v(l)%end_index(j,i)
+          DO  m = surf_s, surf_e
+             k           = surf_lsm_v(l)%k(m)
+             tend(k,j,i) = tend(k,j,i) +                                       &
+                                     surf_lsm_v(l)%mom_flux_w(m) * ddy
+          ENDDO   
+       ENDDO
+!
+!--    Urban-type surfaces
+       DO  l = 0, 1
+          surf_s = surf_usm_v(l)%start_index(j,i)
+          surf_e = surf_usm_v(l)%end_index(j,i)
+          DO  m = surf_s, surf_e
+             k           = surf_usm_v(l)%k(m)
+             tend(k,j,i) = tend(k,j,i) +                                       &
+                                     surf_usm_v(l)%mom_flux_w(m) * ddy
+          ENDDO   
+       ENDDO
+!
+!--    Add horizontal momentum flux u'w' at east- (l=2) and west-facing (l=3)
+!--    surfaces. 
+!--    Default-type surfaces
+       DO  l = 2, 3
+          surf_s = surf_def_v(l)%start_index(j,i)
+          surf_e = surf_def_v(l)%end_index(j,i)
+          DO  m = surf_s, surf_e
+             k           = surf_def_v(l)%k(m)
+             tend(k,j,i) = tend(k,j,i) +                                       &
+                                     surf_def_v(l)%mom_flux_w(m) * ddx
+          ENDDO   
+       ENDDO
+!
+!--    Natural-type surfaces
+       DO  l = 2, 3
+          surf_s = surf_lsm_v(l)%start_index(j,i)
+          surf_e = surf_lsm_v(l)%end_index(j,i)
+          DO  m = surf_s, surf_e
+             k           = surf_lsm_v(l)%k(m)
+             tend(k,j,i) = tend(k,j,i) +                                       &
+                                     surf_lsm_v(l)%mom_flux_w(m) * ddx
+          ENDDO   
+       ENDDO
+!
+!--    Urban-type surfaces
+       DO  l = 2, 3
+          surf_s = surf_usm_v(l)%start_index(j,i)
+          surf_e = surf_usm_v(l)%end_index(j,i)
+          DO  m = surf_s, surf_e
+             k           = surf_usm_v(l)%k(m)
+             tend(k,j,i) = tend(k,j,i) +                                       &
+                                     surf_usm_v(l)%mom_flux_w(m) * ddx
+          ENDDO   
+       ENDDO
+
 
     END SUBROUTINE diffusion_w_ij
Index: /palm/trunk/SOURCE/diffusivities.f90
===================================================================
--- /palm/trunk/SOURCE/diffusivities.f90	(revision 2231)
+++ /palm/trunk/SOURCE/diffusivities.f90	(revision 2232)
@@ -20,5 +20,5 @@
 ! Current revisions:
 ! -----------------
-! 
+! Adjustments to new topography and surface concept
 ! 
 ! Former revisions:
@@ -89,8 +89,10 @@
     USE control_parameters,                                                    &
         ONLY:  atmos_ocean_sign, e_min, g, outflow_l, outflow_n, outflow_r,    &
-                outflow_s, use_single_reference_value, wall_adjustment
+               outflow_s, use_single_reference_value, wall_adjustment,         &
+               wall_adjustment_factor
                 
     USE indices,                                                               &
-        ONLY:  nxl, nxlg, nxr, nxrg, nyn, nyng, nys, nysg, nzb_s_inner, nzb, nzt
+        ONLY:  nxl, nxlg, nxr, nxrg, nyn, nyng, nys, nysg, nzb, nzt,           &
+               wall_flags_0
     USE kinds
     
@@ -100,4 +102,7 @@
         ONLY :  rmask, statistic_regions, sums_l_l
 
+    USE surface_mod,                                                           &
+        ONLY :  bc_h
+
     IMPLICIT NONE
 
@@ -105,4 +110,5 @@
     INTEGER(iwp) ::  j                   !<
     INTEGER(iwp) ::  k                   !<
+    INTEGER(iwp) ::  m                   !<
     INTEGER(iwp) ::  omp_get_thread_num  !<
     INTEGER(iwp) ::  sr                  !<
@@ -110,4 +116,5 @@
 
     REAL(wp)     ::  dvar_dz             !<
+    REAL(wp)     ::  flag                !<
     REAL(wp)     ::  l                   !<
     REAL(wp)     ::  ll                  !<
@@ -129,5 +136,5 @@
 !
 !-- Compute the turbulent diffusion coefficient for momentum
-    !$OMP PARALLEL PRIVATE (dvar_dz,i,j,k,l,ll,l_stable,sqrt_e,sr,tn)
+    !$OMP PARALLEL PRIVATE (dvar_dz,i,j,k,l,ll,l_stable,sqrt_e,sr,tn,flag)
 !$  tn = omp_get_thread_num()
 
@@ -138,8 +145,7 @@
        DO  i = nxlg, nxrg
           DO  j = nysg, nyng
-             DO  k = 1, nzt
-                IF ( k > nzb_s_inner(j,i) )  THEN
-                   e(k,j,i) = MAX( e(k,j,i), e_min )
-                ENDIF
+             DO  k = nzb+1, nzt
+                e(k,j,i) = MAX( e(k,j,i), e_min ) *                            &
+                        MERGE( 1.0_wp, 0.0_wp, BTEST( wall_flags_0(k,j,i), 0 ) )
              ENDDO
           ENDDO
@@ -150,46 +156,46 @@
     DO  i = nxlg, nxrg
        DO  j = nysg, nyng
-          DO  k = 1, nzt
-
-             IF ( k > nzb_s_inner(j,i) )  THEN
-
-                sqrt_e = SQRT( e(k,j,i) )
-!
-!--             Determine the mixing length
-                dvar_dz = atmos_ocean_sign * &  ! inverse effect of pt/rho_ocean gradient
-                          ( var(k+1,j,i) - var(k-1,j,i) ) * dd2zu(k)
-                IF ( dvar_dz > 0.0_wp ) THEN
-                   IF ( use_single_reference_value )  THEN
-                      l_stable = 0.76_wp * sqrt_e /                            &
-                                    SQRT( g / var_reference * dvar_dz ) + 1E-5_wp
-                   ELSE
-                      l_stable = 0.76_wp * sqrt_e /                            &
-                                    SQRT( g / var(k,j,i) * dvar_dz ) + 1E-5_wp
-                   ENDIF
+          DO  k = nzb+1, nzt
+
+             flag = MERGE( 1.0_wp, 0.0_wp, BTEST( wall_flags_0(k,j,i), 0 ) )
+
+             sqrt_e = SQRT( e(k,j,i) )
+!
+!--          Determine the mixing length
+             dvar_dz = atmos_ocean_sign * &  ! inverse effect of pt/rho_ocean gradient
+                       ( var(k+1,j,i) - var(k-1,j,i) ) * dd2zu(k)
+             IF ( dvar_dz > 0.0_wp ) THEN
+                IF ( use_single_reference_value )  THEN
+                   l_stable = 0.76_wp * sqrt_e /                               &
+                                 SQRT( g / var_reference * dvar_dz ) + 1E-5_wp
                 ELSE
-                   l_stable = l_grid(k)
+                   l_stable = 0.76_wp * sqrt_e /                               &
+                                 SQRT( g / var(k,j,i) * dvar_dz ) + 1E-5_wp
                 ENDIF
-!
-!--             Adjustment of the mixing length
-                IF ( wall_adjustment )  THEN
-                   l  = MIN( l_wall(k,j,i), l_grid(k), l_stable )
-                   ll = MIN( l_wall(k,j,i), l_grid(k) )
-                ELSE
-                   l  = MIN( l_grid(k), l_stable )
-                   ll = l_grid(k)
-                ENDIF
-
-      !
-      !--       Compute diffusion coefficients for momentum and heat
-                km(k,j,i) = 0.1_wp * l * sqrt_e
-                kh(k,j,i) = ( 1.0_wp + 2.0_wp * l / ll ) * km(k,j,i)
-
-!
-!--             Summation for averaged profile (cf. flow_statistics)
-                DO  sr = 0, statistic_regions
-                   sums_l_l(k,sr,tn) = sums_l_l(k,sr,tn) + l * rmask(j,i,sr)
-                ENDDO
-
+             ELSE
+                l_stable = l_grid(k)
              ENDIF
+!
+!--          Adjustment of the mixing length
+             IF ( wall_adjustment )  THEN
+                l  = MIN( wall_adjustment_factor * l_wall(k,j,i), l_grid(k),   &
+                          l_stable )
+                ll = MIN( wall_adjustment_factor * l_wall(k,j,i), l_grid(k) )
+             ELSE
+                l  = MIN( l_grid(k), l_stable )
+                ll = l_grid(k)
+             ENDIF
+!
+!--          Compute diffusion coefficients for momentum and heat
+             km(k,j,i) = 0.1_wp * l * sqrt_e                      * flag
+             kh(k,j,i) = ( 1.0_wp + 2.0_wp * l / ll ) * km(k,j,i) * flag
+     
+
+!
+!--          Summation for averaged profile (cf. flow_statistics)
+             DO  sr = 0, statistic_regions
+                sums_l_l(k,sr,tn) = sums_l_l(k,sr,tn) + l * rmask(j,i,sr)      &
+                                                          * flag
+             ENDDO
 
           ENDDO
@@ -202,17 +208,39 @@
 
 !
-!-- Set vertical boundary values (Neumann conditions both at bottom and top).
+!-- Set vertical boundary values (Neumann conditions both at upward- and 
+!-- downward facing walls. To set wall-boundary values, the surface data type 
+!-- is applied.
 !-- Horizontal boundary conditions at vertical walls are not set because
-!-- so far vertical walls require usage of a Prandtl-layer where the boundary
-!-- values of the diffusivities are not needed
+!-- so far vertical surfaces require usage of a Prandtl-layer where the boundary
+!-- values of the diffusivities are not needed.
+!-- Upward-facing
+    !$OMP PARALLEL DO PRIVATE( i, j, k )
+    DO  m = 1, bc_h(0)%ns
+       i = bc_h(0)%i(m)            
+       j = bc_h(0)%j(m)
+       k = bc_h(0)%k(m)
+       km(k-1,j,i) = km(k,j,i)
+       kh(k-1,j,i) = kh(k,j,i)
+    ENDDO
+!
+!-- Downward facing surfaces
+    !$OMP PARALLEL DO PRIVATE( i, j, k )
+    DO  m = 1, bc_h(1)%ns
+       i = bc_h(1)%i(m)            
+       j = bc_h(1)%j(m)
+       k = bc_h(1)%k(m)
+       km(k+1,j,i) = km(k,j,i)
+       kh(k+1,j,i) = kh(k,j,i)
+    ENDDO
+!
+!-- Model top
     !$OMP PARALLEL DO
     DO  i = nxlg, nxrg
        DO  j = nysg, nyng
-          km(nzb_s_inner(j,i),j,i) = km(nzb_s_inner(j,i)+1,j,i)
-          km(nzt+1,j,i)            = km(nzt,j,i)
-          kh(nzb_s_inner(j,i),j,i) = kh(nzb_s_inner(j,i)+1,j,i)
-          kh(nzt+1,j,i)            = kh(nzt,j,i)
+          km(nzt+1,j,i) = km(nzt,j,i)
+          kh(nzt+1,j,i) = kh(nzt,j,i)
        ENDDO
     ENDDO
+
 
 !
Index: /palm/trunk/SOURCE/disturb_field.f90
===================================================================
--- /palm/trunk/SOURCE/disturb_field.f90	(revision 2231)
+++ /palm/trunk/SOURCE/disturb_field.f90	(revision 2232)
@@ -20,5 +20,7 @@
 ! Current revisions:
 ! ------------------
-! 
+! Modify referenced parameter for disturb_field, instead of nzb_uv_inner, pass
+! character to identify the respective grid (u- or v-grid). 
+! Set perturbations within topography to zero using flags.
 ! 
 ! Former revisions:
@@ -70,8 +72,8 @@
 !> order in every case. The perturbation range is steered by dist_range.
 !------------------------------------------------------------------------------!
- SUBROUTINE disturb_field( nzb_uv_inner, dist1, field )
+ SUBROUTINE disturb_field( var_char, dist1, field )
  
 
-    USE control_parameters,   &
+    USE control_parameters,                                                    &
         ONLY:  dist_nxl, dist_nxr, dist_nyn, dist_nys, dist_range,             &
                disturbance_amplitude, disturbance_created,                     &
@@ -83,5 +85,6 @@
         
     USE indices,                                                               &
-        ONLY:  nbgp, nxl, nxlg, nxr, nxrg, nyn, nyng, nys, nysg, nzb, nzt
+        ONLY:  nbgp, nxl, nxlg, nxr, nxrg, nyn, nyng, nys, nysg, nzb, nzb_max, &
+               nzt, wall_flags_0
         
     USE kinds
@@ -96,9 +99,10 @@
     IMPLICIT NONE
 
-    INTEGER(iwp) ::  i  !<
-    INTEGER(iwp) ::  j  !<
-    INTEGER(iwp) ::  k  !<
-    
-    INTEGER(iwp) ::  nzb_uv_inner(nysg:nyng,nxlg:nxrg) !<
+    CHARACTER (LEN = *) ::  var_char !< flag to distinguish betwenn u- and v-component
+
+    INTEGER(iwp) ::  flag_nr !< number of respective flag for u- or v-grid 
+    INTEGER(iwp) ::  i       !< index variable
+    INTEGER(iwp) ::  j       !< index variable
+    INTEGER(iwp) ::  k       !< index variable
 
     REAL(wp) ::  randomnumber  !<
@@ -111,5 +115,7 @@
 
     CALL cpu_log( log_point(20), 'disturb_field', 'start' )
-
+!
+!-- Set flag number, 20 for u-grid, 21 for v-grid, required to mask topography
+    flag_nr = MERGE( 20, 21, TRIM(var_char) == 'u' )
 !
 !-- Create an additional temporary array and initialize the arrays needed
@@ -224,5 +230,9 @@
        DO  i = nxlg, nxrg
           DO  j = nysg, nyng
-             dist1(nzb:nzb_uv_inner(j,i)+1,j,i) = 0.0_wp
+             DO  k = nzb, nzb_max
+                dist1(k,j,i) = MERGE( dist1(k,j,i), 0.0_wp,                    &
+                                      BTEST( wall_flags_0(k,j,i), flag_nr )    &
+                                    )
+             ENDDO
           ENDDO
        ENDDO
Index: /palm/trunk/SOURCE/disturb_heatflux.f90
===================================================================
--- /palm/trunk/SOURCE/disturb_heatflux.f90	(revision 2231)
+++ /palm/trunk/SOURCE/disturb_heatflux.f90	(revision 2232)
@@ -20,5 +20,7 @@
 ! Current revisions:
 ! ------------------
-! 
+! Adjustment according new surface data type.
+! Implemented parallel random number generator to obtain always the same 
+! random number distribution regardless of the processor distribution.
 ! 
 ! Former revisions:
@@ -60,16 +62,13 @@
 !> Generate random, normally distributed heatflux values and store them as the
 !> near-surface heatflux.
-!> On parallel computers, too, this random generator is called at all grid points
-!> of the total array in order to guarantee the same random distribution of the
-!> total array regardless of the number of processors used during the model run.
 !------------------------------------------------------------------------------!
- SUBROUTINE disturb_heatflux
+ SUBROUTINE disturb_heatflux( surf )
  
 
     USE arrays_3d,                                                             &
-        ONLY:  shf, heatflux_input_conversion
+        ONLY:  heatflux_input_conversion
         
     USE control_parameters,                                                    &
-        ONLY:  iran, surface_heatflux, wall_heatflux
+        ONLY:  iran, surface_heatflux, random_generator, wall_heatflux
         
     USE cpulog,                                                                &
@@ -79,13 +78,24 @@
     
     USE indices,                                                               &
-        ONLY:  nx, nxl, nxr, ny, nyn, nys, nzb, nzb_s_inner
+        ONLY:  nzb
+
+    USE random_generator_parallel,                                             &
+        ONLY:  random_number_parallel, random_seed_parallel, random_dummy,     &
+               id_random_array, seq_random_array
+
+    USE surface_mod,                                                           &
+        ONLY:  surf_type
 
     IMPLICIT NONE
 
-    INTEGER(iwp) ::  j  !<
-    INTEGER(iwp) ::  i  !<
+    INTEGER(iwp) ::  i  !< grid index, x direction
+    INTEGER(iwp) ::  j  !< grid index, y direction
+    INTEGER(iwp) ::  k  !< grid index, z direction
+    INTEGER(iwp) ::  m  !< loop variables over surface elements
     
     REAL(wp) ::  random_gauss  !<
     REAL(wp) ::  randomnumber  !<
+
+    TYPE(surf_type) ::  surf   !< surface-type variable
 
 
@@ -93,26 +103,51 @@
 
 !
-!-- Generate random disturbances and store them
-    DO  i = 0, nx
-       DO  j = 0, ny
-          randomnumber = random_gauss( iran, 5.0_wp )
-          IF ( nxl <= i  .AND.  nxr >= i  .AND.  nys <= j  .AND.  nyn >= j )   &
-          THEN
-             IF ( nzb_s_inner(j,i) == 0 )  THEN
-                shf(j,i) = randomnumber * surface_heatflux                     &
-                           * heatflux_input_conversion(nzb)
-             ELSE
+!-- Generate random disturbances and store them. Note, if 
+!-- random_generator /= 'random-parallel' it is not guaranteed to obtain  
+!-- the same random distribution if the number of processors is changed. 
+    IF ( random_generator /= 'random-parallel' )  THEN
+
+       DO  m = 1, surf%ns
+
+          k = surf%k(m)
+
+          randomnumber = random_gauss( iran, 5.0_wp )      
 !
-!--             Over topography surface_heatflux is replaced by wall_heatflux(0)
-                shf(j,i) = randomnumber * wall_heatflux(0)                     &
-                           * heatflux_input_conversion(nzb_s_inner(j,i))
-             ENDIF
+!--       k-1 is topography top index. If this is 0, set surface heatflux. Over
+!--       topography surface_heatflux is replaced by wall_heatflux(0).
+          IF ( k-1 == 0 )  THEN
+             surf%shf(m) = randomnumber * surface_heatflux                     &
+                              * heatflux_input_conversion(nzb)
+          ELSE
+             surf%shf(m) = randomnumber * wall_heatflux(0)                     &
+                              * heatflux_input_conversion(k-1)
           ENDIF
        ENDDO
-    ENDDO
+    ELSE
 
+       DO  m = 1, surf%ns
+
+          i = surf%i(m)
+          j = surf%j(m)
+          k = surf%k(m)
+
+          CALL random_seed_parallel( put=seq_random_array(:, j, i) )
+          CALL random_number_parallel( random_dummy )    
 !
-!-- Exchange lateral boundary conditions for the heatflux array
-    CALL exchange_horiz_2d( shf )
+!--       k-1 is topography top index. If this is 0, set surface heatflux. Over
+!--       topography surface_heatflux is replaced by wall_heatflux(0).
+          IF ( k-1 == 0 )  THEN
+             surf%shf(m) = ( random_dummy - 0.5_wp ) * surface_heatflux        &
+                              * heatflux_input_conversion(nzb)
+          ELSE
+             surf%shf(m) = ( random_dummy - 0.5_wp ) * wall_heatflux(0)        &
+                              * heatflux_input_conversion(k-1)
+          ENDIF
+
+          CALL random_seed_parallel( get=seq_random_array(:, j, i) )
+
+       ENDDO
+
+    ENDIF
 
     CALL cpu_log( log_point(23), 'disturb_heatflux', 'stop' )
Index: /palm/trunk/SOURCE/eqn_state_seawater.f90
===================================================================
--- /palm/trunk/SOURCE/eqn_state_seawater.f90	(revision 2231)
+++ /palm/trunk/SOURCE/eqn_state_seawater.f90	(revision 2232)
@@ -20,5 +20,5 @@
 ! Current revisions:
 ! -----------------
-! 
+! Adjustments to new topography and surface concept
 ! 
 ! Former revisions:
@@ -120,24 +120,32 @@
            ONLY:  hyp, prho, pt_p, rho_ocean, sa_p
        USE indices,                                                            &
-           ONLY:  nxl, nxr, nyn, nys, nzb_s_inner, nzt
+           ONLY:  nxl, nxr, nyn, nys, nzb, nzt, wall_flags_0
+
+       USE surface_mod,                                                        &
+          ONLY :  bc_h
 
        IMPLICIT NONE
 
-       INTEGER(iwp) ::  i  !<
-       INTEGER(iwp) ::  j  !<
-       INTEGER(iwp) ::  k  !<
-
-       REAL(wp) ::  pden  !<
-       REAL(wp) ::  pnom  !<
-       REAL(wp) ::  p1    !<
-       REAL(wp) ::  p2    !<
-       REAL(wp) ::  p3    !<
-       REAL(wp) ::  pt1   !<
-       REAL(wp) ::  pt2   !<
-       REAL(wp) ::  pt3   !<
-       REAL(wp) ::  pt4   !<
-       REAL(wp) ::  sa1   !<
-       REAL(wp) ::  sa15  !<
-       REAL(wp) ::  sa2   !<
+       INTEGER(iwp) ::  i       !< running index x direction
+       INTEGER(iwp) ::  j       !< running index y direction
+       INTEGER(iwp) ::  k       !< running index z direction
+       INTEGER(iwp) ::  l       !< running index of surface type, south- or north-facing wall
+       INTEGER(iwp) ::  m       !< running index surface elements
+       INTEGER(iwp) ::  surf_e  !< End index of surface elements at (j,i)-gridpoint
+       INTEGER(iwp) ::  surf_s  !< Start index of surface elements at (j,i)-gridpoint
+
+       REAL(wp) ::  flag   !< flag to mask topography grid points
+       REAL(wp) ::  pden   !<
+       REAL(wp) ::  pnom   !<
+       REAL(wp) ::  p1     !<
+       REAL(wp) ::  p2     !<
+       REAL(wp) ::  p3     !<
+       REAL(wp) ::  pt1    !<
+       REAL(wp) ::  pt2    !<
+       REAL(wp) ::  pt3    !<
+       REAL(wp) ::  pt4    !<
+       REAL(wp) ::  sa1    !<
+       REAL(wp) ::  sa15   !<
+       REAL(wp) ::  sa2    !<
        
                        
@@ -145,5 +153,5 @@
        DO  i = nxl, nxr
           DO  j = nys, nyn
-             DO  k = nzb_s_inner(j,i)+1, nzt
+             DO  k = nzb+1, nzt
 !
 !--             Pressure is needed in dbar
@@ -171,8 +179,10 @@
                        den(7)*sa1*pt1   + den(8)*sa1*pt3 + den(9)*sa15    +    &
                        den(10)*sa15*pt2
-
+!
+!--             Predetermine flag to mask topography
+                flag = MERGE( 1.0_wp, 0.0_wp, BTEST( wall_flags_0(k,j,i), 0 ) )
 !
 !--             Potential density (without pressure terms)
-                prho(k,j,i) = pnom / pden
+                prho(k,j,i) = pnom / pden * flag
 
                 pnom = pnom +             nom(8)*p1      + nom(9)*p1*pt2  +    &
@@ -184,15 +194,33 @@
 !
 !--             In-situ density
-                rho_ocean(k,j,i) = pnom / pden
+                rho_ocean(k,j,i) = pnom / pden * flag
 
              ENDDO
 !
-!--          Neumann conditions are assumed at bottom and top boundary
-             prho(nzt+1,j,i)            = prho(nzt,j,i)
-             prho(nzb_s_inner(j,i),j,i) = prho(nzb_s_inner(j,i)+1,j,i)
-             rho_ocean(nzt+1,j,i)             = rho_ocean(nzt,j,i)
-             rho_ocean(nzb_s_inner(j,i),j,i)  = rho_ocean(nzb_s_inner(j,i)+1,j,i)
+!--          Neumann conditions are assumed at top boundary
+             prho(nzt+1,j,i)      = prho(nzt,j,i)
+             rho_ocean(nzt+1,j,i) = rho_ocean(nzt,j,i)
 
           ENDDO
+       ENDDO
+!
+!--    Neumann conditions at up/downward-facing surfaces
+       !$OMP PARALLEL DO PRIVATE( i, j, k )
+       DO  m = 1, bc_h(0)%ns
+          i = bc_h(0)%i(m)            
+          j = bc_h(0)%j(m)
+          k = bc_h(0)%k(m)
+          prho(k-1,j,i)      = prho(k,j,i)
+          rho_ocean(k-1,j,i) = rho_ocean(k,j,i)
+       ENDDO
+!
+!--    Downward facing surfaces
+       !$OMP PARALLEL DO PRIVATE( i, j, k )
+       DO  m = 1, bc_h(1)%ns
+          i = bc_h(1)%i(m)            
+          j = bc_h(1)%j(m)
+          k = bc_h(1)%k(m)
+          prho(k+1,j,i)      = prho(k,j,i)
+          rho_ocean(k+1,j,i) = rho_ocean(k,j,i)
        ENDDO
 
@@ -211,14 +239,34 @@
            
        USE indices,                                                            &
-           ONLY:  nzb_s_inner, nzt
+           ONLY:  nzb, nzt, wall_flags_0
+
+       USE surface_mod,                                                        &
+          ONLY :  bc_h
 
        IMPLICIT NONE
 
-       INTEGER(iwp) ::  i, j, k
-
-       REAL(wp)     ::  pden, pnom, p1, p2, p3, pt1, pt2, pt3, pt4, sa1, sa15, &
-                        sa2
-
-       DO  k = nzb_s_inner(j,i)+1, nzt
+       INTEGER(iwp) ::  i       !< running index x direction
+       INTEGER(iwp) ::  j       !< running index y direction
+       INTEGER(iwp) ::  k       !< running index z direction
+       INTEGER(iwp) ::  l       !< running index of surface type, south- or north-facing wall
+       INTEGER(iwp) ::  m       !< running index surface elements
+       INTEGER(iwp) ::  surf_e  !< End index of surface elements at (j,i)-gridpoint
+       INTEGER(iwp) ::  surf_s  !< Start index of surface elements at (j,i)-gridpoint
+
+       REAL(wp) ::  flag   !< flag to mask topography grid points
+       REAL(wp) ::  pden   !<
+       REAL(wp) ::  pnom   !<
+       REAL(wp) ::  p1     !<
+       REAL(wp) ::  p2     !<
+       REAL(wp) ::  p3     !<
+       REAL(wp) ::  pt1    !<
+       REAL(wp) ::  pt2    !<
+       REAL(wp) ::  pt3    !<
+       REAL(wp) ::  pt4    !<
+       REAL(wp) ::  sa1    !<
+       REAL(wp) ::  sa15   !<
+       REAL(wp) ::  sa2    !<
+
+       DO  k = nzb+1, nzt
 !
 !--       Pressure is needed in dbar
@@ -246,8 +294,10 @@
                  den(7)*sa1*pt1   + den(8)*sa1*pt3 + den(9)*sa15    +          &
                  den(10)*sa15*pt2
-
+!
+!--       Predetermine flag to mask topography
+          flag = MERGE( 1.0_wp, 0.0_wp, BTEST( wall_flags_0(k,j,i), 0 ) )
 !
 !--       Potential density (without pressure terms)
-          prho(k,j,i) = pnom / pden
+          prho(k,j,i) = pnom / pden * flag
 
           pnom = pnom +             nom(8)*p1      + nom(9)*p1*pt2  +          &
@@ -258,15 +308,30 @@
 !
 !--       In-situ density
-          rho_ocean(k,j,i) = pnom / pden
-
-
-       ENDDO
-
-!
-!--    Neumann conditions are assumed at bottom and top boundary
-       prho(nzt+1,j,i)            = prho(nzt,j,i)
-       prho(nzb_s_inner(j,i),j,i) = prho(nzb_s_inner(j,i)+1,j,i)
-       rho_ocean(nzt+1,j,i)             = rho_ocean(nzt,j,i)
-       rho_ocean(nzb_s_inner(j,i),j,i)  = rho_ocean(nzb_s_inner(j,i)+1,j,i)
+          rho_ocean(k,j,i) = pnom / pden * flag
+
+
+       ENDDO
+!
+!--    Neumann conditions at up/downward-facing walls
+       surf_s = bc_h(0)%start_index(j,i)   
+       surf_e = bc_h(0)%end_index(j,i)   
+       DO  m = surf_s, surf_e
+          k                  = bc_h(0)%k(m)
+          prho(k-1,j,i)      = prho(k,j,i)
+          rho_ocean(k-1,j,i) = rho_ocean(k,j,i)
+       ENDDO
+!
+!--    Downward facing surfaces
+       surf_s = bc_h(1)%start_index(j,i)   
+       surf_e = bc_h(1)%end_index(j,i)   
+       DO  m = surf_s, surf_e
+          k                  = bc_h(1)%k(m)
+          prho(k+1,j,i)      = prho(k,j,i)
+          rho_ocean(k+1,j,i) = rho_ocean(k,j,i)
+       ENDDO
+!
+!--    Neumann condition are assumed at top boundary
+       prho(nzt+1,j,i)      = prho(nzt,j,i)
+       rho_ocean(nzt+1,j,i) = rho_ocean(nzt,j,i)
 
     END SUBROUTINE eqn_state_seawater_ij
Index: /palm/trunk/SOURCE/flow_statistics.f90
===================================================================
--- /palm/trunk/SOURCE/flow_statistics.f90	(revision 2231)
+++ /palm/trunk/SOURCE/flow_statistics.f90	(revision 2232)
@@ -20,5 +20,5 @@
 ! Current revisions:
 ! -----------------
-! 
+! Adjustments to new topography and surface concept
 ! 
 ! Former revisions:
@@ -224,10 +224,8 @@
     USE arrays_3d,                                                             &
         ONLY:  ddzu, ddzw, e, heatflux_output_conversion, hyp, km, kh,         &
-               momentumflux_output_conversion, nr, ol, p, prho, prr, pt, q,    &
-               qc, ql, qr, qs, qsws, qswst, rho_air, rho_air_zw, rho_ocean, s, &
-               sa, ss, ssws, sswst, saswsb, saswst, shf, td_lsa_lpt, td_lsa_q, &
-               td_sub_lpt, td_sub_q, time_vert, ts, tswst, u, ug, us, usws,    &
-               uswst, vsws, v, vg, vpt, vswst, w, w_subs,                      &
-               waterflux_output_conversion, zw
+               momentumflux_output_conversion, nr, p, prho, prr, pt, q,        &
+               qc, ql, qr, rho_air, rho_air_zw, rho_ocean, s,                  &
+               sa, td_lsa_lpt, td_lsa_q, td_sub_lpt, td_sub_q, time_vert, u,   &
+               ug, v, vg, vpt, w, w_subs, waterflux_output_conversion, zw
         
     USE cloud_parameters,                                                      &
@@ -236,5 +234,5 @@
     USE control_parameters,                                                    &
         ONLY:   average_count_pr, cloud_droplets, cloud_physics, do_sum,       &
-                dt_3d, g, humidity, kappa, large_scale_forcing,                &
+                dt_3d, g, humidity, kappa, land_surface, large_scale_forcing,  &
                 large_scale_subsidence, max_pr_user, message_string, neutral,  &
                 microphysics_seifert, ocean, passive_scalar, simulated_time,   &
@@ -250,13 +248,10 @@
     USE indices,                                                               &
         ONLY:   ngp_2dh, ngp_2dh_s_inner, ngp_3d, ngp_3d_inner, ngp_sums,      &
-                ngp_sums_ls, nxl, nxr, nyn, nys, nzb, nzb_diff_s_inner,        &
-                nzb_s_inner, nzt, nzt_diff
+                ngp_sums_ls, nxl, nxr, nyn, nys, nzb, nzt, wall_flags_0
         
     USE kinds
     
     USE land_surface_model_mod,                                                &
-        ONLY:   ghf_eb, land_surface, m_soil, nzb_soil, nzt_soil,              &
-                qsws_eb, qsws_liq_eb, qsws_soil_eb, qsws_veg_eb, r_a, r_s,     &
-                shf_eb, t_soil
+        ONLY:   m_soil_h, nzb_soil, nzt_soil, t_soil_h
 
     USE netcdf_interface,                                                      &
@@ -277,4 +272,7 @@
     USE statistics
 
+       USE surface_mod,                                                        &
+          ONLY :  surf_def_h, surf_lsm_h, surf_usm_h
+
 
     IMPLICIT NONE
@@ -283,14 +281,18 @@
     INTEGER(iwp) ::  j                   !<
     INTEGER(iwp) ::  k                   !<
+    INTEGER(iwp) ::  ki                  !< 
     INTEGER(iwp) ::  k_surface_level     !<
+    INTEGER(iwp) ::  m                   !< loop variable over all horizontal wall elements 
+    INTEGER(iwp) ::  l                   !< loop variable over surface facing -- up- or downward-facing
     INTEGER(iwp) ::  nt                  !<
     INTEGER(iwp) ::  omp_get_thread_num  !<
     INTEGER(iwp) ::  sr                  !<
     INTEGER(iwp) ::  tn                  !<
-    
+
     LOGICAL ::  first  !<
     
     REAL(wp) ::  dptdz_threshold  !< 
     REAL(wp) ::  fac              !<
+    REAL(wp) ::  flag             !<
     REAL(wp) ::  height           !<
     REAL(wp) ::  pts              !<
@@ -400,15 +402,17 @@
 !--    for other horizontal averages.
        tn = 0
-
-       !$OMP PARALLEL PRIVATE( i, j, k, tn )
-!$     tn = omp_get_thread_num()
-
+       !$OMP PARALLEL PRIVATE( i, j, k, tn, flag )
+       !$ tn = omp_get_thread_num()
        !$OMP DO
        DO  i = nxl, nxr
           DO  j =  nys, nyn
-             DO  k = nzb_s_inner(j,i), nzt+1
-                sums_l(k,1,tn)  = sums_l(k,1,tn)  + u(k,j,i)  * rmask(j,i,sr)
-                sums_l(k,2,tn)  = sums_l(k,2,tn)  + v(k,j,i)  * rmask(j,i,sr)
-                sums_l(k,4,tn)  = sums_l(k,4,tn)  + pt(k,j,i) * rmask(j,i,sr)
+             DO  k = nzb, nzt+1
+                flag = MERGE( 1.0_wp, 0.0_wp, BTEST( wall_flags_0(k,j,i), 22 ) )
+                sums_l(k,1,tn)  = sums_l(k,1,tn)  + u(k,j,i)  * rmask(j,i,sr)  &
+                                                              * flag
+                sums_l(k,2,tn)  = sums_l(k,2,tn)  + v(k,j,i)  * rmask(j,i,sr)  &
+                                                              * flag
+                sums_l(k,4,tn)  = sums_l(k,4,tn)  + pt(k,j,i) * rmask(j,i,sr)  &
+                                                              * flag
              ENDDO
           ENDDO
@@ -421,7 +425,9 @@
           DO  i = nxl, nxr
              DO  j =  nys, nyn
-                DO  k = nzb_s_inner(j,i), nzt+1
-                   sums_l(k,23,tn)  = sums_l(k,23,tn) + &
-                                      sa(k,j,i) * rmask(j,i,sr)
+                DO  k = nzb, nzt+1
+                   sums_l(k,23,tn)  = sums_l(k,23,tn) + sa(k,j,i)              &
+                                    * rmask(j,i,sr)                            &
+                                    * MERGE( 1.0_wp, 0.0_wp,                   &
+                                             BTEST( wall_flags_0(k,j,i), 22 ) )
                 ENDDO
              ENDDO
@@ -437,9 +443,10 @@
           DO  i = nxl, nxr
              DO  j =  nys, nyn
-                DO  k = nzb_s_inner(j,i), nzt+1
-                   sums_l(k,44,tn)  = sums_l(k,44,tn) + &
-                                      vpt(k,j,i) * rmask(j,i,sr)
-                   sums_l(k,41,tn)  = sums_l(k,41,tn) + &
-                                      q(k,j,i) * rmask(j,i,sr)
+                DO  k = nzb, nzt+1
+                   flag = MERGE( 1.0_wp, 0.0_wp, BTEST( wall_flags_0(k,j,i), 22 ) )
+                   sums_l(k,44,tn)  = sums_l(k,44,tn) +                        &
+                                      vpt(k,j,i) * rmask(j,i,sr) * flag
+                   sums_l(k,41,tn)  = sums_l(k,41,tn) +                        &
+                                      q(k,j,i) * rmask(j,i,sr)   * flag
                 ENDDO
              ENDDO
@@ -449,10 +456,13 @@
              DO  i = nxl, nxr
                 DO  j =  nys, nyn
-                   DO  k = nzb_s_inner(j,i), nzt+1
-                      sums_l(k,42,tn) = sums_l(k,42,tn) + &
-                                      ( q(k,j,i) - ql(k,j,i) ) * rmask(j,i,sr)
-                      sums_l(k,43,tn) = sums_l(k,43,tn) + ( &
+                   DO  k = nzb, nzt+1
+                      flag = MERGE( 1.0_wp, 0.0_wp, BTEST( wall_flags_0(k,j,i), 22 ) )
+                      sums_l(k,42,tn) = sums_l(k,42,tn) +                      &
+                                      ( q(k,j,i) - ql(k,j,i) ) * rmask(j,i,sr) &
+                                                               * flag
+                      sums_l(k,43,tn) = sums_l(k,43,tn) + (                    &
                                       pt(k,j,i) + l_d_cp*pt_d_t(k) * ql(k,j,i) &
-                                                          ) * rmask(j,i,sr)
+                                                          ) * rmask(j,i,sr)    &
+                                                            * flag
                    ENDDO
                 ENDDO
@@ -467,6 +477,9 @@
           DO  i = nxl, nxr
              DO  j =  nys, nyn
-                DO  k = nzb_s_inner(j,i), nzt+1
-                   sums_l(k,117,tn)  = sums_l(k,117,tn) + s(k,j,i) * rmask(j,i,sr)
+                DO  k = nzb, nzt+1
+                   sums_l(k,117,tn)  = sums_l(k,117,tn) + s(k,j,i)             &
+                                    * rmask(j,i,sr)                            &
+                                    * MERGE( 1.0_wp, 0.0_wp,                   &
+                                             BTEST( wall_flags_0(k,j,i), 22 ) )
                 ENDDO
              ENDDO
@@ -603,39 +616,48 @@
        !$OMP PARALLEL PRIVATE( i, j, k, pts, sums_ll, sums_l_eper,             &
        !$OMP                   sums_l_etot, tn, ust, ust2, u2, vst, vst2, v2,  &
-       !$OMP                   w2 )
-!$     tn = omp_get_thread_num()
-
+       !$OMP                   w2, flag, m, ki, l )
+       !$ tn = omp_get_thread_num()
        !$OMP DO
        DO  i = nxl, nxr
           DO  j =  nys, nyn
              sums_l_etot = 0.0_wp
-             DO  k = nzb_s_inner(j,i), nzt+1
+             DO  k = nzb, nzt+1
+                flag = MERGE( 1.0_wp, 0.0_wp, BTEST( wall_flags_0(k,j,i), 22 ) )
 !
 !--             Prognostic and diagnostic variables
-                sums_l(k,3,tn)  = sums_l(k,3,tn)  + w(k,j,i)  * rmask(j,i,sr)
-                sums_l(k,8,tn)  = sums_l(k,8,tn)  + e(k,j,i)  * rmask(j,i,sr)
-                sums_l(k,9,tn)  = sums_l(k,9,tn)  + km(k,j,i) * rmask(j,i,sr)
-                sums_l(k,10,tn) = sums_l(k,10,tn) + kh(k,j,i) * rmask(j,i,sr)
-                sums_l(k,40,tn) = sums_l(k,40,tn) + p(k,j,i)
+                sums_l(k,3,tn)  = sums_l(k,3,tn)  + w(k,j,i)  * rmask(j,i,sr)  &
+                                                              * flag
+                sums_l(k,8,tn)  = sums_l(k,8,tn)  + e(k,j,i)  * rmask(j,i,sr)  &
+                                                              * flag
+                sums_l(k,9,tn)  = sums_l(k,9,tn)  + km(k,j,i) * rmask(j,i,sr)  &
+                                                              * flag
+                sums_l(k,10,tn) = sums_l(k,10,tn) + kh(k,j,i) * rmask(j,i,sr)  &
+                                                              * flag
+                sums_l(k,40,tn) = sums_l(k,40,tn) + p(k,j,i)  * flag
 
                 sums_l(k,33,tn) = sums_l(k,33,tn) + &
-                                  ( pt(k,j,i)-hom(k,1,4,sr) )**2 * rmask(j,i,sr)
+                                  ( pt(k,j,i)-hom(k,1,4,sr) )**2 * rmask(j,i,sr)&
+                                                                 * flag
 
                 IF ( humidity )  THEN
                    sums_l(k,70,tn) = sums_l(k,70,tn) + &
-                                  ( q(k,j,i)-hom(k,1,41,sr) )**2 * rmask(j,i,sr)
+                                  ( q(k,j,i)-hom(k,1,41,sr) )**2 * rmask(j,i,sr)&
+                                                                 * flag
                 ENDIF
                 IF ( passive_scalar )  THEN
                    sums_l(k,118,tn) = sums_l(k,118,tn) + &
-                                  ( s(k,j,i)-hom(k,1,117,sr) )**2 * rmask(j,i,sr)
+                                  ( s(k,j,i)-hom(k,1,117,sr) )**2 * rmask(j,i,sr)&
+                                                                  * flag
                 ENDIF
 !
 !--             Higher moments
 !--             (Computation of the skewness of w further below)
-                sums_l(k,38,tn) = sums_l(k,38,tn) + w(k,j,i)**3 * rmask(j,i,sr)
+                sums_l(k,38,tn) = sums_l(k,38,tn) + w(k,j,i)**3 * rmask(j,i,sr) &
+                                                                * flag
 
                 sums_l_etot  = sums_l_etot + &
-                                        0.5_wp * ( u(k,j,i)**2 + v(k,j,i)**2 + &
-                                        w(k,j,i)**2 ) * rmask(j,i,sr)
+                                        0.5_wp * ( u(k,j,i)**2 + v(k,j,i)**2 +  &
+                                        w(k,j,i)**2 )            * rmask(j,i,sr)&
+                                                                 * flag
              ENDDO
 !
@@ -647,19 +669,60 @@
 !
 !--          2D-arrays (being collected in the last column of sums_l)
-             sums_l(nzb,pr_palm,tn)   = sums_l(nzb,pr_palm,tn) +               &
-                                        us(j,i)   * rmask(j,i,sr)
-             sums_l(nzb+1,pr_palm,tn) = sums_l(nzb+1,pr_palm,tn) +             &
-                                        usws(j,i) * rmask(j,i,sr)
-             sums_l(nzb+2,pr_palm,tn) = sums_l(nzb+2,pr_palm,tn) +             &
-                                        vsws(j,i) * rmask(j,i,sr)
-             sums_l(nzb+3,pr_palm,tn) = sums_l(nzb+3,pr_palm,tn) +             &
-                                        ts(j,i)   * rmask(j,i,sr)
-             IF ( humidity )  THEN
-                sums_l(nzb+12,pr_palm,tn) = sums_l(nzb+12,pr_palm,tn) +        &
-                                            qs(j,i)   * rmask(j,i,sr)
+             IF ( surf_def_h(0)%ns >= 1 )  THEN
+                m = surf_def_h(0)%start_index(j,i)
+                sums_l(nzb,pr_palm,tn)   = sums_l(nzb,pr_palm,tn) +               &
+                                        surf_def_h(0)%us(m)   * rmask(j,i,sr)
+                sums_l(nzb+1,pr_palm,tn) = sums_l(nzb+1,pr_palm,tn) +             &
+                                        surf_def_h(0)%usws(m) * rmask(j,i,sr)
+                sums_l(nzb+2,pr_palm,tn) = sums_l(nzb+2,pr_palm,tn) +             &
+                                        surf_def_h(0)%vsws(m) * rmask(j,i,sr)
+                sums_l(nzb+3,pr_palm,tn) = sums_l(nzb+3,pr_palm,tn) +             &
+                                        surf_def_h(0)%ts(m)   * rmask(j,i,sr)
+                IF ( humidity )  THEN
+                   sums_l(nzb+12,pr_palm,tn) = sums_l(nzb+12,pr_palm,tn) +        &
+                                            surf_def_h(0)%qs(m)   * rmask(j,i,sr)
+                ENDIF
+                IF ( passive_scalar )  THEN
+                   sums_l(nzb+13,pr_palm,tn) = sums_l(nzb+13,pr_palm,tn) +        &
+                                            surf_def_h(0)%ss(m)   * rmask(j,i,sr)
+                ENDIF
              ENDIF
-             IF ( passive_scalar )  THEN
-                sums_l(nzb+13,pr_palm,tn) = sums_l(nzb+13,pr_palm,tn) +        &
-                                            ss(j,i)   * rmask(j,i,sr)
+             IF ( surf_lsm_h%ns >= 1 )  THEN
+                m = surf_lsm_h%start_index(j,i)
+                sums_l(nzb,pr_palm,tn)   = sums_l(nzb,pr_palm,tn) +               &
+                                        surf_lsm_h%us(m)   * rmask(j,i,sr)
+                sums_l(nzb+1,pr_palm,tn) = sums_l(nzb+1,pr_palm,tn) +             &
+                                        surf_lsm_h%usws(m) * rmask(j,i,sr)
+                sums_l(nzb+2,pr_palm,tn) = sums_l(nzb+2,pr_palm,tn) +             &
+                                        surf_lsm_h%vsws(m) * rmask(j,i,sr)
+                sums_l(nzb+3,pr_palm,tn) = sums_l(nzb+3,pr_palm,tn) +             &
+                                        surf_lsm_h%ts(m)   * rmask(j,i,sr)
+                IF ( humidity )  THEN
+                   sums_l(nzb+12,pr_palm,tn) = sums_l(nzb+12,pr_palm,tn) +        &
+                                            surf_lsm_h%qs(m)   * rmask(j,i,sr)
+                ENDIF
+                IF ( passive_scalar )  THEN
+                   sums_l(nzb+13,pr_palm,tn) = sums_l(nzb+13,pr_palm,tn) +        &
+                                            surf_lsm_h%ss(m)   * rmask(j,i,sr)
+                ENDIF
+             ENDIF
+             IF ( surf_usm_h%ns >= 1 )  THEN
+                m = surf_lsm_h%start_index(j,i)
+                sums_l(nzb,pr_palm,tn)   = sums_l(nzb,pr_palm,tn) +               &
+                                        surf_usm_h%us(m)   * rmask(j,i,sr)
+                sums_l(nzb+1,pr_palm,tn) = sums_l(nzb+1,pr_palm,tn) +             &
+                                        surf_usm_h%usws(m) * rmask(j,i,sr)
+                sums_l(nzb+2,pr_palm,tn) = sums_l(nzb+2,pr_palm,tn) +             &
+                                        surf_usm_h%vsws(m) * rmask(j,i,sr)
+                sums_l(nzb+3,pr_palm,tn) = sums_l(nzb+3,pr_palm,tn) +             &
+                                        surf_usm_h%ts(m)   * rmask(j,i,sr)
+                IF ( humidity )  THEN
+                   sums_l(nzb+12,pr_palm,tn) = sums_l(nzb+12,pr_palm,tn) +        &
+                                            surf_usm_h%qs(m)   * rmask(j,i,sr)
+                ENDIF
+                IF ( passive_scalar )  THEN
+                   sums_l(nzb+13,pr_palm,tn) = sums_l(nzb+13,pr_palm,tn) +        &
+                                            surf_usm_h%ss(m)   * rmask(j,i,sr)
+                ENDIF
              ENDIF
           ENDDO
@@ -674,5 +737,7 @@
           DO  i = nxl, nxr
              DO  j =  nys, nyn
-                DO  k = nzb_s_inner(j,i), nzt+1
+                DO  k = nzb, nzt+1
+                   flag = MERGE( 1.0_wp, 0.0_wp, BTEST( wall_flags_0(k,j,i), 22 ) )
+
                    u2   = u(k,j,i)**2
                    v2   = v(k,j,i)**2
@@ -681,12 +746,16 @@
                    vst2 = ( v(k,j,i) - hom(k,1,2,sr) )**2
 
-                   sums_l(k,30,tn) = sums_l(k,30,tn) + ust2 * rmask(j,i,sr)
-                   sums_l(k,31,tn) = sums_l(k,31,tn) + vst2 * rmask(j,i,sr)
-                   sums_l(k,32,tn) = sums_l(k,32,tn) + w2   * rmask(j,i,sr)
+                   sums_l(k,30,tn) = sums_l(k,30,tn) + ust2 * rmask(j,i,sr)    &
+                                                            * flag
+                   sums_l(k,31,tn) = sums_l(k,31,tn) + vst2 * rmask(j,i,sr)    &
+                                                            * flag
+                   sums_l(k,32,tn) = sums_l(k,32,tn) + w2   * rmask(j,i,sr)    &
+                                                            * flag
 !
 !--                Perturbation energy
 
                    sums_l(k,34,tn) = sums_l(k,34,tn) + 0.5_wp *                &
-                                  ( ust2 + vst2 + w2 ) * rmask(j,i,sr)
+                                  ( ust2 + vst2 + w2 )      * rmask(j,i,sr)    &
+                                                            * flag
                 ENDDO
              ENDDO
@@ -702,5 +771,7 @@
        DO  i = nxl, nxr
           DO  j =  nys, nyn
-             DO  k = nzb_s_inner(j,i), nzt+1
+             DO  k = nzb, nzt+1
+                flag = MERGE( 1.0_wp, 0.0_wp, BTEST( wall_flags_0(k,j,i), 22 ) )
+
                 w2   = w(k,j,i)**2
                 ust2 = ( u(k,j,i) - hom(k,1,1,sr) )**2
@@ -709,5 +780,7 @@
 
                 sums_l(nzb+5,pr_palm,tn) = sums_l(nzb+5,pr_palm,tn)            &
-                                 + 0.5_wp * ( ust2 + vst2 + w2 ) * rmask(j,i,sr)
+                                 + 0.5_wp * ( ust2 + vst2 + w2 )               &
+                                 * rmask(j,i,sr)                               &
+                                 * flag
              ENDDO
           ENDDO
@@ -728,6 +801,11 @@
 !--                However, this implies no error since staggered velocity 
 !--                components are zero at the walls and inside buildings.
-
-             DO  k = nzb_diff_s_inner(j,i)-1, nzt_diff
+!--          Flag 23 is used to mask surface fluxes as well as model-top fluxes,
+!--          which are added further below. 
+             DO  k = nzb, nzt
+                flag = MERGE( 1.0_wp, 0.0_wp,                                  &
+                              BTEST( wall_flags_0(k,j,i), 23 ) ) *             &
+                       MERGE( 1.0_wp, 0.0_wp,                                  &
+                              BTEST( wall_flags_0(k,j,i), 9  ) )
 !
 !--             Momentum flux w"u"
@@ -739,5 +817,6 @@
                                                            ) * rmask(j,i,sr)   &
                                          * rho_air_zw(k)                       &
-                                         * momentumflux_output_conversion(k)
+                                         * momentumflux_output_conversion(k)   &
+                                         * flag
 !
 !--             Momentum flux w"v"
@@ -749,5 +828,6 @@
                                                            ) * rmask(j,i,sr)   &
                                          * rho_air_zw(k)                       &
-                                         * momentumflux_output_conversion(k)
+                                         * momentumflux_output_conversion(k)   &
+                                         * flag
 !
 !--             Heat flux w"pt"
@@ -757,5 +837,6 @@
                                                * rho_air_zw(k)                 &
                                                * heatflux_output_conversion(k) &
-                                               * ddzu(k+1) * rmask(j,i,sr)
+                                               * ddzu(k+1) * rmask(j,i,sr)     &
+                                               * flag
 
 
@@ -766,5 +847,6 @@
                                          - 0.5_wp * ( kh(k,j,i) + kh(k+1,j,i) )&
                                                * ( sa(k+1,j,i) - sa(k,j,i) )   &
-                                               * ddzu(k+1) * rmask(j,i,sr)
+                                               * ddzu(k+1) * rmask(j,i,sr)     &
+                                               * flag
                 ENDIF
 
@@ -777,5 +859,5 @@
                                                * rho_air_zw(k)                 &
                                                * heatflux_output_conversion(k) &
-                                               * ddzu(k+1) * rmask(j,i,sr)
+                                               * ddzu(k+1) * rmask(j,i,sr) * flag
                    sums_l(k,48,tn) = sums_l(k,48,tn)                           &
                                          - 0.5_wp * ( kh(k,j,i) + kh(k+1,j,i) )&
@@ -783,5 +865,5 @@
                                                * rho_air_zw(k)                 &
                                                * waterflux_output_conversion(k)&
-                                               * ddzu(k+1) * rmask(j,i,sr)
+                                               * ddzu(k+1) * rmask(j,i,sr) * flag
 
                    IF ( cloud_physics ) THEN
@@ -792,5 +874,5 @@
                                                * rho_air_zw(k)                 &
                                                * waterflux_output_conversion(k)&
-                                               * ddzu(k+1) * rmask(j,i,sr) 
+                                               * ddzu(k+1) * rmask(j,i,sr) * flag
                    ENDIF
                 ENDIF
@@ -802,5 +884,6 @@
                                          - 0.5_wp * ( kh(k,j,i) + kh(k+1,j,i) )&
                                                   * ( s(k+1,j,i) - s(k,j,i) )  &
-                                                  * ddzu(k+1) * rmask(j,i,sr)
+                                                  * ddzu(k+1) * rmask(j,i,sr)  &
+                                                              * flag
                 ENDIF
 
@@ -810,66 +893,179 @@
 !--          Subgridscale fluxes in the Prandtl layer
              IF ( use_surface_fluxes )  THEN
-                sums_l(nzb,12,tn) = sums_l(nzb,12,tn) + &
+                DO  l = 0, 1
+                   ki = MERGE( -1, 0, l == 0 )
+                   IF ( surf_def_h(l)%ns >= 1 )  THEN
+                      DO  m = surf_def_h(l)%start_index(j,i), surf_def_h(l)%end_index(j,i)
+                         k = surf_def_h(l)%k(m)
+
+                         sums_l(k+ki,12,tn) = sums_l(k+ki,12,tn) + &
+                                    momentumflux_output_conversion(k+ki) * &
+                                    surf_def_h(l)%usws(m) * rmask(j,i,sr)     ! w"u"
+                         sums_l(k+ki,14,tn) = sums_l(k+ki,14,tn) + &
+                                    momentumflux_output_conversion(k+ki) * &
+                                    surf_def_h(l)%vsws(m) * rmask(j,i,sr)     ! w"v"
+                         sums_l(k+ki,16,tn) = sums_l(k+ki,16,tn) + &
+                                    heatflux_output_conversion(k+ki) * &
+                                    surf_def_h(l)%shf(m)  * rmask(j,i,sr)     ! w"pt"
+                         sums_l(k+ki,58,tn) = sums_l(k+ki,58,tn) + &
+                                    0.0_wp * rmask(j,i,sr)        ! u"pt"
+                         sums_l(k+ki,61,tn) = sums_l(k+ki,61,tn) + &
+                                    0.0_wp * rmask(j,i,sr)        ! v"pt"
+                         IF ( ocean )  THEN
+                            sums_l(k+ki,65,tn) = sums_l(k+ki,65,tn) + &
+                                       surf_def_h(l)%sasws(m) * rmask(j,i,sr)  ! w"sa"
+                         ENDIF
+                         IF ( humidity )  THEN
+                            sums_l(k+ki,48,tn) = sums_l(k+ki,48,tn) +                     &
+                                       waterflux_output_conversion(k+ki) *      &
+                                       surf_def_h(l)%qsws(m) * rmask(j,i,sr)  ! w"q" (w"qv")
+                            sums_l(k+ki,45,tn) = sums_l(k+ki,45,tn) + (                   &
+                                       ( 1.0_wp + 0.61_wp * q(k+ki,j,i) ) *     &
+                                       surf_def_h(l)%shf(m) + 0.61_wp * pt(k+ki,j,i) *      &
+                                                  surf_def_h(l)%qsws(m) )                  &
+                                       * heatflux_output_conversion(k+ki)
+                            IF ( cloud_droplets )  THEN
+                               sums_l(k+ki,45,tn) = sums_l(k+ki,45,tn) + (                &
+                                         ( 1.0_wp + 0.61_wp * q(k+ki,j,i) -     &
+                                           ql(k+ki,j,i) ) * surf_def_h(l)%shf(m) +          &
+                                           0.61_wp * pt(k+ki,j,i) * surf_def_h(l)%qsws(m) ) &
+                                          * heatflux_output_conversion(k+ki)
+                            ENDIF
+                            IF ( cloud_physics )  THEN
+!
+!--                            Formula does not work if ql(k+ki) /= 0.0
+                               sums_l(k+ki,51,tn) = sums_l(k+ki,51,tn) +                  &
+                                          waterflux_output_conversion(k+ki) *   &
+                                          surf_def_h(l)%qsws(m) * rmask(j,i,sr) ! w"q" (w"qv")
+                            ENDIF
+                         ENDIF
+                         IF ( passive_scalar )  THEN
+                            sums_l(k+ki,119,tn) = sums_l(k+ki,119,tn) +                     &
+                                        surf_def_h(l)%ssws(m) * rmask(j,i,sr) ! w"s"
+                         ENDIF
+
+                      ENDDO
+
+                   ENDIF
+                ENDDO
+                IF ( surf_lsm_h%ns >= 1 )  THEN
+                   m = surf_lsm_h%start_index(j,i)
+                   sums_l(nzb,12,tn) = sums_l(nzb,12,tn) + &
                                     momentumflux_output_conversion(nzb) * &
-                                    usws(j,i) * rmask(j,i,sr)     ! w"u"
-                sums_l(nzb,14,tn) = sums_l(nzb,14,tn) + &
+                                    surf_lsm_h%usws(m) * rmask(j,i,sr)     ! w"u"
+                   sums_l(nzb,14,tn) = sums_l(nzb,14,tn) + &
                                     momentumflux_output_conversion(nzb) * &
-                                    vsws(j,i) * rmask(j,i,sr)     ! w"v"
-                sums_l(nzb,16,tn) = sums_l(nzb,16,tn) + &
+                                    surf_lsm_h%vsws(m) * rmask(j,i,sr)     ! w"v"
+                   sums_l(nzb,16,tn) = sums_l(nzb,16,tn) + &
                                     heatflux_output_conversion(nzb) * &
-                                    shf(j,i)  * rmask(j,i,sr)     ! w"pt"
-                sums_l(nzb,58,tn) = sums_l(nzb,58,tn) + &
+                                    surf_lsm_h%shf(m)  * rmask(j,i,sr)     ! w"pt"
+                   sums_l(nzb,58,tn) = sums_l(nzb,58,tn) + &
                                     0.0_wp * rmask(j,i,sr)        ! u"pt"
-                sums_l(nzb,61,tn) = sums_l(nzb,61,tn) + &
+                   sums_l(nzb,61,tn) = sums_l(nzb,61,tn) + &
                                     0.0_wp * rmask(j,i,sr)        ! v"pt"
-                IF ( ocean )  THEN
-                   sums_l(nzb,65,tn) = sums_l(nzb,65,tn) + &
-                                       saswsb(j,i) * rmask(j,i,sr)  ! w"sa"
-                ENDIF
-                IF ( humidity )  THEN
-                   sums_l(nzb,48,tn) = sums_l(nzb,48,tn) +                     &
+                   IF ( ocean )  THEN
+                      sums_l(nzb,65,tn) = sums_l(nzb,65,tn) + &
+                                       surf_lsm_h%sasws(m) * rmask(j,i,sr)  ! w"sa"
+                   ENDIF
+                   IF ( humidity )  THEN
+                      sums_l(nzb,48,tn) = sums_l(nzb,48,tn) +                     &
                                        waterflux_output_conversion(nzb) *      &
-                                       qsws(j,i) * rmask(j,i,sr)  ! w"q" (w"qv")
-                   sums_l(nzb,45,tn) = sums_l(nzb,45,tn) + (                   &
+                                       surf_lsm_h%qsws(m) * rmask(j,i,sr)  ! w"q" (w"qv")
+                      sums_l(nzb,45,tn) = sums_l(nzb,45,tn) + (                   &
                                        ( 1.0_wp + 0.61_wp * q(nzb,j,i) ) *     &
-                                       shf(j,i) + 0.61_wp * pt(nzb,j,i) *      &
-                                                  qsws(j,i) )                  &
+                                       surf_lsm_h%shf(m) + 0.61_wp * pt(nzb,j,i) *      &
+                                                  surf_lsm_h%qsws(m) )                  &
                                        * heatflux_output_conversion(nzb)
-                   IF ( cloud_droplets )  THEN
-                      sums_l(nzb,45,tn) = sums_l(nzb,45,tn) + (                &
+                      IF ( cloud_droplets )  THEN
+                         sums_l(nzb,45,tn) = sums_l(nzb,45,tn) + (                &
                                          ( 1.0_wp + 0.61_wp * q(nzb,j,i) -     &
-                                           ql(nzb,j,i) ) * shf(j,i) +          &
-                                           0.61_wp * pt(nzb,j,i) * qsws(j,i) ) &
+                                           ql(nzb,j,i) ) * surf_lsm_h%shf(m) +          &
+                                           0.61_wp * pt(nzb,j,i) * surf_lsm_h%qsws(m) ) &
                                           * heatflux_output_conversion(nzb)
+                      ENDIF
+                      IF ( cloud_physics )  THEN
+!
+!--                      Formula does not work if ql(nzb) /= 0.0
+                         sums_l(nzb,51,tn) = sums_l(nzb,51,tn) +                  &
+                                          waterflux_output_conversion(nzb) *   &
+                                          surf_lsm_h%qsws(m) * rmask(j,i,sr) ! w"q" (w"qv")
+                      ENDIF
                    ENDIF
-                   IF ( cloud_physics )  THEN
-!
-!--                   Formula does not work if ql(nzb) /= 0.0
-                      sums_l(nzb,51,tn) = sums_l(nzb,51,tn) +                  &
+                   IF ( passive_scalar )  THEN
+                      sums_l(nzb,119,tn) = sums_l(nzb,119,tn) +                     &
+                                        surf_lsm_h%ssws(m) * rmask(j,i,sr) ! w"s"
+                   ENDIF
+
+
+                ENDIF
+                IF ( surf_usm_h%ns >= 1 )  THEN
+                   m = surf_usm_h%start_index(j,i)
+                   sums_l(nzb,12,tn) = sums_l(nzb,12,tn) + &
+                                    momentumflux_output_conversion(nzb) * &
+                                    surf_usm_h%usws(m) * rmask(j,i,sr)     ! w"u"
+                   sums_l(nzb,14,tn) = sums_l(nzb,14,tn) + &
+                                    momentumflux_output_conversion(nzb) * &
+                                    surf_usm_h%vsws(m) * rmask(j,i,sr)     ! w"v"
+                   sums_l(nzb,16,tn) = sums_l(nzb,16,tn) + &
+                                    heatflux_output_conversion(nzb) * &
+                                    surf_usm_h%shf(m)  * rmask(j,i,sr)     ! w"pt"
+                   sums_l(nzb,58,tn) = sums_l(nzb,58,tn) + &
+                                    0.0_wp * rmask(j,i,sr)        ! u"pt"
+                   sums_l(nzb,61,tn) = sums_l(nzb,61,tn) + &
+                                    0.0_wp * rmask(j,i,sr)        ! v"pt"
+                   IF ( ocean )  THEN
+                      sums_l(nzb,65,tn) = sums_l(nzb,65,tn) + &
+                                       surf_usm_h%sasws(m) * rmask(j,i,sr)  ! w"sa"
+                   ENDIF
+                   IF ( humidity )  THEN
+                      sums_l(nzb,48,tn) = sums_l(nzb,48,tn) +                     &
+                                       waterflux_output_conversion(nzb) *      &
+                                       surf_usm_h%qsws(m) * rmask(j,i,sr)  ! w"q" (w"qv")
+                      sums_l(nzb,45,tn) = sums_l(nzb,45,tn) + (                   &
+                                       ( 1.0_wp + 0.61_wp * q(nzb,j,i) ) *     &
+                                       surf_usm_h%shf(m) + 0.61_wp * pt(nzb,j,i) *      &
+                                                  surf_usm_h%qsws(m) )                  &
+                                       * heatflux_output_conversion(nzb)
+                      IF ( cloud_droplets )  THEN
+                         sums_l(nzb,45,tn) = sums_l(nzb,45,tn) + (                &
+                                         ( 1.0_wp + 0.61_wp * q(nzb,j,i) -     &
+                                           ql(nzb,j,i) ) * surf_usm_h%shf(m) +          &
+                                           0.61_wp * pt(nzb,j,i) * surf_usm_h%qsws(m) ) &
+                                          * heatflux_output_conversion(nzb)
+                      ENDIF
+                      IF ( cloud_physics )  THEN
+!
+!--                      Formula does not work if ql(nzb) /= 0.0
+                         sums_l(nzb,51,tn) = sums_l(nzb,51,tn) +                  &
                                           waterflux_output_conversion(nzb) *   &
-                                          qsws(j,i) * rmask(j,i,sr) ! w"q" (w"qv")
+                                          surf_usm_h%qsws(m) * rmask(j,i,sr) ! w"q" (w"qv")
+                      ENDIF
                    ENDIF
-                ENDIF
-                IF ( passive_scalar )  THEN
-                   sums_l(nzb,119,tn) = sums_l(nzb,119,tn) +                     &
-                                        ssws(j,i) * rmask(j,i,sr) ! w"s"
-                ENDIF
+                   IF ( passive_scalar )  THEN
+                      sums_l(nzb,119,tn) = sums_l(nzb,119,tn) +                     &
+                                        surf_usm_h%ssws(m) * rmask(j,i,sr) ! w"s"
+                   ENDIF
+
+
+                ENDIF
+
              ENDIF
 
              IF ( .NOT. neutral )  THEN
-                sums_l(nzb,114,tn) = sums_l(nzb,114,tn) +                      &
-                                    ol(j,i)  * rmask(j,i,sr) ! L
-             ENDIF
-
-
-             IF ( land_surface )  THEN
-                sums_l(nzb,93,tn)  = sums_l(nzb,93,tn) + ghf_eb(j,i)
-                sums_l(nzb,94,tn)  = sums_l(nzb,94,tn) + shf_eb(j,i)
-                sums_l(nzb,95,tn)  = sums_l(nzb,95,tn) + qsws_eb(j,i)
-                sums_l(nzb,96,tn)  = sums_l(nzb,96,tn) + qsws_liq_eb(j,i)
-                sums_l(nzb,97,tn)  = sums_l(nzb,97,tn) + qsws_soil_eb(j,i)
-                sums_l(nzb,98,tn)  = sums_l(nzb,98,tn) + qsws_veg_eb(j,i)
-                sums_l(nzb,99,tn)  = sums_l(nzb,99,tn) + r_a(j,i)
-                sums_l(nzb,100,tn) = sums_l(nzb,100,tn)+ r_s(j,i)
+                IF ( surf_def_h(0)%ns >= 1 )  THEN
+                   m = surf_def_h(0)%start_index(j,i)
+                   sums_l(nzb,114,tn) = sums_l(nzb,114,tn) +                      &
+                                        surf_def_h(0)%ol(m)  * rmask(j,i,sr) ! L
+                ENDIF
+                IF ( surf_lsm_h%ns >= 1 )  THEN
+                   m = surf_lsm_h%start_index(j,i)
+                   sums_l(nzb,114,tn) = sums_l(nzb,114,tn) +                      &
+                                        surf_lsm_h%ol(m)  * rmask(j,i,sr) ! L
+                ENDIF
+                IF ( surf_usm_h%ns >= 1 )  THEN
+                   m = surf_usm_h%start_index(j,i)
+                   sums_l(nzb,114,tn) = sums_l(nzb,114,tn) +                      &
+                                        surf_usm_h%ol(m)  * rmask(j,i,sr) ! L
+                ENDIF
              ENDIF
 
@@ -893,13 +1089,14 @@
 !--          Subgridscale fluxes at the top surface
              IF ( use_top_fluxes )  THEN
+                m = surf_def_h(2)%start_index(j,i)
                 sums_l(nzt:nzt+1,12,tn) = sums_l(nzt:nzt+1,12,tn) + &
                                     momentumflux_output_conversion(nzt:nzt+1) * &
-                                    uswst(j,i) * rmask(j,i,sr)    ! w"u"
+                                    surf_def_h(2)%usws(m) * rmask(j,i,sr)    ! w"u"
                 sums_l(nzt:nzt+1,14,tn) = sums_l(nzt:nzt+1,14,tn) + &
                                     momentumflux_output_conversion(nzt:nzt+1) * &
-                                    vswst(j,i) * rmask(j,i,sr)    ! w"v"
+                                    surf_def_h(2)%vsws(m) * rmask(j,i,sr)    ! w"v"
                 sums_l(nzt:nzt+1,16,tn) = sums_l(nzt:nzt+1,16,tn) + &
                                     heatflux_output_conversion(nzt:nzt+1) * &
-                                    tswst(j,i)  * rmask(j,i,sr)   ! w"pt"
+                                    surf_def_h(2)%shf(m)  * rmask(j,i,sr)   ! w"pt"
                 sums_l(nzt:nzt+1,58,tn) = sums_l(nzt:nzt+1,58,tn) + &
                                     0.0_wp * rmask(j,i,sr)        ! u"pt"
@@ -909,20 +1106,23 @@
                 IF ( ocean )  THEN
                    sums_l(nzt,65,tn) = sums_l(nzt,65,tn) + &
-                                       saswst(j,i) * rmask(j,i,sr)  ! w"sa"
+                                       surf_def_h(2)%sasws(m) * rmask(j,i,sr)  ! w"sa"
                 ENDIF
                 IF ( humidity )  THEN
                    sums_l(nzt,48,tn) = sums_l(nzt,48,tn) +                     &
                                        waterflux_output_conversion(nzt) *      &
-                                       qswst(j,i) * rmask(j,i,sr) ! w"q" (w"qv")
+                                       surf_def_h(2)%qsws(m) * rmask(j,i,sr) ! w"q" (w"qv")
                    sums_l(nzt,45,tn) = sums_l(nzt,45,tn) + (                   &
                                        ( 1.0_wp + 0.61_wp * q(nzt,j,i) ) *     &
-                                       tswst(j,i) + 0.61_wp * pt(nzt,j,i) *    &
-                                                             qswst(j,i) )      &
+                                       surf_def_h(2)%shf(m) +                  &
+                                       0.61_wp * pt(nzt,j,i) *    &
+                                       surf_def_h(2)%qsws(m) )      &
                                        * heatflux_output_conversion(nzt)
                    IF ( cloud_droplets )  THEN
                       sums_l(nzt,45,tn) = sums_l(nzt,45,tn) + (                &
                                           ( 1.0_wp + 0.61_wp * q(nzt,j,i) -    &
-                                            ql(nzt,j,i) ) * tswst(j,i) +       &
-                                           0.61_wp * pt(nzt,j,i) * qswst(j,i) )&
+                                            ql(nzt,j,i) ) *                    &
+                                            surf_def_h(2)%shf(m) +             &
+                                           0.61_wp * pt(nzt,j,i) *             &
+                                           surf_def_h(2)%qsws(m) )&
                                            * heatflux_output_conversion(nzt)
                    ENDIF
@@ -932,10 +1132,10 @@
                       sums_l(nzt,51,tn) = sums_l(nzt,51,tn) + &   ! w"q" (w"qv")
                                           waterflux_output_conversion(nzt) *   &
-                                          qswst(j,i) * rmask(j,i,sr)
+                                          surf_def_h(2)%qsws(m) * rmask(j,i,sr)
                    ENDIF
                 ENDIF
                 IF ( passive_scalar )  THEN
                    sums_l(nzt,119,tn) = sums_l(nzt,119,tn) + &
-                                        sswst(j,i) * rmask(j,i,sr) ! w"s"
+                                        surf_def_h(2)%ssws(m) * rmask(j,i,sr) ! w"s"
                 ENDIF
              ENDIF
@@ -946,5 +1146,6 @@
 !--          ----  speaking the following k-loop would have to be split up and 
 !--                rearranged according to the staggered grid.
-             DO  k = nzb_s_inner(j,i), nzt
+             DO  k = nzb, nzt
+                flag = MERGE( 1.0_wp, 0.0_wp, BTEST( wall_flags_0(k,j,i), 22 ) )
                 ust = 0.5_wp * ( u(k,j,i)   - hom(k,1,1,sr) +                  &
                                  u(k+1,j,i) - hom(k+1,1,1,sr) )
@@ -956,7 +1157,7 @@
 !--             Higher moments
                 sums_l(k,35,tn) = sums_l(k,35,tn) + pts * w(k,j,i)**2 *        &
-                                                    rmask(j,i,sr)
+                                                    rmask(j,i,sr) * flag
                 sums_l(k,36,tn) = sums_l(k,36,tn) + pts**2 * w(k,j,i) *        &
-                                                    rmask(j,i,sr)
+                                                    rmask(j,i,sr) * flag
 
 !
@@ -968,10 +1169,10 @@
                                        sa(k+1,j,i) - hom(k+1,1,23,sr) )
                       sums_l(k,66,tn) = sums_l(k,66,tn) + pts * w(k,j,i) *     &
-                                        rmask(j,i,sr)
+                                        rmask(j,i,sr) * flag
                    ENDIF
-                   sums_l(k,64,tn) = sums_l(k,64,tn) + rho_ocean(k,j,i) *            &
-                                                       rmask(j,i,sr)
+                   sums_l(k,64,tn) = sums_l(k,64,tn) + rho_ocean(k,j,i) *      &
+                                                       rmask(j,i,sr) * flag
                    sums_l(k,71,tn) = sums_l(k,71,tn) + prho(k,j,i) *           &
-                                                       rmask(j,i,sr)
+                                                       rmask(j,i,sr) * flag
                 ENDIF
 
@@ -985,6 +1186,7 @@
                       sums_l(k,46,tn) = sums_l(k,46,tn) + pts * w(k,j,i) *     &
                                                heatflux_output_conversion(k) * &
-                                                          rmask(j,i,sr)
-                      sums_l(k,54,tn) = sums_l(k,54,tn) + ql(k,j,i) * rmask(j,i,sr)
+                                                          rmask(j,i,sr) * flag
+                      sums_l(k,54,tn) = sums_l(k,54,tn) + ql(k,j,i) * rmask(j,i,sr) &
+                                                                    * flag
 
                       IF ( .NOT. cloud_droplets )  THEN
@@ -996,14 +1198,19 @@
                          sums_l(k,52,tn) = sums_l(k,52,tn) + pts * w(k,j,i) *  &
                                              waterflux_output_conversion(k) *  &
-                                                             rmask(j,i,sr)
+                                                             rmask(j,i,sr)  *  &
+                                                             flag
                          sums_l(k,75,tn) = sums_l(k,75,tn) + qc(k,j,i) *       &
-                                                             rmask(j,i,sr)
+                                                             rmask(j,i,sr) *   &
+                                                             flag
                          sums_l(k,76,tn) = sums_l(k,76,tn) + prr(k,j,i) *      &
-                                                             rmask(j,i,sr)
+                                                             rmask(j,i,sr) *   &
+                                                             flag
                          IF ( microphysics_seifert )  THEN
                             sums_l(k,73,tn) = sums_l(k,73,tn) + nr(k,j,i) *    &
-                                                                rmask(j,i,sr)
+                                                                rmask(j,i,sr) *&
+                                                                flag 
                             sums_l(k,74,tn) = sums_l(k,74,tn) + qr(k,j,i) *    &
-                                                                rmask(j,i,sr)
+                                                                rmask(j,i,sr) *&
+                                                                flag
                          ENDIF
                       ENDIF
@@ -1015,5 +1222,6 @@
                          sums_l(k,46,tn) = sums_l(k,46,tn) + pts * w(k,j,i) *  &
                                               heatflux_output_conversion(k) *  &
-                                                             rmask(j,i,sr)
+                                                             rmask(j,i,sr)  *  &
+                                                             flag
                       ELSE IF ( ws_scheme_sca .AND. sr == 0 )  THEN
                          sums_l(k,46,tn) = ( ( 1.0_wp + 0.61_wp *              & 
@@ -1022,5 +1230,6 @@
                                              0.61_wp * hom(k,1,4,sr) *         &
                                              sums_l(k,49,tn)                   &
-                                           ) * heatflux_output_conversion(k)
+                                           ) * heatflux_output_conversion(k) * &
+                                               flag
                       END IF
                    END IF
@@ -1033,5 +1242,5 @@
                                     s(k+1,j,i) - hom(k+1,1,117,sr) )
                    sums_l(k,116,tn) = sums_l(k,116,tn) + pts * w(k,j,i) *      &
-                                                       rmask(j,i,sr)
+                                                       rmask(j,i,sr) * flag
                 ENDIF
 
@@ -1042,66 +1251,132 @@
                                              ( ust**2 + vst**2 + w(k,j,i)**2 ) &
                                            * momentumflux_output_conversion(k) &
-                                             * rmask(j,i,sr)
+                                           * rmask(j,i,sr) * flag
              ENDDO
           ENDDO
        ENDDO
+       !$OMP END PARALLEL
+!
+!--    Treat land-surface quantities according to new wall model structure. 
+       IF ( land_surface )  THEN
+          tn = 0
+          !$OMP PARALLEL PRIVATE( i, j, m, tn )
+          !$ tn = omp_get_thread_num()
+          !$OMP DO
+          DO  m = 1, surf_lsm_h%ns
+             i = surf_lsm_h%i(m)
+             j = surf_lsm_h%j(m)
+        
+             IF ( i >= nxl  .AND.  i <= nxr  .AND.                             &
+                  j >= nys  .AND.  j <= nyn )  THEN 
+                sums_l(nzb,93,tn)  = sums_l(nzb,93,tn) + surf_lsm_h%ghf_eb(m)
+                sums_l(nzb,94,tn)  = sums_l(nzb,94,tn) + surf_lsm_h%shf_eb(m)
+                sums_l(nzb,95,tn)  = sums_l(nzb,95,tn) + surf_lsm_h%qsws_eb(m)
+                sums_l(nzb,96,tn)  = sums_l(nzb,96,tn) + surf_lsm_h%qsws_liq_eb(m)
+                sums_l(nzb,97,tn)  = sums_l(nzb,97,tn) + surf_lsm_h%qsws_soil_eb(m)
+                sums_l(nzb,98,tn)  = sums_l(nzb,98,tn) + surf_lsm_h%qsws_veg_eb(m)
+                sums_l(nzb,99,tn)  = sums_l(nzb,99,tn) + surf_lsm_h%r_a(m)
+                sums_l(nzb,100,tn) = sums_l(nzb,100,tn)+ surf_lsm_h%r_s(m)
+             ENDIF
+          ENDDO
+          !$OMP END PARALLEL
+
+          tn = 0
+          !$OMP PARALLEL PRIVATE( i, j, k, m, tn )
+          !$ tn = omp_get_thread_num()
+          !$OMP DO
+          DO  m = 1, surf_lsm_h%ns
+
+             i = surf_lsm_h%i(m)            
+             j = surf_lsm_h%j(m)
+
+             IF ( i >= nxl  .AND.  i <= nxr  .AND.                             &
+                  j >= nys  .AND.  j <= nyn )  THEN 
+
+                DO  k = nzb_soil, nzt_soil
+                   sums_l(k,89,tn)  = sums_l(k,89,tn)  + t_soil_h%var_2d(k,m)  &
+                                      * rmask(j,i,sr)
+                   sums_l(k,91,tn)  = sums_l(k,91,tn)  + m_soil_h%var_2d(k,m)  &
+                                      * rmask(j,i,sr)
+                ENDDO
+             ENDIF
+          ENDDO
+          !$OMP END PARALLEL
+       ENDIF
 !
 !--    For speed optimization fluxes which have been computed in part directly
 !--    inside the WS advection routines are treated seperatly
 !--    Momentum fluxes first:
+
+       tn = 0
+       !$OMP PARALLEL PRIVATE( i, j, k, tn, flag )
+       !$ tn = omp_get_thread_num()
        IF ( .NOT. ws_scheme_mom .OR. sr /= 0  )  THEN
-         !$OMP DO
-         DO  i = nxl, nxr
-            DO  j = nys, nyn
-               DO  k = nzb_diff_s_inner(j,i)-1, nzt_diff
-                  ust = 0.5_wp * ( u(k,j,i)   - hom(k,1,1,sr) +                &
-                                   u(k+1,j,i) - hom(k+1,1,1,sr) )
-                  vst = 0.5_wp * ( v(k,j,i)   - hom(k,1,2,sr) +                &
-                                   v(k+1,j,i) - hom(k+1,1,2,sr) )
-!
-!--               Momentum flux w*u*
-                  sums_l(k,13,tn) = sums_l(k,13,tn) + 0.5_wp *                 &
-                                                    ( w(k,j,i-1) + w(k,j,i) )  &
-                                          * momentumflux_output_conversion(k)  &
-                                                    * ust * rmask(j,i,sr)
-!
-!--               Momentum flux w*v*
-                  sums_l(k,15,tn) = sums_l(k,15,tn) + 0.5_wp *                 &
-                                                    ( w(k,j-1,i) + w(k,j,i) )  &
-                                          * momentumflux_output_conversion(k)  &
-                                                    * vst * rmask(j,i,sr)
-               ENDDO
-            ENDDO
-         ENDDO
+          !$OMP DO
+          DO  i = nxl, nxr
+             DO  j = nys, nyn
+                DO  k = nzb, nzt
+!
+!--                Flag 23 is used to mask surface fluxes as well as model-top 
+!--                fluxes, which are added further below. 
+                   flag = MERGE( 1.0_wp, 0.0_wp,                               &
+                                 BTEST( wall_flags_0(k,j,i), 23 ) ) *          &
+                          MERGE( 1.0_wp, 0.0_wp,                               &
+                                 BTEST( wall_flags_0(k,j,i), 9  ) )
+
+                   ust = 0.5_wp * ( u(k,j,i)   - hom(k,1,1,sr) +               &
+                                    u(k+1,j,i) - hom(k+1,1,1,sr) )
+                   vst = 0.5_wp * ( v(k,j,i)   - hom(k,1,2,sr) +               &
+                                    v(k+1,j,i) - hom(k+1,1,2,sr) )
+!
+!--                Momentum flux w*u*
+                   sums_l(k,13,tn) = sums_l(k,13,tn) + 0.5_wp *                &
+                                                     ( w(k,j,i-1) + w(k,j,i) ) &
+                                           * momentumflux_output_conversion(k) &
+                                                     * ust * rmask(j,i,sr)     &
+                                                           * flag
+!
+!--                Momentum flux w*v*
+                   sums_l(k,15,tn) = sums_l(k,15,tn) + 0.5_wp *                &
+                                                     ( w(k,j-1,i) + w(k,j,i) ) &
+                                           * momentumflux_output_conversion(k) &
+                                                     * vst * rmask(j,i,sr)     &
+                                                           * flag
+                ENDDO
+             ENDDO
+          ENDDO
 
        ENDIF
        IF ( .NOT. ws_scheme_sca .OR. sr /= 0 )  THEN
-         !$OMP DO
-         DO  i = nxl, nxr
-            DO  j = nys, nyn
-               DO  k = nzb_diff_s_inner(j,i)-1, nzt_diff
-!
-!--               Vertical heat flux
-                  sums_l(k,17,tn) = sums_l(k,17,tn) + 0.5_wp *                 &
+          !$OMP DO
+          DO  i = nxl, nxr
+             DO  j = nys, nyn
+                DO  k = nzb, nzt
+                   flag = MERGE( 1.0_wp, 0.0_wp,                               &
+                                 BTEST( wall_flags_0(k,j,i), 23 ) ) *          &
+                          MERGE( 1.0_wp, 0.0_wp,                               &
+                                 BTEST( wall_flags_0(k,j,i), 9  ) )
+!
+!--                Vertical heat flux
+                   sums_l(k,17,tn) = sums_l(k,17,tn) + 0.5_wp *                &
                            ( pt(k,j,i)   - hom(k,1,4,sr) +                     &
                              pt(k+1,j,i) - hom(k+1,1,4,sr) )                   &
                            * heatflux_output_conversion(k)                     &
-                           * w(k,j,i) * rmask(j,i,sr)
-                  IF ( humidity )  THEN
-                     pts = 0.5_wp * ( q(k,j,i)   - hom(k,1,41,sr) +            &
+                           * w(k,j,i) * rmask(j,i,sr) * flag
+                   IF ( humidity )  THEN
+                      pts = 0.5_wp * ( q(k,j,i)   - hom(k,1,41,sr) +           &
                                       q(k+1,j,i) - hom(k+1,1,41,sr) )
-                     sums_l(k,49,tn) = sums_l(k,49,tn) + pts * w(k,j,i) *      &
+                      sums_l(k,49,tn) = sums_l(k,49,tn) + pts * w(k,j,i) *     &
                                        waterflux_output_conversion(k) *        &
-                                       rmask(j,i,sr)
-                  ENDIF
-                  IF ( passive_scalar )  THEN
-                     pts = 0.5_wp * ( s(k,j,i)   - hom(k,1,117,sr) +            &
+                                       rmask(j,i,sr) * flag
+                   ENDIF
+                   IF ( passive_scalar )  THEN
+                      pts = 0.5_wp * ( s(k,j,i)   - hom(k,1,117,sr) +           &
                                       s(k+1,j,i) - hom(k+1,1,117,sr) )
-                     sums_l(k,116,tn) = sums_l(k,116,tn) + pts * w(k,j,i) *     &
-                                        rmask(j,i,sr)
-                  ENDIF
-               ENDDO
-            ENDDO
-         ENDDO
+                      sums_l(k,116,tn) = sums_l(k,116,tn) + pts * w(k,j,i) *    &
+                                        rmask(j,i,sr) * flag
+                   ENDIF
+                ENDDO
+             ENDDO
+          ENDDO
 
        ENDIF
@@ -1126,5 +1401,6 @@
           DO  i = nxl, nxr
              DO  j = nys, nyn
-                DO  k = nzb_s_inner(j,i)+1, nzt
+                DO  k = nzb+1, nzt
+                   flag = MERGE( 1.0_wp, 0.0_wp, BTEST( wall_flags_0(k,j,i), 0 ) )
 
                    sums_ll(k,1) = sums_ll(k,1) + 0.5_wp * w(k,j,i) * (         &
@@ -1133,8 +1409,8 @@
                 + ( 0.25_wp * ( v(k,j,i)+v(k+1,j,i)+v(k,j+1,i)+v(k+1,j+1,i) )  &
                             - 0.5_wp * ( hom(k,1,2,sr) + hom(k+1,1,2,sr) ) )**2&
-                + w(k,j,i)**2                                        )
+                + w(k,j,i)**2                                        ) * flag
 
                    sums_ll(k,2) = sums_ll(k,2) + 0.5_wp * w(k,j,i)             &
-                                               * ( p(k,j,i) + p(k+1,j,i) )
+                                               * ( p(k,j,i) + p(k+1,j,i) ) * flag
 
                 ENDDO
@@ -1164,14 +1440,17 @@
           DO  i = nxl, nxr
              DO  j = nys, nyn
-                DO  k = nzb_s_inner(j,i)+1, nzt
+                DO  k = nzb+1, nzt
+
+                   flag = MERGE( 1.0_wp, 0.0_wp, BTEST( wall_flags_0(k,j,i), 0 ) )
 
                    sums_l(k,57,tn) = sums_l(k,57,tn) - 0.5_wp * (              &
                    (km(k,j,i)+km(k+1,j,i)) * (e(k+1,j,i)-e(k,j,i)) * ddzu(k+1) &
                  - (km(k-1,j,i)+km(k,j,i)) * (e(k,j,i)-e(k-1,j,i)) * ddzu(k)   &
-                                                                ) * ddzw(k)
+                                                                ) * ddzw(k)    &
+                                                                  * flag
 
                    sums_l(k,69,tn) = sums_l(k,69,tn) - 0.5_wp * (              &
                    (km(k,j,i)+km(k+1,j,i)) * (e(k+1,j,i)-e(k,j,i)) * ddzu(k+1) &
-                                                                )
+                                                                )  * flag
 
                 ENDDO
@@ -1191,5 +1470,6 @@
           DO  i = nxl, nxr
              DO  j = nys, nyn
-                DO  k = nzb_s_inner(j,i)+1, nzt
+                DO  k = nzb+1, nzt
+                   flag = MERGE( 1.0_wp, 0.0_wp, BTEST( wall_flags_0(k,j,i), 0 ) )
 !
 !--                Subgrid horizontal heat fluxes u"pt", v"pt"
@@ -1199,5 +1479,5 @@
                                                * rho_air_zw(k)                 &
                                                * heatflux_output_conversion(k) &
-                                                 * ddx * rmask(j,i,sr)
+                                                 * ddx * rmask(j,i,sr) * flag
                    sums_l(k,61,tn) = sums_l(k,61,tn) - 0.5_wp *                &
                                                    ( kh(k,j,i) + kh(k,j-1,i) ) &
@@ -1205,5 +1485,5 @@
                                                * rho_air_zw(k)                 &
                                                * heatflux_output_conversion(k) &
-                                                 * ddy * rmask(j,i,sr)
+                                                 * ddy * rmask(j,i,sr) * flag
 !
 !--                Resolved horizontal heat fluxes u*pt*, v*pt*
@@ -1212,5 +1492,6 @@
                                     * 0.5_wp * ( pt(k,j,i-1) - hom(k,1,4,sr) + &
                                                  pt(k,j,i)   - hom(k,1,4,sr) ) &
-                                               * heatflux_output_conversion(k)
+                                               * heatflux_output_conversion(k) &
+                                               * flag
                    pts = 0.5_wp * ( pt(k,j-1,i) - hom(k,1,4,sr) +              &
                                     pt(k,j,i)   - hom(k,1,4,sr) )
@@ -1219,5 +1500,6 @@
                                     * 0.5_wp * ( pt(k,j-1,i) - hom(k,1,4,sr) + &
                                                  pt(k,j,i)   - hom(k,1,4,sr) ) &
-                                               * heatflux_output_conversion(k)
+                                               * heatflux_output_conversion(k) &
+                                               * flag
                 ENDDO
              ENDDO
@@ -1279,41 +1561,30 @@
        ENDIF
 
+       tn = 0
        !$OMP PARALLEL PRIVATE( i, j, k, tn )
-!$     tn = omp_get_thread_num()
-       IF ( land_surface )  THEN
-          !$OMP DO
-          DO  i = nxl, nxr
-             DO  j =  nys, nyn
-                DO  k = nzb_soil, nzt_soil
-                   sums_l(k,89,tn)  = sums_l(k,89,tn)  + t_soil(k,j,i)         &
-                                      * rmask(j,i,sr)
-                   sums_l(k,91,tn)  = sums_l(k,91,tn)  + m_soil(k,j,i)         &
-                                      * rmask(j,i,sr)
-                ENDDO
-             ENDDO
-          ENDDO
-       ENDIF
-       
+       !$ tn = omp_get_thread_num()       
        IF ( radiation .AND. radiation_scheme == 'rrtmg' )  THEN
           !$OMP DO
           DO  i = nxl, nxr
              DO  j =  nys, nyn
-                DO  k = nzb_s_inner(j,i)+1, nzt+1
+                DO  k = nzb+1, nzt+1
+                   flag = MERGE( 1.0_wp, 0.0_wp, BTEST( wall_flags_0(k,j,i), 0 ) )
+
                    sums_l(k,102,tn)  = sums_l(k,102,tn)  + rad_lw_in(k,j,i)    &
-                                       * rmask(j,i,sr)
+                                       * rmask(j,i,sr) * flag
                    sums_l(k,103,tn)  = sums_l(k,103,tn)  + rad_lw_out(k,j,i)   &
-                                       * rmask(j,i,sr)
+                                       * rmask(j,i,sr) * flag
                    sums_l(k,104,tn)  = sums_l(k,104,tn)  + rad_sw_in(k,j,i)    &
-                                       * rmask(j,i,sr)
+                                       * rmask(j,i,sr) * flag
                    sums_l(k,105,tn)  = sums_l(k,105,tn)  + rad_sw_out(k,j,i)   &
-                                       * rmask(j,i,sr)
+                                       * rmask(j,i,sr) * flag
                    sums_l(k,106,tn)  = sums_l(k,106,tn)  + rad_lw_cs_hr(k,j,i) &
-                                       * rmask(j,i,sr)
+                                       * rmask(j,i,sr) * flag
                    sums_l(k,107,tn)  = sums_l(k,107,tn)  + rad_lw_hr(k,j,i)    &
-                                       * rmask(j,i,sr)
+                                       * rmask(j,i,sr) * flag
                    sums_l(k,108,tn)  = sums_l(k,108,tn)  + rad_sw_cs_hr(k,j,i) &
-                                       * rmask(j,i,sr)
+                                       * rmask(j,i,sr) * flag
                    sums_l(k,109,tn)  = sums_l(k,109,tn)  + rad_sw_hr(k,j,i)    &
-                                       * rmask(j,i,sr)
+                                       * rmask(j,i,sr) * flag
                 ENDDO
              ENDDO
Index: /palm/trunk/SOURCE/header.f90
===================================================================
--- /palm/trunk/SOURCE/header.f90	(revision 2231)
+++ /palm/trunk/SOURCE/header.f90	(revision 2232)
@@ -20,5 +20,6 @@
 ! Current revisions:
 ! -----------------
-! 
+! Adjustments to new topography and surface concept
+! Generic tunnel setup added
 ! 
 ! Former revisions:
@@ -293,6 +294,5 @@
 
     USE arrays_3d,                                                             &
-        ONLY:  pt_init, qsws, q_init, s_init, sa_init, shf, ug, vg, w_subs, zu,&
-               zw
+        ONLY:  pt_init, q_init, s_init, sa_init, ug, vg, w_subs, zu, zw
         
     USE control_parameters
@@ -320,5 +320,5 @@
  
     USE land_surface_model_mod,                                                &
-        ONLY: land_surface, lsm_header
+        ONLY: lsm_header
 
     USE microphysics_mod,                                                      &
@@ -362,4 +362,7 @@
     USE spectra_mod,                                                           &
         ONLY:  calculate_spectra, spectra_header
+
+    USE surface_mod,                                                           &
+        ONLY:  surf_def_h
 
     IMPLICIT NONE
@@ -933,4 +936,30 @@
           ENDIF
 
+       CASE ( 'tunnel' )
+          IF ( tunnel_width_x /= 9999999.9_wp )  THEN
+!
+!--          Tunnel axis in y direction
+             IF ( tunnel_length == 9999999.9_wp  .OR.                          &
+                  tunnel_length >= ( nx + 1 ) * dx )  THEN
+                WRITE ( io, 273 )  'y', tunnel_height, tunnel_wall_depth,      &
+                                        tunnel_width_x
+             ELSE
+                WRITE ( io, 274 )  'y', tunnel_height, tunnel_wall_depth,      &
+                                        tunnel_width_x, tunnel_length
+             ENDIF
+
+          ELSEIF ( tunnel_width_y /= 9999999.9_wp )  THEN
+!
+!--          Tunnel axis in x direction
+             IF ( tunnel_length == 9999999.9_wp  .OR.                          &
+                  tunnel_length >= ( ny + 1 ) * dy )  THEN
+                WRITE ( io, 273 )  'x', tunnel_height, tunnel_wall_depth,      &
+                                        tunnel_width_y
+             ELSE
+                WRITE ( io, 274 )  'x', tunnel_height, tunnel_wall_depth,      &
+                                        tunnel_width_y, tunnel_length
+             ENDIF
+          ENDIF
+
     END SELECT
 
@@ -1065,5 +1094,5 @@
        IF ( constant_heatflux )  THEN
           IF ( large_scale_forcing .AND. lsf_surf )  THEN
-             WRITE ( io, 306 )  shf(0,0)
+             IF ( surf_def_h(0)%ns >= 1 )  WRITE ( io, 306 )  surf_def_h(0)%shf(1)
           ELSE
              WRITE ( io, 306 )  surface_heatflux
@@ -1073,5 +1102,5 @@
        IF ( humidity  .AND.  constant_waterflux )  THEN
           IF ( large_scale_forcing .AND. lsf_surf )  THEN
-             WRITE ( io, 311 ) qsws(0,0)
+             WRITE ( io, 311 ) surf_def_h(0)%qsws(1)
           ELSE
              WRITE ( io, 311 ) surface_waterflux
@@ -2024,4 +2053,14 @@
               ' Canyon height: ', F6.2, 'm, ch = ', I4, '.'      / &
               ' Canyon position (',A,'-walls): cxl = ', I4,', cxr = ', I4, '.')
+273 FORMAT (  ' Tunnel of infinite length in ',A, &
+              ' direction' / &
+              ' Tunnel height: ', F6.2, / &
+              ' Tunnel-wall depth: ', F6.2      / &
+              ' Tunnel width: ', F6.2 )
+274 FORMAT (  ' Tunnel in ', A, ' direction.' / &
+              ' Tunnel height: ', F6.2, / &    
+              ' Tunnel-wall depth: ', F6.2      / &
+              ' Tunnel width: ', F6.2, / &
+              ' Tunnel length: ', F6.2 )
 278 FORMAT (' Topography grid definition convention:'/ &
             ' cell edge (staggered grid points'/  &
Index: /palm/trunk/SOURCE/init_3d_model.f90
===================================================================
--- /palm/trunk/SOURCE/init_3d_model.f90	(revision 2231)
+++ /palm/trunk/SOURCE/init_3d_model.f90	(revision 2232)
@@ -20,5 +20,9 @@
 ! Current revisions:
 ! ------------------
-! 
+! Adjustments to new topography and surface concept: 
+!   - Modify passed parameters for disturb_field
+!   - Topography representation via flags
+!   - Remove unused arrays. 
+!   - Move initialization of surface-related quantities to surface_mod
 ! 
 ! Former revisions:
@@ -346,5 +350,5 @@
 
     USE land_surface_model_mod,                                                &
-        ONLY:  lsm_init, lsm_init_arrays, land_surface
+        ONLY:  lsm_init, lsm_init_arrays
   
     USE ls_forcing_mod
@@ -383,4 +387,8 @@
     USE surface_layer_fluxes_mod,                                              &
         ONLY:  init_surface_layer_fluxes
+
+    USE surface_mod,                                                           &
+        ONLY :  init_surface_arrays, init_surfaces, surf_def_h, surf_lsm_h,    &
+                surf_usm_h
    
     USE transpose_indices
@@ -398,5 +406,7 @@
     INTEGER(iwp) ::  j             !<
     INTEGER(iwp) ::  k             !<
-    INTEGER(iwp) ::  sr            !<
+    INTEGER(iwp) ::  k_surf        !< surface level index
+    INTEGER(iwp) ::  m             !< index of surface element in surface data type
+    INTEGER(iwp) ::  sr            !< index of statistic region
 
     INTEGER(iwp), DIMENSION(:), ALLOCATABLE   ::  ngp_2dh_l  !<
@@ -447,11 +457,4 @@
               ts_value(dots_max,0:statistic_regions) )
     ALLOCATE( ptdf_x(nxlg:nxrg), ptdf_y(nysg:nyng) )
-
-    ALLOCATE( ol(nysg:nyng,nxlg:nxrg), shf(nysg:nyng,nxlg:nxrg),               &
-              ts(nysg:nyng,nxlg:nxrg), tswst(nysg:nyng,nxlg:nxrg),             &
-              us(nysg:nyng,nxlg:nxrg), usws(nysg:nyng,nxlg:nxrg),              &
-              uswst(nysg:nyng,nxlg:nxrg), vsws(nysg:nyng,nxlg:nxrg),           &
-              vswst(nysg:nyng,nxlg:nxrg), z0(nysg:nyng,nxlg:nxrg),             &
-              z0h(nysg:nyng,nxlg:nxrg), z0q(nysg:nyng,nxlg:nxrg) )
 
     ALLOCATE( d(nzb+1:nzt,nys:nyn,nxl:nxr),                                    &
@@ -519,10 +522,4 @@
     IF ( humidity )  THEN
 !
-!--    2D-humidity
-       ALLOCATE ( qs(nysg:nyng,nxlg:nxrg),                                     &
-                  qsws(nysg:nyng,nxlg:nxrg),                                   &
-                  qswst(nysg:nyng,nxlg:nxrg) )
-
-!
 !--    3D-humidity
 #if defined( __nopointer )
@@ -571,12 +568,4 @@
 
              IF ( microphysics_seifert )  THEN
-!
-!--             2D-rain water content and rain drop concentration arrays
-                ALLOCATE ( qrs(nysg:nyng,nxlg:nxrg),                        &
-                           qrsws(nysg:nyng,nxlg:nxrg),                      &
-                           qrswst(nysg:nyng,nxlg:nxrg),                     &
-                           nrs(nysg:nyng,nxlg:nxrg),                        &
-                           nrsws(nysg:nyng,nxlg:nxrg),                      &
-                           nrswst(nysg:nyng,nxlg:nxrg) )
 !
 !--             3D-rain water content, rain drop concentration arrays
@@ -622,9 +611,4 @@
     
     IF ( passive_scalar )  THEN
-!
-!--    2D-scalar arrays
-       ALLOCATE ( ss(nysg:nyng,nxlg:nxrg),                                     &
-                  ssws(nysg:nyng,nxlg:nxrg),                                   &
-                  sswst(nysg:nyng,nxlg:nxrg) )
 
 !
@@ -642,6 +626,4 @@
 
     IF ( ocean )  THEN
-       ALLOCATE( saswsb(nysg:nyng,nxlg:nxrg),                                  &
-                 saswst(nysg:nyng,nxlg:nxrg) )
 #if defined( __nopointer )
        ALLOCATE( prho(nzb:nzt+1,nysg:nyng,nxlg:nxrg),                          &
@@ -660,8 +642,4 @@
                       ! density to be apointer
 #endif
-       IF ( humidity_remote )  THEN
-          ALLOCATE( qswst_remote(nysg:nyng,nxlg:nxrg))
-          qswst_remote = 0.0_wp
-       ENDIF
     ENDIF
 
@@ -818,11 +796,4 @@
 
 !
-!-- 4D-array for storing the Rif-values at vertical walls
-    IF ( topography /= 'flat' )  THEN
-       ALLOCATE( rif_wall(nzb:nzt+1,nysg:nyng,nxlg:nxrg,1:4) )
-       rif_wall = 0.0_wp
-    ENDIF
-
-!
 !-- Arrays to store velocity data from t-dt and the phase speeds which
 !-- are needed for radiation boundary conditions
@@ -901,5 +872,7 @@
     ENDIF
 #endif
-
+!
+!-- Initialize wall arrays
+    CALL init_surface_arrays
 !
 !-- Allocate land surface model arrays
@@ -944,5 +917,4 @@
     sums_up_fraction_l = 0.0_wp
     sums_wsts_bc_l     = 0.0_wp
-
 
 !
@@ -1007,45 +979,7 @@
              hom(:,1,25,:) = SPREAD( l1d, 2, statistic_regions+1 )
 
-             IF ( constant_flux_layer )  THEN
-                ol   = ( zu(nzb+1) - zw(nzb) ) / ( rif1d(nzb+1) + 1.0E-20_wp )
-                ts   = 0.0_wp  ! could actually be computed more accurately in the
-                               ! 1D model. Update when opportunity arises.
-                us   = us1d
-                usws = usws1d
-                vsws = vsws1d
-             ELSE
-                ts   = 0.0_wp  ! must be set, because used in
-                ol   = ( zu(nzb+1) - zw(nzb) ) / zeta_min  ! flowste
-                us   = 0.0_wp
-                usws = 0.0_wp
-                vsws = 0.0_wp
-             ENDIF
-
           ELSE
              e    = 0.0_wp  ! must be set, because used in
-             ol   = ( zu(nzb+1) - zw(nzb) ) / zeta_min  ! flowste
-             ts   = 0.0_wp
-             us   = 0.0_wp
-             usws = 0.0_wp
-             vsws = 0.0_wp
-          ENDIF
-          uswst = top_momentumflux_u * momentumflux_input_conversion(nzt+1)
-          vswst = top_momentumflux_v * momentumflux_input_conversion(nzt+1)
-
-!
-!--       In every case qs = 0.0 (see also pt)
-!--       This could actually be computed more accurately in the 1D model.
-!--       Update when opportunity arises!
-          IF ( humidity )  THEN
-             qs = 0.0_wp
-             IF ( cloud_physics  .AND.  microphysics_seifert )  THEN
-                qrs = 0.0_wp
-                nrs = 0.0_wp
-             ENDIF
-          ENDIF
-!
-!--       Initialize scaling parameter for passive scalar
-          IF ( passive_scalar ) ss = 0.0_wp          
-
+          ENDIF
 !
 !--       Inside buildings set velocities back to zero
@@ -1053,6 +987,10 @@
              DO  i = nxlg, nxrg
                 DO  j = nysg, nyng
-                   u(nzb:nzb_u_inner(j,i),j,i) = 0.0_wp
-                   v(nzb:nzb_v_inner(j,i),j,i) = 0.0_wp
+                   DO  k = nzb, nzt
+                      u(k,j,i) = MERGE( u(k,j,i), 0.0_wp,                      &
+                                        BTEST( wall_flags_0(k,j,i), 1 ) )
+                      v(k,j,i) = MERGE( v(k,j,i), 0.0_wp,                      &
+                                        BTEST( wall_flags_0(k,j,i), 2 ) )
+                   ENDDO
                 ENDDO
              ENDDO
@@ -1070,6 +1008,6 @@
                 DO  i = nxl-1, nxr+1
                    DO  j = nys-1, nyn+1
-                      IF ( nzb_u_inner(j,i) == 0 ) u(0,j,i) = u(1,j,i)
-                      IF ( nzb_v_inner(j,i) == 0 ) v(0,j,i) = v(1,j,i)
+                      u(nzb,j,i) = u(nzb+1,j,i)
+                      v(nzb,j,i) = v(nzb+1,j,i)
                    ENDDO
                 ENDDO
@@ -1119,6 +1057,10 @@
              DO  i = nxlg, nxrg
                 DO  j = nysg, nyng
-                   u(nzb:nzb_u_inner(j,i)+1,j,i) = 0.0_wp
-                   v(nzb:nzb_v_inner(j,i)+1,j,i) = 0.0_wp
+                   DO  k = nzb, nzt
+                      u(k,j,i) = MERGE( u(k,j,i), 0.0_wp,                      &
+                                        BTEST( wall_flags_0(k,j,i), 20 ) )
+                      v(k,j,i) = MERGE( v(k,j,i), 0.0_wp,                      &
+                                        BTEST( wall_flags_0(k,j,i), 21 ) )
+                   ENDDO
                 ENDDO
              ENDDO
@@ -1183,17 +1125,4 @@
              e    = 0.0_wp
           ENDIF
-          ol    = ( zu(nzb+1) - zw(nzb) ) / zeta_min
-          ts    = 0.0_wp
-!
-!--       Very small number is required for calculation of Obukhov length 
-!--       at first timestep     
-          us    = 1E-30_wp 
-          usws  = 0.0_wp
-          uswst = top_momentumflux_u * momentumflux_input_conversion(nzt+1)
-          vsws  = 0.0_wp
-          vswst = top_momentumflux_v * momentumflux_input_conversion(nzt+1)
-          IF ( humidity )       qs = 0.0_wp
-          IF ( passive_scalar ) ss = 0.0_wp
-
 !
 !--       Compute initial temperature field and other constants used in case
@@ -1282,149 +1211,4 @@
           CALL init_parallel_random_generator(nx, ny, nys, nyn, nxl, nxr)
        ENDIF
-
-!
-!--    Initialize fluxes at bottom surface
-       IF ( use_surface_fluxes )  THEN
-
-          IF ( constant_heatflux )  THEN
-!
-!--          Heat flux is prescribed
-             IF ( random_heatflux )  THEN
-                CALL disturb_heatflux
-             ELSE
-                shf = surface_heatflux * heatflux_input_conversion(nzb)
-!
-!--             Initialize shf with data from external file LSF_DATA
-                IF ( large_scale_forcing .AND. lsf_surf )  THEN
-                   CALL ls_forcing_surf ( simulated_time )
-                ENDIF
-
-!
-!--             Over topography surface_heatflux is replaced by wall_heatflux(0)
-                IF ( TRIM( topography ) /= 'flat' )  THEN
-                   DO  i = nxlg, nxrg
-                      DO  j = nysg, nyng
-                         IF ( nzb_s_inner(j,i) /= 0 )  THEN
-                            shf(j,i) = wall_heatflux(0)                        &
-                                  * heatflux_input_conversion(nzb_s_inner(j,i))
-                         ENDIF
-                      ENDDO
-                   ENDDO
-                ENDIF
-             ENDIF
-          ENDIF
-
-!
-!--       Determine the near-surface water flux
-          IF ( humidity )  THEN
-             IF ( cloud_physics  .AND.  microphysics_seifert )  THEN
-                qrsws = 0.0_wp
-                nrsws = 0.0_wp
-             ENDIF
-             IF ( constant_waterflux )  THEN
-                qsws   = surface_waterflux * waterflux_input_conversion(nzb)
-!
-!--             Over topography surface_waterflux is replaced by 
-!--             wall_humidityflux(0)
-                IF ( TRIM( topography ) /= 'flat' )  THEN
-                   wall_qflux = wall_humidityflux
-                   DO  i = nxlg, nxrg
-                      DO  j = nysg, nyng
-                         IF ( nzb_s_inner(j,i) /= 0 )  THEN
-                            qsws(j,i) = wall_qflux(0)                          &
-                                 * waterflux_input_conversion(nzb_s_inner(j,i))
-                         ENDIF
-                      ENDDO
-                   ENDDO
-                ENDIF
-             ENDIF
-          ENDIF
-!
-!--       Initialize the near-surface scalar flux
-          IF ( passive_scalar )  THEN
-             IF ( constant_scalarflux )  THEN
-                ssws   = surface_scalarflux
-!
-!--             Over topography surface_scalarflux is replaced by 
-!--             wall_scalarflux(0)
-                IF ( TRIM( topography ) /= 'flat' )  THEN
-                   wall_sflux = wall_scalarflux
-                   DO  i = nxlg, nxrg
-                      DO  j = nysg, nyng
-                         IF ( nzb_s_inner(j,i) /= 0 )  ssws(j,i) = wall_sflux(0)
-                      ENDDO
-                   ENDDO
-                ENDIF
-             ENDIF
-          ENDIF    
-!
-!--       Initialize near-surface salinity flux
-          IF ( ocean )  saswsb = bottom_salinityflux
-
-       ENDIF
-
-!
-!--    Initialize fluxes at top surface
-!--    Currently, only the heatflux and salinity flux can be prescribed.
-!--    The latent flux is zero in this case!
-       IF ( use_top_fluxes )  THEN
-!
-!--       Prescribe to heat flux
-          IF ( constant_top_heatflux )  tswst = top_heatflux                   &
-                                             * heatflux_input_conversion(nzt+1)
-!
-!--       Prescribe zero latent flux at the top      
-          IF ( humidity )  THEN
-             qswst = 0.0_wp
-             IF ( cloud_physics  .AND.  microphysics_seifert ) THEN
-                nrswst = 0.0_wp
-                qrswst = 0.0_wp
-             ENDIF
-          ENDIF
-!
-!--       Prescribe top scalar flux
-          IF ( passive_scalar .AND. constant_top_scalarflux )                  &
-             sswst = top_scalarflux
-!
-!--       Prescribe top salinity flux
-          IF ( ocean .AND. constant_top_salinityflux)                          &
-             saswst = top_salinityflux
-!
-!--       Initialization in case of a coupled model run
-          IF ( coupling_mode == 'ocean_to_atmosphere' )  THEN
-             tswst = 0.0_wp
-          ENDIF
-
-       ENDIF
-
-!
-!--    Initialize Prandtl layer quantities
-       IF ( constant_flux_layer )  THEN
-
-          z0 = roughness_length
-          z0h = z0h_factor * z0
-          z0q = z0h_factor * z0
-
-          IF ( .NOT. constant_heatflux )  THEN 
-!
-!--          Surface temperature is prescribed. Here the heat flux cannot be
-!--          simply estimated, because therefore ol, u* and theta* would have
-!--          to be computed by iteration. This is why the heat flux is assumed
-!--          to be zero before the first time step. It approaches its correct
-!--          value in the course of the first few time steps.
-             shf   = 0.0_wp
-          ENDIF
-
-          IF ( humidity  )  THEN
-             IF (  .NOT.  constant_waterflux )  qsws   = 0.0_wp
-             IF ( cloud_physics  .AND.  microphysics_seifert )  THEN
-                qrsws = 0.0_wp
-                nrsws = 0.0_wp
-             ENDIF
-          ENDIF
-          IF ( passive_scalar  .AND.  .NOT.  constant_scalarflux )  ssws = 0.0_wp
-
-       ENDIF
-
 !
 !--    Set the reference state to be used in the buoyancy terms (for ocean runs
@@ -1522,9 +1306,16 @@
 
     ELSEIF ( TRIM( initializing_actions ) == 'read_restart_data'  .OR.         &
-         TRIM( initializing_actions ) == 'cyclic_fill' )                       &
+             TRIM( initializing_actions ) == 'cyclic_fill' )                   &
     THEN
 
        CALL location_message( 'initializing in case of restart / cyclic_fill', &
                               .FALSE. )
+!
+!--    Initialize surface elements and its attributes, e.g. heat- and 
+!--    momentumfluxes, roughness, scaling parameters. As number of surface 
+!--    elements might be different between runs, e.g. in case of cyclic fill, 
+!--    and not all surface elements are read, surface elements need to be 
+!--    initialized before.     
+       CALL init_surfaces
 !
 !--    When reading data for cyclic fill of 3D prerun data files, read
@@ -1671,13 +1462,24 @@
           DO  i = nxlg, nxrg
              DO  j = nysg, nyng
-                u  (nzb:nzb_u_inner(j,i),j,i)   = 0.0_wp
-                v  (nzb:nzb_v_inner(j,i),j,i)   = 0.0_wp
-                w  (nzb:nzb_w_inner(j,i),j,i)   = 0.0_wp
-                e  (nzb:nzb_w_inner(j,i),j,i)   = 0.0_wp
-                tu_m(nzb:nzb_u_inner(j,i),j,i)  = 0.0_wp
-                tv_m(nzb:nzb_v_inner(j,i),j,i)  = 0.0_wp
-                tw_m(nzb:nzb_w_inner(j,i),j,i)  = 0.0_wp
-                te_m(nzb:nzb_w_inner(j,i),j,i)  = 0.0_wp
-                tpt_m(nzb:nzb_w_inner(j,i),j,i) = 0.0_wp
+                DO  k = nzb, nzt
+                   u(k,j,i)     = MERGE( u(k,j,i), 0.0_wp,                     &
+                                         BTEST( wall_flags_0(k,j,i), 1 ) )
+                   v(k,j,i)     = MERGE( v(k,j,i), 0.0_wp,                     &
+                                         BTEST( wall_flags_0(k,j,i), 2 ) )
+                   w(k,j,i)     = MERGE( w(k,j,i), 0.0_wp,                     &
+                                         BTEST( wall_flags_0(k,j,i), 3 ) )
+                   e(k,j,i)     = MERGE( e(k,j,i), 0.0_wp,                     &
+                                         BTEST( wall_flags_0(k,j,i), 0 ) )
+                   tu_m(k,j,i)  = MERGE( tu_m(k,j,i), 0.0_wp,                  &
+                                         BTEST( wall_flags_0(k,j,i), 1 ) )
+                   tv_m(k,j,i)  = MERGE( tv_m(k,j,i), 0.0_wp,                  &
+                                         BTEST( wall_flags_0(k,j,i), 2 ) )
+                   tw_m(k,j,i)  = MERGE( tw_m(k,j,i), 0.0_wp,                  &
+                                         BTEST( wall_flags_0(k,j,i), 3 ) )
+                   te_m(k,j,i)  = MERGE( te_m(k,j,i), 0.0_wp,                  &
+                                         BTEST( wall_flags_0(k,j,i), 0 ) )
+                   tpt_m(k,j,i) = MERGE( tpt_m(k,j,i), 0.0_wp,                 &
+                                         BTEST( wall_flags_0(k,j,i), 0 ) )
+                ENDDO
              ENDDO
           ENDDO
@@ -1766,8 +1568,15 @@
           IF ( nxr == nx )  THEN
              DO  j = nys, nyn
-                DO  k = nzb_u_inner(j,nx)+1, nzt
+                DO  k = nzb+1, nzt
                    volume_flow_initial_l(1) = volume_flow_initial_l(1) +       &
-                                              u_init(k) * dzw(k)
-                   volume_flow_area_l(1)    = volume_flow_area_l(1) + dzw(k)
+                                              u_init(k) * dzw(k)               &
+                                     * MERGE( 1.0_wp, 0.0_wp,                  &
+                                              BTEST( wall_flags_0(k,j,nxr), 1 )&
+                                            )
+
+                   volume_flow_area_l(1)    = volume_flow_area_l(1) + dzw(k)   &
+                                     * MERGE( 1.0_wp, 0.0_wp,                  &
+                                              BTEST( wall_flags_0(k,j,nxr), 1 )&
+                                            )
                 ENDDO
              ENDDO
@@ -1776,8 +1585,14 @@
           IF ( nyn == ny )  THEN
              DO  i = nxl, nxr
-                DO  k = nzb_v_inner(ny,i)+1, nzt
-                   volume_flow_initial_l(2) = volume_flow_initial_l(2) + &
-                                              v_init(k) * dzw(k)
-                   volume_flow_area_l(2)    = volume_flow_area_l(2) + dzw(k)
+                DO  k = nzb+1, nzt
+                   volume_flow_initial_l(2) = volume_flow_initial_l(2) +       &
+                                              v_init(k) * dzw(k)               &        
+                                     * MERGE( 1.0_wp, 0.0_wp,                  &
+                                              BTEST( wall_flags_0(k,nyn,i), 2 )&
+                                            )
+                   volume_flow_area_l(2)    = volume_flow_area_l(2) + dzw(k)   &        
+                                     * MERGE( 1.0_wp, 0.0_wp,                  &
+                                              BTEST( wall_flags_0(k,nyn,i), 2 )&
+                                            )
                 ENDDO
              ENDDO
@@ -1802,8 +1617,14 @@
           IF ( nxr == nx )  THEN
              DO  j = nys, nyn
-                DO  k = nzb_u_inner(j,nx)+1, nzt
+                DO  k = nzb+1, nzt
                    volume_flow_initial_l(1) = volume_flow_initial_l(1) +       &
-                                              hom_sum(k,1,0) * dzw(k)
-                   volume_flow_area_l(1)    = volume_flow_area_l(1) + dzw(k)
+                                              hom_sum(k,1,0) * dzw(k)          &
+                                     * MERGE( 1.0_wp, 0.0_wp,                  &
+                                              BTEST( wall_flags_0(k,j,nx), 1 ) &
+                                            )
+                   volume_flow_area_l(1)    = volume_flow_area_l(1) + dzw(k)   &
+                                     * MERGE( 1.0_wp, 0.0_wp,                  &
+                                              BTEST( wall_flags_0(k,j,nx), 1 ) &
+                                            )
                 ENDDO
              ENDDO
@@ -1812,8 +1633,14 @@
           IF ( nyn == ny )  THEN
              DO  i = nxl, nxr
-                DO  k = nzb_v_inner(ny,i)+1, nzt
+                DO  k = nzb+1, nzt
                    volume_flow_initial_l(2) = volume_flow_initial_l(2) +       &
-                                              hom_sum(k,2,0) * dzw(k)
-                   volume_flow_area_l(2)    = volume_flow_area_l(2) + dzw(k)
+                                              hom_sum(k,2,0) * dzw(k)          &        
+                                     * MERGE( 1.0_wp, 0.0_wp,                  &
+                                              BTEST( wall_flags_0(k,ny,i), 2 ) &
+                                            )
+                   volume_flow_area_l(2)    = volume_flow_area_l(2) + dzw(k)   &        
+                                     * MERGE( 1.0_wp, 0.0_wp,                  &
+                                              BTEST( wall_flags_0(k,ny,i), 2 ) &
+                                            )
                 ENDDO
              ENDDO
@@ -1838,8 +1665,14 @@
           IF ( nxr == nx )  THEN
              DO  j = nys, nyn
-                DO  k = nzb_u_inner(j,nx)+1, nzt
-                   volume_flow_initial_l(1) = volume_flow_initial_l(1) + &
-                                              u(k,j,nx) * dzw(k)
-                   volume_flow_area_l(1)    = volume_flow_area_l(1) + dzw(k)
+                DO  k = nzb+1, nzt
+                   volume_flow_initial_l(1) = volume_flow_initial_l(1) +       &
+                                              u(k,j,nx) * dzw(k)               &
+                                     * MERGE( 1.0_wp, 0.0_wp,                  &
+                                              BTEST( wall_flags_0(k,j,nx), 1 ) &
+                                            )
+                   volume_flow_area_l(1)    = volume_flow_area_l(1) + dzw(k)   &
+                                     * MERGE( 1.0_wp, 0.0_wp,                  &
+                                              BTEST( wall_flags_0(k,j,nx), 1 ) &
+                                            )
                 ENDDO
              ENDDO
@@ -1848,8 +1681,14 @@
           IF ( nyn == ny )  THEN
              DO  i = nxl, nxr
-                DO  k = nzb_v_inner(ny,i)+1, nzt
+                DO  k = nzb+1, nzt
                    volume_flow_initial_l(2) = volume_flow_initial_l(2) +       &
-                                              v(k,ny,i) * dzw(k)
-                   volume_flow_area_l(2)    = volume_flow_area_l(2) + dzw(k)
+                                              v(k,ny,i) * dzw(k)               &        
+                                     * MERGE( 1.0_wp, 0.0_wp,                  &
+                                              BTEST( wall_flags_0(k,ny,i), 2 ) &
+                                            )
+                   volume_flow_area_l(2)    = volume_flow_area_l(2) + dzw(k)   &        
+                                     * MERGE( 1.0_wp, 0.0_wp,                  &
+                                              BTEST( wall_flags_0(k,ny,i), 2 ) &
+                                            )
                 ENDDO
              ENDDO
@@ -1878,5 +1717,34 @@
 
     ENDIF
-
+!
+!-- Initialize surface elements and its attributes, e.g. heat- and 
+!-- momentumfluxes, roughness, scaling parameters. 
+!-- This is already done in case of restart data.  
+    IF ( TRIM( initializing_actions ) /= 'read_restart_data'  .AND.            &
+         TRIM( initializing_actions ) /= 'cyclic_fill' )  THEN
+       CALL init_surfaces
+!
+!--    Finally, if random_heatflux is set, disturb shf at horizontal
+!--    surfaces. Actually, this should be done in surface_mod, where all other 
+!--    initializations of surface quantities are done. However, this
+!--    would create a ring dependency, hence, it is done here. Maybe delete
+!--    disturb_heatflux and tranfer the respective code directly into the 
+!--    initialization in surface_mod.         
+       IF ( use_surface_fluxes  .AND.  constant_heatflux  .AND.                &
+            random_heatflux )  THEN
+          IF ( surf_def_h(0)%ns >= 1 )  CALL disturb_heatflux( surf_def_h(0) )
+          IF ( surf_lsm_h%ns    >= 1 )  CALL disturb_heatflux( surf_lsm_h    )
+          IF ( surf_usm_h%ns    >= 1 )  CALL disturb_heatflux( surf_usm_h    )
+       ENDIF
+    ENDIF
+
+!
+!-- Initialize surface forcing corresponding to large-scale forcing. Therein, 
+!-- initialize heat-fluxes, etc. via datatype. Revise it later!
+    IF ( large_scale_forcing .AND. lsf_surf )  THEN
+       IF ( use_surface_fluxes  .AND.  constant_heatflux )  THEN
+          CALL ls_forcing_surf ( simulated_time )
+       ENDIF
+    ENDIF
 !
 !-- Initialize quantities for special advections schemes
@@ -1891,6 +1759,6 @@
 
        CALL location_message( 'creating initial disturbances', .FALSE. )
-       CALL disturb_field( nzb_u_inner, tend, u )
-       CALL disturb_field( nzb_v_inner, tend, v )
+       CALL disturb_field( 'u', tend, u )
+       CALL disturb_field( 'v', tend, v )
        CALL location_message( 'finished', .TRUE. )
 
@@ -2148,4 +2016,6 @@
     mean_surface_level_height_l = 0.0_wp
 
+!
+!-- To do: New concept for these non-topography grid points!
     DO  sr = 0, statistic_regions
        DO  i = nxl, nxr
@@ -2155,18 +2025,48 @@
 !--             All xy-grid points
                 ngp_2dh_l(sr) = ngp_2dh_l(sr) + 1
-                mean_surface_level_height_l(sr) = mean_surface_level_height_l(sr) &
-                                                  + zw(nzb_s_inner(j,i))
-!
-!--             xy-grid points above topography
-                DO  k = nzb_s_outer(j,i), nz + 1
-                   ngp_2dh_outer_l(k,sr) = ngp_2dh_outer_l(k,sr) + 1
+!
+!--             Determine mean surface-level height. In case of downward-
+!--             facing walls are present, more than one surface level exist.
+!--             In this case, use the lowest surface-level height. 
+                IF ( surf_def_h(0)%start_index(j,i) <=                         &
+                     surf_def_h(0)%end_index(j,i) )  THEN
+                   m = surf_def_h(0)%start_index(j,i)
+                   k = surf_def_h(0)%k(m)
+                   mean_surface_level_height_l(sr) =                           &
+                                       mean_surface_level_height_l(sr) + zw(k-1)
+                ENDIF
+                IF ( surf_lsm_h%start_index(j,i) <=                            &
+                     surf_lsm_h%end_index(j,i) )  THEN
+                   m = surf_lsm_h%start_index(j,i)
+                   k = surf_lsm_h%k(m)
+                   mean_surface_level_height_l(sr) =                           &
+                                       mean_surface_level_height_l(sr) + zw(k-1)
+                ENDIF
+                IF ( surf_usm_h%start_index(j,i) <=                            &
+                     surf_usm_h%end_index(j,i) )  THEN
+                   m = surf_usm_h%start_index(j,i)
+                   k = surf_usm_h%k(m)
+                   mean_surface_level_height_l(sr) =                           &
+                                       mean_surface_level_height_l(sr) + zw(k-1)
+                ENDIF
+
+                k_surf = k - 1
+
+                DO  k = nzb, nzt+1
+!
+!--                xy-grid points above topography
+                   ngp_2dh_outer_l(k,sr) = ngp_2dh_outer_l(k,sr)     +         &
+                                  MERGE( 1, 0, BTEST( wall_flags_0(k,j,i), 24 ) )
+
+                   ngp_2dh_s_inner_l(k,sr) = ngp_2dh_s_inner_l(k,sr) +         &
+                                  MERGE( 1, 0, BTEST( wall_flags_0(k,j,i), 22 ) )
+
                 ENDDO
-                DO  k = nzb_s_inner(j,i), nz + 1
-                   ngp_2dh_s_inner_l(k,sr) = ngp_2dh_s_inner_l(k,sr) + 1
-                ENDDO
 !
 !--             All grid points of the total domain above topography
-                ngp_3d_inner_l(sr) = ngp_3d_inner_l(sr)                        &
-                                     + ( nz - nzb_s_inner(j,i) + 2 )
+                ngp_3d_inner_l(sr) = ngp_3d_inner_l(sr) + ( nz - k_surf + 2 )
+
+
+
              ENDIF
           ENDDO
Index: /palm/trunk/SOURCE/init_grid.f90
===================================================================
--- /palm/trunk/SOURCE/init_grid.f90	(revision 2231)
+++ /palm/trunk/SOURCE/init_grid.f90	(revision 2232)
@@ -20,5 +20,10 @@
 ! Current revisions:
 ! -----------------
-! 
+! - Adjustments according to new topography representation
+! - Bugfix: Move determination of nzb_max behind topography modification in 
+!   cell-edge case 
+! - Get rid off global arrays required for topography output
+! - Enable topography input via netcdf 
+! - Generic tunnel set-up added
 ! 
 ! Former revisions:
@@ -212,4 +217,7 @@
 ! ------------
 !> Creating grid depending constants
+!> To Do: Setting topo flags only based on topo_3d array - flags for former
+!> nzb_outer arrays are still not set properly. 
+!> To Do: Rearrange topo flag list
 !------------------------------------------------------------------------------!
  SUBROUTINE init_grid
@@ -230,24 +238,22 @@
                dz_stretch_level, dz_stretch_level_index, grid_level, ibc_uv_b, &
                io_blocks, io_group, inflow_l, inflow_n, inflow_r, inflow_s,    &
-               masking_method, maximum_grid_level, message_string,             &
+               lod, masking_method, maximum_grid_level, message_string,        &
                momentum_advec, nest_domain, nest_bound_l, nest_bound_n,        &
                nest_bound_r, nest_bound_s, ocean, outflow_l, outflow_n,        &
                outflow_r, outflow_s, psolver, scalar_advec, topography,        &
-               topography_grid_convention, use_surface_fluxes, use_top_fluxes, &
-               wall_adjustment_factor
+               topography_grid_convention, tunnel_height, tunnel_length,       &
+               tunnel_width_x, tunnel_width_y, tunnel_wall_depth,              &
+               use_surface_fluxes, use_top_fluxes, wall_adjustment_factor
          
     USE grid_variables,                                                        &
-        ONLY:  ddx, ddx2, ddy, ddy2, dx, dx2, dy, dy2, fwxm,                   &
-               fwxp, fwym, fwyp, fxm, fxp, fym, fyp, wall_e_x, wall_e_y,       &
-               wall_u, wall_v, wall_w_x, wall_w_y, zu_s_inner, zw_w_inner
+        ONLY:  ddx, ddx2, ddy, ddy2, dx, dx2, dy, dy2, zu_s_inner, zw_w_inner
         
     USE indices,                                                               &
-        ONLY:  flags, nbgp, nx, nxl, nxlg, nxl_mg, nxr, nxrg, nxr_mg,          &
-               ny, nyn, nyng, nyn_mg, nys, nys_mg, nysg, nz, nzb,              &
-               nzb_diff, nzb_diff_s_inner, nzb_diff_s_outer, nzb_diff_u,       &
-               nzb_diff_v, nzb_max, nzb_s_inner, nzb_s_outer, nzb_u_inner,     &
+        ONLY:  advc_flags_1, advc_flags_2, flags, nbgp, nx, nxl, nxlg, nxl_mg, &
+               nxr, nxrg, nxr_mg, ny, nyn, nyng, nyn_mg, nys, nys_mg, nysg, nz,&
+               nzb, nzb_diff, nzb_diff_s_inner, nzb_diff_s_outer,              &
+               nzb_max, nzb_s_inner, nzb_s_outer, nzb_u_inner,                 &
                nzb_u_outer, nzb_v_inner, nzb_v_outer, nzb_w_inner,             &
-               nzb_w_outer, nzt, nzt_diff, nzt_mg, rflags_invers,              &
-               rflags_s_inner, wall_flags_0, wall_flags_00, wall_flags_1,      &
+               nzb_w_outer, nzt, nzt_mg, wall_flags_0, wall_flags_1,           &
                wall_flags_10, wall_flags_2, wall_flags_3,  wall_flags_4,       &
                wall_flags_5, wall_flags_6, wall_flags_7, wall_flags_8,         &
@@ -255,6 +261,13 @@
     
     USE kinds
-    
+#if defined ( __netcdf )
+    USE netcdf_interface,                                                      &
+        ONLY:  netcdf_close_file, netcdf_open_read_file, netcdf_get_attribute, &
+               netcdf_get_variable
+#endif
     USE pegrid
+
+    USE surface_mod,                                                           &
+        ONLY:  init_bc
 
     IMPLICIT NONE
@@ -275,8 +288,10 @@
     INTEGER(iwp) ::  cys           !< index for south canyon wall
     INTEGER(iwp) ::  i             !< index variable along x
+    INTEGER(iwp) ::  id_topo       !< NetCDF id of topograhy input file
     INTEGER(iwp) ::  ii            !< loop variable for reading topography file
     INTEGER(iwp) ::  inc           !< incremental parameter for coarsening grid level
     INTEGER(iwp) ::  j             !< index variable along y
     INTEGER(iwp) ::  k             !< index variable along z
+    INTEGER(iwp) ::  k_top         !< topography top index on local PE
     INTEGER(iwp) ::  l             !< loop variable 
     INTEGER(iwp) ::  nxl_l         !< index of left PE boundary for multigrid level
@@ -286,5 +301,4 @@
     INTEGER(iwp) ::  nzb_local_max !< vertical grid index of maximum topography height
     INTEGER(iwp) ::  nzb_local_min !< vertical grid index of minimum topography height
-    INTEGER(iwp) ::  nzb_si        !< dummy index for local nzb_s_inner
     INTEGER(iwp) ::  nzt_l         !< index of top PE boundary for multigrid level
     INTEGER(iwp) ::  num_hole      !< number of holes (in topography) resolved by only one grid point 
@@ -292,28 +306,30 @@
     INTEGER(iwp) ::  num_wall      !< number of surrounding vertical walls for a single grid point
     INTEGER(iwp) ::  skip_n_rows   !< counting variable to skip rows while reading topography file    
-    INTEGER(iwp) ::  vi            !< dummy for vertical influence
-
-    INTEGER(iwp), DIMENSION(:), ALLOCATABLE   ::                               &
-                     vertical_influence  !< number of vertical grid points above obstacle where adjustment of near-wall mixing length is required
-                                         
-    INTEGER(iwp), DIMENSION(:,:), ALLOCATABLE ::  corner_nl      !< index of north-left corner location to limit near-wall mixing length
-    INTEGER(iwp), DIMENSION(:,:), ALLOCATABLE ::  corner_nr      !< north-right
-    INTEGER(iwp), DIMENSION(:,:), ALLOCATABLE ::  corner_sl      !< south-left
-    INTEGER(iwp), DIMENSION(:,:), ALLOCATABLE ::  corner_sr      !< south-right
+    INTEGER(iwp) ::  hv_in         !< heavyside function to model inner tunnel surface 
+    INTEGER(iwp) ::  hv_out        !< heavyside function to model outer tunnel surface 
+    INTEGER(iwp) ::  txe_out       !< end position of outer tunnel wall in x
+    INTEGER(iwp) ::  txs_out       !< start position of outer tunnel wall in x
+    INTEGER(iwp) ::  tye_out       !< end position of outer tunnel wall in y
+    INTEGER(iwp) ::  tys_out       !< start position of outer tunnel wall in y
+    INTEGER(iwp) ::  txe_in        !< end position of inner tunnel wall in x
+    INTEGER(iwp) ::  txs_in        !< start position of inner tunnel wall in x
+    INTEGER(iwp) ::  tye_in        !< end position of inner tunnel wall in y
+    INTEGER(iwp) ::  tys_in        !< start position of inner tunnel wall in y
+    INTEGER(iwp) ::  td            !< tunnel wall depth
+    INTEGER(iwp) ::  th            !< height of outer tunnel wall
+                                      
     INTEGER(iwp), DIMENSION(:,:), ALLOCATABLE ::  nzb_local      !< index for topography top at cell-center
     INTEGER(iwp), DIMENSION(:,:), ALLOCATABLE ::  nzb_tmp        !< dummy to calculate topography indices on u- and v-grid
-    INTEGER(iwp), DIMENSION(:,:), ALLOCATABLE ::  wall_l         !< distance to adjacent left-facing wall
-    INTEGER(iwp), DIMENSION(:,:), ALLOCATABLE ::  wall_n         !< north-facing
-    INTEGER(iwp), DIMENSION(:,:), ALLOCATABLE ::  wall_r         !< right-facing
-    INTEGER(iwp), DIMENSION(:,:), ALLOCATABLE ::  wall_s         !< right-facing
+
+    INTEGER(iwp), DIMENSION(:,:,:), ALLOCATABLE ::  topo_3d !< input array for 3D topography and dummy array for setting "outer"-flags
+
+    LOGICAL  ::  netcdf_extend = .FALSE. !< Flag indicating wether netcdf topography input file or not
 
     REAL(wp) ::  dum           !< dummy variable to skip columns while reading topography file    
     REAL(wp) ::  dz_stretched  !< stretched vertical grid spacing
 
+    REAL(wp), DIMENSION(:,:), ALLOCATABLE ::  oro_height    !< input variable for terrain height
     REAL(wp), DIMENSION(:,:), ALLOCATABLE ::  topo_height   !< input variable for topography height
-    REAL(wp), DIMENSION(:,:), ALLOCATABLE ::  zu_s_inner_l  !< dummy array on global scale to write topography output array
-    REAL(wp), DIMENSION(:,:), ALLOCATABLE ::  zw_w_inner_l  !< dummy array on global scale to write topography output array
-
-    
+
 !
 !-- Calculation of horizontal array bounds including ghost layers
@@ -464,16 +480,6 @@
 !
 !-- Allocate outer and inner index arrays for topography and set
-!-- defaults.
-
-    ALLOCATE( corner_nl(nys:nyn,nxl:nxr), corner_nr(nys:nyn,nxl:nxr),       &
-              corner_sl(nys:nyn,nxl:nxr), corner_sr(nys:nyn,nxl:nxr),       &
-              wall_l(nys:nyn,nxl:nxr), wall_n(nys:nyn,nxl:nxr),             &
-              wall_r(nys:nyn,nxl:nxr), wall_s(nys:nyn,nxl:nxr) )                     
-     
-    ALLOCATE( fwxm(nysg:nyng,nxlg:nxrg), fwxp(nysg:nyng,nxlg:nxrg),         &
-              fwym(nysg:nyng,nxlg:nxrg), fwyp(nysg:nyng,nxlg:nxrg),         &
-              fxm(nysg:nyng,nxlg:nxrg), fxp(nysg:nyng,nxlg:nxrg),           &
-              fym(nysg:nyng,nxlg:nxrg), fyp(nysg:nyng,nxlg:nxrg),           &
-              nzb_s_inner(nysg:nyng,nxlg:nxrg),                             &
+!-- defaults.                    
+    ALLOCATE( nzb_s_inner(nysg:nyng,nxlg:nxrg),                             &
               nzb_s_outer(nysg:nyng,nxlg:nxrg),                             &
               nzb_u_inner(nysg:nyng,nxlg:nxrg),                             &
@@ -485,21 +491,12 @@
               nzb_diff_s_inner(nysg:nyng,nxlg:nxrg),                        &
               nzb_diff_s_outer(nysg:nyng,nxlg:nxrg),                        &
-              nzb_diff_u(nysg:nyng,nxlg:nxrg),                              &
-              nzb_diff_v(nysg:nyng,nxlg:nxrg),                              &
               nzb_local(nysg:nyng,nxlg:nxrg),                               &
               nzb_tmp(nysg:nyng,nxlg:nxrg),                                 &
-              rflags_s_inner(nzb:nzt+2,nysg:nyng,nxlg:nxrg),                &
-              rflags_invers(nysg:nyng,nxlg:nxrg,nzb:nzt+2),                 &
-              wall_e_x(nysg:nyng,nxlg:nxrg),                                &
-              wall_e_y(nysg:nyng,nxlg:nxrg),                                &
-              wall_u(nysg:nyng,nxlg:nxrg),                                  &
-              wall_v(nysg:nyng,nxlg:nxrg),                                  &
-              wall_w_x(nysg:nyng,nxlg:nxrg),                                &
-              wall_w_y(nysg:nyng,nxlg:nxrg) )
-
-
+              wall_flags_0(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
+
+    ALLOCATE( topo_3d(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
+    topo_3d    = 0
 
     ALLOCATE( l_wall(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
-
 
     nzb_s_inner = nzb;  nzb_s_outer = nzb
@@ -507,7 +504,4 @@
     nzb_v_inner = nzb;  nzb_v_outer = nzb
     nzb_w_inner = nzb;  nzb_w_outer = nzb
-
-    rflags_s_inner = 1.0_wp
-    rflags_invers  = 1.0_wp
 
 !
@@ -519,17 +513,6 @@
        nzb_diff = nzb + 1
     ENDIF
-    IF ( use_top_fluxes )  THEN
-       nzt_diff = nzt - 1
-    ELSE
-       nzt_diff = nzt
-    ENDIF
 
     nzb_diff_s_inner = nzb_diff;  nzb_diff_s_outer = nzb_diff
-    nzb_diff_u = nzb_diff;  nzb_diff_v = nzb_diff
-
-    wall_e_x = 0.0_wp;  wall_e_y = 0.0_wp;  wall_u = 0.0_wp;  wall_v = 0.0_wp
-    wall_w_x = 0.0_wp;  wall_w_y = 0.0_wp
-    fwxp = 1.0_wp;  fwxm = 1.0_wp;  fwyp = 1.0_wp;  fwym = 1.0_wp
-    fxp  = 1.0_wp;  fxm  = 1.0_wp;  fyp  = 1.0_wp;  fym  = 1.0_wp
 
 !
@@ -542,10 +525,4 @@
     ENDDO
     l_wall(nzt+1,:,:) = l_grid(nzt)
-
-    ALLOCATE ( vertical_influence(nzb:nzt) )
-    DO  k = 1, nzt
-       vertical_influence(k) = MIN ( INT( l_grid(k) / &
-                     ( wall_adjustment_factor * dzw(k) ) + 0.5_wp ), nzt - k )
-    ENDDO
 
     DO  k = 1, nzt
@@ -561,10 +538,4 @@
        ENDIF
     ENDDO
-    vertical_influence(0) = vertical_influence(1)
-
-    DO  k = nzb + 1, nzb + vertical_influence(nzb)
-       l_wall(k,:,:) = zu(k) - zw(nzb)
-    ENDDO
-
 !
 !-- Set outer and inner index arrays for non-flat topography.
@@ -580,4 +551,10 @@
 !--       nzb_local is required for the multigrid solver
           nzb_local = 0
+!
+!--       Initialilize 3D topography array, used later for initializing flags
+          topo_3d(nzb+1:nzt+1,:,:) = IBSET( topo_3d(nzb+1:nzt+1,:,:), 0 ) 
+!
+!--       level of detail is required for output routines
+          lod       = 1
 
        CASE ( 'single_building' )
@@ -587,11 +564,6 @@
           blx = NINT( building_length_x / dx )
           bly = NINT( building_length_y / dy )
-          IF ( .NOT. ocean )  THEN
-             bh  = MINLOC( ABS( zw - building_height ), 1 ) - 1
-          ELSE
-             bh  = MINLOC( ABS( zw - zw(0) - building_height ), 1 ) - 1
-          ENDIF
-
-          IF ( ABS( zw(bh  ) - building_height ) == &
+          bh  = MINLOC( ABS( zw - building_height ), 1 ) - 1
+          IF ( ABS( zw(bh)   - building_height ) == &
                ABS( zw(bh+1) - building_height )    )  bh = bh + 1
 
@@ -626,4 +598,18 @@
 
           CALL exchange_horiz_2d_int( nzb_local, nys, nyn, nxl, nxr, nbgp )
+!
+!--       Set bit array to mask topography
+          DO  i = nxlg, nxrg
+             DO  j = nysg, nyng
+
+                topo_3d(nzb_local(j,i)+1:nzt+1,j,i) =                          &
+                                 IBSET( topo_3d(nzb_local(j,i)+1:nzt+1,j,i), 0 ) 
+             ENDDO
+          ENDDO
+!
+!--       level of detail is required for output routines. Here, 2D topography. 
+          lod = 1
+
+          CALL exchange_horiz_int( topo_3d, nbgp )
 
        CASE ( 'single_street_canyon' )
@@ -658,11 +644,6 @@
           ENDIF
 
-          IF ( .NOT. ocean )  THEN
-             ch  = MINLOC( ABS( zw - canyon_height ), 1 ) - 1
-          ELSE
-             ch  = MINLOC( ABS( zw - zw(0) - canyon_height ), 1 ) - 1
-          ENDIF
-
-          IF ( ABS( zw(ch  ) - canyon_height ) == &
+          ch  = MINLOC( ABS( zw - canyon_height ), 1 ) - 1
+          IF ( ABS( zw(ch)   - canyon_height ) == &
                ABS( zw(ch+1) - canyon_height )    )  ch = ch + 1
 
@@ -707,8 +688,166 @@
 
           CALL exchange_horiz_2d_int( nzb_local, nys, nyn, nxl, nxr, nbgp )
+!
+!--       Set bit array to mask topography
+          DO  i = nxlg, nxrg
+             DO  j = nysg, nyng
+                topo_3d(nzb_local(j,i)+1:nzt+1,j,i) =                          &
+                                 IBSET( topo_3d(nzb_local(j,i)+1:nzt+1,j,i), 0 ) 
+             ENDDO
+          ENDDO
+!
+!--       level of detail is required for output routines. Here, 2D topography. 
+          lod = 1
+
+          CALL exchange_horiz_int( topo_3d, nbgp )
+
+       CASE ( 'tunnel' )
+
+!
+!--       Tunnel height
+          IF ( tunnel_height == 9999999.9_wp )  THEN
+             th = zw( INT( 0.2 * nz) )
+          ELSE
+             th = tunnel_height
+          ENDIF
+!
+!--       Tunnel-wall depth
+          IF ( tunnel_wall_depth == 9999999.9_wp )  THEN
+             td = MAX ( dx, dy, dz )
+          ELSE
+             td = tunnel_wall_depth
+          ENDIF
+!
+!--       Check for tunnel width
+          IF ( tunnel_width_x == 9999999.9_wp  .AND.                           &
+               tunnel_width_y == 9999999.9_wp  )  THEN
+             message_string = 'No tunnel width is given. '
+             CALL message( 'init_grid', 'PA0207', 1, 2, 0, 6, 0 )
+          ENDIF
+          IF ( tunnel_width_x /= 9999999.9_wp  .AND.                           &
+               tunnel_width_y /= 9999999.9_wp  )  THEN
+             message_string = 'Inconsistent tunnel parameters:' //             &   
+                              'tunnel can only be oriented' //                 &
+                              'either in x- or in y-direction.'
+             CALL message( 'init_grid', 'PA0207', 1, 2, 0, 6, 0 )
+          ENDIF
+!
+!--       Tunnel axis along y
+          IF ( tunnel_width_x /= 9999999.9_wp )  THEN
+             IF ( tunnel_width_x > ( nx + 1 ) * dx )  THEN
+                message_string = 'Tunnel width too large'
+                CALL message( 'init_grid', 'PA0207', 1, 2, 0, 6, 0 )
+             ENDIF
+
+             txs_out = INT( ( nx + 1 ) * 0.5_wp * dx - tunnel_width_x * 0.5_wp )
+             txe_out = INT( ( nx + 1 ) * 0.5_wp * dx + tunnel_width_x * 0.5_wp )
+             txs_in  = INT( ( nx + 1 ) * 0.5_wp * dx -                         &
+                                      ( tunnel_width_x * 0.5_wp - td ) )
+             txe_in  = INT( ( nx + 1 ) * 0.5_wp * dx +                         &
+                                      ( tunnel_width_x * 0.5_wp - td ) )
+
+             tys_out = INT( ( ny + 1 ) * 0.5_wp * dy - tunnel_length * 0.5_wp )
+             tye_out = INT( ( ny + 1 ) * 0.5_wp * dy + tunnel_length * 0.5_wp )
+             tys_in  = tys_out
+             tye_in  = tye_out
+          ENDIF
+          IF ( tunnel_width_x /= 9999999.9_wp  .AND.                           &
+               tunnel_width_x - 2.0_wp * tunnel_wall_depth <= 2.0_wp * dx )  THEN
+             message_string = 'Tunnel width too small'
+             CALL message( 'init_grid', 'PA0207', 1, 2, 0, 6, 0 )
+          ENDIF
+          IF ( tunnel_width_y /= 9999999.9_wp  .AND.                           &
+               tunnel_width_y - 2.0_wp * tunnel_wall_depth <= 2.0_wp * dy )  THEN
+             message_string = 'Tunnel width too small'
+             CALL message( 'init_grid', 'PA0207', 1, 2, 0, 6, 0 )
+          ENDIF
+!
+!--       Tunnel axis along x
+          IF ( tunnel_width_y /= 9999999.9_wp )  THEN
+             IF ( tunnel_width_y > ( ny + 1 ) * dy )  THEN
+                message_string = 'Tunnel width too large'
+                CALL message( 'init_grid', 'PA0207', 1, 2, 0, 6, 0 )
+             ENDIF
+
+             txs_out = INT( ( nx + 1 ) * 0.5_wp * dx - tunnel_length * 0.5_wp )
+             txe_out = INT( ( nx + 1 ) * 0.5_wp * dx + tunnel_length * 0.5_wp )
+             txs_in  = txs_out
+             txe_in  = txe_out
+
+             tys_out = INT( ( ny + 1 ) * 0.5_wp * dy - tunnel_width_y * 0.5_wp )
+             tye_out = INT( ( ny + 1 ) * 0.5_wp * dy + tunnel_width_y * 0.5_wp )
+             tys_in  = INT( ( ny + 1 ) * 0.5_wp * dy -                         &
+                                     ( tunnel_width_y * 0.5_wp - td ) )
+             tye_in  = INT( ( ny + 1 ) * 0.5_wp * dy +                         &
+                                     ( tunnel_width_y * 0.5_wp - td ) )
+          ENDIF
+
+          topo_3d = 0
+          DO  i = nxl, nxr
+             DO  j = nys, nyn
+!
+!--             Use heaviside function to model outer tunnel surface
+                hv_out = th * 0.5_wp *                                         &
+                              ( ( SIGN( 1.0_wp, i * dx - txs_out ) + 1.0_wp )  &
+                              - ( SIGN( 1.0_wp, i * dx - txe_out ) + 1.0_wp ) )
+
+                hv_out = hv_out * 0.5_wp *                                     &
+                            ( ( SIGN( 1.0_wp, j * dy - tys_out ) + 1.0_wp )    &
+                            - ( SIGN( 1.0_wp, j * dy - tye_out ) + 1.0_wp ) )
+! 
+!--             Use heaviside function to model inner tunnel surface
+                hv_in  = ( th - td ) * 0.5_wp *                                &
+                                ( ( SIGN( 1.0_wp, i * dx - txs_in ) + 1.0_wp ) &
+                                - ( SIGN( 1.0_wp, i * dx - txe_in ) + 1.0_wp ) )
+
+                hv_in = hv_in * 0.5_wp *                                       &
+                                ( ( SIGN( 1.0_wp, j * dy - tys_in ) + 1.0_wp ) &
+                                - ( SIGN( 1.0_wp, j * dy - tye_in ) + 1.0_wp ) )
+!
+!--             Set flags at x-y-positions without any tunnel surface
+                IF ( hv_out - hv_in == 0.0_wp )  THEN
+                   topo_3d(nzb+1:nzt+1,j,i) = IBSET( topo_3d(nzb+1:nzt+1,j,i), 0 )
+!
+!--             Set flags at x-y-positions with tunnel surfaces
+                ELSE
+                   DO  k = nzb + 1, nzt + 1
+!
+!--                   Inner tunnel
+                      IF ( hv_out - hv_in == th )  THEN
+                         IF ( zw(k) <= hv_out )  THEN
+                            topo_3d(k,j,i) = IBCLR( topo_3d(k,j,i), 0 )
+                         ELSE
+                            topo_3d(k,j,i) = IBSET( topo_3d(k,j,i), 0 )
+                         ENDIF
+                      ENDIF
+!
+!--                   Lateral tunnel walls
+                      IF ( hv_out - hv_in == td )  THEN
+                         IF ( zw(k) <= hv_in )  THEN 
+                            topo_3d(k,j,i) = IBSET( topo_3d(k,j,i), 0 )
+                         ELSEIF ( zw(k) > hv_in  .AND.  zw(k) <= hv_out )  THEN 
+                            topo_3d(k,j,i) = IBCLR( topo_3d(k,j,i), 0 )
+                         ELSEIF ( zw(k) > hv_out )  THEN 
+                            topo_3d(k,j,i) = IBSET( topo_3d(k,j,i), 0 )
+                         ENDIF
+                      ENDIF
+                   ENDDO
+                ENDIF
+             ENDDO
+          ENDDO
+
+          nzb_local = 0
+!
+!--       level of detail is required for output routines. Here, 3D topography. 
+          lod = 2
+
+          CALL exchange_horiz_int( topo_3d, nbgp )
 
        CASE ( 'read_from_file' )
 
+          ALLOCATE ( oro_height(nys:nyn,nxl:nxr)  )
           ALLOCATE ( topo_height(nys:nyn,nxl:nxr) )
+          oro_height  = 0.0_wp
+          topo_height = 0.0_wp
 
           DO  ii = 0, io_blocks-1
@@ -717,35 +856,100 @@
 !
 !--             Arbitrary irregular topography data in PALM format (exactly
-!--             matching the grid size and total domain size)
-                OPEN( 90, FILE='TOPOGRAPHY_DATA'//TRIM( coupling_char ),       &
-                          STATUS='OLD', FORM='FORMATTED', ERR=10 )
-!
-!--             Read topography PE-wise. Rows are read from nyn to nys, columns
-!--             are read from nxl to nxr. At first, ny-nyn rows need to be skipped.
-                skip_n_rows = 0
-                DO WHILE ( skip_n_rows < ny - nyn )
-                   READ( 90, * )  
-                   skip_n_rows = skip_n_rows + 1
-                ENDDO
-!
-!--             Read data from nyn to nys and nxl to nxr. Therefore, skip 
-!--             column until nxl-1 is reached
-                DO  j = nyn, nys, -1
-                   READ( 90, *, ERR=11, END=11 )                               &
+!--             matching the grid size and total domain size). 
+!--             First, check if NetCDF file for topography exist or not.
+!--             This case, read topography from NetCDF, else read it from 
+!--             ASCII file.
+#if defined ( __netcdf )
+                INQUIRE( FILE='TOPOGRAPHY_DATA_NC'//TRIM( coupling_char ),     &
+                         EXIST=netcdf_extend )
+!
+!--             NetCDF branch    
+                IF ( netcdf_extend )  THEN
+!
+!--                Open file in read-only mode
+                   CALL netcdf_open_read_file( 'TOPOGRAPHY_DATA_NC',           &
+                                               id_topo, 20 )  !Error number still need to be set properly 
+
+!
+!--                Read terrain height. Reading is done PE-wise, i.e. each
+!--                processor reads its own domain. Reading is realized
+!--                via looping over x-dimension, i.e. calling 
+!--                netcdf_get_variable reads topography along y for given x. 
+!--                Orography is 2D. 
+                   DO  i = nxl, nxr
+                      CALL netcdf_get_variable( id_topo, 'orography_0',        &
+                                                i, oro_height(:,i), 20 )  !Error number still need to be set properly 
+                   ENDDO
+!
+!--                Read attribute lod (level of detail), required for variable 
+!--                buildings_0 
+                   CALL netcdf_get_attribute( id_topo, "lod", lod, .FALSE.,    &
+                                              20, 'buildings_0' ) !Error number still need to be set properly 
+!
+!--                Read building height
+!--                2D for lod = 1, 3D for lod = 2
+                   IF ( lod == 1 )  THEN
+                      DO  i = nxl, nxr
+                         CALL netcdf_get_variable( id_topo, 'buildings_0',     &
+                                                   i, topo_height(:,i), 20 )  !Error number still need to be set properly 
+                      ENDDO
+
+                   ELSEIF ( lod == 2 )  THEN
+!
+!--                   Read data PE-wise. Read yz-slices.
+                      DO  i = nxl, nxr
+                         DO  j = nys, nyn
+                            CALL netcdf_get_variable( id_topo, 'buildings_0',  &
+                                                      i, j, topo_3d(:,j,i), 20 )  !Error number still need to be set properly 
+                         ENDDO
+                      ENDDO
+                   ELSE 
+                      message_string = 'NetCDF attribute lod ' //              &
+                                       '(level of detail) is not set properly.'
+                      CALL message( 'init_grid', 'PA0208', 1, 2, 0, 6, 0 ) !Error number still need to be set properly 
+                   ENDIF
+!
+!--                Close topography input file
+                   CALL netcdf_close_file( id_topo, 20 )
+#endif
+
+!
+!--             ASCII branch. Please note, reading of 3D topography is not
+!--             supported in ASCII format. Further, no distinction is made 
+!--             between orography and buildings
+                ELSE
+
+                   OPEN( 90, FILE='TOPOGRAPHY_DATA'//TRIM( coupling_char ),    &
+                         STATUS='OLD', FORM='FORMATTED', ERR=10 )
+!
+!--                Read topography PE-wise. Rows are read from nyn to nys, columns
+!--                are read from nxl to nxr. At first, ny-nyn rows need to be skipped.
+                   skip_n_rows = 0
+                   DO WHILE ( skip_n_rows < ny - nyn )
+                      READ( 90, * )  
+                      skip_n_rows = skip_n_rows + 1
+                   ENDDO
+!
+!--                Read data from nyn to nys and nxl to nxr. Therefore, skip 
+!--                column until nxl-1 is reached
+                   DO  j = nyn, nys, -1
+                      READ( 90, *, ERR=11, END=11 )                            &
                                               ( dum, i = 0, nxl-1 ),           &
                                               ( topo_height(j,i), i = nxl, nxr )
-                ENDDO
-
-                GOTO 12
+                   ENDDO
+
+                   GOTO 12
           
- 10             message_string = 'file TOPOGRAPHY'//TRIM( coupling_char )//    &
-                                 ' does not exist'
-                CALL message( 'init_grid', 'PA0208', 1, 2, 0, 6, 0 )
-
- 11             message_string = 'errors in file TOPOGRAPHY_DATA'//            &
-                                 TRIM( coupling_char )
-                CALL message( 'init_grid', 'PA0209', 1, 2, 0, 6, 0 )
-
- 12             CLOSE( 90 )
+ 10                message_string = 'file TOPOGRAPHY'//TRIM( coupling_char )// &
+                                    ' does not exist'
+                   CALL message( 'init_grid', 'PA0208', 1, 2, 0, 6, 0 )
+
+ 11                message_string = 'errors in file TOPOGRAPHY_DATA'//         &
+                                    TRIM( coupling_char )
+                   CALL message( 'init_grid', 'PA0209', 1, 2, 0, 6, 0 )
+
+ 12                CLOSE( 90 )
+
+                ENDIF
 
              ENDIF
@@ -761,15 +965,21 @@
              DO  j = nys, nyn
                 IF ( .NOT. ocean )  THEN
-                   nzb_local(j,i) = MINLOC( ABS( zw - topo_height(j,i) ), 1 ) - 1
-                   IF ( ABS( zw(nzb_local(j,i)  ) - topo_height(j,i) ) ==      &
-                        ABS( zw(nzb_local(j,i)+1) - topo_height(j,i) )    )    &
+                   nzb_local(j,i) = MINLOC( ABS( zw - topo_height(j,i)         &
+                                                    - oro_height(j,i) ), 1 ) - 1
+                   IF ( ABS( zw(nzb_local(j,i)  ) - topo_height(j,i)           &
+                                                  - oro_height(j,i)  ) ==      &
+                        ABS( zw(nzb_local(j,i)+1) - topo_height(j,i)           &
+                                                  - oro_height(j,i)  )    )    &
                       nzb_local(j,i) = nzb_local(j,i) + 1
                 ELSE
                    nzb_local(j,i) = MINLOC( ABS( zw - zw(0)                    &
-                                                    - topo_height(j,i) ), 1 ) - 1
+                                                    - topo_height(j,i)         &
+                                                    - oro_height(j,i) ), 1 ) - 1
                    IF ( ABS( zw(nzb_local(j,i)  ) - zw(0)                      &
-                                                  - topo_height(j,i) )  ==     &
+                                                  - topo_height(j,i)           &
+                                                  - oro_height(j,i)  )  ==     &
                         ABS( zw(nzb_local(j,i)+1) - zw(0)                      &
-                                                  - topo_height(j,i) )    )    &
+                                                  - topo_height(j,i)           &
+                                                  - oro_height(j,i)  )    )    &
                       nzb_local(j,i) = nzb_local(j,i) + 1
                 ENDIF
@@ -778,4 +988,5 @@
           ENDDO
 
+          DEALLOCATE ( oro_height  )
           DEALLOCATE ( topo_height )
 !
@@ -836,10 +1047,25 @@
              CALL message( 'init_grid', 'PA0430', 0, 0, 0, 6, 0 )
           ENDIF
+
+!
+!--       Set bit array to mask topography. Only required for lod = 1
+          IF ( lod == 1 )  THEN
+             DO  i = nxlg, nxrg
+                DO  j = nysg, nyng
+                   topo_3d(nzb_local(j,i)+1:nzt+1,j,i) =                          &
+                                 IBSET( topo_3d(nzb_local(j,i)+1:nzt+1,j,i), 0 ) 
+                ENDDO
+             ENDDO
+          ENDIF
 !
 !--       Exchange ghost-points, as well as add cyclic or Neumann boundary 
 !--       conditions.
+          CALL exchange_horiz_int( topo_3d, nbgp )
           CALL exchange_horiz_2d_int( nzb_local, nys, nyn, nxl, nxr, nbgp )
           
           IF ( .NOT. bc_ns_cyc )  THEN
+             IF ( nys == 0  )  topo_3d(:,-1,:)   = topo_3d(:,0,:)
+             IF ( nyn == ny )  topo_3d(:,ny+1,:) = topo_3d(:,ny,:)
+
              IF ( nys == 0  )  nzb_local(-1,:)   = nzb_local(0,:)
              IF ( nyn == ny )  nzb_local(ny+1,:) = nzb_local(ny,:)
@@ -847,7 +1073,11 @@
 
           IF ( .NOT. bc_lr_cyc )  THEN
+             IF ( nxl == 0  )  topo_3d(:,:,-1)   = topo_3d(:,:,0)
+             IF ( nxr == nx )  topo_3d(:,:,nx+1) = topo_3d(:,:,nx)     
+
              IF ( nxl == 0  )  nzb_local(:,-1)   = nzb_local(:,0)
              IF ( nxr == nx )  nzb_local(:,nx+1) = nzb_local(:,nx)          
           ENDIF
+
 
        CASE DEFAULT
@@ -857,25 +1087,7 @@
 !--       case in the user interface. There, the subroutine user_init_grid 
 !--       checks which of these two conditions applies.
-          CALL user_init_grid( nzb_local )
+          CALL user_init_grid( topo_3d )
 
     END SELECT
-!
-!-- Determine the maximum level of topography. Furthermore it is used for
-!-- steering the degradation of order of the applied advection scheme.
-!-- In case of non-cyclic lateral boundaries, the order of the advection
-!-- scheme has to be reduced up to nzt (required at the lateral boundaries).
-#if defined( __parallel )
-    CALL MPI_ALLREDUCE( MAXVAL( nzb_local ) + 1, nzb_max, 1, MPI_INTEGER,      &
-                        MPI_MAX, comm2d, ierr )
-#else
-    nzb_max = MAXVAL( nzb_local ) + 1
-#endif
-    IF ( inflow_l .OR. outflow_l .OR. inflow_r .OR. outflow_r .OR.             &
-         inflow_n .OR. outflow_n .OR. inflow_s .OR. outflow_s .OR.             &
-         nest_domain )                                                         &
-    THEN
-       nzb_max = nzt
-    ENDIF
-
 !
 !-- Consistency checks and index array initialization are only required for
@@ -901,4 +1113,41 @@
                                 '&MAXVAL( nzb_local ) = ', nzb_local_max
           CALL message( 'init_grid', 'PA0210', 1, 2, 0, 6, 0 )
+       ENDIF
+!
+!--    In case of non-flat topography, check whether the convention how to 
+!--    define the topography grid has been set correctly, or whether the default
+!--    is applicable. If this is not possible, abort.
+       IF ( TRIM( topography_grid_convention ) == ' ' )  THEN
+          IF ( TRIM( topography ) /= 'single_building' .AND.                   &
+               TRIM( topography ) /= 'single_street_canyon' .AND.              &
+               TRIM( topography ) /= 'tunnel'  .AND.                           &
+               TRIM( topography ) /= 'read_from_file')  THEN
+!--          The default value is not applicable here, because it is only valid
+!--          for the two standard cases 'single_building' and 'read_from_file'
+!--          defined in init_grid.
+             WRITE( message_string, * )                                        &
+                  'The value for "topography_grid_convention" ',               &
+                  'is not set. Its default value is & only valid for ',        &
+                  '"topography" = ''single_building'', ',                      &
+                  '''single_street_canyon'' & or ''read_from_file''.',         &
+                  ' & Choose ''cell_edge'' or ''cell_center''.'
+             CALL message( 'init_grid', 'PA0239', 1, 2, 0, 6, 0 )
+          ELSE
+!--          The default value is applicable here.
+!--          Set convention according to topography.
+             IF ( TRIM( topography ) == 'single_building' .OR.                 &
+                  TRIM( topography ) == 'single_street_canyon' )  THEN
+                topography_grid_convention = 'cell_edge'
+             ELSEIF ( TRIM( topography ) == 'read_from_file'  .OR.             &
+                      TRIM( topography ) == 'tunnel')  THEN
+                topography_grid_convention = 'cell_center'
+             ENDIF
+          ENDIF
+       ELSEIF ( TRIM( topography_grid_convention ) /= 'cell_edge' .AND.        &
+                TRIM( topography_grid_convention ) /= 'cell_center' )  THEN
+          WRITE( message_string, * )                                           &
+               'The value for "topography_grid_convention" is ',               &
+               'not recognized. & Choose ''cell_edge'' or ''cell_center''.'
+          CALL message( 'init_grid', 'PA0240', 1, 2, 0, 6, 0 )
        ENDIF
 
@@ -964,11 +1213,38 @@
                 nzb_local(j,i) = MIN( nzb_local(j,i), nzb_local(j+1,i) )
              ENDDO
-          ENDDO
+          ENDDO  
 !
 !--       Exchange ghost points          
           CALL exchange_horiz_2d_int( nzb_local, nys, nyn, nxl, nxr, nbgp )
+!
+!--       Apply cell-edge convention also for 3D topo array. The former setting
+!--       of nzb_local will be removed later. 
+          DO  j = nys+1, nyn+1
+             DO  i = nxl-1, nxr
+                DO  k = nzb, nzt+1
+                   IF ( BTEST( topo_3d(k,j,i), 0 )  .OR.                       &
+                        BTEST( topo_3d(k,j,i+1), 0 ) )                         &
+                      topo_3d(k,j,i) = IBSET( topo_3d(k,j,i), 0 )
+                ENDDO
+             ENDDO
+          ENDDO      
+          CALL exchange_horiz_int( topo_3d, nbgp )   
+
+          DO  i = nxl, nxr+1
+             DO  j = nys-1, nyn
+                DO  k = nzb, nzt+1
+                   IF ( BTEST( topo_3d(k,j,i), 0 )  .OR.                       &
+                        BTEST( topo_3d(k,j+1,i), 0 ) )                         &
+                      topo_3d(k,j,i) = IBSET( topo_3d(k,j,i), 0 )
+                ENDDO
+             ENDDO
+          ENDDO  
+          CALL exchange_horiz_int( topo_3d, nbgp )
+   
        ENDIF
+      
 !
 !--    Initialize index arrays nzb_s_inner and nzb_w_inner
+
        nzb_s_inner = nzb_local
        nzb_w_inner = nzb_local
@@ -1103,62 +1379,4 @@
        CALL exchange_horiz_2d_int( nzb_s_outer, nys, nyn, nxl, nxr, nbgp )
 
-!
-!--    Allocate and set the arrays containing the topography height
-       ALLOCATE( zu_s_inner(0:nx+1,0:ny+1), zw_w_inner(0:nx+1,0:ny+1),         &
-                 zu_s_inner_l(0:nx+1,0:ny+1), zw_w_inner_l(0:nx+1,0:ny+1) )
-                 
-       zu_s_inner   = 0.0_wp
-       zw_w_inner   = 0.0_wp
-       zu_s_inner_l = 0.0_wp
-       zw_w_inner_l = 0.0_wp
-       
-       DO  i = nxl, nxr
-          DO  j = nys, nyn
-             zu_s_inner_l(i,j) = zu(nzb_local(j,i))
-             zw_w_inner_l(i,j) = zw(nzb_local(j,i))
-          ENDDO
-       ENDDO
-       
-#if defined( __parallel )
-       CALL MPI_REDUCE( zu_s_inner_l, zu_s_inner, (nx+2)*(ny+2),         &
-                           MPI_REAL, MPI_SUM, 0, comm2d, ierr )       
-       CALL MPI_REDUCE( zw_w_inner_l, zw_w_inner, (nx+2)*(ny+2),         &
-                           MPI_REAL, MPI_SUM, 0, comm2d, ierr )  
-#else
-       zu_s_inner = zu_s_inner_l
-       zw_w_inner = zw_w_inner_l
-#endif
-
-      DEALLOCATE( zu_s_inner_l, zw_w_inner_l )
-      IF ( myid /= 0 )  DEALLOCATE( zu_s_inner, zw_w_inner )
-!
-!--   Set south and left ghost points, required for netcdf output
-      IF ( myid == 0 )  THEN
-         IF( bc_lr_cyc )  THEN
-            zu_s_inner(nx+1,:) = zu_s_inner(0,:)
-            zw_w_inner(nx+1,:) = zw_w_inner(0,:)
-         ELSE
-            zu_s_inner(nx+1,:) = zu_s_inner(nx,:)
-            zw_w_inner(nx+1,:) = zw_w_inner(nx,:)
-         ENDIF
-         IF( bc_ns_cyc )  THEN
-            zu_s_inner(:,ny+1) = zu_s_inner(:,0)
-            zw_w_inner(:,ny+1) = zw_w_inner(:,0)
-         ELSE
-            zu_s_inner(:,ny+1) = zu_s_inner(:,ny)
-            zw_w_inner(:,ny+1) = zw_w_inner(:,ny)
-         ENDIF
-      ENDIF
-!
-!--    Set flag arrays to be used for masking of grid points
-       DO  i = nxlg, nxrg
-          DO  j = nysg, nyng
-             DO  k = nzb, nzt+1
-                IF ( k <= nzb_s_inner(j,i) )  rflags_s_inner(k,j,i) = 0.0_wp
-                IF ( k <= nzb_s_inner(j,i) )  rflags_invers(j,i,k)  = 0.0_wp
-             ENDDO
-          ENDDO
-       ENDDO
-
     ENDIF
 !
@@ -1166,4 +1384,34 @@
 !-- grid-levels further below.
     DEALLOCATE( nzb_tmp )
+
+!
+!-- Determine the maximum level of topography. It is used for
+!-- steering the degradation of order of the applied advection scheme.
+!-- In case of non-cyclic lateral boundaries, the order of the advection
+!-- scheme has to be reduced up to nzt (required at the lateral boundaries).
+    k_top = 0
+    DO  i = nxl, nxr
+       DO  j = nys, nyn
+          DO  k = nzb, nzt + 1
+             k_top = MAX( k_top, MERGE( k, 0,                                  &
+                                        .NOT. BTEST( topo_3d(k,j,i), 0 ) ) )
+          ENDDO
+       ENDDO
+    ENDDO
+#if defined( __parallel )
+    CALL MPI_ALLREDUCE( k_top + 1, nzb_max, 1, MPI_INTEGER,                    & !is +1 really necessary here?
+                        MPI_MAX, comm2d, ierr )
+#else
+    nzb_max = k_top + 1
+#endif
+    IF ( inflow_l .OR. outflow_l .OR. inflow_r .OR. outflow_r .OR.             &
+         inflow_n .OR. outflow_n .OR. inflow_s .OR. outflow_s .OR.             &
+         nest_domain )                                                         &
+    THEN
+       nzb_max = nzt
+    ENDIF
+!
+!-- Finally, if topography extents up to the model top, limit nzb_max to nzt.
+    nzb_max = MIN( nzb_max, nzt ) 
 
 !
@@ -1172,11 +1420,7 @@
 !-- applied 
     IF ( constant_flux_layer  .OR.  use_surface_fluxes )  THEN
-       nzb_diff_u         = nzb_u_inner + 2
-       nzb_diff_v         = nzb_v_inner + 2
        nzb_diff_s_inner   = nzb_s_inner + 2
        nzb_diff_s_outer   = nzb_s_outer + 2
     ELSE
-       nzb_diff_u         = nzb_u_inner + 1
-       nzb_diff_v         = nzb_v_inner + 1
        nzb_diff_s_inner   = nzb_s_inner + 1
        nzb_diff_s_outer   = nzb_s_outer + 1
@@ -1184,108 +1428,289 @@
 
 !
-!-- Calculation of wall switches and factors required by diffusion_u/v.f90 and 
-!-- for limitation of near-wall mixing length l_wall further below
-    corner_nl = 0
-    corner_nr = 0
-    corner_sl = 0
-    corner_sr = 0
-    wall_l    = 0
-    wall_n    = 0
-    wall_r    = 0
-    wall_s    = 0
-
-    DO  i = nxl, nxr
-       DO  j = nys, nyn
-!
-!--       u-component
-          IF ( nzb_u_outer(j,i) > nzb_u_outer(j+1,i) )  THEN
-             wall_u(j,i) = 1.0_wp   ! north wall (location of adjacent fluid)
-             fym(j,i)    = 0.0_wp
-             fyp(j,i)    = 1.0_wp
-          ELSEIF ( nzb_u_outer(j,i) > nzb_u_outer(j-1,i) )  THEN
-             wall_u(j,i) = 1.0_wp   ! south wall (location of adjacent fluid)
-             fym(j,i)    = 1.0_wp
-             fyp(j,i)    = 0.0_wp
-          ENDIF
-!
-!--       v-component
-          IF ( nzb_v_outer(j,i) > nzb_v_outer(j,i+1) )  THEN
-             wall_v(j,i) = 1.0_wp   ! rigth wall (location of adjacent fluid)
-             fxm(j,i)    = 0.0_wp
-             fxp(j,i)    = 1.0_wp
-          ELSEIF ( nzb_v_outer(j,i) > nzb_v_outer(j,i-1) )  THEN
-             wall_v(j,i) = 1.0_wp   ! left wall (location of adjacent fluid)
-             fxm(j,i)    = 1.0_wp
-             fxp(j,i)    = 0.0_wp
-          ENDIF
-!
-!--       w-component, also used for scalars, separate arrays for shear 
-!--       production of tke
-          IF ( nzb_w_outer(j,i) > nzb_w_outer(j+1,i) )  THEN
-             wall_e_y(j,i) =  1.0_wp   ! north wall (location of adjacent fluid)
-             wall_w_y(j,i) =  1.0_wp
-             fwym(j,i)     =  0.0_wp
-             fwyp(j,i)     =  1.0_wp
-          ELSEIF ( nzb_w_outer(j,i) > nzb_w_outer(j-1,i) )  THEN
-             wall_e_y(j,i) = -1.0_wp   ! south wall (location of adjacent fluid)
-             wall_w_y(j,i) =  1.0_wp
-             fwym(j,i)     =  1.0_wp
-             fwyp(j,i)     =  0.0_wp
-          ENDIF
-          IF ( nzb_w_outer(j,i) > nzb_w_outer(j,i+1) )  THEN
-             wall_e_x(j,i) =  1.0_wp   ! right wall (location of adjacent fluid)
-             wall_w_x(j,i) =  1.0_wp
-             fwxm(j,i)     =  0.0_wp
-             fwxp(j,i)     =  1.0_wp
-          ELSEIF ( nzb_w_outer(j,i) > nzb_w_outer(j,i-1) )  THEN
-             wall_e_x(j,i) = -1.0_wp   ! left wall (location of adjacent fluid)
-             wall_w_x(j,i) =  1.0_wp
-             fwxm(j,i)     =  1.0_wp
-             fwxp(j,i)     =  0.0_wp
-          ENDIF
-!
-!--       Wall and corner locations inside buildings for limitation of
-!--       near-wall mixing length l_wall
-          IF ( nzb_s_inner(j,i) > nzb_s_inner(j+1,i) )  THEN
-
-             wall_n(j,i) = nzb_s_inner(j+1,i) + 1            ! North wall
-
-             IF ( nzb_s_inner(j,i) > nzb_s_inner(j,i-1) )  THEN
-                corner_nl(j,i) = MAX( nzb_s_inner(j+1,i),  & ! Northleft corner
-                                      nzb_s_inner(j,i-1) ) + 1
-             ENDIF
-
-             IF ( nzb_s_inner(j,i) > nzb_s_inner(j,i+1) )  THEN
-                corner_nr(j,i) = MAX( nzb_s_inner(j+1,i),  & ! Northright corner
-                                      nzb_s_inner(j,i+1) ) + 1
-             ENDIF
-
-          ENDIF
-
-          IF ( nzb_s_inner(j,i) > nzb_s_inner(j-1,i) )  THEN
-
-             wall_s(j,i) = nzb_s_inner(j-1,i) + 1            ! South wall
-             IF ( nzb_s_inner(j,i) > nzb_s_inner(j,i-1) )  THEN
-                corner_sl(j,i) = MAX( nzb_s_inner(j-1,i),  & ! Southleft corner
-                                      nzb_s_inner(j,i-1) ) + 1
-             ENDIF
-
-             IF ( nzb_s_inner(j,i) > nzb_s_inner(j,i+1) )  THEN
-                corner_sr(j,i) = MAX( nzb_s_inner(j-1,i),  & ! Southright corner
-                                      nzb_s_inner(j,i+1) ) + 1
-             ENDIF
-
-          ENDIF
-
-          IF ( nzb_s_inner(j,i) > nzb_s_inner(j,i-1) )  THEN
-             wall_l(j,i) = nzb_s_inner(j,i-1) + 1            ! Left wall
-          ENDIF
-
-          IF ( nzb_s_inner(j,i) > nzb_s_inner(j,i+1) )  THEN
-             wall_r(j,i) = nzb_s_inner(j,i+1) + 1            ! Right wall
-          ENDIF
+!-- Set-up topography flags. First, set flags only for s, u, v and w-grid.
+!-- Further special flags will be set in following loops. 
+    wall_flags_0 = 0
+    DO  j = nys, nyn
+       DO  i = nxl, nxr
+          DO  k = nzb, nzt+1
+!
+!--          scalar grid
+             IF ( BTEST( topo_3d(k,j,i), 0 ) )                                 &
+                wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i), 0 )
+!
+!--          v grid
+             IF ( BTEST( topo_3d(k,j,i),   0 )  .AND.                          &
+                  BTEST( topo_3d(k,j-1,i), 0 ) )                               &
+                wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i), 2 )
+!
+!--     To do: set outer arrays on basis of topo_3d array, adjust for downward-facing walls
+!--          s grid outer array
+             IF ( k >= nzb_s_outer(j,i) )                                      &
+                wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i), 24 )
+!
+!--          s grid outer array
+             IF ( k >= nzb_u_outer(j,i) )                                      &
+                wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i), 26 )
+!
+!--          s grid outer array
+             IF ( k >= nzb_v_outer(j,i) )                                      &
+                wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i), 27 )
+!
+!--          w grid outer array
+             IF ( k >= nzb_w_outer(j,i) )                                      &
+                wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i), 28 )
+          ENDDO
+
+          DO k = nzb, nzt
+!
+!--          w grid
+             IF ( BTEST( topo_3d(k,j,i),   0 )  .AND.                          &
+                  BTEST( topo_3d(k+1,j,i), 0 ) )                               &
+                wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i), 3 )
+          ENDDO
+          wall_flags_0(nzt+1,j,i) = IBSET( wall_flags_0(nzt+1,j,i), 3 )
 
        ENDDO
     ENDDO
+!
+!-- u grid. Note, reverse 
+!-- memory access is required for setting flag on u-grid
+    DO  j = nys, nyn
+       DO  i = nxl, nxr
+          DO k = nzb, nzt+1
+             IF ( BTEST( topo_3d(k,j,i),   0 )  .AND.                          &
+                  BTEST( topo_3d(k,j,i-1), 0 ) )                               &
+                wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i), 1 )
+          ENDDO
+       ENDDO
+    ENDDO
+!
+!-- Set further special flags
+    DO i = nxl, nxr
+       DO j = nys, nyn
+          DO k = nzb, nzt+1
+!
+!--          scalar grid, former nzb_diff_s_inner.
+!--          Note, use this flag also to mask topography in diffusion_u and 
+!--          diffusion_v along the vertical direction. In case of 
+!--          use_surface_fluxes, fluxes are calculated via MOST, else, simple
+!--          gradient approach is applied. Please note, in case of u- and v-
+!--          diffuison, a small error is made at edges (on the east side for u,
+!--          at the north side for v), since topography on scalar grid point
+!--          is used instead of topography on u/v-grid. As number of topography grid
+!--          points on uv-grid is different than s-grid, different number of 
+!--          surface elements would be required. In order to avoid this, 
+!--          treat edges (u(k,j,i+1)) simply by a gradient approach, i.e. these
+!--          points are not masked within diffusion_u. Tests had shown that the
+!--          effect on the flow is negligible. 
+             IF ( constant_flux_layer  .OR.  use_surface_fluxes )  THEN
+                IF ( BTEST( wall_flags_0(k,j,i), 0 ) )                         &
+                   wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i), 8 )
+             ELSE
+                wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i), 8 )
+             ENDIF
+
+          ENDDO
+!
+!--       Special flag to control vertical diffusion at model top - former 
+!--       nzt_diff
+          wall_flags_0(:,j,i) = IBSET( wall_flags_0(:,j,i), 9 )
+          IF ( use_top_fluxes )                                                &
+             wall_flags_0(nzt:nzt+1,j,i) = IBCLR( wall_flags_0(nzt:nzt+1,j,i), 9 )
+
+          DO k = nzb+1, nzt
+!
+!--          Special flag on u grid, former nzb_u_inner + 1, required   
+!--          for disturb_field and initialization. Do not disturb directly at
+!--          topography, as well as initialize u with zero one grid point outside
+!--          of topography.
+             IF ( BTEST( wall_flags_0(k-1,j,i), 1 )  .AND.                     &
+                  BTEST( wall_flags_0(k,j,i),   1 )  .AND.                     &
+                  BTEST( wall_flags_0(k+1,j,i), 1 ) )                          &
+                wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i), 20 )
+!
+!--          Special flag on v grid, former nzb_v_inner + 1, required   
+!--          for disturb_field and initialization. Do not disturb directly at
+!--          topography, as well as initialize v with zero one grid point outside
+!--          of topography.
+             IF ( BTEST( wall_flags_0(k-1,j,i), 2 )  .AND.                     &
+                  BTEST( wall_flags_0(k,j,i),   2 )  .AND.                     &
+                  BTEST( wall_flags_0(k+1,j,i), 2 ) )                          &
+                wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i), 21 )
+!
+!--          Special flag on scalar grid, former nzb_s_inner+1. Used for 
+!--          lpm_sgs_tke
+             IF ( BTEST( wall_flags_0(k,j,i),   0 )  .AND.                     &
+                  BTEST( wall_flags_0(k-1,j,i), 0 )  .AND.                     &
+                  BTEST( wall_flags_0(k+1,j,i), 0 ) )                          &
+                wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i), 25 )
+!
+!--          Special flag on scalar grid, nzb_diff_s_outer - 1, required in 
+!--          in production_e
+             IF ( constant_flux_layer  .OR.  use_surface_fluxes )  THEN
+                IF ( BTEST( wall_flags_0(k,j,i),   24 )  .AND.                 &
+                     BTEST( wall_flags_0(k-1,j,i), 24 )  .AND.                 &
+                     BTEST( wall_flags_0(k+1,j,i), 0 ) )                       &
+                   wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i), 29 )
+             ELSE
+                IF ( BTEST( wall_flags_0(k,j,i), 0 ) )                         &
+                   wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i), 29 )
+             ENDIF
+!
+!--          Special flag on scalar grid, nzb_diff_s_outer - 1, required in 
+!--          in production_e
+             IF ( constant_flux_layer  .OR.  use_surface_fluxes )  THEN
+                IF ( BTEST( wall_flags_0(k,j,i),   0 )  .AND.                  &
+                     BTEST( wall_flags_0(k-1,j,i), 0 )  .AND.                  &
+                     BTEST( wall_flags_0(k+1,j,i), 0 ) )                       &
+                   wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i), 30 )
+             ELSE
+                IF ( BTEST( wall_flags_0(k,j,i), 0 ) )                         &
+                   wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i), 30 )
+             ENDIF
+          ENDDO
+!
+!--       Flags indicating downward facing walls
+          DO k = nzb+1, nzt
+!
+!--          Scalar grid
+             IF ( BTEST( wall_flags_0(k-1,j,i), 0 )  .AND.                     &
+            .NOT. BTEST( wall_flags_0(k,j,i), 0   ) )                          & 
+                wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i), 13 ) 
+!
+!--          Downward facing wall on u grid
+             IF ( BTEST( wall_flags_0(k-1,j,i), 1 )  .AND.                     &
+            .NOT. BTEST( wall_flags_0(k,j,i), 1   ) )                          & 
+                wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i), 15 )
+!
+!--          Downward facing wall on v grid
+             IF ( BTEST( wall_flags_0(k-1,j,i), 2 )  .AND.                     &
+            .NOT. BTEST( wall_flags_0(k,j,i), 2   ) )                          & 
+                wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i), 17 )
+!
+!--          Downward facing wall on w grid
+             IF ( BTEST( wall_flags_0(k-1,j,i), 3 )  .AND.                     &
+            .NOT. BTEST( wall_flags_0(k,j,i), 3 ) )                            & 
+                wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i), 19 )
+          ENDDO
+!
+!--       Flags indicating upward facing walls
+          DO k = nzb, nzt
+!
+!--          Upward facing wall on scalar grid
+             IF ( .NOT. BTEST( wall_flags_0(k,j,i),   0 )  .AND.               &
+                        BTEST( wall_flags_0(k+1,j,i), 0 ) )                    & 
+                wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i), 12 )
+!
+!--          Upward facing wall on u grid
+             IF ( .NOT. BTEST( wall_flags_0(k,j,i),   1 )  .AND.               &
+                        BTEST( wall_flags_0(k+1,j,i), 1 ) )                    & 
+                wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i), 14 )
+
+!
+!--          Upward facing wall on v grid
+             IF ( .NOT. BTEST( wall_flags_0(k,j,i),   2 )  .AND.               &
+                        BTEST( wall_flags_0(k+1,j,i), 2 ) )                    & 
+                wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i), 16 )
+
+!
+!--          Upward facing wall on w grid
+             IF ( .NOT. BTEST( wall_flags_0(k,j,i),   3 )  .AND.               &
+                        BTEST( wall_flags_0(k+1,j,i), 3 ) )                    & 
+                wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i), 18 )
+!
+!--          Special flag on scalar grid, former nzb_s_inner
+             IF ( BTEST( wall_flags_0(k,j,i), 0 )  .OR.                        &
+                  BTEST( wall_flags_0(k,j,i), 12 ) .OR.                        &
+                  BTEST( wall_flags_0(k,j,i), 13 ) )                           &
+                wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i), 22 )
+!
+!--          Special flag on scalar grid, nzb_diff_s_inner - 1, required for 
+!--          flow_statistics
+             IF ( constant_flux_layer  .OR.  use_surface_fluxes )  THEN
+                IF ( BTEST( wall_flags_0(k,j,i),   0 )  .AND.                  &
+                     BTEST( wall_flags_0(k+1,j,i), 0 ) )                       &
+                   wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i), 23 )
+             ELSE
+                IF ( BTEST( wall_flags_0(k,j,i), 22 ) )                        &
+                   wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i), 23 )
+             ENDIF
+
+
+          ENDDO
+          wall_flags_0(nzt+1,j,i) = IBSET( wall_flags_0(nzt+1,j,i), 22 )
+          wall_flags_0(nzt+1,j,i) = IBSET( wall_flags_0(nzt+1,j,i), 23 )
+       ENDDO
+    ENDDO
+!
+!-- Exchange ghost points for wall flags
+    CALL exchange_horiz_int( wall_flags_0, nbgp )
+!
+!-- Set boundary conditions also for flags. Can be interpreted as Neumann
+!-- boundary conditions for topography. 
+    IF ( .NOT. bc_ns_cyc )  THEN
+       IF ( nys == 0  )  wall_flags_0(:,-1,:)   = wall_flags_0(:,0,:)
+       IF ( nyn == ny )  wall_flags_0(:,ny+1,:) = wall_flags_0(:,ny,:)
+    ENDIF
+    IF ( .NOT. bc_lr_cyc )  THEN
+       IF ( nxl == 0  )  wall_flags_0(:,:,-1)   = wall_flags_0(:,:,0)
+       IF ( nxr == nx )  wall_flags_0(:,:,nx+1) = wall_flags_0(:,:,nx)           
+    ENDIF
+
+!
+!-- Initialize boundary conditions via surface type
+    CALL init_bc
+!
+!-- Allocate and set topography height arrays required for data output
+    IF ( TRIM( topography ) /= 'flat' )  THEN
+!
+!--    Allocate and set the arrays containing the topography height
+
+       IF ( nxr == nx  .AND.  nyn /= ny )  THEN
+          ALLOCATE( zu_s_inner(nxl:nxr+1,nys:nyn),                             &
+                    zw_w_inner(nxl:nxr+1,nys:nyn) )
+       ELSEIF ( nxr /= nx  .AND.  nyn == ny )  THEN
+          ALLOCATE( zu_s_inner(nxl:nxr,nys:nyn+1),                             &
+                    zw_w_inner(nxl:nxr,nys:nyn+1) )
+       ELSEIF ( nxr == nx  .AND.  nyn == ny )  THEN
+          ALLOCATE( zu_s_inner(nxl:nxr+1,nys:nyn+1),                           &
+                    zw_w_inner(nxl:nxr+1,nys:nyn+1) )
+       ELSE
+          ALLOCATE( zu_s_inner(nxl:nxr,nys:nyn),                               &
+                    zw_w_inner(nxl:nxr,nys:nyn) )
+       ENDIF
+
+       zu_s_inner   = 0.0_wp
+       zw_w_inner   = 0.0_wp
+!
+!--    Determine local topography height on scalar and w-grid. Note, setting
+!--    lateral boundary values is not necessary, realized via wall_flags_0 
+!--    array. Further, please note that loop bounds are different from 
+!--    nxl to nxr and nys to nyn on south and right model boundary, hence, 
+!--    use intrinsic lbound and ubound functions to infer array bounds.
+       DO  i = lbound(zu_s_inner, 1), ubound(zu_s_inner, 1)
+          DO  j = lbound(zu_s_inner, 2), ubound(zu_s_inner, 2)
+!
+!--          Topography height on scalar grid. Therefore, determine index of 
+!--          upward-facing surface element on scalar grid (bit 12). 
+             zu_s_inner(i,j) = zu( MAXLOC( MERGE(                              &
+                                         1, 0, BTEST( wall_flags_0(:,j,i), 12 )&
+                                                ), DIM = 1                     &
+                                         ) - 1                                 &
+                                 )
+!
+!--          Topography height on w grid. Therefore, determine index of 
+!--          upward-facing surface element on w grid (bit 18).
+             zw_w_inner(i,j) = zw( MAXLOC( MERGE(                              &
+                                         1, 0, BTEST( wall_flags_0(:,j,i), 18 )&
+                                                ), DIM = 1                     &
+                                         ) - 1                                 &
+                                 )
+          ENDDO
+       ENDDO
+
+
+    ENDIF
+
 !
 !-- Calculate wall flag arrays for the multigrid method.
@@ -1450,8 +1875,8 @@
 !-- required in the ws-scheme, the arrays need to be allocated here as they are 
 !-- used in OpenACC directives. 
-    ALLOCATE( wall_flags_0(nzb:nzt+1,nysg:nyng,nxlg:nxrg),                     &
-              wall_flags_00(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
-    wall_flags_0  = 0
-    wall_flags_00 = 0
+    ALLOCATE( advc_flags_1(nzb:nzt+1,nysg:nyng,nxlg:nxrg),                     &
+              advc_flags_2(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
+    advc_flags_1 = 0
+    advc_flags_2 = 0
 !
 !-- Init flags for ws-scheme to degrade order of the numerics near walls, i.e. 
@@ -1466,148 +1891,91 @@
 !-- Go through all points of the subdomain one by one and look for the closest
 !-- surface
-    IF ( TRIM(topography) /= 'flat' )  THEN
-       DO  i = nxl, nxr
-          DO  j = nys, nyn
-
-             nzb_si = nzb_s_inner(j,i)
-             vi     = vertical_influence(nzb_si)
-
-             IF ( wall_n(j,i) > 0 )  THEN
-!
-!--             North wall (y distance)
-                DO  k = wall_n(j,i), nzb_si
-                   l_wall(k,j+1,i) = MIN( l_wall(k,j+1,i), 0.5_wp * dy )
-                ENDDO
-!
-!--             Above North wall (yz distance)
-                DO  k = nzb_si + 1, nzb_si + vi
-                   l_wall(k,j+1,i) = MIN( l_wall(k,j+1,i),                     &
-                                          SQRT( 0.25_wp * dy**2 +              &
-                                          ( zu(k) - zw(nzb_si) )**2 ) )
-                ENDDO
-!
-!--             Northleft corner (xy distance)
-                IF ( corner_nl(j,i) > 0 )  THEN
-                   DO  k = corner_nl(j,i), nzb_si
-                      l_wall(k,j+1,i-1) = MIN( l_wall(k,j+1,i-1), &
-                                               0.5_wp * SQRT( dx**2 + dy**2 ) )
-                   ENDDO
-!
-!--                Above Northleft corner (xyz distance)
-                   DO  k = nzb_si + 1, nzb_si + vi
-                      l_wall(k,j+1,i-1) = MIN( l_wall(k,j+1,i-1),              &
-                                            SQRT( 0.25_wp * (dx**2 + dy**2) +  &
-                                            ( zu(k) - zw(nzb_si) )**2 ) )
-                   ENDDO
-                ENDIF
-!
-!--             Northright corner (xy distance)
-                IF ( corner_nr(j,i) > 0 )  THEN
-                   DO  k = corner_nr(j,i), nzb_si
-                       l_wall(k,j+1,i+1) = MIN( l_wall(k,j+1,i+1),             &
-                                                0.5_wp * SQRT( dx**2 + dy**2 ) )
-                   ENDDO
-!
-!--                Above northright corner (xyz distance)
-                   DO  k = nzb_si + 1, nzb_si + vi
-                      l_wall(k,j+1,i+1) = MIN( l_wall(k,j+1,i+1),              &
-                                            SQRT( 0.25_wp * (dx**2 + dy**2) +  &
-                                            ( zu(k) - zw(nzb_si) )**2 ) )
-                   ENDDO
-                ENDIF
+    DO  i = nxl, nxr
+       DO  j = nys, nyn
+          DO  k = nzb+1, nzt
+!
+!--          Check if current gridpoint belongs to the atmosphere
+             IF ( BTEST( wall_flags_0(k,j,i), 0 ) )  THEN
+!
+!--             Check for neighbouring grid-points.
+!--             Vertical distance, down
+                IF ( .NOT. BTEST( wall_flags_0(k-1,j,i), 0 ) )                 &
+                   l_wall(k,j,i) = MIN( l_grid(k), zu(k) - zw(k-1) )
+!
+!--             Vertical distance, up
+                IF ( .NOT. BTEST( wall_flags_0(k+1,j,i), 0 ) )                 &
+                   l_wall(k,j,i) = MIN( l_grid(k), zw(k) - zu(k) )
+!
+!--             y-distance
+                IF ( .NOT. BTEST( wall_flags_0(k,j-1,i), 0 )  .OR.             &
+                     .NOT. BTEST( wall_flags_0(k,j+1,i), 0 ) )                 &
+                   l_wall(k,j,i) = MIN( l_wall(k,j,i), l_grid(k), 0.5_wp * dy )
+!
+!--             x-distance
+                IF ( .NOT. BTEST( wall_flags_0(k,j,i-1), 0 )  .OR.             &
+                     .NOT. BTEST( wall_flags_0(k,j,i+1), 0 ) )                 &
+                   l_wall(k,j,i) = MIN( l_wall(k,j,i), l_grid(k), 0.5_wp * dx )
+!
+!--              yz-distance (vertical edges, down)
+                 IF ( .NOT. BTEST( wall_flags_0(k-1,j-1,i), 0 )  .OR.          &
+                      .NOT. BTEST( wall_flags_0(k-1,j+1,i), 0 )  )             &
+                   l_wall(k,j,i) = MIN( l_wall(k,j,i), l_grid(k),              &
+                                        SQRT( 0.25_wp * dy**2 +                &
+                                       ( zu(k) - zw(k-1) )**2 ) )
+!
+!--              yz-distance (vertical edges, up)
+                 IF ( .NOT. BTEST( wall_flags_0(k+1,j-1,i), 0 )  .OR.          &
+                      .NOT. BTEST( wall_flags_0(k+1,j+1,i), 0 )  )             &
+                   l_wall(k,j,i) = MIN( l_wall(k,j,i), l_grid(k),              &
+                                        SQRT( 0.25_wp * dy**2 +                &
+                                       ( zw(k) - zu(k) )**2 ) )
+!
+!--              xz-distance (vertical edges, down)
+                 IF ( .NOT. BTEST( wall_flags_0(k-1,j,i-1), 0 )  .OR.          &
+                      .NOT. BTEST( wall_flags_0(k-1,j,i+1), 0 )  )             &
+                   l_wall(k,j,i) = MIN( l_wall(k,j,i), l_grid(k),              &
+                                        SQRT( 0.25_wp * dx**2 +                &
+                                       ( zu(k) - zw(k-1) )**2 ) )
+!
+!--              xz-distance (vertical edges, up)
+                 IF ( .NOT. BTEST( wall_flags_0(k+1,j,i-1), 0 )  .OR.          &
+                      .NOT. BTEST( wall_flags_0(k+1,j,i+1), 0 )  )             &
+                   l_wall(k,j,i) = MIN( l_wall(k,j,i), l_grid(k),              &
+                                        SQRT( 0.25_wp * dx**2 +                &
+                                       ( zw(k) - zu(k) )**2 ) )
+!
+!--             xy-distance (horizontal edges)
+                IF ( .NOT. BTEST( wall_flags_0(k,j-1,i-1), 0 )  .OR.           &
+                     .NOT. BTEST( wall_flags_0(k,j+1,i-1), 0 )  .OR.           &
+                     .NOT. BTEST( wall_flags_0(k,j-1,i+1), 0 )  .OR.           &
+                     .NOT. BTEST( wall_flags_0(k,j+1,i+1), 0 ) )               &
+                   l_wall(k,j,i) = MIN( l_wall(k,j,i), l_grid(k),              &
+                                        SQRT( 0.25_wp * ( dx**2 + dy**2 ) ) )
+!
+!--             xyz distance (vertical and horizontal edges, down)
+                IF ( .NOT. BTEST( wall_flags_0(k-1,j-1,i-1), 0 )  .OR.         &
+                     .NOT. BTEST( wall_flags_0(k-1,j+1,i-1), 0 )  .OR.         &
+                     .NOT. BTEST( wall_flags_0(k-1,j-1,i+1), 0 )  .OR.         &
+                     .NOT. BTEST( wall_flags_0(k-1,j+1,i+1), 0 ) )             &
+                   l_wall(k,j,i) = MIN( l_wall(k,j,i), l_grid(k),              &
+                                        SQRT( 0.25_wp * ( dx**2 + dy**2 )      &
+                                              +  ( zu(k) - zw(k-1) )**2  ) )
+!
+!--             xyz distance (vertical and horizontal edges, up)
+                IF ( .NOT. BTEST( wall_flags_0(k+1,j-1,i-1), 0 )  .OR.         &
+                     .NOT. BTEST( wall_flags_0(k+1,j+1,i-1), 0 )  .OR.         &
+                     .NOT. BTEST( wall_flags_0(k+1,j-1,i+1), 0 )  .OR.         &
+                     .NOT. BTEST( wall_flags_0(k+1,j+1,i+1), 0 ) )             &
+                   l_wall(k,j,i) = MIN( l_wall(k,j,i), l_grid(k),              &
+                                        SQRT( 0.25_wp * ( dx**2 + dy**2 )      &
+                                              +  ( zw(k) - zu(k) )**2  ) )
+                  
              ENDIF
-
-             IF ( wall_s(j,i) > 0 )  THEN
-!
-!--             South wall (y distance)
-                DO  k = wall_s(j,i), nzb_si
-                   l_wall(k,j-1,i) = MIN( l_wall(k,j-1,i), 0.5_wp * dy )
-                ENDDO
-!
-!--             Above south wall (yz distance)
-                DO  k = nzb_si + 1, nzb_si + vi
-                   l_wall(k,j-1,i) = MIN( l_wall(k,j-1,i),                     &
-                                          SQRT( 0.25_wp * dy**2 +              &
-                                          ( zu(k) - zw(nzb_si) )**2 ) )
-                ENDDO
-!
-!--             Southleft corner (xy distance)
-                IF ( corner_sl(j,i) > 0 )  THEN
-                   DO  k = corner_sl(j,i), nzb_si
-                      l_wall(k,j-1,i-1) = MIN( l_wall(k,j-1,i-1),              &
-                                               0.5_wp * SQRT( dx**2 + dy**2 ) )
-                   ENDDO
-!
-!--                Above southleft corner (xyz distance)
-                   DO  k = nzb_si + 1, nzb_si + vi
-                      l_wall(k,j-1,i-1) = MIN( l_wall(k,j-1,i-1),              &
-                                            SQRT( 0.25_wp * (dx**2 + dy**2) +  &
-                                            ( zu(k) - zw(nzb_si) )**2 ) )
-                   ENDDO
-                ENDIF
-!
-!--             Southright corner (xy distance)
-                IF ( corner_sr(j,i) > 0 )  THEN
-                   DO  k = corner_sr(j,i), nzb_si
-                      l_wall(k,j-1,i+1) = MIN( l_wall(k,j-1,i+1),              &
-                                               0.5_wp * SQRT( dx**2 + dy**2 ) )
-                   ENDDO
-!
-!--                Above southright corner (xyz distance)
-                   DO  k = nzb_si + 1, nzb_si + vi
-                      l_wall(k,j-1,i+1) = MIN( l_wall(k,j-1,i+1),              &
-                                            SQRT( 0.25_wp * (dx**2 + dy**2) +  &
-                                            ( zu(k) - zw(nzb_si) )**2 ) )
-                   ENDDO
-                ENDIF
-
-             ENDIF
-
-             IF ( wall_l(j,i) > 0 )  THEN
-!
-!--             Left wall (x distance)
-                DO  k = wall_l(j,i), nzb_si
-                   l_wall(k,j,i-1) = MIN( l_wall(k,j,i-1), 0.5_wp * dx )
-                ENDDO
-!
-!--             Above left wall (xz distance)
-                DO  k = nzb_si + 1, nzb_si + vi
-                   l_wall(k,j,i-1) = MIN( l_wall(k,j,i-1),                     &
-                                       SQRT( 0.25_wp * dx**2 +                 &
-                                       ( zu(k) - zw(nzb_si) )**2 ) )
-                ENDDO
-             ENDIF
-
-             IF ( wall_r(j,i) > 0 )  THEN
-!
-!--             Right wall (x distance)
-                DO  k = wall_r(j,i), nzb_si
-                   l_wall(k,j,i+1) = MIN( l_wall(k,j,i+1), 0.5_wp * dx )
-                ENDDO
-!
-!--             Above right wall (xz distance)
-                DO  k = nzb_si + 1, nzb_si + vi
-                   l_wall(k,j,i+1) = MIN( l_wall(k,j,i+1),                     &
-                                          SQRT( 0.25_wp * dx**2 +              &
-                                          ( zu(k) - zw(nzb_si) )**2 ) )
-                ENDDO
-
-             ENDIF
-
           ENDDO
        ENDDO
-
-    ENDIF
-
-!
-!-- Multiplication with wall_adjustment_factor
-    l_wall = wall_adjustment_factor * l_wall
-
+    ENDDO
 !
 !-- Set lateral boundary conditions for l_wall
-    CALL exchange_horiz( l_wall, nbgp )
-
-    DEALLOCATE( corner_nl, corner_nr, corner_sl, corner_sr, nzb_local, &
-                vertical_influence, wall_l, wall_n, wall_r, wall_s )
+    CALL exchange_horiz( l_wall, nbgp )     
 
 
Index: /palm/trunk/SOURCE/interaction_droplets_ptq.f90
===================================================================
--- /palm/trunk/SOURCE/interaction_droplets_ptq.f90	(revision 2231)
+++ /palm/trunk/SOURCE/interaction_droplets_ptq.f90	(revision 2232)
@@ -20,5 +20,5 @@
 ! Current revisions:
 ! -----------------
-! 
+! Adjustments to new topography concept
 ! 
 ! Former revisions:
@@ -106,5 +106,5 @@
            
        USE indices,                                                            &
-           ONLY:  nxl, nxr, nyn, nys, nzb_s_inner, nzt
+           ONLY:  nxl, nxr, nyn, nys, nzb, nzt, wall_flags_0
            
        USE kinds
@@ -114,14 +114,20 @@
        IMPLICIT NONE
 
-       INTEGER(iwp) ::  i !<
-       INTEGER(iwp) ::  j !<
-       INTEGER(iwp) ::  k !<
+       INTEGER(iwp) ::  i    !< running index x direction
+       INTEGER(iwp) ::  j    !< running index y direction 
+       INTEGER(iwp) ::  k    !< running index z direction
 
+       REAL(wp) ::  flag     !< flag to mask topography grid points
  
        DO  i = nxl, nxr
           DO  j = nys, nyn
-             DO  k = nzb_s_inner(j,i)+1, nzt
-                q_p(k,j,i)  = q_p(k,j,i)  - ql_c(k,j,i)
-                pt_p(k,j,i) = pt_p(k,j,i) + l_d_cp * ql_c(k,j,i) * pt_d_t(k)
+             DO  k = nzb+1, nzt
+!
+!--             Predetermine flag to mask topography
+                flag = MERGE( 1.0_wp, 0.0_wp, BTEST( wall_flags_0(k,j,i), 0 ) )
+
+                q_p(k,j,i)  = q_p(k,j,i)  - ql_c(k,j,i) * flag
+                pt_p(k,j,i) = pt_p(k,j,i) + l_d_cp * ql_c(k,j,i) * pt_d_t(k)   &
+                                                        * flag
              ENDDO
           ENDDO
@@ -145,5 +151,5 @@
 
        USE indices,                                                            &
-           ONLY:  nzb_s_inner, nzt
+           ONLY:  nzb, nzt, wall_flags_0
 
        USE kinds,                                                              &
@@ -154,12 +160,18 @@
        IMPLICIT NONE
 
-       INTEGER(iwp) ::  i !<
-       INTEGER(iwp) ::  j !<
-       INTEGER(iwp) ::  k !<
+       INTEGER(iwp) ::  i    !< running index x direction
+       INTEGER(iwp) ::  j    !< running index y direction 
+       INTEGER(iwp) ::  k    !< running index z direction
+
+       REAL(wp) ::  flag     !< flag to mask topography grid points
 
 
-       DO  k = nzb_s_inner(j,i)+1, nzt
-          q_p(k,j,i)  = q_p(k,j,i)  - ql_c(k,j,i)
-          pt_p(k,j,i) = pt_p(k,j,i) + l_d_cp * ql_c(k,j,i) * pt_d_t(k)
+       DO  k = nzb+1, nzt
+!
+!--       Predetermine flag to mask topography
+          flag = MERGE( 1.0_wp, 0.0_wp, BTEST( wall_flags_0(k,j,i), 0 ) )
+
+          q_p(k,j,i)  = q_p(k,j,i)  - ql_c(k,j,i) * flag
+          pt_p(k,j,i) = pt_p(k,j,i) + l_d_cp * ql_c(k,j,i) * pt_d_t(k) * flag
        ENDDO
 
Index: /palm/trunk/SOURCE/land_surface_model_mod.f90
===================================================================
--- /palm/trunk/SOURCE/land_surface_model_mod.f90	(revision 2231)
+++ /palm/trunk/SOURCE/land_surface_model_mod.f90	(revision 2232)
@@ -20,5 +20,10 @@
 ! Current revisions:
 ! -----------------
-! 
+! Adjustments to new topography and surface concept
+!   - now, also vertical walls are possible
+!   - for vertical walls, parametrization of r_a (aerodynamic resisistance) is 
+!     implemented. 
+!
+! Add check for soil moisture, it must not exceed its saturation value.
 ! 
 ! Former revisions:
@@ -159,4 +164,8 @@
 !> DALES and UCLA-LES models.
 !>
+!> @todo Extensive verification energy-balance solver for vertical surfaces, 
+!>       e.g. parametrization of r_a
+!> @todo Revise single land-surface processes for vertical surfaces, e.g. 
+!>       treatment of humidity, etc. 
 !> @todo Consider partial absorption of the net shortwave radiation by the 
 !>       skin layer.
@@ -174,6 +183,5 @@
  
     USE arrays_3d,                                                             &
-        ONLY:  hyp, ol, pt, pt_p, prr, q, q_p, ql, qsws, shf, ts, us, vpt, z0, &
-               z0h, z0q
+        ONLY:  hyp, pt, pt_p, prr, q, q_p, ql, vpt, u, v, w
 
     USE cloud_parameters,                                                      &
@@ -183,10 +191,10 @@
         ONLY:  cloud_physics, dt_3d, humidity, intermediate_timestep_count,    &
                initializing_actions, intermediate_timestep_count_max,          &
-               max_masks, precipitation, pt_surface,                           &
+               land_surface, max_masks, precipitation, pt_surface,             &
                rho_surface, roughness_length, surface_pressure,                &
                timestep_scheme, tsc, z0h_factor, time_since_reference_point
 
     USE indices,                                                               &
-        ONLY:  nbgp, nxlg, nxrg, nyng, nysg, nzb, nzb_s_inner 
+        ONLY:  nbgp, nxl, nxlg, nxr, nxrg, nyn, nyng, nys, nysg, nzb 
 
     USE kinds
@@ -196,11 +204,18 @@
     USE radiation_model_mod,                                                   &
         ONLY:  force_radiation_call, rad_net, rad_sw_in, rad_lw_out,           &
-               rad_lw_out_change_0, unscheduled_radiation_calls
+               rad_lw_out_change_0, radiation_scheme, unscheduled_radiation_calls
         
     USE statistics,                                                            &
         ONLY:  hom, statistic_regions
 
+    USE surface_mod,                                                        &
+        ONLY :  surf_lsm_h, surf_lsm_v, surf_type
+
     IMPLICIT NONE
 
+    TYPE surf_type_lsm
+       REAL(wp), DIMENSION(:),   ALLOCATABLE ::  var_1D !< 1D prognostic variable
+       REAL(wp), DIMENSION(:,:), ALLOCATABLE ::  var_2D !< 2D prognostic variable
+    END TYPE surf_type_lsm
 !
 !-- LSM model constants
@@ -225,14 +240,7 @@
                     soil_type = 3    !< NAMELIST soil_type_2d
 
-    INTEGER(iwp), DIMENSION(:,:), ALLOCATABLE ::  soil_type_2d, &  !< soil type, 0: user-defined, 1-7: generic (see list)
-                                                  veg_type_2d      !< vegetation type, 0: user-defined, 1-19: generic (see list)
-
-    LOGICAL, DIMENSION(:,:), ALLOCATABLE :: water_surface,     & !< flag parameter for water surfaces (classes 14+15)
-                                            pave_surface,      & !< flag parameter for pavements (asphalt etc.) (class 20)
-                                            building_surface     !< flag parameter indicating that the surface element is covered by buildings (no LSM actions, not implemented yet)
-
     LOGICAL :: conserve_water_content = .TRUE.,  & !< open or closed bottom surface for the soil model
-               force_radiation_call_l = .FALSE., & !< flag parameter for unscheduled radiation model calls
-               land_surface = .FALSE.              !< flag parameter indicating wheather the lsm is used
+               force_radiation_call_l = .FALSE., & !< flag to force calling of radiation routine
+               aero_resist_kray = .TRUE.           !< flag to control parametrization of aerodynamic resistance at vertical surface elements
 
 !   value 9999999.9_wp -> generic available or user-defined value must be set
@@ -288,100 +296,114 @@
               dz_soil                                                            !< soil grid spacing (edge-edge)
 
+
 #if defined( __nopointer )
-    REAL(wp), DIMENSION(:,:), ALLOCATABLE, TARGET :: t_surface,   & !< surface temperature (K)
-                                                     t_surface_p, & !< progn. surface temperature (K)
-                                                     m_liq_eb,    & !< liquid water reservoir (m)
-                                                     m_liq_eb_av, & !< liquid water reservoir (m)
-                                                     m_liq_eb_p     !< progn. liquid water reservoir (m)
+    TYPE(surf_type_lsm), TARGET  ::  t_soil_h,    & !< Soil temperature (K), horizontal surface elements
+                                     t_soil_h_p,  & !< Prog. soil temperature (K), horizontal surface elements
+                                     m_soil_h,    & !< Soil moisture (m3/m3), horizontal surface elements
+                                     m_soil_h_p     !< Prog. soil moisture (m3/m3), horizontal surface elements
+
+    TYPE(surf_type_lsm), DIMENSION(0:3), TARGET  ::  &
+                                     t_soil_v,    & !< Soil temperature (K), vertical surface elements
+                                     t_soil_v_p,  & !< Prog. soil temperature (K), vertical surface elements
+                                     m_soil_v,    & !< Soil moisture (m3/m3), vertical surface elements
+                                     m_soil_v_p     !< Prog. soil moisture (m3/m3), vertical surface elements
 #else
-    REAL(wp), DIMENSION(:,:), POINTER :: t_surface,      &
-                                         t_surface_p,    & 
-                                         m_liq_eb,       & 
-                                         m_liq_eb_p
-
-    REAL(wp), DIMENSION(:,:), ALLOCATABLE, TARGET :: t_surface_1, t_surface_2, &
-                                                     m_liq_eb_av,              &
-                                                     m_liq_eb_1, m_liq_eb_2
+    TYPE(surf_type_lsm), POINTER ::  t_soil_h,    & !< Soil temperature (K), horizontal surface elements
+                                     t_soil_h_p,  & !< Prog. soil temperature (K), horizontal surface elements
+                                     m_soil_h,    & !< Soil moisture (m3/m3), horizontal surface elements
+                                     m_soil_h_p     !< Prog. soil moisture (m3/m3), horizontal surface elements 
+
+    TYPE(surf_type_lsm), TARGET  ::  t_soil_h_1,  & !<
+                                     t_soil_h_2,  & !<
+                                     m_soil_h_1,  & !<
+                                     m_soil_h_2     !<
+
+    TYPE(surf_type_lsm), DIMENSION(:), POINTER :: &
+                                     t_soil_v,    & !< Soil temperature (K), vertical surface elements
+                                     t_soil_v_p,  & !< Prog. soil temperature (K), vertical surface elements
+                                     m_soil_v,    & !< Soil moisture (m3/m3), vertical surface elements
+                                     m_soil_v_p     !< Prog. soil moisture (m3/m3), vertical surface elements   
+
+    TYPE(surf_type_lsm), DIMENSION(0:3), TARGET ::&
+                                     t_soil_v_1,  & !<
+                                     t_soil_v_2,  & !<
+                                     m_soil_v_1,  & !<
+                                     m_soil_v_2     !<
+#endif    
+
+#if defined( __nopointer )
+    TYPE(surf_type_lsm), TARGET   ::  t_surface_h,    & !< surface temperature (K), horizontal surface elements 
+                                      t_surface_h_p,  & !< progn. surface temperature (K), horizontal surface elements 
+                                      m_liq_eb_h,     & !< liquid water reservoir (m), horizontal surface elements 
+                                      m_liq_eb_h_p      !< progn. liquid water reservoir (m), horizontal surface elements 
+
+    TYPE(surf_type_lsm), DIMENSION(0:3), TARGET   ::  &
+                                      t_surface_v,    & !< surface temperature (K), vertical surface elements 
+                                      t_surface_v_p,  & !< progn. surface temperature (K), vertical surface elements 
+                                      m_liq_eb_v,     & !< liquid water reservoir (m), vertical surface elements 
+                                      m_liq_eb_v_p      !< progn. liquid water reservoir (m), vertical surface elements 
+#else
+    TYPE(surf_type_lsm), POINTER  ::  t_surface_h,    & !< surface temperature (K), horizontal surface elements 
+                                      t_surface_h_p,  & !< progn. surface temperature (K), horizontal surface elements 
+                                      m_liq_eb_h,     & !< liquid water reservoir (m), horizontal surface elements 
+                                      m_liq_eb_h_p      !< progn. liquid water reservoir (m), horizontal surface elements 
+
+    TYPE(surf_type_lsm), TARGET   ::  t_surface_h_1,  & !<
+                                      t_surface_h_2,  & !<
+                                      m_liq_eb_h_1,   & !<
+                                      m_liq_eb_h_2      !<
+
+    TYPE(surf_type_lsm), DIMENSION(:), POINTER  ::    &
+                                      t_surface_v,    & !< surface temperature (K), vertical surface elements 
+                                      t_surface_v_p,  & !< progn. surface temperature (K), vertical surface elements 
+                                      m_liq_eb_v,     & !< liquid water reservoir (m), vertical surface elements 
+                                      m_liq_eb_v_p      !< progn. liquid water reservoir (m), vertical surface elements 
+
+    TYPE(surf_type_lsm), DIMENSION(0:3), TARGET   ::  &
+                                      t_surface_v_1,  & !<
+                                      t_surface_v_2,  & !<
+                                      m_liq_eb_v_1,   & !<
+                                      m_liq_eb_v_2      !<
 #endif
 
-!
-!-- Temporal tendencies for time stepping            
-    REAL(wp), DIMENSION(:,:), ALLOCATABLE :: tt_surface_m,  & !< surface temperature tendency (K)
-                                             tm_liq_eb_m      !< liquid water reservoir tendency (m)
+#if defined( __nopointer )
+    REAL(wp), DIMENSION(:,:), ALLOCATABLE, TARGET :: m_liq_eb_av
+#else
+    REAL(wp), DIMENSION(:,:), ALLOCATABLE, TARGET :: m_liq_eb_av
+#endif
+
+#if defined( __nopointer )
+    REAL(wp), DIMENSION(:,:,:), ALLOCATABLE, TARGET ::  t_soil_av, & !< Average of t_soil
+                                                        m_soil_av    !< Average of m_soil
+#else
+    REAL(wp), DIMENSION(:,:,:), ALLOCATABLE, TARGET ::  t_soil_av, & !< Average of t_soil
+                                                        m_soil_av    !< Average of m_soil
+#endif
+
+    TYPE(surf_type_lsm), TARGET ::  tm_liq_eb_h_m   !< liquid water reservoir tendency (m), horizontal surface elements 
+    TYPE(surf_type_lsm), TARGET ::  tt_surface_h_m  !< surface temperature tendency (K), horizontal surface elements 
+    TYPE(surf_type_lsm), TARGET ::  tt_soil_h_m     !< t_soil storage array, horizontal surface elements 
+    TYPE(surf_type_lsm), TARGET ::  tm_soil_h_m     !< m_soil storage array, horizontal surface elements 
+
+    TYPE(surf_type_lsm), DIMENSION(0:3), TARGET ::  tm_liq_eb_v_m   !< liquid water reservoir tendency (m), vertical surface elements 
+    TYPE(surf_type_lsm), DIMENSION(0:3), TARGET ::  tt_surface_v_m  !< surface temperature tendency (K), vertical surface elements 
+    TYPE(surf_type_lsm), DIMENSION(0:3), TARGET ::  tt_soil_v_m     !< t_soil storage array, vertical surface elements 
+    TYPE(surf_type_lsm), DIMENSION(0:3), TARGET ::  tm_soil_v_m     !< m_soil storage array, vertical surface elements 
 
 !
 !-- Energy balance variables                
     REAL(wp), DIMENSION(:,:), ALLOCATABLE :: &
-              alpha_vg,         & !< coef. of Van Genuchten
-              c_liq,            & !< liquid water coverage (of vegetated area)
               c_liq_av,         & !< average of c_liq
               c_soil_av,        & !< average of c_soil
-              c_veg,            & !< vegetation coverage
               c_veg_av,         & !< average of c_veg
-              f_sw_in,          & !< fraction of absorbed shortwave radiation by the surface layer (not implemented yet)
-              ghf_eb,           & !< ground heat flux
               ghf_eb_av,        & !< average of ghf_eb
-              gamma_w_sat,      & !< hydraulic conductivity at saturation
-              g_d,              & !< coefficient for dependence of r_canopy on water vapour pressure deficit
-              lai,              & !< leaf area index
               lai_av,           & !< average of lai
-              lambda_surface_s, & !< coupling between surface and soil (depends on vegetation type)
-              lambda_surface_u, & !< coupling between surface and soil (depends on vegetation type)
-              l_vg,             & !< coef. of Van Genuchten
-              m_fc,             & !< soil moisture at field capacity (m3/m3)
-              m_res,            & !< residual soil moisture
-              m_sat,            & !< saturation soil moisture (m3/m3)
-              m_wilt,           & !< soil moisture at permanent wilting point (m3/m3)
-              n_vg,             & !< coef. Van Genuchten  
-              qsws_eb,          & !< surface flux of latent heat (total)
               qsws_eb_av,       & !< average of qsws_eb
-              qsws_liq_eb,      & !< surface flux of latent heat (liquid water portion)
               qsws_liq_eb_av,   & !< average of qsws_liq_eb
-              qsws_soil_eb,     & !< surface flux of latent heat (soil portion)
               qsws_soil_eb_av,  & !< average of qsws_soil_eb
-              qsws_veg_eb,      & !< surface flux of latent heat (vegetation portion)
               qsws_veg_eb_av,   & !< average of qsws_veg_eb
-              rad_net_l,        & !< local copy of rad_net (net radiation at surface)
-              r_a,              & !< aerodynamic resistance 
               r_a_av,           & !< average of r_a
-              r_canopy,         & !< canopy resistance
-              r_soil,           & !< soil resistance
-              r_soil_min,       & !< minimum soil resistance
-              r_s,              & !< total surface resistance (combination of r_soil and r_canopy)
               r_s_av,           & !< average of r_s
-              r_canopy_min,     & !< minimum canopy (stomatal) resistance
-              shf_eb,           & !< surface flux of sensible heat
               shf_eb_av           !< average of shf_eb
-
-
-    REAL(wp), DIMENSION(:,:,:), ALLOCATABLE ::                                 &
-              lambda_h, &   !< heat conductivity of soil (W/m/K)                            
-              lambda_w, &   !< hydraulic diffusivity of soil (?)
-              gamma_w,  &   !< hydraulic conductivity of soil (W/m/K)
-              rho_c_total   !< volumetric heat capacity of the actual soil matrix (?) 
-
-#if defined( __nopointer )
-    REAL(wp), DIMENSION(:,:,:), ALLOCATABLE, TARGET ::                         &
-              t_soil,    & !< Soil temperature (K)
-              t_soil_av, & !< Average of t_soil
-              t_soil_p,  & !< Prog. soil temperature (K)
-              m_soil,    & !< Soil moisture (m3/m3)
-              m_soil_av, & !< Average of m_soil
-              m_soil_p     !< Prog. soil moisture (m3/m3)
-#else
-    REAL(wp), DIMENSION(:,:,:), POINTER ::                                     &
-              t_soil, t_soil_p, &
-              m_soil, m_soil_p    
-
-    REAL(wp), DIMENSION(:,:,:), ALLOCATABLE, TARGET ::                         &
-              t_soil_av, t_soil_1, t_soil_2,                                   &
-              m_soil_av, m_soil_1, m_soil_2
-#endif
-
-
-    REAL(wp), DIMENSION(:,:,:), ALLOCATABLE ::                                 &
-              tt_soil_m, & !< t_soil storage array
-              tm_soil_m, & !< m_soil storage array
-              root_fr      !< root fraction (sum=1) 
 
 
@@ -571,5 +593,5 @@
 !
 !-- Public parameters, constants and initial values
-    PUBLIC land_surface, skip_time_do_lsm
+    PUBLIC aero_resist_kray, skip_time_do_lsm
 
 !
@@ -578,11 +600,6 @@
 
 !
-!-- Public 2D output variables
-    PUBLIC ghf_eb, qsws_eb, qsws_liq_eb, qsws_soil_eb,qsws_veg_eb, r_a, r_s,   &
-           shf_eb
-
-!
 !-- Public prognostic variables
-    PUBLIC m_soil, t_soil
+    PUBLIC m_soil_h, t_soil_h
 
 
@@ -871,5 +888,5 @@
     USE control_parameters,                                                    &
         ONLY:  bc_pt_b, bc_q_b, constant_flux_layer, message_string,           &
-               most_method, topography
+               most_method
                  
     USE radiation_model_mod,                                                   &
@@ -879,5 +896,5 @@
     IMPLICIT NONE
 
- 
+    INTEGER(iwp) ::  k        !< running index, z-dimension
 !
 !-- Dirichlet boundary conditions are required as the surface fluxes are
@@ -897,10 +914,4 @@
     ENDIF
 
-    IF ( topography /= 'flat' )  THEN
-       message_string = 'lsm cannot be used ' //                            & 
-                        'in combination with  topography /= "flat"'
-       CALL message( 'check_parameters', 'PA0415', 1, 2, 0, 6, 0 )
-    ENDIF
-
     IF ( ( veg_type == 14  .OR.  veg_type == 15 ) .AND.                     &
            most_method == 'lookup' )  THEN
@@ -1044,4 +1055,14 @@
 
     ENDIF
+!
+!-- Check for proper setting of soil moisture, must not be larger than its 
+!-- saturation value. 
+    DO  k = nzb_soil, nzt_soil
+       IF ( soil_moisture(k) > m_soil_pars(0,soil_type) )  THEN 
+          message_string = 'soil_moisture must not exceed its saturation' // &
+                           ' value'
+          CALL message( 'check_parameters', 'PA0403', 1, 2, 0, 6, 0 )
+       ENDIF
+    ENDDO
 
     IF (  .NOT.  radiation )  THEN
@@ -1059,5 +1080,5 @@
 !> Solver for the energy balance at the surface.
 !------------------------------------------------------------------------------!
- SUBROUTINE lsm_energy_balance
+ SUBROUTINE lsm_energy_balance( horizontal, l )
 
 
@@ -1065,6 +1086,15 @@
 
     INTEGER(iwp) ::  i         !< running index
+    INTEGER(iwp) ::  i_off     !< offset to determine index of surface element, seen from atmospheric grid point, for x
     INTEGER(iwp) ::  j         !< running index
-    INTEGER(iwp) ::  k, ks     !< running index
+    INTEGER(iwp) ::  j_off     !< offset to determine index of surface element, seen from atmospheric grid point, for y
+    INTEGER(iwp) ::  k         !< running index
+    INTEGER(iwp) ::  k_off     !< offset to determine index of surface element, seen from atmospheric grid point, for z
+    INTEGER(iwp) ::  k_rad     !< index to access radiation array
+    INTEGER(iwp) ::  ks        !< running index
+    INTEGER(iwp) ::  l         !< surface-facing index
+    INTEGER(iwp) ::  m         !< running index concerning wall elements
+
+    LOGICAL      ::  horizontal !< Flag indicating horizontal or vertical surfaces
 
     REAL(wp) :: c_surface_tmp,& !< temporary variable for storing the volumetric heat capacity of the surface
@@ -1090,166 +1120,235 @@
                 qv1            !< specific humidity at first grid level
 
+    TYPE(surf_type_lsm), POINTER ::  surf_t_surface
+    TYPE(surf_type_lsm), POINTER ::  surf_t_surface_p
+    TYPE(surf_type_lsm), POINTER ::  surf_tt_surface_m
+    TYPE(surf_type_lsm), POINTER ::  surf_m_liq_eb
+    TYPE(surf_type_lsm), POINTER ::  surf_m_liq_eb_p
+    TYPE(surf_type_lsm), POINTER ::  surf_tm_liq_eb_m
+
+    TYPE(surf_type_lsm), POINTER ::  surf_m_soil
+    TYPE(surf_type_lsm), POINTER ::  surf_t_soil
+
+    TYPE(surf_type), POINTER  ::  surf  !< surface-date type variable
+
+    IF ( horizontal )  THEN
+       surf              => surf_lsm_h
+
+       surf_t_surface    => t_surface_h
+       surf_t_surface_p  => t_surface_h_p
+       surf_tt_surface_m => tt_surface_h_m
+       surf_m_liq_eb     => m_liq_eb_h
+       surf_m_liq_eb_p   => m_liq_eb_h_p
+       surf_tm_liq_eb_m  => tm_liq_eb_h_m
+       surf_m_soil       => m_soil_h
+       surf_t_soil       => t_soil_h
+
+       k_off     = -1
+       j_off     = 0
+       i_off     = 0
+    ELSE
+       surf              => surf_lsm_v(l)
+
+       surf_t_surface    => t_surface_v(l)
+       surf_t_surface_p  => t_surface_v_p(l)
+       surf_tt_surface_m => tt_surface_v_m(l)
+       surf_m_liq_eb     => m_liq_eb_v(l)
+       surf_m_liq_eb_p   => m_liq_eb_v_p(l)
+       surf_tm_liq_eb_m  => tm_liq_eb_v_m(l)
+       surf_m_soil       => m_soil_v(l)
+       surf_t_soil       => t_soil_v(l)
+
+       k_off = 0
+       IF ( l == 0 )  THEN 
+          j_off = -1 
+          i_off = 0
+       ELSEIF ( l == 1 )  THEN 
+          j_off = 1 
+          i_off = 0
+       ELSEIF ( l == 2 )  THEN 
+          j_off = 0 
+          i_off = -1
+       ELSEIF ( l == 3 )  THEN 
+          j_off = 0 
+          i_off = 1
+       ENDIF
+    ENDIF
+
 !
 !-- Calculate the exner function for the current time step
     exn = ( surface_pressure / 1000.0_wp )**0.286_wp
 
-    DO  i = nxlg, nxrg
-       DO  j = nysg, nyng
-          k = nzb_s_inner(j,i)
-
-!
-!--       Set lambda_surface according to stratification between skin layer and soil
-          IF (  .NOT.  pave_surface(j,i) )  THEN
-
-             c_surface_tmp = c_surface
-
-             IF ( t_surface(j,i) >= t_soil(nzb_soil,j,i))  THEN
-                lambda_surface = lambda_surface_s(j,i)
-             ELSE
-                lambda_surface = lambda_surface_u(j,i)
-             ENDIF
+    DO  m = 1, surf%ns
+
+       i   = surf%i(m)            
+       j   = surf%j(m)
+       k   = surf%k(m)
+!
+!--    Determine height index for radiation. Note, in clear-sky case radiation
+!--    arrays have rank 0 in first dimensions, so index must be zero. In case
+!--    of RRTMG radiation arrays have non-zero rank in first dimension, so that 
+!--    radiation can be obtained at respective height level
+       k_rad = MERGE( 0, k + k_off, radiation_scheme /= 'rrtmg' )
+!
+!--    Set lambda_surface according to stratification between skin layer and soil
+       IF (  .NOT.  surf%pave_surface(m) )  THEN
+
+          c_surface_tmp = c_surface
+
+          IF ( surf_t_surface%var_1d(m) >= surf_t_soil%var_2d(nzb_soil,m))  THEN
+             lambda_surface = surf%lambda_surface_s(m)
           ELSE
-
-             c_surface_tmp = pave_heat_capacity * dz_soil(nzb_soil) * 0.5_wp
-             lambda_surface = pave_heat_conductivity * ddz_soil(nzb_soil)
-
-          ENDIF
-
-!
-!--       First step: calculate aerodyamic resistance. As pt, us, ts
-!--       are not available for the prognostic time step, data from the last
-!--       time step is used here. Note that this formulation is the
-!--       equivalent to the ECMWF formulation using drag coefficients
-          IF ( cloud_physics )  THEN
-             pt1 = pt(k+1,j,i) + l_d_cp * pt_d_t(k+1) * ql(k+1,j,i)
-             qv1 = q(k+1,j,i) - ql(k+1,j,i)
-          ELSE
-             pt1 = pt(k+1,j,i)
-             qv1 = q(k+1,j,i)
-          ENDIF
-
-          r_a(j,i) = (pt1 - pt(k,j,i)) / (ts(j,i) * us(j,i) + 1.0E-20_wp)
-
-!
-!--       Make sure that the resistance does not drop to zero for neutral 
-!--       stratification
-          IF ( ABS(r_a(j,i)) < 1.0_wp )  r_a(j,i) = 1.0_wp
-
-!
-!--       Second step: calculate canopy resistance r_canopy
-!--       f1-f3 here are defined as 1/f1-f3 as in ECMWF documentation
+             lambda_surface = surf%lambda_surface_u(m)
+          ENDIF
+       ELSE
+
+          c_surface_tmp = pave_heat_capacity * dz_soil(nzb_soil) * 0.5_wp
+          lambda_surface = pave_heat_conductivity * ddz_soil(nzb_soil)
+
+       ENDIF
+
+!
+!--    First step: calculate aerodyamic resistance. As pt, us, ts
+!--    are not available for the prognostic time step, data from the last
+!--    time step is used here. Note that this formulation is the
+!--    equivalent to the ECMWF formulation using drag coefficients
+       IF ( cloud_physics )  THEN
+          pt1 = pt(k,j,i) + l_d_cp * pt_d_t(k) * ql(k,j,i)
+          qv1 = q(k,j,i) - ql(k,j,i)
+       ELSE
+          pt1 = pt(k,j,i)
+          qv1 = q(k,j,i)
+       ENDIF
+!
+!--    Calculate aerodynamical resistance. For horizontal and vertical 
+!--    surfaces MOST is applied. Moreover, for vertical surfaces, resistance
+!--    can be obtain via parameterization of Mason (2000) / 
+!--    Krayenhoff and Voogt (2006).
+!--    To do: detailed investigation which approach is better!
+       IF ( horizontal  .OR.  .NOT. aero_resist_kray )  THEN
+          surf%r_a(m) = ( pt1 - surf_lsm_h%pt_surface(m) ) /                   &
+                        ( surf%ts(m) * surf%us(m) + 1.0E-20_wp )
+       ELSE
+          surf%r_a(m) = 1.0_wp / ( 11.8_wp + 4.2_wp *                          &
+                        SQRT( ( ( u(k,j,i) + u(k,j,i+1) ) * 0.5_wp )**2 +      &
+                              ( ( v(k,j,i) + v(k,j+1,i) ) * 0.5_wp )**2 +      &
+                              ( ( w(k,j,i) + w(k-1,j,i) ) * 0.5_wp )**2 )      &
+                                 )
+       ENDIF
+!
+!--    Make sure that the resistance does not drop to zero for neutral 
+!--    stratification
+       IF ( ABS( surf%r_a(m) ) < 1.0_wp )  surf%r_a(m) = 1.0_wp
+!
+!--    Second step: calculate canopy resistance r_canopy
+!--    f1-f3 here are defined as 1/f1-f3 as in ECMWF documentation
  
-!--       f1: correction for incoming shortwave radiation (stomata close at 
-!--       night)
-          f1 = MIN( 1.0_wp, ( 0.004_wp * rad_sw_in(k,j,i) + 0.05_wp ) /        &
-                           (0.81_wp * (0.004_wp * rad_sw_in(k,j,i)             &
-                            + 1.0_wp)) )
-
-
-
-!
-!--       f2: correction for soil moisture availability to plants (the 
-!--       integrated soil moisture must thus be considered here)
-!--       f2 = 0 for very dry soils
-          m_total = 0.0_wp
-          DO  ks = nzb_soil, nzt_soil
-              m_total = m_total + root_fr(ks,j,i)                              &
-                        * MAX(m_soil(ks,j,i),m_wilt(j,i))
-          ENDDO 
-
-          IF ( m_total > m_wilt(j,i)  .AND.  m_total < m_fc(j,i) )  THEN
-             f2 = ( m_total - m_wilt(j,i) ) / (m_fc(j,i) - m_wilt(j,i) )
-          ELSEIF ( m_total >= m_fc(j,i) )  THEN
-             f2 = 1.0_wp
-          ELSE
-             f2 = 1.0E-20_wp
-          ENDIF
-
-!
-!--       Calculate water vapour pressure at saturation 
-          e_s = 0.01_wp * 610.78_wp * EXP( 17.269_wp * ( t_surface(j,i)        &
-                        - 273.16_wp ) / ( t_surface(j,i) - 35.86_wp ) )
-
-!
-!--       f3: correction for vapour pressure deficit
-          IF ( g_d(j,i) /= 0.0_wp )  THEN
-!
-!--          Calculate vapour pressure
-             e  = qv1 * surface_pressure / 0.622_wp
-             f3 = EXP ( -g_d(j,i) * (e_s - e) )
-          ELSE
-             f3 = 1.0_wp
-          ENDIF
-
-!
-!--       Calculate canopy resistance. In case that c_veg is 0 (bare soils),
-!--       this calculation is obsolete, as r_canopy is not used below.
-!--       To do: check for very dry soil -> r_canopy goes to infinity
-          r_canopy(j,i) = r_canopy_min(j,i) / (lai(j,i) * f1 * f2 * f3         &
-                                          + 1.0E-20_wp)
-
-!
-!--       Third step: calculate bare soil resistance r_soil. The Clapp & 
-!--       Hornberger parametrization does not consider c_veg.
-          IF ( soil_type_2d(j,i) /= 7 )  THEN
-             m_min = c_veg(j,i) * m_wilt(j,i) + (1.0_wp - c_veg(j,i)) *        &
-                     m_res(j,i)
-          ELSE
-             m_min = m_wilt(j,i)
-          ENDIF
-
-          f2 = ( m_soil(nzb_soil,j,i) - m_min ) / ( m_fc(j,i) - m_min )
-          f2 = MAX(f2,1.0E-20_wp)
-          f2 = MIN(f2,1.0_wp)
-
-          r_soil(j,i) = r_soil_min(j,i) / f2
-
-!
-!--       Calculate the maximum possible liquid water amount on plants and
-!--       bare surface. For vegetated surfaces, a maximum depth of 0.2 mm is
-!--       assumed, while paved surfaces might hold up 1 mm of water. The 
-!--       liquid water fraction for paved surfaces is calculated after 
-!--       Noilhan & Planton (1989), while the ECMWF formulation is used for
-!--       vegetated surfaces and bare soils.
-          IF ( pave_surface(j,i) )  THEN
-             m_liq_eb_max = m_max_depth * 5.0_wp
-             c_liq(j,i) = MIN( 1.0_wp, (m_liq_eb(j,i) / m_liq_eb_max)**0.67 )
-          ELSE
-             m_liq_eb_max = m_max_depth * ( c_veg(j,i) * lai(j,i)              &
-                            + (1.0_wp - c_veg(j,i)) )
-             c_liq(j,i) = MIN( 1.0_wp, m_liq_eb(j,i) / m_liq_eb_max )
-          ENDIF
-
-!
-!--       Calculate saturation specific humidity
-          q_s = 0.622_wp * e_s / surface_pressure
-
-!
-!--       In case of dewfall, set evapotranspiration to zero
-!--       All super-saturated water is then removed from the air
-          IF ( humidity  .AND.  q_s <= qv1 )  THEN
-             r_canopy(j,i) = 0.0_wp
-             r_soil(j,i)   = 0.0_wp
-          ENDIF
-
-!
-!--       Calculate coefficients for the total evapotranspiration 
-!--       In case of water surface, set vegetation and soil fluxes to zero.
-!--       For pavements, only evaporation of liquid water is possible.
-          IF ( water_surface(j,i) )  THEN
-             f_qsws_veg  = 0.0_wp
-             f_qsws_soil = 0.0_wp
-             f_qsws_liq  = rho_lv / r_a(j,i)
-          ELSEIF ( pave_surface (j,i) )  THEN
-             f_qsws_veg  = 0.0_wp
-             f_qsws_soil = 0.0_wp
-             f_qsws_liq  = rho_lv * c_liq(j,i) / r_a(j,i)
-          ELSE
-             f_qsws_veg  = rho_lv * c_veg(j,i) * (1.0_wp - c_liq(j,i))/        &
-                           (r_a(j,i) + r_canopy(j,i))
-             f_qsws_soil = rho_lv * (1.0_wp - c_veg(j,i)) / (r_a(j,i) +        &
-                                                             r_soil(j,i))
-             f_qsws_liq  = rho_lv * c_veg(j,i) * c_liq(j,i) / r_a(j,i)
-          ENDIF
+!--    f1: correction for incoming shortwave radiation (stomata close at 
+!--    night)
+       f1 = MIN( 1.0_wp, ( 0.004_wp * rad_sw_in(k_rad,j+j_off,i+i_off) + 0.05_wp ) /&
+                        (0.81_wp * (0.004_wp * rad_sw_in(k_rad,j+j_off,i+i_off)&
+                         + 1.0_wp)) )
+!
+!--    f2: correction for soil moisture availability to plants (the 
+!--    integrated soil moisture must thus be considered here)
+!--    f2 = 0 for very dry soils
+       m_total = 0.0_wp
+       DO  ks = nzb_soil, nzt_soil
+           m_total = m_total + surf%root_fr(ks,m)                              &
+                     * MAX( surf_m_soil%var_2d(ks,m), surf%m_wilt(m) )
+       ENDDO 
+
+       IF ( m_total > surf%m_wilt(m)  .AND.                                    &
+            m_total < surf%m_fc(m) )  THEN
+          f2 = ( m_total - surf%m_wilt(m) ) /                                  &
+               ( surf%m_fc(m) - surf%m_wilt(m) )
+       ELSEIF ( m_total >= surf%m_fc(m) )  THEN
+          f2 = 1.0_wp
+       ELSE
+          f2 = 1.0E-20_wp
+       ENDIF
+!
+!--    Calculate water vapour pressure at saturation 
+       e_s = 0.01_wp * 610.78_wp * EXP( 17.269_wp * ( surf_t_surface%var_1d(m) &
+                     - 273.16_wp ) / ( surf_t_surface%var_1d(m) - 35.86_wp ) )
+!
+!--    f3: correction for vapour pressure deficit
+       IF ( surf%g_d(m) /= 0.0_wp )  THEN
+!
+!--       Calculate vapour pressure
+          e  = qv1 * surface_pressure / 0.622_wp
+          f3 = EXP ( - surf%g_d(m) * (e_s - e) )
+       ELSE
+          f3 = 1.0_wp
+       ENDIF
+!
+!--    Calculate canopy resistance. In case that c_veg is 0 (bare soils),
+!--    this calculation is obsolete, as r_canopy is not used below.
+!--    To do: check for very dry soil -> r_canopy goes to infinity
+       surf%r_canopy(m) = surf%r_canopy_min(m) /                               &
+                              ( surf%lai(m) * f1 * f2 * f3 + 1.0E-20_wp )
+!
+!--    Third step: calculate bare soil resistance r_soil. The Clapp & 
+!--    Hornberger parametrization does not consider c_veg.
+       IF ( surf%soil_type_2d(m) /= 7 )  THEN
+          m_min = surf%c_veg(m) * surf%m_wilt(m) +                             &
+                         ( 1.0_wp - surf%c_veg(m) ) * surf%m_res(m)
+       ELSE
+          m_min = surf%m_wilt(m)
+       ENDIF
+
+       f2 = ( surf_m_soil%var_2d(nzb_soil,m) - m_min ) / ( surf%m_fc(m) - m_min )
+       f2 = MAX( f2, 1.0E-20_wp )
+       f2 = MIN( f2, 1.0_wp     )
+
+       surf%r_soil(m) = surf%r_soil_min(m) / f2
+
+!
+!--    Calculate the maximum possible liquid water amount on plants and
+!--    bare surface. For vegetated surfaces, a maximum depth of 0.2 mm is
+!--    assumed, while paved surfaces might hold up 1 mm of water. The 
+!--    liquid water fraction for paved surfaces is calculated after 
+!--    Noilhan & Planton (1989), while the ECMWF formulation is used for
+!--    vegetated surfaces and bare soils.
+       IF ( surf%pave_surface(m) )  THEN
+          m_liq_eb_max = m_max_depth * 5.0_wp
+          surf%c_liq(m) = MIN( 1.0_wp, ( surf_m_liq_eb%var_1d(m) / m_liq_eb_max)**0.67 )
+       ELSE
+          m_liq_eb_max = m_max_depth * ( surf%c_veg(m) * surf%lai(m)&
+                            + ( 1.0_wp - surf%c_veg(m) ) )
+          surf%c_liq(m) = MIN( 1.0_wp, surf_m_liq_eb%var_1d(m) / m_liq_eb_max )
+       ENDIF
+!
+!--    Calculate saturation specific humidity
+       q_s = 0.622_wp * e_s / surface_pressure
+!
+!--    In case of dewfall, set evapotranspiration to zero
+!--    All super-saturated water is then removed from the air
+       IF ( humidity  .AND.  q_s <= qv1 )  THEN
+          surf%r_canopy(m) = 0.0_wp
+          surf%r_soil(m)   = 0.0_wp
+       ENDIF
+
+!
+!--    Calculate coefficients for the total evapotranspiration 
+!--    In case of water surface, set vegetation and soil fluxes to zero.
+!--    For pavements, only evaporation of liquid water is possible.
+       IF ( surf%water_surface(m) )  THEN
+          f_qsws_veg  = 0.0_wp
+          f_qsws_soil = 0.0_wp
+          f_qsws_liq  = rho_lv / surf%r_a(m)
+       ELSEIF ( surf%pave_surface (m) )  THEN
+          f_qsws_veg  = 0.0_wp
+          f_qsws_soil = 0.0_wp
+          f_qsws_liq  = rho_lv * surf%c_liq(m) / surf%r_a(m)
+       ELSE
+          f_qsws_veg  = rho_lv * surf%c_veg(m) *                               &
+                            ( 1.0_wp        - surf%c_liq(m)    ) /             &
+                            ( surf%r_a(m) + surf%r_canopy(m) )
+          f_qsws_soil = rho_lv * (1.0_wp    - surf%c_veg(m)    ) /             &
+                            ( surf%r_a(m) + surf%r_soil(m)   )
+          f_qsws_liq  = rho_lv * surf%c_veg(m) * surf%c_liq(m)   /             &
+                              surf%r_a(m)
+       ENDIF
 !
 !--       If soil moisture is below wilting point, plants do no longer
@@ -1259,233 +1358,228 @@
 !           ENDIF
 
-          f_shf  = rho_cp / r_a(j,i)
-          f_qsws = f_qsws_veg + f_qsws_soil + f_qsws_liq
-
-!
-!--       Calculate derivative of q_s for Taylor series expansion
-          e_s_dt = e_s * ( 17.269_wp / (t_surface(j,i) - 35.86_wp) -           &
-                           17.269_wp*(t_surface(j,i) - 273.16_wp)              &
-                           / (t_surface(j,i) - 35.86_wp)**2 )
-
-          dq_s_dt = 0.622_wp * e_s_dt / surface_pressure
-
-!
-!--       Add LW up so that it can be removed in prognostic equation
-          rad_net_l(j,i) = rad_net(j,i) + rad_lw_out(nzb,j,i)
-
-!
-!--       Calculate new skin temperature
-          IF ( humidity )  THEN
-
-!
-!--          Numerator of the prognostic equation
-             coef_1 = rad_net_l(j,i) + rad_lw_out_change_0(j,i)                &
-                      * t_surface(j,i) - rad_lw_out(nzb,j,i)                   &
-                      + f_shf * pt1 + f_qsws * ( qv1 - q_s                     &
-                      + dq_s_dt * t_surface(j,i) ) + lambda_surface            &
-                      * t_soil(nzb_soil,j,i)
-
-!
-!--          Denominator of the prognostic equation
-             coef_2 = rad_lw_out_change_0(j,i) + f_qsws * dq_s_dt              &
-                      + lambda_surface + f_shf / exn
-          ELSE
-
-!
-!--          Numerator of the prognostic equation
-             coef_1 = rad_net_l(j,i) + rad_lw_out_change_0(j,i)                &
-                      * t_surface(j,i) - rad_lw_out(nzb,j,i)                   &
-                      + f_shf * pt1  + lambda_surface                          &
-                      * t_soil(nzb_soil,j,i)
-
-!
-!--          Denominator of the prognostic equation
-             coef_2 = rad_lw_out_change_0(j,i) + lambda_surface + f_shf / exn
-
-          ENDIF
-
-          tend = 0.0_wp
-
-!
-!--       Implicit solution when the surface layer has no heat capacity,
-!--       otherwise use RK3 scheme.
-          t_surface_p(j,i) = ( coef_1 * dt_3d * tsc(2) + c_surface_tmp *       &
-                             t_surface(j,i) ) / ( c_surface_tmp + coef_2       &
-                                * dt_3d * tsc(2) ) 
-
-!
-!--       Add RK3 term
-          IF ( c_surface_tmp /= 0.0_wp )  THEN
-
-             t_surface_p(j,i) = t_surface_p(j,i) + dt_3d * tsc(3)              &
-                                * tt_surface_m(j,i)
-
-!
-!--          Calculate true tendency
-             tend = (t_surface_p(j,i) - t_surface(j,i) - dt_3d * tsc(3)        &
-                    * tt_surface_m(j,i)) / (dt_3d  * tsc(2))
-!
-!--          Calculate t_surface tendencies for the next Runge-Kutta step
-             IF ( timestep_scheme(1:5) == 'runge' )  THEN
-                IF ( intermediate_timestep_count == 1 )  THEN
-                   tt_surface_m(j,i) = tend
-                ELSEIF ( intermediate_timestep_count <                         &
-                         intermediate_timestep_count_max )  THEN
-                   tt_surface_m(j,i) = -9.5625_wp * tend + 5.3125_wp           &
-                                       * tt_surface_m(j,i)
-                ENDIF
+       f_shf  = rho_cp / surf%r_a(m)
+       f_qsws = f_qsws_veg + f_qsws_soil + f_qsws_liq
+!
+!--    Calculate derivative of q_s for Taylor series expansion
+       e_s_dt = e_s * ( 17.269_wp / ( surf_t_surface%var_1d(m) - 35.86_wp) -   &
+                        17.269_wp*( surf_t_surface%var_1d(m) - 273.16_wp)      &
+                       / ( surf_t_surface%var_1d(m) - 35.86_wp)**2 )
+
+       dq_s_dt = 0.622_wp * e_s_dt / surface_pressure
+!
+!--    Add LW up so that it can be removed in prognostic equation
+       surf%rad_net_l(m) = rad_net(j,i) + rad_lw_out(nzb,j,i)
+!
+!--    Calculate new skin temperature
+       IF ( humidity )  THEN
+!
+!--       Numerator of the prognostic equation
+          coef_1 = surf%rad_net_l(m) + rad_lw_out_change_0(j,i)                &
+                   * surf_t_surface%var_1d(m) - rad_lw_out(nzb,j,i)            &
+                   + f_shf * pt1 + f_qsws * ( qv1 - q_s                        &
+                   + dq_s_dt * surf_t_surface%var_1d(m) ) + lambda_surface     &
+                   * surf_t_soil%var_2d(nzb_soil,m)
+!
+!--       Denominator of the prognostic equation
+          coef_2 = rad_lw_out_change_0(j,i) + f_qsws * dq_s_dt                 &
+                   + lambda_surface + f_shf / exn
+       ELSE
+!
+!--       Numerator of the prognostic equation
+          coef_1 = surf%rad_net_l(m) + rad_lw_out_change_0(j,i)                &
+                   * surf_t_surface%var_1d(m) - rad_lw_out(nzb,j,i)            &
+                   + f_shf * pt1  + lambda_surface                             &
+                   * surf_t_soil%var_2d(nzb_soil,m)
+!
+!--       Denominator of the prognostic equation
+          coef_2 = rad_lw_out_change_0(j,i) + lambda_surface + f_shf / exn
+
+       ENDIF
+
+       tend = 0.0_wp
+
+!
+!--    Implicit solution when the surface layer has no heat capacity,
+!--    otherwise use RK3 scheme.
+       surf_t_surface_p%var_1d(m) = ( coef_1 * dt_3d * tsc(2) + c_surface_tmp *&
+                          surf_t_surface%var_1d(m) ) / ( c_surface_tmp + coef_2&
+                                             * dt_3d * tsc(2) ) 
+
+!
+!--    Add RK3 term
+       IF ( c_surface_tmp /= 0.0_wp )  THEN
+
+          surf_t_surface_p%var_1d(m) = surf_t_surface_p%var_1d(m) + dt_3d *    &
+                                       tsc(3) * surf_tt_surface_m%var_1d(m)
+
+!
+!--       Calculate true tendency
+          tend = ( surf_t_surface_p%var_1d(m) - surf_t_surface%var_1d(m) -     &
+                   dt_3d * tsc(3) * surf_tt_surface_m%var_1d(m)) / (dt_3d  * tsc(2))
+!
+!--       Calculate t_surface tendencies for the next Runge-Kutta step
+          IF ( timestep_scheme(1:5) == 'runge' )  THEN
+             IF ( intermediate_timestep_count == 1 )  THEN
+                surf_tt_surface_m%var_1d(m) = tend
+             ELSEIF ( intermediate_timestep_count <                            &
+                      intermediate_timestep_count_max )  THEN
+                surf_tt_surface_m%var_1d(m) = -9.5625_wp * tend +              &
+                                               5.3125_wp * surf_tt_surface_m%var_1d(m)
              ENDIF
           ENDIF
-
-!
-!--       In case of fast changes in the skin temperature, it is possible to
-!--       update the radiative fluxes independently from the prescribed
-!--       radiation call frequency. This effectively prevents oscillations,
-!--       especially when setting skip_time_do_radiation /= 0. The threshold
-!--       value of 0.2 used here is just a first guess. This method should be
-!--       revised in the future as tests have shown that the threshold is 
-!--       often reached, when no oscillations would occur (causes immense
-!--       computing time for the radiation code).
-          IF ( ABS( t_surface_p(j,i) - t_surface(j,i) ) > 0.2_wp  .AND.        &
-               unscheduled_radiation_calls )  THEN
-             force_radiation_call_l = .TRUE.
-          ENDIF
-
-          pt(k,j,i) = t_surface_p(j,i) / exn
-
-!
-!--       Calculate fluxes
-          rad_net_l(j,i)   = rad_net_l(j,i) + rad_lw_out_change_0(j,i)         &
-                             * t_surface(j,i) - rad_lw_out(nzb,j,i)            &
-                             - rad_lw_out_change_0(j,i) * t_surface_p(j,i)
-
-          rad_net(j,i) = rad_net_l(j,i)
-          rad_lw_out(nzb,j,i) = rad_lw_out(nzb,j,i) + rad_lw_out_change_0(j,i) &
-                                * ( t_surface_p(j,i) - t_surface(j,i) )
-
-          ghf_eb(j,i)    = lambda_surface * (t_surface_p(j,i)                  &
-                           - t_soil(nzb_soil,j,i))
-
-          shf_eb(j,i)    = - f_shf * ( pt1 - pt(k,j,i) )
-
-          shf(j,i) = shf_eb(j,i) / rho_cp
-
-          IF ( humidity )  THEN
-             qsws_eb(j,i)  = - f_qsws    * ( qv1 - q_s + dq_s_dt               &
-                             * t_surface(j,i) - dq_s_dt * t_surface_p(j,i) )
-
-             qsws(j,i) = qsws_eb(j,i) / rho_lv
-
-             qsws_veg_eb(j,i)  = - f_qsws_veg  * ( qv1 - q_s                   &
-                                 + dq_s_dt * t_surface(j,i) - dq_s_dt          &
-                                 * t_surface_p(j,i) )
-
-             qsws_soil_eb(j,i) = - f_qsws_soil * ( qv1 - q_s                   &
-                                 + dq_s_dt * t_surface(j,i) - dq_s_dt          &
-                                 * t_surface_p(j,i) )
-
-             qsws_liq_eb(j,i)  = - f_qsws_liq  * ( qv1 - q_s                   &
-                                 + dq_s_dt * t_surface(j,i) - dq_s_dt          &
-                                 * t_surface_p(j,i) )
-          ENDIF
-
-!
-!--       Calculate the true surface resistance
-          IF ( qsws_eb(j,i) == 0.0_wp )  THEN
-             r_s(j,i) = 1.0E10_wp
-          ELSE
-             r_s(j,i) = - rho_lv * ( qv1 - q_s + dq_s_dt                       &
-                        * t_surface(j,i) - dq_s_dt * t_surface_p(j,i) )        &
-                        / qsws_eb(j,i) - r_a(j,i)
-          ENDIF
-
-!
-!--       Calculate change in liquid water reservoir due to dew fall or 
-!--       evaporation of liquid water
-          IF ( humidity )  THEN
-!
-!--          If precipitation is activated, add rain water to qsws_liq_eb
-!--          and qsws_soil_eb according the the vegetation coverage.
-!--          precipitation_rate is given in mm.
-             IF ( precipitation )  THEN
-
-!
-!--             Add precipitation to liquid water reservoir, if possible.
-!--             Otherwise, add the water to soil. In case of
-!--             pavements, the exceeding water amount is implicitely removed 
-!--             as runoff as qsws_soil_eb is then not used in the soil model
-                IF ( m_liq_eb(j,i) /= m_liq_eb_max )  THEN
-                   qsws_liq_eb(j,i) = qsws_liq_eb(j,i)                         &
-                                    + c_veg(j,i) * prr(k,j,i) * hyrho(k)       &
-                                    * 0.001_wp * rho_l * l_v
-                ELSE
-                   qsws_soil_eb(j,i) = qsws_soil_eb(j,i)                       &
-                                     + c_veg(j,i) * prr(k,j,i) * hyrho(k)      &
-                                     * 0.001_wp * rho_l * l_v
-                ENDIF
-
-!--             Add precipitation to bare soil according to the bare soil
-!--             coverage.
-                qsws_soil_eb(j,i) = qsws_soil_eb(j,i) + (1.0_wp                &
-                                    - c_veg(j,i)) * prr(k,j,i) * hyrho(k)      &
-                                    * 0.001_wp * rho_l * l_v
+       ENDIF
+
+!
+!--    In case of fast changes in the skin temperature, it is possible to
+!--    update the radiative fluxes independently from the prescribed
+!--    radiation call frequency. This effectively prevents oscillations,
+!--    especially when setting skip_time_do_radiation /= 0. The threshold
+!--    value of 0.2 used here is just a first guess. This method should be
+!--    revised in the future as tests have shown that the threshold is 
+!--    often reached, when no oscillations would occur (causes immense
+!--    computing time for the radiation code).
+       IF ( ABS( surf_t_surface_p%var_1d(m) - surf_t_surface%var_1d(m) ) > 0.2_wp  .AND. &
+            unscheduled_radiation_calls )  THEN
+          force_radiation_call_l = .TRUE.
+       ENDIF
+
+       pt(k+k_off,j+j_off,i+i_off) = surf_t_surface_p%var_1d(m) / exn  !is actually no air temperature
+       surf%pt_surface(m)          = surf_t_surface_p%var_1d(m) / exn
+
+!
+!--    Calculate fluxes
+       surf%rad_net_l(m) = surf%rad_net_l(m) +                                 &
+                            rad_lw_out_change_0(j,i)                           &
+                          * surf_t_surface%var_1d(m) - rad_lw_out(nzb,j,i)     &
+                          - rad_lw_out_change_0(j,i) * surf_t_surface_p%var_1d(m)
+
+       rad_net(j,i) = surf%rad_net_l(m)
+       rad_lw_out(nzb,j,i) = rad_lw_out(nzb,j,i) + rad_lw_out_change_0(j,i) *  &
+                     ( surf_t_surface_p%var_1d(m) - surf_t_surface%var_1d(m) )
+
+       surf%ghf_eb(m) = lambda_surface * ( surf_t_surface_p%var_1d(m)          &
+                                             - surf_t_soil%var_2d(nzb_soil,m) )
+
+       surf%shf_eb(m) = - f_shf * ( pt1 - surf%pt_surface(m) )
+
+       surf%shf(m) = surf%shf_eb(m) / rho_cp
+
+       IF ( humidity )  THEN
+          surf%qsws_eb(m)  = - f_qsws * ( qv1 - q_s + dq_s_dt                  &
+                          * surf_t_surface%var_1d(m) - dq_s_dt *               &
+                            surf_t_surface_p%var_1d(m) )
+
+          surf%qsws(m) = surf%qsws_eb(m) / rho_lv
+
+          surf%qsws_veg_eb(m)  = - f_qsws_veg  * ( qv1 - q_s                   &
+                              + dq_s_dt * surf_t_surface%var_1d(m) - dq_s_dt   &
+                              * surf_t_surface_p%var_1d(m) )
+
+          surf%qsws_soil_eb(m) = - f_qsws_soil * ( qv1 - q_s                   &
+                              + dq_s_dt * surf_t_surface%var_1d(m) - dq_s_dt   &
+                              * surf_t_surface_p%var_1d(m) )
+
+          surf%qsws_liq_eb(m)  = - f_qsws_liq  * ( qv1 - q_s                   &
+                              + dq_s_dt * surf_t_surface%var_1d(m) - dq_s_dt   &
+                              * surf_t_surface_p%var_1d(m) )
+       ENDIF
+
+!
+!--    Calculate the true surface resistance
+       IF ( surf%qsws_eb(m) == 0.0_wp )  THEN
+          surf%r_s(m) = 1.0E10_wp
+       ELSE
+          surf%r_s(m) = - rho_lv * ( qv1 - q_s + dq_s_dt                       &
+                          * surf_t_surface%var_1d(m) - dq_s_dt *               &
+                            surf_t_surface_p%var_1d(m) ) /                     &
+                            surf%qsws_eb(m) - surf%r_a(m)
+       ENDIF
+
+!
+!--    Calculate change in liquid water reservoir due to dew fall or 
+!--    evaporation of liquid water
+       IF ( humidity )  THEN
+!
+!--       If precipitation is activated, add rain water to qsws_liq_eb
+!--       and qsws_soil_eb according the the vegetation coverage.
+!--       precipitation_rate is given in mm.
+          IF ( precipitation )  THEN
+
+!
+!--          Add precipitation to liquid water reservoir, if possible.
+!--          Otherwise, add the water to soil. In case of
+!--          pavements, the exceeding water amount is implicitely removed 
+!--          as runoff as qsws_soil_eb is then not used in the soil model
+             IF ( surf_m_liq_eb%var_1d(m) /= m_liq_eb_max )  THEN
+                surf%qsws_liq_eb(m) = surf%qsws_liq_eb(m)                      &
+                                 + surf%c_veg(m) * prr(k+k_off,j+j_off,i+i_off)&
+                                 * hyrho(k+k_off)                              &
+                                 * 0.001_wp * rho_l * l_v
+             ELSE
+                surf%qsws_soil_eb(m) = surf%qsws_soil_eb(m)                    &
+                                 + surf%c_veg(m) * prr(k+k_off,j+j_off,i+i_off)&
+                                 * hyrho(k+k_off)                              &
+                                 * 0.001_wp * rho_l * l_v
              ENDIF
 
-!
-!--          If the air is saturated, check the reservoir water level
-             IF ( qsws_eb(j,i) < 0.0_wp )  THEN
-
-!
-!--             Check if reservoir is full (avoid values > m_liq_eb_max)
-!--             In that case, qsws_liq_eb goes to qsws_soil_eb. In this 
-!--             case qsws_veg_eb is zero anyway (because c_liq = 1),       
-!--             so that tend is zero and no further check is needed
-                IF ( m_liq_eb(j,i) == m_liq_eb_max )  THEN
-                   qsws_soil_eb(j,i) = qsws_soil_eb(j,i)                       &
-                                        + qsws_liq_eb(j,i)
-
-                   qsws_liq_eb(j,i)  = 0.0_wp
-                ENDIF
-
-!
-!--             In case qsws_veg_eb becomes negative (unphysical behavior), 
-!--             let the water enter the liquid water reservoir as dew on the
-!--             plant
-                IF ( qsws_veg_eb(j,i) < 0.0_wp )  THEN
-                   qsws_liq_eb(j,i) = qsws_liq_eb(j,i) + qsws_veg_eb(j,i)
-                   qsws_veg_eb(j,i) = 0.0_wp
-                ENDIF
-             ENDIF                    
-  
-             tend = - qsws_liq_eb(j,i) * drho_l_lv
-             m_liq_eb_p(j,i) = m_liq_eb(j,i) + dt_3d * ( tsc(2) * tend         &
-                                                + tsc(3) * tm_liq_eb_m(j,i) )
-
-!
-!--          Check if reservoir is overfull -> reduce to maximum
-!--          (conservation of water is violated here)
-             m_liq_eb_p(j,i) = MIN(m_liq_eb_p(j,i),m_liq_eb_max)
-
-!
-!--          Check if reservoir is empty (avoid values < 0.0)
-!--          (conservation of water is violated here)
-             m_liq_eb_p(j,i) = MAX(m_liq_eb_p(j,i),0.0_wp)
-
-
-!
-!--          Calculate m_liq_eb tendencies for the next Runge-Kutta step
-             IF ( timestep_scheme(1:5) == 'runge' )  THEN
-                IF ( intermediate_timestep_count == 1 )  THEN
-                   tm_liq_eb_m(j,i) = tend
-                ELSEIF ( intermediate_timestep_count <                         &
-                         intermediate_timestep_count_max )  THEN
-                   tm_liq_eb_m(j,i) = -9.5625_wp * tend + 5.3125_wp            &
-                                    * tm_liq_eb_m(j,i)
-                ENDIF
+!--          Add precipitation to bare soil according to the bare soil
+!--          coverage.
+             surf%qsws_soil_eb(m) = surf%qsws_soil_eb(m) + ( 1.0_wp            &
+                               - surf%c_veg(m) ) * prr(k+k_off,j+j_off,i+i_off)&
+                               * hyrho(k+k_off)                                &
+                               * 0.001_wp * rho_l * l_v
+          ENDIF
+
+!
+!--       If the air is saturated, check the reservoir water level
+          IF ( surf%qsws_eb(m) < 0.0_wp )  THEN
+!
+!--          Check if reservoir is full (avoid values > m_liq_eb_max)
+!--          In that case, qsws_liq_eb goes to qsws_soil_eb. In this 
+!--          case qsws_veg_eb is zero anyway (because c_liq = 1),       
+!--          so that tend is zero and no further check is needed
+             IF ( surf_m_liq_eb%var_1d(m) == m_liq_eb_max )  THEN
+                surf%qsws_soil_eb(m) = surf%qsws_soil_eb(m) + surf%qsws_liq_eb(m)
+
+                surf%qsws_liq_eb(m)  = 0.0_wp
              ENDIF
 
-          ENDIF
-
-       ENDDO
+!
+!--          In case qsws_veg_eb becomes negative (unphysical behavior), 
+!--          let the water enter the liquid water reservoir as dew on the
+!--          plant
+             IF ( surf%qsws_veg_eb(m) < 0.0_wp )  THEN
+                surf%qsws_liq_eb(m) = surf%qsws_liq_eb(m) + surf%qsws_veg_eb(m)
+                surf%qsws_veg_eb(m) = 0.0_wp
+             ENDIF
+          ENDIF                    
+ 
+          tend = - surf%qsws_liq_eb(m) * drho_l_lv
+          surf_m_liq_eb_p%var_1d(m) = surf_m_liq_eb%var_1d(m) + dt_3d *        &
+                                        ( tsc(2) * tend +                      &
+                                          tsc(3) * surf_tm_liq_eb_m%var_1d(m) )
+!
+!--       Check if reservoir is overfull -> reduce to maximum
+!--       (conservation of water is violated here)
+          surf_m_liq_eb_p%var_1d(m) = MIN( surf_m_liq_eb_p%var_1d(m),m_liq_eb_max )
+
+!
+!--       Check if reservoir is empty (avoid values < 0.0)
+!--       (conservation of water is violated here)
+          surf_m_liq_eb_p%var_1d(m) = MAX( surf_m_liq_eb_p%var_1d(m), 0.0_wp )
+!
+!--       Calculate m_liq_eb tendencies for the next Runge-Kutta step
+          IF ( timestep_scheme(1:5) == 'runge' )  THEN
+             IF ( intermediate_timestep_count == 1 )  THEN
+                surf_tm_liq_eb_m%var_1d(m) = tend
+             ELSEIF ( intermediate_timestep_count <                            &
+                      intermediate_timestep_count_max )  THEN
+                surf_tm_liq_eb_m%var_1d(m) = -9.5625_wp * tend +               &
+                                              5.3125_wp * surf_tm_liq_eb_m%var_1d(m)
+             ENDIF
+          ENDIF
+
+       ENDIF
+
     ENDDO
 
@@ -1497,5 +1591,5 @@
 #if defined( __parallel )
        IF ( collective_wait )  CALL MPI_BARRIER( comm2d, ierr )
-       CALL MPI_ALLREDUCE( force_radiation_call_l, force_radiation_call,    &
+       CALL MPI_ALLREDUCE( force_radiation_call_l, force_radiation_call,       &
                            1, MPI_LOGICAL, MPI_LOR, comm2d, ierr )
 #else
@@ -1513,5 +1607,59 @@
 !
 !-- Calculate new roughness lengths (for water surfaces only)
-    CALL calc_z0_water_surface
+    IF ( horizontal )  CALL calc_z0_water_surface
+
+    CONTAINS
+!------------------------------------------------------------------------------!
+! Description:
+! ------------
+!> Calculation of specific humidity of the skin layer (surface). It is assumend
+!> that the skin is always saturated.
+!------------------------------------------------------------------------------!
+    SUBROUTINE calc_q_surface
+
+       IMPLICIT NONE
+
+       REAL(wp) :: resistance    !< aerodynamic and soil resistance term
+
+       DO  m = 1, surf%ns
+
+          i   = surf%i(m)            
+          j   = surf%j(m)
+          k   = surf%k(m)
+
+!
+!--       Calculate water vapour pressure at saturation
+          e_s = 0.01_wp * 610.78_wp * EXP( 17.269_wp *                         &
+                                 ( surf_t_surface_p%var_1d(m) - 273.16_wp ) /  &
+                                 ( surf_t_surface_p%var_1d(m) - 35.86_wp  )    &
+                                         )
+
+!
+!--       Calculate specific humidity at saturation
+          q_s = 0.622_wp * e_s / surface_pressure
+
+          resistance = surf%r_a(m) / ( surf%r_a(m) + surf%r_s(m) )
+
+!
+!--       Calculate specific humidity at surface
+          IF ( cloud_physics )  THEN
+             q(k+k_off,j+j_off,i+i_off) = resistance * q_s +                   &
+                                        ( 1.0_wp - resistance ) *              &
+                                        ( q(k,j,i) - ql(k,j,i) )
+          ELSE
+             q(k+k_off,j+j_off,i+i_off) = resistance * q_s +                   &
+                                        ( 1.0_wp - resistance ) *              &
+                                          q(k,j,i)
+          ENDIF
+
+!
+!--       Update virtual potential temperature
+          vpt(k+k_off,j+j_off,i+i_off) = pt(k+k_off,j+j_off,i+i_off) *         &
+                     ( 1.0_wp + 0.61_wp * q(k+k_off,j+j_off,i+i_off) )
+
+       ENDDO
+
+    END SUBROUTINE calc_q_surface
+
 
 
@@ -1607,16 +1755,17 @@
        IMPLICIT NONE
 
-       INTEGER(iwp) ::  i !< running index
-       INTEGER(iwp) ::  j !< running index
-       INTEGER(iwp) ::  k !< running index
+       INTEGER(iwp) ::  i     !< running index
+       INTEGER(iwp) ::  i_off !< index offset of surface element, seen from atmospheric grid point 
+       INTEGER(iwp) ::  j     !< running index
+       INTEGER(iwp) ::  j_off !< index offset of surface element, seen from atmospheric grid point 
+       INTEGER(iwp) ::  k     !< running index
+       INTEGER(iwp) ::  l     !< running index surface facing
+       INTEGER(iwp) ::  m     !< running index
 
        REAL(wp) :: pt1   !< potential temperature at first grid level
-
 
 !
 !--    Calculate Exner function
        exn = ( surface_pressure / 1000.0_wp )**0.286_wp
-
-
 !
 !--    If no cloud physics is used, rho_surface has not been calculated before
@@ -1634,43 +1783,89 @@
 !
 !--    Set inital values for prognostic quantities
-       tt_surface_m = 0.0_wp
-       tt_soil_m    = 0.0_wp
-       tm_soil_m    = 0.0_wp
-       tm_liq_eb_m  = 0.0_wp
-       c_liq        = 0.0_wp
-
-       ghf_eb = 0.0_wp
-       shf_eb = rho_cp * shf
+!--    Horizontal surfaces
+       tt_surface_h_m%var_1d = 0.0_wp
+       tt_soil_h_m%var_2d    = 0.0_wp
+       tm_soil_h_m%var_2d    = 0.0_wp
+       tm_liq_eb_h_m%var_1d  = 0.0_wp
+       surf_lsm_h%c_liq = 0.0_wp
+
+       surf_lsm_h%ghf_eb = 0.0_wp
+       surf_lsm_h%shf_eb = rho_cp * surf_lsm_h%shf
 
        IF ( humidity )  THEN
-          qsws_eb = rho_lv * qsws
+          surf_lsm_h%qsws_eb = rho_lv * surf_lsm_h%qsws
        ELSE
-          qsws_eb = 0.0_wp
-       ENDIF
-
-       qsws_liq_eb  = 0.0_wp
-       qsws_soil_eb = 0.0_wp
-       qsws_veg_eb  = 0.0_wp
-
-       r_a        = 50.0_wp
-       r_s        = 50.0_wp
-       r_canopy   = 0.0_wp
-       r_soil     = 0.0_wp
+          surf_lsm_h%qsws_eb = 0.0_wp
+       ENDIF
+
+       surf_lsm_h%qsws_liq_eb  = 0.0_wp
+       surf_lsm_h%qsws_soil_eb = 0.0_wp
+       surf_lsm_h%qsws_veg_eb  = 0.0_wp
+
+       surf_lsm_h%r_a        = 50.0_wp
+       surf_lsm_h%r_s        = 50.0_wp
+       surf_lsm_h%r_canopy   = 0.0_wp
+       surf_lsm_h%r_soil     = 0.0_wp
+!
+!--    Do the same for vertical surfaces
+       DO  l = 0, 3
+          tt_surface_v_m(l)%var_1d = 0.0_wp
+          tt_soil_v_m(l)%var_2d    = 0.0_wp
+          tm_soil_v_m(l)%var_2d    = 0.0_wp
+          tm_liq_eb_v_m(l)%var_1d  = 0.0_wp
+          surf_lsm_v(l)%c_liq = 0.0_wp
+
+          surf_lsm_v(l)%ghf_eb = 0.0_wp
+          surf_lsm_v(l)%shf_eb = rho_cp * surf_lsm_v(l)%shf
+
+          IF ( humidity )  THEN
+             surf_lsm_v(l)%qsws_eb = rho_lv * surf_lsm_v(l)%qsws
+          ELSE
+             surf_lsm_v(l)%qsws_eb = 0.0_wp
+          ENDIF
+
+          surf_lsm_v(l)%qsws_liq_eb  = 0.0_wp
+          surf_lsm_v(l)%qsws_soil_eb = 0.0_wp
+          surf_lsm_v(l)%qsws_veg_eb  = 0.0_wp
+
+          surf_lsm_v(l)%r_a        = 50.0_wp
+          surf_lsm_v(l)%r_s        = 50.0_wp
+          surf_lsm_v(l)%r_canopy   = 0.0_wp
+          surf_lsm_v(l)%r_soil     = 0.0_wp
+       ENDDO
 
 !
 !--    Allocate 3D soil model arrays
-       ALLOCATE ( root_fr(nzb_soil:nzt_soil,nysg:nyng,nxlg:nxrg) )
-       ALLOCATE ( lambda_h(nzb_soil:nzt_soil,nysg:nyng,nxlg:nxrg) )
-       ALLOCATE ( rho_c_total(nzb_soil:nzt_soil,nysg:nyng,nxlg:nxrg) )
-
-       lambda_h = 0.0_wp
+!--    First, for horizontal surfaces
+       ALLOCATE ( surf_lsm_h%root_fr(nzb_soil:nzt_soil,1:surf_lsm_h%ns)     )
+       ALLOCATE ( surf_lsm_h%lambda_h(nzb_soil:nzt_soil,1:surf_lsm_h%ns)    )
+       ALLOCATE ( surf_lsm_h%rho_c_total(nzb_soil:nzt_soil,1:surf_lsm_h%ns) )
+
+       surf_lsm_h%lambda_h = 0.0_wp
 !
 !--    If required, allocate humidity-related variables for the soil model
        IF ( humidity )  THEN
-          ALLOCATE ( lambda_w(nzb_soil:nzt_soil,nysg:nyng,nxlg:nxrg) )
-          ALLOCATE ( gamma_w(nzb_soil:nzt_soil,nysg:nyng,nxlg:nxrg) )   
-
-          lambda_w = 0.0_wp 
-       ENDIF
+          ALLOCATE ( surf_lsm_h%lambda_w(nzb_soil:nzt_soil,1:surf_lsm_h%ns) )
+          ALLOCATE ( surf_lsm_h%gamma_w(nzb_soil:nzt_soil,1:surf_lsm_h%ns)  )  
+
+          surf_lsm_h%lambda_w = 0.0_wp 
+       ENDIF
+!
+!--    For vertical surfaces
+       DO  l = 0, 3
+          ALLOCATE ( surf_lsm_v(l)%root_fr(nzb_soil:nzt_soil,1:surf_lsm_v(l)%ns)     )
+          ALLOCATE ( surf_lsm_v(l)%lambda_h(nzb_soil:nzt_soil,1:surf_lsm_v(l)%ns)    )
+          ALLOCATE ( surf_lsm_v(l)%rho_c_total(nzb_soil:nzt_soil,1:surf_lsm_v(l)%ns) )
+
+          surf_lsm_v(l)%lambda_h = 0.0_wp
+!
+!--       If required, allocate humidity-related variables for the soil model
+          IF ( humidity )  THEN
+             ALLOCATE ( surf_lsm_v(l)%lambda_w(nzb_soil:nzt_soil,1:surf_lsm_v(l)%ns) )
+             ALLOCATE ( surf_lsm_v(l)%gamma_w(nzb_soil:nzt_soil,1:surf_lsm_v(l)%ns)  )  
+
+             surf_lsm_v(l)%lambda_w = 0.0_wp 
+          ENDIF      
+       ENDDO
 
 !
@@ -1735,21 +1930,38 @@
 !
 !--    Map values to the respective 2D arrays
-       alpha_vg      = alpha_vangenuchten
-       l_vg          = l_vangenuchten
-       n_vg          = n_vangenuchten 
-       gamma_w_sat   = hydraulic_conductivity
-       m_sat         = saturation_moisture
-       m_fc          = field_capacity
-       m_wilt        = wilting_point
-       m_res         = residual_moisture
-       r_soil_min    = min_soil_resistance
+!--    Horizontal surfaces
+       surf_lsm_h%alpha_vg      = alpha_vangenuchten
+       surf_lsm_h%l_vg          = l_vangenuchten
+       surf_lsm_h%n_vg          = n_vangenuchten 
+       surf_lsm_h%gamma_w_sat   = hydraulic_conductivity
+       surf_lsm_h%m_sat         = saturation_moisture
+       surf_lsm_h%m_fc          = field_capacity
+       surf_lsm_h%m_wilt        = wilting_point
+       surf_lsm_h%m_res         = residual_moisture
+       surf_lsm_h%r_soil_min    = min_soil_resistance
+!
+!--    Vertical surfaces
+       DO  l = 0, 3
+          surf_lsm_v(l)%alpha_vg      = alpha_vangenuchten
+          surf_lsm_v(l)%l_vg          = l_vangenuchten
+          surf_lsm_v(l)%n_vg          = n_vangenuchten 
+          surf_lsm_v(l)%gamma_w_sat   = hydraulic_conductivity
+          surf_lsm_v(l)%m_sat         = saturation_moisture
+          surf_lsm_v(l)%m_fc          = field_capacity
+          surf_lsm_v(l)%m_wilt        = wilting_point
+          surf_lsm_v(l)%m_res         = residual_moisture
+          surf_lsm_v(l)%r_soil_min    = min_soil_resistance
+       ENDDO
+
+
 
 !
 !--    Initial run actions
        IF (  TRIM( initializing_actions ) /= 'read_restart_data' )  THEN
-
-          t_soil    = 0.0_wp
-          m_liq_eb  = 0.0_wp
-          m_soil    = 0.0_wp
+!
+!--       First, for horizontal surfaces
+          t_soil_h%var_2d    = 0.0_wp
+          m_soil_h%var_2d    = 0.0_wp
+          m_liq_eb_h%var_1d  = 0.0_wp
 
 !
@@ -1758,34 +1970,82 @@
 !--       wilting point) -> problems with devision by zero)
           DO  k = nzb_soil, nzt_soil
-             t_soil(k,:,:)    = soil_temperature(k)
-             m_soil(k,:,:)    = MAX(soil_moisture(k),m_wilt(:,:))
+             t_soil_h%var_2d(k,:)      = soil_temperature(k)
+             m_soil_h%var_2d(k,:)      = MAX(soil_moisture(k),surf_lsm_h%m_wilt(:))
              soil_moisture(k) = MAX(soil_moisture(k),wilting_point)
           ENDDO
-          t_soil(nzt_soil+1,:,:) = soil_temperature(nzt_soil+1)
+          t_soil_h%var_2d(nzt_soil+1,:) = soil_temperature(nzt_soil+1)
 
 !
 !--       Calculate surface temperature
-          t_surface   = pt_surface * exn
+          t_surface_h%var_1d(:)    = pt_surface * exn
+          surf_lsm_h%pt_surface(:) = pt_surface
 
 !
 !--       Set artifical values for ts and us so that r_a has its initial value 
-!--       for the first time step
-          DO  i = nxlg, nxrg
-             DO  j = nysg, nyng
-                k = nzb_s_inner(j,i)
+!--       for the first time step. Only for interior core domain, not for ghost points
+          DO  m = 1, surf_lsm_h%ns
+             i   = surf_lsm_h%i(m)            
+             j   = surf_lsm_h%j(m)
+             k   = surf_lsm_h%k(m)
+
+             IF ( cloud_physics )  THEN
+                pt1 = pt(k,j,i) + l_d_cp * pt_d_t(k) * ql(k,j,i)
+             ELSE
+                pt1 = pt(k,j,i)
+             ENDIF
+
+!
+!--          Assure that r_a cannot be zero at model start
+             IF ( pt1 == surf_lsm_h%pt_surface(m) )  pt1 = pt1 + 1.0E-10_wp
+
+             surf_lsm_h%us(m)   = 0.1_wp
+             surf_lsm_h%ts(m)   = ( pt1 - surf_lsm_h%pt_surface(m) ) / surf_lsm_h%r_a(m)
+             surf_lsm_h%shf(m)  = - surf_lsm_h%us(m) * surf_lsm_h%ts(m)
+          ENDDO
+!
+!--       Vertical surfaces
+          DO  l = 0, 3
+
+             t_soil_v(l)%var_2d    = 0.0_wp
+             m_soil_v(l)%var_2d    = 0.0_wp
+             m_liq_eb_v(l)%var_1d  = 0.0_wp
+
+!
+!--          Map user settings of T and q for each soil layer
+!--          (make sure that the soil moisture does not drop below the permanent
+!--          wilting point) -> problems with devision by zero)
+             DO  k = nzb_soil, nzt_soil
+                t_soil_v(l)%var_2d(k,:)      = soil_temperature(k)
+                m_soil_v(l)%var_2d(k,:)      = MAX(soil_moisture(k),surf_lsm_v(l)%m_wilt(:))
+                soil_moisture(k) = MAX(soil_moisture(k),wilting_point)
+             ENDDO
+             t_soil_v(l)%var_2d(nzt_soil+1,:) = soil_temperature(nzt_soil+1)
+
+!
+!--          Calculate surface temperature
+             t_surface_v(l)%var_1d(:)   = pt_surface * exn
+             surf_lsm_h%pt_surface(:)   = pt_surface
+
+!
+!--          Set artifical values for ts and us so that r_a has its initial value 
+!--          for the first time step. Only for interior core domain, not for ghost points
+             DO  m = 1, surf_lsm_v(l)%ns
+                i   = surf_lsm_v(l)%i(m)            
+                j   = surf_lsm_v(l)%j(m)
+                k   = surf_lsm_v(l)%k(m)
 
                 IF ( cloud_physics )  THEN
-                   pt1 = pt(k+1,j,i) + l_d_cp * pt_d_t(k+1) * ql(k+1,j,i)
+                   pt1 = pt(k,j,i) + l_d_cp * pt_d_t(k) * ql(k,j,i)
                 ELSE
-                   pt1 = pt(k+1,j,i)
+                   pt1 = pt(k,j,i)
                 ENDIF
 
 !
 !--             Assure that r_a cannot be zero at model start
-                IF ( pt1 == pt(k,j,i) )  pt1 = pt1 + 1.0E-10_wp
-
-                us(j,i)  = 0.1_wp
-                ts(j,i)  = (pt1 - pt(k,j,i)) / r_a(j,i)
-                shf(j,i) = - us(j,i) * ts(j,i)
+                IF ( pt1 == surf_lsm_h%pt_surface(m) )  pt1 = pt1 + 1.0E-10_wp
+
+                surf_lsm_v(l)%us(m)   = 0.1_wp
+                surf_lsm_v(l)%ts(m)   = ( pt1 - surf_lsm_h%pt_surface(m) ) / surf_lsm_v(l)%r_a(m)
+                surf_lsm_v(l)%shf(m)  = - surf_lsm_v(l)%us(m) * surf_lsm_v(l)%ts(m)
              ENDDO
           ENDDO
@@ -1794,16 +2054,61 @@
 !--    Actions for restart runs
        ELSE
-
-          DO  i = nxlg, nxrg
-             DO  j = nysg, nyng
-                k = nzb_s_inner(j,i)                
-                t_surface(j,i) = pt(k,j,i) * exn
-             ENDDO
+!
+!--       Horizontal surfaces
+          DO  m = 1, surf_lsm_h%ns
+             i   = surf_lsm_h%i(m)            
+             j   = surf_lsm_h%j(m)
+             k   = surf_lsm_h%k(m)          
+             t_surface_h%var_1d(m) = pt(k-1,j,i) * exn
           ENDDO
-
-       ENDIF
-
-       DO  k = nzb_soil, nzt_soil
-          root_fr(k,:,:) = root_fraction(k)
+!
+!--       Vertical surfaces
+          DO  l = 0, 3
+!
+!--          Set index offset of surface element, seen from atmospheric grid point 
+             IF ( l == 0 )  THEN 
+                j_off = -1 
+                i_off = 0
+             ELSEIF ( l == 1 )  THEN 
+                j_off = 1 
+                i_off = 0
+             ELSEIF ( l == 2 )  THEN 
+                j_off = 0 
+                i_off = -1
+             ELSEIF ( l == 3 )  THEN 
+                j_off = 0 
+                i_off = 1
+             ENDIF
+             DO  m = 1, surf_lsm_v(l)%ns
+                i   = surf_lsm_v(l)%i(m)            
+                j   = surf_lsm_v(l)%j(m)
+                k   = surf_lsm_v(l)%k(m)          
+                t_surface_v(l)%var_1d(m) = pt(k,j+j_off,i+i_off) * exn
+             ENDDO
+          ENDDO
+
+       ENDIF
+!
+!--    Initialize root fraction
+!--    Horizontal surfaces
+       DO  m = 1, surf_lsm_h%ns
+          i   = surf_lsm_h%i(m)            
+          j   = surf_lsm_h%j(m)
+
+          DO  k = nzb_soil, nzt_soil
+             surf_lsm_h%root_fr(k,m) = root_fraction(k)
+          ENDDO
+       ENDDO
+!
+!--    Vertical surfaces
+       DO  l = 0, 3
+          DO  m = 1, surf_lsm_v(l)%ns
+             i   = surf_lsm_v(l)%i(m)            
+             j   = surf_lsm_v(l)%j(m)
+
+             DO  k = nzb_soil, nzt_soil
+                surf_lsm_v(l)%root_fr(k,m) = root_fraction(k)
+             ENDDO
+          ENDDO
        ENDDO
 
@@ -1843,7 +2148,23 @@
 
           IF ( ANY( root_fraction == 9999999.9_wp ) )  THEN
-             DO  k = nzb_soil, nzt_soil
-                root_fr(k,:,:) = root_distribution(k,veg_type)
-                root_fraction(k) = root_distribution(k,veg_type)
+             DO  m = 1, surf_lsm_h%ns
+                i   = surf_lsm_h%i(m)            
+                j   = surf_lsm_h%j(m)
+
+                DO  k = nzb_soil, nzt_soil
+                   surf_lsm_h%root_fr(k,m) = root_distribution(k,veg_type)
+                   root_fraction(k)    = root_distribution(k,veg_type)
+                ENDDO
+             ENDDO
+             DO  l = 0, 3
+                DO  m = 1, surf_lsm_v(l)%ns
+                   i   = surf_lsm_v(l)%i(m)            
+                   j   = surf_lsm_v(l)%j(m)
+
+                   DO  k = nzb_soil, nzt_soil
+                      surf_lsm_v(l)%root_fr(k,m) = root_distribution(k,veg_type)
+                      root_fraction(k)    = root_distribution(k,veg_type)
+                   ENDDO
+                ENDDO
              ENDDO
           ENDIF
@@ -1877,19 +2198,39 @@
 !--    Map vegetation and soil types to 2D array to allow for heterogeneous 
 !--    surfaces via user interface see below
-       veg_type_2d = veg_type
-       soil_type_2d = soil_type
+!--    First for horizontal surfaces
+       surf_lsm_h%veg_type_2d  = veg_type
+       surf_lsm_h%soil_type_2d = soil_type
 
 !
 !--    Map vegetation parameters to the respective 2D arrays
-       r_canopy_min         = min_canopy_resistance
-       lai                  = leaf_area_index
-       c_veg                = vegetation_coverage
-       g_d                  = canopy_resistance_coefficient
-       lambda_surface_s     = lambda_surface_stable
-       lambda_surface_u     = lambda_surface_unstable
-       f_sw_in              = f_shortwave_incoming
-       z0                   = z0_eb
-       z0h                  = z0h_eb
-       z0q                  = z0q_eb
+       surf_lsm_h%r_canopy_min      = min_canopy_resistance
+       surf_lsm_h%lai               = leaf_area_index
+       surf_lsm_h%c_veg             = vegetation_coverage
+       surf_lsm_h%g_d               = canopy_resistance_coefficient
+       surf_lsm_h%lambda_surface_s  = lambda_surface_stable
+       surf_lsm_h%lambda_surface_u  = lambda_surface_unstable
+       surf_lsm_h%f_sw_in           = f_shortwave_incoming
+       surf_lsm_h%z0                = z0_eb
+       surf_lsm_h%z0h               = z0h_eb
+       surf_lsm_h%z0q               = z0q_eb
+
+!--    Vertical surfaces
+       DO  l = 0, 3
+          surf_lsm_v(l)%veg_type_2d  = veg_type
+          surf_lsm_v(l)%soil_type_2d = soil_type
+
+!
+!--       Map vegetation parameters to the respective 2D arrays
+          surf_lsm_v(l)%r_canopy_min      = min_canopy_resistance
+          surf_lsm_v(l)%lai               = leaf_area_index
+          surf_lsm_v(l)%c_veg             = vegetation_coverage
+          surf_lsm_v(l)%g_d               = canopy_resistance_coefficient
+          surf_lsm_v(l)%lambda_surface_s  = lambda_surface_stable
+          surf_lsm_v(l)%lambda_surface_u  = lambda_surface_unstable
+          surf_lsm_v(l)%f_sw_in           = f_shortwave_incoming
+          surf_lsm_v(l)%z0                = z0_eb
+          surf_lsm_v(l)%z0h               = z0h_eb
+          surf_lsm_v(l)%z0q               = z0q_eb
+       ENDDO
 
 !
@@ -1900,25 +2241,34 @@
 !--    Set flag parameter if vegetation type was set to a water surface. Also
 !--    set temperature to a constant value in all "soil" layers.
-       DO  i = nxlg, nxrg
-          DO  j = nysg, nyng
-             IF ( veg_type_2d(j,i) == 14  .OR.  veg_type_2d(j,i) == 15 )  THEN
-                water_surface(j,i) = .TRUE.
-                t_soil(:,j,i) = t_surface(j,i)
-             ELSEIF ( veg_type_2d(j,i) == 20 )  THEN
-                pave_surface(j,i) = .TRUE.
-                m_soil(:,j,i) = 0.0_wp
-             ENDIF
-
-          ENDDO
+!--    For now, do not set water surface for vertical surfaces
+       DO  m = 1, surf_lsm_h%ns
+          i   = surf_lsm_h%i(m)            
+          j   = surf_lsm_h%j(m)
+
+          IF ( surf_lsm_h%veg_type_2d(m) == 14  .OR.                           &
+               surf_lsm_h%veg_type_2d(m) == 15 )  THEN
+             surf_lsm_h%water_surface(m) = .TRUE.
+             t_soil_h%var_2d(:,m) = t_surface_h%var_1d(m)
+          ELSEIF ( surf_lsm_h%veg_type_2d(m) == 20 )  THEN
+             surf_lsm_h%pave_surface(m) = .TRUE.
+             m_soil_h%var_2d(:,m)            = 0.0_wp
+          ENDIF
+
        ENDDO
 
 !
-!--    Calculate new roughness lengths (for water surfaces only)
+!--    Calculate new roughness lengths (for water surfaces only, i.e. only 
+!-     horizontal surfaces)
        CALL calc_z0_water_surface
 
-       t_soil_p    = t_soil
-       m_soil_p    = m_soil
-       m_liq_eb_p  = m_liq_eb
-       t_surface_p = t_surface
+       t_soil_h_p    = t_soil_h
+       m_soil_h_p    = m_soil_h
+       m_liq_eb_h_p  = m_liq_eb_h
+       t_surface_h_p = t_surface_h
+
+       t_soil_v_p    = t_soil_v
+       m_soil_v_p    = m_soil_v
+       m_liq_eb_v_p  = m_liq_eb_v
+       t_surface_v_p = t_surface_v
 
 
@@ -1926,10 +2276,8 @@
 !--    Store initial profiles of t_soil and m_soil (assuming they are 
 !--    horizontally homogeneous on this PE)
-       hom(nzb_soil:nzt_soil,1,90,:)  = SPREAD( t_soil(nzb_soil:nzt_soil,      &
-                                                nysg,nxlg), 2,                 &
-                                                statistic_regions+1 )
-       hom(nzb_soil:nzt_soil,1,92,:)  = SPREAD( m_soil(nzb_soil:nzt_soil,      &
-                                                nysg,nxlg), 2,                 &
-                                                statistic_regions+1 )
+       hom(nzb_soil:nzt_soil,1,90,:)  = SPREAD( t_soil_h%var_2d(nzb_soil:nzt_soil,1),  &
+                                                2, statistic_regions+1 )
+       hom(nzb_soil:nzt_soil,1,92,:)  = SPREAD( m_soil_h%var_2d(nzb_soil:nzt_soil,1),  & 
+                                                2, statistic_regions+1 )
 
     END SUBROUTINE lsm_init
@@ -1946,79 +2294,175 @@
        IMPLICIT NONE
 
-!
-!--    Allocate surface and soil temperature / humidity
+       INTEGER(iwp) ::  l !< index indicating facing of surface array 
+
+!
+!--    Allocate surface and soil temperature / humidity. Please note, 
+!--    these arrays are allocated according to surface-data structure,
+!--    even if they do not belong to the data type due to the 
+!--    pointer arithmetric (TARGET attribute is not allowed in a data-type). 
 #if defined( __nopointer )
-       ALLOCATE ( m_liq_eb(nysg:nyng,nxlg:nxrg) )
-       ALLOCATE ( m_liq_eb_p(nysg:nyng,nxlg:nxrg) )
-       ALLOCATE ( m_soil(nzb_soil:nzt_soil,nysg:nyng,nxlg:nxrg) )
-       ALLOCATE ( m_soil_p(nzb_soil:nzt_soil,nysg:nyng,nxlg:nxrg) )
-       ALLOCATE ( t_surface(nysg:nyng,nxlg:nxrg) )
-       ALLOCATE ( t_surface_p(nysg:nyng,nxlg:nxrg) )
-       ALLOCATE ( t_soil(nzb_soil:nzt_soil+1,nysg:nyng,nxlg:nxrg) )
-       ALLOCATE ( t_soil_p(nzb_soil:nzt_soil+1,nysg:nyng,nxlg:nxrg) )
+!
+!--    Horizontal surfaces
+       ALLOCATE ( m_liq_eb_h%var_1d(1:surf_lsm_h%ns)                     )
+       ALLOCATE ( m_liq_eb_h_p%var_1d(1:surf_lsm_h%ns)                   )
+       ALLOCATE ( t_surface_h%var_1d(1:surf_lsm_h%ns)                    )
+       ALLOCATE ( t_surface_h_p%var_1d(1:surf_lsm_h%ns)                  )
+       ALLOCATE ( m_soil_h%var_2d(nzb_soil:nzt_soil,1:surf_lsm_h%ns)     )
+       ALLOCATE ( m_soil_h_p%var_2d(nzb_soil:nzt_soil,1:surf_lsm_h%ns)   )
+       ALLOCATE ( t_soil_h%var_2d(nzb_soil:nzt_soil+1,1:surf_lsm_h%ns)   )
+       ALLOCATE ( t_soil_h_p%var_2d(nzb_soil:nzt_soil+1,1:surf_lsm_h%ns) )
+!
+!--    Vertical surfaces
+       DO  l = 0, 3
+          ALLOCATE ( m_liq_eb_v(l)%var_1d(1:surf_lsm_v(l)%ns)                     )
+          ALLOCATE ( m_liq_eb_v(l)_p%var_1d(1:surf_lsm_v(l)%ns)                   )
+          ALLOCATE ( t_surface_v(l)%var_1d(1:surf_lsm_v(l)%ns)                    )
+          ALLOCATE ( t_surface_v(l)_p%var_1d(1:surf_lsm_v(l)%ns)                  )
+          ALLOCATE ( m_soil_v(l)%var_2d(nzb_soil:nzt_soil,1:surf_lsm_v(l)%ns)     )
+          ALLOCATE ( m_soil_v(l)_p%var_2d(nzb_soil:nzt_soil,1:surf_lsm_v(l)%ns)   )
+          ALLOCATE ( t_soil_v(l)%var_2d(nzb_soil:nzt_soil+1,1:surf_lsm_v(l)%ns)   )
+          ALLOCATE ( t_soil_v(l)_p%var_2d(nzb_soil:nzt_soil+1,1:surf_lsm_v(l)%ns) )
+       ENDDO
 #else
-       ALLOCATE ( m_liq_eb_1(nysg:nyng,nxlg:nxrg) )
-       ALLOCATE ( m_liq_eb_2(nysg:nyng,nxlg:nxrg) )
-       ALLOCATE ( m_soil_1(nzb_soil:nzt_soil,nysg:nyng,nxlg:nxrg) )
-       ALLOCATE ( m_soil_2(nzb_soil:nzt_soil,nysg:nyng,nxlg:nxrg) )
-       ALLOCATE ( t_surface_1(nysg:nyng,nxlg:nxrg) )
-       ALLOCATE ( t_surface_2(nysg:nyng,nxlg:nxrg) )
-       ALLOCATE ( t_soil_1(nzb_soil:nzt_soil+1,nysg:nyng,nxlg:nxrg) )
-       ALLOCATE ( t_soil_2(nzb_soil:nzt_soil+1,nysg:nyng,nxlg:nxrg) )
+!
+!--    Horizontal surfaces
+       ALLOCATE ( m_liq_eb_h_1%var_1d(1:surf_lsm_h%ns)                   )
+       ALLOCATE ( m_liq_eb_h_2%var_1d(1:surf_lsm_h%ns)                   )
+       ALLOCATE ( t_surface_h_1%var_1d(1:surf_lsm_h%ns)                  )
+       ALLOCATE ( t_surface_h_2%var_1d(1:surf_lsm_h%ns)                  )
+       ALLOCATE ( m_soil_h_1%var_2d(nzb_soil:nzt_soil,1:surf_lsm_h%ns)   )
+       ALLOCATE ( m_soil_h_2%var_2d(nzb_soil:nzt_soil,1:surf_lsm_h%ns)   )
+       ALLOCATE ( t_soil_h_1%var_2d(nzb_soil:nzt_soil+1,1:surf_lsm_h%ns) )
+       ALLOCATE ( t_soil_h_2%var_2d(nzb_soil:nzt_soil+1,1:surf_lsm_h%ns) )
+!
+!--    Vertical surfaces
+       DO  l = 0, 3
+          ALLOCATE ( m_liq_eb_v_1(l)%var_1d(1:surf_lsm_v(l)%ns)                   )
+          ALLOCATE ( m_liq_eb_v_2(l)%var_1d(1:surf_lsm_v(l)%ns)                   )
+          ALLOCATE ( t_surface_v_1(l)%var_1d(1:surf_lsm_v(l)%ns)                  )
+          ALLOCATE ( t_surface_v_2(l)%var_1d(1:surf_lsm_v(l)%ns)                  )
+          ALLOCATE ( m_soil_v_1(l)%var_2d(nzb_soil:nzt_soil,1:surf_lsm_v(l)%ns)   )
+          ALLOCATE ( m_soil_v_2(l)%var_2d(nzb_soil:nzt_soil,1:surf_lsm_v(l)%ns)   )
+          ALLOCATE ( t_soil_v_1(l)%var_2d(nzb_soil:nzt_soil+1,1:surf_lsm_v(l)%ns) )
+          ALLOCATE ( t_soil_v_2(l)%var_2d(nzb_soil:nzt_soil+1,1:surf_lsm_v(l)%ns) )
+       ENDDO
 #endif
 
 !
 !--    Allocate intermediate timestep arrays
-       ALLOCATE ( tm_liq_eb_m(nysg:nyng,nxlg:nxrg) )
-       ALLOCATE ( tm_soil_m(nzb_soil:nzt_soil,nysg:nyng,nxlg:nxrg) )
-       ALLOCATE ( tt_surface_m(nysg:nyng,nxlg:nxrg) )
-       ALLOCATE ( tt_soil_m(nzb_soil:nzt_soil,nysg:nyng,nxlg:nxrg) )
+!--    Horizontal surfaces
+       ALLOCATE ( tm_liq_eb_h_m%var_1d(1:surf_lsm_h%ns)                  )
+       ALLOCATE ( tt_surface_h_m%var_1d(1:surf_lsm_h%ns)                 )
+       ALLOCATE ( tm_soil_h_m%var_2d(nzb_soil:nzt_soil,1:surf_lsm_h%ns)  )
+       ALLOCATE ( tt_soil_h_m%var_2d(nzb_soil:nzt_soil,1:surf_lsm_h%ns)  ) 
+!
+!--    Horizontal surfaces
+       DO  l = 0, 3
+          ALLOCATE ( tm_liq_eb_v_m(l)%var_1d(1:surf_lsm_v(l)%ns)                  )
+          ALLOCATE ( tt_surface_v_m(l)%var_1d(1:surf_lsm_v(l)%ns)                 )
+          ALLOCATE ( tm_soil_v_m(l)%var_2d(nzb_soil:nzt_soil,1:surf_lsm_v(l)%ns)  )
+          ALLOCATE ( tt_soil_v_m(l)%var_2d(nzb_soil:nzt_soil,1:surf_lsm_v(l)%ns)  )
+       ENDDO 
+!
+!--    Allocate skin-surface temperature
+       ALLOCATE ( surf_lsm_h%pt_surface(1:surf_lsm_h%ns) )
+       DO  l = 0, 3
+          ALLOCATE ( surf_lsm_v(l)%pt_surface(1:surf_lsm_v(l)%ns) )
+       ENDDO 
 
 !
 !--    Allocate 2D vegetation model arrays
-       ALLOCATE ( alpha_vg(nysg:nyng,nxlg:nxrg) )
-       ALLOCATE ( building_surface(nysg:nyng,nxlg:nxrg) )
-       ALLOCATE ( c_liq(nysg:nyng,nxlg:nxrg) )
-       ALLOCATE ( c_veg(nysg:nyng,nxlg:nxrg) )
-       ALLOCATE ( f_sw_in(nysg:nyng,nxlg:nxrg) )
-       ALLOCATE ( ghf_eb(nysg:nyng,nxlg:nxrg) )
-       ALLOCATE ( gamma_w_sat(nysg:nyng,nxlg:nxrg) )
-       ALLOCATE ( g_d(nysg:nyng,nxlg:nxrg) )
-       ALLOCATE ( lai(nysg:nyng,nxlg:nxrg) )
-       ALLOCATE ( l_vg(nysg:nyng,nxlg:nxrg) )
-       ALLOCATE ( lambda_surface_u(nysg:nyng,nxlg:nxrg) )
-       ALLOCATE ( lambda_surface_s(nysg:nyng,nxlg:nxrg) )
-       ALLOCATE ( m_fc(nysg:nyng,nxlg:nxrg) )
-       ALLOCATE ( m_res(nysg:nyng,nxlg:nxrg) )
-       ALLOCATE ( m_sat(nysg:nyng,nxlg:nxrg) )
-       ALLOCATE ( m_wilt(nysg:nyng,nxlg:nxrg) )
-       ALLOCATE ( n_vg(nysg:nyng,nxlg:nxrg) )
-       ALLOCATE ( pave_surface(nysg:nyng,nxlg:nxrg) )
-       ALLOCATE ( qsws_eb(nysg:nyng,nxlg:nxrg) )
-       ALLOCATE ( qsws_soil_eb(nysg:nyng,nxlg:nxrg) )
-       ALLOCATE ( qsws_liq_eb(nysg:nyng,nxlg:nxrg) )
-       ALLOCATE ( qsws_veg_eb(nysg:nyng,nxlg:nxrg) )
-       ALLOCATE ( rad_net_l(nysg:nyng,nxlg:nxrg) )
-       ALLOCATE ( r_a(nysg:nyng,nxlg:nxrg) )
-       ALLOCATE ( r_canopy(nysg:nyng,nxlg:nxrg) )
-       ALLOCATE ( r_soil(nysg:nyng,nxlg:nxrg) )
-       ALLOCATE ( r_soil_min(nysg:nyng,nxlg:nxrg) )
-       ALLOCATE ( r_s(nysg:nyng,nxlg:nxrg) )
-       ALLOCATE ( r_canopy_min(nysg:nyng,nxlg:nxrg) )
-       ALLOCATE ( shf_eb(nysg:nyng,nxlg:nxrg) )
-       ALLOCATE ( soil_type_2d(nysg:nyng,nxlg:nxrg) )
-       ALLOCATE ( veg_type_2d(nysg:nyng,nxlg:nxrg) )
-       ALLOCATE ( water_surface(nysg:nyng,nxlg:nxrg) )
-
-       water_surface = .FALSE.
-       pave_surface  = .FALSE.
-
+!--    Horizontal surfaces
+       ALLOCATE ( surf_lsm_h%alpha_vg(1:surf_lsm_h%ns)         )
+       ALLOCATE ( surf_lsm_h%building_surface(1:surf_lsm_h%ns) )
+       ALLOCATE ( surf_lsm_h%c_liq(1:surf_lsm_h%ns)            )
+       ALLOCATE ( surf_lsm_h%c_veg(1:surf_lsm_h%ns)            )
+       ALLOCATE ( surf_lsm_h%f_sw_in(1:surf_lsm_h%ns)          )
+       ALLOCATE ( surf_lsm_h%ghf_eb(1:surf_lsm_h%ns)           )
+       ALLOCATE ( surf_lsm_h%gamma_w_sat(1:surf_lsm_h%ns)      )
+       ALLOCATE ( surf_lsm_h%g_d(1:surf_lsm_h%ns)              )
+       ALLOCATE ( surf_lsm_h%lai(1:surf_lsm_h%ns)              )
+       ALLOCATE ( surf_lsm_h%l_vg(1:surf_lsm_h%ns)             )
+       ALLOCATE ( surf_lsm_h%lambda_surface_u(1:surf_lsm_h%ns) )
+       ALLOCATE ( surf_lsm_h%lambda_surface_s(1:surf_lsm_h%ns) )
+       ALLOCATE ( surf_lsm_h%m_fc(1:surf_lsm_h%ns)             )
+       ALLOCATE ( surf_lsm_h%m_res(1:surf_lsm_h%ns)            )
+       ALLOCATE ( surf_lsm_h%m_sat(1:surf_lsm_h%ns)            )
+       ALLOCATE ( surf_lsm_h%m_wilt(1:surf_lsm_h%ns)           )
+       ALLOCATE ( surf_lsm_h%n_vg(1:surf_lsm_h%ns)             )
+       ALLOCATE ( surf_lsm_h%pave_surface(1:surf_lsm_h%ns)     )
+       ALLOCATE ( surf_lsm_h%qsws_eb(1:surf_lsm_h%ns)          )
+       ALLOCATE ( surf_lsm_h%qsws_soil_eb(1:surf_lsm_h%ns)     )
+       ALLOCATE ( surf_lsm_h%qsws_liq_eb(1:surf_lsm_h%ns)      )
+       ALLOCATE ( surf_lsm_h%qsws_veg_eb(1:surf_lsm_h%ns)      )
+       ALLOCATE ( surf_lsm_h%rad_net_l(1:surf_lsm_h%ns)        )
+       ALLOCATE ( surf_lsm_h%r_a(1:surf_lsm_h%ns)              )
+       ALLOCATE ( surf_lsm_h%r_canopy(1:surf_lsm_h%ns)         )
+       ALLOCATE ( surf_lsm_h%r_soil(1:surf_lsm_h%ns)           )
+       ALLOCATE ( surf_lsm_h%r_soil_min(1:surf_lsm_h%ns)       )
+       ALLOCATE ( surf_lsm_h%r_s(1:surf_lsm_h%ns)              )
+       ALLOCATE ( surf_lsm_h%r_canopy_min(1:surf_lsm_h%ns)     )
+       ALLOCATE ( surf_lsm_h%shf_eb(1:surf_lsm_h%ns)           )
+       ALLOCATE ( surf_lsm_h%soil_type_2d(1:surf_lsm_h%ns)     )
+       ALLOCATE ( surf_lsm_h%veg_type_2d(1:surf_lsm_h%ns)      )
+       ALLOCATE ( surf_lsm_h%water_surface(1:surf_lsm_h%ns)    )
+
+       surf_lsm_h%water_surface = .FALSE.
+       surf_lsm_h%pave_surface  = .FALSE.
+!
+!--    Vertical surfaces
+       DO  l = 0, 3
+          ALLOCATE ( surf_lsm_v(l)%alpha_vg(1:surf_lsm_v(l)%ns)         )
+          ALLOCATE ( surf_lsm_v(l)%building_surface(1:surf_lsm_v(l)%ns) )
+          ALLOCATE ( surf_lsm_v(l)%c_liq(1:surf_lsm_v(l)%ns)            )
+          ALLOCATE ( surf_lsm_v(l)%c_veg(1:surf_lsm_v(l)%ns)            )
+          ALLOCATE ( surf_lsm_v(l)%f_sw_in(1:surf_lsm_v(l)%ns)          )
+          ALLOCATE ( surf_lsm_v(l)%ghf_eb(1:surf_lsm_v(l)%ns)           )
+          ALLOCATE ( surf_lsm_v(l)%gamma_w_sat(1:surf_lsm_v(l)%ns)      )
+          ALLOCATE ( surf_lsm_v(l)%g_d(1:surf_lsm_v(l)%ns)              )
+          ALLOCATE ( surf_lsm_v(l)%lai(1:surf_lsm_v(l)%ns)              )
+          ALLOCATE ( surf_lsm_v(l)%l_vg(1:surf_lsm_v(l)%ns)             )
+          ALLOCATE ( surf_lsm_v(l)%lambda_surface_u(1:surf_lsm_v(l)%ns) )
+          ALLOCATE ( surf_lsm_v(l)%lambda_surface_s(1:surf_lsm_v(l)%ns) )
+          ALLOCATE ( surf_lsm_v(l)%m_fc(1:surf_lsm_v(l)%ns)             )
+          ALLOCATE ( surf_lsm_v(l)%m_res(1:surf_lsm_v(l)%ns)            )
+          ALLOCATE ( surf_lsm_v(l)%m_sat(1:surf_lsm_v(l)%ns)            )
+          ALLOCATE ( surf_lsm_v(l)%m_wilt(1:surf_lsm_v(l)%ns)           )
+          ALLOCATE ( surf_lsm_v(l)%n_vg(1:surf_lsm_v(l)%ns)             )
+          ALLOCATE ( surf_lsm_v(l)%pave_surface(1:surf_lsm_v(l)%ns)     )
+          ALLOCATE ( surf_lsm_v(l)%qsws_eb(1:surf_lsm_v(l)%ns)          )
+          ALLOCATE ( surf_lsm_v(l)%qsws_soil_eb(1:surf_lsm_v(l)%ns)     )
+          ALLOCATE ( surf_lsm_v(l)%qsws_liq_eb(1:surf_lsm_v(l)%ns)      )
+          ALLOCATE ( surf_lsm_v(l)%qsws_veg_eb(1:surf_lsm_v(l)%ns)      )
+          ALLOCATE ( surf_lsm_v(l)%rad_net_l(1:surf_lsm_v(l)%ns)        )
+          ALLOCATE ( surf_lsm_v(l)%r_a(1:surf_lsm_v(l)%ns)              )
+          ALLOCATE ( surf_lsm_v(l)%r_canopy(1:surf_lsm_v(l)%ns)         )
+          ALLOCATE ( surf_lsm_v(l)%r_soil(1:surf_lsm_v(l)%ns)           )
+          ALLOCATE ( surf_lsm_v(l)%r_soil_min(1:surf_lsm_v(l)%ns)       )
+          ALLOCATE ( surf_lsm_v(l)%r_s(1:surf_lsm_v(l)%ns)              )
+          ALLOCATE ( surf_lsm_v(l)%r_canopy_min(1:surf_lsm_v(l)%ns)     )
+          ALLOCATE ( surf_lsm_v(l)%shf_eb(1:surf_lsm_v(l)%ns)           )
+          ALLOCATE ( surf_lsm_v(l)%soil_type_2d(1:surf_lsm_v(l)%ns)     )
+          ALLOCATE ( surf_lsm_v(l)%veg_type_2d(1:surf_lsm_v(l)%ns)      )
+          ALLOCATE ( surf_lsm_v(l)%water_surface(1:surf_lsm_v(l)%ns)    )
+
+          surf_lsm_v(l)%water_surface = .FALSE.
+          surf_lsm_v(l)%pave_surface  = .FALSE.
+       ENDDO
+   
 #if ! defined( __nopointer )
 !
 !--    Initial assignment of the pointers
-       t_soil    => t_soil_1;    t_soil_p    => t_soil_2
-       t_surface => t_surface_1; t_surface_p => t_surface_2
-       m_soil    => m_soil_1;    m_soil_p    => m_soil_2
-       m_liq_eb  => m_liq_eb_1;  m_liq_eb_p  => m_liq_eb_2
+!--    Horizontal surfaces
+       t_soil_h    => t_soil_h_1;    t_soil_h_p    => t_soil_h_2
+       t_surface_h => t_surface_h_1; t_surface_h_p => t_surface_h_2
+       m_soil_h    => m_soil_h_1;    m_soil_h_p    => m_soil_h_2
+       m_liq_eb_h  => m_liq_eb_h_1;  m_liq_eb_h_p  => m_liq_eb_h_2
+!
+!--    Vertical surfaces
+       t_soil_v    => t_soil_v_1;    t_soil_v_p    => t_soil_v_2
+       t_surface_v => t_surface_v_1; t_surface_v_p => t_surface_v_2
+       m_soil_v    => m_soil_v_1;    m_soil_v_p    => m_soil_v_2
+       m_liq_eb_v  => m_liq_eb_v_1;  m_liq_eb_v_p  => m_liq_eb_v_2
 #endif
 
@@ -2043,5 +2487,5 @@
                                   conserve_water_content,                      &
                                   f_shortwave_incoming, field_capacity,        & 
-                                  hydraulic_conductivity,                      &
+                                  aero_resist_kray, hydraulic_conductivity,                      &
                                   lambda_surface_stable,                       &
                                   lambda_surface_unstable, leaf_area_index,    &
@@ -2087,14 +2531,16 @@
 !> temperature and water content.
 !------------------------------------------------------------------------------!
-    SUBROUTINE lsm_soil_model
+    SUBROUTINE lsm_soil_model( horizontal, l )
 
 
        IMPLICIT NONE
 
-       INTEGER(iwp) ::  i   !< running index
-       INTEGER(iwp) ::  j   !< running index
-       INTEGER(iwp) ::  k   !< running index
-
-       REAL(wp)     :: h_vg !< Van Genuchten coef. h
+       INTEGER(iwp) ::  k       !< running index
+       INTEGER(iwp) ::  l       !< surface-data type index indication facing
+       INTEGER(iwp) ::  m       !< running index
+
+       LOGICAL      ::  horizontal !< flag indication horizontal wall, required to set pointer accordingly
+
+       REAL(wp)     ::  h_vg !< Van Genuchten coef. h
 
        REAL(wp), DIMENSION(nzb_soil:nzt_soil) :: gamma_temp,  & !< temp. gamma
@@ -2102,271 +2548,294 @@
                                                  tend           !< tendency
 
-       DO  i = nxlg, nxrg
-          DO  j = nysg, nyng
-
-             IF ( pave_surface(j,i) )  THEN
-                rho_c_total(nzb_soil,j,i) = pave_heat_capacity
-                lambda_temp(nzb_soil)     = pave_heat_conductivity
+       TYPE(surf_type_lsm), POINTER ::  surf_m_soil
+       TYPE(surf_type_lsm), POINTER ::  surf_m_soil_p
+       TYPE(surf_type_lsm), POINTER ::  surf_t_soil
+       TYPE(surf_type_lsm), POINTER ::  surf_t_soil_p
+       TYPE(surf_type_lsm), POINTER ::  surf_tm_soil_m
+       TYPE(surf_type_lsm), POINTER ::  surf_tt_soil_m
+
+       TYPE(surf_type), POINTER  ::  surf  !< surface-date type variable
+
+       IF ( horizontal )  THEN
+          surf           => surf_lsm_h
+
+          surf_m_soil    => m_soil_h
+          surf_m_soil_p  => m_soil_h_p
+          surf_t_soil    => t_soil_h
+          surf_t_soil_p  => t_soil_h_p
+          surf_tm_soil_m => tm_soil_h_m
+          surf_tt_soil_m => tt_soil_h_m
+       ELSE
+          surf           => surf_lsm_v(l)
+
+          surf_m_soil    => m_soil_v(l)
+          surf_m_soil_p  => m_soil_v_p(l)
+          surf_t_soil    => t_soil_v(l)
+          surf_t_soil_p  => t_soil_v_p(l)
+          surf_tm_soil_m => tm_soil_v_m(l)
+          surf_tt_soil_m => tt_soil_v_m(l)
+       ENDIF
+
+       DO  m = 1, surf%ns
+
+          IF ( surf%pave_surface(m) )  THEN
+             surf%rho_c_total(nzb_soil,m) = pave_heat_capacity
+             lambda_temp(nzb_soil)          = pave_heat_conductivity
+          ENDIF
+
+          IF (  .NOT.  surf%water_surface(m) )  THEN
+             DO  k = nzb_soil, nzt_soil
+
+                IF ( surf%pave_surface(m)  .AND.  zs(k) <= pave_depth )  THEN
+                    
+                   surf%rho_c_total(k,m) = pave_heat_capacity
+                   lambda_temp(k)        = pave_heat_conductivity   
+
+                ELSE            
+!
+!--                Calculate volumetric heat capacity of the soil, taking 
+!--                into account water content 
+                   surf%rho_c_total(k,m) = (rho_c_soil *                 &
+                                               ( 1.0_wp - surf%m_sat(m) )&
+                                               + rho_c_water * surf_m_soil%var_2d(k,m) )
+
+!
+!--                Calculate soil heat conductivity at the center of the soil
+!--                layers
+                   lambda_h_sat = lambda_h_sm**(1.0_wp - surf%m_sat(m)) *&
+                                  lambda_h_water ** surf_m_soil%var_2d(k,m)
+
+                   ke = 1.0_wp + LOG10( MAX( 0.1_wp, surf_m_soil%var_2d(k,m) /             &
+                                                     surf%m_sat(m) ) )
+
+                   lambda_temp(k) = ke * (lambda_h_sat - lambda_h_dry) +       &
+                                    lambda_h_dry
+                ENDIF
+             ENDDO
+
+!
+!--          Calculate soil heat conductivity (lambda_h) at the _stag level 
+!--          using linear interpolation. For pavement surface, the
+!--          true pavement depth is considered
+             DO  k = nzb_soil, nzt_soil-1
+                IF ( surf%pave_surface(m)  .AND.  zs(k)   < pave_depth   &
+                                                 .AND.  zs(k+1) > pave_depth )  THEN
+                   surf%lambda_h(k,m) = ( pave_depth - zs(k) ) / dz_soil(k+1)&
+                                     * lambda_temp(k)                          &
+                                     + ( 1.0_wp - ( pave_depth - zs(k) )       &
+                                     / dz_soil(k+1) ) * lambda_temp(k+1)
+                ELSE
+                   surf%lambda_h(k,m) = ( lambda_temp(k+1) + lambda_temp(k) )&
+                                     * 0.5_wp
+                ENDIF
+             ENDDO
+             surf%lambda_h(nzt_soil,m) = lambda_temp(nzt_soil)
+
+!
+!--          Prognostic equation for soil temperature t_soil
+             tend(:) = 0.0_wp
+
+             tend(nzb_soil) = ( 1.0_wp / surf%rho_c_total(nzb_soil,m) ) *&
+                    ( surf%lambda_h(nzb_soil,m) * ( surf_t_soil%var_2d(nzb_soil+1,m) &
+                      - surf_t_soil%var_2d(nzb_soil,m) ) * ddz_soil(nzb_soil+1)            &
+                      + surf%ghf_eb(m) ) * ddz_soil_stag(nzb_soil)
+
+             DO  k = nzb_soil+1, nzt_soil
+                tend(k) = ( 1.0_wp / surf%rho_c_total(k,m) )             &
+                          * (   surf%lambda_h(k,m)                       &
+                              * ( surf_t_soil%var_2d(k+1,m) - surf_t_soil%var_2d(k,m) )                &
+                              * ddz_soil(k+1)                                  &
+                              - surf%lambda_h(k-1,m)                     &
+                              * ( surf_t_soil%var_2d(k,m) - surf_t_soil%var_2d(k-1,m) )                &
+                              * ddz_soil(k)                                    &
+                            ) * ddz_soil_stag(k)
+
+             ENDDO
+
+             surf_t_soil_p%var_2d(nzb_soil:nzt_soil,m) = surf_t_soil%var_2d(nzb_soil:nzt_soil,m)       &
+                                               + dt_3d * ( tsc(2)              &
+                                               * tend(nzb_soil:nzt_soil)       & 
+                                               + tsc(3)                        &
+                                               * surf_tt_soil_m%var_2d(nzb_soil:nzt_soil,m) )
+
+!
+!--          Calculate t_soil tendencies for the next Runge-Kutta step
+             IF ( timestep_scheme(1:5) == 'runge' )  THEN
+                IF ( intermediate_timestep_count == 1 )  THEN
+                   DO  k = nzb_soil, nzt_soil
+                      surf_tt_soil_m%var_2d(k,m) = tend(k)
+                   ENDDO
+                ELSEIF ( intermediate_timestep_count <                         &
+                         intermediate_timestep_count_max )  THEN
+                   DO  k = nzb_soil, nzt_soil
+                      surf_tt_soil_m%var_2d(k,m) = -9.5625_wp * tend(k) + 5.3125_wp        &
+                                         * surf_tt_soil_m%var_2d(k,m)
+                   ENDDO
+                ENDIF
              ENDIF
 
-             IF (  .NOT.  water_surface(j,i) )  THEN
+
+             DO  k = nzb_soil, nzt_soil
+
+!
+!--             Calculate soil diffusivity at the center of the soil layers
+                lambda_temp(k) = (- b_ch * surf%gamma_w_sat(m) * psi_sat     &
+                                  / surf%m_sat(m) ) * ( MAX( surf_m_soil%var_2d(k,m),    &
+                                  surf%m_wilt(m) ) / surf%m_sat(m) )**(&
+                                                            b_ch + 2.0_wp )
+
+!
+!--             Parametrization of Van Genuchten
+                IF ( soil_type /= 7 )  THEN
+!
+!--                Calculate the hydraulic conductivity after Van Genuchten 
+!--                (1980)
+                   h_vg = ( ( ( surf%m_res(m) - surf%m_sat(m) ) /  &
+                              ( surf%m_res(m) -                          &
+                                MAX( surf_m_soil%var_2d(k,m), surf%m_wilt(m) )       &
+                              )                                                &
+                            )**(                                               &
+                          surf%n_vg(m) / ( surf%n_vg(m) - 1.0_wp ) &
+                               ) - 1.0_wp                                      &
+                          )**( 1.0_wp / surf%n_vg(m) ) / surf%alpha_vg(m)
+
+                   gamma_temp(k) = surf%gamma_w_sat(m) * ( ( ( 1.0_wp +  &
+                          ( surf%alpha_vg(m) * h_vg )**surf%n_vg(m)&
+                                                               )**(            &
+                              1.0_wp - 1.0_wp / surf%n_vg(m)) - (        &
+                          surf%alpha_vg(m) * h_vg )**( surf%n_vg(m)&
+                              - 1.0_wp) )**2 )                                 &
+                              / ( ( 1.0_wp + ( surf%alpha_vg(m) * h_vg   &
+                              )**surf%n_vg(m) )**( ( 1.0_wp  - 1.0_wp    &
+                              / surf%n_vg(m) ) *                         &
+                              ( surf%l_vg(m) + 2.0_wp) ) )
+!
+!--             Parametrization of Clapp & Hornberger
+                ELSE
+                   gamma_temp(k) = surf%gamma_w_sat(m) * ( surf_m_soil%var_2d(k,m)   &
+                                   / surf%m_sat(m) )**(2.0_wp * b_ch + 3.0_wp)
+                ENDIF
+
+             ENDDO
+
+!
+!--          Prognostic equation for soil moisture content. Only performed,
+!--          when humidity is enabled in the atmosphere and the surface type
+!--          is not pavement (implies dry soil below).
+             IF ( humidity  .AND.  .NOT.  surf%pave_surface(m) )  THEN
+!
+!--             Calculate soil diffusivity (lambda_w) at the _stag level 
+!--             using linear interpolation. To do: replace this with
+!--             ECMWF-IFS Eq. 8.81
+                DO  k = nzb_soil, nzt_soil-1
+                    
+                   surf%lambda_w(k,m) = ( lambda_temp(k+1) +             &
+                                                lambda_temp(k) ) * 0.5_wp
+                   surf%gamma_w(k,m)  = ( gamma_temp(k+1)  +             &
+                                                gamma_temp(k) )  * 0.5_wp
+
+                ENDDO
+
+!
+!
+!--             In case of a closed bottom (= water content is conserved), 
+!--             set hydraulic conductivity to zero to that no water will be 
+!--             lost in the bottom layer.
+                IF ( conserve_water_content )  THEN
+                   surf%gamma_w(nzt_soil,m) = 0.0_wp
+                ELSE
+                   surf%gamma_w(nzt_soil,m) = gamma_temp(nzt_soil)
+                ENDIF     
+
+!--             The root extraction (= root_extr * qsws_veg_eb / (rho_l     
+!--             * l_v)) ensures the mass conservation for water. The         
+!--             transpiration of plants equals the cumulative withdrawals by 
+!--             the roots in the soil. The scheme takes into account the 
+!--             availability of water in the soil layers as well as the root 
+!--             fraction in the respective layer. Layer with moisture below 
+!--             wilting point will not contribute, which reflects the 
+!--             preference of plants to take water from moister layers.
+!
+!--             Calculate the root extraction (ECMWF 7.69, the sum of 
+!--             root_extr = 1). The energy balance solver guarantees a 
+!--             positive transpiration, so that there is no need for an 
+!--             additional check.
+                m_total = 0.0_wp
                 DO  k = nzb_soil, nzt_soil
-
-
-                   IF ( pave_surface(j,i)  .AND.  zs(k) <= pave_depth )  THEN
-                    
-                      rho_c_total(k,j,i) = pave_heat_capacity
-                      lambda_temp(k)     = pave_heat_conductivity   
-
-                   ELSE            
-!
-!--                   Calculate volumetric heat capacity of the soil, taking 
-!--                   into account water content 
-                      rho_c_total(k,j,i) = (rho_c_soil * (1.0_wp - m_sat(j,i)) &
-                                           + rho_c_water * m_soil(k,j,i))
-
-!
-!--                   Calculate soil heat conductivity at the center of the soil
-!--                   layers
-                      lambda_h_sat = lambda_h_sm ** (1.0_wp - m_sat(j,i)) *    &
-                                     lambda_h_water ** m_soil(k,j,i)
-
-                      ke = 1.0_wp + LOG10(MAX(0.1_wp,m_soil(k,j,i)             &
-                                                     / m_sat(j,i)))
-
-                      lambda_temp(k) = ke * (lambda_h_sat - lambda_h_dry) +    &
-                                       lambda_h_dry
-                   ENDIF
-
+                    IF ( surf_m_soil%var_2d(k,m) > surf%m_wilt(m) )  THEN
+                       m_total = m_total + surf%root_fr(k,m) * surf_m_soil%var_2d(k,m)
+                    ENDIF
+                ENDDO  
+                 IF ( m_total > 0.0_wp )  THEN
+                   DO  k = nzb_soil, nzt_soil
+                      IF ( surf_m_soil%var_2d(k,m) > surf%m_wilt(m) )  THEN
+                         root_extr(k) = surf%root_fr(k,m) * surf_m_soil%var_2d(k,m)  &
+                                                            / m_total
+                      ELSE
+                         root_extr(k) = 0.0_wp
+                      ENDIF
+                   ENDDO
+                ENDIF
+!
+!--             Prognostic equation for soil water content m_soil_h.
+                tend(:) = 0.0_wp
+
+                tend(nzb_soil) = ( surf%lambda_w(nzb_soil,m) *   (       &
+                         surf_m_soil%var_2d(nzb_soil+1,m) - surf_m_soil%var_2d(nzb_soil,m) )           &
+                         * ddz_soil(nzb_soil+1) - surf%gamma_w(nzb_soil,m) - &
+                                                     (                         &
+                            root_extr(nzb_soil) * surf%qsws_veg_eb(m)    &
+                            + surf%qsws_soil_eb(m) ) * drho_l_lv )       &
+                            * ddz_soil_stag(nzb_soil)
+
+                DO  k = nzb_soil+1, nzt_soil-1
+                   tend(k) = ( surf%lambda_w(k,m) * ( surf_m_soil%var_2d(k+1,m)      &
+                             - surf_m_soil%var_2d(k,m) ) * ddz_soil(k+1)                   &
+                             - surf%gamma_w(k,m)                         &
+                             - surf%lambda_w(k-1,m) * ( surf_m_soil%var_2d(k,m) -    &
+                             surf_m_soil%var_2d(k-1,m)) * ddz_soil(k)                      &
+                             + surf%gamma_w(k-1,m) - (root_extr(k)       &
+                             * surf%qsws_veg_eb(m) * drho_l_lv)          &
+                             ) * ddz_soil_stag(k)
                 ENDDO
-
-!
-!--             Calculate soil heat conductivity (lambda_h) at the _stag level 
-!--             using linear interpolation. For pavement surface, the
-!--             true pavement depth is considered
-                DO  k = nzb_soil, nzt_soil-1
-                   IF ( pave_surface(j,i)  .AND.  zs(k)   < pave_depth         &
-                                           .AND.  zs(k+1) > pave_depth )  THEN
-                      lambda_h(k,j,i) = ( pave_depth - zs(k) ) / dz_soil(k+1)  &
-                                        * lambda_temp(k)                       &
-                                        + ( 1.0_wp - ( pave_depth - zs(k) )    &
-                                        / dz_soil(k+1) ) * lambda_temp(k+1)
-                   ELSE
-                      lambda_h(k,j,i) = ( lambda_temp(k+1) + lambda_temp(k) )  &
-                                        * 0.5_wp
-                   ENDIF
+                tend(nzt_soil) = ( - surf%gamma_w(nzt_soil,m)            &
+                                     - surf%lambda_w(nzt_soil-1,m)       &
+                                     * ( surf_m_soil%var_2d(nzt_soil,m)                    &
+                                     - surf_m_soil%var_2d(nzt_soil-1,m))                   &
+                                     * ddz_soil(nzt_soil)                      &
+                                     + surf%gamma_w(nzt_soil-1,m) - (    &
+                                       root_extr(nzt_soil)                     &
+                                     * surf%qsws_veg_eb(m) * drho_l_lv ) &
+                                  ) * ddz_soil_stag(nzt_soil)             
+
+                surf_m_soil_p%var_2d(nzb_soil:nzt_soil,m) = surf_m_soil%var_2d(nzb_soil:nzt_soil,m)    &
+                                                + dt_3d * ( tsc(2) * tend(:)   &
+                                                + tsc(3) * surf_tm_soil_m%var_2d(:,m) )   
+   
+!
+!--             Account for dry soils (find a better solution here!)
+                DO  k = nzb_soil, nzt_soil
+                   IF ( surf_m_soil_p%var_2d(k,m) < 0.0_wp )  surf_m_soil_p%var_2d(k,m) = 0.0_wp
                 ENDDO
-                lambda_h(nzt_soil,j,i) = lambda_temp(nzt_soil)
-
-
-
-
-!
-!--             Prognostic equation for soil temperature t_soil
-                tend(:) = 0.0_wp
-
-                tend(nzb_soil) = (1.0_wp/rho_c_total(nzb_soil,j,i)) *          &
-                          ( lambda_h(nzb_soil,j,i) * ( t_soil(nzb_soil+1,j,i)  &
-                            - t_soil(nzb_soil,j,i) ) * ddz_soil(nzb_soil+1)    &
-                            + ghf_eb(j,i) ) * ddz_soil_stag(nzb_soil)
-
-                DO  k = nzb_soil+1, nzt_soil
-                   tend(k) = (1.0_wp/rho_c_total(k,j,i))                       &
-                             * (   lambda_h(k,j,i)                             &
-                                 * ( t_soil(k+1,j,i) - t_soil(k,j,i) )         &
-                                 * ddz_soil(k+1)                               &
-                                 - lambda_h(k-1,j,i)                           &
-                                 * ( t_soil(k,j,i) - t_soil(k-1,j,i) )         &
-                                 * ddz_soil(k)                                 &
-                               ) * ddz_soil_stag(k)
-
-                ENDDO
-
-                t_soil_p(nzb_soil:nzt_soil,j,i) = t_soil(nzb_soil:nzt_soil,j,i)&
-                                                  + dt_3d * ( tsc(2)           &
-                                                  * tend(nzb_soil:nzt_soil)    & 
-                                                  + tsc(3)                     &
-                                                  * tt_soil_m(:,j,i) )   
-
-!
-!--             Calculate t_soil tendencies for the next Runge-Kutta step
+
+!
+!--             Calculate m_soil tendencies for the next Runge-Kutta step
                 IF ( timestep_scheme(1:5) == 'runge' )  THEN
                    IF ( intermediate_timestep_count == 1 )  THEN
                       DO  k = nzb_soil, nzt_soil
-                         tt_soil_m(k,j,i) = tend(k)
+                         surf_tm_soil_m%var_2d(k,m) = tend(k)
                       ENDDO
                    ELSEIF ( intermediate_timestep_count <                      &
                             intermediate_timestep_count_max )  THEN
                       DO  k = nzb_soil, nzt_soil
-                         tt_soil_m(k,j,i) = -9.5625_wp * tend(k) + 5.3125_wp   &
-                                         * tt_soil_m(k,j,i)
+                         surf_tm_soil_m%var_2d(k,m) = -9.5625_wp * tend(k) + 5.3125_wp     &
+                                  * surf_tm_soil_m%var_2d(k,m)
                       ENDDO
                    ENDIF
                 ENDIF
-
-
-                DO  k = nzb_soil, nzt_soil
-
-!
-!--                Calculate soil diffusivity at the center of the soil layers
-                   lambda_temp(k) = (- b_ch * gamma_w_sat(j,i) * psi_sat       &
-                                     / m_sat(j,i) ) * ( MAX( m_soil(k,j,i),    &
-                                     m_wilt(j,i) ) / m_sat(j,i) )**(           &
-                                     b_ch + 2.0_wp )
-
-!
-!--                Parametrization of Van Genuchten
-                   IF ( soil_type /= 7 )  THEN
-!
-!--                   Calculate the hydraulic conductivity after Van Genuchten 
-!--                   (1980)
-                      h_vg = ( ( (m_res(j,i) - m_sat(j,i)) / ( m_res(j,i) -    &
-                                 MAX( m_soil(k,j,i), m_wilt(j,i) ) ) )**(      &
-                                 n_vg(j,i) / (n_vg(j,i) - 1.0_wp ) ) - 1.0_wp  &
-                             )**( 1.0_wp / n_vg(j,i) ) / alpha_vg(j,i)
-
-
-                      gamma_temp(k) = gamma_w_sat(j,i) * ( ( (1.0_wp +         &
-                                      ( alpha_vg(j,i) * h_vg )**n_vg(j,i))**(  &
-                                      1.0_wp - 1.0_wp / n_vg(j,i) ) - (        &
-                                      alpha_vg(j,i) * h_vg )**( n_vg(j,i)      &
-                                      - 1.0_wp) )**2 )                         &
-                                      / ( ( 1.0_wp + ( alpha_vg(j,i) * h_vg    &
-                                      )**n_vg(j,i) )**( ( 1.0_wp  - 1.0_wp     &
-                                      / n_vg(j,i) ) *( l_vg(j,i) + 2.0_wp) ) )
-
-!
-!--                Parametrization of Clapp & Hornberger
-                   ELSE
-                      gamma_temp(k) = gamma_w_sat(j,i) * ( m_soil(k,j,i)       &
-                                      / m_sat(j,i) )**(2.0_wp * b_ch + 3.0_wp)
-                   ENDIF
-
-                ENDDO
-
-!
-!--             Prognostic equation for soil moisture content. Only performed,
-!--             when humidity is enabled in the atmosphere and the surface type
-!--             is not pavement (implies dry soil below).
-                IF ( humidity  .AND.  .NOT.  pave_surface(j,i) )  THEN
-!
-!--                Calculate soil diffusivity (lambda_w) at the _stag level 
-!--                using linear interpolation. To do: replace this with
-!--                ECMWF-IFS Eq. 8.81
-                   DO  k = nzb_soil, nzt_soil-1
-                     
-                      lambda_w(k,j,i) = ( lambda_temp(k+1) + lambda_temp(k) )  &
-                                        * 0.5_wp
-                      gamma_w(k,j,i)  = ( gamma_temp(k+1) + gamma_temp(k) )    &
-                                        * 0.5_wp
-
-                   ENDDO
-
-!
-!
-!--                In case of a closed bottom (= water content is conserved), 
-!--                set hydraulic conductivity to zero to that no water will be 
-!--                lost in the bottom layer.
-                   IF ( conserve_water_content )  THEN
-                      gamma_w(nzt_soil,j,i) = 0.0_wp
-                   ELSE
-                      gamma_w(nzt_soil,j,i) = gamma_temp(nzt_soil)
-                   ENDIF     
-
-!--                The root extraction (= root_extr * qsws_veg_eb / (rho_l     
-!--                * l_v)) ensures the mass conservation for water. The         
-!--                transpiration of plants equals the cumulative withdrawals by 
-!--                the roots in the soil. The scheme takes into account the 
-!--                availability of water in the soil layers as well as the root 
-!--                fraction in the respective layer. Layer with moisture below 
-!--                wilting point will not contribute, which reflects the 
-!--                preference of plants to take water from moister layers.
-
-!
-!--                Calculate the root extraction (ECMWF 7.69, the sum of 
-!--                root_extr = 1). The energy balance solver guarantees a 
-!--                positive transpiration, so that there is no need for an 
-!--                additional check.
-                   m_total = 0.0_wp
-                   DO  k = nzb_soil, nzt_soil
-                       IF ( m_soil(k,j,i) > m_wilt(j,i) )  THEN
-                          m_total = m_total + root_fr(k,j,i) * m_soil(k,j,i)
-                       ENDIF
-                   ENDDO  
-
-                   IF ( m_total > 0.0_wp )  THEN
-                      DO  k = nzb_soil, nzt_soil
-                         IF ( m_soil(k,j,i) > m_wilt(j,i) )  THEN
-                            root_extr(k) = root_fr(k,j,i) * m_soil(k,j,i)      &
-                                                            / m_total
-                         ELSE
-                            root_extr(k) = 0.0_wp
-                         ENDIF
-                      ENDDO
-                   ENDIF
-
-!
-!--                Prognostic equation for soil water content m_soil.
-                   tend(:) = 0.0_wp
-
-                   tend(nzb_soil) = ( lambda_w(nzb_soil,j,i) * (               &
-                            m_soil(nzb_soil+1,j,i) - m_soil(nzb_soil,j,i) )    &
-                            * ddz_soil(nzb_soil+1) - gamma_w(nzb_soil,j,i) - ( &
-                               root_extr(nzb_soil) * qsws_veg_eb(j,i)          &
-                               + qsws_soil_eb(j,i) ) * drho_l_lv )             &
-                               * ddz_soil_stag(nzb_soil)
-
-                   DO  k = nzb_soil+1, nzt_soil-1
-                      tend(k) = ( lambda_w(k,j,i) * ( m_soil(k+1,j,i)          &
-                                - m_soil(k,j,i) ) * ddz_soil(k+1)              &
-                                - gamma_w(k,j,i)                               &
-                                - lambda_w(k-1,j,i) * (m_soil(k,j,i) -         &
-                                m_soil(k-1,j,i)) * ddz_soil(k)                 &
-                                + gamma_w(k-1,j,i) - (root_extr(k)             &
-                                * qsws_veg_eb(j,i) * drho_l_lv)                &
-                                ) * ddz_soil_stag(k)
-
-                   ENDDO
-                   tend(nzt_soil) = ( - gamma_w(nzt_soil,j,i)                  &
-                                           - lambda_w(nzt_soil-1,j,i)          &
-                                           * (m_soil(nzt_soil,j,i)             &
-                                           - m_soil(nzt_soil-1,j,i))           &
-                                           * ddz_soil(nzt_soil)                &
-                                           + gamma_w(nzt_soil-1,j,i) - (       &
-                                             root_extr(nzt_soil)               &
-                                           * qsws_veg_eb(j,i) * drho_l_lv  )   &
-                                     ) * ddz_soil_stag(nzt_soil)             
-
-                   m_soil_p(nzb_soil:nzt_soil,j,i) = m_soil(nzb_soil:nzt_soil,j,i)&
-                                                   + dt_3d * ( tsc(2) * tend(:)   &
-                                                   + tsc(3) * tm_soil_m(:,j,i) )   
-   
-!
-!--                Account for dry soils (find a better solution here!)
-                   DO  k = nzb_soil, nzt_soil
-                      IF ( m_soil_p(k,j,i) < 0.0_wp )  m_soil_p(k,j,i) = 0.0_wp
-                   ENDDO
-
-!
-!--                Calculate m_soil tendencies for the next Runge-Kutta step
-                   IF ( timestep_scheme(1:5) == 'runge' )  THEN
-                      IF ( intermediate_timestep_count == 1 )  THEN
-                         DO  k = nzb_soil, nzt_soil
-                            tm_soil_m(k,j,i) = tend(k)
-                         ENDDO
-                      ELSEIF ( intermediate_timestep_count <                   &
-                               intermediate_timestep_count_max )  THEN
-                         DO  k = nzb_soil, nzt_soil
-                            tm_soil_m(k,j,i) = -9.5625_wp * tend(k) + 5.3125_wp&
-                                     * tm_soil_m(k,j,i)
-                         ENDDO
-                      ENDIF
-                   ENDIF
-
-                ENDIF
-
              ENDIF
 
-          ENDDO
+          ENDIF
+
        ENDDO
 
@@ -2386,10 +2855,19 @@
 
 #if defined( __nopointer )
-
-       t_surface    = t_surface_p
-       t_soil       = t_soil_p
+!
+!--    Horizontal surfaces
+       t_surface_h  = t_surface_h_p
+       t_soil_h     = t_soil_h_p
        IF ( humidity )  THEN
-          m_soil    = m_soil_p
-          m_liq_eb  = m_liq_eb_p
+          m_soil_h    = m_soil_h_p
+          m_liq_eb_h  = m_liq_eb_h_p
+       ENDIF
+!
+!--    Vertical surfaces
+       t_surface_v  = t_surface_v_p
+       t_soil_v     = t_soil_v_p
+       IF ( humidity )  THEN
+          m_soil_v    = m_soil_v_p
+          m_liq_eb_v  = m_liq_eb_v_p
        ENDIF
 
@@ -2399,20 +2877,39 @@
 
           CASE ( 0 )
-
-             t_surface  => t_surface_1; t_surface_p  => t_surface_2
-             t_soil     => t_soil_1;    t_soil_p     => t_soil_2
+!
+!--          Horizontal surfaces
+             t_surface_h  => t_surface_h_1; t_surface_h_p  => t_surface_h_2
+             t_soil_h     => t_soil_h_1;    t_soil_h_p     => t_soil_h_2
              IF ( humidity )  THEN
-                m_soil    => m_soil_1;   m_soil_p    => m_soil_2
-                m_liq_eb  => m_liq_eb_1; m_liq_eb_p  => m_liq_eb_2
+                m_soil_h    => m_soil_h_1;   m_soil_h_p    => m_soil_h_2
+                m_liq_eb_h  => m_liq_eb_h_1; m_liq_eb_h_p  => m_liq_eb_h_2
              ENDIF
+!
+!--          Vertical surfaces
+             t_surface_v  => t_surface_v_1; t_surface_v_p  => t_surface_v_2
+             t_soil_v     => t_soil_v_1;    t_soil_v_p     => t_soil_v_2
+             IF ( humidity )  THEN
+                m_soil_v    => m_soil_v_1;   m_soil_v_p    => m_soil_v_2
+                m_liq_eb_v  => m_liq_eb_v_1; m_liq_eb_v_p  => m_liq_eb_v_2
+             ENDIF
+
 
 
           CASE ( 1 )
-
-             t_surface  => t_surface_2; t_surface_p  => t_surface_1
-             t_soil     => t_soil_2;    t_soil_p     => t_soil_1
+!
+!--          Horizontal surfaces
+             t_surface_h  => t_surface_h_2; t_surface_h_p  => t_surface_h_1
+             t_soil_h     => t_soil_h_2;    t_soil_h_p     => t_soil_h_1
              IF ( humidity )  THEN
-                m_soil    => m_soil_2;   m_soil_p    => m_soil_1
-                m_liq_eb  => m_liq_eb_2; m_liq_eb_p  => m_liq_eb_1
+                m_soil_h    => m_soil_h_2;   m_soil_h_p    => m_soil_h_1
+                m_liq_eb_h  => m_liq_eb_h_2; m_liq_eb_h_p  => m_liq_eb_h_1
+             ENDIF
+!
+!--          Vertical surfaces
+             t_surface_v  => t_surface_v_2; t_surface_v_p  => t_surface_v_1
+             t_soil_v     => t_soil_v_2;    t_soil_v_p     => t_soil_v_1
+             IF ( humidity )  THEN
+                m_soil_v    => m_soil_v_2;   m_soil_v_p    => m_soil_v_1
+                m_liq_eb_v  => m_liq_eb_v_2; m_liq_eb_v_p  => m_liq_eb_v_1
              ENDIF
 
@@ -2445,7 +2942,8 @@
     CHARACTER (LEN=*) :: variable !< 
 
-    INTEGER(iwp) ::  i !< 
-    INTEGER(iwp) ::  j !< 
-    INTEGER(iwp) ::  k !< 
+    INTEGER(iwp) ::  i       !< 
+    INTEGER(iwp) ::  j       !< 
+    INTEGER(iwp) ::  k       !< 
+    INTEGER(iwp) ::  m       !< running index
 
     IF ( mode == 'allocate' )  THEN
@@ -2553,109 +3051,112 @@
 
           CASE ( 'c_liq*' )
-             DO  i = nxlg, nxrg
-                DO  j = nysg, nyng
-                   c_liq_av(j,i) = c_liq_av(j,i) + c_liq(j,i)
+             DO  m = 1, surf_lsm_h%ns
+                i   = surf_lsm_h%i(m)            
+                j   = surf_lsm_h%j(m)
+                c_liq_av(j,i) = c_liq_av(j,i) + surf_lsm_h%c_liq(m)
+             ENDDO
+
+          CASE ( 'c_soil*' )
+             DO  m = 1, surf_lsm_h%ns
+                i   = surf_lsm_h%i(m)            
+                j   = surf_lsm_h%j(m)
+                c_soil_av(j,i) = c_soil_av(j,i) + (1.0 - surf_lsm_h%c_veg(m))
+             ENDDO
+
+          CASE ( 'c_veg*' )
+             DO  m = 1, surf_lsm_h%ns
+                i   = surf_lsm_h%i(m)            
+                j   = surf_lsm_h%j(m)
+                c_veg_av(j,i) = c_veg_av(j,i) + surf_lsm_h%c_veg(m)
+             ENDDO
+
+          CASE ( 'ghf_eb*' )
+             DO  m = 1, surf_lsm_h%ns
+                i   = surf_lsm_h%i(m)            
+                j   = surf_lsm_h%j(m)
+                ghf_eb_av(j,i) = ghf_eb_av(j,i) + surf_lsm_h%ghf_eb(m)
+             ENDDO
+
+          CASE ( 'lai*' )
+             DO  m = 1, surf_lsm_h%ns
+                i   = surf_lsm_h%i(m)            
+                j   = surf_lsm_h%j(m)
+                lai_av(j,i) = lai_av(j,i) + surf_lsm_h%lai(m)
+             ENDDO
+
+          CASE ( 'm_liq_eb*' )
+             DO  m = 1, surf_lsm_h%ns
+                i   = surf_lsm_h%i(m)            
+                j   = surf_lsm_h%j(m)
+                m_liq_eb_av(j,i) = m_liq_eb_av(j,i) + m_liq_eb_h%var_1d(m)
+             ENDDO
+
+          CASE ( 'm_soil' )
+             DO  m = 1, surf_lsm_h%ns
+                i   = surf_lsm_h%i(m)            
+                j   = surf_lsm_h%j(m)
+                DO  k = nzb_soil, nzt_soil
+                   m_soil_av(k,j,i) = m_soil_av(k,j,i) + m_soil_h%var_2d(k,m)
                 ENDDO
              ENDDO
 
-          CASE ( 'c_soil*' )
-             DO  i = nxlg, nxrg
-                DO  j = nysg, nyng
-                   c_soil_av(j,i) = c_soil_av(j,i) + (1.0 - c_veg(j,i))
-                ENDDO
-             ENDDO
-
-          CASE ( 'c_veg*' )
-             DO  i = nxlg, nxrg
-                DO  j = nysg, nyng
-                   c_veg_av(j,i) = c_veg_av(j,i) + c_veg(j,i)
-                ENDDO
-             ENDDO
-
-          CASE ( 'ghf_eb*' )
-             DO  i = nxlg, nxrg
-                DO  j = nysg, nyng
-                   ghf_eb_av(j,i) = ghf_eb_av(j,i) + ghf_eb(j,i)
-                ENDDO
-             ENDDO
-
-          CASE ( 'lai*' )
-             DO  i = nxlg, nxrg
-                DO  j = nysg, nyng
-                   lai_av(j,i) = lai_av(j,i) + lai(j,i)
-                ENDDO
-             ENDDO
-
-          CASE ( 'm_liq_eb*' )
-             DO  i = nxlg, nxrg
-                DO  j = nysg, nyng
-                   m_liq_eb_av(j,i) = m_liq_eb_av(j,i) + m_liq_eb(j,i)
-                ENDDO
-             ENDDO
-
-          CASE ( 'm_soil' )
-             DO  i = nxlg, nxrg
-                DO  j = nysg, nyng
-                   DO  k = nzb_soil, nzt_soil
-                      m_soil_av(k,j,i) = m_soil_av(k,j,i) + m_soil(k,j,i)
-                   ENDDO
-                ENDDO
-             ENDDO
-
           CASE ( 'qsws_eb*' )
-             DO  i = nxlg, nxrg
-                DO  j = nysg, nyng
-                   qsws_eb_av(j,i) = qsws_eb_av(j,i) + qsws_eb(j,i)
-                ENDDO
+             DO  m = 1, surf_lsm_h%ns
+                i   = surf_lsm_h%i(m)            
+                j   = surf_lsm_h%j(m)
+                qsws_eb_av(j,i) = qsws_eb_av(j,i) + surf_lsm_h%qsws_eb(m)
              ENDDO
 
           CASE ( 'qsws_liq_eb*' )
-             DO  i = nxlg, nxrg
-                DO  j = nysg, nyng
-                   qsws_liq_eb_av(j,i) = qsws_liq_eb_av(j,i) + qsws_liq_eb(j,i)
-                ENDDO
+             DO  m = 1, surf_lsm_h%ns
+                i   = surf_lsm_h%i(m)            
+                j   = surf_lsm_h%j(m)
+                qsws_liq_eb_av(j,i) = qsws_liq_eb_av(j,i) +                    &
+                                      surf_lsm_h%qsws_liq_eb(m)
              ENDDO
 
           CASE ( 'qsws_soil_eb*' )
-             DO  i = nxlg, nxrg
-                DO  j = nysg, nyng
-                   qsws_soil_eb_av(j,i) = qsws_soil_eb_av(j,i) + qsws_soil_eb(j,i)
-                ENDDO
+             DO  m = 1, surf_lsm_h%ns
+                i   = surf_lsm_h%i(m)            
+                j   = surf_lsm_h%j(m)
+                qsws_soil_eb_av(j,i) = qsws_soil_eb_av(j,i) +                  &
+                                       surf_lsm_h%qsws_soil_eb(m)
              ENDDO
 
           CASE ( 'qsws_veg_eb*' )
-             DO  i = nxlg, nxrg
-                DO  j = nysg, nyng
-                   qsws_veg_eb_av(j,i) = qsws_veg_eb_av(j,i) + qsws_veg_eb(j,i)
-                ENDDO
+             DO  m = 1, surf_lsm_h%ns
+                i   = surf_lsm_h%i(m)            
+                j   = surf_lsm_h%j(m)
+                qsws_veg_eb_av(j,i) = qsws_veg_eb_av(j,i) +                    &
+                                      surf_lsm_h%qsws_veg_eb(m)
              ENDDO
 
           CASE ( 'r_a*' )
-             DO  i = nxlg, nxrg
-                DO  j = nysg, nyng
-                   r_a_av(j,i) = r_a_av(j,i) + r_a(j,i)
-                ENDDO
+             DO  m = 1, surf_lsm_h%ns
+                i   = surf_lsm_h%i(m)            
+                j   = surf_lsm_h%j(m)
+                r_a_av(j,i) = r_a_av(j,i) + surf_lsm_h%r_a(m)
              ENDDO
 
           CASE ( 'r_s*' )
-             DO  i = nxlg, nxrg
-                DO  j = nysg, nyng
-                   r_s_av(j,i) = r_s_av(j,i) + r_s(j,i)
-                ENDDO
+             DO  m = 1, surf_lsm_h%ns
+                i   = surf_lsm_h%i(m)            
+                j   = surf_lsm_h%j(m)
+                r_s_av(j,i) = r_s_av(j,i) + surf_lsm_h%r_s(m)
              ENDDO
 
           CASE ( 'shf_eb*' )
-             DO  i = nxlg, nxrg
-                DO  j = nysg, nyng
-                   shf_eb_av(j,i) = shf_eb_av(j,i) + shf_eb(j,i)
-                ENDDO
+             DO  m = 1, surf_lsm_h%ns
+                i   = surf_lsm_h%i(m)            
+                j   = surf_lsm_h%j(m)
+                shf_eb_av(j,i) = shf_eb_av(j,i) + surf_lsm_h%shf_eb(m)
              ENDDO
 
           CASE ( 't_soil' )
-             DO  i = nxlg, nxrg
-                DO  j = nysg, nyng
-                   DO  k = nzb_soil, nzt_soil
-                      t_soil_av(k,j,i) = t_soil_av(k,j,i) + t_soil(k,j,i)
-                   ENDDO
+             DO  m = 1, surf_lsm_h%ns
+                i   = surf_lsm_h%i(m)            
+                j   = surf_lsm_h%j(m)
+                DO  k = nzb_soil, nzt_soil
+                   t_soil_av(k,j,i) = t_soil_av(k,j,i) + t_soil_h%var_2d(k,m)
                 ENDDO
              ENDDO
@@ -2671,6 +3172,6 @@
 
           CASE ( 'c_liq*' )
-             DO  i = nxlg, nxrg
-                DO  j = nysg, nyng
+             DO  i = nxl, nxr
+                DO  j = nys, nyn
                    c_liq_av(j,i) = c_liq_av(j,i) / REAL( average_count_3d, KIND=wp )
                 ENDDO
@@ -2678,6 +3179,6 @@
 
           CASE ( 'c_soil*' )
-             DO  i = nxlg, nxrg
-                DO  j = nysg, nyng
+             DO  i = nxl, nxr
+                DO  j = nys, nyn
                    c_soil_av(j,i) = c_soil_av(j,i) / REAL( average_count_3d, KIND=wp )
                 ENDDO
@@ -2685,6 +3186,6 @@
 
           CASE ( 'c_veg*' )
-             DO  i = nxlg, nxrg
-                DO  j = nysg, nyng
+             DO  i = nxl, nxr
+                DO  j = nys, nyn
                    c_veg_av(j,i) = c_veg_av(j,i) / REAL( average_count_3d, KIND=wp )
                 ENDDO
@@ -2692,6 +3193,6 @@
 
           CASE ( 'ghf_eb*' )
-             DO  i = nxlg, nxrg
-                DO  j = nysg, nyng
+             DO  i = nxl, nxr
+                DO  j = nys, nyn
                    ghf_eb_av(j,i) = ghf_eb_av(j,i) / REAL( average_count_3d, KIND=wp )
                 ENDDO
@@ -2699,6 +3200,6 @@
 
          CASE ( 'lai*' )
-             DO  i = nxlg, nxrg
-                DO  j = nysg, nyng
+             DO  i = nxl, nxr
+                DO  j = nys, nyn
                    lai_av(j,i) = lai_av(j,i) / REAL( average_count_3d, KIND=wp )
                 ENDDO
@@ -2706,6 +3207,6 @@
 
           CASE ( 'm_liq_eb*' )
-             DO  i = nxlg, nxrg
-                DO  j = nysg, nyng
+             DO  i = nxl, nxr
+                DO  j = nys, nyn
                    m_liq_eb_av(j,i) = m_liq_eb_av(j,i) / REAL( average_count_3d, KIND=wp )
                 ENDDO
@@ -2713,6 +3214,6 @@
 
           CASE ( 'm_soil' )
-             DO  i = nxlg, nxrg
-                DO  j = nysg, nyng
+             DO  i = nxl, nxr
+                DO  j = nys, nyn
                    DO  k = nzb_soil, nzt_soil
                       m_soil_av(k,j,i) = m_soil_av(k,j,i) / REAL( average_count_3d, KIND=wp )
@@ -2722,6 +3223,6 @@
 
           CASE ( 'qsws_eb*' )
-             DO  i = nxlg, nxrg
-                DO  j = nysg, nyng
+             DO  i = nxl, nxr
+                DO  j = nys, nyn
                    qsws_eb_av(j,i) = qsws_eb_av(j,i) / REAL( average_count_3d, KIND=wp )
                 ENDDO
@@ -2729,6 +3230,6 @@
 
           CASE ( 'qsws_liq_eb*' )
-             DO  i = nxlg, nxrg
-                DO  j = nysg, nyng
+             DO  i = nxl, nxr
+                DO  j = nys, nyn
                    qsws_liq_eb_av(j,i) = qsws_liq_eb_av(j,i) / REAL( average_count_3d, KIND=wp )
                 ENDDO
@@ -2736,6 +3237,6 @@
 
           CASE ( 'qsws_soil_eb*' )
-             DO  i = nxlg, nxrg
-                DO  j = nysg, nyng
+             DO  i = nxl, nxr
+                DO  j = nys, nyn
                    qsws_soil_eb_av(j,i) = qsws_soil_eb_av(j,i) / REAL( average_count_3d, KIND=wp )
                 ENDDO
@@ -2743,6 +3244,6 @@
 
           CASE ( 'qsws_veg_eb*' )
-             DO  i = nxlg, nxrg
-                DO  j = nysg, nyng
+             DO  i = nxl, nxr
+                DO  j = nys, nyn
                    qsws_veg_eb_av(j,i) = qsws_veg_eb_av(j,i) / REAL( average_count_3d, KIND=wp )
                 ENDDO
@@ -2750,6 +3251,6 @@
 
           CASE ( 'r_a*' )
-             DO  i = nxlg, nxrg
-                DO  j = nysg, nyng
+             DO  i = nxl, nxr
+                DO  j = nys, nyn
                    r_a_av(j,i) = r_a_av(j,i) / REAL( average_count_3d, KIND=wp )
                 ENDDO
@@ -2757,6 +3258,6 @@
 
           CASE ( 'r_s*' )
-             DO  i = nxlg, nxrg
-                DO  j = nysg, nyng
+             DO  i = nxl, nxr
+                DO  j = nys, nyn
                    r_s_av(j,i) = r_s_av(j,i) / REAL( average_count_3d, KIND=wp )
                 ENDDO
@@ -2764,6 +3265,6 @@
 
           CASE ( 't_soil' )
-             DO  i = nxlg, nxrg
-                DO  j = nysg, nyng
+             DO  i = nxl, nxr
+                DO  j = nys, nyn
                    DO  k = nzb_soil, nzt_soil
                       t_soil_av(k,j,i) = t_soil_av(k,j,i) / REAL( average_count_3d, KIND=wp )
@@ -2771,4 +3272,6 @@
                 ENDDO
              ENDDO
+!
+!-- 
 
        END SELECT
@@ -2837,8 +3340,9 @@
     CHARACTER (LEN=*) ::  variable !< 
 
-    INTEGER(iwp) ::  av !< 
-    INTEGER(iwp) ::  i  !< 
-    INTEGER(iwp) ::  j  !< 
-    INTEGER(iwp) ::  k  !< 
+    INTEGER(iwp) ::  av      !< 
+    INTEGER(iwp) ::  i       !< running index 
+    INTEGER(iwp) ::  j       !< running index
+    INTEGER(iwp) ::  k       !< running index
+    INTEGER(iwp) ::  m       !< running index
     INTEGER(iwp) ::  nzb_do  !< 
     INTEGER(iwp) ::  nzt_do  !< 
@@ -2849,15 +3353,17 @@
     REAL(wp), DIMENSION(nxlg:nxrg,nysg:nyng,nzb:nzt+1) ::  local_pf !< 
 
+
     found = .TRUE.
 
     SELECT CASE ( TRIM( variable ) )
-
-
+!
+!--    Before data is transfered to local_pf, transfer is it 2D dummy variable and exchange ghost points therein. 
+!--    However, at this point this is only required for instantaneous arrays, time-averaged quantities are already exchanged. 
        CASE ( 'c_liq*_xy' )        ! 2d-array
           IF ( av == 0 )  THEN
-             DO  i = nxlg, nxrg
-                DO  j = nysg, nyng
-                   local_pf(i,j,nzb+1) = c_liq(j,i) * c_veg(j,i)
-                ENDDO
+             DO  m = 1, surf_lsm_h%ns
+                i                   = surf_lsm_h%i(m)            
+                j                   = surf_lsm_h%j(m)
+                local_pf(i,j,nzb+1) = surf_lsm_h%c_liq(m) * surf_lsm_h%c_veg(m)
              ENDDO
           ELSE
@@ -2874,8 +3380,8 @@
        CASE ( 'c_soil*_xy' )        ! 2d-array
           IF ( av == 0 )  THEN
-             DO  i = nxlg, nxrg
-                DO  j = nysg, nyng
-                   local_pf(i,j,nzb+1) = 1.0_wp - c_veg(j,i)
-                ENDDO
+             DO  m = 1, surf_lsm_h%ns
+                i                   = surf_lsm_h%i(m)            
+                j                   = surf_lsm_h%j(m)
+                local_pf(i,j,nzb+1) = 1.0_wp - surf_lsm_h%c_veg(m)
              ENDDO
           ELSE
@@ -2892,8 +3398,8 @@
        CASE ( 'c_veg*_xy' )        ! 2d-array
           IF ( av == 0 )  THEN
-             DO  i = nxlg, nxrg
-                DO  j = nysg, nyng
-                   local_pf(i,j,nzb+1) = c_veg(j,i)
-                ENDDO
+             DO  m = 1, surf_lsm_h%ns
+                i                   = surf_lsm_h%i(m)            
+                j                   = surf_lsm_h%j(m)
+                local_pf(i,j,nzb+1) = surf_lsm_h%c_veg(m)
              ENDDO
           ELSE
@@ -2910,8 +3416,8 @@
        CASE ( 'ghf_eb*_xy' )        ! 2d-array
           IF ( av == 0 )  THEN
-             DO  i = nxlg, nxrg
-                DO  j = nysg, nyng
-                   local_pf(i,j,nzb+1) = ghf_eb(j,i)
-                ENDDO
+             DO  m = 1, surf_lsm_h%ns
+                i                   = surf_lsm_h%i(m)            
+                j                   = surf_lsm_h%j(m)
+                local_pf(i,j,nzb+1) = surf_lsm_h%ghf_eb(m)
              ENDDO
           ELSE
@@ -2928,8 +3434,8 @@
        CASE ( 'lai*_xy' )        ! 2d-array
           IF ( av == 0 )  THEN
-             DO  i = nxlg, nxrg
-                DO  j = nysg, nyng
-                   local_pf(i,j,nzb+1) = lai(j,i)
-                ENDDO
+             DO  m = 1, surf_lsm_h%ns
+                i                   = surf_lsm_h%i(m)            
+                j                   = surf_lsm_h%j(m)
+                local_pf(i,j,nzb+1) = surf_lsm_h%lai(m)
              ENDDO
           ELSE
@@ -2946,8 +3452,8 @@
        CASE ( 'm_liq_eb*_xy' )        ! 2d-array
           IF ( av == 0 )  THEN
-             DO  i = nxlg, nxrg
-                DO  j = nysg, nyng
-                   local_pf(i,j,nzb+1) = m_liq_eb(j,i)
-                ENDDO
+             DO  m = 1, surf_lsm_h%ns
+                i                   = surf_lsm_h%i(m)            
+                j                   = surf_lsm_h%j(m)
+                local_pf(i,j,nzb+1) = m_liq_eb_h%var_1d(m)
              ENDDO
           ELSE
@@ -2964,9 +3470,9 @@
        CASE ( 'm_soil_xy', 'm_soil_xz', 'm_soil_yz' )
           IF ( av == 0 )  THEN
-             DO  i = nxlg, nxrg
-                DO  j = nysg, nyng
-                   DO k = nzb_soil, nzt_soil
-                      local_pf(i,j,k) = m_soil(k,j,i)
-                   ENDDO
+             DO  m = 1, surf_lsm_h%ns
+                i   = surf_lsm_h%i(m)            
+                j   = surf_lsm_h%j(m)
+                DO k = nzb_soil, nzt_soil
+                   local_pf(i,j,k) = m_soil_h%var_2d(k,m)
                 ENDDO
              ENDDO
@@ -2988,8 +3494,8 @@
        CASE ( 'qsws_eb*_xy' )        ! 2d-array
           IF ( av == 0 ) THEN
-             DO  i = nxlg, nxrg
-                DO  j = nysg, nyng
-                   local_pf(i,j,nzb+1) =  qsws_eb(j,i)
-                ENDDO
+             DO  m = 1, surf_lsm_h%ns
+                i                   = surf_lsm_h%i(m)            
+                j                   = surf_lsm_h%j(m)
+                local_pf(i,j,nzb+1) =  surf_lsm_h%qsws_eb(m)
              ENDDO
           ELSE
@@ -3006,8 +3512,8 @@
        CASE ( 'qsws_liq_eb*_xy' )        ! 2d-array
           IF ( av == 0 ) THEN
-             DO  i = nxlg, nxrg
-                DO  j = nysg, nyng
-                   local_pf(i,j,nzb+1) =  qsws_liq_eb(j,i)
-                ENDDO
+             DO  m = 1, surf_lsm_h%ns
+                i                   = surf_lsm_h%i(m)            
+                j                   = surf_lsm_h%j(m)
+                local_pf(i,j,nzb+1) = surf_lsm_h%qsws_liq_eb(m)
              ENDDO
           ELSE
@@ -3024,8 +3530,8 @@
        CASE ( 'qsws_soil_eb*_xy' )        ! 2d-array
           IF ( av == 0 ) THEN
-             DO  i = nxlg, nxrg
-                DO  j = nysg, nyng
-                   local_pf(i,j,nzb+1) =  qsws_soil_eb(j,i)
-                ENDDO
+             DO  m = 1, surf_lsm_h%ns
+                i                   = surf_lsm_h%i(m)            
+                j                   = surf_lsm_h%j(m)
+                local_pf(i,j,nzb+1) =  surf_lsm_h%qsws_soil_eb(m)
              ENDDO
           ELSE
@@ -3042,8 +3548,8 @@
        CASE ( 'qsws_veg_eb*_xy' )        ! 2d-array
           IF ( av == 0 ) THEN
-             DO  i = nxlg, nxrg
-                DO  j = nysg, nyng
-                   local_pf(i,j,nzb+1) =  qsws_veg_eb(j,i)
-                ENDDO
+             DO  m = 1, surf_lsm_h%ns
+                i                   = surf_lsm_h%i(m)            
+                j                   = surf_lsm_h%j(m)
+                local_pf(i,j,nzb+1) =  surf_lsm_h%qsws_veg_eb(m)
              ENDDO
           ELSE
@@ -3061,8 +3567,8 @@
        CASE ( 'r_a*_xy' )        ! 2d-array
           IF ( av == 0 )  THEN
-             DO  i = nxlg, nxrg
-                DO  j = nysg, nyng
-                   local_pf(i,j,nzb+1) = r_a(j,i)
-                ENDDO
+             DO  m = 1, surf_lsm_h%ns
+                i                   = surf_lsm_h%i(m)            
+                j                   = surf_lsm_h%j(m)
+                local_pf(i,j,nzb+1) = surf_lsm_h%r_a(m)
              ENDDO
           ELSE
@@ -3079,8 +3585,8 @@
        CASE ( 'r_s*_xy' )        ! 2d-array
           IF ( av == 0 )  THEN
-             DO  i = nxlg, nxrg
-                DO  j = nysg, nyng
-                   local_pf(i,j,nzb+1) = r_s(j,i)
-                ENDDO
+             DO  m = 1, surf_lsm_h%ns
+                i                   = surf_lsm_h%i(m)            
+                j                   = surf_lsm_h%j(m)
+                local_pf(i,j,nzb+1) = surf_lsm_h%r_s(m)
              ENDDO
           ELSE
@@ -3097,8 +3603,8 @@
        CASE ( 'shf_eb*_xy' )        ! 2d-array
           IF ( av == 0 ) THEN
-             DO  i = nxlg, nxrg
-                DO  j = nysg, nyng
-                   local_pf(i,j,nzb+1) =  shf_eb(j,i)
-                ENDDO
+             DO  m = 1, surf_lsm_h%ns
+                i                   = surf_lsm_h%i(m)            
+                j                   = surf_lsm_h%j(m)
+                local_pf(i,j,nzb+1) =  surf_lsm_h%shf_eb(m)
              ENDDO
           ELSE
@@ -3115,9 +3621,9 @@
        CASE ( 't_soil_xy', 't_soil_xz', 't_soil_yz' )
           IF ( av == 0 )  THEN
-             DO  i = nxlg, nxrg
-                DO  j = nysg, nyng
-                   DO k = nzb_soil, nzt_soil
-                      local_pf(i,j,k) = t_soil(k,j,i)
-                   ENDDO
+             DO  m = 1, surf_lsm_h%ns
+                i   = surf_lsm_h%i(m)            
+                j   = surf_lsm_h%j(m)
+                DO k = nzb_soil, nzt_soil
+                   local_pf(i,j,k) = t_soil_h%var_2d(k,m)
                 ENDDO
              ENDDO
@@ -3168,4 +3674,5 @@
     INTEGER(iwp) ::  j     !< 
     INTEGER(iwp) ::  k     !< 
+    INTEGER(iwp) ::  m     !< running index
 
     LOGICAL      ::  found !< 
@@ -3178,15 +3685,16 @@
 
     SELECT CASE ( TRIM( variable ) )
-
+!
+!--   Requires 3D exchange
 
       CASE ( 'm_soil' )
 
          IF ( av == 0 )  THEN
-            DO  i = nxlg, nxrg
-               DO  j = nysg, nyng
-                  DO  k = nzb_soil, nzt_soil
-                     local_pf(i,j,k) = m_soil(k,j,i)
-                  ENDDO
-               ENDDO
+            DO  m = 1, surf_lsm_h%ns
+                i   = surf_lsm_h%i(m)            
+                j   = surf_lsm_h%j(m)
+                DO  k = nzb_soil, nzt_soil
+                   local_pf(i,j,k) = m_soil_h%var_2d(k,m)
+                ENDDO
             ENDDO
          ELSE
@@ -3203,9 +3711,9 @@
 
          IF ( av == 0 )  THEN
-            DO  i = nxlg, nxrg
-               DO  j = nysg, nyng
-                  DO  k = nzb_soil, nzt_soil
-                     local_pf(i,j,k) = t_soil(k,j,i)
-                  ENDDO
+            DO  m = 1, surf_lsm_h%ns
+               i   = surf_lsm_h%i(m)            
+               j   = surf_lsm_h%j(m)
+               DO  k = nzb_soil, nzt_soil
+                  local_pf(i,j,k) = t_soil_h%var_2d(k,m)
                ENDDO
             ENDDO
@@ -3261,9 +3769,9 @@
           WRITE ( 14 )  'lai_av              ';  WRITE ( 14 )  lai_av
        ENDIF
-       WRITE ( 14 )  'm_liq_eb            ';  WRITE ( 14 )  m_liq_eb
+       WRITE ( 14 )     'm_liq_eb            ';  WRITE ( 14 )  m_liq_eb_h
        IF ( ALLOCATED( m_liq_eb_av ) )  THEN
           WRITE ( 14 )  'm_liq_eb_av         ';  WRITE ( 14 )  m_liq_eb_av
        ENDIF
-       WRITE ( 14 )  'm_soil              ';  WRITE ( 14 )  m_soil
+       WRITE ( 14 )     'm_soil              ';  WRITE ( 14 )  m_soil_h
        IF ( ALLOCATED( m_soil_av ) )  THEN
           WRITE ( 14 )  'm_soil_av           ';  WRITE ( 14 )  m_soil_av
@@ -3284,5 +3792,5 @@
           WRITE ( 14 )  'shf_eb_av           ';  WRITE ( 14 )  shf_eb_av
        ENDIF
-       WRITE ( 14 )  't_soil              ';  WRITE ( 14 )  t_soil
+       WRITE ( 14 )     't_soil              ';  WRITE ( 14 )  t_soil_h
        IF ( ALLOCATED( t_soil_av ) )  THEN
           WRITE ( 14 )  't_soil_av           ';  WRITE ( 14 )  t_soil_av
@@ -3349,4 +3857,16 @@
           tmp_3d2   !< 
 
+    REAL(wp),                                                                  &
+       DIMENSION(1:surf_lsm_h%ns) ::                                  &
+          tmp_walltype_1d   !< 
+
+    REAL(wp),                                                                  &
+       DIMENSION(nzb_soil:nzt_soil+1,1:surf_lsm_h%ns) ::              &
+          tmp_walltype_2d   !< 
+
+    REAL(wp),                                                                  &
+       DIMENSION(nzb_soil:nzt_soil,1:surf_lsm_h%ns) ::                &
+          tmp_walltype_2d2  !< 
+
 
    IF ( initializing_actions == 'read_restart_data' )  THEN
@@ -3366,6 +3886,6 @@
             nync = nynfa(i,k) + offset_ya(i,k)
 
-
             SELECT CASE ( TRIM( field_char ) )
+
 
                 CASE ( 'c_liq_av' )
@@ -3374,5 +3894,5 @@
                    ENDIF
                    IF ( k == 1 )  READ ( 13 )  tmp_2d
-                   c_liq_av(nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp) = &
+                   c_liq_av(nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp) =         &
                                   tmp_2d(nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
 
@@ -3382,5 +3902,5 @@
                    ENDIF
                    IF ( k == 1 )  READ ( 13 )  tmp_2d
-                   c_soil_av(nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp) = &
+                   c_soil_av(nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp) =        &
                                   tmp_2d(nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
 
@@ -3390,5 +3910,5 @@
                    ENDIF
                    IF ( k == 1 )  READ ( 13 )  tmp_2d
-                   c_veg_av(nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp) = &
+                   c_veg_av(nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp) =         &
                                   tmp_2d(nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
 
@@ -3398,11 +3918,11 @@
                    ENDIF
                    IF ( k == 1 )  READ ( 13 )  tmp_2d
-                   ghf_eb_av(nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp) = &
+                   ghf_eb_av(nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp) =        &
                                   tmp_2d(nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
 
                 CASE ( 'm_liq_eb' )
-                   IF ( k == 1 )  READ ( 13 )  tmp_2d
-                   m_liq_eb(nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp)  =        &
-                                 tmp_2d(nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
+                   IF ( k == 1 )  READ ( 13 )  tmp_walltype_1d !tmp_2d
+                   m_liq_eb_h%var_1d(1:surf_lsm_h%ns)  =                       &
+                                 tmp_walltype_1d(1:surf_lsm_h%ns)
 
                 CASE ( 'lai_av' )
@@ -3411,5 +3931,5 @@
                    ENDIF
                    IF ( k == 1 )  READ ( 13 )  tmp_2d
-                   lai_av(nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp) = &
+                   lai_av(nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp) =           &
                                   tmp_2d(nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
 
@@ -3423,8 +3943,7 @@
 
                 CASE ( 'm_soil' )
-                   IF ( k == 1 )  READ ( 13 )  tmp_3d2(:,:,:)
-                   m_soil(:,nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp) =         &
-                          tmp_3d2(nzb_soil:nzt_soil,nysf-nbgp:nynf             &
-                          +nbgp,nxlf-nbgp:nxrf+nbgp)
+                   IF ( k == 1 )  READ ( 13 )  tmp_walltype_2d2(:,:)
+                   m_soil_h%var_2d(:,1:surf_lsm_h%ns) =                        &
+                          tmp_walltype_2d2(:,1:surf_lsm_h%ns)   
 
                 CASE ( 'm_soil_av' )
@@ -3442,5 +3961,5 @@
                    ENDIF  
                    IF ( k == 1 )  READ ( 13 )  tmp_2d
-                   qsws_eb_av(nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp)  = &
+                   qsws_eb_av(nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp)  =      &
                                           tmp_2d(nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
 
@@ -3450,5 +3969,5 @@
                    ENDIF  
                    IF ( k == 1 )  READ ( 13 )  tmp_2d
-                   qsws_liq_eb_av(nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp)  = &
+                   qsws_liq_eb_av(nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp)  =  &
                                           tmp_2d(nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
                 CASE ( 'qsws_soil_eb_av' )
@@ -3473,12 +3992,11 @@
                    ENDIF
                    IF ( k == 1 )  READ ( 13 )  tmp_2d
-                   shf_eb_av(nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp)  = &
+                   shf_eb_av(nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp)  =       &
                          tmp_2d(nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
 
                 CASE ( 't_soil' )
-                   IF ( k == 1 )  READ ( 13 )  tmp_3d
-                   t_soil(:,nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp) =         &
-                                   tmp_3d(:,nysf-nbgp:nynf+nbgp,               &
-                                                nxlf-nbgp:nxrf+nbgp)
+                   IF ( k == 1 )  READ ( 13 )  tmp_walltype_2d(:,:)
+                   t_soil_h%var_2d(:,1:surf_lsm_h%ns) =                        &
+                         tmp_walltype_2d(:,1:surf_lsm_h%ns)      
 
                 CASE ( 't_soil_av' )
@@ -3488,5 +4006,5 @@
                    IF ( k == 1 )  READ ( 13 )  tmp_3d2(:,:,:)
                    t_soil_av(:,nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp) =      &
-                                    tmp_3d(:,nysf-nbgp:nynf+nbgp,             &
+                                    tmp_3d2(:,nysf-nbgp:nynf+nbgp,             &
                                     nxlf-nbgp:nxrf+nbgp)
 
@@ -3525,6 +4043,7 @@
        IMPLICIT NONE
 
-       INTEGER :: i  !< running index
-       INTEGER :: j  !< running index
+       INTEGER(iwp) ::  i       !< running index
+       INTEGER(iwp) ::  j       !< running index
+       INTEGER(iwp) ::  m       !< running index
 
        REAL(wp), PARAMETER :: alpha_ch  = 0.018_wp !< Charnock constant (0.01-0.11). Use 0.01 for FLake and 0.018 for ECMWF
@@ -3533,41 +4052,45 @@
 !       REAL(wp) :: re_0 !< near-surface roughness Reynolds number
 
-
-       DO  i = nxlg, nxrg    
-          DO  j = nysg, nyng
-             IF ( water_surface(j,i) )  THEN
-
-!
-!--             Disabled: FLake parameterization. Ideally, the Charnock 
-!--             coefficient should depend on the water depth and the fetch
-!--             length
-!                re_0 = z0(j,i) * us(j,i) / molecular_viscosity
+       DO  m = 1, surf_lsm_h%ns
+
+          i   = surf_lsm_h%i(m)            
+          j   = surf_lsm_h%j(m)
+          
+          IF ( surf_lsm_h%water_surface(m) )  THEN
+
+!
+!--          Disabled: FLake parameterization. Ideally, the Charnock 
+!--          coefficient should depend on the water depth and the fetch
+!--          length
+!             re_0 = z0(j,i) * us(j,i) / molecular_viscosity
 !        
-!                z0(j,i) = MAX( 0.1_wp * molecular_viscosity / us(j,i),            &
-!                              alpha_ch * us(j,i) / g )
-!
-!                z0h(j,i) = z0(j,i) * EXP( - kappa / pr_number * ( 4.0_wp * SQRT( re_0 ) - 3.2_wp ) )
-!                z0q(j,i) = z0(j,i) * EXP( - kappa / pr_number * ( 4.0_wp * SQRT( re_0 ) - 4.2_wp ) )
-
-!
-!--              Set minimum roughness length for u* > 0.2
-!                IF ( us(j,i) > 0.2_wp )  THEN
-!                   z0h(j,i) = MAX( 1.0E-5_wp, z0h(j,i) )
-!                   z0q(j,i) = MAX( 1.0E-5_wp, z0q(j,i) )
-!                ENDIF
-
-!
-!--             ECMWF IFS model parameterization after Beljaars (1994). At low
-!--             wind speed, the sea surface becomes aerodynamically smooth and
-!--             the roughness scales with the viscosity. At high wind speed, the
-!--             Charnock relation is used.
-                z0(j,i) =   ( 0.11_wp * molecular_viscosity / us(j,i) )        &
-                          + ( alpha_ch * us(j,i)**2 / g )
-
-                z0h(j,i) = 0.40_wp * molecular_viscosity / us(j,i)
-                z0q(j,i) = 0.62_wp * molecular_viscosity / us(j,i)
-
-             ENDIF
-          ENDDO
+!             z0(j,i) = MAX( 0.1_wp * molecular_viscosity / us(j,i),            &
+!                           alpha_ch * us(j,i) / g )
+!
+!             z0h(j,i) = z0(j,i) * EXP( - kappa / pr_number * ( 4.0_wp * SQRT( re_0 ) - 3.2_wp ) )
+!             z0q(j,i) = z0(j,i) * EXP( - kappa / pr_number * ( 4.0_wp * SQRT( re_0 ) - 4.2_wp ) )
+
+!
+!--           Set minimum roughness length for u* > 0.2
+!             IF ( us(j,i) > 0.2_wp )  THEN
+!                z0h(j,i) = MAX( 1.0E-5_wp, z0h(j,i) )
+!                z0q(j,i) = MAX( 1.0E-5_wp, z0q(j,i) )
+!             ENDIF
+
+!
+!--          ECMWF IFS model parameterization after Beljaars (1994). At low
+!--          wind speed, the sea surface becomes aerodynamically smooth and
+!--          the roughness scales with the viscosity. At high wind speed, the
+!--          Charnock relation is used.
+             surf_lsm_h%z0(m)  = ( 0.11_wp * molecular_viscosity /             &
+                                 surf_lsm_h%us(m) )  &
+                               + ( alpha_ch * surf_lsm_h%us(m)**2 / g )
+
+             surf_lsm_h%z0h(m) = 0.40_wp * molecular_viscosity /               &
+                                 surf_lsm_h%us(m)
+             surf_lsm_h%z0q(m) = 0.62_wp * molecular_viscosity /               &
+                                 surf_lsm_h%us(m)
+
+          ENDIF
        ENDDO
 
@@ -3575,54 +4098,4 @@
 
 
-!------------------------------------------------------------------------------!
-! Description:
-! ------------
-!> Calculation of specific humidity of the skin layer (surface). It is assumend
-!> that the skin is always saturated.
-!------------------------------------------------------------------------------!
-    SUBROUTINE calc_q_surface
-
-       IMPLICIT NONE
-
-       INTEGER :: i              !< running index
-       INTEGER :: j              !< running index
-       INTEGER :: k              !< running index
-
-       REAL(wp) :: resistance    !< aerodynamic and soil resistance term
-
-       DO  i = nxlg, nxrg    
-          DO  j = nysg, nyng
-             k = nzb_s_inner(j,i)
-
-!
-!--          Calculate water vapour pressure at saturation
-             e_s = 0.01_wp * 610.78_wp * EXP( 17.269_wp * ( t_surface_p(j,i)   &
-                   - 273.16_wp ) / ( t_surface_p(j,i) - 35.86_wp ) )
-
-!
-!--          Calculate specific humidity at saturation
-             q_s = 0.622_wp * e_s / surface_pressure
-
-             resistance = r_a(j,i) / (r_a(j,i) + r_s(j,i))
-
-!
-!--          Calculate specific humidity at surface
-             IF ( cloud_physics )  THEN
-                q(k,j,i) = resistance * q_s + (1.0_wp - resistance)            &
-                             * ( q(k+1,j,i) - ql(k+1,j,i) )
-             ELSE
-                q(k,j,i) = resistance * q_s + (1.0_wp - resistance)            &
-                             * q(k+1,j,i)
-             ENDIF
-
-!
-!--          Update virtual potential temperature
-             vpt(k,j,i) = pt(k,j,i) * ( 1.0_wp + 0.61_wp * q(k,j,i) )
-
-          ENDDO
-       ENDDO
-
-    END SUBROUTINE calc_q_surface
-
 
  END MODULE land_surface_model_mod
Index: /palm/trunk/SOURCE/lpm.f90
===================================================================
--- /palm/trunk/SOURCE/lpm.f90	(revision 2231)
+++ /palm/trunk/SOURCE/lpm.f90	(revision 2232)
@@ -20,5 +20,5 @@
 ! Current revisions:
 ! ------------------
-! 
+! Adjustments to new topography concept
 ! 
 ! Former revisions:
@@ -123,5 +123,5 @@
 
     USE indices,                                                               &
-        ONLY: nxl, nxr, nys, nyn, nzb, nzb_max, nzt, nzb_w_inner
+        ONLY: nxl, nxr, nys, nyn, nzb, nzb_max, nzt
 
     USE kinds
@@ -365,5 +365,4 @@
 !--    Increment time since last release
        IF ( dt_3d_reached )  time_prel = time_prel + dt_3d
-
 !
 !--    Move Particles local to PE to a different grid cell
Index: /palm/trunk/SOURCE/lpm_advec.f90
===================================================================
--- /palm/trunk/SOURCE/lpm_advec.f90	(revision 2231)
+++ /palm/trunk/SOURCE/lpm_advec.f90	(revision 2232)
@@ -20,5 +20,5 @@
 ! Current revisions:
 ! ------------------
-! 
+! Adjustments to new topography and surface concept
 ! 
 ! Former revisions:
@@ -109,5 +109,5 @@
 
     USE arrays_3d,                                                             &
-        ONLY:  de_dx, de_dy, de_dz, diss, e, km, u, us, usws, v, vsws, w, zu, zw
+        ONLY:  de_dx, de_dy, de_dz, diss, e, km, u, v, w, zu, zw
 
     USE cpulog
@@ -123,5 +123,5 @@
         
     USE indices,                                                               &
-        ONLY:  nzb, nzb_s_inner, nzt
+        ONLY:  nzb, nzb_max, nzt, wall_flags_0
         
     USE kinds
@@ -136,4 +136,7 @@
         ONLY:  hom
 
+    USE surface_mod,                                                           &
+        ONLY:  surf_def_h, surf_lsm_h, surf_usm_h
+
     IMPLICIT NONE
 
@@ -147,4 +150,5 @@
     INTEGER(iwp) ::  jlog                        !< index variable along y 
     INTEGER(iwp) ::  k                           !< index variable along z 
+    INTEGER(iwp) ::  k_wall                      !< vertical index of topography top 
     INTEGER(iwp) ::  kp                          !< index variable along z 
     INTEGER(iwp) ::  kw                          !< index variable along z
@@ -152,4 +156,5 @@
     INTEGER(iwp) ::  nb                          !< block number particles are sorted in
     INTEGER(iwp) ::  num_gp                      !< number of adjacent grid points inside topography 
+    INTEGER(iwp) ::  surf_start                  !< Index on surface data-type for current grid box 
 
     INTEGER(iwp), DIMENSION(0:7) ::  start_index !< start particle index for current block
@@ -194,6 +199,8 @@
     REAL(wp) ::  u_int_u            !< x/y-interpolated u-component at particle position at upper vertical level
     REAL(wp) ::  us_int             !< friction velocity at particle grid box
+    REAL(wp) ::  usws_int           !< surface momentum flux (u component) at particle grid box
     REAL(wp) ::  v_int_l            !< x/y-interpolated v-component at particle position at lower vertical level
     REAL(wp) ::  v_int_u            !< x/y-interpolated v-component at particle position at upper vertical level
+    REAL(wp) ::  vsws_int           !< surface momentum flux (u component) at particle grid box
     REAL(wp) ::  vv_int             !<
     REAL(wp) ::  w_int_l            !< x/y-interpolated w-component at particle position at lower vertical level
@@ -258,6 +265,4 @@
        j = jp + block_offset(nb)%j_off
        k = kp + block_offset(nb)%k_off
-
-
 !
 !--    Interpolate u velocity-component
@@ -271,18 +276,24 @@
 !--       Monin-Obukhov relations (if branch). 
 !--       First, check if particle is located below first vertical grid level 
-!--       (Prandtl-layer height)
+!--       above topography (Prandtl-layer height)
           ilog = ( particles(n)%x + 0.5_wp * dx ) * ddx
           jlog = ( particles(n)%y + 0.5_wp * dy ) * ddy
-
-          IF ( constant_flux_layer  .AND.                                      &
-               zv(n) - zw(nzb_s_inner(jlog,ilog)) < z_p )  THEN
+!
+!--       Determine vertical index of topography top
+          k_wall = MAXLOC(                                                     &
+                       MERGE( 1, 0,                                            &
+                              BTEST( wall_flags_0(nzb:nzb_max,jlog,ilog), 12 ) &
+                            ), DIM = 1                                         &
+                         ) - 1
+
+          IF ( constant_flux_layer  .AND.  zv(n) - zw(k_wall) < z_p )  THEN
 !
 !--          Resolved-scale horizontal particle velocity is zero below z0. 
-             IF ( zv(n) - zw(nzb_s_inner(jlog,ilog)) < z0_av_global )  THEN
+             IF ( zv(n) - zw(k_wall) < z0_av_global )  THEN
                 u_int(n) = 0.0_wp
              ELSE
 !
 !--             Determine the sublayer. Further used as index.
-                height_p = ( zv(n) - zw(nzb_s_inner(jlog,ilog)) - z0_av_global ) &
+                height_p = ( zv(n) - zw(k_wall) - z0_av_global ) &
                                      * REAL( number_of_sublayers, KIND=wp )    &
                                      * d_z_p_z0 
@@ -296,9 +307,26 @@
                                    ) 
 !
-!--             Limit friction velocity. In narrow canyons or holes the 
-!--             friction velocity can become very small, resulting in a too
-!--             large particle speed.
-                us_int   = MAX( 0.5_wp * ( us(jlog,ilog) + us(jlog,ilog-1) ),  &
-                                0.01_wp )  
+!--             Get friction velocity and momentum flux from new surface data 
+!--             types.
+                IF ( surf_def_h(0)%start_index(jlog,ilog) <=                   &
+                     surf_def_h(0)%end_index(jlog,ilog) )  THEN
+                   surf_start = surf_def_h(0)%start_index(jlog,ilog)
+!--                Limit friction velocity. In narrow canyons or holes the 
+!--                friction velocity can become very small, resulting in a too
+!--                large particle speed.
+                   us_int    = MAX( surf_def_h(0)%us(surf_start), 0.01_wp )  
+                   usws_int  = surf_def_h(0)%usws(surf_start)
+                ELSEIF ( surf_lsm_h%start_index(jlog,ilog) <=                  &
+                         surf_lsm_h%end_index(jlog,ilog) )  THEN
+                   surf_start = surf_lsm_h%start_index(jlog,ilog)
+                   us_int    = MAX( surf_lsm_h%us(surf_start), 0.01_wp )  
+                   usws_int  = surf_lsm_h%usws(surf_start)
+                ELSEIF ( surf_usm_h%start_index(jlog,ilog) <=                  &
+                         surf_usm_h%end_index(jlog,ilog) )  THEN
+                   surf_start = surf_usm_h%start_index(jlog,ilog)
+                   us_int    = MAX( surf_usm_h%us(surf_start), 0.01_wp )  
+                   usws_int  = surf_usm_h%usws(surf_start)
+                ENDIF
+
 !
 !--             Neutral solution is applied for all situations, e.g. also for 
@@ -308,5 +336,5 @@
 !--             as sensitivity studies revealed no significant effect of 
 !--             using the neutral solution also for un/stable situations.
-                u_int(n) = -usws(jlog,ilog) / ( us_int * kappa + 1E-10_wp )          & 
+                u_int(n) = -usws_int / ( us_int * kappa + 1E-10_wp )           & 
                             * log_z_z0_int - u_gtrans
                 
@@ -352,8 +380,14 @@
           ilog = ( particles(n)%x + 0.5_wp * dx ) * ddx
           jlog = ( particles(n)%y + 0.5_wp * dy ) * ddy
-          IF ( constant_flux_layer  .AND.                                      &
-               zv(n) - zw(nzb_s_inner(jlog,ilog)) < z_p )  THEN
-
-             IF ( zv(n) - zw(nzb_s_inner(jlog,ilog)) < z0_av_global )  THEN
+!
+!--       Determine vertical index of topography top
+          k_wall = MAXLOC(                                                     &
+                       MERGE( 1, 0,                                            &
+                              BTEST( wall_flags_0(nzb:nzb_max,jlog,ilog), 12 ) &
+                            ), DIM = 1                                         &
+                         ) - 1
+
+          IF ( constant_flux_layer  .AND.  zv(n) - zw(k_wall) < z_p )  THEN
+             IF ( zv(n) - zw(k_wall) < z0_av_global )  THEN
 !
 !--             Resolved-scale horizontal particle velocity is zero below z0. 
@@ -365,5 +399,5 @@
 !--             topography particle on u-grid can be above surface-layer height,
 !--             whereas it can be below on v-grid. 
-                height_p = ( zv(n) - zw(nzb_s_inner(jlog,ilog)) - z0_av_global ) &
+                height_p = ( zv(n) - zw(k_wall) - z0_av_global ) &
                                   * REAL( number_of_sublayers, KIND=wp )       &
                                   * d_z_p_z0 
@@ -377,9 +411,25 @@
                                    ) 
 !
-!--             Limit friction velocity. In narrow canyons or holes the 
-!--             friction velocity can become very small, resulting in a too
-!--             large particle speed.
-                us_int   = MAX( 0.5_wp * ( us(jlog,ilog) + us(jlog-1,ilog) ),  &
-                                0.01_wp )    
+!--             Get friction velocity and momentum flux from new surface data 
+!--             types.
+                IF ( surf_def_h(0)%start_index(jlog,ilog) <=                   &
+                     surf_def_h(0)%end_index(jlog,ilog) )  THEN
+                   surf_start = surf_def_h(0)%start_index(jlog,ilog)
+!--                Limit friction velocity. In narrow canyons or holes the 
+!--                friction velocity can become very small, resulting in a too
+!--                large particle speed.
+                   us_int    = MAX( surf_def_h(0)%us(surf_start), 0.01_wp )  
+                   vsws_int  = surf_def_h(0)%usws(surf_start)
+                ELSEIF ( surf_lsm_h%start_index(jlog,ilog) <=                  &
+                         surf_lsm_h%end_index(jlog,ilog) )  THEN
+                   surf_start = surf_lsm_h%start_index(jlog,ilog)
+                   us_int    = MAX( surf_lsm_h%us(surf_start), 0.01_wp )  
+                   vsws_int  = surf_lsm_h%usws(surf_start)
+                ELSEIF ( surf_usm_h%start_index(jlog,ilog) <=                  &
+                         surf_usm_h%end_index(jlog,ilog) )  THEN
+                   surf_start = surf_usm_h%start_index(jlog,ilog)
+                   us_int    = MAX( surf_usm_h%us(surf_start), 0.01_wp )  
+                   vsws_int  = surf_usm_h%usws(surf_start)
+                ENDIF 
 !
 !--             Neutral solution is applied for all situations, e.g. also for 
@@ -389,5 +439,5 @@
 !--             as sensitivity studies revealed no significant effect of 
 !--             using the neutral solution also for un/stable situations.
-                v_int(n) = -vsws(jlog,ilog) / ( us_int * kappa + 1E-10_wp )    &
+                v_int(n) = -vsws_int / ( us_int * kappa + 1E-10_wp )           &
                          * log_z_z0_int - v_gtrans
 
@@ -622,5 +672,15 @@
              num_gp = 0
 
-             IF ( k > nzb_s_inner(j,i)  .OR.  nzb_s_inner(j,i) == 0 )  THEN 
+!
+!--          Determine vertical index of topography top at (j,i)
+             k_wall = MAXLOC(                                                  &
+                          MERGE( 1, 0,                                         &
+                                 BTEST( wall_flags_0(nzb:nzb_max,j,i), 12 )    &
+                               ), DIM = 1                                      &
+                            ) - 1
+!
+!--          To do: Reconsider order of computations in order to avoid 
+!--          unnecessary index calculations.
+             IF ( k > k_wall  .OR.  k_wall == 0 )  THEN 
                 num_gp = num_gp + 1
                 gp_outside_of_building(1) = 1
@@ -634,5 +694,13 @@
                 de_dzi(num_gp) = de_dz(k,j,i)
              ENDIF
-             IF ( k > nzb_s_inner(j+1,i)  .OR.  nzb_s_inner(j+1,i) == 0 )  THEN
+
+!
+!--          Determine vertical index of topography top at (j+1,i)
+             k_wall = MAXLOC(                                                  &
+                          MERGE( 1, 0,                                         &
+                                 BTEST( wall_flags_0(nzb:nzb_max,j+1,i), 12 )  &
+                               ), DIM = 1                                      &
+                            ) - 1
+             IF ( k > k_wall  .OR.  k_wall == 0 )  THEN
                 num_gp = num_gp + 1
                 gp_outside_of_building(2) = 1
@@ -647,5 +715,12 @@
              ENDIF
 
-             IF ( k+1 > nzb_s_inner(j,i)  .OR.  nzb_s_inner(j,i) == 0 )  THEN
+!
+!--          Determine vertical index of topography top at (j,i)
+             k_wall = MAXLOC(                                                  &
+                          MERGE( 1, 0,                                         &
+                                 BTEST( wall_flags_0(nzb:nzb_max,j,i), 12 )    &
+                               ), DIM = 1                                      &
+                            ) - 1
+             IF ( k+1 > k_wall  .OR.  k_wall == 0 )  THEN
                 num_gp = num_gp + 1
                 gp_outside_of_building(3) = 1
@@ -660,5 +735,12 @@
              ENDIF
 
-             IF ( k+1 > nzb_s_inner(j+1,i)  .OR.  nzb_s_inner(j+1,i) == 0 )  THEN
+!
+!--          Determine vertical index of topography top at (j+1,i)
+             k_wall = MAXLOC(                                                  &
+                          MERGE( 1, 0,                                         &
+                                 BTEST( wall_flags_0(nzb:nzb_max,j+1,i), 12 )  &
+                               ), DIM = 1                                      &
+                            ) - 1
+             IF ( k+1 > k_wall  .OR.  k_wall == 0 )  THEN
                 num_gp = num_gp + 1
                 gp_outside_of_building(4) = 1
@@ -673,5 +755,12 @@
              ENDIF
 
-             IF ( k > nzb_s_inner(j,i+1)  .OR.  nzb_s_inner(j,i+1) == 0 )  THEN
+!
+!--          Determine vertical index of topography top at (j,i+1)
+             k_wall = MAXLOC(                                                  &
+                          MERGE( 1, 0,                                         &
+                                 BTEST( wall_flags_0(nzb:nzb_max,j,i+1), 12 )  &
+                               ), DIM = 1                                      &
+                            ) - 1
+             IF ( k > k_wall  .OR.  k_wall == 0 )  THEN
                 num_gp = num_gp + 1
                 gp_outside_of_building(5) = 1
@@ -686,5 +775,12 @@
              ENDIF
 
-             IF ( k > nzb_s_inner(j+1,i+1)  .OR.  nzb_s_inner(j+1,i+1) == 0 )  THEN
+!
+!--          Determine vertical index of topography top at (j+1,i+1)
+             k_wall = MAXLOC(                                                  &
+                          MERGE( 1, 0,                                         &
+                                 BTEST( wall_flags_0(nzb:nzb_max,j+1,i+1), 12 )&
+                               ), DIM = 1                                      &
+                            ) - 1
+             IF ( k > k_wall  .OR.  k_wall == 0 )  THEN
                 num_gp = num_gp + 1
                 gp_outside_of_building(6) = 1
@@ -699,5 +795,12 @@
              ENDIF
 
-             IF ( k+1 > nzb_s_inner(j,i+1)  .OR.  nzb_s_inner(j,i+1) == 0 )  THEN
+!
+!--          Determine vertical index of topography top at (j,i+1)
+             k_wall = MAXLOC(                                                  &
+                          MERGE( 1, 0,                                         &
+                                 BTEST( wall_flags_0(nzb:nzb_max,j,i+1), 12 )  &
+                               ), DIM = 1                                      &
+                            ) - 1
+             IF ( k+1 > k_wall  .OR.  k_wall == 0 )  THEN
                 num_gp = num_gp + 1
                 gp_outside_of_building(7) = 1
@@ -712,5 +815,12 @@
              ENDIF
 
-             IF ( k+1 > nzb_s_inner(j+1,i+1)  .OR.  nzb_s_inner(j+1,i+1) == 0)  THEN
+!
+!--          Determine vertical index of topography top at (j+1,i+1)
+             k_wall = MAXLOC(                                                  &
+                          MERGE( 1, 0,                                         &
+                                 BTEST( wall_flags_0(nzb:nzb_max,j+1,i+1), 12 )&
+                               ), DIM = 1                                      &
+                            ) - 1
+             IF ( k+1 > k_wall  .OR.  k_wall == 0)  THEN
                 num_gp = num_gp + 1
                 gp_outside_of_building(8) = 1
Index: /palm/trunk/SOURCE/lpm_boundary_conds.f90
===================================================================
--- /palm/trunk/SOURCE/lpm_boundary_conds.f90	(revision 2231)
+++ /palm/trunk/SOURCE/lpm_boundary_conds.f90	(revision 2232)
@@ -20,5 +20,6 @@
 ! Current revisions:
 ! -----------------
-! 
+! Adjustments to new topography and surface concept
+! Rename character range into location, as range is an intrinsic. 
 ! 
 ! Former revisions:
@@ -78,5 +79,5 @@
 !> (see offset_ocean_*)
 !------------------------------------------------------------------------------!
- SUBROUTINE lpm_boundary_conds( range )
+ SUBROUTINE lpm_boundary_conds( location )
  
 
@@ -94,5 +95,5 @@
 
     USE indices,                                                               &
-        ONLY:  nxl, nxr, nyn, nys, nz, nzb_s_inner
+        ONLY:  nxl, nxr, nyn, nys, nz, nzb, nzb_max, wall_flags_0
 
     USE kinds
@@ -107,5 +108,5 @@
     IMPLICIT NONE
 
-    CHARACTER (LEN=*) ::  range     !<
+    CHARACTER (LEN=*) ::  location     !<
     
     INTEGER(iwp) ::  inc            !< dummy for sorting algorithmus
@@ -118,4 +119,5 @@
     INTEGER(iwp) ::  j2             !< grid index (x) of current particle position
     INTEGER(iwp) ::  j3             !< grid index (x) of intermediate particle position
+    INTEGER(iwp) ::  k_wall         !< vertical index of topography top
     INTEGER(iwp) ::  n              !< particle number
     INTEGER(iwp) ::  t_index        !< running index for intermediate particle timesteps in reflection algorithmus
@@ -167,5 +169,5 @@
 
 
-    IF ( range == 'bottom/top' )  THEN
+    IF ( location == 'bottom/top' )  THEN
 
 !
@@ -232,5 +234,5 @@
        ENDDO
 
-    ELSEIF ( range == 'walls' )  THEN
+    ELSEIF ( location == 'walls' )  THEN
 
 
@@ -281,9 +283,27 @@
           ENDIF
 !
-!--       Walls aligned in xy layer at which particle can be possiblly reflected
-          zwall1 = zw(nzb_s_inner(j2,i2))
-          zwall2 = zw(nzb_s_inner(j1,i1))
-          zwall3 = zw(nzb_s_inner(j1,i2))
-          zwall4 = zw(nzb_s_inner(j2,i1))
+!--       Walls aligned in xy layer at which particle can be possiblly reflected.
+!--       The construct of MERGE and BTEST is used to determine the topography-
+!--       top index (former nzb_s_inner). 
+          zwall1 = zw( MAXLOC(                                                 &
+                          MERGE( 1, 0,                                         &
+                                 BTEST( wall_flags_0(nzb:nzb_max,j2,i2), 12 )  &
+                               ), DIM = 1                                      &
+                             ) - 1 )                                             
+          zwall2 = zw( MAXLOC(                                                 &
+                          MERGE( 1, 0,                                         &
+                                 BTEST( wall_flags_0(nzb:nzb_max,j1,i1), 12 )  &
+                               ), DIM = 1                                      &
+                             ) - 1 )  
+          zwall3 = zw( MAXLOC(                                                 &
+                          MERGE( 1, 0,                                         &
+                                 BTEST( wall_flags_0(nzb:nzb_max,j1,i2), 12 )  &
+                               ), DIM = 1                                      &
+                             ) - 1 )  
+          zwall4 = zw( MAXLOC(                                                 &
+                          MERGE( 1, 0,                                         &
+                                 BTEST( wall_flags_0(nzb:nzb_max,j2,i1), 12 )  &
+                               ), DIM = 1                                      &
+                             ) - 1 )  
 !
 !--       Initialize flags to check if particle reflection is necessary
@@ -469,7 +489,12 @@
 !--             constant is required, as the particle position do not 
 !--             necessarily exactly match the wall location due to rounding 
-!--             errors.   
+!--             errors. At first, determine index of topography top at (j3,i3)  
+                k_wall = MAXLOC(                                               &
+                            MERGE( 1, 0,                                       &
+                                 BTEST( wall_flags_0(nzb:nzb_max,j3,i3), 12 )  &
+                                 ), DIM = 1                                    &
+                               ) - 1  
                 IF ( ABS( pos_x - xwall ) < eps      .AND.                     &
-                     pos_z <= zw(nzb_s_inner(j3,i3)) .AND.                     &
+                     pos_z <= zw(k_wall)             .AND.                     &
                      reach_x(t_index)                .AND.                     &
                      .NOT. reflect_x )  THEN
@@ -504,7 +529,13 @@
 !
 !--             Check if a particle needs to be reflected at any xz-wall. If 
-!--             necessary, carry out reflection.
+!--             necessary, carry out reflection. At first, determine index of
+!--             topography top at (j3,i3)  
+                k_wall = MAXLOC(                                               &
+                            MERGE( 1, 0,                                       &
+                                 BTEST( wall_flags_0(nzb:nzb_max,j3,i3), 12 )  &
+                                 ), DIM = 1                                    &
+                               ) - 1  
                 IF ( ABS( pos_y - ywall ) < eps      .AND.                     &
-                     pos_z <= zw(nzb_s_inner(j3,i3)) .AND.                     &
+                     pos_z <= zw(k_wall)             .AND.                     &
                      reach_y(t_index)                .AND.                     &
                      .NOT. reflect_y ) THEN
@@ -525,11 +556,19 @@
 !
 !--             Check if a particle needs to be reflected at any xy-wall. If 
-!--             necessary, carry out reflection.
+!--             necessary, carry out reflection. 
                 IF ( downwards .AND. reach_z(t_index) .AND.                    &
                      .NOT. reflect_z )  THEN
-                   IF ( pos_z - zw(nzb_s_inner(j3,i3)) < eps ) THEN
+!
+!--                Determine index of topography top at (j3,i3) and chick if
+!--                particle is below.  
+                   k_wall = MAXLOC(                                            &
+                          MERGE( 1, 0,                                         &
+                                   BTEST( wall_flags_0(nzb:nzb_max,j3,i3), 12 )&
+                               ), DIM = 1                                      &
+                                  ) - 1  
+                   IF ( pos_z - zw(k_wall) < eps ) THEN
   
-                      pos_z = MAX( 2.0_wp * zw(nzb_s_inner(j3,i3)) - pos_z,    &
-                                   zw(nzb_s_inner(j3,i3)) )
+                      pos_z = MAX( 2.0_wp * zw(k_wall) - pos_z,    &
+                                   zw(k_wall) )
 
                       particles(n)%speed_z = - particles(n)%speed_z
Index: /palm/trunk/SOURCE/lpm_init.f90
===================================================================
--- /palm/trunk/SOURCE/lpm_init.f90	(revision 2231)
+++ /palm/trunk/SOURCE/lpm_init.f90	(revision 2232)
@@ -20,4 +20,5 @@
 ! Current revisions:
 ! -----------------
+! Adjustments according to new topography realization
 ! 
 ! 
@@ -146,5 +147,5 @@
 
     USE arrays_3d,                                                             &
-        ONLY:  de_dx, de_dy, de_dz, zu, zw, z0
+        ONLY:  de_dx, de_dy, de_dz, zu, zw
 
     USE control_parameters,                                                    &
@@ -157,5 +158,5 @@
     USE indices,                                                               &
         ONLY:  nx, nxl, nxlg, nxrg, nxr, ny, nyn, nys, nyng, nysg, nz, nzb,    &
-               nzb_w_inner, nzt
+               nzb_max, nzt, wall_flags_0
 
     USE kinds
@@ -196,4 +197,7 @@
         ONLY:  random_function
 
+    USE surface_mod,                                                           &
+        ONLY:  surf_def_h, surf_lsm_h, surf_usm_h
+
     IMPLICIT NONE
 
@@ -287,4 +291,14 @@
        number_of_particle_groups = max_number_of_particle_groups
     ENDIF
+!
+!-- Check if downward-facing walls exist. This case, reflection boundary
+!-- conditions (as well as subgrid-scale velocities) may do not work
+!-- propably (not realized so far). 
+    IF ( surf_def_h(1)%ns >= 1 )  THEN
+       WRITE( message_string, * ) 'Overhanging topograpyh do not work '// &   
+                                  'with particles' 
+       CALL message( 'lpm_init', 'PA0212', 0, 1, 0, 6, 0 )
+
+    ENDIF 
 
 !
@@ -355,5 +369,5 @@
        
        ALLOCATE ( log_z_z0(0:number_of_sublayers) ) 
-       z_p         = zu(nzb+1) - zw(nzb)
+       z_p = zu(nzb+1) - zw(nzb)
 
 !
@@ -362,5 +376,6 @@
 !--    However, sensitivity studies showed that the effect is 
 !--    negligible. 
-       z0_av_local  = SUM( z0(nys:nyn,nxl:nxr) )
+       z0_av_local  = SUM( surf_def_h(0)%z0 ) + SUM( surf_lsm_h%z0 ) +         &
+                      SUM( surf_usm_h%z0 )
        z0_av_global = 0.0_wp
 
@@ -577,4 +592,6 @@
     INTEGER(iwp)               ::  j           !< loop variable ( particles per point )
     INTEGER(iwp)               ::  jp          !< index variable along y
+    INTEGER(iwp)               ::  k           !< index variable along z
+    INTEGER(iwp)               ::  k_surf      !< index of surface grid point
     INTEGER(iwp)               ::  kp          !< index variable along z
     INTEGER(iwp)               ::  loop_stride !< loop variable for initialization
@@ -679,20 +696,38 @@
 !
 !--                            Determine the grid indices of the particle position
-                              ip = ( tmp_particle%x + 0.5_wp * dx ) * ddx
+                               ip = ( tmp_particle%x + 0.5_wp * dx ) * ddx
                                jp = ( tmp_particle%y + 0.5_wp * dy ) * ddy
                                kp = tmp_particle%z / dz + 1 + offset_ocean_nzt
+!
+!--                            Determine surface level. Therefore, check for
+!--                            upward-facing wall on w-grid. MAXLOC will return 
+!--                            the index of the lowest upward-facing wall.
+                               k_surf = MAXLOC(                                &
+                                             MERGE( 1, 0,                      &
+                                   BTEST( wall_flags_0(nzb:nzb_max,jp,ip), 18 )&
+                                                  ), DIM = 1                   &
+                                              ) - 1
 
                                IF ( seed_follows_topography )  THEN
 !
 !--                               Particle height is given relative to topography
-                                  kp = kp + nzb_w_inner(jp,ip)
-                                  tmp_particle%z = tmp_particle%z +            &
-                                                         zw(nzb_w_inner(jp,ip))
-                                  IF ( kp > nzt )  THEN
+                                  kp = kp + k_surf
+                                  tmp_particle%z = tmp_particle%z + zw(k_surf)
+!--                               Skip particle release if particle position is
+!--                               above model top, or within topography in case
+!--                               of overhanging structures.
+                                  IF ( kp > nzt  .OR.                          &
+                                 .NOT. BTEST( wall_flags_0(kp,jp,ip), 0 ) )  THEN
                                      pos_x = pos_x + pdx(i)
                                      CYCLE xloop
                                   ENDIF
+!
+!--                            Skip particle release if particle position is 
+!--                            below surface, or within topography in case
+!--                            of overhanging structures.
                                ELSEIF ( .NOT. seed_follows_topography .AND.    &
-                                        tmp_particle%z <= zw(nzb_w_inner(jp,ip)) )  THEN
+                                         tmp_particle%z <= zw(k_surf)  .OR.    &
+                                        .NOT. BTEST( wall_flags_0(kp,jp,ip), 0 ) )&
+                               THEN
                                   pos_x = pos_x + pdx(i)
                                   CYCLE xloop                               
@@ -820,5 +855,5 @@
                                      pdx(particles(n)%group)
                       particles(n)%x = particles(n)%x +                        &
-                              MERGE( rand_contr, SIGN( dx, rand_contr ), &
+                              MERGE( rand_contr, SIGN( dx, rand_contr ),       &
                                      ABS( rand_contr ) < dx                    &
                                    ) 
@@ -828,5 +863,5 @@
                                      pdy(particles(n)%group)
                       particles(n)%y = particles(n)%y +                        &
-                              MERGE( rand_contr, SIGN( dy, rand_contr ), &
+                              MERGE( rand_contr, SIGN( dy, rand_contr ),       &
                                      ABS( rand_contr ) < dy                    &
                                    ) 
@@ -836,5 +871,5 @@
                                      pdz(particles(n)%group)
                       particles(n)%z = particles(n)%z +                        &
-                              MERGE( rand_contr, SIGN( dz, rand_contr ), &
+                              MERGE( rand_contr, SIGN( dz, rand_contr ),       &
                                      ABS( rand_contr ) < dz                    &
                                    ) 
@@ -854,8 +889,12 @@
                    i = ( particles(n)%x + 0.5_wp * dx ) * ddx
                    j = ( particles(n)%y + 0.5_wp * dy ) * ddy
-                   IF ( particles(n)%z <= zw(nzb_w_inner(j,i)) )  THEN
+                   k =   particles(n)%z / dz + 1 + offset_ocean_nzt
+!
+!--                Check if particle is within topography
+                   IF ( .NOT. BTEST( wall_flags_0(k,j,i), 0 ) )  THEN
                       particles(n)%particle_mask = .FALSE.
                       deleted_particles = deleted_particles + 1
                    ENDIF
+
                 ENDDO
              ENDDO
Index: /palm/trunk/SOURCE/lpm_init_sgs_tke.f90
===================================================================
--- /palm/trunk/SOURCE/lpm_init_sgs_tke.f90	(revision 2231)
+++ /palm/trunk/SOURCE/lpm_init_sgs_tke.f90	(revision 2232)
@@ -20,5 +20,5 @@
 ! Current revisions:
 ! ------------------
-! 
+! Adjustments according to new topography realization
 ! 
 ! Former revisions:
@@ -73,6 +73,6 @@
 
     USE indices,                                                               &
-        ONLY:  nbgp, ngp_2dh_outer, nxl, nxr, nyn, nys, nzb, nzb_s_inner,      &
-               nzb_s_outer, nzt
+        ONLY:  nbgp, ngp_2dh_outer, nxl, nxr, nyn, nys, nzb,                   &
+               nzb_s_outer, nzt, wall_flags_0
 
     USE kinds
@@ -86,10 +86,15 @@
         ONLY:  flow_statistics_called, hom, sums, sums_l
 
+    USE surface_mod,                                                           &
+        ONLY:  bc_h
+
     IMPLICIT NONE
 
-    INTEGER(iwp) ::  i      !<
-    INTEGER(iwp) ::  j      !<
-    INTEGER(iwp) ::  k      !<
-
+    INTEGER(iwp) ::  i      !< index variable along x
+    INTEGER(iwp) ::  j      !< index variable along y
+    INTEGER(iwp) ::  k      !< index variable along z
+    INTEGER(iwp) ::  m      !< running index for the surface elements 
+
+    REAL(wp) ::  flag1      !< flag to mask topography
 
 !
@@ -99,18 +104,22 @@
           DO  k = nzb, nzt+1
 
-             IF ( k <= nzb_s_inner(j,i-1)  .AND.  k > nzb_s_inner(j,i)  .AND.  &
-                  k  > nzb_s_inner(j,i+1) )                                    &
+             IF ( .NOT. BTEST( wall_flags_0(k,j,i-1), 0 )  .AND.               &
+                        BTEST( wall_flags_0(k,j,i), 0   )  .AND.               &
+                        BTEST( wall_flags_0(k,j,i+1), 0 ) )                    &
              THEN
                 de_dx(k,j,i) = 2.0_wp * sgs_wf_part *                          &
                                ( e(k,j,i+1) - e(k,j,i) ) * ddx
-             ELSEIF ( k  > nzb_s_inner(j,i-1)  .AND.  k > nzb_s_inner(j,i)     &
-                      .AND.  k <= nzb_s_inner(j,i+1) )                         &
+             ELSEIF ( BTEST( wall_flags_0(k,j,i-1), 0 )  .AND.                 &
+                      BTEST( wall_flags_0(k,j,i), 0   )  .AND.                 &
+                .NOT. BTEST( wall_flags_0(k,j,i+1), 0 ) )                      &
              THEN
                 de_dx(k,j,i) = 2.0_wp * sgs_wf_part *                          &
                                ( e(k,j,i) - e(k,j,i-1) ) * ddx
-             ELSEIF ( k < nzb_s_inner(j,i)  .AND.  k < nzb_s_inner(j,i+1) )    &
+             ELSEIF ( .NOT. BTEST( wall_flags_0(k,j,i), 22   )  .AND.          &
+                      .NOT. BTEST( wall_flags_0(k,j,i+1), 22 ) )               &   
              THEN
                 de_dx(k,j,i) = 0.0_wp
-             ELSEIF ( k < nzb_s_inner(j,i-1)  .AND.  k < nzb_s_inner(j,i) )    &
+             ELSEIF ( .NOT. BTEST( wall_flags_0(k,j,i-1), 22 )  .AND.          &
+                      .NOT. BTEST( wall_flags_0(k,j,i), 22   ) )               &
              THEN
                 de_dx(k,j,i) = 0.0_wp
@@ -119,18 +128,22 @@
              ENDIF
 
-             IF ( k <= nzb_s_inner(j-1,i)  .AND.  k > nzb_s_inner(j,i)  .AND.  &
-                  k  > nzb_s_inner(j+1,i) )                                    &
+             IF ( .NOT. BTEST( wall_flags_0(k,j-1,i), 0 )  .AND.               &
+                        BTEST( wall_flags_0(k,j,i), 0   )  .AND.               &
+                        BTEST( wall_flags_0(k,j+1,i), 0 ) )                    &
              THEN
                 de_dy(k,j,i) = 2.0_wp * sgs_wf_part *                          &
                                ( e(k,j+1,i) - e(k,j,i) ) * ddy
-             ELSEIF ( k  > nzb_s_inner(j-1,i)  .AND.  k  > nzb_s_inner(j,i)    &
-                      .AND.  k <= nzb_s_inner(j+1,i) )                         &
+             ELSEIF ( BTEST( wall_flags_0(k,j-1,i), 0 )  .AND.                 &
+                      BTEST( wall_flags_0(k,j,i), 0   )  .AND.                 &
+                .NOT. BTEST( wall_flags_0(k,j+1,i), 0 ) )                      &
              THEN
                 de_dy(k,j,i) = 2.0_wp * sgs_wf_part *                          &
                                ( e(k,j,i) - e(k,j-1,i) ) * ddy
-             ELSEIF ( k < nzb_s_inner(j,i)  .AND.  k < nzb_s_inner(j+1,i) )    &
+             ELSEIF ( .NOT. BTEST( wall_flags_0(k,j,i), 22   )  .AND.          &
+                      .NOT. BTEST( wall_flags_0(k,j+1,i), 22 ) )               &   
              THEN
                 de_dy(k,j,i) = 0.0_wp
-             ELSEIF ( k < nzb_s_inner(j-1,i)  .AND.  k < nzb_s_inner(j,i) )    &
+             ELSEIF ( .NOT. BTEST( wall_flags_0(k,j-1,i), 22 )  .AND.          &
+                      .NOT. BTEST( wall_flags_0(k,j,i), 22   ) )               &
              THEN
                 de_dy(k,j,i) = 0.0_wp
@@ -144,25 +157,38 @@
 
 !
-!-- TKE gradient along z, including bottom and top boundary conditions
+!-- TKE gradient along z at topograhy and  including bottom and top boundary conditions
     DO  i = nxl, nxr
        DO  j = nys, nyn
-
-          DO  k = nzb_s_inner(j,i)+2, nzt-1
-             de_dz(k,j,i)  = 2.0_wp * sgs_wf_part *                            &
-                             ( e(k+1,j,i) - e(k-1,j,i) ) / ( zu(k+1)-zu(k-1) )
-          ENDDO
-
-          k = nzb_s_inner(j,i)
-          de_dz(nzb:k,j,i) = 0.0_wp
-          de_dz(k+1,j,i)   = 2.0_wp * sgs_wf_part *                            &
-                             ( e(k+2,j,i) - e(k+1,j,i) ) / ( zu(k+2) - zu(k+1) )
+          DO  k = nzb+1, nzt-1
+!
+!--          Flag to mask topography
+             flag1 = MERGE( 1.0_wp, 0.0_wp, BTEST( wall_flags_0(k,j,i), 0  ) )
+
+             de_dz(k,j,i) = 2.0_wp * sgs_wf_part *                             &
+                           ( e(k+1,j,i) - e(k-1,j,i) ) / ( zu(k+1) - zu(k-1) ) &
+                                                 * flag1 
+          ENDDO
+!
+!--       upward-facing surfaces
+          DO  m = bc_h(0)%start_index(j,i), bc_h(0)%end_index(j,i)
+             k            = bc_h(0)%k(m)
+             de_dz(k,j,i) = 2.0_wp * sgs_wf_part *                             &
+                           ( e(k+1,j,i) - e(k,j,i)   ) / ( zu(k+1) - zu(k) )
+          ENDDO
+!
+!--       downward-facing surfaces
+          DO  m = bc_h(1)%start_index(j,i), bc_h(1)%end_index(j,i)
+             k            = bc_h(1)%k(m)
+             de_dz(k,j,i) = 2.0_wp * sgs_wf_part *                             &
+                           ( e(k,j,i) - e(k-1,j,i)   ) / ( zu(k) - zu(k-1) )
+          ENDDO
+
+          de_dz(nzb,j,i)   = 0.0_wp
           de_dz(nzt,j,i)   = 0.0_wp
           de_dz(nzt+1,j,i) = 0.0_wp
        ENDDO
     ENDDO
-
-
-!
-!-- Lateral boundary conditions
+!
+!-- Ghost point exchange
     CALL exchange_horiz( de_dx, nbgp )
     CALL exchange_horiz( de_dy, nbgp )
@@ -185,7 +211,11 @@
        DO  i = nxl, nxr
           DO  j =  nys, nyn
-             DO  k = nzb_s_outer(j,i), nzt+1
-                sums_l(k,1,0)  = sums_l(k,1,0)  + u(k,j,i)
-                sums_l(k,2,0)  = sums_l(k,2,0)  + v(k,j,i)
+             DO  k = nzb, nzt+1
+!
+!--             Flag indicate nzb_s_outer 
+                flag1 = MERGE( 1.0_wp, 0.0_wp, BTEST( wall_flags_0(k,j,i), 24 ) )
+
+                sums_l(k,1,0)  = sums_l(k,1,0)  + u(k,j,i) * flag1
+                sums_l(k,2,0)  = sums_l(k,2,0)  + v(k,j,i) * flag1
              ENDDO
           ENDDO
@@ -221,9 +251,13 @@
        DO  i = nxl, nxr
           DO  j = nys, nyn
-             DO  k = nzb_s_outer(j,i), nzt+1
-                sums_l(k,8,0)  = sums_l(k,8,0)  + e(k,j,i)
-                sums_l(k,30,0) = sums_l(k,30,0) + ( u(k,j,i) - hom(k,1,1,0) )**2
-                sums_l(k,31,0) = sums_l(k,31,0) + ( v(k,j,i) - hom(k,1,2,0) )**2
-                sums_l(k,32,0) = sums_l(k,32,0) + w(k,j,i)**2
+             DO  k = nzb, nzt+1
+!
+!--             Flag indicate nzb_s_outer 
+                flag1 = MERGE( 1.0_wp, 0.0_wp, BTEST( wall_flags_0(k,j,i), 24 ) )
+
+                sums_l(k,8,0)  = sums_l(k,8,0)  + e(k,j,i)                       * flag1
+                sums_l(k,30,0) = sums_l(k,30,0) + ( u(k,j,i) - hom(k,1,1,0) )**2 * flag1
+                sums_l(k,31,0) = sums_l(k,31,0) + ( v(k,j,i) - hom(k,1,2,0) )**2 * flag1
+                sums_l(k,32,0) = sums_l(k,32,0) + w(k,j,i)**2                    * flag1
              ENDDO
           ENDDO
Index: /palm/trunk/SOURCE/ls_forcing_mod.f90
===================================================================
--- /palm/trunk/SOURCE/ls_forcing_mod.f90	(revision 2231)
+++ /palm/trunk/SOURCE/ls_forcing_mod.f90	(revision 2232)
@@ -20,5 +20,8 @@
 ! Current revisions:
 ! ------------------
-! 
+! Adopt to new topography structure, even though no well-conceived topography 
+! concept concerning nudging and large-scale for exist so far. 
+!
+! Also adopt to new surface-structure, i.e. fluxes are obtained from data-types 
 ! 
 ! Former revisions:
@@ -356,5 +359,5 @@
 
        USE arrays_3d,                                                          &
-           ONLY:  p_surf, pt_surf, q_surf, qsws, qsws_surf, shf, shf_surf,     &
+           ONLY:  p_surf, pt_surf, q_surf, qsws_surf, shf_surf,                &
                   heatflux_input_conversion, waterflux_input_conversion,       &
                   time_surf, time_vert, ug, ug_vert, vg, vg_vert
@@ -369,8 +372,12 @@
        USE kinds
 
+       USE surface_mod,                                                        &
+           ONLY:  surf_def_h, surf_lsm_h, surf_usm_h
+
        IMPLICIT NONE
 
        INTEGER(iwp) ::  nt                     !<
 
+       REAL(wp)             :: dum_surf_flux  !<
        REAL(wp)             :: fac            !<
        REAL(wp), INTENT(in) :: time           !<
@@ -398,7 +405,15 @@
 !--       In case of Neumann boundary condition pt_surface is needed for 
 !--       calculation of reference density
-          shf        = ( shf_surf(nt) + fac * ( shf_surf(nt+1) - shf_surf(nt) )&
-                       ) * heatflux_input_conversion(nzb)
-          pt_surface = pt_surf(nt) + fac * ( pt_surf(nt+1) - pt_surf(nt) )
+          dum_surf_flux = ( shf_surf(nt) + fac *                               &
+                            ( shf_surf(nt+1) - shf_surf(nt) )                  &
+                          ) * heatflux_input_conversion(nzb)
+!
+!--       Save surface sensible heat flux on default, natural and urban surface
+!--       type, if required 
+          IF ( surf_def_h(0)%ns >= 1 )  surf_def_h(0)%shf(:) = dum_surf_flux
+          IF ( surf_lsm_h%ns    >= 1 )  surf_lsm_h%shf(:)    = dum_surf_flux
+          IF ( surf_usm_h%ns    >= 1 )  surf_usm_h%shf(:)    = dum_surf_flux
+
+          pt_surface    = pt_surf(nt) + fac * ( pt_surf(nt+1) - pt_surf(nt) )
 
        ENDIF
@@ -411,7 +426,13 @@
 
        ELSEIF ( ibc_q_b == 1 )  THEN
-
-          qsws = ( qsws_surf(nt) + fac * ( qsws_surf(nt+1) - qsws_surf(nt) )   &
-                 ) * waterflux_input_conversion(nzb)
+          dum_surf_flux = ( qsws_surf(nt) + fac *                              &
+                             ( qsws_surf(nt+1) - qsws_surf(nt) )               &
+                             ) * waterflux_input_conversion(nzb)
+!
+!--       Save surface sensible heat flux on default, natural and urban surface
+!--       type, if required 
+          IF ( surf_def_h(0)%ns >= 1 )  surf_def_h(0)%qsws(:) = dum_surf_flux
+          IF ( surf_lsm_h%ns    >= 1 )  surf_lsm_h%qsws(:)    = dum_surf_flux
+          IF ( surf_usm_h%ns    >= 1 )  surf_usm_h%qsws(:)    = dum_surf_flux
 
        ENDIF
@@ -516,7 +537,9 @@
              DO  i = nxl, nxr
                 DO  j = nys, nyn
-                   DO  k = nzb_u_inner(j,i)+1, nzt
+                   DO  k = nzb+1, nzt
                       tend(k,j,i) = tend(k,j,i) + td_lsa_lpt(k,nt) + fac *     &
-                                    ( td_lsa_lpt(k,nt+1) - td_lsa_lpt(k,nt) )
+                                    ( td_lsa_lpt(k,nt+1) - td_lsa_lpt(k,nt) ) *&
+                                        MERGE( 1.0_wp, 0.0_wp,                 &
+                                               BTEST( wall_flags_0(k,j,i), 0 ) )
                    ENDDO
                 ENDDO
@@ -527,7 +550,9 @@
              DO  i = nxl, nxr
                 DO  j = nys, nyn
-                   DO  k = nzb_u_inner(j,i)+1, nzt
+                   DO  k = nzb+1, nzt
                       tend(k,j,i) = tend(k,j,i) + td_lsa_q(k,nt) + fac *       &
-                                    ( td_lsa_q(k,nt+1) - td_lsa_q(k,nt) )
+                                    ( td_lsa_q(k,nt+1) - td_lsa_q(k,nt) ) *    &
+                                        MERGE( 1.0_wp, 0.0_wp,                 &
+                                               BTEST( wall_flags_0(k,j,i), 0 ) )
                    ENDDO
                 ENDDO
@@ -546,7 +571,9 @@
                 DO  i = nxl, nxr
                    DO  j = nys, nyn
-                      DO  k = nzb_u_inner(j,i)+1, nzt
+                      DO  k = nzb+1, nzt
                          tend(k,j,i) = tend(k,j,i) + td_sub_lpt(k,nt) + fac *  &
-                                       ( td_sub_lpt(k,nt+1) - td_sub_lpt(k,nt) )
+                                     ( td_sub_lpt(k,nt+1) - td_sub_lpt(k,nt) )*&
+                                        MERGE( 1.0_wp, 0.0_wp,                 &
+                                               BTEST( wall_flags_0(k,j,i), 0 ) )
                       ENDDO
                    ENDDO
@@ -557,7 +584,9 @@
                 DO  i = nxl, nxr
                    DO  j = nys, nyn
-                      DO  k = nzb_u_inner(j,i)+1, nzt
+                      DO  k = nzb+1, nzt
                          tend(k,j,i) = tend(k,j,i) + td_sub_q(k,nt) + fac *    &
-                                       ( td_sub_q(k,nt+1) - td_sub_q(k,nt) )
+                                       ( td_sub_q(k,nt+1) - td_sub_q(k,nt) ) * &
+                                        MERGE( 1.0_wp, 0.0_wp,                 &
+                                               BTEST( wall_flags_0(k,j,i), 0 ) )
                       ENDDO
                    ENDDO
@@ -618,14 +647,18 @@
           CASE ( 'pt' )
 
-             DO  k = nzb_u_inner(j,i)+1, nzt
+             DO  k = nzb+1, nzt
                 tend(k,j,i) = tend(k,j,i) + td_lsa_lpt(k,nt)                   &
-                              + fac * ( td_lsa_lpt(k,nt+1) - td_lsa_lpt(k,nt) )
+                             + fac * ( td_lsa_lpt(k,nt+1) - td_lsa_lpt(k,nt) )*&
+                                        MERGE( 1.0_wp, 0.0_wp,                 &
+                                               BTEST( wall_flags_0(k,j,i), 0 ) )
              ENDDO
 
           CASE ( 'q' )
 
-             DO  k = nzb_u_inner(j,i)+1, nzt
+             DO  k = nzb+1, nzt
                 tend(k,j,i) = tend(k,j,i) + td_lsa_q(k,nt)                     &
-                              + fac * ( td_lsa_q(k,nt+1) - td_lsa_q(k,nt) )
+                              + fac * ( td_lsa_q(k,nt+1) - td_lsa_q(k,nt) ) *  &
+                                        MERGE( 1.0_wp, 0.0_wp,                 &
+                                               BTEST( wall_flags_0(k,j,i), 0 ) )
              ENDDO
 
@@ -640,14 +673,18 @@
              CASE ( 'pt' )
 
-                DO  k = nzb_u_inner(j,i)+1, nzt
+                DO  k = nzb+1, nzt
                    tend(k,j,i) = tend(k,j,i) + td_sub_lpt(k,nt) + fac *        &
-                                 ( td_sub_lpt(k,nt+1) - td_sub_lpt(k,nt) )
+                                 ( td_sub_lpt(k,nt+1) - td_sub_lpt(k,nt) ) *   &
+                                        MERGE( 1.0_wp, 0.0_wp,                 &
+                                               BTEST( wall_flags_0(k,j,i), 0 ) )
                 ENDDO
   
              CASE ( 'q' )
 
-                DO  k = nzb_u_inner(j,i)+1, nzt
+                DO  k = nzb+1, nzt
                    tend(k,j,i) = tend(k,j,i) + td_sub_q(k,nt) + fac *          &
-                                 ( td_sub_q(k,nt+1) - td_sub_q(k,nt) )
+                                 ( td_sub_q(k,nt+1) - td_sub_q(k,nt) ) *       &
+                                        MERGE( 1.0_wp, 0.0_wp,                 &
+                                               BTEST( wall_flags_0(k,j,i), 0 ) )
                 ENDDO
 
Index: /palm/trunk/SOURCE/microphysics_mod.f90
===================================================================
--- /palm/trunk/SOURCE/microphysics_mod.f90	(revision 2231)
+++ /palm/trunk/SOURCE/microphysics_mod.f90	(revision 2232)
@@ -20,5 +20,5 @@
 ! Current revisions:
 ! ------------------
-! 
+! Adjustments to new topography and surface concept
 ! 
 ! Former revisions:
@@ -402,5 +402,5 @@
 
        USE indices,                                                            &
-           ONLY:  nxlg, nxrg, nysg, nyng, nzb_s_inner, nzt
+           ONLY:  nxlg, nxrg, nyng, nysg, nzb, nzb_max, nzt, wall_flags_0
 
        USE kinds
@@ -416,5 +416,5 @@
        DO  i = nxlg, nxrg
           DO  j = nysg, nyng
-             DO  k = nzb_s_inner(j,i)+1, nzt
+             DO  k = nzb+1, nzt
                 IF ( qr(k,j,i) <= eps_sb )  THEN
                    qr(k,j,i) = 0.0_wp
@@ -422,7 +422,11 @@
                 ELSE
                    IF ( nr(k,j,i) * xrmin > qr(k,j,i) * hyrho(k) )  THEN
-                      nr(k,j,i) = qr(k,j,i) * hyrho(k) / xrmin
+                      nr(k,j,i) = qr(k,j,i) * hyrho(k) / xrmin *               &
+                                       MERGE( 1.0_wp, 0.0_wp,                  &           
+                                              BTEST( wall_flags_0(k,j,i), 0 ) )
                    ELSEIF ( nr(k,j,i) * xrmax < qr(k,j,i) * hyrho(k) )  THEN
-                      nr(k,j,i) = qr(k,j,i) * hyrho(k) / xrmax
+                      nr(k,j,i) = qr(k,j,i) * hyrho(k) / xrmax *               &
+                                       MERGE( 1.0_wp, 0.0_wp,                  &           
+                                              BTEST( wall_flags_0(k,j,i), 0 ) )
                    ENDIF
                 ENDIF
@@ -459,5 +463,5 @@
 
        USE indices,                                                            &
-           ONLY:  nxlg, nxrg, nysg, nyng, nzb_s_inner, nzt
+           ONLY:  nxlg, nxrg, nyng, nysg, nzb, nzb_max, nzt, wall_flags_0
 
        USE kinds
@@ -472,4 +476,5 @@
        REAL(wp)     ::  autocon           !<
        REAL(wp)     ::  dissipation       !<
+       REAL(wp)     ::  flag              !< flag to mask topography grid points
        REAL(wp)     ::  k_au              !<
        REAL(wp)     ::  l_mix             !<
@@ -487,5 +492,8 @@
        DO  i = nxlg, nxrg
           DO  j = nysg, nyng
-             DO  k = nzb_s_inner(j,i)+1, nzt
+             DO  k = nzb+1, nzt
+!
+!--             Predetermine flag to mask topography
+                flag = MERGE( 1.0_wp, 0.0_wp, BTEST( wall_flags_0(k,j,i), 0 ) )
 
                 IF ( qc(k,j,i) > eps_sb )  THEN
@@ -554,7 +562,8 @@
                    autocon = MIN( autocon, qc(k,j,i) / dt_micro )
 
-                   qr(k,j,i) = qr(k,j,i) + autocon * dt_micro
-                   qc(k,j,i) = qc(k,j,i) - autocon * dt_micro
-                   nr(k,j,i) = nr(k,j,i) + autocon / x0 * hyrho(k) * dt_micro
+                   qr(k,j,i) = qr(k,j,i) + autocon * dt_micro * flag
+                   qc(k,j,i) = qc(k,j,i) - autocon * dt_micro * flag
+                   nr(k,j,i) = nr(k,j,i) + autocon / x0 * hyrho(k) * dt_micro  &
+                                                              * flag
 
                 ENDIF
@@ -583,5 +592,5 @@
 
        USE indices,                                                            &
-           ONLY:  nxlg, nxrg, nyng, nysg, nzb_s_inner, nzt
+           ONLY:  nxlg, nxrg, nyng, nysg, nzb, nzb_max, nzt, wall_flags_0
 
        USE kinds
@@ -590,13 +599,25 @@
        IMPLICIT NONE
 
-       INTEGER(iwp) ::  i !<
-       INTEGER(iwp) ::  j !<
-       INTEGER(iwp) ::  k !<
+       INTEGER(iwp) ::  i      !<
+       INTEGER(iwp) ::  j      !<
+       INTEGER(iwp) ::  k      !<
+       INTEGER(iwp) ::  k_wall !< topgraphy top index
 
        REAL(wp)    ::  dqdt_precip !<
+       REAL(wp)    ::  flag        !< flag to mask topography grid points
 
        DO  i = nxlg, nxrg
           DO  j = nysg, nyng
-             DO  k = nzb_s_inner(j,i)+1, nzt
+!
+!--          Determine vertical index of topography top
+             k_wall = MAXLOC(                                                  &
+                          MERGE( 1, 0,                                         &
+                                 BTEST( wall_flags_0(nzb:nzb_max,j,i), 12 )    &
+                               ), DIM = 1                                      &
+                            ) - 1
+             DO  k = nzb+1, nzt
+!
+!--             Predetermine flag to mask topography
+                flag = MERGE( 1.0_wp, 0.0_wp, BTEST( wall_flags_0(k,j,i), 0 ) )
 
                 IF ( qc(k,j,i) > ql_crit )  THEN
@@ -606,13 +627,12 @@
                 ENDIF
 
-                qc(k,j,i) = qc(k,j,i) - dqdt_precip * dt_micro
-                q(k,j,i)  = q(k,j,i)  - dqdt_precip * dt_micro
+                qc(k,j,i) = qc(k,j,i) - dqdt_precip * dt_micro * flag
+                q(k,j,i)  = q(k,j,i)  - dqdt_precip * dt_micro * flag
                 pt(k,j,i) = pt(k,j,i) + dqdt_precip * dt_micro * l_d_cp *      &
-                                        pt_d_t(k)
+                                        pt_d_t(k)              * flag
 
 !
 !--             Compute the rain rate (stored on surface grid point)
-                prr(nzb_s_inner(j,i),j,i) = prr(nzb_s_inner(j,i),j,i) +        &
-                                            dqdt_precip * dzw(k)
+                prr(k_wall,j,i) = prr(k_wall,j,i) + dqdt_precip * dzw(k) * flag
 
              ENDDO
@@ -643,5 +663,5 @@
 
        USE indices,                                                            &
-           ONLY:  nxlg, nxrg, nysg, nyng, nzb_s_inner, nzt
+           ONLY:  nxlg, nxrg, nyng, nysg, nzb, nzb_max, nzt, wall_flags_0
 
        USE kinds
@@ -654,4 +674,5 @@
 
        REAL(wp)     ::  accr              !<
+       REAL(wp)     ::  flag              !< flag to mask topography grid points
        REAL(wp)     ::  k_cr              !<
        REAL(wp)     ::  phi_ac            !<
@@ -662,5 +683,8 @@
        DO  i = nxlg, nxrg
           DO  j = nysg, nyng
-             DO  k = nzb_s_inner(j,i)+1, nzt
+             DO  k = nzb+1, nzt
+!
+!--             Predetermine flag to mask topography
+                flag = MERGE( 1.0_wp, 0.0_wp, BTEST( wall_flags_0(k,j,i), 0 ) )
 
                 IF ( ( qc(k,j,i) > eps_sb )  .AND.  ( qr(k,j,i) > eps_sb ) )  THEN
@@ -690,6 +714,6 @@
                    accr = MIN( accr, qc(k,j,i) / dt_micro )
 
-                   qr(k,j,i) = qr(k,j,i) + accr * dt_micro
-                   qc(k,j,i) = qc(k,j,i) - accr * dt_micro
+                   qr(k,j,i) = qr(k,j,i) + accr * dt_micro * flag
+                   qc(k,j,i) = qc(k,j,i) - accr * dt_micro * flag
 
                 ENDIF
@@ -724,5 +748,5 @@
 
        USE indices,                                                            &
-           ONLY:  nxlg, nxrg, nysg, nyng, nzb_s_inner, nzt
+           ONLY:  nxlg, nxrg, nyng, nysg, nzb, nzb_max, nzt, wall_flags_0
 
        USE kinds
@@ -736,4 +760,5 @@
        REAL(wp)     ::  breakup           !<
        REAL(wp)     ::  dr                !<
+       REAL(wp)     ::  flag              !< flag to mask topography grid points
        REAL(wp)     ::  phi_br            !<
        REAL(wp)     ::  selfcoll          !<
@@ -743,5 +768,9 @@
        DO  i = nxlg, nxrg
           DO  j = nysg, nyng
-             DO  k = nzb_s_inner(j,i)+1, nzt
+             DO  k = nzb+1, nzt
+!
+!--             Predetermine flag to mask topography
+                flag = MERGE( 1.0_wp, 0.0_wp, BTEST( wall_flags_0(k,j,i), 0 ) )
+
                 IF ( qr(k,j,i) > eps_sb )  THEN
 !
@@ -763,5 +792,5 @@
 
                    selfcoll = MAX( breakup - selfcoll, -nr(k,j,i) / dt_micro )
-                   nr(k,j,i) = nr(k,j,i) + selfcoll * dt_micro
+                   nr(k,j,i) = nr(k,j,i) + selfcoll * dt_micro * flag
 
                 ENDIF
@@ -796,5 +825,5 @@
 
        USE indices,                                                            &
-           ONLY:  nxlg, nxrg, nysg, nyng, nzb_s_inner, nzt
+           ONLY:  nxlg, nxrg, nyng, nysg, nzb, nzb_max, nzt, wall_flags_0
 
        USE kinds
@@ -812,4 +841,5 @@
        REAL(wp)     ::  evap_nr           !<
        REAL(wp)     ::  f_vent            !<
+       REAL(wp)     ::  flag              !< flag to mask topography grid points
        REAL(wp)     ::  g_evap            !<
        REAL(wp)     ::  lambda_r          !<
@@ -828,5 +858,9 @@
        DO  i = nxlg, nxrg
           DO  j = nysg, nyng
-             DO  k = nzb_s_inner(j,i)+1, nzt
+             DO  k = nzb+1, nzt
+!
+!--             Predetermine flag to mask topography
+                flag = MERGE( 1.0_wp, 0.0_wp, BTEST( wall_flags_0(k,j,i), 0 ) )
+
                 IF ( qr(k,j,i) > eps_sb )  THEN
 !
@@ -916,6 +950,6 @@
                                      -nr(k,j,i) / dt_micro )
 
-                      qr(k,j,i) = qr(k,j,i) + evap    * dt_micro
-                      nr(k,j,i) = nr(k,j,i) + evap_nr * dt_micro
+                      qr(k,j,i) = qr(k,j,i) + evap    * dt_micro * flag
+                      nr(k,j,i) = nr(k,j,i) + evap_nr * dt_micro * flag
 
                    ENDIF
@@ -951,5 +985,5 @@
 
        USE indices,                                                            &
-           ONLY:  nxlg, nxrg, nysg, nyng, nzb, nzb_s_inner, nzt
+           ONLY:  nxlg, nxrg, nyng, nysg, nzb, nzb_max, nzt, wall_flags_0
 
        USE kinds
@@ -965,5 +999,6 @@
        INTEGER(iwp) ::  k             !<
 
-       REAL(wp), DIMENSION(nzb:nzt+1) :: sed_qc !<
+       REAL(wp)                       ::  flag   !< flag to mask topography grid points
+       REAL(wp), DIMENSION(nzb:nzt+1) ::  sed_qc !<
 
        CALL cpu_log( log_point_s(59), 'sed_cloud', 'start' )
@@ -973,9 +1008,13 @@
        DO  i = nxlg, nxrg
           DO  j = nysg, nyng
-             DO  k = nzt, nzb_s_inner(j,i)+1, -1
+             DO  k = nzt, nzb+1, -1
+!
+!--             Predetermine flag to mask topography
+                flag = MERGE( 1.0_wp, 0.0_wp, BTEST( wall_flags_0(k,j,i), 0 ) )
 
                 IF ( qc(k,j,i) > eps_sb )  THEN
                    sed_qc(k) = sed_qc_const * nc_const**( -2.0_wp / 3.0_wp ) * &
-                               ( qc(k,j,i) * hyrho(k) )**( 5.0_wp / 3.0_wp )
+                               ( qc(k,j,i) * hyrho(k) )**( 5.0_wp / 3.0_wp ) * &
+                                                                           flag
                 ELSE
                    sed_qc(k) = 0.0_wp
@@ -984,13 +1023,13 @@
                 sed_qc(k) = MIN( sed_qc(k), hyrho(k) * dzu(k+1) * q(k,j,i) /   &
                                             dt_micro + sed_qc(k+1)             &
-                               )
+                               ) * flag
 
                 q(k,j,i)  = q(k,j,i)  + ( sed_qc(k+1) - sed_qc(k) ) *          &
-                                        ddzu(k+1) / hyrho(k) * dt_micro
+                                        ddzu(k+1) / hyrho(k) * dt_micro * flag
                 qc(k,j,i) = qc(k,j,i) + ( sed_qc(k+1) - sed_qc(k) ) *          &
-                                        ddzu(k+1) / hyrho(k) * dt_micro
+                                        ddzu(k+1) / hyrho(k) * dt_micro * flag
                 pt(k,j,i) = pt(k,j,i) - ( sed_qc(k+1) - sed_qc(k) ) *          &
                                         ddzu(k+1) / hyrho(k) * l_d_cp *        &
-                                        pt_d_t(k) * dt_micro
+                                        pt_d_t(k) * dt_micro            * flag
 
 !
@@ -998,7 +1037,8 @@
                 IF ( call_microphysics_at_all_substeps )  THEN
                    prr(k,j,i) = prr(k,j,i) +  sed_qc(k) / hyrho(k)             &
-                                * weight_substep(intermediate_timestep_count)
+                                * weight_substep(intermediate_timestep_count)  &
+                                * flag
                 ELSE
-                   prr(k,j,i) = prr(k,j,i) + sed_qc(k) / hyrho(k)
+                   prr(k,j,i) = prr(k,j,i) + sed_qc(k) / hyrho(k) * flag
                 ENDIF
 
@@ -1032,5 +1072,5 @@
 
        USE indices,                                                            &
-           ONLY:  nxlg, nxrg, nysg, nyng, nzb, nzb_s_inner, nzt
+           ONLY:  nxlg, nxrg, nyng, nysg, nzb, nzb_max, nzt, wall_flags_0
 
        USE kinds
@@ -1039,10 +1079,17 @@
            ONLY:  weight_substep
 
+       USE surface_mod,                                                        &
+           ONLY :  bc_h
+       
        IMPLICIT NONE
 
-       INTEGER(iwp) ::  i                          !<
-       INTEGER(iwp) ::  j                          !<
-       INTEGER(iwp) ::  k                          !<
-       INTEGER(iwp) ::  k_run                      !<
+       INTEGER(iwp) ::  i             !< running index x direction
+       INTEGER(iwp) ::  j             !< running index y direction
+       INTEGER(iwp) ::  k             !< running index z direction
+       INTEGER(iwp) ::  k_run         !< 
+       INTEGER(iwp) ::  l             !< running index of surface type
+       INTEGER(iwp) ::  m             !< running index surface elements
+       INTEGER(iwp) ::  surf_e        !< End index of surface elements at (j,i)-gridpoint
+       INTEGER(iwp) ::  surf_s        !< Start index of surface elements at (j,i)-gridpoint
 
        REAL(wp)     ::  c_run                      !<
@@ -1052,4 +1099,5 @@
        REAL(wp)     ::  dr                         !<
        REAL(wp)     ::  flux                       !<
+       REAL(wp)     ::  flag                       !< flag to mask topography grid points
        REAL(wp)     ::  lambda_r                   !<
        REAL(wp)     ::  mu_r                       !<
@@ -1071,5 +1119,9 @@
        DO  i = nxlg, nxrg
           DO  j = nysg, nyng
-             DO  k = nzb_s_inner(j,i)+1, nzt
+             DO  k = nzb+1, nzt
+!
+!--             Predetermine flag to mask topography
+                flag = MERGE( 1.0_wp, 0.0_wp, BTEST( wall_flags_0(k,j,i), 0 ) )
+
                 IF ( qr(k,j,i) > eps_sb )  THEN
 !
@@ -1093,5 +1145,5 @@
                                                   ( mu_r + 1.0_wp ) )          &
                                               )                                &
-                                )
+                                ) * flag
 
                    w_qr(k) = MAX( 0.1_wp, MIN( 20.0_wp,                        &
@@ -1101,5 +1153,5 @@
                                                   ( mu_r + 4.0_wp ) )          &
                                              )                                 &
-                                )
+                                ) * flag
                 ELSE
                    w_nr(k) = 0.0_wp
@@ -1108,18 +1160,39 @@
              ENDDO
 !
-!--          Adjust boundary values
-             w_nr(nzb_s_inner(j,i)) = w_nr(nzb_s_inner(j,i)+1)
-             w_qr(nzb_s_inner(j,i)) = w_qr(nzb_s_inner(j,i)+1)
+!--          Adjust boundary values using surface data type. 
+!--          Upward-facing
+             surf_s = bc_h(0)%start_index(j,i)   
+             surf_e = bc_h(0)%end_index(j,i)
+             DO  m = surf_s, surf_e
+                k         = bc_h(0)%k(m)
+                w_nr(k-1) = w_nr(k)
+                w_qr(k-1) = w_qr(k)
+             ENDDO
+!
+!--          Downward-facing
+             surf_s = bc_h(1)%start_index(j,i)   
+             surf_e = bc_h(1)%end_index(j,i)
+             DO  m = surf_s, surf_e
+                k         = bc_h(1)%k(m)
+                w_nr(k+1) = w_nr(k)
+                w_qr(k+1) = w_qr(k)
+             ENDDO
+!
+!--          Model top boundary value
              w_nr(nzt+1) = 0.0_wp
              w_qr(nzt+1) = 0.0_wp
 !
 !--          Compute Courant number
-             DO  k = nzb_s_inner(j,i)+1, nzt
+             DO  k = nzb+1, nzt
+!
+!--             Predetermine flag to mask topography
+                flag = MERGE( 1.0_wp, 0.0_wp, BTEST( wall_flags_0(k,j,i), 0 ) )
+
                 c_nr(k) = 0.25_wp * ( w_nr(k-1) +                              &
                                       2.0_wp * w_nr(k) + w_nr(k+1) ) *         &
-                          dt_micro * ddzu(k)
+                          dt_micro * ddzu(k) * flag
                 c_qr(k) = 0.25_wp * ( w_qr(k-1) +                              &
                                       2.0_wp * w_qr(k) + w_qr(k+1) ) *         &
-                          dt_micro * ddzu(k)
+                          dt_micro * ddzu(k) * flag
              ENDDO
 !
@@ -1127,5 +1200,9 @@
              IF ( limiter_sedimentation )  THEN
 
-                DO k = nzb_s_inner(j,i)+1, nzt
+                DO k = nzb+1, nzt
+!
+!--                Predetermine flag to mask topography
+                   flag = MERGE( 1.0_wp, 0.0_wp, BTEST( wall_flags_0(k,j,i), 0 ) )
+
                    d_mean = 0.5_wp * ( qr(k+1,j,i) - qr(k-1,j,i) )
                    d_min  = qr(k,j,i) - MIN( qr(k+1,j,i), qr(k,j,i), qr(k-1,j,i) )
@@ -1134,5 +1211,6 @@
                    qr_slope(k) = SIGN(1.0_wp, d_mean) * MIN ( 2.0_wp * d_min,  &
                                                               2.0_wp * d_max,  &
-                                                              ABS( d_mean ) )
+                                                              ABS( d_mean ) )  &
+                                                      * flag
 
                    d_mean = 0.5_wp * ( nr(k+1,j,i) - nr(k-1,j,i) )
@@ -1156,7 +1234,10 @@
 !
 !--          Compute sedimentation flux
-             DO  k = nzt, nzb_s_inner(j,i)+1, -1
-!
-!--             Sum up all rain drop number densities which contribute to the flux
+             DO  k = nzt, nzb+1, -1
+!
+!--             Predetermine flag to mask topography
+                flag = MERGE( 1.0_wp, 0.0_wp, BTEST( wall_flags_0(k,j,i), 0 ) )
+!
+!--             Sum up all rain drop number densities which contribute to the flux 
 !--             through k-1/2
                 flux  = 0.0_wp
@@ -1167,8 +1248,10 @@
                    flux  = flux + hyrho(k_run) *                               &
                            ( nr(k_run,j,i) + nr_slope(k_run) *                 &
-                           ( 1.0_wp - c_run ) * 0.5_wp ) * c_run * dzu(k_run)
-                   z_run = z_run + dzu(k_run)
-                   k_run = k_run + 1
-                   c_run = MIN( 1.0_wp, c_nr(k_run) - z_run * ddzu(k_run) )
+                           ( 1.0_wp - c_run ) * 0.5_wp ) * c_run * dzu(k_run)  &
+                                              * flag
+                   z_run = z_run + dzu(k_run) * flag
+                   k_run = k_run + 1          * flag
+                   c_run = MIN( 1.0_wp, c_nr(k_run) - z_run * ddzu(k_run) )    &
+                                              * flag
                 ENDDO
 !
@@ -1180,7 +1263,7 @@
                           )
 
-                sed_nr(k) = flux / dt_micro
+                sed_nr(k) = flux / dt_micro * flag
                 nr(k,j,i) = nr(k,j,i) + ( sed_nr(k+1) - sed_nr(k) ) *          &
-                                        ddzu(k+1) / hyrho(k) * dt_micro
+                                        ddzu(k+1) / hyrho(k) * dt_micro * flag
 !
 !--             Sum up all rain water content which contributes to the flux
@@ -1195,8 +1278,9 @@
                    flux  = flux + hyrho(k_run) * ( qr(k_run,j,i) +             &
                                   qr_slope(k_run) * ( 1.0_wp - c_run ) *       &
-                                  0.5_wp ) * c_run * dzu(k_run)
-                   z_run = z_run + dzu(k_run)
-                   k_run = k_run + 1
-                   c_run = MIN( 1.0_wp, c_qr(k_run) - z_run * ddzu(k_run) )
+                                  0.5_wp ) * c_run * dzu(k_run) * flag
+                   z_run = z_run + dzu(k_run)                   * flag
+                   k_run = k_run + 1                            * flag
+                   c_run = MIN( 1.0_wp, c_qr(k_run) - z_run * ddzu(k_run) )    &
+                                                                * flag
 
                 ENDDO
@@ -1209,20 +1293,21 @@
                           )
 
-                sed_qr(k) = flux / dt_micro
+                sed_qr(k) = flux / dt_micro * flag
 
                 qr(k,j,i) = qr(k,j,i) + ( sed_qr(k+1) - sed_qr(k) ) *          &
-                                        ddzu(k+1) / hyrho(k) * dt_micro
+                                        ddzu(k+1) / hyrho(k) * dt_micro * flag
                 q(k,j,i)  = q(k,j,i)  + ( sed_qr(k+1) - sed_qr(k) ) *          &
-                                        ddzu(k+1) / hyrho(k) * dt_micro
+                                        ddzu(k+1) / hyrho(k) * dt_micro * flag
                 pt(k,j,i) = pt(k,j,i) - ( sed_qr(k+1) - sed_qr(k) ) *          &
                                         ddzu(k+1) / hyrho(k) * l_d_cp *        &
-                                        pt_d_t(k) * dt_micro
+                                        pt_d_t(k) * dt_micro            * flag
 !
 !--             Compute the rain rate
                 IF ( call_microphysics_at_all_substeps )  THEN
                    prr(k,j,i) = prr(k,j,i) + sed_qr(k) / hyrho(k)             &
-                                * weight_substep(intermediate_timestep_count)
+                                * weight_substep(intermediate_timestep_count) &
+                                * flag
                 ELSE
-                   prr(k,j,i) = prr(k,j,i) + sed_qr(k) / hyrho(k)
+                   prr(k,j,i) = prr(k,j,i) + sed_qr(k) / hyrho(k) * flag
                 ENDIF
 
@@ -1256,13 +1341,19 @@
 
        USE indices,                                                            &
-           ONLY:  nxl, nxr, nys, nyn, nzb_s_inner
+           ONLY:  nxl, nxr, nys, nyn, nzb, nzt, wall_flags_0
 
        USE kinds
 
+       USE surface_mod,                                                        &
+           ONLY :  bc_h
+
        IMPLICIT NONE
 
-       INTEGER(iwp) ::  i                          !:
-       INTEGER(iwp) ::  j                          !:
-
+       INTEGER(iwp) ::  i             !< running index x direction
+       INTEGER(iwp) ::  j             !< running index y direction
+       INTEGER(iwp) ::  k             !< running index y direction
+       INTEGER(iwp) ::  m             !< running index surface elements
+       INTEGER(iwp) ::  surf_e        !< End index of surface elements at (j,i)-gridpoint
+       INTEGER(iwp) ::  surf_s        !< Start index of surface elements at (j,i)-gridpoint
 
        IF ( ( dt_do2d_xy - time_do2d_xy ) < precipitation_amount_interval .AND.&
@@ -1270,14 +1361,15 @@
             intermediate_timestep_count == intermediate_timestep_count_max ) ) &
        THEN
-
-          DO  i = nxl, nxr
-             DO  j = nys, nyn
-
-                precipitation_amount(j,i) = precipitation_amount(j,i) +        &
-                                            prr(nzb_s_inner(j,i)+1,j,i) *      &
-                                            hyrho(nzb_s_inner(j,i)+1) * dt_3d
-
-             ENDDO
+!
+!--       Run over all upward-facing surface elements, i.e. non-natural, 
+!--       natural and urban
+          DO  m = 1, bc_h(0)%ns
+             i = bc_h(0)%i(m)            
+             j = bc_h(0)%j(m)
+             k = bc_h(0)%k(m)
+             precipitation_amount(j,i) = precipitation_amount(j,i) +           &
+                                               prr(k,j,i) * hyrho(k) * dt_3d
           ENDDO
+
        ENDIF
 
@@ -1410,5 +1502,5 @@
 
        USE indices,                                                            &
-           ONLY:  nzb_s_inner, nzt
+           ONLY:  nzb, nzt, wall_flags_0
 
        USE kinds
@@ -1420,5 +1512,10 @@
        INTEGER(iwp) ::  k                 !<
 
-       DO  k = nzb_s_inner(j,i)+1, nzt
+       REAL(wp) ::  flag                  !< flag to indicate first grid level above surface
+
+       DO  k = nzb+1, nzt
+!
+!--       Predetermine flag to mask topography
+          flag = MERGE( 1.0_wp, 0.0_wp, BTEST( wall_flags_0(k,j,i), 0 ) )
 
           IF ( qr_1d(k) <= eps_sb )  THEN
@@ -1431,7 +1528,7 @@
 !--          too big weights of rain drops (Stevens and Seifert, 2008).
              IF ( nr_1d(k) * xrmin > qr_1d(k) * hyrho(k) )  THEN
-                nr_1d(k) = qr_1d(k) * hyrho(k) / xrmin
+                nr_1d(k) = qr_1d(k) * hyrho(k) / xrmin * flag
              ELSEIF ( nr_1d(k) * xrmax < qr_1d(k) * hyrho(k) )  THEN
-                nr_1d(k) = qr_1d(k) * hyrho(k) / xrmax
+                nr_1d(k) = qr_1d(k) * hyrho(k) / xrmax * flag
              ENDIF
 
@@ -1463,5 +1560,5 @@
 
        USE indices,                                                            &
-           ONLY:  nzb_s_inner, nzt
+           ONLY:  nzb, nzt, wall_flags_0
 
        USE kinds
@@ -1476,4 +1573,5 @@
        REAL(wp)     ::  autocon           !<
        REAL(wp)     ::  dissipation       !<
+       REAL(wp)     ::  flag              !< flag to indicate first grid level above surface
        REAL(wp)     ::  k_au              !<
        REAL(wp)     ::  l_mix             !<
@@ -1487,5 +1585,8 @@
        REAL(wp)     ::  xc                !<
 
-       DO  k = nzb_s_inner(j,i)+1, nzt
+       DO  k = nzb+1, nzt
+!
+!--       Predetermine flag to mask topography
+          flag = MERGE( 1.0_wp, 0.0_wp, BTEST( wall_flags_0(k,j,i), 0 ) )
 
           IF ( qc_1d(k) > eps_sb )  THEN
@@ -1551,7 +1652,7 @@
              autocon = MIN( autocon, qc_1d(k) / dt_micro )
 
-             qr_1d(k) = qr_1d(k) + autocon * dt_micro
-             qc_1d(k) = qc_1d(k) - autocon * dt_micro
-             nr_1d(k) = nr_1d(k) + autocon / x0 * hyrho(k) * dt_micro
+             qr_1d(k) = qr_1d(k) + autocon * dt_micro                 * flag
+             qc_1d(k) = qc_1d(k) - autocon * dt_micro                 * flag
+             nr_1d(k) = nr_1d(k) + autocon / x0 * hyrho(k) * dt_micro * flag
 
           ENDIF
@@ -1575,5 +1676,5 @@
 
        USE indices,                                                            &
-           ONLY:  nzb_s_inner, nzt
+           ONLY:  nzb, nzb_max, nzt, wall_flags_0
 
        USE kinds
@@ -1582,11 +1683,23 @@
        IMPLICIT NONE
 
-       INTEGER(iwp) ::  i !<
-       INTEGER(iwp) ::  j !<
-       INTEGER(iwp) ::  k !<
+       INTEGER(iwp) ::  i      !<
+       INTEGER(iwp) ::  j      !<
+       INTEGER(iwp) ::  k      !<
+       INTEGER(iwp) ::  k_wall !< topography top index
 
        REAL(wp)    ::  dqdt_precip !<
-
-       DO  k = nzb_s_inner(j,i)+1, nzt
+       REAL(wp)    ::  flag              !< flag to indicate first grid level above surface
+
+!
+!--    Determine vertical index of topography top
+       k_wall = MAXLOC(                                                        &
+                        MERGE( 1, 0,                                           &
+                               BTEST( wall_flags_0(nzb:nzb_max,j,i), 12 )      &
+                             ), DIM = 1                                        &
+                      ) - 1
+       DO  k = nzb+1, nzt
+!
+!--       Predetermine flag to mask topography
+          flag = MERGE( 1.0_wp, 0.0_wp, BTEST( wall_flags_0(k,j,i), 0 ) )
 
           IF ( qc_1d(k) > ql_crit )  THEN
@@ -1596,12 +1709,11 @@
           ENDIF
 
-          qc_1d(k) = qc_1d(k) - dqdt_precip * dt_micro
-          q_1d(k)  = q_1d(k)  - dqdt_precip * dt_micro
-          pt_1d(k) = pt_1d(k) + dqdt_precip * dt_micro * l_d_cp * pt_d_t(k)
+          qc_1d(k) = qc_1d(k) - dqdt_precip * dt_micro * flag
+          q_1d(k)  = q_1d(k)  - dqdt_precip * dt_micro * flag
+          pt_1d(k) = pt_1d(k) + dqdt_precip * dt_micro * l_d_cp * pt_d_t(k) * flag
 
 !
 !--       Compute the rain rate (stored on surface grid point)
-          prr(nzb_s_inner(j,i),j,i) = prr(nzb_s_inner(j,i),j,i) +              &
-                                      dqdt_precip * dzw(k)
+          prr(k_wall,j,i) = prr(k_wall,j,i) + dqdt_precip * dzw(k) * flag
 
        ENDDO
@@ -1626,5 +1738,5 @@
 
        USE indices,                                                            &
-           ONLY:  nzb_s_inner, nzt
+           ONLY:  nzb, nzt, wall_flags_0
 
        USE kinds
@@ -1637,9 +1749,14 @@
 
        REAL(wp)     ::  accr              !<
+       REAL(wp)     ::  flag              !< flag to indicate first grid level above surface
        REAL(wp)     ::  k_cr              !<
        REAL(wp)     ::  phi_ac            !<
        REAL(wp)     ::  tau_cloud         !<
 
-       DO  k = nzb_s_inner(j,i)+1, nzt
+       DO  k = nzb+1, nzt
+!
+!--       Predetermine flag to mask topography
+          flag = MERGE( 1.0_wp, 0.0_wp, BTEST( wall_flags_0(k,j,i), 0 ) )
+
           IF ( ( qc_1d(k) > eps_sb )  .AND.  ( qr_1d(k) > eps_sb ) )  THEN
 !
@@ -1667,6 +1784,6 @@
              accr = MIN( accr, qc_1d(k) / dt_micro )
 
-             qr_1d(k) = qr_1d(k) + accr * dt_micro
-             qc_1d(k) = qc_1d(k) - accr * dt_micro
+             qr_1d(k) = qr_1d(k) + accr * dt_micro * flag
+             qc_1d(k) = qc_1d(k) - accr * dt_micro * flag
 
           ENDIF
@@ -1691,5 +1808,5 @@
 
        USE indices,                                                            &
-           ONLY:  nzb_s_inner, nzt
+           ONLY:  nzb, nzt, wall_flags_0
 
        USE kinds
@@ -1703,8 +1820,13 @@
        REAL(wp)     ::  breakup           !<
        REAL(wp)     ::  dr                !<
+       REAL(wp)     ::  flag              !< flag to indicate first grid level above surface
        REAL(wp)     ::  phi_br            !<
        REAL(wp)     ::  selfcoll          !<
 
-       DO  k = nzb_s_inner(j,i)+1, nzt
+       DO  k = nzb+1, nzt
+!
+!--       Predetermine flag to mask topography
+          flag = MERGE( 1.0_wp, 0.0_wp, BTEST( wall_flags_0(k,j,i), 0 ) )
+
           IF ( qr_1d(k) > eps_sb )  THEN
 !
@@ -1724,5 +1846,5 @@
 
              selfcoll = MAX( breakup - selfcoll, -nr_1d(k) / dt_micro )
-             nr_1d(k) = nr_1d(k) + selfcoll * dt_micro
+             nr_1d(k) = nr_1d(k) + selfcoll * dt_micro * flag
 
           ENDIF
@@ -1750,5 +1872,5 @@
 
        USE indices,                                                            &
-           ONLY:  nzb_s_inner, nzt
+           ONLY:  nzb, nzt, wall_flags_0
 
        USE kinds
@@ -1766,4 +1888,5 @@
        REAL(wp)     ::  evap_nr           !<
        REAL(wp)     ::  f_vent            !<
+       REAL(wp)     ::  flag              !< flag to indicate first grid level above surface
        REAL(wp)     ::  g_evap            !<
        REAL(wp)     ::  lambda_r          !<
@@ -1778,5 +1901,9 @@
        REAL(wp)     ::  xr                !<
 
-       DO  k = nzb_s_inner(j,i)+1, nzt
+       DO  k = nzb+1, nzt
+!
+!--       Predetermine flag to mask topography
+          flag = MERGE( 1.0_wp, 0.0_wp, BTEST( wall_flags_0(k,j,i), 0 ) )
+
           IF ( qr_1d(k) > eps_sb )  THEN
 !
@@ -1862,6 +1989,6 @@
                                -nr_1d(k) / dt_micro )
 
-                qr_1d(k) = qr_1d(k) + evap    * dt_micro
-                nr_1d(k) = nr_1d(k) + evap_nr * dt_micro
+                qr_1d(k) = qr_1d(k) + evap    * dt_micro * flag
+                nr_1d(k) = nr_1d(k) + evap_nr * dt_micro * flag
 
              ENDIF
@@ -1891,5 +2018,5 @@
 
        USE indices,                                                            &
-           ONLY:  nzb, nzb_s_inner, nzt
+           ONLY:  nzb, nzb, nzt, wall_flags_0
 
        USE kinds
@@ -1904,12 +2031,17 @@
        INTEGER(iwp) ::  k             !<
 
-       REAL(wp), DIMENSION(nzb:nzt+1) :: sed_qc  !<
+       REAL(wp)                       ::  flag    !< flag to indicate first grid level above surface
+       REAL(wp), DIMENSION(nzb:nzt+1) ::  sed_qc  !<
 
        sed_qc(nzt+1) = 0.0_wp
 
-       DO  k = nzt, nzb_s_inner(j,i)+1, -1
+       DO  k = nzt, nzb+1, -1
+!
+!--       Predetermine flag to mask topography
+          flag = MERGE( 1.0_wp, 0.0_wp, BTEST( wall_flags_0(k,j,i), 0 ) )
+
           IF ( qc_1d(k) > eps_sb )  THEN
              sed_qc(k) = sed_qc_const * nc_1d(k)**( -2.0_wp / 3.0_wp ) *       &
-                         ( qc_1d(k) * hyrho(k) )**( 5.0_wp / 3.0_wp )
+                         ( qc_1d(k) * hyrho(k) )**( 5.0_wp / 3.0_wp )  * flag
           ELSE
              sed_qc(k) = 0.0_wp
@@ -1918,20 +2050,20 @@
           sed_qc(k) = MIN( sed_qc(k), hyrho(k) * dzu(k+1) * q_1d(k) /          &
                                       dt_micro + sed_qc(k+1)                   &
-                         )
+                         ) * flag
 
           q_1d(k)  = q_1d(k)  + ( sed_qc(k+1) - sed_qc(k) ) * ddzu(k+1) /      &
-                                hyrho(k) * dt_micro
+                                hyrho(k) * dt_micro * flag
           qc_1d(k) = qc_1d(k) + ( sed_qc(k+1) - sed_qc(k) ) * ddzu(k+1) /      &
-                                hyrho(k) * dt_micro
+                                hyrho(k) * dt_micro * flag
           pt_1d(k) = pt_1d(k) - ( sed_qc(k+1) - sed_qc(k) ) * ddzu(k+1) /      &
-                                hyrho(k) * l_d_cp * pt_d_t(k) * dt_micro
+                                hyrho(k) * l_d_cp * pt_d_t(k) * dt_micro * flag
 
 !
 !--       Compute the precipitation rate of cloud (fog) droplets
           IF ( call_microphysics_at_all_substeps )  THEN
-             prr(k,j,i) = prr(k,j,i) + sed_qc(k) / hyrho(k) *               &
-                             weight_substep(intermediate_timestep_count)
+             prr(k,j,i) = prr(k,j,i) + sed_qc(k) / hyrho(k) *                  &
+                              weight_substep(intermediate_timestep_count) * flag
           ELSE
-             prr(k,j,i) = prr(k,j,i) + sed_qc(k) / hyrho(k)
+             prr(k,j,i) = prr(k,j,i) + sed_qc(k) / hyrho(k) * flag
           ENDIF
 
@@ -1959,5 +2091,5 @@
 
        USE indices,                                                            &
-           ONLY:  nzb, nzb_s_inner, nzt
+           ONLY:  nzb, nzb, nzt, wall_flags_0
 
        USE kinds
@@ -1966,10 +2098,16 @@
            ONLY:  weight_substep
 
+       USE surface_mod,                                                        &
+           ONLY :  bc_h
+       
        IMPLICIT NONE
 
-       INTEGER(iwp) ::  i                          !<
-       INTEGER(iwp) ::  j                          !<
-       INTEGER(iwp) ::  k                          !<
-       INTEGER(iwp) ::  k_run                      !<
+       INTEGER(iwp) ::  i             !< running index x direction
+       INTEGER(iwp) ::  j             !< running index y direction
+       INTEGER(iwp) ::  k             !< running index z direction
+       INTEGER(iwp) ::  k_run         !<
+       INTEGER(iwp) ::  m             !< running index surface elements
+       INTEGER(iwp) ::  surf_e        !< End index of surface elements at (j,i)-gridpoint
+       INTEGER(iwp) ::  surf_s        !< Start index of surface elements at (j,i)-gridpoint
 
        REAL(wp)     ::  c_run                      !<
@@ -1979,4 +2117,5 @@
        REAL(wp)     ::  dr                         !<
        REAL(wp)     ::  flux                       !<
+       REAL(wp)     ::  flag                       !< flag to indicate first grid level above surface
        REAL(wp)     ::  lambda_r                   !<
        REAL(wp)     ::  mu_r                       !<
@@ -1994,5 +2133,9 @@
 !
 !--    Compute velocities
-       DO  k = nzb_s_inner(j,i)+1, nzt
+       DO  k = nzb+1, nzt
+!
+!--       Predetermine flag to mask topography
+          flag = MERGE( 1.0_wp, 0.0_wp, BTEST( wall_flags_0(k,j,i), 0 ) )
+
           IF ( qr_1d(k) > eps_sb )  THEN
 !
@@ -2013,5 +2156,5 @@
                                             ( mu_r + 1.0_wp ) )                &
                                         )                                      &
-                          )
+                          ) * flag
              w_qr(k) = MAX( 0.1_wp, MIN( 20.0_wp,                              &
                                          a_term - b_term * ( 1.0_wp +          &
@@ -2019,5 +2162,5 @@
                                             ( mu_r + 4.0_wp ) )                &
                                        )                                       &
-                          )
+                          ) * flag
           ELSE
              w_nr(k) = 0.0_wp
@@ -2026,16 +2169,37 @@
        ENDDO
 !
-!--    Adjust boundary values
-       w_nr(nzb_s_inner(j,i)) = w_nr(nzb_s_inner(j,i)+1)
-       w_qr(nzb_s_inner(j,i)) = w_qr(nzb_s_inner(j,i)+1)
+!--    Adjust boundary values using surface data type. 
+!--    Upward facing non-natural
+       surf_s = bc_h(0)%start_index(j,i)   
+       surf_e = bc_h(0)%end_index(j,i)
+       DO  m = surf_s, surf_e
+          k         = bc_h(0)%k(m)
+          w_nr(k-1) = w_nr(k)
+          w_qr(k-1) = w_qr(k)
+       ENDDO
+!
+!--    Downward facing non-natural
+       surf_s = bc_h(1)%start_index(j,i)   
+       surf_e = bc_h(1)%end_index(j,i)
+       DO  m = surf_s, surf_e
+          k         = bc_h(1)%k(m)
+          w_nr(k+1) = w_nr(k)
+          w_qr(k+1) = w_qr(k)
+       ENDDO
+!
+!--    Neumann boundary condition at model top
        w_nr(nzt+1) = 0.0_wp
        w_qr(nzt+1) = 0.0_wp
 !
 !--    Compute Courant number
-       DO  k = nzb_s_inner(j,i)+1, nzt
+       DO  k = nzb+1, nzt
+!
+!--       Predetermine flag to mask topography
+          flag = MERGE( 1.0_wp, 0.0_wp, BTEST( wall_flags_0(k,j,i), 0 ) )
+
           c_nr(k) = 0.25_wp * ( w_nr(k-1) + 2.0_wp * w_nr(k) + w_nr(k+1) ) *   &
-                    dt_micro * ddzu(k)
+                    dt_micro * ddzu(k) * flag
           c_qr(k) = 0.25_wp * ( w_qr(k-1) + 2.0_wp * w_qr(k) + w_qr(k+1) ) *   &
-                    dt_micro * ddzu(k)
+                    dt_micro * ddzu(k) * flag
        ENDDO
 !
@@ -2043,5 +2207,9 @@
        IF ( limiter_sedimentation )  THEN
 
-          DO k = nzb_s_inner(j,i)+1, nzt
+          DO k = nzb+1, nzt
+!
+!--          Predetermine flag to mask topography
+             flag = MERGE( 1.0_wp, 0.0_wp, BTEST( wall_flags_0(k,j,i), 0 ) )
+
              d_mean = 0.5_wp * ( qr_1d(k+1) - qr_1d(k-1) )
              d_min  = qr_1d(k) - MIN( qr_1d(k+1), qr_1d(k), qr_1d(k-1) )
@@ -2050,5 +2218,5 @@
              qr_slope(k) = SIGN(1.0_wp, d_mean) * MIN ( 2.0_wp * d_min,        &
                                                         2.0_wp * d_max,        &
-                                                        ABS( d_mean ) )
+                                                        ABS( d_mean ) ) * flag
 
              d_mean = 0.5_wp * ( nr_1d(k+1) - nr_1d(k-1) )
@@ -2058,5 +2226,5 @@
              nr_slope(k) = SIGN(1.0_wp, d_mean) * MIN ( 2.0_wp * d_min,        &
                                                         2.0_wp * d_max,        &
-                                                        ABS( d_mean ) )
+                                                        ABS( d_mean ) ) * flag
           ENDDO
 
@@ -2072,7 +2240,10 @@
 !
 !--    Compute sedimentation flux
-       DO  k = nzt, nzb_s_inner(j,i)+1, -1
-!
-!--       Sum up all rain drop number densities which contribute to the flux
+       DO  k = nzt, nzb+1, -1
+!
+!--       Predetermine flag to mask topography
+          flag = MERGE( 1.0_wp, 0.0_wp, BTEST( wall_flags_0(k,j,i), 0 ) )
+!
+!--       Sum up all rain drop number densities which contribute to the flux 
 !--       through k-1/2
           flux  = 0.0_wp
@@ -2083,8 +2254,8 @@
              flux  = flux + hyrho(k_run) *                                     &
                      ( nr_1d(k_run) + nr_slope(k_run) * ( 1.0_wp - c_run ) *   &
-                     0.5_wp ) * c_run * dzu(k_run)
-             z_run = z_run + dzu(k_run)
-             k_run = k_run + 1
-             c_run = MIN( 1.0_wp, c_nr(k_run) - z_run * ddzu(k_run) )
+                     0.5_wp ) * c_run * dzu(k_run) * flag
+             z_run = z_run + dzu(k_run)            * flag
+             k_run = k_run + 1                     * flag
+             c_run = MIN( 1.0_wp, c_nr(k_run) - z_run * ddzu(k_run) ) * flag
           ENDDO
 !
@@ -2094,7 +2265,7 @@
                       hyrho(k) * dzu(k+1) * nr_1d(k) + sed_nr(k+1) * dt_micro )
 
-          sed_nr(k) = flux / dt_micro
+          sed_nr(k) = flux / dt_micro * flag
           nr_1d(k)  = nr_1d(k) + ( sed_nr(k+1) - sed_nr(k) ) * ddzu(k+1) /     &
-                                    hyrho(k) * dt_micro
+                                    hyrho(k) * dt_micro * flag
 !
 !--       Sum up all rain water content which contributes to the flux
@@ -2109,8 +2280,8 @@
              flux  = flux + hyrho(k_run) *                                     &
                      ( qr_1d(k_run) + qr_slope(k_run) * ( 1.0_wp - c_run ) *   &
-                     0.5_wp ) * c_run * dzu(k_run)
-             z_run = z_run + dzu(k_run)
-             k_run = k_run + 1
-             c_run = MIN( 1.0_wp, c_qr(k_run) - z_run * ddzu(k_run) )
+                     0.5_wp ) * c_run * dzu(k_run) * flag
+             z_run = z_run + dzu(k_run)            * flag
+             k_run = k_run + 1                     * flag
+             c_run = MIN( 1.0_wp, c_qr(k_run) - z_run * ddzu(k_run) ) * flag
 
           ENDDO
@@ -2120,19 +2291,19 @@
                       hyrho(k) * dzu(k) * qr_1d(k) + sed_qr(k+1) * dt_micro )
 
-          sed_qr(k) = flux / dt_micro
+          sed_qr(k) = flux / dt_micro * flag
 
           qr_1d(k) = qr_1d(k) + ( sed_qr(k+1) - sed_qr(k) ) * ddzu(k+1) /      &
-                                hyrho(k) * dt_micro
+                                hyrho(k) * dt_micro * flag
           q_1d(k)  = q_1d(k)  + ( sed_qr(k+1) - sed_qr(k) ) * ddzu(k+1) /      &
-                                hyrho(k) * dt_micro
+                                hyrho(k) * dt_micro * flag
           pt_1d(k) = pt_1d(k) - ( sed_qr(k+1) - sed_qr(k) ) * ddzu(k+1) /      &
-                                hyrho(k) * l_d_cp * pt_d_t(k) * dt_micro
+                                hyrho(k) * l_d_cp * pt_d_t(k) * dt_micro * flag
 !
 !--       Compute the rain rate
           IF ( call_microphysics_at_all_substeps )  THEN
              prr(k,j,i) = prr(k,j,i) + sed_qr(k) / hyrho(k)                    &
-                          * weight_substep(intermediate_timestep_count)
+                          * weight_substep(intermediate_timestep_count) * flag
           ELSE
-             prr(k,j,i) = prr(k,j,i) + sed_qr(k) / hyrho(k)
+             prr(k,j,i) = prr(k,j,i) + sed_qr(k) / hyrho(k) * flag
           ENDIF
 
@@ -2162,13 +2333,19 @@
 
        USE indices,                                                            &
-           ONLY:  nzb_s_inner
+           ONLY:  nzb, nzt, wall_flags_0
 
        USE kinds
 
+       USE surface_mod,                                                        &
+           ONLY :  bc_h
+
        IMPLICIT NONE
 
-       INTEGER(iwp) ::  i                          !:
-       INTEGER(iwp) ::  j                          !:
-
+       INTEGER(iwp) ::  i             !< running index x direction
+       INTEGER(iwp) ::  j             !< running index y direction
+       INTEGER(iwp) ::  k             !< running index z direction
+       INTEGER(iwp) ::  m             !< running index surface elements
+       INTEGER(iwp) ::  surf_e        !< End index of surface elements at (j,i)-gridpoint
+       INTEGER(iwp) ::  surf_s        !< Start index of surface elements at (j,i)-gridpoint
 
        IF ( ( dt_do2d_xy - time_do2d_xy ) < precipitation_amount_interval .AND.&
@@ -2177,7 +2354,12 @@
        THEN
 
-          precipitation_amount(j,i) = precipitation_amount(j,i) +              &
-                                      prr(nzb_s_inner(j,i)+1,j,i) *            &
-                                      hyrho(nzb_s_inner(j,i)+1) * dt_3d
+          surf_s = bc_h(0)%start_index(j,i)   
+          surf_e = bc_h(0)%end_index(j,i)
+          DO  m = surf_s, surf_e
+             k                         = bc_h(0)%k(m)
+             precipitation_amount(j,i) = precipitation_amount(j,i) +           &
+                                               prr(k,j,i) * hyrho(k) * dt_3d
+          ENDDO
+
        ENDIF
 
Index: /palm/trunk/SOURCE/modules.f90
===================================================================
--- /palm/trunk/SOURCE/modules.f90	(revision 2231)
+++ /palm/trunk/SOURCE/modules.f90	(revision 2232)
@@ -20,5 +20,24 @@
 ! Current revisions:
 ! ------------------
-! 
+! Renamed wall_flags_0 and wall_flags_00 into advc_flags_1 and advc_flags_2, 
+! respectively. Moreover, introduced further flag array wall_flags_0. 
+!
+! Adjustments for new topography concept:
+!   -fwxm, fwxp, fwym, fwyp, fxm, fxp, fym, fyp, rif_wall, wall_e_x, wall_e_y, 
+!   -wall_v, wall_u, wall_w_x, wall_w_y, wall_qflux, wall_sflux, wall_nrflux, 
+!   -wall_qrflux
+!
+! Adjustments for new surface concept:
+!   +land_surface
+!   -z0, z0h, z0q, us, ts, qs, qsws, nrs, nrsws, qrs, qrsws, ssws, ss, saswsb 
+!   -nzb_diff_u, nzb_diff_v, nzt_diff
+!   -uswst, vswst, tswst, sswst, saswst, qswst, qrswst, nrswst, qswst_remote
+!
+! Generic tunnel setup:
+!   +tunnel_height, tunnel_length, tunnel_width_x, tunnel_width_y, 
+!   +tunnel_wall_depth
+!
+! Topography input via netcdf
+!   +lod
 ! 
 ! Former revisions:
@@ -534,8 +553,4 @@
     REAL(wp), DIMENSION(:,:), ALLOCATABLE ::  f3_mg                 !< 
     REAL(wp), DIMENSION(:,:), ALLOCATABLE ::  mean_inflow_profiles  !< 
-    REAL(wp), DIMENSION(:,:), ALLOCATABLE ::  nrs                   !< 
-    REAL(wp), DIMENSION(:,:), ALLOCATABLE ::  nrsws                 !< 
-    REAL(wp), DIMENSION(:,:), ALLOCATABLE ::  nrswst                !< 
-    REAL(wp), DIMENSION(:,:), ALLOCATABLE ::  ol                    !< Obukhov length 
     REAL(wp), DIMENSION(:,:), ALLOCATABLE ::  precipitation_amount  !< 
     REAL(wp), DIMENSION(:,:), ALLOCATABLE ::  precipitation_rate    !< 
@@ -543,17 +558,4 @@
     REAL(wp), DIMENSION(:,:), ALLOCATABLE ::  pt_slope_ref          !< 
     REAL(wp), DIMENSION(:,:), ALLOCATABLE ::  qnudge                !< 
-    REAL(wp), DIMENSION(:,:), ALLOCATABLE ::  qs                    !< 
-    REAL(wp), DIMENSION(:,:), ALLOCATABLE ::  qsws                  !< 
-    REAL(wp), DIMENSION(:,:), ALLOCATABLE ::  qswst                 !< 
-    REAL(wp), DIMENSION(:,:), ALLOCATABLE ::  qswst_remote          !< 
-    REAL(wp), DIMENSION(:,:), ALLOCATABLE ::  qrs                   !< 
-    REAL(wp), DIMENSION(:,:), ALLOCATABLE ::  qrsws                 !< 
-    REAL(wp), DIMENSION(:,:), ALLOCATABLE ::  qrswst                !< 
-    REAL(wp), DIMENSION(:,:), ALLOCATABLE ::  saswsb                !< 
-    REAL(wp), DIMENSION(:,:), ALLOCATABLE ::  saswst                !< 
-    REAL(wp), DIMENSION(:,:), ALLOCATABLE ::  shf                   !< 
-    REAL(wp), DIMENSION(:,:), ALLOCATABLE ::  ss                    !< 
-    REAL(wp), DIMENSION(:,:), ALLOCATABLE ::  ssws                  !< 
-    REAL(wp), DIMENSION(:,:), ALLOCATABLE ::  sswst                 !< 
     REAL(wp), DIMENSION(:,:), ALLOCATABLE ::  tnudge                !< 
     REAL(wp), DIMENSION(:,:), ALLOCATABLE ::  td_lsa_lpt            !< 
@@ -563,20 +565,10 @@
     REAL(wp), DIMENSION(:,:), ALLOCATABLE ::  total_2d_a            !< 
     REAL(wp), DIMENSION(:,:), ALLOCATABLE ::  total_2d_o            !< 
-    REAL(wp), DIMENSION(:,:), ALLOCATABLE ::  ts                    !< 
-    REAL(wp), DIMENSION(:,:), ALLOCATABLE ::  tswst                 !< 
     REAL(wp), DIMENSION(:,:), ALLOCATABLE ::  ug_vert               !< 
     REAL(wp), DIMENSION(:,:), ALLOCATABLE ::  unudge                !< 
-    REAL(wp), DIMENSION(:,:), ALLOCATABLE ::  us                    !< 
-    REAL(wp), DIMENSION(:,:), ALLOCATABLE ::  usws                  !< 
-    REAL(wp), DIMENSION(:,:), ALLOCATABLE ::  uswst                 !< 
     REAL(wp), DIMENSION(:,:), ALLOCATABLE ::  vnudge                !< 
     REAL(wp), DIMENSION(:,:), ALLOCATABLE ::  vg_vert               !< 
-    REAL(wp), DIMENSION(:,:), ALLOCATABLE ::  vsws                  !< 
-    REAL(wp), DIMENSION(:,:), ALLOCATABLE ::  vswst                 !< 
     REAL(wp), DIMENSION(:,:), ALLOCATABLE ::  wnudge                !< 
     REAL(wp), DIMENSION(:,:), ALLOCATABLE ::  wsubs_vert            !< 
-    REAL(wp), DIMENSION(:,:), ALLOCATABLE ::  z0                    !< roughness length for momentum
-    REAL(wp), DIMENSION(:,:), ALLOCATABLE ::  z0h                   !< roughness length for heat
-    REAL(wp), DIMENSION(:,:), ALLOCATABLE ::  z0q                   !< roughness length for moisture
     
     REAL(wp), DIMENSION(:,:,:), ALLOCATABLE ::  d          !< 
@@ -744,5 +736,4 @@
 #endif
 
-    REAL(wp), DIMENSION(:,:,:,:), ALLOCATABLE ::  rif_wall !< 
     REAL(wp), DIMENSION(:,:,:,:), ALLOCATABLE ::  tri      !< 
 
@@ -1014,4 +1005,5 @@
     INTEGER(iwp) ::  io_blocks = 1                     !< 
     INTEGER(iwp) ::  iran = -1234567                   !< 
+    INTEGER(iwp) ::  lod = 1                           !< level of detail, topography input parameter 
     INTEGER(iwp) ::  masks = 0                         !< 
     INTEGER(iwp) ::  maximum_grid_level                !< 
@@ -1130,4 +1122,5 @@
     LOGICAL ::  large_scale_forcing = .FALSE.                !< 
     LOGICAL ::  large_scale_subsidence = .FALSE.             !< 
+    LOGICAL ::  land_surface = .FALSE.                       !< flag parameter indicating wheather the lsm is used
     LOGICAL ::  lsf_exception = .FALSE.                      !< temporary flag for use of lsf with buildings on flat terrain
     LOGICAL ::  lsf_surf = .TRUE.                            !< 
@@ -1183,5 +1176,4 @@
     LOGICAL ::  ws_scheme_sca = .FALSE.                      !< 
     LOGICAL ::  ws_scheme_mom = .FALSE.                      !< 
-
     LOGICAL ::  data_output_xy(0:1) = .FALSE.                !< 
     LOGICAL ::  data_output_xz(0:1) = .FALSE.                !< 
@@ -1322,4 +1314,9 @@
     REAL(wp) ::  top_salinityflux = 9999999.9_wp               !< 
     REAL(wp) ::  top_scalarflux = 9999999.9_wp                 !< 
+    REAL(wp) ::  tunnel_height = 9999999.9_wp                  !< height of tunnel outer wall
+    REAL(wp) ::  tunnel_length = 9999999.9_wp                  !< tunnel length
+    REAL(wp) ::  tunnel_width_x = 9999999.9_wp                 !< tunnel width in x, with respect to outer wall
+    REAL(wp) ::  tunnel_width_y = 9999999.9_wp                 !< tunnel width in y, with respect to outer wall
+    REAL(wp) ::  tunnel_wall_depth = 9999999.9_wp              !< tunnel wall depth
     REAL(wp) ::  ug_surface = 0.0_wp                           !< 
     REAL(wp) ::  u_bulk = 0.0_wp                               !< 
@@ -1366,9 +1363,5 @@
     REAL(wp) ::  wall_heatflux(0:4) = 0.0_wp                       !< 
     REAL(wp) ::  wall_humidityflux(0:4) = 0.0_wp                   !< 
-    REAL(wp) ::  wall_nrflux(0:4) = 0.0_wp                         !< 
-    REAL(wp) ::  wall_qflux(0:4) = 0.0_wp                          !< 
-    REAL(wp) ::  wall_qrflux(0:4) = 0.0_wp                         !< 
     REAL(wp) ::  wall_salinityflux(0:4) = 0.0_wp                   !< 
-    REAL(wp) ::  wall_sflux(0:4) = 0.0_wp                          !< 
     REAL(wp) ::  wall_scalarflux(0:4) = 0.0_wp                     !< 
     REAL(wp) ::  subs_vertical_gradient(10) = 0.0_wp               !< 
@@ -1534,18 +1527,4 @@
     REAL(wp), DIMENSION(:), ALLOCATABLE ::  ddy2_mg  !< 
 
-    REAL(wp), DIMENSION(:,:), ALLOCATABLE ::  fwxm        !< 
-    REAL(wp), DIMENSION(:,:), ALLOCATABLE ::  fwxp        !< 
-    REAL(wp), DIMENSION(:,:), ALLOCATABLE ::  fwym        !< 
-    REAL(wp), DIMENSION(:,:), ALLOCATABLE ::  fwyp        !< 
-    REAL(wp), DIMENSION(:,:), ALLOCATABLE ::  fxm         !< 
-    REAL(wp), DIMENSION(:,:), ALLOCATABLE ::  fxp         !< 
-    REAL(wp), DIMENSION(:,:), ALLOCATABLE ::  fym         !< 
-    REAL(wp), DIMENSION(:,:), ALLOCATABLE ::  fyp         !< 
-    REAL(wp), DIMENSION(:,:), ALLOCATABLE ::  wall_e_x    !< 
-    REAL(wp), DIMENSION(:,:), ALLOCATABLE ::  wall_e_y    !< 
-    REAL(wp), DIMENSION(:,:), ALLOCATABLE ::  wall_u      !< 
-    REAL(wp), DIMENSION(:,:), ALLOCATABLE ::  wall_v      !< 
-    REAL(wp), DIMENSION(:,:), ALLOCATABLE ::  wall_w_x    !< 
-    REAL(wp), DIMENSION(:,:), ALLOCATABLE ::  wall_w_y    !< 
     REAL(wp), DIMENSION(:,:), ALLOCATABLE ::  zu_s_inner  !<  
     REAL(wp), DIMENSION(:,:), ALLOCATABLE ::  zw_w_inner  !< 
@@ -1594,5 +1573,4 @@
     INTEGER(iwp) ::  nzb_max      !< 
     INTEGER(iwp) ::  nzt          !< 
-    INTEGER(iwp) ::  nzt_diff     !< 
 
     INTEGER(idp), DIMENSION(:), ALLOCATABLE ::  ngp_3d        !< 
@@ -1612,6 +1590,4 @@
     INTEGER(iwp), DIMENSION(:,:), ALLOCATABLE ::  nzb_diff_s_inner  !< 
     INTEGER(iwp), DIMENSION(:,:), ALLOCATABLE ::  nzb_diff_s_outer  !< 
-    INTEGER(iwp), DIMENSION(:,:), ALLOCATABLE ::  nzb_diff_u        !< 
-    INTEGER(iwp), DIMENSION(:,:), ALLOCATABLE ::  nzb_diff_v        !< 
     INTEGER(iwp), DIMENSION(:,:), ALLOCATABLE ::  nzb_inner         !< 
     INTEGER(iwp), DIMENSION(:,:), ALLOCATABLE ::  nzb_outer         !< 
@@ -1627,7 +1603,4 @@
     INTEGER(iwp), DIMENSION(:,:,:), POINTER ::  flags  !<
 
-    INTEGER(iwp), DIMENSION(:,:,:), ALLOCATABLE ::  wall_flags_0   !< 
-    INTEGER(iwp), DIMENSION(:,:,:), ALLOCATABLE ::  wall_flags_00  !< 
-
     INTEGER(iwp), DIMENSION(:,:,:), ALLOCATABLE,  TARGET ::  wall_flags_1   !< 
     INTEGER(iwp), DIMENSION(:,:,:), ALLOCATABLE,  TARGET ::  wall_flags_2   !< 
@@ -1641,6 +1614,7 @@
     INTEGER(iwp), DIMENSION(:,:,:), ALLOCATABLE,  TARGET ::  wall_flags_10  !< 
 
-    REAL(wp), DIMENSION(:,:,:), ALLOCATABLE ::  rflags_s_inner  !< 
-    REAL(wp), DIMENSION(:,:,:), ALLOCATABLE ::  rflags_invers   !< 
+    INTEGER(iwp), DIMENSION(:,:,:), ALLOCATABLE ::  advc_flags_1            !< flags used to degrade order of advection scheme
+    INTEGER(iwp), DIMENSION(:,:,:), ALLOCATABLE ::  advc_flags_2            !< flags used to degrade order of advection scheme
+    INTEGER(iwp), DIMENSION(:,:,:), ALLOCATABLE ::  wall_flags_0            !< flags to mask topography
 
     SAVE
Index: /palm/trunk/SOURCE/netcdf_interface_mod.f90
===================================================================
--- /palm/trunk/SOURCE/netcdf_interface_mod.f90	(revision 2231)
+++ /palm/trunk/SOURCE/netcdf_interface_mod.f90	(revision 2232)
@@ -20,6 +20,16 @@
 ! Current revisions:
 ! ------------------
+! Adjustments to new topography and surface concept
 ! 
-! 
+! Topograpyh height arrays (zu_s_inner, zw_w_inner) are defined locally, output
+! only if parallel netcdf. 
+!
+! Build interface for topography input: 
+! - open file in read-only mode
+! - read global attributes
+! - read variables
+!
+! Bugfix in xy output (land-surface case)
+!
 ! Former revisions:
 ! -----------------
@@ -198,5 +208,6 @@
  MODULE netcdf_interface
 
-    USE control_parameters, ONLY: max_masks, fl_max, var_fl_max, varnamelength
+    USE control_parameters,                                                    &
+        ONLY:  max_masks, fl_max, var_fl_max, varnamelength
     USE kinds
 #if defined( __netcdf )
@@ -397,4 +408,8 @@
     END INTERFACE netcdf_create_dim
 
+    INTERFACE netcdf_close_file
+       MODULE PROCEDURE netcdf_close_file
+    END INTERFACE netcdf_close_file
+
     INTERFACE netcdf_create_file
        MODULE PROCEDURE netcdf_create_file
@@ -409,14 +424,28 @@
     END INTERFACE netcdf_define_header
 
+    INTERFACE netcdf_get_attribute
+       MODULE PROCEDURE netcdf_get_attribute
+    END INTERFACE netcdf_get_attribute
+
+    INTERFACE netcdf_get_variable
+       MODULE PROCEDURE netcdf_get_variable_2d
+       MODULE PROCEDURE netcdf_get_variable_3d
+    END INTERFACE netcdf_get_variable
+
     INTERFACE netcdf_handle_error
        MODULE PROCEDURE netcdf_handle_error
     END INTERFACE netcdf_handle_error
 
+    INTERFACE netcdf_open_read_file
+       MODULE PROCEDURE netcdf_open_read_file
+    END INTERFACE netcdf_open_read_file
+
     INTERFACE netcdf_open_write_file
        MODULE PROCEDURE netcdf_open_write_file
     END INTERFACE netcdf_open_write_file
 
-    PUBLIC netcdf_create_file, netcdf_define_header, netcdf_handle_error,      &
-           netcdf_open_write_file
+    PUBLIC netcdf_create_file, netcdf_close_file, netcdf_define_header,        &
+           netcdf_handle_error, netcdf_get_attribute, netcdf_get_variable,     &
+           netcdf_open_read_file, netcdf_open_write_file
 
  CONTAINS
@@ -434,11 +463,12 @@
     USE control_parameters,                                                    &
         ONLY:  averaging_interval, averaging_interval_pr,                      &
-               data_output_pr,  domask,  dopr_n,        &
+               data_output_pr, domask, dopr_n,                                 &
                dopr_time_count, dopts_time_count, dots_time_count,             &
-               do2d, do2d_xz_time_count, do3d,                &
+               do2d, do2d_xz_time_count, do3d,                                 &
                do2d_yz_time_count, dt_data_output_av, dt_do2d_xy, dt_do2d_xz,  &
                dt_do2d_yz, dt_do3d, mask_size, do2d_xy_time_count,             &
-               do3d_time_count, domask_time_count, end_time, mask_i_global,    &
-               mask_j_global, mask_k_global, message_string, mid, ntdim_2d_xy, &
+               do3d_time_count, domask_time_count, end_time, land_surface,     &
+               lod, mask_size_l, mask_i, mask_i_global, mask_j, mask_j_global, &
+               mask_k_global, message_string, mid, ntdim_2d_xy,                &
                ntdim_2d_xz, ntdim_2d_yz, ntdim_3d, nz_do3d, prt_time_count,    &
                run_description_header, section, simulated_time,                &
@@ -452,10 +482,10 @@
 
     USE indices,                                                               &
-        ONLY:  nx, ny, nz ,nzb, nzt
+        ONLY:  nx, nxl, nxr, ny, nys, nyn, nz ,nzb, nzt
 
     USE kinds
 
     USE land_surface_model_mod,                                                &
-        ONLY: land_surface, lsm_define_netcdf_grid, nzb_soil, nzt_soil, nzs, zs
+        ONLY: lsm_define_netcdf_grid, nzb_soil, nzt_soil, nzs, zs
 
     USE pegrid
@@ -750,6 +780,7 @@
 !
 !--       In case of non-flat topography define 2d-arrays containing the height
-!--       information
-          IF ( TRIM( topography ) /= 'flat' )  THEN
+!--       information. Only for parallel netcdf output.
+          IF ( TRIM( topography ) /= 'flat'  .AND.                             &
+               netcdf_data_format > 4 )  THEN
 !
 !--          Define zusi = zu(nzb_s_inner)
@@ -992,27 +1023,28 @@
 !
 !--       In case of non-flat topography write height information
-          IF ( TRIM( topography ) /= 'flat' )  THEN
-
-             ALLOCATE( netcdf_data_2d(mask_size(mid,1),mask_size(mid,2)) )
-             netcdf_data_2d = zu_s_inner( mask_i_global(mid,:mask_size(mid,1)),&
-                                          mask_j_global(mid,:mask_size(mid,2)) )
-
-             nc_stat = NF90_PUT_VAR( id_set_mask(mid,av),         &
-                                     id_var_zusi_mask(mid,av),    &
-                                     netcdf_data_2d,              &
-                                     start = (/ 1, 1 /),          &
-                                     count = (/ mask_size(mid,1), &
-                                                mask_size(mid,2) /) )
+          IF ( TRIM( topography ) /= 'flat'  .AND.                             &
+               netcdf_data_format > 4 )  THEN
+
+             ALLOCATE( netcdf_data_2d(mask_size_l(mid,1),mask_size_l(mid,2)) )
+             netcdf_data_2d = zu_s_inner( mask_i(mid,:mask_size_l(mid,1)),     &
+                                          mask_j(mid,:mask_size_l(mid,2)) )
+
+             nc_stat = NF90_PUT_VAR( id_set_mask(mid,av),                      &
+                                     id_var_zusi_mask(mid,av),                 &
+                                     netcdf_data_2d,                           &
+                                     start = (/ 1, 1 /),                       &
+                                     count = (/ mask_size_l(mid,1),            &
+                                                mask_size_l(mid,2) /) )
              CALL netcdf_handle_error( 'netcdf_define_header', 505 )
 
-             netcdf_data_2d = zw_w_inner( mask_i_global(mid,:mask_size(mid,1)),&
-                                          mask_j_global(mid,:mask_size(mid,2)) )
-
-             nc_stat = NF90_PUT_VAR( id_set_mask(mid,av),         &
-                                     id_var_zwwi_mask(mid,av),    &
-                                     netcdf_data_2d,              &
-                                     start = (/ 1, 1 /),          &
-                                     count = (/ mask_size(mid,1), &
-                                                mask_size(mid,2) /) )
+             netcdf_data_2d = zw_w_inner( mask_i(mid,:mask_size_l(mid,1)),     &
+                                          mask_j(mid,:mask_size_l(mid,2)) )
+
+             nc_stat = NF90_PUT_VAR( id_set_mask(mid,av),                      &
+                                     id_var_zwwi_mask(mid,av),                 &
+                                     netcdf_data_2d,                           &
+                                     start = (/ 1, 1 /),                       &
+                                     count = (/ mask_size_l(mid,1),            &
+                                                mask_size_l(mid,2) /) )
              CALL netcdf_handle_error( 'netcdf_define_header', 506 )
 
@@ -1283,6 +1315,8 @@
 !
 !--       In case of non-flat topography define 2d-arrays containing the height
-!--       information
-          IF ( TRIM( topography ) /= 'flat' )  THEN
+!--       information. Only output 2d topography information in case of parallel
+!--       output.
+          IF ( TRIM( topography ) /= 'flat'  .AND.                             &
+               netcdf_data_format > 4 )  THEN
 !
 !--          Define zusi = zu(nzb_s_inner)
@@ -1542,22 +1576,4 @@
              CALL netcdf_handle_error( 'netcdf_define_header', 86 )
 
-!
-!--          In case of non-flat topography write height information
-             IF ( TRIM( topography ) /= 'flat' )  THEN
-
-                nc_stat = NF90_PUT_VAR( id_set_3d(av), id_var_zusi_3d(av), &
-                                        zu_s_inner(0:nx+1,0:ny+1), &
-                                        start = (/ 1, 1 /), &
-                                        count = (/ nx+2, ny+2 /) )
-                CALL netcdf_handle_error( 'netcdf_define_header', 419 )
-
-                nc_stat = NF90_PUT_VAR( id_set_3d(av), id_var_zwwi_3d(av), &
-                                        zw_w_inner(0:nx+1,0:ny+1), &
-                                        start = (/ 1, 1 /), &
-                                        count = (/ nx+2, ny+2 /) )
-                CALL netcdf_handle_error( 'netcdf_define_header', 420 )
-
-             ENDIF
-
              IF ( land_surface )  THEN
 !
@@ -1568,4 +1584,57 @@
                 CALL netcdf_handle_error( 'netcdf_define_header', 86 )
              ENDIF
+
+          ENDIF
+!
+!--       In case of non-flat topography write height information. Only for
+!--       parallel netcdf output.
+          IF ( TRIM( topography ) /= 'flat'  .AND.                             &
+               netcdf_data_format > 4 )  THEN
+
+             IF ( nxr == nx  .AND.  nyn /= ny )  THEN
+                nc_stat = NF90_PUT_VAR( id_set_3d(av), id_var_zusi_3d(av),     &
+                                        zu_s_inner(nxl:nxr+1,nys:nyn),         &
+                                        start = (/ nxl+1, nys+1 /),            &
+                                        count = (/ nxr-nxl+2, nyn-nys+1 /) )
+             ELSEIF ( nxr /= nx  .AND.  nyn == ny )  THEN
+                nc_stat = NF90_PUT_VAR( id_set_3d(av), id_var_zusi_3d(av),     &
+                                        zu_s_inner(nxl:nxr,nys:nyn+1),         &
+                                        start = (/ nxl+1, nys+1 /),            &
+                                        count = (/ nxr-nxl+1, nyn-nys+2 /) )
+             ELSEIF ( nxr == nx  .AND.  nyn == ny )  THEN
+                nc_stat = NF90_PUT_VAR( id_set_3d(av), id_var_zusi_3d(av),     &
+                                        zu_s_inner(nxl:nxr+1,nys:nyn+1),       &
+                                        start = (/ nxl+1, nys+1 /),            &
+                                        count = (/ nxr-nxl+2, nyn-nys+2 /) )
+             ELSE
+                nc_stat = NF90_PUT_VAR( id_set_3d(av), id_var_zusi_3d(av),     &
+                                        zu_s_inner(nxl:nxr,nys:nyn),           &
+                                        start = (/ nxl+1, nys+1 /),            &
+                                        count = (/ nxr-nxl+1, nyn-nys+1 /) )
+             ENDIF
+             CALL netcdf_handle_error( 'netcdf_define_header', 419 )
+
+             IF ( nxr == nx  .AND.  nyn /= ny )  THEN
+                nc_stat = NF90_PUT_VAR( id_set_3d(av), id_var_zwwi_3d(av),     &
+                                        zw_w_inner(nxl:nxr+1,nys:nyn),         &
+                                        start = (/ nxl+1, nys+1 /),            &
+                                        count = (/ nxr-nxl+2, nyn-nys+1 /) )
+             ELSEIF ( nxr /= nx  .AND.  nyn == ny )  THEN
+                nc_stat = NF90_PUT_VAR( id_set_3d(av), id_var_zwwi_3d(av),     &
+                                        zw_w_inner(nxl:nxr,nys:nyn+1),         &
+                                        start = (/ nxl+1, nys+1 /),            &
+                                        count = (/ nxr-nxl+1, nyn-nys+2 /) )
+             ELSEIF ( nxr == nx  .AND.  nyn == ny )  THEN
+                nc_stat = NF90_PUT_VAR( id_set_3d(av), id_var_zwwi_3d(av),     &
+                                        zw_w_inner(nxl:nxr+1,nys:nyn+1),       &
+                                        start = (/ nxl+1, nys+1 /),            &
+                                        count = (/ nxr-nxl+2, nyn-nys+2 /) )
+             ELSE
+                nc_stat = NF90_PUT_VAR( id_set_3d(av), id_var_zwwi_3d(av),     &
+                                        zw_w_inner(nxl:nxr,nys:nyn),           &
+                                        start = (/ nxl+1, nys+1 /),            &
+                                        count = (/ nxr-nxl+1, nyn-nys+1 /) )
+             ENDIF
+             CALL netcdf_handle_error( 'netcdf_define_header', 420 )
 
           ENDIF
@@ -1841,6 +1910,6 @@
           IF ( land_surface )  THEN
 
-             ns_do = 0
-             DO WHILE ( section(ns_do+1,1) < nzs )
+             ns_do = 1
+             DO WHILE ( section(ns_do,1) /= -9999  .AND.  ns <= nzs )
                 ns_do = ns_do + 1
              ENDDO
@@ -1900,6 +1969,7 @@
 !
 !--       In case of non-flat topography define 2d-arrays containing the height
-!--       information
-          IF ( TRIM( topography ) /= 'flat' )  THEN
+!--       information. Only for parallel netcdf output.
+          IF ( TRIM( topography ) /= 'flat'  .AND.                             &
+               netcdf_data_format > 4  )  THEN
 !
 !--          Define zusi = zu(nzb_s_inner)
@@ -2211,23 +2281,57 @@
              DEALLOCATE( netcdf_data )
 
-!
-!--          In case of non-flat topography write height information
-             IF ( TRIM( topography ) /= 'flat' )  THEN
-
-                nc_stat = NF90_PUT_VAR( id_set_xy(av), id_var_zusi_xy(av), &
-                                        zu_s_inner(0:nx+1,0:ny+1), &
-                                        start = (/ 1, 1 /), &
-                                        count = (/ nx+2, ny+2 /) )
-                CALL netcdf_handle_error( 'netcdf_define_header', 427 )
-
-                nc_stat = NF90_PUT_VAR( id_set_xy(av), id_var_zwwi_xy(av), &
-                                        zw_w_inner(0:nx+1,0:ny+1), &
-                                        start = (/ 1, 1 /), &
-                                        count = (/ nx+2, ny+2 /) )
-                CALL netcdf_handle_error( 'netcdf_define_header', 428 )
-
+          ENDIF
+
+!
+!--       In case of non-flat topography write height information. Only for 
+!--       parallel netcdf output.
+          IF ( TRIM( topography ) /= 'flat'  .AND.                             &
+               netcdf_data_format > 4  )  THEN
+
+             IF ( nxr == nx  .AND.  nyn /= ny )  THEN
+                nc_stat = NF90_PUT_VAR( id_set_xy(av), id_var_zusi_xy(av),     &
+                                        zu_s_inner(nxl:nxr+1,nys:nyn),         &
+                                        start = (/ nxl+1, nys+1 /),            &
+                                        count = (/ nxr-nxl+2, nyn-nys+1 /) )
+             ELSEIF ( nxr /= nx  .AND.  nyn == ny )  THEN
+                nc_stat = NF90_PUT_VAR( id_set_xy(av), id_var_zusi_xy(av),     &
+                                        zu_s_inner(nxl:nxr,nys:nyn+1),         &
+                                        start = (/ nxl+1, nys+1 /),            &
+                                        count = (/ nxr-nxl+1, nyn-nys+2 /) )
+             ELSEIF ( nxr == nx  .AND.  nyn == ny )  THEN
+                nc_stat = NF90_PUT_VAR( id_set_xy(av), id_var_zusi_xy(av),     &
+                                        zu_s_inner(nxl:nxr+1,nys:nyn+1),       &
+                                        start = (/ nxl+1, nys+1 /),            &
+                                        count = (/ nxr-nxl+2, nyn-nys+2 /) )
+             ELSE
+                nc_stat = NF90_PUT_VAR( id_set_xy(av), id_var_zusi_xy(av),     &
+                                        zu_s_inner(nxl:nxr,nys:nyn),           &
+                                        start = (/ nxl+1, nys+1 /),            &
+                                        count = (/ nxr-nxl+1, nyn-nys+1 /) )
              ENDIF
-
-
+             CALL netcdf_handle_error( 'netcdf_define_header', 427 )
+
+             IF ( nxr == nx  .AND.  nyn /= ny )  THEN
+                nc_stat = NF90_PUT_VAR( id_set_xy(av), id_var_zwwi_xy(av),     &
+                                        zw_w_inner(nxl:nxr+1,nys:nyn),         &
+                                        start = (/ nxl+1, nys+1 /),            &
+                                        count = (/ nxr-nxl+2, nyn-nys+1 /) )
+             ELSEIF ( nxr /= nx  .AND.  nyn == ny )  THEN
+                nc_stat = NF90_PUT_VAR( id_set_xy(av), id_var_zwwi_xy(av),     &
+                                        zw_w_inner(nxl:nxr,nys:nyn+1),         &
+                                        start = (/ nxl+1, nys+1 /),            &
+                                        count = (/ nxr-nxl+1, nyn-nys+2 /) )
+             ELSEIF ( nxr == nx  .AND.  nyn == ny )  THEN
+                nc_stat = NF90_PUT_VAR( id_set_xy(av), id_var_zwwi_xy(av),     &
+                                        zw_w_inner(nxl:nxr+1,nys:nyn+1),       &
+                                        start = (/ nxl+1, nys+1 /),            &
+                                        count = (/ nxr-nxl+2, nyn-nys+2 /) )
+             ELSE
+                nc_stat = NF90_PUT_VAR( id_set_xy(av), id_var_zwwi_xy(av),     &
+                                        zw_w_inner(nxl:nxr,nys:nyn),           &
+                                        start = (/ nxl+1, nys+1 /),            &
+                                        count = (/ nxr-nxl+1, nyn-nys+1 /) )
+             ENDIF
+             CALL netcdf_handle_error( 'netcdf_define_header', 428 )
 
           ENDIF
@@ -5337,4 +5441,173 @@
 ! Description:
 ! ------------
+!> Closes an existing netCDF file.
+!------------------------------------------------------------------------------!
+ 
+ SUBROUTINE netcdf_close_file( id, errno )
+#if defined( __netcdf )
+
+    USE pegrid
+
+    IMPLICIT NONE
+
+    INTEGER(iwp), INTENT(IN)           ::  errno     !< error number
+    INTEGER(iwp), INTENT(INOUT)        ::  id        !< file id
+
+    nc_stat = NF90_CLOSE( id )
+    CALL netcdf_handle_error( 'netcdf_close', errno )
+#endif
+ END SUBROUTINE netcdf_close_file
+
+!------------------------------------------------------------------------------!
+! Description:
+! ------------
+!> Opens an existing netCDF file for reading only and gives back the id.
+!------------------------------------------------------------------------------!
+ 
+ SUBROUTINE netcdf_open_read_file( filename, id, errno )
+#if defined( __netcdf )
+
+    USE pegrid
+
+    IMPLICIT NONE
+
+    CHARACTER (LEN=*), INTENT(IN) ::  filename  !< filename
+    INTEGER(iwp), INTENT(IN)      ::  errno     !< error number
+    INTEGER(iwp), INTENT(INOUT)   ::  id        !< file id
+    LOGICAL                       ::  file_open = .FALSE.
+
+    nc_stat = NF90_OPEN( filename, NF90_NOWRITE, id )
+
+    CALL netcdf_handle_error( 'netcdf_open_read_file', errno )
+
+#endif
+ END SUBROUTINE netcdf_open_read_file
+
+!------------------------------------------------------------------------------!
+! Description:
+! ------------
+!> Reads the global attributes of a file
+!------------------------------------------------------------------------------!
+ 
+ SUBROUTINE netcdf_get_attribute( id, attribute_name, value, global, errno, variable_name )
+#if defined( __netcdf )
+
+    USE pegrid
+
+    IMPLICIT NONE
+
+    CHARACTER(LEN=*)            ::  attribute_name   !< attribute name
+    CHARACTER(LEN=*), OPTIONAL  ::  variable_name    !< variable name 
+
+    INTEGER(iwp), INTENT(IN)    ::  errno            !< error number
+    INTEGER(iwp), INTENT(INOUT) ::  id               !< file id
+    INTEGER(iwp), INTENT(INOUT) ::  value            !< read value
+
+    INTEGER(iwp)                ::  id_var           !< variable id
+
+    LOGICAL, INTENT(IN) ::  global                   !< flag indicating global attributes
+
+!
+!-- Read global attribute
+    IF ( global )  THEN
+       nc_stat = NF90_GET_ATT( id, NF90_GLOBAL, TRIM( attribute_name ), value )
+       CALL netcdf_handle_error( 'netcdf_get_attribute global', errno )
+!
+!-- Read attributes referring to a single variable. Therefore, first inquire 
+!-- variable id
+    ELSE
+       nc_stat = NF90_INQ_VARID( id, TRIM( variable_name ), id_var )
+       CALL netcdf_handle_error( 'netcdf_get_attribute', errno )
+       nc_stat = NF90_GET_ATT( id, id_var, TRIM( attribute_name ), value )
+       CALL netcdf_handle_error( 'netcdf_get_attribute', errno )       
+    ENDIF
+#endif
+ END SUBROUTINE netcdf_get_attribute
+
+!------------------------------------------------------------------------------!
+! Description:
+! ------------
+!> Reads a 2D REAL variable of a file. Reading is done processor-wise, 
+!> i.e. each core reads its own domain, as well as in slices along x. 
+!------------------------------------------------------------------------------!
+ 
+ SUBROUTINE netcdf_get_variable_2d( id, variable_name, i, var, errno )
+#if defined( __netcdf )
+
+    USE indices
+    USE pegrid
+
+    IMPLICIT NONE
+
+    CHARACTER(LEN=*)              ::  variable_name   !< attribute name
+    INTEGER(iwp), INTENT(IN)      ::  errno           !< error number
+    INTEGER(iwp), INTENT(IN)      ::  i               !< index along x direction
+
+    INTEGER(iwp), INTENT(INOUT)   ::  id              !< file id
+
+    INTEGER(iwp)                  ::  id_var          !< variable id
+
+    REAL(wp), DIMENSION(nys:nyn), INTENT(INOUT) ::  var  !< variable to be read
+    REAL(wp) :: var_dum
+!
+!-- Inquire variable id
+    nc_stat = NF90_INQ_VARID( id, TRIM( variable_name ), id_var )
+!
+!-- Get variable
+    nc_stat = NF90_GET_VAR( id, id_var, var(nys:nyn),                        &
+                            start = (/ i+1, nys+1 /),                          &
+                            count = (/ 1, nyn - nys + 1 /) )
+
+    CALL netcdf_handle_error( 'netcdf_get_variable', errno )
+#endif
+ END SUBROUTINE netcdf_get_variable_2d
+
+!------------------------------------------------------------------------------!
+! Description:
+! ------------
+!> Reads a 3D INTEGER variable of a file. Reading is done processor-wise, 
+!> i.e. each core reads its own domain, as well as in slices along x. 
+!------------------------------------------------------------------------------!
+ 
+ SUBROUTINE netcdf_get_variable_3d( id, variable_name, i, j, var, errno )
+#if defined( __netcdf )
+
+    USE indices
+    USE pegrid
+
+    IMPLICIT NONE
+
+    CHARACTER(LEN=*)              ::  variable_name   !< attribute name
+    INTEGER(iwp), INTENT(IN)      ::  errno           !< error number
+    INTEGER(iwp), INTENT(IN)      ::  i               !< index along x direction
+    INTEGER(iwp), INTENT(IN)      ::  j               !< index along y direction
+
+    INTEGER(iwp), INTENT(INOUT)   ::  id              !< file id
+
+    INTEGER(iwp)                  ::  id_var          !< variable id
+    INTEGER(iwp)                  ::  id_z            !< id of z-dimension
+    INTEGER(iwp)                  ::  nz_file         !< number of grid-points in file
+
+    INTEGER(iwp), DIMENSION(nzb:nzt+1), INTENT(INOUT) ::  var  !< variable to be read
+!
+!-- Get dimension of z-axis
+    nc_stat = NF90_INQ_DIMID( id, "z", id_z )
+    nc_stat = NF90_INQUIRE_DIMENSION( id, id_z, len = nz_file )
+!
+!-- Inquire variable id
+    nc_stat = NF90_INQ_VARID( id, TRIM( variable_name ), id_var )
+!
+!-- Get variable
+    nc_stat = NF90_GET_VAR( id, id_var, var(0:nz_file-1),                  &
+                            start = (/ i+1, j+1, 1 /),                         &
+                            count = (/ 1, 1, nz_file /) )
+
+    CALL netcdf_handle_error( 'netcdf_get_variable', errno )
+#endif
+ END SUBROUTINE netcdf_get_variable_3d
+
+!------------------------------------------------------------------------------!
+! Description:
+! ------------
 !> Opens an existing netCDF file for writing and gives back the id.
 !> The parallel flag has to be TRUE for parallel netCDF output support.
Index: /palm/trunk/SOURCE/nudging_mod.f90
===================================================================
--- /palm/trunk/SOURCE/nudging_mod.f90	(revision 2231)
+++ /palm/trunk/SOURCE/nudging_mod.f90	(revision 2232)
@@ -20,5 +20,5 @@
 ! Current revisions:
 ! ------------------
-! 
+! Adjustments to new topography concept
 ! 
 ! Former revisions:
@@ -332,5 +332,5 @@
 
        USE indices,                                                            &
-           ONLY:  nxl, nxr, nys, nyn, nzb, nzb_u_inner, nzt
+           ONLY:  nxl, nxr, nys, nyn, nzb, nzt, wall_flags_0
 
        USE kinds
@@ -372,10 +372,12 @@
                 DO  j = nys, nyn
 
-                   DO  k = nzb_u_inner(j,i)+1, nzt
+                   DO  k = nzb+1, nzt
 
                       tmp_tend = - ( hom(k,1,1,0) - ( unudge(k,nt) * dtp +     &
                                      unudge(k,nt+1) * dtm ) ) / tmp_tnudge(k)
 
-                      tend(k,j,i) = tend(k,j,i) + tmp_tend
+                      tend(k,j,i) = tend(k,j,i) + tmp_tend *                   &
+                                        MERGE( 1.0_wp, 0.0_wp,                 &
+                                               BTEST( wall_flags_0(k,j,i), 1 ) )
 
                       sums_ls_l(k,6) = sums_ls_l(k,6) + tmp_tend *             &
@@ -393,10 +395,12 @@
                 DO  j = nys, nyn
 
-                   DO  k = nzb_u_inner(j,i)+1, nzt
+                   DO  k = nzb+1, nzt
 
                       tmp_tend = - ( hom(k,1,2,0) - ( vnudge(k,nt) * dtp +     &
                                      vnudge(k,nt+1) * dtm ) ) / tmp_tnudge(k)
 
-                      tend(k,j,i) = tend(k,j,i) + tmp_tend
+                      tend(k,j,i) = tend(k,j,i) + tmp_tend *                   &
+                                        MERGE( 1.0_wp, 0.0_wp,                 &
+                                               BTEST( wall_flags_0(k,j,i), 2 ) )
 
                       sums_ls_l(k,7) = sums_ls_l(k,7) + tmp_tend *             &
@@ -414,10 +418,12 @@
                 DO  j = nys, nyn
 
-                   DO  k = nzb_u_inner(j,i)+1, nzt
+                   DO  k = nzb+1, nzt
 
                       tmp_tend = - ( hom(k,1,4,0) - ( ptnudge(k,nt) * dtp +    &
                                      ptnudge(k,nt+1) * dtm ) ) / tmp_tnudge(k)
 
-                      tend(k,j,i) = tend(k,j,i) + tmp_tend
+                      tend(k,j,i) = tend(k,j,i) + tmp_tend *                   &
+                                        MERGE( 1.0_wp, 0.0_wp,                 &
+                                               BTEST( wall_flags_0(k,j,i), 0 ) )
 
                       sums_ls_l(k,4) = sums_ls_l(k,4) + tmp_tend *             &
@@ -435,10 +441,12 @@
                 DO  j = nys, nyn
 
-                   DO  k = nzb_u_inner(j,i)+1, nzt
+                   DO  k = nzb+1, nzt
 
                       tmp_tend = - ( hom(k,1,41,0) - ( qnudge(k,nt) * dtp +    &
                                      qnudge(k,nt+1) * dtm ) ) / tmp_tnudge(k)
 
-                      tend(k,j,i) = tend(k,j,i) + tmp_tend
+                      tend(k,j,i) = tend(k,j,i) + tmp_tend *                   &
+                                        MERGE( 1.0_wp, 0.0_wp,                 &
+                                               BTEST( wall_flags_0(k,j,i), 0 ) )
 
                       sums_ls_l(k,5) = sums_ls_l(k,5) + tmp_tend *             &
@@ -476,5 +484,5 @@
 
        USE indices,                                                            &
-           ONLY:  nxl, nxr, nys, nyn, nzb, nzb_u_inner, nzt
+           ONLY:  nxl, nxr, nys, nyn, nzb, nzt, wall_flags_0
 
        USE kinds
@@ -514,10 +522,12 @@
           CASE ( 'u' )
 
-             DO  k = nzb_u_inner(j,i)+1, nzt
+             DO  k = nzb+1, nzt
 
                 tmp_tend = - ( hom(k,1,1,0) - ( unudge(k,nt) * dtp +           &
                                unudge(k,nt+1) * dtm ) ) / tmp_tnudge(k)
 
-                tend(k,j,i) = tend(k,j,i) + tmp_tend
+                tend(k,j,i) = tend(k,j,i) + tmp_tend *                         &
+                                        MERGE( 1.0_wp, 0.0_wp,                 &
+                                               BTEST( wall_flags_0(k,j,i), 1 ) )
 
                 sums_ls_l(k,6) = sums_ls_l(k,6) + tmp_tend                     &
@@ -529,10 +539,12 @@
           CASE ( 'v' )
 
-             DO  k = nzb_u_inner(j,i)+1, nzt
+             DO  k = nzb+1, nzt
 
                 tmp_tend = - ( hom(k,1,2,0) - ( vnudge(k,nt) * dtp +           &
                                vnudge(k,nt+1) * dtm ) ) / tmp_tnudge(k)
 
-                tend(k,j,i) = tend(k,j,i) + tmp_tend
+                tend(k,j,i) = tend(k,j,i) + tmp_tend *                         &
+                                        MERGE( 1.0_wp, 0.0_wp,                 &
+                                               BTEST( wall_flags_0(k,j,i), 2 ) )
 
                 sums_ls_l(k,7) = sums_ls_l(k,7) + tmp_tend                     &
@@ -544,10 +556,12 @@
           CASE ( 'pt' )
 
-             DO  k = nzb_u_inner(j,i)+1, nzt
+             DO  k = nzb+1, nzt
 
                 tmp_tend = - ( hom(k,1,4,0) - ( ptnudge(k,nt) * dtp +          &
                                ptnudge(k,nt+1) * dtm ) ) / tmp_tnudge(k)
 
-                tend(k,j,i) = tend(k,j,i) + tmp_tend
+                tend(k,j,i) = tend(k,j,i) + tmp_tend *                         &
+                                        MERGE( 1.0_wp, 0.0_wp,                 &
+                                               BTEST( wall_flags_0(k,j,i), 0 ) )
 
                 sums_ls_l(k,4) = sums_ls_l(k,4) + tmp_tend                     &
@@ -560,10 +574,12 @@
           CASE ( 'q' )
 
-             DO  k = nzb_u_inner(j,i)+1, nzt
+             DO  k = nzb+1, nzt
 
                 tmp_tend = - ( hom(k,1,41,0) - ( qnudge(k,nt) * dtp +          &
                                qnudge(k,nt+1) * dtm ) ) / tmp_tnudge(k)
 
-                tend(k,j,i) = tend(k,j,i) + tmp_tend
+                tend(k,j,i) = tend(k,j,i) + tmp_tend *                         &
+                                        MERGE( 1.0_wp, 0.0_wp,                 &
+                                               BTEST( wall_flags_0(k,j,i), 0 ) )
 
                 sums_ls_l(k,5) = sums_ls_l(k,5) + tmp_tend                     &
Index: /palm/trunk/SOURCE/palm.f90
===================================================================
--- /palm/trunk/SOURCE/palm.f90	(revision 2231)
+++ /palm/trunk/SOURCE/palm.f90	(revision 2232)
@@ -20,5 +20,8 @@
 ! Current revisions:
 ! -----------------
-! 
+! Renamed wall_flags_0 and wall_flags_00 into advc_flags_1 and advc_flags_2, 
+! respectively, within copyin statement. Moreover, introduced further flag 
+! array wall_flags_0. 
+! Remove unused variables from ONLY list.
 ! 
 ! Former revisions:
@@ -165,7 +168,8 @@
 
     USE control_parameters,                                                    &
+
         ONLY:  cloud_physics, constant_diffusion, coupling_char, coupling_mode,&
                do2d_at_begin, do3d_at_begin, humidity, initializing_actions,   &
-               io_blocks, io_group,                                            &
+               land_surface, io_blocks, io_group,                              &
                large_scale_forcing, message_string, microphysics_seifert,      &
                nest_domain, neutral,                                           &
@@ -179,19 +183,11 @@
         ONLY:  cpu_log, log_point, cpu_statistics
 
-    USE grid_variables,                                                        &
-        ONLY:  fxm, fxp, fym, fyp, fwxm, fwxp, fwym, fwyp, wall_e_x, wall_e_y, &
-               wall_u, wall_v, wall_w_x, wall_w_y
-
     USE indices,                                                               &
-        ONLY:  nbgp, ngp_2dh, ngp_2dh_s_inner, nzb_diff_s_inner, nzb_diff_s_outer,   &
-               nzb_diff_u, nzb_diff_v, nzb_s_inner, nzb_s_outer, nzb_u_inner,  &
-               nzb_u_outer, nzb_v_inner, nzb_v_outer, nzb_w_inner,             &
-               nzb_w_outer, rflags_invers, rflags_s_inner, wall_flags_0,       &
-               wall_flags_00
+        ONLY:  nbgp
 
     USE kinds
 
     USE land_surface_model_mod,                                                &
-        ONLY:  land_surface, lsm_last_actions
+        ONLY:  lsm_last_actions
 
     USE ls_forcing_mod,                                                        &
@@ -213,11 +209,5 @@
     USE radiation_model_mod,                                                   &
         ONLY:  radiation, radiation_last_actions
-
-    USE statistics,                                                            &
-        ONLY:  hom, rmask, weight_pres, weight_substep
-
-    USE surface_layer_fluxes_mod,                                              &
-        ONLY:  pt1, qv1, uv_total
-        
+       
     USE urban_surface_mod,                                                     &
         ONLY:  usm_write_restart_data        
Index: /palm/trunk/SOURCE/parin.f90
===================================================================
--- /palm/trunk/SOURCE/parin.f90	(revision 2231)
+++ /palm/trunk/SOURCE/parin.f90	(revision 2232)
@@ -20,5 +20,8 @@
 ! Current revisions:
 ! -----------------
-! 
+! typo corrected
+! +wall_salinityflux
+! +tunnel_height, tunnel_lenght, tunnel_width_x, tunnel_width_y, 
+!  tunnel_wall_depth
 ! 
 ! Former revisions:
@@ -373,6 +376,8 @@
              topography, topography_grid_convention, top_heatflux,             &
              top_momentumflux_u, top_momentumflux_v, top_salinityflux,         &
-             top_scalarflux, transpose_compute_overlap, turbulent_inflow,      &
-             turbulent_outflow,                                                &
+             top_scalarflux, transpose_compute_overlap,                        &
+             tunnel_height, tunnel_length, tunnel_width_x, tunnel_width_y,     &
+             tunnel_wall_depth,                                                &
+             turbulent_inflow, turbulent_outflow,                              &
              use_subsidence_tendencies, ug_surface, ug_vertical_gradient,      &
              ug_vertical_gradient_level, use_surface_fluxes, use_cmax,         &
@@ -381,5 +386,5 @@
              vg_vertical_gradient_level, v_bulk, v_profile, ventilation_effect,&
              wall_adjustment, wall_heatflux, wall_humidityflux,                &
-             wall_scalarflux, zeta_max, zeta_min, z0h_factor
+             wall_salinityflux, wall_scalarflux, zeta_max, zeta_min, z0h_factor
       
     NAMELIST /d3par/  averaging_interval, averaging_interval_pr,               &
@@ -594,5 +599,5 @@
           CALL wtm_parin
 !
-!--       Check if virtual flights should be carried out and read &flight_part
+!--       Check if virtual flights should be carried out and read &flight_par
 !--       if required
           CALL flight_parin
Index: /palm/trunk/SOURCE/plant_canopy_model_mod.f90
===================================================================
--- /palm/trunk/SOURCE/plant_canopy_model_mod.f90	(revision 2231)
+++ /palm/trunk/SOURCE/plant_canopy_model_mod.f90	(revision 2232)
@@ -20,5 +20,5 @@
 ! Current revisions:
 ! -----------------
-! 
+! Adjustments to new topography concept
 ! 
 ! Former revisions:
@@ -118,9 +118,9 @@
  
     USE arrays_3d,                                                             &
-        ONLY:  dzu, dzw, e, q, s, shf, tend, u, v, w, zu, zw 
+        ONLY:  dzu, dzw, e, q, s, tend, u, v, w, zu, zw 
 
     USE indices,                                                               &
         ONLY:  nbgp, nxl, nxlg, nxlu, nxr, nxrg, nyn, nyng, nys, nysg, nysv,   &
-               nz, nzb, nzb_s_inner, nzb_u_inner, nzb_v_inner, nzb_w_inner, nzt
+               nz, nzb, nzb_max, nzt, wall_flags_0
 
     USE kinds
@@ -549,8 +549,8 @@
        USE control_parameters,                                                 &
            ONLY:  coupling_char, dz, humidity, io_blocks, io_group,            &
-                  message_string, ocean, passive_scalar 
-
-       USE control_parameters,                                                 &
-           ONLY:  urban_surface
+                  message_string, ocean, passive_scalar, urban_surface
+
+       USE surface_mod,                                                        &
+           ONLY: surf_def_h, surf_lsm_h, surf_usm_h
 
        IMPLICIT NONE
@@ -562,4 +562,5 @@
        INTEGER(iwp) ::  j   !< running index
        INTEGER(iwp) ::  k   !< running index
+       INTEGER(iwp) ::  m   !< running index
 
        REAL(wp) ::  int_bpdf        !< vertical integral for lad-profile construction
@@ -639,5 +640,5 @@
           canopy_height = pch_index * dz
 
-          DO k = nzb, pch_index
+          DO k = 0, pch_index
              int_bpdf = int_bpdf +                                             &
                       ( ( ( zw(k) / canopy_height )**( alpha_lad-1.0_wp ) ) *  &
@@ -649,5 +650,5 @@
 !
 !--       Preliminary lad profile (defined on w-grid)
-          DO k = nzb, pch_index
+          DO k = 0, pch_index
              pre_lad(k) =  lai_beta *                                          &
                         ( ( ( zw(k) / canopy_height )**( alpha_lad-1.0_wp ) )  &
@@ -662,5 +663,5 @@
 !--       when calculating the canopy tendencies)
           lad(0) = pre_lad(0)
-          DO k = nzb+1, pch_index
+          DO k = 1, pch_index
              lad(k) = 0.5 * ( pre_lad(k-1) + pre_lad(k) )
           ENDDO          
@@ -761,27 +762,45 @@
           ENDDO
 
+!            
+!--       In areas with canopy the surface value of the canopy heat 
+!--       flux distribution overrides the surface heat flux (shf) 
+!--       Start with default surface type
+          DO  m = 1, surf_def_h(0)%ns
+             k = surf_def_h(0)%k(m)
+             IF ( cum_lai_hf(0,j,i) /= 0.0_wp )                                &
+                surf_def_h(0)%shf(m) = cthf * exp( -ext_coef * cum_lai_hf(0,j,i) )
+          ENDDO
+!
+!--       Natural surfaces
+          DO  m = 1, surf_lsm_h%ns
+             k = surf_lsm_h%k(m)
+             IF ( cum_lai_hf(0,j,i) /= 0.0_wp )                                &
+                surf_lsm_h%shf(m) = cthf * exp( -ext_coef * cum_lai_hf(0,j,i) )
+          ENDDO
+!
+!--       Urban surfaces
+          DO  m = 1, surf_usm_h%ns
+             k = surf_usm_h%k(m)
+             IF ( cum_lai_hf(0,j,i) /= 0.0_wp )                                &
+                surf_usm_h%shf(m) = cthf * exp( -ext_coef * cum_lai_hf(0,j,i) )
+          ENDDO
+!
 !
 !--       Calculation of the heating rate (K/s) within the different layers of 
-!--       the plant canopy
+!--       the plant canopy. Calculation is only necessary in areas covered with
+!--       canopy. 
+!--       Within the different canopy layers the plant-canopy heating
+!--       rate (pc_heating_rate) is calculated as the vertical 
+!--       divergence of the canopy heat fluxes at the top and bottom
+!--       of the respective layer
           DO  i = nxlg, nxrg
              DO  j = nysg, nyng
-!
-!--             Calculation only necessary in areas covered with canopy
-                IF ( cum_lai_hf(0,j,i) /= 0.0_wp )  THEN
-!--             
-!--                In areas with canopy the surface value of the canopy heat 
-!--                flux distribution overrides the surface heat flux (shf) 
-                   shf(j,i) = cthf * exp( -ext_coef * cum_lai_hf(0,j,i) )
-!
-!--                Within the different canopy layers the plant-canopy heating
-!--                rate (pc_heating_rate) is calculated as the vertical 
-!--                divergence of the canopy heat fluxes at the top and bottom
-!--                of the respective layer
-                   DO  k = 1, pch_index
-                      pc_heating_rate(k,j,i) = cthf *                         &
-                                                ( exp(-ext_coef*cum_lai_hf(k,j,i)) -  &
-                                                  exp(-ext_coef*cum_lai_hf(k-1,j,i)) ) / dzw(k)
-                   ENDDO
-                ENDIF
+                DO  k = 1, pch_index
+                   IF ( cum_lai_hf(0,j,i) /= 0.0_wp )  THEN
+                      pc_heating_rate(k,j,i) = cthf *                             &
+                                ( exp(-ext_coef*cum_lai_hf(k,j,i)) -              &
+                                  exp(-ext_coef*cum_lai_hf(k-1,j,i) ) ) / dzw(k)
+                   ENDIF
+                ENDDO
              ENDDO
           ENDDO
@@ -966,4 +985,5 @@
        INTEGER(iwp) ::  j         !< running index
        INTEGER(iwp) ::  k         !< running index
+       INTEGER(iwp) ::  k_wall    !< vertical index of topography top
        INTEGER(iwp) ::  kk        !< running index for flat lad arrays
 
@@ -987,7 +1007,14 @@
              DO  i = nxlu, nxr
                 DO  j = nys, nyn
-                   DO  k = nzb_u_inner(j,i)+1, nzb_u_inner(j,i)+pch_index
-
-                      kk = k - nzb_u_inner(j,i)  !- lad arrays are defined flat
+!
+!--                Determine topography-top index on u-grid
+                   k_wall = MAXLOC(                                            &
+                          MERGE( 1, 0,                                         &
+                                 BTEST( wall_flags_0(nzb:nzb_max,j,i), 14 )    &
+                               ), DIM = 1                                      &
+                                  ) - 1
+                   DO  k = k_wall+1, k_wall+pch_index
+
+                      kk = k - k_wall   !- lad arrays are defined flat
 !
 !--                   In order to create sharp boundaries of the plant canopy, 
@@ -1048,7 +1075,14 @@
              DO  i = nxl, nxr
                 DO  j = nysv, nyn
-                   DO  k = nzb_v_inner(j,i)+1, nzb_v_inner(j,i)+pch_index
-
-                      kk = k - nzb_v_inner(j,i)  !- lad arrays are defined flat
+!
+!--                Determine topography-top index on v-grid
+                   k_wall = MAXLOC(                                            &
+                          MERGE( 1, 0,                                         &
+                                 BTEST( wall_flags_0(nzb:nzb_max,j,i), 16 )    &
+                               ), DIM = 1                                      &
+                                  ) - 1
+                   DO  k = k_wall+1, k_wall+pch_index
+
+                      kk = k - k_wall   !- lad arrays are defined flat
 !
 !--                   In order to create sharp boundaries of the plant canopy, 
@@ -1109,7 +1143,14 @@
              DO  i = nxl, nxr
                 DO  j = nys, nyn
-                   DO  k = nzb_w_inner(j,i)+1, nzb_w_inner(j,i)+pch_index-1
-
-                      kk = k - nzb_w_inner(j,i)  !- lad arrays are defined flat
+!
+!--                Determine topography-top index on w-grid
+                   k_wall = MAXLOC(                                            &
+                          MERGE( 1, 0,                                         &
+                                 BTEST( wall_flags_0(nzb:nzb_max,j,i), 18 )    &
+                               ), DIM = 1                                      &
+                                  ) - 1
+                   DO  k = k_wall+1, k_wall+pch_index-1
+
+                      kk = k - k_wall   !- lad arrays are defined flat
 
                       pre_tend = 0.0_wp
@@ -1157,6 +1198,14 @@
              DO  i = nxl, nxr
                 DO  j = nys, nyn
-                   DO  k = nzb_s_inner(j,i)+1, nzb_s_inner(j,i)+pch_index
-                      kk = k - nzb_s_inner(j,i)  !- lad arrays are defined flat
+!
+!--                Determine topography-top index on scalar-grid
+                   k_wall = MAXLOC(                                            &
+                          MERGE( 1, 0,                                         &
+                                 BTEST( wall_flags_0(nzb:nzb_max,j,i), 12 )    &
+                               ), DIM = 1                                      &
+                                  ) - 1
+                   DO  k = k_wall+1, k_wall+pch_index
+
+                      kk = k - k_wall   !- lad arrays are defined flat
                       tend(k,j,i) = tend(k,j,i) + pc_heating_rate(kk,j,i)
                    ENDDO
@@ -1169,6 +1218,14 @@
              DO  i = nxl, nxr
                 DO  j = nys, nyn
-                   DO  k = nzb_s_inner(j,i)+1, nzb_s_inner(j,i)+pch_index
-                      kk = k - nzb_s_inner(j,i)  !- lad arrays are defined flat
+!
+!--                Determine topography-top index on scalar-grid
+                   k_wall = MAXLOC(                                            &
+                          MERGE( 1, 0,                                         &
+                                 BTEST( wall_flags_0(nzb:nzb_max,j,i), 12 )    &
+                               ), DIM = 1                                      &
+                                  ) - 1
+                   DO  k = k_wall+1, k_wall+pch_index
+
+                      kk = k - k_wall   !- lad arrays are defined flat
                       tend(k,j,i) = tend(k,j,i) -                              &
                                        lsec *                                  &
@@ -1194,6 +1251,14 @@
              DO  i = nxl, nxr
                 DO  j = nys, nyn
-                   DO  k = nzb_s_inner(j,i)+1, nzb_s_inner(j,i)+pch_index
-                      kk = k - nzb_s_inner(j,i)  !- lad arrays are defined flat
+!
+!--                Determine topography-top index on scalar-grid
+                   k_wall = MAXLOC(                                            &
+                          MERGE( 1, 0,                                         &
+                                 BTEST( wall_flags_0(nzb:nzb_max,j,i), 12 )    &
+                               ), DIM = 1                                      &
+                                  ) - 1
+                   DO  k = k_wall+1, k_wall+pch_index
+
+                      kk = k - k_wall   !- lad arrays are defined flat
                       tend(k,j,i) = tend(k,j,i) -                              &
                                        2.0_wp * cdc *                          &
@@ -1218,6 +1283,14 @@
              DO  i = nxl, nxr
                 DO  j = nys, nyn
-                   DO  k = nzb_s_inner(j,i)+1, nzb_s_inner(j,i)+pch_index
-                      kk = k - nzb_s_inner(j,i)  !- lad arrays are defined flat
+!
+!--                Determine topography-top index on scalar-grid
+                   k_wall = MAXLOC(                                            &
+                          MERGE( 1, 0,                                         &
+                                 BTEST( wall_flags_0(nzb:nzb_max,j,i), 12 )    &
+                               ), DIM = 1                                      &
+                                  ) - 1
+                   DO  k = k_wall+1, k_wall+pch_index
+
+                      kk = k - k_wall   !- lad arrays are defined flat
                       tend(k,j,i) = tend(k,j,i) -                              &
                                        lsec *                                  &
@@ -1288,4 +1361,5 @@
        INTEGER(iwp) ::  j         !< running index
        INTEGER(iwp) ::  k         !< running index
+       INTEGER(iwp) ::  k_wall    !< vertical index of topography top
        INTEGER(iwp) ::  kk        !< running index for flat lad arrays
 
@@ -1307,7 +1381,14 @@
 !--       u-component
           CASE ( 1 )
-             DO  k = nzb_u_inner(j,i)+1, nzb_u_inner(j,i)+pch_index
-
-                kk = k - nzb_u_inner(j,i)  !- lad arrays are defined flat
+!
+!--          Determine topography-top index on u-grid
+             k_wall = MAXLOC(                                                  &
+                          MERGE( 1, 0,                                         &
+                                 BTEST( wall_flags_0(nzb:nzb_max,j,i), 14 )    &
+                               ), DIM = 1                                      &
+                            ) - 1
+             DO  k = k_wall+1, k_wall+pch_index
+
+                kk = k - k_wall  !- lad arrays are defined flat
 !
 !--             In order to create sharp boundaries of the plant canopy, 
@@ -1363,7 +1444,14 @@
 !--       v-component
           CASE ( 2 )
-             DO  k = nzb_v_inner(j,i)+1, nzb_v_inner(j,i)+pch_index
-
-                kk = k - nzb_v_inner(j,i)  !- lad arrays are defined flat
+!
+!--          Determine topography-top index on v-grid
+             k_wall = MAXLOC(                                                  &
+                          MERGE( 1, 0,                                         &
+                                 BTEST( wall_flags_0(nzb:nzb_max,j,i), 16 )    &
+                               ), DIM = 1                                      &
+                            ) - 1
+             DO  k = k_wall+1, k_wall+pch_index
+
+                kk = k - k_wall  !- lad arrays are defined flat
 !
 !--             In order to create sharp boundaries of the plant canopy, 
@@ -1419,7 +1507,14 @@
 !--       w-component
           CASE ( 3 )
-             DO  k = nzb_w_inner(j,i)+1, nzb_w_inner(j,i)+pch_index-1
-
-                kk = k - nzb_w_inner(j,i)  !- lad arrays are defined flat
+!
+!--          Determine topography-top index on w-grid
+             k_wall = MAXLOC(                                                  &
+                          MERGE( 1, 0,                                         &
+                                 BTEST( wall_flags_0(nzb:nzb_max,j,i), 18 )    &
+                               ), DIM = 1                                      &
+                            ) - 1
+             DO  k = k_wall+1, k_wall+pch_index-1
+
+                kk = k - k_wall  !- lad arrays are defined flat
 
                 pre_tend = 0.0_wp
@@ -1462,6 +1557,13 @@
 !--       potential temperature
           CASE ( 4 )
-             DO  k = nzb_s_inner(j,i)+1, nzb_s_inner(j,i)+pch_index
-                kk = k - nzb_s_inner(j,i)  !- lad arrays are defined flat
+!
+!--          Determine topography-top index on scalar grid
+             k_wall = MAXLOC(                                                  &
+                          MERGE( 1, 0,                                         &
+                                 BTEST( wall_flags_0(nzb:nzb_max,j,i), 12 )    &
+                               ), DIM = 1                                      &
+                            ) - 1
+             DO  k = k_wall+1, k_wall+pch_index
+                kk = k - k_wall  !- lad arrays are defined flat
                 tend(k,j,i) = tend(k,j,i) + pc_heating_rate(kk,j,i)
              ENDDO
@@ -1471,6 +1573,14 @@
 !--       humidity
           CASE ( 5 )
-             DO  k = nzb_s_inner(j,i)+1, nzb_s_inner(j,i)+pch_index
-                kk = k - nzb_s_inner(j,i)  !- lad arrays are defined flat
+!
+!--          Determine topography-top index on scalar grid
+             k_wall = MAXLOC(                                                  &
+                          MERGE( 1, 0,                                         &
+                                 BTEST( wall_flags_0(nzb:nzb_max,j,i), 12 )    &
+                               ), DIM = 1                                      &
+                            ) - 1
+             DO  k = k_wall+1, k_wall+pch_index
+
+                kk = k - k_wall
                 tend(k,j,i) = tend(k,j,i) -                                    &
                                  lsec *                                        &
@@ -1492,6 +1602,14 @@
 !--       sgs-tke
           CASE ( 6 )
-             DO  k = nzb_s_inner(j,i)+1, nzb_s_inner(j,i)+pch_index
-                kk = k - nzb_s_inner(j,i)  !- lad arrays are defined flat
+!
+!--          Determine topography-top index on scalar grid
+             k_wall = MAXLOC(                                                  &
+                          MERGE( 1, 0,                                         &
+                                 BTEST( wall_flags_0(nzb:nzb_max,j,i), 12 )    &
+                               ), DIM = 1                                      &
+                            ) - 1
+             DO  k = k_wall+1, k_wall+pch_index
+
+                kk = k - k_wall
                 tend(k,j,i) = tend(k,j,i) -                                    &
                                  2.0_wp * cdc *                                &
@@ -1513,6 +1631,14 @@
 !--       scalar concentration 
           CASE ( 7 )
-             DO  k = nzb_s_inner(j,i)+1, nzb_s_inner(j,i)+pch_index
-                kk = k - nzb_s_inner(j,i)  !- lad arrays are defined flat
+!
+!--          Determine topography-top index on scalar grid
+             k_wall = MAXLOC(                                                  &
+                          MERGE( 1, 0,                                         &
+                                 BTEST( wall_flags_0(nzb:nzb_max,j,i), 12 )    &
+                               ), DIM = 1                                      &
+                            ) - 1
+             DO  k = k_wall+1, k_wall+pch_index
+
+                kk = k - k_wall
                 tend(k,j,i) = tend(k,j,i) -                                    &
                                  lsec *                                        &
Index: /palm/trunk/SOURCE/pmc_interface_mod.f90
===================================================================
--- /palm/trunk/SOURCE/pmc_interface_mod.f90	(revision 2231)
+++ /palm/trunk/SOURCE/pmc_interface_mod.f90	(revision 2232)
@@ -21,5 +21,5 @@
 ! Current revisions:
 ! ------------------
-! 
+! Adjustments to new topography concept
 ! 
 ! Former revisions:
@@ -139,10 +139,10 @@
     USE arrays_3d,                                                             &
         ONLY:  dzu, dzw, e, e_p, nr, pt, pt_p, q, q_p, qr, u, u_p, v, v_p,     &
-               w, w_p, zu, zw, z0
+               w, w_p, zu, zw
 #else
    USE arrays_3d,                                                              &
         ONLY:  dzu, dzw, e, e_p, e_1, e_2, nr, nr_2, nr_p, pt, pt_p, pt_1,     &
                pt_2, q, q_p, q_1, q_2, qr, qr_2, s, s_2, u, u_p, u_1, u_2, v,  &
-               v_p, v_1, v_2, w, w_p, w_1, w_2, zu, zw, z0
+               v_p, v_1, v_2, w, w_p, w_1, w_2, zu, zw
 #endif
 
@@ -151,5 +151,5 @@
                message_string, microphysics_seifert, nest_bound_l, nest_bound_r,&
                nest_bound_s, nest_bound_n, nest_domain, neutral, passive_scalar,& 
-               simulated_time, topography, volume_flow
+               roughness_length, simulated_time, topography, volume_flow
 
     USE cpulog,                                                                 &
@@ -161,6 +161,5 @@
     USE indices,                                                                &
         ONLY:  nbgp, nx, nxl, nxlg, nxlu, nxr, nxrg, ny, nyn, nyng, nys, nysg,  &
-               nysv, nz, nzb, nzb_s_inner, nzb_u_inner, nzb_u_outer,            &
-               nzb_v_inner, nzb_v_outer, nzb_w_inner, nzb_w_outer, nzt
+               nysv, nz, nzb, nzb_max, nzt, wall_flags_0
 
     USE kinds
@@ -201,4 +200,7 @@
 
 #endif
+
+    USE surface_mod,                                                            &
+        ONLY:  surf_def_h, surf_lsm_h, surf_usm_h
 
     IMPLICIT NONE
@@ -1310,4 +1312,5 @@
 
        INTEGER(iwp) ::  direction    !:  Wall normal index: 1=k, 2=j, 3=i.
+       INTEGER(iwp) ::  end_index    !:  End index of present surface data type
        INTEGER(iwp) ::  i            !:
        INTEGER(iwp) ::  icorr        !:
@@ -1319,13 +1322,25 @@
        INTEGER(iwp) ::  jw           !:
        INTEGER(iwp) ::  k            !:
+       INTEGER(iwp) ::  k_wall_u_ji    !:
+       INTEGER(iwp) ::  k_wall_u_ji_p  !:
+       INTEGER(iwp) ::  k_wall_u_ji_m  !:
+       INTEGER(iwp) ::  k_wall_v_ji    !:
+       INTEGER(iwp) ::  k_wall_v_ji_p  !:
+       INTEGER(iwp) ::  k_wall_v_ji_m  !:
+       INTEGER(iwp) ::  k_wall_w_ji    !:
+       INTEGER(iwp) ::  k_wall_w_ji_p  !:
+       INTEGER(iwp) ::  k_wall_w_ji_m  !:
        INTEGER(iwp) ::  kb           !:
        INTEGER(iwp) ::  kcorr        !:
        INTEGER(iwp) ::  lc           !:
+       INTEGER(iwp) ::  m            !: Running index for surface data type
        INTEGER(iwp) ::  ni           !:
        INTEGER(iwp) ::  nj           !:
        INTEGER(iwp) ::  nk           !:
        INTEGER(iwp) ::  nzt_topo_max !:
+       INTEGER(iwp) ::  start_index  !:  Start index of present surface data type
        INTEGER(iwp) ::  wall_index   !:  Index of the wall-node coordinate
 
+       REAL(wp)     ::  z0_topo      !:  roughness at vertical walls
        REAL(wp), ALLOCATABLE, DIMENSION(:) ::  lcr   !:
 
@@ -1339,6 +1354,37 @@
           DO  i = nxl-1, nxl
              DO  j = nys, nyn
-                nzt_topo_nestbc_l = MAX( nzt_topo_nestbc_l, nzb_u_inner(j,i),   &
-                                         nzb_v_inner(j,i), nzb_w_inner(j,i) )
+!
+!--             Concept need to be reconsidered for 3D-topography
+!--             Determine largest topography index on scalar grid
+                nzt_topo_nestbc_l = MAX( nzt_topo_nestbc_l,                    &
+                  MAXLOC(                                                      &
+                          MERGE( 1, 0,                                         &
+                                 BTEST( wall_flags_0(nzb:nzb_max,j,i), 12 )    &
+                               ), DIM = 1                                      &
+                        ) - 1          )
+!
+!--             Determine largest topography index on u grid
+                nzt_topo_nestbc_l = MAX( nzt_topo_nestbc_l,                    &
+                  MAXLOC(                                                      &
+                          MERGE( 1, 0,                                         &
+                                 BTEST( wall_flags_0(nzb:nzb_max,j,i), 14 )  &
+                               ), DIM = 1                                      &
+                        ) - 1          )
+!
+!--             Determine largest topography index on v grid
+                nzt_topo_nestbc_l = MAX( nzt_topo_nestbc_l,                    &
+                  MAXLOC(                                                      &
+                          MERGE( 1, 0,                                         &
+                                 BTEST( wall_flags_0(nzb:nzb_max,j,i), 16 )  &
+                               ), DIM = 1                                      &
+                        ) - 1          )
+!
+!--             Determine largest topography index on w grid
+                nzt_topo_nestbc_l = MAX( nzt_topo_nestbc_l,                    &
+                  MAXLOC(                                                      &
+                          MERGE( 1, 0,                                         &
+                                 BTEST( wall_flags_0(nzb:nzb_max,j,i), 18 )  &
+                               ), DIM = 1                                      &
+                        ) - 1          )
              ENDDO
           ENDDO
@@ -1350,6 +1396,37 @@
           i = nxr + 1
           DO  j = nys, nyn
-             nzt_topo_nestbc_r = MAX( nzt_topo_nestbc_r, nzb_u_inner(j,i),      &
-                                      nzb_v_inner(j,i), nzb_w_inner(j,i) )
+!
+!--             Concept need to be reconsidered for 3D-topography
+!--             Determine largest topography index on scalar grid
+                nzt_topo_nestbc_r = MAX( nzt_topo_nestbc_r,                    &
+                  MAXLOC(                                                      &
+                          MERGE( 1, 0,                                         &
+                                 BTEST( wall_flags_0(nzb:nzb_max,j,i), 12 )  &
+                               ), DIM = 1                                      &
+                        ) - 1          )
+!
+!--             Determine largest topography index on u grid
+                nzt_topo_nestbc_r = MAX( nzt_topo_nestbc_r,                    &
+                  MAXLOC(                                                      &
+                          MERGE( 1, 0,                                         &
+                                 BTEST( wall_flags_0(nzb:nzb_max,j,i), 14 )  &
+                               ), DIM = 1                                      &
+                        ) - 1          )
+!
+!--             Determine largest topography index on v grid
+                nzt_topo_nestbc_r = MAX( nzt_topo_nestbc_r,                    &
+                  MAXLOC(                                                      &
+                          MERGE( 1, 0,                                         &
+                                 BTEST( wall_flags_0(nzb:nzb_max,j,i), 16 )  &
+                               ), DIM = 1                                      &
+                        ) - 1          )
+!
+!--             Determine largest topography index on w grid
+                nzt_topo_nestbc_r = MAX( nzt_topo_nestbc_r,                    &
+                  MAXLOC(                                                      &
+                          MERGE( 1, 0,                                         &
+                                 BTEST( wall_flags_0(nzb:nzb_max,j,i), 18 )  &
+                               ), DIM = 1                                      &
+                        ) - 1          )
           ENDDO
           nzt_topo_nestbc_r = nzt_topo_nestbc_r + 1
@@ -1360,6 +1437,37 @@
           DO  j = nys-1, nys
              DO  i = nxl, nxr
-                nzt_topo_nestbc_s = MAX( nzt_topo_nestbc_s, nzb_u_inner(j,i),   &
-                                         nzb_v_inner(j,i), nzb_w_inner(j,i) )
+!
+!--             Concept need to be reconsidered for 3D-topography
+!--             Determine largest topography index on scalar grid
+                nzt_topo_nestbc_s = MAX( nzt_topo_nestbc_s,                    &
+                  MAXLOC(                                                      &
+                          MERGE( 1, 0,                                         &
+                                 BTEST( wall_flags_0(nzb:nzb_max,j,i), 12 )  &
+                               ), DIM = 1                                      &
+                        ) - 1          )
+!
+!--             Determine largest topography index on u grid
+                nzt_topo_nestbc_s = MAX( nzt_topo_nestbc_s,                    &
+                  MAXLOC(                                                      &
+                          MERGE( 1, 0,                                         &
+                                 BTEST( wall_flags_0(nzb:nzb_max,j,i), 14 )  &
+                               ), DIM = 1                                      &
+                        ) - 1          )
+!
+!--             Determine largest topography index on v grid
+                nzt_topo_nestbc_s = MAX( nzt_topo_nestbc_s,                    &
+                  MAXLOC(                                                      &
+                          MERGE( 1, 0,                                         &
+                                 BTEST( wall_flags_0(nzb:nzb_max,j,i), 16 )  &
+                               ), DIM = 1                                      &
+                        ) - 1          )
+!
+!--             Determine largest topography index on w grid
+                nzt_topo_nestbc_s = MAX( nzt_topo_nestbc_s,                    &
+                  MAXLOC(                                                      &
+                          MERGE( 1, 0,                                         &
+                                 BTEST( wall_flags_0(nzb:nzb_max,j,i), 18 )  &
+                               ), DIM = 1                                      &
+                        ) - 1          )
              ENDDO
           ENDDO
@@ -1371,6 +1479,37 @@
           j = nyn + 1
           DO  i = nxl, nxr
-             nzt_topo_nestbc_n = MAX( nzt_topo_nestbc_n, nzb_u_inner(j,i),      &
-                                      nzb_v_inner(j,i), nzb_w_inner(j,i) )
+!
+!--             Concept need to be reconsidered for 3D-topography
+!--             Determine largest topography index on scalar grid
+                nzt_topo_nestbc_n = MAX( nzt_topo_nestbc_n,                    &
+                  MAXLOC(                                                      &
+                          MERGE( 1, 0,                                         &
+                                 BTEST( wall_flags_0(nzb:nzb_max,j,i), 12 )  &
+                               ), DIM = 1                                      &
+                        ) - 1          )
+!
+!--             Determine largest topography index on u grid
+                nzt_topo_nestbc_n = MAX( nzt_topo_nestbc_n,                    &
+                  MAXLOC(                                                      &
+                          MERGE( 1, 0,                                         &
+                                 BTEST( wall_flags_0(nzb:nzb_max,j,i), 14 )  &
+                               ), DIM = 1                                      &
+                        ) - 1          )
+!
+!--             Determine largest topography index on v grid
+                nzt_topo_nestbc_n = MAX( nzt_topo_nestbc_n,                    &
+                  MAXLOC(                                                      &
+                          MERGE( 1, 0,                                         &
+                                 BTEST( wall_flags_0(nzb:nzb_max,j,i), 16 )  &
+                               ), DIM = 1                                      &
+                        ) - 1          )
+!
+!--             Determine largest topography index on w grid
+                nzt_topo_nestbc_n = MAX( nzt_topo_nestbc_n,                    &
+                  MAXLOC(                                                      &
+                          MERGE( 1, 0,                                         &
+                                 BTEST( wall_flags_0(nzb:nzb_max,j,i), 18 )  &
+                               ), DIM = 1                                      &
+                        ) - 1          )
           ENDDO
           nzt_topo_nestbc_n = nzt_topo_nestbc_n + 1
@@ -1422,9 +1561,50 @@
 !--          Left boundary for u
              i   = 0
-             kb  = nzb_u_inner(j,i)
-             k   = kb + 1
-             wall_index = kb
-             CALL pmci_define_loglaw_correction_parameters( lc, lcr, k, j,      &
-                                inc, wall_index, z0(j,i), kb, direction, ncorr )
+!
+!--          For loglaw correction the roughness z0 is required. z0, however, 
+!--          is part of the surfacetypes now, so call subroutine according
+!--          to the present surface tpye. 
+!--          Default surface type
+             IF ( surf_def_h(0)%start_index(j,i) <=                            &
+                  surf_def_h(0)%end_index(j,i) )  THEN
+                start_index = surf_def_h(0)%start_index(j,i)
+                end_index   = surf_def_h(0)%end_index(j,i)
+                DO  m = start_index, end_index
+                   k          = surf_def_h(0)%k(m)
+                   wall_index = k - 1 
+                   kb         = k - 1
+                   CALL pmci_define_loglaw_correction_parameters( lc, lcr, k,  &
+                            j, inc, wall_index, surf_def_h(0)%z0(m), &
+                            kb, direction, ncorr )
+                ENDDO
+!
+!--          Natural surface type
+             ELSEIF ( surf_lsm_h%start_index(j,i) <=                           &
+                      surf_lsm_h%end_index(j,i) )  THEN
+                start_index = surf_lsm_h%start_index(j,i)
+                end_index   = surf_lsm_h%end_index(j,i)
+                DO  m = start_index, end_index
+                   k          = surf_lsm_h%k(m)
+                   wall_index = k - 1 
+                   kb         = k - 1
+                   CALL pmci_define_loglaw_correction_parameters( lc, lcr, k,  &
+                            j, inc, wall_index, surf_lsm_h%z0(m),    &
+                            kb, direction, ncorr )
+                ENDDO
+!
+!--          Urban surface type
+             ELSEIF ( surf_usm_h%start_index(j,i) <=                           &
+                      surf_usm_h%end_index(j,i) )  THEN
+                start_index = surf_usm_h%start_index(j,i)
+                end_index = surf_usm_h%end_index(j,i)
+                DO  m = start_index, end_index
+                   k          = surf_usm_h%k(m)
+                   wall_index = k - 1 
+                   kb         = k - 1
+                   CALL pmci_define_loglaw_correction_parameters( lc, lcr, k,  &
+                            j, inc, wall_index, surf_usm_h%z0(m),    &
+                            kb, direction, ncorr )
+                ENDDO
+             ENDIF
              logc_u_l(1,k,j) = lc
              logc_ratio_u_l(1,0:ncorr-1,k,j) = lcr(0:ncorr-1)
@@ -1433,9 +1613,50 @@
 !--          Left boundary for v
              i   = -1
-             kb  =  nzb_v_inner(j,i)
-             k   =  kb + 1
-             wall_index = kb
-             CALL pmci_define_loglaw_correction_parameters( lc, lcr, k, j,      &
-                                inc, wall_index, z0(j,i), kb, direction, ncorr )
+!
+!--          For loglaw correction the roughness z0 is required. z0, however, 
+!--          is part of the surfacetypes now, so call subroutine according
+!--          to the present surface tpye. 
+!--          Default surface type
+             IF ( surf_def_h(0)%start_index(j,i) <=                            &
+                  surf_def_h(0)%end_index(j,i) )  THEN
+                start_index = surf_def_h(0)%start_index(j,i)
+                end_index   = surf_def_h(0)%end_index(j,i)
+                DO  m = start_index, end_index
+                   k          = surf_def_h(0)%k(m)
+                   wall_index = k - 1 
+                   kb         = k - 1
+                   CALL pmci_define_loglaw_correction_parameters( lc, lcr, k,  &
+                            j, inc, wall_index, surf_def_h(0)%z0(m), &
+                            kb, direction, ncorr )
+                ENDDO
+!
+!--          Natural surface type
+             ELSEIF ( surf_lsm_h%start_index(j,i) <=                           &
+                      surf_lsm_h%end_index(j,i) )  THEN
+                start_index = surf_lsm_h%start_index(j,i)
+                end_index   = surf_lsm_h%end_index(j,i)
+                DO  m = start_index, end_index
+                   k          = surf_lsm_h%k(m)
+                   wall_index = k - 1 
+                   kb         = k - 1
+                   CALL pmci_define_loglaw_correction_parameters( lc, lcr, k,  &
+                            j, inc, wall_index, surf_lsm_h%z0(m),    &
+                            kb, direction, ncorr )
+                ENDDO
+!
+!--          Urban surface type
+             ELSEIF ( surf_usm_h%start_index(j,i) <=                           &
+                      surf_usm_h%end_index(j,i) )  THEN
+                start_index = surf_usm_h%start_index(j,i)
+                end_index = surf_usm_h%end_index(j,i)
+                DO  m = start_index, end_index
+                   k          = surf_usm_h%k(m)
+                   wall_index = k - 1 
+                   kb         = k - 1
+                   CALL pmci_define_loglaw_correction_parameters( lc, lcr, k,  &
+                            j, inc, wall_index, surf_usm_h%z0(m),    &
+                            kb, direction, ncorr )
+                ENDDO
+             ENDIF
              logc_v_l(1,k,j) = lc
              logc_ratio_v_l(1,0:ncorr-1,k,j) = lcr(0:ncorr-1)
@@ -1469,9 +1690,51 @@
 !--          Right boundary for u
              i   = nxr + 1
-             kb  = nzb_u_inner(j,i)
-             k   = kb + 1
-             wall_index = kb
-             CALL pmci_define_loglaw_correction_parameters( lc, lcr, k, j,      &
-                                inc, wall_index, z0(j,i), kb, direction, ncorr )
+!
+!--          For loglaw correction the roughness z0 is required. z0, however, 
+!--          is part of the surfacetypes now, so call subroutine according
+!--          to the present surface tpye. 
+!--          Default surface type
+             IF ( surf_def_h(0)%start_index(j,i) <=                            &
+                  surf_def_h(0)%end_index(j,i) )  THEN
+                start_index = surf_def_h(0)%start_index(j,i)
+                end_index   = surf_def_h(0)%end_index(j,i)
+                DO  m = start_index, end_index
+                   k          = surf_def_h(0)%k(m)
+                   wall_index = k - 1 
+                   kb         = k - 1
+                   CALL pmci_define_loglaw_correction_parameters( lc, lcr, k,  &
+                            j, inc, wall_index, surf_def_h(0)%z0(m), &
+                            kb, direction, ncorr )
+                ENDDO
+!
+!--          Natural surface type
+             ELSEIF ( surf_lsm_h%start_index(j,i) <=                           &
+                      surf_lsm_h%end_index(j,i) )  THEN
+                start_index = surf_lsm_h%start_index(j,i)
+                end_index   = surf_lsm_h%end_index(j,i)
+                DO  m = start_index, end_index
+                   k          = surf_lsm_h%k(m)
+                   wall_index = k - 1 
+                   kb         = k - 1
+                   CALL pmci_define_loglaw_correction_parameters( lc, lcr, k,  &
+                            j, inc, wall_index, surf_lsm_h%z0(m),    &
+                            kb, direction, ncorr )
+                ENDDO
+!
+!--          Urban surface type
+             ELSEIF ( surf_usm_h%start_index(j,i) <=                           &
+                      surf_usm_h%end_index(j,i) )  THEN
+                start_index = surf_usm_h%start_index(j,i)
+                end_index = surf_usm_h%end_index(j,i)
+                DO  m = start_index, end_index
+                   k          = surf_usm_h%k(m)
+                   wall_index = k - 1 
+                   kb         = k - 1
+                   CALL pmci_define_loglaw_correction_parameters( lc, lcr, k,  &
+                            j, inc, wall_index, surf_usm_h%z0(m),    &
+                            kb, direction, ncorr )
+                ENDDO
+             ENDIF
+
              logc_u_r(1,k,j) = lc
              logc_ratio_u_r(1,0:ncorr-1,k,j) = lcr(0:ncorr-1)
@@ -1480,9 +1743,50 @@
 !--          Right boundary for v
              i   = nxr + 1
-             kb  = nzb_v_inner(j,i)
-             k   = kb + 1
-             wall_index = kb
-             CALL pmci_define_loglaw_correction_parameters( lc, lcr, k, j,      &
-                                inc, wall_index, z0(j,i), kb, direction, ncorr )
+!
+!--          For loglaw correction the roughness z0 is required. z0, however, 
+!--          is part of the surfacetypes now, so call subroutine according
+!--          to the present surface tpye. 
+!--          Default surface type
+             IF ( surf_def_h(0)%start_index(j,i) <=                            &
+                  surf_def_h(0)%end_index(j,i) )  THEN
+                start_index = surf_def_h(0)%start_index(j,i)
+                end_index   = surf_def_h(0)%end_index(j,i)
+                DO  m = start_index, end_index
+                   k          = surf_def_h(0)%k(m)
+                   wall_index = k - 1 
+                   kb         = k - 1
+                   CALL pmci_define_loglaw_correction_parameters( lc, lcr, k,  &
+                            j, inc, wall_index, surf_def_h(0)%z0(m), &
+                            kb, direction, ncorr )
+                ENDDO
+!
+!--          Natural surface type
+             ELSEIF ( surf_lsm_h%start_index(j,i) <=                           &
+                      surf_lsm_h%end_index(j,i) )  THEN
+                start_index = surf_lsm_h%start_index(j,i)
+                end_index   = surf_lsm_h%end_index(j,i)
+                DO  m = start_index, end_index
+                   k          = surf_lsm_h%k(m)
+                   wall_index = k - 1 
+                   kb         = k - 1
+                   CALL pmci_define_loglaw_correction_parameters( lc, lcr, k,  &
+                            j, inc, wall_index, surf_lsm_h%z0(m),    &
+                            kb, direction, ncorr )
+                ENDDO
+!
+!--          Urban surface type
+             ELSEIF ( surf_usm_h%start_index(j,i) <=                           &
+                      surf_usm_h%end_index(j,i) )  THEN
+                start_index = surf_usm_h%start_index(j,i)
+                end_index = surf_usm_h%end_index(j,i)
+                DO  m = start_index, end_index
+                   k          = surf_usm_h%k(m)
+                   wall_index = k - 1 
+                   kb         = k - 1
+                   CALL pmci_define_loglaw_correction_parameters( lc, lcr, k,  &
+                            j, inc, wall_index, surf_usm_h%z0(m),    &
+                            kb, direction, ncorr )
+                ENDDO
+             ENDIF
              logc_v_r(1,k,j) = lc
              logc_ratio_v_r(1,0:ncorr-1,k,j) = lcr(0:ncorr-1)
@@ -1516,9 +1820,50 @@
 !--          South boundary for u
              j   = -1
-             kb  =  nzb_u_inner(j,i)
-             k   =  kb + 1
-             wall_index = kb
-             CALL pmci_define_loglaw_correction_parameters( lc, lcr, k, j,      &
-                                inc, wall_index, z0(j,i), kb, direction, ncorr )
+!
+!--          For loglaw correction the roughness z0 is required. z0, however, 
+!--          is part of the surfacetypes now, so call subroutine according
+!--          to the present surface tpye. 
+!--          Default surface type
+             IF ( surf_def_h(0)%start_index(j,i) <=                            &
+                  surf_def_h(0)%end_index(j,i) )  THEN
+                start_index = surf_def_h(0)%start_index(j,i)
+                end_index   = surf_def_h(0)%end_index(j,i)
+                DO  m = start_index, end_index
+                   k          = surf_def_h(0)%k(m)
+                   wall_index = k - 1 
+                   kb         = k - 1
+                   CALL pmci_define_loglaw_correction_parameters( lc, lcr, k,  &
+                            j, inc, wall_index, surf_def_h(0)%z0(m), &
+                            kb, direction, ncorr )
+                ENDDO
+!
+!--          Natural surface type
+             ELSEIF ( surf_lsm_h%start_index(j,i) <=                           &
+                      surf_lsm_h%end_index(j,i) )  THEN
+                start_index = surf_lsm_h%start_index(j,i)
+                end_index   = surf_lsm_h%end_index(j,i)
+                DO  m = start_index, end_index
+                   k          = surf_lsm_h%k(m)
+                   wall_index = k - 1 
+                   kb         = k - 1
+                   CALL pmci_define_loglaw_correction_parameters( lc, lcr, k,  &
+                            j, inc, wall_index, surf_lsm_h%z0(m),    &
+                            kb, direction, ncorr )
+                ENDDO
+!
+!--          Urban surface type
+             ELSEIF ( surf_usm_h%start_index(j,i) <=                           &
+                      surf_usm_h%end_index(j,i) )  THEN
+                start_index = surf_usm_h%start_index(j,i)
+                end_index = surf_usm_h%end_index(j,i)
+                DO  m = start_index, end_index
+                   k          = surf_usm_h%k(m)
+                   wall_index = k - 1 
+                   kb         = k - 1
+                   CALL pmci_define_loglaw_correction_parameters( lc, lcr, k,  &
+                            j, inc, wall_index, surf_usm_h%z0(m),    &
+                            kb, direction, ncorr )
+                ENDDO
+             ENDIF
              logc_u_s(1,k,i) = lc
              logc_ratio_u_s(1,0:ncorr-1,k,i) = lcr(0:ncorr-1)
@@ -1527,9 +1872,50 @@
 !--          South boundary for v
              j   = 0
-             kb  = nzb_v_inner(j,i)
-             k   = kb + 1
-             wall_index = kb
-             CALL pmci_define_loglaw_correction_parameters( lc, lcr, k, j,      &
-                                inc, wall_index, z0(j,i), kb, direction, ncorr )
+!
+!--          For loglaw correction the roughness z0 is required. z0, however, 
+!--          is part of the surfacetypes now, so call subroutine according
+!--          to the present surface tpye. 
+!--          Default surface type
+             IF ( surf_def_h(0)%start_index(j,i) <=                            &
+                  surf_def_h(0)%end_index(j,i) )  THEN
+                start_index = surf_def_h(0)%start_index(j,i)
+                end_index   = surf_def_h(0)%end_index(j,i)
+                DO  m = start_index, end_index
+                   k          = surf_def_h(0)%k(m)
+                   wall_index = k - 1 
+                   kb         = k - 1
+                   CALL pmci_define_loglaw_correction_parameters( lc, lcr, k,  &
+                            j, inc, wall_index, surf_def_h(0)%z0(m), &
+                            kb, direction, ncorr )
+                ENDDO
+!
+!--          Natural surface type
+             ELSEIF ( surf_lsm_h%start_index(j,i) <=                           &
+                      surf_lsm_h%end_index(j,i) )  THEN
+                start_index = surf_lsm_h%start_index(j,i)
+                end_index   = surf_lsm_h%end_index(j,i)
+                DO  m = start_index, end_index
+                   k          = surf_lsm_h%k(m)
+                   wall_index = k - 1 
+                   kb         = k - 1
+                   CALL pmci_define_loglaw_correction_parameters( lc, lcr, k,  &
+                            j, inc, wall_index, surf_lsm_h%z0(m),    &
+                            kb, direction, ncorr )
+                ENDDO
+!
+!--          Urban surface type
+             ELSEIF ( surf_usm_h%start_index(j,i) <=                           &
+                      surf_usm_h%end_index(j,i) )  THEN
+                start_index = surf_usm_h%start_index(j,i)
+                end_index = surf_usm_h%end_index(j,i)
+                DO  m = start_index, end_index
+                   k          = surf_usm_h%k(m)
+                   wall_index = k - 1 
+                   kb         = k - 1
+                   CALL pmci_define_loglaw_correction_parameters( lc, lcr, k,  &
+                            j, inc, wall_index, surf_usm_h%z0(m),    &
+                            kb, direction, ncorr )
+                ENDDO
+             ENDIF
              logc_v_s(1,k,i) = lc
              logc_ratio_v_s(1,0:ncorr-1,k,i) = lcr(0:ncorr-1)
@@ -1563,9 +1949,50 @@
 !--          North boundary for u
              j   = nyn + 1
-             kb  = nzb_u_inner(j,i)
-             k   = kb + 1
-             wall_index = kb
-             CALL pmci_define_loglaw_correction_parameters( lc, lcr, k, j,      &
-                                inc, wall_index, z0(j,i), kb, direction, ncorr )
+!
+!--          For loglaw correction the roughness z0 is required. z0, however, 
+!--          is part of the surfacetypes now, so call subroutine according
+!--          to the present surface tpye. 
+!--          Default surface type
+             IF ( surf_def_h(0)%start_index(j,i) <=                            &
+                  surf_def_h(0)%end_index(j,i) )  THEN
+                start_index = surf_def_h(0)%start_index(j,i)
+                end_index   = surf_def_h(0)%end_index(j,i)
+                DO  m = start_index, end_index
+                   k          = surf_def_h(0)%k(m)
+                   wall_index = k - 1 
+                   kb         = k - 1
+                   CALL pmci_define_loglaw_correction_parameters( lc, lcr, k,  &
+                            j, inc, wall_index, surf_def_h(0)%z0(m), &
+                            kb, direction, ncorr )
+                ENDDO
+!
+!--          Natural surface type
+             ELSEIF ( surf_lsm_h%start_index(j,i) <=                           &
+                      surf_lsm_h%end_index(j,i) )  THEN
+                start_index = surf_lsm_h%start_index(j,i)
+                end_index   = surf_lsm_h%end_index(j,i)
+                DO  m = start_index, end_index
+                   k          = surf_lsm_h%k(m)
+                   wall_index = k - 1 
+                   kb         = k - 1
+                   CALL pmci_define_loglaw_correction_parameters( lc, lcr, k,  &
+                            j, inc, wall_index, surf_lsm_h%z0(m),    &
+                            kb, direction, ncorr )
+                ENDDO
+!
+!--          Urban surface type
+             ELSEIF ( surf_usm_h%start_index(j,i) <=                           &
+                      surf_usm_h%end_index(j,i) )  THEN
+                start_index = surf_usm_h%start_index(j,i)
+                end_index = surf_usm_h%end_index(j,i)
+                DO  m = start_index, end_index
+                   k          = surf_usm_h%k(m)
+                   wall_index = k - 1 
+                   kb         = k - 1
+                   CALL pmci_define_loglaw_correction_parameters( lc, lcr, k,  &
+                            j, inc, wall_index, surf_usm_h%z0(m),    &
+                            kb, direction, ncorr )
+                ENDDO
+             ENDIF
              logc_u_n(1,k,i) = lc
              logc_ratio_u_n(1,0:ncorr-1,k,i) = lcr(0:ncorr-1)
@@ -1574,9 +2001,50 @@
 !--          North boundary for v
              j   = nyn + 1
-             kb  = nzb_v_inner(j,i)
-             k   = kb + 1
-             wall_index = kb
-             CALL pmci_define_loglaw_correction_parameters( lc, lcr, k, j,      &
-                                inc, wall_index, z0(j,i), kb, direction, ncorr )
+!
+!--          For loglaw correction the roughness z0 is required. z0, however, 
+!--          is part of the surfacetypes now, so call subroutine according
+!--          to the present surface tpye. 
+!--          Default surface type
+             IF ( surf_def_h(0)%start_index(j,i) <=                            &
+                  surf_def_h(0)%end_index(j,i) )  THEN
+                start_index = surf_def_h(0)%start_index(j,i)
+                end_index   = surf_def_h(0)%end_index(j,i)
+                DO  m = start_index, end_index
+                   k          = surf_def_h(0)%k(m)
+                   wall_index = k - 1 
+                   kb         = k - 1
+                   CALL pmci_define_loglaw_correction_parameters( lc, lcr, k,  &
+                            j, inc, wall_index, surf_def_h(0)%z0(m), &
+                            kb, direction, ncorr )
+                ENDDO
+!
+!--          Natural surface type
+             ELSEIF ( surf_lsm_h%start_index(j,i) <=                           &
+                      surf_lsm_h%end_index(j,i) )  THEN
+                start_index = surf_lsm_h%start_index(j,i)
+                end_index   = surf_lsm_h%end_index(j,i)
+                DO  m = start_index, end_index
+                   k          = surf_lsm_h%k(m)
+                   wall_index = k - 1 
+                   kb         = k - 1
+                   CALL pmci_define_loglaw_correction_parameters( lc, lcr, k,  &
+                            j, inc, wall_index, surf_lsm_h%z0(m),    &
+                            kb, direction, ncorr )
+                ENDDO
+!
+!--          Urban surface type
+             ELSEIF ( surf_usm_h%start_index(j,i) <=                           &
+                      surf_usm_h%end_index(j,i) )  THEN
+                start_index = surf_usm_h%start_index(j,i)
+                end_index = surf_usm_h%end_index(j,i)
+                DO  m = start_index, end_index
+                   k          = surf_usm_h%k(m)
+                   wall_index = k - 1 
+                   kb         = k - 1
+                   CALL pmci_define_loglaw_correction_parameters( lc, lcr, k,  &
+                            j, inc, wall_index, surf_usm_h%z0(m),    &
+                            kb, direction, ncorr )
+                ENDDO
+             ENDIF
              logc_v_n(1,k,i) = lc
              logc_ratio_v_n(1,0:ncorr-1,k,i) = lcr(0:ncorr-1)
@@ -1590,8 +2058,20 @@
 !--    Then vertical walls and corners if necessary
        IF ( topography /= 'flat' )  THEN
+!
+!--       Workaround, set z0 at vertical surfaces simply to the given roughness
+!--       lenth, which is required to determine the logarithmic correction 
+!--       factors at the child boundaries, which are at the ghost-points. 
+!--       The surface data type for vertical surfaces, however, is not defined 
+!--       at ghost-points, so that no z0 can be retrieved at this point. 
+!--       Maybe, revise this later and define vertical surface datattype also
+!--       at ghost-points.
+          z0_topo = roughness_length
 
           kb = 0       ! kb is not used when direction > 1
 !        
 !--       Left boundary
+
+!
+!--       Are loglaw-correction parameters also calculated inside topo? 
           IF ( nest_bound_l )  THEN
 
@@ -1599,15 +2079,48 @@
 
              DO  j = nys, nyn
+                k_wall_u_ji   = MAXLOC(                                        &
+                            MERGE( 1, 0,                                       &
+                          BTEST( wall_flags_0(nzb:nzt_topo_nestbc_l,j,0), 26 ) &
+                                 ), DIM = 1                                    &
+                                      ) - 1
+                k_wall_u_ji_p = MAXLOC(                                        &
+                            MERGE( 1, 0,                                       &
+                          BTEST( wall_flags_0(nzb:nzt_topo_nestbc_l,j+1,0), 26 )&
+                                 ), DIM = 1                                    &
+                                      ) - 1
+                k_wall_u_ji_m = MAXLOC(                                        &
+                            MERGE( 1, 0,                                       &
+                          BTEST( wall_flags_0(nzb:nzt_topo_nestbc_l,j-1,0), 26 )&
+                                 ), DIM = 1                                    &
+                                      ) - 1
+
+                k_wall_w_ji   = MAXLOC(                                        &
+                            MERGE( 1, 0,                                       &
+                          BTEST( wall_flags_0(nzb:nzt_topo_nestbc_l,j,-1), 28 )&
+                                 ), DIM = 1                                    &
+                                      ) - 1
+                k_wall_w_ji_p = MAXLOC(                                        &
+                            MERGE( 1, 0,                                       &
+                          BTEST( wall_flags_0(nzb:nzt_topo_nestbc_l,j+1,-1), 28 )&
+                                 ), DIM = 1                                    &
+                                      ) - 1
+                k_wall_w_ji_m = MAXLOC(                                        &
+                            MERGE( 1, 0,                                       &
+                          BTEST( wall_flags_0(nzb:nzt_topo_nestbc_l,j-1,-1), 28 )&
+                                 ), DIM = 1                                    &
+                                      ) - 1
+
                 DO  k = nzb, nzt_topo_nestbc_l
+
+                   i            = 0
 !
 !--                Wall for u on the south side, but not on the north side
-                   i  = 0
-                   IF ( ( nzb_u_outer(j,i) > nzb_u_outer(j+1,i) ) .AND.         &
-                        ( nzb_u_outer(j,i) == nzb_u_outer(j-1,i) ) )            &
+                   IF ( ( k_wall_u_ji > k_wall_u_ji_p ) .AND.                  &
+                        ( k_wall_u_ji == k_wall_u_ji_m ) )                     &
                    THEN
                       inc        =  1
                       wall_index =  j
-                      CALL pmci_define_loglaw_correction_parameters( lc, lcr,   &
-                          k, j, inc, wall_index, z0(j,i), kb, direction, ncorr )
+                      CALL pmci_define_loglaw_correction_parameters( lc, lcr,  &
+                          k, j, inc, wall_index, z0_topo, kb, direction, ncorr )
 !
 !--                   The direction of the wall-normal index is stored as the
@@ -1620,11 +2133,10 @@
 !
 !--                Wall for u on the north side, but not on the south side
-                   i  = 0
-                   IF ( ( nzb_u_outer(j,i) > nzb_u_outer(j-1,i) ) .AND.         &
-                        ( nzb_u_outer(j,i) == nzb_u_outer(j+1,i) ) )  THEN
+                   IF ( ( k_wall_u_ji > k_wall_u_ji_m ) .AND.                  &
+                        ( k_wall_u_ji == k_wall_u_ji_p ) )  THEN
                       inc        = -1
                       wall_index =  j + 1
-                      CALL pmci_define_loglaw_correction_parameters( lc, lcr,   &
-                          k, j, inc, wall_index, z0(j,i), kb, direction, ncorr )
+                      CALL pmci_define_loglaw_correction_parameters( lc, lcr,  &
+                          k, j, inc, wall_index, z0_topo, kb, direction, ncorr )
 !
 !--                   The direction of the wall-normal index is stored as the
@@ -1635,13 +2147,14 @@
                    ENDIF
 
+                   i  = -1
 !
 !--                Wall for w on the south side, but not on the north side.
-                   i  = -1
-                   IF ( ( nzb_w_outer(j,i) > nzb_w_outer(j+1,i) )  .AND.        &
-                        ( nzb_w_outer(j,i) == nzb_w_outer(j-1,i) ) )  THEN
+
+                   IF ( ( k_wall_w_ji > k_wall_w_ji_p )  .AND.                 & 
+                        ( k_wall_w_ji == k_wall_w_ji_m ) )  THEN    
                       inc        =  1
                       wall_index =  j
-                      CALL pmci_define_loglaw_correction_parameters( lc, lcr,   &
-                          k, j, inc, wall_index, z0(j,i), kb, direction, ncorr )
+                      CALL pmci_define_loglaw_correction_parameters( lc, lcr,  &
+                          k, j, inc, wall_index, z0_topo, kb, direction, ncorr )
 !
 !--                   The direction of the wall-normal index is stored as the
@@ -1654,11 +2167,10 @@
 !
 !--                Wall for w on the north side, but not on the south side.
-                   i  = -1
-                   IF ( ( nzb_w_outer(j,i) > nzb_w_outer(j-1,i) )  .AND.        &
-                        ( nzb_w_outer(j,i) == nzb_w_outer(j+1,i) ) )  THEN
+                   IF ( ( k_wall_w_ji > k_wall_w_ji_m )  .AND.                 &
+                        ( k_wall_w_ji == k_wall_w_ji_p ) )  THEN
                       inc        = -1
                       wall_index =  j+1
-                      CALL pmci_define_loglaw_correction_parameters( lc, lcr,   &
-                          k, j, inc, wall_index, z0(j,i), kb, direction, ncorr )
+                      CALL pmci_define_loglaw_correction_parameters( lc, lcr,  &
+                          k, j, inc, wall_index, z0_topo, kb, direction, ncorr )
 !
 !--                   The direction of the wall-normal index is stored as the
@@ -1682,13 +2194,45 @@
 
              DO  j = nys, nyn
+
+                k_wall_u_ji    = MAXLOC(                                       &
+                            MERGE( 1, 0,                                       &
+                          BTEST( wall_flags_0(nzb:nzt_topo_nestbc_r,j,i), 26 ) &
+                                 ), DIM = 1                                    &
+                                     ) - 1
+                k_wall_u_ji_p  = MAXLOC(                                       &
+                            MERGE( 1, 0,                                       &
+                          BTEST( wall_flags_0(nzb:nzt_topo_nestbc_r,j+1,i), 26 )&
+                                 ), DIM = 1                                    &
+                                     ) - 1
+                k_wall_u_ji_m  = MAXLOC(                                       &
+                            MERGE( 1, 0,                                       &
+                          BTEST( wall_flags_0(nzb:nzt_topo_nestbc_r,j-1,i), 26 )&
+                                     ), DIM = 1                                &
+                                        ) - 1
+
+                k_wall_w_ji    = MAXLOC(                                       &
+                            MERGE( 1, 0,                                       &
+                          BTEST( wall_flags_0(nzb:nzt_topo_nestbc_r,j,i), 28 ) &
+                                 ), DIM = 1                                    &
+                                     ) - 1
+                k_wall_w_ji_p  = MAXLOC(                                       &
+                            MERGE( 1, 0,                                       &
+                          BTEST( wall_flags_0(nzb:nzt_topo_nestbc_r,j+1,i), 28 )&
+                                 ), DIM = 1                                    &
+                                     ) - 1
+                k_wall_w_ji_m  = MAXLOC(                                       &
+                            MERGE( 1, 0,                                       &
+                          BTEST( wall_flags_0(nzb:nzt_topo_nestbc_r,j-1,i), 28 )&
+                                     ), DIM = 1                                &
+                                        ) - 1
                 DO  k = nzb, nzt_topo_nestbc_r
 !
 !--                Wall for u on the south side, but not on the north side
-                   IF ( ( nzb_u_outer(j,i) > nzb_u_outer(j+1,i) )  .AND.        &
-                        ( nzb_u_outer(j,i) == nzb_u_outer(j-1,i) ) )  THEN
+                   IF ( ( k_wall_u_ji > k_wall_u_ji_p )  .AND.                 &
+                        ( k_wall_u_ji == k_wall_u_ji_m ) )  THEN
                       inc        = 1
                       wall_index = j
                       CALL pmci_define_loglaw_correction_parameters( lc, lcr,   &
-                          k, j, inc, wall_index, z0(j,i), kb, direction, ncorr )
+                          k, j, inc, wall_index, z0_topo, kb, direction, ncorr )
 !
 !--                   The direction of the wall-normal index is stored as the
@@ -1701,10 +2245,10 @@
 !
 !--                Wall for u on the north side, but not on the south side
-                   IF ( ( nzb_u_outer(j,i) > nzb_u_outer(j-1,i) )  .AND.        &
-                        ( nzb_u_outer(j,i) == nzb_u_outer(j+1,i) ) )  THEN
+                   IF ( ( k_wall_u_ji > k_wall_u_ji_m )  .AND.                  &
+                        ( k_wall_u_ji == k_wall_u_ji_p ) )  THEN
                       inc        = -1
                       wall_index =  j+1
                       CALL pmci_define_loglaw_correction_parameters( lc, lcr,   &
-                          k, j, inc, wall_index, z0(j,i), kb, direction, ncorr )
+                          k, j, inc, wall_index, z0_topo, kb, direction, ncorr )
 !
 !--                   The direction of the wall-normal index is stored as the
@@ -1717,10 +2261,10 @@
 !
 !--                Wall for w on the south side, but not on the north side
-                   IF ( ( nzb_w_outer(j,i) > nzb_w_outer(j+1,i) )  .AND.        &
-                        ( nzb_w_outer(j,i) == nzb_w_outer(j-1,i) ) )  THEN
+                   IF ( ( k_wall_w_ji > k_wall_w_ji_p )  .AND.                 &
+                        ( k_wall_w_ji == k_wall_w_ji_m ) )  THEN
                       inc        =  1
                       wall_index =  j
-                      CALL pmci_define_loglaw_correction_parameters( lc, lcr,   &
-                          k, j, inc, wall_index, z0(j,i), kb, direction, ncorr )
+                      CALL pmci_define_loglaw_correction_parameters( lc, lcr,  &
+                          k, j, inc, wall_index, z0_topo, kb, direction, ncorr )
 !
 !--                   The direction of the wall-normal index is stored as the
@@ -1733,10 +2277,10 @@
 !
 !--                Wall for w on the north side, but not on the south side
-                   IF ( ( nzb_w_outer(j,i) > nzb_w_outer(j-1,i) )  .AND.        &
-                        ( nzb_w_outer(j,i) == nzb_w_outer(j+1,i) ) )  THEN
+                   IF ( ( k_wall_w_ji > k_wall_w_ji_m )  .AND.                 &
+                        ( k_wall_w_ji == k_wall_w_ji_p ) )  THEN
                       inc        = -1
                       wall_index =  j+1
-                      CALL pmci_define_loglaw_correction_parameters( lc, lcr,   &
-                          k, j, inc, wall_index, z0(j,i), kb, direction, ncorr )
+                      CALL pmci_define_loglaw_correction_parameters( lc, lcr,  &
+                          k, j, inc, wall_index, z0_topo, kb, direction, ncorr )
 
 !
@@ -1760,14 +2304,46 @@
 
              DO  i = nxl, nxr
+
+                k_wall_v_ji    = MAXLOC(                                       &
+                            MERGE( 1, 0,                                       &
+                          BTEST( wall_flags_0(nzb:nzt_topo_nestbc_s,0,i), 27 ) &
+                                 ), DIM = 1                                    &
+                                     ) - 1
+                k_wall_v_ji_p  = MAXLOC(                                       &
+                            MERGE( 1, 0,                                       &
+                          BTEST( wall_flags_0(nzb:nzt_topo_nestbc_s,0,i+1), 27 )&
+                                 ), DIM = 1                                    &
+                                     ) - 1
+                k_wall_v_ji_m  = MAXLOC(                                       &
+                            MERGE( 1, 0,                                       &
+                          BTEST( wall_flags_0(nzb:nzt_topo_nestbc_s,0,i-1), 27 )&
+                                     ), DIM = 1                                &
+                                        ) - 1
+
+                k_wall_w_ji    = MAXLOC(                                       &
+                            MERGE( 1, 0,                                       &
+                          BTEST( wall_flags_0(nzb:nzt_topo_nestbc_s,-1,i), 28 )&
+                                 ), DIM = 1                                    &
+                                     ) - 1
+                k_wall_w_ji_p  = MAXLOC(                                       &
+                            MERGE( 1, 0,                                       &
+                          BTEST( wall_flags_0(nzb:nzt_topo_nestbc_s,-1,i+1), 28 )&
+                                 ), DIM = 1                                    &
+                                     ) - 1
+                k_wall_w_ji_m  = MAXLOC(                                       &
+                            MERGE( 1, 0,                                       &
+                          BTEST( wall_flags_0(nzb:nzt_topo_nestbc_s,-1,i-1), 28 )&
+                                     ), DIM = 1                                &
+                                        ) - 1
                 DO  k = nzb, nzt_topo_nestbc_s
 !
 !--                Wall for v on the left side, but not on the right side
                    j  = 0
-                   IF ( ( nzb_v_outer(j,i) > nzb_v_outer(j,i+1) )  .AND.        &
-                        ( nzb_v_outer(j,i) == nzb_v_outer(j,i-1) ) )  THEN
+                   IF ( ( k_wall_v_ji > k_wall_v_ji_p )  .AND.                 &
+                        ( k_wall_v_ji == k_wall_v_ji_m ) )  THEN
                       inc        =  1
                       wall_index =  i
-                      CALL pmci_define_loglaw_correction_parameters( lc, lcr,   &
-                          k, i, inc, wall_index, z0(j,i), kb, direction, ncorr )
+                      CALL pmci_define_loglaw_correction_parameters( lc, lcr,  &
+                          k, i, inc, wall_index, z0_topo, kb, direction, ncorr )
 !
 !--                   The direction of the wall-normal index is stored as the
@@ -1781,10 +2357,10 @@
 !--                Wall for v on the right side, but not on the left side
                    j  = 0
-                   IF ( ( nzb_v_outer(j,i) > nzb_v_outer(j,i-1) )  .AND.        &
-                        ( nzb_v_outer(j,i) == nzb_v_outer(j,i+1) ) )  THEN
+                   IF ( ( k_wall_v_ji > k_wall_v_ji_m )  .AND.                 &
+                        ( k_wall_v_ji == k_wall_v_ji_p ) )  THEN
                       inc        = -1
                       wall_index =  i+1
-                      CALL pmci_define_loglaw_correction_parameters( lc, lcr,   &
-                          k, i, inc, wall_index, z0(j,i), kb, direction, ncorr )
+                      CALL pmci_define_loglaw_correction_parameters( lc, lcr,  &
+                          k, i, inc, wall_index, z0_topo, kb, direction, ncorr )
 !
 !--                   The direction of the wall-normal index is stored as the
@@ -1798,10 +2374,10 @@
 !--                Wall for w on the left side, but not on the right side
                    j  = -1
-                   IF ( ( nzb_w_outer(j,i) > nzb_w_outer(j,i+1) )  .AND.        &
-                        ( nzb_w_outer(j,i) == nzb_w_outer(j,i-1) ) )  THEN
+                   IF ( ( k_wall_w_ji > k_wall_w_ji_p )  .AND.                 &
+                        ( k_wall_w_ji == k_wall_w_ji_m ) )  THEN
                       inc        =  1
                       wall_index =  i
-                      CALL pmci_define_loglaw_correction_parameters( lc, lcr,   &
-                          k, i, inc, wall_index, z0(j,i), kb, direction, ncorr )
+                      CALL pmci_define_loglaw_correction_parameters( lc, lcr,  &
+                          k, i, inc, wall_index, z0_topo, kb, direction, ncorr )
 !
 !--                   The direction of the wall-normal index is stored as the
@@ -1815,10 +2391,10 @@
 !--                Wall for w on the right side, but not on the left side
                    j  = -1
-                   IF ( ( nzb_w_outer(j,i) > nzb_w_outer(j,i-1) )  .AND.        &
-                        ( nzb_w_outer(j,i) == nzb_w_outer(j,i+1) ) )  THEN
+                   IF ( ( k_wall_w_ji > k_wall_w_ji_m )  .AND.                 &
+                        ( k_wall_w_ji == k_wall_w_ji_p ) )  THEN
                       inc        = -1
                       wall_index =  i+1
-                      CALL pmci_define_loglaw_correction_parameters( lc, lcr,   &
-                          k, i, inc, wall_index, z0(j,i), kb, direction, ncorr )
+                      CALL pmci_define_loglaw_correction_parameters( lc, lcr,  &
+                          k, i, inc, wall_index, z0_topo, kb, direction, ncorr )
 !
 !--                   The direction of the wall-normal index is stored as the
@@ -1842,13 +2418,45 @@
 
              DO  i = nxl, nxr
+                k_wall_v_ji    = MAXLOC(                                       &
+                            MERGE( 1, 0,                                       &
+                          BTEST( wall_flags_0(nzb:nzt_topo_nestbc_n,j,i), 27 ) &
+                                 ), DIM = 1                                    &
+                                       ) - 1
+
+                k_wall_v_ji_p  = MAXLOC(                                       &
+                            MERGE( 1, 0,                                       &
+                          BTEST( wall_flags_0(nzb:nzt_topo_nestbc_n,j,i+1), 27 )&
+                                 ), DIM = 1                                    &
+                                       ) - 1
+                k_wall_v_ji_m  = MAXLOC(                                       &
+                            MERGE( 1, 0,                                       &
+                          BTEST( wall_flags_0(nzb:nzt_topo_nestbc_n,j,i-1), 27 )&
+                                     ), DIM = 1                                &
+                                       ) - 1
+
+                k_wall_w_ji    = MAXLOC(                                       &
+                            MERGE( 1, 0,                                       &
+                          BTEST( wall_flags_0(nzb:nzt_topo_nestbc_n,j,i), 28 )  &
+                                 ), DIM = 1                                    &
+                                       ) - 1
+                k_wall_w_ji_p  = MAXLOC(                                       &
+                            MERGE( 1, 0,                                       &
+                          BTEST( wall_flags_0(nzb:nzt_topo_nestbc_n,j,i+1), 28 )&
+                                 ), DIM = 1                                    &
+                                       ) - 1
+                k_wall_w_ji_m  = MAXLOC(                                       &
+                            MERGE( 1, 0,                                       &
+                          BTEST( wall_flags_0(nzb:nzt_topo_nestbc_n,j,i-1), 28 )&
+                                     ), DIM = 1                                &
+                                       ) - 1
                 DO  k = nzb, nzt_topo_nestbc_n
 !
 !--                Wall for v on the left side, but not on the right side
-                   IF ( ( nzb_v_outer(j,i) > nzb_v_outer(j,i+1) )  .AND.        &
-                        ( nzb_v_outer(j,i) == nzb_v_outer(j,i-1) ) )  THEN
+                   IF ( ( k_wall_v_ji > k_wall_v_ji_p )  .AND.                 &
+                        ( k_wall_v_ji == k_wall_v_ji_m ) )  THEN
                       inc        = 1
                       wall_index = i
-                      CALL pmci_define_loglaw_correction_parameters( lc, lcr,   &
-                          k, i, inc, wall_index, z0(j,i), kb, direction, ncorr )
+                      CALL pmci_define_loglaw_correction_parameters( lc, lcr,  &
+                          k, i, inc, wall_index, z0_topo, kb, direction, ncorr )
 !
 !--                   The direction of the wall-normal index is stored as the
@@ -1861,10 +2469,10 @@
 !
 !--                Wall for v on the right side, but not on the left side
-                   IF ( ( nzb_v_outer(j,i) > nzb_v_outer(j,i-1) )  .AND.        &
-                        ( nzb_v_outer(j,i) == nzb_v_outer(j,i+1) ) )  THEN
+                   IF ( ( k_wall_v_ji > k_wall_v_ji_m )  .AND.                 &
+                        ( k_wall_v_ji == k_wall_v_ji_p ) )  THEN
                       inc        = -1
                       wall_index =  i + 1
-                      CALL pmci_define_loglaw_correction_parameters( lc, lcr,   &
-                          k, i, inc, wall_index, z0(j,i), kb, direction, ncorr )
+                      CALL pmci_define_loglaw_correction_parameters( lc, lcr,  &
+                          k, i, inc, wall_index, z0_topo, kb, direction, ncorr )
 !
 !--                   The direction of the wall-normal index is stored as the
@@ -1877,10 +2485,10 @@
 !
 !--                Wall for w on the left side, but not on the right side
-                   IF ( ( nzb_w_outer(j,i) > nzb_w_outer(j,i+1) )  .AND.        &
-                        ( nzb_w_outer(j,i) == nzb_w_outer(j,i-1) ) )  THEN
+                   IF ( ( k_wall_v_ji > k_wall_v_ji_p )  .AND.                 &
+                        ( k_wall_v_ji == k_wall_v_ji_m ) )  THEN
                       inc        = 1
                       wall_index = i
-                      CALL pmci_define_loglaw_correction_parameters( lc, lcr,   &
-                          k, i, inc, wall_index, z0(j,i), kb, direction, ncorr )
+                      CALL pmci_define_loglaw_correction_parameters( lc, lcr,  &
+                          k, i, inc, wall_index, z0_topo, kb, direction, ncorr )
 !
 !--                   The direction of the wall-normal index is stored as the
@@ -1893,10 +2501,10 @@
 !
 !--                Wall for w on the right side, but not on the left side
-                   IF ( ( nzb_w_outer(j,i) > nzb_w_outer(j,i-1) )  .AND.        &
-                        ( nzb_w_outer(j,i) == nzb_w_outer(j,i+1) ) )  THEN
+                   IF ( ( k_wall_v_ji > k_wall_v_ji_m )  .AND.                 &
+                        ( k_wall_v_ji == k_wall_v_ji_p ) )  THEN
                       inc        = -1
                       wall_index =  i+1
                       CALL pmci_define_loglaw_correction_parameters( lc, lcr,   &
-                          k, i, inc, wall_index, z0(j,i), kb, direction, ncorr )
+                          k, i, inc, wall_index, z0_topo, kb, direction, ncorr )
 !
 !--                   The direction of the wall-normal index is stored as the
@@ -2416,5 +3024,5 @@
 
 
-    SUBROUTINE pmci_init_tkefactor
+SUBROUTINE pmci_init_tkefactor
 
 !
@@ -2426,4 +3034,9 @@
 
        IMPLICIT NONE
+
+       INTEGER(iwp)        ::  k                     !: index variable along z
+       INTEGER(iwp)        ::  k_wall                !: topography-top index along z
+       INTEGER(iwp)        ::  kc                    !:
+
        REAL(wp), PARAMETER ::  cfw = 0.2_wp          !:
        REAL(wp), PARAMETER ::  c_tkef = 0.6_wp       !:
@@ -2434,8 +3047,5 @@
        REAL(wp)            ::  height                !:
        REAL(wp), PARAMETER ::  p13 = 1.0_wp/3.0_wp   !:
-       REAL(wp), PARAMETER ::  p23 = 2.0_wp/3.0_wp   !:
-       INTEGER(iwp)        ::  k                     !:
-       INTEGER(iwp)        ::  kc                    !:
-        
+       REAL(wp), PARAMETER ::  p23 = 2.0_wp/3.0_wp   !:        
 
        IF ( nest_bound_l )  THEN
@@ -2444,14 +3054,21 @@
           i = nxl - 1
           DO  j = nysg, nyng
-             DO  k = nzb_s_inner(j,i) + 1, nzt
+             k_wall = MAXLOC(                                                  &
+                          MERGE( 1, 0,                                         &
+                                 BTEST( wall_flags_0(nzb:nzb_max,j,i), 12 )    &
+                               ), DIM = 1                                      &
+                            ) - 1
+
+             DO  k = k_wall + 1, nzt
+
                 kc     = kco(k+1)
                 glsf   = ( dx * dy * dzu(k) )**p13
                 glsc   = ( cg%dx * cg%dy *cg%dzu(kc) )**p13
-                height = zu(k) - zu(nzb_s_inner(j,i))
+                height = zu(k) - zu(k_wall)
                 fw     = EXP( -cfw * height / glsf )
                 tkefactor_l(k,j) = c_tkef * ( fw0 * fw + ( 1.0_wp - fw ) *      &
                                               ( glsf / glsc )**p23 )
              ENDDO
-             tkefactor_l(nzb_s_inner(j,i),j) = c_tkef * fw0
+             tkefactor_l(k_wall,j) = c_tkef * fw0
           ENDDO
        ENDIF
@@ -2462,14 +3079,21 @@
           i = nxr + 1
           DO  j = nysg, nyng
-             DO  k = nzb_s_inner(j,i) + 1, nzt
+             k_wall = MAXLOC(                                                  &
+                          MERGE( 1, 0,                                         &
+                                 BTEST( wall_flags_0(nzb:nzb_max,j,i), 12 )    &
+                               ), DIM = 1                                      &
+                            ) - 1
+
+             DO  k = k_wall + 1, nzt
+
                 kc     = kco(k+1)
                 glsf   = ( dx * dy * dzu(k) )**p13
                 glsc   = ( cg%dx * cg%dy * cg%dzu(kc) )**p13
-                height = zu(k) - zu(nzb_s_inner(j,i))
+                height = zu(k) - zu(k_wall)
                 fw     = EXP( -cfw * height / glsf )
                 tkefactor_r(k,j) = c_tkef * ( fw0 * fw + ( 1.0_wp - fw ) *      &
                                               ( glsf / glsc )**p23 )
              ENDDO
-             tkefactor_r(nzb_s_inner(j,i),j) = c_tkef * fw0
+             tkefactor_r(k_wall,j) = c_tkef * fw0
           ENDDO
        ENDIF
@@ -2480,14 +3104,21 @@
           j = nys - 1
           DO  i = nxlg, nxrg
-             DO  k = nzb_s_inner(j,i) + 1, nzt
+             k_wall = MAXLOC(                                                  &
+                          MERGE( 1, 0,                                         &
+                                 BTEST( wall_flags_0(nzb:nzb_max,j,i), 12 )    &
+                               ), DIM = 1                                      &
+                            ) - 1
+
+             DO  k = k_wall + 1, nzt
+
                 kc     = kco(k+1)
                 glsf   = ( dx * dy * dzu(k) )**p13
                 glsc   = ( cg%dx * cg%dy * cg%dzu(kc) ) ** p13
-                height = zu(k) - zu(nzb_s_inner(j,i))
+                height = zu(k) - zu(k_wall)
                 fw     = EXP( -cfw*height / glsf )
                 tkefactor_s(k,i) = c_tkef * ( fw0 * fw + ( 1.0_wp - fw ) *      &
                                               ( glsf / glsc )**p23 )
              ENDDO
-             tkefactor_s(nzb_s_inner(j,i),i) = c_tkef * fw0
+             tkefactor_s(k_wall,i) = c_tkef * fw0
           ENDDO
        ENDIF
@@ -2498,14 +3129,20 @@
           j = nyn + 1
           DO  i = nxlg, nxrg
-             DO  k = nzb_s_inner(j,i)+1, nzt
+             k_wall = MAXLOC(                                                  &
+                          MERGE( 1, 0,                                         &
+                                 BTEST( wall_flags_0(nzb:nzb_max,j,i), 12 )    &
+                               ), DIM = 1                                      &
+                            ) - 1
+             DO  k = k_wall + 1, nzt
+
                 kc     = kco(k+1)
                 glsf   = ( dx * dy * dzu(k) )**p13
                 glsc   = ( cg%dx * cg%dy * cg%dzu(kc) )**p13
-                height = zu(k) - zu(nzb_s_inner(j,i))
+                height = zu(k) - zu(k_wall)
                 fw     = EXP( -cfw * height / glsf )
-                tkefactor_n(k,i) = c_tkef * ( fw0 * fw + ( 1.0_wp - fw ) *      &
+                tkefactor_n(k,i) = c_tkef * ( fw0 * fw + ( 1.0_wp - fw ) *     &
                                               ( glsf / glsc )**p23 )
              ENDDO
-             tkefactor_n(nzb_s_inner(j,i),i) = c_tkef * fw0
+             tkefactor_n(k_wall,i) = c_tkef * fw0
           ENDDO
        ENDIF
@@ -2513,12 +3150,21 @@
        ALLOCATE( tkefactor_t(nysg:nyng,nxlg:nxrg) )
        k = nzt
+
        DO  i = nxlg, nxrg
           DO  j = nysg, nyng
+!
+!--          Determine vertical index for local topography top
+             k_wall = MAXLOC(                                                  &
+                        MERGE( 1, 0,                                           &
+                               BTEST( wall_flags_0(nzb:nzb_max,j,i), 12 )      &
+                             ), DIM = 1                                        &
+                            ) - 1
+
              kc     = kco(k+1)
              glsf   = ( dx * dy * dzu(k) )**p13
              glsc   = ( cg%dx * cg%dy * cg%dzu(kc) )**p13
-             height = zu(k) - zu(nzb_s_inner(j,i))
+             height = zu(k) - zu(k_wall)
              fw     = EXP( -cfw * height / glsf )
-             tkefactor_t(j,i) = c_tkef * ( fw0 * fw + ( 1.0_wp - fw ) *         &
+             tkefactor_t(j,i) = c_tkef * ( fw0 * fw + ( 1.0_wp - fw ) *        &
                                            ( glsf / glsc )**p23 )
           ENDDO
@@ -2783,4 +3429,5 @@
     INTEGER(iwp) ::  jcn        !:
     INTEGER(iwp) ::  jcs        !:
+    INTEGER(iwp) ::  k          !:
 
     REAL(wp) ::  waittime       !:
@@ -2804,15 +3451,15 @@
 !--    The interpolation.
        CALL pmci_interp_tril_all ( u,  uc,  icu, jco, kco, r1xu, r2xu, r1yo,    &
-                                   r2yo, r1zo, r2zo, nzb_u_inner, 'u' )
+                                   r2yo, r1zo, r2zo, 'u' )
        CALL pmci_interp_tril_all ( v,  vc,  ico, jcv, kco, r1xo, r2xo, r1yv,    &
-                                   r2yv, r1zo, r2zo, nzb_v_inner, 'v' )
+                                   r2yv, r1zo, r2zo, 'v' )
        CALL pmci_interp_tril_all ( w,  wc,  ico, jco, kcw, r1xo, r2xo, r1yo,    &
-                                   r2yo, r1zw, r2zw, nzb_w_inner, 'w' )
+                                   r2yo, r1zw, r2zw, 'w' )
        CALL pmci_interp_tril_all ( e,  ec,  ico, jco, kco, r1xo, r2xo, r1yo,    &
-                                   r2yo, r1zo, r2zo, nzb_s_inner, 'e' )
+                                   r2yo, r1zo, r2zo, 'e' )
 
        IF ( .NOT. neutral )  THEN
           CALL pmci_interp_tril_all ( pt, ptc, ico, jco, kco, r1xo, r2xo,       &
-                                      r1yo, r2yo, r1zo, r2zo, nzb_s_inner, 's' )
+                                      r1yo, r2yo, r1zo, r2zo, 's' )
        ENDIF
 
@@ -2820,19 +3467,15 @@
 
           CALL pmci_interp_tril_all ( q, q_c, ico, jco, kco, r1xo, r2xo, r1yo,   &
-                                      r2yo, r1zo, r2zo, nzb_s_inner, 's' )
+                                      r2yo, r1zo, r2zo, 's' )
 
           IF ( cloud_physics  .AND.  microphysics_seifert )  THEN
 !              CALL pmci_interp_tril_all ( qc, qcc, ico, jco, kco, r1xo, r2xo,    &
-!                                          r1yo, r2yo, r1zo, r2zo, nzb_s_inner,   & 
-!                                          's' ) 
+!                                          r1yo, r2yo, r1zo, r2zo, 's' ) 
              CALL pmci_interp_tril_all ( qr, qrc, ico, jco, kco, r1xo, r2xo,    &
-                                         r1yo, r2yo, r1zo, r2zo, nzb_s_inner,   & 
-                                         's' )
+                                         r1yo, r2yo, r1zo, r2zo, 's' )
 !             CALL pmci_interp_tril_all ( nc, ncc, ico, jco, kco, r1xo, r2xo,    &
-!                                         r1yo, r2yo, r1zo, r2zo, nzb_s_inner,   & 
-!                                         's' )   
+!                                         r1yo, r2yo, r1zo, r2zo, 's' )   
              CALL pmci_interp_tril_all ( nr, nrc, ico, jco, kco, r1xo, r2xo,    &
-                                         r1yo, r2yo, r1zo, r2zo, nzb_s_inner,   & 
-                                         's' )
+                                         r1yo, r2yo, r1zo, r2zo, 's' )
           ENDIF
 
@@ -2841,5 +3484,5 @@
        IF ( passive_scalar )  THEN
           CALL pmci_interp_tril_all ( s, sc, ico, jco, kco, r1xo, r2xo, r1yo,   &
-                                      r2yo, r1zo, r2zo, nzb_s_inner, 's' )
+                                      r2yo, r1zo, r2zo, 's' )
        ENDIF
 
@@ -2851,12 +3494,22 @@
           DO   i = nxlg, nxrg
              DO   j = nysg, nyng
-                u(nzb:nzb_u_inner(j,i),j,i)   = 0.0_wp
-                v(nzb:nzb_v_inner(j,i),j,i)   = 0.0_wp
-                w(nzb:nzb_w_inner(j,i),j,i)   = 0.0_wp
-                e(nzb:nzb_s_inner(j,i),j,i)   = 0.0_wp
-                u_p(nzb:nzb_u_inner(j,i),j,i) = 0.0_wp
-                v_p(nzb:nzb_v_inner(j,i),j,i) = 0.0_wp
-                w_p(nzb:nzb_w_inner(j,i),j,i) = 0.0_wp
-                e_p(nzb:nzb_s_inner(j,i),j,i) = 0.0_wp
+                DO  k = nzb, nzt
+                   u(k,j,i)   = MERGE( u(k,j,i), 0.0_wp,                       &
+                                       BTEST( wall_flags_0(k,j,i), 1 ) )
+                   v(k,j,i)   = MERGE( v(k,j,i), 0.0_wp,                       &
+                                       BTEST( wall_flags_0(k,j,i), 2 ) )
+                   w(k,j,i)   = MERGE( w(k,j,i), 0.0_wp,                       &
+                                       BTEST( wall_flags_0(k,j,i), 3 ) )
+                   e(k,j,i)   = MERGE( e(k,j,i), 0.0_wp,                       &
+                                       BTEST( wall_flags_0(k,j,i), 0 ) )
+                   u_p(k,j,i) = MERGE( u_p(k,j,i), 0.0_wp,                     &
+                                       BTEST( wall_flags_0(k,j,i), 1 ) )
+                   v_p(k,j,i) = MERGE( v_p(k,j,i), 0.0_wp,                     &
+                                       BTEST( wall_flags_0(k,j,i), 2 ) )
+                   w_p(k,j,i) = MERGE( w_p(k,j,i), 0.0_wp,                     &
+                                       BTEST( wall_flags_0(k,j,i), 3 ) )
+                   e_p(k,j,i) = MERGE( e_p(k,j,i), 0.0_wp,                     &
+                                       BTEST( wall_flags_0(k,j,i), 0 ) )
+                ENDDO
              ENDDO
           ENDDO
@@ -2869,5 +3522,5 @@
 
     SUBROUTINE pmci_interp_tril_all( f, fc, ic, jc, kc, r1x, r2x, r1y, r2y,     &
-                                     r1z, r2z, kb, var )
+                                     r1z, r2z, var )
 !
 !--    Interpolation of the internal values for the child-domain initialization
@@ -2881,18 +3534,20 @@
        INTEGER(iwp), DIMENSION(nysg:nyng), INTENT(IN)           ::  jc    !:
        INTEGER(iwp), DIMENSION(nzb:nzt+1), INTENT(IN)           ::  kc    !:
-       INTEGER(iwp), DIMENSION(nysg:nyng,nxlg:nxrg), INTENT(IN) ::  kb    !:
-
-       INTEGER(iwp) ::  i      !:
-       INTEGER(iwp) ::  ib     !:
-       INTEGER(iwp) ::  ie     !:
-       INTEGER(iwp) ::  j      !:
-       INTEGER(iwp) ::  jb     !:
-       INTEGER(iwp) ::  je     !:
-       INTEGER(iwp) ::  k      !:
-       INTEGER(iwp) ::  k1     !:
-       INTEGER(iwp) ::  kbc    !:
-       INTEGER(iwp) ::  l      !:
-       INTEGER(iwp) ::  m      !:
-       INTEGER(iwp) ::  n      !:
+
+       INTEGER(iwp) ::  flag_nr  !: Number of flag array to mask topography on respective u/v/w or s grid
+       INTEGER(iwp) ::  flag_nr2 !: Number of flag array to indicate vertical index of topography top on respective u/v/w or s grid
+       INTEGER(iwp) ::  i        !:
+       INTEGER(iwp) ::  ib       !:
+       INTEGER(iwp) ::  ie       !:
+       INTEGER(iwp) ::  j        !:
+       INTEGER(iwp) ::  jb       !:
+       INTEGER(iwp) ::  je       !:
+       INTEGER(iwp) ::  k        !:
+       INTEGER(iwp) ::  k_wall   !:
+       INTEGER(iwp) ::  k1       !:
+       INTEGER(iwp) ::  kbc      !:
+       INTEGER(iwp) ::  l        !:
+       INTEGER(iwp) ::  m        !:
+       INTEGER(iwp) ::  n        !:
 
        REAL(wp), DIMENSION(nzb:nzt+1,nysg:nyng,nxlg:nxrg), INTENT(INOUT) :: f !:
@@ -2914,4 +3569,5 @@
        REAL(wp) ::  logzuc1    !:
        REAL(wp) ::  zuc1       !:
+       REAL(wp) ::  z0_topo    !:  roughness at vertical walls
 
 
@@ -2945,8 +3601,23 @@
        ENDIF
 !
+!--    Determine number of flag array to be used to mask topography
+       IF ( var == 'u' )  THEN
+          flag_nr  = 1
+          flag_nr2 = 14
+       ELSEIF ( var == 'v' )  THEN
+          flag_nr  = 2
+          flag_nr2 = 16
+       ELSEIF ( var == 'w' )  THEN
+          flag_nr  = 3
+          flag_nr2 = 18
+       ELSE
+          flag_nr  = 0
+          flag_nr2 = 12
+       ENDIF
+!
 !--    Trilinear interpolation.
        DO  i = ib, ie
           DO  j = jb, je
-             DO  k = kb(j,i), nzt + 1
+             DO  k = nzb, nzt + 1
                 l = ic(i)
                 m = jc(j)
@@ -2970,27 +3641,35 @@
 !--    too.
        IF ( var == 'u' .OR. var == 'v' )  THEN
+          z0_topo = roughness_length
           DO  i = ib, nxr
              DO  j = jb, nyn
+!
+!--             Determine vertical index of topography top at grid point (j,i)
+                k_wall = MAXLOC(                                               &
+                      MERGE( 1, 0,                                             &
+                             BTEST( wall_flags_0(nzb:nzb_max,j,i), flag_nr2 )  &
+                           ), DIM = 1                                          &
+                               ) - 1
+!
+!--             kbc is the first coarse-grid point above the surface
                 kbc = 1
-!
-!--             kbc is the first coarse-grid point above the surface
-                DO  WHILE ( cg%zu(kbc) < zu(kb(j,i)) )
+                DO  WHILE ( cg%zu(kbc) < zu(k_wall) )
                    kbc = kbc + 1
                 ENDDO
                 zuc1 = cg%zu(kbc)
-                k1   = kb(j,i) + 1
+                k1   = k_wall + 1
                 DO  WHILE ( zu(k1) < zuc1 )
                    k1 = k1 + 1
                 ENDDO
-                logzuc1 = LOG( ( zu(k1) - zu(kb(j,i)) ) / z0(j,i) )
-
-                k = kb(j,i) + 1
+                logzuc1 = LOG( ( zu(k1) - zu(k_wall) ) / z0_topo )
+
+                k = k_wall + 1
                 DO  WHILE ( zu(k) < zuc1 )
-                   logratio = ( LOG( ( zu(k) - zu(kb(j,i)) ) / z0(j,i)) ) /     &
+                   logratio = ( LOG( ( zu(k) - zu(k_wall) ) / z0_topo ) ) /     &
                                 logzuc1
                    f(k,j,i) = logratio * f(k1,j,i)
                    k  = k + 1
                 ENDDO
-                f(kb(j,i),j,i) = 0.0_wp
+                f(k_wall,j,i) = 0.0_wp
              ENDDO
           ENDDO
@@ -3000,7 +3679,15 @@
           DO  i = ib, nxr
               DO  j = jb, nyn
-                f(kb(j,i),j,i) = 0.0_wp
-             ENDDO
-          ENDDO
+!
+!--              Determine vertical index of topography top at grid point (j,i)
+                 k_wall = MAXLOC(                                              &
+                      MERGE( 1, 0,                                             &
+                             BTEST( wall_flags_0(nzb:nzb_max,j,i), flag_nr2 )  &
+                           ), DIM = 1                                          &
+                                ) - 1
+
+                 f(k_wall,j,i) = 0.0_wp
+              ENDDO
+           ENDDO
 
        ENDIF
@@ -3137,6 +3824,8 @@
        innor = dy
        DO   j = nys, nyn
-          DO   k = nzb_u_inner(j,i)+1, nzt
-             volume_flow_l(1) = volume_flow_l(1) + innor * u(k,j,i) * dzw(k)
+          DO   k = nzb+1, nzt
+             volume_flow_l(1) = volume_flow_l(1) + innor * u(k,j,i) * dzw(k)   &
+                                     * MERGE( 1.0_wp, 0.0_wp,                  &
+                                              BTEST( wall_flags_0(k,j,i), 1 ) )
           ENDDO
        ENDDO
@@ -3147,6 +3836,8 @@
        innor = -dy
        DO   j = nys, nyn
-          DO   k = nzb_u_inner(j,i)+1, nzt
-             volume_flow_l(1) = volume_flow_l(1) + innor * u(k,j,i) * dzw(k)
+          DO   k = nzb+1, nzt
+             volume_flow_l(1) = volume_flow_l(1) + innor * u(k,j,i) * dzw(k)   &
+                                     * MERGE( 1.0_wp, 0.0_wp,                  &
+                                              BTEST( wall_flags_0(k,j,i), 1 ) )
           ENDDO
        ENDDO
@@ -3170,6 +3861,8 @@
        innor = dx
        DO   i = nxl, nxr
-          DO   k = nzb_v_inner(j,i)+1, nzt
-             volume_flow_l(2) = volume_flow_l(2) + innor * v(k,j,i) * dzw(k)
+          DO   k = nzb+1, nzt
+             volume_flow_l(2) = volume_flow_l(2) + innor * v(k,j,i) * dzw(k)   &
+                                     * MERGE( 1.0_wp, 0.0_wp,                  &
+                                              BTEST( wall_flags_0(k,j,i), 2 ) )
           ENDDO
        ENDDO
@@ -3180,6 +3873,8 @@
        innor = -dx
        DO   i = nxl, nxr
-          DO   k = nzb_v_inner(j,i)+1, nzt
-             volume_flow_l(2) = volume_flow_l(2) + innor * v(k,j,i) * dzw(k)
+          DO   k = nzb+1, nzt
+             volume_flow_l(2) = volume_flow_l(2) + innor * v(k,j,i) * dzw(k)   &
+                                     * MERGE( 1.0_wp, 0.0_wp,                  &
+                                              BTEST( wall_flags_0(k,j,i), 2 ) )
           ENDDO
        ENDDO
@@ -3340,6 +4035,7 @@
     INTEGER(iwp) ::  child_id    !:
     INTEGER(iwp) ::  i           !:
+    INTEGER(iwp) ::  ierr        !:
     INTEGER(iwp) ::  j           !:
-    INTEGER(iwp) ::  ierr        !:
+    INTEGER(iwp) ::  k           !:
     INTEGER(iwp) ::  m           !:
 
@@ -3374,8 +4070,13 @@
              DO   i = nxlg, nxrg
                 DO   j = nysg, nyng
-                   u(nzb:nzb_u_inner(j,i),j,i)  = 0.0_wp
-                   v(nzb:nzb_v_inner(j,i),j,i)  = 0.0_wp
-                   w(nzb:nzb_w_inner(j,i),j,i)  = 0.0_wp
-                   e(nzb:nzb_s_inner(j,i),j,i)  = 0.0_wp
+                   DO  k = nzb, nzt+1
+                      u(k,j,i)  = MERGE( u(k,j,i), 0.0_wp,                     &
+                                         BTEST( wall_flags_0(k,j,i), 1 ) )
+                      v(k,j,i)  = MERGE( v(k,j,i), 0.0_wp,                     &
+                                         BTEST( wall_flags_0(k,j,i), 2 ) )
+                      w(k,j,i)  = MERGE( w(k,j,i), 0.0_wp,                     &
+                                         BTEST( wall_flags_0(k,j,i), 3 ) )
+                      e(k,j,i)  = MERGE( e(k,j,i), 0.0_wp,                     &
+                                         BTEST( wall_flags_0(k,j,i), 0 ) )
 !
 !--                TO_DO: zero setting of temperature within topography creates
@@ -3385,4 +4086,5 @@
 !                      q(nzb:nzb_s_inner(j,i),j,i) = 0.0_wp
 !                   ENDIF
+                   ENDDO
                 ENDDO
              ENDDO
@@ -3463,20 +4165,20 @@
           IF ( nest_bound_l )  THEN
              CALL pmci_interp_tril_lr( u,  uc,  icu, jco, kco, r1xu, r2xu,      &
-                                       r1yo, r2yo, r1zo, r2zo, nzb_u_inner,     &
+                                       r1yo, r2yo, r1zo, r2zo,                  &
                                        logc_u_l, logc_ratio_u_l,                &
                                        nzt_topo_nestbc_l, 'l', 'u' )
 
              CALL pmci_interp_tril_lr( v,  vc,  ico, jcv, kco, r1xo, r2xo,      &
-                                       r1yv, r2yv, r1zo, r2zo, nzb_v_inner,     &
+                                       r1yv, r2yv, r1zo, r2zo,                  &
                                        logc_v_l, logc_ratio_v_l,                &
                                        nzt_topo_nestbc_l, 'l', 'v' )
 
              CALL pmci_interp_tril_lr( w,  wc,  ico, jco, kcw, r1xo, r2xo,      &
-                                       r1yo, r2yo, r1zw, r2zw, nzb_w_inner,     &
+                                       r1yo, r2yo, r1zw, r2zw,                  &
                                        logc_w_l, logc_ratio_w_l,                &
                                        nzt_topo_nestbc_l, 'l', 'w' )
 
              CALL pmci_interp_tril_lr( e,  ec,  ico, jco, kco, r1xo, r2xo,      &
-                                       r1yo, r2yo, r1zo, r2zo, nzb_s_inner,     &
+                                       r1yo, r2yo, r1zo, r2zo,                  &
                                        logc_u_l, logc_ratio_u_l,                &
                                        nzt_topo_nestbc_l, 'l', 'e' )
@@ -3484,5 +4186,5 @@
              IF ( .NOT. neutral )  THEN
                 CALL pmci_interp_tril_lr( pt, ptc, ico, jco, kco, r1xo, r2xo,   &
-                                          r1yo, r2yo, r1zo, r2zo, nzb_s_inner,  &
+                                          r1yo, r2yo, r1zo, r2zo,               &
                                           logc_u_l, logc_ratio_u_l,             &
                                           nzt_topo_nestbc_l, 'l', 's' )
@@ -3492,5 +4194,5 @@
 
                 CALL pmci_interp_tril_lr( q, q_c, ico, jco, kco, r1xo, r2xo,    &
-                                          r1yo, r2yo, r1zo, r2zo, nzb_s_inner,  &
+                                          r1yo, r2yo, r1zo, r2zo,               &
                                           logc_u_l, logc_ratio_u_l,             &
                                           nzt_topo_nestbc_l, 'l', 's' )
@@ -3500,5 +4202,5 @@
 !                    CALL pmci_interp_tril_lr( qc, qcc, ico, jco, kco, r1xo, r2xo,&
 !                                              r1yo, r2yo, r1zo, r2zo,            &
-!                                              nzb_s_inner, logc_u_l,             &
+!                                              logc_u_l,                          &
 !                                              logc_ratio_u_l, nzt_topo_nestbc_l, &
 !                                              'l', 's' )  
@@ -3506,5 +4208,5 @@
                    CALL pmci_interp_tril_lr( qr, qrc, ico, jco, kco, r1xo, r2xo,&
                                              r1yo, r2yo, r1zo, r2zo,            &
-                                             nzb_s_inner, logc_u_l,             &
+                                             logc_u_l,                          &
                                              logc_ratio_u_l, nzt_topo_nestbc_l, &
                                              'l', 's' ) 
@@ -3512,5 +4214,5 @@
 !                    CALL pmci_interp_tril_lr( nc, ncc, ico, jco, kco, r1xo, r2xo,&
 !                                              r1yo, r2yo, r1zo, r2zo,            &
-!                                              nzb_s_inner, logc_u_l,             &
+!                                              logc_u_l,                          &
 !                                              logc_ratio_u_l, nzt_topo_nestbc_l, &
 !                                              'l', 's' ) 
@@ -3518,5 +4220,5 @@
                    CALL pmci_interp_tril_lr( nr, nrc, ico, jco, kco, r1xo, r2xo,&
                                              r1yo, r2yo, r1zo, r2zo,            &
-                                             nzb_s_inner, logc_u_l,             &
+                                             logc_u_l,                          &
                                              logc_ratio_u_l, nzt_topo_nestbc_l, &
                                              'l', 's' )             
@@ -3527,5 +4229,5 @@
              IF ( passive_scalar )  THEN
                 CALL pmci_interp_tril_lr( s, sc, ico, jco, kco, r1xo, r2xo,     &
-                                          r1yo, r2yo, r1zo, r2zo, nzb_s_inner,  &
+                                          r1yo, r2yo, r1zo, r2zo,               &
                                           logc_u_l, logc_ratio_u_l,             &
                                           nzt_topo_nestbc_l, 'l', 's' )
@@ -3533,24 +4235,22 @@
 
              IF ( TRIM( nesting_mode ) == 'one-way' )  THEN
-
-                CALL pmci_extrap_ifoutflow_lr( u, nzb_u_inner, 'l', 'u' )
-                CALL pmci_extrap_ifoutflow_lr( v, nzb_v_inner, 'l', 'v' )
-                CALL pmci_extrap_ifoutflow_lr( w, nzb_w_inner, 'l', 'w' )
-                CALL pmci_extrap_ifoutflow_lr( e, nzb_s_inner, 'l', 'e' )
+                CALL pmci_extrap_ifoutflow_lr( u, 'l', 'u' )
+                CALL pmci_extrap_ifoutflow_lr( v, 'l', 'v' )
+                CALL pmci_extrap_ifoutflow_lr( w, 'l', 'w' )
+                CALL pmci_extrap_ifoutflow_lr( e, 'l', 'e' )
 
                 IF ( .NOT. neutral )  THEN
-                   CALL pmci_extrap_ifoutflow_lr( pt,nzb_s_inner, 'l', 's' )
+                   CALL pmci_extrap_ifoutflow_lr( pt, 'l', 's' )
                 ENDIF
 
                 IF ( humidity )  THEN
-
-                   CALL pmci_extrap_ifoutflow_lr( q, nzb_s_inner, 'l', 's' )
+                   CALL pmci_extrap_ifoutflow_lr( q, 'l', 's' )
 
                    IF ( cloud_physics  .AND.  microphysics_seifert )  THEN
 
-!                       CALL pmci_extrap_ifoutflow_lr( qc, nzb_s_inner, 'l', 's' )
-                      CALL pmci_extrap_ifoutflow_lr( qr, nzb_s_inner, 'l', 's' )
-!                      CALL pmci_extrap_ifoutflow_lr( nc, nzb_s_inner, 'l', 's' )
-                      CALL pmci_extrap_ifoutflow_lr( nr, nzb_s_inner, 'l', 's' )
+!                       CALL pmci_extrap_ifoutflow_lr( qc, 'l', 's' )
+                      CALL pmci_extrap_ifoutflow_lr( qr, 'l', 's' )
+!                      CALL pmci_extrap_ifoutflow_lr( nc, 'l', 's' )
+                      CALL pmci_extrap_ifoutflow_lr( nr, 'l', 's' )
 
                    ENDIF
@@ -3559,5 +4259,5 @@
 
                 IF ( passive_scalar )  THEN
-                   CALL pmci_extrap_ifoutflow_lr( s, nzb_s_inner, 'l', 's' )
+                   CALL pmci_extrap_ifoutflow_lr( s, 'l', 's' )
                 ENDIF
 
@@ -3569,38 +4269,39 @@
    !--    Right border pe
           IF ( nest_bound_r )  THEN
-
-             CALL pmci_interp_tril_lr( u,  uc,  icu, jco, kco, r1xu, r2xu,     &
-                                       r1yo, r2yo, r1zo, r2zo, nzb_u_inner,    &
-                                       logc_u_r, logc_ratio_u_r,               &
+             CALL pmci_interp_tril_lr( u,  uc,  icu, jco, kco, r1xu, r2xu,      &
+                                       r1yo, r2yo, r1zo, r2zo,                  &
+                                       logc_u_r, logc_ratio_u_r,                &
                                        nzt_topo_nestbc_r, 'r', 'u' )
 
-             CALL pmci_interp_tril_lr( v,  vc,  ico, jcv, kco, r1xo, r2xo,     &
-                                       r1yv, r2yv, r1zo, r2zo, nzb_v_inner,    &
-                                       logc_v_r, logc_ratio_v_r,               &
+             CALL pmci_interp_tril_lr( v,  vc,  ico, jcv, kco, r1xo, r2xo,      &
+                                       r1yv, r2yv, r1zo, r2zo,                  &
+                                       logc_v_r, logc_ratio_v_r,                &
                                        nzt_topo_nestbc_r, 'r', 'v' )
 
-             CALL pmci_interp_tril_lr( w,  wc,  ico, jco, kcw, r1xo, r2xo,     &
-                                       r1yo, r2yo, r1zw, r2zw, nzb_w_inner,    &
-                                       logc_w_r, logc_ratio_w_r,               &
+             CALL pmci_interp_tril_lr( w,  wc,  ico, jco, kcw, r1xo, r2xo,      &
+                                       r1yo, r2yo, r1zw, r2zw,                  &
+                                       logc_w_r, logc_ratio_w_r,                &
                                        nzt_topo_nestbc_r, 'r', 'w' )
 
-             CALL pmci_interp_tril_lr( e,  ec,  ico, jco, kco, r1xo, r2xo,     &
-                                       r1yo,r2yo, r1zo, r2zo, nzb_s_inner,     &
-                                       logc_u_r, logc_ratio_u_r,               &
+             CALL pmci_interp_tril_lr( e,  ec,  ico, jco, kco, r1xo, r2xo,      &
+                                       r1yo,r2yo, r1zo, r2zo,                   &
+                                       logc_u_r, logc_ratio_u_r,                &
                                        nzt_topo_nestbc_r, 'r', 'e' )
 
+
              IF ( .NOT. neutral )  THEN
-                CALL pmci_interp_tril_lr( pt, ptc, ico, jco, kco, r1xo, r2xo,  &
-                                          r1yo, r2yo, r1zo, r2zo, nzb_s_inner, &
-                                          logc_u_r, logc_ratio_u_r,            &
+                CALL pmci_interp_tril_lr( pt, ptc, ico, jco, kco, r1xo, r2xo,   &
+                                          r1yo, r2yo, r1zo, r2zo,               &
+                                          logc_u_r, logc_ratio_u_r,             &
                                           nzt_topo_nestbc_r, 'r', 's' )
+
              ENDIF
 
              IF ( humidity )  THEN
-
-                CALL pmci_interp_tril_lr( q, q_c, ico, jco, kco, r1xo, r2xo,   &
-                                          r1yo, r2yo, r1zo, r2zo, nzb_s_inner, &
-                                          logc_u_r, logc_ratio_u_r,            &
+                CALL pmci_interp_tril_lr( q, q_c, ico, jco, kco, r1xo, r2xo,    &
+                                          r1yo, r2yo, r1zo, r2zo,               &
+                                          logc_u_r, logc_ratio_u_r,             &
                                           nzt_topo_nestbc_r, 'r', 's' )
+
 
                 IF ( cloud_physics  .AND.  microphysics_seifert )  THEN
@@ -3608,5 +4309,5 @@
 !                    CALL pmci_interp_tril_lr( qc, qcc, ico, jco, kco, r1xo,     &
 !                                              r2xo, r1yo, r2yo, r1zo, r2zo,     &
-!                                              nzb_s_inner, logc_u_r,            &
+!                                              logc_u_r,                         &
 !                                              logc_ratio_u_r, nzt_topo_nestbc_r,&
 !                                              'r', 's' ) 
@@ -3614,5 +4315,5 @@
                    CALL pmci_interp_tril_lr( qr, qrc, ico, jco, kco, r1xo,     &
                                              r2xo, r1yo, r2yo, r1zo, r2zo,     &
-                                             nzb_s_inner, logc_u_r,            &
+                                             logc_u_r,                         &
                                              logc_ratio_u_r, nzt_topo_nestbc_r,&
                                              'r', 's' ) 
@@ -3620,5 +4321,5 @@
 !                    CALL pmci_interp_tril_lr( nc, ncc, ico, jco, kco, r1xo,     &
 !                                              r2xo, r1yo, r2yo, r1zo, r2zo,     &
-!                                              nzb_s_inner, logc_u_r,            &
+!                                              logc_u_r,                         &
 !                                              logc_ratio_u_r, nzt_topo_nestbc_r,&
 !                                              'r', 's' ) 
@@ -3626,5 +4327,5 @@
                    CALL pmci_interp_tril_lr( nr, nrc, ico, jco, kco, r1xo,     &
                                              r2xo, r1yo, r2yo, r1zo, r2zo,     &
-                                             nzb_s_inner, logc_u_r,            &
+                                             logc_u_r,                         &
                                              logc_ratio_u_r, nzt_topo_nestbc_r,&
                                              'r', 's' ) 
@@ -3636,29 +4337,28 @@
              IF ( passive_scalar )  THEN
                 CALL pmci_interp_tril_lr( s, sc, ico, jco, kco, r1xo, r2xo,    &
-                                          r1yo, r2yo, r1zo, r2zo, nzb_s_inner, &
+                                          r1yo, r2yo, r1zo, r2zo,              &
                                           logc_u_r, logc_ratio_u_r,            &
                                           nzt_topo_nestbc_r, 'r', 's' )
+
              ENDIF
 
              IF ( TRIM( nesting_mode ) == 'one-way' )  THEN
-
-                CALL pmci_extrap_ifoutflow_lr( u, nzb_u_inner, 'r', 'u' )
-                CALL pmci_extrap_ifoutflow_lr( v, nzb_v_inner, 'r', 'v' )
-                CALL pmci_extrap_ifoutflow_lr( w, nzb_w_inner, 'r', 'w' )
-                CALL pmci_extrap_ifoutflow_lr( e, nzb_s_inner, 'r', 'e' )
+                CALL pmci_extrap_ifoutflow_lr( u, 'r', 'u' )
+                CALL pmci_extrap_ifoutflow_lr( v, 'r', 'v' )
+                CALL pmci_extrap_ifoutflow_lr( w, 'r', 'w' )
+                CALL pmci_extrap_ifoutflow_lr( e, 'r', 'e' )
 
                 IF ( .NOT. neutral )  THEN
-                   CALL pmci_extrap_ifoutflow_lr( pt,nzb_s_inner, 'r', 's' )
+                   CALL pmci_extrap_ifoutflow_lr( pt, 'r', 's' )
                 ENDIF
 
                 IF ( humidity )  THEN
-
-                   CALL pmci_extrap_ifoutflow_lr( q, nzb_s_inner, 'r', 's' )
+                   CALL pmci_extrap_ifoutflow_lr( q, 'r', 's' )
 
                    IF ( cloud_physics  .AND.  microphysics_seifert )  THEN
-!                       CALL pmci_extrap_ifoutflow_lr( qc, nzb_s_inner, 'r', 's' )
-                      CALL pmci_extrap_ifoutflow_lr( qr, nzb_s_inner, 'r', 's' )
-!                      CALL pmci_extrap_ifoutflow_lr( nc, nzb_s_inner, 'r', 's' )  
-                      CALL pmci_extrap_ifoutflow_lr( nr, nzb_s_inner, 'r', 's' )
+!                       CALL pmci_extrap_ifoutflow_lr( qc, 'r', 's' )
+                      CALL pmci_extrap_ifoutflow_lr( qr, 'r', 's' )
+!                      CALL pmci_extrap_ifoutflow_lr( nc, 'r', 's' )  
+                      CALL pmci_extrap_ifoutflow_lr( nr, 'r', 's' )
                    ENDIF
 
@@ -3666,5 +4366,5 @@
 
                 IF ( passive_scalar )  THEN
-                   CALL pmci_extrap_ifoutflow_lr( s, nzb_s_inner, 'r', 's' )
+                   CALL pmci_extrap_ifoutflow_lr( s, 'r', 's' )
                 ENDIF
              ENDIF
@@ -3675,36 +4375,32 @@
    !--    South border pe
           IF ( nest_bound_s )  THEN
-             CALL pmci_interp_tril_sn( u,  uc,  icu, jco, kco, r1xu, r2xu,     &
-                                       r1yo, r2yo, r1zo, r2zo, nzb_u_inner,    &
-                                       logc_u_s, logc_ratio_u_s,               &
+             CALL pmci_interp_tril_sn( u,  uc,  icu, jco, kco, r1xu, r2xu,      &
+                                       r1yo, r2yo, r1zo, r2zo,                  &
+                                       logc_u_s, logc_ratio_u_s,                &
                                        nzt_topo_nestbc_s, 's', 'u' )
-
-             CALL pmci_interp_tril_sn( v,  vc,  ico, jcv, kco, r1xo, r2xo,     &
-                                       r1yv, r2yv, r1zo, r2zo, nzb_v_inner,    &
-                                       logc_v_s, logc_ratio_v_s,               &
+             CALL pmci_interp_tril_sn( v,  vc,  ico, jcv, kco, r1xo, r2xo,      &
+                                       r1yv, r2yv, r1zo, r2zo,                  &
+                                       logc_v_s, logc_ratio_v_s,                &
                                        nzt_topo_nestbc_s, 's', 'v' )
-
-             CALL pmci_interp_tril_sn( w,  wc,  ico, jco, kcw, r1xo, r2xo,     &
-                                       r1yo, r2yo, r1zw, r2zw, nzb_w_inner,    &
-                                       logc_w_s, logc_ratio_w_s,               &
+             CALL pmci_interp_tril_sn( w,  wc,  ico, jco, kcw, r1xo, r2xo,      &
+                                       r1yo, r2yo, r1zw, r2zw,                  &
+                                       logc_w_s, logc_ratio_w_s,                &
                                        nzt_topo_nestbc_s, 's','w' )
-
-             CALL pmci_interp_tril_sn( e,  ec,  ico, jco, kco, r1xo, r2xo,     &
-                                       r1yo, r2yo, r1zo, r2zo, nzb_s_inner,    &
-                                       logc_u_s, logc_ratio_u_s,               &
+             CALL pmci_interp_tril_sn( e,  ec,  ico, jco, kco, r1xo, r2xo,      &
+                                       r1yo, r2yo, r1zo, r2zo,                  &
+                                       logc_u_s, logc_ratio_u_s,                &
                                        nzt_topo_nestbc_s, 's', 'e' )
 
              IF ( .NOT. neutral )  THEN
-                CALL pmci_interp_tril_sn( pt, ptc, ico, jco, kco, r1xo, r2xo,  &
-                                          r1yo, r2yo, r1zo, r2zo, nzb_s_inner, &
-                                          logc_u_s, logc_ratio_u_s,            &
+                CALL pmci_interp_tril_sn( pt, ptc, ico, jco, kco, r1xo, r2xo,   &
+                                          r1yo, r2yo, r1zo, r2zo,               &
+                                          logc_u_s, logc_ratio_u_s,             &
                                           nzt_topo_nestbc_s, 's', 's' )
              ENDIF
 
              IF ( humidity )  THEN
-
-                CALL pmci_interp_tril_sn( q, q_c, ico, jco, kco, r1xo, r2xo,   &
-                                          r1yo,r2yo, r1zo, r2zo, nzb_s_inner,  &
-                                          logc_u_s, logc_ratio_u_s,            &
+                CALL pmci_interp_tril_sn( q, q_c, ico, jco, kco, r1xo, r2xo,    &
+                                          r1yo,r2yo, r1zo, r2zo,                &
+                                          logc_u_s, logc_ratio_u_s,             &
                                           nzt_topo_nestbc_s, 's', 's' )
 
@@ -3713,5 +4409,5 @@
 !                    CALL pmci_interp_tril_sn( qc, qcc, ico, jco, kco, r1xo,     &
 !                                              r2xo, r1yo,r2yo, r1zo, r2zo,      &
-!                                              nzb_s_inner, logc_u_s,            &
+!                                              logc_u_s,                         &
 !                                              logc_ratio_u_s, nzt_topo_nestbc_s,&
 !                                              's', 's' )
@@ -3719,5 +4415,5 @@
                    CALL pmci_interp_tril_sn( qr, qrc, ico, jco, kco, r1xo,     &
                                              r2xo, r1yo,r2yo, r1zo, r2zo,      &
-                                             nzb_s_inner, logc_u_s,            &
+                                             logc_u_s,                         &
                                              logc_ratio_u_s, nzt_topo_nestbc_s,&
                                              's', 's' )
@@ -3725,5 +4421,5 @@
 !                    CALL pmci_interp_tril_sn( nc, ncc, ico, jco, kco, r1xo,     &
 !                                              r2xo, r1yo,r2yo, r1zo, r2zo,      &
-!                                              nzb_s_inner, logc_u_s,            &
+!                                              logc_u_s,                         &
 !                                              logc_ratio_u_s, nzt_topo_nestbc_s,&
 !                                              's', 's' )
@@ -3731,5 +4427,5 @@
                    CALL pmci_interp_tril_sn( nr, nrc, ico, jco, kco, r1xo,     &
                                              r2xo, r1yo,r2yo, r1zo, r2zo,      &
-                                             nzb_s_inner, logc_u_s,            &
+                                             logc_u_s,                         &
                                              logc_ratio_u_s, nzt_topo_nestbc_s,&
                                              's', 's' )
@@ -3740,30 +4436,28 @@
 
              IF ( passive_scalar )  THEN
-                CALL pmci_interp_tril_sn( s, sc, ico, jco, kco, r1xo, r2xo,    &
-                                          r1yo,r2yo, r1zo, r2zo, nzb_s_inner,  &
-                                          logc_u_s, logc_ratio_u_s,            &
+                CALL pmci_interp_tril_sn( s, sc, ico, jco, kco, r1xo, r2xo,     &
+                                          r1yo,r2yo, r1zo, r2zo,                &
+                                          logc_u_s, logc_ratio_u_s,             &
                                           nzt_topo_nestbc_s, 's', 's' )
              ENDIF
 
              IF ( TRIM( nesting_mode ) == 'one-way' )  THEN
-
-                CALL pmci_extrap_ifoutflow_sn( u, nzb_u_inner, 's', 'u' )
-                CALL pmci_extrap_ifoutflow_sn( v, nzb_v_inner, 's', 'v' )
-                CALL pmci_extrap_ifoutflow_sn( w, nzb_w_inner, 's', 'w' )
-                CALL pmci_extrap_ifoutflow_sn( e, nzb_s_inner, 's', 'e' )
+                CALL pmci_extrap_ifoutflow_sn( u, 's', 'u' )
+                CALL pmci_extrap_ifoutflow_sn( v, 's', 'v' )
+                CALL pmci_extrap_ifoutflow_sn( w, 's', 'w' )
+                CALL pmci_extrap_ifoutflow_sn( e, 's', 'e' )
 
                 IF ( .NOT. neutral )  THEN
-                   CALL pmci_extrap_ifoutflow_sn( pt,nzb_s_inner, 's', 's' )
+                   CALL pmci_extrap_ifoutflow_sn( pt, 's', 's' )
                 ENDIF
 
                 IF ( humidity )  THEN
-
-                   CALL pmci_extrap_ifoutflow_sn( q, nzb_s_inner, 's', 's' )
+                   CALL pmci_extrap_ifoutflow_sn( q,  's', 's' )
 
                    IF ( cloud_physics  .AND.  microphysics_seifert )  THEN
-!                       CALL pmci_extrap_ifoutflow_sn( qc, nzb_s_inner, 's', 's' ) 
-                      CALL pmci_extrap_ifoutflow_sn( qr, nzb_s_inner, 's', 's' )      
-!                       CALL pmci_extrap_ifoutflow_sn( nc, nzb_s_inner, 's', 's' ) 
-                      CALL pmci_extrap_ifoutflow_sn( nr, nzb_s_inner, 's', 's' ) 
+!                       CALL pmci_extrap_ifoutflow_sn( qc, 's', 's' ) 
+                      CALL pmci_extrap_ifoutflow_sn( qr, 's', 's' )      
+!                       CALL pmci_extrap_ifoutflow_sn( nc, 's', 's' ) 
+                      CALL pmci_extrap_ifoutflow_sn( nr, 's', 's' ) 
 
                    ENDIF
@@ -3772,5 +4466,5 @@
 
                 IF ( passive_scalar )  THEN
-                   CALL pmci_extrap_ifoutflow_sn( s, nzb_s_inner, 's', 's' )
+                   CALL pmci_extrap_ifoutflow_sn( s,  's', 's' )
                 ENDIF
 
@@ -3782,34 +4476,35 @@
    !--    North border pe
           IF ( nest_bound_n )  THEN
-
-             CALL pmci_interp_tril_sn( u,  uc,  icu, jco, kco, r1xu, r2xu,     &
-                                       r1yo, r2yo, r1zo, r2zo, nzb_u_inner,    &
-                                       logc_u_n, logc_ratio_u_n,               &
+             CALL pmci_interp_tril_sn( u,  uc,  icu, jco, kco, r1xu, r2xu,      &
+                                       r1yo, r2yo, r1zo, r2zo,                  &
+                                       logc_u_n, logc_ratio_u_n,                &
                                        nzt_topo_nestbc_n, 'n', 'u' )
-             CALL pmci_interp_tril_sn( v,  vc,  ico, jcv, kco, r1xo, r2xo,     &
-                                       r1yv, r2yv, r1zo, r2zo, nzb_v_inner,    &
-                                       logc_v_n, logc_ratio_v_n,               & 
+
+             CALL pmci_interp_tril_sn( v,  vc,  ico, jcv, kco, r1xo, r2xo,      &
+                                       r1yv, r2yv, r1zo, r2zo,                  &
+                                       logc_v_n, logc_ratio_v_n,                & 
                                        nzt_topo_nestbc_n, 'n', 'v' )
-             CALL pmci_interp_tril_sn( w,  wc,  ico, jco, kcw, r1xo, r2xo,     &
-                                       r1yo, r2yo, r1zw, r2zw, nzb_w_inner,    &
-                                       logc_w_n, logc_ratio_w_n,               &
+
+             CALL pmci_interp_tril_sn( w,  wc,  ico, jco, kcw, r1xo, r2xo,      &
+                                       r1yo, r2yo, r1zw, r2zw,                  &
+                                       logc_w_n, logc_ratio_w_n,                &
                                        nzt_topo_nestbc_n, 'n', 'w' )
-             CALL pmci_interp_tril_sn( e,  ec,  ico, jco, kco, r1xo, r2xo,     &
-                                       r1yo, r2yo, r1zo, r2zo, nzb_s_inner,    &
-                                       logc_u_n, logc_ratio_u_n,               &
+
+             CALL pmci_interp_tril_sn( e,  ec,  ico, jco, kco, r1xo, r2xo,      &
+                                       r1yo, r2yo, r1zo, r2zo,                  &
+                                       logc_u_n, logc_ratio_u_n,                &
                                        nzt_topo_nestbc_n, 'n', 'e' )
 
              IF ( .NOT. neutral )  THEN
-                CALL pmci_interp_tril_sn( pt, ptc, ico, jco, kco, r1xo, r2xo,  &
-                                          r1yo, r2yo, r1zo, r2zo, nzb_s_inner, &
-                                          logc_u_n, logc_ratio_u_n,            &
+                CALL pmci_interp_tril_sn( pt, ptc, ico, jco, kco, r1xo, r2xo,   &
+                                          r1yo, r2yo, r1zo, r2zo,               &
+                                          logc_u_n, logc_ratio_u_n,             &
                                           nzt_topo_nestbc_n, 'n', 's' )
              ENDIF
 
              IF ( humidity )  THEN
-
-                CALL pmci_interp_tril_sn( q, q_c, ico, jco, kco, r1xo, r2xo,   &
-                                          r1yo, r2yo, r1zo, r2zo, nzb_s_inner, &
-                                          logc_u_n, logc_ratio_u_n,            &
+                CALL pmci_interp_tril_sn( q, q_c, ico, jco, kco, r1xo, r2xo,    &
+                                          r1yo, r2yo, r1zo, r2zo,               &
+                                          logc_u_n, logc_ratio_u_n,             &
                                           nzt_topo_nestbc_n, 'n', 's' )
 
@@ -3818,5 +4513,5 @@
 !                    CALL pmci_interp_tril_sn( qc, qcc, ico, jco, kco, r1xo,     &
 !                                              r2xo, r1yo, r2yo, r1zo, r2zo,     &
-!                                              nzb_s_inner, logc_u_n,            &
+!                                              logc_u_n,                         &
 !                                              logc_ratio_u_n, nzt_topo_nestbc_n,& 
 !                                              'n', 's' )
@@ -3824,5 +4519,5 @@
                    CALL pmci_interp_tril_sn( qr, qrc, ico, jco, kco, r1xo,     &
                                              r2xo, r1yo, r2yo, r1zo, r2zo,     &
-                                             nzb_s_inner, logc_u_n,            &
+                                             logc_u_n,                         &
                                              logc_ratio_u_n, nzt_topo_nestbc_n,& 
                                              'n', 's' )
@@ -3830,5 +4525,5 @@
 !                    CALL pmci_interp_tril_sn( nc, ncc, ico, jco, kco, r1xo,     &
 !                                              r2xo, r1yo, r2yo, r1zo, r2zo,     &
-!                                              nzb_s_inner, logc_u_n,            &
+!                                              logc_u_n,                         &
 !                                              logc_ratio_u_n, nzt_topo_nestbc_n,& 
 !                                              'n', 's' )
@@ -3836,5 +4531,5 @@
                    CALL pmci_interp_tril_sn( nr, nrc, ico, jco, kco, r1xo,     &
                                              r2xo, r1yo, r2yo, r1zo, r2zo,     &
-                                             nzb_s_inner, logc_u_n,            &
+                                             logc_u_n,                         &
                                              logc_ratio_u_n, nzt_topo_nestbc_n,& 
                                              'n', 's' )
@@ -3845,30 +4540,28 @@
 
              IF ( passive_scalar )  THEN
-                CALL pmci_interp_tril_sn( s, sc, ico, jco, kco, r1xo, r2xo,    &
-                                          r1yo, r2yo, r1zo, r2zo, nzb_s_inner, &
-                                          logc_u_n, logc_ratio_u_n,            &
+                CALL pmci_interp_tril_sn( s, sc, ico, jco, kco, r1xo, r2xo,     &
+                                          r1yo, r2yo, r1zo, r2zo,               &
+                                          logc_u_n, logc_ratio_u_n,             &
                                           nzt_topo_nestbc_n, 'n', 's' )
              ENDIF
 
              IF ( TRIM( nesting_mode ) == 'one-way' )  THEN
-
-                CALL pmci_extrap_ifoutflow_sn( u, nzb_u_inner, 'n', 'u' )
-                CALL pmci_extrap_ifoutflow_sn( v, nzb_v_inner, 'n', 'v' )
-                CALL pmci_extrap_ifoutflow_sn( w, nzb_w_inner, 'n', 'w' )
-                CALL pmci_extrap_ifoutflow_sn( e, nzb_s_inner, 'n', 'e' )
+                CALL pmci_extrap_ifoutflow_sn( u, 'n', 'u' )
+                CALL pmci_extrap_ifoutflow_sn( v, 'n', 'v' )
+                CALL pmci_extrap_ifoutflow_sn( w, 'n', 'w' )
+                CALL pmci_extrap_ifoutflow_sn( e, 'n', 'e' )
 
                 IF ( .NOT. neutral )  THEN
-                   CALL pmci_extrap_ifoutflow_sn( pt,nzb_s_inner, 'n', 's' )
+                   CALL pmci_extrap_ifoutflow_sn( pt, 'n', 's' )
                 ENDIF
 
                 IF ( humidity )  THEN
-
-                   CALL pmci_extrap_ifoutflow_sn( q, nzb_s_inner, 'n', 's' )
+                   CALL pmci_extrap_ifoutflow_sn( q,  'n', 's' )
 
                    IF ( cloud_physics  .AND.  microphysics_seifert )  THEN
-!                       CALL pmci_extrap_ifoutflow_sn( qc, nzb_s_inner, 'n', 's' )
-                      CALL pmci_extrap_ifoutflow_sn( qr, nzb_s_inner, 'n', 's' )
-!                       CALL pmci_extrap_ifoutflow_sn( nc, nzb_s_inner, 'n', 's' )
-                      CALL pmci_extrap_ifoutflow_sn( nr, nzb_s_inner, 'n', 's' )
+!                       CALL pmci_extrap_ifoutflow_sn( qc, 'n', 's' )
+                      CALL pmci_extrap_ifoutflow_sn( qr, 'n', 's' )
+!                       CALL pmci_extrap_ifoutflow_sn( nc, 'n', 's' )
+                      CALL pmci_extrap_ifoutflow_sn( nr, 'n', 's' )
                    ENDIF
 
@@ -3876,5 +4569,5 @@
 
                 IF ( passive_scalar )  THEN
-                   CALL pmci_extrap_ifoutflow_sn( s, nzb_s_inner, 'n', 's' )
+                   CALL pmci_extrap_ifoutflow_sn( s,  'n', 's' )
                 ENDIF
 
@@ -3883,5 +4576,5 @@
           ENDIF
 
-       ENDIF       !: IF ( nesting_mode /= 'vertical' )
+       ENDIF       ! IF ( nesting_mode /= 'vertical' )
 
 !
@@ -4016,5 +4709,5 @@
 
    SUBROUTINE pmci_interp_tril_lr( f, fc, ic, jc, kc, r1x, r2x, r1y, r2y, r1z,  &
-                                   r2z, kb, logc, logc_ratio, nzt_topo_nestbc,  &
+                                   r2z, logc, logc_ratio, nzt_topo_nestbc,      &
                                    edge, var )
 !
@@ -4040,5 +4733,4 @@
       INTEGER(iwp), DIMENSION(nxlg:nxrg), INTENT(IN)           ::  ic     !:
       INTEGER(iwp), DIMENSION(nysg:nyng), INTENT(IN)           ::  jc     !:
-      INTEGER(iwp), DIMENSION(nysg:nyng,nxlg:nxrg), INTENT(IN) ::  kb     !:
       INTEGER(iwp), DIMENSION(nzb:nzt+1), INTENT(IN)           ::  kc     !:
       INTEGER(iwp), DIMENSION(1:2,nzb:nzt_topo_nestbc,nys:nyn),                 &
@@ -4049,22 +4741,25 @@
       CHARACTER(LEN=1), INTENT(IN) ::  var    !:
 
-      INTEGER(iwp) ::  i       !:
-      INTEGER(iwp) ::  ib      !:
-      INTEGER(iwp) ::  ibgp    !:
-      INTEGER(iwp) ::  iw      !:
-      INTEGER(iwp) ::  j       !:
-      INTEGER(iwp) ::  jco     !:
-      INTEGER(iwp) ::  jcorr   !:
-      INTEGER(iwp) ::  jinc    !:
-      INTEGER(iwp) ::  jw      !:
-      INTEGER(iwp) ::  j1      !:
-      INTEGER(iwp) ::  k       !:
-      INTEGER(iwp) ::  kco     !:
-      INTEGER(iwp) ::  kcorr   !:
-      INTEGER(iwp) ::  k1      !:
-      INTEGER(iwp) ::  l       !:
-      INTEGER(iwp) ::  m       !:
-      INTEGER(iwp) ::  n       !:
-      INTEGER(iwp) ::  kbc     !:
+      INTEGER(iwp) ::  flag_nr  !: Number of flag array to mask topography on respective u/v/w or s grid
+      INTEGER(iwp) ::  flag_nr2 !: Number of flag array to indicate vertical index of topography top on respective u/v/w or s grid
+      INTEGER(iwp) ::  i        !:
+      INTEGER(iwp) ::  ib       !:
+      INTEGER(iwp) ::  ibgp     !:
+      INTEGER(iwp) ::  iw       !:
+      INTEGER(iwp) ::  j        !:
+      INTEGER(iwp) ::  jco      !:
+      INTEGER(iwp) ::  jcorr    !:
+      INTEGER(iwp) ::  jinc     !:
+      INTEGER(iwp) ::  jw       !:
+      INTEGER(iwp) ::  j1       !:
+      INTEGER(iwp) ::  k        !:
+      INTEGER(iwp) ::  k_wall   !: vertical index of topography top
+      INTEGER(iwp) ::  kco      !:
+      INTEGER(iwp) ::  kcorr    !:
+      INTEGER(iwp) ::  k1       !:
+      INTEGER(iwp) ::  l        !:
+      INTEGER(iwp) ::  m        !:
+      INTEGER(iwp) ::  n        !:
+      INTEGER(iwp) ::  kbc      !:
       
       REAL(wp) ::  coarse_dx   !:
@@ -4094,7 +4789,22 @@
          ib = nxr + 2
       ENDIF
+!
+!--    Determine number of flag array to be used to mask topography
+       IF ( var == 'u' )  THEN
+          flag_nr  = 1
+          flag_nr2 = 14
+       ELSEIF ( var == 'v' )  THEN
+          flag_nr  = 2
+          flag_nr2 = 16
+       ELSEIF ( var == 'w' )  THEN
+          flag_nr  = 3
+          flag_nr2 = 18
+       ELSE
+          flag_nr  = 0
+          flag_nr2 = 12
+       ENDIF
       
       DO  j = nys, nyn+1
-         DO  k = kb(j,i), nzt+1
+         DO  k = nzb, nzt+1
             l = ic(i)
             m = jc(j)
@@ -4119,5 +4829,13 @@
       IF ( var == 'u' .OR. var == 'v' )  THEN           
          DO  j = nys, nyn
-            k = kb(j,i)+1
+!
+!--         Determine vertical index of topography top at grid point (j,i)
+            k_wall = MAXLOC(                                                   &
+                        MERGE( 1, 0,                                           &
+                               BTEST( wall_flags_0(nzb:nzb_max,j,i), flag_nr2 )&
+                             ), DIM = 1                                        &
+                           ) - 1
+
+            k = k_wall+1
             IF ( ( logc(1,k,j) /= 0 )  .AND.  ( logc(2,k,j) == 0 ) )  THEN
                k1 = logc(1,k,j)
@@ -4141,5 +4859,12 @@
 !--         Solid surface only on south/north side of the node                   
             DO  j = nys, nyn
-               DO  k = kb(j,i)+1, nzt_topo_nestbc
+!
+!--            Determine vertical index of topography top at grid point (j,i)
+               k_wall = MAXLOC(                                                &
+                     MERGE( 1, 0,                                              &
+                            BTEST( wall_flags_0(nzb:nzb_max,j,i), flag_nr2 )   &
+                          ), DIM = 1                                           &
+                              ) - 1
+               DO  k = k_wall+1, nzt_topo_nestbc
                   IF ( ( logc(2,k,j) /= 0 )  .AND.  ( logc(1,k,j) == 0 ) )  THEN
 !
@@ -4162,5 +4887,12 @@
          IF ( var == 'u' )  THEN
             DO  j = nys, nyn
-               k = kb(j,i) + 1
+!
+!--            Determine vertical index of topography top at grid point (j,i)
+               k_wall = MAXLOC(                                                &
+                     MERGE( 1, 0,                                              &
+                            BTEST( wall_flags_0(nzb:nzb_max,j,i), flag_nr2 )   &
+                          ), DIM = 1                                           &
+                              ) - 1
+               k = k_wall + 1
                IF ( ( logc(2,k,j) /= 0 )  .AND.  ( logc(1,k,j) /= 0 ) )  THEN
                   k1   = logc(1,k,j)                 
@@ -4190,5 +4922,12 @@
          IF ( edge == 'l' )  THEN
             DO  j = nys, nyn + 1
-               DO  k = kb(j,i), nzt + 1
+!
+!--            Determine vertical index of topography top at grid point (j,i)
+               k_wall = MAXLOC(                                                &
+                     MERGE( 1, 0,                                              &
+                            BTEST( wall_flags_0(nzb:nzb_max,j,i), flag_nr2 )   &
+                          ), DIM = 1                                           &
+                              ) - 1
+               DO  k = k_wall, nzt + 1
                   f(k,j,i) = tkefactor_l(k,j) * f(k,j,i)
                ENDDO
@@ -4196,5 +4935,12 @@
          ELSEIF ( edge == 'r' )  THEN           
             DO  j = nys, nyn+1
-               DO  k = kb(j,i), nzt+1
+!
+!--            Determine vertical index of topography top at grid point (j,i)
+               k_wall = MAXLOC(                                                &
+                     MERGE( 1, 0,                                              &
+                            BTEST( wall_flags_0(nzb:nzb_max,j,i), flag_nr2 )   &
+                          ), DIM = 1                                           &
+                              ) - 1
+               DO  k = k_wall, nzt+1
                   f(k,j,i) = tkefactor_r(k,j) * f(k,j,i)
                ENDDO
@@ -4220,5 +4966,5 @@
 
    SUBROUTINE pmci_interp_tril_sn( f, fc, ic, jc, kc, r1x, r2x, r1y, r2y, r1z,  &
-                                   r2z, kb, logc, logc_ratio,                   &
+                                   r2z, logc, logc_ratio,                   &
                                    nzt_topo_nestbc, edge, var )
 
@@ -4245,5 +4991,4 @@
       INTEGER(iwp), DIMENSION(nxlg:nxrg), INTENT(IN)           ::  ic    !:
       INTEGER(iwp), DIMENSION(nysg:nyng), INTENT(IN)           ::  jc    !:
-      INTEGER(iwp), DIMENSION(nysg:nyng,nxlg:nxrg), INTENT(IN) ::  kb    !:
       INTEGER(iwp), DIMENSION(nzb:nzt+1), INTENT(IN)           ::  kc    !:
       INTEGER(iwp), DIMENSION(1:2,nzb:nzt_topo_nestbc,nxl:nxr),                 &
@@ -4254,4 +4999,6 @@
       CHARACTER(LEN=1), INTENT(IN) ::  var    !:
       
+      INTEGER(iwp) ::  flag_nr  !: Number of flag array to mask topography on respective u/v/w or s grid
+      INTEGER(iwp) ::  flag_nr2 !: Number of flag array to indicate vertical index of topography top on respective u/v/w or s grid
       INTEGER(iwp) ::  i       !:
       INTEGER(iwp) ::  iinc    !:
@@ -4263,4 +5010,5 @@
       INTEGER(iwp) ::  jbgp    !:
       INTEGER(iwp) ::  k       !:
+      INTEGER(iwp) ::  k_wall   !: vertical index of topography top
       INTEGER(iwp) ::  kcorr   !:
       INTEGER(iwp) ::  kco     !:
@@ -4297,6 +5045,29 @@
       ENDIF
 
+!
+!--    Determine number of flag array to be used to mask topography
+       IF ( var == 'u' )  THEN
+          flag_nr  = 1
+          flag_nr2 = 14
+       ELSEIF ( var == 'v' )  THEN
+          flag_nr  = 2
+          flag_nr2 = 16
+       ELSEIF ( var == 'w' )  THEN
+          flag_nr  = 3
+          flag_nr2 = 18
+       ELSE
+          flag_nr  = 0
+          flag_nr2 = 12
+       ENDIF
+
       DO  i = nxl, nxr+1
-         DO  k = kb(j,i), nzt+1
+!
+!--      Determine vertical index of topography top at grid point (j,i)
+         k_wall = MAXLOC(                                                      &
+                        MERGE( 1, 0,                                           &
+                               BTEST( wall_flags_0(nzb:nzb_max,j,i), flag_nr2 )&
+                             ), DIM = 1                                        &
+                           ) - 1
+         DO  k = k_wall, nzt+1
             l = ic(i)
             m = jc(j)
@@ -4321,5 +5092,13 @@
       IF ( var == 'u'  .OR.  var == 'v' )  THEN           
          DO  i = nxl, nxr
-            k = kb(j,i) + 1
+!
+!--         Determine vertical index of topography top at grid point (j,i)
+            k_wall = MAXLOC(                                                   &
+                        MERGE( 1, 0,                                           &
+                               BTEST( wall_flags_0(nzb:nzb_max,j,i), flag_nr2 )&
+                             ), DIM = 1                                        &
+                           ) - 1
+
+            k = k_wall + 1
             IF ( ( logc(1,k,i) /= 0 )  .AND.  ( logc(2,k,i) == 0 ) )  THEN
                k1 = logc(1,k,i)
@@ -4342,5 +5121,12 @@
          IF ( var == 'v' .OR. var == 'w' )  THEN
             DO  i = nxl, nxr
-               DO  k = kb(j,i), nzt_topo_nestbc
+!
+!--            Determine vertical index of topography top at grid point (j,i)
+               k_wall = MAXLOC(                                                &
+                     MERGE( 1, 0,                                              &
+                            BTEST( wall_flags_0(nzb:nzb_max,j,i), flag_nr2 )   &
+                          ), DIM = 1                                           &
+                              ) - 1
+               DO  k = k_wall, nzt_topo_nestbc
 !
 !--               Solid surface only on left/right side of the node           
@@ -4365,5 +5151,12 @@
          IF ( var == 'v' )  THEN
             DO  i = nxl, nxr
-               k = kb(j,i) + 1
+!
+!--            Determine vertical index of topography top at grid point (j,i)
+               k_wall = MAXLOC(                                                &
+                     MERGE( 1, 0,                                              &
+                            BTEST( wall_flags_0(nzb:nzb_max,j,i), flag_nr2 )   &
+                          ), DIM = 1                                           &
+                              ) - 1
+               k = k_wall + 1
                IF ( ( logc(2,k,i) /= 0 )  .AND.  ( logc(1,k,i) /= 0 ) )  THEN
                   k1   = logc(1,k,i)         
@@ -4393,5 +5186,12 @@
          IF ( edge == 's' )  THEN
             DO  i = nxl, nxr + 1
-               DO  k = kb(j,i), nzt+1
+!
+!--            Determine vertical index of topography top at grid point (j,i)
+               k_wall = MAXLOC(                                                &
+                     MERGE( 1, 0,                                              &
+                            BTEST( wall_flags_0(nzb:nzb_max,j,i), flag_nr2 )   &
+                          ), DIM = 1                                           &
+                              ) - 1
+               DO  k = k_wall, nzt+1
                   f(k,j,i) = tkefactor_s(k,i) * f(k,j,i)
                ENDDO
@@ -4399,5 +5199,12 @@
          ELSEIF ( edge == 'n' )  THEN
             DO  i = nxl, nxr + 1
-               DO  k = kb(j,i), nzt+1
+!
+!--            Determine vertical index of topography top at grid point (j,i)
+               k_wall = MAXLOC(                                                &
+                     MERGE( 1, 0,                                              &
+                            BTEST( wall_flags_0(nzb:nzb_max,j,i), flag_nr2 )   &
+                          ), DIM = 1                                           &
+                              ) - 1
+               DO  k = k_wall, nzt+1
                   f(k,j,i) = tkefactor_n(k,i) * f(k,j,i)
                ENDDO
@@ -4510,5 +5317,5 @@
 
 
-    SUBROUTINE pmci_extrap_ifoutflow_lr( f, kb, edge, var )
+    SUBROUTINE pmci_extrap_ifoutflow_lr( f, edge, var )
 !
 !--    After the interpolation of ghost-node values for the child-domain
@@ -4524,12 +5331,12 @@
        CHARACTER(LEN=1), INTENT(IN) ::  var    !:
 
-       INTEGER(iwp) ::  i     !:
-       INTEGER(iwp) ::  ib    !:
-       INTEGER(iwp) ::  ibgp  !:
-       INTEGER(iwp) ::  ied   !:
-       INTEGER(iwp) ::  j     !:
-       INTEGER(iwp) ::  k     !:
-      
-       INTEGER(iwp), DIMENSION(nysg:nyng,nxlg:nxrg), INTENT(IN) ::  kb   !:
+       INTEGER(iwp) ::  flag_nr !: Number of flag array to mask topography on respective u/v/w or s grid
+       INTEGER(iwp) ::  i       !:
+       INTEGER(iwp) ::  ib      !:
+       INTEGER(iwp) ::  ibgp    !:
+       INTEGER(iwp) ::  ied     !:
+       INTEGER(iwp) ::  j       !:
+       INTEGER(iwp) ::  k       !:
+       INTEGER(iwp) ::  k_wall  !:
 
        REAL(wp) ::  outnor    !:
@@ -4557,7 +5364,25 @@
           outnor = 1.0_wp
        ENDIF
+!
+!--    Determine number of flag array to be used to mask topography
+       IF ( var == 'u' )  THEN
+          flag_nr  = 14
+       ELSEIF ( var == 'v' )  THEN
+          flag_nr  = 16
+       ELSEIF ( var == 'w' )  THEN
+          flag_nr  = 18
+       ELSE
+          flag_nr  = 12
+       ENDIF
 
        DO  j = nys, nyn+1
-          DO  k = kb(j,i), nzt+1
+!
+!--       Determine vertical index of topography top at grid point (j,i)
+          k_wall = MAXLOC(                                                     &
+                     MERGE( 1, 0,                                              &
+                            BTEST( wall_flags_0(nzb:nzb_max,j,i), flag_nr )    &
+                          ), DIM = 1                                           &
+                         ) - 1
+          DO  k = k_wall, nzt+1
              vdotnor = outnor * u(k,j,ied)
 !
@@ -4568,5 +5393,5 @@
           ENDDO
           IF ( (var == 'u' )  .OR.  (var == 'v' )  .OR.  (var == 'w') )  THEN
-             f(kb(j,i),j,i) = 0.0_wp
+             f(k_wall,j,i) = 0.0_wp
           ENDIF
        ENDDO
@@ -4588,5 +5413,5 @@
 
 
-    SUBROUTINE pmci_extrap_ifoutflow_sn( f, kb, edge, var )
+    SUBROUTINE pmci_extrap_ifoutflow_sn( f, edge, var )
 !
 !--    After  the interpolation of ghost-node values for the child-domain
@@ -4601,4 +5426,5 @@
        CHARACTER(LEN=1), INTENT(IN) ::  var    !:
       
+       INTEGER(iwp) ::  flag_nr   !: Number of flag array to mask topography on respective u/v/w or s grid
        INTEGER(iwp) ::  i         !:
        INTEGER(iwp) ::  j         !:
@@ -4607,6 +5433,5 @@
        INTEGER(iwp) ::  jed       !:
        INTEGER(iwp) ::  k         !:
-
-       INTEGER(iwp), DIMENSION(nysg:nyng,nxlg:nxrg), INTENT(IN) ::  kb   !:
+       INTEGER(iwp) ::  k_wall    !:
 
        REAL(wp)     ::  outnor    !:
@@ -4635,6 +5460,25 @@
        ENDIF
 
+!
+!--    Determine number of flag array to be used to mask topography
+       IF ( var == 'u' )  THEN
+          flag_nr  = 14
+       ELSEIF ( var == 'v' )  THEN
+          flag_nr  = 16
+       ELSEIF ( var == 'w' )  THEN
+          flag_nr  = 18
+       ELSE
+          flag_nr  = 12
+       ENDIF
+
        DO  i = nxl, nxr+1
-          DO  k = kb(j,i), nzt+1
+!
+!--       Determine vertical index of topography top at grid point (j,i)
+          k_wall = MAXLOC(                                                     &
+                     MERGE( 1, 0,                                              &
+                            BTEST( wall_flags_0(nzb:nzb_max,j,i), flag_nr )    &
+                          ), DIM = 1                                           &
+                         ) - 1
+          DO  k = k_wall, nzt+1
              vdotnor = outnor * v(k,jed,i)
 !
@@ -4645,5 +5489,5 @@
           ENDDO
           IF ( (var == 'u' )  .OR.  (var == 'v' )  .OR.  (var == 'w') )  THEN
-             f(kb(j,i),j,i) = 0.0_wp
+             f(k_wall,j,i) = 0.0_wp
           ENDIF
        ENDDO
Index: /palm/trunk/SOURCE/poismg_mod.f90
===================================================================
--- /palm/trunk/SOURCE/poismg_mod.f90	(revision 2231)
+++ /palm/trunk/SOURCE/poismg_mod.f90	(revision 2232)
@@ -26,7 +26,4 @@
 ! $Id$
 !
-! 2084 2016-12-09 15:59:42Z knoop
-! Bugfix: missing rho_air_mg even/odd sorting implemented
-! 
 ! 2073 2016-11-30 14:34:05Z raasch
 ! change of openmp directives in restrict
@@ -111,6 +108,4 @@
     REAL(wp), DIMENSION(:,:), SAVE, ALLOCATABLE ::  f1_mg_b, f2_mg_b, f3_mg_b  !< blocked version of f1_mg ...
 
-    REAL(wp), DIMENSION(:,:), SAVE, ALLOCATABLE ::  rho_air_mg_b               !< blocked version of rho_air_mg
-
     INTERFACE poismg
        MODULE PROCEDURE poismg
@@ -320,7 +315,7 @@
                 kp1 = k-ind_even_odd
                 r(k,j,i) = f_mg(k,j,i)                                         &
-                      - rho_air_mg_b(k,l) * ddx2_mg(l) *                         &
+                      - rho_air_mg(k,l) * ddx2_mg(l) *                         &
                       ( p_mg(k,j,i+1) +  p_mg(k,j,i-1)  )                      &
-                      - rho_air_mg_b(k,l) * ddy2_mg(l) *                         &
+                      - rho_air_mg(k,l) * ddy2_mg(l) *                         &
                       ( p_mg(k,j+1,i) + p_mg(k,j-1,i)  )                       &
                       - f2_mg_b(k,l) * p_mg(kp1,j,i)                           &
@@ -333,7 +328,7 @@
                 kp1 = k+ind_even_odd+1
                 r(k,j,i) = f_mg(k,j,i)                                         &
-                      - rho_air_mg_b(k,l) * ddx2_mg(l) *                         &
+                      - rho_air_mg(k,l) * ddx2_mg(l) *                         &
                       ( p_mg(k,j,i+1) +  p_mg(k,j,i-1)  )                      &
-                      - rho_air_mg_b(k,l) * ddy2_mg(l) *                         &
+                      - rho_air_mg(k,l) * ddy2_mg(l) *                         &
                       ( p_mg(k,j+1,i) + p_mg(k,j-1,i)  )                       &
                       - f2_mg_b(k,l) * p_mg(kp1,j,i)                           &
@@ -766,7 +761,7 @@
                          kp1 = k-ind_even_odd
                          p_mg(k,j,i) = 1.0_wp / f1_mg_b(k,l) * (               &
-                                 rho_air_mg_b(k,l) * ddx2_mg(l) *                &
+                                 rho_air_mg(k,l) * ddx2_mg(l) *                &
                                ( p_mg(k,j,i+1) + p_mg(k,j,i-1) )               &
-                               + rho_air_mg_b(k,l) * ddy2_mg(l) *                &
+                               + rho_air_mg(k,l) * ddy2_mg(l) *                &
                                ( p_mg(k,j+1,i) + p_mg(k,j-1,i) )               &
                                + f2_mg_b(k,l) * p_mg(kp1,j,i)                  &
@@ -785,7 +780,7 @@
                          kp1 = k-ind_even_odd
                          p_mg(k,j,i) = 1.0_wp / f1_mg_b(k,l) * (               &
-                                 rho_air_mg_b(k,l) * ddx2_mg(l) *                &
+                                 rho_air_mg(k,l) * ddx2_mg(l) *                &
                                ( p_mg(k,j,i+1) + p_mg(k,j,i-1) )               &
-                               + rho_air_mg_b(k,l) * ddy2_mg(l) *                &
+                               + rho_air_mg(k,l) * ddy2_mg(l) *                &
                                ( p_mg(k,j+1,i) + p_mg(k,j-1,i) )               &
                                + f2_mg_b(k,l) * p_mg(kp1,j,i)                  &
@@ -804,7 +799,7 @@
                          kp1 = k+ind_even_odd+1
                          p_mg(k,j,i) = 1.0_wp / f1_mg_b(k,l) * (               &
-                                 rho_air_mg_b(k,l) * ddx2_mg(l) *                &
+                                 rho_air_mg(k,l) * ddx2_mg(l) *                &
                                ( p_mg(k,j,i+1) + p_mg(k,j,i-1) )               &
-                               + rho_air_mg_b(k,l) * ddy2_mg(l) *                &
+                               + rho_air_mg(k,l) * ddy2_mg(l) *                &
                                ( p_mg(k,j+1,i) + p_mg(k,j-1,i) )               &
                                + f2_mg_b(k,l) * p_mg(kp1,j,i)                  &
@@ -823,7 +818,7 @@
                          kp1 = k+ind_even_odd+1
                          p_mg(k,j,i) = 1.0_wp / f1_mg_b(k,l) * (               &
-                                 rho_air_mg_b(k,l) * ddx2_mg(l) *                &
+                                 rho_air_mg(k,l) * ddx2_mg(l) *                &
                                ( p_mg(k,j,i+1) + p_mg(k,j,i-1) )               &
-                               + rho_air_mg_b(k,l) * ddy2_mg(l) *                &
+                               + rho_air_mg(k,l) * ddy2_mg(l) *                &
                                ( p_mg(k,j+1,i) + p_mg(k,j-1,i) )               &
                                + f2_mg_b(k,l) * p_mg(kp1,j,i)                  &
@@ -854,7 +849,7 @@
                          j   = jj
                          p_mg(k,j,i) = 1.0_wp / f1_mg_b(k,l) * (               &
-                                 rho_air_mg_b(k,l) * ddx2_mg(l) *                &
+                                 rho_air_mg(k,l) * ddx2_mg(l) *                &
                                ( p_mg(k,j,i+1) + p_mg(k,j,i-1) )               &
-                               + rho_air_mg_b(k,l) * ddy2_mg(l) *                &
+                               + rho_air_mg(k,l) * ddy2_mg(l) *                &
                                ( p_mg(k,j+1,i) + p_mg(k,j-1,i) )               &
                                + f2_mg_b(k,l) * p_mg(kp1,j,i)                  &
@@ -863,7 +858,7 @@
                          j = jj+2
                          p_mg(k,j,i) = 1.0_wp / f1_mg_b(k,l) * (               &
-                                 rho_air_mg_b(k,l) * ddx2_mg(l) *                &
+                                 rho_air_mg(k,l) * ddx2_mg(l) *                &
                                ( p_mg(k,j,i+1) + p_mg(k,j,i-1) )               &
-                               + rho_air_mg_b(k,l) * ddy2_mg(l) *                &
+                               + rho_air_mg(k,l) * ddy2_mg(l) *                &
                                ( p_mg(k,j+1,i) + p_mg(k,j-1,i) )               &
                                + f2_mg_b(k,l) * p_mg(kp1,j,i)                  &
@@ -880,7 +875,7 @@
                          j   = jj
                          p_mg(k,j,i) = 1.0_wp / f1_mg_b(k,l) * (               &
-                                 rho_air_mg_b(k,l) * ddx2_mg(l) *                &
+                                 rho_air_mg(k,l) * ddx2_mg(l) *                &
                                ( p_mg(k,j,i+1) + p_mg(k,j,i-1) )               &
-                               + rho_air_mg_b(k,l) * ddy2_mg(l) *                &
+                               + rho_air_mg(k,l) * ddy2_mg(l) *                &
                                ( p_mg(k,j+1,i) + p_mg(k,j-1,i) )               &
                                + f2_mg_b(k,l) * p_mg(kp1,j,i)                  &
@@ -889,7 +884,7 @@
                          j = jj+2
                          p_mg(k,j,i) = 1.0_wp / f1_mg_b(k,l) * (               &
-                                 rho_air_mg_b(k,l) * ddx2_mg(l) *                &
+                                 rho_air_mg(k,l) * ddx2_mg(l) *                &
                                ( p_mg(k,j,i+1) + p_mg(k,j,i-1) )               &
-                               + rho_air_mg_b(k,l) * ddy2_mg(l) *                &
+                               + rho_air_mg(k,l) * ddy2_mg(l) *                &
                                ( p_mg(k,j+1,i) + p_mg(k,j-1,i) )               &
                                + f2_mg_b(k,l) * p_mg(kp1,j,i)                  &
@@ -906,7 +901,7 @@
                          j   = jj
                          p_mg(k,j,i) = 1.0_wp / f1_mg_b(k,l) * (               &
-                                 rho_air_mg_b(k,l) * ddx2_mg(l) *                &
+                                 rho_air_mg(k,l) * ddx2_mg(l) *                &
                                ( p_mg(k,j,i+1) + p_mg(k,j,i-1) )               &
-                               + rho_air_mg_b(k,l) * ddy2_mg(l) *                &
+                               + rho_air_mg(k,l) * ddy2_mg(l) *                &
                                ( p_mg(k,j+1,i) + p_mg(k,j-1,i) )               &
                                + f2_mg_b(k,l) * p_mg(kp1,j,i)                  &
@@ -915,7 +910,7 @@
                          j = jj+2
                          p_mg(k,j,i) = 1.0_wp / f1_mg_b(k,l) * (               &
-                                 rho_air_mg_b(k,l) * ddx2_mg(l) *                &
+                                 rho_air_mg(k,l) * ddx2_mg(l) *                &
                                ( p_mg(k,j,i+1) + p_mg(k,j,i-1) )               &
-                               + rho_air_mg_b(k,l) * ddy2_mg(l) *                &
+                               + rho_air_mg(k,l) * ddy2_mg(l) *                &
                                ( p_mg(k,j+1,i) + p_mg(k,j-1,i) )               &
                                + f2_mg_b(k,l) * p_mg(kp1,j,i)                  &
@@ -932,7 +927,7 @@
                          j   = jj
                          p_mg(k,j,i) = 1.0_wp / f1_mg_b(k,l) * (               &
-                                 rho_air_mg_b(k,l) * ddx2_mg(l) *                &
+                                 rho_air_mg(k,l) * ddx2_mg(l) *                &
                                ( p_mg(k,j,i+1) + p_mg(k,j,i-1) )               &
-                               + rho_air_mg_b(k,l) * ddy2_mg(l) *                &
+                               + rho_air_mg(k,l) * ddy2_mg(l) *                &
                                ( p_mg(k,j+1,i) + p_mg(k,j-1,i) )               &
                                + f2_mg_b(k,l) * p_mg(kp1,j,i)                  &
@@ -941,7 +936,7 @@
                          j = jj+2
                          p_mg(k,j,i) = 1.0_wp / f1_mg_b(k,l) * (               &
-                                 rho_air_mg_b(k,l) * ddx2_mg(l) *                &
+                                 rho_air_mg(k,l) * ddx2_mg(l) *                &
                                ( p_mg(k,j,i+1) + p_mg(k,j,i-1) )               &
-                               + rho_air_mg_b(k,l) * ddy2_mg(l) *                &
+                               + rho_air_mg(k,l) * ddy2_mg(l) *                &
                                ( p_mg(k,j+1,i) + p_mg(k,j-1,i) )               &
                                + f2_mg_b(k,l) * p_mg(kp1,j,i)                  &
@@ -1758,5 +1753,5 @@
 
        USE arrays_3d,                                                          &
-           ONLY:  f1_mg, f2_mg, f3_mg, rho_air_mg
+           ONLY:  f1_mg, f2_mg, f3_mg
 
        USE control_parameters,                                                 &
@@ -1784,6 +1779,5 @@
        ALLOCATE( f1_mg_b(nzb:nzt+1,maximum_grid_level),                        &
                  f2_mg_b(nzb:nzt+1,maximum_grid_level),                        &
-                 f3_mg_b(nzb:nzt+1,maximum_grid_level),                        &
-                 rho_air_mg_b(nzb:nzt+1,maximum_grid_level) )
+                 f3_mg_b(nzb:nzt+1,maximum_grid_level) )
 
 !
@@ -1806,7 +1800,4 @@
                                           f3_mg_b(nzb:nzt_mg(grid_level)+1,l), &
                                           l )
-          CALL sort_k_to_even_odd_blocks( rho_air_mg(nzb+1:nzt_mg(grid_level),l),   &
-                                          rho_air_mg_b(nzb:nzt_mg(grid_level)+1,l), &
-                                          l )
        ENDDO
 
Index: /palm/trunk/SOURCE/poismg_noopt.f90
===================================================================
--- /palm/trunk/SOURCE/poismg_noopt.f90	(revision 2231)
+++ /palm/trunk/SOURCE/poismg_noopt.f90	(revision 2232)
@@ -20,5 +20,5 @@
 ! Current revisions:
 ! -----------------
-! 
+! Bugfixes OpenMP
 ! 
 ! Former revisions:
@@ -495,5 +495,7 @@
     END SELECT
     
-!$OMP PARALLEL PRIVATE (i,j,k,ic,jc,kc)
+!$OMP PARALLEL PRIVATE (i,j,k,ic,jc,kc, rkjim,rkjip,rkjpi,rkjmi,rkjmim,rkjpim, &
+!$OMP rkjmip, rkjpip,rkmji,rkmjim,rkmjip,rkmjpi,rkmjmi,rkmjmim,rkmjpim,rkmjmip,&
+!$OMP rkmjpip          )
 !$OMP DO
     DO  ic = nxl_mg(l), nxr_mg(l)    
Index: /palm/trunk/SOURCE/pres.f90
===================================================================
--- /palm/trunk/SOURCE/pres.f90	(revision 2231)
+++ /palm/trunk/SOURCE/pres.f90	(revision 2232)
@@ -20,5 +20,5 @@
 ! Current revisions:
 ! ------------------
-! 
+! Adjustments to new topography and surface concept
 ! 
 ! Former revisions:
@@ -156,7 +156,6 @@
     USE indices,                                                               &
         ONLY:  nbgp, ngp_2dh_outer, nx, nxl, nxlg, nxl_mg, nxr, nxrg, nxr_mg,  &
-               ny, nys, nysg, nys_mg, nyn, nyng, nyn_mg, nzb, nzb_s_inner,     &
-               nzb_u_inner, nzb_v_inner, nzb_w_inner, nzt, nzt_mg,             &
-               rflags_s_inner
+               ny, nys, nysg, nys_mg, nyn, nyng, nyn_mg, nzb, nzt, nzt_mg,     &
+               wall_flags_0
 
     USE kinds
@@ -176,4 +175,7 @@
                weight_substep
 
+    USE surface_mod,                                                           &
+        ONLY :  bc_h
+
     IMPLICIT NONE
 
@@ -181,4 +183,5 @@
     INTEGER(iwp) ::  j              !<
     INTEGER(iwp) ::  k              !<
+    INTEGER(iwp) ::  m              !<
 
     REAL(wp)     ::  ddt_3d         !<
@@ -269,6 +272,9 @@
 !
 !--       Sum up the volume flow through the south/north boundary
-          DO  k = nzb_u_inner(j,i)+1, nzt
-             volume_flow_l(1) = volume_flow_l(1) + u(k,j,i) * dzw(k)
+          DO  k = nzb+1, nzt
+             volume_flow_l(1) = volume_flow_l(1) + u(k,j,i) * dzw(k)           &
+                                     * MERGE( 1.0_wp, 0.0_wp,                  &
+                                              BTEST( wall_flags_0(k,j,i), 1 )  &
+                                            )
           ENDDO
        ENDDO
@@ -285,6 +291,9 @@
 
        DO  j = nysg, nyng
-          DO  k = nzb_u_inner(j,i)+1, nzt
-             u(k,j,i) = u(k,j,i) + volume_flow_offset(1)
+          DO  k = nzb+1, nzt
+             u(k,j,i) = u(k,j,i) + volume_flow_offset(1)                       &
+                                     * MERGE( 1.0_wp, 0.0_wp,                  &
+                                              BTEST( wall_flags_0(k,j,i), 1 )  &
+                                            )
           ENDDO
        ENDDO
@@ -308,6 +317,9 @@
 !
 !--       Sum up the volume flow through the south/north boundary
-          DO  k = nzb_v_inner(j,i)+1, nzt
-             volume_flow_l(2) = volume_flow_l(2) + v(k,j,i) * dzw(k)
+          DO  k = nzb+1, nzt
+             volume_flow_l(2) = volume_flow_l(2) + v(k,j,i) * dzw(k)           &
+                                     * MERGE( 1.0_wp, 0.0_wp,                  &
+                                              BTEST( wall_flags_0(k,j,i), 2 )  &
+                                            )
           ENDDO
        ENDDO
@@ -324,6 +336,9 @@
 
        DO  i = nxlg, nxrg
-          DO  k = nzb_v_inner(j,i)+1, nzt
-             v(k,j,i) = v(k,j,i) + volume_flow_offset(2)
+          DO  k = nzb+1, nzt
+             v(k,j,i) = v(k,j,i) + volume_flow_offset(2)                       &
+                                     * MERGE( 1.0_wp, 0.0_wp,                  &
+                                              BTEST( wall_flags_0(k,j,i), 2 )  &
+                                            )
           ENDDO
        ENDDO
@@ -350,6 +365,9 @@
        DO  i = nxl, nxr
           DO  j = nys, nyn
-             DO  k = nzb_w_inner(j,i)+1, nzt
-                w_l_l(k) = w_l_l(k) + w(k,j,i)
+             DO  k = nzb+1, nzt
+                w_l_l(k) = w_l_l(k) + w(k,j,i)                                 &
+                                     * MERGE( 1.0_wp, 0.0_wp,                  &
+                                              BTEST( wall_flags_0(k,j,i), 3 )  &
+                                            )
              ENDDO
           ENDDO
@@ -367,6 +385,9 @@
        DO  i = nxlg, nxrg
           DO  j = nysg, nyng
-             DO  k = nzb_w_inner(j,i)+1, nzt
-                w(k,j,i) = w(k,j,i) - w_l(k)
+             DO  k = nzb+1, nzt
+                w(k,j,i) = w(k,j,i) - w_l(k)                                   &
+                                     * MERGE( 1.0_wp, 0.0_wp,                  &
+                                              BTEST( wall_flags_0(k,j,i), 3 )  &
+                                            )
              ENDDO
           ENDDO
@@ -379,5 +400,5 @@
 
     IF ( psolver(1:9) == 'multigrid' )  THEN
-       !$OMP PARALLEL DO SCHEDULE( STATIC )
+       !$OMP PARALLEL DO SCHEDULE( STATIC ) PRIVATE (i,j,k)
        DO  i = nxl-1, nxr+1
           DO  j = nys-1, nyn+1
@@ -388,5 +409,5 @@
        ENDDO
     ELSE
-       !$OMP PARALLEL DO SCHEDULE( STATIC )
+       !$OMP PARALLEL DO SCHEDULE( STATIC ) PRIVATE (i,j,k)
        DO  i = nxl, nxr
           DO  j = nys, nyn
@@ -406,15 +427,21 @@
     DO  i = nxl, nxr
        DO  j = nys, nyn
-          DO  k = nzb_s_inner(j,i)+1, nzt
+          DO  k = nzb+1, nzt
              d(k,j,i) = ( ( u(k,j,i+1) - u(k,j,i) ) * rho_air(k) * ddx +       &
                           ( v(k,j+1,i) - v(k,j,i) ) * rho_air(k) * ddy +       &
                           ( w(k,j,i)   * rho_air_zw(k) -                       &
                             w(k-1,j,i) * rho_air_zw(k-1) ) * ddzw(k)           &
-                        ) * ddt_3d * d_weight_pres 
+                        ) * ddt_3d * d_weight_pres                             &
+                                   * MERGE( 1.0_wp, 0.0_wp,                    &
+                                            BTEST( wall_flags_0(k,j,i), 0 )    &
+                                          )
           ENDDO
 !
 !--       Compute possible PE-sum of divergences for flow_statistics
-          DO  k = nzb_s_inner(j,i)+1, nzt
-             threadsum = threadsum + ABS( d(k,j,i) )
+          DO  k = nzb+1, nzt
+             threadsum = threadsum + ABS( d(k,j,i) )                           &
+                                   * MERGE( 1.0_wp, 0.0_wp,                    &
+                                            BTEST( wall_flags_0(k,j,i), 0 )    &
+                                          )
           ENDDO
 
@@ -438,5 +465,8 @@
                           ( w(k,j,i)   * rho_air_zw(k) -                       &
                             w(k-1,j,i) * rho_air_zw(k-1) ) * ddzw(k)           &
-                        ) * ddt_3d * d_weight_pres * rflags_s_inner(k,j,i)
+                        ) * ddt_3d * d_weight_pres                             &
+                                   * MERGE( 1.0_wp, 0.0_wp,                    &
+                                            BTEST( wall_flags_0(k,j,i), 0 )    &
+                                          )     
           ENDDO
        ENDDO
@@ -484,5 +514,5 @@
 !--    Store computed perturbation pressure and set boundary condition in
 !--    z-direction
-       !$OMP PARALLEL DO
+       !$OMP PARALLEL DO PRIVATE (i,j,k)
        DO  i = nxl, nxr
           DO  j = nys, nyn
@@ -499,20 +529,44 @@
        IF ( ibc_p_b == 1 )  THEN
 !
-!--       Neumann (dp/dz = 0)
-          !$OMP PARALLEL DO
-          DO  i = nxlg, nxrg
-             DO  j = nysg, nyng
-                tend(nzb_s_inner(j,i),j,i) = tend(nzb_s_inner(j,i)+1,j,i)
-             ENDDO
+!--       Neumann (dp/dz = 0). Using surfae data type, first for non-natural 
+!--       surfaces, then for natural and urban surfaces
+!--       Upward facing
+          !$OMP PARALLEL DO PRIVATE( i, j, k )
+          DO  m = 1, bc_h(0)%ns
+             i             = bc_h(0)%i(m)            
+             j             = bc_h(0)%j(m)
+             k             = bc_h(0)%k(m)
+             tend(k-1,j,i) = tend(k,j,i)
+          ENDDO
+!
+!--       Downward facing
+          !$OMP PARALLEL DO PRIVATE( i, j, k )
+          DO  m = 1, bc_h(1)%ns
+             i             = bc_h(1)%i(m)            
+             j             = bc_h(1)%j(m)
+             k             = bc_h(1)%k(m)
+             tend(k+1,j,i) = tend(k,j,i)
           ENDDO
 
        ELSE
 !
-!--       Dirichlet
-          !$OMP PARALLEL DO
-          DO  i = nxlg, nxrg
-             DO  j = nysg, nyng
-                tend(nzb_s_inner(j,i),j,i) = 0.0_wp
-             ENDDO
+!--       Dirichlet. Using surface data type, first for non-natural 
+!--       surfaces, then for natural and urban surfaces
+!--       Upward facing
+          !$OMP PARALLEL DO PRIVATE( i, j, k )
+          DO  m = 1, bc_h(0)%ns
+             i             = bc_h(0)%i(m)            
+             j             = bc_h(0)%j(m)
+             k             = bc_h(0)%k(m)
+             tend(k-1,j,i) = 0.0_wp
+          ENDDO
+!
+!--       Downward facing
+          !$OMP PARALLEL DO PRIVATE( i, j, k )
+          DO  m = 1, bc_h(1)%ns
+             i             = bc_h(1)%i(m)            
+             j             = bc_h(1)%j(m)
+             k             = bc_h(1)%k(m)
+             tend(k+1,j,i) = 0.0_wp
           ENDDO
 
@@ -524,5 +578,5 @@
 !
 !--       Neumann
-          !$OMP PARALLEL DO
+          !$OMP PARALLEL DO PRIVATE (i,j,k)
           DO  i = nxlg, nxrg
              DO  j = nysg, nyng
@@ -534,5 +588,5 @@
 !
 !--       Dirichlet
-          !$OMP PARALLEL DO
+          !$OMP PARALLEL DO PRIVATE (i,j,k)
           DO  i = nxlg, nxrg
              DO  j = nysg, nyng
@@ -646,26 +700,29 @@
        DO  j = nys, nyn
 
-          DO  k = 1, nzt
-             IF ( k > nzb_w_inner(j,i) )  THEN
-                w(k,j,i) = w(k,j,i) - dt_3d *                                 &
-                           ( tend(k+1,j,i) - tend(k,j,i) ) * ddzu(k+1) *      &
-                           weight_pres_l
-             ENDIF
-          ENDDO
-
-          DO  k = 1, nzt
-             IF ( k > nzb_u_inner(j,i) )  THEN
-                u(k,j,i) = u(k,j,i) - dt_3d *                                 &
-                           ( tend(k,j,i) - tend(k,j,i-1) ) * ddx *            &
-                           weight_pres_l
-             ENDIF
-          ENDDO
-
-          DO  k = 1, nzt
-             IF ( k > nzb_v_inner(j,i) )  THEN
-                v(k,j,i) = v(k,j,i) - dt_3d *                                 &
-                           ( tend(k,j,i) - tend(k,j-1,i) ) * ddy *            &
-                           weight_pres_l
-             ENDIF
+          DO  k = nzb+1, nzt
+             w(k,j,i) = w(k,j,i) - dt_3d *                                     &
+                           ( tend(k+1,j,i) - tend(k,j,i) ) * ddzu(k+1)         &
+                                     * weight_pres_l                           &
+                                     * MERGE( 1.0_wp, 0.0_wp,                  &
+                                              BTEST( wall_flags_0(k,j,i), 3 )  &
+                                            )
+          ENDDO
+
+          DO  k = nzb+1, nzt
+             u(k,j,i) = u(k,j,i) - dt_3d *                                     &
+                           ( tend(k,j,i) - tend(k,j,i-1) ) * ddx               &
+                                     * weight_pres_l                           &
+                                     * MERGE( 1.0_wp, 0.0_wp,                  &
+                                              BTEST( wall_flags_0(k,j,i), 1 )  &
+                                            )
+          ENDDO
+
+          DO  k = nzb+1, nzt
+             v(k,j,i) = v(k,j,i) - dt_3d *                                     &
+                           ( tend(k,j,i) - tend(k,j-1,i) ) * ddy               &
+                                     * weight_pres_l                           &
+                                     * MERGE( 1.0_wp, 0.0_wp,                  &
+                                              BTEST( wall_flags_0(k,j,i), 2 )  &
+                                            )
           ENDDO                                                         
 
@@ -676,5 +733,5 @@
 !
 !-- Sum up the volume flow through the right and north boundary
-    IF ( conserve_volume_flow  .AND.  bc_lr_cyc  .AND.  bc_ns_cyc  .AND.  &
+    IF ( conserve_volume_flow  .AND.  bc_lr_cyc  .AND.  bc_ns_cyc  .AND.       &
          nxr == nx )  THEN
 
@@ -683,6 +740,9 @@
        DO  j = nys, nyn
           !$OMP CRITICAL
-          DO  k = nzb_u_inner(j,nx) + 1, nzt
-             volume_flow_l(1) = volume_flow_l(1) + u(k,j,nx) * dzw(k)
+          DO  k = nzb+1, nzt
+             volume_flow_l(1) = volume_flow_l(1) + u(k,j,nxr) * dzw(k)         &
+                                     * MERGE( 1.0_wp, 0.0_wp,                  &
+                                              BTEST( wall_flags_0(k,j,nxr), 1 )&
+                                            )
           ENDDO
           !$OMP END CRITICAL
@@ -692,5 +752,5 @@
     ENDIF
 
-    IF ( conserve_volume_flow  .AND.  bc_ns_cyc  .AND.  bc_lr_cyc  .AND.  &
+    IF ( conserve_volume_flow  .AND.  bc_ns_cyc  .AND.  bc_lr_cyc  .AND.       &
          nyn == ny )  THEN
 
@@ -699,6 +759,9 @@
        DO  i = nxl, nxr
           !$OMP CRITICAL
-          DO  k = nzb_v_inner(ny,i) + 1, nzt
-             volume_flow_l(2) = volume_flow_l(2) + v(k,ny,i) * dzw(k)
+          DO  k = nzb+1, nzt
+             volume_flow_l(2) = volume_flow_l(2) + v(k,nyn,i) * dzw(k)         &
+                                     * MERGE( 1.0_wp, 0.0_wp,                  &
+                                              BTEST( wall_flags_0(k,nyn,i), 2 )&
+                                            )
            ENDDO
           !$OMP END CRITICAL
@@ -727,9 +790,15 @@
        DO  i = nxl, nxr
           DO  j = nys, nyn
-             DO  k = nzb_u_inner(j,i) + 1, nzt
-                u(k,j,i) = u(k,j,i) + volume_flow_offset(1)
-             ENDDO
-             DO  k = nzb_v_inner(j,i) + 1, nzt
-                v(k,j,i) = v(k,j,i) + volume_flow_offset(2)
+             DO  k = nzb+1, nzt
+                u(k,j,i) = u(k,j,i) + volume_flow_offset(1)                    &
+                                     * MERGE( 1.0_wp, 0.0_wp,                  &
+                                              BTEST( wall_flags_0(k,j,i), 1 )  &
+                                            )
+             ENDDO
+             DO  k = nzb+1, nzt
+                v(k,j,i) = v(k,j,i) + volume_flow_offset(2)                    &
+                                     * MERGE( 1.0_wp, 0.0_wp,                  &
+                                              BTEST( wall_flags_0(k,j,i), 2 )  &
+                                            )
              ENDDO
           ENDDO
@@ -768,9 +837,12 @@
        DO  i = nxl, nxr
           DO  j = nys, nyn
-             DO  k = nzb_s_inner(j,i)+1, nzt
-             d(k,j,i) = ( u(k,j,i+1) - u(k,j,i) ) * rho_air(k) * ddx +         &
-                        ( v(k,j+1,i) - v(k,j,i) ) * rho_air(k) * ddy +         &
-                        ( w(k,j,i)   * rho_air_zw(k) -                         &
-                          w(k-1,j,i) * rho_air_zw(k-1) ) * ddzw(k)
+             DO  k = nzb+1, nzt
+             d(k,j,i) = ( ( u(k,j,i+1) - u(k,j,i) ) * rho_air(k) * ddx +       &
+                          ( v(k,j+1,i) - v(k,j,i) ) * rho_air(k) * ddy +       &
+                          ( w(k,j,i)   * rho_air_zw(k) -                       &
+                            w(k-1,j,i) * rho_air_zw(k-1) ) * ddzw(k)           &
+                        ) * MERGE( 1.0_wp, 0.0_wp,                             &
+                                   BTEST( wall_flags_0(k,j,i), 0 )             &
+                                 )
              ENDDO
              DO  k = nzb+1, nzt
@@ -783,10 +855,12 @@
        DO  i = nxl, nxr
           DO  j = nys, nyn
-             DO  k = 1, nzt
+             DO  k = nzb+1, nzt
                 d(k,j,i) = ( ( u(k,j,i+1) - u(k,j,i) ) * rho_air(k) * ddx +    &
                              ( v(k,j+1,i) - v(k,j,i) ) * rho_air(k) * ddy +    &
                              ( w(k,j,i)   * rho_air_zw(k) -                    &
                                w(k-1,j,i) * rho_air_zw(k-1) ) * ddzw(k)        &
-                           ) * rflags_s_inner(k,j,i)
+                           ) * MERGE( 1.0_wp, 0.0_wp,                          &
+                                   BTEST( wall_flags_0(k,j,i), 0 )             &
+                                    )
              ENDDO
           ENDDO
Index: /palm/trunk/SOURCE/production_e.f90
===================================================================
--- /palm/trunk/SOURCE/production_e.f90	(revision 2231)
+++ /palm/trunk/SOURCE/production_e.f90	(revision 2232)
@@ -20,5 +20,5 @@
 ! Current revisions:
 ! -----------------
-! 
+! Adjustments to new surface concept
 !
 ! Former revisions:
@@ -106,8 +106,4 @@
 !------------------------------------------------------------------------------!
  MODULE production_e_mod
- 
-
-    USE wall_fluxes_mod,                                                       &
-        ONLY:  wall_fluxes_e
 
     USE kinds
@@ -115,9 +111,4 @@
     PRIVATE
     PUBLIC production_e, production_e_init
-
-    LOGICAL, SAVE ::  first_call = .TRUE.  !<
-
-    REAL(wp), DIMENSION(:,:), ALLOCATABLE, SAVE ::  u_0  !<
-    REAL(wp), DIMENSION(:,:), ALLOCATABLE, SAVE ::  v_0  !<
 
     INTERFACE production_e
@@ -141,6 +132,5 @@
 
        USE arrays_3d,                                                          &
-           ONLY:  ddzw, dd2zu, kh, km, prho, pt, q, ql, qsws, qswst, shf,      &
-                  tend, tswst, u, v, vpt, w
+           ONLY:  ddzw, dd2zu, kh, km, prho, pt, q, ql, tend, u, v, vpt, w
 
        USE cloud_parameters,                                                   &
@@ -154,88 +144,79 @@
 
        USE grid_variables,                                                     &
-           ONLY:  ddx, dx, ddy, dy, wall_e_x, wall_e_y
+           ONLY:  ddx, dx, ddy, dy
 
        USE indices,                                                            &
-           ONLY:  nxl, nxr, nys, nyn, nzb, nzb_diff_s_inner,                   &
-                   nzb_diff_s_outer, nzb_s_inner, nzt, nzt_diff
+           ONLY:  nxl, nxr, nys, nyn, nzb, nzt, wall_flags_0
+
+       USE surface_mod,                                                        &
+           ONLY :  surf_def_h, surf_def_v, surf_lsm_h, surf_lsm_v, surf_usm_h, &
+                   surf_usm_v
 
        IMPLICIT NONE
 
-       INTEGER(iwp) ::  i           !<
-       INTEGER(iwp) ::  j           !<
-       INTEGER(iwp) ::  k           !<
-
-       REAL(wp)     ::  def         !<
-       REAL(wp)     ::  dudx        !<
-       REAL(wp)     ::  dudy        !<
-       REAL(wp)     ::  dudz        !<
-       REAL(wp)     ::  dvdx        !<
-       REAL(wp)     ::  dvdy        !<
-       REAL(wp)     ::  dvdz        !<
-       REAL(wp)     ::  dwdx        !<
-       REAL(wp)     ::  dwdy        !<
-       REAL(wp)     ::  dwdz        !<
+       INTEGER(iwp) ::  i       !< running index x-direction
+       INTEGER(iwp) ::  j       !< running index y-direction
+       INTEGER(iwp) ::  k       !< running index z-direction
+       INTEGER(iwp) ::  l       !< running index for different surface type orientation
+       INTEGER(iwp) ::  m       !< running index surface elements
+       INTEGER(iwp) ::  surf_e  !< end index of surface elements at given i-j position
+       INTEGER(iwp) ::  surf_s  !< start index of surface elements at given i-j position
+
+       REAL(wp)     ::  def         !< 
+       REAL(wp)     ::  flag        !< flag to mask topography
        REAL(wp)     ::  k1          !<
        REAL(wp)     ::  k2          !<
-       REAL(wp)     ::  km_neutral  !<
+       REAL(wp)     ::  km_neutral  !< diffusion coefficient assuming neutral conditions - used to compute shear production at surfaces
        REAL(wp)     ::  theta       !<
        REAL(wp)     ::  temp        !<
-
-!       REAL(wp), DIMENSION(nzb:nzt+1,nys:nyn,nxl:nxr) ::  usvs, vsus, wsus, wsvs
-       REAL(wp), DIMENSION(nzb:nzt+1) ::  usvs  !<
-       REAL(wp), DIMENSION(nzb:nzt+1) ::  vsus  !<
-       REAL(wp), DIMENSION(nzb:nzt+1) ::  wsus  !<
-       REAL(wp), DIMENSION(nzb:nzt+1) ::  wsvs  !<
-
-!
-!--    First calculate horizontal momentum flux u'v', w'v', v'u', w'u' at
-!--    vertical walls, if neccessary
-!--    So far, results are slightly different from the ij-Version.
-!--    Therefore, ij-Version is called further below within the ij-loops.
-!       IF ( topography /= 'flat' )  THEN
-!          CALL wall_fluxes_e( usvs, 1.0_wp, 0.0_wp, 0.0_wp, 0.0_wp, wall_e_y )
-!          CALL wall_fluxes_e( wsvs, 0.0_wp, 0.0_wp, 1.0_wp, 0.0_wp, wall_e_y )
-!          CALL wall_fluxes_e( vsus, 0.0_wp, 1.0_wp, 0.0_wp, 0.0_wp, wall_e_x )
-!          CALL wall_fluxes_e( wsus, 0.0_wp, 0.0_wp, 0.0_wp, 1.0_wp, wall_e_x )
-!       ENDIF
-
+       REAL(wp)     ::  sign_dir    !< sign of wall-tke flux, depending on wall orientation 
+       REAL(wp)     ::  usvs        !< momentum flux u"v"
+       REAL(wp)     ::  vsus        !< momentum flux v"u"
+       REAL(wp)     ::  wsus        !< momentum flux w"u"
+       REAL(wp)     ::  wsvs        !< momentum flux w"v"
+
+       REAL(wp), DIMENSION(nzb+1:nzt,nys:nyn) ::  dudx  !< Gradient of u-component in x-direction
+       REAL(wp), DIMENSION(nzb+1:nzt,nys:nyn) ::  dudy  !< Gradient of u-component in y-direction
+       REAL(wp), DIMENSION(nzb+1:nzt,nys:nyn) ::  dudz  !< Gradient of u-component in z-direction
+       REAL(wp), DIMENSION(nzb+1:nzt,nys:nyn) ::  dvdx  !< Gradient of v-component in x-direction
+       REAL(wp), DIMENSION(nzb+1:nzt,nys:nyn) ::  dvdy  !< Gradient of v-component in y-direction
+       REAL(wp), DIMENSION(nzb+1:nzt,nys:nyn) ::  dvdz  !< Gradient of v-component in z-direction
+       REAL(wp), DIMENSION(nzb+1:nzt,nys:nyn) ::  dwdx  !< Gradient of w-component in x-direction
+       REAL(wp), DIMENSION(nzb+1:nzt,nys:nyn) ::  dwdy  !< Gradient of w-component in y-direction
+       REAL(wp), DIMENSION(nzb+1:nzt,nys:nyn) ::  dwdz  !< Gradient of w-component in z-direction
 
        DO  i = nxl, nxr
 
-!
-!--       Calculate TKE production by shear
-          DO  j = nys, nyn
-             DO  k = nzb_diff_s_outer(j,i), nzt
-
-                dudx  =           ( u(k,j,i+1) - u(k,j,i)     ) * ddx
-                dudy  = 0.25_wp * ( u(k,j+1,i) + u(k,j+1,i+1) - &
-                                    u(k,j-1,i) - u(k,j-1,i+1) ) * ddy
-                dudz  = 0.5_wp  * ( u(k+1,j,i) + u(k+1,j,i+1) - &
-                                    u(k-1,j,i) - u(k-1,j,i+1) ) * dd2zu(k)
-
-                dvdx  = 0.25_wp * ( v(k,j,i+1) + v(k,j+1,i+1) - &
-                                    v(k,j,i-1) - v(k,j+1,i-1) ) * ddx
-                dvdy  =           ( v(k,j+1,i) - v(k,j,i)     ) * ddy
-                dvdz  = 0.5_wp  * ( v(k+1,j,i) + v(k+1,j+1,i) - &
-                                    v(k-1,j,i) - v(k-1,j+1,i) ) * dd2zu(k)
-
-                dwdx  = 0.25_wp * ( w(k,j,i+1) + w(k-1,j,i+1) - &
-                                    w(k,j,i-1) - w(k-1,j,i-1) ) * ddx
-                dwdy  = 0.25_wp * ( w(k,j+1,i) + w(k-1,j+1,i) - &
-                                    w(k,j-1,i) - w(k-1,j-1,i) ) * ddy
-                dwdz  =           ( w(k,j,i)   - w(k-1,j,i)   ) * ddzw(k)
-
-                def = 2.0_wp * ( dudx**2 + dvdy**2 + dwdz**2 ) +           &
-                      dudy**2 + dvdx**2 + dwdx**2 + dwdy**2 + dudz**2 + &
-                      dvdz**2 + 2.0_wp * ( dvdx*dudy + dwdx*dudz + dwdy*dvdz )
-
-                IF ( def < 0.0_wp )  def = 0.0_wp
-
-                tend(k,j,i) = tend(k,j,i) + km(k,j,i) * def
-
+          IF ( constant_flux_layer )  THEN
+
+!
+!--          Calculate TKE production by shear. Calculate gradients at all grid 
+!--          points first, gradients at surface-bounded grid points will be 
+!--          overwritten further below. 
+             DO  j = nys, nyn
+                DO  k = nzb+1, nzt
+
+                   dudx(k,j) =           ( u(k,j,i+1) - u(k,j,i)     ) * ddx
+                   dudy(k,j) = 0.25_wp * ( u(k,j+1,i) + u(k,j+1,i+1) -         &
+                                           u(k,j-1,i) - u(k,j-1,i+1) ) * ddy
+                   dudz(k,j) = 0.5_wp  * ( u(k+1,j,i) + u(k+1,j,i+1) -         &
+                                           u(k-1,j,i) - u(k-1,j,i+1) ) *       &
+                                                            dd2zu(k)
+   
+                   dvdx(k,j) = 0.25_wp * ( v(k,j,i+1) + v(k,j+1,i+1) -         &
+                                           v(k,j,i-1) - v(k,j+1,i-1) ) * ddx
+                   dvdy(k,j) =           ( v(k,j+1,i) - v(k,j,i)     ) * ddy
+                   dvdz(k,j) = 0.5_wp  * ( v(k+1,j,i) + v(k+1,j+1,i) -         &
+                                           v(k-1,j,i) - v(k-1,j+1,i) ) *       &
+                                                            dd2zu(k)
+
+                   dwdx(k,j) = 0.25_wp * ( w(k,j,i+1) + w(k-1,j,i+1) -         &
+                                           w(k,j,i-1) - w(k-1,j,i-1) ) * ddx
+                   dwdy(k,j) = 0.25_wp * ( w(k,j+1,i) + w(k-1,j+1,i) -         &
+                                           w(k,j-1,i) - w(k-1,j-1,i) ) * ddy
+                   dwdz(k,j) =           ( w(k,j,i)   - w(k-1,j,i)   ) * ddzw(k)
+
+                ENDDO
              ENDDO
-          ENDDO
-
-          IF ( constant_flux_layer )  THEN
 
 !
@@ -244,282 +225,251 @@
 !--          'bottom and wall: use u_0,v_0 and wall functions'
              DO  j = nys, nyn
-
-                IF ( ( wall_e_x(j,i) /= 0.0_wp ) .OR. ( wall_e_y(j,i) /= 0.0_wp ) ) &
-                THEN
-
-                   k = nzb_diff_s_inner(j,i) - 1
-                   dudx = ( u(k,j,i+1) - u(k,j,i) ) * ddx
-                   dudz = 0.5_wp * ( u(k+1,j,i) + u(k+1,j,i+1) - &
-                                     u_0(j,i)   - u_0(j,i+1)   ) * dd2zu(k)
-                   dvdy = ( v(k,j+1,i) - v(k,j,i) ) * ddy
-                   dvdz = 0.5_wp * ( v(k+1,j,i) + v(k+1,j+1,i) - &
-                                     v_0(j,i)   - v_0(j+1,i)   ) * dd2zu(k)
-                   dwdz = ( w(k,j,i) - w(k-1,j,i) ) * ddzw(k)
-
-                   IF ( wall_e_y(j,i) /= 0.0_wp )  THEN
-!
-!--                   Inconsistency removed: as the thermal stratification is 
-!--                   not taken into account for the evaluation of the wall 
-!--                   fluxes at vertical walls, the eddy viscosity km must not 
-!--                   be used for the evaluation of the velocity gradients dudy 
-!--                   and dwdy
-!--                   Note: The validity of the new method has not yet been 
-!--                         shown, as so far no suitable data for a validation 
-!--                         has been available
-                      CALL wall_fluxes_e( i, j, k, nzb_diff_s_outer(j,i)-2, &
-                                          usvs, 1.0_wp, 0.0_wp, 0.0_wp, 0.0_wp )
-                      CALL wall_fluxes_e( i, j, k, nzb_diff_s_outer(j,i)-2, &
-                                          wsvs, 0.0_wp, 0.0_wp, 1.0_wp, 0.0_wp )
-                      km_neutral = kappa * ( usvs(k)**2 + wsvs(k)**2 )**0.25_wp * &
-                                   0.5_wp * dy 
-                      IF ( km_neutral > 0.0_wp )  THEN
-                         dudy = - wall_e_y(j,i) * usvs(k) / km_neutral
-                         dwdy = - wall_e_y(j,i) * wsvs(k) / km_neutral
-                      ELSE
-                         dudy = 0.0_wp
-                         dwdy = 0.0_wp
-                      ENDIF
-                   ELSE
-                      dudy = 0.25_wp * ( u(k,j+1,i) + u(k,j+1,i+1) - &
-                                         u(k,j-1,i) - u(k,j-1,i+1) ) * ddy
-                      dwdy = 0.25_wp * ( w(k,j+1,i) + w(k-1,j+1,i) - &
-                                         w(k,j-1,i) - w(k-1,j-1,i) ) * ddy
-                   ENDIF
-
-                   IF ( wall_e_x(j,i) /= 0.0_wp )  THEN
-!
-!--                   Inconsistency removed: as the thermal stratification is 
-!--                   not taken into account for the evaluation of the wall 
-!--                   fluxes at vertical walls, the eddy viscosity km must not 
-!--                   be used for the evaluation of the velocity gradients dvdx 
-!--                   and dwdx
-!--                   Note: The validity of the new method has not yet been 
-!--                         shown, as so far no suitable data for a validation 
-!--                         has been available
-                      CALL wall_fluxes_e( i, j, k, nzb_diff_s_outer(j,i)-2, &
-                                          vsus, 0.0_wp, 1.0_wp, 0.0_wp, 0.0_wp )
-                      CALL wall_fluxes_e( i, j, k, nzb_diff_s_outer(j,i)-2, &
-                                          wsus, 0.0_wp, 0.0_wp, 0.0_wp, 1.0_wp )
-                      km_neutral = kappa * ( vsus(k)**2 + wsus(k)**2 )**0.25_wp * &
-                                   0.5_wp * dx
-                      IF ( km_neutral > 0.0_wp )  THEN
-                         dvdx = - wall_e_x(j,i) * vsus(k) / km_neutral
-                         dwdx = - wall_e_x(j,i) * wsus(k) / km_neutral
-                      ELSE
-                         dvdx = 0.0_wp
-                         dwdx = 0.0_wp
-                      ENDIF
-                   ELSE
-                      dvdx = 0.25_wp * ( v(k,j,i+1) + v(k,j+1,i+1) - &
-                                         v(k,j,i-1) - v(k,j+1,i-1) ) * ddx
-                      dwdx = 0.25_wp * ( w(k,j,i+1) + w(k-1,j,i+1) - &
-                                         w(k,j,i-1) - w(k-1,j,i-1) ) * ddx
-                   ENDIF
-
-                   def = 2.0_wp * ( dudx**2 + dvdy**2 + dwdz**2 ) +           &
-                         dudy**2 + dvdx**2 + dwdx**2 + dwdy**2 + dudz**2 + &
-                         dvdz**2 + 2.0_wp * ( dvdx*dudy + dwdx*dudz + dwdy*dvdz )
+!
+!--             Compute gradients at north- and south-facing surfaces.
+!--             First, for default surfaces, then for urban surfaces. 
+!--             Note, so far no natural vertical surfaces implemented
+                DO  l = 0, 1
+                   surf_s = surf_def_v(l)%start_index(j,i)
+                   surf_e = surf_def_v(l)%end_index(j,i)
+                   DO  m = surf_s, surf_e
+                      k           = surf_def_v(l)%k(m)
+                      usvs        = surf_def_v(l)%mom_flux_tke(0,m)
+                      wsvs        = surf_def_v(l)%mom_flux_tke(1,m)
+      
+                      km_neutral = kappa * ( usvs**2 + wsvs**2 )**0.25_wp      &
+                                      * 0.5_wp * dy
+!
+!--                   -1.0 for right-facing wall, 1.0 for left-facing wall
+                      sign_dir = MERGE( 1.0_wp, -1.0_wp,                       &
+                                        BTEST( wall_flags_0(k,j-1,i), 0 ) ) 
+                      dudy(k,j) = sign_dir * usvs / ( km_neutral + 1E-10_wp )
+                      dwdy(k,j) = sign_dir * wsvs / ( km_neutral + 1E-10_wp )
+                   ENDDO
+!
+!--                Natural surfaces
+                   surf_s = surf_lsm_v(l)%start_index(j,i)
+                   surf_e = surf_lsm_v(l)%end_index(j,i)
+                   DO  m = surf_s, surf_e
+                      k           = surf_lsm_v(l)%k(m)
+                      usvs        = surf_lsm_v(l)%mom_flux_tke(0,m)
+                      wsvs        = surf_lsm_v(l)%mom_flux_tke(1,m)
+      
+                      km_neutral = kappa * ( usvs**2 + wsvs**2 )**0.25_wp      &
+                                      * 0.5_wp * dy
+!
+!--                   -1.0 for right-facing wall, 1.0 for left-facing wall
+                      sign_dir = MERGE( 1.0_wp, -1.0_wp,                       &
+                                        BTEST( wall_flags_0(k,j-1,i), 0 ) ) 
+                      dudy(k,j) = sign_dir * usvs / ( km_neutral + 1E-10_wp )
+                      dwdy(k,j) = sign_dir * wsvs / ( km_neutral + 1E-10_wp )
+                   ENDDO 
+!
+!--                Urban surfaces
+                   surf_s = surf_usm_v(l)%start_index(j,i)
+                   surf_e = surf_usm_v(l)%end_index(j,i)
+                   DO  m = surf_s, surf_e
+                      k           = surf_usm_v(l)%k(m)
+                      usvs        = surf_usm_v(l)%mom_flux_tke(0,m)
+                      wsvs        = surf_usm_v(l)%mom_flux_tke(1,m)
+      
+                      km_neutral = kappa * ( usvs**2 + wsvs**2 )**0.25_wp      &
+                                      * 0.5_wp * dy
+!
+!--                   -1.0 for right-facing wall, 1.0 for left-facing wall
+                      sign_dir = MERGE( 1.0_wp, -1.0_wp,                       &
+                                        BTEST( wall_flags_0(k,j-1,i), 0 ) ) 
+                      dudy(k,j) = sign_dir * usvs / ( km_neutral + 1E-10_wp )
+                      dwdy(k,j) = sign_dir * wsvs / ( km_neutral + 1E-10_wp )
+                   ENDDO  
+                ENDDO
+!
+!--             Compute gradients at east- and west-facing walls
+                DO  l = 2, 3
+                   surf_s = surf_def_v(l)%start_index(j,i)
+                   surf_e = surf_def_v(l)%end_index(j,i)
+                   DO  m = surf_s, surf_e
+                      k     = surf_def_v(l)%k(m)
+                      vsus  = surf_def_v(l)%mom_flux_tke(0,m)
+                      wsus  = surf_def_v(l)%mom_flux_tke(1,m)
+
+                      km_neutral = kappa * ( vsus**2 + wsus**2 )**0.25_wp      &
+                                         * 0.5_wp * dx
+!
+!--                   -1.0 for right-facing wall, 1.0 for left-facing wall
+                      sign_dir = MERGE( 1.0_wp, -1.0_wp,                       &
+                                        BTEST( wall_flags_0(k,j,i-1), 0 ) ) 
+                      dvdx(k,j) = sign_dir * vsus / ( km_neutral + 1E-10_wp )
+                      dwdx(k,j) = sign_dir * wsus / ( km_neutral + 1E-10_wp )
+                   ENDDO 
+!
+!--                Natural surfaces                   
+                   surf_s = surf_lsm_v(l)%start_index(j,i)
+                   surf_e = surf_lsm_v(l)%end_index(j,i)
+                   DO  m = surf_s, surf_e
+                      k     = surf_lsm_v(l)%k(m)
+                      vsus  = surf_lsm_v(l)%mom_flux_tke(0,m)
+                      wsus  = surf_lsm_v(l)%mom_flux_tke(1,m)
+
+                      km_neutral = kappa * ( vsus**2 + wsus**2 )**0.25_wp      &
+                                         * 0.5_wp * dx
+!
+!--                   -1.0 for right-facing wall, 1.0 for left-facing wall
+                      sign_dir = MERGE( 1.0_wp, -1.0_wp,                       &
+                                        BTEST( wall_flags_0(k,j,i-1), 0 ) ) 
+                      dvdx(k,j) = sign_dir * vsus / ( km_neutral + 1E-10_wp )
+                      dwdx(k,j) = sign_dir * wsus / ( km_neutral + 1E-10_wp )
+                   ENDDO   
+!
+!--                Urban surfaces                   
+                   surf_s = surf_usm_v(l)%start_index(j,i)
+                   surf_e = surf_usm_v(l)%end_index(j,i)
+                   DO  m = surf_s, surf_e
+                      k     = surf_usm_v(l)%k(m)
+                      vsus  = surf_usm_v(l)%mom_flux_tke(0,m)
+                      wsus  = surf_usm_v(l)%mom_flux_tke(1,m)
+
+                      km_neutral = kappa * ( vsus**2 + wsus**2 )**0.25_wp      &
+                                         * 0.5_wp * dx
+!
+!--                   -1.0 for right-facing wall, 1.0 for left-facing wall
+                      sign_dir = MERGE( 1.0_wp, -1.0_wp,                       &
+                                        BTEST( wall_flags_0(k,j,i-1), 0 ) ) 
+                      dvdx(k,j) = sign_dir * vsus / ( km_neutral + 1E-10_wp )
+                      dwdx(k,j) = sign_dir * wsus / ( km_neutral + 1E-10_wp )
+                   ENDDO 
+                ENDDO
+!
+!--             Compute gradients at upward-facing surfaces
+                surf_s = surf_def_h(0)%start_index(j,i)
+                surf_e = surf_def_h(0)%end_index(j,i)
+                DO  m = surf_s, surf_e
+                   k = surf_def_h(0)%k(m)
+!
+!--                Please note, actually, an interpolation of u_0 and v_0 
+!--                onto the grid center would be required. However, this 
+!--                would require several data transfers between 2D-grid and
+!--                wall type. The effect of this missing interpolation is 
+!--                negligible. (See also production_e_init).
+                   dudz(k,j) = ( u(k+1,j,i) - surf_def_h(0)%u_0(m) ) * dd2zu(k)   
+                   dvdz(k,j) = ( v(k+1,j,i) - surf_def_h(0)%v_0(m) ) * dd2zu(k)
+            
+                ENDDO
+!
+!--             Natural surfaces
+                surf_s = surf_lsm_h%start_index(j,i)
+                surf_e = surf_lsm_h%end_index(j,i)
+                DO  m = surf_s, surf_e
+                   k = surf_lsm_h%k(m)
+!
+!--                Please note, actually, an interpolation of u_0 and v_0 
+!--                onto the grid center would be required. However, this 
+!--                would require several data transfers between 2D-grid and
+!--                wall type. The effect of this missing interpolation is 
+!--                negligible. (See also production_e_init).
+                   dudz(k,j) = ( u(k+1,j,i) - surf_lsm_h%u_0(m) ) * dd2zu(k)   
+                   dvdz(k,j) = ( v(k+1,j,i) - surf_lsm_h%v_0(m) ) * dd2zu(k)
+            
+                ENDDO
+!
+!--             Urban surfaces
+                surf_s = surf_usm_h%start_index(j,i)
+                surf_e = surf_usm_h%end_index(j,i)
+                DO  m = surf_s, surf_e
+                   k = surf_usm_h%k(m)
+!
+!--                Please note, actually, an interpolation of u_0 and v_0 
+!--                onto the grid center would be required. However, this 
+!--                would require several data transfers between 2D-grid and
+!--                wall type. The effect of this missing interpolation is 
+!--                negligible. (See also production_e_init).
+                   dudz(k,j) = ( u(k+1,j,i) - surf_usm_h%u_0(m) ) * dd2zu(k)   
+                   dvdz(k,j) = ( v(k+1,j,i) - surf_usm_h%v_0(m) ) * dd2zu(k)
+            
+                ENDDO
+!
+!--             Compute gradients at downward-facing walls, only for 
+!--             non-natural default surfaces
+                surf_s = surf_def_h(1)%start_index(j,i)
+                surf_e = surf_def_h(1)%end_index(j,i)
+                DO  m = surf_s, surf_e
+                   k = surf_def_h(1)%k(m)
+!
+!--                Please note, actually, an interpolation of u_0 and v_0 
+!--                onto the grid center would be required. However, this 
+!--                would require several data transfers between 2D-grid and
+!--                wall type. The effect of this missing interpolation is 
+!--                negligible. (See also production_e_init).
+                   dudz(k,j) = ( surf_def_h(1)%u_0(m) - u(k-1,j,i) ) * dd2zu(k)   
+                   dvdz(k,j) = ( surf_def_h(1)%v_0(m) - v(k-1,j,i) ) * dd2zu(k)
+
+                ENDDO
+
+             ENDDO
+
+             DO  j = nys, nyn
+                DO  k = nzb+1, nzt
+
+                   def = 2.0_wp * ( dudx(k,j)**2 + dvdy(k,j)**2 + dwdz(k,j)**2 ) + &
+                                    dudy(k,j)**2 + dvdx(k,j)**2 + dwdx(k,j)**2 +   &
+                                    dwdy(k,j)**2 + dudz(k,j)**2 + dvdz(k,j)**2 +   &
+                         2.0_wp * ( dvdx(k,j)*dudy(k,j) + dwdx(k,j)*dudz(k,j)  +   &
+                                    dwdy(k,j)*dvdz(k,j) )
 
                    IF ( def < 0.0_wp )  def = 0.0_wp
 
-                   tend(k,j,i) = tend(k,j,i) + km(k,j,i) * def
-
-
-!
-!--                (3) - will be executed only, if there is at least one level
-!--                between (2) and (4), i.e. the topography must have a
-!--                minimum height of 2 dz. Wall fluxes for this case have
-!--                already been calculated for (2).
-!--                'wall only: use wall functions'
-
-                   DO  k = nzb_diff_s_inner(j,i), nzb_diff_s_outer(j,i)-2
-
-                      dudx = ( u(k,j,i+1) - u(k,j,i) ) * ddx
-                      dudz = 0.5_wp * ( u(k+1,j,i) + u(k+1,j,i+1) - &
-                                        u(k-1,j,i) - u(k-1,j,i+1) ) * dd2zu(k)
-                      dvdy =          ( v(k,j+1,i) - v(k,j,i)     ) * ddy
-                      dvdz = 0.5_wp * ( v(k+1,j,i) + v(k+1,j+1,i) - &
-                                        v(k-1,j,i) - v(k-1,j+1,i) ) * dd2zu(k)
-                      dwdz = ( w(k,j,i) - w(k-1,j,i) ) * ddzw(k)
-
-                      IF ( wall_e_y(j,i) /= 0.0_wp )  THEN
-!
-!--                      Inconsistency removed: as the thermal stratification 
-!--                      is not taken into account for the evaluation of the 
-!--                      wall fluxes at vertical walls, the eddy viscosity km 
-!--                      must not be used for the evaluation of the velocity 
-!--                      gradients dudy and dwdy
-!--                      Note: The validity of the new method has not yet 
-!--                            been shown, as so far no suitable data for a 
-!--                            validation has been available
-                         km_neutral = kappa * ( usvs(k)**2 + & 
-                                                wsvs(k)**2 )**0.25_wp * 0.5_wp * dy
-                         IF ( km_neutral > 0.0_wp )  THEN
-                            dudy = - wall_e_y(j,i) * usvs(k) / km_neutral
-                            dwdy = - wall_e_y(j,i) * wsvs(k) / km_neutral
-                         ELSE
-                            dudy = 0.0_wp
-                            dwdy = 0.0_wp
-                         ENDIF
-                      ELSE
-                         dudy = 0.25_wp * ( u(k,j+1,i) + u(k,j+1,i+1) - &
+                   flag  = MERGE( 1.0_wp, 0.0_wp, BTEST( wall_flags_0(k,j,i), 0 ) ) 
+
+                   tend(k,j,i) = tend(k,j,i) + km(k,j,i) * def * flag
+
+                ENDDO
+             ENDDO
+
+          ELSEIF ( use_surface_fluxes )  THEN
+
+             DO  j = nys, nyn
+!
+!--             Calculate TKE production by shear. Here, no additional
+!--             wall-bounded code is considered. 
+!--             Why?
+                DO  k = nzb+1, nzt
+
+                   dudx(k,j)  =           ( u(k,j,i+1) - u(k,j,i)     ) * ddx
+                   dudy(k,j)  = 0.25_wp * ( u(k,j+1,i) + u(k,j+1,i+1) -        &
                                             u(k,j-1,i) - u(k,j-1,i+1) ) * ddy
-                         dwdy = 0.25_wp * ( w(k,j+1,i) + w(k-1,j+1,i) - &
+                   dudz(k,j)  = 0.5_wp  * ( u(k+1,j,i) + u(k+1,j,i+1) -        &
+                                            u(k-1,j,i) - u(k-1,j,i+1) ) *      &
+                                                                        dd2zu(k)
+
+                   dvdx(k,j)  = 0.25_wp * ( v(k,j,i+1) + v(k,j+1,i+1) -        &
+                                            v(k,j,i-1) - v(k,j+1,i-1) ) * ddx
+                   dvdy(k,j)  =           ( v(k,j+1,i) - v(k,j,i)     ) * ddy
+                   dvdz(k,j)  = 0.5_wp  * ( v(k+1,j,i) + v(k+1,j+1,i) -        &
+                                            v(k-1,j,i) - v(k-1,j+1,i) ) *      &
+                                                                        dd2zu(k)
+
+                   dwdx(k,j)  = 0.25_wp * ( w(k,j,i+1) + w(k-1,j,i+1) -        &
+                                            w(k,j,i-1) - w(k-1,j,i-1) ) * ddx
+                   dwdy(k,j)  = 0.25_wp * ( w(k,j+1,i) + w(k-1,j+1,i) -        &
                                             w(k,j-1,i) - w(k-1,j-1,i) ) * ddy
-                      ENDIF
-
-                      IF ( wall_e_x(j,i) /= 0.0_wp )  THEN
-!
-!--                      Inconsistency removed: as the thermal stratification 
-!--                      is not taken into account for the evaluation of the 
-!--                      wall fluxes at vertical walls, the eddy viscosity km 
-!--                      must not be used for the evaluation of the velocity 
-!--                      gradients dvdx and dwdx
-!--                      Note: The validity of the new method has not yet 
-!--                            been shown, as so far no suitable data for a 
-!--                            validation has been available
-                         km_neutral = kappa * ( vsus(k)**2 + & 
-                                                wsus(k)**2 )**0.25_wp * 0.5_wp * dx
-                         IF ( km_neutral > 0.0_wp )  THEN
-                            dvdx = - wall_e_x(j,i) * vsus(k) / km_neutral
-                            dwdx = - wall_e_x(j,i) * wsus(k) / km_neutral
-                         ELSE
-                            dvdx = 0.0_wp
-                            dwdx = 0.0_wp
-                         ENDIF
-                      ELSE
-                         dvdx = 0.25_wp * ( v(k,j,i+1) + v(k,j+1,i+1) - &
-                                            v(k,j,i-1) - v(k,j+1,i-1) ) * ddx
-                         dwdx = 0.25_wp * ( w(k,j,i+1) + w(k-1,j,i+1) - &
-                                            w(k,j,i-1) - w(k-1,j,i-1) ) * ddx
-                      ENDIF
-
-                      def = 2.0_wp * ( dudx**2 + dvdy**2 + dwdz**2 ) +           &
-                           dudy**2 + dvdx**2 + dwdx**2 + dwdy**2 + dudz**2 +  &
-                           dvdz**2 + 2.0_wp * ( dvdx*dudy + dwdx*dudz + dwdy*dvdz )
-
-                      IF ( def < 0.0_wp )  def = 0.0_wp
-
-                      tend(k,j,i) = tend(k,j,i) + km(k,j,i) * def
-
-                   ENDDO
-
-                ENDIF
-
-             ENDDO
-
-!
-!--          (4) - will allways be executed.
-!--          'special case: free atmosphere' (as for case (0))
-             DO  j = nys, nyn
-
-                IF ( ( wall_e_x(j,i) /= 0.0_wp ) .OR. ( wall_e_y(j,i) /= 0.0_wp ) ) &
-                THEN
-
-                   k = nzb_diff_s_outer(j,i)-1
-
-                   dudx  =           ( u(k,j,i+1) - u(k,j,i)     ) * ddx
-                   dudy  = 0.25_wp * ( u(k,j+1,i) + u(k,j+1,i+1) - &
-                                       u(k,j-1,i) - u(k,j-1,i+1) ) * ddy
-                   dudz  = 0.5_wp  * ( u(k+1,j,i) + u(k+1,j,i+1) - &
-                                       u(k-1,j,i) - u(k-1,j,i+1) ) * dd2zu(k)
-
-                   dvdx  = 0.25_wp * ( v(k,j,i+1) + v(k,j+1,i+1) - &
-                                       v(k,j,i-1) - v(k,j+1,i-1) ) * ddx
-                   dvdy  =           ( v(k,j+1,i) - v(k,j,i)     ) * ddy
-                   dvdz  = 0.5_wp  * ( v(k+1,j,i) + v(k+1,j+1,i) - &
-                                       v(k-1,j,i) - v(k-1,j+1,i) ) * dd2zu(k)
-
-                   dwdx  = 0.25_wp * ( w(k,j,i+1) + w(k-1,j,i+1) - &
-                                       w(k,j,i-1) - w(k-1,j,i-1) ) * ddx
-                   dwdy  = 0.25_wp * ( w(k,j+1,i) + w(k-1,j+1,i) - &
-                                       w(k,j-1,i) - w(k-1,j-1,i) ) * ddy
-                   dwdz  =           ( w(k,j,i)   - w(k-1,j,i)   ) * ddzw(k)
-
-                   def = 2.0_wp * ( dudx**2 + dvdy**2 + dwdz**2 ) +           &
-                         dudy**2 + dvdx**2 + dwdx**2 + dwdy**2 + dudz**2 + &
-                         dvdz**2 + 2.0_wp * ( dvdx*dudy + dwdx*dudz + dwdy*dvdz )
+                   dwdz(k,j)  =           ( w(k,j,i)   - w(k-1,j,i)   ) *      &
+                                                                        ddzw(k)
+      
+                   def = 2.0_wp * (                                            &
+                                dudx(k,j)**2 + dvdy(k,j)**2 + dwdz(k,j)**2     &
+                                  ) +                                          &
+                                dudy(k,j)**2 + dvdx(k,j)**2 + dwdx(k,j)**2 +   &
+                                dwdy(k,j)**2 + dudz(k,j)**2 + dvdz(k,j)**2 +   &
+                         2.0_wp * (                                            &
+                                dvdx(k,j)*dudy(k,j) + dwdx(k,j)*dudz(k,j)  +   &
+                                dwdy(k,j)*dvdz(k,j)                            &
+                                  )
 
                    IF ( def < 0.0_wp )  def = 0.0_wp
 
-                   tend(k,j,i) = tend(k,j,i) + km(k,j,i) * def
-
-                ENDIF
-
-             ENDDO
-
-!
-!--          Position without adjacent wall
-!--          (1) - will allways be executed. 
-!--          'bottom only: use u_0,v_0'
-             DO  j = nys, nyn
-
-                IF ( ( wall_e_x(j,i) == 0.0_wp ) .AND. ( wall_e_y(j,i) == 0.0_wp ) ) &
-                THEN
-
-                   k = nzb_diff_s_inner(j,i)-1
-
-                   dudx  =           ( u(k,j,i+1) - u(k,j,i)     ) * ddx
-                   dudy  = 0.25_wp * ( u(k,j+1,i) + u(k,j+1,i+1) - &
-                                       u(k,j-1,i) - u(k,j-1,i+1) ) * ddy
-                   dudz  = 0.5_wp  * ( u(k+1,j,i) + u(k+1,j,i+1) - &
-                                       u_0(j,i)   - u_0(j,i+1)   ) * dd2zu(k)
-
-                   dvdx  = 0.25_wp * ( v(k,j,i+1) + v(k,j+1,i+1) - &
-                                       v(k,j,i-1) - v(k,j+1,i-1) ) * ddx
-                   dvdy  =           ( v(k,j+1,i) - v(k,j,i)     ) * ddy
-                   dvdz  = 0.5_wp  * ( v(k+1,j,i) + v(k+1,j+1,i) - &
-                                       v_0(j,i)   - v_0(j+1,i)   ) * dd2zu(k)
-
-                   dwdx  = 0.25_wp * ( w(k,j,i+1) + w(k-1,j,i+1) - &
-                                       w(k,j,i-1) - w(k-1,j,i-1) ) * ddx
-                   dwdy  = 0.25_wp * ( w(k,j+1,i) + w(k-1,j+1,i) - &
-                                       w(k,j-1,i) - w(k-1,j-1,i) ) * ddy
-                   dwdz  =           ( w(k,j,i)   - w(k-1,j,i)   ) * ddzw(k)
-
-                   def = 2.0_wp * ( dudx**2 + dvdy**2 + dwdz**2 ) +           &
-                         dudy**2 + dvdx**2 + dwdx**2 + dwdy**2 + dudz**2 + &
-                         dvdz**2 + 2.0_wp * ( dvdx*dudy + dwdx*dudz + dwdy*dvdz )
-
-                   IF ( def < 0.0_wp )  def = 0.0_wp
-
-                   tend(k,j,i) = tend(k,j,i) + km(k,j,i) * def
-
-                ENDIF
-
-             ENDDO
-
-          ELSEIF ( use_surface_fluxes )  THEN
-
-             DO  j = nys, nyn
-
-                k = nzb_diff_s_outer(j,i)-1
-
-                dudx  =           ( u(k,j,i+1) - u(k,j,i)     ) * ddx
-                dudy  = 0.25_wp * ( u(k,j+1,i) + u(k,j+1,i+1) - &
-                                    u(k,j-1,i) - u(k,j-1,i+1) ) * ddy
-                dudz  = 0.5_wp  * ( u(k+1,j,i) + u(k+1,j,i+1) - &
-                                   u(k-1,j,i) - u(k-1,j,i+1) ) * dd2zu(k)
-
-                dvdx  = 0.25_wp * ( v(k,j,i+1) + v(k,j+1,i+1) - &
-                                    v(k,j,i-1) - v(k,j+1,i-1) ) * ddx
-                dvdy  =           ( v(k,j+1,i) - v(k,j,i)     ) * ddy
-                dvdz  = 0.5_wp  * ( v(k+1,j,i) + v(k+1,j+1,i) - &
-                                    v(k-1,j,i) - v(k-1,j+1,i) ) * dd2zu(k)
-
-                dwdx  = 0.25_wp * ( w(k,j,i+1) + w(k-1,j,i+1) - &
-                                    w(k,j,i-1) - w(k-1,j,i-1) ) * ddx
-                dwdy  = 0.25_wp * ( w(k,j+1,i) + w(k-1,j+1,i) - &
-                                    w(k,j-1,i) - w(k-1,j-1,i) ) * ddy
-                dwdz  =           ( w(k,j,i)   - w(k-1,j,i)   ) * ddzw(k)
-
-                def = 2.0_wp * ( dudx**2 + dvdy**2 + dwdz**2 ) +           &
-                      dudy**2 + dvdx**2 + dwdx**2 + dwdy**2 + dudz**2 + &
-                      dvdz**2 + 2.0_wp * ( dvdx*dudy + dwdx*dudz + dwdy*dvdz )
-
-                IF ( def < 0.0_wp )  def = 0.0_wp
-
-                tend(k,j,i) = tend(k,j,i) + km(k,j,i) * def
-
+                   flag  = MERGE( 1.0_wp, 0.0_wp,                              &
+                                  BTEST( wall_flags_0(k,j,i), 29 ) ) 
+                   tend(k,j,i) = tend(k,j,i) + km(k,j,i) * def * flag
+      
+                ENDDO
              ENDDO
 
@@ -539,9 +489,12 @@
 !--                   in the bottom and top surface layer
                       DO  j = nys, nyn
-                         DO  k = nzb_s_inner(j,i)+1, nzt
+                         DO  k = nzb+1, nzt
                             tend(k,j,i) = tend(k,j,i) +                        &
                                           kh(k,j,i) * g / rho_reference *      &
                                           ( prho(k+1,j,i) - prho(k-1,j,i) ) *  &
-                                          dd2zu(k)
+                                          dd2zu(k) *                           &
+                                    MERGE( 1.0_wp, 0.0_wp,                     &
+                                             BTEST( wall_flags_0(k,j,i), 0 )   &
+                                          )
                          ENDDO
                       ENDDO
@@ -550,21 +503,60 @@
 
                       DO  j = nys, nyn
-                         DO  k = nzb_diff_s_inner(j,i), nzt_diff
-                            tend(k,j,i) = tend(k,j,i) -                   &
-                                          kh(k,j,i) * g / pt_reference *  &
-                                          ( pt(k+1,j,i) - pt(k-1,j,i) ) * &
-                                          dd2zu(k)
+                         DO  k = nzb+1, nzt
+!
+!--                         Flag 9 is used to mask top fluxes, flag 30 to mask
+!--                         surface fluxes
+                            tend(k,j,i) = tend(k,j,i) -                        &
+                                          kh(k,j,i) * g / pt_reference  *      &
+                                          ( pt(k+1,j,i) - pt(k-1,j,i) ) *      &
+                                          dd2zu(k)                      *      &
+                                      MERGE( 1.0_wp, 0.0_wp,                   &
+                                             BTEST( wall_flags_0(k,j,i), 30 )  &
+                                           )                            *      &
+                                      MERGE( 1.0_wp, 0.0_wp,                   &
+                                             BTEST( wall_flags_0(k,j,i), 9 )   &
+                                           )  
                          ENDDO
 
                          IF ( use_surface_fluxes )  THEN
-                            k = nzb_diff_s_inner(j,i)-1
-                            tend(k,j,i) = tend(k,j,i) + g / pt_reference * &
-                                                        shf(j,i)
+!
+!--                         Default surfaces, up- and downward-facing
+                            DO  l = 0, 1
+                               surf_s = surf_def_h(l)%start_index(j,i)
+                               surf_e = surf_def_h(l)%end_index(j,i)
+                               DO  m = surf_s, surf_e
+                                  k = surf_def_h(l)%k(m)
+                                  tend(k,j,i) = tend(k,j,i) + g / pt_reference &
+                                                         * surf_def_h(l)%shf(m)   
+                               ENDDO   
+                            ENDDO      
+!
+!--                         Natural surfaces
+                            surf_s = surf_lsm_h%start_index(j,i)
+                            surf_e = surf_lsm_h%end_index(j,i)
+                            DO  m = surf_s, surf_e
+                               k = surf_lsm_h%k(m)
+                               tend(k,j,i) = tend(k,j,i) + g / pt_reference    &
+                                                         * surf_lsm_h%shf(m)   
+                            ENDDO
+!
+!--                         Urban surfaces
+                            surf_s = surf_usm_h%start_index(j,i)
+                            surf_e = surf_usm_h%end_index(j,i)
+                            DO  m = surf_s, surf_e
+                               k = surf_usm_h%k(m)
+                               tend(k,j,i) = tend(k,j,i) + g / pt_reference    &
+                                                         * surf_usm_h%shf(m)   
+                            ENDDO                          
                          ENDIF
 
                          IF ( use_top_fluxes )  THEN
-                            k = nzt
-                            tend(k,j,i) = tend(k,j,i) + g / pt_reference * &
-                                                        tswst(j,i)
+                            surf_s = surf_def_h(2)%start_index(j,i)
+                            surf_e = surf_def_h(2)%end_index(j,i)
+                            DO  m = surf_s, surf_e
+                               k = surf_def_h(2)%k(m)
+                               tend(k,j,i) = tend(k,j,i) + g / pt_reference *     &
+                                                           surf_def_h(2)%shf(m) 
+                            ENDDO
                          ENDIF
                       ENDDO
@@ -579,9 +571,12 @@
 !--                   in the bottom and top surface layer
                       DO  j = nys, nyn
-                         DO  k = nzb_s_inner(j,i)+1, nzt
+                         DO  k = nzb+1, nzt
                             tend(k,j,i) = tend(k,j,i) +                        &
                                           kh(k,j,i) * g / prho(k,j,i) *        &
                                           ( prho(k+1,j,i) - prho(k-1,j,i) ) *  &
-                                          dd2zu(k)
+                                          dd2zu(k)                           * &
+                                     MERGE( 1.0_wp, 0.0_wp,                    &
+                                             BTEST( wall_flags_0(k,j,i), 0 )   &
+                                          )
                          ENDDO
                       ENDDO
@@ -590,21 +585,60 @@
 
                       DO  j = nys, nyn
-                         DO  k = nzb_diff_s_inner(j,i), nzt_diff
-                            tend(k,j,i) = tend(k,j,i) -                   &
-                                          kh(k,j,i) * g / pt(k,j,i) *     &
-                                          ( pt(k+1,j,i) - pt(k-1,j,i) ) * &
-                                          dd2zu(k)
+                         DO  k = nzb+1, nzt
+!
+!--                         Flag 9 is used to mask top fluxes, flag 30 to mask
+!--                         surface fluxes
+                            tend(k,j,i) = tend(k,j,i) -                        &
+                                          kh(k,j,i) * g / pt(k,j,i) *          &
+                                          ( pt(k+1,j,i) - pt(k-1,j,i) ) *      &
+                                          dd2zu(k)                      *      &
+                                      MERGE( 1.0_wp, 0.0_wp,                   &
+                                             BTEST( wall_flags_0(k,j,i), 30 )  &
+                                           )                            *      &
+                                      MERGE( 1.0_wp, 0.0_wp,                   &
+                                             BTEST( wall_flags_0(k,j,i), 9 )   &
+                                           ) 
                          ENDDO
 
                          IF ( use_surface_fluxes )  THEN
-                            k = nzb_diff_s_inner(j,i)-1
-                            tend(k,j,i) = tend(k,j,i) + g / pt(k,j,i) * &
-                                                        shf(j,i)
+!
+!--                         Default surfaces, up- and downwrd-facing
+                            DO  l = 0, 1
+                               surf_s = surf_def_h(l)%start_index(j,i)
+                               surf_e = surf_def_h(l)%end_index(j,i)
+                               DO  m = surf_s, surf_e
+                                  k = surf_def_h(l)%k(m)
+                                  tend(k,j,i) = tend(k,j,i) + g / pt_reference &
+                                                         * surf_def_h(l)%shf(m)   
+                               ENDDO  
+                            ENDDO
+!
+!--                         Natural surfaces
+                            surf_s = surf_lsm_h%start_index(j,i)
+                            surf_e = surf_lsm_h%end_index(j,i)
+                            DO  m = surf_s, surf_e
+                               k = surf_lsm_h%k(m)
+                               tend(k,j,i) = tend(k,j,i) + g / pt_reference    &
+                                                         * surf_lsm_h%shf(m)   
+                            ENDDO  
+!
+!--                         Urban surfaces
+                            surf_s = surf_usm_h%start_index(j,i)
+                            surf_e = surf_usm_h%end_index(j,i)
+                            DO  m = surf_s, surf_e
+                               k = surf_usm_h%k(m)
+                               tend(k,j,i) = tend(k,j,i) + g / pt_reference    &
+                                                         * surf_usm_h%shf(m)   
+                            ENDDO  
                          ENDIF
 
                          IF ( use_top_fluxes )  THEN
-                            k = nzt
-                            tend(k,j,i) = tend(k,j,i) + g / pt(k,j,i) * &
-                                                        tswst(j,i)
+                            surf_s = surf_def_h(2)%start_index(j,i)
+                            surf_e = surf_def_h(2)%end_index(j,i)
+                            DO  m = surf_s, surf_e
+                               k = surf_def_h(2)%k(m)
+                               tend(k,j,i) = tend(k,j,i) + g / pt_reference *     &
+                                                           surf_def_h(2)%shf(m) 
+                            ENDDO
                          ENDIF
                       ENDDO
@@ -618,6 +652,8 @@
                 DO  j = nys, nyn
 
-                   DO  k = nzb_diff_s_inner(j,i), nzt_diff
-
+                   DO  k = nzb+1, nzt
+!
+!--                   Flag 9 is used to mask top fluxes, flag 30 to mask
+!--                   surface fluxes
                       IF ( .NOT. cloud_physics .AND. .NOT. cloud_droplets ) THEN
                          k1 = 1.0_wp + 0.61_wp * q(k,j,i)
@@ -627,48 +663,11 @@
                                          ( k1 * ( pt(k+1,j,i)-pt(k-1,j,i) ) +  &
                                            k2 * ( q(k+1,j,i) - q(k-1,j,i) )    &
-                                         ) * dd2zu(k)
-                      ELSE IF ( cloud_physics )  THEN
-                         IF ( ql(k,j,i) == 0.0_wp )  THEN
-                            k1 = 1.0_wp + 0.61_wp * q(k,j,i)
-                            k2 = 0.61_wp * pt(k,j,i)
-                         ELSE
-                            theta = pt(k,j,i) + pt_d_t(k) * l_d_cp * ql(k,j,i)
-                            temp  = theta * t_d_pt(k)
-                            k1 = ( 1.0_wp - q(k,j,i) + 1.61_wp *               &
-                                          ( q(k,j,i) - ql(k,j,i) ) *          &
-                                 ( 1.0_wp + 0.622_wp * l_d_r / temp ) ) /        &
-                                 ( 1.0_wp + 0.622_wp * l_d_r * l_d_cp *          &
-                                 ( q(k,j,i) - ql(k,j,i) ) / ( temp * temp ) )
-                            k2 = theta * ( l_d_cp / temp * k1 - 1.0_wp )
-                         ENDIF
-                         tend(k,j,i) = tend(k,j,i) - kh(k,j,i) *               &
-                                         g / vpt(k,j,i) *                      &
-                                         ( k1 * ( pt(k+1,j,i)-pt(k-1,j,i) ) +  &
-                                           k2 * ( q(k+1,j,i) - q(k-1,j,i) )    &
-                                         ) * dd2zu(k)
-                      ELSE IF ( cloud_droplets )  THEN
-                         k1 = 1.0_wp + 0.61_wp * q(k,j,i) - ql(k,j,i)
-                         k2 = 0.61_wp * pt(k,j,i)
-                         tend(k,j,i) = tend(k,j,i) -                          & 
-                                       kh(k,j,i) * g / vpt(k,j,i) *           &
-                                       ( k1 * ( pt(k+1,j,i)- pt(k-1,j,i) ) +  &
-                                         k2 * ( q(k+1,j,i) -  q(k-1,j,i) ) -  &
-                                         pt(k,j,i) * ( ql(k+1,j,i) -          &
-                                         ql(k-1,j,i) ) ) * dd2zu(k)
-                      ENDIF
-
-                   ENDDO
-
-                ENDDO
-
-                IF ( use_surface_fluxes )  THEN
-
-                   DO  j = nys, nyn
-
-                      k = nzb_diff_s_inner(j,i)-1
-
-                      IF ( .NOT. cloud_physics .AND. .NOT. cloud_droplets ) THEN
-                         k1 = 1.0_wp + 0.61_wp * q(k,j,i)
-                         k2 = 0.61_wp * pt(k,j,i)
+                                         ) * dd2zu(k) *                        &
+                                      MERGE( 1.0_wp, 0.0_wp,                   &
+                                             BTEST( wall_flags_0(k,j,i), 30 )  &
+                                           )          *                        &
+                                      MERGE( 1.0_wp, 0.0_wp,                   &
+                                             BTEST( wall_flags_0(k,j,i), 9 )   &
+                                           )
                       ELSE IF ( cloud_physics )  THEN
                          IF ( ql(k,j,i) == 0.0_wp )  THEN
@@ -685,13 +684,143 @@
                             k2 = theta * ( l_d_cp / temp * k1 - 1.0_wp )
                          ENDIF
+                         tend(k,j,i) = tend(k,j,i) - kh(k,j,i) *               &
+                                         g / vpt(k,j,i) *                      &
+                                         ( k1 * ( pt(k+1,j,i)-pt(k-1,j,i) ) +  &
+                                           k2 * ( q(k+1,j,i) - q(k-1,j,i) )    &
+                                         ) * dd2zu(k) *                        &
+                                      MERGE( 1.0_wp, 0.0_wp,                   &
+                                             BTEST( wall_flags_0(k,j,i), 30 )  &
+                                           )          *                        &
+                                      MERGE( 1.0_wp, 0.0_wp,                   &
+                                             BTEST( wall_flags_0(k,j,i), 9 )   &
+                                           )
                       ELSE IF ( cloud_droplets )  THEN
                          k1 = 1.0_wp + 0.61_wp * q(k,j,i) - ql(k,j,i)
                          k2 = 0.61_wp * pt(k,j,i)
+                         tend(k,j,i) = tend(k,j,i) -                           & 
+                                       kh(k,j,i) * g / vpt(k,j,i) *            &
+                                       ( k1 * ( pt(k+1,j,i)- pt(k-1,j,i) ) +   &
+                                         k2 * ( q(k+1,j,i) -  q(k-1,j,i) ) -   &
+                                         pt(k,j,i) * ( ql(k+1,j,i) -           &
+                                         ql(k-1,j,i) ) ) * dd2zu(k) *          &
+                                      MERGE( 1.0_wp, 0.0_wp,                   &
+                                             BTEST( wall_flags_0(k,j,i), 30 )  &
+                                           )                        *          &
+                                      MERGE( 1.0_wp, 0.0_wp,                   &
+                                             BTEST( wall_flags_0(k,j,i), 9 )   &
+                                           )
                       ENDIF
 
-                      tend(k,j,i) = tend(k,j,i) + g / vpt(k,j,i) * &
-                                            ( k1* shf(j,i) + k2 * qsws(j,i) )
                    ENDDO
 
+                ENDDO
+
+                IF ( use_surface_fluxes )  THEN
+
+                   DO  j = nys, nyn
+!
+!--                   Treat horizontal default surfaces, up- and downward-facing
+                      DO  l = 0, 1
+                         surf_s = surf_def_h(l)%start_index(j,i)
+                         surf_e = surf_def_h(l)%end_index(j,i)
+                         DO  m = surf_s, surf_e
+                            k = surf_def_h(l)%k(m)
+
+                            IF ( .NOT. cloud_physics .AND. .NOT. cloud_droplets ) THEN
+                               k1 = 1.0_wp + 0.61_wp * q(k,j,i)
+                               k2 = 0.61_wp * pt(k,j,i)
+                            ELSE IF ( cloud_physics )  THEN
+                               IF ( ql(k,j,i) == 0.0_wp )  THEN
+                                  k1 = 1.0_wp + 0.61_wp * q(k,j,i)
+                                  k2 = 0.61_wp * pt(k,j,i)
+                               ELSE
+                                  theta = pt(k,j,i) + pt_d_t(k) * l_d_cp * ql(k,j,i)
+                                  temp  = theta * t_d_pt(k)
+                                  k1 = ( 1.0_wp - q(k,j,i) + 1.61_wp *         &
+                                             ( q(k,j,i) - ql(k,j,i) ) *        &
+                                    ( 1.0_wp + 0.622_wp * l_d_r / temp ) ) /   &
+                                    ( 1.0_wp + 0.622_wp * l_d_r * l_d_cp *     &
+                                    ( q(k,j,i) - ql(k,j,i) ) / ( temp * temp ) )
+                                  k2 = theta * ( l_d_cp / temp * k1 - 1.0_wp )
+                               ENDIF
+                            ELSE IF ( cloud_droplets )  THEN
+                               k1 = 1.0_wp + 0.61_wp * q(k,j,i) - ql(k,j,i)
+                               k2 = 0.61_wp * pt(k,j,i)
+                            ENDIF
+
+                            tend(k,j,i) = tend(k,j,i) + g / vpt(k,j,i) *       &
+                                               ( k1 * surf_def_h(l)%shf(m) +   &
+                                                 k2 * surf_def_h(l)%qsws(m) )
+                         ENDDO
+                      ENDDO
+!
+!--                   Treat horizontal natural surfaces
+                      surf_s = surf_lsm_h%start_index(j,i)
+                      surf_e = surf_lsm_h%end_index(j,i)
+                      DO  m = surf_s, surf_e
+                         k = surf_lsm_h%k(m)
+
+                         IF ( .NOT. cloud_physics .AND. .NOT. cloud_droplets ) THEN
+                            k1 = 1.0_wp + 0.61_wp * q(k,j,i)
+                            k2 = 0.61_wp * pt(k,j,i)
+                         ELSE IF ( cloud_physics )  THEN
+                            IF ( ql(k,j,i) == 0.0_wp )  THEN
+                               k1 = 1.0_wp + 0.61_wp * q(k,j,i)
+                               k2 = 0.61_wp * pt(k,j,i)
+                            ELSE
+                               theta = pt(k,j,i) + pt_d_t(k) * l_d_cp * ql(k,j,i)
+                               temp  = theta * t_d_pt(k)
+                               k1 = ( 1.0_wp - q(k,j,i) + 1.61_wp *            &
+                                             ( q(k,j,i) - ql(k,j,i) ) *        &
+                                    ( 1.0_wp + 0.622_wp * l_d_r / temp ) ) /   &
+                                    ( 1.0_wp + 0.622_wp * l_d_r * l_d_cp *     &
+                                    ( q(k,j,i) - ql(k,j,i) ) / ( temp * temp ) )
+                               k2 = theta * ( l_d_cp / temp * k1 - 1.0_wp )
+                            ENDIF
+                         ELSE IF ( cloud_droplets )  THEN
+                            k1 = 1.0_wp + 0.61_wp * q(k,j,i) - ql(k,j,i)
+                            k2 = 0.61_wp * pt(k,j,i)
+                         ENDIF
+
+                         tend(k,j,i) = tend(k,j,i) + g / vpt(k,j,i) *          &
+                                               ( k1 * surf_lsm_h%shf(m) +      &
+                                                 k2 * surf_lsm_h%qsws(m) )
+                      ENDDO
+!
+!--                   Treat horizontal urban surfaces
+                      surf_s = surf_usm_h%start_index(j,i)
+                      surf_e = surf_usm_h%end_index(j,i)
+                      DO  m = surf_s, surf_e
+                         k = surf_lsm_h%k(m)
+
+                         IF ( .NOT. cloud_physics .AND. .NOT. cloud_droplets ) THEN
+                            k1 = 1.0_wp + 0.61_wp * q(k,j,i)
+                            k2 = 0.61_wp * pt(k,j,i)
+                         ELSE IF ( cloud_physics )  THEN
+                            IF ( ql(k,j,i) == 0.0_wp )  THEN
+                               k1 = 1.0_wp + 0.61_wp * q(k,j,i)
+                               k2 = 0.61_wp * pt(k,j,i)
+                            ELSE
+                               theta = pt(k,j,i) + pt_d_t(k) * l_d_cp * ql(k,j,i)
+                               temp  = theta * t_d_pt(k)
+                               k1 = ( 1.0_wp - q(k,j,i) + 1.61_wp *            &
+                                             ( q(k,j,i) - ql(k,j,i) ) *        &
+                                    ( 1.0_wp + 0.622_wp * l_d_r / temp ) ) /   &
+                                    ( 1.0_wp + 0.622_wp * l_d_r * l_d_cp *     &
+                                    ( q(k,j,i) - ql(k,j,i) ) / ( temp * temp ) )
+                               k2 = theta * ( l_d_cp / temp * k1 - 1.0_wp )
+                            ENDIF
+                         ELSE IF ( cloud_droplets )  THEN
+                            k1 = 1.0_wp + 0.61_wp * q(k,j,i) - ql(k,j,i)
+                            k2 = 0.61_wp * pt(k,j,i)
+                         ENDIF
+
+                         tend(k,j,i) = tend(k,j,i) + g / vpt(k,j,i) *          &
+                                               ( k1 * surf_usm_h%shf(m) +      &
+                                                 k2 * surf_usm_h%qsws(m) )
+                      ENDDO
+
+                   ENDDO
+
                 ENDIF
 
@@ -700,5 +829,608 @@
                    DO  j = nys, nyn
 
-                      k = nzt
+                      surf_s = surf_def_h(2)%start_index(j,i)
+                      surf_e = surf_def_h(2)%end_index(j,i)
+                      DO  m = surf_s, surf_e
+                         k = surf_def_h(2)%k(m)
+
+                         IF ( .NOT. cloud_physics .AND. .NOT. cloud_droplets ) THEN
+                            k1 = 1.0_wp + 0.61_wp * q(k,j,i)
+                            k2 = 0.61_wp * pt(k,j,i)
+                         ELSE IF ( cloud_physics )  THEN
+                            IF ( ql(k,j,i) == 0.0_wp )  THEN
+                               k1 = 1.0_wp + 0.61_wp * q(k,j,i)
+                               k2 = 0.61_wp * pt(k,j,i)
+                            ELSE
+                               theta = pt(k,j,i) + pt_d_t(k) * l_d_cp * ql(k,j,i)
+                               temp  = theta * t_d_pt(k)
+                               k1 = ( 1.0_wp - q(k,j,i) + 1.61_wp *            &
+                                          ( q(k,j,i) - ql(k,j,i) ) *           &
+                                 ( 1.0_wp + 0.622_wp * l_d_r / temp ) ) /      &
+                                 ( 1.0_wp + 0.622_wp * l_d_r * l_d_cp *        &
+                                 ( q(k,j,i) - ql(k,j,i) ) / ( temp * temp ) )
+                               k2 = theta * ( l_d_cp / temp * k1 - 1.0_wp )
+                            ENDIF
+                         ELSE IF ( cloud_droplets )  THEN
+                            k1 = 1.0_wp + 0.61_wp * q(k,j,i) - ql(k,j,i)
+                            k2 = 0.61_wp * pt(k,j,i)
+                         ENDIF
+
+                         tend(k,j,i) = tend(k,j,i) + g / vpt(k,j,i) *          &
+                                               ( k1 * surf_def_h(2)%shf(m) +   &
+                                                 k2 * surf_def_h(2)%qsws(m) )
+
+                      ENDDO
+
+                   ENDDO
+
+                ENDIF
+
+             ENDIF
+
+          ENDIF
+
+       ENDDO
+
+    END SUBROUTINE production_e
+
+
+!------------------------------------------------------------------------------!
+! Description:
+! ------------
+!> Call for grid point i,j
+!------------------------------------------------------------------------------!
+    SUBROUTINE production_e_ij( i, j )
+
+       USE arrays_3d,                                                          &
+           ONLY:  ddzw, dd2zu, kh, km, prho, pt, q, ql, tend, u, v, vpt, w
+
+       USE cloud_parameters,                                                   &
+           ONLY:  l_d_cp, l_d_r, pt_d_t, t_d_pt
+
+       USE control_parameters,                                                 &
+           ONLY:  cloud_droplets, cloud_physics, constant_flux_layer, g,       &
+                  humidity, kappa, neutral, ocean, pt_reference,               &
+                  rho_reference, use_single_reference_value,                   &
+                  use_surface_fluxes, use_top_fluxes
+
+       USE grid_variables,                                                     &
+           ONLY:  ddx, dx, ddy, dy
+
+       USE indices,                                                            &
+           ONLY:  nxl, nxr, nys, nyn, nzb, nzb, nzt, wall_flags_0
+
+       USE surface_mod,                                                        &
+           ONLY :  surf_def_h, surf_def_v, surf_lsm_h, surf_lsm_v, surf_usm_h, &
+                   surf_usm_v 
+
+       IMPLICIT NONE
+
+       INTEGER(iwp) ::  i       !< running index x-direction
+       INTEGER(iwp) ::  j       !< running index y-direction
+       INTEGER(iwp) ::  k       !< running index z-direction
+       INTEGER(iwp) ::  l       !< running index for different surface type orientation
+       INTEGER(iwp) ::  m       !< running index surface elements
+       INTEGER(iwp) ::  surf_e  !< end index of surface elements at given i-j position
+       INTEGER(iwp) ::  surf_s  !< start index of surface elements at given i-j position
+
+       REAL(wp)     ::  def         !<
+       REAL(wp)     ::  flag        !< flag to mask topography
+       REAL(wp)     ::  k1          !<
+       REAL(wp)     ::  k2          !<
+       REAL(wp)     ::  km_neutral  !< diffusion coefficient assuming neutral conditions - used to compute shear production at surfaces
+       REAL(wp)     ::  theta       !<
+       REAL(wp)     ::  temp        !<
+       REAL(wp)     ::  sign_dir    !< sign of wall-tke flux, depending on wall orientation 
+       REAL(wp)     ::  usvs        !< momentum flux u"v"
+       REAL(wp)     ::  vsus        !< momentum flux v"u"
+       REAL(wp)     ::  wsus        !< momentum flux w"u"
+       REAL(wp)     ::  wsvs        !< momentum flux w"v"
+
+
+       REAL(wp), DIMENSION(nzb+1:nzt)  ::  dudx        !< Gradient of u-component in x-direction
+       REAL(wp), DIMENSION(nzb+1:nzt)  ::  dudy        !< Gradient of u-component in y-direction
+       REAL(wp), DIMENSION(nzb+1:nzt)  ::  dudz        !< Gradient of u-component in z-direction
+       REAL(wp), DIMENSION(nzb+1:nzt)  ::  dvdx        !< Gradient of v-component in x-direction
+       REAL(wp), DIMENSION(nzb+1:nzt)  ::  dvdy        !< Gradient of v-component in y-direction
+       REAL(wp), DIMENSION(nzb+1:nzt)  ::  dvdz        !< Gradient of v-component in z-direction
+       REAL(wp), DIMENSION(nzb+1:nzt)  ::  dwdx        !< Gradient of w-component in x-direction
+       REAL(wp), DIMENSION(nzb+1:nzt)  ::  dwdy        !< Gradient of w-component in y-direction
+       REAL(wp), DIMENSION(nzb+1:nzt)  ::  dwdz        !< Gradient of w-component in z-direction
+
+
+       IF ( constant_flux_layer )  THEN
+!
+!--       Calculate TKE production by shear. Calculate gradients at all grid 
+!--       points first, gradients at surface-bounded grid points will be 
+!--       overwritten further below. 
+          DO  k = nzb+1, nzt
+
+             dudx(k)  =           ( u(k,j,i+1) - u(k,j,i)     ) * ddx
+             dudy(k)  = 0.25_wp * ( u(k,j+1,i) + u(k,j+1,i+1) -                &
+                                    u(k,j-1,i) - u(k,j-1,i+1) ) * ddy 
+             dudz(k)  = 0.5_wp  * ( u(k+1,j,i) + u(k+1,j,i+1) -                &
+                                    u(k-1,j,i) - u(k-1,j,i+1) ) * dd2zu(k) 
+
+             dvdx(k)  = 0.25_wp * ( v(k,j,i+1) + v(k,j+1,i+1) -                &
+                                    v(k,j,i-1) - v(k,j+1,i-1) ) * ddx      
+             dvdy(k)  =           ( v(k,j+1,i) - v(k,j,i)     ) * ddy
+             dvdz(k)  = 0.5_wp  * ( v(k+1,j,i) + v(k+1,j+1,i) -                &
+                                    v(k-1,j,i) - v(k-1,j+1,i) ) * dd2zu(k) 
+
+             dwdx(k)  = 0.25_wp * ( w(k,j,i+1) + w(k-1,j,i+1) -                &
+                                    w(k,j,i-1) - w(k-1,j,i-1) ) * ddx      
+             dwdy(k)  = 0.25_wp * ( w(k,j+1,i) + w(k-1,j+1,i) -                &
+                                    w(k,j-1,i) - w(k-1,j-1,i) ) * ddy      
+             dwdz(k)  =           ( w(k,j,i)   - w(k-1,j,i)   ) * ddzw(k)
+
+          ENDDO
+!
+!--       Compute gradients at north- and south-facing surfaces.
+!--       Note, no vertical natural surfaces so far.
+          DO  l = 0, 1
+!
+!--          Default surfaces
+             surf_s = surf_def_v(l)%start_index(j,i)
+             surf_e = surf_def_v(l)%end_index(j,i)
+             DO  m = surf_s, surf_e
+                k           = surf_def_v(l)%k(m)
+                usvs        = surf_def_v(l)%mom_flux_tke(0,m)
+                wsvs        = surf_def_v(l)%mom_flux_tke(1,m)
+
+                km_neutral = kappa * ( usvs**2 + wsvs**2 )**0.25_wp            &
+                                * 0.5_wp * dy
+!
+!--             -1.0 for right-facing wall, 1.0 for left-facing wall
+                sign_dir = MERGE( 1.0_wp, -1.0_wp,                             &
+                                  BTEST( wall_flags_0(k,j-1,i), 0 ) ) 
+                dudy(k) = sign_dir * usvs / ( km_neutral + 1E-10_wp )
+                dwdy(k) = sign_dir * wsvs / ( km_neutral + 1E-10_wp )
+             ENDDO   
+!
+!--          Natural surfaces
+             surf_s = surf_lsm_v(l)%start_index(j,i)
+             surf_e = surf_lsm_v(l)%end_index(j,i)
+             DO  m = surf_s, surf_e
+                k           = surf_lsm_v(l)%k(m)
+                usvs        = surf_lsm_v(l)%mom_flux_tke(0,m)
+                wsvs        = surf_lsm_v(l)%mom_flux_tke(1,m)
+
+                km_neutral = kappa * ( usvs**2 + wsvs**2 )**0.25_wp            &
+                                * 0.5_wp * dy
+!
+!--             -1.0 for right-facing wall, 1.0 for left-facing wall
+                sign_dir = MERGE( 1.0_wp, -1.0_wp,                             &
+                                  BTEST( wall_flags_0(k,j-1,i), 0 ) ) 
+                dudy(k) = sign_dir * usvs / ( km_neutral + 1E-10_wp )
+                dwdy(k) = sign_dir * wsvs / ( km_neutral + 1E-10_wp )
+             ENDDO 
+!
+!--          Urban surfaces
+             surf_s = surf_usm_v(l)%start_index(j,i)
+             surf_e = surf_usm_v(l)%end_index(j,i)
+             DO  m = surf_s, surf_e
+                k           = surf_usm_v(l)%k(m)
+                usvs        = surf_usm_v(l)%mom_flux_tke(0,m)
+                wsvs        = surf_usm_v(l)%mom_flux_tke(1,m)
+
+                km_neutral = kappa * ( usvs**2 + wsvs**2 )**0.25_wp            &
+                                * 0.5_wp * dy
+!
+!--             -1.0 for right-facing wall, 1.0 for left-facing wall
+                sign_dir = MERGE( 1.0_wp, -1.0_wp,                             &
+                                  BTEST( wall_flags_0(k,j-1,i), 0 ) ) 
+                dudy(k) = sign_dir * usvs / ( km_neutral + 1E-10_wp )
+                dwdy(k) = sign_dir * wsvs / ( km_neutral + 1E-10_wp )
+             ENDDO 
+          ENDDO
+!
+!--       Compute gradients at east- and west-facing walls
+          DO  l = 2, 3
+!
+!--          Default surfaces
+             surf_s = surf_def_v(l)%start_index(j,i)
+             surf_e = surf_def_v(l)%end_index(j,i)
+             DO  m = surf_s, surf_e
+                k           = surf_def_v(l)%k(m)
+                vsus        = surf_def_v(l)%mom_flux_tke(0,m)
+                wsus        = surf_def_v(l)%mom_flux_tke(1,m)
+
+                km_neutral = kappa * ( vsus**2 + wsus**2 )**0.25_wp            &
+                                   * 0.5_wp * dx
+!
+!--             -1.0 for right-facing wall, 1.0 for left-facing wall
+                sign_dir = MERGE( 1.0_wp, -1.0_wp,                             &
+                                  BTEST( wall_flags_0(k,j,i-1), 0 ) ) 
+                dvdx(k) = sign_dir * vsus / ( km_neutral + 1E-10_wp )
+                dwdx(k) = sign_dir * wsus / ( km_neutral + 1E-10_wp )
+             ENDDO 
+!
+!--          Natural surfaces
+             surf_s = surf_lsm_v(l)%start_index(j,i)
+             surf_e = surf_lsm_v(l)%end_index(j,i)
+             DO  m = surf_s, surf_e
+                k           = surf_lsm_v(l)%k(m)
+                vsus        = surf_lsm_v(l)%mom_flux_tke(0,m)
+                wsus        = surf_lsm_v(l)%mom_flux_tke(1,m)
+
+                km_neutral = kappa * ( vsus**2 + wsus**2 )**0.25_wp            &
+                                   * 0.5_wp * dx
+!
+!--             -1.0 for right-facing wall, 1.0 for left-facing wall
+                sign_dir = MERGE( 1.0_wp, -1.0_wp,                             &
+                                  BTEST( wall_flags_0(k,j,i-1), 0 ) ) 
+                dvdx(k) = sign_dir * vsus / ( km_neutral + 1E-10_wp )
+                dwdx(k) = sign_dir * wsus / ( km_neutral + 1E-10_wp )
+             ENDDO 
+!
+!--          Urban surfaces
+             surf_s = surf_usm_v(l)%start_index(j,i)
+             surf_e = surf_usm_v(l)%end_index(j,i)
+             DO  m = surf_s, surf_e
+                k           = surf_usm_v(l)%k(m)
+                vsus        = surf_usm_v(l)%mom_flux_tke(0,m)
+                wsus        = surf_usm_v(l)%mom_flux_tke(1,m)
+
+                km_neutral = kappa * ( vsus**2 + wsus**2 )**0.25_wp            &
+                                   * 0.5_wp * dx
+!
+!--             -1.0 for right-facing wall, 1.0 for left-facing wall
+                sign_dir = MERGE( 1.0_wp, -1.0_wp,                             &
+                                  BTEST( wall_flags_0(k,j,i-1), 0 ) ) 
+                dvdx(k) = sign_dir * vsus / ( km_neutral + 1E-10_wp )
+                dwdx(k) = sign_dir * wsus / ( km_neutral + 1E-10_wp )
+             ENDDO 
+          ENDDO
+!
+!--       Compute gradients at upward-facing walls, first for 
+!--       non-natural default surfaces
+          surf_s = surf_def_h(0)%start_index(j,i)
+          surf_e = surf_def_h(0)%end_index(j,i)
+          DO  m = surf_s, surf_e
+             k = surf_def_h(0)%k(m)
+!
+!--          Please note, actually, an interpolation of u_0 and v_0 
+!--          onto the grid center would be required. However, this 
+!--          would require several data transfers between 2D-grid and
+!--          wall type. The effect of this missing interpolation is 
+!--          negligible. (See also production_e_init).
+             dudz(k)     = ( u(k+1,j,i) - surf_def_h(0)%u_0(m) ) * dd2zu(k)   
+             dvdz(k)     = ( v(k+1,j,i) - surf_def_h(0)%v_0(m) ) * dd2zu(k)
+
+          ENDDO
+!
+!--       Natural surfaces
+          surf_s = surf_lsm_h%start_index(j,i)
+          surf_e = surf_lsm_h%end_index(j,i)
+          DO  m = surf_s, surf_e
+             k = surf_lsm_h%k(m)
+!
+!--          Please note, actually, an interpolation of u_0 and v_0 
+!--          onto the grid center would be required. However, this 
+!--          would require several data transfers between 2D-grid and
+!--          wall type. The effect of this missing interpolation is 
+!--          negligible. (See also production_e_init).
+             dudz(k)     = ( u(k+1,j,i) - surf_lsm_h%u_0(m) ) * dd2zu(k)   
+             dvdz(k)     = ( v(k+1,j,i) - surf_lsm_h%v_0(m) ) * dd2zu(k)
+          ENDDO
+!
+!--       Urban surfaces
+          surf_s = surf_usm_h%start_index(j,i)
+          surf_e = surf_usm_h%end_index(j,i)
+          DO  m = surf_s, surf_e
+             k = surf_usm_h%k(m)
+!
+!--          Please note, actually, an interpolation of u_0 and v_0 
+!--          onto the grid center would be required. However, this 
+!--          would require several data transfers between 2D-grid and
+!--          wall type. The effect of this missing interpolation is 
+!--          negligible. (See also production_e_init).
+             dudz(k)     = ( u(k+1,j,i) - surf_usm_h%u_0(m) ) * dd2zu(k)   
+             dvdz(k)     = ( v(k+1,j,i) - surf_usm_h%v_0(m) ) * dd2zu(k)
+          ENDDO
+!
+!--       Compute gradients at downward-facing walls, only for 
+!--       non-natural default surfaces
+          surf_s = surf_def_h(1)%start_index(j,i)
+          surf_e = surf_def_h(1)%end_index(j,i)
+          DO  m = surf_s, surf_e
+             k = surf_def_h(1)%k(m)
+!
+!--          Please note, actually, an interpolation of u_0 and v_0 
+!--          onto the grid center would be required. However, this 
+!--          would require several data transfers between 2D-grid and
+!--          wall type. The effect of this missing interpolation is 
+!--          negligible. (See also production_e_init).
+             dudz(k)     = ( surf_def_h(1)%u_0(m) - u(k-1,j,i) ) * dd2zu(k)   
+             dvdz(k)     = ( surf_def_h(1)%v_0(m) - v(k-1,j,i) ) * dd2zu(k) 
+
+          ENDDO
+
+          DO  k = nzb+1, nzt
+
+             def = 2.0_wp * ( dudx(k)**2 + dvdy(k)**2 + dwdz(k)**2 ) +         &
+                              dudy(k)**2 + dvdx(k)**2 + dwdx(k)**2   +         &
+                              dwdy(k)**2 + dudz(k)**2 + dvdz(k)**2   +         &
+                   2.0_wp * ( dvdx(k)*dudy(k) + dwdx(k)*dudz(k) + dwdy(k)*dvdz(k) )
+
+             IF ( def < 0.0_wp )  def = 0.0_wp
+
+             flag  = MERGE( 1.0_wp, 0.0_wp, BTEST( wall_flags_0(k,j,i), 0 ) ) 
+
+             tend(k,j,i) = tend(k,j,i) + km(k,j,i) * def * flag
+
+          ENDDO
+
+       ELSEIF ( use_surface_fluxes )  THEN
+!
+!--       Calculate TKE production by shear. Here, no additional
+!--       wall-bounded code is considered. 
+!--       Why?
+          DO  k = nzb+1, nzt
+
+             dudx(k)  =           ( u(k,j,i+1) - u(k,j,i)     ) * ddx
+             dudy(k)  = 0.25_wp * ( u(k,j+1,i) + u(k,j+1,i+1) -                &
+                                    u(k,j-1,i) - u(k,j-1,i+1) ) * ddy
+             dudz(k)  = 0.5_wp  * ( u(k+1,j,i) + u(k+1,j,i+1) -                &
+                                    u(k-1,j,i) - u(k-1,j,i+1) ) * dd2zu(k)
+
+             dvdx(k)  = 0.25_wp * ( v(k,j,i+1) + v(k,j+1,i+1) -                &
+                                    v(k,j,i-1) - v(k,j+1,i-1) ) * ddx
+             dvdy(k)  =           ( v(k,j+1,i) - v(k,j,i)     ) * ddy
+             dvdz(k)  = 0.5_wp  * ( v(k+1,j,i) + v(k+1,j+1,i) -                &
+                                    v(k-1,j,i) - v(k-1,j+1,i) ) * dd2zu(k)
+
+             dwdx(k)  = 0.25_wp * ( w(k,j,i+1) + w(k-1,j,i+1) -                &
+                                    w(k,j,i-1) - w(k-1,j,i-1) ) * ddx
+             dwdy(k)  = 0.25_wp * ( w(k,j+1,i) + w(k-1,j+1,i) -                &
+                                    w(k,j-1,i) - w(k-1,j-1,i) ) * ddy
+             dwdz(k)  =           ( w(k,j,i)   - w(k-1,j,i)   ) * ddzw(k)
+
+             def = 2.0_wp * ( dudx(k)**2 + dvdy(k)**2 + dwdz(k)**2 ) +         &
+                              dudy(k)**2 + dvdx(k)**2 + dwdx(k)**2   +         &
+                              dwdy(k)**2 + dudz(k)**2 + dvdz(k)**2   +         &
+                   2.0_wp * ( dvdx(k)*dudy(k) + dwdx(k)*dudz(k) + dwdy(k)*dvdz(k) )
+
+             IF ( def < 0.0_wp )  def = 0.0_wp
+
+             flag        = MERGE( 1.0_wp, 0.0_wp,                              &
+                                  BTEST( wall_flags_0(k,j,i), 29 ) ) 
+             tend(k,j,i) = tend(k,j,i) + km(k,j,i) * def * flag
+
+          ENDDO
+
+       ENDIF
+
+!
+!--    If required, calculate TKE production by buoyancy
+       IF ( .NOT. neutral )  THEN
+
+          IF ( .NOT. humidity )  THEN
+
+             IF ( use_single_reference_value )  THEN
+
+                IF ( ocean )  THEN
+!
+!--                So far in the ocean no special treatment of density flux in
+!--                the bottom and top surface layer
+                   DO  k = nzb+1, nzt
+                      tend(k,j,i) = tend(k,j,i) +                              &
+                                    kh(k,j,i) * g / rho_reference *            &
+                                    ( prho(k+1,j,i) - prho(k-1,j,i) ) *        &
+                                    dd2zu(k) *                                 &
+                                      MERGE( 1.0_wp, 0.0_wp,                   &
+                                             BTEST( wall_flags_0(k,j,i), 0 )   &
+                                           )                                   
+                   ENDDO
+
+                ELSE
+
+                   DO  k = nzb+1, nzt
+!
+!--                   Flag 9 is used to mask top fluxes, flag 30 to mask
+!--                   surface fluxes
+                      tend(k,j,i) = tend(k,j,i) -                              &
+                                    kh(k,j,i) * g / pt_reference *             &
+                                    ( pt(k+1,j,i) - pt(k-1,j,i) ) * dd2zu(k) * &
+                                      MERGE( 1.0_wp, 0.0_wp,                   &
+                                             BTEST( wall_flags_0(k,j,i), 30 )  &
+                                           ) *                                 &
+                                      MERGE( 1.0_wp, 0.0_wp,                   &
+                                             BTEST( wall_flags_0(k,j,i), 9 )   &
+                                           )
+
+                   ENDDO
+
+                   IF ( use_surface_fluxes )  THEN
+!
+!--                   Default surfaces, up- and downward-facing
+                      DO  l = 0, 1
+                         surf_s = surf_def_h(l)%start_index(j,i)
+                         surf_e = surf_def_h(l)%end_index(j,i)
+                         DO  m = surf_s, surf_e
+                            k = surf_def_h(l)%k(m)
+                            tend(k,j,i) = tend(k,j,i) + g / pt_reference *     &
+                                                           surf_def_h(l)%shf(m) 
+                         ENDDO
+                      ENDDO
+!
+!--                   Natural surfaces
+                      surf_s = surf_lsm_h%start_index(j,i)
+                      surf_e = surf_lsm_h%end_index(j,i)
+                      DO  m = surf_s, surf_e
+                         k = surf_lsm_h%k(m)
+                         tend(k,j,i) = tend(k,j,i) + g / pt_reference *        &
+                                                           surf_lsm_h%shf(m) 
+                      ENDDO
+!
+!--                   Urban surfaces
+                      surf_s = surf_usm_h%start_index(j,i)
+                      surf_e = surf_usm_h%end_index(j,i)
+                      DO  m = surf_s, surf_e
+                         k = surf_usm_h%k(m)
+                         tend(k,j,i) = tend(k,j,i) + g / pt_reference *        &
+                                                           surf_usm_h%shf(m) 
+                      ENDDO
+                   ENDIF
+
+                   IF ( use_top_fluxes )  THEN
+                      surf_s = surf_def_h(2)%start_index(j,i)
+                      surf_e = surf_def_h(2)%end_index(j,i)
+                      DO  m = surf_s, surf_e
+                         k = surf_def_h(2)%k(m)
+                         tend(k,j,i) = tend(k,j,i) + g / pt_reference *        &
+                                                           surf_def_h(2)%shf(m) 
+                      ENDDO
+                   ENDIF
+
+                ENDIF
+
+             ELSE
+
+                IF ( ocean )  THEN
+!
+!--                So far in the ocean no special treatment of density flux in
+!--                the bottom and top surface layer
+                   DO  k = nzb+1, nzt
+                      tend(k,j,i) = tend(k,j,i) +                              &
+                                    kh(k,j,i) * g / prho(k,j,i)       *        &
+                                    ( prho(k+1,j,i) - prho(k-1,j,i) ) *        &
+                                    dd2zu(k) *                                 &
+                                      MERGE( 1.0_wp, 0.0_wp,                   &
+                                             BTEST( wall_flags_0(k,j,i), 0 )   &
+                                           )
+                   ENDDO
+
+                ELSE
+
+                   DO  k = nzb+1, nzt
+!
+!--                   Flag 9 is used to mask top fluxes, flag 30 to mask
+!--                   surface fluxes
+                      tend(k,j,i) = tend(k,j,i) -                              &
+                                    kh(k,j,i) * g / pt(k,j,i) *                &
+                                    ( pt(k+1,j,i) - pt(k-1,j,i) ) * dd2zu(k) * &
+                                      MERGE( 1.0_wp, 0.0_wp,                   &
+                                             BTEST( wall_flags_0(k,j,i), 30 )  &
+                                           ) *                                 &
+                                      MERGE( 1.0_wp, 0.0_wp,                   &
+                                             BTEST( wall_flags_0(k,j,i), 9 )   &
+                                           )
+                   ENDDO
+
+                   IF ( use_surface_fluxes )  THEN
+!
+!--                   Default surfaces, up- and downward-facing
+                      DO  l = 0, 1
+                         surf_s = surf_def_h(l)%start_index(j,i)
+                         surf_e = surf_def_h(l)%end_index(j,i)
+                         DO  m = surf_s, surf_e
+                            k = surf_def_h(l)%k(m)
+                            tend(k,j,i) = tend(k,j,i) + g / pt_reference       &
+                                                   * surf_def_h(l)%shf(m)   
+                         ENDDO  
+                      ENDDO
+!
+!--                   Natural surfaces
+                      surf_s = surf_lsm_h%start_index(j,i)
+                      surf_e = surf_lsm_h%end_index(j,i)
+                      DO  m = surf_s, surf_e
+                         k = surf_lsm_h%k(m)
+                         tend(k,j,i) = tend(k,j,i) + g / pt_reference          &
+                                                     * surf_lsm_h%shf(m)   
+                      ENDDO  
+!
+!--                   Urban surfaces
+                      surf_s = surf_usm_h%start_index(j,i)
+                      surf_e = surf_usm_h%end_index(j,i)
+                      DO  m = surf_s, surf_e
+                         k = surf_usm_h%k(m)
+                         tend(k,j,i) = tend(k,j,i) + g / pt_reference          &
+                                                     * surf_usm_h%shf(m)   
+                      ENDDO
+                   ENDIF
+
+                   IF ( use_top_fluxes )  THEN
+                      surf_s = surf_def_h(2)%start_index(j,i)
+                      surf_e = surf_def_h(2)%end_index(j,i)
+                      DO  m = surf_s, surf_e
+                         k = surf_def_h(2)%k(m)
+                         tend(k,j,i) = tend(k,j,i) + g / pt_reference *        &
+                                                           surf_def_h(2)%shf(m) 
+                      ENDDO
+                   ENDIF
+
+                ENDIF
+
+             ENDIF
+
+          ELSE
+
+             DO  k = nzb+1, nzt
+!
+!--             Flag 9 is used to mask top fluxes, flag 30 to mask surface fluxes
+                IF ( .NOT. cloud_physics .AND. .NOT. cloud_droplets )  THEN
+                   k1 = 1.0_wp + 0.61_wp * q(k,j,i)
+                   k2 = 0.61_wp * pt(k,j,i)
+                   tend(k,j,i) = tend(k,j,i) - kh(k,j,i) * g / vpt(k,j,i) *    &
+                                         ( k1 * ( pt(k+1,j,i)-pt(k-1,j,i) ) +  &
+                                           k2 * ( q(k+1,j,i) - q(k-1,j,i) )    &
+                                         ) * dd2zu(k) *                        &
+                                      MERGE( 1.0_wp, 0.0_wp,                   &
+                                             BTEST( wall_flags_0(k,j,i), 30 )  &
+                                           )          *                        &
+                                      MERGE( 1.0_wp, 0.0_wp,                   &
+                                             BTEST( wall_flags_0(k,j,i), 9 )   &
+                                           )
+
+                ELSE IF ( cloud_physics )  THEN
+                   IF ( ql(k,j,i) == 0.0_wp )  THEN
+                      k1 = 1.0_wp + 0.61_wp * q(k,j,i)
+                      k2 = 0.61_wp * pt(k,j,i)
+                   ELSE
+                      theta = pt(k,j,i) + pt_d_t(k) * l_d_cp * ql(k,j,i)
+                      temp  = theta * t_d_pt(k)
+                      k1 = ( 1.0_wp - q(k,j,i) + 1.61_wp *                     &
+                                    ( q(k,j,i) - ql(k,j,i) ) *                 &
+                           ( 1.0_wp + 0.622_wp * l_d_r / temp ) ) /            &
+                           ( 1.0_wp + 0.622_wp * l_d_r * l_d_cp *              &
+                           ( q(k,j,i) - ql(k,j,i) ) / ( temp * temp ) )
+                      k2 = theta * ( l_d_cp / temp * k1 - 1.0_wp )
+                   ENDIF
+                   tend(k,j,i) = tend(k,j,i) - kh(k,j,i) * g / vpt(k,j,i) *    &
+                                         ( k1 * ( pt(k+1,j,i)-pt(k-1,j,i) ) +  &
+                                           k2 * ( q(k+1,j,i) - q(k-1,j,i) )    &
+                                         ) * dd2zu(k) *                        &
+                                      MERGE( 1.0_wp, 0.0_wp,                   &
+                                             BTEST( wall_flags_0(k,j,i), 30 )  &
+                                           )          *                        &
+                                      MERGE( 1.0_wp, 0.0_wp,                   &
+                                             BTEST( wall_flags_0(k,j,i), 9 )   &
+                                           )
+                ELSE IF ( cloud_droplets )  THEN
+                   k1 = 1.0_wp + 0.61_wp * q(k,j,i) - ql(k,j,i)
+                   k2 = 0.61_wp * pt(k,j,i)
+                   tend(k,j,i) = tend(k,j,i) - kh(k,j,i) * g / vpt(k,j,i) *    &
+                                     ( k1 * ( pt(k+1,j,i)-pt(k-1,j,i) ) +      &
+                                       k2 * ( q(k+1,j,i) - q(k-1,j,i) ) -      &
+                                       pt(k,j,i) * ( ql(k+1,j,i) -             &
+                                                     ql(k-1,j,i) ) ) * dd2zu(k)&
+                                    * MERGE( 1.0_wp, 0.0_wp,                   &
+                                             BTEST( wall_flags_0(k,j,i), 30 )  &
+                                           )                                   &
+                                    * MERGE( 1.0_wp, 0.0_wp,                   &
+                                             BTEST( wall_flags_0(k,j,i), 9 )   &
+                                           )    
+                ENDIF
+             ENDDO
+
+             IF ( use_surface_fluxes )  THEN
+!
+!--             Treat horizontal default surfaces, up- and downward-facing
+                DO  l = 0, 1
+                   surf_s = surf_def_h(l)%start_index(j,i)
+                   surf_e = surf_def_h(l)%end_index(j,i)
+                   DO  m = surf_s, surf_e
+                      k = surf_def_h(l)%k(m)
 
                       IF ( .NOT. cloud_physics .AND. .NOT. cloud_droplets ) THEN
@@ -710,12 +1442,12 @@
                             k2 = 0.61_wp * pt(k,j,i)
                          ELSE
-                            theta = pt(k,j,i) + pt_d_t(k) * l_d_cp * ql(k,j,i)
-                            temp  = theta * t_d_pt(k)
-                            k1 = ( 1.0_wp - q(k,j,i) + 1.61_wp *               &
-                                          ( q(k,j,i) - ql(k,j,i) ) *           &
-                                 ( 1.0_wp + 0.622_wp * l_d_r / temp ) ) /      &
-                                 ( 1.0_wp + 0.622_wp * l_d_r * l_d_cp *        &
-                                 ( q(k,j,i) - ql(k,j,i) ) / ( temp * temp ) )
-                            k2 = theta * ( l_d_cp / temp * k1 - 1.0_wp )
+                           theta = pt(k,j,i) + pt_d_t(k) * l_d_cp * ql(k,j,i)
+                           temp  = theta * t_d_pt(k)
+                           k1 = ( 1.0_wp - q(k,j,i) + 1.61_wp *                &
+                                      ( q(k,j,i) - ql(k,j,i) ) *               &
+                             ( 1.0_wp + 0.622_wp * l_d_r / temp ) ) /          &
+                             ( 1.0_wp + 0.622_wp * l_d_r * l_d_cp *            & 
+                             ( q(k,j,i) - ql(k,j,i) ) / ( temp * temp ) )
+                           k2 = theta * ( l_d_cp / temp * k1 - 1.0_wp )
                          ENDIF
                       ELSE IF ( cloud_droplets )  THEN
@@ -724,536 +1456,113 @@
                       ENDIF
 
-                      tend(k,j,i) = tend(k,j,i) + g / vpt(k,j,i) * &
-                                            ( k1* tswst(j,i) + k2 * qswst(j,i) )
+                      tend(k,j,i) = tend(k,j,i) + g / vpt(k,j,i) *             &
+                                         ( k1 * surf_def_h(l)%shf(m) +         &
+                                           k2 * surf_def_h(l)%qsws(m) )
                    ENDDO
-
-                ENDIF
+                ENDDO
+!
+!--             Treat horizontal natural surfaces
+                surf_s = surf_lsm_h%start_index(j,i)
+                surf_e = surf_lsm_h%end_index(j,i)
+                DO  m = surf_s, surf_e
+                   k = surf_lsm_h%k(m)
+
+                   IF ( .NOT. cloud_physics .AND. .NOT. cloud_droplets ) THEN
+                       k1 = 1.0_wp + 0.61_wp * q(k,j,i)
+                       k2 = 0.61_wp * pt(k,j,i)
+                   ELSE IF ( cloud_physics )  THEN
+                       IF ( ql(k,j,i) == 0.0_wp )  THEN
+                          k1 = 1.0_wp + 0.61_wp * q(k,j,i)
+                          k2 = 0.61_wp * pt(k,j,i)
+                       ELSE
+                          theta = pt(k,j,i) + pt_d_t(k) * l_d_cp * ql(k,j,i)
+                          temp  = theta * t_d_pt(k)
+                          k1 = ( 1.0_wp - q(k,j,i) + 1.61_wp *                 &
+                                        ( q(k,j,i) - ql(k,j,i) ) *             &
+                               ( 1.0_wp + 0.622_wp * l_d_r / temp ) ) /        &
+                               ( 1.0_wp + 0.622_wp * l_d_r * l_d_cp *          &
+                               ( q(k,j,i) - ql(k,j,i) ) / ( temp * temp ) )
+                          k2 = theta * ( l_d_cp / temp * k1 - 1.0_wp )
+                      ENDIF
+                   ELSE IF ( cloud_droplets )  THEN
+                      k1 = 1.0_wp + 0.61_wp * q(k,j,i) - ql(k,j,i)
+                      k2 = 0.61_wp * pt(k,j,i)
+                   ENDIF
+
+                   tend(k,j,i) = tend(k,j,i) + g / vpt(k,j,i) *                &
+                                            ( k1 * surf_lsm_h%shf(m) +         &
+                                              k2 * surf_lsm_h%qsws(m) )
+                ENDDO
+!
+!--             Treat horizontal urban surfaces
+                surf_s = surf_usm_h%start_index(j,i)
+                surf_e = surf_usm_h%end_index(j,i)
+                DO  m = surf_s, surf_e
+                   k = surf_usm_h%k(m)
+
+                   IF ( .NOT. cloud_physics .AND. .NOT. cloud_droplets ) THEN
+                       k1 = 1.0_wp + 0.61_wp * q(k,j,i)
+                       k2 = 0.61_wp * pt(k,j,i)
+                   ELSE IF ( cloud_physics )  THEN
+                       IF ( ql(k,j,i) == 0.0_wp )  THEN
+                          k1 = 1.0_wp + 0.61_wp * q(k,j,i)
+                          k2 = 0.61_wp * pt(k,j,i)
+                       ELSE
+                          theta = pt(k,j,i) + pt_d_t(k) * l_d_cp * ql(k,j,i)
+                          temp  = theta * t_d_pt(k)
+                          k1 = ( 1.0_wp - q(k,j,i) + 1.61_wp *                 &
+                                        ( q(k,j,i) - ql(k,j,i) ) *             &
+                               ( 1.0_wp + 0.622_wp * l_d_r / temp ) ) /        &
+                               ( 1.0_wp + 0.622_wp * l_d_r * l_d_cp *          &
+                               ( q(k,j,i) - ql(k,j,i) ) / ( temp * temp ) )
+                          k2 = theta * ( l_d_cp / temp * k1 - 1.0_wp )
+                      ENDIF
+                   ELSE IF ( cloud_droplets )  THEN
+                      k1 = 1.0_wp + 0.61_wp * q(k,j,i) - ql(k,j,i)
+                      k2 = 0.61_wp * pt(k,j,i)
+                   ENDIF
+
+                   tend(k,j,i) = tend(k,j,i) + g / vpt(k,j,i) *                &
+                                            ( k1 * surf_usm_h%shf(m) +         &
+                                              k2 * surf_usm_h%qsws(m) )
+                ENDDO
 
              ENDIF
 
-          ENDIF
-
-       ENDDO
-
-    END SUBROUTINE production_e
-
-
-!------------------------------------------------------------------------------!
-! Description:
-! ------------
-!> Call for grid point i,j
-!------------------------------------------------------------------------------!
-    SUBROUTINE production_e_ij( i, j )
-
-       USE arrays_3d,                                                          &
-           ONLY:  ddzw, dd2zu, kh, km, prho, pt, q, ql, qsws, qswst, shf,      &
-                  tend, tswst, u, v, vpt, w
-
-       USE cloud_parameters,                                                   &
-           ONLY:  l_d_cp, l_d_r, pt_d_t, t_d_pt
-
-       USE control_parameters,                                                 &
-           ONLY:  cloud_droplets, cloud_physics, constant_flux_layer, g,       &
-                  humidity, kappa, neutral, ocean, pt_reference,               &
-                  rho_reference, use_single_reference_value,                   &
-                  use_surface_fluxes, use_top_fluxes
-
-       USE grid_variables,                                                     &
-           ONLY:  ddx, dx, ddy, dy, wall_e_x, wall_e_y
-
-       USE indices,                                                            &
-           ONLY:  nxl, nxr, nys, nyn, nzb, nzb_diff_s_inner,                   &
-                  nzb_diff_s_outer, nzb_s_inner, nzt, nzt_diff
-
-       IMPLICIT NONE
-
-       INTEGER(iwp) ::  i           !<
-       INTEGER(iwp) ::  j           !<
-       INTEGER(iwp) ::  k           !<
-
-       REAL(wp)     ::  def         !<
-       REAL(wp)     ::  dudx        !<
-       REAL(wp)     ::  dudy        !<
-       REAL(wp)     ::  dudz        !<
-       REAL(wp)     ::  dvdx        !<
-       REAL(wp)     ::  dvdy        !<
-       REAL(wp)     ::  dvdz        !<
-       REAL(wp)     ::  dwdx        !<
-       REAL(wp)     ::  dwdy        !<
-       REAL(wp)     ::  dwdz        !<
-       REAL(wp)     ::  k1          !<
-       REAL(wp)     ::  k2          !<
-       REAL(wp)     ::  km_neutral  !<
-       REAL(wp)     ::  theta       !<
-       REAL(wp)     ::  temp        !<
-
-       REAL(wp), DIMENSION(nzb:nzt+1) ::  usvs  !<
-       REAL(wp), DIMENSION(nzb:nzt+1) ::  vsus  !<
-       REAL(wp), DIMENSION(nzb:nzt+1) ::  wsus  !<
-       REAL(wp), DIMENSION(nzb:nzt+1) ::  wsvs  !<
-
-!
-!--    Calculate TKE production by shear
-       DO  k = nzb_diff_s_outer(j,i), nzt
-
-          dudx  =           ( u(k,j,i+1) - u(k,j,i)     ) * ddx
-          dudy  = 0.25_wp * ( u(k,j+1,i) + u(k,j+1,i+1) - &
-                              u(k,j-1,i) - u(k,j-1,i+1) ) * ddy
-          dudz  = 0.5_wp  * ( u(k+1,j,i) + u(k+1,j,i+1) - &
-                              u(k-1,j,i) - u(k-1,j,i+1) ) * dd2zu(k)
-
-          dvdx  = 0.25_wp * ( v(k,j,i+1) + v(k,j+1,i+1) - &
-                              v(k,j,i-1) - v(k,j+1,i-1) ) * ddx
-          dvdy  =           ( v(k,j+1,i) - v(k,j,i)     ) * ddy
-          dvdz  = 0.5_wp  * ( v(k+1,j,i) + v(k+1,j+1,i) - &
-                              v(k-1,j,i) - v(k-1,j+1,i) ) * dd2zu(k)
-
-          dwdx  = 0.25_wp * ( w(k,j,i+1) + w(k-1,j,i+1) - &
-                              w(k,j,i-1) - w(k-1,j,i-1) ) * ddx
-          dwdy  = 0.25_wp * ( w(k,j+1,i) + w(k-1,j+1,i) - &
-                              w(k,j-1,i) - w(k-1,j-1,i) ) * ddy
-          dwdz  =           ( w(k,j,i)   - w(k-1,j,i)   ) * ddzw(k)
-
-          def = 2.0_wp * ( dudx**2 + dvdy**2 + dwdz**2 )                       &
-                + dudy**2 + dvdx**2 + dwdx**2 + dwdy**2 + dudz**2 + dvdz**2    &
-                + 2.0_wp * ( dvdx*dudy + dwdx*dudz + dwdy*dvdz )
-
-          IF ( def < 0.0_wp )  def = 0.0_wp
-
-          tend(k,j,i) = tend(k,j,i) + km(k,j,i) * def
-
-       ENDDO
-
-       IF ( constant_flux_layer )  THEN
-
-          IF ( ( wall_e_x(j,i) /= 0.0_wp ) .OR. ( wall_e_y(j,i) /= 0.0_wp ) )  THEN
-
-!
-!--          Position beneath wall
-!--          (2) - Will allways be executed.
-!--          'bottom and wall: use u_0,v_0 and wall functions'
-             k = nzb_diff_s_inner(j,i)-1
-
-             dudx = ( u(k,j,i+1) - u(k,j,i) ) * ddx
-             dudz = 0.5_wp * ( u(k+1,j,i) + u(k+1,j,i+1) - &
-                               u_0(j,i)   - u_0(j,i+1)   ) * dd2zu(k)
-             dvdy =          ( v(k,j+1,i) - v(k,j,i)     ) * ddy
-             dvdz = 0.5_wp * ( v(k+1,j,i) + v(k+1,j+1,i) - &
-                               v_0(j,i)   - v_0(j+1,i)   ) * dd2zu(k)
-             dwdz = ( w(k,j,i) - w(k-1,j,i) ) * ddzw(k)
-
-             IF ( wall_e_y(j,i) /= 0.0_wp )  THEN
-!
-!--             Inconsistency removed: as the thermal stratification 
-!--             is not taken into account for the evaluation of the 
-!--             wall fluxes at vertical walls, the eddy viscosity km 
-!--             must not be used for the evaluation of the velocity 
-!--             gradients dudy and dwdy
-!--             Note: The validity of the new method has not yet 
-!--                   been shown, as so far no suitable data for a 
-!--                   validation has been available
-                CALL wall_fluxes_e( i, j, k, nzb_diff_s_outer(j,i)-2, &
-                                    usvs, 1.0_wp, 0.0_wp, 0.0_wp, 0.0_wp )
-                CALL wall_fluxes_e( i, j, k, nzb_diff_s_outer(j,i)-2, &
-                                    wsvs, 0.0_wp, 0.0_wp, 1.0_wp, 0.0_wp )
-                km_neutral = kappa * ( usvs(k)**2 + wsvs(k)**2 )**0.25_wp * &
-                             0.5_wp * dy
-                IF ( km_neutral > 0.0_wp )  THEN
-                   dudy = - wall_e_y(j,i) * usvs(k) / km_neutral
-                   dwdy = - wall_e_y(j,i) * wsvs(k) / km_neutral
-                ELSE
-                   dudy = 0.0_wp
-                   dwdy = 0.0_wp
-                ENDIF
-             ELSE
-                dudy = 0.25_wp * ( u(k,j+1,i) + u(k,j+1,i+1) - &
-                                   u(k,j-1,i) - u(k,j-1,i+1) ) * ddy
-                dwdy = 0.25_wp * ( w(k,j+1,i) + w(k-1,j+1,i) - &
-                                   w(k,j-1,i) - w(k-1,j-1,i) ) * ddy
-             ENDIF
-
-             IF ( wall_e_x(j,i) /= 0.0_wp )  THEN
-!
-!--             Inconsistency removed: as the thermal stratification 
-!--             is not taken into account for the evaluation of the 
-!--             wall fluxes at vertical walls, the eddy viscosity km 
-!--             must not be used for the evaluation of the velocity 
-!--             gradients dvdx and dwdx
-!--             Note: The validity of the new method has not yet 
-!--                   been shown, as so far no suitable data for a 
-!--                   validation has been available
-                CALL wall_fluxes_e( i, j, k, nzb_diff_s_outer(j,i)-2, &
-                                    vsus, 0.0_wp, 1.0_wp, 0.0_wp, 0.0_wp )
-                CALL wall_fluxes_e( i, j, k, nzb_diff_s_outer(j,i)-2, &
-                                    wsus, 0.0_wp, 0.0_wp, 0.0_wp, 1.0_wp )
-                km_neutral = kappa * ( vsus(k)**2 + wsus(k)**2 )**0.25_wp * & 
-                             0.5_wp * dx
-                IF ( km_neutral > 0.0_wp )  THEN
-                   dvdx = - wall_e_x(j,i) * vsus(k) / km_neutral
-                   dwdx = - wall_e_x(j,i) * wsus(k) / km_neutral
-                ELSE
-                   dvdx = 0.0_wp
-                   dwdx = 0.0_wp
-                ENDIF
-             ELSE
-                dvdx = 0.25_wp * ( v(k,j,i+1) + v(k,j+1,i+1) - &
-                                   v(k,j,i-1) - v(k,j+1,i-1) ) * ddx
-                dwdx = 0.25_wp * ( w(k,j,i+1) + w(k-1,j,i+1) - &
-                                   w(k,j,i-1) - w(k-1,j,i-1) ) * ddx
-             ENDIF
-
-             def = 2.0_wp * ( dudx**2 + dvdy**2 + dwdz**2 ) +           &
-                   dudy**2 + dvdx**2 + dwdx**2 + dwdy**2 + dudz**2 + &
-                   dvdz**2 + 2.0_wp * ( dvdx*dudy + dwdx*dudz + dwdy*dvdz )
-
-             IF ( def < 0.0_wp )  def = 0.0_wp
-
-             tend(k,j,i) = tend(k,j,i) + km(k,j,i) * def
-
-!
-!--          (3) - will be executed only, if there is at least one level
-!--          between (2) and (4), i.e. the topography must have a
-!--          minimum height of 2 dz. Wall fluxes for this case have
-!--          already been calculated for (2).
-!--          'wall only: use wall functions'
-             DO  k = nzb_diff_s_inner(j,i), nzb_diff_s_outer(j,i)-2
-
-                dudx = ( u(k,j,i+1) - u(k,j,i) ) * ddx
-                dudz = 0.5_wp * ( u(k+1,j,i) + u(k+1,j,i+1) - &
-                                  u(k-1,j,i) - u(k-1,j,i+1) ) * dd2zu(k)
-                dvdy =          ( v(k,j+1,i) - v(k,j,i)     ) * ddy
-                dvdz = 0.5_wp * ( v(k+1,j,i) + v(k+1,j+1,i) - &
-                                  v(k-1,j,i) - v(k-1,j+1,i) ) * dd2zu(k)
-                dwdz = ( w(k,j,i) - w(k-1,j,i) ) * ddzw(k)
-
-                IF ( wall_e_y(j,i) /= 0.0_wp )  THEN
-!
-!--                Inconsistency removed: as the thermal stratification 
-!--                is not taken into account for the evaluation of the 
-!--                wall fluxes at vertical walls, the eddy viscosity km 
-!--                must not be used for the evaluation of the velocity 
-!--                gradients dudy and dwdy
-!--                Note: The validity of the new method has not yet 
-!--                      been shown, as so far no suitable data for a 
-!--                      validation has been available
-                   km_neutral = kappa * ( usvs(k)**2 + & 
-                                          wsvs(k)**2 )**0.25_wp * 0.5_wp * dy
-                   IF ( km_neutral > 0.0_wp )  THEN
-                      dudy = - wall_e_y(j,i) * usvs(k) / km_neutral
-                      dwdy = - wall_e_y(j,i) * wsvs(k) / km_neutral
-                   ELSE
-                      dudy = 0.0_wp
-                      dwdy = 0.0_wp
-                   ENDIF
-                ELSE
-                   dudy = 0.25_wp * ( u(k,j+1,i) + u(k,j+1,i+1) - &
-                                      u(k,j-1,i) - u(k,j-1,i+1) ) * ddy
-                   dwdy = 0.25_wp * ( w(k,j+1,i) + w(k-1,j+1,i) - &
-                                      w(k,j-1,i) - w(k-1,j-1,i) ) * ddy
-                ENDIF
-
-                IF ( wall_e_x(j,i) /= 0.0_wp )  THEN
-!
-!--                Inconsistency removed: as the thermal stratification 
-!--                is not taken into account for the evaluation of the 
-!--                wall fluxes at vertical walls, the eddy viscosity km 
-!--                must not be used for the evaluation of the velocity 
-!--                gradients dvdx and dwdx
-!--                Note: The validity of the new method has not yet 
-!--                      been shown, as so far no suitable data for a 
-!--                      validation has been available
-                   km_neutral = kappa * ( vsus(k)**2 + & 
-                                          wsus(k)**2 )**0.25_wp * 0.5_wp * dx
-                   IF ( km_neutral > 0.0_wp )  THEN
-                      dvdx = - wall_e_x(j,i) * vsus(k) / km_neutral
-                      dwdx = - wall_e_x(j,i) * wsus(k) / km_neutral
-                   ELSE
-                      dvdx = 0.0_wp
-                      dwdx = 0.0_wp
-                   ENDIF
-                ELSE
-                   dvdx = 0.25_wp * ( v(k,j,i+1) + v(k,j+1,i+1) - &
-                                      v(k,j,i-1) - v(k,j+1,i-1) ) * ddx
-                   dwdx = 0.25_wp * ( w(k,j,i+1) + w(k-1,j,i+1) - &
-                                      w(k,j,i-1) - w(k-1,j,i-1) ) * ddx
-                ENDIF
-
-                def = 2.0_wp * ( dudx**2 + dvdy**2 + dwdz**2 ) +           &
-                      dudy**2 + dvdx**2 + dwdx**2 + dwdy**2 + dudz**2 + &
-                      dvdz**2 + 2.0_wp * ( dvdx*dudy + dwdx*dudz + dwdy*dvdz )
-
-                IF ( def < 0.0_wp )  def = 0.0_wp
-
-                tend(k,j,i) = tend(k,j,i) + km(k,j,i) * def
-
-             ENDDO
-
-!
-!--          (4) - will allways be executed.
-!--          'special case: free atmosphere' (as for case (0))
-             k = nzb_diff_s_outer(j,i)-1
-
-             dudx  =           ( u(k,j,i+1) - u(k,j,i)     ) * ddx
-             dudy  = 0.25_wp * ( u(k,j+1,i) + u(k,j+1,i+1) - &
-                                 u(k,j-1,i) - u(k,j-1,i+1) ) * ddy
-             dudz  = 0.5_wp  * ( u(k+1,j,i) + u(k+1,j,i+1) - &
-                                 u(k-1,j,i) - u(k-1,j,i+1) ) * dd2zu(k)
-
-             dvdx  = 0.25_wp * ( v(k,j,i+1) + v(k,j+1,i+1) - &
-                                 v(k,j,i-1) - v(k,j+1,i-1) ) * ddx
-             dvdy  =           ( v(k,j+1,i) - v(k,j,i)     ) * ddy
-             dvdz  = 0.5_wp  * ( v(k+1,j,i) + v(k+1,j+1,i) - &
-                                 v(k-1,j,i) - v(k-1,j+1,i) ) * dd2zu(k)
-
-             dwdx  = 0.25_wp * ( w(k,j,i+1) + w(k-1,j,i+1) - &
-                                 w(k,j,i-1) - w(k-1,j,i-1) ) * ddx
-             dwdy  = 0.25_wp * ( w(k,j+1,i) + w(k-1,j+1,i) - &
-                                 w(k,j-1,i) - w(k-1,j-1,i) ) * ddy
-             dwdz  =           ( w(k,j,i)   - w(k-1,j,i)   ) * ddzw(k)
-
-             def = 2.0_wp * ( dudx**2 + dvdy**2 + dwdz**2 ) +        &
-                   dudy**2 + dvdx**2 + dwdx**2 + dwdy**2 + dudz**2 + &
-                   dvdz**2 + 2.0_wp * ( dvdx*dudy + dwdx*dudz + dwdy*dvdz )
-
-             IF ( def < 0.0_wp )  def = 0.0_wp
-
-             tend(k,j,i) = tend(k,j,i) + km(k,j,i) * def
-
-          ELSE
-
-!
-!--          Position without adjacent wall
-!--          (1) - will allways be executed. 
-!--          'bottom only: use u_0,v_0'
-             k = nzb_diff_s_inner(j,i)-1
-
-             dudx  =           ( u(k,j,i+1) - u(k,j,i)     ) * ddx
-             dudy  = 0.25_wp * ( u(k,j+1,i) + u(k,j+1,i+1) - &
-                                 u(k,j-1,i) - u(k,j-1,i+1) ) * ddy
-             dudz  = 0.5_wp  * ( u(k+1,j,i) + u(k+1,j,i+1) - &
-                                 u_0(j,i)   - u_0(j,i+1)   ) * dd2zu(k)
-
-             dvdx  = 0.25_wp * ( v(k,j,i+1) + v(k,j+1,i+1) - &
-                                 v(k,j,i-1) - v(k,j+1,i-1) ) * ddx
-             dvdy  =           ( v(k,j+1,i) - v(k,j,i)     ) * ddy
-             dvdz  = 0.5_wp  * ( v(k+1,j,i) + v(k+1,j+1,i) - &
-                                 v_0(j,i)   - v_0(j+1,i)   ) * dd2zu(k)
-
-             dwdx  = 0.25_wp * ( w(k,j,i+1) + w(k-1,j,i+1) - &
-                                 w(k,j,i-1) - w(k-1,j,i-1) ) * ddx
-             dwdy  = 0.25_wp * ( w(k,j+1,i) + w(k-1,j+1,i) - &
-                                 w(k,j-1,i) - w(k-1,j-1,i) ) * ddy
-             dwdz  =           ( w(k,j,i)   - w(k-1,j,i)   ) * ddzw(k)
-
-             def = 2.0_wp * ( dudx**2 + dvdy**2 + dwdz**2 )                       &
-                   + dudy**2 + dvdx**2 + dwdx**2 + dwdy**2 + dudz**2 + dvdz**2 &
-                   + 2.0_wp * ( dvdx*dudy + dwdx*dudz + dwdy*dvdz )
-
-             IF ( def < 0.0_wp )  def = 0.0_wp
-
-             tend(k,j,i) = tend(k,j,i) + km(k,j,i) * def
-
-          ENDIF
-
-       ELSEIF ( use_surface_fluxes )  THEN
-
-          k = nzb_diff_s_outer(j,i)-1
-
-          dudx  =           ( u(k,j,i+1) - u(k,j,i)     ) * ddx
-          dudy  = 0.25_wp * ( u(k,j+1,i) + u(k,j+1,i+1) - &
-                              u(k,j-1,i) - u(k,j-1,i+1) ) * ddy
-          dudz  = 0.5_wp  * ( u(k+1,j,i) + u(k+1,j,i+1) - &
-                              u(k-1,j,i) - u(k-1,j,i+1) ) * dd2zu(k)
-
-          dvdx  = 0.25_wp * ( v(k,j,i+1) + v(k,j+1,i+1) - &
-                              v(k,j,i-1) - v(k,j+1,i-1) ) * ddx
-          dvdy  =           ( v(k,j+1,i) - v(k,j,i)     ) * ddy
-          dvdz  = 0.5_wp  * ( v(k+1,j,i) + v(k+1,j+1,i) - &
-                              v(k-1,j,i) - v(k-1,j+1,i) ) * dd2zu(k)
-
-          dwdx  = 0.25_wp * ( w(k,j,i+1) + w(k-1,j,i+1) - &
-                              w(k,j,i-1) - w(k-1,j,i-1) ) * ddx
-          dwdy  = 0.25_wp * ( w(k,j+1,i) + w(k-1,j+1,i) - &
-                              w(k,j-1,i) - w(k-1,j-1,i) ) * ddy
-          dwdz  =           ( w(k,j,i)   - w(k-1,j,i)   ) * ddzw(k)
-
-          def = 2.0_wp * ( dudx**2 + dvdy**2 + dwdz**2 ) +           &
-                dudy**2 + dvdx**2 + dwdx**2 + dwdy**2 + dudz**2 + &
-                dvdz**2 + 2.0_wp * ( dvdx*dudy + dwdx*dudz + dwdy*dvdz )
-
-          IF ( def < 0.0_wp )  def = 0.0_wp
-
-          tend(k,j,i) = tend(k,j,i) + km(k,j,i) * def
-
-       ENDIF
-
-!
-!--    If required, calculate TKE production by buoyancy
-       IF ( .NOT. neutral )  THEN
-
-          IF ( .NOT. humidity )  THEN
-
-             IF ( use_single_reference_value )  THEN
-
-                IF ( ocean )  THEN
-!
-!--                So far in the ocean no special treatment of density flux in
-!--                the bottom and top surface layer
-                   DO  k = nzb_s_inner(j,i)+1, nzt
-                      tend(k,j,i) = tend(k,j,i) +                   &
-                                    kh(k,j,i) * g / rho_reference * &
-                                    ( prho(k+1,j,i) - prho(k-1,j,i) ) * dd2zu(k)
-                   ENDDO
-
-                ELSE
-
-                   DO  k = nzb_diff_s_inner(j,i), nzt_diff
-                      tend(k,j,i) = tend(k,j,i) -                  &
-                                    kh(k,j,i) * g / pt_reference * &
-                                    ( pt(k+1,j,i) - pt(k-1,j,i) ) * dd2zu(k)
-                   ENDDO
-
-                   IF ( use_surface_fluxes )  THEN
-                      k = nzb_diff_s_inner(j,i)-1
-                      tend(k,j,i) = tend(k,j,i) + g / pt_reference * shf(j,i)
-                   ENDIF
-
-                   IF ( use_top_fluxes )  THEN
-                      k = nzt
-                      tend(k,j,i) = tend(k,j,i) + g / pt_reference * tswst(j,i)
-                   ENDIF
-
-                ENDIF
-
-             ELSE
-
-                IF ( ocean )  THEN
-!
-!--                So far in the ocean no special treatment of density flux in
-!--                the bottom and top surface layer
-                   DO  k = nzb_s_inner(j,i)+1, nzt
-                      tend(k,j,i) = tend(k,j,i) +                              &
-                                    kh(k,j,i) * g / prho(k,j,i) *              &
-                                    ( prho(k+1,j,i) - prho(k-1,j,i) ) * dd2zu(k)
-                   ENDDO
-
-                ELSE
-
-                   DO  k = nzb_diff_s_inner(j,i), nzt_diff
-                      tend(k,j,i) = tend(k,j,i) -               &
-                                    kh(k,j,i) * g / pt(k,j,i) * &
-                                    ( pt(k+1,j,i) - pt(k-1,j,i) ) * dd2zu(k)
-                   ENDDO
-
-                   IF ( use_surface_fluxes )  THEN
-                      k = nzb_diff_s_inner(j,i)-1
-                      tend(k,j,i) = tend(k,j,i) + g / pt(k,j,i) * shf(j,i)
-                   ENDIF
-
-                   IF ( use_top_fluxes )  THEN
-                      k = nzt
-                      tend(k,j,i) = tend(k,j,i) + g / pt(k,j,i) * tswst(j,i)
-                   ENDIF
-
-                ENDIF
-
-             ENDIF
-
-          ELSE
-
-             DO  k = nzb_diff_s_inner(j,i), nzt_diff
-
-                IF ( .NOT. cloud_physics .AND. .NOT. cloud_droplets )  THEN
-                   k1 = 1.0_wp + 0.61_wp * q(k,j,i)
-                   k2 = 0.61_wp * pt(k,j,i)
-                   tend(k,j,i) = tend(k,j,i) - kh(k,j,i) * g / vpt(k,j,i) *   &
-                                         ( k1 * ( pt(k+1,j,i)-pt(k-1,j,i) ) + &
-                                           k2 * ( q(k+1,j,i) - q(k-1,j,i) )   &
-                                         ) * dd2zu(k)
-                ELSE IF ( cloud_physics )  THEN
-                   IF ( ql(k,j,i) == 0.0_wp )  THEN
+             IF ( use_top_fluxes )  THEN
+                surf_s = surf_def_h(2)%start_index(j,i)
+                surf_e = surf_def_h(2)%end_index(j,i)
+                DO  m = surf_s, surf_e
+                   k = surf_def_h(2)%k(m)
+
+
+
+                   IF ( .NOT. cloud_physics .AND. .NOT. cloud_droplets )  THEN
                       k1 = 1.0_wp + 0.61_wp * q(k,j,i)
                       k2 = 0.61_wp * pt(k,j,i)
-                   ELSE
-                      theta = pt(k,j,i) + pt_d_t(k) * l_d_cp * ql(k,j,i)
-                      temp  = theta * t_d_pt(k)
-                      k1 = ( 1.0_wp - q(k,j,i) + 1.61_wp *                 &
-                                    ( q(k,j,i) - ql(k,j,i) ) *          &
-                           ( 1.0_wp + 0.622_wp * l_d_r / temp ) ) /        &
-                           ( 1.0_wp + 0.622_wp * l_d_r * l_d_cp *          &
+                   ELSE IF ( cloud_physics )  THEN
+                      IF ( ql(k,j,i) == 0.0_wp )  THEN
+                         k1 = 1.0_wp + 0.61_wp * q(k,j,i)
+                         k2 = 0.61_wp * pt(k,j,i)
+                      ELSE
+                         theta = pt(k,j,i) + pt_d_t(k) * l_d_cp * ql(k,j,i)
+                         temp  = theta * t_d_pt(k)
+                         k1 = ( 1.0_wp - q(k,j,i) + 1.61_wp *                  &
+                                    ( q(k,j,i) - ql(k,j,i) ) *                 &
+                           ( 1.0_wp + 0.622_wp * l_d_r / temp ) ) /            &
+                           ( 1.0_wp + 0.622_wp * l_d_r * l_d_cp *              &
                            ( q(k,j,i) - ql(k,j,i) ) / ( temp * temp ) )
-                      k2 = theta * ( l_d_cp / temp * k1 - 1.0_wp )
+                         k2 = theta * ( l_d_cp / temp * k1 - 1.0_wp )
+                      ENDIF
+                   ELSE IF ( cloud_droplets )  THEN
+                      k1 = 1.0_wp + 0.61_wp * q(k,j,i) - ql(k,j,i)
+                      k2 = 0.61_wp * pt(k,j,i)
                    ENDIF
-                   tend(k,j,i) = tend(k,j,i) - kh(k,j,i) * g / vpt(k,j,i) *   &
-                                         ( k1 * ( pt(k+1,j,i)-pt(k-1,j,i) ) + &
-                                           k2 * ( q(k+1,j,i) - q(k-1,j,i) )   &
-                                         ) * dd2zu(k)
-                ELSE IF ( cloud_droplets )  THEN
-                   k1 = 1.0_wp + 0.61_wp * q(k,j,i) - ql(k,j,i)
-                   k2 = 0.61_wp * pt(k,j,i)
-                   tend(k,j,i) = tend(k,j,i) - kh(k,j,i) * g / vpt(k,j,i) *  &
-                                     ( k1 * ( pt(k+1,j,i)-pt(k-1,j,i) ) +    &
-                                       k2 * ( q(k+1,j,i) - q(k-1,j,i) ) -    &
-                                       pt(k,j,i) * ( ql(k+1,j,i) -           &
-                                                     ql(k-1,j,i) ) ) * dd2zu(k)
-                ENDIF
-             ENDDO
-
-             IF ( use_surface_fluxes )  THEN
-                k = nzb_diff_s_inner(j,i)-1
-
-                IF ( .NOT. cloud_physics .AND. .NOT. cloud_droplets )  THEN
-                   k1 = 1.0_wp + 0.61_wp * q(k,j,i)
-                   k2 = 0.61_wp * pt(k,j,i)
-                ELSE IF ( cloud_physics )  THEN
-                   IF ( ql(k,j,i) == 0.0_wp )  THEN
-                      k1 = 1.0_wp + 0.61_wp * q(k,j,i)
-                      k2 = 0.61_wp * pt(k,j,i)
-                   ELSE
-                      theta = pt(k,j,i) + pt_d_t(k) * l_d_cp * ql(k,j,i)
-                      temp  = theta * t_d_pt(k)
-                      k1 = ( 1.0_wp - q(k,j,i) + 1.61_wp *                 &
-                                    ( q(k,j,i) - ql(k,j,i) ) *          &
-                           ( 1.0_wp + 0.622_wp * l_d_r / temp ) ) /        &
-                           ( 1.0_wp + 0.622_wp * l_d_r * l_d_cp *          &
-                           ( q(k,j,i) - ql(k,j,i) ) / ( temp * temp ) )
-                      k2 = theta * ( l_d_cp / temp * k1 - 1.0_wp )
-                   ENDIF
-                ELSE IF ( cloud_droplets )  THEN
-                   k1 = 1.0_wp + 0.61_wp * q(k,j,i) - ql(k,j,i)
-                   k2 = 0.61_wp * pt(k,j,i)
-                ENDIF
-
-                tend(k,j,i) = tend(k,j,i) + g / vpt(k,j,i) * &
-                                            ( k1* shf(j,i) + k2 * qsws(j,i) )
-             ENDIF
-
-             IF ( use_top_fluxes )  THEN
-                k = nzt
-
-                IF ( .NOT. cloud_physics .AND. .NOT. cloud_droplets )  THEN
-                   k1 = 1.0_wp + 0.61_wp * q(k,j,i)
-                   k2 = 0.61_wp * pt(k,j,i)
-                ELSE IF ( cloud_physics )  THEN
-                   IF ( ql(k,j,i) == 0.0_wp )  THEN
-                      k1 = 1.0_wp + 0.61_wp * q(k,j,i)
-                      k2 = 0.61_wp * pt(k,j,i)
-                   ELSE
-                      theta = pt(k,j,i) + pt_d_t(k) * l_d_cp * ql(k,j,i)
-                      temp  = theta * t_d_pt(k)
-                      k1 = ( 1.0_wp - q(k,j,i) + 1.61_wp *                 &
-                                    ( q(k,j,i) - ql(k,j,i) ) *          &
-                           ( 1.0_wp + 0.622_wp * l_d_r / temp ) ) /        &
-                           ( 1.0_wp + 0.622_wp * l_d_r * l_d_cp *          &
-                           ( q(k,j,i) - ql(k,j,i) ) / ( temp * temp ) )
-                      k2 = theta * ( l_d_cp / temp * k1 - 1.0_wp )
-                   ENDIF
-                ELSE IF ( cloud_droplets )  THEN
-                   k1 = 1.0_wp + 0.61_wp * q(k,j,i) - ql(k,j,i)
-                   k2 = 0.61_wp * pt(k,j,i)
-                ENDIF
-
-                tend(k,j,i) = tend(k,j,i) + g / vpt(k,j,i) * &
-                                            ( k1* tswst(j,i) + k2 * qswst(j,i) )
+
+                   tend(k,j,i) = tend(k,j,i) + g / vpt(k,j,i) *                &
+                               ( k1* surf_def_h(2)%shf(m) +                    &
+                                 k2 * surf_def_h(2)%qsws(m) )
+                ENDDO
+
              ENDIF
 
@@ -1273,5 +1582,5 @@
 
        USE arrays_3d,                                                          &
-           ONLY:  kh, km, u, us, usws, v, vsws, zu
+           ONLY:  kh, km, u, v, zu
 
        USE control_parameters,                                                 &
@@ -1282,20 +1591,16 @@
                   nzb_v_inner
 
+       USE surface_mod,                                                        &
+           ONLY :  surf_def_h, surf_def_v, surf_lsm_h, surf_usm_h 
+
        IMPLICIT NONE
 
-       INTEGER(iwp) ::  i   !<
-       INTEGER(iwp) ::  j   !<
-       INTEGER(iwp) ::  ku  !<
-       INTEGER(iwp) ::  kv  !<
+       INTEGER(iwp) ::  i   !< grid index x-direction
+       INTEGER(iwp) ::  j   !< grid index y-direction
+       INTEGER(iwp) ::  k   !< grid index z-direction
+       INTEGER(iwp) ::  l   !< running index surface type (up- or downward-facing)
+       INTEGER(iwp) ::  m   !< running index surface elements
 
        IF ( constant_flux_layer )  THEN
-
-          IF ( first_call )  THEN
-             ALLOCATE( u_0(nysg:nyng,nxlg:nxrg), v_0(nysg:nyng,nxlg:nxrg) )
-             u_0 = 0.0_wp   ! just to avoid access of uninitialized memory
-             v_0 = 0.0_wp   ! within exchange_horiz_2d
-             first_call = .FALSE.
-          ENDIF
-
 !
 !--       Calculate a virtual velocity at the surface in a way that the
@@ -1306,34 +1611,124 @@
 !--       (otherwise the timestep may be significantly reduced by large
 !--       surface winds).
-!--       Upper bounds are nxr+1 and nyn+1 because otherwise these values are
 !--       not available in case of non-cyclic boundary conditions.
 !--       WARNING: the exact analytical solution would require the determination
 !--                of the eddy diffusivity by km = u* * kappa * zp / phi_m.
-          !$OMP PARALLEL DO PRIVATE( ku, kv )
-          DO  i = nxl, nxr+1
-             DO  j = nys, nyn+1
-
-                ku = nzb_u_inner(j,i)+1
-                kv = nzb_v_inner(j,i)+1
-
-                u_0(j,i) = u(ku+1,j,i) + usws(j,i) * ( zu(ku+1) - zu(ku-1) ) / &
-                                 ( 0.5_wp * ( km(ku,j,i) + km(ku,j,i-1) ) +    &
-                                   1.0E-20_wp )
-!                                  ( us(j,i) * kappa * zu(1) )
-                v_0(j,i) = v(kv+1,j,i) + vsws(j,i) * ( zu(kv+1) - zu(kv-1) ) / &
-                                 ( 0.5_wp * ( km(kv,j,i) + km(kv,j-1,i) ) +    &
-                                   1.0E-20_wp )
-!                                  ( us(j,i) * kappa * zu(1) )
-
-                IF ( ABS( u(ku+1,j,i) - u_0(j,i) )  > &
-                     ABS( u(ku+1,j,i) - u(ku-1,j,i) ) )  u_0(j,i) = u(ku-1,j,i)
-                IF ( ABS( v(kv+1,j,i) - v_0(j,i) )  > &
-                     ABS( v(kv+1,j,i) - v(kv-1,j,i) ) )  v_0(j,i) = v(kv-1,j,i)
-
-             ENDDO
+!--       Default surfaces, upward-facing
+          !$OMP PARALLEL DO PRIVATE(i,j,k,m)
+          DO  m = 1, surf_def_h(0)%ns
+
+             i = surf_def_h(0)%i(m)            
+             j = surf_def_h(0)%j(m)
+             k = surf_def_h(0)%k(m)
+!
+!--          Note, calculatione of u_0 and v_0 is not fully accurate, as u/v 
+!--          and km are not on the same grid. Actually, a further 
+!--          interpolation of km onto the u/v-grid is necessary. However, the
+!--          effect of this error is negligible. 
+             surf_def_h(0)%u_0(m) = u(k+1,j,i) + surf_def_h(0)%usws(m) *       &
+                                        ( zu(k+1)    - zu(k-1)    )  /         &
+                                        ( km(k,j,i)  + 1.0E-20_wp )  
+             surf_def_h(0)%v_0(m) = v(k+1,j,i) + surf_def_h(0)%vsws(m) *       &
+                                        ( zu(k+1)    - zu(k-1)    )  /         &
+                                        ( km(k,j,i)  + 1.0E-20_wp )  
+
+             IF ( ABS( u(k+1,j,i) - surf_def_h(0)%u_0(m) )  >                  &
+                  ABS( u(k+1,j,i) - u(k-1,j,i)           )                     &
+                )  surf_def_h(0)%u_0(m) = u(k-1,j,i)
+
+             IF ( ABS( v(k+1,j,i) - surf_def_h(0)%v_0(m) )  >                  &
+                  ABS( v(k+1,j,i) - v(k-1,j,i)           )                     &
+                )  surf_def_h(0)%v_0(m) = v(k-1,j,i)
+
           ENDDO
-
-          CALL exchange_horiz_2d( u_0 )
-          CALL exchange_horiz_2d( v_0 )
+!
+!--       Default surfaces, downward-facing
+          !$OMP PARALLEL DO PRIVATE(i,j,k,m)
+          DO  m = 1, surf_def_h(1)%ns
+
+             i = surf_def_h(1)%i(m)            
+             j = surf_def_h(1)%j(m)
+             k = surf_def_h(1)%k(m)
+!
+!--          Note, calculatione of u_0 and v_0 is not fully accurate, as u/v 
+!--          and km are not on the same grid. Actually, a further 
+!--          interpolation of km onto the u/v-grid is necessary. However, the
+!--          effect of this error is negligible. 
+!--          In case of downward-facing surfaces, gradient is calculated 
+!--          between u_0 and u(k-1).
+             surf_def_h(1)%u_0(m) = u(k-1,j,i) - surf_def_h(1)%usws(m) *       &
+                                        ( zu(k+1)    - zu(k-1)    )  /         &
+                                        ( km(k,j,i)  + 1.0E-20_wp )  
+             surf_def_h(1)%v_0(m) = v(k-1,j,i) - surf_def_h(1)%vsws(m) *       &
+                                        ( zu(k+1)    - zu(k-1)    )  /         &
+                                        ( km(k,j,i)  + 1.0E-20_wp )  
+
+             IF ( ABS( surf_def_h(1)%u_0(m) - u(k-1,j,i) )  >                  &
+                  ABS( u(k+1,j,i)           - u(k-1,j,i) )                     &
+                )  surf_def_h(1)%u_0(m) = u(k+1,j,i)
+
+             IF ( ABS( surf_def_h(1)%v_0(m) - v(k-1,j,i) )  >                  &
+                  ABS( v(k+1,j,i)           - v(k-1,j,i) )                     &
+                )  surf_def_h(1)%v_0(m) = v(k+1,j,i)
+
+          ENDDO
+!
+!--       Natural surfaces, upward-facing
+          !$OMP PARALLEL DO PRIVATE(i,j,k,m)
+          DO  m = 1, surf_lsm_h%ns
+
+             i = surf_lsm_h%i(m)            
+             j = surf_lsm_h%j(m)
+             k = surf_lsm_h%k(m)
+!
+!--          Note, calculatione of u_0 and v_0 is not fully accurate, as u/v 
+!--          and km are not on the same grid. Actually, a further 
+!--          interpolation of km onto the u/v-grid is necessary. However, the
+!--          effect of this error is negligible. 
+             surf_lsm_h%u_0(m) = u(k+1,j,i) + surf_lsm_h%usws(m)      *        &
+                                           ( zu(k+1)   - zu(k-1)    )  /       &
+                                           ( km(k,j,i) + 1.0E-20_wp )  
+             surf_lsm_h%v_0(m) = v(k+1,j,i) + surf_lsm_h%vsws(m)      *        &
+                                           ( zu(k+1)   - zu(k-1)    )  /       &
+                                           ( km(k,j,i) + 1.0E-20_wp )
+
+             IF ( ABS( u(k+1,j,i) - surf_lsm_h%u_0(m) )  >                     &
+                  ABS( u(k+1,j,i) - u(k-1,j,i)   )                             &
+                )  surf_lsm_h%u_0(m) = u(k-1,j,i)
+
+             IF ( ABS( v(k+1,j,i) - surf_lsm_h%v_0(m) )  >                     &
+                  ABS( v(k+1,j,i) - v(k-1,j,i)   )                             &
+                )  surf_lsm_h%v_0(m) = v(k-1,j,i)
+
+          ENDDO
+!
+!--       Urban surfaces, upward-facing
+          !$OMP PARALLEL DO PRIVATE(i,j,k,m)
+          DO  m = 1, surf_usm_h%ns
+
+             i = surf_usm_h%i(m)            
+             j = surf_usm_h%j(m)
+             k = surf_usm_h%k(m)
+!
+!--          Note, calculatione of u_0 and v_0 is not fully accurate, as u/v 
+!--          and km are not on the same grid. Actually, a further 
+!--          interpolation of km onto the u/v-grid is necessary. However, the
+!--          effect of this error is negligible. 
+             surf_usm_h%u_0(m) = u(k+1,j,i) + surf_usm_h%usws(m)      *        &
+                                           ( zu(k+1)   - zu(k-1)    )  /       &
+                                           ( km(k,j,i) + 1.0E-20_wp )  
+             surf_usm_h%v_0(m) = v(k+1,j,i) + surf_usm_h%vsws(m)      *        &
+                                           ( zu(k+1)   - zu(k-1)    )  /       &
+                                           ( km(k,j,i) + 1.0E-20_wp )
+
+             IF ( ABS( u(k+1,j,i) - surf_usm_h%u_0(m) )  >                     &
+                  ABS( u(k+1,j,i) - u(k-1,j,i)   )                             &
+                )  surf_usm_h%u_0(m) = u(k-1,j,i)
+
+             IF ( ABS( v(k+1,j,i) - surf_usm_h%v_0(m) )  >                     &
+                  ABS( v(k+1,j,i) - v(k-1,j,i)   )                             &
+                )  surf_usm_h%v_0(m) = v(k-1,j,i)
+
+          ENDDO
 
        ENDIF
Index: /palm/trunk/SOURCE/prognostic_equations.f90
===================================================================
--- /palm/trunk/SOURCE/prognostic_equations.f90	(revision 2231)
+++ /palm/trunk/SOURCE/prognostic_equations.f90	(revision 2232)
@@ -20,6 +20,7 @@
 ! Current revisions:
 ! ------------------
+! Adjutst to new surface-type structure. Remove call for usm_wall_heat_flux, 
+! which is realized directly in diffusion_s now.
 ! 
-!
 ! Former revisions:
 ! -----------------
@@ -225,9 +226,8 @@
                flux_s_pt, flux_s_q, flux_s_qr, flux_s_s, flux_s_sa, flux_l_e,  &
                flux_l_nr, flux_l_pt, flux_l_q, flux_l_qr, flux_l_s, flux_l_sa, &
-               nr, nr_p, nrsws, nrswst, pt, ptdf_x, ptdf_y, pt_init, pt_p,     &
-               prho, q, q_init, q_p, qsws, qswst, qr, qr_p, qrsws, qrswst, rdf,&
-               rdf_sc, ref_state, rho_ocean, s, s_init, s_p, sa, sa_init, sa_p,      &
-               saswsb, saswst, shf, ssws, sswst, tend,                         &
-               te_m, tnr_m, tpt_m, tq_m, tqr_m, ts_m, tsa_m, tswst, tu_m, tv_m,&
+               nr, nr_p, pt, ptdf_x, ptdf_y, pt_init, pt_p,                    &
+               prho, q, q_init, q_p, qr, qr_p, rdf,                            &
+               rdf_sc, ref_state, rho_ocean, s, s_init, s_p, sa, sa_init, sa_p,&
+               tend, te_m, tnr_m, tpt_m, tq_m, tqr_m, ts_m, tsa_m, tu_m, tv_m, &
                tw_m, u, ug, u_init, u_p, v, vg, vpt, v_init, v_p, w, w_p
 
@@ -243,8 +243,6 @@
                prho_reference, pt_reference, pt_reference, pt_reference,       &
                scalar_advec, scalar_advec, simulated_time, sloping_surface,    &
-               timestep_scheme, tsc, urban_surface, use_subsidence_tendencies, &
-               use_upstream_for_tke, wall_heatflux,                            &
-               wall_nrflux, wall_qflux, wall_qflux, wall_qflux, wall_qrflux,   &
-               wall_salinityflux, wall_sflux, ws_scheme_mom, ws_scheme_sca
+               timestep_scheme, tsc, use_subsidence_tendencies,                &
+               use_upstream_for_tke, ws_scheme_mom, ws_scheme_sca
 
     USE cpulog,                                                                &
@@ -255,6 +253,6 @@
 
     USE indices,                                                               &
-        ONLY:  nxl, nxlg, nxlu, nxr, nxrg, nyn, nyng, nys, nysg, nysv,         &
-               nzb_s_inner, nzb_u_inner, nzb_v_inner, nzb_w_inner, nzt
+        ONLY:  nxl, nxlg, nxlu, nxr, nxrg, nyn, nyng, nys, nysg, nysv, nzb,    &
+               nzt, wall_flags_0
 
     USE advec_ws,                                                              &
@@ -339,9 +337,10 @@
         ONLY:  subsidence
 
-    USE urban_surface_mod,                                                     &
-        ONLY:  usm_wall_heat_flux
-
     USE user_actions_mod,                                                      &
         ONLY:  user_actions
+
+    USE surface_mod,                                                           &
+        ONLY :  surf_def_h, surf_def_v, surf_lsm_h, surf_lsm_v, surf_usm_h,    &
+                surf_usm_v 
 
     USE wind_turbine_model_mod,                                                &
@@ -404,4 +403,6 @@
        !$OMP PARALLEL private (i,j)
        !$OMP DO
+!$OMP PARALLEL PRIVATE (i, j)
+!$OMP DO
        DO  i = nxlg, nxrg
           DO  j = nysg, nyng
@@ -410,4 +411,5 @@
        ENDDO
        !$OMP END PARALLEL
+!$OMP END PARALLEL
     ENDIF
 
@@ -474,8 +476,14 @@
 !
 !--          Prognostic equation for u-velocity component
-             DO  k = nzb_u_inner(j,i)+1, nzt
-                u_p(k,j,i) = u(k,j,i) + dt_3d * ( tsc(2) * tend(k,j,i) +       &
-                                                  tsc(3) * tu_m(k,j,i) )       &
-                                      - tsc(5) * rdf(k) * ( u(k,j,i) - u_init(k) )
+             DO  k = nzb+1, nzt
+
+                u_p(k,j,i) = u(k,j,i) + ( dt_3d *                               &
+                                            ( tsc(2) * tend(k,j,i) +            &
+                                              tsc(3) * tu_m(k,j,i) )            &
+                                            - tsc(5) * rdf(k)                   &
+                                                     * ( u(k,j,i) - u_init(k) ) &
+                                        ) * MERGE( 1.0_wp, 0.0_wp,              &
+                                                   BTEST( wall_flags_0(k,j,i), 1 )&
+                                                 )
              ENDDO
 
@@ -484,11 +492,12 @@
              IF ( timestep_scheme(1:5) == 'runge' )  THEN
                 IF ( intermediate_timestep_count == 1 )  THEN
-                   DO  k = nzb_u_inner(j,i)+1, nzt
+                   DO  k = nzb+1, nzt
                       tu_m(k,j,i) = tend(k,j,i)
                    ENDDO
                 ELSEIF ( intermediate_timestep_count < &
                          intermediate_timestep_count_max )  THEN
-                   DO  k = nzb_u_inner(j,i)+1, nzt
-                      tu_m(k,j,i) = -9.5625_wp * tend(k,j,i) + 5.3125_wp * tu_m(k,j,i)
+                   DO  k = nzb+1, nzt
+                      tu_m(k,j,i) =   -9.5625_wp * tend(k,j,i)                &
+                                     + 5.3125_wp * tu_m(k,j,i)
                    ENDDO
                 ENDIF
@@ -537,8 +546,13 @@
 !
 !--          Prognostic equation for v-velocity component
-             DO  k = nzb_v_inner(j,i)+1, nzt
-                v_p(k,j,i) = v(k,j,i) + dt_3d * ( tsc(2) * tend(k,j,i) +       &
-                                                  tsc(3) * tv_m(k,j,i) )       &
-                                      - tsc(5) * rdf(k) * ( v(k,j,i) - v_init(k) )
+             DO  k = nzb+1, nzt
+                v_p(k,j,i) = v(k,j,i) + ( dt_3d *                              &
+                                            ( tsc(2) * tend(k,j,i) +           &
+                                              tsc(3) * tv_m(k,j,i) )           &
+                                            - tsc(5) * rdf(k)                  &
+                                                     * ( v(k,j,i) - v_init(k) )&
+                                        ) * MERGE( 1.0_wp, 0.0_wp,             &
+                                                   BTEST( wall_flags_0(k,j,i), 2 )&
+                                                 )
              ENDDO
 
@@ -547,11 +561,12 @@
              IF ( timestep_scheme(1:5) == 'runge' )  THEN
                 IF ( intermediate_timestep_count == 1 )  THEN
-                   DO  k = nzb_v_inner(j,i)+1, nzt
+                   DO  k = nzb+1, nzt
                       tv_m(k,j,i) = tend(k,j,i)
                    ENDDO
                 ELSEIF ( intermediate_timestep_count < &
                          intermediate_timestep_count_max )  THEN
-                   DO  k = nzb_v_inner(j,i)+1, nzt
-                      tv_m(k,j,i) = -9.5625_wp * tend(k,j,i) + 5.3125_wp * tv_m(k,j,i)
+                   DO  k = nzb+1, nzt
+                      tv_m(k,j,i) =   -9.5625_wp * tend(k,j,i)                 &
+                                     + 5.3125_wp * tv_m(k,j,i)
                    ENDDO
                 ENDIF
@@ -596,11 +611,14 @@
 
           CALL user_actions( i, j, 'w-tendency' )
-
 !
 !--       Prognostic equation for w-velocity component
-          DO  k = nzb_w_inner(j,i)+1, nzt-1
-             w_p(k,j,i) = w(k,j,i) + dt_3d * ( tsc(2) * tend(k,j,i) +          &
+          DO  k = nzb+1, nzt-1
+             w_p(k,j,i) = w(k,j,i) + ( dt_3d *                                 &
+                                             ( tsc(2) * tend(k,j,i) +          &
                                                tsc(3) * tw_m(k,j,i) )          &
-                                   - tsc(5) * rdf(k) * w(k,j,i)
+                                             - tsc(5) * rdf(k) * w(k,j,i)      &
+                                     ) * MERGE( 1.0_wp, 0.0_wp,                &
+                                                BTEST( wall_flags_0(k,j,i), 3 )&
+                                              )
           ENDDO
 
@@ -609,11 +627,12 @@
           IF ( timestep_scheme(1:5) == 'runge' )  THEN
              IF ( intermediate_timestep_count == 1 )  THEN
-                DO  k = nzb_w_inner(j,i)+1, nzt-1
+                DO  k = nzb+1, nzt-1
                    tw_m(k,j,i) = tend(k,j,i)
                 ENDDO
              ELSEIF ( intermediate_timestep_count < &
                       intermediate_timestep_count_max )  THEN
-                DO  k = nzb_w_inner(j,i)+1, nzt-1
-                   tw_m(k,j,i) = -9.5625_wp * tend(k,j,i) + 5.3125_wp * tw_m(k,j,i)
+                DO  k = nzb+1, nzt-1
+                   tw_m(k,j,i) =   -9.5625_wp * tend(k,j,i)                    &
+                                  + 5.3125_wp * tw_m(k,j,i)
                 ENDDO
              ENDIF
@@ -628,5 +647,5 @@
              IF ( timestep_scheme(1:5) == 'runge' )  THEN
                    IF ( ws_scheme_sca )  THEN
-                      CALL advec_s_ws( i, j, pt, 'pt', flux_s_pt, diss_s_pt, &
+                      CALL advec_s_ws( i, j, pt, 'pt', flux_s_pt, diss_s_pt,   &
                                        flux_l_pt, diss_l_pt, i_omp_start, tn )
                    ELSE
@@ -636,12 +655,14 @@
                 CALL advec_s_up( i, j, pt )
              ENDIF
-             CALL diffusion_s( i, j, pt, shf, tswst, wall_heatflux )
-
-!
-!--          Tendency pt from wall heat flux from urban surface
-             IF ( urban_surface )  THEN
-                CALL usm_wall_heat_flux( i, j )
-             ENDIF
-
+             CALL diffusion_s( i, j, pt,                                       &
+                               surf_def_h(0)%shf, surf_def_h(1)%shf,           &
+                               surf_def_h(2)%shf,                              &
+                               surf_lsm_h%shf,    surf_usm_h%shf,              &
+                               surf_def_v(0)%shf, surf_def_v(1)%shf,           &
+                               surf_def_v(2)%shf, surf_def_v(3)%shf,           &
+                               surf_lsm_v(0)%shf, surf_lsm_v(1)%shf,           &
+                               surf_lsm_v(2)%shf, surf_lsm_v(3)%shf,           &
+                               surf_usm_v(0)%shf, surf_usm_v(1)%shf,           &
+                               surf_usm_v(2)%shf, surf_usm_v(3)%shf )
 !
 !--          If required compute heating/cooling due to long wave radiation
@@ -683,12 +704,18 @@
 
              CALL user_actions( i, j, 'pt-tendency' )
-
 !
 !--          Prognostic equation for potential temperature
-             DO  k = nzb_s_inner(j,i)+1, nzt
-                pt_p(k,j,i) = pt(k,j,i) + dt_3d * ( tsc(2) * tend(k,j,i) +     &
+             DO  k = nzb+1, nzt
+                pt_p(k,j,i) = pt(k,j,i) + ( dt_3d *                            &
+                                                  ( tsc(2) * tend(k,j,i) +     &
                                                     tsc(3) * tpt_m(k,j,i) )    &
-                                        - tsc(5) * ( pt(k,j,i) - pt_init(k) ) *&
-                                          ( rdf_sc(k) + ptdf_x(i) + ptdf_y(j) )
+                                                  - tsc(5)                     &
+                                                  * ( pt(k,j,i) - pt_init(k) ) &
+                                                  * ( rdf_sc(k) + ptdf_x(i)    &
+                                                                + ptdf_y(j) )  &
+                                          )                                    &
+                                       * MERGE( 1.0_wp, 0.0_wp,                &
+                                                BTEST( wall_flags_0(k,j,i), 0 )&
+                                              )
              ENDDO
 
@@ -697,12 +724,12 @@
              IF ( timestep_scheme(1:5) == 'runge' )  THEN
                 IF ( intermediate_timestep_count == 1 )  THEN
-                   DO  k = nzb_s_inner(j,i)+1, nzt
+                   DO  k = nzb+1, nzt
                       tpt_m(k,j,i) = tend(k,j,i)
                    ENDDO
                 ELSEIF ( intermediate_timestep_count < &
                          intermediate_timestep_count_max )  THEN
-                   DO  k = nzb_s_inner(j,i)+1, nzt
-                      tpt_m(k,j,i) = -9.5625_wp * tend(k,j,i) + &
-                                      5.3125_wp * tpt_m(k,j,i)
+                   DO  k = nzb+1, nzt
+                      tpt_m(k,j,i) =   -9.5625_wp * tend(k,j,i) +              &
+                                        5.3125_wp * tpt_m(k,j,i)
                    ENDDO
                 ENDIF
@@ -729,5 +756,14 @@
                 CALL advec_s_up( i, j, sa )
              ENDIF
-             CALL diffusion_s( i, j, sa, saswsb, saswst, wall_salinityflux )
+             CALL diffusion_s( i, j, sa,                                       &
+                               surf_def_h(0)%sasws, surf_def_h(1)%sasws,       &
+                               surf_def_h(2)%sasws,                            &
+                               surf_lsm_h%sasws,    surf_usm_h%sasws,          & 
+                               surf_def_v(0)%sasws, surf_def_v(1)%sasws,       &
+                               surf_def_v(2)%sasws, surf_def_v(3)%sasws,       &
+                               surf_lsm_v(0)%sasws, surf_lsm_v(1)%sasws,       &
+                               surf_lsm_v(2)%sasws, surf_lsm_v(3)%sasws,       &
+                               surf_usm_v(0)%sasws, surf_usm_v(1)%sasws,       &
+                               surf_usm_v(2)%sasws, surf_usm_v(3)%sasws )
 
              CALL user_actions( i, j, 'sa-tendency' )
@@ -735,9 +771,13 @@
 !
 !--          Prognostic equation for salinity
-             DO  k = nzb_s_inner(j,i)+1, nzt
-                sa_p(k,j,i) = sa(k,j,i) + dt_3d * ( tsc(2) * tend(k,j,i) +     &
+             DO  k = nzb+1, nzt
+                sa_p(k,j,i) = sa(k,j,i) + ( dt_3d *                            &
+                                                  ( tsc(2) * tend(k,j,i) +     &
                                                     tsc(3) * tsa_m(k,j,i) )    &
-                                        - tsc(5) * rdf_sc(k) *                 &
-                                          ( sa(k,j,i) - sa_init(k) )
+                                                  - tsc(5) * rdf_sc(k)         &
+                                                   * ( sa(k,j,i) - sa_init(k) )&
+                                          ) * MERGE( 1.0_wp, 0.0_wp,           &
+                                                BTEST( wall_flags_0(k,j,i), 0 )&
+                                                   )
                 IF ( sa_p(k,j,i) < 0.0_wp )  sa_p(k,j,i) = 0.1_wp * sa(k,j,i)
              ENDDO
@@ -747,13 +787,13 @@
              IF ( timestep_scheme(1:5) == 'runge' )  THEN
                 IF ( intermediate_timestep_count == 1 )  THEN
-                   DO  k = nzb_s_inner(j,i)+1, nzt
+                   DO  k = nzb+1, nzt
                       tsa_m(k,j,i) = tend(k,j,i)
                    ENDDO
                 ELSEIF ( intermediate_timestep_count < &
                          intermediate_timestep_count_max )  THEN
-                   DO  k = nzb_s_inner(j,i)+1, nzt
-                      tsa_m(k,j,i) = -9.5625_wp * tend(k,j,i) + &
-                                      5.3125_wp * tsa_m(k,j,i)
-                   ENDDO
+                   DO  k = nzb+1, nzt
+                      tsa_m(k,j,i) =   -9.5625_wp * tend(k,j,i) +              &
+                                        5.3125_wp * tsa_m(k,j,i)
+                   ENDDO  
                 ENDIF
              ENDIF
@@ -783,5 +823,14 @@
                 CALL advec_s_up( i, j, q )
              ENDIF
-             CALL diffusion_s( i, j, q, qsws, qswst, wall_qflux )
+             CALL diffusion_s( i, j, q,                                        &
+                               surf_def_h(0)%qsws, surf_def_h(1)%qsws,         &
+                               surf_def_h(2)%qsws,                             &
+                               surf_lsm_h%qsws,    surf_usm_h%qsws,            &
+                               surf_def_v(0)%qsws, surf_def_v(1)%qsws,         &
+                               surf_def_v(2)%qsws, surf_def_v(3)%qsws,         &
+                               surf_lsm_v(0)%qsws, surf_lsm_v(1)%qsws,         &
+                               surf_lsm_v(2)%qsws, surf_lsm_v(3)%qsws,         &
+                               surf_usm_v(0)%qsws, surf_usm_v(1)%qsws,         &
+                               surf_usm_v(2)%qsws, surf_usm_v(3)%qsws )
 
 !
@@ -810,9 +859,14 @@
 !
 !--          Prognostic equation for total water content / scalar
-             DO  k = nzb_s_inner(j,i)+1, nzt
-                q_p(k,j,i) = q(k,j,i) + dt_3d * ( tsc(2) * tend(k,j,i) +       &
+             DO  k = nzb+1, nzt
+                q_p(k,j,i) = q(k,j,i) + ( dt_3d *                              &
+                                                ( tsc(2) * tend(k,j,i) +       &
                                                   tsc(3) * tq_m(k,j,i) )       &
-                                      - tsc(5) * rdf_sc(k) *                   &
-                                        ( q(k,j,i) - q_init(k) )
+                                                - tsc(5) * rdf_sc(k) *         &
+                                                      ( q(k,j,i) - q_init(k) ) &
+                                        )                                      &
+                                       * MERGE( 1.0_wp, 0.0_wp,                &
+                                                BTEST( wall_flags_0(k,j,i), 0 )&
+                                              )                
                 IF ( q_p(k,j,i) < 0.0_wp )  q_p(k,j,i) = 0.1_wp * q(k,j,i)
              ENDDO
@@ -822,12 +876,12 @@
              IF ( timestep_scheme(1:5) == 'runge' )  THEN
                 IF ( intermediate_timestep_count == 1 )  THEN
-                   DO  k = nzb_s_inner(j,i)+1, nzt
+                   DO  k = nzb+1, nzt
                       tq_m(k,j,i) = tend(k,j,i)
                    ENDDO
                 ELSEIF ( intermediate_timestep_count < &
                          intermediate_timestep_count_max )  THEN
-                   DO  k = nzb_s_inner(j,i)+1, nzt
-                      tq_m(k,j,i) = -9.5625_wp * tend(k,j,i) + &
-                                     5.3125_wp * tq_m(k,j,i)
+                   DO  k = nzb+1, nzt
+                      tq_m(k,j,i) =   -9.5625_wp * tend(k,j,i) +               &
+                                       5.3125_wp * tq_m(k,j,i)
                    ENDDO
                 ENDIF
@@ -853,12 +907,27 @@
                    CALL advec_s_up( i, j, qr )
                 ENDIF
-                CALL diffusion_s( i, j, qr, qrsws, qrswst, wall_qrflux )
+                CALL diffusion_s( i, j, qr,                                   &
+                                  surf_def_h(0)%qrsws, surf_def_h(1)%qrsws,   &
+                                  surf_def_h(2)%qrsws,                        &
+                                  surf_lsm_h%qrsws,    surf_usm_h%qrsws,      &  
+                                  surf_def_v(0)%qrsws, surf_def_v(1)%qrsws,   &
+                                  surf_def_v(2)%qrsws, surf_def_v(3)%qrsws,   &
+                                  surf_lsm_v(0)%qrsws, surf_lsm_v(1)%qrsws,   &
+                                  surf_lsm_v(2)%qrsws, surf_lsm_v(3)%qrsws,   &
+                                  surf_usm_v(0)%qrsws, surf_usm_v(1)%qrsws,   &
+                                  surf_usm_v(2)%qrsws, surf_usm_v(3)%qrsws )
 
 !
 !--             Prognostic equation for rain water content
-                DO  k = nzb_s_inner(j,i)+1, nzt
-                   qr_p(k,j,i) = qr(k,j,i) + dt_3d * ( tsc(2) * tend(k,j,i) +  &
-                                                       tsc(3) * tqr_m(k,j,i) ) &
-                                           - tsc(5) * rdf_sc(k) * qr(k,j,i)
+                DO  k = nzb+1, nzt
+                   qr_p(k,j,i) = qr(k,j,i) + ( dt_3d *                         &
+                                                      ( tsc(2) * tend(k,j,i) + &
+                                                        tsc(3) * tqr_m(k,j,i) )&
+                                                      - tsc(5) * rdf_sc(k)     &
+                                                               * qr(k,j,i)     &
+                                             )                                 &
+                                       * MERGE( 1.0_wp, 0.0_wp,                &
+                                                BTEST( wall_flags_0(k,j,i), 0 )&
+                                              ) 
                    IF ( qr_p(k,j,i) < 0.0_wp )  qr_p(k,j,i) = 0.0_wp
                 ENDDO
@@ -867,12 +936,12 @@
                 IF ( timestep_scheme(1:5) == 'runge' )  THEN
                    IF ( intermediate_timestep_count == 1 )  THEN
-                      DO  k = nzb_s_inner(j,i)+1, nzt
+                      DO  k = nzb+1, nzt
                          tqr_m(k,j,i) = tend(k,j,i)
                       ENDDO
                    ELSEIF ( intermediate_timestep_count < &
                             intermediate_timestep_count_max )  THEN
-                      DO  k = nzb_s_inner(j,i)+1, nzt
-                         tqr_m(k,j,i) = -9.5625_wp * tend(k,j,i) + &
-                                        5.3125_wp * tqr_m(k,j,i)
+                      DO  k = nzb+1, nzt
+                         tqr_m(k,j,i) =   -9.5625_wp * tend(k,j,i) +           &
+                                           5.3125_wp * tqr_m(k,j,i)
                       ENDDO
                    ENDIF
@@ -893,12 +962,27 @@
                    CALL advec_s_up( i, j, nr )
                 ENDIF
-                CALL diffusion_s( i, j, nr, nrsws, nrswst, wall_nrflux )
+                CALL diffusion_s( i, j, nr,                                    &
+                                  surf_def_h(0)%nrsws, surf_def_h(1)%nrsws,    &
+                                  surf_def_h(2)%nrsws,                         &
+                                  surf_lsm_h%nrsws,    surf_usm_h%nrsws,       &
+                                  surf_def_v(0)%nrsws, surf_def_v(1)%nrsws,    &
+                                  surf_def_v(2)%nrsws, surf_def_v(3)%nrsws,    &
+                                  surf_lsm_v(0)%nrsws, surf_lsm_v(1)%nrsws,    &
+                                  surf_lsm_v(2)%nrsws, surf_lsm_v(3)%nrsws,    &
+                                  surf_usm_v(0)%nrsws, surf_usm_v(1)%nrsws,    &
+                                  surf_usm_v(2)%nrsws, surf_usm_v(3)%nrsws )
 
 !
 !--             Prognostic equation for rain drop concentration
-                DO  k = nzb_s_inner(j,i)+1, nzt
-                   nr_p(k,j,i) = nr(k,j,i) + dt_3d * ( tsc(2) * tend(k,j,i) +  &
-                                                       tsc(3) * tnr_m(k,j,i) ) &
-                                           - tsc(5) * rdf_sc(k) * nr(k,j,i)
+                DO  k = nzb+1, nzt
+                   nr_p(k,j,i) = nr(k,j,i) + ( dt_3d *                         &
+                                                      ( tsc(2) * tend(k,j,i) + &
+                                                        tsc(3) * tnr_m(k,j,i) )&
+                                                      - tsc(5) * rdf_sc(k)     &
+                                                               * nr(k,j,i)     &
+                                             )                                 &
+                                       * MERGE( 1.0_wp, 0.0_wp,                &
+                                                BTEST( wall_flags_0(k,j,i), 0 )&
+                                              )
                    IF ( nr_p(k,j,i) < 0.0_wp )  nr_p(k,j,i) = 0.0_wp
                 ENDDO
@@ -907,12 +991,12 @@
                 IF ( timestep_scheme(1:5) == 'runge' )  THEN
                    IF ( intermediate_timestep_count == 1 )  THEN
-                      DO  k = nzb_s_inner(j,i)+1, nzt
+                      DO  k = nzb+1, nzt
                          tnr_m(k,j,i) = tend(k,j,i)
                       ENDDO
                    ELSEIF ( intermediate_timestep_count < &
                             intermediate_timestep_count_max )  THEN
-                      DO  k = nzb_s_inner(j,i)+1, nzt
-                         tnr_m(k,j,i) = -9.5625_wp * tend(k,j,i) + &
-                                        5.3125_wp * tnr_m(k,j,i)
+                      DO  k = nzb+1, nzt
+                         tnr_m(k,j,i) =   -9.5625_wp * tend(k,j,i) +           &
+                                           5.3125_wp * tnr_m(k,j,i)
                       ENDDO
                    ENDIF
@@ -940,5 +1024,14 @@
                 CALL advec_s_up( i, j, s )
              ENDIF
-             CALL diffusion_s( i, j, s, ssws, sswst, wall_sflux )
+             CALL diffusion_s( i, j, s,                                        &
+                               surf_def_h(0)%ssws, surf_def_h(1)%ssws,         &
+                               surf_def_h(2)%ssws,                             &
+                               surf_lsm_h%ssws,    surf_usm_h%ssws,            &
+                               surf_def_v(0)%ssws, surf_def_v(1)%ssws,         &
+                               surf_def_v(2)%ssws, surf_def_v(3)%ssws,         &
+                               surf_lsm_v(0)%ssws, surf_lsm_v(1)%ssws,         &
+                               surf_lsm_v(2)%ssws, surf_lsm_v(3)%ssws,         &
+                               surf_usm_v(0)%ssws, surf_usm_v(1)%ssws,         &
+                               surf_usm_v(2)%ssws, surf_usm_v(3)%ssws )
 
 !
@@ -971,9 +1064,14 @@
 !
 !--          Prognostic equation for scalar
-             DO  k = nzb_s_inner(j,i)+1, nzt
-                s_p(k,j,i) = s(k,j,i) + dt_3d * ( tsc(2) * tend(k,j,i) +       &
-                                                  tsc(3) * ts_m(k,j,i) )       &
-                                      - tsc(5) * rdf_sc(k) *                   &
-                                        ( s(k,j,i) - s_init(k) )
+             DO  k = nzb+1, nzt
+                s_p(k,j,i) = s(k,j,i) + (  dt_3d *                             &
+                                            ( tsc(2) * tend(k,j,i) +           &
+                                              tsc(3) * ts_m(k,j,i) )           &
+                                            - tsc(5) * rdf_sc(k)               &
+                                                     * ( s(k,j,i) - s_init(k) )&
+                                        )                                      &
+                                       * MERGE( 1.0_wp, 0.0_wp,                &
+                                                BTEST( wall_flags_0(k,j,i), 0 )&
+                                              )
                 IF ( s_p(k,j,i) < 0.0_wp )  s_p(k,j,i) = 0.1_wp * s(k,j,i)
              ENDDO
@@ -983,12 +1081,12 @@
              IF ( timestep_scheme(1:5) == 'runge' )  THEN
                 IF ( intermediate_timestep_count == 1 )  THEN
-                   DO  k = nzb_s_inner(j,i)+1, nzt
+                   DO  k = nzb+1, nzt
                       ts_m(k,j,i) = tend(k,j,i)
                    ENDDO
                 ELSEIF ( intermediate_timestep_count < &
                          intermediate_timestep_count_max )  THEN
-                   DO  k = nzb_s_inner(j,i)+1, nzt
-                      ts_m(k,j,i) = -9.5625_wp * tend(k,j,i) + &
-                                     5.3125_wp * ts_m(k,j,i)
+                   DO  k = nzb+1, nzt
+                      ts_m(k,j,i) =   -9.5625_wp * tend(k,j,i) +               &
+                                       5.3125_wp * ts_m(k,j,i)
                    ENDDO
                 ENDIF
@@ -1037,7 +1135,12 @@
 !--          reasons in the course of the integration. In such cases the old
 !--          TKE value is reduced by 90%.
-             DO  k = nzb_s_inner(j,i)+1, nzt
-                e_p(k,j,i) = e(k,j,i) + dt_3d * ( tsc(2) * tend(k,j,i) +       &
-                                                  tsc(3) * te_m(k,j,i) )
+             DO  k = nzb+1, nzt
+                e_p(k,j,i) = e(k,j,i) + ( dt_3d *                              &
+                                                ( tsc(2) * tend(k,j,i) +       &
+                                                  tsc(3) * te_m(k,j,i) )       &
+                                        )                                      &
+                                       * MERGE( 1.0_wp, 0.0_wp,                &
+                                                BTEST( wall_flags_0(k,j,i), 0 )&
+                                              )
                 IF ( e_p(k,j,i) < 0.0_wp )  e_p(k,j,i) = 0.1_wp * e(k,j,i)
              ENDDO
@@ -1047,12 +1150,12 @@
              IF ( timestep_scheme(1:5) == 'runge' )  THEN
                 IF ( intermediate_timestep_count == 1 )  THEN
-                   DO  k = nzb_s_inner(j,i)+1, nzt
+                   DO  k = nzb+1, nzt
                       te_m(k,j,i) = tend(k,j,i)
                    ENDDO
                 ELSEIF ( intermediate_timestep_count < &
                          intermediate_timestep_count_max )  THEN
-                   DO  k = nzb_s_inner(j,i)+1, nzt
-                      te_m(k,j,i) = -9.5625_wp * tend(k,j,i) + &
-                                     5.3125_wp * te_m(k,j,i)
+                   DO  k = nzb+1, nzt
+                      te_m(k,j,i) =   -9.5625_wp * tend(k,j,i) +               &
+                                       5.3125_wp * te_m(k,j,i)
                    ENDDO
                 ENDIF
@@ -1064,4 +1167,7 @@
     ENDDO
     !$OMP END PARALLEL
+
+
+
 
     CALL cpu_log( log_point(32), 'all progn.equations', 'stop' )
@@ -1150,8 +1256,12 @@
     DO  i = nxlu, nxr
        DO  j = nys, nyn
-          DO  k = nzb_u_inner(j,i)+1, nzt
-             u_p(k,j,i) = u(k,j,i) + dt_3d * ( tsc(2) * tend(k,j,i) +          &
-                                               tsc(3) * tu_m(k,j,i) )          &
-                                   - tsc(5) * rdf(k) * ( u(k,j,i) - u_init(k) )
+          DO  k = nzb+1, nzt
+             u_p(k,j,i) = u(k,j,i) + ( dt_3d * ( tsc(2) * tend(k,j,i) +          &
+                                                 tsc(3) * tu_m(k,j,i) )          &
+                                               - tsc(5) * rdf(k) *               &
+                                                        ( u(k,j,i) - u_init(k) ) &
+                                     ) * MERGE( 1.0_wp, 0.0_wp,                  &
+                                                 BTEST( wall_flags_0(k,j,i), 1 ) &
+                                              )
           ENDDO
        ENDDO
@@ -1164,5 +1274,5 @@
           DO  i = nxlu, nxr
              DO  j = nys, nyn
-                DO  k = nzb_u_inner(j,i)+1, nzt
+                DO  k = nzb+1, nzt
                    tu_m(k,j,i) = tend(k,j,i)
                 ENDDO
@@ -1173,6 +1283,7 @@
           DO  i = nxlu, nxr
              DO  j = nys, nyn
-                DO  k = nzb_u_inner(j,i)+1, nzt
-                   tu_m(k,j,i) = -9.5625_wp * tend(k,j,i) + 5.3125_wp * tu_m(k,j,i)
+                DO  k = nzb+1, nzt
+                   tu_m(k,j,i) =    -9.5625_wp * tend(k,j,i)                   &
+                                   + 5.3125_wp * tu_m(k,j,i)
                 ENDDO
              ENDDO
@@ -1230,8 +1341,12 @@
     DO  i = nxl, nxr
        DO  j = nysv, nyn
-          DO  k = nzb_v_inner(j,i)+1, nzt
-             v_p(k,j,i) = v(k,j,i) + dt_3d * ( tsc(2) * tend(k,j,i) +          &
-                                               tsc(3) * tv_m(k,j,i) )          &
-                                   - tsc(5) * rdf(k) * ( v(k,j,i) - v_init(k) )
+          DO  k = nzb+1, nzt
+             v_p(k,j,i) = v(k,j,i) + ( dt_3d * ( tsc(2) * tend(k,j,i) +        &
+                                                 tsc(3) * tv_m(k,j,i) )        &
+                                               - tsc(5) * rdf(k) *             &
+                                                      ( v(k,j,i) - v_init(k) ) &
+                                     ) * MERGE( 1.0_wp, 0.0_wp,                &
+                                                BTEST( wall_flags_0(k,j,i), 2 )&
+                                              )
           ENDDO
        ENDDO
@@ -1244,5 +1359,5 @@
           DO  i = nxl, nxr
              DO  j = nysv, nyn
-                DO  k = nzb_v_inner(j,i)+1, nzt
+                DO  k = nzb+1, nzt
                    tv_m(k,j,i) = tend(k,j,i)
                 ENDDO
@@ -1253,6 +1368,7 @@
           DO  i = nxl, nxr
              DO  j = nysv, nyn
-                DO  k = nzb_v_inner(j,i)+1, nzt
-                   tv_m(k,j,i) = -9.5625_wp * tend(k,j,i) + 5.3125_wp * tv_m(k,j,i)
+                DO  k = nzb+1, nzt
+                   tv_m(k,j,i) =   -9.5625_wp * tend(k,j,i)                    &
+                                  + 5.3125_wp * tv_m(k,j,i)
                 ENDDO
              ENDDO
@@ -1306,8 +1422,11 @@
     DO  i = nxl, nxr
        DO  j = nys, nyn
-          DO  k = nzb_w_inner(j,i)+1, nzt-1
-             w_p(k,j,i) = w(k,j,i) + dt_3d * ( tsc(2) * tend(k,j,i) +          &
-                                               tsc(3) * tw_m(k,j,i) )          &
-                                   - tsc(5) * rdf(k) * w(k,j,i)
+          DO  k = nzb+1, nzt-1
+             w_p(k,j,i) = w(k,j,i) + ( dt_3d * ( tsc(2) * tend(k,j,i) +        &
+                                                 tsc(3) * tw_m(k,j,i) )        &
+                                               - tsc(5) * rdf(k) * w(k,j,i)    &
+                                     ) * MERGE( 1.0_wp, 0.0_wp,                &
+                                                BTEST( wall_flags_0(k,j,i), 3 )&
+                                              )
           ENDDO
        ENDDO
@@ -1320,5 +1439,5 @@
           DO  i = nxl, nxr
              DO  j = nys, nyn
-                DO  k = nzb_w_inner(j,i)+1, nzt-1
+                DO  k = nzb+1, nzt-1
                    tw_m(k,j,i) = tend(k,j,i)
                 ENDDO
@@ -1329,6 +1448,7 @@
           DO  i = nxl, nxr
              DO  j = nys, nyn
-                DO  k = nzb_w_inner(j,i)+1, nzt-1
-                   tw_m(k,j,i) = -9.5625_wp * tend(k,j,i) + 5.3125_wp * tw_m(k,j,i)
+                DO  k = nzb+1, nzt-1
+                   tw_m(k,j,i) =   -9.5625_wp * tend(k,j,i)                    &
+                                  + 5.3125_wp * tw_m(k,j,i)
                 ENDDO
              ENDDO
@@ -1376,12 +1496,14 @@
        ENDIF
 
-       CALL diffusion_s( pt, shf, tswst, wall_heatflux )
-
-!
-!--    Tendency pt from wall heat flux from urban surface
-       IF ( urban_surface )  THEN
-          CALL usm_wall_heat_flux
-       ENDIF
-
+       CALL diffusion_s( pt,                                                   &
+                         surf_def_h(0)%shf, surf_def_h(1)%shf,                 &
+                         surf_def_h(2)%shf,                                    &
+                         surf_lsm_h%shf,    surf_usm_h%shf,                    &
+                         surf_def_v(0)%shf, surf_def_v(1)%shf,                 &
+                         surf_def_v(2)%shf, surf_def_v(3)%shf,                 &
+                         surf_lsm_v(0)%shf, surf_lsm_v(1)%shf,                 &
+                         surf_lsm_v(2)%shf, surf_lsm_v(3)%shf,                 &
+                         surf_usm_v(0)%shf, surf_usm_v(1)%shf,                 &
+                         surf_usm_v(2)%shf, surf_usm_v(3)%shf )
 !
 !--    If required compute heating/cooling due to long wave radiation processes
@@ -1426,9 +1548,14 @@
        DO  i = nxl, nxr
           DO  j = nys, nyn
-             DO  k = nzb_s_inner(j,i)+1, nzt
-                pt_p(k,j,i) = pt(k,j,i) + dt_3d * ( sbt * tend(k,j,i) +        &
-                                                    tsc(3) * tpt_m(k,j,i) )    &
-                                        - tsc(5) * ( pt(k,j,i) - pt_init(k) ) *&
-                                          ( rdf_sc(k) + ptdf_x(i) + ptdf_y(j) )
+             DO  k = nzb+1, nzt
+                pt_p(k,j,i) = pt(k,j,i) + ( dt_3d * ( sbt * tend(k,j,i) +      &
+                                                   tsc(3) * tpt_m(k,j,i) )     &
+                                                 - tsc(5) *                    &
+                                                   ( pt(k,j,i) - pt_init(k) ) *&
+                                          ( rdf_sc(k) + ptdf_x(i) + ptdf_y(j) )&
+                                          )                                    &
+                                   * MERGE( 1.0_wp, 0.0_wp,                    &
+                                             BTEST( wall_flags_0(k,j,i), 0 )   &
+                                          )
              ENDDO
           ENDDO
@@ -1441,5 +1568,5 @@
              DO  i = nxl, nxr
                 DO  j = nys, nyn
-                   DO  k = nzb_s_inner(j,i)+1, nzt
+                   DO  k = nzb+1, nzt
                       tpt_m(k,j,i) = tend(k,j,i)
                    ENDDO
@@ -1450,7 +1577,7 @@
              DO  i = nxl, nxr
                 DO  j = nys, nyn
-                   DO  k = nzb_s_inner(j,i)+1, nzt
-                      tpt_m(k,j,i) = -9.5625_wp * tend(k,j,i) + &
-                                      5.3125_wp * tpt_m(k,j,i)
+                   DO  k = nzb+1, nzt
+                      tpt_m(k,j,i) =   -9.5625_wp * tend(k,j,i) +              &
+                                        5.3125_wp * tpt_m(k,j,i)
                    ENDDO
                 ENDDO
@@ -1499,5 +1626,14 @@
        ENDIF
 
-       CALL diffusion_s( sa, saswsb, saswst, wall_salinityflux )
+       CALL diffusion_s( sa,                                                   &
+                         surf_def_h(0)%sasws, surf_def_h(1)%sasws,             &
+                         surf_def_h(2)%sasws,                                  &
+                         surf_lsm_h%sasws,    surf_usm_h%sasws,                &
+                         surf_def_v(0)%sasws, surf_def_v(1)%sasws,             &
+                         surf_def_v(2)%sasws, surf_def_v(3)%sasws,             &
+                         surf_lsm_v(0)%sasws, surf_lsm_v(1)%sasws,             &
+                         surf_lsm_v(2)%sasws, surf_lsm_v(3)%sasws,             &
+                         surf_usm_v(0)%sasws, surf_usm_v(1)%sasws,             &
+                         surf_usm_v(2)%sasws, surf_usm_v(3)%sasws )
 
        CALL user_actions( 'sa-tendency' )
@@ -1507,9 +1643,13 @@
        DO  i = nxl, nxr
           DO  j = nys, nyn
-             DO  k = nzb_s_inner(j,i)+1, nzt
-                sa_p(k,j,i) = sa(k,j,i) + dt_3d * ( sbt * tend(k,j,i) +        &
-                                                    tsc(3) * tsa_m(k,j,i) )    &
-                                        - tsc(5) * rdf_sc(k) *                 &
-                                          ( sa(k,j,i) - sa_init(k) )
+             DO  k = nzb+1, nzt
+                sa_p(k,j,i) = sa(k,j,i) + ( dt_3d * ( sbt * tend(k,j,i) +      &
+                                                   tsc(3) * tsa_m(k,j,i) )     &
+                                                 - tsc(5) * rdf_sc(k) *        &
+                                                 ( sa(k,j,i) - sa_init(k) )    &
+                                          )                                    &
+                                   * MERGE( 1.0_wp, 0.0_wp,                    &
+                                             BTEST( wall_flags_0(k,j,i), 0 )   &
+                                          )
                 IF ( sa_p(k,j,i) < 0.0_wp )  sa_p(k,j,i) = 0.1_wp * sa(k,j,i)
              ENDDO
@@ -1523,5 +1663,5 @@
              DO  i = nxl, nxr
                 DO  j = nys, nyn
-                   DO  k = nzb_s_inner(j,i)+1, nzt
+                   DO  k = nzb+1, nzt
                       tsa_m(k,j,i) = tend(k,j,i)
                    ENDDO
@@ -1532,7 +1672,7 @@
              DO  i = nxl, nxr
                 DO  j = nys, nyn
-                   DO  k = nzb_s_inner(j,i)+1, nzt
-                      tsa_m(k,j,i) = -9.5625_wp * tend(k,j,i) + &
-                                      5.3125_wp * tsa_m(k,j,i)
+                   DO  k = nzb+1, nzt
+                      tsa_m(k,j,i) =   -9.5625_wp * tend(k,j,i) +              &
+                                        5.3125_wp * tsa_m(k,j,i)
                    ENDDO
                 ENDDO
@@ -1587,5 +1727,14 @@
        ENDIF
 
-       CALL diffusion_s( q, qsws, qswst, wall_qflux )
+       CALL diffusion_s( q,                                                    &
+                         surf_def_h(0)%qsws, surf_def_h(1)%qsws,               &
+                         surf_def_h(2)%qsws,                                   &
+                         surf_lsm_h%qsws,    surf_usm_h%qsws,                  &
+                         surf_def_v(0)%qsws, surf_def_v(1)%qsws,               &
+                         surf_def_v(2)%qsws, surf_def_v(3)%qsws,               &
+                         surf_lsm_v(0)%qsws, surf_lsm_v(1)%qsws,               &
+                         surf_lsm_v(2)%qsws, surf_lsm_v(3)%qsws,               &
+                         surf_usm_v(0)%qsws, surf_usm_v(1)%qsws,               &
+                         surf_usm_v(2)%qsws, surf_usm_v(3)%qsws )
 
 !
@@ -1616,9 +1765,12 @@
        DO  i = nxl, nxr
           DO  j = nys, nyn
-             DO  k = nzb_s_inner(j,i)+1, nzt
-                q_p(k,j,i) = q(k,j,i) + dt_3d * ( sbt * tend(k,j,i) +          &
-                                                  tsc(3) * tq_m(k,j,i) )       &
-                                      - tsc(5) * rdf_sc(k) *                   &
-                                        ( q(k,j,i) - q_init(k) )
+             DO  k = nzb+1, nzt
+                q_p(k,j,i) = q(k,j,i) + ( dt_3d * ( sbt * tend(k,j,i) +        &
+                                                 tsc(3) * tq_m(k,j,i) )        &
+                                               - tsc(5) * rdf_sc(k) *          &
+                                                      ( q(k,j,i) - q_init(k) ) &
+                                        ) * MERGE( 1.0_wp, 0.0_wp,             &
+                                                   BTEST( wall_flags_0(k,j,i), 0 ) &
+                                                 )
                 IF ( q_p(k,j,i) < 0.0_wp )  q_p(k,j,i) = 0.1_wp * q(k,j,i)
              ENDDO
@@ -1632,5 +1784,5 @@
              DO  i = nxl, nxr
                 DO  j = nys, nyn
-                   DO  k = nzb_s_inner(j,i)+1, nzt
+                   DO  k = nzb+1, nzt
                       tq_m(k,j,i) = tend(k,j,i)
                    ENDDO
@@ -1641,6 +1793,7 @@
              DO  i = nxl, nxr
                 DO  j = nys, nyn
-                   DO  k = nzb_s_inner(j,i)+1, nzt
-                      tq_m(k,j,i) = -9.5625_wp * tend(k,j,i) + 5.3125_wp * tq_m(k,j,i)
+                   DO  k = nzb+1, nzt
+                      tq_m(k,j,i) =   -9.5625_wp * tend(k,j,i)                 &
+                                     + 5.3125_wp * tq_m(k,j,i)
                    ENDDO
                 ENDDO
@@ -1688,5 +1841,14 @@
           ENDIF
 
-          CALL diffusion_s( qr, qrsws, qrswst, wall_qrflux )
+          CALL diffusion_s( qr,                                                &
+                            surf_def_h(0)%qrsws, surf_def_h(1)%qrsws,          &
+                            surf_def_h(2)%qrsws,                               &
+                            surf_lsm_h%qrsws,    surf_usm_h%qrsws,             &
+                            surf_def_v(0)%qrsws, surf_def_v(1)%qrsws,          &
+                            surf_def_v(2)%qrsws, surf_def_v(3)%qrsws,          &
+                            surf_lsm_v(0)%qrsws, surf_lsm_v(1)%qrsws,          &
+                            surf_lsm_v(2)%qrsws, surf_lsm_v(3)%qrsws,          &
+                            surf_usm_v(0)%qrsws, surf_usm_v(1)%qrsws,          &
+                            surf_usm_v(2)%qrsws, surf_usm_v(3)%qrsws )
 
 !
@@ -1694,8 +1856,13 @@
           DO  i = nxl, nxr
              DO  j = nys, nyn
-                DO  k = nzb_s_inner(j,i)+1, nzt
-                   qr_p(k,j,i) = qr(k,j,i) + dt_3d * ( sbt * tend(k,j,i) +     &
-                                                     tsc(3) * tqr_m(k,j,i) )   &
-                                           - tsc(5) * rdf_sc(k) * qr(k,j,i)
+                DO  k = nzb+1, nzt
+                   qr_p(k,j,i) = qr(k,j,i) + ( dt_3d * ( sbt * tend(k,j,i) +   &
+                                                      tsc(3) * tqr_m(k,j,i) )  &
+                                                    - tsc(5) * rdf_sc(k) *     &
+                                                               qr(k,j,i)       &
+                                             )                                 &
+                                    * MERGE( 1.0_wp, 0.0_wp,                   &
+                                             BTEST( wall_flags_0(k,j,i), 0 )   &
+                                          )
                    IF ( qr_p(k,j,i) < 0.0_wp )  qr_p(k,j,i) = 0.0_wp
                 ENDDO
@@ -1709,5 +1876,5 @@
                 DO  i = nxl, nxr
                    DO  j = nys, nyn
-                      DO  k = nzb_s_inner(j,i)+1, nzt
+                      DO  k = nzb+1, nzt
                          tqr_m(k,j,i) = tend(k,j,i)
                       ENDDO
@@ -1718,7 +1885,7 @@
                 DO  i = nxl, nxr
                    DO  j = nys, nyn
-                      DO  k = nzb_s_inner(j,i)+1, nzt
-                         tqr_m(k,j,i) = -9.5625_wp * tend(k,j,i) + 5.3125_wp * &
-                                                                   tqr_m(k,j,i)
+                      DO  k = nzb+1, nzt
+                         tqr_m(k,j,i) =   -9.5625_wp * tend(k,j,i)             &
+                                         + 5.3125_wp * tqr_m(k,j,i)
                       ENDDO
                    ENDDO
@@ -1760,5 +1927,14 @@
           ENDIF
 
-          CALL diffusion_s( nr, nrsws, nrswst, wall_nrflux )
+          CALL diffusion_s( nr,                                                &
+                            surf_def_h(0)%nrsws, surf_def_h(1)%nrsws,          &
+                            surf_def_h(2)%nrsws,                               &
+                            surf_lsm_h%nrsws,    surf_usm_h%nrsws,             & 
+                            surf_def_v(0)%nrsws, surf_def_v(1)%nrsws,          &
+                            surf_def_v(2)%nrsws, surf_def_v(3)%nrsws,          &
+                            surf_lsm_v(0)%nrsws, surf_lsm_v(1)%nrsws,          &
+                            surf_lsm_v(2)%nrsws, surf_lsm_v(3)%nrsws,          &
+                            surf_usm_v(0)%nrsws, surf_usm_v(1)%nrsws,          &
+                            surf_usm_v(2)%nrsws, surf_usm_v(3)%nrsws )
 
 !
@@ -1766,8 +1942,13 @@
           DO  i = nxl, nxr
              DO  j = nys, nyn
-                DO  k = nzb_s_inner(j,i)+1, nzt
-                   nr_p(k,j,i) = nr(k,j,i) + dt_3d * ( sbt * tend(k,j,i) +     &
-                                                     tsc(3) * tnr_m(k,j,i) )   &
-                                           - tsc(5) * rdf_sc(k) * nr(k,j,i)
+                DO  k = nzb+1, nzt
+                   nr_p(k,j,i) = nr(k,j,i) + ( dt_3d * ( sbt * tend(k,j,i) +   &
+                                                      tsc(3) * tnr_m(k,j,i) )  &
+                                                    - tsc(5) * rdf_sc(k) *     &
+                                                               nr(k,j,i)       &
+                                             )                                 &
+                                   * MERGE( 1.0_wp, 0.0_wp,                    &
+                                             BTEST( wall_flags_0(k,j,i), 0 )   &
+                                          )
                    IF ( nr_p(k,j,i) < 0.0_wp )  nr_p(k,j,i) = 0.0_wp
                 ENDDO
@@ -1781,5 +1962,5 @@
                 DO  i = nxl, nxr
                    DO  j = nys, nyn
-                      DO  k = nzb_s_inner(j,i)+1, nzt
+                      DO  k = nzb+1, nzt
                          tnr_m(k,j,i) = tend(k,j,i)
                       ENDDO
@@ -1790,7 +1971,7 @@
                 DO  i = nxl, nxr
                    DO  j = nys, nyn
-                      DO  k = nzb_s_inner(j,i)+1, nzt
-                         tnr_m(k,j,i) = -9.5625_wp * tend(k,j,i) + 5.3125_wp * &
-                                                                   tnr_m(k,j,i)
+                      DO  k = nzb+1, nzt
+                         tnr_m(k,j,i) =  -9.5625_wp * tend(k,j,i)             &
+                                         + 5.3125_wp * tnr_m(k,j,i)
                       ENDDO
                    ENDDO
@@ -1840,5 +2021,14 @@
        ENDIF
 
-       CALL diffusion_s( s, ssws, sswst, wall_sflux )
+       CALL diffusion_s( s,                                                    &
+                         surf_def_h(0)%ssws, surf_def_h(1)%ssws,               &
+                         surf_def_h(2)%ssws,                                   &
+                         surf_lsm_h%ssws,    surf_usm_h%ssws,                  &
+                         surf_def_v(0)%ssws, surf_def_v(1)%ssws,               &
+                         surf_def_v(2)%ssws, surf_def_v(3)%ssws,               &
+                         surf_lsm_v(0)%ssws, surf_lsm_v(1)%ssws,               &
+                         surf_lsm_v(2)%ssws, surf_lsm_v(3)%ssws,               &
+                         surf_usm_v(0)%ssws, surf_usm_v(1)%ssws,               &
+                         surf_usm_v(2)%ssws, surf_usm_v(3)%ssws )
 
 !
@@ -1871,9 +2061,13 @@
        DO  i = nxl, nxr
           DO  j = nys, nyn
-             DO  k = nzb_s_inner(j,i)+1, nzt
-                s_p(k,j,i) = s(k,j,i) + dt_3d * ( sbt * tend(k,j,i) +          &
-                                                  tsc(3) * ts_m(k,j,i) )       &
-                                      - tsc(5) * rdf_sc(k) *                   &
-                                        ( s(k,j,i) - s_init(k) )
+             DO  k = nzb+1, nzt
+                s_p(k,j,i) = s(k,j,i) + ( dt_3d * ( sbt * tend(k,j,i) +        &
+                                                 tsc(3) * ts_m(k,j,i) )        &
+                                               - tsc(5) * rdf_sc(k) *          &
+                                                    ( s(k,j,i) - s_init(k) )   &
+                                        )                                      &
+                                   * MERGE( 1.0_wp, 0.0_wp,                    &
+                                             BTEST( wall_flags_0(k,j,i), 0 )   &
+                                          )
                 IF ( s_p(k,j,i) < 0.0_wp )  s_p(k,j,i) = 0.1_wp * s(k,j,i)
              ENDDO
@@ -1887,5 +2081,5 @@
              DO  i = nxl, nxr
                 DO  j = nys, nyn
-                   DO  k = nzb_s_inner(j,i)+1, nzt
+                   DO  k = nzb+1, nzt
                       ts_m(k,j,i) = tend(k,j,i)
                    ENDDO
@@ -1896,6 +2090,7 @@
              DO  i = nxl, nxr
                 DO  j = nys, nyn
-                   DO  k = nzb_s_inner(j,i)+1, nzt
-                      ts_m(k,j,i) = -9.5625_wp * tend(k,j,i) + 5.3125_wp * ts_m(k,j,i)
+                   DO  k = nzb+1, nzt
+                      ts_m(k,j,i) =   -9.5625_wp * tend(k,j,i)                 &
+                                     + 5.3125_wp * ts_m(k,j,i)
                    ENDDO
                 ENDDO
@@ -1973,7 +2168,11 @@
        DO  i = nxl, nxr
           DO  j = nys, nyn
-             DO  k = nzb_s_inner(j,i)+1, nzt
-                e_p(k,j,i) = e(k,j,i) + dt_3d * ( sbt * tend(k,j,i) +          &
-                                                  tsc(3) * te_m(k,j,i) )
+             DO  k = nzb+1, nzt
+                e_p(k,j,i) = e(k,j,i) + ( dt_3d * ( sbt * tend(k,j,i) +        &
+                                                 tsc(3) * te_m(k,j,i) )        &
+                                        )                                      &
+                                   * MERGE( 1.0_wp, 0.0_wp,                    &
+                                             BTEST( wall_flags_0(k,j,i), 0 )   &
+                                          )
                 IF ( e_p(k,j,i) < 0.0_wp )  e_p(k,j,i) = 0.1_wp * e(k,j,i)
              ENDDO
@@ -1987,5 +2186,5 @@
              DO  i = nxl, nxr
                 DO  j = nys, nyn
-                   DO  k = nzb_s_inner(j,i)+1, nzt
+                   DO  k = nzb+1, nzt
                       te_m(k,j,i) = tend(k,j,i)
                    ENDDO
@@ -1996,6 +2195,7 @@
              DO  i = nxl, nxr
                 DO  j = nys, nyn
-                   DO  k = nzb_s_inner(j,i)+1, nzt
-                      te_m(k,j,i) = -9.5625_wp * tend(k,j,i) + 5.3125_wp * te_m(k,j,i)
+                   DO  k = nzb+1, nzt
+                      te_m(k,j,i) =   -9.5625_wp * tend(k,j,i)                 &
+                                     + 5.3125_wp * te_m(k,j,i)
                    ENDDO
                 ENDDO
Index: /palm/trunk/SOURCE/radiation_model_mod.f90
===================================================================
--- /palm/trunk/SOURCE/radiation_model_mod.f90	(revision 2231)
+++ /palm/trunk/SOURCE/radiation_model_mod.f90	(revision 2232)
@@ -20,5 +20,6 @@
 ! Current revisions:
 ! -----------------
-! 
+! Adjustments to new topography concept
+! Bugfix in read restart
 ! 
 ! Former revisions:
@@ -147,5 +148,6 @@
 
     USE indices,                                                               &
-        ONLY:  nxl, nxlg, nxr, nxrg, nyn, nyng, nys, nysg, nzb_s_inner, nzb, nzt
+        ONLY:  nxl, nxlg, nxr, nxrg, nyn, nyng, nys, nysg, nzb, nzt,           &
+               wall_flags_0
 
     USE kinds
@@ -1160,5 +1162,11 @@
        DO i = nxlg, nxrg
           DO j = nysg, nyng
-             k = nzb_s_inner(j,i)
+!
+!--          Obtain vertical index of topography top 
+             k = MAXLOC(                                                       &
+                        MERGE( 1, 0,                                           &
+                               BTEST( wall_flags_0(:,j,i), 12 )                &
+                             ), DIM = 1                                        &
+                       ) - 1
 
              exn1 = (hyp(k+1) / 100000.0_wp )**0.286_wp
@@ -1210,5 +1218,11 @@
        DO i = nxlg, nxrg
           DO j = nysg, nyng
-             k = nzb_s_inner(j,i)
+!
+!--          Obtain vertical index of topography top. So far it is identical to nzb.
+             k = MAXLOC(                                                       &
+                        MERGE( 1, 0,                                           &
+                               BTEST( wall_flags_0(:,j,i), 12 )                &
+                             ), DIM = 1                                        &
+                       ) - 1
 
              rad_net(j,i)      = net_radiation
Index: /palm/trunk/SOURCE/read_3d_binary.f90
===================================================================
--- /palm/trunk/SOURCE/read_3d_binary.f90	(revision 2231)
+++ /palm/trunk/SOURCE/read_3d_binary.f90	(revision 2232)
@@ -20,5 +20,6 @@
 ! Current revisions:
 ! -----------------
-! 
+! Adjustments to new surface concept - move output of surface varariables
+! to surface_mod
 ! 
 ! Former revisions:
@@ -120,15 +121,13 @@
 
     USE arrays_3d,                                                             &
-        ONLY:  e, kh, km, ol, p, pt, q, ql, qc, nr, nrs, nrsws, nrswst,        &
-               prr, precipitation_amount, qr,                                  &
-               qrs, qrsws, qrswst, qs, qsws, qswst, s, sa, saswsb, saswst,     &
-               ss, ssws, sswst, rif_wall, shf, ss, ts, tswst, u, u_m_l, u_m_n, &
-               u_m_r, u_m_s, us, usws, uswst, v, v_m_l, v_m_n, v_m_r, v_m_s,   &
-               vpt, vsws, vswst, w, w_m_l, w_m_n, w_m_r, w_m_s, z0, z0h, z0q
+        ONLY:  e, kh, km, p, pt, q, ql, qc, nr, prr, precipitation_amount, qr, &
+               s, sa, u, u_m_l, u_m_n, u_m_r, u_m_s, v, v_m_l, v_m_n, v_m_r,   &
+               v_m_s, vpt, w, w_m_l, w_m_n, w_m_r, w_m_s
 
     USE averaging
 
     USE control_parameters,                                                    &
-        ONLY:  iran, message_string, outflow_l, outflow_n, outflow_r, outflow_s
+        ONLY:  iran, land_surface, message_string, outflow_l, outflow_n,       &
+               outflow_r, outflow_s
 
     USE cpulog,                                                                &
@@ -142,5 +141,5 @@
 
     USE land_surface_model_mod,                                                &
-        ONLY:  land_surface, lsm_read_restart_data
+        ONLY:  lsm_read_restart_data
 
     USE particle_attributes,                                                   &
@@ -161,4 +160,6 @@
         ONLY:  spectrum_x, spectrum_y
 
+    USE surface_mod,                                                           &
+        ONLY :  surface_read_restart_data
 
     IMPLICIT NONE
@@ -436,4 +437,8 @@
              nync = nynfa(i,k) + offset_ya(i,k)
 
+             write(9,*) "f", nxlf, nxrf, nysf, nynf
+             write(9,*) "c", nxlc, nxrc, nysc, nync
+
+
 
              SELECT CASE ( TRIM( field_chr ) )
@@ -494,23 +499,4 @@
                    nr_av(:,nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp) = &
                                     tmp_3d(:,nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
-
-                CASE ( 'nrs' )
-                   IF ( k == 1 )  READ ( 13 )  tmp_2d
-                   nrs(nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp)  = &
-                                          tmp_2d(nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
-
-                CASE ( 'nrsws' )
-                   IF ( k == 1 )  READ ( 13 )  tmp_2d
-                   nrsws(nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp)  = &
-                                          tmp_2d(nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
-
-                CASE ( 'nrswst' )
-                   IF ( k == 1 )  READ ( 13 )  tmp_2d
-                   nrswst(nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp)  = &
-                                          tmp_2d(nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
-                CASE ( 'ol' )
-                   IF ( k == 1 )  READ ( 13 )  tmp_2d
-                   ol(nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp)  = &
-                                         tmp_2d(nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
 
                 CASE ( 'p' )
@@ -637,19 +623,4 @@
                                     tmp_3d(:,nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
 
-                CASE ( 'qrs' )
-                   IF ( k == 1 )  READ ( 13 )  tmp_2d
-                   qrs(nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp)  = &
-                                          tmp_2d(nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
-
-                CASE ( 'qrsws' )
-                   IF ( k == 1 )  READ ( 13 )  tmp_2d
-                   qrsws(nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp)  = &
-                                          tmp_2d(nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
-
-                CASE ( 'qrswst' )
-                   IF ( k == 1 )  READ ( 13 )  tmp_2d
-                   qrswst(nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp)  = &
-                                          tmp_2d(nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
-
                 CASE ( 'ql_c_av' )
                    IF ( .NOT. ALLOCATED( ql_c_av ) )  THEN
@@ -675,14 +646,4 @@
                    ql_vp_av(:,nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp) = &
                                         tmp_3d(:,nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
-
-                CASE ( 'qs' )
-                   IF ( k == 1 )  READ ( 13 )  tmp_2d
-                   qs(nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp)  = &
-                                          tmp_2d(nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
-
-                CASE ( 'qsws' )
-                   IF ( k == 1 )  READ ( 13 )  tmp_2d
-                   qsws(nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp)  = &
-                                          tmp_2d(nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
 
                 CASE ( 'qsws_av' )
@@ -694,9 +655,4 @@
                                           tmp_2d(nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
 
-                CASE ( 'qswst' )
-                   IF ( k == 1 )  READ ( 13 )  tmp_2d
-                   qswst(nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp)  = &
-                                          tmp_2d(nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
-
                 CASE ( 'qv_av' )
                    IF ( .NOT. ALLOCATED( qv_av ) )  THEN
@@ -722,14 +678,5 @@
                    rho_ocean_av(:,nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp) = &
                                 tmp_3d(:,nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
-
-                CASE ( 'rif_wall' )
-                   IF ( k == 1 )  THEN
-                      ALLOCATE( tmp_4d(nzb:nzt+1,nys_on_file-nbgp:nyn_on_file+nbgp, &
-                                       nxl_on_file-nbgp:nxr_on_file+nbgp,1:4) )
-                      READ ( 13 )  tmp_4d
-                   ENDIF
-                   rif_wall(:,nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp,:) = &
-                            tmp_4d(:,nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp,:)
-                            
+                           
                 CASE ( 's' )
                    IF ( k == 1 )  READ ( 13 )  tmp_3d
@@ -757,19 +704,4 @@
                    sa_av(:,nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp) = &
                                     tmp_3d(:,nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
-
-                CASE ( 'saswsb' )
-                   IF ( k == 1 )  READ ( 13 )  tmp_2d
-                   saswsb(nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp)  = &
-                         tmp_2d(nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
-
-                CASE ( 'saswst' )
-                   IF ( k == 1 )  READ ( 13 )  tmp_2d
-                   saswst(nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp)  = &
-                         tmp_2d(nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
-
-                CASE ( 'shf' )
-                   IF ( k == 1 )  READ ( 13 )  tmp_2d
-                   shf(nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp)  = &
-                      tmp_2d(nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
 
                 CASE ( 'shf_av' )
@@ -811,14 +743,4 @@
                    ENDIF
                    
-                CASE ( 'ss' )
-                   IF ( k == 1 )  READ ( 13 )  tmp_2d
-                   ss(nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp)  = &
-                                          tmp_2d(nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
-
-                CASE ( 'ssws' )
-                   IF ( k == 1 )  READ ( 13 )  tmp_2d
-                   ssws(nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp)  = &
-                                          tmp_2d(nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
-
                 CASE ( 'ssws_av' )
                    IF ( .NOT. ALLOCATED( ssws_av ) )  THEN
@@ -828,15 +750,5 @@
                    ssws_av(nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp)  = &
                                           tmp_2d(nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
-
-                CASE ( 'sswst' )
-                   IF ( k == 1 )  READ ( 13 )  tmp_2d
-                   sswst(nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp)  = &
-                                          tmp_2d(nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp) 
                  
-                CASE ( 'ts' )
-                   IF ( k == 1 )  READ ( 13 )  tmp_2d
-                   ts(nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp)  = &
-                     tmp_2d(nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
-
                 CASE ( 'ts_av' )
                    IF ( .NOT. ALLOCATED( ts_av ) )  THEN
@@ -847,9 +759,4 @@
                         tmp_2d(nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
 
-                CASE ( 'tswst' )
-                   IF ( k == 1 )  READ ( 13 )  tmp_2d
-                   tswst(nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp)  = &
-                         tmp_2d(nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
-
                 CASE ( 'u' )
                    IF ( k == 1 )  READ ( 13 )  tmp_3d
@@ -905,19 +812,4 @@
                    ENDIF
 
-                CASE ( 'us' )
-                   IF ( k == 1 )  READ ( 13 )  tmp_2d
-                   us(nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp)  = &
-                     tmp_2d(nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
-
-                CASE ( 'usws' )
-                   IF ( k == 1 )  READ ( 13 )  tmp_2d
-                   usws(nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp)  = &
-                       tmp_2d(nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
-
-                CASE ( 'uswst' )
-                   IF ( k == 1 )  READ ( 13 )  tmp_2d
-                   uswst(nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp)  = &
-                        tmp_2d(nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
-
                 CASE ( 'us_av' )
                    IF ( .NOT. ALLOCATED( us_av ) )  THEN
@@ -994,14 +886,4 @@
                                tmp_3d(:,nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
 
-                CASE ( 'vsws' )
-                   IF ( k == 1 )  READ ( 13 )  tmp_2d
-                   vsws(nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp)  = &
-                       tmp_2d(nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
-
-                CASE ( 'vswst' )
-                   IF ( k == 1 )  READ ( 13 )  tmp_2d
-                   vswst(nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp)  = &
-                        tmp_2d(nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
-
                 CASE ( 'w' )
                    IF ( k == 1 )  READ ( 13 )  tmp_3d
@@ -1058,9 +940,4 @@
                    DEALLOCATE( tmp_3dwws )
 
-                CASE ( 'z0' )
-                   IF ( k == 1 )  READ ( 13 )  tmp_2d
-                   z0(nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp)  = &
-                     tmp_2d(nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
-
                 CASE ( 'z0_av' )
                    IF ( .NOT. ALLOCATED( z0_av ) )  THEN
@@ -1071,9 +948,4 @@
                        tmp_2d(nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
 
-                CASE ( 'z0h' )
-                   IF ( k == 1 )  READ ( 13 )  tmp_2d
-                   z0h(nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp)  = &
-                     tmp_2d(nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
-
                 CASE ( 'z0h_av' )
                    IF ( .NOT. ALLOCATED( z0h_av ) )  THEN
@@ -1083,9 +955,4 @@
                    z0h_av(nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp)  = &
                        tmp_2d(nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
-
-                CASE ( 'z0q' )
-                   IF ( k == 1 )  READ ( 13 )  tmp_2d
-                   z0q(nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp)  = &
-                     tmp_2d(nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
 
                 CASE ( 'z0q_av' )
@@ -1128,4 +995,10 @@
 
        ENDDO  ! loop over variables
+!
+!--    Read surface related variables
+       CALL surface_read_restart_data( i, nxlfa, nxl_on_file, nxrfa,           &
+                                       nxr_on_file, nynfa, nyn_on_file, nysfa, &
+                                       nys_on_file, offset_xa, offset_ya,      &
+                                       overlap_count(i) )
 
 !
Index: /palm/trunk/SOURCE/read_var_list.f90
===================================================================
--- /palm/trunk/SOURCE/read_var_list.f90	(revision 2231)
+++ /palm/trunk/SOURCE/read_var_list.f90	(revision 2232)
@@ -20,6 +20,9 @@
 ! Current revisions:
 ! ------------------
-! 
-! 
+! Replace wall_qflux, wall_sflux by wall_humidityflux and wall_scalarflux; add
+! wall_salinityflux
+! +tunnel_height, tunnel_length, tunnel_width_x, tunnel_width_y, 
+!  tunnel_wall_depth
+!
 ! Former revisions:
 ! -----------------
@@ -705,4 +708,14 @@
           CASE ( 'collision_turbulence' )
              READ ( 13 )  collision_turbulence
+          CASE ( 'tunnel_height' )
+             READ ( 13 )  tunnel_height
+          CASE ( 'tunnel_length' )
+             READ ( 13 )  tunnel_length
+          CASE ( 'tunnel_width_x' )
+             READ ( 13 )  tunnel_width_x
+          CASE ( 'tunnel_width_y' )
+             READ ( 13 )  tunnel_width_y
+          CASE ( 'tunnel_wall_depth' )
+             READ ( 13 )  tunnel_wall_depth
           CASE ( 'turbulent_inflow' )
              READ ( 13 )  turbulent_inflow
@@ -769,8 +782,10 @@
           CASE ( 'wall_heatflux' )
              READ ( 13 )  wall_heatflux
-          CASE ( 'wall_qflux' )
-             READ ( 13 )  wall_qflux
-          CASE ( 'wall_sflux' )
-             READ ( 13 )  wall_sflux
+          CASE ( 'wall_humidityflux' )
+             READ ( 13 )  wall_humidityflux
+          CASE ( 'wall_scalarflux' )
+             READ ( 13 )  wall_scalarflux
+          CASE ( 'wall_salinityflux' )
+             READ ( 13 )  wall_salinityflux
           CASE ( 'w_max' )
              READ ( 13 )  w_max
@@ -851,4 +866,5 @@
 
     READ ( 13 )  version_on_file
+
 
 !
@@ -932,5 +948,4 @@
     ENDIF
 
-
 !
 !-- Now read and check some control parameters and skip the rest
Index: /palm/trunk/SOURCE/subsidence_mod.f90
===================================================================
--- /palm/trunk/SOURCE/subsidence_mod.f90	(revision 2231)
+++ /palm/trunk/SOURCE/subsidence_mod.f90	(revision 2232)
@@ -20,5 +20,5 @@
 ! Current revisions:
 ! -----------------
-! 
+! Adjustments to new topography and surface concept
 ! 
 ! Former revisions:
@@ -195,6 +195,6 @@
 
        USE indices,                                                            &
-           ONLY:  nxl, nxlg, nxr, nxrg, nyn, nyng, nys, nysg, nzb, nzb_s_inner,&
-                  nzt
+           ONLY:  nxl, nxlg, nxr, nxrg, nyn, nyng, nys, nysg, nzb, nzt,        &
+                  wall_flags_0
 
        USE kinds
@@ -225,11 +225,15 @@
           DO  j = nys, nyn
 
-             DO  k = nzb_s_inner(j,i)+1, nzt 
+             DO  k = nzb+1, nzt 
                 IF ( w_subs(k) < 0.0_wp )  THEN    ! large-scale subsidence
                    tmp_tend = - w_subs(k) *                                    &
-                              ( var(k+1,j,i) - var(k,j,i) ) * ddzu(k+1)
+                              ( var(k+1,j,i) - var(k,j,i) ) * ddzu(k+1) *      &
+                                        MERGE( 1.0_wp, 0.0_wp,                 &
+                                               BTEST( wall_flags_0(k,j,i), 0 ) )
                 ELSE                               ! large-scale ascent
                    tmp_tend = - w_subs(k) *                                    &
-                              ( var(k,j,i) - var(k-1,j,i) ) * ddzu(k)
+                              ( var(k,j,i) - var(k-1,j,i) ) * ddzu(k) *        &
+                                        MERGE( 1.0_wp, 0.0_wp,                 &
+                                               BTEST( wall_flags_0(k,j,i), 0 ) )
                 ENDIF
 
@@ -238,5 +242,7 @@
                 IF ( large_scale_forcing )  THEN
                    sums_ls_l(k,ls_index) = sums_ls_l(k,ls_index) + tmp_tend    &
-                                   * weight_substep(intermediate_timestep_count)
+                                 * weight_substep(intermediate_timestep_count) &
+                                 * MERGE( 1.0_wp, 0.0_wp,                      &
+                                          BTEST( wall_flags_0(k,j,i), 0 ) )
                 ENDIF
              ENDDO
@@ -304,5 +310,5 @@
 
        USE indices,                                                            &
-           ONLY:  nxl, nxlg, nxrg, nyng, nys, nysg, nzb_s_inner, nzb, nzt
+           ONLY:  nxl, nxlg, nxrg, nyng, nys, nysg, nzb, nzt, wall_flags_0
 
        USE kinds
@@ -330,9 +336,14 @@
 !
 !--    Influence of w_subsidence on the current tendency term
-       DO  k = nzb_s_inner(j,i)+1, nzt 
+       DO  k = nzb+1, nzt 
           IF ( w_subs(k) < 0.0_wp )  THEN      ! large-scale subsidence
-             tmp_tend = - w_subs(k) * ( var(k+1,j,i) - var(k,j,i) ) * ddzu(k+1)
+             tmp_tend = - w_subs(k) * ( var(k+1,j,i) - var(k,j,i) )            &
+                                    * ddzu(k+1)                                &
+                                    * MERGE( 1.0_wp, 0.0_wp,                   &
+                                             BTEST( wall_flags_0(k,j,i), 0 ) )
           ELSE                                 ! large-scale ascent
-             tmp_tend = - w_subs(k) * ( var(k,j,i) - var(k-1,j,i) ) * ddzu(k)
+             tmp_tend = - w_subs(k) * ( var(k,j,i) - var(k-1,j,i) ) * ddzu(k)  &
+                                    * MERGE( 1.0_wp, 0.0_wp,                   &
+                                             BTEST( wall_flags_0(k,j,i), 0 ) )
           ENDIF
 
@@ -341,5 +352,7 @@
           IF ( large_scale_forcing )  THEN
              sums_ls_l(k,ls_index) = sums_ls_l(k,ls_index) + tmp_tend          &
-                                   * weight_substep(intermediate_timestep_count)
+                                  * weight_substep(intermediate_timestep_count)&
+                                  * MERGE( 1.0_wp, 0.0_wp,                     &
+                                           BTEST( wall_flags_0(k,j,i), 0 ) )
           ENDIF
        ENDDO
Index: /palm/trunk/SOURCE/sum_up_3d_data.f90
===================================================================
--- /palm/trunk/SOURCE/sum_up_3d_data.f90	(revision 2231)
+++ /palm/trunk/SOURCE/sum_up_3d_data.f90	(revision 2232)
@@ -20,5 +20,5 @@
 ! Current revisions:
 ! -----------------
-! 
+! Adjustments to new surface concept
 ! 
 ! Former revisions:
@@ -132,7 +132,6 @@
 
     USE arrays_3d,                                                             &
-        ONLY:  dzw, e, nr, ol, p, pt, precipitation_rate, q, qc, ql, ql_c,     &
-               ql_v, qr, qsws, rho_ocean, s, sa, shf, ssws, ts, u, us, v, vpt, w, z0,&
-               z0h, z0q
+        ONLY:  dzw, e, nr, p, pt, precipitation_rate, q, qc, ql, ql_c, ql_v,   &
+               qr, rho_ocean, s, sa, u, v, vpt, w
 
     USE averaging,                                                             &
@@ -147,6 +146,6 @@
 
     USE control_parameters,                                                    &
-        ONLY:  average_count_3d, cloud_physics, doav, doav_n, rho_surface,     &
-               urban_surface, varnamelength
+        ONLY:  average_count_3d, cloud_physics, doav, doav_n, land_surface,    &
+               rho_surface, urban_surface, varnamelength
 
     USE cpulog,                                                                &
@@ -159,5 +158,5 @@
 
     USE land_surface_model_mod,                                                &
-        ONLY:  land_surface, lsm_3d_data_averaging
+        ONLY:  lsm_3d_data_averaging
 
     USE particle_attributes,                                                   &
@@ -167,4 +166,7 @@
         ONLY:  radiation, radiation_3d_data_averaging
 
+    USE surface_mod,                                                           &
+        ONLY:  surf_def_h, surf_lsm_h, surf_usm_h
+
     USE urban_surface_mod,                                                     &
         ONLY:  usm_average_3d_data
@@ -173,8 +175,9 @@
     IMPLICIT NONE
 
-    INTEGER(iwp) ::  i   !< running index
+    INTEGER(iwp) ::  i   !< grid index x direction
     INTEGER(iwp) ::  ii  !< running index
-    INTEGER(iwp) ::  j   !< running index
-    INTEGER(iwp) ::  k   !< running index
+    INTEGER(iwp) ::  j   !< grid index y direction
+    INTEGER(iwp) ::  k   !< grid index x direction
+    INTEGER(iwp) ::  m   !< running index surface type
     INTEGER(iwp) ::  n   !< 
 
@@ -490,8 +493,18 @@
 
           CASE ( 'ol*' )
-             DO  i = nxlg, nxrg
-                DO  j = nysg, nyng
-                   ol_av(j,i) = ol_av(j,i) + ol(j,i)
-                ENDDO
+             DO  m = 1, surf_def_h(0)%ns
+                i = surf_def_h(0)%i(m)
+                j = surf_def_h(0)%j(m)
+                ol_av(j,i) = ol_av(j,i) + surf_def_h(0)%ol(m)
+             ENDDO
+             DO  m = 1, surf_lsm_h%ns
+                i = surf_lsm_h%i(m)
+                j = surf_lsm_h%j(m)
+                ol_av(j,i) = ol_av(j,i) + surf_lsm_h%ol(m)
+             ENDDO
+             DO  m = 1, surf_usm_h%ns
+                i = surf_usm_h%i(m)
+                j = surf_usm_h%j(m)
+                ol_av(j,i) = ol_av(j,i) + surf_usm_h%ol(m)
              ENDDO
 
@@ -645,8 +658,18 @@
 
           CASE ( 'qsws*' )
-             DO  i = nxlg, nxrg
-                DO  j = nysg, nyng
-                   qsws_av(j,i) = qsws_av(j,i) + qsws(j,i)
-                ENDDO
+             DO  m = 1, surf_def_h(0)%ns
+                i = surf_def_h(0)%i(m)
+                j = surf_def_h(0)%j(m)
+                qsws_av(j,i) = qsws_av(j,i) + surf_def_h(0)%qsws(m)
+             ENDDO
+             DO  m = 1, surf_lsm_h%ns
+                i = surf_lsm_h%i(m)
+                j = surf_lsm_h%j(m)
+                qsws_av(j,i) = qsws_av(j,i) + surf_lsm_h%qsws(m)
+             ENDDO
+             DO  m = 1, surf_usm_h%ns
+                i = surf_usm_h%i(m)
+                j = surf_usm_h%j(m)
+                qsws_av(j,i) = qsws_av(j,i) + surf_usm_h%qsws(m)
              ENDDO
 
@@ -688,22 +711,53 @@
 
           CASE ( 'shf*' )
-             DO  i = nxlg, nxrg
-                DO  j = nysg, nyng
-                   shf_av(j,i) = shf_av(j,i) + shf(j,i)
-                ENDDO
-             ENDDO
+             DO  m = 1, surf_def_h(0)%ns
+                i = surf_def_h(0)%i(m)
+                j = surf_def_h(0)%j(m)
+                shf_av(j,i) = shf_av(j,i) + surf_def_h(0)%shf(m)
+             ENDDO
+             DO  m = 1, surf_lsm_h%ns
+                i = surf_lsm_h%i(m)
+                j = surf_lsm_h%j(m)
+                shf_av(j,i) = shf_av(j,i) + surf_lsm_h%shf(m)
+             ENDDO
+             DO  m = 1, surf_usm_h%ns
+                i = surf_usm_h%i(m)
+                j = surf_usm_h%j(m)
+                shf_av(j,i) = shf_av(j,i) + surf_usm_h%shf(m)
+             ENDDO
+
 
           CASE ( 'ssws*' )
-             DO  i = nxlg, nxrg
-                DO  j = nysg, nyng
-                   ssws_av(j,i) = ssws_av(j,i) + ssws(j,i)
-                ENDDO
+             DO  m = 1, surf_def_h(0)%ns
+                i = surf_def_h(0)%i(m)
+                j = surf_def_h(0)%j(m)
+                ssws_av(j,i) = ssws_av(j,i) + surf_def_h(0)%ssws(m)
+             ENDDO
+             DO  m = 1, surf_lsm_h%ns
+                i = surf_lsm_h%i(m)
+                j = surf_lsm_h%j(m)
+                ssws_av(j,i) = ssws_av(j,i) + surf_lsm_h%ssws(m)
+             ENDDO
+             DO  m = 1, surf_usm_h%ns
+                i = surf_usm_h%i(m)
+                j = surf_usm_h%j(m)
+                ssws_av(j,i) = ssws_av(j,i) + surf_usm_h%ssws(m)
              ENDDO
 
           CASE ( 't*' )
-             DO  i = nxlg, nxrg
-                DO  j = nysg, nyng
-                   ts_av(j,i) = ts_av(j,i) + ts(j,i)
-                ENDDO
+             DO  m = 1, surf_def_h(0)%ns
+                i = surf_def_h(0)%i(m)
+                j = surf_def_h(0)%j(m)
+                ts_av(j,i) = ts_av(j,i) + surf_def_h(0)%ts(m)
+             ENDDO
+             DO  m = 1, surf_lsm_h%ns
+                i = surf_lsm_h%i(m)
+                j = surf_lsm_h%j(m)
+                ts_av(j,i) = ts_av(j,i) + surf_lsm_h%ts(m)
+             ENDDO
+             DO  m = 1, surf_usm_h%ns
+                i = surf_usm_h%i(m)
+                j = surf_usm_h%j(m)
+                ts_av(j,i) = ts_av(j,i) + surf_usm_h%ts(m)
              ENDDO
 
@@ -718,8 +772,18 @@
 
           CASE ( 'u*' )
-             DO  i = nxlg, nxrg
-                DO  j = nysg, nyng
-                   us_av(j,i) = us_av(j,i) + us(j,i)
-                ENDDO
+             DO  m = 1, surf_def_h(0)%ns
+                i = surf_def_h(0)%i(m)
+                j = surf_def_h(0)%j(m)
+                us_av(j,i) = us_av(j,i) + surf_def_h(0)%us(m)
+             ENDDO
+             DO  m = 1, surf_lsm_h%ns
+                i = surf_lsm_h%i(m)
+                j = surf_lsm_h%j(m)
+                us_av(j,i) = us_av(j,i) + surf_lsm_h%us(m)
+             ENDDO
+             DO  m = 1, surf_usm_h%ns
+                i = surf_usm_h%i(m)
+                j = surf_usm_h%j(m)
+                us_av(j,i) = us_av(j,i) + surf_usm_h%us(m)
              ENDDO
 
@@ -752,22 +816,52 @@
 
           CASE ( 'z0*' )
-             DO  i = nxlg, nxrg
-                DO  j = nysg, nyng
-                   z0_av(j,i) = z0_av(j,i) + z0(j,i)
-                ENDDO
+             DO  m = 1, surf_def_h(0)%ns
+                i = surf_def_h(0)%i(m)
+                j = surf_def_h(0)%j(m)
+                z0_av(j,i) = z0_av(j,i) + surf_def_h(0)%z0(m)
+             ENDDO
+             DO  m = 1, surf_lsm_h%ns
+                i = surf_lsm_h%i(m)
+                j = surf_lsm_h%j(m)
+                z0_av(j,i) = z0_av(j,i) + surf_lsm_h%z0(m)
+             ENDDO
+             DO  m = 1, surf_usm_h%ns
+                i = surf_usm_h%i(m)
+                j = surf_usm_h%j(m)
+                z0_av(j,i) = z0_av(j,i) + surf_usm_h%z0(m)
              ENDDO
 
           CASE ( 'z0h*' )
-             DO  i = nxlg, nxrg
-                DO  j = nysg, nyng
-                   z0h_av(j,i) = z0h_av(j,i) + z0h(j,i)
-                ENDDO
+             DO  m = 1, surf_def_h(0)%ns
+                i = surf_def_h(0)%i(m)
+                j = surf_def_h(0)%j(m)
+                z0h_av(j,i) = z0h_av(j,i) + surf_def_h(0)%z0h(m)
+             ENDDO
+             DO  m = 1, surf_lsm_h%ns
+                i = surf_lsm_h%i(m)
+                j = surf_lsm_h%j(m)
+                z0h_av(j,i) = z0h_av(j,i) + surf_lsm_h%z0h(m)
+             ENDDO
+             DO  m = 1, surf_usm_h%ns
+                i = surf_usm_h%i(m)
+                j = surf_usm_h%j(m)
+                z0h_av(j,i) = z0h_av(j,i) + surf_usm_h%z0h(m)
              ENDDO
 
           CASE ( 'z0q*' )
-             DO  i = nxlg, nxrg
-                DO  j = nysg, nyng
-                   z0q_av(j,i) = z0q_av(j,i) + z0q(j,i)
-                ENDDO
+             DO  m = 1, surf_def_h(0)%ns
+                i = surf_def_h(0)%i(m)
+                j = surf_def_h(0)%j(m)
+                z0q_av(j,i) = z0q_av(j,i) + surf_def_h(0)%z0q(m)
+             ENDDO
+             DO  m = 1, surf_lsm_h%ns
+                i = surf_lsm_h%i(m)
+                j = surf_lsm_h%j(m)
+                z0q_av(j,i) = z0q_av(j,i) + surf_lsm_h%z0q(m)
+             ENDDO
+             DO  m = 1, surf_usm_h%ns
+                i = surf_usm_h%i(m)
+                j = surf_usm_h%j(m)
+                z0q_av(j,i) = z0q_av(j,i) + surf_usm_h%z0q(m)
              ENDDO
 !             
Index: /palm/trunk/SOURCE/surface_coupler.f90
===================================================================
--- /palm/trunk/SOURCE/surface_coupler.f90	(revision 2231)
+++ /palm/trunk/SOURCE/surface_coupler.f90	(revision 2232)
@@ -20,5 +20,6 @@
 ! Current revisions:
 ! ------------------
-! 
+! Adjust to new surface structure. Transfer 1D surface fluxes onto 2D grid 
+! (and back). 
 ! 
 ! Former revisions:
@@ -83,6 +84,5 @@
 
     USE arrays_3d,                                                             &
-        ONLY:  pt, shf, qsws, qswst_remote, rho_ocean, sa, saswst, total_2d_a,       &
-               total_2d_o, tswst, u, usws, uswst, v, vsws, vswst
+        ONLY:  pt, rho_ocean, sa, total_2d_a, total_2d_o, u, v
 
     USE cloud_parameters,                                                      &
@@ -91,6 +91,7 @@
     USE control_parameters,                                                    &
         ONLY:  coupling_mode, coupling_mode_remote, coupling_topology,         &
-               humidity, humidity_remote, message_string, terminate_coupled,   &
-               terminate_coupled_remote, time_since_reference_point
+               humidity, humidity_remote, land_surface, message_string,        &
+               terminate_coupled, terminate_coupled_remote,                    &
+               time_since_reference_point, urban_surface
 
     USE cpulog,                                                                &
@@ -105,10 +106,19 @@
     USE pegrid
 
+    USE surface_mod,                                                           &
+        ONLY :  surf_def_h, surf_lsm_h, surf_type, surf_usm_h
+
     IMPLICIT NONE
 
+    INTEGER(iwp) ::  i                                    !< index variable x-direction 
+    INTEGER(iwp) ::  j                                    !< index variable y-direction 
+    INTEGER(iwp) ::  m                                    !< running index for surface elements
+
+    REAL(wp)    ::  cpw = 4218.0_wp                       !< heat capacity of water at constant pressure
     REAL(wp)    ::  time_since_reference_point_rem        !< 
     REAL(wp)    ::  total_2d(-nbgp:ny+nbgp,-nbgp:nx+nbgp) !< 
 
-    REAL(wp)    ::  cpw = 4218.0_wp !< heat capacity of water at constant pressure
+    REAL(wp), DIMENSION(nysg:nyng,nxlg:nxrg) ::  surface_flux !< dummy array for surface fluxes on 2D grid
+
 
 #if defined( __parallel )
@@ -164,5 +174,5 @@
 !
 !-- Exchange the current simulated time between the models,
-!-- currently just for total_2ding
+!-- currently just for total_2d
     IF ( coupling_topology == 0 ) THEN
    
@@ -197,32 +207,44 @@
 
 !
-!--       Send heat flux at bottom surface to the ocean
-          CALL MPI_SEND( shf(nysg,nxlg), ngp_xy, MPI_REAL, target_id, 12, &
-                         comm_inter, ierr )
-!
-!--       Send humidity flux at bottom surface to the ocean
+!--       Send heat flux at bottom surface to the ocean. First, transfer from 
+!--       1D surface type to 2D grid.
+          CALL transfer_1D_to_2D_equal( surf_def_h(0)%shf, surf_lsm_h%shf,     &
+                                        surf_usm_h%shf )
+          CALL MPI_SEND( surface_flux(nysg,nxlg), ngp_xy, MPI_REAL, target_id, &
+                         12, comm_inter, ierr )
+!
+!--       Send humidity flux at bottom surface to the ocean. First, transfer
+!--       from 1D surface type to 2D grid.
+          CALL transfer_1D_to_2D_equal( surf_def_h(0)%qsws, surf_lsm_h%qsws,   &
+                                        surf_usm_h%qsws )
           IF ( humidity )  THEN
-             CALL MPI_SEND( qsws(nysg,nxlg), ngp_xy, MPI_REAL, target_id, 13, &
-                            comm_inter, ierr )
+             CALL MPI_SEND( surface_flux(nysg,nxlg), ngp_xy, MPI_REAL,         &
+                            target_id, 13, comm_inter, ierr )
           ENDIF
 !
 !--       Receive temperature at the bottom surface from the ocean
-          CALL MPI_RECV( pt(0,nysg,nxlg), 1, type_xy, target_id, 14, &
+          CALL MPI_RECV( pt(0,nysg,nxlg), 1, type_xy, target_id, 14,           &
                          comm_inter, status, ierr )
 !
-!--       Send the momentum flux (u) at bottom surface to the ocean
-          CALL MPI_SEND( usws(nysg,nxlg), ngp_xy, MPI_REAL, target_id, 15, &
-                         comm_inter, ierr )
-!
-!--       Send the momentum flux (v) at bottom surface to the ocean
-          CALL MPI_SEND( vsws(nysg,nxlg), ngp_xy, MPI_REAL, target_id, 16, &
-                         comm_inter, ierr )
+!--       Send the momentum flux (u) at bottom surface to the ocean. First, 
+!--       transfer from 1D surface type to 2D grid.
+          CALL transfer_1D_to_2D_equal( surf_def_h(0)%usws, surf_lsm_h%usws,   &
+                                        surf_usm_h%usws )
+          CALL MPI_SEND( surface_flux(nysg,nxlg), ngp_xy, MPI_REAL, target_id, &
+                         15, comm_inter, ierr )
+!
+!--       Send the momentum flux (v) at bottom surface to the ocean. First, 
+!--       transfer from 1D surface type to 2D grid.
+          CALL transfer_1D_to_2D_equal( surf_def_h(0)%vsws, surf_lsm_h%vsws,   &
+                                        surf_usm_h%vsws )
+          CALL MPI_SEND( surface_flux(nysg,nxlg), ngp_xy, MPI_REAL, target_id, &
+                         16, comm_inter, ierr )
 !
 !--       Receive u at the bottom surface from the ocean
-          CALL MPI_RECV( u(0,nysg,nxlg), 1, type_xy, target_id, 17, &
+          CALL MPI_RECV( u(0,nysg,nxlg), 1, type_xy, target_id, 17,            &
                          comm_inter, status, ierr )
 !
 !--       Receive v at the bottom surface from the ocean
-          CALL MPI_RECV( v(0,nysg,nxlg), 1, type_xy, target_id, 18, &
+          CALL MPI_RECV( v(0,nysg,nxlg), 1, type_xy, target_id, 18,            &
                          comm_inter, status, ierr )
 !
@@ -235,7 +257,10 @@
           total_2d_a = 0.0_wp
           total_2d   = 0.0_wp
-          total_2d(nys:nyn,nxl:nxr) = shf(nys:nyn,nxl:nxr)
-
-          CALL MPI_REDUCE( total_2d, total_2d_a, ngp_a, MPI_REAL, MPI_SUM, 0, &
+!
+!--       Transfer from 1D surface type to 2D grid.
+          CALL transfer_1D_to_2D_unequal( surf_def_h(0)%shf, surf_lsm_h%shf,   &
+                                          surf_usm_h%shf )
+
+          CALL MPI_REDUCE( total_2d, total_2d_a, ngp_a, MPI_REAL, MPI_SUM, 0,  &
                            comm2d, ierr )
           CALL interpolate_to_ocean( 12 )   
@@ -245,5 +270,9 @@
              total_2d_a = 0.0_wp
              total_2d   = 0.0_wp
-             total_2d(nys:nyn,nxl:nxr) = qsws(nys:nyn,nxl:nxr)
+!
+!--          Transfer from 1D surface type to 2D grid.
+             CALL transfer_1D_to_2D_unequal( surf_def_h(0)%qsws,              &
+                                             surf_lsm_h%qsws,                 &
+                                             surf_usm_h%qsws )
 
              CALL MPI_REDUCE( total_2d, total_2d_a, ngp_a, MPI_REAL, MPI_SUM, &
@@ -254,5 +283,5 @@
 !--       Receive temperature at the bottom surface from the ocean
           IF ( myid == 0 )  THEN
-             CALL MPI_RECV( total_2d_a(-nbgp,-nbgp), ngp_a, MPI_REAL, &
+             CALL MPI_RECV( total_2d_a(-nbgp,-nbgp), ngp_a, MPI_REAL,          &
                             target_id, 14, comm_inter, status, ierr )   
           ENDIF
@@ -265,5 +294,8 @@
           total_2d_a = 0.0_wp 
           total_2d   = 0.0_wp
-          total_2d(nys:nyn,nxl:nxr) = usws(nys:nyn,nxl:nxr)
+!
+!--       Transfer from 1D surface type to 2D grid.
+          CALL transfer_1D_to_2D_unequal( surf_def_h(0)%usws, surf_lsm_h%usws, &
+                                          surf_usm_h%usws )
           CALL MPI_REDUCE( total_2d, total_2d_a, ngp_a, MPI_REAL, MPI_SUM, 0, &
                            comm2d, ierr )
@@ -273,5 +305,8 @@
           total_2d_a = 0.0_wp
           total_2d   = 0.0_wp
-          total_2d(nys:nyn,nxl:nxr) = vsws(nys:nyn,nxl:nxr)
+!
+!--       Transfer from 1D surface type to 2D grid.
+          CALL transfer_1D_to_2D_unequal( surf_def_h(0)%usws, surf_lsm_h%usws, &
+                                          surf_usm_h%usws )
           CALL MPI_REDUCE( total_2d, total_2d_a, ngp_a, MPI_REAL, MPI_SUM, 0, &
                            comm2d, ierr )
@@ -308,12 +343,14 @@
 !
 !--       Receive heat flux at the sea surface (top) from the atmosphere
-          CALL MPI_RECV( tswst(nysg,nxlg), ngp_xy, MPI_REAL, target_id, 12, &
+          CALL MPI_RECV( surface_flux(nysg,nxlg), ngp_xy, MPI_REAL, target_id, 12, &
                          comm_inter, status, ierr )
+          CALL transfer_2D_to_1D_equal( surf_def_h(2)%shf )
 !
 !--       Receive humidity flux from the atmosphere (bottom)
 !--       and add it to the heat flux at the sea surface (top)...
           IF ( humidity_remote )  THEN
-             CALL MPI_RECV( qswst_remote(nysg,nxlg), ngp_xy, MPI_REAL, &
+             CALL MPI_RECV( surface_flux(nysg,nxlg), ngp_xy, MPI_REAL, &
                             target_id, 13, comm_inter, status, ierr )
+             CALL transfer_2D_to_1D_equal( surf_def_h(2)%qsws )
           ENDIF
 !
@@ -323,10 +360,12 @@
 !
 !--       Receive momentum flux (u) at the sea surface (top) from the atmosphere
-          CALL MPI_RECV( uswst(nysg,nxlg), ngp_xy, MPI_REAL, target_id, 15, &
+          CALL MPI_RECV( surface_flux(nysg,nxlg), ngp_xy, MPI_REAL, target_id, 15, &
                          comm_inter, status, ierr )
+          CALL transfer_2D_to_1D_equal( surf_def_h(2)%usws )
 !
 !--       Receive momentum flux (v) at the sea surface (top) from the atmosphere
-          CALL MPI_RECV( vswst(nysg,nxlg), ngp_xy, MPI_REAL, target_id, 16, &
+          CALL MPI_RECV( surface_flux(nysg,nxlg), ngp_xy, MPI_REAL, target_id, 16, &
                          comm_inter, status, ierr )
+          CALL transfer_2D_to_1D_equal( surf_def_h(2)%vsws )
 !
 !--       Send u to the atmosphere
@@ -350,5 +389,5 @@
           CALL MPI_BCAST( total_2d_o(-nbgp,-nbgp), ngp_o, MPI_REAL, 0, comm2d, &
                           ierr )
-          tswst(nysg:nyng,nxlg:nxrg) = total_2d_o(nysg:nyng,nxlg:nxrg)
+          CALL transfer_2D_to_1D_unequal( surf_def_h(2)%shf )
 !
 !--       Receive humidity flux at the sea surface (top) from the atmosphere
@@ -361,5 +400,5 @@
              CALL MPI_BCAST( total_2d_o(-nbgp,-nbgp), ngp_o, MPI_REAL, 0, &
                              comm2d, ierr)
-             qswst_remote(nysg:nyng,nxlg:nxrg) = total_2d_o(nysg:nyng,nxlg:nxrg)
+             CALL transfer_2D_to_1D_unequal( surf_def_h(2)%qsws )
           ENDIF
 !
@@ -381,5 +420,5 @@
           CALL MPI_BCAST( total_2d_o(-nbgp,-nbgp), ngp_o, MPI_REAL, &
                           0, comm2d, ierr )
-          uswst(nysg:nyng,nxlg:nxrg) = total_2d_o(nysg:nyng,nxlg:nxrg)
+          CALL transfer_2D_to_1D_unequal( surf_def_h(2)%usws )
 !
 !--       Receive momentum flux (v) at the sea surface (top) from the atmosphere
@@ -391,5 +430,5 @@
           CALL MPI_BCAST( total_2d_o(-nbgp,-nbgp), ngp_o, MPI_REAL, 0, comm2d, &
                           ierr )
-          vswst(nysg:nyng,nxlg:nxrg) = total_2d_o(nysg:nyng,nxlg:nxrg)
+          CALL transfer_2D_to_1D_unequal( surf_def_h(2)%vsws )
 !
 !--       Send u to atmosphere
@@ -415,26 +454,38 @@
        IF ( humidity_remote )  THEN
 !
-!--       Here tswst is still the sum of atmospheric bottom heat fluxes,
+!--       Here top heat flux is still the sum of atmospheric bottom heat fluxes,
 !--       * latent heat of vaporization in m2/s2, or 540 cal/g, or 40.65 kJ/mol
 !--       /(rho_atm(=1.0)*c_p)
-          tswst = tswst + qswst_remote * l_v / cp
-!
-!--        ...and convert it to a salinity flux at the sea surface (top)
-!--       following Steinhorn (1991), JPO 21, pp. 1681-1683:
-!--       S'w' = -S * evaporation / ( rho_water * ( 1 - S ) )
-          saswst = -1.0_wp * sa(nzt,:,:) * 0.001_wp * qswst_remote /  &
-                    ( rho_ocean(nzt,:,:) * ( 1.0_wp - sa(nzt,:,:) * 0.001_wp ) )
+          DO  m = 1, surf_def_h(2)%ns
+             i = surf_def_h(2)%i(m)
+             j = surf_def_h(2)%j(m)
+             
+             surf_def_h(2)%shf(m) = surf_def_h(2)%shf(m) +                     &
+                                    surf_def_h(2)%qsws(m) * l_v / cp
+!
+!--          ...and convert it to a salinity flux at the sea surface (top)
+!--          following Steinhorn (1991), JPO 21, pp. 1681-1683:
+!--          S'w' = -S * evaporation / ( rho_water * ( 1 - S ) )
+             surf_def_h(2)%sasws(m) = -1.0_wp * sa(nzt,j,i) * 0.001_wp *       &
+                                      surf_def_h(2)%qsws(m) /                  &
+                                    ( rho_ocean(nzt,j,i) *                     &
+                                      ( 1.0_wp - sa(nzt,j,i) * 0.001_wp )      &
+                                    )
+          ENDDO
        ENDIF
 
 !
 !--    Adjust the kinematic heat flux with respect to ocean density
-!--    (constants are the specific heat capacities for air and water)
-!--    now tswst is the ocean top heat flux
-       tswst = tswst / rho_ocean(nzt,:,:) * cp / cpw
-
-!
-!--    Adjust the momentum fluxes with respect to ocean density
-       uswst = uswst / rho_ocean(nzt,:,:)
-       vswst = vswst / rho_ocean(nzt,:,:)
+!--    (constants are the specific heat capacities for air and water), as well 
+!--    as momentum fluxes 
+       DO  m = 1, surf_def_h(2)%ns
+          i = surf_def_h(2)%i(m)
+          j = surf_def_h(2)%j(m)
+          surf_def_h(2)%shf(m) = surf_def_h(2)%shf(m) / rho_ocean(nzt,j,i) *   &
+                                 cp / cpw
+
+          surf_def_h(2)%usws(m) = surf_def_h(2)%usws(m) / rho_ocean(nzt,j,i)
+          surf_def_h(2)%vsws(m) = surf_def_h(2)%vsws(m) / rho_ocean(nzt,j,i)
+       ENDDO
 
     ENDIF
@@ -447,4 +498,161 @@
 
 #endif
+
+     CONTAINS 
+
+!       Description:
+!------------------------------------------------------------------------------!
+!>      Data transfer from 1D surface-data type to 2D dummy array for equal 
+!>      grids in atmosphere and ocean.
+!------------------------------------------------------------------------------!
+        SUBROUTINE transfer_1D_to_2D_equal( def_1d, lsm_1d, usm_1d )
+
+           IMPLICIT NONE
+
+            INTEGER(iwp) ::  i   !< running index x
+            INTEGER(iwp) ::  j   !< running index y
+            INTEGER(iwp) ::  m   !< running index surface type
+
+            REAL(wp), DIMENSION(1:surf_def_h(0)%ns) ::  def_1d !< 1D surface flux, default surfaces
+            REAL(wp), DIMENSION(1:surf_lsm_h%ns)    ::  lsm_1d !< 1D surface flux, natural surfaces
+            REAL(wp), DIMENSION(1:surf_usm_h%ns)    ::  usm_1d !< 1D surface flux, urban surfaces
+!
+!--         Transfer surface flux at default surfaces to 2D grid 
+            DO  m = 1, surf_def_h(0)%ns
+               i = surf_def_h(0)%i(m)
+               j = surf_def_h(0)%j(m)
+               surface_flux(j,i) = def_1d(m)
+            ENDDO
+!
+!--         Transfer surface flux at natural surfaces to 2D grid 
+            IF ( land_surface )  THEN 
+               DO  m = 1, SIZE(lsm_1d)
+                  i = surf_lsm_h%i(m)
+                  j = surf_lsm_h%j(m)
+                  surface_flux(j,i) = lsm_1d(m)
+               ENDDO
+            ENDIF
+!
+!--         Transfer surface flux at natural surfaces to 2D grid 
+            IF ( urban_surface )  THEN 
+               DO  m = 1, SIZE(usm_1d)
+                  i = surf_usm_h%i(m)
+                  j = surf_usm_h%j(m)
+                  surface_flux(j,i) = usm_1d(m)
+               ENDDO
+            ENDIF
+
+        END SUBROUTINE transfer_1D_to_2D_equal
+
+!       Description:
+!------------------------------------------------------------------------------!
+!>      Data transfer from 2D array for equal grids onto 1D surface-data type
+!>      array.
+!------------------------------------------------------------------------------!
+        SUBROUTINE transfer_2D_to_1D_equal( def_1d )
+
+           IMPLICIT NONE
+
+            INTEGER(iwp) ::  i   !< running index x
+            INTEGER(iwp) ::  j   !< running index y
+            INTEGER(iwp) ::  m   !< running index surface type
+
+            REAL(wp), DIMENSION(1:surf_def_h(2)%ns) ::  def_1d !< 1D surface flux, default surfaces
+!
+!--         Transfer surface flux to 1D surface type, only for default surfaces 
+            DO  m = 1, surf_def_h(2)%ns
+               i = surf_def_h(2)%i(m)
+               j = surf_def_h(2)%j(m)
+               def_1d(m) = surface_flux(j,i)
+            ENDDO
+
+        END SUBROUTINE transfer_2D_to_1D_equal
+
+!       Description:
+!------------------------------------------------------------------------------!
+!>      Data transfer from 1D surface-data type to 2D dummy array from unequal 
+!>      grids in atmosphere and ocean.
+!------------------------------------------------------------------------------!
+        SUBROUTINE transfer_1D_to_2D_unequal( def_1d, lsm_1d, usm_1d )
+
+           IMPLICIT NONE
+
+            INTEGER(iwp) ::  i   !< running index x
+            INTEGER(iwp) ::  j   !< running index y
+            INTEGER(iwp) ::  m   !< running index surface type
+
+            REAL(wp), DIMENSION(1:surf_def_h(0)%ns) ::  def_1d !< 1D surface flux, default surfaces
+            REAL(wp), DIMENSION(1:surf_lsm_h%ns)    ::  lsm_1d !< 1D surface flux, natural surfaces
+            REAL(wp), DIMENSION(1:surf_usm_h%ns)    ::  usm_1d !< 1D surface flux, urban surfaces
+!
+!--         Transfer surface flux at default surfaces to 2D grid. Transfer no
+!--         ghost-grid points since total_2d is a global array.
+            DO  m = 1, SIZE(def_1d)
+               i = surf_def_h(0)%i(m)
+               j = surf_def_h(0)%j(m)
+
+               IF ( i >= nxl  .AND.  i <= nxr  .AND.                           &
+                    j >= nys  .AND.  j <= nyn )  THEN
+                  total_2d(j,i) = def_1d(m)
+               ENDIF
+            ENDDO
+!
+!--         Transfer surface flux at natural surfaces to 2D grid 
+            IF ( land_surface )  THEN 
+               DO  m = 1, SIZE(lsm_1d)
+                  i = surf_lsm_h%i(m)
+                  j = surf_lsm_h%j(m)
+
+                  IF ( i >= nxl  .AND.  i <= nxr  .AND.                        &
+                       j >= nys  .AND.  j <= nyn )  THEN
+                     total_2d(j,i) = lsm_1d(m)
+                  ENDIF
+               ENDDO
+            ENDIF
+!
+!--         Transfer surface flux at natural surfaces to 2D grid 
+            IF ( urban_surface )  THEN 
+               DO  m = 1, SIZE(usm_1d)
+                  i = surf_usm_h%i(m)
+                  j = surf_usm_h%j(m)
+
+                  IF ( i >= nxl  .AND.  i <= nxr  .AND.                        &
+                       j >= nys  .AND.  j <= nyn )  THEN
+                     total_2d(j,i) = usm_1d(m)
+                  ENDIF
+               ENDDO
+            ENDIF
+
+        END SUBROUTINE transfer_1D_to_2D_unequal
+
+!       Description:
+!------------------------------------------------------------------------------!
+!>      Data transfer from 2D dummy array from unequal grids to 1D surface-data 
+!>      type.
+!------------------------------------------------------------------------------!
+        SUBROUTINE transfer_2D_to_1D_unequal( def_1d )
+
+           IMPLICIT NONE
+
+            INTEGER(iwp) ::  i   !< running index x
+            INTEGER(iwp) ::  j   !< running index y
+            INTEGER(iwp) ::  m   !< running index surface type
+
+            REAL(wp), DIMENSION(1:surf_def_h(2)%ns) ::  def_1d !< 1D surface flux, default surfaces
+!
+!--         Transfer 2D surface flux to default surfaces data type. Transfer no
+!--         ghost-grid points since total_2d is a global array.
+            DO  m = 1, SIZE(def_1d)
+               i = surf_def_h(2)%i(m)
+               j = surf_def_h(2)%j(m)
+
+               IF ( i >= nxl  .AND.  i <= nxr  .AND.                           &
+                    j >= nys  .AND.  j <= nyn )  THEN
+                  def_1d(m) = total_2d_o(j,i)
+               ENDIF
+            ENDDO
+
+
+        END SUBROUTINE transfer_2D_to_1D_unequal
 
   END SUBROUTINE surface_coupler
Index: /palm/trunk/SOURCE/surface_layer_fluxes_mod.f90
===================================================================
--- /palm/trunk/SOURCE/surface_layer_fluxes_mod.f90	(revision 2231)
+++ /palm/trunk/SOURCE/surface_layer_fluxes_mod.f90	(revision 2232)
@@ -20,5 +20,6 @@
 ! Current revisions:
 ! ------------------
-! 
+! Adjustments to new surface concept
+! OpenMP bugfix
 ! 
 ! Former revisions:
@@ -171,7 +172,6 @@
 
     USE arrays_3d,                                                             &
-        ONLY:  e, kh, nr, nrs, nrsws, ol, pt, q, ql, qr, qrs, qrsws, qs, qsws, &
-               s, shf, ss, ssws, ts, u, us, usws, v, vpt, vsws, zu, zw, z0,    &
-               z0h, z0q, drho_air_zw, rho_air_zw
+        ONLY:  e, kh, nr, pt, q, ql, qr, s, u, v, vpt, w, zu, zw, drho_air_zw, &
+               rho_air_zw
 
     USE cloud_parameters,                                                      &
@@ -187,15 +187,16 @@
                constant_waterflux, coupling_mode, g, humidity, ibc_e_b,        &
                ibc_pt_b, initializing_actions, kappa,                          &
-               intermediate_timestep_count,                                    &
-               intermediate_timestep_count_max, large_scale_forcing, lsf_surf, &
+               intermediate_timestep_count, intermediate_timestep_count_max,   &
+               land_surface, large_scale_forcing, lsf_surf,                    &
                message_string, microphysics_seifert, most_method, neutral,     &
                passive_scalar, pt_surface, q_surface, run_coupled,             &
                surface_pressure, simulated_time, terminate_run,                &
-               urban_surface,                                                  &
-               zeta_max, zeta_min 
+               urban_surface, zeta_max, zeta_min
+
+    USE grid_variables,                                                        &
+        ONLY:  dx, dy  
 
     USE indices,                                                               &
-        ONLY:  nxl, nxlg, nxr, nxrg, nys, nysg, nyn, nyng, nzb_s_inner,        &
-               nzb_u_inner, nzb_v_inner
+        ONLY:  nxl, nxr, nys, nyn, nzb
 
     USE kinds
@@ -204,6 +205,9 @@
 
     USE land_surface_model_mod,                                                &
-        ONLY:  land_surface, skip_time_do_lsm
-
+        ONLY:  aero_resist_kray, skip_time_do_lsm
+
+    USE surface_mod,                                                           &
+        ONLY :  surf_def_h, surf_def_v, surf_lsm_h, surf_lsm_v, surf_type,     &
+                surf_usm_h, surf_usm_v
         
 
@@ -213,13 +217,15 @@
     INTEGER(iwp) ::  j              !< loop index y direction
     INTEGER(iwp) ::  k              !< loop index z direction
-    INTEGER(iwp) ::  l_bnd  = 7500  !< Lookup table index of the last time step
-
-    INTEGER(iwp), PARAMETER     :: num_steps = 15000  !< number of steps in the lookup table
-
-    LOGICAL      ::  coupled_run  !< Flag for coupled atmosphere-ocean runs
-
-    REAL(wp), DIMENSION(:,:), ALLOCATABLE :: pt1,      & !< Potential temperature at first grid level (required for cloud_physics = .T.)
-                                             qv1,      & !< Specific humidity at first grid level (required for cloud_physics = .T.)
-                                             uv_total    !< Total velocity at first grid level
+    INTEGER(iwp) ::  l              !< loop index for surf type
+    INTEGER(iwp) ::  li_bnd  = 7500 !< Lookup table index of the last time step
+
+    INTEGER(iwp), PARAMETER ::  num_steps = 15000  !< number of steps in the lookup table
+
+    LOGICAL      ::  coupled_run       !< Flag for coupled atmosphere-ocean runs
+    LOGICAL      ::  downward = .FALSE.!< Flag indicating downward-facing horizontal surface
+    LOGICAL      ::  mom_uv  = .FALSE. !< Flag indicating calculation of usvs and vsus at vertical surfaces
+    LOGICAL      ::  mom_w   = .FALSE. !< Flag indicating calculation of wsus and wsvs at vertical surfaces
+    LOGICAL      ::  mom_tke = .FALSE. !< Flag indicating calculation of momentum fluxes at vertical surfaces used for TKE production 
+    LOGICAL      ::  surf_vertical     !< Flag indicating vertical surfaces
 
     REAL(wp), DIMENSION(0:num_steps-1) :: rib_tab,  & !< Lookup table bulk Richardson number
@@ -232,4 +238,6 @@
                      z_mo                 !< Height of the constant flux layer where MOST is assumed
 
+    TYPE(surf_type), POINTER ::  surf     !< surf-type array, used to generalize subroutines
+
 
     SAVE
@@ -237,5 +245,5 @@
     PRIVATE
 
-    PUBLIC init_surface_layer_fluxes, pt1, qv1, surface_layer_fluxes, uv_total
+    PUBLIC init_surface_layer_fluxes, surface_layer_fluxes
 
     INTERFACE init_surface_layer_fluxes
@@ -260,4 +268,6 @@
        IMPLICIT NONE
 
+       surf_vertical = .FALSE.
+       downward      = .FALSE.
 !
 !--    In case cloud physics is used, it is required to derive potential
@@ -265,5 +275,25 @@
 !--    and q
        IF ( cloud_physics )  THEN
-          CALL calc_pt_q
+!
+!--       First call for horizontal default-type surfaces (l=0 - upward facing, 
+!--       l=1 - downward facing)
+          DO  l = 0, 1
+             IF ( surf_def_h(l)%ns >= 1  )  THEN
+                surf => surf_def_h(l)
+                CALL calc_pt_q
+             ENDIF
+          ENDDO
+!
+!--       Call for natural-type surfaces
+          IF ( surf_lsm_h%ns >= 1  )  THEN
+             surf => surf_lsm_h
+             CALL calc_pt_q
+          ENDIF
+!
+!--       Call for urban-type surfaces
+          IF ( surf_usm_h%ns >= 1  )  THEN
+             surf => surf_usm_h
+             CALL calc_pt_q
+          ENDIF
        ENDIF
 
@@ -277,36 +307,373 @@
 !
 !--    Depending on setting of most_method use the "old" routine
+!--    Note, each routine is called for different surface types. 
+!--    First call for default-type horizontal surfaces, for natural- and 
+!--    urban-type surfaces. Note, at this place only upward-facing horizontal
+!--    surfaces are treted. 
        IF ( most_method == 'circular' )  THEN
-
-          CALL calc_scaling_parameters
-
-          CALL calc_uv_total
-
-          IF ( .NOT. neutral )  THEN
-             CALL calc_ol
-          ENDIF
-
-          CALL calc_us
-
-          CALL calc_surface_fluxes
-
+!
+!--       Default-type upward-facing horizontal surfaces
+          IF ( surf_def_h(0)%ns >= 1  )  THEN
+             surf => surf_def_h(0)
+             CALL calc_scaling_parameters
+             CALL calc_uvw_abs
+             IF ( .NOT. neutral )  CALL calc_ol
+             CALL calc_us
+             CALL calc_surface_fluxes
+          ENDIF
+!
+!--       Natural-type horizontal surfaces
+          IF ( surf_lsm_h%ns >= 1  )  THEN
+             surf => surf_lsm_h
+             CALL calc_scaling_parameters
+             CALL calc_uvw_abs
+             IF ( .NOT. neutral )  CALL calc_ol
+             CALL calc_us
+             CALL calc_surface_fluxes
+          ENDIF
+!
+!--       Urban-type horizontal surfaces
+          IF ( surf_usm_h%ns >= 1  )  THEN
+             surf => surf_usm_h
+             CALL calc_scaling_parameters
+             CALL calc_uvw_abs
+             IF ( .NOT. neutral )  CALL calc_ol
+             CALL calc_us
+             CALL calc_surface_fluxes
+          ENDIF
 !
 !--    Use either Newton iteration or a lookup table for the bulk Richardson
 !--    number to calculate the Obukhov length 
        ELSEIF ( most_method == 'newton'  .OR.  most_method == 'lookup' )  THEN
-
-          CALL calc_uv_total
-
-          IF ( .NOT. neutral )  THEN
-             CALL calc_ol
-          ENDIF
-
+!
+!--       Default-type upward-facing horizontal surfaces
+          IF ( surf_def_h(0)%ns >= 1  )  THEN
+             surf => surf_def_h(0)
+             CALL calc_uvw_abs
+             IF ( .NOT. neutral )  CALL calc_ol
+             CALL calc_us
+             CALL calc_scaling_parameters
+             CALL calc_surface_fluxes
+          ENDIF
+!
+!--       Natural-type horizontal surfaces
+          IF ( surf_lsm_h%ns >= 1  )  THEN
+             surf => surf_lsm_h
+             CALL calc_uvw_abs
+             IF ( .NOT. neutral )  CALL calc_ol
+             CALL calc_us
+             CALL calc_scaling_parameters
+             CALL calc_surface_fluxes
+          ENDIF
+!
+!--       Urban-type horizontal surfaces
+          IF ( surf_usm_h%ns >= 1  )  THEN
+             surf => surf_usm_h
+             CALL calc_uvw_abs
+             IF ( .NOT. neutral )  CALL calc_ol
+             CALL calc_us
+             CALL calc_scaling_parameters
+             CALL calc_surface_fluxes
+          ENDIF
+
+       ENDIF
+!
+!--    Treat downward-facing horizontal surfaces. Note, so far, these are 
+!--    always default type. Stratification is not considered
+!--    in this case, hence, no further distinction between different 
+!--    most_method is required.  
+       IF ( surf_def_h(1)%ns >= 1  )  THEN
+          downward = .TRUE.
+          surf => surf_def_h(1)
+          CALL calc_uvw_abs
           CALL calc_us
-
-          CALL calc_scaling_parameters
-
           CALL calc_surface_fluxes
-
+          downward = .FALSE.
        ENDIF
+!
+!--    Calculate surfaces fluxes at vertical surfaces for momentum 
+!--    and subgrid-scale TKE.
+!--    No stability is considered. Therefore, scaling parameters and Obukhov-
+!--    length do not need to be calculated and no distinction in 'circular',
+!--    'Newton' or 'lookup' is necessary so far. 
+!--    Note, this will change if stability is once considered.
+       surf_vertical = .TRUE.
+!
+!--    Calculate horizontal momentum fluxes at north- and south-facing 
+!--    surfaces(usvs).
+!--    For default-type surfaces
+       mom_uv = .TRUE. 
+       DO  l = 0, 1
+          IF ( surf_def_v(l)%ns >= 1  )  THEN
+             surf => surf_def_v(l)
+!
+!--          Compute surface-parallel velocity
+             CALL calc_uvw_abs_v_ugrid
+!
+!--          Compute respective friction velocity on staggered grid
+             CALL calc_us
+!
+!--          Compute respective surface fluxes for momentum and TKE
+             CALL calc_surface_fluxes
+          ENDIF
+       ENDDO
+!
+!--    For natural-type surfaces. Please note, even though stability is not
+!--    considered for the calculation of momentum fluxes at vertical surfaces,
+!--    scaling parameters and Obukov length are calculated nevertheless in this
+!--    case. This is due to the requirement of ts in parameterization of heat
+!--    flux in land-surface model in case of aero_resist_kray is not true.
+       IF ( .NOT. aero_resist_kray )  THEN
+          IF ( most_method == 'circular' )  THEN
+             DO  l = 0, 1
+                IF ( surf_lsm_v(l)%ns >= 1  )  THEN
+                   surf => surf_lsm_v(l)
+!
+!--                Compute scaling parameters
+                   CALL calc_scaling_parameters
+!
+!--                Compute surface-parallel velocity
+                   CALL calc_uvw_abs_v_ugrid
+!
+!--                Compute Obukhov length
+                   IF ( .NOT. neutral )  CALL calc_ol
+!
+!--                Compute respective friction velocity on staggered grid
+                   CALL calc_us
+!
+!--                Compute respective surface fluxes for momentum and TKE
+                   CALL calc_surface_fluxes
+                ENDIF
+             ENDDO
+          ELSE
+             DO  l = 0, 1
+                IF ( surf_lsm_v(l)%ns >= 1  )  THEN
+                   surf => surf_lsm_v(l)
+!
+!--                Compute surface-parallel velocity
+                   CALL calc_uvw_abs_v_ugrid
+!
+!--                Compute Obukhov length
+                   IF ( .NOT. neutral )  CALL calc_ol
+!
+!--                Compute respective friction velocity on staggered grid
+                   CALL calc_us
+!
+!--                Compute scaling parameters
+                   CALL calc_scaling_parameters
+!
+!--                Compute respective surface fluxes for momentum and TKE
+                   CALL calc_surface_fluxes
+                ENDIF
+             ENDDO
+          ENDIF
+!
+!--    No ts is required, so scaling parameters and Obukhov length do not need
+!--    to be computed.
+       ELSE
+          DO  l = 0, 1
+             IF ( surf_lsm_v(l)%ns >= 1  )  THEN
+                surf => surf_lsm_v(l)
+!   
+!--             Compute surface-parallel velocity
+                CALL calc_uvw_abs_v_ugrid
+!
+!--             Compute respective friction velocity on staggered grid
+                CALL calc_us
+!
+!--             Compute respective surface fluxes for momentum and TKE
+                CALL calc_surface_fluxes
+             ENDIF
+          ENDDO
+       ENDIF
+!
+!--    For urban-type surfaces
+       DO  l = 0, 1
+          IF ( surf_usm_v(l)%ns >= 1  )  THEN
+             surf => surf_usm_v(l)
+!
+!--          Compute surface-parallel velocity
+             CALL calc_uvw_abs_v_ugrid
+!
+!--          Compute respective friction velocity on staggered grid
+             CALL calc_us
+!
+!--          Compute respective surface fluxes for momentum and TKE
+             CALL calc_surface_fluxes
+          ENDIF
+       ENDDO
+!
+!--    Calculate horizontal momentum fluxes at east- and west-facing 
+!--    surfaces (vsus).
+!--    For default-type surfaces
+       DO  l = 2, 3
+          IF ( surf_def_v(l)%ns >= 1  )  THEN
+             surf => surf_def_v(l)
+!
+!--          Compute surface-parallel velocity
+             CALL calc_uvw_abs_v_vgrid
+!
+!--          Compute respective friction velocity on staggered grid
+             CALL calc_us
+!
+!--          Compute respective surface fluxes for momentum and TKE
+             CALL calc_surface_fluxes
+          ENDIF
+       ENDDO
+!
+!--    For natural-type surfaces. Please note, even though stability is not
+!--    considered for the calculation of momentum fluxes at vertical surfaces,
+!--    scaling parameters and Obukov length are calculated nevertheless in this
+!--    case. This is due to the requirement of ts in parameterization of heat
+!--    flux in land-surface model in case of aero_resist_kray is not true.
+       IF ( .NOT. aero_resist_kray )  THEN
+          IF ( most_method == 'circular' )  THEN
+             DO  l = 2, 3
+                IF ( surf_lsm_v(l)%ns >= 1  )  THEN
+                   surf => surf_lsm_v(l)
+!
+!--                Compute scaling parameters
+                   CALL calc_scaling_parameters
+!
+!--                Compute surface-parallel velocity
+                   CALL calc_uvw_abs_v_vgrid
+!
+!--                Compute Obukhov length
+                   IF ( .NOT. neutral )  CALL calc_ol
+!
+!--                Compute respective friction velocity on staggered grid
+                   CALL calc_us
+!
+!--                Compute respective surface fluxes for momentum and TKE
+                   CALL calc_surface_fluxes
+                ENDIF
+             ENDDO
+          ELSE
+             DO  l = 2, 3
+                IF ( surf_lsm_v(l)%ns >= 1  )  THEN
+                   surf => surf_lsm_v(l)
+!
+!--                Compute surface-parallel velocity
+                   CALL calc_uvw_abs_v_vgrid
+!
+!--                Compute Obukhov length
+                   IF ( .NOT. neutral )  CALL calc_ol
+!
+!--                Compute respective friction velocity on staggered grid
+                   CALL calc_us
+!
+!--                Compute scaling parameters
+                   CALL calc_scaling_parameters
+!
+!--                Compute respective surface fluxes for momentum and TKE
+                   CALL calc_surface_fluxes
+                ENDIF
+             ENDDO
+          ENDIF
+       ELSE
+          DO  l = 2, 3
+             IF ( surf_lsm_v(l)%ns >= 1  )  THEN
+                surf => surf_lsm_v(l)
+!   
+!--             Compute surface-parallel velocity
+                CALL calc_uvw_abs_v_vgrid
+!
+!--             Compute respective friction velocity on staggered grid
+                CALL calc_us
+!
+!--             Compute respective surface fluxes for momentum and TKE
+                CALL calc_surface_fluxes
+             ENDIF
+          ENDDO
+       ENDIF
+!
+!--    For urban-type surfaces
+       DO  l = 2, 3
+          IF ( surf_usm_v(l)%ns >= 1  )  THEN
+             surf => surf_usm_v(l)
+!
+!--          Compute surface-parallel velocity
+             CALL calc_uvw_abs_v_vgrid
+!
+!--          Compute respective friction velocity on staggered grid
+             CALL calc_us
+!
+!--          Compute respective surface fluxes for momentum and TKE
+             CALL calc_surface_fluxes
+          ENDIF
+       ENDDO
+       mom_uv = .FALSE.
+!
+!--    Calculate horizontal momentum fluxes of w (wsus and wsvs) at vertial 
+!--    surfaces.
+       mom_w = .TRUE.
+!
+!--    Default-type surfaces
+       DO  l = 0, 3
+          IF ( surf_def_v(l)%ns >= 1  )  THEN
+             surf => surf_def_v(l)
+             CALL calc_uvw_abs_v_wgrid
+             CALL calc_us
+             CALL calc_surface_fluxes
+          ENDIF
+       ENDDO 
+!
+!--    Natural-type surfaces
+       DO  l = 0, 3
+          IF ( surf_lsm_v(l)%ns >= 1  )  THEN
+             surf => surf_lsm_v(l)
+             CALL calc_uvw_abs_v_wgrid
+             CALL calc_us
+             CALL calc_surface_fluxes
+          ENDIF
+       ENDDO 
+!
+!--    Urban-type surfaces
+       DO  l = 0, 3
+          IF ( surf_usm_v(l)%ns >= 1  )  THEN
+             surf => surf_usm_v(l)
+             CALL calc_uvw_abs_v_wgrid
+             CALL calc_us
+             CALL calc_surface_fluxes
+          ENDIF
+       ENDDO 
+       mom_w = .FALSE.   
+!
+!--    Calculate momentum fluxes usvs, vsus, wsus and wsvs at vertical 
+!--    surfaces for TKE production. Note, here, momentum fluxes are defined 
+!--    at grid center and are not staggered as before.
+       mom_tke = .TRUE.
+!
+!--    Default-type surfaces
+       DO  l = 0, 3
+          IF ( surf_def_v(l)%ns >= 1  )  THEN
+             surf => surf_def_v(l)
+             CALL calc_uvw_abs_v_sgrid
+             CALL calc_us
+             CALL calc_surface_fluxes
+          ENDIF
+       ENDDO 
+!
+!--    Natural-type surfaces
+       DO  l = 0, 3
+          IF ( surf_lsm_v(l)%ns >= 1  )  THEN
+             surf => surf_lsm_v(l)
+             CALL calc_uvw_abs_v_sgrid
+             CALL calc_us
+             CALL calc_surface_fluxes
+          ENDIF
+       ENDDO 
+!
+!--    Urban-type surfaces
+       DO  l = 0, 3
+          IF ( surf_usm_v(l)%ns >= 1  )  THEN
+             surf => surf_usm_v(l)
+             CALL calc_uvw_abs_v_sgrid
+             CALL calc_us
+             CALL calc_surface_fluxes
+          ENDIF
+       ENDDO 
+       mom_tke = .FALSE.
+  
 
     END SUBROUTINE surface_layer_fluxes
@@ -324,5 +691,5 @@
        IMPLICIT NONE
 
-       INTEGER(iwp) :: l,          & !< Index for loop to create lookup table
+       INTEGER(iwp) :: li,         & !< Index for loop to create lookup table
                        num_steps_n   !< Number of non-stretched zeta steps
 
@@ -339,15 +706,6 @@
                    z0h_min   = 0.0_wp,   & !< Minimum value of z0h to create table
                    z0_min    = 0.0_wp      !< Minimum value of z0 to create table
-!
-!--    When cloud physics is used, arrays for storing potential temperature and
-!--    specific humidity at first grid level are required
-       IF ( cloud_physics )  THEN
-          ALLOCATE ( pt1(nysg:nyng,nxlg:nxrg) )
-          ALLOCATE ( qv1(nysg:nyng,nxlg:nxrg) )
-       ENDIF
-
-!
-!--    Allocate field for storing the horizontal velocity
-       ALLOCATE ( uv_total(nysg:nyng,nxlg:nxrg) )
+
+
 
 
@@ -355,5 +713,9 @@
 !--    In case of runs with neutral statification, set Obukhov length to a
 !--    large value
-       IF ( neutral ) ol = 1.0E10_wp
+       IF ( neutral )  THEN
+          IF ( surf_def_h(0)%ns >= 1 )  surf_def_h(0)%ol = 1.0E10_wp
+          IF ( surf_lsm_h%ns    >= 1 )  surf_lsm_h%ol    = 1.0E10_wp
+          IF ( surf_usm_h%ns    >= 1 )  surf_usm_h%ol    = 1.0E10_wp
+       ENDIF
 
        IF ( most_method == 'lookup' )  THEN
@@ -361,9 +723,44 @@
 !
 !--       Check for roughness heterogeneity. In that case terminate run and
-!--       inform user
-          IF ( MINVAL( z0h ) /= MAXVAL( z0h )  .OR.                            &
-               MINVAL( z0  ) /= MAXVAL( z0  ) )  THEN
-             terminate_run_l = .TRUE.
-          ENDIF
+!--       inform user. Check for both, natural and non-natural walls.
+          IF ( surf_def_h(0)%ns >= 1 )  THEN
+             IF ( MINVAL( surf_def_h(0)%z0h ) /= MAXVAL( surf_def_h(0)%z0h )  .OR. &
+                  MINVAL( surf_def_h(0)%z0  ) /= MAXVAL( surf_def_h(0)%z0  ) )  THEN
+                terminate_run_l = .TRUE.
+             ENDIF
+          ENDIF
+          IF ( surf_lsm_h%ns >= 1 )  THEN
+             IF ( MINVAL( surf_lsm_h%z0h ) /= MAXVAL( surf_lsm_h%z0h )  .OR.       &
+                  MINVAL( surf_lsm_h%z0  ) /= MAXVAL( surf_lsm_h%z0  ) )  THEN
+                terminate_run_l = .TRUE.
+             ENDIF
+          ENDIF
+          IF ( surf_usm_h%ns >= 1 )  THEN
+             IF ( MINVAL( surf_usm_h%z0h ) /= MAXVAL( surf_usm_h%z0h )  .OR.       &
+                  MINVAL( surf_usm_h%z0  ) /= MAXVAL( surf_usm_h%z0  ) )  THEN
+                terminate_run_l = .TRUE.
+             ENDIF
+          ENDIF
+!
+!--       Check roughness homogeneity between differt surface types. 
+          IF ( surf_lsm_h%ns >= 1  .AND.  surf_def_h(0)%ns >= 1 )  THEN
+             IF ( MINVAL( surf_lsm_h%z0h ) /= MAXVAL( surf_def_h(0)%z0h )  .OR.    &
+                  MINVAL( surf_lsm_h%z0  ) /= MAXVAL( surf_def_h(0)%z0  ) )  THEN
+                terminate_run_l = .TRUE.
+             ENDIF
+          ENDIF
+          IF ( surf_usm_h%ns >= 1  .AND.  surf_def_h(0)%ns >= 1 )  THEN
+             IF ( MINVAL( surf_usm_h%z0h ) /= MAXVAL( surf_def_h(0)%z0h )  .OR.    &
+                  MINVAL( surf_usm_h%z0  ) /= MAXVAL( surf_def_h(0)%z0  ) )  THEN
+                terminate_run_l = .TRUE.
+             ENDIF
+          ENDIF
+          IF ( surf_usm_h%ns >= 1  .AND.  surf_lsm_h%ns >= 1 )  THEN
+             IF ( MINVAL( surf_usm_h%z0h ) /= MAXVAL( surf_lsm_h%z0h )  .OR.       &
+                  MINVAL( surf_usm_h%z0  ) /= MAXVAL( surf_lsm_h%z0  ) )  THEN
+                terminate_run_l = .TRUE.
+             ENDIF
+          ENDIF
+
 
 #if defined( __parallel )
@@ -389,5 +786,5 @@
 !
 !--       Use the lowest possible value for z_mo
-          k    = MINVAL(nzb_s_inner)
+          k    = nzb
           z_mo = zu(k+1) - zw(k)
 
@@ -401,6 +798,6 @@
           zeta_step   = (zeta_max - zeta_stretch) / REAL(num_steps_n)
 
-          DO l = 1, num_steps_n
-             zeta_tmp(l) = zeta_tmp(l-1) + zeta_step
+          DO li = 1, num_steps_n
+             zeta_tmp(li) = zeta_tmp(li-1) + zeta_step
           ENDDO
 
@@ -415,6 +812,6 @@
 !
 !--       Calculate z/L range from zeta_min to zeta_stretch
-          DO l = num_steps_n+1, num_steps-1
-             zeta_tmp(l) = zeta_tmp(l-1) + zeta_step
+          DO li = num_steps_n+1, num_steps-1
+             zeta_tmp(li) = zeta_tmp(li-1) + zeta_step
              zeta_step = zeta_step * regr
           ENDDO
@@ -422,7 +819,14 @@
 !
 !--       Save roughness lengths to temporary variables
-          z0h_min = z0h(nys,nxl)
-          z0_min  = z0(nys,nxl)
-          
+          IF ( surf_def_h(0)%ns >= 1  )  THEN
+             z0h_min = surf_def_h(0)%z0h(1)
+             z0_min  = surf_def_h(0)%z0(1)
+          ELSEIF ( surf_lsm_h%ns >= 1 )  THEN
+             z0h_min = surf_lsm_h%z0h(1)
+             z0_min  = surf_lsm_h%z0(1)
+          ELSEIF ( surf_usm_h%ns >= 1 )  THEN
+             z0h_min = surf_usm_h%z0h(1)
+             z0_min  = surf_usm_h%z0(1)
+          ENDIF         
 !
 !--       Calculate lookup table for the Richardson number versus Obukhov length
@@ -430,21 +834,21 @@
 !--       boundary conditions for temperature
           IF ( ibc_pt_b == 1 )  THEN
-             DO l = 0, num_steps-1
-                ol_tab(l)  = - z_mo / zeta_tmp(num_steps-1-l)
-                rib_tab(l) = z_mo / ol_tab(l)  / ( LOG( z_mo / z0_min )        &
-                                                - psi_m( z_mo / ol_tab(l) )    &
-                                                + psi_m( z0_min / ol_tab(l) )  &
+             DO li = 0, num_steps-1
+                ol_tab(li)  = - z_mo / zeta_tmp(num_steps-1-li)
+                rib_tab(li) = z_mo / ol_tab(li)  / ( LOG( z_mo / z0_min )       &
+                                                - psi_m( z_mo / ol_tab(li) )    &
+                                                + psi_m( z0_min / ol_tab(li) )  &
                                                   )**3
              ENDDO  
           ELSE
-             DO l = 0, num_steps-1
-                ol_tab(l)  = - z_mo / zeta_tmp(num_steps-1-l)
-                rib_tab(l) = z_mo / ol_tab(l)  * ( LOG( z_mo / z0h_min )       &
-                                              - psi_h( z_mo / ol_tab(l) )      &
-                                              + psi_h( z0h_min / ol_tab(l) )   &
+             DO li = 0, num_steps-1
+                ol_tab(li)  = - z_mo / zeta_tmp(num_steps-1-li)
+                rib_tab(li) = z_mo / ol_tab(li)  * ( LOG( z_mo / z0h_min )     &
+                                              - psi_h( z_mo / ol_tab(li) )     &
+                                              + psi_h( z0h_min / ol_tab(li) )  &
                                             )                                  &
                                           / ( LOG( z_mo / z0_min )             &
-                                              - psi_m( z_mo / ol_tab(l) )      &
-                                              + psi_m( z0_min / ol_tab(l) )    &
+                                              - psi_m( z_mo / ol_tab(li) )     &
+                                              + psi_m( z0_min / ol_tab(li) )   &
                                             )**2
              ENDDO
@@ -467,34 +871,226 @@
 ! ------------
 !> Compute the absolute value of the horizontal velocity (relative to the
-!> surface). This is required by all methods
+!> surface) for horizontal surface elements. This is required by all methods.
 !------------------------------------------------------------------------------!
-    SUBROUTINE calc_uv_total
+    SUBROUTINE calc_uvw_abs
 
        IMPLICIT NONE
 
-
-       !$OMP PARALLEL DO PRIVATE( k )
-       DO  i = nxl, nxr
-          DO  j = nys, nyn
-
-             k   = nzb_s_inner(j,i)
-             uv_total(j,i) = SQRT( ( 0.5_wp * ( u(k+1,j,i) + u(k+1,j,i+1)      &
-                                         - u(k,j,i)   - u(k,j,i+1) ) )**2 +    &
-                              ( 0.5_wp * ( v(k+1,j,i) + v(k+1,j+1,i)           &
-                                         - v(k,j,i)   - v(k,j+1,i) ) )**2 )
-
-!
-!--          For too small values of the local wind, MOST does not work. A
-!--          threshold value is thus set if required
-!            uv_total(j,i) = MAX(0.01_wp,uv_total(j,i))
-
+       INTEGER(iwp) ::  i             !< running index x direction
+       INTEGER(iwp) ::  ibit          !< flag to mask computation of relative velocity in case of downward-facing surfaces
+       INTEGER(iwp) ::  j             !< running index y direction
+       INTEGER(iwp) ::  k             !< running index z direction
+       INTEGER(iwp) ::  m             !< running index surface elements
+
+!
+!--    ibit is 1 for upward-facing surfaces, zero for downward-facing surfaces.
+       ibit = MERGE( 1, 0, .NOT. downward )
+
+       DO  m = 1, surf%ns
+
+          i   = surf%i(m)            
+          j   = surf%j(m)
+          k   = surf%k(m)
+!
+!--       Compute the absolute value of the horizontal velocity.
+!--       (relative to the surface in case the lower surface is the ocean).
+!--       Please note, in new surface modelling concept the index values changed,
+!--       i.e. the reference grid point is not the surface-grid point itself but
+!--       the first grid point outside of the topography. 
+!--       Note, in case of coupled ocean-atmosphere simulations relative velocity
+!--       with respect to the ocean surface is used, hence, (k-1,j,i) values
+!--       are used to calculate the absolute velocity. 
+!--       However, this do not apply for downward-facing walls. To mask this, 
+!--       use ibit, which checks for upward/downward-facing surfaces. 
+
+          surf%uvw_abs(m) = SQRT(                                              &
+                              ( 0.5_wp * (   u(k,j,i)   + u(k,j,i+1)           &
+                                        -  ( u(k-1,j,i) + u(k-1,j,i+1)         &
+                                           ) * ibit                            &
+                                         )                                     &
+                              )**2 +                                           &
+                              ( 0.5_wp * (   v(k,j,i)   + v(k,j+1,i)           &
+                                        -  ( v(k-1,j,i) + v(k-1,j+1,i)         &
+                                           ) * ibit                            &
+                                         )                                     &
+                              )**2                                             &
+                                )
+
+       ENDDO
+
+    END SUBROUTINE calc_uvw_abs
+
+
+!------------------------------------------------------------------------------!
+! Description:
+! ------------
+!> Compute the absolute value of the horizontal velocity (relative to the
+!> surface) for horizontal surface elements. This is required by all methods.
+!------------------------------------------------------------------------------!
+    SUBROUTINE calc_uvw_abs_v_ugrid
+
+       IMPLICIT NONE
+
+       INTEGER(iwp) ::  i             !< running index x direction
+       INTEGER(iwp) ::  j             !< running index y direction
+       INTEGER(iwp) ::  k             !< running index z direction
+       INTEGER(iwp) ::  m             !< running index surface elements
+
+       REAL(wp)     ::  u_i
+       REAL(wp)     ::  w_i
+
+
+       DO  m = 1, surf%ns
+          i   = surf%i(m)            
+          j   = surf%j(m)
+          k   = surf%k(m)
+!
+!--       Compute the absolute value of the surface parallel velocity on u-grid.
+          u_i  = u(k,j,i)
+          w_i  = 0.25_wp * ( w(k-1,j,i-1) + w(k-1,j,i) +                       &
+                             w(k,j,i-1)   + w(k,j,i) ) 
+
+          surf%uvw_abs(m) = SQRT( u_i**2 + w_i**2 ) 
+
+       ENDDO
+
+    END SUBROUTINE calc_uvw_abs_v_ugrid
+
+!------------------------------------------------------------------------------!
+! Description:
+! ------------
+!> Compute the absolute value of the horizontal velocity (relative to the
+!> surface) for horizontal surface elements. This is required by all methods.
+!------------------------------------------------------------------------------!
+    SUBROUTINE calc_uvw_abs_v_vgrid
+
+       IMPLICIT NONE
+
+       INTEGER(iwp) ::  i             !< running index x direction
+       INTEGER(iwp) ::  j             !< running index y direction
+       INTEGER(iwp) ::  k             !< running index z direction
+       INTEGER(iwp) ::  m             !< running index surface elements
+
+       REAL(wp)     ::  v_i
+       REAL(wp)     ::  w_i
+
+
+       DO  m = 1, surf%ns
+          i   = surf%i(m)            
+          j   = surf%j(m)
+          k   = surf%k(m)
+
+          v_i  = u(k,j,i)
+          w_i  = 0.25_wp * ( w(k-1,j-1,i) + w(k-1,j,i) +                       &
+                             w(k,j-1,i)   + w(k,j,i) ) 
+
+          surf%uvw_abs(m) = SQRT( v_i**2 + w_i**2 ) 
+
+       ENDDO
+
+    END SUBROUTINE calc_uvw_abs_v_vgrid
+
+!------------------------------------------------------------------------------!
+! Description:
+! ------------
+!> Compute the absolute value of the horizontal velocity (relative to the
+!> surface) for horizontal surface elements. This is required by all methods.
+!------------------------------------------------------------------------------!
+    SUBROUTINE calc_uvw_abs_v_wgrid
+
+       IMPLICIT NONE
+
+       INTEGER(iwp) ::  i             !< running index x direction
+       INTEGER(iwp) ::  j             !< running index y direction
+       INTEGER(iwp) ::  k             !< running index z direction
+       INTEGER(iwp) ::  m             !< running index surface elements
+
+       REAL(wp)     ::  u_i
+       REAL(wp)     ::  v_i
+       REAL(wp)     ::  w_i
+!
+!--    North- (l=0) and south-facing (l=1) surfaces 
+       IF ( l == 0  .OR.  l == 1 )  THEN
+          DO  m = 1, surf%ns
+             i   = surf%i(m)            
+             j   = surf%j(m)
+             k   = surf%k(m)
+
+             u_i  = 0.25_wp * ( u(k+1,j,i+1) + u(k+1,j,i) +                    &
+                                u(k,j,i+1)   + u(k,j,i) )
+             v_i  = 0.0_wp
+             w_i  = w(k,j,i)
+
+             surf%uvw_abs(m) = SQRT( u_i**2 + v_i**2 + w_i**2 ) 
           ENDDO
-       ENDDO
-
-!
-!--    Values of uv_total need to be exchanged at the ghost boundaries
-       CALL exchange_horiz_2d( uv_total )
-
-    END SUBROUTINE calc_uv_total
+!
+!--    East- (l=2) and west-facing (l=3) surfaces
+       ELSE
+          DO  m = 1, surf%ns
+             i   = surf%i(m)            
+             j   = surf%j(m)
+             k   = surf%k(m)
+
+             u_i  = 0.0_wp
+             v_i  = 0.25_wp * ( v(k+1,j+1,i) + v(k+1,j,i) +                    &
+                                v(k,j+1,i)   + v(k,j,i) )
+             w_i  = w(k,j,i)
+
+             surf%uvw_abs(m) = SQRT( u_i**2 + v_i**2 + w_i**2 ) 
+          ENDDO
+       ENDIF            
+
+    END SUBROUTINE calc_uvw_abs_v_wgrid
+
+!------------------------------------------------------------------------------!
+! Description:
+! ------------
+!> Compute the absolute value of the horizontal velocity (relative to the
+!> surface) for horizontal surface elements. This is required by all methods.
+!------------------------------------------------------------------------------!
+    SUBROUTINE calc_uvw_abs_v_sgrid
+
+       IMPLICIT NONE
+
+       INTEGER(iwp) ::  i             !< running index x direction
+       INTEGER(iwp) ::  j             !< running index y direction
+       INTEGER(iwp) ::  k             !< running index z direction
+       INTEGER(iwp) ::  m             !< running index surface elements
+
+       REAL(wp)     ::  u_i
+       REAL(wp)     ::  v_i
+       REAL(wp)     ::  w_i
+
+!
+!--    North- (l=0) and south-facing (l=1) walls 
+       IF ( l == 0  .OR.  l == 1 )  THEN
+          DO  m = 1, surf%ns
+             i   = surf%i(m)            
+             j   = surf%j(m)
+             k   = surf%k(m)
+
+             u_i = 0.5_wp * ( u(k,j,i) + u(k,j,i+1) )
+             v_i = 0.0_wp
+             w_i = 0.5_wp * ( w(k,j,i) + w(k-1,j,i) )
+
+             surf%uvw_abs(m) = SQRT( u_i**2 + v_i**2 + w_i**2 ) 
+          ENDDO
+!
+!--    East- (l=2) and west-facing (l=3) walls 
+       ELSE
+          DO  m = 1, surf%ns
+             i   = surf%i(m)            
+             j   = surf%j(m)
+             k   = surf%k(m)
+
+             u_i = 0.0_wp
+             v_i = 0.5_wp * ( v(k,j,i) + v(k,j+1,i) )
+             w_i = 0.5_wp * ( w(k,j,i) + w(k-1,j,i) )
+
+             surf%uvw_abs(m) = SQRT( u_i**2 + v_i**2 + w_i**2 ) 
+          ENDDO
+       ENDIF  
+
+    END SUBROUTINE calc_uvw_abs_v_sgrid
 
 
@@ -508,8 +1104,7 @@
        IMPLICIT NONE
 
-       INTEGER(iwp) :: iter,  & !< Newton iteration step
-                       l        !< look index
-
-       REAL(wp), DIMENSION(nysg:nyng,nxlg:nxrg) :: rib !< Bulk Richardson number
+       INTEGER(iwp) ::  iter    !< Newton iteration step
+       INTEGER(iwp) ::  li      !< look index
+       INTEGER(iwp) ::  m       !< loop variable over all horizontal wall elements 
 
        REAL(wp)     :: f,      & !< Function for Newton iteration: f = Ri - [...]/[...]^2 = 0
@@ -521,46 +1116,75 @@
 
        IF ( TRIM( most_method ) /= 'circular' )  THEN
-      
-          !$OMP PARALLEL DO PRIVATE( k, z_mo )
-          DO  i = nxl, nxr
-             DO  j = nys, nyn
-
-                k   = nzb_s_inner(j,i)
-                z_mo = zu(k+1) - zw(k)
-
-!
-!--             Evaluate bulk Richardson number (calculation depends on
-!--             definition based on setting of boundary conditions
-                IF ( ibc_pt_b /= 1 )  THEN
-                   IF ( humidity )  THEN
-                      rib(j,i) = g * z_mo * ( vpt(k+1,j,i) - vpt(k,j,i) )      &
-                           / ( uv_total(j,i)**2 * vpt(k+1,j,i) + 1.0E-20_wp )
-                   ELSE
-                      rib(j,i) = g * z_mo * ( pt(k+1,j,i) - pt(k,j,i) )        &
-                           / ( uv_total(j,i)**2 * pt(k+1,j,i)  + 1.0E-20_wp )
-                   ENDIF      
-                ELSE
-!
-!--                When using Neumann boundary conditions, the buoyancy flux
-!--                is required but cannot be calculated at the surface, as pt
-!--                and q are not known at the surface. Hence the values at 
-!--                first grid level are used to estimate the buoyancy flux
-                   IF ( humidity )  THEN
-                      rib(j,i) = - g * z_mo * ( ( 1.0_wp + 0.61_wp             &
-                                 * q(k+1,j,i) ) * shf(j,i) + 0.61_wp           &
-                                 * pt(k+1,j,i) * qsws(j,i) ) * drho_air_zw(k)  &
-                                 / ( uv_total(j,i)**3 * vpt(k+1,j,i) * kappa**2&
-                                 + 1.0E-20_wp)
-                   ELSE
-                      rib(j,i) = - g * z_mo * shf(j,i) * drho_air_zw(k)        &
-                           / ( uv_total(j,i)**3 * pt(k+1,j,i) * kappa**2       &
+!
+!--       Evaluate bulk Richardson number (calculation depends on
+!--       definition based on setting of boundary conditions
+          IF ( ibc_pt_b /= 1 )  THEN
+             IF ( humidity )  THEN
+                !$OMP PARALLEL DO PRIVATE( i, j, k, z_mo )
+                DO  m = 1, surf%ns
+
+                   i   = surf%i(m)            
+                   j   = surf%j(m)
+                   k   = surf%k(m)
+
+                   z_mo = surf%z_mo(m)
+
+                   surf%rib(m) = g * z_mo *                                    &
+                                         ( vpt(k,j,i) - vpt(k-1,j,i) ) /       &
+                      ( surf%uvw_abs(m)**2 * vpt(k,j,i) + 1.0E-20_wp )
+                ENDDO
+             ELSE
+                !$OMP PARALLEL DO PRIVATE( i, j, k, z_mo )
+                DO  m = 1, surf%ns
+
+                   i   = surf%i(m)            
+                   j   = surf%j(m)
+                   k   = surf%k(m)
+
+                   z_mo = surf%z_mo(m)
+
+                   surf%rib(m) = g * z_mo *                                    &
+                                         ( pt(k,j,i) - pt(k-1,j,i)   ) /       &
+                      ( surf%uvw_abs(m)**2 * pt(k,j,i)  + 1.0E-20_wp )
+                ENDDO
+             ENDIF
+          ELSE
+             IF ( humidity )  THEN
+                !$OMP PARALLEL DO PRIVATE( i, j, k, z_mo )
+                DO  m = 1, surf%ns
+
+                   i   = surf%i(m)            
+                   j   = surf%j(m)
+                   k   = surf%k(m)
+
+                   z_mo = surf%z_mo(m)
+
+                   surf%rib(m) = - g * z_mo * ( ( 1.0_wp + 0.61_wp             &
+                           * q(k,j,i) ) * surf%shf(m) + 0.61_wp                &
+                           * pt(k,j,i) * surf%qsws(m) ) *                      &
+                             drho_air_zw(k-1)                /                 &
+                         ( surf%uvw_abs(m)**3 * vpt(k,j,i) * kappa**2          &
                            + 1.0E-20_wp )
-                   ENDIF
-                ENDIF  
-     
-             ENDDO
-          ENDDO 
+                ENDDO
+             ELSE
+                !$OMP PARALLEL DO PRIVATE( i, j, k, z_mo )
+                DO  m = 1, surf%ns
+
+                   i   = surf%i(m)            
+                   j   = surf%j(m)
+                   k   = surf%k(m)
+
+                   z_mo = surf%z_mo(m)
+
+                   surf%rib(m) = - g * z_mo * surf%shf(m) *                    &
+                                        drho_air_zw(k-1)            /          &
+                        ( surf%uvw_abs(m)**3 * pt(k,j,i) * kappa**2            &
+                           + 1.0E-20_wp )
+                ENDDO
+             ENDIF
+          ENDIF
 
        ENDIF
+
 
 !
@@ -569,201 +1193,252 @@
        IF ( TRIM( most_method ) == 'newton' )  THEN
 
-          !$OMP PARALLEL DO PRIVATE( k, z_mo )
-          DO  i = nxl, nxr
-             DO  j = nys, nyn
-
-                k   = nzb_s_inner(j,i)
-                z_mo = zu(k+1) - zw(k)
-
-!
-!--             Store current value in case the Newton iteration fails
-                ol_old = ol(j,i)
+          DO  m = 1, surf%ns
+
+             i   = surf%i(m)            
+             j   = surf%j(m)
+             k   = surf%k(m)
+
+             z_mo = surf%z_mo(m)
+
+!
+!--          Store current value in case the Newton iteration fails
+             ol_old = surf%ol(m)
+
+!
+!--          Ensure that the bulk Richardson number and the Obukhov 
+!--          length have the same sign
+             IF ( surf%rib(m) * surf%ol(m) < 0.0_wp  .OR.                      &
+                  ABS( surf%ol(m) ) == ol_max )  THEN
+                IF ( surf%rib(m) > 1.0_wp ) surf%ol(m) =  0.01_wp
+                IF ( surf%rib(m) < 0.0_wp ) surf%ol(m) = -0.01_wp
+             ENDIF
+!
+!--          Iteration to find Obukhov length
+             iter = 0
+             DO
+                iter = iter + 1
+!
+!--             In case of divergence, use the value of the previous time step
+                IF ( iter > 1000 )  THEN
+                   surf%ol(m) = ol_old
+                   EXIT
+                ENDIF
+
+                ol_m = surf%ol(m)
+                ol_l = ol_m - 0.001_wp * ol_m
+                ol_u = ol_m + 0.001_wp * ol_m
+
+
+                IF ( ibc_pt_b /= 1 )  THEN
+!
+!--                Calculate f = Ri - [...]/[...]^2 = 0
+                   f = surf%rib(m) - ( z_mo / ol_m ) * (                       &
+                                                 LOG( z_mo / surf%z0h(m) )     &
+                                                 - psi_h( z_mo / ol_m )        &
+                                                 + psi_h( surf%z0h(m) /        &
+                                                          ol_m )               &
+                                                               )               &
+                                              / ( LOG( z_mo / surf%z0(m) )     &
+                                                 - psi_m( z_mo / ol_m )        &
+                                                 + psi_m( surf%z0(m) /         &
+                                                          ol_m )               &
+                                                 )**2
+
+!
+!--                 Calculate df/dL
+                    f_d_ol = ( - ( z_mo / ol_u ) * ( LOG( z_mo /               &
+                                                             surf%z0h(m) )     &
+                                            - psi_h( z_mo / ol_u )             &
+                                            + psi_h( surf%z0h(m) / ol_u )      &
+                                              )                                &
+                                            / ( LOG( z_mo / surf%z0(m) )       &
+                                            - psi_m( z_mo / ol_u )             &
+                                            + psi_m( surf%z0(m) / ol_u )       &
+                                              )**2                             &
+                           + ( z_mo / ol_l ) * ( LOG( z_mo / surf%z0h(m) )     &
+                                            - psi_h( z_mo / ol_l )             &
+                                            + psi_h( surf%z0h(m) / ol_l )      &
+                                              )                                &
+                                            / ( LOG( z_mo / surf%z0(m) )       &
+                                            - psi_m( z_mo / ol_l )             &
+                                            + psi_m( surf%z0(m) / ol_l )       &
+                                              )**2                             &
+                             ) / ( ol_u - ol_l )
+                ELSE
+!
+!--                Calculate f = Ri - 1 /[...]^3 = 0
+                   f = surf%rib(m) - ( z_mo / ol_m ) /                         &
+                                                ( LOG( z_mo / surf%z0(m) )     &
+                                            - psi_m( z_mo / ol_m )             &
+                                            + psi_m( surf%z0(m) / ol_m )       &
+                                                )**3
+
+!
+!--                Calculate df/dL
+                   f_d_ol = ( - ( z_mo / ol_u ) / ( LOG( z_mo /                &
+                                                            surf%z0(m) )       &
+                                            - psi_m( z_mo / ol_u )             &
+                                            + psi_m( surf%z0(m) / ol_u )       &
+                                                     )**3                      &
+                           + ( z_mo / ol_l ) / ( LOG( z_mo / surf%z0(m) )      &
+                                            - psi_m( z_mo / ol_l )             &
+                                            + psi_m( surf%z0(m) / ol_l )       &
+                                               )**3                            &
+                                  ) / ( ol_u - ol_l )
+                ENDIF
+!
+!--             Calculate new L
+                surf%ol(m) = ol_m - f / f_d_ol
 
 !
 !--             Ensure that the bulk Richardson number and the Obukhov 
-!--             lengtH have the same sign
-                IF ( rib(j,i) * ol(j,i) < 0.0_wp  .OR.                         &
-                     ABS( ol(j,i) ) == ol_max )  THEN
-                   IF ( rib(j,i) > 0.0_wp ) ol(j,i) =  0.01_wp
-                   IF ( rib(j,i) < 0.0_wp ) ol(j,i) = -0.01_wp
+!--             length have the same sign and ensure convergence.
+                IF ( surf%ol(m) * ol_m < 0.0_wp )  surf%ol(m) = ol_m * 0.5_wp
+!
+!--             If unrealistic value occurs, set L to the maximum
+!--             value that is allowed
+                IF ( ABS( surf%ol(m) ) > ol_max )  THEN
+                   surf%ol(m) = ol_max
+                   EXIT
                 ENDIF
 !
-!--             Iteration to find Obukhov length
-                iter = 0
-                DO
-                   iter = iter + 1
-!
-!--                In case of divergence, use the value of the previous time step
-                   IF ( iter > 1000 )  THEN
-                      ol(j,i) = ol_old
-                      EXIT
-                   ENDIF
-
-                   ol_m = ol(j,i)
-                   ol_l = ol_m - 0.001_wp * ol_m
-                   ol_u = ol_m + 0.001_wp * ol_m
-
-
-                   IF ( ibc_pt_b /= 1 )  THEN
-!
-!--                   Calculate f = Ri - [...]/[...]^2 = 0
-                      f = rib(j,i) - ( z_mo / ol_m ) * ( LOG( z_mo / z0h(j,i) )&
-                                                    - psi_h( z_mo / ol_m )     &
-                                                    + psi_h( z0h(j,i) / ol_m ) &
-                                                   )                           &
-                                                 / ( LOG( z_mo / z0(j,i) )     &
-                                                    - psi_m( z_mo / ol_m )     &
-                                                    + psi_m( z0(j,i) / ol_m )  &
-                                                    )**2
-
-!
-!--                    Calculate df/dL
-                       f_d_ol = ( - ( z_mo / ol_u ) * ( LOG( z_mo / z0h(j,i) ) &
-                                                   - psi_h( z_mo / ol_u )      &
-                                                   + psi_h( z0h(j,i) / ol_u )  &
-                                                 )                             &
-                                               / ( LOG( z_mo / z0(j,i) )       &
-                                                   - psi_m( z_mo / ol_u )      &
-                                                   + psi_m( z0(j,i) / ol_u )   &
-                                                 )**2                          &
-                              + ( z_mo / ol_l ) * ( LOG( z_mo / z0h(j,i) )     &
-                                                   - psi_h( z_mo / ol_l )      &
-                                                   + psi_h( z0h(j,i) / ol_l )  &
-                                                 )                             &
-                                               / ( LOG( z_mo / z0(j,i) )       &
-                                                   - psi_m( z_mo / ol_l )      &
-                                                   + psi_m( z0(j,i) / ol_l )   &
-                                                 )**2                          &
-                                ) / ( ol_u - ol_l )
-                   ELSE
-!
-!--                   Calculate f = Ri - 1 /[...]^3 = 0
-                      f = rib(j,i) - ( z_mo / ol_m ) / ( LOG( z_mo / z0(j,i) )&
-                                                    - psi_m( z_mo / ol_m )    &
-                                                    + psi_m( z0(j,i) / ol_m ) &
-                                                       )**3
-
-!
-!--                   Calculate df/dL
-                      f_d_ol = ( - ( z_mo / ol_u ) / ( LOG( z_mo / z0(j,i) )  &
-                                                   - psi_m( z_mo / ol_u )     &
-                                                   + psi_m( z0(j,i) / ol_u )  &
-                                                 )**3                         &
-                              + ( z_mo / ol_l ) / ( LOG( z_mo / z0(j,i) )     &
-                                                   - psi_m( z_mo / ol_l )     &
-                                                   + psi_m( z0(j,i) / ol_l )  &
-                                                 )**3                         &
-                                     ) / ( ol_u - ol_l )
-                   ENDIF
-!
-!--                Calculate new L
-                   ol(j,i) = ol_m - f / f_d_ol
-
-!
-!--                Ensure that the bulk Richardson number and the Obukhov 
-!--                length have the same sign and ensure convergence.
-                   IF ( ol(j,i) * ol_m < 0.0_wp )  ol(j,i) = ol_m * 0.5_wp
-
-!
-!--                If unrealistic value occurs, set L to the maximum
-!--                value that is allowed
-                   IF ( ABS( ol(j,i) ) > ol_max )  THEN
-                      ol(j,i) = ol_max
-                      EXIT
-                   ENDIF
-!
-!--                Check for convergence
-                   IF ( ABS( ( ol(j,i) - ol_m ) / ol(j,i) ) < 1.0E-4_wp )  THEN
-                      EXIT
-                   ELSE
-                      CYCLE
-                   ENDIF
-
+!--             Check for convergence
+                IF ( ABS( ( surf%ol(m) - ol_m ) /                              &
+                     surf%ol(m) ) < 1.0E-4_wp )  THEN
+                   EXIT
+                ELSE
+                   CYCLE
+                ENDIF
+
+             ENDDO
+          ENDDO
+
+       ELSEIF ( TRIM( most_method ) == 'lookup' )  THEN
+
+          !$OMP PARALLEL DO PRIVATE( i, j, k, z_mo, li ) FIRSTPRIVATE( li_bnd ) LASTPRIVATE( li_bnd )
+          DO  m = 1, surf%ns
+
+             i   = surf%i(m)            
+             j   = surf%j(m)
+             k   = surf%k(m)
+!
+!--          If the bulk Richardson number is outside the range of the lookup
+!--          table, set it to the exceeding threshold value
+             IF ( surf%rib(m) < rib_min )  surf%rib(m) = rib_min
+             IF ( surf%rib(m) > rib_max )  surf%rib(m) = rib_max
+
+!
+!--          Find the correct index bounds for linear interpolation. As the
+!--          Richardson number will not differ very much from time step to
+!--          time step , use the index from the last step and search in the 
+!--          correct direction
+             li = li_bnd
+             IF ( rib_tab(li) - surf%rib(m) > 1.0_wp )  THEN
+                DO  WHILE ( rib_tab(li-1) - surf%rib(m) > 1.0_wp  .AND.  li > 1 )
+                   li = li-1
                 ENDDO
-                       
-             ENDDO
+             ELSE
+                DO  WHILE ( rib_tab(li) - surf%rib(m) < 0.0_wp                 &
+                           .AND.  li < num_steps-1 )
+                   li = li+1
+                ENDDO
+             ENDIF
+             li_bnd = li
+
+!
+!--          Linear interpolation to find the correct value of z/L
+             surf%ol(m) = ( ol_tab(li-1) + ( ol_tab(li) - ol_tab(li-1) )       &
+                         / (  rib_tab(li) - rib_tab(li-1) )                    &
+                         * ( surf%rib(m) - rib_tab(li-1) ) )
+
           ENDDO
 
-       ELSEIF ( TRIM( most_method ) == 'lookup' )  THEN
-
-          !$OMP PARALLEL DO PRIVATE( k, l, z_mo ) FIRSTPRIVATE( l_bnd ) LASTPRIVATE( l_bnd )
-          DO  i = nxl, nxr
-             DO  j = nys, nyn
-
-!
-!--             If the bulk Richardson number is outside the range of the lookup
-!--             table, set it to the exceeding threshold value
-                IF ( rib(j,i) < rib_min )  rib(j,i) = rib_min
-                IF ( rib(j,i) > rib_max )  rib(j,i) = rib_max
-
-!
-!--             Find the correct index bounds for linear interpolation. As the
-!--             Richardson number will not differ very much from time step to
-!--             time step , use the index from the last step and search in the 
-!--             correct direction
-                l = l_bnd
-                IF ( rib_tab(l) - rib(j,i) > 0.0_wp )  THEN
-                   DO  WHILE ( rib_tab(l-1) - rib(j,i) > 0.0_wp  .AND.  l > 0 )
-                      l = l-1
-                   ENDDO
-                ELSE
-                   DO  WHILE ( rib_tab(l) - rib(j,i) < 0.0_wp                  &
-                              .AND.  l < num_steps-1 )
-                      l = l+1
-                   ENDDO
-                ENDIF
-                l_bnd = l
-
-!
-!--             Linear interpolation to find the correct value of z/L
-                ol(j,i) = ( ol_tab(l-1) + ( ol_tab(l) - ol_tab(l-1) )          &
-                            / (  rib_tab(l) - rib_tab(l-1) )                   &
-                            * ( rib(j,i) - rib_tab(l-1) ) )
-
-             ENDDO
-          ENDDO
-
        ELSEIF ( TRIM( most_method ) == 'circular' )  THEN
 
-          !$OMP PARALLEL DO PRIVATE( k, z_mo )
-          DO  i = nxl, nxr
-             DO  j = nys, nyn
-
-                k   = nzb_s_inner(j,i)
-                z_mo = zu(k+1) - zw(k)
-
-                IF ( .NOT. humidity )  THEN
-                   ol(j,i) =  ( pt(k+1,j,i) *  us(j,i)**2 ) / ( kappa * g      &
-                              * ts(j,i) + 1E-30_wp )
-                ELSEIF ( cloud_physics )  THEN
-
-                   ol(j,i) =  ( vpt(k+1,j,i) * us(j,i)**2 ) / ( kappa * g      &
-                              * ( ts(j,i) + 0.61_wp * pt1(j,i) * qs(j,i)       &
-                              + 0.61_wp * qv1(j,i) * ts(j,i) - ts(j,i)         &
-                              * ql(k+1,j,i) ) + 1E-30_wp )
-                ELSE
-                   ol(j,i) =  ( vpt(k+1,j,i) *  us(j,i)**2 ) / ( kappa * g     &
-                              * ( ts(j,i) + 0.61_wp * pt(k+1,j,i) * qs(j,i)    &
-                                  + 0.61_wp * q(k+1,j,i) * ts(j,i) ) + 1E-30_wp )
-                ENDIF
+          IF ( .NOT. humidity )  THEN
+             !$OMP PARALLEL DO PRIVATE( i, j, k, z_mo )
+             DO  m = 1, surf%ns
+
+                i   = surf%i(m)            
+                j   = surf%j(m)
+                k   = surf%k(m)
+
+                z_mo = surf%z_mo(m)
+
+                surf%ol(m) =  ( pt(k,j,i) *  surf%us(m)**2 ) /                 &
+                                       ( kappa * g *                           &
+                                         surf%ts(m) + 1E-30_wp )
 !
 !--             Limit the value range of the Obukhov length.
-!--             This is necessary for very small velocities (u,v --> 0), because
+!--             This is necessary for very small velocities (u,v --> 1), because
 !--             the absolute value of ol can then become very small, which in
 !--             consequence would result in very large shear stresses and very
 !--             small momentum fluxes (both are generally unrealistic).
-                IF ( ( z_mo / ( ol(j,i) + 1E-30_wp ) ) < zeta_min )            &
-                   ol(j,i) = z_mo / zeta_min
-                IF ( ( z_mo / ( ol(j,i) + 1E-30_wp ) ) > zeta_max )            &
-                   ol(j,i) = z_mo / zeta_max
-             ENDDO
-          ENDDO
+                IF ( ( z_mo / ( surf%ol(m) + 1E-30_wp ) ) < zeta_min )         &
+                   surf%ol(m) = z_mo / zeta_min
+                IF ( ( z_mo / ( surf%ol(m) + 1E-30_wp ) ) > zeta_max )         &
+                   surf%ol(m) = z_mo / zeta_max
+
+             ENDDO
+          ELSEIF ( cloud_physics )  THEN
+             !$OMP PARALLEL DO PRIVATE( i, j, k, z_mo )
+             DO  m = 1, surf%ns
+
+                i   = surf%i(m)            
+                j   = surf%j(m)
+                k   = surf%k(m)
+
+                z_mo = surf%z_mo(m)
+
+
+                surf%ol(m) =  ( vpt(k,j,i) * surf%us(m)**2 ) /                 &
+                    ( kappa * g * ( surf%ts(m) +                               &
+                         0.61_wp * surf%pt1(m) * surf%us(m)                    &
+                       + 0.61_wp * surf%qv1(m) * surf%ts(m) -                  &
+                                   surf%ts(m)  * ql(k,j,i) ) + 1E-30_wp )
+!
+!--             Limit the value range of the Obukhov length.
+!--             This is necessary for very small velocities (u,v --> 1), because
+!--             the absolute value of ol can then become very small, which in
+!--             consequence would result in very large shear stresses and very
+!--             small momentum fluxes (both are generally unrealistic).
+                IF ( ( z_mo / ( surf%ol(m) + 1E-30_wp ) ) < zeta_min )         &
+                   surf%ol(m) = z_mo / zeta_min
+                IF ( ( z_mo / ( surf%ol(m) + 1E-30_wp ) ) > zeta_max )         &
+                   surf%ol(m) = z_mo / zeta_max
+
+             ENDDO
+          ELSE
+
+             !$OMP PARALLEL DO PRIVATE( i, j, k, z_mo )
+             DO  m = 1, surf%ns
+
+                i   = surf%i(m)            
+                j   = surf%j(m)
+                k   = surf%k(m)
+
+                z_mo = surf%z_mo(m)
+
+                surf%ol(m) =  ( vpt(k,j,i) *  surf%us(m)**2 ) /                &
+                    ( kappa * g * ( surf%ts(m) + 0.61_wp * pt(k,j,i) *         &
+                                    surf%qs(m) + 0.61_wp * q(k,j,i)  *         &
+                                    surf%ts(m) ) + 1E-30_wp )
+
+!
+!--             Limit the value range of the Obukhov length.
+!--             This is necessary for very small velocities (u,v --> 1), because
+!--             the absolute value of ol can then become very small, which in
+!--             consequence would result in very large shear stresses and very
+!--             small momentum fluxes (both are generally unrealistic).
+                IF ( ( z_mo / ( surf%ol(m) + 1E-30_wp ) ) < zeta_min )         &
+                   surf%ol(m) = z_mo / zeta_min
+                IF ( ( z_mo / ( surf%ol(m) + 1E-30_wp ) ) > zeta_max )         &
+                   surf%ol(m) = z_mo / zeta_max
+
+             ENDDO
+
+          ENDIF
 
        ENDIF
-
-!
-!--    Values of ol at ghost point locations are needed for the evaluation
-!--    of usws and vsws.
-       CALL exchange_horiz_2d( ol )
 
     END SUBROUTINE calc_ol
@@ -775,18 +1450,51 @@
        IMPLICIT NONE
 
-       !$OMP PARALLEL DO PRIVATE( k, z_mo )
-       DO  i = nxlg, nxrg
-          DO  j = nysg, nyng
-
-             k   = nzb_s_inner(j,i)+1
-             z_mo = zu(k+1) - zw(k)
-
-!
-!--          Compute u* at the scalars' grid points
-             us(j,i) = kappa * uv_total(j,i) / ( LOG( z_mo / z0(j,i) )         &
-                                          - psi_m( z_mo / ol(j,i) )            &
-                                          + psi_m( z0(j,i) / ol(j,i) ) )
+       INTEGER(iwp) ::  m       !< loop variable over all horizontal surf elements 
+
+!
+!--    Compute u* at horizontal surfaces at the scalars' grid points
+       IF ( .NOT. surf_vertical )  THEN
+!
+!--       Compute u* at upward-facing surfaces
+          IF ( .NOT. downward )  THEN
+             !$OMP PARALLEL  DO PRIVATE( k, z_mo )
+             DO  m = 1, surf%ns
+
+                k    = surf%k(m)
+                z_mo = surf%z_mo(m)
+!
+!--             Compute u* at the scalars' grid points
+                surf%us(m) = kappa * surf%uvw_abs(m) /                         &
+                            ( LOG( z_mo / surf%z0(m) )                         &
+                           - psi_m( z_mo / surf%ol(m) )                        &
+                           + psi_m( surf%z0(m) / surf%ol(m) ) )
+   
+             ENDDO
+!
+!--       Compute u* at downward-facing surfaces. This case, do not consider
+!--       any stability. 
+          ELSE
+             !$OMP PARALLEL  DO PRIVATE( k, z_mo )
+             DO  m = 1, surf%ns
+
+                k    = surf%k(m)
+                z_mo = surf%z_mo(m)
+!
+!--             Compute u* at the scalars' grid points
+                surf%us(m) = kappa * surf%uvw_abs(m) / LOG( z_mo / surf%z0(m) )
+   
+             ENDDO
+          ENDIF
+!
+!--    Compute u* at vertical surfaces at the u/v/v grid, respectively. 
+!--    No stability is considered in this case.
+       ELSE
+          !$OMP PARALLEL DO PRIVATE( z_mo )
+          DO  m = 1, surf%ns
+             z_mo = surf%z_mo(m)
+
+             surf%us(m) = kappa * surf%uvw_abs(m) / LOG( z_mo / surf%z0(m) )
           ENDDO
-       ENDDO
+       ENDIF
 
     END SUBROUTINE calc_us
@@ -794,14 +1502,21 @@
 !
 !-- Calculate potential temperature and specific humidity at first grid level
+!-- ( only for upward-facing surfs )
     SUBROUTINE calc_pt_q
 
        IMPLICIT NONE
 
-       DO  i = nxlg, nxrg
-          DO  j = nysg, nyng
-             k   = nzb_s_inner(j,i)+1
-             pt1(j,i) = pt(k,j,i) + l_d_cp * pt_d_t(k) * ql(k,j,i)
-             qv1(j,i) = q(k,j,i) - ql(k,j,i)
-          ENDDO
+       INTEGER(iwp) ::  m       !< loop variable over all horizontal surf elements 
+
+       !$OMP PARALLEL DO PRIVATE( i, j, k )
+       DO  m = 1, surf%ns 
+
+          i   = surf%i(m)            
+          j   = surf%j(m)
+          k   = surf%k(m)
+
+          surf%pt1(m) = pt(k,j,i) + l_d_cp * pt_d_t(k) * ql(k,j,i)
+          surf%qv1(m) = q(k,j,i) - ql(k,j,i)
+
        ENDDO
 
@@ -814,118 +1529,193 @@
        IMPLICIT NONE
 
+
+       INTEGER(iwp)  ::  m       !< loop variable over all horizontal surf elements 
+
 ! 
-!--    Compute theta*
-       IF ( constant_heatflux )  THEN
-
+!--    Compute theta* at horizontal surfaces
+       IF ( constant_heatflux  .AND.  .NOT. surf_vertical )  THEN
 !
 !--       For a given heat flux in the surface layer:
-          !$OMP PARALLEL DO
-          DO  i = nxlg, nxrg
-             DO  j = nysg, nyng
-                k   = nzb_s_inner(j,i)
-                ts(j,i) = -shf(j,i) * drho_air_zw(k) / ( us(j,i) + 1E-30_wp )
-!
-!--             ts must be limited, because otherwise overflow may occur in case
-!--             of us=0 when computing ol further below
-                IF ( ts(j,i) < -1.05E5_wp )  ts(j,i) = -1.0E5_wp
-                IF ( ts(j,i) >   1.0E5_wp )  ts(j,i) =  1.0E5_wp
-             ENDDO
+
+          !$OMP PARALLEL DO PRIVATE( i, j, k )
+          DO  m = 1, surf%ns 
+
+             i   = surf%i(m)            
+             j   = surf%j(m)
+             k   = surf%k(m)
+
+             surf%ts(m) = -surf%shf(m) * drho_air_zw(k-1) /                    &
+                                  ( surf%us(m) + 1E-30_wp )
+
+!
+!--          ts must be limited, because otherwise overflow may occur in case
+!--          of us=0 when computing ol further below
+             IF ( surf%ts(m) < -1.05E5_wp )  surf%ts(m) = -1.0E5_wp
+             IF ( surf%ts(m) >  1.0E5_wp  )  surf%ts(m) =  1.0E5_wp
+
           ENDDO
 
-       ELSE
+       ELSEIF ( .NOT. surf_vertical ) THEN
 !
 !--       For a given surface temperature:
           IF ( large_scale_forcing  .AND.  lsf_surf )  THEN
-             !$OMP PARALLEL DO
-             DO  i = nxlg, nxrg
-                DO  j = nysg, nyng
-                   k = nzb_s_inner(j,i)
-                   pt(k,j,i) = pt_surface
-                ENDDO
-             ENDDO
-          ENDIF
-
-          !$OMP PARALLEL DO PRIVATE( k, z_mo )
-          DO  i = nxlg, nxrg
-             DO  j = nysg, nyng
-
-                k   = nzb_s_inner(j,i)
-                z_mo = zu(k+1) - zw(k)
-
-                IF ( cloud_physics )  THEN
-                   ts(j,i) = kappa * ( pt1(j,i) - pt(k,j,i) )                  &
-                                     / ( LOG( z_mo / z0h(j,i) )                &
-                                         - psi_h( z_mo / ol(j,i) )             &
-                                         + psi_h( z0h(j,i) / ol(j,i) ) )
-                ELSE
-                   ts(j,i) = kappa * ( pt(k+1,j,i) - pt(k,j,i) )               &
-                                     / ( LOG( z_mo / z0h(j,i) )                &
-                                         - psi_h( z_mo / ol(j,i) )             &
-                                         + psi_h( z0h(j,i) / ol(j,i) ) )
-                ENDIF
-
-             ENDDO
+
+             !$OMP PARALLEL DO PRIVATE( i, j, k )
+             DO  m = 1, surf%ns 
+                i   = surf%i(m)            
+                j   = surf%j(m)
+                k   = surf%k(m)
+
+                pt(k-1,j,i) = pt_surface
+             ENDDO
+          ENDIF
+
+          IF ( cloud_physics )  THEN
+             !$OMP PARALLEL DO PRIVATE( i, j, k, z_mo )
+             DO  m = 1, surf%ns   
+
+                i   = surf%i(m)            
+                j   = surf%j(m)
+                k   = surf%k(m)
+
+                z_mo = surf%z_mo(m)
+
+                surf%ts(m) = kappa * ( surf%pt1(m) - pt(k-1,j,i) )             &
+                                     / ( LOG( z_mo / surf%z0h(m) )             &
+                                         - psi_h( z_mo / surf%ol(m) )          &
+                                         + psi_h( surf%z0h(m) / surf%ol(m) ) )
+
+             ENDDO
+          ELSE
+             !$OMP PARALLEL DO PRIVATE( i, j, k, z_mo )
+             DO  m = 1, surf%ns   
+
+                i   = surf%i(m)            
+                j   = surf%j(m)
+                k   = surf%k(m)
+
+                z_mo = surf%z_mo(m)
+
+                surf%ts(m) = kappa * ( pt(k,j,i) - pt(k-1,j,i) )               &
+                                     / ( LOG( z_mo / surf%z0h(m) )             &
+                                         - psi_h( z_mo / surf%ol(m) )          &
+                                         + psi_h( surf%z0h(m) / surf%ol(m) ) )
+             ENDDO
+          ENDIF
+       ENDIF
+! 
+!--    Compute theta* at vertical surfaces. This is only required in case of 
+!--    land-surface model, in order to compute aerodynamical resistance.
+       IF ( surf_vertical )  THEN
+          !$OMP PARALLEL DO PRIVATE( i, j, k )
+          DO  m = 1, surf%ns 
+
+             i          =  surf%i(m)            
+             j          =  surf%j(m)
+             k          =  surf%k(m)
+             surf%ts(m) = -surf%shf(m) / ( surf%us(m) + 1E-30_wp )
+!
+!--          ts must be limited, because otherwise overflow may occur in case
+!--          of us=0 when computing ol further below
+             IF ( surf%ts(m) < -1.05E5_wp )  surf%ts(m) = -1.0E5_wp
+             IF ( surf%ts(m) >  1.0E5_wp  )  surf%ts(m) =  1.0E5_wp
+
           ENDDO
        ENDIF
 
 !
-!--    If required compute q*
+!--    If required compute q* at horizontal surfaces
        IF ( humidity )  THEN
-          IF ( constant_waterflux )  THEN
+          IF ( constant_waterflux  .AND.  .NOT. surf_vertical )  THEN
 !
 !--          For a given water flux in the surface layer
-             !$OMP PARALLEL DO
-             DO  i = nxlg, nxrg
-                DO  j = nysg, nyng
-                   k   = nzb_s_inner(j,i)
-                   qs(j,i) = -qsws(j,i) * drho_air_zw(k) / ( us(j,i) + 1E-30_wp )
-                ENDDO
-             ENDDO
-
-          ELSE
+             !$OMP PARALLEL DO PRIVATE( i, j, k )
+             DO  m = 1, surf%ns  
+
+                i   = surf%i(m)            
+                j   = surf%j(m)
+                k   = surf%k(m)
+                surf%qs(m) = -surf%qsws(m) * drho_air_zw(k-1) /                &
+                                               ( surf%us(m) + 1E-30_wp )
+
+             ENDDO
+
+          ELSEIF ( .NOT. surf_vertical )  THEN 
              coupled_run = ( coupling_mode == 'atmosphere_to_ocean'  .AND.     &
                              run_coupled )
 
              IF ( large_scale_forcing  .AND.  lsf_surf )  THEN
-                !$OMP PARALLEL DO
-                DO  i = nxlg, nxrg
-                   DO  j = nysg, nyng
-                      k = nzb_s_inner(j,i)
-                      q(k,j,i) = q_surface
-                   ENDDO
+                !$OMP PARALLEL DO PRIVATE( i, j, k )
+                DO  m = 1, surf%ns  
+
+                   i   = surf%i(m)           
+                   j   = surf%j(m)
+                   k   = surf%k(m)
+                   q(k-1,j,i) = q_surface
+                   
                 ENDDO
              ENDIF
 
-             !$OMP PARALLEL DO PRIVATE( e_s, k, z_mo )
-             DO  i = nxlg, nxrg
-                DO  j = nysg, nyng
-
-                   k   = nzb_s_inner(j,i)
-                   z_mo = zu(k+1) - zw(k)
-
-!
-!--                Assume saturation for atmosphere coupled to ocean (but not
-!--                in case of precursor runs)
-                   IF ( coupled_run )  THEN
-                      e_s = 6.1_wp * &
-                              EXP( 0.07_wp * ( MIN(pt(k,j,i),pt(k+1,j,i))      &
+!
+!--          Assume saturation for atmosphere coupled to ocean (but not
+!--          in case of precursor runs)
+             IF ( coupled_run )  THEN
+                !$OMP PARALLEL DO PRIVATE( i, j, k, e_s )
+                DO  m = 1, surf%ns   
+                   i   = surf%i(m)            
+                   j   = surf%j(m)
+                   k   = surf%k(m)
+                   e_s = 6.1_wp * &
+                              EXP( 0.07_wp * ( MIN(pt(k-1,j,i),pt(k,j,i))      &
                                                - 273.15_wp ) )
-                      q(k,j,i) = 0.622_wp * e_s / ( surface_pressure - e_s )
-                   ENDIF
-
-                   IF ( cloud_physics )  THEN
-                      qs(j,i) = kappa * ( qv1(j,i) - q(k,j,i) )                &
-                                        / ( LOG( z_mo / z0q(j,i) )             &
-                                            - psi_h( z_mo / ol(j,i) )          &
-                                            + psi_h( z0q(j,i) / ol(j,i) ) )
-
-                   ELSE
-                      qs(j,i) = kappa * ( q(k+1,j,i) - q(k,j,i) )              &
-                                        / ( LOG( z_mo / z0q(j,i) )             &
-                                            - psi_h( z_mo / ol(j,i) )          &
-                                            + psi_h( z0q(j,i) / ol(j,i) ) )
-                   ENDIF
-
+                   q(k-1,j,i) = 0.622_wp * e_s / ( surface_pressure - e_s )
                 ENDDO
+             ENDIF
+
+             IF ( cloud_physics )  THEN
+               !$OMP PARALLEL DO PRIVATE( i, j, k, z_mo )
+                DO  m = 1, surf%ns   
+
+                   i   = surf%i(m)            
+                   j   = surf%j(m)
+                   k   = surf%k(m)
+   
+                   z_mo = surf%z_mo(m)
+
+                   surf%qs(m) = kappa * ( surf%qv1(m) - q(k-1,j,i) )           &
+                                        / ( LOG( z_mo / surf%z0q(m) )          &
+                                            - psi_h( z_mo / surf%ol(m) )       &
+                                            + psi_h( surf%z0q(m) /             &
+                                                     surf%ol(m) ) )
+                ENDDO
+             ELSE
+                !$OMP PARALLEL DO PRIVATE( i, j, k, z_mo )
+                DO  m = 1, surf%ns   
+
+                   i   = surf%i(m)            
+                   j   = surf%j(m)
+                   k   = surf%k(m)
+   
+                   z_mo = surf%z_mo(m)
+
+                   surf%qs(m) = kappa * ( q(k,j,i) - q(k-1,j,i) )              &
+                                        / ( LOG( z_mo / surf%z0q(m) )          &
+                                            - psi_h( z_mo / surf%ol(m) )       &
+                                            + psi_h( surf%z0q(m) /             &
+                                                     surf%ol(m) ) )
+                ENDDO
+             ENDIF
+          ENDIF
+! 
+!--       Compute q* at vertical surfaces
+          IF ( surf_vertical )  THEN
+             !$OMP PARALLEL DO PRIVATE( i, j, k )
+             DO  m = 1, surf%ns  
+
+                i          =  surf%i(m)            
+                j          =  surf%j(m)
+                k          =  surf%k(m)
+                surf%qs(m) = -surf%qsws(m) / ( surf%us(m) + 1E-30_wp )
+
              ENDDO
           ENDIF
@@ -935,12 +1725,26 @@
 !--    If required compute s*
        IF ( passive_scalar )  THEN
-          IF ( constant_scalarflux )  THEN
-!
-!--          For a given water flux in the surface layer
-             !$OMP PARALLEL DO
-             DO  i = nxlg, nxrg
-                DO  j = nysg, nyng
-                   ss(j,i) = -ssws(j,i) / ( us(j,i) + 1E-30_wp )
-                ENDDO
+!
+!--       At horizontal surfaces
+          IF ( constant_scalarflux  .AND.  .NOT. surf_vertical )  THEN
+!
+!--          For a given scalar flux in the surface layer
+             !$OMP PARALLEL DO PRIVATE( i, j, k )
+             DO  m = 1, surf%ns  
+                i   = surf%i(m)            
+                j   = surf%j(m)
+                k   = surf%k(m)
+                surf%ss(m) = -surf%ssws(m) / ( surf%us(m) + 1E-30_wp )
+             ENDDO
+          ENDIF
+!
+!--       At vertical surfaces
+          IF ( surf_vertical )  THEN
+             !$OMP PARALLEL DO PRIVATE( i, j, k )
+             DO  m = 1, surf%ns  
+                i          =  surf%i(m)            
+                j          =  surf%j(m)
+                k          =  surf%k(m)
+                surf%ss(m) = -surf%ssws(m) / ( surf%us(m) + 1E-30_wp )
              ENDDO
           ENDIF
@@ -950,24 +1754,24 @@
 !
 !--    If required compute qr* and nr*
-       IF ( cloud_physics  .AND.  microphysics_seifert )   &
-       THEN
-
-          !$OMP PARALLEL DO PRIVATE( k, z_mo )
-          DO  i = nxlg, nxrg
-             DO  j = nysg, nyng
-
-                k   = nzb_s_inner(j,i)
-                z_mo = zu(k+1) - zw(k)
-
-                qrs(j,i) = kappa * ( qr(k+1,j,i) - qr(k,j,i) )              &
-                                 / ( LOG( z_mo / z0q(j,i) )                 &
-                                     - psi_h( z_mo / ol(j,i) )              &
-                                     + psi_h( z0q(j,i) / ol(j,i) ) )
-
-                nrs(j,i) = kappa * ( nr(k+1,j,i) - nr(k,j,i) )              &
-                                 / ( LOG( z_mo / z0q(j,i) )                 &
-                                     - psi_h( z_mo / ol(j,i) )              &
-                                     + psi_h( z0q(j,i) / ol(j,i) ) )
-             ENDDO
+       IF ( cloud_physics  .AND.  microphysics_seifert  .AND.                  &
+            .NOT. surf_vertical )  THEN
+          !$OMP PARALLEL DO PRIVATE( i, j, k, z_mo )
+          DO  m = 1, surf%ns    
+
+             i    = surf%i(m)            
+             j    = surf%j(m)
+             k    = surf%k(m)
+
+             z_mo = surf%z_mo(m)
+
+             surf%qrs(m) = kappa * ( qr(k,j,i) - qr(k-1,j,i) )                 &
+                                 / ( LOG( z_mo / surf%z0q(m) )                 &
+                                 - psi_h( z_mo / surf%ol(m) )                  &
+                                 + psi_h( surf%z0q(m) / surf%ol(m) ) )
+
+             surf%nrs(m) = kappa * ( nr(k,j,i) - nr(k-1,j,i) )                 &
+                                 / ( LOG( z_mo / surf%z0q(m) )                 &
+                                 - psi_h( z_mo / surf%ol(m) )                  &
+                                 + psi_h( surf%z0q(m) / surf%ol(m) ) )
           ENDDO
 
@@ -984,136 +1788,288 @@
        IMPLICIT NONE
 
-       REAL(wp) :: ol_mid !< Grid-interpolated L
-
-!
-!--    Compute u'w' for the total model domain.
-!--    First compute the corresponding component of u* and square it.
-       !$OMP PARALLEL DO PRIVATE( k, ol_mid, z_mo )
-       DO  i = nxl, nxr
-          DO  j = nys, nyn
-
-             k   = nzb_u_inner(j,i)
-             z_mo = zu(k+1) - zw(k)
-!
-!--          Compute bulk Obukhov length for this point
-             ol_mid = 0.5_wp * ( ol(j,i-1) + ol(j,i) )
-
-             IF ( ol_mid == 0.0_wp )  THEN
-                ol_mid = MIN(ol(j,i-1), ol(j,i))
+       INTEGER(iwp)  ::  m       !< loop variable over all horizontal surf elements 
+
+       REAL(wp)                            ::  dum     !< dummy to precalculate logarithm
+       REAL(wp)                            ::  flag_u  !< flag indicating u-grid, used for calculation of horizontal momentum fluxes at vertical surfaces
+       REAL(wp)                            ::  flag_v  !< flag indicating v-grid, used for calculation of horizontal momentum fluxes at vertical surfaces
+       REAL(wp), DIMENSION(:), ALLOCATABLE ::  u_i     !< u-component interpolated onto scalar grid point, required for momentum fluxes at vertical surfaces 
+       REAL(wp), DIMENSION(:), ALLOCATABLE ::  v_i     !< v-component interpolated onto scalar grid point, required for momentum fluxes at vertical surfaces 
+       REAL(wp), DIMENSION(:), ALLOCATABLE ::  w_i     !< w-component interpolated onto scalar grid point, required for momentum fluxes at vertical surfaces 
+
+!
+!--    Calcuate surface fluxes at horizontal walls
+       IF ( .NOT. surf_vertical )  THEN
+!
+!--       Compute u'w' for the total model domain at upward-facing surfaces.
+!--       First compute the corresponding component of u* and square it.
+          IF ( .NOT. downward )  THEN
+             !$OMP PARALLEL DO PRIVATE( i, j, k, z_mo )
+             DO  m = 1, surf%ns  
+   
+                i = surf%i(m)            
+                j = surf%j(m)
+                k = surf%k(m)
+
+                z_mo = surf%z_mo(m)
+
+                surf%usws(m) = kappa * ( u(k,j,i) - u(k-1,j,i) )               &
+                              / ( LOG( z_mo / surf%z0(m) )                     &
+                                  - psi_m( z_mo / surf%ol(m) )                 &
+                                  + psi_m( surf%z0(m) / surf%ol(m) ) )
+!
+!--             Please note, the computation of usws is not fully accurate. Actually 
+!--             a further interpolation of us onto the u-grid, where usws is defined, 
+!--             is required. However, this is not done as this would require several
+!--             data transfers between 2D-grid and the surf-type. 
+!--             The impact of the missing interpolation is negligible as several 
+!--             tests had shown. 
+!--             Same also for ol.  
+                surf%usws(m) = -surf%usws(m) * surf%us(m) * rho_air_zw(k-1)
+
+             ENDDO
+!
+!--       At downward-facing surfaces
+          ELSE
+             !$OMP PARALLEL DO PRIVATE( i, j, k, z_mo )
+             DO  m = 1, surf%ns  
+   
+                i = surf%i(m)            
+                j = surf%j(m)
+                k = surf%k(m)
+
+                z_mo = surf%z_mo(m)
+
+                surf%usws(m) = kappa * u(k,j,i) / LOG( z_mo / surf%z0(m) )
+!
+!--        To Do: Is the sign correct???
+                surf%usws(m) = surf%usws(m) * surf%us(m) * rho_air_zw(k)
+
+             ENDDO     
+          ENDIF
+
+!
+!--       Compute v'w' for the total model domain.
+!--       First compute the corresponding component of u* and square it.
+!--       Upward-facing surfaces
+          IF ( .NOT. downward )  THEN
+             !$OMP PARALLEL DO PRIVATE( i, j, k, z_mo )
+             DO  m = 1, surf%ns  
+                i = surf%i(m)            
+                j = surf%j(m)
+                k = surf%k(m)
+
+                z_mo = surf%z_mo(m)
+
+                surf%vsws(m) = kappa * ( v(k,j,i) - v(k-1,j,i) )               &
+                           / ( LOG( z_mo / surf%z0(m) )                        &
+                               - psi_m( z_mo / surf%ol(m) )                    &
+                               + psi_m( surf%z0(m) / surf%ol(m) ) )
+!
+!--             Please note, the computation of vsws is not fully accurate. Actually 
+!--             a further interpolation of us onto the v-grid, where vsws is defined, 
+!--             is required. However, this is not done as this would require several
+!--             data transfers between 2D-grid and the surf-type. 
+!--             The impact of the missing interpolation is negligible as several 
+!--             tests had shown. 
+!--             Same also for ol.  
+                surf%vsws(m) = -surf%vsws(m) * surf%us(m) * rho_air_zw(k-1)
+             ENDDO
+!
+!--       Downward-facing surfaces
+          ELSE
+             !$OMP PARALLEL DO PRIVATE( i, j, k, z_mo )
+             DO  m = 1, surf%ns  
+                i = surf%i(m)            
+                j = surf%j(m)
+                k = surf%k(m)
+
+                z_mo = surf%z_mo(m)
+
+                surf%vsws(m) = kappa * v(k,j,i) / LOG( z_mo / surf%z0(m) )
+ 
+                surf%vsws(m) = surf%vsws(m) * surf%us(m) * rho_air_zw(k)
+             ENDDO
+          ENDIF
+!
+!--       Compute the vertical kinematic heat flux
+          IF (  .NOT.  constant_heatflux  .AND.  ( simulated_time <=           &
+               skip_time_do_lsm  .OR.  .NOT.  land_surface )  .AND.            &
+               .NOT.  urban_surface  .AND.  .NOT. downward )  THEN
+             !$OMP PARALLEL DO PRIVATE( i, j, k )
+             DO  m = 1, surf%ns 
+                i    = surf%i(m)            
+                j    = surf%j(m)
+                k    = surf%k(m)
+                surf%shf(m) = -surf%ts(m) * surf%us(m) * rho_air_zw(k-1)
+             ENDDO
+          ENDIF
+!
+!--       Compute the vertical water flux
+          IF (  .NOT.  constant_waterflux  .AND.  humidity  .AND.              &
+                ( simulated_time <= skip_time_do_lsm                           &
+               .OR.  .NOT.  land_surface )  .AND.  .NOT. downward )  THEN
+             !$OMP PARALLEL DO PRIVATE( i, j, k )
+             DO  m = 1, surf%ns 
+                i    = surf%i(m)            
+                j    = surf%j(m)
+                k    = surf%k(m)
+                surf%qsws(m) = -surf%qs(m) * surf%us(m) * rho_air_zw(k-1)
+             ENDDO
+          ENDIF
+!
+!--       Compute the vertical scalar flux
+          IF (  .NOT.  constant_scalarflux  .AND.  passive_scalar  .AND.       &
+                .NOT.  downward )  THEN
+             !$OMP PARALLEL DO PRIVATE( i, j, k )
+             DO  m = 1, surf%ns   
+
+                i    = surf%i(m)            
+                j    = surf%j(m)
+                k    = surf%k(m)
+                surf%ssws(m) = -surf%ss(m) * surf%us(m)
+
+             ENDDO
+          ENDIF       
+!
+!--       Compute (turbulent) fluxes of rain water content and rain drop conc.
+          IF ( cloud_physics  .AND.  microphysics_seifert  .AND.              &
+               .NOT. downward)  THEN
+             !$OMP PARALLEL DO PRIVATE( i, j, k )
+             DO  m = 1, surf%ns   
+
+                i    = surf%i(m)            
+                j    = surf%j(m)
+                k    = surf%k(m)
+
+                surf%qrsws(m) = -surf%qrs(m) * surf%us(m)
+                surf%nrsws(m) = -surf%nrs(m) * surf%us(m)
+             ENDDO
+          ENDIF
+
+!
+!--       Bottom boundary condition for the TKE. 
+          IF ( ibc_e_b == 2 )  THEN
+             !$OMP PARALLEL DO PRIVATE( i, j, k )
+             DO  m = 1, surf%ns   
+
+                i    = surf%i(m)            
+                j    = surf%j(m)
+                k    = surf%k(m)
+
+                e(k,j,i) = ( surf%us(m) / 0.1_wp )**2
+!
+!--             As a test: cm = 0.4
+!               e(k,j,i) = ( us(j,i) / 0.4_wp )**2
+                e(k-1,j,i)   = e(k,j,i)
+
+             ENDDO
+          ENDIF
+!
+!--    Calcuate surface fluxes at vertical surfaces. No stability is considered. 
+       ELSE
+!
+!--       Compute usvs l={0,1} and vsus l={2,3}
+          IF ( mom_uv )  THEN
+!
+!--          Generalize computation by introducing flags. At north- and south-
+!--          facing surfaces u-component is used, at east- and west-facing
+!--          surfaces v-component is used.
+             flag_u = MERGE( 1.0_wp, 0.0_wp, l == 0  .OR.  l == 1 )   
+             flag_v = MERGE( 1.0_wp, 0.0_wp, l == 2  .OR.  l == 3 )   
+             !$OMP PARALLEL  DO PRIVATE( i, j, k, z_mo )
+             DO  m = 1, surf%ns  
+                i = surf%i(m)            
+                j = surf%j(m)
+                k = surf%k(m)
+
+                z_mo = surf%z_mo(m)
+
+                surf%mom_flux_uv(m) = kappa *                                  &
+                                ( flag_u * u(k,j,i) + flag_v * v(k,j,i) )  /   &
+                                                        LOG( z_mo / surf%z0(m) )
+
+               surf%mom_flux_uv(m) =                                           &
+                                    - surf%mom_flux_uv(m) * surf%us(m)
+             ENDDO
+          ENDIF
+!
+!--       Compute wsus l={0,1} and wsvs l={2,3}
+          IF ( mom_w )  THEN
+             !$OMP PARALLEL  DO PRIVATE( i, j, k, z_mo )
+             DO  m = 1, surf%ns  
+                i = surf%i(m)            
+                j = surf%j(m)
+                k = surf%k(m)
+
+                z_mo = surf%z_mo(m)
+
+                surf%mom_flux_w(m) = kappa * w(k,j,i) / LOG( z_mo / surf%z0(m) )
+
+                surf%mom_flux_w(m) =                                           &
+                                     - surf%mom_flux_w(m) * surf%us(m)
+             ENDDO
+          ENDIF
+!
+!--       Compute momentum fluxes used for subgrid-scale TKE production at 
+!--       vertical surfaces. In constrast to the calculated momentum fluxes at 
+!--       vertical surfaces before, which are defined on the u/v/w-grid, 
+!--       respectively), the TKE fluxes are defined at the scalar grid. 
+!--       
+          IF ( mom_tke )  THEN
+!
+!--          Precalculate velocity components at scalar grid point. 
+             ALLOCATE( u_i(1:surf%ns) )
+             ALLOCATE( v_i(1:surf%ns) )
+             ALLOCATE( w_i(1:surf%ns) )
+
+             IF ( l == 0  .OR.  l == 1 )  THEN
+                !$OMP PARALLEL DO PRIVATE( i, j, k )
+                DO  m = 1, surf%ns  
+                   i = surf%i(m)            
+                   j = surf%j(m)
+                   k = surf%k(m)
+
+                   u_i(m) = 0.5_wp * ( u(k,j,i) + u(k,j,i+1) )
+                   v_i(m) = 0.0_wp
+                   w_i(m) = 0.5_wp * ( w(k,j,i) + w(k-1,j,i) )
+                ENDDO
+             ELSE
+                !$OMP PARALLEL DO PRIVATE( i, j, k )
+                DO  m = 1, surf%ns  
+                   i = surf%i(m)            
+                   j = surf%j(m)
+                   k = surf%k(m)
+
+                   u_i(m) = 0.0_wp
+                   v_i(m) = 0.5_wp * ( v(k,j,i) + v(k,j+1,i) )
+                   w_i(m) = 0.5_wp * ( w(k,j,i) + w(k-1,j,i) )
+                ENDDO
              ENDIF
 
-             usws(j,i) = kappa * ( u(k+1,j,i) - u(k,j,i) )                     &
-                                 / ( LOG( z_mo / z0(j,i) )                     &
-                                     - psi_m( z_mo / ol_mid )                  &
-                                     + psi_m( z0(j,i) / ol_mid ) )
-
-             usws(j,i) = -usws(j,i) * 0.5_wp * ( us(j,i-1) + us(j,i) )         &
-                                    * rho_air_zw(k)
-          ENDDO
-       ENDDO
-
-!
-!--    Compute v'w' for the total model domain.
-!--    First compute the corresponding component of u* and square it.
-       !$OMP PARALLEL DO PRIVATE( k, ol_mid, z_mo )
-       DO  i = nxl, nxr
-          DO  j = nys, nyn
-
-             k   = nzb_v_inner(j,i)
-             z_mo = zu(k+1) - zw(k)
-!
-!--          Compute bulk Obukhov length for this point
-             ol_mid = 0.5_wp * ( ol(j-1,i) + ol(j,i) )
-
-             IF ( ol_mid == 0.0_wp )  THEN
-                ol_mid = MIN(ol(j-1,i), ol(j-1,i))
-             ENDIF
-
-             vsws(j,i) = kappa * ( v(k+1,j,i) - v(k,j,i) )                     &
-                                 / ( LOG( z_mo / z0(j,i) )                     &
-                                     - psi_m( z_mo / ol_mid )                  &
-                                     + psi_m( z0(j,i) / ol_mid ) )
-
-             vsws(j,i) = -vsws(j,i) * 0.5_wp * ( us(j-1,i) + us(j,i) )         &
-                                    * rho_air_zw(k)
-
-          ENDDO
-       ENDDO
-
-!
-!--    Exchange the boundaries for the momentum fluxes (is this still required?)
-       CALL exchange_horiz_2d( usws )
-       CALL exchange_horiz_2d( vsws )
-
-!
-!--    Compute the vertical kinematic heat flux
-       IF (  .NOT.  constant_heatflux  .AND.  ( simulated_time <=            &
-            skip_time_do_lsm  .OR.  .NOT.  land_surface )  .AND.             &
-            .NOT.  urban_surface )  THEN
-          !$OMP PARALLEL DO
-          DO  i = nxlg, nxrg
-             DO  j = nysg, nyng
-                k   = nzb_s_inner(j,i)
-                shf(j,i) = -ts(j,i) * us(j,i) * rho_air_zw(k)
-             ENDDO
-          ENDDO
-
-       ENDIF
-
-!
-!--    Compute the vertical water flux
-       IF (  .NOT.  constant_waterflux  .AND.  humidity  .AND.                 &
-             ( simulated_time <= skip_time_do_lsm                              &
-            .OR.  .NOT.  land_surface ) )  THEN
-          !$OMP PARALLEL DO
-          DO  i = nxlg, nxrg
-             DO  j = nysg, nyng
-                k   = nzb_s_inner(j,i)
-                qsws(j,i) = -qs(j,i) * us(j,i) * rho_air_zw(k)
-             ENDDO
-          ENDDO
-
-       ENDIF
-       
-!
-!--    Compute the vertical scalar flux
-       IF (  .NOT.  constant_scalarflux  .AND.  passive_scalar  .AND.          &
-             ( simulated_time <= skip_time_do_lsm                              &
-            .OR.  .NOT.  land_surface ) )  THEN
-          !$OMP PARALLEL DO
-          DO  i = nxlg, nxrg
-             DO  j = nysg, nyng
-                ssws(j,i) = -ss(j,i) * us(j,i)
-             ENDDO
-          ENDDO
-
-       ENDIF       
-
-!
-!--    Compute (turbulent) fluxes of rain water content and rain drop conc.
-       IF ( cloud_physics  .AND.  microphysics_seifert )  THEN
-          !$OMP PARALLEL DO
-          DO  i = nxlg, nxrg
-             DO  j = nysg, nyng
-                qrsws(j,i) = -qrs(j,i) * us(j,i)
-                nrsws(j,i) = -nrs(j,i) * us(j,i)
-             ENDDO
-          ENDDO
-       ENDIF
-
-!
-!--    Bottom boundary condition for the TKE
-       IF ( ibc_e_b == 2 )  THEN
-          !$OMP PARALLEL DO
-          DO  i = nxlg, nxrg
-             DO  j = nysg, nyng
-                k = nzb_s_inner(j,i)
-                e(k+1,j,i) = ( us(j,i) / 0.1_wp )**2
-!
-!--             As a test: cm = 0.4
-!               e(k+1,j,i) = ( us(j,i) / 0.4_wp )**2
-                e(k,j,i)   = e(k+1,j,i)
-             ENDDO
-          ENDDO
+             !$OMP PARALLEL DO PRIVATE( i, j, k, dum, z_mo )
+             DO  m = 1, surf%ns  
+                i = surf%i(m)            
+                j = surf%j(m)
+                k = surf%k(m)
+
+                z_mo = surf%z_mo(m)
+
+                dum = kappa / LOG( z_mo / surf%z0(m) )
+!
+!--             usvs (l=0,1) and vsus (l=2,3)
+                surf%mom_flux_tke(0,m) = dum * ( u_i(m) + v_i(m) )
+!
+!--             wsvs (l=0,1) and wsus (l=2,3)
+                surf%mom_flux_tke(1,m) = dum * w_i(m)
+
+                surf%mom_flux_tke(0:1,m) =                                     &
+                               - surf%mom_flux_tke(0:1,m) * surf%us(m)
+             ENDDO
+!
+!--          Deallocate temporary arrays
+             DEALLOCATE( u_i )             
+             DEALLOCATE( v_i )  
+             DEALLOCATE( w_i )  
+          ENDIF
        ENDIF
 
Index: /palm/trunk/SOURCE/surface_mod.f90
===================================================================
--- /palm/trunk/SOURCE/surface_mod.f90	(revision 2232)
+++ /palm/trunk/SOURCE/surface_mod.f90	(revision 2232)
@@ -0,0 +1,2891 @@
+!> @file surface_mod.f90
+!------------------------------------------------------------------------------!
+! This file is part of PALM.
+!
+! PALM is free software: you can redistribute it and/or modify it under the
+! terms of the GNU General Public License as published by the Free Software
+! Foundation, either version 3 of the License, or (at your option) any later
+! version.
+!
+! PALM is distributed in the hope that it will be useful, but WITHOUT ANY
+! WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+! A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+!
+! You should have received a copy of the GNU General Public License along with
+! PALM. If not, see <http://www.gnu.org/licenses/>.
+!
+! Copyright 1997-2016 Leibniz Universitaet Hannover
+!
+!------------------------------------------------------------------------------!
+! Current revisions:
+! ------------------
+! 
+! 
+! Former revisions:
+! -----------------
+
+! Revision 1.1  2016/12/20 10:06:06  suehring
+! Initial revision
+!
+!
+! Description:
+! ------------
+!> Surface module contains defines derived data structures to treat surface-
+!> bounded grid cells. Three different types of surfaces are defined: 
+!> default surfaces, natural surfaces, and urban surfaces. Moreover, the module
+!> encompasses the initialization of near-surface grid cells, and handles reading 
+!> and writing restart data. 
+!> In addition, a further derived data structure is defined, in order to set
+!> boundary conditions at surfaces.   
+!------------------------------------------------------------------------------!
+ MODULE surface_mod
+
+    USE arrays_3d,                                                             &
+        ONLY:  zu, zw, heatflux_input_conversion, waterflux_input_conversion,  &
+               momentumflux_input_conversion
+
+    USE control_parameters               
+
+    USE indices,                                                               &
+        ONLY:  nxl, nxlg, nxr, nxrg, nys, nysg, nyn, nyng, nzb, nzt, wall_flags_0
+
+    USE grid_variables,                                                        &
+        ONLY:  dx, dy
+
+    USE kinds
+
+    USE model_1d,                                                              &
+        ONLY:  rif1d, us1d, usws1d, vsws1d
+       
+
+    IMPLICIT NONE
+
+!
+!-- Data type used to identify grid-points where horizontal boundary conditions 
+!-- are applied 
+    TYPE bc_type
+
+       INTEGER(iwp) :: ns                                  !< number of surface elements on the PE
+
+       INTEGER(iwp), DIMENSION(:), ALLOCATABLE ::  i       !< x-index linking to the PALM 3D-grid  
+       INTEGER(iwp), DIMENSION(:), ALLOCATABLE ::  j       !< y-index linking to the PALM 3D-grid    
+       INTEGER(iwp), DIMENSION(:), ALLOCATABLE ::  k       !< z-index linking to the PALM 3D-grid   
+
+       INTEGER(iwp), DIMENSION(:,:), ALLOCATABLE :: start_index !< start index within surface data type for given (j,i) 
+       INTEGER(iwp), DIMENSION(:,:), ALLOCATABLE :: end_index   !< end index within surface data type for given (j,i)  
+
+    END TYPE bc_type
+!
+!-- Data type used to identify and treat surface-bounded grid points  
+    TYPE surf_type
+
+       INTEGER(iwp) :: ns                                  !< number of surface elements on the PE
+       INTEGER(iwp), DIMENSION(:), ALLOCATABLE ::  i       !< x-index linking to the PALM 3D-grid  
+       INTEGER(iwp), DIMENSION(:), ALLOCATABLE ::  j       !< y-index linking to the PALM 3D-grid    
+       INTEGER(iwp), DIMENSION(:), ALLOCATABLE ::  k       !< z-index linking to the PALM 3D-grid       
+
+       INTEGER(iwp), DIMENSION(:), ALLOCATABLE ::  facing  !< Bit indicating surface orientation 
+     
+       INTEGER(iwp), DIMENSION(:,:), ALLOCATABLE :: start_index !< Start index within surface data type for given (j,i) 
+       INTEGER(iwp), DIMENSION(:,:), ALLOCATABLE :: end_index   !< End index within surface data type for given (j,i)  
+
+       REAL(wp), DIMENSION(:), ALLOCATABLE ::  z_mo      !< surface-layer height 
+       REAL(wp), DIMENSION(:), ALLOCATABLE ::  uvw_abs   !< absolute surface-parallel velocity
+       REAL(wp), DIMENSION(:), ALLOCATABLE ::  us        !< friction velocity
+       REAL(wp), DIMENSION(:), ALLOCATABLE ::  ts        !< scaling parameter temerature
+       REAL(wp), DIMENSION(:), ALLOCATABLE ::  qs        !< scaling parameter humidity
+       REAL(wp), DIMENSION(:), ALLOCATABLE ::  ss        !< scaling parameter passive scalar
+       REAL(wp), DIMENSION(:), ALLOCATABLE ::  qrs       !< scaling parameter qr
+       REAL(wp), DIMENSION(:), ALLOCATABLE ::  nrs       !< scaling parameter nr
+
+       REAL(wp), DIMENSION(:), ALLOCATABLE ::  ol        !< Obukhov length
+       REAL(wp), DIMENSION(:), ALLOCATABLE ::  rib       !< Richardson bulk number
+
+       REAL(wp), DIMENSION(:), ALLOCATABLE ::  z0        !< roughness length for momentum
+       REAL(wp), DIMENSION(:), ALLOCATABLE ::  z0h       !< roughness length for heat
+       REAL(wp), DIMENSION(:), ALLOCATABLE ::  z0q       !< roughness length for humidity
+
+       REAL(wp), DIMENSION(:), ALLOCATABLE ::  pt1       !< Specific humidity at first grid level (required for cloud_physics = .T.)
+       REAL(wp), DIMENSION(:), ALLOCATABLE ::  qv1       !< Potential temperature at first grid level (required for cloud_physics = .T.)
+!
+!--    Define arrays for surface fluxes
+       REAL(wp), DIMENSION(:), ALLOCATABLE ::  usws      !< vertical momentum flux for u-component at horizontal surfaces
+       REAL(wp), DIMENSION(:), ALLOCATABLE ::  vsws      !< vertical momentum flux for v-component at horizontal surfaces 
+
+       REAL(wp), DIMENSION(:), ALLOCATABLE ::  shf       !< surface flux sensible heat
+       REAL(wp), DIMENSION(:), ALLOCATABLE ::  qsws      !< surface flux latent heat 
+       REAL(wp), DIMENSION(:), ALLOCATABLE ::  ssws      !< surface flux passive scalar
+       REAL(wp), DIMENSION(:), ALLOCATABLE ::  qrsws     !< surface flux qr
+       REAL(wp), DIMENSION(:), ALLOCATABLE ::  nrsws     !< surface flux nr
+       REAL(wp), DIMENSION(:), ALLOCATABLE ::  sasws     !< surface flux salinity
+!
+!--    Required for horizontal walls in production_e
+       REAL(wp), DIMENSION(:), ALLOCATABLE ::  u_0       !< virtual velocity component (see production_e_init for further explanation)
+       REAL(wp), DIMENSION(:), ALLOCATABLE ::  v_0       !< virtual velocity component (see production_e_init for further explanation)
+
+       REAL(wp), DIMENSION(:), ALLOCATABLE   ::  mom_flux_uv  !< momentum flux usvs and vsus at vertical surfaces (used in diffusion_u and diffusion_v)
+       REAL(wp), DIMENSION(:), ALLOCATABLE   ::  mom_flux_w   !< momentum flux wsus and wsvs at vertical surfaces (used in diffusion_w)
+       REAL(wp), DIMENSION(:,:), ALLOCATABLE ::  mom_flux_tke !< momentum flux usvs, vsus, wsus, wsvs at vertical surfaces at grid center (used in production_e)
+!
+!--    Variables required for LSM as well as for USM
+       REAL(wp), DIMENSION(:), ALLOCATABLE   ::  pt_surface        !< skin-surface temperature
+       REAL(wp), DIMENSION(:), ALLOCATABLE   ::  rad_net_l         !< net radiation 
+       REAL(wp), DIMENSION(:,:), ALLOCATABLE ::  lambda_h          !< heat conductivity of soil (W/m/K) 
+
+!
+!--    Variables required for land-surface model    
+       INTEGER(iwp), DIMENSION(:), ALLOCATABLE ::  soil_type_2d    !< soil type, 0: user-defined, 1-7: generic (see list)
+       INTEGER(iwp), DIMENSION(:), ALLOCATABLE ::  veg_type_2d     !< vegetation type, 0: user-defined, 1-19: generic (see list)
+
+       LOGICAL, DIMENSION(:), ALLOCATABLE  ::  building_surface    !< flag parameter indicating that the surface element is covered by buildings (no LSM actions, not implemented yet)
+       LOGICAL, DIMENSION(:), ALLOCATABLE  ::  pave_surface        !< flag parameter for pavements (asphalt etc.) (class 20)
+       LOGICAL, DIMENSION(:), ALLOCATABLE  ::  water_surface       !< flag parameter for water surfaces (classes 14+15)
+
+       REAL(wp), DIMENSION(:), ALLOCATABLE ::  alpha_vg            !< coef. of Van Genuchten
+       REAL(wp), DIMENSION(:), ALLOCATABLE ::  c_liq               !< liquid water coverage (of vegetated area)
+       REAL(wp), DIMENSION(:), ALLOCATABLE ::  c_veg               !< vegetation coverage
+       REAL(wp), DIMENSION(:), ALLOCATABLE ::  f_sw_in             !< fraction of absorbed shortwave radiation by the surface layer (not implemented yet)
+       REAL(wp), DIMENSION(:), ALLOCATABLE ::  ghf_eb              !< ground heat flux
+       REAL(wp), DIMENSION(:), ALLOCATABLE ::  gamma_w_sat         !< hydraulic conductivity at saturation
+       REAL(wp), DIMENSION(:), ALLOCATABLE ::  g_d                 !< coefficient for dependence of r_canopy on water vapour pressure deficit
+       REAL(wp), DIMENSION(:), ALLOCATABLE ::  l_vg                !< coef. of Van Genuchten
+       REAL(wp), DIMENSION(:), ALLOCATABLE ::  lai                 !< leaf area index
+       REAL(wp), DIMENSION(:), ALLOCATABLE ::  lambda_surface_u    !< coupling between surface and soil (depends on vegetation type)
+       REAL(wp), DIMENSION(:), ALLOCATABLE ::  lambda_surface_s    !< coupling between surface and soil (depends on vegetation type)
+       REAL(wp), DIMENSION(:), ALLOCATABLE ::  m_fc                !< soil moisture at field capacity (m3/m3)
+       REAL(wp), DIMENSION(:), ALLOCATABLE ::  m_res               !< residual soil moisture
+       REAL(wp), DIMENSION(:), ALLOCATABLE ::  m_sat               !< saturation soil moisture (m3/m3)
+       REAL(wp), DIMENSION(:), ALLOCATABLE ::  m_wilt              !< soil moisture at permanent wilting point (m3/m3)
+       REAL(wp), DIMENSION(:), ALLOCATABLE ::  n_vg                !< coef. Van Genuchten  
+       REAL(wp), DIMENSION(:), ALLOCATABLE ::  qsws_eb             !< surface flux of latent heat (total)
+       REAL(wp), DIMENSION(:), ALLOCATABLE ::  qsws_liq_eb         !< surface flux of latent heat (liquid water portion)
+       REAL(wp), DIMENSION(:), ALLOCATABLE ::  qsws_soil_eb        !< surface flux of latent heat (soil portion)
+       REAL(wp), DIMENSION(:), ALLOCATABLE ::  qsws_veg_eb         !< surface flux of latent heat (vegetation portion)
+       REAL(wp), DIMENSION(:), ALLOCATABLE ::  r_a                 !< aerodynamic resistance 
+       REAL(wp), DIMENSION(:), ALLOCATABLE ::  r_canopy            !< canopy resistance
+       REAL(wp), DIMENSION(:), ALLOCATABLE ::  r_soil              !< soil resistance
+       REAL(wp), DIMENSION(:), ALLOCATABLE ::  r_soil_min          !< minimum soil resistance
+       REAL(wp), DIMENSION(:), ALLOCATABLE ::  r_s                 !< total surface resistance (combination of r_soil and r_canopy)
+       REAL(wp), DIMENSION(:), ALLOCATABLE ::  r_canopy_min        !< minimum canopy (stomatal) resistance
+       REAL(wp), DIMENSION(:), ALLOCATABLE ::  shf_eb              !< surface flux of sensible heat
+
+       REAL(wp), DIMENSION(:,:), ALLOCATABLE ::  lambda_w          !< hydraulic diffusivity of soil (?)
+       REAL(wp), DIMENSION(:,:), ALLOCATABLE ::  gamma_w           !< hydraulic conductivity of soil (W/m/K)
+       REAL(wp), DIMENSION(:,:), ALLOCATABLE ::  rho_c_total       !< volumetric heat capacity of the actual soil matrix (?) 
+       REAL(wp), DIMENSION(:,:), ALLOCATABLE ::  root_fr           !< root fraction within the soil layers
+!
+!--    Urban surface variables
+       INTEGER(iwp), DIMENSION(:), ALLOCATABLE ::  surface_types   !< array of types of wall parameters
+
+       LOGICAL, DIMENSION(:), ALLOCATABLE  ::  isroof_surf         !< flag indication roof surfaces
+
+       REAL(wp), DIMENSION(:), ALLOCATABLE ::  albedo_surf         !< albedo of the surface
+       REAL(wp), DIMENSION(:), ALLOCATABLE ::  c_surface           !< heat capacity of the wall surface skin ( J mâ2 Kâ1 )
+       REAL(wp), DIMENSION(:), ALLOCATABLE ::  emiss_surf          !< emissivity of the wall surface
+       REAL(wp), DIMENSION(:), ALLOCATABLE ::  lambda_surf         !< heat conductivity Î»S between air and surface ( W mâ2 Kâ1 )
+       REAL(wp), DIMENSION(:), ALLOCATABLE ::  roughness_wall      !< roughness relative to concrete
+       REAL(wp), DIMENSION(:), ALLOCATABLE ::  thickness_wall      !< thickness of the wall, roof and soil layers
+
+       REAL(wp), DIMENSION(:), ALLOCATABLE ::  surfoutsl           !< reflected shortwave radiation for local surface in i-th reflection
+       REAL(wp), DIMENSION(:), ALLOCATABLE ::  surfoutll           !< reflected + emitted longwave radiation for local surface in i-th reflection
+       REAL(wp), DIMENSION(:), ALLOCATABLE ::  surfhf              !< total radiation flux incoming to minus outgoing from local surface
+
+       REAL(wp), DIMENSION(:), ALLOCATABLE ::  tt_surface_m        !< surface temperature tendency (K)
+       REAL(wp), DIMENSION(:), ALLOCATABLE ::  wshf                !< kinematic wall heat flux of sensible heat (actually no longer needed)
+       REAL(wp), DIMENSION(:), ALLOCATABLE ::  wshf_eb             !< wall heat flux of sensible heat in wall normal direction
+
+
+       REAL(wp), DIMENSION(:), ALLOCATABLE ::  wghf_eb             !< wall ground heat flux
+
+       REAL(wp), DIMENSION(:), ALLOCATABLE ::  rad_in_sw           !< incoming shortwave radiation
+       REAL(wp), DIMENSION(:), ALLOCATABLE ::  rad_out_sw          !< emitted shortwave radiation
+       REAL(wp), DIMENSION(:), ALLOCATABLE ::  rad_in_lw           !< incoming longwave radiation
+       REAL(wp), DIMENSION(:), ALLOCATABLE ::  rad_out_lw          !< emitted longwave radiation
+
+       REAL(wp), DIMENSION(:), ALLOCATABLE ::  surfinsw            !< shortwave radiation falling to local surface including radiation from reflections
+       REAL(wp), DIMENSION(:), ALLOCATABLE ::  surfoutsw           !< total shortwave radiation outgoing from nonvirtual surfaces surfaces after all reflection
+       REAL(wp), DIMENSION(:), ALLOCATABLE ::  surfinlw            !< longwave radiation falling to local surface including radiation from reflections
+       REAL(wp), DIMENSION(:), ALLOCATABLE ::  surfoutlw           !< total longwave radiation outgoing from nonvirtual surfaces surfaces after all reflection
+
+
+       REAL(wp), DIMENSION(:,:), ALLOCATABLE ::  rho_c_wall        !< volumetric heat capacity of the material ( J m-3 K-1 ) (= 2.19E6)
+       REAL(wp), DIMENSION(:,:), ALLOCATABLE ::  dz_wall           !< wall grid spacing (center-center)
+       REAL(wp), DIMENSION(:,:), ALLOCATABLE ::  ddz_wall          !< 1/dz_wall
+       REAL(wp), DIMENSION(:,:), ALLOCATABLE ::  dz_wall_stag      !< wall grid spacing (edge-edge)
+       REAL(wp), DIMENSION(:,:), ALLOCATABLE ::  ddz_wall_stag     !< 1/dz_wall_stag
+       REAL(wp), DIMENSION(:,:), ALLOCATABLE ::  tt_wall_m         !< t_wall prognostic array 
+       REAL(wp), DIMENSION(:,:), ALLOCATABLE ::  zw                !< wall layer depths (m)
+
+
+!-- arrays for time averages
+       REAL(wp), DIMENSION(:), ALLOCATABLE ::  rad_net_av       !< average of rad_net_l
+       REAL(wp), DIMENSION(:), ALLOCATABLE ::  surfinsw_av      !< average of sw radiation falling to local surface including radiation from reflections
+       REAL(wp), DIMENSION(:), ALLOCATABLE ::  surfinlw_av      !< average of lw radiation falling to local surface including radiation from reflections
+       REAL(wp), DIMENSION(:), ALLOCATABLE ::  surfinswdir_av   !< average of direct sw radiation falling to local surface
+       REAL(wp), DIMENSION(:), ALLOCATABLE ::  surfinswdif_av   !< average of diffuse sw radiation from sky and model boundary falling to local surface
+       REAL(wp), DIMENSION(:), ALLOCATABLE ::  surfinlwdif_av   !< average of diffuse lw radiation from sky and model boundary falling to local surface
+       REAL(wp), DIMENSION(:), ALLOCATABLE ::  surfinswref_av   !< average of sw radiation falling to surface from reflections
+       REAL(wp), DIMENSION(:), ALLOCATABLE ::  surfinlwref_av   !< average of lw radiation falling to surface from reflections
+       REAL(wp), DIMENSION(:), ALLOCATABLE ::  surfoutsw_av     !< average of total sw radiation outgoing from nonvirtual surfaces surfaces after all reflection
+       REAL(wp), DIMENSION(:), ALLOCATABLE ::  surfoutlw_av     !< average of total lw radiation outgoing from nonvirtual surfaces surfaces after all reflection
+       REAL(wp), DIMENSION(:), ALLOCATABLE ::  surfins_av       !< average of array of residua of sw radiation absorbed in surface after last reflection
+       REAL(wp), DIMENSION(:), ALLOCATABLE ::  surfinl_av       !< average of array of residua of lw radiation absorbed in surface after last reflection
+       REAL(wp), DIMENSION(:), ALLOCATABLE ::  surfhf_av        !< average of total radiation flux incoming to minus outgoing from local surface  
+       REAL(wp), DIMENSION(:), ALLOCATABLE ::  wghf_eb_av       !< average of wghf_eb
+       REAL(wp), DIMENSION(:), ALLOCATABLE ::  wshf_eb_av       !< average of wshf_eb
+       REAL(wp), DIMENSION(:), ALLOCATABLE ::  t_surf_av        !< average of wall surface temperature (K)
+
+       REAL(wp), DIMENSION(:,:), ALLOCATABLE ::  t_wall_av      !< Average of t_wall
+
+    END TYPE surf_type
+
+    TYPE (bc_type), DIMENSION(0:1)           ::  bc_h        !< boundary condition data type, horizontal upward- and downward facing surfaces
+
+    TYPE (surf_type), DIMENSION(0:2), TARGET ::  surf_def_h  !< horizontal default surfaces (Up, Down, and Top)
+    TYPE (surf_type), DIMENSION(0:3), TARGET ::  surf_def_v  !< vertical default surfaces (North, South, West, East)
+    TYPE (surf_type)                , TARGET ::  surf_lsm_h  !< horizontal natural land surfaces, so far only upward-facing
+    TYPE (surf_type), DIMENSION(0:3), TARGET ::  surf_lsm_v  !< vertical land surfaces (North, South, West, East)
+    TYPE (surf_type)                , TARGET ::  surf_usm_h  !< horizontal urban surfaces, so far only upward-facing
+    TYPE (surf_type), DIMENSION(0:3), TARGET ::  surf_usm_v  !< vertical urban surfaces (North, South, West, East)
+
+    INTEGER(iwp) ::  ns_h_on_file(0:2)                       !< total number of horizontal surfaces with the same facing, required for writing restart data 
+    INTEGER(iwp) ::  ns_v_on_file(0:3)                       !< total number of vertical surfaces with the same facing, required for writing restart data 
+
+
+    SAVE
+
+    PRIVATE
+!
+!-- Public variables
+    PUBLIC bc_h, ns_h_on_file, ns_v_on_file, surf_def_h, surf_def_v,           &
+           surf_lsm_h, surf_lsm_v, surf_usm_h, surf_usm_v, surf_type
+!
+!-- Public subroutines
+    PUBLIC init_bc, init_surfaces, init_surface_arrays,                        &
+           surface_read_restart_data, surface_write_restart_data,              &
+           surface_last_actions
+
+    INTERFACE init_bc
+       MODULE PROCEDURE init_bc
+    END INTERFACE init_bc
+
+    INTERFACE init_surfaces
+       MODULE PROCEDURE init_surfaces
+    END INTERFACE init_surfaces
+
+    INTERFACE init_surface_arrays
+       MODULE PROCEDURE init_surface_arrays
+    END INTERFACE init_surface_arrays
+
+    INTERFACE surface_read_restart_data
+       MODULE PROCEDURE surface_read_restart_data
+    END INTERFACE surface_read_restart_data
+
+    INTERFACE surface_write_restart_data
+       MODULE PROCEDURE surface_write_restart_data
+    END INTERFACE surface_write_restart_data
+
+    INTERFACE surface_last_actions
+       MODULE PROCEDURE surface_last_actions
+    END INTERFACE surface_last_actions
+
+
+ CONTAINS
+
+!------------------------------------------------------------------------------!
+! Description:
+! ------------
+!> Initialize data type for setting boundary conditions at horizontal surfaces. 
+!------------------------------------------------------------------------------!
+    SUBROUTINE init_bc
+
+       IMPLICIT NONE
+
+       INTEGER(iwp) ::  i         !<
+       INTEGER(iwp) ::  j         !<
+       INTEGER(iwp) ::  k         !<
+
+       INTEGER(iwp), DIMENSION(0:1) ::  num_h         !<
+       INTEGER(iwp), DIMENSION(0:1) ::  num_h_kji     !<
+       INTEGER(iwp), DIMENSION(0:1) ::  start_index_h !<
+
+!
+!--    First of all, count the number of upward- and downward-facing surfaces
+       num_h = 0
+       DO  i = nxlg, nxrg
+          DO  j = nysg, nyng
+             DO  k = nzb+1, nzt
+!
+!--             Check if current gridpoint belongs to the atmosphere
+                IF ( BTEST( wall_flags_0(k,j,i), 0 ) )  THEN
+!
+!--                Upward-facing
+                   IF ( .NOT. BTEST( wall_flags_0(k-1,j,i), 0 ) )              &
+                      num_h(0) = num_h(0) + 1
+!
+!--                Downward-facing
+                   IF ( .NOT. BTEST( wall_flags_0(k+1,j,i), 0 ) )              &
+                      num_h(1) = num_h(1) + 1
+                ENDIF
+             ENDDO
+          ENDDO
+       ENDDO
+!
+!--    Save the number of surface elements
+       bc_h(0)%ns = num_h(0)
+       bc_h(1)%ns = num_h(1)
+!
+!--    ALLOCATE data type variables
+!--    Upward facing
+       ALLOCATE( bc_h(0)%i(1:bc_h(0)%ns) )
+       ALLOCATE( bc_h(0)%j(1:bc_h(0)%ns) )
+       ALLOCATE( bc_h(0)%k(1:bc_h(0)%ns) )
+       ALLOCATE( bc_h(0)%start_index(nysg:nyng,nxlg:nxrg) )
+       ALLOCATE( bc_h(0)%end_index(nysg:nyng,nxlg:nxrg)   )
+       bc_h(0)%start_index = 1
+       bc_h(0)%end_index   = 0
+!
+!--    Downward facing
+       ALLOCATE( bc_h(1)%i(1:bc_h(1)%ns) )
+       ALLOCATE( bc_h(1)%j(1:bc_h(1)%ns) )
+       ALLOCATE( bc_h(1)%k(1:bc_h(1)%ns) )
+       ALLOCATE( bc_h(1)%start_index(nysg:nyng,nxlg:nxrg) )
+       ALLOCATE( bc_h(1)%end_index(nysg:nyng,nxlg:nxrg)   )
+       bc_h(1)%start_index = 1
+       bc_h(1)%end_index   = 0
+!
+!--    Store the respective indices on data type
+       num_h(0:1)         = 1
+       start_index_h(0:1) = 1
+       DO  i = nxlg, nxrg
+          DO  j = nysg, nyng
+
+             num_h_kji(0:1) = 0
+             DO  k = nzb+1, nzt
+!
+!--             Check if current gridpoint belongs to the atmosphere
+                IF ( BTEST( wall_flags_0(k,j,i), 0 ) )  THEN
+!
+!--                Upward-facing
+                   IF ( .NOT. BTEST( wall_flags_0(k-1,j,i), 0 ) )  THEN
+                      bc_h(0)%i(num_h(0)) = i
+                      bc_h(0)%j(num_h(0)) = j
+                      bc_h(0)%k(num_h(0)) = k
+                      num_h_kji(0)        = num_h_kji(0) + 1
+                      num_h(0)            = num_h(0) + 1
+                   ENDIF
+!
+!--                Downward-facing
+                   IF ( .NOT. BTEST( wall_flags_0(k+1,j,i), 0 ) )  THEN
+                      bc_h(1)%i(num_h(1)) = i
+                      bc_h(1)%j(num_h(1)) = j
+                      bc_h(1)%k(num_h(1)) = k
+                      num_h_kji(1)        = num_h_kji(1) + 1
+                      num_h(1)            = num_h(1) + 1
+                   ENDIF
+                ENDIF
+             ENDDO
+             bc_h(0)%start_index(j,i) = start_index_h(0)
+             bc_h(0)%end_index(j,i)   = bc_h(0)%start_index(j,i) + num_h_kji(0) - 1
+             start_index_h(0)         = bc_h(0)%end_index(j,i) + 1
+
+             bc_h(1)%start_index(j,i) = start_index_h(1)
+             bc_h(1)%end_index(j,i)   = bc_h(1)%start_index(j,i) + num_h_kji(1) - 1
+             start_index_h(1)         = bc_h(1)%end_index(j,i) + 1
+          ENDDO
+       ENDDO
+
+
+    END SUBROUTINE init_bc
+
+
+!------------------------------------------------------------------------------!
+! Description:
+! ------------
+!> Initialize horizontal and vertical surfaces. Counts the number of default-,
+!> natural and urban surfaces and allocates memory, respectively. 
+!------------------------------------------------------------------------------!
+    SUBROUTINE init_surface_arrays
+
+       IMPLICIT NONE
+
+       INTEGER(iwp)                 ::  i         !< running index x-direction 
+       INTEGER(iwp)                 ::  j         !< running index y-direction
+       INTEGER(iwp)                 ::  k         !< running index z-direction
+       INTEGER(iwp)                 ::  l         !< index variable for surface facing
+       INTEGER(iwp)                 ::  num_lsm_h !< number of horizontally-aligned natural surfaces 
+       INTEGER(iwp)                 ::  num_usm_h !< number of horizontally-aligned urban surfaces 
+
+       INTEGER(iwp), DIMENSION(0:2) ::  num_def_h !< number of horizontally-aligned default surfaces 
+       INTEGER(iwp), DIMENSION(0:3) ::  num_def_v !< number of vertically-aligned default surfaces 
+       INTEGER(iwp), DIMENSION(0:3) ::  num_lsm_v !< number of vertically-aligned natural surfaces 
+       INTEGER(iwp), DIMENSION(0:3) ::  num_usm_v !< number of vertically-aligned urban surfaces 
+
+
+       num_def_h = 0
+       num_def_v = 0
+       num_lsm_h = 0
+       num_lsm_v = 0
+       num_usm_h = 0
+       num_usm_v = 0
+!
+!--    Count number of horizontal surfaces on local domain 
+       DO  i = nxl, nxr
+          DO  j = nys, nyn
+             DO  k = nzb+1, nzt
+!
+!--             Check if current gridpoint belongs to the atmosphere
+                IF ( BTEST( wall_flags_0(k,j,i), 0 ) )  THEN
+!
+!--                Check if grid point adjoins to any upward-facing horizontal
+!--                surface, e.g. the Earth surface, plane roofs, or ceilings.
+                   IF ( .NOT. BTEST( wall_flags_0(k-1,j,i), 0 ) )  THEN
+!
+!--                   Land-surface type
+                      IF ( land_surface )  THEN
+                         num_lsm_h    = num_lsm_h    + 1 
+!
+!--                   Urban surface tpye
+                      ELSEIF ( urban_surface )  THEN 
+                         num_usm_h    = num_usm_h    + 1 
+!
+!--                   Default-surface type
+                      ELSE
+                         num_def_h(0) = num_def_h(0) + 1 
+                      ENDIF
+
+                   ENDIF
+!
+!--                Check for top-fluxes
+                   IF ( k == nzt  .AND.  use_top_fluxes )  THEN
+                      num_def_h(2) = num_def_h(2) + 1
+!
+!--                Check for any other downward-facing surface. So far only for 
+!--                default surface type.
+                   ELSEIF ( .NOT. BTEST( wall_flags_0(k+1,j,i), 0 ) )  THEN
+                      num_def_h(1) = num_def_h(1) + 1
+                   ENDIF 
+
+                ENDIF
+             ENDDO
+          ENDDO
+       ENDDO
+!
+!--    Count number of vertical surfaces on local domain 
+       DO  i = nxl, nxr
+          DO  j = nys, nyn
+             DO  k = nzb+1, nzt
+                IF ( BTEST( wall_flags_0(k,j,i), 0 ) )  THEN
+!
+!--                Northward-facing
+                   IF ( .NOT. BTEST( wall_flags_0(k,j-1,i), 0 ) )  THEN
+                      IF ( urban_surface )  THEN
+                         num_usm_v(0) = num_usm_v(0) + 1 
+                      ELSEIF ( land_surface )  THEN
+                         num_lsm_v(0) = num_lsm_v(0) + 1 
+                      ELSE
+                         num_def_v(0) = num_def_v(0) + 1 
+                      ENDIF
+                   ENDIF
+!
+!--                Southward-facing
+                   IF ( .NOT. BTEST( wall_flags_0(k,j+1,i), 0 ) )  THEN
+                      IF ( urban_surface )  THEN
+                         num_usm_v(1) = num_usm_v(1) + 1 
+                      ELSEIF ( land_surface )  THEN
+                         num_lsm_v(1) = num_lsm_v(1) + 1 
+                      ELSE
+                         num_def_v(1) = num_def_v(1) + 1 
+                      ENDIF
+                   ENDIF
+!
+!--                Eastward-facing
+                   IF ( .NOT. BTEST( wall_flags_0(k,j,i-1), 0 ) )  THEN
+                      IF ( urban_surface )  THEN
+                         num_usm_v(2) = num_usm_v(2) + 1 
+                      ELSEIF ( land_surface )  THEN
+                         num_lsm_v(2) = num_lsm_v(2) + 1 
+                      ELSE
+                         num_def_v(2) = num_def_v(2) + 1 
+                      ENDIF
+                   ENDIF
+!
+!--                Westward-facing
+                   IF ( .NOT. BTEST( wall_flags_0(k,j,i+1), 0 ) )  THEN
+                      IF ( urban_surface )  THEN
+                         num_usm_v(3) = num_usm_v(3) + 1
+                      ELSEIF ( land_surface )  THEN
+                         num_lsm_v(3) = num_lsm_v(3) + 1  
+                      ELSE
+                         num_def_v(3) = num_def_v(3) + 1 
+                      ENDIF
+                   ENDIF
+                ENDIF
+             ENDDO
+          ENDDO
+       ENDDO
+
+!
+!--    Store number of surfaces per core.
+!--    Horizontal surface, default type, upward facing
+       surf_def_h(0)%ns = num_def_h(0)
+!
+!--    Horizontal surface, default type, downward facing
+       surf_def_h(1)%ns = num_def_h(1)
+!
+!--    Horizontal surface, default type, top downward facing
+       surf_def_h(2)%ns = num_def_h(2)
+!
+!--    Horizontal surface, natural type, so far only upward-facing
+       surf_lsm_h%ns    = num_lsm_h  
+!
+!--    Horizontal surface, urban type, so far only upward-facing
+       surf_usm_h%ns    = num_usm_h    
+!
+!--    Vertical surface, default type, northward facing
+       surf_def_v(0)%ns = num_def_v(0)
+!
+!--    Vertical surface, default type, southward facing
+       surf_def_v(1)%ns = num_def_v(1)
+!
+!--    Vertical surface, default type, eastward facing
+       surf_def_v(2)%ns = num_def_v(2)
+!
+!--    Vertical surface, default type, westward facing
+       surf_def_v(3)%ns = num_def_v(3)
+!
+!--    Vertical surface, natural type, northward facing
+       surf_lsm_v(0)%ns = num_lsm_v(0)
+!
+!--    Vertical surface, natural type, southward facing
+       surf_lsm_v(1)%ns = num_lsm_v(1)
+!
+!--    Vertical surface, natural type, eastward facing
+       surf_lsm_v(2)%ns = num_lsm_v(2)
+!
+!--    Vertical surface, natural type, westward facing
+       surf_lsm_v(3)%ns = num_lsm_v(3)
+!
+!--    Vertical surface, urban type, northward facing
+       surf_usm_v(0)%ns = num_usm_v(0)
+!
+!--    Vertical surface, urban type, southward facing
+       surf_usm_v(1)%ns = num_usm_v(1)
+!
+!--    Vertical surface, urban type, eastward facing
+       surf_usm_v(2)%ns = num_usm_v(2)
+!
+!--    Vertical surface, urban type, westward facing
+       surf_usm_v(3)%ns = num_usm_v(3)
+!
+!--    Allocate required attributes for horizontal surfaces - default type. 
+!--    Upward-facing (l=0) and downward-facing (l=1).
+       DO  l = 0, 1
+          CALL allocate_surface_attributes_h ( surf_def_h(l), nys, nyn, nxl, nxr )
+       ENDDO
+!
+!--    Allocate required attributes for model top
+       CALL allocate_surface_attributes_h_top ( surf_def_h(2), nys, nyn, nxl, nxr )
+!
+!--    Allocate required attributes for horizontal surfaces - natural type. 
+       CALL allocate_surface_attributes_h ( surf_lsm_h, nys, nyn, nxl, nxr )
+!
+!--    Allocate required attributes for horizontal surfaces - urban type. 
+       CALL allocate_surface_attributes_h ( surf_usm_h, nys, nyn, nxl, nxr )
+
+!
+!--    Allocate required attributes for vertical surfaces. 
+!--    Northward-facing (l=0), southward-facing (l=1), eastward-facing (l=2)
+!--    and westward-facing (l=3).
+!--    Default type.
+       DO  l = 0, 3
+          CALL allocate_surface_attributes_v ( surf_def_v(l), .FALSE.,         &
+                                               nys, nyn, nxl, nxr )
+       ENDDO
+!
+!--    Natural type
+       DO  l = 0, 3
+          CALL allocate_surface_attributes_v ( surf_lsm_v(l), .TRUE.,          &
+                                               nys, nyn, nxl, nxr )
+       ENDDO
+!
+!--    Urban type
+       DO  l = 0, 3
+          CALL allocate_surface_attributes_v ( surf_usm_v(l), .FALSE.,         &
+                                               nys, nyn, nxl, nxr )
+       ENDDO
+
+    END SUBROUTINE init_surface_arrays
+
+!------------------------------------------------------------------------------!
+! Description:
+! ------------
+!> Allocating memory for upward and downward-facing horizontal surface types, 
+!> except for top fluxes. 
+!------------------------------------------------------------------------------!
+    SUBROUTINE allocate_surface_attributes_h( surfaces,                        &
+                                              nys_l, nyn_l, nxl_l, nxr_l )
+
+       IMPLICIT NONE
+
+       INTEGER(iwp) ::  nyn_l  !< north bound of local 2d array start/end_index, is equal to nyn, except for restart-array
+       INTEGER(iwp) ::  nys_l  !< south bound of local 2d array start/end_index, is equal to nyn, except for restart-array
+       INTEGER(iwp) ::  nxl_l  !< west bound of local 2d array start/end_index, is equal to nyn, except for restart-array
+       INTEGER(iwp) ::  nxr_l  !< east bound of local 2d array start/end_index, is equal to nyn, except for restart-array
+
+       TYPE(surf_type) ::  surfaces  !< respective surface type
+
+!
+!--    Allocate arrays for start and end index of horizontal surface type 
+!--    for each (j,i)-grid point. This is required e.g. in diffion_x, which is
+!--    called for each (j,i). In order to find the location where the 
+!--    respective flux is store within the surface-type, start- and end- 
+!--    index are stored for each (j,i). For example, each (j,i) can have
+!--    several entries where fluxes for horizontal surfaces might be stored,
+!--    e.g. for overhanging structures where several upward-facing surfaces
+!--    might exist for given (j,i).
+!--    If no surface of respective type exist at current (j,i), set indicies
+!--    such that loop in diffusion routines will not be entered. 
+       ALLOCATE ( surfaces%start_index(nys_l:nyn_l,nxl_l:nxr_l) )
+       ALLOCATE ( surfaces%end_index(nys_l:nyn_l,nxl_l:nxr_l)   )
+       surfaces%start_index = 0
+       surfaces%end_index   = -1
+!
+!--    Indices to locate surface element
+       ALLOCATE ( surfaces%i(1:surfaces%ns)  )
+       ALLOCATE ( surfaces%j(1:surfaces%ns)  )
+       ALLOCATE ( surfaces%k(1:surfaces%ns)  )
+!
+!--    Surface-layer height
+       ALLOCATE ( surfaces%z_mo(1:surfaces%ns) )
+!
+!--    Surface orientation
+       ALLOCATE ( surfaces%facing(1:surfaces%ns) )
+!
+!--    Surface-parallel wind velocity
+       ALLOCATE ( surfaces%uvw_abs(1:surfaces%ns) )
+!      ALLOCATE ( surfaces%pt_surface(1:surfaces%ns) )
+!
+!--    Roughness
+       ALLOCATE ( surfaces%z0(1:surfaces%ns)  )
+       ALLOCATE ( surfaces%z0h(1:surfaces%ns) )
+       ALLOCATE ( surfaces%z0q(1:surfaces%ns) )
+!
+!--    Friction velocity
+       ALLOCATE ( surfaces%us(1:surfaces%ns) )
+!
+!--    Stability parameter
+       ALLOCATE ( surfaces%ol(1:surfaces%ns) )
+!
+!--    Bulk Richardson number
+       ALLOCATE ( surfaces%rib(1:surfaces%ns) )
+!
+!--    Vertical momentum fluxes of u and v
+       ALLOCATE ( surfaces%usws(1:surfaces%ns) )  
+       ALLOCATE ( surfaces%vsws(1:surfaces%ns) )  
+!
+!--    Required in production_e
+       IF ( .NOT. constant_diffusion )  THEN    
+          ALLOCATE ( surfaces%u_0(1:surfaces%ns) )  
+          ALLOCATE ( surfaces%v_0(1:surfaces%ns) )
+       ENDIF 
+!
+!--    Characteristic temperature and surface flux of sensible heat
+       ALLOCATE ( surfaces%ts(1:surfaces%ns)  )    
+       ALLOCATE ( surfaces%shf(1:surfaces%ns) )    
+!
+!--    Characteristic humidity and surface flux of latent heat
+       IF ( humidity )  THEN
+          ALLOCATE ( surfaces%qs(1:surfaces%ns)   ) 
+          ALLOCATE ( surfaces%qsws(1:surfaces%ns) )      
+       ENDIF 
+!
+!--    Characteristic scalar and surface flux of scalar
+       IF ( passive_scalar )  THEN
+          ALLOCATE ( surfaces%ss(1:surfaces%ns)   )   
+          ALLOCATE ( surfaces%ssws(1:surfaces%ns) ) 
+       ENDIF 
+!
+!--    When cloud physics is used, arrays for storing potential temperature and
+!--    specific humidity at first grid level are required. 
+       IF ( cloud_physics )  THEN
+          ALLOCATE ( surfaces%pt1(1:surfaces%ns) )
+          ALLOCATE ( surfaces%qv1(1:surfaces%ns) )
+       ENDIF
+!
+!--       
+       IF ( cloud_physics .AND. microphysics_seifert)  THEN
+          ALLOCATE ( surfaces%qrs(1:surfaces%ns)   )
+          ALLOCATE ( surfaces%nrs(1:surfaces%ns)   )
+          ALLOCATE ( surfaces%qrsws(1:surfaces%ns) )
+          ALLOCATE ( surfaces%nrsws(1:surfaces%ns) )
+       ENDIF
+!
+!--    Salinity surface flux
+       IF ( ocean )  ALLOCATE ( surfaces%sasws(1:surfaces%ns) )
+
+    END SUBROUTINE allocate_surface_attributes_h
+
+
+!------------------------------------------------------------------------------!
+! Description:
+! ------------
+!> Allocating memory for model-top fluxes  
+!------------------------------------------------------------------------------!
+    SUBROUTINE allocate_surface_attributes_h_top( surfaces,                    &
+                                                  nys_l, nyn_l, nxl_l, nxr_l )
+
+       IMPLICIT NONE
+
+       INTEGER(iwp) ::  nyn_l  !< north bound of local 2d array start/end_index, is equal to nyn, except for restart-array
+       INTEGER(iwp) ::  nys_l  !< south bound of local 2d array start/end_index, is equal to nyn, except for restart-array
+       INTEGER(iwp) ::  nxl_l  !< west bound of local 2d array start/end_index, is equal to nyn, except for restart-array
+       INTEGER(iwp) ::  nxr_l  !< east bound of local 2d array start/end_index, is equal to nyn, except for restart-array
+
+       TYPE(surf_type) ::  surfaces !< respective surface type
+
+       ALLOCATE ( surfaces%start_index(nys_l:nyn_l,nxl_l:nxr_l) )
+       ALLOCATE ( surfaces%end_index(nys_l:nyn_l,nxl_l:nxr_l)   )
+       surfaces%start_index = 0
+       surfaces%end_index   = -1
+!
+!--    Indices to locate surface (model-top) element
+       ALLOCATE ( surfaces%i(1:surfaces%ns)  )
+       ALLOCATE ( surfaces%j(1:surfaces%ns)  )
+       ALLOCATE ( surfaces%k(1:surfaces%ns)  )
+!
+!--    Vertical momentum fluxes of u and v
+       ALLOCATE ( surfaces%usws(1:surfaces%ns) )  
+       ALLOCATE ( surfaces%vsws(1:surfaces%ns) )  
+!
+!--    Sensible heat flux
+       ALLOCATE ( surfaces%shf(1:surfaces%ns) )    
+!
+!--    Latent heat flux
+       IF ( humidity )  THEN
+          ALLOCATE ( surfaces%qsws(1:surfaces%ns) )      
+       ENDIF 
+!
+!--    Scalar flux
+       IF ( passive_scalar )  THEN
+          ALLOCATE ( surfaces%ssws(1:surfaces%ns) ) 
+       ENDIF 
+!
+!--       
+       IF ( cloud_physics .AND. microphysics_seifert)  THEN
+          ALLOCATE ( surfaces%qrsws(1:surfaces%ns) )
+          ALLOCATE ( surfaces%nrsws(1:surfaces%ns) )
+       ENDIF
+!
+!--    Salinity flux
+       IF ( ocean )  ALLOCATE ( surfaces%sasws(1:surfaces%ns) )
+
+    END SUBROUTINE allocate_surface_attributes_h_top
+
+!------------------------------------------------------------------------------!
+! Description:
+! ------------
+!> Allocating memory for vertical surface types. 
+!------------------------------------------------------------------------------!
+    SUBROUTINE allocate_surface_attributes_v( surfaces, lsm,                   &
+                                              nys_l, nyn_l, nxl_l, nxr_l )
+
+       IMPLICIT NONE
+
+       INTEGER(iwp) ::  nyn_l  !< north bound of local 2d array start/end_index, is equal to nyn, except for restart-array
+       INTEGER(iwp) ::  nys_l  !< south bound of local 2d array start/end_index, is equal to nyn, except for restart-array
+       INTEGER(iwp) ::  nxl_l  !< west bound of local 2d array start/end_index, is equal to nyn, except for restart-array
+       INTEGER(iwp) ::  nxr_l  !< east bound of local 2d array start/end_index, is equal to nyn, except for restart-array
+
+       LOGICAL         ::  lsm      !< flag indicating data type of natural land surface
+
+       TYPE(surf_type) ::  surfaces !< respective surface type
+
+!
+!--    Allocate arrays for start and end index of vertical surface type 
+!--    for each (j,i)-grid point. This is required in diffion_x, which is
+!--    called for each (j,i). In order to find the location where the 
+!--    respective flux is store within the surface-type, start- and end- 
+!--    index are stored for each (j,i). For example, each (j,i) can have
+!--    several entries where fluxes for vertical surfaces might be stored.  
+!--    In the flat case, where no vertical walls exit, set indicies such 
+!--    that loop in diffusion routines will not be entered. 
+       ALLOCATE ( surfaces%start_index(nys_l:nyn_l,nxl_l:nxr_l) )
+       ALLOCATE ( surfaces%end_index(nys_l:nyn_l,nxl_l:nxr_l)   )
+       surfaces%start_index = 0
+       surfaces%end_index   = -1
+!
+!--    Indices to locate surface element.
+       ALLOCATE ( surfaces%i(1:surfaces%ns) )
+       ALLOCATE ( surfaces%j(1:surfaces%ns) )
+       ALLOCATE ( surfaces%k(1:surfaces%ns) )
+!
+!--    Surface-layer height
+       ALLOCATE ( surfaces%z_mo(1:surfaces%ns) )
+!
+!--    Surface orientation
+       ALLOCATE ( surfaces%facing(1:surfaces%ns) )
+!
+!--    Surface parallel wind velocity
+       ALLOCATE ( surfaces%uvw_abs(1:surfaces%ns) )
+!
+!--    Roughness
+       ALLOCATE ( surfaces%z0(1:surfaces%ns)  )
+       ALLOCATE ( surfaces%z0h(1:surfaces%ns) )
+       ALLOCATE ( surfaces%z0q(1:surfaces%ns) )
+
+!
+!--    Friction velocity
+       ALLOCATE ( surfaces%us(1:surfaces%ns) )
+!
+!--    Allocate Obukhov length and bulk Richardson number. Only required 
+!--    for natural land surfaces
+       IF ( lsm )  THEN
+          ALLOCATE( surfaces%ol(1:surfaces%ns)  ) 
+          ALLOCATE( surfaces%rib(1:surfaces%ns) ) 
+       ENDIF
+!
+!--    Allocate arrays for surface momentum fluxes for u and v. For u at north- 
+!--    and south-facing surfaces, for v at east- and west-facing surfaces.
+       ALLOCATE ( surfaces%mom_flux_uv(1:surfaces%ns) )
+!
+!--    Allocate array for surface momentum flux for w - wsus and wsvs
+       ALLOCATE ( surfaces%mom_flux_w(1:surfaces%ns) ) 
+!
+!--    Allocate array for surface momentum flux for subgrid-scale tke wsus and 
+!--    wsvs; first index usvs or vsws, second index for wsus or wsvs, depending
+!--    on surface.
+       ALLOCATE ( surfaces%mom_flux_tke(0:1,1:surfaces%ns) )  
+!
+!--    Characteristic temperature and surface flux of sensible heat
+       ALLOCATE ( surfaces%ts(1:surfaces%ns)  )    
+       ALLOCATE ( surfaces%shf(1:surfaces%ns) )    
+!
+!--    Characteristic humidity and surface flux of latent heat
+       IF ( humidity )  THEN
+          ALLOCATE ( surfaces%qs(1:surfaces%ns)   ) 
+          ALLOCATE ( surfaces%qsws(1:surfaces%ns) )      
+       ENDIF 
+!
+!--    Characteristic scalar and surface flux of scalar
+       IF ( passive_scalar )  THEN
+          ALLOCATE ( surfaces%ss(1:surfaces%ns)   )   
+          ALLOCATE ( surfaces%ssws(1:surfaces%ns) ) 
+       ENDIF 
+
+       IF ( cloud_physics .AND. microphysics_seifert)  THEN
+          ALLOCATE ( surfaces%qrs(1:surfaces%ns)   )
+          ALLOCATE ( surfaces%nrs(1:surfaces%ns)   )
+          ALLOCATE ( surfaces%qrsws(1:surfaces%ns) )
+          ALLOCATE ( surfaces%nrsws(1:surfaces%ns) )
+       ENDIF
+!
+!--    Salinity surface flux
+       IF ( ocean )  ALLOCATE ( surfaces%sasws(1:surfaces%ns) )
+
+    END SUBROUTINE allocate_surface_attributes_v
+
+!------------------------------------------------------------------------------!
+! Description:
+! ------------
+!> Initialize surface elements. 
+!------------------------------------------------------------------------------!
+    SUBROUTINE init_surfaces
+
+       IMPLICIT NONE
+
+       INTEGER(iwp) ::  i         !< running index x-direction
+       INTEGER(iwp) ::  j         !< running index y-direction
+       INTEGER(iwp) ::  k         !< running index z-direction
+       INTEGER(iwp) ::  l         !< index variable used to distinguish surface facing
+       INTEGER(iwp) ::  m         !< running index surface elements
+
+       INTEGER(iwp)                 ::  start_index_lsm_h !< dummy to determing local start index in surface type for given (j,i), for horizontal natural surfaces
+       INTEGER(iwp)                 ::  start_index_usm_h !< dummy to determing local start index in surface type for given (j,i), for horizontal urban surfaces
+
+       INTEGER(iwp)                 ::  num_lsm_h     !< current number of horizontal surface element, natural type
+       INTEGER(iwp)                 ::  num_lsm_h_kji !< dummy to determing local end index in surface type for given (j,i), for for horizonal natural surfaces
+       INTEGER(iwp)                 ::  num_usm_h     !< current number of horizontal surface element, urban type
+       INTEGER(iwp)                 ::  num_usm_h_kji !< dummy to determing local end index in surface type for given (j,i), for for horizonal urban surfaces
+
+       INTEGER(iwp), DIMENSION(0:2) ::  num_def_h     !< current number of horizontal surface element, default type
+       INTEGER(iwp), DIMENSION(0:2) ::  num_def_h_kji !< dummy to determing local end index in surface type for given (j,i), for horizonal default surfaces
+       INTEGER(iwp), DIMENSION(0:2) ::  start_index_def_h !< dummy to determing local start index in surface type for given (j,i), for horizontal default surfaces
+     
+       INTEGER(iwp), DIMENSION(0:3) ::  num_def_v     !< current number of vertical surface element, default type
+       INTEGER(iwp), DIMENSION(0:3) ::  num_def_v_kji !< dummy to determing local end index in surface type for given (j,i), for vertical default surfaces
+       INTEGER(iwp), DIMENSION(0:3) ::  num_lsm_v     !< current number of vertical surface element, natural type
+       INTEGER(iwp), DIMENSION(0:3) ::  num_lsm_v_kji !< dummy to determing local end index in surface type for given (j,i), for vertical natural surfaces
+       INTEGER(iwp), DIMENSION(0:3) ::  num_usm_v     !< current number of vertical surface element, urban type
+       INTEGER(iwp), DIMENSION(0:3) ::  num_usm_v_kji !< dummy to determing local end index in surface type for given (j,i), for vertical urban surfaces
+
+       INTEGER(iwp), DIMENSION(0:3) ::  start_index_def_v !< dummy to determing local start index in surface type for given (j,i), for vertical default surfaces
+       INTEGER(iwp), DIMENSION(0:3) ::  start_index_lsm_v !< dummy to determing local start index in surface type for given (j,i), for vertical natural surfaces
+       INTEGER(iwp), DIMENSION(0:3) ::  start_index_usm_v !< dummy to determing local start index in surface type for given (j,i), for vertical urban surfaces
+
+
+!
+!--    Initialize surface attributes, store indicies, surfaces orientation, etc., 
+       num_def_h(0:2) = 1
+       num_def_v(0:3) = 1
+
+       num_lsm_h      = 1
+       num_lsm_v(0:3) = 1
+
+       num_usm_h      = 1
+       num_usm_v(0:3) = 1
+
+       start_index_def_h(0:2) = 1
+       start_index_def_v(0:3) = 1
+
+       start_index_lsm_h      = 1
+       start_index_lsm_v(0:3) = 1
+
+       start_index_usm_h      = 1
+       start_index_usm_v(0:3) = 1
+
+       DO  i = nxl, nxr
+          DO  j = nys, nyn
+
+             num_def_h_kji = 0
+             num_def_v_kji = 0
+             num_lsm_h_kji = 0
+             num_lsm_v_kji = 0
+             num_usm_h_kji = 0
+             num_usm_v_kji = 0
+
+             DO  k = nzb+1, nzt
+!
+!--             Check if current gridpoint belongs to the atmosphere
+                IF ( BTEST( wall_flags_0(k,j,i), 0 ) )  THEN
+!
+!--                Upward-facing surface. Distinguish between differet surface types.
+!--                To do, think about method to flag natural and non-natural 
+!--                surfaces. Only to ask for land_surface or urban surface 
+!--                is just a work-around. 
+                   IF ( .NOT. BTEST( wall_flags_0(k-1,j,i), 0 ) )  THEN 
+!
+!--                   Natural surface type          
+                      IF ( land_surface )  THEN
+                         CALL initialize_horizontal_surfaces( k, j, i,         &
+                                                              surf_lsm_h,      &
+                                                              num_lsm_h,       &
+                                                              num_lsm_h_kji,   &
+                                                              .TRUE., .FALSE. )  
+!
+!--                   Urban surface tpye
+                      ELSEIF ( urban_surface )  THEN
+                         CALL initialize_horizontal_surfaces( k, j, i,         &
+                                                              surf_usm_h,      &
+                                                              num_usm_h,       &
+                                                              num_usm_h_kji,   &
+                                                              .TRUE., .FALSE. )  
+!
+!--                   Default surface type
+                      ELSE
+                         CALL initialize_horizontal_surfaces( k, j, i,         &
+                                                              surf_def_h(0),   &
+                                                              num_def_h(0),    &
+                                                              num_def_h_kji(0),&
+                                                              .TRUE., .FALSE. )  
+                      ENDIF
+                   ENDIF  
+!
+!--                downward-facing surface, first, model top
+                   IF ( k == nzt  .AND.  use_top_fluxes )  THEN
+                      CALL initialize_top( k, j, i, surf_def_h(2),             &
+                                           num_def_h(2), num_def_h_kji(2) )
+!
+!--                Check for any other downward-facing surface. So far only for 
+!--                default surface type.
+                   ELSEIF ( .NOT. BTEST( wall_flags_0(k+1,j,i), 0 ) )  THEN
+                      CALL initialize_horizontal_surfaces( k, j, i,            &
+                                                           surf_def_h(1),      &
+                                                           num_def_h(1),       &
+                                                           num_def_h_kji(1),   &
+                                                           .FALSE., .TRUE. )    
+                   ENDIF 
+!
+!--                Check for vertical walls and, if required, initialize it.
+!                  Start with northward-facing surface.
+                   IF ( .NOT. BTEST( wall_flags_0(k,j-1,i), 0 ) )  THEN
+                      IF ( urban_surface )  THEN
+                         CALL initialize_vertical_surfaces( 0, k, j, i,        &
+                                                            surf_usm_v(0),     &
+                                                            num_usm_v(0),      &
+                                                            num_usm_v_kji(0),  &
+                                                            .FALSE., .FALSE.,  &             
+                                                            .FALSE., .TRUE. ) 
+                      ELSEIF ( land_surface )  THEN
+                         CALL initialize_vertical_surfaces( 0, k, j, i,        &
+                                                            surf_lsm_v(0),     &
+                                                            num_lsm_v(0),      &
+                                                            num_lsm_v_kji(0),  &
+                                                            .FALSE., .FALSE.,  &             
+                                                            .FALSE., .TRUE. ) 
+                      ELSE
+                         CALL initialize_vertical_surfaces( 0, k, j, i,        &
+                                                            surf_def_v(0),     &
+                                                            num_def_v(0),      &
+                                                            num_def_v_kji(0),  &
+                                                            .FALSE., .FALSE.,  &             
+                                                            .FALSE., .TRUE. ) 
+                      ENDIF
+                   ENDIF
+!
+!--                southward-facing surface
+                   IF ( .NOT. BTEST( wall_flags_0(k,j+1,i), 0 ) )  THEN
+                      IF ( urban_surface )  THEN
+                         CALL initialize_vertical_surfaces( 1, k, j, i,        &
+                                                            surf_usm_v(1),     &
+                                                            num_usm_v(1),      &
+                                                            num_usm_v_kji(1),  &
+                                                            .FALSE., .FALSE.,  &
+                                                            .TRUE., .FALSE. )
+                      ELSEIF ( land_surface )  THEN
+                         CALL initialize_vertical_surfaces( 1, k, j, i,        &
+                                                            surf_lsm_v(1),     &
+                                                            num_lsm_v(1),      &
+                                                            num_lsm_v_kji(1),  &
+                                                            .FALSE., .FALSE.,  &
+                                                            .TRUE., .FALSE. )  
+                      ELSE
+                         CALL initialize_vertical_surfaces( 1, k, j, i,        &
+                                                            surf_def_v(1),     &
+                                                            num_def_v(1),      &
+                                                            num_def_v_kji(1),  &
+                                                            .FALSE., .FALSE.,  &
+                                                            .TRUE., .FALSE. ) 
+                      ENDIF
+                   ENDIF
+!
+!--                eastward-facing surface
+                   IF ( .NOT. BTEST( wall_flags_0(k,j,i-1), 0 ) )  THEN
+                      IF ( urban_surface )  THEN
+                         CALL initialize_vertical_surfaces( 2, k, j, i,        &
+                                                            surf_usm_v(2),     &
+                                                            num_usm_v(2),      &
+                                                            num_usm_v_kji(2),  &
+                                                            .TRUE., .FALSE.,   &
+                                                            .FALSE., .FALSE. ) 
+                      ELSEIF ( land_surface )  THEN
+                         CALL initialize_vertical_surfaces( 2, k, j, i,        &
+                                                            surf_lsm_v(2),     &
+                                                            num_lsm_v(2),      &
+                                                            num_lsm_v_kji(2),  &
+                                                            .TRUE., .FALSE.,   &
+                                                            .FALSE., .FALSE. ) 
+                      ELSE
+                         CALL initialize_vertical_surfaces( 2, k, j, i,        &
+                                                            surf_def_v(2),     &
+                                                            num_def_v(2),      &
+                                                            num_def_v_kji(2),  &
+                                                            .TRUE., .FALSE.,   &
+                                                            .FALSE., .FALSE. ) 
+                      ENDIF
+                   ENDIF 
+!   
+!--                westward-facing surface
+                   IF ( .NOT. BTEST( wall_flags_0(k,j,i+1), 0 ) )  THEN
+                      IF ( urban_surface )  THEN
+                         CALL initialize_vertical_surfaces( 3, k, j, i,        &
+                                                            surf_usm_v(3),     &
+                                                            num_usm_v(3),      &
+                                                            num_usm_v_kji(3),  &
+                                                           .FALSE., .TRUE.,    &
+                                                           .FALSE., .FALSE. ) 
+                      ELSEIF ( land_surface )  THEN
+                         CALL initialize_vertical_surfaces( 3, k, j, i,        &
+                                                            surf_lsm_v(3),     &
+                                                            num_lsm_v(3),      &
+                                                            num_lsm_v_kji(3),  &
+                                                           .FALSE., .TRUE.,    &
+                                                           .FALSE., .FALSE. ) 
+                      ELSE
+                         CALL initialize_vertical_surfaces( 3, k, j, i,        &
+                                                            surf_def_v(3),     &
+                                                            num_def_v(3),      &
+                                                            num_def_v_kji(3),  &
+                                                           .FALSE., .TRUE.,    &
+                                                           .FALSE., .FALSE. ) 
+                      ENDIF
+                   ENDIF
+                ENDIF
+
+ 
+             ENDDO
+!
+!--          Determine start- and end-index at grid point (j,i). Also, for 
+!--          horizontal surfaces more than 1 horizontal surface element can 
+!--          exist at grid point (j,i) if overhanging structures are present.
+!--          Upward-facing surfaces
+             surf_def_h(0)%start_index(j,i) = start_index_def_h(0)
+             surf_def_h(0)%end_index(j,i)   = surf_def_h(0)%start_index(j,i) + &
+                                                 num_def_h_kji(0) - 1
+             start_index_def_h(0)           = surf_def_h(0)%end_index(j,i) + 1
+!
+!--          Downward-facing surfaces, except model top
+             surf_def_h(1)%start_index(j,i) = start_index_def_h(1)                                                 
+             surf_def_h(1)%end_index(j,i)   = surf_def_h(1)%start_index(j,i) + &
+                                                 num_def_h_kji(1) - 1
+             start_index_def_h(1)           = surf_def_h(1)%end_index(j,i) + 1
+!
+!--          Downward-facing surfaces -- model top fluxes
+             surf_def_h(2)%start_index(j,i) = start_index_def_h(2)                                                 
+             surf_def_h(2)%end_index(j,i)   = surf_def_h(2)%start_index(j,i) + &
+                                                 num_def_h_kji(2) - 1
+             start_index_def_h(2)           = surf_def_h(2)%end_index(j,i) + 1
+!
+!--          Horizontal natural land surfaces
+             surf_lsm_h%start_index(j,i)    = start_index_lsm_h
+             surf_lsm_h%end_index(j,i)      = surf_lsm_h%start_index(j,i) +    &
+                                                 num_lsm_h_kji - 1
+             start_index_lsm_h              = surf_lsm_h%end_index(j,i) + 1
+!
+!--          Horizontal urban surfaces
+             surf_usm_h%start_index(j,i)    = start_index_usm_h
+             surf_usm_h%end_index(j,i)      = surf_usm_h%start_index(j,i) +    &
+                                                 num_usm_h_kji - 1
+             start_index_usm_h              = surf_usm_h%end_index(j,i) + 1
+
+!
+!--          Vertical surfaces - Default type
+             surf_def_v(0)%start_index(j,i) = start_index_def_v(0)
+             surf_def_v(1)%start_index(j,i) = start_index_def_v(1)
+             surf_def_v(2)%start_index(j,i) = start_index_def_v(2)
+             surf_def_v(3)%start_index(j,i) = start_index_def_v(3)
+             surf_def_v(0)%end_index(j,i)   = start_index_def_v(0) +           & 
+                                              num_def_v_kji(0) - 1
+             surf_def_v(1)%end_index(j,i)   = start_index_def_v(1) +           &
+                                              num_def_v_kji(1) - 1
+             surf_def_v(2)%end_index(j,i)   = start_index_def_v(2) +           &
+                                              num_def_v_kji(2) - 1
+             surf_def_v(3)%end_index(j,i)   = start_index_def_v(3) +           &
+                                              num_def_v_kji(3) - 1
+             start_index_def_v(0)           = surf_def_v(0)%end_index(j,i) + 1
+             start_index_def_v(1)           = surf_def_v(1)%end_index(j,i) + 1
+             start_index_def_v(2)           = surf_def_v(2)%end_index(j,i) + 1
+             start_index_def_v(3)           = surf_def_v(3)%end_index(j,i) + 1
+!
+!--          Natural type
+             surf_lsm_v(0)%start_index(j,i) = start_index_lsm_v(0)
+             surf_lsm_v(1)%start_index(j,i) = start_index_lsm_v(1)
+             surf_lsm_v(2)%start_index(j,i) = start_index_lsm_v(2)
+             surf_lsm_v(3)%start_index(j,i) = start_index_lsm_v(3)
+             surf_lsm_v(0)%end_index(j,i)   = start_index_lsm_v(0) +           & 
+                                              num_lsm_v_kji(0) - 1
+             surf_lsm_v(1)%end_index(j,i)   = start_index_lsm_v(1) +           &
+                                              num_lsm_v_kji(1) - 1
+             surf_lsm_v(2)%end_index(j,i)   = start_index_lsm_v(2) +           &
+                                              num_lsm_v_kji(2) - 1
+             surf_lsm_v(3)%end_index(j,i)   = start_index_lsm_v(3) +           &
+                                              num_lsm_v_kji(3) - 1
+             start_index_lsm_v(0)           = surf_lsm_v(0)%end_index(j,i) + 1
+             start_index_lsm_v(1)           = surf_lsm_v(1)%end_index(j,i) + 1
+             start_index_lsm_v(2)           = surf_lsm_v(2)%end_index(j,i) + 1
+             start_index_lsm_v(3)           = surf_lsm_v(3)%end_index(j,i) + 1
+!
+!--          Urban type
+             surf_usm_v(0)%start_index(j,i) = start_index_usm_v(0)
+             surf_usm_v(1)%start_index(j,i) = start_index_usm_v(1)
+             surf_usm_v(2)%start_index(j,i) = start_index_usm_v(2)
+             surf_usm_v(3)%start_index(j,i) = start_index_usm_v(3)
+             surf_usm_v(0)%end_index(j,i)   = start_index_usm_v(0) +           & 
+                                              num_usm_v_kji(0) - 1
+             surf_usm_v(1)%end_index(j,i)   = start_index_usm_v(1) +           &
+                                              num_usm_v_kji(1) - 1
+             surf_usm_v(2)%end_index(j,i)   = start_index_usm_v(2) +           &
+                                              num_usm_v_kji(2) - 1
+             surf_usm_v(3)%end_index(j,i)   = start_index_usm_v(3) +           &
+                                              num_usm_v_kji(3) - 1
+             start_index_usm_v(0)           = surf_usm_v(0)%end_index(j,i) + 1
+             start_index_usm_v(1)           = surf_usm_v(1)%end_index(j,i) + 1
+             start_index_usm_v(2)           = surf_usm_v(2)%end_index(j,i) + 1
+             start_index_usm_v(3)           = surf_usm_v(3)%end_index(j,i) + 1
+
+
+          ENDDO
+       ENDDO
+
+       CONTAINS
+
+!------------------------------------------------------------------------------!
+! Description:
+! ------------
+!> Initialize horizontal surface elements, upward- and downward-facing. 
+!> Note, horizontal surface type alsw comprises model-top fluxes, which are,
+!> initialized in a different routine. 
+!------------------------------------------------------------------------------!
+          SUBROUTINE initialize_horizontal_surfaces( k, j, i, surf, num_h,     &
+                                                     num_h_kji, upward_facing, &
+                                                     downward_facing )       
+
+             IMPLICIT NONE 
+
+             INTEGER(iwp)  ::  i                !< running index x-direction
+             INTEGER(iwp)  ::  j                !< running index y-direction
+             INTEGER(iwp)  ::  k                !< running index z-direction
+             INTEGER(iwp)  ::  num_h            !< current number of surface element
+             INTEGER(iwp)  ::  num_h_kji        !< dummy increment
+
+             LOGICAL       ::  upward_facing    !< flag indicating upward-facing surface
+             LOGICAL       ::  downward_facing  !< flag indicating downward-facing surface
+
+             TYPE( surf_type ) :: surf          !< respective surface type
+!
+!--          Store indices of respective surface element
+             surf%i(num_h) = i
+             surf%j(num_h) = j
+             surf%k(num_h) = k
+!
+!--          Surface orientation, bit 0 is set to 1 for upward-facing surfaces, 
+!--          bit 1 is for downward-facing surfaces.
+             IF ( upward_facing   )  surf%facing(num_h) = IBSET( surf%facing(num_h), 0 )
+             IF ( downward_facing )  surf%facing(num_h) = IBSET( surf%facing(num_h), 1 )
+!
+!--          Initialize surface-layer height
+             IF ( upward_facing )  THEN
+                surf%z_mo(num_h)  = zu(k) - zw(k-1)
+             ELSE
+                surf%z_mo(num_h)  = zw(k) - zu(k)
+             ENDIF
+ 
+             surf%z0(num_h)    = roughness_length
+             surf%z0h(num_h)   = z0h_factor * roughness_length
+             surf%z0q(num_h)   = z0h_factor * roughness_length          
+!
+!--          Initialization in case of 1D pre-cursor run
+             IF ( INDEX( initializing_actions, 'set_1d-model_profiles' ) /= 0 )&
+             THEN
+                IF ( .NOT. constant_diffusion )  THEN
+                   IF ( constant_flux_layer )  THEN
+                      surf%ol(num_h)   = surf%z_mo(num_h) /                    &
+                                            ( rif1d(nzb+1) + 1.0E-20_wp )
+                      surf%us(num_h)   = us1d
+                      surf%usws(num_h) = usws1d
+                      surf%vsws(num_h) = vsws1d
+                   ELSE
+                      surf%ol(num_h)   = surf%z_mo(num_h) / zeta_min
+                      surf%us(num_h)   = 0.0_wp
+                      surf%usws(num_h) = 0.0_wp
+                      surf%vsws(num_h) = 0.0_wp
+                   ENDIF
+                ELSE
+                   surf%ol(num_h)   = surf%z_mo(num_h) / zeta_min
+                   surf%us(num_h)   = 0.0_wp
+                   surf%usws(num_h) = 0.0_wp
+                   surf%vsws(num_h) = 0.0_wp
+                ENDIF
+!
+!--          Initialization in case of constant profiles
+             ELSEIF ( INDEX(initializing_actions, 'set_constant_profiles') /= 0 )&
+             THEN
+
+                surf%ol(num_h)   = surf%z_mo(num_h) / zeta_min
+!
+!--             Very small number is required for calculation of Obukhov length 
+!--             at first timestep     
+                surf%us(num_h)    = 1E-30_wp 
+                surf%usws(num_h)  = 0.0_wp
+                surf%vsws(num_h)  = 0.0_wp
+        
+             ENDIF
+
+             surf%rib(num_h)   = 0.0_wp 
+             surf%uvw_abs(num_h) = 0.0_wp
+
+             IF ( .NOT. constant_diffusion )  THEN    
+                surf%u_0(num_h)     = 0.0_wp  
+                surf%v_0(num_h)     = 0.0_wp
+             ENDIF 
+
+             surf%ts(num_h)   = 0.0_wp
+
+             IF ( humidity )  THEN
+                surf%qs(num_h)   = 0.0_wp
+                IF ( cloud_physics .AND. microphysics_seifert)  THEN
+                   surf%qrs(num_h) = 0.0_wp
+                   surf%nrs(num_h) = 0.0_wp
+   
+                   surf%qrsws(num_h) = 0.0_wp
+                   surf%nrsws(num_h) = 0.0_wp
+
+                   surf%pt1(num_h) = 0.0_wp
+                   surf%qv1(num_h) = 0.0_wp
+
+                ENDIF
+             ENDIF
+
+             IF ( passive_scalar )  surf%ss(num_h) = 0.0_wp
+!
+!--          Inititalize surface fluxes of sensible and latent heat, as well as
+!--          passive scalar
+             IF ( use_surface_fluxes )  THEN
+
+                IF ( upward_facing )  THEN
+                   IF ( constant_heatflux )  THEN
+!   
+!--                   Initialize surface heatflux. However, skip this for now if 
+!--                   if random_heatflux is set. This case, shf is initialized later.
+                      IF ( .NOT. random_heatflux )  THEN
+                         surf%shf(num_h) = surface_heatflux *               &
+                                                 heatflux_input_conversion(nzb)
+!
+!--                      Check if surface heat flux might be replaced by 
+!--                      prescribed wall heatflux
+                         IF ( k-1 /= 0 )  THEN
+                            surf%shf(num_h) = wall_heatflux(0) *            &
+                                                 heatflux_input_conversion(k-1)
+                         ENDIF
+!
+!--                      Initialize shf with data from external file LSF_DATA. Will 
+!--                      be done directly in ls_foring_surf
+!--                      Attention: Just a workaround, need to be revised!!!
+                         IF ( large_scale_forcing .AND. lsf_surf )  THEN
+!                             CALL ls_forcing_surf ( simulated_time )
+!                             surf%shf(num_h) = shf(j,i)  
+                         ENDIF
+                      ENDIF
+                   ELSE
+                      surf%shf(num_h) = 0.0_wp
+                   ENDIF
+!
+!--             Set heat-flux at downward-facing surfaces to zero
+                ELSE
+                   surf%shf(num_h) = 0.0_wp
+                ENDIF
+
+                IF ( humidity )  THEN
+                   IF ( upward_facing )  THEN
+                      IF ( constant_waterflux )  THEN
+                         surf%qsws(num_h) = surface_waterflux *                &
+                                                 waterflux_input_conversion(nzb)
+                         IF ( k-1 /= 0 )  THEN
+                            surf%qsws(num_h) = wall_humidityflux(0) *          &
+                                                 waterflux_input_conversion(k-1)
+                         ENDIF
+                      ELSE
+                         surf%qsws(num_h) = 0.0_wp
+                      ENDIF
+                   ELSE
+                      surf%qsws(num_h) = 0.0_wp
+                   ENDIF
+                ENDIF
+
+                IF ( passive_scalar )  THEN
+                   IF ( upward_facing )  THEN
+                      IF ( constant_scalarflux )  THEN
+                         surf%ssws(num_h) = surface_scalarflux
+
+                         IF ( k-1 /= 0 )                                       &
+                            surf%ssws(num_h) = wall_scalarflux(0) *            &
+                                                  waterflux_input_conversion(k-1)
+
+                      ELSE
+                         surf%ssws(num_h) = 0.0_wp
+                      ENDIF
+                   ELSE
+                      surf%ssws(num_h) = 0.0_wp
+                   ENDIF
+                ENDIF
+
+                IF ( ocean )  THEN
+                   IF ( upward_facing )  THEN 
+                      surf%sasws(num_h) = bottom_salinityflux
+                   ELSE
+                      surf%sasws(num_h) = 0.0_wp
+                   ENDIF
+                ENDIF
+             ENDIF
+!
+!--          Increment surface indices
+             num_h     = num_h + 1
+             num_h_kji = num_h_kji + 1      
+
+
+          END SUBROUTINE initialize_horizontal_surfaces
+       
+
+!------------------------------------------------------------------------------!
+! Description:
+! ------------
+!> Initialize model-top fluxes. Currently, only the heatflux and salinity flux 
+!> can be prescribed, latent flux is zero in this case!
+!------------------------------------------------------------------------------!
+          SUBROUTINE initialize_top( k, j, i, surf, num_h, num_h_kji )       
+
+             IMPLICIT NONE 
+
+             INTEGER(iwp)  ::  i                !< running index x-direction
+             INTEGER(iwp)  ::  j                !< running index y-direction
+             INTEGER(iwp)  ::  k                !< running index z-direction
+             INTEGER(iwp)  ::  num_h            !< current number of surface element
+             INTEGER(iwp)  ::  num_h_kji        !< dummy increment
+
+             TYPE( surf_type ) :: surf          !< respective surface type
+!
+!--          Store indices of respective surface element
+             surf%i(num_h) = i
+             surf%j(num_h) = j
+             surf%k(num_h) = k
+!
+!--          Initialize top heat flux
+             IF ( constant_top_heatflux )                                      &
+                surf%shf = top_heatflux * heatflux_input_conversion(nzt+1)
+!
+!--          Initialization in case of a coupled model run
+             IF ( coupling_mode == 'ocean_to_atmosphere' )  THEN
+                surf%shf = 0.0_wp
+             ENDIF
+!
+!--          Prescribe latent heat flux at the top      
+             IF ( humidity )  THEN
+             surf%qsws = 0.0_wp
+                IF ( cloud_physics  .AND.  microphysics_seifert ) THEN
+                   surf%nrsws = 0.0_wp
+                   surf%qrsws = 0.0_wp
+                ENDIF
+             ENDIF
+!
+!--          Prescribe top scalar flux
+             IF ( passive_scalar .AND. constant_top_scalarflux )               &
+                surf%ssws = top_scalarflux
+!
+!--          Prescribe top salinity flux
+             IF ( ocean .AND. constant_top_salinityflux)                          &
+                surf%sasws = top_salinityflux
+!
+!--          Initialization in case of a coupled model run
+             IF ( coupling_mode == 'ocean_to_atmosphere' )  THEN
+                surf%shf = 0.0_wp
+             ENDIF
+!
+!--          Top momentum fluxes
+             surf%usws = top_momentumflux_u * momentumflux_input_conversion(nzt+1)
+             surf%vsws = top_momentumflux_v * momentumflux_input_conversion(nzt+1)
+!
+!--          Increment surface indices
+             num_h     = num_h + 1
+             num_h_kji = num_h_kji + 1      
+
+
+          END SUBROUTINE initialize_top
+
+
+!------------------------------------------------------------------------------!
+! Description:
+! ------------
+!> Initialize vertical surface elements. 
+!------------------------------------------------------------------------------!
+          SUBROUTINE initialize_vertical_surfaces( l, k, j, i, surf, num_v,    &
+                                                num_v_kji, east_facing,        &
+                                                west_facing, south_facing,     &
+                                                north_facing )       
+
+             IMPLICIT NONE 
+
+             INTEGER(iwp)  ::  component !<
+             INTEGER(iwp)  ::  i               !< running index x-direction
+             INTEGER(iwp)  ::  j               !< running index x-direction
+             INTEGER(iwp)  ::  k               !< running index x-direction
+             INTEGER(iwp)  ::  l               !< index variable for the surface type, indicating the facing 
+             INTEGER(iwp)  ::  num_v           !< current number of surface element
+             INTEGER(iwp)  ::  num_v_kji       !< current number of surface element at (j,i)
+
+
+             LOGICAL       ::  east_facing     !< flag indicating east-facing surfaces
+             LOGICAL       ::  north_facing    !< flag indicating north-facing surfaces
+             LOGICAL       ::  south_facing    !< flag indicating south-facing surfaces
+             LOGICAL       ::  west_facing     !< flag indicating west-facing surfaces
+
+             TYPE( surf_type ) :: surf         !< respective surface type
+
+!
+!--          Store indices of respective wall element
+             surf%i(num_v)   = i
+             surf%j(num_v)   = j
+             surf%k(num_v)   = k
+!
+!--          Initialize surface-layer height, or more precisely, distance to surface
+             IF ( north_facing  .OR.  south_facing )  THEN
+                surf%z_mo(num_v)  = 0.5_wp * dy
+             ELSE
+                surf%z_mo(num_v)  = 0.5_wp * dx
+             ENDIF
+
+             surf%facing(num_v)  = 0
+!
+!--          Surface orientation. Moreover, set component id to map wall_heatflux, 
+!--          etc., on surface type (further below)
+             IF ( north_facing )  THEN
+                surf%facing(num_v) = IBSET( surf%facing(num_v), 0 )  
+                component          = 4
+             ENDIF
+
+             IF ( south_facing )  THEN
+                surf%facing(num_v) = IBSET( surf%facing(num_v), 1 ) 
+                component          = 3
+             ENDIF
+
+             IF ( east_facing )  THEN
+                surf%facing(num_v) = IBSET( surf%facing(num_v), 2 )
+                component          = 2
+             ENDIF
+
+             IF ( west_facing )  THEN
+                surf%facing(num_v) = IBSET( surf%facing(num_v), 3 ) 
+                component          = 1
+             ENDIF
+
+ 
+             surf%z0(num_v)  = roughness_length
+             surf%z0h(num_v) = z0h_factor * roughness_length
+             surf%z0q(num_v) = z0h_factor * roughness_length
+
+             surf%us(num_v)  = 0.0_wp
+!
+!--          If required, initialize Obukhov length
+             IF ( ALLOCATED( surf%ol ) )                                       &
+                surf%ol(num_v) = surf%z_mo(num_v) / zeta_min
+
+             surf%uvw_abs(num_v)   = 0.0_wp
+
+             surf%mom_flux_uv(num_v) = 0.0_wp
+             surf%mom_flux_w(num_v)  = 0.0_wp
+             surf%mom_flux_tke(0:1,num_v) = 0.0_wp
+
+             surf%ts(num_v)    = 0.0_wp
+             surf%shf(num_v)   = wall_heatflux(component)
+
+             IF ( humidity )  THEN
+                surf%qs(num_v)   = 0.0_wp
+                surf%qsws(num_v) = wall_humidityflux(component)
+!
+!--             Following wall fluxes are assumed to be zero 
+                IF ( cloud_physics .AND. microphysics_seifert)  THEN
+                   surf%qrs(num_v) = 0.0_wp
+                   surf%nrs(num_v) = 0.0_wp
+   
+                   surf%qrsws(num_v) = 0.0_wp
+                   surf%nrsws(num_v) = 0.0_wp
+                ENDIF
+             ENDIF
+
+             IF ( passive_scalar )  THEN
+                surf%ss(num_v)   = 0.0_wp
+                surf%ssws(num_v) = wall_scalarflux(component)
+             ENDIF
+!
+!--          So far, salinityflux at vertical surfaces is simply zero 
+!--          at the moment  
+             IF ( ocean )  surf%sasws(num_v) = wall_salinityflux(component)
+!
+!--          Increment wall indices
+             num_v                 = num_v + 1
+             num_v_kji             = num_v_kji + 1
+
+          END SUBROUTINE initialize_vertical_surfaces
+
+    END SUBROUTINE init_surfaces
+
+!------------------------------------------------------------------------------!
+! Description:
+! ------------
+!> Gathers all surface elements with the same facing (but possibly different 
+!> type) onto a surface type, and writes binary data into restart files. 
+!------------------------------------------------------------------------------!
+    SUBROUTINE surface_write_restart_data
+
+       IMPLICIT NONE
+
+       CHARACTER(LEN=1)             ::  dum
+
+       INTEGER(iwp)                 ::  i
+       INTEGER(iwp)                 ::  j
+       INTEGER(iwp)                 ::  l
+       INTEGER(iwp)                 ::  m
+       INTEGER(iwp), DIMENSION(0:3) ::  mm
+
+       TYPE(surf_type), DIMENSION(0:2) ::  surf_h
+       TYPE(surf_type), DIMENSION(0:3) ::  surf_v
+
+!
+!--    Determine total number of horizontal and vertical surface elements before
+!--    writing var_list
+       CALL surface_last_actions
+!
+!--    Count number of grid points with same facing and allocate attributes respectively
+!--    Horizontal upward facing
+       surf_h(0)%ns = ns_h_on_file(0)
+       CALL allocate_surface_attributes_h( surf_h(0), nys, nyn, nxl, nxr )
+!
+!--    Horizontal downward facing
+       surf_h(1)%ns = ns_h_on_file(1)
+       CALL allocate_surface_attributes_h( surf_h(1), nys, nyn, nxl, nxr )
+!
+!--    Model top
+       surf_h(2)%ns = ns_h_on_file(2)
+       CALL allocate_surface_attributes_h_top( surf_h(2), nys, nyn, nxl, nxr )
+!
+!--    Vertical surfaces
+       DO  l = 0, 3
+          surf_v(l)%ns = ns_v_on_file(l)
+          CALL allocate_surface_attributes_v( surf_v(l), .FALSE.,              &
+                                              nys, nyn, nxl, nxr )
+       ENDDO
+!
+!--    In the following, gather data from surfaces elements with the same 
+!--    facing (but possibly differt type) on 1 data-type array.
+       mm(0:2) = 1
+       DO  l = 0, 2
+          DO  i = nxl, nxr
+             DO  j = nys, nyn
+                DO  m = surf_def_h(l)%start_index(j,i),                        &
+                        surf_def_h(l)%end_index(j,i)
+                   IF ( ALLOCATED( surf_def_h(l)%us ) )                        &
+                      surf_h(l)%us(mm(l))      = surf_def_h(l)%us(m)
+                   IF ( ALLOCATED( surf_def_h(l)%ts ) )                        &
+                      surf_h(l)%ts(mm(l))      = surf_def_h(l)%ts(m)
+                   IF ( ALLOCATED( surf_def_h(l)%qs ) )                        &
+                      surf_h(l)%qs(mm(l))      = surf_def_h(l)%qs(m)
+                   IF ( ALLOCATED( surf_def_h(l)%ss ) )                        &
+                      surf_h(l)%ss(mm(l))      = surf_def_h(l)%ss(m)
+                   IF ( ALLOCATED( surf_def_h(l)%qrs ) )                       &
+                      surf_h(l)%qrs(mm(l))     = surf_def_h(l)%qrs(m)
+                   IF ( ALLOCATED( surf_def_h(l)%nrs ) )                       &
+                      surf_h(l)%nrs(mm(l))     = surf_def_h(l)%nrs(m)
+                   IF ( ALLOCATED( surf_def_h(l)%ol ) )                        &
+                      surf_h(l)%ol(mm(l))      = surf_def_h(l)%ol(m)
+                   IF ( ALLOCATED( surf_def_h(l)%rib ) )                       &
+                      surf_h(l)%rib(mm(l))     = surf_def_h(l)%rib(m)
+                   IF ( ALLOCATED( surf_def_h(l)%usws ) )                      &
+                      surf_h(l)%usws(mm(l))    = surf_def_h(l)%usws(m)
+                   IF ( ALLOCATED( surf_def_h(l)%vsws ) )                      &
+                      surf_h(l)%vsws(mm(l))    = surf_def_h(l)%vsws(m)
+                   IF ( ALLOCATED( surf_def_h(l)%shf ) )                       &
+                      surf_h(l)%shf(mm(l))     = surf_def_h(l)%shf(m)
+                   IF ( ALLOCATED( surf_def_h(l)%qsws ) )                      &
+                      surf_h(l)%qsws(mm(l))    = surf_def_h(l)%qsws(m)
+                   IF ( ALLOCATED( surf_def_h(l)%ssws ) )                      &
+                      surf_h(l)%qsws(mm(l))    = surf_def_h(l)%ssws(m)
+                   IF ( ALLOCATED( surf_def_h(l)%nrsws ) )                     &
+                      surf_h(l)%nrsws(mm(l))   = surf_def_h(l)%nrsws(m)
+                   IF ( ALLOCATED( surf_def_h(l)%sasws ) )                     &
+                      surf_h(l)%sasws(mm(l))   = surf_def_h(l)%sasws(m)
+                
+                   mm(l) = mm(l) + 1
+                ENDDO
+
+                IF ( l == 0 )  THEN
+                   DO  m = surf_lsm_h%start_index(j,i),                        &
+                           surf_lsm_h%end_index(j,i)
+                      IF ( ALLOCATED( surf_lsm_h%us ) )                        &
+                         surf_h(0)%us(mm(0))      = surf_lsm_h%us(m)
+                      IF ( ALLOCATED( surf_lsm_h%ts ) )                        &
+                         surf_h(0)%ts(mm(0))      = surf_lsm_h%ts(m)
+                      IF ( ALLOCATED( surf_lsm_h%qs ) )                        &
+                         surf_h(0)%qs(mm(0))      = surf_lsm_h%qs(m)
+                      IF ( ALLOCATED( surf_lsm_h%ss ) )                        &
+                         surf_h(0)%ss(mm(0))      = surf_lsm_h%ss(m)
+                      IF ( ALLOCATED( surf_lsm_h%qrs ) )                       &
+                         surf_h(0)%qrs(mm(0))     = surf_lsm_h%qrs(m)
+                      IF ( ALLOCATED( surf_lsm_h%nrs ) )                       &
+                         surf_h(0)%nrs(mm(0))     = surf_lsm_h%nrs(m)
+                      IF ( ALLOCATED( surf_lsm_h%ol ) )                        &
+                         surf_h(0)%ol(mm(0))      = surf_lsm_h%ol(m)
+                      IF ( ALLOCATED( surf_lsm_h%rib ) )                       &
+                         surf_h(0)%rib(mm(0))     = surf_lsm_h%rib(m)
+                      IF ( ALLOCATED( surf_lsm_h%usws ) )                      &
+                         surf_h(0)%usws(mm(0))    = surf_lsm_h%usws(m)
+                      IF ( ALLOCATED( surf_lsm_h%vsws ) )                      &
+                         surf_h(0)%vsws(mm(0))    = surf_lsm_h%vsws(m)
+                      IF ( ALLOCATED( surf_lsm_h%shf ) )                       &
+                         surf_h(0)%shf(mm(0))     = surf_lsm_h%shf(m)
+                      IF ( ALLOCATED( surf_lsm_h%qsws ) )                      &
+                         surf_h(0)%qsws(mm(0))    = surf_lsm_h%qsws(m)
+                      IF ( ALLOCATED( surf_lsm_h%ssws ) )                      &
+                         surf_h(0)%qsws(mm(0))    = surf_lsm_h%ssws(m)
+                      IF ( ALLOCATED( surf_lsm_h%nrsws ) )                     &
+                         surf_h(0)%nrsws(mm(0))   = surf_lsm_h%nrsws(m)
+                      IF ( ALLOCATED( surf_lsm_h%sasws ) )                     &
+                        surf_h(0)%sasws(mm(0))   = surf_lsm_h%sasws(m)
+                
+                      mm(0) = mm(0) + 1
+             
+                   ENDDO
+
+                   DO  m = surf_usm_h%start_index(j,i),                        &
+                           surf_usm_h%end_index(j,i)
+                      IF ( ALLOCATED( surf_usm_h%us ) )                        &
+                         surf_h(0)%us(mm(0))      = surf_usm_h%us(m)
+                      IF ( ALLOCATED( surf_usm_h%ts ) )                        &
+                         surf_h(0)%ts(mm(0))      = surf_usm_h%ts(m)
+                      IF ( ALLOCATED( surf_usm_h%qs ) )                        &
+                         surf_h(0)%qs(mm(0))      = surf_usm_h%qs(m)
+                      IF ( ALLOCATED( surf_usm_h%ss ) )                        &
+                         surf_h(0)%ss(mm(0))      = surf_usm_h%ss(m)
+                      IF ( ALLOCATED( surf_usm_h%qrs ) )                       &
+                         surf_h(0)%qrs(mm(0))     = surf_usm_h%qrs(m)
+                      IF ( ALLOCATED( surf_usm_h%nrs ) )                       &
+                         surf_h(0)%nrs(mm(0))     = surf_usm_h%nrs(m)
+                      IF ( ALLOCATED( surf_usm_h%ol ) )                        &
+                         surf_h(0)%ol(mm(0))      = surf_usm_h%ol(m)
+                      IF ( ALLOCATED( surf_usm_h%rib ) )                       &
+                         surf_h(0)%rib(mm(0))     = surf_usm_h%rib(m)
+                      IF ( ALLOCATED( surf_usm_h%usws ) )                      &
+                         surf_h(0)%usws(mm(0))    = surf_usm_h%usws(m)
+                      IF ( ALLOCATED( surf_usm_h%vsws ) )                      &
+                         surf_h(0)%vsws(mm(0))    = surf_usm_h%vsws(m)
+                      IF ( ALLOCATED( surf_usm_h%shf ) )                       &
+                         surf_h(0)%shf(mm(0))     = surf_usm_h%shf(m)
+                      IF ( ALLOCATED( surf_usm_h%qsws ) )                      &
+                         surf_h(0)%qsws(mm(0))    = surf_usm_h%qsws(m)
+                      IF ( ALLOCATED( surf_usm_h%ssws ) )                      &
+                         surf_h(0)%qsws(mm(0))    = surf_usm_h%ssws(m)
+                      IF ( ALLOCATED( surf_usm_h%nrsws ) )                     &
+                         surf_h(0)%nrsws(mm(0))   = surf_usm_h%nrsws(m)
+                      IF ( ALLOCATED( surf_usm_h%sasws ) )                     &
+                        surf_h(0)%sasws(mm(0))   = surf_usm_h%sasws(m)
+                
+                      mm(0) = mm(0) + 1
+             
+                   ENDDO
+
+
+                ENDIF
+
+             ENDDO
+
+          ENDDO
+          IF ( l == 0 )  THEN
+             surf_h(l)%start_index = MAX( surf_def_h(l)%start_index,           &
+                                          surf_lsm_h%start_index,              &
+                                          surf_usm_h%start_index )
+             surf_h(l)%end_index   = MAX( surf_def_h(l)%end_index,             &
+                                          surf_lsm_h%end_index,                &
+                                          surf_usm_h%end_index )
+          ELSE
+             surf_h(l)%start_index = surf_def_h(l)%start_index
+             surf_h(l)%end_index   = surf_def_h(l)%end_index
+          ENDIF
+       ENDDO
+
+
+       mm(0:3) = 1
+       DO  l = 0, 3
+          DO  i = nxl, nxr
+             DO  j = nys, nyn
+                DO  m = surf_def_v(l)%start_index(j,i),                        &
+                        surf_def_v(l)%end_index(j,i)
+                   IF ( ALLOCATED( surf_def_v(l)%us ) )                        &
+                      surf_v(l)%us(mm(l))      = surf_def_v(l)%us(m)
+                   IF ( ALLOCATED( surf_def_v(l)%ts ) )                        &
+                      surf_v(l)%ts(mm(l))      = surf_def_v(l)%ts(m)
+                   IF ( ALLOCATED( surf_def_v(l)%qs ) )                        &
+                      surf_v(l)%qs(mm(l))      = surf_def_v(l)%qs(m)
+                   IF ( ALLOCATED( surf_def_v(l)%ss ) )                        &
+                      surf_v(l)%ss(mm(l))      = surf_def_v(l)%ss(m)
+                   IF ( ALLOCATED( surf_def_v(l)%qrs ) )                       &
+                      surf_v(l)%qrs(mm(l))     = surf_def_v(l)%qrs(m)
+                   IF ( ALLOCATED( surf_def_v(l)%nrs ) )                       &
+                      surf_v(l)%nrs(mm(l))     = surf_def_v(l)%nrs(m)
+                   IF ( ALLOCATED( surf_def_v(l)%ol ) )                        &
+                      surf_v(l)%ol(mm(l))      = surf_def_v(l)%ol(m)
+                   IF ( ALLOCATED( surf_def_v(l)%rib ) )                       &
+                      surf_v(l)%rib(mm(l))     = surf_def_v(l)%rib(m)
+                   IF ( ALLOCATED( surf_def_v(l)%shf ) )                       &
+                      surf_v(l)%shf(mm(l))     = surf_def_v(l)%shf(m)
+                   IF ( ALLOCATED( surf_def_v(l)%qsws ) )                      &
+                      surf_v(l)%qsws(mm(l))    = surf_def_v(l)%qsws(m)
+                   IF ( ALLOCATED( surf_def_v(l)%ssws ) )                      &
+                      surf_v(l)%qsws(mm(l))    = surf_def_v(l)%ssws(m)
+                   IF ( ALLOCATED( surf_def_v(l)%nrsws ) )                     &
+                      surf_v(l)%nrsws(mm(l))   = surf_def_v(l)%nrsws(m)
+                   IF ( ALLOCATED( surf_def_v(l)%sasws ) )                     &
+                      surf_v(l)%sasws(mm(l))   = surf_def_v(l)%sasws(m)
+                   IF ( ALLOCATED( surf_def_v(l)%mom_flux_uv) )                &
+                      surf_v(l)%mom_flux_uv(mm(l))  = surf_def_v(l)%mom_flux_uv(m)
+                   IF ( ALLOCATED( surf_def_v(l)%mom_flux_w) )                 &
+                      surf_v(l)%mom_flux_w(mm(l))   = surf_def_v(l)%mom_flux_w(m)
+                   IF ( ALLOCATED( surf_def_v(l)%mom_flux_tke) )               &
+                      surf_v(l)%mom_flux_tke(0:1,mm(l)) = surf_def_v(l)%mom_flux_tke(0:1,m)
+                
+                   mm(l) = mm(l) + 1
+                ENDDO
+
+                DO  m = surf_lsm_v(l)%start_index(j,i),                        &
+                        surf_lsm_v(l)%end_index(j,i)
+                   IF ( ALLOCATED( surf_lsm_v(l)%us ) )                        &
+                      surf_v(l)%us(mm(l))      = surf_lsm_v(l)%us(m)
+                   IF ( ALLOCATED( surf_lsm_v(l)%ts ) )                        &
+                      surf_v(l)%ts(mm(l))      = surf_lsm_v(l)%ts(m)
+                   IF ( ALLOCATED( surf_lsm_v(l)%qs ) )                        &
+                      surf_v(l)%qs(mm(l))      = surf_lsm_v(l)%qs(m)
+                   IF ( ALLOCATED( surf_lsm_v(l)%ss ) )                        &
+                      surf_v(l)%ss(mm(l))      = surf_lsm_v(l)%ss(m)
+                   IF ( ALLOCATED( surf_lsm_v(l)%qrs ) )                       &
+                      surf_v(l)%qrs(mm(l))     = surf_lsm_v(l)%qrs(m)
+                   IF ( ALLOCATED( surf_lsm_v(l)%nrs ) )                       &
+                      surf_v(l)%nrs(mm(l))     = surf_lsm_v(l)%nrs(m)
+                   IF ( ALLOCATED( surf_lsm_v(l)%ol ) )                        &
+                      surf_v(l)%ol(mm(l))      = surf_lsm_v(l)%ol(m)
+                   IF ( ALLOCATED( surf_lsm_v(l)%rib ) )                       &
+                      surf_v(l)%rib(mm(l))     = surf_lsm_v(l)%rib(m)
+                   IF ( ALLOCATED( surf_lsm_v(l)%usws ) )                      &
+                      surf_v(l)%usws(mm(l))    = surf_lsm_v(l)%usws(m)
+                   IF ( ALLOCATED( surf_lsm_v(l)%vsws ) )                      &
+                      surf_v(l)%vsws(mm(l))    = surf_lsm_v(l)%vsws(m)
+                   IF ( ALLOCATED( surf_lsm_v(l)%shf ) )                       &
+                      surf_v(l)%shf(mm(l))     = surf_lsm_v(l)%shf(m)
+                   IF ( ALLOCATED( surf_lsm_v(l)%qsws ) )                      &
+                      surf_v(l)%qsws(mm(l))    = surf_lsm_v(l)%qsws(m)
+                   IF ( ALLOCATED( surf_lsm_v(l)%ssws ) )                      &
+                      surf_v(l)%qsws(mm(l))    = surf_lsm_v(l)%ssws(m)
+                   IF ( ALLOCATED( surf_lsm_v(l)%nrsws ) )                     &
+                      surf_v(l)%nrsws(mm(l))   = surf_lsm_v(l)%nrsws(m)
+                   IF ( ALLOCATED( surf_lsm_v(l)%sasws ) )                     &
+                      surf_v(l)%sasws(mm(l))   = surf_lsm_v(l)%sasws(m)
+                   IF ( ALLOCATED( surf_lsm_v(l)%mom_flux_uv) )                &
+                      surf_v(l)%mom_flux_uv(mm(l))  = surf_lsm_v(l)%mom_flux_uv(m)
+                   IF ( ALLOCATED( surf_lsm_v(l)%mom_flux_w) )                 &
+                      surf_v(l)%mom_flux_w(mm(l))   = surf_lsm_v(l)%mom_flux_w(m)
+                   IF ( ALLOCATED( surf_lsm_v(l)%mom_flux_tke) )               &
+                      surf_v(l)%mom_flux_tke(0:1,mm(l)) = surf_lsm_v(l)%mom_flux_tke(0:1,m)
+                
+                   mm(l) = mm(l) + 1
+                ENDDO
+
+                DO  m = surf_usm_v(l)%start_index(j,i),                        &
+                        surf_usm_v(l)%end_index(j,i)
+                   IF ( ALLOCATED( surf_usm_v(l)%us ) )                        &
+                      surf_v(l)%us(mm(l))      = surf_usm_v(l)%us(m)
+                   IF ( ALLOCATED( surf_usm_v(l)%ts ) )                        &
+                      surf_v(l)%ts(mm(l))      = surf_usm_v(l)%ts(m)
+                   IF ( ALLOCATED( surf_usm_v(l)%qs ) )                        &
+                      surf_v(l)%qs(mm(l))      = surf_usm_v(l)%qs(m)
+                   IF ( ALLOCATED( surf_usm_v(l)%ss ) )                        &
+                      surf_v(l)%ss(mm(l))      = surf_usm_v(l)%ss(m)
+                   IF ( ALLOCATED( surf_usm_v(l)%qrs ) )                       &
+                      surf_v(l)%qrs(mm(l))     = surf_usm_v(l)%qrs(m)
+                   IF ( ALLOCATED( surf_usm_v(l)%nrs ) )                       &
+                      surf_v(l)%nrs(mm(l))     = surf_usm_v(l)%nrs(m)
+                   IF ( ALLOCATED( surf_usm_v(l)%ol ) )                        &
+                      surf_v(l)%ol(mm(l))      = surf_usm_v(l)%ol(m)
+                   IF ( ALLOCATED( surf_usm_v(l)%rib ) )                       &
+                      surf_v(l)%rib(mm(l))     = surf_usm_v(l)%rib(m)
+                   IF ( ALLOCATED( surf_usm_v(l)%usws ) )                      &
+                      surf_v(l)%usws(mm(l))    = surf_usm_v(l)%usws(m)
+                   IF ( ALLOCATED( surf_usm_v(l)%vsws ) )                      &
+                      surf_v(l)%vsws(mm(l))    = surf_usm_v(l)%vsws(m)
+                   IF ( ALLOCATED( surf_usm_v(l)%shf ) )                       &
+                      surf_v(l)%shf(mm(l))     = surf_usm_v(l)%shf(m)
+                   IF ( ALLOCATED( surf_usm_v(l)%qsws ) )                      &
+                      surf_v(l)%qsws(mm(l))    = surf_usm_v(l)%qsws(m)
+                   IF ( ALLOCATED( surf_usm_v(l)%ssws ) )                      &
+                      surf_v(l)%qsws(mm(l))    = surf_usm_v(l)%ssws(m)
+                   IF ( ALLOCATED( surf_usm_v(l)%nrsws ) )                     &
+                      surf_v(l)%nrsws(mm(l))   = surf_usm_v(l)%nrsws(m)
+                   IF ( ALLOCATED( surf_usm_v(l)%sasws ) )                     &
+                      surf_v(l)%sasws(mm(l))   = surf_usm_v(l)%sasws(m)
+                   IF ( ALLOCATED( surf_usm_v(l)%mom_flux_uv) )                &
+                      surf_v(l)%mom_flux_uv(mm(l))  = surf_usm_v(l)%mom_flux_uv(m)
+                   IF ( ALLOCATED( surf_usm_v(l)%mom_flux_w) )                 &
+                      surf_v(l)%mom_flux_w(mm(l))   = surf_usm_v(l)%mom_flux_w(m)
+                   IF ( ALLOCATED( surf_usm_v(l)%mom_flux_tke) )               &
+                      surf_v(l)%mom_flux_tke(0:1,mm(l)) = surf_usm_v(l)%mom_flux_tke(0:1,m)
+                
+                   mm(l) = mm(l) + 1
+                ENDDO
+             
+             ENDDO
+          ENDDO
+!
+!--       Finally, determine start- and end-index for the respective surface
+          surf_v(l)%start_index = MAX( surf_def_v(l)%start_index,              &
+                                       surf_lsm_v(l)%start_index,              &
+                                       surf_usm_v(l)%start_index )
+          surf_v(l)%end_index   = MAX( surf_def_v(l)%end_index,                &
+                                       surf_lsm_v(l)%end_index,                &
+                                       surf_usm_v(l)%end_index   )
+       ENDDO
+
+       WRITE ( 14 )  'ns_h_on_file                  '
+       WRITE ( 14 )   ns_h_on_file
+       WRITE ( 14 )  'ns_v_on_file                  '
+       WRITE ( 14 )   ns_v_on_file
+!
+!--    Write required restart data.
+!--    Start with horizontal surfaces (upward-, downward-facing, and model top)
+       DO  l = 0, 2
+          WRITE( dum, '(I1)')  l
+          
+          WRITE ( 14 )  'surf_h(' // dum // ')%start_index         '  
+          WRITE ( 14 )   surf_h(l)%start_index
+          WRITE ( 14 )  'surf_h(' // dum // ')%end_index           '  
+          WRITE ( 14 )   surf_h(l)%end_index
+
+          WRITE ( 14 )  'surf_h(' // dum // ')%us                  ' 
+          IF ( ALLOCATED ( surf_h(l)%us ) )  THEN
+             WRITE ( 14 )  surf_h(l)%us
+          ENDIF
+          WRITE ( 14 )  'surf_h(' // dum // ')%ts                  '  
+          IF ( ALLOCATED ( surf_h(l)%ts ) )  THEN
+             WRITE ( 14 )  surf_h(l)%ts
+          ENDIF
+          WRITE ( 14 )  'surf_h(' // dum // ')%qs                  '  
+          IF ( ALLOCATED ( surf_h(l)%qs ) )  THEN
+             WRITE ( 14 )  surf_h(l)%qs
+          ENDIF
+          WRITE ( 14 )  'surf_h(' // dum // ')%ss                  '  
+          IF ( ALLOCATED ( surf_h(l)%ss ) )  THEN
+             WRITE ( 14 )  surf_h(l)%ss
+          ENDIF
+          WRITE ( 14 )  'surf_h(' // dum // ')%qrs                 '
+          IF ( ALLOCATED ( surf_h(l)%qrs ) )  THEN  
+             WRITE ( 14 )  surf_h(l)%qrs
+          ENDIF
+          WRITE ( 14 )  'surf_h(' // dum // ')%nrs                 '  
+          IF ( ALLOCATED ( surf_h(l)%nrs ) )  THEN
+             WRITE ( 14 )  surf_h(l)%nrs
+          ENDIF
+          WRITE ( 14 )  'surf_h(' // dum // ')%ol                  '  
+          IF ( ALLOCATED ( surf_h(l)%ol ) )  THEN
+             WRITE ( 14 )  surf_h(l)%ol
+          ENDIF
+          WRITE ( 14 )  'surf_h(' // dum // ')%rib                 '  
+          IF ( ALLOCATED ( surf_h(l)%rib ) )  THEN
+             WRITE ( 14 )  surf_h(l)%rib
+          ENDIF
+          WRITE ( 14 )  'surf_h(' // dum // ')%usws                '  
+          IF ( ALLOCATED ( surf_h(l)%usws ) )  THEN
+             WRITE ( 14 )  surf_h(l)%usws
+          ENDIF
+          WRITE ( 14 )  'surf_h(' // dum // ')%vsws                '  
+          IF ( ALLOCATED ( surf_h(l)%vsws ) )  THEN
+             WRITE ( 14 )  surf_h(l)%vsws
+          ENDIF
+          WRITE ( 14 )  'surf_h(' // dum // ')%shf                 ' 
+          IF ( ALLOCATED ( surf_h(l)%shf ) )  THEN
+             WRITE ( 14 )  surf_h(l)%shf
+          ENDIF
+          WRITE ( 14 )  'surf_h(' // dum // ')%qsws                '  
+          IF ( ALLOCATED ( surf_h(l)%qsws ) )  THEN
+             WRITE ( 14 )  surf_h(l)%qsws
+          ENDIF
+          WRITE ( 14 )  'surf_h(' // dum // ')%ssws                '  
+          IF ( ALLOCATED ( surf_h(l)%ssws ) )  THEN 
+             WRITE ( 14 )  surf_h(l)%ssws
+          ENDIF
+          WRITE ( 14 )  'surf_h(' // dum // ')%qrsws               '  
+          IF ( ALLOCATED ( surf_h(l)%qrsws ) )  THEN
+             WRITE ( 14 )  surf_h(l)%qrsws
+          ENDIF
+          WRITE ( 14 )  'surf_h(' // dum // ')%nrsws               '  
+          IF ( ALLOCATED ( surf_h(l)%nrsws ) )  THEN
+             WRITE ( 14 )  surf_h(l)%nrsws
+          ENDIF
+          WRITE ( 14 )  'surf_h(' // dum // ')%sasws               ' 
+          IF ( ALLOCATED ( surf_h(l)%sasws ) )  THEN 
+             WRITE ( 14 )  surf_h(l)%sasws
+          ENDIF
+       ENDDO
+!
+!--    Write vertical surfaces
+       DO  l = 0, 3
+          WRITE( dum, '(I1)')  l
+
+          WRITE ( 14 )  'surf_v(' // dum // ')%start_index         '  
+          WRITE ( 14 )   surf_v(l)%start_index
+          WRITE ( 14 )  'surf_v(' // dum // ')%end_index           '  
+          WRITE ( 14 )   surf_v(l)%end_index
+
+          WRITE ( 14 )  'surf_v(' // dum // ')%us                  '  
+          IF ( ALLOCATED ( surf_v(l)%us ) )  THEN
+             WRITE ( 14 )  surf_v(l)%us
+          ENDIF
+          WRITE ( 14 )  'surf_v(' // dum // ')%ts                  ' 
+          IF ( ALLOCATED ( surf_v(l)%ts ) )  THEN
+             WRITE ( 14 )  surf_v(l)%ts
+          ENDIF
+          WRITE ( 14 )  'surf_v(' // dum // ')%qs                  '  
+          IF ( ALLOCATED ( surf_v(l)%qs ) )  THEN
+             WRITE ( 14 )  surf_v(l)%qs
+          ENDIF
+          WRITE ( 14 )  'surf_v(' // dum // ')%ss                  '  
+          IF ( ALLOCATED ( surf_v(l)%ss ) )  THEN
+             WRITE ( 14 )  surf_v(l)%ss
+          ENDIF
+          WRITE ( 14 )  'surf_v(' // dum // ')%qrs                 '  
+          IF ( ALLOCATED ( surf_v(l)%qrs ) )  THEN
+             WRITE ( 14 )  surf_v(l)%qrs
+          ENDIF
+          WRITE ( 14 )  'surf_v(' // dum // ')%nrs                 ' 
+          IF ( ALLOCATED ( surf_v(l)%nrs ) )  THEN 
+             WRITE ( 14 )  surf_v(l)%nrs
+          ENDIF
+          WRITE ( 14 )  'surf_v(' // dum // ')%ol                  '  
+          IF ( ALLOCATED ( surf_v(l)%ol ) )  THEN
+             WRITE ( 14 )  surf_v(l)%ol
+          ENDIF
+          WRITE ( 14 )  'surf_v(' // dum // ')%rib                 '  
+          IF ( ALLOCATED ( surf_v(l)%rib ) )  THEN
+             WRITE ( 14 )  surf_v(l)%rib
+          ENDIF
+          WRITE ( 14 )  'surf_v(' // dum // ')%shf                 '  
+          IF ( ALLOCATED ( surf_v(l)%shf ) )  THEN
+             WRITE ( 14 )  surf_v(l)%shf
+          ENDIF
+          WRITE ( 14 )  'surf_v(' // dum // ')%qsws                '  
+          IF ( ALLOCATED ( surf_v(l)%qsws ) )  THEN
+             WRITE ( 14 )  surf_v(l)%qsws
+          ENDIF
+          WRITE ( 14 )  'surf_v(' // dum // ')%ssws                '  
+          IF ( ALLOCATED ( surf_v(l)%ssws ) )  THEN
+             WRITE ( 14 )  surf_v(l)%ssws
+          ENDIF
+          WRITE ( 14 )  'surf_v(' // dum // ')%qrsws               '  
+          IF ( ALLOCATED ( surf_v(l)%qrsws ) )  THEN
+             WRITE ( 14 )  surf_v(l)%qrsws
+          ENDIF
+          WRITE ( 14 )  'surf_v(' // dum // ')%nrsws               '  
+          IF ( ALLOCATED ( surf_v(l)%nrsws ) )  THEN
+             WRITE ( 14 )  surf_v(l)%nrsws
+          ENDIF
+          WRITE ( 14 )  'surf_v(' // dum // ')%sasws               '  
+          IF ( ALLOCATED ( surf_v(l)%sasws ) )  THEN
+             WRITE ( 14 )  surf_v(l)%sasws
+          ENDIF
+          WRITE ( 14 )  'surf_v(' // dum // ')%mom_uv              '  
+          IF ( ALLOCATED ( surf_v(l)%mom_flux_uv ) )  THEN
+             WRITE ( 14 )  surf_v(l)%mom_flux_uv
+          ENDIF
+          WRITE ( 14 )  'surf_v(' // dum // ')%mom_w               '  
+          IF ( ALLOCATED ( surf_v(l)%mom_flux_w ) )  THEN
+             WRITE ( 14 )  surf_v(l)%mom_flux_w
+          ENDIF
+          WRITE ( 14 )  'surf_v(' // dum // ')%mom_tke             '  
+          IF ( ALLOCATED ( surf_v(l)%mom_flux_tke ) )  THEN
+             WRITE ( 14 )  surf_v(l)%mom_flux_tke
+          ENDIF
+
+       ENDDO
+
+       WRITE ( 14 )  '*** end surf ***              '
+
+    END SUBROUTINE surface_write_restart_data
+
+
+!------------------------------------------------------------------------------!
+! Description:
+! ------------
+!> Reads surface-related restart data. Please note, restart data for a certain
+!> surface orientation (e.g. horizontal upward-facing) is stored in one 
+!> array, even if surface elements may belong to different surface types 
+!> natural or urban for example). Surface elements are redistributed into its
+!> respective surface types within this routine. This allows e.g. changing the 
+!> surface type after reading the restart data, which might be required in case 
+!> of cyclic-filling a simulation. 
+!------------------------------------------------------------------------------!
+    SUBROUTINE surface_read_restart_data( ii,                                  &
+                                       nxlfa, nxl_on_file, nxrfa, nxr_on_file, &
+                                       nynfa, nyn_on_file, nysfa, nys_on_file, &
+                                       offset_xa, offset_ya, overlap_count )
+
+       USE pegrid,                                                             &
+           ONLY: numprocs_previous_run
+
+       CHARACTER (LEN=1)  ::  dum         !< dummy to create correct string for reading input variable
+       CHARACTER (LEN=30) ::  field_chr   !< input variable
+
+       INTEGER(iwp)       ::  i           !< running index along x-direction, refers to former domain size
+       INTEGER(iwp)       ::  ic          !< running index along x-direction, refers to current domain size
+       INTEGER(iwp)       ::  j           !< running index along y-direction, refers to former domain size
+       INTEGER(iwp)       ::  jc          !< running index along y-direction, refers to former domain size
+       INTEGER(iwp)       ::  k           !< running index along z-direction
+       INTEGER(iwp)       ::  l           !< index variable for surface type
+       INTEGER(iwp)       ::  m           !< running index for surface elements, refers to gathered array encompassing all surface types
+       INTEGER(iwp)       ::  mm          !< running index for surface elements, refers to individual surface types
+
+       INTEGER(iwp)       ::  ii               !< running index over input files
+       INTEGER(iwp)       ::  kk               !< running index over previous input files covering current local domain
+       INTEGER(iwp)       ::  nxlc             !< index of left boundary on current subdomain
+       INTEGER(iwp)       ::  nxlf             !< index of left boundary on former subdomain 
+       INTEGER(iwp)       ::  nxl_on_file      !< index of left boundary on former local domain 
+       INTEGER(iwp)       ::  nxrc             !< index of right boundary on current subdomain
+       INTEGER(iwp)       ::  nxrf             !< index of right boundary on former subdomain
+       INTEGER(iwp)       ::  nxr_on_file      !< index of right boundary on former local domain  
+       INTEGER(iwp)       ::  nync             !< index of north boundary on current subdomain
+       INTEGER(iwp)       ::  nynf             !< index of north boundary on former subdomain
+       INTEGER(iwp)       ::  nyn_on_file      !< index of norht boundary on former local domain  
+       INTEGER(iwp)       ::  nysc             !< index of south boundary on current subdomain 
+       INTEGER(iwp)       ::  nysf             !< index of south boundary on former subdomain
+       INTEGER(iwp)       ::  nys_on_file      !< index of south boundary on former local domain  
+       INTEGER(iwp)       ::  overlap_count    !< number of overlaps
+  
+       INTEGER(iwp), DIMENSION(numprocs_previous_run,1000) ::  nxlfa       !< 
+       INTEGER(iwp), DIMENSION(numprocs_previous_run,1000) ::  nxrfa       !< 
+       INTEGER(iwp), DIMENSION(numprocs_previous_run,1000) ::  nynfa       !< 
+       INTEGER(iwp), DIMENSION(numprocs_previous_run,1000) ::  nysfa       !< 
+       INTEGER(iwp), DIMENSION(numprocs_previous_run,1000) ::  offset_xa   !< 
+       INTEGER(iwp), DIMENSION(numprocs_previous_run,1000) ::  offset_ya   !< 
+
+
+       LOGICAL                         ::  horizontal_surface !< flag indicating horizontal surfaces
+       LOGICAL                         ::  vertical_surface   !< flag indicating vertical surfaces
+       LOGICAL                         ::  surf_match_def     !< flag indicating that surface element is of default type
+       LOGICAL                         ::  surf_match_lsm     !< flag indicating that surface element is of natural type
+       LOGICAL                         ::  surf_match_usm     !< flag indicating that surface element is of urban type
+
+       TYPE(surf_type), DIMENSION(0:2) ::  surf_h             !< horizontal surface type on file
+       TYPE(surf_type), DIMENSION(0:3) ::  surf_v             !< vertical surface type on file
+
+!
+!--    Read number of respective surface elements on file
+       READ ( 13 )  field_chr
+       IF ( TRIM( field_chr ) /= 'ns_h_on_file' )  THEN
+!
+!--       Add a proper error message
+       ENDIF
+       READ ( 13 ) ns_h_on_file
+
+       READ ( 13 )  field_chr
+       IF ( TRIM( field_chr ) /= 'ns_v_on_file' )  THEN
+!
+!--       Add a proper error message
+       ENDIF
+       READ ( 13 ) ns_v_on_file
+!
+!--    Allocate memory for number of surface elements on file. Please note, 
+!--    these number is not necessarily the same as the final number of surface
+!--    elements on local domain, which is the case if processor topology changes
+!--    during restart runs. 
+!--    Horizontal upward facing
+       surf_h(0)%ns = ns_h_on_file(0)
+       CALL allocate_surface_attributes_h( surf_h(0),                          &
+                                           nys_on_file, nyn_on_file,           &
+                                           nxl_on_file, nxr_on_file )
+!
+!--    Horizontal downward facing
+       surf_h(1)%ns = ns_h_on_file(1)
+       CALL allocate_surface_attributes_h( surf_h(1),                          &
+                                           nys_on_file, nyn_on_file,           &
+                                           nxl_on_file, nxr_on_file )
+!
+!--    Model top
+       surf_h(2)%ns = ns_h_on_file(2)
+       CALL allocate_surface_attributes_h_top( surf_h(2),                      &
+                                               nys_on_file, nyn_on_file,       &
+                                               nxl_on_file, nxr_on_file )
+!
+!--    Vertical surfaces
+       DO  l = 0, 3
+          surf_v(l)%ns = ns_v_on_file(l)
+          CALL allocate_surface_attributes_v( surf_v(l), .FALSE.,              &
+                                              nys_on_file, nyn_on_file,        &
+                                              nxl_on_file, nxr_on_file )
+       ENDDO
+
+       IF ( initializing_actions == 'read_restart_data'  .OR.                  &
+            initializing_actions == 'cyclic_fill' )  THEN
+!
+!--       Initial setting of flags for horizontal and vertical surfaces, will
+!--       be set after start- and end-indices are read. 
+          horizontal_surface = .FALSE.
+          vertical_surface   = .FALSE.
+
+          READ ( 13 )  field_chr
+
+          DO  WHILE ( TRIM( field_chr ) /= '*** end surf ***' )
+!
+!--          Map data on file as often as needed (data are read only for k=1)
+             DO  kk = 1, overlap_count
+!
+!--             Get the index range of the subdomain on file which overlap with the
+!--             current subdomain
+                nxlf = nxlfa(ii,kk)
+                nxlc = nxlfa(ii,kk) + offset_xa(ii,kk)
+                nxrf = nxrfa(ii,kk)
+                nxrc = nxrfa(ii,kk) + offset_xa(ii,kk)
+                nysf = nysfa(ii,kk)
+                nysc = nysfa(ii,kk) + offset_ya(ii,kk)
+                nynf = nynfa(ii,kk)
+                nync = nynfa(ii,kk) + offset_ya(ii,kk)
+
+                SELECT CASE ( TRIM( field_chr ) )
+
+                   CASE ( 'surf_h(0)%start_index' )
+                      IF ( kk == 1 )                                           &
+                         READ ( 13 )  surf_h(0)%start_index
+                      l = 0
+                   CASE ( 'surf_h(0)%end_index' )   
+                      IF ( kk == 1 )                                           &
+                         READ ( 13 )  surf_h(0)%end_index
+                      horizontal_surface = .TRUE.
+                      vertical_surface   = .FALSE.
+                   CASE ( 'surf_h(0)%us' )         
+                      IF ( ALLOCATED( surf_h(0)%us )  .AND.  kk == 1 )         &
+                         READ ( 13 )  surf_h(0)%us
+                   CASE ( 'surf_h(0)%ts' )         
+                      IF ( ALLOCATED( surf_h(0)%ts )  .AND.  kk == 1 )         &
+                         READ ( 13 )  surf_h(0)%ts
+                   CASE ( 'surf_h(0)%qs' )         
+                      IF ( ALLOCATED( surf_h(0)%qs )  .AND.  kk == 1 )         &
+                         READ ( 13 )  surf_h(0)%qs
+                   CASE ( 'surf_h(0)%ss' )         
+                      IF ( ALLOCATED( surf_h(0)%ss )  .AND.  kk == 1 )         &
+                         READ ( 13 )  surf_h(0)%ss
+                   CASE ( 'surf_h(0)%qrs' )         
+                      IF ( ALLOCATED( surf_h(0)%qrs )  .AND.  kk == 1 )        &
+                         READ ( 13 )  surf_h(0)%qrs
+                   CASE ( 'surf_h(0)%nrs' )         
+                      IF ( ALLOCATED( surf_h(0)%nrs )  .AND.  kk == 1 )        &
+                         READ ( 13 )  surf_h(0)%nrs
+                   CASE ( 'surf_h(0)%ol' )         
+                      IF ( ALLOCATED( surf_h(0)%ol )  .AND.  kk == 1 )         &
+                         READ ( 13 )  surf_h(0)%ol
+                   CASE ( 'surf_h(0)%rib' )         
+                      IF ( ALLOCATED( surf_h(0)%rib )  .AND.  kk == 1 )        &
+                         READ ( 13 )  surf_h(0)%rib
+                   CASE ( 'surf_h(0)%usws' )         
+                      IF ( ALLOCATED( surf_h(0)%usws )  .AND.  kk == 1 )       &
+                         READ ( 13 )  surf_h(0)%usws
+                   CASE ( 'surf_h(0)%vsws' )         
+                      IF ( ALLOCATED( surf_h(0)%vsws )  .AND.  kk == 1 )       &
+                         READ ( 13 )  surf_h(0)%vsws
+                   CASE ( 'surf_h(0)%shf' )         
+                      IF ( ALLOCATED( surf_h(0)%shf )  .AND.  kk == 1 )        &
+                         READ ( 13 )  surf_h(0)%shf
+                   CASE ( 'surf_h(0)%qsws' )         
+                      IF ( ALLOCATED( surf_h(0)%qsws )  .AND.  kk == 1 )       &
+                         READ ( 13 )  surf_h(0)%qsws
+                   CASE ( 'surf_h(0)%ssws' )         
+                      IF ( ALLOCATED( surf_h(0)%ssws )  .AND.  kk == 1 )       &
+                         READ ( 13 )  surf_h(0)%ssws
+                   CASE ( 'surf_h(0)%qrsws' )         
+                      IF ( ALLOCATED( surf_h(0)%qrsws )  .AND.  kk == 1 )      &
+                         READ ( 13 )  surf_h(0)%qrsws
+                   CASE ( 'surf_h(0)%nrsws' )         
+                      IF ( ALLOCATED( surf_h(0)%nrsws )  .AND.  kk == 1 )      &
+                         READ ( 13 )  surf_h(0)%nrsws
+                   CASE ( 'surf_h(0)%sasws' )         
+                      IF ( ALLOCATED( surf_h(0)%sasws )  .AND.  kk == 1 )      &
+                         READ ( 13 )  surf_h(0)%sasws
+
+                   CASE ( 'surf_h(1)%start_index' )   
+                      IF ( kk == 1 )                                           &
+                         READ ( 13 )  surf_h(1)%start_index
+                      l = 1
+                   CASE ( 'surf_h(1)%end_index' )   
+                      IF ( kk == 1 )                                           &
+                         READ ( 13 )  surf_h(1)%end_index
+                   CASE ( 'surf_h(1)%us' )         
+                      IF ( ALLOCATED( surf_h(1)%us )  .AND.  kk == 1 )         &
+                         READ ( 13 )  surf_h(1)%us
+                   CASE ( 'surf_h(1)%ts' )         
+                      IF ( ALLOCATED( surf_h(1)%ts )  .AND.  kk == 1 )         &
+                         READ ( 13 )  surf_h(1)%ts
+                   CASE ( 'surf_h(1)%qs' )         
+                      IF ( ALLOCATED( surf_h(1)%qs )  .AND.  kk == 1 )         &
+                         READ ( 13 )  surf_h(1)%qs
+                   CASE ( 'surf_h(1)%ss' )         
+                      IF ( ALLOCATED( surf_h(1)%ss )  .AND.  kk == 1 )         &
+                         READ ( 13 )  surf_h(1)%ss
+                   CASE ( 'surf_h(1)%qrs' )         
+                      IF ( ALLOCATED( surf_h(1)%qrs )  .AND.  kk == 1 )        &
+                         READ ( 13 )  surf_h(1)%qrs
+                   CASE ( 'surf_h(1)%nrs' )         
+                      IF ( ALLOCATED( surf_h(1)%nrs )  .AND.  kk == 1 )        &
+                         READ ( 13 )  surf_h(1)%nrs
+                   CASE ( 'surf_h(1)%ol' )         
+                      IF ( ALLOCATED( surf_h(1)%ol )  .AND.  kk == 1 )         &
+                         READ ( 13 )  surf_h(1)%ol
+                   CASE ( 'surf_h(1)%rib' )         
+                      IF ( ALLOCATED( surf_h(1)%rib )  .AND.  kk == 1 )        &
+                         READ ( 13 )  surf_h(1)%rib
+                   CASE ( 'surf_h(1)%usws' )         
+                      IF ( ALLOCATED( surf_h(1)%usws )  .AND.  kk == 1 )       &
+                         READ ( 13 )  surf_h(1)%usws
+                   CASE ( 'surf_h(1)%vsws' )         
+                      IF ( ALLOCATED( surf_h(1)%vsws )  .AND.  kk == 1 )       &
+                         READ ( 13 )  surf_h(1)%vsws
+                   CASE ( 'surf_h(1)%shf' )         
+                      IF ( ALLOCATED( surf_h(1)%shf )  .AND.  kk == 1 )        &
+                         READ ( 13 )  surf_h(1)%shf
+                   CASE ( 'surf_h(1)%qsws' )         
+                      IF ( ALLOCATED( surf_h(1)%qsws )  .AND.  kk == 1 )       &
+                         READ ( 13 )  surf_h(1)%qsws
+                   CASE ( 'surf_h(1)%ssws' )         
+                      IF ( ALLOCATED( surf_h(1)%ssws )  .AND.  kk == 1 )       &
+                         READ ( 13 )  surf_h(1)%ssws
+                   CASE ( 'surf_h(1)%qrsws' )         
+                      IF ( ALLOCATED( surf_h(1)%qrsws )  .AND.  kk == 1 )      &
+                         READ ( 13 )  surf_h(1)%qrsws
+                   CASE ( 'surf_h(1)%nrsws' )         
+                      IF ( ALLOCATED( surf_h(1)%nrsws )  .AND.  kk == 1 )      &
+                         READ ( 13 )  surf_h(1)%nrsws
+                   CASE ( 'surf_h(1)%sasws' )         
+                      IF ( ALLOCATED( surf_h(1)%sasws )  .AND.  kk == 1 )      &
+                         READ ( 13 )  surf_h(1)%sasws
+
+                   CASE ( 'surf_h(2)%start_index' )   
+                      IF ( kk == 1 )                                           &
+                         READ ( 13 )  surf_h(2)%start_index
+                      l = 2
+                   CASE ( 'surf_h(2)%end_index' )   
+                      IF ( kk == 1 )                                           &
+                         READ ( 13 )  surf_h(2)%end_index
+                   CASE ( 'surf_h(2)%us' )         
+                      IF ( ALLOCATED( surf_h(2)%us )  .AND.  kk == 1 )         &
+                         READ ( 13 )  surf_h(2)%us
+                   CASE ( 'surf_h(2)%ts' )         
+                      IF ( ALLOCATED( surf_h(2)%ts )  .AND.  kk == 1 )         &
+                         READ ( 13 )  surf_h(2)%ts
+                   CASE ( 'surf_h(2)%qs' )        
+                      IF ( ALLOCATED( surf_h(2)%qs )  .AND.  kk == 1 )         &
+                         READ ( 13 )  surf_h(2)%qs
+                   CASE ( 'surf_h(2)%ss' )         
+                      IF ( ALLOCATED( surf_h(2)%ss )  .AND.  kk == 1 )         &
+                         READ ( 13 )  surf_h(2)%ss
+                   CASE ( 'surf_h(2)%qrs' )         
+                      IF ( ALLOCATED( surf_h(2)%qrs )  .AND.  kk == 1 )        &
+                         READ ( 13 )  surf_h(2)%qrs
+                   CASE ( 'surf_h(2)%nrs' )         
+                      IF ( ALLOCATED( surf_h(2)%nrs )  .AND.  kk == 1 )        &
+                         READ ( 13 )  surf_h(2)%nrs
+                   CASE ( 'surf_h(2)%ol' )         
+                      IF ( ALLOCATED( surf_h(2)%ol )  .AND.  kk == 1 )         &
+                         READ ( 13 )  surf_h(2)%ol
+                   CASE ( 'surf_h(2)%rib' )         
+                      IF ( ALLOCATED( surf_h(2)%rib )  .AND.  kk == 1 )        &
+                         READ ( 13 )  surf_h(2)%rib
+                   CASE ( 'surf_h(2)%usws' )         
+                      IF ( ALLOCATED( surf_h(2)%usws )  .AND.  kk == 1 )       &
+                         READ ( 13 )  surf_h(2)%usws
+                   CASE ( 'surf_h(2)%vsws' )         
+                      IF ( ALLOCATED( surf_h(2)%vsws )  .AND.  kk == 1 )       &
+                         READ ( 13 )  surf_h(2)%vsws
+                   CASE ( 'surf_h(2)%shf' )         
+                      IF ( ALLOCATED( surf_h(2)%shf )  .AND.  kk == 1 )        &
+                         READ ( 13 )  surf_h(2)%shf
+                   CASE ( 'surf_h(2)%qsws' )         
+                      IF ( ALLOCATED( surf_h(2)%qsws )  .AND.  kk == 1 )       &
+                         READ ( 13 )  surf_h(2)%qsws
+                   CASE ( 'surf_h(2)%ssws' )         
+                      IF ( ALLOCATED( surf_h(2)%ssws )  .AND.  kk == 1 )       &
+                         READ ( 13 )  surf_h(2)%ssws
+                   CASE ( 'surf_h(2)%qrsws' )         
+                      IF ( ALLOCATED( surf_h(2)%qrsws )  .AND.  kk == 1 )      &
+                         READ ( 13 )  surf_h(2)%qrsws
+                   CASE ( 'surf_h(2)%nrsws' )         
+                      IF ( ALLOCATED( surf_h(2)%nrsws )  .AND.  kk == 1 )      &
+                         READ ( 13 )  surf_h(2)%nrsws
+                   CASE ( 'surf_h(2)%sasws' )         
+                      IF ( ALLOCATED( surf_h(2)%sasws )  .AND.  kk == 1 )      &
+                         READ ( 13 )  surf_h(2)%sasws
+
+                   CASE ( 'surf_v(0)%start_index' )   
+                      IF ( kk == 1 )                                           &
+                         READ ( 13 )  surf_v(0)%start_index
+                      l = 0
+                      horizontal_surface = .FALSE.
+                      vertical_surface   = .TRUE.
+                   CASE ( 'surf_v(0)%end_index' )   
+                      IF ( kk == 1 )                                           &
+                         READ ( 13 )  surf_v(0)%end_index
+                   CASE ( 'surf_v(0)%us' )         
+                      IF ( ALLOCATED( surf_v(0)%us )  .AND.  kk == 1 )         &
+                         READ ( 13 )  surf_v(0)%us
+                   CASE ( 'surf_v(0)%ts' )         
+                      IF ( ALLOCATED( surf_v(0)%ts )  .AND.  kk == 1 )         &
+                         READ ( 13 )  surf_v(0)%ts
+                   CASE ( 'surf_v(0)%qs' )         
+                      IF ( ALLOCATED( surf_v(0)%qs )  .AND.  kk == 1 )         &
+                         READ ( 13 )  surf_v(0)%qs
+                   CASE ( 'surf_v(0)%ss' )         
+                      IF ( ALLOCATED( surf_v(0)%ss )  .AND.  kk == 1 )         &
+                         READ ( 13 )  surf_v(0)%ss
+                   CASE ( 'surf_v(0)%qrs' )         
+                      IF ( ALLOCATED( surf_v(0)%qrs )  .AND.  kk == 1 )        &
+                         READ ( 13 )  surf_v(0)%qrs
+                   CASE ( 'surf_v(0)%nrs' )         
+                      IF ( ALLOCATED( surf_v(0)%nrs )  .AND.  kk == 1 )        &
+                         READ ( 13 )  surf_v(0)%nrs
+                   CASE ( 'surf_v(0)%ol' )         
+                      IF ( ALLOCATED( surf_v(0)%ol )  .AND.  kk == 1 )         &
+                         READ ( 13 )  surf_v(0)%ol
+                   CASE ( 'surf_v(0)%rib' )         
+                      IF ( ALLOCATED( surf_v(0)%rib )  .AND.  kk == 1 )        &
+                         READ ( 13 )  surf_v(0)%rib
+                   CASE ( 'surf_v(0)%shf' )         
+                      IF ( ALLOCATED( surf_v(0)%shf )  .AND.  kk == 1 )        &
+                         READ ( 13 )  surf_v(0)%shf
+                   CASE ( 'surf_v(0)%qsws' )         
+                      IF ( ALLOCATED( surf_v(0)%qsws )  .AND.  kk == 1 )       &
+                         READ ( 13 )  surf_v(0)%qsws
+                   CASE ( 'surf_v(0)%ssws' )         
+                      IF ( ALLOCATED( surf_v(0)%ssws )  .AND.  kk == 1 )       &
+                         READ ( 13 )  surf_v(0)%ssws
+                   CASE ( 'surf_v(0)%qrsws' )         
+                      IF ( ALLOCATED( surf_v(0)%qrsws )  .AND.  kk == 1 )      &
+                         READ ( 13 )  surf_v(0)%qrsws
+                   CASE ( 'surf_v(0)%nrsws' )         
+                      IF ( ALLOCATED( surf_v(0)%nrsws )  .AND.  kk == 1 )      &
+                         READ ( 13 )  surf_v(0)%nrsws
+                   CASE ( 'surf_v(0)%sasws' )         
+                      IF ( ALLOCATED( surf_v(0)%sasws )  .AND.  kk == 1 )      &
+                         READ ( 13 )  surf_v(0)%sasws
+                   CASE ( 'surf_v(0)%mom_uv' )         
+                      IF ( ALLOCATED( surf_v(0)%mom_flux_uv )  .AND.  kk == 1 )&
+                         READ ( 13 )  surf_v(0)%mom_flux_uv
+                   CASE ( 'surf_v(0)%mom_w' )         
+                      IF ( ALLOCATED( surf_v(0)%mom_flux_w )  .AND.  kk == 1 ) &
+                         READ ( 13 )  surf_v(0)%mom_flux_w
+                   CASE ( 'surf_v(0)%mom_tke' )         
+                      IF ( ALLOCATED( surf_v(0)%mom_flux_tke )  .AND.  kk == 1 )&
+                         READ ( 13 )  surf_v(0)%mom_flux_tke
+
+                   CASE ( 'surf_v(1)%start_index' )   
+                      IF ( kk == 1 )                                           &
+                         READ ( 13 )  surf_v(1)%start_index
+                      l = 1
+                   CASE ( 'surf_v(1)%end_index' )   
+                      IF ( kk == 1 )                                           &
+                         READ ( 13 )  surf_v(1)%end_index
+                   CASE ( 'surf_v(1)%us' )         
+                      IF ( ALLOCATED( surf_v(1)%us )  .AND.  kk == 1 )         &
+                         READ ( 13 )  surf_v(1)%us
+                   CASE ( 'surf_v(1)%ts' )         
+                      IF ( ALLOCATED( surf_v(1)%ts )  .AND.  kk == 1 )         &
+                         READ ( 13 )  surf_v(1)%ts
+                   CASE ( 'surf_v(1)%qs' )         
+                      IF ( ALLOCATED( surf_v(1)%qs )  .AND.  kk == 1 )         &
+                         READ ( 13 )  surf_v(1)%qs
+                   CASE ( 'surf_v(1)%ss' )         
+                      IF ( ALLOCATED( surf_v(1)%ss )  .AND.  kk == 1 )         &
+                         READ ( 13 )  surf_v(1)%ss
+                   CASE ( 'surf_v(1)%qrs' )         
+                      IF ( ALLOCATED( surf_v(1)%qrs )  .AND.  kk == 1 )        &
+                         READ ( 13 )  surf_v(1)%qrs
+                   CASE ( 'surf_v(1)%nrs' )         
+                      IF ( ALLOCATED( surf_v(1)%nrs )  .AND.  kk == 1 )        &
+                         READ ( 13 )  surf_v(1)%nrs
+                   CASE ( 'surf_v(1)%ol' )         
+                      IF ( ALLOCATED( surf_v(1)%ol )  .AND.  kk == 1 )         &
+                         READ ( 13 )  surf_v(1)%ol
+                   CASE ( 'surf_v(1)%rib' )         
+                      IF ( ALLOCATED( surf_v(1)%rib )  .AND.  kk == 1 )        &
+                         READ ( 13 )  surf_v(1)%rib
+                   CASE ( 'surf_v(1)%shf' )         
+                      IF ( ALLOCATED( surf_v(1)%shf )  .AND.  kk == 1 )        &
+                         READ ( 13 )  surf_v(1)%shf
+                   CASE ( 'surf_v(1)%qsws' )         
+                      IF ( ALLOCATED( surf_v(1)%qsws )  .AND.  kk == 1 )       &
+                         READ ( 13 )  surf_v(1)%qsws
+                   CASE ( 'surf_v(1)%ssws' )         
+                      IF ( ALLOCATED( surf_v(1)%ssws )  .AND.  kk == 1 )       &
+                         READ ( 13 )  surf_v(1)%ssws
+                   CASE ( 'surf_v(1)%qrsws' )         
+                      IF ( ALLOCATED( surf_v(1)%qrsws )  .AND.  kk == 1 )      &
+                         READ ( 13 )  surf_v(1)%qrsws
+                   CASE ( 'surf_v(1)%nrsws' )         
+                      IF ( ALLOCATED( surf_v(1)%nrsws )  .AND.  kk == 1 )      &
+                         READ ( 13 )  surf_v(1)%nrsws
+                   CASE ( 'surf_v(1)%sasws' )         
+                      IF ( ALLOCATED( surf_v(1)%sasws )  .AND.  kk == 1 )      &
+                         READ ( 13 )  surf_v(1)%sasws
+                   CASE ( 'surf_v(1)%mom_uv' )         
+                      IF ( ALLOCATED( surf_v(1)%mom_flux_uv )  .AND.  kk == 1 )&
+                         READ ( 13 )  surf_v(1)%mom_flux_uv
+                   CASE ( 'surf_v(1)%mom_w' )         
+                      IF ( ALLOCATED( surf_v(1)%mom_flux_w )  .AND.  kk == 1 ) &
+                         READ ( 13 )  surf_v(1)%mom_flux_w
+                   CASE ( 'surf_v(1)%mom_tke' )         
+                      IF ( ALLOCATED( surf_v(1)%mom_flux_tke )  .AND.  kk == 1 )&
+                         READ ( 13 )  surf_v(1)%mom_flux_tke
+
+                   CASE ( 'surf_v(2)%start_index' )   
+                      IF ( kk == 1 )                                           &
+                         READ ( 13 )  surf_v(2)%start_index
+                      l = 2
+                   CASE ( 'surf_v(2)%end_index' )   
+                      IF ( kk == 1 )                                           &
+                         READ ( 13 )  surf_v(2)%end_index
+                   CASE ( 'surf_v(2)%us' )         
+                      IF ( ALLOCATED( surf_v(2)%us )  .AND.  kk == 1 )         &
+                         READ ( 13 )  surf_v(2)%us
+                   CASE ( 'surf_v(2)%ts' )         
+                      IF ( ALLOCATED( surf_v(2)%ts )  .AND.  kk == 1 )         &
+                         READ ( 13 )  surf_v(2)%ts
+                   CASE ( 'surf_v(2)%qs' )         
+                      IF ( ALLOCATED( surf_v(2)%qs )  .AND.  kk == 1 )         &
+                         READ ( 13 )  surf_v(2)%qs
+                   CASE ( 'surf_v(2)%ss' )         
+                      IF ( ALLOCATED( surf_v(2)%ss )  .AND.  kk == 1 )         &
+                         READ ( 13 )  surf_v(2)%ss
+                   CASE ( 'surf_v(2)%qrs' )         
+                      IF ( ALLOCATED( surf_v(2)%qrs )  .AND.  kk == 1 )        &
+                         READ ( 13 )  surf_v(2)%qrs
+                   CASE ( 'surf_v(2)%nrs' )         
+                      IF ( ALLOCATED( surf_v(2)%nrs )  .AND.  kk == 1 )        &
+                         READ ( 13 )  surf_v(2)%nrs
+                   CASE ( 'surf_v(2)%ol' )         
+                      IF ( ALLOCATED( surf_v(2)%ol )  .AND.  kk == 1 )         &
+                         READ ( 13 )  surf_v(2)%ol
+                   CASE ( 'surf_v(2)%rib' )         
+                      IF ( ALLOCATED( surf_v(2)%rib )  .AND.  kk == 1 )        &
+                         READ ( 13 )  surf_v(2)%rib
+                   CASE ( 'surf_v(2)%shf' )         
+                      IF ( ALLOCATED( surf_v(2)%shf )  .AND.  kk == 1 )        &
+                         READ ( 13 )  surf_v(2)%shf
+                   CASE ( 'surf_v(2)%qsws' )         
+                      IF ( ALLOCATED( surf_v(2)%qsws )  .AND.  kk == 1 )       &
+                         READ ( 13 )  surf_v(2)%qsws
+                   CASE ( 'surf_v(2)%ssws' )         
+                      IF ( ALLOCATED( surf_v(2)%ssws )  .AND.  kk == 1 )       &
+                         READ ( 13 )  surf_v(2)%ssws
+                   CASE ( 'surf_v(2)%qrsws' )         
+                      IF ( ALLOCATED( surf_v(2)%qrsws )  .AND.  kk == 1 )      &
+                         READ ( 13 )  surf_v(2)%qrsws
+                   CASE ( 'surf_v(2)%nrsws' )         
+                      IF ( ALLOCATED( surf_v(2)%nrsws )  .AND.  kk == 1 )      &
+                         READ ( 13 )  surf_v(2)%nrsws
+                   CASE ( 'surf_v(2)%sasws' )         
+                      IF ( ALLOCATED( surf_v(2)%sasws )  .AND.  kk == 1 )      &
+                         READ ( 13 )  surf_v(2)%sasws
+                   CASE ( 'surf_v(2)%mom_uv' )         
+                      IF ( ALLOCATED( surf_v(2)%mom_flux_uv )  .AND.  kk == 1 )&
+                         READ ( 13 )  surf_v(2)%mom_flux_uv
+                   CASE ( 'surf_v(2)%mom_w' )         
+                      IF ( ALLOCATED( surf_v(2)%mom_flux_w )  .AND.  kk == 1 ) &
+                         READ ( 13 )  surf_v(2)%mom_flux_w
+                   CASE ( 'surf_v(2)%mom_tke' )         
+                      IF ( ALLOCATED( surf_v(2)%mom_flux_tke )  .AND.  kk == 1 )&
+                         READ ( 13 )  surf_v(2)%mom_flux_tke
+
+                   CASE ( 'surf_v(3)%start_index' )   
+                      IF ( kk == 1 )                                           &
+                         READ ( 13 )  surf_v(3)%start_index
+                      l = 3
+                   CASE ( 'surf_v(3)%end_index' )   
+                      IF ( kk == 1 )                                           &
+                         READ ( 13 )  surf_v(3)%end_index
+                   CASE ( 'surf_v(3)%us' )         
+                      IF ( ALLOCATED( surf_v(3)%us )  .AND.  kk == 1 )         &
+                         READ ( 13 )  surf_v(3)%us
+                   CASE ( 'surf_v(3)%ts' )         
+                      IF ( ALLOCATED( surf_v(3)%ts )  .AND.  kk == 1 )         &
+                         READ ( 13 )  surf_v(3)%ts
+                   CASE ( 'surf_v(3)%qs' )        
+                      IF ( ALLOCATED( surf_v(3)%qs )  .AND.  kk == 1 )         &
+                         READ ( 13 )  surf_v(3)%qs
+                   CASE ( 'surf_v(3)%ss' )         
+                      IF ( ALLOCATED( surf_v(3)%ss )  .AND.  kk == 1 )         &
+                         READ ( 13 )  surf_v(3)%ss
+                   CASE ( 'surf_v(3)%qrs' )         
+                      IF ( ALLOCATED( surf_v(3)%qrs )  .AND.  kk == 1 )        &
+                         READ ( 13 )  surf_v(3)%qrs
+                   CASE ( 'surf_v(3)%nrs' )         
+                      IF ( ALLOCATED( surf_v(3)%nrs )  .AND.  kk == 1 )        &
+                         READ ( 13 )  surf_v(3)%nrs
+                   CASE ( 'surf_v(3)%ol' )         
+                      IF ( ALLOCATED( surf_v(3)%ol )  .AND.  kk == 1 )         &
+                         READ ( 13 )  surf_v(3)%ol
+                   CASE ( 'surf_v(3)%rib' )         
+                      IF ( ALLOCATED( surf_v(3)%rib )  .AND.  kk == 1 )        &
+                         READ ( 13 )  surf_v(3)%rib
+                   CASE ( 'surf_v(3)%shf' )         
+                      IF ( ALLOCATED( surf_v(3)%shf )  .AND.  kk == 1 )        &
+                         READ ( 13 )  surf_v(3)%shf
+                   CASE ( 'surf_v(3)%qsws' )         
+                      IF ( ALLOCATED( surf_v(3)%qsws )  .AND.  kk == 1 )       &
+                         READ ( 13 )  surf_v(3)%qsws
+                   CASE ( 'surf_v(3)%ssws' )         
+                      IF ( ALLOCATED( surf_v(3)%ssws )  .AND.  kk == 1 )       &
+                         READ ( 13 )  surf_v(3)%ssws
+                   CASE ( 'surf_v(3)%qrsws' )         
+                      IF ( ALLOCATED( surf_v(3)%qrsws )  .AND.  kk == 1 )      &
+                         READ ( 13 )  surf_v(3)%qrsws
+                   CASE ( 'surf_v(3)%nrsws' )         
+                      IF ( ALLOCATED( surf_v(3)%nrsws )  .AND.  kk == 1 )      &
+                         READ ( 13 )  surf_v(3)%nrsws
+                   CASE ( 'surf_v(3)%sasws' )         
+                      IF ( ALLOCATED( surf_v(3)%sasws )  .AND.  kk == 1 )      &
+                         READ ( 13 )  surf_v(3)%sasws
+                   CASE ( 'surf_v(3)%mom_uv' )         
+                      IF ( ALLOCATED( surf_v(3)%mom_flux_uv )  .AND.  kk == 1 )&
+                         READ ( 13 )  surf_v(3)%mom_flux_uv
+                   CASE ( 'surf_v(3)%mom_w' )         
+                      IF ( ALLOCATED( surf_v(3)%mom_flux_w )  .AND.  kk == 1 ) &
+                         READ ( 13 )  surf_v(3)%mom_flux_w
+                   CASE ( 'surf_v(3)%mom_tke' )         
+                      IF ( ALLOCATED( surf_v(3)%mom_flux_tke )  .AND.  kk == 1 )&
+                         READ ( 13 )  surf_v(3)%mom_flux_tke
+
+                END SELECT
+!
+!--             Redistribute surface elements on its respective type. 
+                IF ( horizontal_surface )  THEN
+                   ic = nxlc
+                   DO  i = nxlf, nxrf
+                      jc = nysc
+                      DO  j = nysf, nynf
+
+                         surf_match_def  = surf_def_h(l)%end_index(jc,ic) >=   &
+                                           surf_def_h(l)%start_index(jc,ic)
+                         surf_match_lsm  = surf_lsm_h%end_index(jc,ic)    >=   &
+                                           surf_lsm_h%start_index(jc,ic)
+                         surf_match_usm  = surf_usm_h%end_index(jc,ic)    >=   &
+                                           surf_usm_h%start_index(jc,ic)
+
+                         IF ( surf_match_def )  THEN
+                            mm = surf_def_h(l)%start_index(jc,ic)
+                            DO  m = surf_h(l)%start_index(j,i),                &
+                                    surf_h(l)%end_index(j,i)
+                               CALL restore_surface_elements( surf_def_h(l),   &
+                                                              mm, surf_h(l), m )
+                               mm = mm + 1
+                            ENDDO
+                         ENDIF
+
+                         IF ( surf_match_lsm )  THEN
+                            mm = surf_lsm_h%start_index(jc,ic)
+                            DO  m = surf_h(l)%start_index(j,i),                &
+                                    surf_h(l)%end_index(j,i)
+                               CALL restore_surface_elements( surf_lsm_h,      &
+                                                              mm, surf_h(l), m )
+                               mm = mm + 1
+                            ENDDO
+                         ENDIF
+
+                         IF ( surf_match_usm )  THEN
+                            mm = surf_usm_h%start_index(jc,ic)
+                            DO  m = surf_h(l)%start_index(j,i),                &
+                                    surf_h(l)%end_index(j,i)
+                               CALL restore_surface_elements( surf_usm_h,      &
+                                                              mm, surf_h(l), m )
+                               mm = mm + 1
+                            ENDDO
+                         ENDIF
+
+                         jc = jc + 1
+                      ENDDO
+                      ic = ic + 1
+                   ENDDO
+                ELSEIF ( vertical_surface )  THEN
+                   ic = nxlc
+                   DO  i = nxlf, nxrf
+                      jc = nysc
+                      DO  j = nysf, nynf
+
+                         surf_match_def  = surf_def_v(l)%end_index(jc,ic) >=   &
+                                           surf_def_v(l)%start_index(jc,ic)
+                         surf_match_lsm  = surf_lsm_v(l)%end_index(jc,ic) >=   &
+                                           surf_lsm_v(l)%start_index(jc,ic)
+                         surf_match_usm  = surf_usm_v(l)%end_index(jc,ic) >=   &
+                                           surf_usm_v(l)%start_index(jc,ic)
+
+
+
+                         IF ( surf_match_def )  THEN
+                            mm = surf_def_v(l)%start_index(jc,ic)
+                            DO  m = surf_v(l)%start_index(j,i),                &
+                                    surf_v(l)%end_index(j,i)
+                               CALL restore_surface_elements( surf_def_v(l),   &
+                                                              mm, surf_v(l), m )
+                               mm = mm + 1
+                            ENDDO
+                         ENDIF
+
+                         IF ( surf_match_lsm )  THEN
+                            mm = surf_lsm_v(l)%start_index(jc,ic)
+                            DO  m = surf_v(l)%start_index(j,i),                &
+                                    surf_v(l)%end_index(j,i)
+                               CALL restore_surface_elements( surf_lsm_v(l),   &
+                                                              mm, surf_v(l), m )
+                               mm = mm + 1
+                            ENDDO
+                         ENDIF
+   
+                         IF ( surf_match_usm )  THEN
+                            mm = surf_usm_v(l)%start_index(jc,ic)
+                            DO  m = surf_v(l)%start_index(j,i),                &
+                                    surf_v(l)%end_index(j,i)
+                               CALL restore_surface_elements( surf_usm_v(l),   &
+                                                              mm, surf_v(l), m )
+                               mm = mm + 1
+                            ENDDO
+                         ENDIF
+
+                         jc = jc + 1
+                      ENDDO
+                      ic = ic + 1
+                   ENDDO
+                ENDIF
+
+             ENDDO
+
+             READ ( 13 )  field_chr
+
+          ENDDO
+
+       ENDIF
+
+
+       CONTAINS
+!------------------------------------------------------------------------------!
+! Description:
+! ------------
+!> Restores surfacle elements back on its respective type.
+!------------------------------------------------------------------------------!
+          SUBROUTINE restore_surface_elements( surf_target, m_target,          &
+                                               surf_file,   m_file )
+
+             IMPLICIT NONE
+
+             INTEGER(iwp)      ::  m_file      !< respective surface-element index of current surface array 
+             INTEGER(iwp)      ::  m_target    !< respecitve surface-element index of surface array on file
+
+             TYPE( surf_type ) ::  surf_target !< target surface type
+             TYPE( surf_type ) ::  surf_file   !< surface type on file
+
+             IF ( SCAN( TRIM( field_chr ), '%us' ) /= 0 )  THEN 
+                IF ( ALLOCATED( surf_target%us )  .AND.                        &
+                     ALLOCATED( surf_file%us   ) )                             & 
+                   surf_target%us(m_target) = surf_file%us(m_file)
+             ENDIF
+
+             IF ( SCAN( TRIM( field_chr ), '%ol' ) /= 0 )  THEN 
+                IF ( ALLOCATED( surf_target%ol )  .AND.                        &
+                     ALLOCATED( surf_file%ol   ) )                             & 
+                   surf_target%ol(m_target) = surf_file%ol(m_file)
+             ENDIF
+
+             IF ( SCAN( TRIM( field_chr ), '%usws' ) /= 0 )  THEN 
+                IF ( ALLOCATED( surf_target%usws )  .AND.                      &
+                     ALLOCATED( surf_file%usws   ) )                           & 
+                   surf_target%usws(m_target) = surf_file%usws(m_file)
+             ENDIF
+
+             IF ( SCAN( TRIM( field_chr ), '%vsws' ) /= 0 )  THEN 
+                IF ( ALLOCATED( surf_target%vsws )  .AND.                      &
+                     ALLOCATED( surf_file%vsws   ) )                           & 
+                   surf_target%vsws(m_target) = surf_file%vsws(m_file)
+             ENDIF
+
+             IF ( SCAN( TRIM( field_chr ), '%ts' ) /= 0 )  THEN 
+                IF ( ALLOCATED( surf_target%ts )  .AND.                        &
+                     ALLOCATED( surf_file%ts   ) )                             & 
+                   surf_target%ts(m_target) = surf_file%ts(m_file)
+             ENDIF
+
+             IF ( SCAN( TRIM( field_chr ), '%shf' ) /= 0 )  THEN 
+                IF ( ALLOCATED( surf_target%shf )  .AND.                       &
+                     ALLOCATED( surf_file%shf   ) )                            & 
+                   surf_target%shf(m_target) = surf_file%shf(m_file)
+             ENDIF
+
+             IF ( SCAN( TRIM( field_chr ), '%qs' ) /= 0 )  THEN 
+                IF ( ALLOCATED( surf_target%qs )  .AND.                        &
+                     ALLOCATED( surf_file%qs   ) )                             & 
+                   surf_target%qs(m_target) = surf_file%qs(m_file)
+             ENDIF
+
+             IF ( SCAN( TRIM( field_chr ), '%qsws' ) /= 0 )  THEN 
+                IF ( ALLOCATED( surf_target%qsws )  .AND.                      &
+                     ALLOCATED( surf_file%qsws   ) )                           & 
+                   surf_target%qsws(m_target) = surf_file%qsws(m_file)
+             ENDIF
+
+             IF ( SCAN( TRIM( field_chr ), '%ss' ) /= 0 )  THEN 
+                IF ( ALLOCATED( surf_target%ss )  .AND.                        &
+                     ALLOCATED( surf_file%ss   ) )                             & 
+                   surf_target%ss(m_target) = surf_file%ss(m_file)
+             ENDIF
+
+             IF ( SCAN( TRIM( field_chr ), '%ssws' ) /= 0 )  THEN 
+                IF ( ALLOCATED( surf_target%ssws )  .AND.                      &
+                     ALLOCATED( surf_file%ssws   ) )                           & 
+                   surf_target%ssws(m_target) = surf_file%ssws(m_file)
+             ENDIF
+
+             IF ( SCAN( TRIM( field_chr ), '%qrs' ) /= 0 )  THEN 
+                IF ( ALLOCATED( surf_target%qrs )  .AND.                       &
+                     ALLOCATED( surf_file%qrs   ) )                            & 
+                  surf_target%qrs(m_target) = surf_file%qrs(m_file)
+             ENDIF
+
+             IF ( SCAN( TRIM( field_chr ), '%qrsws' ) /= 0 )  THEN 
+                IF ( ALLOCATED( surf_target%qrsws )  .AND.                     &
+                     ALLOCATED( surf_file%qrsws   ) )                          & 
+                   surf_target%qrsws(m_target) = surf_file%qrsws(m_file)
+             ENDIF
+
+             IF ( SCAN( TRIM( field_chr ), '%nrs' ) /= 0 )  THEN 
+                IF ( ALLOCATED( surf_target%nrs )  .AND.                       &
+                     ALLOCATED( surf_file%nrs   ) )                            & 
+                   surf_target%nrs(m_target) = surf_file%nrs(m_file)
+             ENDIF
+
+             IF ( SCAN( TRIM( field_chr ), '%nrsws' ) /= 0 )  THEN 
+                IF ( ALLOCATED( surf_target%nrsws )  .AND.                     &
+                     ALLOCATED( surf_file%nrsws   ) )                          & 
+                   surf_target%nrsws(m_target) = surf_file%nrsws(m_file)
+             ENDIF
+
+             IF ( SCAN( TRIM( field_chr ), '%sasws' ) /= 0 )  THEN 
+                IF ( ALLOCATED( surf_target%sasws )  .AND.                     &
+                     ALLOCATED( surf_file%sasws   ) )                          & 
+                   surf_target%sasws(m_target) = surf_file%sasws(m_file)
+             ENDIF
+
+             IF ( SCAN( TRIM( field_chr ), '%mom_uv' ) /= 0 )  THEN 
+                IF ( ALLOCATED( surf_target%mom_flux_uv )  .AND.               &
+                     ALLOCATED( surf_file%mom_flux_uv   ) )                    & 
+                   surf_target%mom_flux_uv(m_target) =                         &
+                                           surf_file%mom_flux_uv(m_file)
+             ENDIF
+
+             IF ( SCAN( TRIM( field_chr ), '%mom_w' ) /= 0 )  THEN 
+                IF ( ALLOCATED( surf_target%mom_flux_w )  .AND.                &
+                     ALLOCATED( surf_file%mom_flux_w   ) )                     & 
+                   surf_target%mom_flux_w(m_target) =                          &
+                                           surf_file%mom_flux_w(m_file)
+             ENDIF
+
+             IF ( SCAN( TRIM( field_chr ), '%mom_tke' ) /= 0 )  THEN 
+                IF ( ALLOCATED( surf_target%mom_flux_tke )  .AND.              &
+                     ALLOCATED( surf_file%mom_flux_tke   ) )                   & 
+                   surf_target%mom_flux_tke(0:1,m_target) =                    &
+                                           surf_file%mom_flux_tke(0:1,m_file)
+             ENDIF
+
+          END SUBROUTINE restore_surface_elements
+
+    END SUBROUTINE surface_read_restart_data
+
+ 
+!------------------------------------------------------------------------------!
+! Description:
+! ------------
+!> Counts the number of surface elements with the same facing, required for 
+!> reading and writing restart data.
+!------------------------------------------------------------------------------!
+    SUBROUTINE surface_last_actions
+
+       IMPLICIT NONE
+!
+!--    Horizontal surfaces
+       ns_h_on_file(0) = surf_def_h(0)%ns + surf_lsm_h%ns + surf_usm_h%ns
+       ns_h_on_file(1) = surf_def_h(1)%ns
+       ns_h_on_file(2) = surf_def_h(2)%ns
+!
+!--    Vertical surfaces
+       ns_v_on_file(0) = surf_def_v(0)%ns + surf_lsm_v(0)%ns + surf_usm_v(0)%ns
+       ns_v_on_file(1) = surf_def_v(1)%ns + surf_lsm_v(1)%ns + surf_usm_v(1)%ns
+       ns_v_on_file(2) = surf_def_v(2)%ns + surf_lsm_v(2)%ns + surf_usm_v(2)%ns
+       ns_v_on_file(3) = surf_def_v(3)%ns + surf_lsm_v(3)%ns + surf_usm_v(3)%ns
+
+    END SUBROUTINE surface_last_actions
+
+
+ END MODULE surface_mod
Index: /palm/trunk/SOURCE/swap_timelevel.f90
===================================================================
--- /palm/trunk/SOURCE/swap_timelevel.f90	(revision 2231)
+++ /palm/trunk/SOURCE/swap_timelevel.f90	(revision 2232)
@@ -20,5 +20,5 @@
 ! Current revisions:
 ! -----------------
-! 
+! Adjustments to new surface concept
 ! 
 ! Former revisions:
@@ -111,5 +111,5 @@
 
     USE land_surface_model_mod,                                                &
-        ONLY: land_surface, lsm_swap_timelevel
+        ONLY: lsm_swap_timelevel
 
     USE cpulog,                                                                &
@@ -117,5 +117,5 @@
 
     USE control_parameters,                                                    &
-        ONLY:  cloud_physics, constant_diffusion, humidity,                    &
+        ONLY:  cloud_physics, constant_diffusion, humidity, land_surface,      &
                microphysics_seifert, neutral, ocean, passive_scalar,           &
                timestep_count, urban_surface
Index: /palm/trunk/SOURCE/time_integration.f90
===================================================================
--- /palm/trunk/SOURCE/time_integration.f90	(revision 2231)
+++ /palm/trunk/SOURCE/time_integration.f90	(revision 2232)
@@ -20,5 +20,6 @@
 ! Current revisions:
 ! ------------------
-! 
+! Adjustments to new topography and surface concept
+! Modify passed parameters for disturb_field
 ! 
 ! Former revisions:
@@ -278,6 +279,6 @@
                dt_dopr_listing, dt_dots, dt_dvrp, dt_run_control,              &
                end_time, first_call_lpm, galilei_transformation, humidity,     &
-               intermediate_timestep_count,                                    &
-               intermediate_timestep_count_max, large_scale_forcing,           &
+               intermediate_timestep_count, intermediate_timestep_count_max,   &
+               land_surface, large_scale_forcing,                              &
                loop_optimization, lsf_surf, lsf_vert, masks,                   &
                microphysics_seifert, mid, nest_domain,                         &
@@ -308,6 +309,5 @@
 
     USE indices,                                                               &
-        ONLY:  nbgp, nx, nxl, nxlg, nxr, nxrg, nyn, nyng, nys, nysg, nzb, nzt, &
-               nzb_u_inner, nzb_v_inner
+        ONLY:  nbgp, nx, nxl, nxlg, nxr, nxrg, nyn, nyng, nys, nysg, nzb, nzt
 
     USE interaction_droplets_ptq_mod,                                          &
@@ -319,5 +319,5 @@
 
     USE land_surface_model_mod,                                                &
-        ONLY:  land_surface, lsm_energy_balance, lsm_soil_model,               &
+        ONLY:  lsm_energy_balance, lsm_soil_model,                             &
                skip_time_do_lsm
 
@@ -365,6 +365,9 @@
         ONLY:  surface_layer_fluxes
 
+    USE surface_mod,                                                           &
+        ONLY:  surf_def_h, surf_lsm_h, surf_usm_h
+
     USE urban_surface_mod,                                                     &
-        ONLY:  usm_material_heat_model, usm_material_model,     &
+        ONLY:  usm_material_heat_model, usm_material_model,                    &
                usm_radiation, usm_surface_energy_balance              
 
@@ -433,5 +436,4 @@
 
        CALL cpu_log( log_point_s(10), 'timesteps', 'start' )
-
 !
 !--    Determine ug, vg and w_subs in dependence on data from external file 
@@ -594,5 +596,4 @@
 !--       velocities at the outflow in case of a non-cyclic lateral wall)
           CALL boundary_conds
-
 !
 !--       Swap the time levels in preparation for the next time step.
@@ -678,6 +679,6 @@
                 IF ( disturbance_energy_limit /= 0.0_wp  .AND.                 &
                      hom(nzb+5,1,pr_palm,0) < disturbance_energy_limit )  THEN
-                   CALL disturb_field( nzb_u_inner, tend, u )
-                   CALL disturb_field( nzb_v_inner, tend, v )
+                   CALL disturb_field( 'u', tend, u )
+                   CALL disturb_field( 'v', tend, v )
                 ELSEIF ( ( .NOT. bc_lr_cyc  .OR.  .NOT. bc_ns_cyc )            &
                      .AND. .NOT. nest_domain )  THEN
@@ -686,6 +687,6 @@
 !--                near the inflow throughout the whole simulation
                    dist_range = 1
-                   CALL disturb_field( nzb_u_inner, tend, u )
-                   CALL disturb_field( nzb_v_inner, tend, v )
+                   CALL disturb_field( 'u', tend, u )
+                   CALL disturb_field( 'v', tend, v )
                    dist_range = 0
                 ENDIF
@@ -728,5 +729,6 @@
 
 !
-!--          First the vertical fluxes in the surface (constant flux) layer are computed
+!--          First the vertical (and horizontal) fluxes in the surface 
+!--          (constant flux) layer are computed
              IF ( constant_flux_layer )  THEN
                 CALL cpu_log( log_point(19), 'surface_layer_fluxes', 'start' )
@@ -737,10 +739,29 @@
 !
 !--          If required, solve the energy balance for the surface and run soil 
-!--          model
+!--          model. Call for horizontal as well as vertical surfaces
              IF ( land_surface .AND. simulated_time > skip_time_do_lsm)  THEN
 
                 CALL cpu_log( log_point(54), 'land_surface', 'start' )
-                CALL lsm_energy_balance
-                CALL lsm_soil_model
+!
+!--             Call for horizontal upward-facing surfaces
+                CALL lsm_energy_balance( .TRUE., -1 )
+                CALL lsm_soil_model( .TRUE., -1 )
+!
+!--             Call for northward-facing surfaces
+                CALL lsm_energy_balance( .FALSE., 0 )
+                CALL lsm_soil_model( .FALSE., 0 )
+!
+!--             Call for southward-facing surfaces
+                CALL lsm_energy_balance( .FALSE., 1 )
+                CALL lsm_soil_model( .FALSE., 1 )
+!
+!--             Call for eastward-facing surfaces
+                CALL lsm_energy_balance( .FALSE., 2 )
+                CALL lsm_soil_model( .FALSE., 2 )
+!
+!--             Call for westward-facing surfaces
+                CALL lsm_energy_balance( .FALSE., 3 )
+                CALL lsm_soil_model( .FALSE., 3 )
+
                 CALL cpu_log( log_point(54), 'land_surface', 'stop' )
              ENDIF
@@ -770,4 +791,5 @@
                 CALL diffusivities( vpt, pt_reference )
              ENDIF
+
              CALL cpu_log( log_point(17), 'diffusivities', 'stop' )
 
@@ -1048,5 +1070,9 @@
 !
 !--    If required, set the heat flux for the next time step at a random value
-       IF ( constant_heatflux  .AND.  random_heatflux )  CALL disturb_heatflux
+       IF ( constant_heatflux  .AND.  random_heatflux )  THEN
+          IF ( surf_def_h(0)%ns >= 1 )  CALL disturb_heatflux( surf_def_h(0) )
+          IF ( surf_lsm_h%ns    >= 1 )  CALL disturb_heatflux( surf_lsm_h    )
+          IF ( surf_usm_h%ns    >= 1 )  CALL disturb_heatflux( surf_usm_h    )
+       ENDIF
 
 !
Index: /palm/trunk/SOURCE/urban_surface_mod.f90
===================================================================
--- /palm/trunk/SOURCE/urban_surface_mod.f90	(revision 2231)
+++ /palm/trunk/SOURCE/urban_surface_mod.f90	(revision 2232)
@@ -21,5 +21,6 @@
 ! Current revisions:
 ! ------------------
-! 
+! Adjustments according to new surface-type structure. Remove usm_wall_heat_flux; 
+! insteat, heat fluxes are directly applied in diffusion_s.
 ! 
 ! Former revisions:
@@ -103,4 +104,7 @@
 !>    reflection step using MPI_Alltoall instead of current MPI_Allgather.
 !>
+!> 3. Temporarily large values of surface heat flux can be observed, up to
+!>    1.2 Km/s, which seem to be not realistic.
+!>
 !> @todo Check optimizations for RMA operations
 !> @todo Alternatives for MPI_WIN_ALLOCATE? (causes problems with openmpi)
@@ -111,5 +115,5 @@
 
     USE arrays_3d,                                                             &
-        ONLY:  zu, pt, pt_1, pt_2, p, ol, shf, ts, us, u, v, w, hyp, tend
+        ONLY:  zu, pt, pt_1, pt_2, p, u, v, w, hyp, tend
 
     USE cloud_parameters,                                                      &
@@ -137,5 +141,5 @@
     USE indices,                                                               &
         ONLY:  nx, ny, nnx, nny, nnz, nxl, nxlg, nxr, nxrg, nyn, nyng, nys,    &
-               nysg, nzb_s_inner, nzb_s_outer, nzb, nzt, nbgp
+               nysg, nzb, nzt, nbgp, wall_flags_0
 
     USE, INTRINSIC :: iso_c_binding 
@@ -157,4 +161,6 @@
     USE statistics,                                                            &
         ONLY:  hom, statistic_regions
+
+    USE surface_mod
 
                
@@ -265,4 +271,14 @@
         REAL(wp)                                   :: rtransp           !< 
     END TYPE
+!
+!-- Type for surface temperatures at vertical walls. Is not necessary for horizontal walls. 
+    TYPE t_surf_vertical
+       REAL(wp), DIMENSION(:), ALLOCATABLE         :: t
+    END TYPE t_surf_vertical
+!
+!-- Type for wall temperatures at vertical walls. Is not necessary for horizontal walls. 
+    TYPE t_wall_vertical
+       REAL(wp), DIMENSION(:,:), ALLOCATABLE       :: t
+    END TYPE t_wall_vertical
 
 !-- arrays for calculation of svf and csf
@@ -320,5 +336,5 @@
     REAL(wp), DIMENSION(:), ALLOCATABLE            ::  surfins_av       !< average of array of residua of sw radiation absorbed in surface after last reflection
     REAL(wp), DIMENSION(:), ALLOCATABLE            ::  surfinl_av       !< average of array of residua of lw radiation absorbed in surface after last reflection
-    REAL(wp), DIMENSION(:), ALLOCATABLE            ::  surfhf_av        !< average of total radiation flux incoming to minus outgoing from local surface    
+    REAL(wp), DIMENSION(:), ALLOCATABLE            ::  surfhf_av        !< average of total radiation flux incoming to minus outgoing from local surface  
     
 !-- block variables needed for calculation of the plant canopy model inside the urban surface model
@@ -367,21 +383,24 @@
 !-- surface and material model variables for walls, ground, roofs
 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-    INTEGER(iwp), DIMENSION(:), ALLOCATABLE        :: surface_types      !< array of types of wall parameters
     REAL(wp), DIMENSION(:), ALLOCATABLE            :: zwn                !< normalized wall layer depths (m)
-    REAL(wp), DIMENSION(:,:), ALLOCATABLE          :: ddz_wall           !< 1/dz_wall
-    REAL(wp), DIMENSION(:,:), ALLOCATABLE          :: ddz_wall_stag      !< 1/dz_wall_stag
-    REAL(wp), DIMENSION(:,:), ALLOCATABLE          :: dz_wall            !< wall grid spacing (center-center)
-    REAL(wp), DIMENSION(:,:), ALLOCATABLE          :: dz_wall_stag       !< wall grid spacing (edge-edge) 
-    REAL(wp), DIMENSION(:,:), ALLOCATABLE          :: zw                 !< wall layer depths (m)
 
 #if defined( __nopointer )
-    REAL(wp), DIMENSION(:), ALLOCATABLE, TARGET    :: t_surf             !< wall surface temperature (K)
-    REAL(wp), DIMENSION(:), ALLOCATABLE, TARGET    :: t_surf_p           !< progn. wall surface temperature (K)
+    REAL(wp), DIMENSION(:), ALLOCATABLE, TARGET    :: t_surf_h           !< wall surface temperature (K) at horizontal walls
+    REAL(wp), DIMENSION(:), ALLOCATABLE, TARGET    :: t_surf_h_p         !< progn. wall surface temperature (K) at horizontal walls
+
+    TYPE(t_surf_vertical), DIMENSION(0:3), TARGET  ::  t_surf_v
+    TYPE(t_surf_vertical), DIMENSION(0:3), TARGET  ::  t_surf_v_p
 #else
-    REAL(wp), DIMENSION(:), POINTER                :: t_surf
-    REAL(wp), DIMENSION(:), POINTER                :: t_surf_p 
-
-    REAL(wp), DIMENSION(:), ALLOCATABLE, TARGET    :: t_surf_1
-    REAL(wp), DIMENSION(:), ALLOCATABLE, TARGET    :: t_surf_2
+    REAL(wp), DIMENSION(:), POINTER                :: t_surf_h
+    REAL(wp), DIMENSION(:), POINTER                :: t_surf_h_p 
+
+    REAL(wp), DIMENSION(:), ALLOCATABLE, TARGET    :: t_surf_h_1
+    REAL(wp), DIMENSION(:), ALLOCATABLE, TARGET    :: t_surf_h_2
+
+    TYPE(t_surf_vertical), DIMENSION(:), POINTER ::  t_surf_v
+    TYPE(t_surf_vertical), DIMENSION(:), POINTER ::  t_surf_v_p
+
+    TYPE(t_surf_vertical), DIMENSION(0:3), TARGET  :: t_surf_v_1
+    TYPE(t_surf_vertical), DIMENSION(0:3), TARGET  :: t_surf_v_2
 #endif
     REAL(wp), DIMENSION(:), ALLOCATABLE, TARGET    :: t_surf_av          !< average of wall surface temperature (K)
@@ -394,31 +413,22 @@
 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 !-- parameters of the land, roof and wall surfaces
-    LOGICAL,  DIMENSION(:), ALLOCATABLE            :: isroof_surf        !< is the surface the part of a roof
     REAL(wp), DIMENSION(:), ALLOCATABLE            :: albedo_surf        !< albedo of the surface
 !-- parameters of the wall surfaces
-    REAL(wp), DIMENSION(:), ALLOCATABLE            :: c_surface          !< heat capacity of the wall surface skin ( J mâ2 Kâ1 )
     REAL(wp), DIMENSION(:), ALLOCATABLE            :: emiss_surf         !< emissivity of the wall surface
-    REAL(wp), DIMENSION(:), ALLOCATABLE            :: lambda_surf        !< heat conductivity Î»S between air and surface ( W mâ2 Kâ1 )
-    
-!-- parameters of the walls material
-    REAL(wp), DIMENSION(:), ALLOCATABLE            :: thickness_wall     !< thickness of the wall, roof and soil layers
-    REAL(wp), DIMENSION(:,:), ALLOCATABLE          :: rho_c_wall         !< volumetric heat capacity of the material ( J m-3 K-1 ) (= 2.19E6)
-    REAL(wp), DIMENSION(:,:), ALLOCATABLE          :: lambda_h           !< heat conductivity Î»T of the material ( W m-1 K-1 )
-    REAL(wp), DIMENSION(:), ALLOCATABLE            :: roughness_wall     !< roughness relative to concrete
-    
-!-- output wall heat flux arrays
-    REAL(wp), DIMENSION(:), ALLOCATABLE            :: wshf               !< kinematic wall heat flux of sensible heat (needed for diffusion_s!<)
-    REAL(wp), DIMENSION(:), ALLOCATABLE            :: wshf_eb            !< wall heat flux of sensible heat in wall normal direction
-    REAL(wp), DIMENSION(:), ALLOCATABLE            :: wshf_eb_av         !< average of wshf_eb
-    REAL(wp), DIMENSION(:), ALLOCATABLE            :: wghf_eb            !< wall ground heat flux
-    REAL(wp), DIMENSION(:), ALLOCATABLE            :: wghf_eb_av         !< average of wghf_eb
 
 #if defined( __nopointer )
-    REAL(wp), DIMENSION(:,:), ALLOCATABLE, TARGET  :: t_wall             !< Wall temperature (K)
-    REAL(wp), DIMENSION(:,:), ALLOCATABLE, TARGET  :: t_wall_av          !< Average of t_wall
-    REAL(wp), DIMENSION(:,:), ALLOCATABLE, TARGET  :: t_wall_p           !< Prog. wall temperature (K)
+    REAL(wp), DIMENSION(:), ALLOCATABLE, TARGET    :: t_wall_h             !< Wall temperature (K)
+    REAL(wp), DIMENSION(:), ALLOCATABLE, TARGET    :: t_wall_h_av          !< Average of t_wall
+    REAL(wp), DIMENSION(:), ALLOCATABLE, TARGET    :: t_wall_h_p           !< Prog. wall temperature (K)
+
+    TYPE(t_wall_vertical), DIMENSION(0:3), TARGET  :: t_wall_v             !< Wall temperature (K)
+    TYPE(t_wall_vertical), DIMENSION(0:3), TARGET  :: t_wall_v_av          !< Average of t_wall
+    TYPE(t_wall_vertical), DIMENSION(0:3), TARGET  :: t_wall_v_p           !< Prog. wall temperature (K)
 #else
-    REAL(wp), DIMENSION(:,:), POINTER              :: t_wall, t_wall_p
-    REAL(wp), DIMENSION(:,:), ALLOCATABLE, TARGET  :: t_wall_av, t_wall_1, t_wall_2
+    REAL(wp), DIMENSION(:,:), POINTER                :: t_wall_h, t_wall_h_p
+    REAL(wp), DIMENSION(:,:), ALLOCATABLE, TARGET    :: t_wall_h_av, t_wall_h_1, t_wall_h_2
+
+    TYPE(t_wall_vertical), DIMENSION(:), POINTER   :: t_wall_v, t_wall_v_p
+    TYPE(t_wall_vertical), DIMENSION(0:3), TARGET  :: t_wall_v_av, t_wall_v_1, t_wall_v_2
 #endif
 
@@ -488,10 +498,5 @@
        MODULE PROCEDURE usm_swap_timelevel
     END INTERFACE usm_swap_timelevel
-    
-    INTERFACE usm_wall_heat_flux
-       MODULE PROCEDURE usm_wall_heat_flux
-       MODULE PROCEDURE usm_wall_heat_flux_ij
-    END INTERFACE usm_wall_heat_flux
-    
+        
     INTERFACE usm_write_restart_data
        MODULE PROCEDURE usm_write_restart_data
@@ -508,5 +513,4 @@
            usm_energy_balance_land, usm_energy_balance_wall, nrefsteps,        &
            usm_init_urban_surface, usm_radiation, usm_read_restart_data,       &
-           usm_wall_heat_flux,                                                 &
            usm_surface_energy_balance, usm_material_heat_model,                &
            usm_swap_timelevel, usm_check_data_output, usm_average_3d_data,     &
@@ -531,7 +535,9 @@
         IMPLICIT NONE
        
-        INTEGER(iwp)                            :: i, j, k, d, l, ir, jr, ids
-        INTEGER(iwp)                            :: nzubl, nzutl, isurf, ipcgb
-        INTEGER(iwp)                            :: procid
+        INTEGER(iwp) :: i, j, k, d, l, ir, jr, ids, m
+        INTEGER(iwp) :: k_topo     !< vertical index indicating topography top for given (j,i)
+        INTEGER(iwp) :: k_topo2    !< vertical index indicating topography top for given (j,i)
+        INTEGER(iwp) :: nzubl, nzutl, isurf, ipcgb
+        INTEGER(iwp) :: procid
 
         
@@ -543,8 +549,24 @@
         CALL location_message( '', .TRUE. )
         CALL location_message( '    allocation of needed arrays', .TRUE. )
-!--     find nzub, nzut, nzu
-        nzubl = minval(nzb_s_inner(nys:nyn,nxl:nxr))
-        nzutl = maxval(nzb_s_inner(nys:nyn,nxl:nxr))
+!
+!--     Find nzub, nzut, nzu via wall_flag_0 array (nzb_s_inner will be 
+!--     removed later). The following contruct finds the lowest / largest index
+!--     for any upward-facing wall (see bit 12). 
+        nzubl = MINVAL(                                                        &
+                    MAXLOC(                                                    &
+                          MERGE( 1, 0,                                         &
+                                 BTEST( wall_flags_0(:,nys:nyn,nxl:nxr), 12 )  &
+                               ), DIM = 1                                      &
+                          ) - 1                                                & 
+                            )
+        nzutl = MAXVAL(                                                        &
+                   MAXLOC(                                                     &
+                          MERGE( 1, 0,                                         &
+                                 BTEST( wall_flags_0(:,nys:nyn,nxl:nxr), 12 )  &
+                               ), DIM = 1                                      &
+                          ) - 1                                                &
+                            )
         nzubl = max(nzubl,nzb)
+
         
         IF ( plant_canopy )  THEN
@@ -559,8 +581,14 @@
             DO i = nxl, nxr
                 DO j = nys, nyn
+!
+!--                 Find topography top index
+                    k_topo = MAXLOC( MERGE( 1, 0,                              &
+                                             BTEST( wall_flags_0(:,j,i), 12 )  &
+                                           ), DIM = 1                          &
+                                   ) - 1
                     DO k = nzt+1, 0, -1
                         IF ( lad_s(k,j,i) /= 0.0_wp )  THEN
 !--                         we are at the top of the pcs
-                            pct(j,i) = k + nzb_s_inner(j,i)
+                            pct(j,i) = k + k_topo
                             pch(j,i) = k
                             npcbl = npcbl + pch(j,i)
@@ -601,27 +629,23 @@
         CALL location_message( '    calculation of indices for surfaces', .TRUE. )
         nsurfl = 0
-!--     calculate land surface and roof
-        startland = nsurfl+1
-        nsurfl = nsurfl+(nxr-nxl+1)*(nyn-nys+1)
-        endland = nsurfl
-        nlands = endland-startland+1
-
-!--     calculation of the walls
+!
+!--     Number of land- and roof surfaces. Note, since horizontal surface elements
+!--     are already counted in surface_mod, in case be simply reused here.
+        startland = 1
+        nsurfl    = surf_usm_h%ns
+        endland   = nsurfl
+        nlands    = endland-startland+1
+
+!
+!--     Number of vertical surfaces. As vertical surfaces are already 
+!--     counted in surface mod, it can be reused here. 
         startwall = nsurfl+1
-        DO i = nxl, nxr
-            DO j = nys, nyn
-!--             test for walls
-!--             (we don't use array flags because it isn't calculated in case of masking_method=.T.)
-                DO ids = 1, 4  !-- four wall directions
-                    jr = min(max(j-jdir(ids),0),ny)
-                    ir = min(max(i-idir(ids),0),nx)
-                    nsurfl = nsurfl + max(0, nzb_s_inner(jr,ir)-nzb_s_inner(j,i))
-                ENDDO
-            ENDDO
-        ENDDO
+        nsurfl = nsurfl + surf_usm_v(0)%ns + surf_usm_v(1)%ns +        &
+                          surf_usm_v(2)%ns + surf_usm_v(3)%ns 
         endwall = nsurfl
         nwalls = endwall-startwall+1
-        
-!--     range of energy balance surfaces
+
+        
+!--     range of energy balance surfaces  ! will be treated separately by surf_usm_h and surf_usm_v
         nenergy = 0
         IF ( usm_energy_balance_land )  THEN
@@ -641,5 +665,5 @@
 !--     block of virtual surfaces
 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-!--     calculate sky surfaces
+!--     calculate sky surfaces  ! not used so far!
         startsky = nsurfl+1
         nsurfl = nsurfl+(nxr-nxl+1)*(nyn-nys+1)
@@ -656,14 +680,24 @@
         ijdb = RESHAPE( (/ nxl,nxr,nyn,nyn,nxl,nxr,nys,nys,nxr,nxr,nys,nyn,nxl,nxl,nys,nyn /), (/4, 4/) )
 !--     calulation of the free borders of the domain
-        DO ids = 6,9
-            IF ( isborder(ids) )  THEN
-!--             free border of the domain in direction ids
-                DO i = ijdb(1,ids), ijdb(2,ids)
-                    DO j = ijdb(3,ids), ijdb(4,ids)
-                        k = nzut - max(nzb_s_inner(j,i), nzb_s_inner(j-jdir(ids),i-idir(ids)))
-                        nsurfl = nsurfl + k
-                    ENDDO
-                ENDDO
-            ENDIF
+        DO  ids = 6,9
+           IF ( isborder(ids) )  THEN
+!--           free border of the domain in direction ids
+              DO  i = ijdb(1,ids), ijdb(2,ids)
+                 DO  j = ijdb(3,ids), ijdb(4,ids)
+
+                    k_topo =   MAXLOC( MERGE( 1, 0,                            &
+                                             BTEST( wall_flags_0(:,j,i), 12 )  &
+                                            ), DIM = 1                         &
+                                     ) - 1
+                    k_topo2 =  MAXLOC( MERGE( 1, 0,                            &
+                                             BTEST( wall_flags_0(:,j-jdir(ids),i-idir(ids)), 12 )  &
+                                            ), DIM = 1                         &
+                                     ) - 1 
+
+                    k = nzut - MAX( k_topo, k_topo2 )
+                    nsurfl = nsurfl + k
+                 ENDDO
+              ENDDO
+           ENDIF
         ENDDO
         
@@ -676,5 +710,11 @@
             DO i = nxl, nxr
                 DO j = nys, nyn
-                    DO k = nzb_s_inner(j,i)+1, pct(j,i)
+!
+!--                 Find topography top index
+                    k_topo = MAXLOC( MERGE( 1, 0,                              &
+                                             BTEST( wall_flags_0(:,j,i), 12 )  &
+                                          ), DIM = 1                           &
+                                   ) - 1
+                    DO k = k_topo + 1, pct(j,i)
                         ipcgb = ipcgb + 1
                         gridpcbl(k,j,i) = ipcgb
@@ -689,5 +729,5 @@
 
 !--     fill surfl
-        ALLOCATE(surfl(4,nsurfl))
+        ALLOCATE(surfl(5,nsurfl))
         isurf = 0
         
@@ -695,7 +735,10 @@
         DO i = nxl, nxr
             DO j = nys, nyn
-                isurf = isurf + 1
-                k = nzb_s_inner(j,i)+1
-                surfl(:,isurf) = (/iroof,k,j,i/)
+               DO  m = surf_usm_h%start_index(j,i), surf_usm_h%end_index(j,i)
+                  k = surf_usm_h%k(m)
+
+                  isurf = isurf + 1
+                  surfl(:,isurf) = (/iroof,k,j,i,m/)
+               ENDDO
             ENDDO
         ENDDO
@@ -704,12 +747,32 @@
         DO i = nxl, nxr
             DO j = nys, nyn
-                DO ids = 1, 4  !> four wall directions
-                    jr = min(max(j-jdir(ids),0),ny)
-                    ir = min(max(i-idir(ids),0),nx)
-                    DO k = nzb_s_inner(j,i)+1, nzb_s_inner(jr,ir)
-                        isurf = isurf + 1
-                        surfl(:,isurf) = (/ids,k,j,i/)
-                    ENDDO
-                ENDDO
+               l = 0
+               DO  m = surf_usm_v(l)%start_index(j,i), surf_usm_v(l)%end_index(j,i)
+                  k = surf_usm_v(l)%k(m)
+
+                  isurf          = isurf + 1
+                  surfl(:,isurf) = (/2,k,j,i,m/)
+               ENDDO
+               l = 1
+               DO  m = surf_usm_v(l)%start_index(j,i), surf_usm_v(l)%end_index(j,i)
+                  k = surf_usm_v(l)%k(m)
+
+                  isurf          = isurf + 1
+                  surfl(:,isurf) = (/1,k,j,i,m/)
+               ENDDO
+               l = 2
+               DO  m = surf_usm_v(l)%start_index(j,i), surf_usm_v(l)%end_index(j,i)
+                  k = surf_usm_v(l)%k(m)
+
+                  isurf          = isurf + 1
+                  surfl(:,isurf) = (/4,k,j,i,m/)
+               ENDDO
+               l = 3
+               DO  m = surf_usm_v(l)%start_index(j,i), surf_usm_v(l)%end_index(j,i)
+                  k = surf_usm_v(l)%k(m)
+
+                  isurf          = isurf + 1
+                  surfl(:,isurf) = (/3,k,j,i,m/)
+               ENDDO
             ENDDO
         ENDDO
@@ -720,5 +783,5 @@
                 isurf = isurf + 1
                 k = nzut
-                surfl(:,isurf) = (/isky,k,j,i/)
+                surfl(:,isurf) = (/isky,k,j,i,-1/)
             ENDDO
         ENDDO
@@ -730,7 +793,15 @@
                 DO i = ijdb(1,ids), ijdb(2,ids)
                     DO j = ijdb(3,ids), ijdb(4,ids)
-                        DO k = max(nzb_s_inner(j,i),nzb_s_inner(j-jdir(ids),i-idir(ids)))+1, nzut
+                        k_topo =   MAXLOC( MERGE( 1, 0,                        &
+                                             BTEST( wall_flags_0(:,j,i), 12 )  &
+                                                ), DIM = 1                     &
+                                         ) - 1
+                        k_topo2 =  MAXLOC( MERGE( 1, 0,                        &
+                                             BTEST( wall_flags_0(:,j-jdir(ids),i-idir(ids)), 12 )  &
+                                                ), DIM = 1                     &
+                                         ) - 1 
+                        DO k = MAX(k_topo,k_topo2)+1, nzut
                             isurf = isurf + 1
-                            surfl(:,isurf) = (/ids,k,j,i/)
+                            surfl(:,isurf) = (/ids,k,j,i,-1/)
                         ENDDO
                     ENDDO
@@ -755,8 +826,8 @@
         surfstart(numprocs) = k
         nsurf = k
-        ALLOCATE(surf(4,nsurf))
+        ALLOCATE(surf(5,nsurf))
         
 #if defined( __parallel )
-        CALL MPI_AllGatherv(surfl, nsurfl*4, MPI_INTEGER, surf, nsurfs*4, surfstart*4, MPI_INTEGER, comm2d, ierr)
+        CALL MPI_AllGatherv(surfl, nsurfl*5, MPI_INTEGER, surf, nsurfs*5, surfstart*5, MPI_INTEGER, comm2d, ierr)
 #else
         surf = surfl
@@ -787,6 +858,28 @@
         ALLOCATE( surfouts(nsurf) ) !TODO: global surfaces without virtual
         ALLOCATE( surfoutl(nsurf) ) !TODO: global surfaces without virtual
-        ALLOCATE( surfhf(startenergy:endenergy) )
-        ALLOCATE( rad_net_l(startenergy:endenergy) )
+
+
+
+!
+!--     Allocate radiation arrays which are part of the new data type. 
+!--     For horizontal surfaces.
+        ALLOCATE( surf_usm_h%surfhf(1:surf_usm_h%ns)    )
+        ALLOCATE( surf_usm_h%rad_net_l(1:surf_usm_h%ns) )
+!
+!--  New
+        ALLOCATE( surf_usm_h%rad_in_sw(1:surf_usm_h%ns)  )
+        ALLOCATE( surf_usm_h%rad_out_sw(1:surf_usm_h%ns) )
+        ALLOCATE( surf_usm_h%rad_in_lw(1:surf_usm_h%ns)  )
+        ALLOCATE( surf_usm_h%rad_out_lw(1:surf_usm_h%ns) )
+!
+!--     For vertical surfaces
+        DO  l = 0, 3
+           ALLOCATE( surf_usm_v(l)%surfhf(1:surf_usm_v(l)%ns)    )
+           ALLOCATE( surf_usm_v(l)%rad_net_l(1:surf_usm_v(l)%ns) )
+           ALLOCATE( surf_usm_v(l)%rad_in_sw(1:surf_usm_v(l)%ns)  )
+           ALLOCATE( surf_usm_v(l)%rad_out_sw(1:surf_usm_v(l)%ns) )
+           ALLOCATE( surf_usm_v(l)%rad_in_lw(1:surf_usm_v(l)%ns)  )
+           ALLOCATE( surf_usm_v(l)%rad_out_lw(1:surf_usm_v(l)%ns) )
+        ENDDO
 
 !--     Wall surface model
@@ -794,5 +887,8 @@
        
 !--     allocate array of wall types and wall parameters
-        ALLOCATE ( surface_types(startenergy:endenergy) )
+        ALLOCATE ( surf_usm_h%surface_types(1:surf_usm_h%ns) )
+        DO  l = 0, 3
+           ALLOCATE( surf_usm_v(l)%surface_types(1:surf_usm_v(l)%ns) )
+        ENDDO
        
 !--     broadband albedo of the land, roof and wall surface
@@ -802,58 +898,131 @@
         ALLOCATE ( albedo_surf(nsurfl) )
         albedo_surf = 1.0_wp
+        ALLOCATE ( surf_usm_h%albedo_surf(1:surf_usm_h%ns) )
+        DO  l = 0, 3
+           ALLOCATE( surf_usm_v(l)%albedo_surf(1:surf_usm_v(l)%ns) )
+        ENDDO
        
-!--     wall and roof surface parameters
-        ALLOCATE ( isroof_surf(startenergy:endenergy) )
+!--     wall and roof surface parameters. First for horizontal surfaces
         ALLOCATE ( emiss_surf(startenergy:endenergy) )
-        ALLOCATE ( lambda_surf(startenergy:endenergy) )
-        ALLOCATE ( c_surface(startenergy:endenergy) )
-        ALLOCATE ( roughness_wall(startenergy:endenergy) )
+
+        ALLOCATE ( surf_usm_h%isroof_surf(1:surf_usm_h%ns)    )
+        ALLOCATE ( surf_usm_h%emiss_surf(1:surf_usm_h%ns)     )
+        ALLOCATE ( surf_usm_h%lambda_surf(1:surf_usm_h%ns)    )
+        ALLOCATE ( surf_usm_h%c_surface(1:surf_usm_h%ns)      )
+        ALLOCATE ( surf_usm_h%roughness_wall(1:surf_usm_h%ns) )
+!
+!--     For vertical surfaces.
+        DO  l = 0, 3
+           ALLOCATE ( surf_usm_v(l)%emiss_surf(1:surf_usm_v(l)%ns)     )
+           ALLOCATE ( surf_usm_v(l)%lambda_surf(1:surf_usm_v(l)%ns)    )
+           ALLOCATE ( surf_usm_v(l)%c_surface(1:surf_usm_v(l)%ns)      )
+           ALLOCATE ( surf_usm_v(l)%roughness_wall(1:surf_usm_v(l)%ns) )
+        ENDDO
        
-!--     allocate wall and roof material parameters
-        ALLOCATE ( thickness_wall(startenergy:endenergy) )
-        ALLOCATE ( lambda_h(nzb_wall:nzt_wall,startenergy:endenergy) )
-        ALLOCATE ( rho_c_wall(nzb_wall:nzt_wall,startenergy:endenergy) )
-
-!--     allocate wall and roof layers sizes
+!--     allocate wall and roof material parameters. First for horizontal surfaces
+        ALLOCATE ( surf_usm_h%thickness_wall(1:surf_usm_h%ns)               )
+        ALLOCATE ( surf_usm_h%lambda_h(nzb_wall:nzt_wall,1:surf_usm_h%ns)   )
+        ALLOCATE ( surf_usm_h%rho_c_wall(nzb_wall:nzt_wall,1:surf_usm_h%ns) )
+!
+!--     For vertical surfaces.
+        DO  l = 0, 3
+           ALLOCATE ( surf_usm_v(l)%thickness_wall(1:surf_usm_v(l)%ns)               )
+           ALLOCATE ( surf_usm_v(l)%lambda_h(nzb_wall:nzt_wall,1:surf_usm_v(l)%ns)   )
+           ALLOCATE ( surf_usm_v(l)%rho_c_wall(nzb_wall:nzt_wall,1:surf_usm_v(l)%ns) )
+        ENDDO
+
+!--     allocate wall and roof layers sizes. For horizontal surfaces.
         ALLOCATE ( zwn(nzb_wall:nzt_wall) )
-        ALLOCATE ( dz_wall(nzb_wall:nzt_wall+1, startenergy:endenergy) )
-        ALLOCATE ( ddz_wall(nzb_wall:nzt_wall+1, startenergy:endenergy) )
-        ALLOCATE ( dz_wall_stag(nzb_wall:nzt_wall, startenergy:endenergy) )
-        ALLOCATE ( ddz_wall_stag(nzb_wall:nzt_wall, startenergy:endenergy) )
-        ALLOCATE ( zw(nzb_wall:nzt_wall, startenergy:endenergy) )
-
-!--     allocate wall and roof temperature arrays
+        ALLOCATE ( surf_usm_h%dz_wall(nzb_wall:nzt_wall+1,1:surf_usm_h%ns)     )
+        ALLOCATE ( surf_usm_h%ddz_wall(nzb_wall:nzt_wall+1,1:surf_usm_h%ns)    )
+        ALLOCATE ( surf_usm_h%dz_wall_stag(nzb_wall:nzt_wall,1:surf_usm_h%ns)  )
+        ALLOCATE ( surf_usm_h%ddz_wall_stag(nzb_wall:nzt_wall,1:surf_usm_h%ns) )
+        ALLOCATE ( surf_usm_h%zw(nzb_wall:nzt_wall,1:surf_usm_h%ns)            )
+!
+!--     For vertical surfaces.
+        DO  l = 0, 3
+           ALLOCATE ( surf_usm_v(l)%dz_wall(nzb_wall:nzt_wall+1,1:surf_usm_v(l)%ns)     )
+           ALLOCATE ( surf_usm_v(l)%ddz_wall(nzb_wall:nzt_wall+1,1:surf_usm_v(l)%ns)    )
+           ALLOCATE ( surf_usm_v(l)%dz_wall_stag(nzb_wall:nzt_wall,1:surf_usm_v(l)%ns)  )
+           ALLOCATE ( surf_usm_v(l)%ddz_wall_stag(nzb_wall:nzt_wall,1:surf_usm_v(l)%ns) )
+           ALLOCATE ( surf_usm_v(l)%zw(nzb_wall:nzt_wall,1:surf_usm_v(l)%ns)            )
+        ENDDO
+
+!--     allocate wall and roof temperature arrays, for horizontal walls
 #if defined( __nopointer )
-        ALLOCATE ( t_surf(startenergy:endenergy) )
-        ALLOCATE ( t_surf_p(startenergy:endenergy) )
-        ALLOCATE ( t_wall(nzb_wall:nzt_wall+1,startenergy:endenergy) )
-        ALLOCATE ( t_wall_p(nzb_wall:nzt_wall+1,startenergy:endenergy) )
+        ALLOCATE ( t_surf_h(1:surf_usm_h%ns) )
+        ALLOCATE ( t_surf_h_p(1:surf_usm_h%ns) )
+        ALLOCATE ( t_wall_h(nzb_wall:nzt_wall+1,1:surf_usm_h%ns) )
+        ALLOCATE ( t_wall_h_p(nzb_wall:nzt_wall+1,1:surf_usm_h%ns) )
+
+        ALLOCATE ( t_surf_h(1:surf_usm_h%ns) )
+        ALLOCATE ( t_surf_h_p(1:surf_usm_h%ns) )
+        ALLOCATE ( t_wall_h(nzb_wall:nzt_wall+1,1:surf_usm_h%ns) )
+        ALLOCATE ( t_wall_h_p(nzb_wall:nzt_wall+1,1:surf_usm_h%ns) )
 #else
-        ALLOCATE ( t_surf_1(startenergy:endenergy) )
-        ALLOCATE ( t_surf_2(startenergy:endenergy) )
-        ALLOCATE ( t_wall_1(nzb_wall:nzt_wall+1,startenergy:endenergy) )
-        ALLOCATE ( t_wall_2(nzb_wall:nzt_wall+1,startenergy:endenergy) )
+        ALLOCATE ( t_surf_h_1(1:surf_usm_h%ns) )
+        ALLOCATE ( t_surf_h_2(1:surf_usm_h%ns) )
+        ALLOCATE ( t_wall_h_1(nzb_wall:nzt_wall+1,1:surf_usm_h%ns) )
+        ALLOCATE ( t_wall_h_2(nzb_wall:nzt_wall+1,1:surf_usm_h%ns) )
 
 !--     initial assignment of the pointers
-        t_wall    => t_wall_1;    t_wall_p    => t_wall_2
-        t_surf => t_surf_1; t_surf_p => t_surf_2
+        t_wall_h    => t_wall_h_1;    t_wall_h_p    => t_wall_h_2
+        t_surf_h => t_surf_h_1; t_surf_h_p => t_surf_h_2
 #endif
 
-!--     allocate intermediate timestep arrays
-        ALLOCATE ( tt_surface_m(startenergy:endenergy) )
-        ALLOCATE ( tt_wall_m(nzb_wall:nzt_wall+1,startenergy:endenergy) )
-
-!--     allocate wall heat flux output array
-        ALLOCATE ( wshf(startwall:endwall) )
-        ALLOCATE ( wshf_eb(startenergy:endenergy) )
-        ALLOCATE ( wghf_eb(startenergy:endenergy) )
-
-!--     set inital values for prognostic quantities
-        tt_surface_m = 0.0_wp
-        tt_wall_m    = 0.0_wp
-
-        wshf = 0.0_wp
-        wshf_eb = 0.0_wp
-        wghf_eb = 0.0_wp
+!--     allocate wall and roof temperature arrays, for vertical walls
+#if defined( __nopointer )
+        DO  l = 0, 3
+           ALLOCATE ( t_surf_v(l)%t(1:surf_usm_v(l)%ns) )
+           ALLOCATE ( t_surf_v(l)%t_p(1:surf_usm_v(l)%ns) )
+           ALLOCATE ( t_wall_v(l)%t(nzb_wall:nzt_wall+1,1:surf_usm_v(l)%ns) )
+           ALLOCATE ( t_wall_v(l)%t_p(nzb_wall:nzt_wall+1,1:surf_usm_v(l)%ns) )
+        ENDDO
+#else
+        DO  l = 0, 3
+           ALLOCATE ( t_surf_v_1(l)%t(1:surf_usm_v(l)%ns) )
+           ALLOCATE ( t_surf_v_2(l)%t(1:surf_usm_v(l)%ns) )
+           ALLOCATE ( t_wall_v_1(l)%t(nzb_wall:nzt_wall+1,1:surf_usm_v(l)%ns) )
+           ALLOCATE ( t_wall_v_2(l)%t(nzb_wall:nzt_wall+1,1:surf_usm_v(l)%ns) )
+        ENDDO
+!
+!--     initial assignment of the pointers
+        t_wall_v    => t_wall_v_1;    t_wall_v_p    => t_wall_v_2
+        t_surf_v => t_surf_v_1; t_surf_v_p => t_surf_v_2
+#endif
+!
+!--     Allocate intermediate timestep arrays. For horizontal surfaces.
+        ALLOCATE ( surf_usm_h%tt_surface_m(1:surf_usm_h%ns)                  )
+        ALLOCATE ( surf_usm_h%tt_wall_m(nzb_wall:nzt_wall+1,1:surf_usm_h%ns) )
+!
+!--     Set inital values for prognostic quantities
+        IF ( ALLOCATED( surf_usm_h%tt_surface_m ) )  surf_usm_h%tt_surface_m = 0.0_wp
+        IF ( ALLOCATED( surf_usm_h%tt_wall_m    ) )  surf_usm_h%tt_wall_m    = 0.0_wp
+!
+!--     Now, for vertical surfaces
+        DO  l = 0, 3
+           ALLOCATE ( surf_usm_v(l)%tt_surface_m(1:surf_usm_v(l)%ns)                  )
+           ALLOCATE ( surf_usm_v(l)%tt_wall_m(nzb_wall:nzt_wall+1,1:surf_usm_v(l)%ns) )
+           IF ( ALLOCATED( surf_usm_v(l)%tt_surface_m ) )  surf_usm_v(l)%tt_surface_m = 0.0_wp
+           IF ( ALLOCATED( surf_usm_v(l)%tt_wall_m    ) )  surf_usm_v(l)%tt_wall_m    = 0.0_wp
+        ENDDO
+
+!--     allocate wall heat flux output array and set initial values. For horizontal surfaces
+!         ALLOCATE ( surf_usm_h%wshf(1:surf_usm_h%ns)    )  !can be removed 
+        ALLOCATE ( surf_usm_h%wshf_eb(1:surf_usm_h%ns) )
+        ALLOCATE ( surf_usm_h%wghf_eb(1:surf_usm_h%ns) )
+        IF ( ALLOCATED( surf_usm_h%wshf    ) )  surf_usm_h%wshf    = 0.0_wp
+        IF ( ALLOCATED( surf_usm_h%wshf_eb ) )  surf_usm_h%wshf_eb = 0.0_wp
+        IF ( ALLOCATED( surf_usm_h%wghf_eb ) )  surf_usm_h%wghf_eb = 0.0_wp
+!
+!--     Now, for vertical surfaces
+        DO  l = 0, 3
+!            ALLOCATE ( surf_usm_v(l)%wshf(1:surf_usm_v(l)%ns)    )    ! can be removed
+           ALLOCATE ( surf_usm_v(l)%wshf_eb(1:surf_usm_v(l)%ns) )
+           ALLOCATE ( surf_usm_v(l)%wghf_eb(1:surf_usm_v(l)%ns) )
+           IF ( ALLOCATED( surf_usm_v(l)%wshf    ) )  surf_usm_v(l)%wshf    = 0.0_wp
+           IF ( ALLOCATED( surf_usm_v(l)%wshf_eb ) )  surf_usm_v(l)%wshf_eb = 0.0_wp
+           IF ( ALLOCATED( surf_usm_v(l)%wghf_eb ) )  surf_usm_v(l)%wghf_eb = 0.0_wp
+        ENDDO
         
     END SUBROUTINE usm_allocate_urban_surface
@@ -874,5 +1043,5 @@
         CHARACTER (len=*), INTENT(IN) :: variable
   
-        INTEGER(iwp)                                       :: i, j, k, l, ids, iwl,istat
+        INTEGER(iwp)                                       :: i, j, k, l, m, ids, iwl,istat
         CHARACTER (len=varnamelength)                      :: var, surfid
         INTEGER(iwp), PARAMETER                            :: nd = 5
@@ -910,22 +1079,40 @@
                 CASE ( 'usm_rad_net' )
 !--                 array of complete radiation balance
-                    IF ( .NOT.  ALLOCATED(rad_net_av) )  THEN
-                        ALLOCATE( rad_net_av(startenergy:endenergy) )
-                        rad_net_av = 0.0_wp
+                    IF ( .NOT.  ALLOCATED(surf_usm_h%rad_net_av) )  THEN
+                        ALLOCATE( surf_usm_h%rad_net_av(1:surf_usm_h%ns) )
+                        surf_usm_h%rad_net_av = 0.0_wp
                     ENDIF
+                    DO  l = 0, 3
+                       IF ( .NOT.  ALLOCATED(surf_usm_v(l)%rad_net_av) )  THEN
+                           ALLOCATE( surf_usm_v(l)%rad_net_av(1:surf_usm_v(l)%ns) )
+                           surf_usm_v(l)%rad_net_av = 0.0_wp
+                       ENDIF
+                    ENDDO
                     
                 CASE ( 'usm_rad_insw' )
 !--                 array of sw radiation falling to surface after i-th reflection
-                    IF ( .NOT.  ALLOCATED(surfinsw_av) )  THEN
-                        ALLOCATE( surfinsw_av(startenergy:endenergy) )
-                        surfinsw_av = 0.0_wp
+                    IF ( .NOT.  ALLOCATED(surf_usm_h%surfinsw_av) )  THEN
+                        ALLOCATE( surf_usm_h%surfinsw_av(1:surf_usm_h%ns) )
+                        surf_usm_h%surfinsw_av = 0.0_wp
                     ENDIF
+                    DO  l = 0, 3
+                       IF ( .NOT.  ALLOCATED(surf_usm_v(l)%surfinsw_av) )  THEN
+                           ALLOCATE( surf_usm_v(l)%surfinsw_av(1:surf_usm_v(l)%ns) )
+                           surf_usm_v(l)%surfinsw_av = 0.0_wp
+                       ENDIF
+                    ENDDO
                                     
                 CASE ( 'usm_rad_inlw' )
 !--                 array of lw radiation falling to surface after i-th reflection
-                    IF ( .NOT.  ALLOCATED(surfinlw_av) )  THEN
-                        ALLOCATE( surfinlw_av(startenergy:endenergy) )
-                        surfinlw_av = 0.0_wp
+                    IF ( .NOT.  ALLOCATED(surf_usm_h%surfinlw_av) )  THEN
+                        ALLOCATE( surf_usm_h%surfinlw_av(1:surf_usm_h%ns) )
+                        surf_usm_h%surfinlw_av = 0.0_wp
                     ENDIF
+                    DO  l = 0, 3
+                       IF ( .NOT.  ALLOCATED(surf_usm_v(l)%surfinlw_av) )  THEN
+                           ALLOCATE( surf_usm_v(l)%surfinlw_av(1:surf_usm_v(l)%ns) )
+                           surf_usm_v(l)%surfinlw_av = 0.0_wp
+                       ENDIF
+                    ENDDO
 
                 CASE ( 'usm_rad_inswdir' )
@@ -952,5 +1139,5 @@
                 CASE ( 'usm_rad_inlwdif' )
 !--                 array of sw radiation falling to surface after i-th reflection
-                    IF ( .NOT.  ALLOCATED(surfinlwdif_av) )  THEN
+                   IF ( .NOT.  ALLOCATED(surfinlwdif_av) )  THEN
                         ALLOCATE( surfinlwdif_av(startenergy:endenergy) )
                         surfinlwdif_av = 0.0_wp
@@ -977,5 +1164,4 @@
                         surfoutlw_av = 0.0_wp
                     ENDIF
-
                 CASE ( 'usm_rad_ressw' )
 !--                 array of residua of sw radiation absorbed in surface after last reflection
@@ -984,5 +1170,5 @@
                         surfins_av = 0.0_wp
                     ENDIF
-                                    
+                                   
                 CASE ( 'usm_rad_reslw' )
 !--                 array of residua of lw radiation absorbed in surface after last reflection
@@ -994,37 +1180,67 @@
                 CASE ( 'usm_rad_hf' )
 !--                 array of heat flux from radiation for surfaces after i-th reflection
-                    IF ( .NOT.  ALLOCATED(surfhf_av) )  THEN
-                        ALLOCATE( surfhf_av(startenergy:endenergy) )
-                        surfhf_av = 0.0_wp
+                    IF ( .NOT.  ALLOCATED(surf_usm_h%surfhf_av) )  THEN
+                        ALLOCATE( surf_usm_h%surfhf_av(1:surf_usm_h%ns) )
+                        surf_usm_h%surfhf_av = 0.0_wp
                     ENDIF
+                    DO  l = 0, 3
+                       IF ( .NOT.  ALLOCATED(surf_usm_v(l)%surfhf_av) )  THEN
+                           ALLOCATE( surf_usm_v(l)%surfhf_av(1:surf_usm_v(l)%ns) )
+                           surf_usm_v(l)%surfhf_av = 0.0_wp
+                       ENDIF
+                    ENDDO
 
                 CASE ( 'usm_wshf' )
 !--                 array of sensible heat flux from surfaces
 !--                 land surfaces
-                    IF ( .NOT.  ALLOCATED(wshf_eb_av) )  THEN
-                        ALLOCATE( wshf_eb_av(startenergy:endenergy) )
-                        wshf_eb_av = 0.0_wp
+                    IF ( .NOT.  ALLOCATED(surf_usm_h%wshf_eb_av) )  THEN
+                        ALLOCATE( surf_usm_h%wshf_eb_av(1:surf_usm_h%ns) )
+                        surf_usm_h%wshf_eb_av = 0.0_wp
                     ENDIF
+                    DO  l = 0, 3
+                       IF ( .NOT.  ALLOCATED(surf_usm_v(l)%wshf_eb_av) )  THEN
+                           ALLOCATE( surf_usm_v(l)%wshf_eb_av(1:surf_usm_v(l)%ns) )
+                           surf_usm_v(l)%wshf_eb_av = 0.0_wp
+                       ENDIF
+                    ENDDO
 
                 CASE ( 'usm_wghf' )
 !--                 array of heat flux from ground (wall, roof, land)
-                    IF ( .NOT.  ALLOCATED(wghf_eb_av) )  THEN
-                        ALLOCATE( wghf_eb_av(startenergy:endenergy) )
-                        wghf_eb_av = 0.0_wp
+                    IF ( .NOT.  ALLOCATED(surf_usm_h%wghf_eb_av) )  THEN
+                        ALLOCATE( surf_usm_h%wghf_eb_av(1:surf_usm_h%ns) )
+                        surf_usm_h%wghf_eb_av = 0.0_wp
                     ENDIF
+                    DO  l = 0, 3
+                       IF ( .NOT.  ALLOCATED(surf_usm_v(l)%wghf_eb_av) )  THEN
+                           ALLOCATE( surf_usm_v(l)%wghf_eb_av(1:surf_usm_v(l)%ns) )
+                           surf_usm_v(l)%wghf_eb_av = 0.0_wp
+                       ENDIF
+                    ENDDO
 
                 CASE ( 'usm_t_surf' )
 !--                 surface temperature for surfaces
-                    IF ( .NOT.  ALLOCATED(t_surf_av) )  THEN
-                        ALLOCATE( t_surf_av(startenergy:endenergy) )
-                        t_surf_av = 0.0_wp
+                    IF ( .NOT.  ALLOCATED(surf_usm_h%t_surf_av) )  THEN
+                        ALLOCATE( surf_usm_h%t_surf_av(1:surf_usm_h%ns) )
+                        surf_usm_h%t_surf_av = 0.0_wp
                     ENDIF
+                    DO  l = 0, 3
+                       IF ( .NOT.  ALLOCATED(surf_usm_v(l)%t_surf_av) )  THEN
+                           ALLOCATE( surf_usm_v(l)%t_surf_av(1:surf_usm_v(l)%ns) )
+                           surf_usm_v(l)%t_surf_av = 0.0_wp
+                       ENDIF
+                    ENDDO
 
                 CASE ( 'usm_t_wall' )
 !--                 wall temperature for iwl layer of walls and land
-                    IF ( .NOT.  ALLOCATED(t_wall_av) )  THEN
-                        ALLOCATE( t_wall_av(nzb_wall:nzt_wall,startenergy:endenergy) )
-                        t_wall_av = 0.0_wp
+                    IF ( .NOT.  ALLOCATED(surf_usm_h%t_wall_av) )  THEN
+                        ALLOCATE( surf_usm_h%t_wall_av(nzb_wall:nzt_wall,1:surf_usm_h%ns) )
+                        surf_usm_h%t_wall_av = 0.0_wp
                     ENDIF
+                    DO  l = 0, 3
+                       IF ( .NOT.  ALLOCATED(surf_usm_v(l)%t_wall_av) )  THEN
+                           ALLOCATE( surf_usm_v(l)%t_wall_av(nzb_wall:nzt_wall,1:surf_usm_v(l)%ns) )
+                           surf_usm_v(l)%t_wall_av = 0.0_wp
+                       ENDIF
+                    ENDDO
 
                CASE DEFAULT
@@ -1039,8 +1255,15 @@
                 CASE ( 'usm_rad_net' )
 !--                 array of complete radiation balance
-                    DO l = startenergy, endenergy
-                        IF ( surfl(id,l) == ids )  THEN
-                            rad_net_av(l) = rad_net_av(l) + rad_net_l(l)
-                        ENDIF
+                    DO  m = 1, surf_usm_h%ns
+                       surf_usm_h%rad_net_av(m) =                              &
+                                          surf_usm_h%rad_net_av(m) +           &
+                                          surf_usm_h%rad_net_l(m)
+                    ENDDO
+                    DO  l = 0, 3
+                       DO  m = 1, surf_usm_v(l)%ns
+                          surf_usm_v(l)%rad_net_av(m) =                        &
+                                          surf_usm_v(l)%rad_net_av(m) +        &
+                                          surf_usm_v(l)%rad_net_l(m)
+                       ENDDO
                     ENDDO
                     
@@ -1085,4 +1308,5 @@
                         ENDIF
                     ENDDO
+
                     
                 CASE ( 'usm_rad_inlwdif' )
@@ -1090,10 +1314,19 @@
                     DO l = startenergy, endenergy
                         IF ( surfl(id,l) == ids )  THEN
+                            surfinswref_av(l) = surfinswref_av(l) + surfinsw(l) - &
+                                                surfinswdir(l) - surfinswdif(l)
+                        ENDIF
+                    ENDDO
+!                     
+                CASE ( 'usm_rad_inlwref' )
+!--                 array of lw radiation falling to surface from reflections
+                    DO l = startenergy, endenergy
+                        IF ( surfl(id,l) == ids )  THEN
                             surfinlwdif_av(l) = surfinlwdif_av(l) + surfinlwdif(l)
                         ENDIF
                     ENDDO
                     
-                CASE ( 'usm_rad_inlwref' )
-!--                 array of lw radiation falling to surface from reflections
+                CASE ( 'usm_rad_outsw' )
+!--                 array of sw radiation emitted from surface after i-th reflection
                     DO l = startenergy, endenergy
                         IF ( surfl(id,l) == ids )  THEN
@@ -1103,17 +1336,9 @@
                     ENDDO
                     
-                CASE ( 'usm_rad_outsw' )
-!--                 array of sw radiation emitted from surface after i-th reflection
-                    DO l = startenergy, endenergy
-                        IF ( surfl(id,l) == ids )  THEN
-                            surfoutsw_av(l) = surfoutsw_av(l) + surfoutsw(l)
-                        ENDIF
-                    ENDDO
-                    
                 CASE ( 'usm_rad_outlw' )
 !--                 array of lw radiation emitted from surface after i-th reflection
                     DO l = startenergy, endenergy
                         IF ( surfl(id,l) == ids )  THEN
-                            surfoutlw_av(l) = surfoutlw_av(l) + surfoutlw(l)
+                            surfoutsw_av(l) = surfoutsw_av(l) + surfoutsw(l)
                         ENDIF
                     ENDDO
@@ -1123,5 +1348,5 @@
                     DO l = startenergy, endenergy
                         IF ( surfl(id,l) == ids )  THEN
-                            surfins_av(l) = surfins_av(l) + surfins(l)
+                            surfoutlw_av(l) = surfoutlw_av(l) + surfoutlw(l)
                         ENDIF
                     ENDDO
@@ -1131,5 +1356,5 @@
                     DO l = startenergy, endenergy
                         IF ( surfl(id,l) == ids )  THEN
-                            surfinl_av(l) = surfinl_av(l) + surfinl(l)
+                            surfins_av(l) = surfins_av(l) + surfins(l)
                         ENDIF
                     ENDDO
@@ -1137,40 +1362,75 @@
                 CASE ( 'usm_rad_hf' )
 !--                 array of heat flux from radiation for surfaces after i-th reflection
-                    DO l = startenergy, endenergy
-                        IF ( surfl(id,l) == ids )  THEN
-                            surfhf_av(l) = surfhf_av(l) + surfhf(l)
-                        ENDIF
+                    DO  m = 1, surf_usm_h%ns
+                       surf_usm_h%surfhf_av(m) =                               &
+                                          surf_usm_h%surfhf_av(m) +            &
+                                          surf_usm_h%surfhf(m)
+                    ENDDO
+                    DO  l = 0, 3
+                       DO  m = 1, surf_usm_v(l)%ns
+                          surf_usm_v(l)%surfhf_av(m) =                         &
+                                          surf_usm_v(l)%surfhf_av(m) +         &
+                                          surf_usm_v(l)%surfhf(m)
+                       ENDDO
                     ENDDO
                     
                 CASE ( 'usm_wshf' )
 !--                 array of sensible heat flux from surfaces (land, roof, wall)
-                    DO l = startenergy, endenergy
-                        IF ( surfl(id,l) == ids )  THEN
-                            wshf_eb_av(l) = wshf_eb_av(l) + wshf_eb(l)
-                        ENDIF
+                    DO  m = 1, surf_usm_h%ns
+                       surf_usm_h%wshf_eb_av(m) =                              &
+                                          surf_usm_h%wshf_eb_av(m) +           &
+                                          surf_usm_h%wshf_eb(m)
+                    ENDDO
+                    DO  l = 0, 3
+                       DO  m = 1, surf_usm_v(l)%ns
+                          surf_usm_v(l)%wshf_eb_av(m) =                        &
+                                          surf_usm_v(l)%wshf_eb_av(m) +        &
+                                          surf_usm_v(l)%wshf_eb(m)
+                       ENDDO
                     ENDDO
                     
                 CASE ( 'usm_wghf' )
 !--                 array of heat flux from ground (wall, roof, land)
-                    DO l = startenergy, endenergy
-                        IF ( surfl(id,l) == ids )  THEN
-                            wghf_eb_av(l) = wghf_eb_av(l) + wghf_eb(l)
-                        ENDIF
+                    DO  m = 1, surf_usm_h%ns
+                       surf_usm_h%wghf_eb_av(m) =                              &
+                                          surf_usm_h%wghf_eb_av(m) +           &
+                                          surf_usm_h%wghf_eb(m)
+                    ENDDO
+                    DO  l = 0, 3
+                       DO  m = 1, surf_usm_v(l)%ns
+                          surf_usm_v(l)%wghf_eb_av(m) =                        &
+                                          surf_usm_v(l)%wghf_eb_av(m) +        &
+                                          surf_usm_v(l)%wghf_eb(m)
+                       ENDDO
                     ENDDO
                     
                 CASE ( 'usm_t_surf' )
 !--                 surface temperature for surfaces
-                    DO l = startenergy, endenergy
-                        IF ( surfl(id,l) == ids )  THEN
-                            t_surf_av(l) = t_surf_av(l) + t_surf(l)
-                        ENDIF
+                    DO  m = 1, surf_usm_h%ns
+                       surf_usm_h%t_surf_av(m) =                               & 
+                                          surf_usm_h%t_surf_av(m) +            &
+                                          t_surf_h(m)
+                    ENDDO
+                    DO  l = 0, 3
+                       DO  m = 1, surf_usm_v(l)%ns
+                          surf_usm_v(l)%t_surf_av(m) =                         &
+                                          surf_usm_v(l)%t_surf_av(m) +         &
+                                          t_surf_v(l)%t(m)
+                       ENDDO
                     ENDDO
                     
                 CASE ( 'usm_t_wall' )
 !--                 wall temperature for  iwl layer of walls and land
-                    DO l = startenergy, endenergy
-                        IF ( surfl(id,l) == ids )  THEN
-                            t_wall_av(iwl, l) = t_wall_av(iwl,l) + t_wall(iwl, l)
-                        ENDIF
+                    DO  m = 1, surf_usm_h%ns
+                       surf_usm_h%t_wall_av(iwl,m) =                           &
+                                          surf_usm_h%t_wall_av(iwl,m) +        &
+                                          t_wall_h(iwl,m)
+                    ENDDO
+                    DO  l = 0, 3
+                       DO  m = 1, surf_usm_v(l)%ns
+                          surf_usm_v(l)%t_wall_av(iwl,m) =                     &
+                                          surf_usm_v(l)%t_wall_av(iwl,m) +     &
+                                          t_wall_v(l)%t(iwl,m)
+                       ENDDO
                     ENDDO
                     
@@ -1186,8 +1446,15 @@
                 CASE ( 'usm_rad_net' )
 !--                 array of complete radiation balance
-                    DO l = startenergy, endenergy
-                        IF ( surfl(id,l) == ids )  THEN
-                            rad_net_av(l) = rad_net_av(l) / REAL( average_count_3d, kind=wp )
-                        ENDIF
+                    DO  m = 1, surf_usm_h%ns
+                       surf_usm_h%rad_net_av(m) =                              &
+                                          surf_usm_h%rad_net_av(m) /           &
+                                          REAL( average_count_3d, kind=wp )
+                    ENDDO
+                    DO  l = 0, 3
+                       DO  m = 1, surf_usm_v(l)%ns
+                          surf_usm_v(l)%rad_net_av(m) =                        &
+                                          surf_usm_v(l)%rad_net_av(m) /        &
+                                          REAL( average_count_3d, kind=wp )
+                       ENDDO
                     ENDDO
                     
@@ -1199,5 +1466,5 @@
                         ENDIF
                     ENDDO
-                                    
+                             
                 CASE ( 'usm_rad_inlw' )
 !--                 array of lw radiation falling to surface after i-th reflection
@@ -1207,5 +1474,5 @@
                         ENDIF
                     ENDDO
-
+                    
                 CASE ( 'usm_rad_inswdir' )
 !--                 array of direct sw radiation falling to surface from sun
@@ -1215,5 +1482,5 @@
                         ENDIF
                     ENDDO
-
+                    
                 CASE ( 'usm_rad_inswdif' )
 !--                 array of difusion sw radiation falling to surface from sky and borders of the domain
@@ -1223,5 +1490,5 @@
                         ENDIF
                     ENDDO
-
+                    
                 CASE ( 'usm_rad_inswref' )
 !--                 array of sw radiation falling to surface from reflections
@@ -1231,5 +1498,5 @@
                         ENDIF
                     ENDDO
-
+                    
                 CASE ( 'usm_rad_inlwdif' )
 !--                 array of sw radiation falling to surface after i-th reflection
@@ -1239,5 +1506,5 @@
                         ENDIF
                     ENDDO
-
+                    
                 CASE ( 'usm_rad_inlwref' )
 !--                 array of lw radiation falling to surface from reflections
@@ -1247,5 +1514,5 @@
                         ENDIF
                     ENDDO
-
+                    
                 CASE ( 'usm_rad_outsw' )
 !--                 array of sw radiation emitted from surface after i-th reflection
@@ -1255,5 +1522,5 @@
                         ENDIF
                     ENDDO
-
+                    
                 CASE ( 'usm_rad_outlw' )
 !--                 array of lw radiation emitted from surface after i-th reflection
@@ -1263,5 +1530,5 @@
                         ENDIF
                     ENDDO
-
+                    
                 CASE ( 'usm_rad_ressw' )
 !--                 array of residua of sw radiation absorbed in surface after last reflection
@@ -1282,40 +1549,75 @@
                 CASE ( 'usm_rad_hf' )
 !--                 array of heat flux from radiation for surfaces after i-th reflection
-                    DO l = startenergy, endenergy
-                        IF ( surfl(id,l) == ids )  THEN
-                            surfhf_av(l) = surfhf_av(l) / REAL( average_count_3d, kind=wp )
-                        ENDIF
-                    ENDDO
-
+                    DO  m = 1, surf_usm_h%ns
+                       surf_usm_h%surfhf_av(m) =                               &
+                                          surf_usm_h%surfhf_av(m) /            &
+                                          REAL( average_count_3d, kind=wp )
+                    ENDDO
+                    DO  l = 0, 3
+                       DO  m = 1, surf_usm_v(l)%ns
+                          surf_usm_v(l)%surfhf_av(m) =                         &
+                                          surf_usm_v(l)%surfhf_av(m) /         &
+                                          REAL( average_count_3d, kind=wp )
+                       ENDDO
+                    ENDDO
+                    
                 CASE ( 'usm_wshf' )
 !--                 array of sensible heat flux from surfaces (land, roof, wall)
-                    DO l = startenergy, endenergy
-                        IF ( surfl(id,l) == ids )  THEN
-                            wshf_eb_av(l) = wshf_eb_av(l) / REAL( average_count_3d, kind=wp )
-                        ENDIF
-                    ENDDO
-
+                    DO  m = 1, surf_usm_h%ns
+                       surf_usm_h%wshf_eb_av(m) =                              &
+                                          surf_usm_h%wshf_eb_av(m) /           &
+                                          REAL( average_count_3d, kind=wp )
+                    ENDDO
+                    DO  l = 0, 3
+                       DO  m = 1, surf_usm_v(l)%ns
+                          surf_usm_v(l)%wshf_eb_av(m) =                        &
+                                          surf_usm_v(l)%wshf_eb_av(m) /        &
+                                          REAL( average_count_3d, kind=wp )
+                       ENDDO
+                    ENDDO
+                    
                 CASE ( 'usm_wghf' )
 !--                 array of heat flux from ground (wall, roof, land)
-                    DO l = startenergy, endenergy
-                        IF ( surfl(id,l) == ids )  THEN
-                            wghf_eb_av(l) = wghf_eb_av(l) / REAL( average_count_3d, kind=wp )
-                        ENDIF
-                    ENDDO
-
+                    DO  m = 1, surf_usm_h%ns
+                       surf_usm_h%wghf_eb_av(m) =                              &
+                                          surf_usm_h%wghf_eb_av(m) /           &
+                                          REAL( average_count_3d, kind=wp )
+                    ENDDO
+                    DO  l = 0, 3
+                       DO  m = 1, surf_usm_v(l)%ns
+                          surf_usm_v(l)%wghf_eb_av(m) =                        &
+                                          surf_usm_v(l)%wghf_eb_av(m) /        &
+                                          REAL( average_count_3d, kind=wp )
+                       ENDDO
+                    ENDDO
+                    
                 CASE ( 'usm_t_surf' )
 !--                 surface temperature for surfaces
-                    DO l = startenergy, endenergy
-                        IF ( surfl(id,l) == ids )  THEN
-                            t_surf_av(l) = t_surf_av(l) / REAL( average_count_3d, kind=wp )
-                        ENDIF
-                    ENDDO
-
+                    DO  m = 1, surf_usm_h%ns
+                       surf_usm_h%t_surf_av(m) =                               & 
+                                          surf_usm_h%t_surf_av(m) /            &
+                                          REAL( average_count_3d, kind=wp )
+                    ENDDO
+                    DO  l = 0, 3
+                       DO  m = 1, surf_usm_v(l)%ns
+                          surf_usm_v(l)%t_surf_av(m) =                         &
+                                          surf_usm_v(l)%t_surf_av(m) /         &
+                                          REAL( average_count_3d, kind=wp )
+                       ENDDO
+                    ENDDO
+                    
                 CASE ( 'usm_t_wall' )
 !--                 wall temperature for  iwl layer of walls and land
-                    DO l = startenergy, endenergy
-                        IF ( surfl(id,l) == ids )  THEN
-                            t_wall_av(iwl, l) = t_wall_av(iwl,l) / REAL( average_count_3d, kind=wp )
-                        ENDIF
+                    DO  m = 1, surf_usm_h%ns
+                       surf_usm_h%t_wall_av(iwl,m) =                           &
+                                          surf_usm_h%t_wall_av(iwl,m) /        &
+                                          REAL( average_count_3d, kind=wp )
+                    ENDDO
+                    DO  l = 0, 3
+                       DO  m = 1, surf_usm_v(l)%ns
+                          surf_usm_v(l)%t_wall_av(iwl,m) =                     &
+                                          surf_usm_v(l)%t_wall_av(iwl,m) /     &
+                                          REAL( average_count_3d, kind=wp )
+                       ENDDO
                     ENDDO
 
@@ -1493,9 +1795,8 @@
         TYPE(c_ptr)                                 :: lad_s_rma_p     !< allocated c pointer
         INTEGER(kind=MPI_ADDRESS_KIND)              :: size_lad_rma
-    
+!    
 !--     calculation of the SVF
         CALL location_message( '    calculation of SVF and CSF', .TRUE. )
-
-
+!
 !--     precalculate face areas for different face directions using normal vector
         DO d = 0, 9
@@ -1524,10 +1825,20 @@
 #if defined( __parallel )
         ALLOCATE( nzterrl(nys:nyn,nxl:nxr) )
-        nzterrl = nzb_s_inner(nys:nyn,nxl:nxr)
+        nzterrl = MAXLOC(                                                      &
+                          MERGE( 1, 0,                                         &
+                                 BTEST( wall_flags_0(:,nys:nyn,nxl:nxr), 12 )  &
+                               ), DIM = 1                                      &
+                        ) - 1  ! = nzb_s_inner(nys:nyn,nxl:nxr)
         CALL MPI_AllGather( nzterrl, nnx*nny, MPI_INTEGER, &
                             nzterr, nnx*nny, MPI_INTEGER, comm2d, ierr )
         DEALLOCATE(nzterrl)
 #else
-        nzterr = RESHAPE( nzb_s_inner(nys:nyn,nxl:nxr), (/(nx+1)*(ny+1)/) )
+        nzterr = RESHAPE( MAXLOC(                                              &
+                          MERGE( 1, 0,                                         &
+                                 BTEST( wall_flags_0(:,nys:nyn,nxl:nxr), 12 )  &
+                               ), DIM = 1                                      &
+                                ) - 1,                                         &
+                          (/(nx+1)*(ny+1)/)                                    &
+                        )
 #endif
         IF ( plant_canopy )  THEN
@@ -1579,5 +1890,10 @@
             DO i = nxl, nxr
                 DO j = nys, nyn
-                    k = nzb_s_inner(j, i)
+                    k = MAXLOC(                                                &
+                                MERGE( 1, 0,                                   &
+                                       BTEST( wall_flags_0(:,j,i), 12 )        &
+                                     ), DIM = 1                                &
+                              ) - 1
+
                     usm_lad(k:nzut, j, i) = lad_s(0:nzut-k, j, i)
                 ENDDO
@@ -1972,5 +2288,4 @@
         CALL message( 'init_urban_surface', 'PA0502', 2, 2, 0, 6, 0 )
        
-
     END SUBROUTINE usm_calc_svf
 
@@ -2089,5 +2404,6 @@
         INTEGER(iwp), DIMENSION(0:nd-1)                        :: dirend
         INTEGER(iwp)                                           :: ids,isurf,isvf,isurfs,isurflt
-        INTEGER(iwp)                                           :: is,js,ks,i,j,k,iwl,istat
+        INTEGER(iwp)                                           :: is,js,ks,i,j,k,iwl,istat, l, m
+        INTEGER(iwp)                                           ::  k_topo    !< topography top index
 
         dirstart = (/ startland, startwall, startwall, startwall, startwall /)
@@ -2139,42 +2455,71 @@
           CASE ( 'usm_surfz' )
 !--           array of lw radiation falling to local surface after i-th reflection
-              DO isurf = dirstart(ids), dirend(ids)
-                  IF ( surfl(id,isurf) == ids )  THEN
-                      IF ( surfl(id,isurf) == iroof )  THEN
-                          temp_pf(0,surfl(iy,isurf),surfl(ix,isurf)) =             &
-                                  max(temp_pf(0,surfl(iy,isurf),surfl(ix,isurf)),  &
-                                      REAL(surfl(iz,isurf),wp))
-                      ELSE
-                          temp_pf(0,surfl(iy,isurf),surfl(ix,isurf)) =             &
-                                  max(temp_pf(0,surfl(iy,isurf),surfl(ix,isurf)),  &
-                                      REAL(surfl(iz,isurf),wp)+1.0_wp)
-                      ENDIF
-                  ENDIF
+              DO  m = 1, surf_usm_h%ns
+                 i = surf_usm_h%i(m)
+                 j = surf_usm_h%j(m)
+                 k = surf_usm_h%k(m)
+                 temp_pf(0,j,i) = MAX( temp_pf(0,j,i), REAL( k, kind=wp) )
+              ENDDO
+              DO  l = 0, 3
+                 DO  m = 1, surf_usm_v(l)%ns
+                    i = surf_usm_v(l)%i(m)
+                    j = surf_usm_v(l)%j(m)
+                    k = surf_usm_v(l)%k(m)
+                    temp_pf(0,j,i) = MAX( temp_pf(0,j,i), REAL( k, kind=wp) + 1.0_wp )
+                 ENDDO
               ENDDO
 
           CASE ( 'usm_surfcat' )
 !--           surface category
-              DO isurf = dirstart(ids), dirend(ids)
-                 IF ( surfl(id,isurf) == ids )  THEN
-                     temp_pf(surfl(iz,isurf),surfl(iy,isurf),surfl(ix,isurf)) = surface_types(isurf)
-                 ENDIF
+              DO  m = 1, surf_usm_h%ns
+                 i = surf_usm_h%i(m)
+                 j = surf_usm_h%j(m)
+                 k = surf_usm_h%k(m)
+                 temp_pf(k,j,i) = surf_usm_h%surface_types(m)
+              ENDDO
+              DO  l = 0, 3
+                 DO  m = 1, surf_usm_v(l)%ns
+                    i = surf_usm_v(l)%i(m)
+                    j = surf_usm_v(l)%j(m)
+                    k = surf_usm_v(l)%k(m)
+                    temp_pf(k,j,i) = surf_usm_v(l)%surface_types(m)
+                 ENDDO
               ENDDO
               
           CASE ( 'usm_surfalb' )
 !--           surface albedo
-              DO isurf = dirstart(ids), dirend(ids)
-                 IF ( surfl(id,isurf) == ids )  THEN
-                     temp_pf(surfl(iz,isurf),surfl(iy,isurf),surfl(ix,isurf)) = albedo_surf(isurf)
-                 ENDIF
+              DO  m = 1, surf_usm_h%ns
+                 i = surf_usm_h%i(m)
+                 j = surf_usm_h%j(m)
+                 k = surf_usm_h%k(m)
+                 temp_pf(k,j,i) = surf_usm_h%albedo_surf(m)
+              ENDDO
+              DO  l = 0, 3
+                 DO  m = 1, surf_usm_v(l)%ns
+                    i = surf_usm_v(l)%i(m)
+                    j = surf_usm_v(l)%j(m)
+                    k = surf_usm_v(l)%k(m)
+                    temp_pf(k,j,i) = surf_usm_v(l)%albedo_surf(m)
+                 ENDDO
               ENDDO
               
           CASE ( 'usm_surfemis' )
 !--           surface albedo
-              DO isurf = dirstart(ids), dirend(ids)
-                 IF ( surfl(id,isurf) == ids )  THEN
-                     temp_pf(surfl(iz,isurf),surfl(iy,isurf),surfl(ix,isurf)) = emiss_surf(isurf)
-                 ENDIF
+              DO  m = 1, surf_usm_h%ns
+                 i = surf_usm_h%i(m)
+                 j = surf_usm_h%j(m)
+                 k = surf_usm_h%k(m)
+                 temp_pf(k,j,i) = surf_usm_h%emiss_surf(m)
               ENDDO
-              
+              DO  l = 0, 3
+                 DO  m = 1, surf_usm_v(l)%ns
+                    i = surf_usm_v(l)%i(m)
+                    j = surf_usm_v(l)%j(m)
+                    k = surf_usm_v(l)%k(m)
+                    temp_pf(k,j,i) = surf_usm_v(l)%emiss_surf(m)
+                 ENDDO
+              ENDDO
+!
+!-- Not adjusted so far              
           CASE ( 'usm_svf', 'usm_dif' )
 !--           shape view factors or iradiance factors to selected surface
@@ -2197,13 +2542,35 @@
           CASE ( 'usm_rad_net' )
 !--           array of complete radiation balance
-              DO isurf = dirstart(ids), dirend(ids)
-                 IF ( surfl(id,isurf) == ids )  THEN
-                   IF ( av == 0 )  THEN
-                     temp_pf(surfl(iz,isurf),surfl(iy,isurf),surfl(ix,isurf)) = rad_net_l(isurf)
-                   ELSE
-                     temp_pf(surfl(iz,isurf),surfl(iy,isurf),surfl(ix,isurf)) = rad_net_av(isurf)
-                   ENDIF
-                 ENDIF
-              ENDDO
+              IF ( av == 0 )  THEN
+                 DO  m = 1, surf_usm_h%ns
+                    i = surf_usm_h%i(m)
+                    j = surf_usm_h%j(m)
+                    k = surf_usm_h%k(m)
+                    temp_pf(k,j,i) = surf_usm_h%rad_net_l(m)
+                 ENDDO
+                 DO  l = 0, 3
+                    DO  m = 1, surf_usm_v(l)%ns
+                       i = surf_usm_v(l)%i(m)
+                       j = surf_usm_v(l)%j(m)
+                       k = surf_usm_v(l)%k(m)
+                       temp_pf(k,j,i) = surf_usm_v(l)%rad_net_l(m)
+                    ENDDO
+                 ENDDO
+              ELSE
+                 DO  m = 1, surf_usm_h%ns
+                    i = surf_usm_h%i(m)
+                    j = surf_usm_h%j(m)
+                    k = surf_usm_h%k(m)
+                    temp_pf(k,j,i) = surf_usm_h%rad_net_av(m)
+                 ENDDO
+                 DO  l = 0, 3
+                    DO  m = 1, surf_usm_v(l)%ns
+                       i = surf_usm_v(l)%i(m)
+                       j = surf_usm_v(l)%j(m)
+                       k = surf_usm_v(l)%k(m)
+                       temp_pf(k,j,i) = surf_usm_v(l)%rad_net_av(m)
+                    ENDDO
+                 ENDDO
+              ENDIF
 
           CASE ( 'usm_rad_insw' )
@@ -2268,16 +2635,4 @@
               ENDDO
 
-          CASE ( 'usm_rad_inlwdif' )
-!--           array of sw radiation falling to surface after i-th reflection
-              DO isurf = dirstart(ids), dirend(ids)
-                 IF ( surfl(id,isurf) == ids )  THEN
-                   IF ( av == 0 )  THEN
-                     temp_pf(surfl(iz,isurf),surfl(iy,isurf),surfl(ix,isurf)) = surfinlwdif(isurf)
-                   ELSE
-                     temp_pf(surfl(iz,isurf),surfl(iy,isurf),surfl(ix,isurf)) = surfinlwdif_av(isurf)
-                   ENDIF
-                 ENDIF
-              ENDDO
-
           CASE ( 'usm_rad_inlwref' )
 !--           array of lw radiation falling to surface from reflections
@@ -2339,65 +2694,175 @@
                  ENDIF
               ENDDO
-
+ 
           CASE ( 'usm_rad_hf' )
 !--           array of heat flux from radiation for surfaces after all reflections
-              DO isurf = dirstart(ids), dirend(ids)
-                 IF ( surfl(id,isurf) == ids )  THEN
-                   IF ( av == 0 )  THEN
-                     temp_pf(surfl(iz,isurf),surfl(iy,isurf),surfl(ix,isurf)) = surfhf(isurf)
-                   ELSE
-                     temp_pf(surfl(iz,isurf),surfl(iy,isurf),surfl(ix,isurf)) = surfhf_av(isurf)
-                   ENDIF
-                 ENDIF
-              ENDDO
-
+              IF ( av == 0 )  THEN
+                 DO  m = 1, surf_usm_h%ns
+                    i = surf_usm_h%i(m)
+                    j = surf_usm_h%j(m)
+                    k = surf_usm_h%k(m)
+                    temp_pf(k,j,i) = surf_usm_h%surfhf(m)
+                 ENDDO
+                 DO  l = 0, 3
+                    DO  m = 1, surf_usm_v(l)%ns
+                       i = surf_usm_v(l)%i(m)
+                       j = surf_usm_v(l)%j(m)
+                       k = surf_usm_v(l)%k(m)
+                       temp_pf(k,j,i) = surf_usm_v(l)%surfhf(m)
+                    ENDDO
+                 ENDDO
+              ELSE
+                 DO  m = 1, surf_usm_h%ns
+                    i = surf_usm_h%i(m)
+                    j = surf_usm_h%j(m)
+                    k = surf_usm_h%k(m)
+                    temp_pf(k,j,i) = surf_usm_h%surfhf_av(m)
+                 ENDDO
+                 DO  l = 0, 3
+                    DO  m = 1, surf_usm_v(l)%ns
+                       i = surf_usm_v(l)%i(m)
+                       j = surf_usm_v(l)%j(m)
+                       k = surf_usm_v(l)%k(m)
+                       temp_pf(k,j,i) = surf_usm_v(l)%surfhf_av(m)
+                    ENDDO
+                 ENDDO
+              ENDIF
+ 
           CASE ( 'usm_wshf' )
 !--           array of sensible heat flux from surfaces
-!--           horizontal surfaces
-              DO isurf = dirstart(ids), dirend(ids)
-                 IF ( surfl(id,isurf) == ids )  THEN
-                   IF ( av == 0 )  THEN
-                     temp_pf(surfl(iz,isurf),surfl(iy,isurf),surfl(ix,isurf)) = wshf_eb(isurf)
-                   ELSE
-                     temp_pf(surfl(iz,isurf),surfl(iy,isurf),surfl(ix,isurf)) = wshf_eb_av(isurf)
-                   ENDIF
-                 ENDIF
-              ENDDO
+              IF ( av == 0 )  THEN
+                 DO  m = 1, surf_usm_h%ns
+                    i = surf_usm_h%i(m)
+                    j = surf_usm_h%j(m)
+                    k = surf_usm_h%k(m)
+                    temp_pf(k,j,i) = surf_usm_h%wshf_eb(m)
+                 ENDDO
+                 DO  l = 0, 3
+                    DO  m = 1, surf_usm_v(l)%ns
+                       i = surf_usm_v(l)%i(m)
+                       j = surf_usm_v(l)%j(m)
+                       k = surf_usm_v(l)%k(m)
+                       temp_pf(k,j,i) = surf_usm_v(l)%wshf_eb(m)
+                    ENDDO
+                 ENDDO
+              ELSE
+                 DO  m = 1, surf_usm_h%ns
+                    i = surf_usm_h%i(m)
+                    j = surf_usm_h%j(m)
+                    k = surf_usm_h%k(m)
+                    temp_pf(k,j,i) = surf_usm_h%wshf_eb_av(m)
+                 ENDDO
+                 DO  l = 0, 3
+                    DO  m = 1, surf_usm_v(l)%ns
+                       i = surf_usm_v(l)%i(m)
+                       j = surf_usm_v(l)%j(m)
+                       k = surf_usm_v(l)%k(m)
+                       temp_pf(k,j,i) = surf_usm_v(l)%wshf_eb_av(m)
+                    ENDDO
+                 ENDDO
+              ENDIF
+
 
           CASE ( 'usm_wghf' )
 !--           array of heat flux from ground (land, wall, roof)
-              DO isurf = dirstart(ids), dirend(ids)
-                 IF ( surfl(id,isurf) == ids )  THEN
-                   IF ( av == 0 )  THEN
-                     temp_pf(surfl(iz,isurf),surfl(iy,isurf),surfl(ix,isurf)) = wghf_eb(isurf)
-                   ELSE
-                     temp_pf(surfl(iz,isurf),surfl(iy,isurf),surfl(ix,isurf)) = wghf_eb_av(isurf)
-                   ENDIF
-                 ENDIF
-              ENDDO
+              IF ( av == 0 )  THEN
+                 DO  m = 1, surf_usm_h%ns
+                    i = surf_usm_h%i(m)
+                    j = surf_usm_h%j(m)
+                    k = surf_usm_h%k(m)
+                    temp_pf(k,j,i) = surf_usm_h%wghf_eb(m)
+                 ENDDO
+                 DO  l = 0, 3
+                    DO  m = 1, surf_usm_v(l)%ns
+                       i = surf_usm_v(l)%i(m)
+                       j = surf_usm_v(l)%j(m)
+                       k = surf_usm_v(l)%k(m)
+                       temp_pf(k,j,i) = surf_usm_v(l)%wghf_eb(m)
+                    ENDDO
+                 ENDDO
+              ELSE
+                 DO  m = 1, surf_usm_h%ns
+                    i = surf_usm_h%i(m)
+                    j = surf_usm_h%j(m)
+                    k = surf_usm_h%k(m)
+                    temp_pf(k,j,i) = surf_usm_h%wghf_eb_av(m)
+                 ENDDO
+                 DO  l = 0, 3
+                    DO  m = 1, surf_usm_v(l)%ns
+                       i = surf_usm_v(l)%i(m)
+                       j = surf_usm_v(l)%j(m)
+                       k = surf_usm_v(l)%k(m)
+                       temp_pf(k,j,i) = surf_usm_v(l)%wghf_eb_av(m)
+                    ENDDO
+                 ENDDO
+              ENDIF
 
           CASE ( 'usm_t_surf' )
 !--           surface temperature for surfaces
-              DO isurf = max(startenergy,dirstart(ids)), min(endenergy,dirend(ids))
-                 IF ( surfl(id,isurf) == ids )  THEN
-                   IF ( av == 0 )  THEN
-                     temp_pf(surfl(iz,isurf),surfl(iy,isurf),surfl(ix,isurf)) = t_surf(isurf)
-                   ELSE
-                     temp_pf(surfl(iz,isurf),surfl(iy,isurf),surfl(ix,isurf)) = t_surf_av(isurf)
-                   ENDIF
-                 ENDIF
-              ENDDO
+              IF ( av == 0 )  THEN
+                 DO  m = 1, surf_usm_h%ns
+                    i = surf_usm_h%i(m)
+                    j = surf_usm_h%j(m)
+                    k = surf_usm_h%k(m)
+                    temp_pf(k,j,i) = t_surf_h(m)
+                 ENDDO
+                 DO  l = 0, 3
+                    DO  m = 1, surf_usm_v(l)%ns
+                       i = surf_usm_v(l)%i(m)
+                       j = surf_usm_v(l)%j(m)
+                       k = surf_usm_v(l)%k(m)
+                       temp_pf(k,j,i) = t_surf_v(l)%t(m)
+                    ENDDO
+                 ENDDO
+              ELSE
+                 DO  m = 1, surf_usm_h%ns
+                    i = surf_usm_h%i(m)
+                    j = surf_usm_h%j(m)
+                    k = surf_usm_h%k(m)
+                    temp_pf(k,j,i) = surf_usm_h%t_surf_av(m)
+                 ENDDO
+                 DO  l = 0, 3
+                    DO  m = 1, surf_usm_v(l)%ns
+                       i = surf_usm_v(l)%i(m)
+                       j = surf_usm_v(l)%j(m)
+                       k = surf_usm_v(l)%k(m)
+                       temp_pf(k,j,i) = surf_usm_v(l)%t_surf_av(m)
+                    ENDDO
+                 ENDDO
+              ENDIF
               
           CASE ( 'usm_t_wall' )
 !--           wall temperature for  iwl layer of walls and land
-              DO isurf = dirstart(ids), dirend(ids)
-                 IF ( surfl(id,isurf) == ids )  THEN
-                   IF ( av == 0 )  THEN
-                     temp_pf(surfl(iz,isurf),surfl(iy,isurf),surfl(ix,isurf)) = t_wall(iwl,isurf)
-                   ELSE
-                     temp_pf(surfl(iz,isurf),surfl(iy,isurf),surfl(ix,isurf)) = t_wall_av(iwl,isurf)
-                   ENDIF
-                 ENDIF
-              ENDDO
+              IF ( av == 0 )  THEN
+                 DO  m = 1, surf_usm_h%ns
+                    i = surf_usm_h%i(m)
+                    j = surf_usm_h%j(m)
+                    k = surf_usm_h%k(m)
+                    temp_pf(k,j,i) = t_wall_h(iwl,m)
+                 ENDDO
+                 DO  l = 0, 3
+                    DO  m = 1, surf_usm_v(l)%ns
+                       i = surf_usm_v(l)%i(m)
+                       j = surf_usm_v(l)%j(m)
+                       k = surf_usm_v(l)%k(m)
+                       temp_pf(k,j,i) = t_wall_v(l)%t(iwl,m)
+                    ENDDO
+                 ENDDO
+              ELSE
+                 DO  m = 1, surf_usm_h%ns
+                    i = surf_usm_h%i(m)
+                    j = surf_usm_h%j(m)
+                    k = surf_usm_h%k(m)
+                    temp_pf(k,j,i) = surf_usm_h%t_wall_av(iwl,m)
+                 ENDDO
+                 DO  l = 0, 3
+                    DO  m = 1, surf_usm_v(l)%ns
+                       i = surf_usm_v(l)%i(m)
+                       j = surf_usm_v(l)%j(m)
+                       k = surf_usm_v(l)%k(m)
+                       temp_pf(k,j,i) = surf_usm_v(l)%t_wall_av(iwl,m)
+                    ENDDO
+                 ENDDO
+              ENDIF
              
           CASE DEFAULT
@@ -2408,4 +2873,6 @@
 !--     fill out array local_pf which is subsequently treated by data_output_3d
         CALL exchange_horiz( temp_pf, nbgp )
+!
+!--  To Do: why reversed loop order
         DO j = nysg,nyng
             DO i = nxlg,nxrg
@@ -2589,5 +3056,5 @@
         IMPLICIT NONE
 
-        INTEGER(iwp) ::  k, l            !< running indices
+        INTEGER(iwp) ::  k, l, m            !< running indices
         
         CALL location_message( '    initialization of wall surface model', .TRUE. )
@@ -2596,26 +3063,55 @@
 !--     Temperature is defined at the center of the wall layers,
 !--     whereas gradients/fluxes are defined at the edges (_stag)
-        DO l = nzb_wall, nzt_wall
-           zwn(l) = zwn_default(l)
+        DO k = nzb_wall, nzt_wall
+           zwn(k) = zwn_default(k)
         ENDDO
-        
-!--     apply for all particular wall grids
-        DO l = startenergy, endenergy
-           zw(:,l) = zwn(:) * thickness_wall(l)
-           dz_wall(nzb_wall,l) = zw(nzb_wall,l)
+!        
+!--     apply for all particular surface grids. First for horizontal surfaces
+        DO  m = 1, surf_usm_h%ns
+           surf_usm_h%zw(:,m)             = zwn(:) *                           &
+                                            surf_usm_h%thickness_wall(m)
+           surf_usm_h%dz_wall(nzb_wall,m) = surf_usm_h%zw(nzb_wall,m)
            DO k = nzb_wall+1, nzt_wall
-               dz_wall(k,l) = zw(k,l) - zw(k-1,l)
+               surf_usm_h%dz_wall(k,m) = surf_usm_h%zw(k,m) -                  &
+                                         surf_usm_h%zw(k-1,m)
            ENDDO
            
-           dz_wall(nzt_wall+1,l) = dz_wall(nzt_wall,l)
+           surf_usm_h%dz_wall(nzt_wall+1,m) = surf_usm_h%dz_wall(nzt_wall,m)
 
            DO k = nzb_wall, nzt_wall-1
-               dz_wall_stag(k,l) = 0.5 * (dz_wall(k+1,l) + dz_wall(k,l))
+               surf_usm_h%dz_wall_stag(k,m) = 0.5 * (                          &
+                           surf_usm_h%dz_wall(k+1,m) + surf_usm_h%dz_wall(k,m) )
            ENDDO
-           dz_wall_stag(nzt_wall,l) = dz_wall(nzt_wall,l)
+           surf_usm_h%dz_wall_stag(nzt_wall,m) = surf_usm_h%dz_wall(nzt_wall,m)
         ENDDO
-        
-        ddz_wall      = 1.0_wp / dz_wall
-        ddz_wall_stag = 1.0_wp / dz_wall_stag
+        surf_usm_h%ddz_wall      = 1.0_wp / surf_usm_h%dz_wall
+        surf_usm_h%ddz_wall_stag = 1.0_wp / surf_usm_h%dz_wall_stag
+!        
+!--     For vertical surfaces
+        DO  l = 0, 3
+           DO  m = 1, surf_usm_v(l)%ns
+              surf_usm_v(l)%zw(:,m)             = zwn(:) *                     &
+                                                  surf_usm_v(l)%thickness_wall(m)
+              surf_usm_v(l)%dz_wall(nzb_wall,m) = surf_usm_v(l)%zw(nzb_wall,m)
+              DO k = nzb_wall+1, nzt_wall
+                  surf_usm_v(l)%dz_wall(k,m) = surf_usm_v(l)%zw(k,m) -         &
+                                               surf_usm_v(l)%zw(k-1,m)
+              ENDDO
+           
+              surf_usm_v(l)%dz_wall(nzt_wall+1,m) =                            &
+                                              surf_usm_v(l)%dz_wall(nzt_wall,m)
+
+              DO k = nzb_wall, nzt_wall-1
+                  surf_usm_v(l)%dz_wall_stag(k,m) = 0.5 * (                    &
+                                                surf_usm_v(l)%dz_wall(k+1,m) + &
+                                                surf_usm_v(l)%dz_wall(k,m) )
+              ENDDO
+              surf_usm_v(l)%dz_wall_stag(nzt_wall,m) =                         &
+                                              surf_usm_v(l)%dz_wall(nzt_wall,m)
+           ENDDO
+           surf_usm_v(l)%ddz_wall      = 1.0_wp / surf_usm_v(l)%dz_wall
+           surf_usm_v(l)%ddz_wall_stag = 1.0_wp / surf_usm_v(l)%dz_wall_stag
+        ENDDO      
+
         
         CALL location_message( '    wall structures filed out', .TRUE. )
@@ -2635,5 +3131,5 @@
         IMPLICIT NONE
 
-        INTEGER(iwp) ::  i, j, k, l            !< running indices
+        INTEGER(iwp) ::  i, j, k, l, m            !< running indices
         REAL(wp)     ::  c, d, tin, exn
         
@@ -2699,42 +3195,83 @@
         ELSE
        
-!--         Calculate initial surface temperature
+!--         Calculate initial surface temperature from pt of adjacent gridbox
             exn = ( surface_pressure / 1000.0_wp )**0.286_wp
 
-            DO l = startenergy, endenergy
-                k = surfl(iz,l)
-                j = surfl(iy,l)
-                i = surfl(ix,l)
-
-!--              Initial surface temperature set from pt of adjacent gridbox
-                t_surf(l) = pt(k,j,i) * exn
+!
+!--         At horizontal surfaces. Please note, t_surf_h is defined on a 
+!--         different data type, but with the same dimension.
+            DO  m = 1, surf_usm_h%ns
+               i = surf_usm_h%i(m)            
+               j = surf_usm_h%j(m)
+               k = surf_usm_h%k(m)
+
+               t_surf_h(m) = pt(k,j,i) * exn
             ENDDO
+!
+!--         At vertical surfaces.
+            DO  l = 0, 3
+               DO  m = 1, surf_usm_v(l)%ns
+                  i = surf_usm_v(l)%i(m)            
+                  j = surf_usm_v(l)%j(m)
+                  k = surf_usm_v(l)%k(m)
+
+                  t_surf_v(l)%t(m) = pt(k,j,i) * exn
+               ENDDO
+            ENDDO
+
       
 !--         initial values for t_wall
 !--         outer value is set to surface temperature
 !--         inner value is set to wall_inner_temperature
-!--         and profile is logaritmic (linear in nz)
-            DO l = startenergy, endenergy
-                IF ( isroof_surf(l) )  THEN
-                    tin = roof_inner_temperature
-                ELSE IF ( surf(id,l)==iroof )  THEN
-                    tin = soil_inner_temperature
-                ELSE
-                    tin = wall_inner_temperature
-                ENDIF
-                DO k = nzb_wall, nzt_wall+1
-                    c = REAL(k-nzb_wall,wp)/REAL(nzt_wall+1-nzb_wall,wp)
-                    t_wall(k,:) = (1.0_wp-c)*t_surf(:) + c*tin
-                ENDDO
+!--         and profile is logaritmic (linear in nz).
+!--         Horizontal surfaces
+            DO  m = 1, surf_usm_h%ns
+!
+!--            Roof
+               IF ( surf_usm_h%isroof_surf(m) )  THEN
+                   tin = roof_inner_temperature
+!
+!--            Normal land surface
+               ELSE 
+                   tin = soil_inner_temperature
+               ENDIF
+
+               DO k = nzb_wall, nzt_wall+1
+                   c = REAL( k - nzb_wall, wp ) /                              &
+                       REAL( nzt_wall + 1 - nzb_wall , wp )
+
+                   t_wall_h(k,m) = ( 1.0_wp - c ) * t_surf_h(m) + c * tin
+               ENDDO
             ENDDO
+!
+!--         Vertical surfaces
+            DO  l = 0, 3
+               DO  m = 1, surf_usm_v(l)%ns
+!
+!--               Inner wall
+                  tin = wall_inner_temperature
+
+                  DO k = nzb_wall, nzt_wall+1
+                     c = REAL( k - nzb_wall, wp ) /                            &
+                         REAL( nzt_wall + 1 - nzb_wall , wp )
+
+                     t_wall_v(l)%t(k,m) = ( 1.0_wp - c ) * t_surf_v(l)%t(m) +  &
+                                          c * tin
+                  ENDDO
+               ENDDO
+            ENDDO
+
         ENDIF
         
 !--    
-!--        Possibly DO user-defined actions (e.g. define heterogeneous wall surface)
+!--     Possibly DO user-defined actions (e.g. define heterogeneous wall surface)
         CALL user_init_urban_surface
 
 !--     initialize prognostic values for the first timestep
-        t_surf_p = t_surf
-        t_wall_p = t_wall
+        t_surf_h_p = t_surf_h
+        t_surf_v_p = t_surf_v
+
+        t_wall_h_p = t_wall_h
+        t_wall_v_p = t_wall_v
         
 !--     Adjust radiative fluxes for urban surface at model start
@@ -2759,54 +3296,113 @@
         IMPLICIT NONE
 
-        INTEGER(iwp) ::  i,j,k,l,kw                      !< running indices
+        INTEGER(iwp) ::  i,j,k,l,kw, m                      !< running indices
 
         REAL(wp), DIMENSION(nzb_wall:nzt_wall) :: wtend  !< tendency
 
-                                               
-        DO l = startenergy, endenergy
-!--         calculate frequently used parameters
-            k = surfl(iz,l)
-            j = surfl(iy,l)
-            i = surfl(ix,l)
-
-            !
-!--         prognostic equation for ground/wall/roof temperature t_wall
-            wtend(:) = 0.0_wp
-            wtend(nzb_wall) = (1.0_wp/rho_c_wall(nzb_wall,l)) *                     &
-                       ( lambda_h(nzb_wall,l) * ( t_wall(nzb_wall+1,l)              &
-                         - t_wall(nzb_wall,l) ) * ddz_wall(nzb_wall+1,l)            &
-                         + wghf_eb(l) ) * ddz_wall_stag(nzb_wall,l)
+!
+!--     For horizontal surfaces                                   
+        DO  m = 1, surf_usm_h%ns
+!
+!--        Obtain indices
+           i = surf_usm_h%i(m)            
+           j = surf_usm_h%j(m)
+           k = surf_usm_h%k(m)
+!
+!--        prognostic equation for ground/roof temperature t_wall_h
+           wtend(:) = 0.0_wp
+           wtend(nzb_wall) = (1.0_wp / surf_usm_h%rho_c_wall(nzb_wall,m)) *    &
+                                      ( surf_usm_h%lambda_h(nzb_wall,m) *      &
+                                        ( t_wall_h(nzb_wall+1,m)               &
+                                        - t_wall_h(nzb_wall,m) ) *             &
+                                        surf_usm_h%ddz_wall(nzb_wall+1,m)      &
+                                      + surf_usm_h%wghf_eb(m) ) *              &
+                                        surf_usm_h%ddz_wall_stag(nzb_wall,m)
             
-            DO  kw = nzb_wall+1, nzt_wall
-                wtend(kw) = (1.0_wp/rho_c_wall(kw,l))                               &
-                              * (   lambda_h(kw,l)                                  &
-                                 * ( t_wall(kw+1,l) - t_wall(kw,l) )                &
-                                 * ddz_wall(kw+1,l)                                 &
-                              - lambda_h(kw-1,l)                                    &
-                                 * ( t_wall(kw,l) - t_wall(kw-1,l) )                &
-                                 * ddz_wall(kw,l)                                   &
-                              ) * ddz_wall_stag(kw,l)
+           DO  kw = nzb_wall+1, nzt_wall
+               wtend(kw) = (1.0_wp / surf_usm_h%rho_c_wall(kw,m))              &
+                              * (   surf_usm_h%lambda_h(kw,m)                  &
+                                 * ( t_wall_h(kw+1,m) - t_wall_h(kw,m) )       &
+                                 * surf_usm_h%ddz_wall(kw+1,m)                 &
+                              - surf_usm_h%lambda_h(kw-1,m)                    &
+                                 * ( t_wall_h(kw,m) - t_wall_h(kw-1,m) )       &
+                                 * surf_usm_h%ddz_wall(kw,m)                   &
+                              ) * surf_usm_h%ddz_wall_stag(kw,m)
             ENDDO
 
-            t_wall_p(nzb_wall:nzt_wall,l) = t_wall(nzb_wall:nzt_wall,l)             &
-                                             + dt_3d * ( tsc(2)                     &
-                                             * wtend(nzb_wall:nzt_wall) + tsc(3)    &
-                                             * tt_wall_m(nzb_wall:nzt_wall,l) )   
+           t_wall_h_p(nzb_wall:nzt_wall,m) = t_wall_h(nzb_wall:nzt_wall,m)     &
+                                 + dt_3d * ( tsc(2)                            &
+                                 * wtend(nzb_wall:nzt_wall) + tsc(3)           &
+                                 * surf_usm_h%tt_wall_m(nzb_wall:nzt_wall,m) )   
             
-            !
-!--         calculate t_wall tendencies for the next Runge-Kutta step
-            IF ( timestep_scheme(1:5) == 'runge' )  THEN
-                IF ( intermediate_timestep_count == 1 )  THEN
+!
+!--        calculate t_wall tendencies for the next Runge-Kutta step
+           IF ( timestep_scheme(1:5) == 'runge' )  THEN
+               IF ( intermediate_timestep_count == 1 )  THEN
+                  DO  kw = nzb_wall, nzt_wall
+                     surf_usm_h%tt_wall_m(kw,m) = wtend(kw)
+                  ENDDO
+               ELSEIF ( intermediate_timestep_count <                          &
+                        intermediate_timestep_count_max )  THEN
                    DO  kw = nzb_wall, nzt_wall
-                      tt_wall_m(kw,l) = wtend(kw)
+                      surf_usm_h%tt_wall_m(kw,m) = -9.5625_wp * wtend(kw) +    &
+                                         5.3125_wp * surf_usm_h%tt_wall_m(kw,m)
                    ENDDO
-                ELSEIF ( intermediate_timestep_count <                              &
-                         intermediate_timestep_count_max )  THEN
-                    DO  kw = nzb_wall, nzt_wall
-                        tt_wall_m(kw,l) = -9.5625_wp * wtend(kw) + 5.3125_wp        &
-                                         * tt_wall_m(kw,l)
-                    ENDDO
-                ENDIF
-            ENDIF
+               ENDIF
+           ENDIF
+        ENDDO
+!
+!--     For vertical surfaces     
+        DO  l = 0, 3                              
+           DO  m = 1, surf_usm_v(l)%ns
+!
+!--           Obtain indices
+              i = surf_usm_v(l)%i(m)            
+              j = surf_usm_v(l)%j(m)
+              k = surf_usm_v(l)%k(m)
+!
+!--           prognostic equation for wall temperature t_wall_v
+              wtend(:) = 0.0_wp
+              wtend(nzb_wall) = (1.0_wp / surf_usm_v(l)%rho_c_wall(nzb_wall,m)) * &
+                                      ( surf_usm_v(l)%lambda_h(nzb_wall,m) *   &
+                                        ( t_wall_v(l)%t(nzb_wall+1,m)          &
+                                        - t_wall_v(l)%t(nzb_wall,m) ) *        &
+                                        surf_usm_v(l)%ddz_wall(nzb_wall+1,m)   &
+                                      + surf_usm_v(l)%wghf_eb(m) ) *           &
+                                        surf_usm_v(l)%ddz_wall_stag(nzb_wall,m)
+            
+              DO  kw = nzb_wall+1, nzt_wall
+                  wtend(kw) = (1.0_wp / surf_usm_v(l)%rho_c_wall(kw,m))        &
+                           * (   surf_usm_v(l)%lambda_h(kw,m)                  &
+                              * ( t_wall_v(l)%t(kw+1,m) - t_wall_v(l)%t(kw,m) )&
+                              * surf_usm_v(l)%ddz_wall(kw+1,m)                 &
+                           - surf_usm_v(l)%lambda_h(kw-1,m)                    &
+                              * ( t_wall_v(l)%t(kw,m) - t_wall_v(l)%t(kw-1,m) )&
+                              * surf_usm_v(l)%ddz_wall(kw,m)                   &
+                              ) * surf_usm_v(l)%ddz_wall_stag(kw,m)
+               ENDDO
+
+              t_wall_v_p(l)%t(nzb_wall:nzt_wall,m) =                           &
+                                   t_wall_v(l)%t(nzb_wall:nzt_wall,m)          &
+                                 + dt_3d * ( tsc(2)                            &
+                                 * wtend(nzb_wall:nzt_wall) + tsc(3)           &
+                                 * surf_usm_v(l)%tt_wall_m(nzb_wall:nzt_wall,m) )   
+            
+!
+!--           calculate t_wall tendencies for the next Runge-Kutta step
+              IF ( timestep_scheme(1:5) == 'runge' )  THEN
+                  IF ( intermediate_timestep_count == 1 )  THEN
+                     DO  kw = nzb_wall, nzt_wall
+                        surf_usm_v(l)%tt_wall_m(kw,m) = wtend(kw)
+                     ENDDO
+                  ELSEIF ( intermediate_timestep_count <                       &
+                           intermediate_timestep_count_max )  THEN
+                      DO  kw = nzb_wall, nzt_wall
+                         surf_usm_v(l)%tt_wall_m(kw,m) =                       &
+                                     - 9.5625_wp * wtend(kw) +                 &
+                                       5.3125_wp * surf_usm_v(l)%tt_wall_m(kw,m)
+                      ENDDO
+                  ENDIF
+              ENDIF
+           ENDDO
         ENDDO
 
@@ -2857,9 +3453,7 @@
 !--    Read user-defined namelist
        READ ( 11, urban_surface_par )
-
 !
 !--    Set flag that indicates that the land surface model is switched on
        urban_surface = .TRUE.
-       
 
  10    CONTINUE
@@ -2879,5 +3473,5 @@
         IMPLICIT NONE
        
-        INTEGER(iwp)               :: i, j, k, kk, is, js, d, ku, refstep
+        INTEGER(iwp)               :: i, j, k, kk, is, js, d, ku, refstep, m, mm, l, ll
         INTEGER(iwp)               :: nzubl, nzutl, isurf, isurfsrc, isurf1, isvf, icsf, ipcgb
         INTEGER(iwp), DIMENSION(4) :: bdycross
@@ -2892,4 +3486,5 @@
         REAL(wp)                   :: pc_box_area, pc_abs_frac, pc_abs_eff
         INTEGER(iwp)               :: pc_box_dimshift !< transform for best accuracy
+        INTEGER(iwp), DIMENSION(0:3) :: reorder = (/ 1, 0, 3, 2 /)
         
         
@@ -2949,23 +3544,55 @@
 !--     First pass: direct + diffuse irradiance
 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-        surfinswdir   = 0._wp
-        surfinswdif   = 0._wp
-        surfinlwdif   = 0._wp
-        surfins   = 0._wp
-        surfinl   = 0._wp
-        surfoutsl    = 0._wp
-        surfoutll    = 0._wp
+        surfinswdir   = 0._wp !nsurfl
+        surfinswdif   = 0._wp !nsurfl
+        surfinlwdif   = 0._wp !nsurfl
+        surfins       = 0._wp !nsurfl
+        surfinl       = 0._wp !nsurfl
+        surfoutsl(:)  = 0.0_wp !start-end
+        surfoutll(:)  = 0.0_wp !start-end
         
 !--     Set up thermal radiation from surfaces
 !--     emiss_surf is defined only for surfaces for which energy balance is calculated
-        surfoutll(startenergy:endenergy) = emiss_surf(startenergy:endenergy) * sigma_sb   &
-                                           * t_surf(startenergy:endenergy)**4
+!--     Workaround: reorder surface data type back on 1D array including all surfaces, 
+!--     which implies to reorder horizontal and vertical surfaces
+!
+!--     Horizontal walls
+        mm = 1
+        DO  i = nxl, nxr
+           DO  j = nys, nyn
+
+              DO  m = surf_usm_h%start_index(j,i), surf_usm_h%end_index(j,i)
+                 surfoutll(mm) = surf_usm_h%emiss_surf(m) * sigma_sb   &
+                                     * t_surf_h(m)**4
+                 albedo_surf(mm) = surf_usm_h%albedo_surf(m)
+                 emiss_surf(mm)  = surf_usm_h%emiss_surf(m)
+                 mm = mm + 1
+              ENDDO
+           ENDDO
+        ENDDO
+!
+!--     Vertical walls
+        DO  i = nxl, nxr
+           DO  j = nys, nyn
+              DO  ll = 0, 3
+                 l = reorder(ll)
+                 DO  m = surf_usm_v(l)%start_index(j,i), surf_usm_v(l)%end_index(j,i)
+                    surfoutll(mm) = surf_usm_v(l)%emiss_surf(m) * sigma_sb   &
+                                     * t_surf_v(l)%t(m)**4
+                    albedo_surf(mm) = surf_usm_v(l)%albedo_surf(m)
+                    emiss_surf(mm) = surf_usm_v(l)%emiss_surf(m)
+                    mm = mm + 1
+                 ENDDO
+              ENDDO
+           ENDDO
+        ENDDO
         
 #if defined( __parallel )
 !--     might be optimized and gather only values relevant for current processor
+        
         CALL MPI_AllGatherv(surfoutll, nenergy, MPI_REAL, &
-                            surfoutl, nsurfs, surfstart, MPI_REAL, comm2d, ierr)
+                            surfoutl, nsurfs, surfstart, MPI_REAL, comm2d, ierr) !nsurf global
 #else
-        surfoutl(:) = surfoutll(:)
+        surfoutl(:) = surfoutll(:) !nsurf global
 #endif
         
@@ -3005,8 +3632,8 @@
                 surfinl(isurf) = surfinl(isurf) + svf(1,isvf) * surfoutl(isurfsrc)
             ENDIF
-            
-            IF ( zenith(0) > 0  .AND.  all( surf(:, isurfsrc) == bdycross ) )  THEN
+
+            IF ( zenith(0) > 0  .AND.  all( surf(1:4,isurfsrc) == bdycross ) )  THEN
 !--             found svf between model boundary and the face => face isn't shaded
-                surfinswdir(isurf) = rad_sw_in_dir(j, i) &
+                surfinswdir(isurf) = rad_sw_in_dir(j,i) &
                     * costheta(surfl(id, isurf)) * svf(2,isvf) / zenith(0)
 
@@ -3050,5 +3677,5 @@
                 ENDIF
 
-                IF ( zenith(0) > 0  .AND.  all( surf(:, isurfsrc) == bdycross ) )  THEN
+                IF ( zenith(0) > 0  .AND.  all( surf(1:4,isurfsrc) == bdycross ) )  THEN
 !--                 found svf between model boundary and the pcgb => pcgb isn't shaded
                     pc_abs_frac = 1._wp - exp(pc_abs_eff * lad_s(k,j,i))
@@ -3058,4 +3685,5 @@
             ENDDO
         ENDIF
+
         surfins(startenergy:endenergy) = surfinswdir(startenergy:endenergy) + surfinswdif(startenergy:endenergy)
         surfinl(startenergy:endenergy) = surfinl(startenergy:endenergy) + surfinlwdif(startenergy:endenergy)
@@ -3064,6 +3692,6 @@
         surfoutsw(:) = 0.0_wp
         surfoutlw(:) = surfoutll(:)
-        surfhf(startenergy:endenergy) = surfinsw(startenergy:endenergy) + surfinlw(startenergy:endenergy) &
-                                      - surfoutsw(startenergy:endenergy) - surfoutlw(startenergy:endenergy)
+!         surfhf(startenergy:endenergy) = surfinsw(startenergy:endenergy) + surfinlw(startenergy:endenergy) &
+!                                       - surfoutsw(startenergy:endenergy) - surfoutlw(startenergy:endenergy)
         
 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
@@ -3117,6 +3745,6 @@
             surfoutsw(startenergy:endenergy) = surfoutsw(startenergy:endenergy) + surfoutsl(startenergy:endenergy)
             surfoutlw(startenergy:endenergy) = surfoutlw(startenergy:endenergy) + surfoutll(startenergy:endenergy)
-            surfhf(startenergy:endenergy) = surfinsw(startenergy:endenergy) + surfinlw(startenergy:endenergy) &
-                                          - surfoutsw(startenergy:endenergy) - surfoutlw(startenergy:endenergy)
+!             surfhf(startenergy:endenergy) = surfinsw(startenergy:endenergy) + surfinlw(startenergy:endenergy) &
+!                                           - surfoutsw(startenergy:endenergy) - surfoutlw(startenergy:endenergy)
         
         ENDDO
@@ -3129,9 +3757,72 @@
                 i = pcbl(ix, ipcgb)
                 k = pcbl(iz, ipcgb)
-                kk = k - nzb_s_inner(j,i)  !- lad arrays are defined flat
+                kk = k - MAXLOC(                                               &
+                                MERGE( 1, 0,                                   &
+                                       BTEST( wall_flags_0(:,j,i), 12 )        &
+                                     ), DIM = 1                                &
+                               ) - 1 ! kk = k - nzb_s_inner(j,i)  !- lad arrays are defined flat
                 pc_heating_rate(kk, j, i) = (pcbinsw(ipcgb) + pcbinlw(ipcgb)) &
                     * pchf_prep(k) * pt(k, j, i) !-- = dT/dt
             ENDDO
         ENDIF
+!
+!--     Transfer radiation arrays required for energy balance to the respective data types
+        DO  i = startenergy, endenergy
+           m  = surfl(5,i)          
+!
+!--        upward-facing
+           IF ( surfl(1,i) == 0 )  THEN
+              surf_usm_h%rad_in_sw(m)  = surfinsw(i) 
+              surf_usm_h%rad_out_sw(m) = surfoutsw(i) 
+              surf_usm_h%rad_in_lw(m)  = surfinlw(i)
+              surf_usm_h%rad_out_lw(m) = surfoutlw(i)
+!
+!--        southward-facding
+           ELSEIF ( surfl(1,i) == 1 )  THEN
+              surf_usm_v(1)%rad_in_sw(m)  = surfinsw(i) 
+              surf_usm_v(1)%rad_out_sw(m) = surfoutsw(i) 
+              surf_usm_v(1)%rad_in_lw(m)  = surfinlw(i)
+              surf_usm_v(1)%rad_out_lw(m) = surfoutlw(i)
+!
+!--        northward-facding
+           ELSEIF ( surfl(1,i) == 2 )  THEN
+              surf_usm_v(0)%rad_in_sw(m)  = surfinsw(i) 
+              surf_usm_v(0)%rad_out_sw(m) = surfoutsw(i) 
+              surf_usm_v(0)%rad_in_lw(m)  = surfinlw(i)
+              surf_usm_v(0)%rad_out_lw(m) = surfoutlw(i)
+!
+!--        westward-facding
+           ELSEIF ( surfl(1,i) == 3 )  THEN
+              surf_usm_v(3)%rad_in_sw(m)  = surfinsw(i) 
+              surf_usm_v(3)%rad_out_sw(m) = surfoutsw(i) 
+              surf_usm_v(3)%rad_in_lw(m)  = surfinlw(i)
+              surf_usm_v(3)%rad_out_lw(m) = surfoutlw(i)
+!
+!--        eastward-facing
+           ELSEIF ( surfl(1,i) == 4 )  THEN
+              surf_usm_v(2)%rad_in_sw(m)  = surfinsw(i) 
+              surf_usm_v(2)%rad_out_sw(m) = surfoutsw(i) 
+              surf_usm_v(2)%rad_in_lw(m)  = surfinlw(i)
+              surf_usm_v(2)%rad_out_lw(m) = surfoutlw(i)
+           ENDIF
+
+        ENDDO
+
+
+        DO  m = 1, surf_usm_h%ns
+           surf_usm_h%surfhf(m) = surf_usm_h%rad_in_sw(m)  +                   &
+                                  surf_usm_h%rad_in_lw(m)  -                   &
+                                  surf_usm_h%rad_out_sw(m) -                   &
+                                  surf_usm_h%rad_out_lw(m)
+        ENDDO
+
+        DO  l = 0, 3
+           DO  m = 1, surf_usm_v(l)%ns
+              surf_usm_v(l)%surfhf(m) = surf_usm_v(l)%rad_in_sw(m)  +          &
+                                        surf_usm_v(l)%rad_in_lw(m)  -          &
+                                        surf_usm_v(l)%rad_out_sw(m) -          &
+                                        surf_usm_v(l)%rad_out_lw(m)
+           ENDDO
+        ENDDO
 
 !--     return surface radiation to horizontal surfaces 
@@ -3207,5 +3898,5 @@
         REAL(wp), PARAMETER                    :: grow_factor = 1.5_wp !< factor of expansion of grow arrays
 
-
+!
 !--     Maximum number of gridboxes visited equals to maximum number of boundaries crossed in each dimension plus one. That's also
 !--     the maximum number of plant canopy boxes written. We grow the acsf array accordingly using exponential factor.
@@ -3351,5 +4042,4 @@
         visible = .TRUE.
 
-        
     END SUBROUTINE usm_raytrace
     
@@ -3470,24 +4160,103 @@
                 SELECT CASE ( TRIM( variable_chr ) )
                 
-                   CASE ( 't_surf' )
+                   CASE ( 't_surf_h' )
 #if defined( __nopointer )                   
-                      IF ( .NOT.  ALLOCATED( t_surf ) )                         &
-                         ALLOCATE( t_surf(startenergy:endenergy) )
-                      READ ( 13 )  t_surf
+                      IF ( .NOT.  ALLOCATED( t_surf_h ) )                      &
+                         ALLOCATE( t_surf_h(1:surf_usm_h%ns) )
+                      READ ( 13 )  t_surf_h
 #else                      
-                      IF ( .NOT.  ALLOCATED( t_surf_1 ) )                         &
-                         ALLOCATE( t_surf_1(startenergy:endenergy) )
-                      READ ( 13 )  t_surf_1
+                      IF ( .NOT.  ALLOCATED( t_surf_h_1 ) )                    &
+                         ALLOCATE( t_surf_h_1(1:surf_usm_h%ns) )
+                      READ ( 13 )  t_surf_h_1
 #endif
-
-                   CASE ( 't_wall' )
+                   CASE ( 't_surf_v(0)' )
+#if defined( __nopointer )                   
+                      IF ( .NOT.  ALLOCATED( t_surf_v(0)%t ) )                 &
+                         ALLOCATE( t_surf_v(0)%t(1:surf_usm_v(0)%ns) )
+                      READ ( 13 )  t_surf_v(0)%t
+#else                      
+                      IF ( .NOT.  ALLOCATED( t_surf_v_1(0)%t ) )               &
+                         ALLOCATE( t_surf_v_1(0)%t(1:surf_usm_v(0)%ns) )
+                      READ ( 13 )  t_surf_v_1(0)%t
+#endif
+                   CASE ( 't_surf_v(1)' )
+#if defined( __nopointer )                   
+                      IF ( .NOT.  ALLOCATED( t_surf_v(1)%t ) )                 &
+                         ALLOCATE( t_surf_v(1)%t(1:surf_usm_v(1)%ns) )
+                      READ ( 13 )  t_surf_v(1)%t
+#else                      
+                      IF ( .NOT.  ALLOCATED( t_surf_v_1(1)%t ) )               &
+                         ALLOCATE( t_surf_v_1(1)%t(1:surf_usm_v(1)%ns) )
+                      READ ( 13 )  t_surf_v_1(1)%t
+#endif
+                   CASE ( 't_surf_v(2)' )
+#if defined( __nopointer )                   
+                      IF ( .NOT.  ALLOCATED( t_surf_v(2)%t ) )                 &
+                         ALLOCATE( t_surf_v(2)%t(1:surf_usm_v(2)%ns) )
+                      READ ( 13 )  t_surf_v(2)%t
+#else                      
+                      IF ( .NOT.  ALLOCATED( t_surf_v_1(2)%t ) )               &
+                         ALLOCATE( t_surf_v_1(2)%t(1:surf_usm_v(2)%ns) )
+                      READ ( 13 )  t_surf_v_1(2)%t
+#endif
+                   CASE ( 't_surf_v(3)' )
+#if defined( __nopointer )                   
+                      IF ( .NOT.  ALLOCATED( t_surf_v(3)%t ) )                 &
+                         ALLOCATE( t_surf_v(3)%t(1:surf_usm_v(3)%ns) )
+                      READ ( 13 )  t_surf_v(3)%t
+#else                      
+                      IF ( .NOT.  ALLOCATED( t_surf_v_1(3)%t ) )               &
+                         ALLOCATE( t_surf_v_1(3)%t(1:surf_usm_v(3)%ns) )
+                      READ ( 13 )  t_surf_v_1(3)%t
+#endif
+                   CASE ( 't_wall_h' )
 #if defined( __nopointer )
-                      IF ( .NOT.  ALLOCATED( t_wall ) )                         &
-                         ALLOCATE( t_wall(nzb_wall:nzt_wall+1,startenergy:endenergy) )
-                      READ ( 13 )  t_wall
+                      IF ( .NOT.  ALLOCATED( t_wall_h ) )                      &
+                         ALLOCATE( t_wall_h(nzb_wall:nzt_wall+1,1:surf_usm_h%ns) )
+                      READ ( 13 )  t_wall_h
 #else
-                      IF ( .NOT.  ALLOCATED( t_wall_1 ) )                         &
-                         ALLOCATE( t_wall_1(nzb_wall:nzt_wall+1,startenergy:endenergy) )
-                      READ ( 13 )  t_wall_1
+                      IF ( .NOT.  ALLOCATED( t_wall_h_1 ) )                    &
+                         ALLOCATE( t_wall_h_1(nzb_wall:nzt_wall+1,1:surf_usm_h%ns) )
+                      READ ( 13 )  t_wall_h_1
+#endif
+                   CASE ( 't_wall_v(0)' )
+#if defined( __nopointer )
+                      IF ( .NOT.  ALLOCATED( t_wall_v(0)%t ) )                      &
+                         ALLOCATE( t_wall_v(0)%t(nzb_wall:nzt_wall+1,1:surf_usm_v(0)%ns) )
+                      READ ( 13 )  t_wall_v(0)%t
+#else
+                      IF ( .NOT.  ALLOCATED( t_wall_v_1(0)%t ) )                    &
+                         ALLOCATE( t_wall_v_1(0)%t(nzb_wall:nzt_wall+1,1:surf_usm_v(0)%ns) )
+                      READ ( 13 )  t_wall_v_1(0)%t
+#endif
+                   CASE ( 't_wall_v(1)' )
+#if defined( __nopointer )
+                      IF ( .NOT.  ALLOCATED( t_wall_v(1)%t ) )                      &
+                         ALLOCATE( t_wall_v(1)%t(nzb_wall:nzt_wall+1,1:surf_usm_v(1)%ns) )
+                      READ ( 13 )  t_wall_v(1)%t
+#else
+                      IF ( .NOT.  ALLOCATED( t_wall_v_1(0)%t ) )                    &
+                         ALLOCATE( t_wall_v_1(1)%t(nzb_wall:nzt_wall+1,1:surf_usm_v(1)%ns) )
+                      READ ( 13 )  t_wall_v_1(1)%t
+#endif
+                   CASE ( 't_wall_v(2)' )
+#if defined( __nopointer )
+                      IF ( .NOT.  ALLOCATED( t_wall_v(2)%t ) )                      &
+                         ALLOCATE( t_wall_v(2)%t(nzb_wall:nzt_wall+1,1:surf_usm_v(2)%ns) )
+                      READ ( 13 )  t_wall_v(2)%t
+#else
+                      IF ( .NOT.  ALLOCATED( t_wall_v_1(2)%t ) )                    &
+                         ALLOCATE( t_wall_v_1(2)%t(nzb_wall:nzt_wall+1,1:surf_usm_v(2)%ns) )
+                      READ ( 13 )  t_wall_v_1(2)%t
+#endif
+                   CASE ( 't_wall_v(3)' )
+#if defined( __nopointer )
+                      IF ( .NOT.  ALLOCATED( t_wall_v(3)%t ) )                      &
+                         ALLOCATE( t_wall_v(3)%t(nzb_wall:nzt_wall+1,1:surf_usm_v(3)%ns) )
+                      READ ( 13 )  t_wall_v(3)%t
+#else
+                      IF ( .NOT.  ALLOCATED( t_wall_v_1(3)%t ) )                    &
+                         ALLOCATE( t_wall_v_1(3)%t(nzb_wall:nzt_wall+1,1:surf_usm_v(3)%ns) )
+                      READ ( 13 )  t_wall_v_1(3)%t
 #endif
 
@@ -3593,5 +4362,5 @@
         INTEGER(iwp), DIMENSION(0:17, nysg:nyng, nxlg:nxrg)   :: usm_par
         REAL(wp), DIMENSION(1:14, nysg:nyng, nxlg:nxrg)       :: usm_val
-        INTEGER(iwp)                                          :: k, l, d, iw, jw, kw, it, ip, ii, ij
+        INTEGER(iwp)                                          :: k, l, d, iw, jw, kw, it, ip, ii, ij, m
         INTEGER(iwp)                                          :: i, j
         INTEGER(iwp)                                          :: nz, roof, dirwe, dirsn
@@ -3733,152 +4502,198 @@
             ENDDO
         ENDDO
-        
-!--     assign the surface types to local surface array
-        DO  l = startenergy, endenergy
-            
-            d = surfl(id,l)
-            kw = surfl(iz,l)
-            j = surfl(iy,l)
-            i = surfl(ix,l)
-            IF ( d == iroof )  THEN
-!--             horizontal surface - land or roof
-                iw = i
-                jw = j
-                IF ( usm_par(5,jw,iw) == 0 )  THEN
-                    IF ( zu(kw) >= roof_height_limit )  THEN
-                        isroof_surf(l) = .TRUE.
-                        surface_types(l) = roof_category         !< default category for root surface
-                    ELSE
-                        isroof_surf(l) = .FALSE.
-                        surface_types(l) = land_category         !< default category for land surface
-                    ENDIF
-                    albedo_surf(l) = -1.0_wp
-                    thickness_wall(l) = -1.0_wp
-                ELSE
-                    IF ( usm_par(2,jw,iw)==0 )  THEN
-                        isroof_surf(l) = .FALSE.
-                        thickness_wall(l) = -1.0_wp
-                    ELSE
-                        isroof_surf(l) = .TRUE.
-                        thickness_wall(l) = usm_val(2,jw,iw)
-                    ENDIF
-                    surface_types(l) = usm_par(5,jw,iw)
-                    albedo_surf(l) = usm_val(1,jw,iw)
-                ENDIF
-            ELSE
-                SELECT CASE (d)
-                    CASE (iwest)
-                        iw = i
-                        jw = j
-                        ii = 6
-                        ij = 3
-                    CASE (ieast)
-                        iw = i-1
-                        jw = j
-                        ii = 6
-                        ij = 3
-                    CASE (isouth)
-                        iw = i
-                        jw = j
-                        ii = 12
-                        ij = 9
-                    CASE (inorth)
-                        iw = i
-                        jw = j-1
-                        ii = 12
-                        ij = 9
-                END SELECT
-                
-                IF ( kw <= usm_par(ii,jw,iw) )  THEN
-!--                 pedestrant zone
-                    isroof_surf(l) = .FALSE.
-                    IF ( usm_par(ii+1,jw,iw) == 0 )  THEN
-                        surface_types(l) = pedestrant_category   !< default category for wall surface in pedestrant zone
-                        albedo_surf(l) = -1.0_wp
-                        thickness_wall(l) = -1.0_wp
-                    ELSE
-                        surface_types(l) = usm_par(ii+1,jw,iw)
-                        albedo_surf(l) = usm_val(ij,jw,iw)
-                        thickness_wall(l) = usm_val(ij+1,jw,iw)
-                    ENDIF
-                ELSE IF ( kw <= usm_par(ii+2,jw,iw) )  THEN
-!--                 wall zone
-                    isroof_surf(l) = .FALSE.
-                    IF ( usm_par(ii+3,jw,iw) == 0 )  THEN
-                        surface_types(l) = wall_category         !< default category for wall surface
-                        albedo_surf(l) = -1.0_wp
-                        thickness_wall(l) = -1.0_wp
-                    ELSE
-                        surface_types(l) = usm_par(ii+3,jw,iw)
-                        albedo_surf(l) = usm_val(ij+2,jw,iw)
-                        thickness_wall(l) = usm_val(ij+3,jw,iw)
-                    ENDIF
-                ELSE IF ( kw <= usm_par(ii+4,jw,iw) )  THEN
-!--                 roof zone
-                    isroof_surf(l) = .TRUE.
-                    IF ( usm_par(ii+5,jw,iw) == 0 )  THEN
-                        surface_types(l) = roof_category         !< default category for roof surface
-                        albedo_surf(l) = -1.0_wp
-                        thickness_wall(l) = -1.0_wp
-                    ELSE
-                        surface_types(l) = usm_par(ii+5,jw,iw)
-                        albedo_surf(l) = usm_val(ij+4,jw,iw)
-                        thickness_wall(l) = usm_val(ij+5,jw,iw)
-                    ENDIF
-                ELSE
-!--                 something wrong
-                    CALL message( 'usm_read_urban_surface', 'PA0505', 1, 2, 0, 6, 0 )
-                ENDIF
-            ENDIF
-            
-!--         find the type position
-            it = surface_types(l)
-            ip = -99999
-            DO k = 1, n_surface_types
-                IF ( surface_type_codes(k) == it )  THEN
+!        
+!--     Assign the surface types to the respective data type. 
+!--     First, for horizontal upward-facing surfaces. 
+        DO  m = 1, surf_usm_h%ns
+           iw = surf_usm_h%i(m)
+           jw = surf_usm_h%j(m)
+           kw = surf_usm_h%k(m)
+
+           IF ( usm_par(5,jw,iw) == 0 )  THEN
+              IF ( zu(kw) >= roof_height_limit )  THEN
+                 surf_usm_h%isroof_surf(m)   = .TRUE.
+                 surf_usm_h%surface_types(m) = roof_category         !< default category for root surface
+              ELSE
+                 surf_usm_h%isroof_surf(m)   = .FALSE.
+                 surf_usm_h%surface_types(m) = land_category         !< default category for land surface
+              ENDIF
+              surf_usm_h%albedo_surf(m)    = -1.0_wp
+              surf_usm_h%thickness_wall(m) = -1.0_wp
+           ELSE
+              IF ( usm_par(2,jw,iw)==0 )  THEN
+                 surf_usm_h%isroof_surf(m)    = .FALSE.
+                 surf_usm_h%thickness_wall(m) = -1.0_wp
+              ELSE
+                 surf_usm_h%isroof_surf(m)    = .TRUE.
+                 surf_usm_h%thickness_wall(m) = usm_val(2,jw,iw)
+              ENDIF
+              surf_usm_h%surface_types(m) = usm_par(5,jw,iw)
+              surf_usm_h%albedo_surf(m)   = usm_val(1,jw,iw)
+           ENDIF
+!
+!--        Find the type position
+           it = surf_usm_h%surface_types(m)
+           ip = -99999
+           DO k = 1, n_surface_types
+              IF ( surface_type_codes(k) == it )  THEN
+                 ip = k
+                 EXIT
+              ENDIF
+           ENDDO
+           IF ( ip == -99999 )  THEN
+!--           wall category not found
+              WRITE (message_string, "(A,I5,A,3I5)") 'wall category ', it,     &
+                                     ' not found  for i,j,k=', iw,jw,kw
+              CALL message( 'usm_read_urban_surface', 'PA0506', 1, 2, 0, 6, 0 )
+           ENDIF
+!
+!--        Albedo
+           IF ( surf_usm_h%albedo_surf(m) < 0.0_wp )  THEN
+              surf_usm_h%albedo_surf(m) = surface_params(ialbedo,ip)
+           ENDIF
+!
+!--        emissivity of the wall
+           surf_usm_h%emiss_surf(m) = surface_params(iemiss,ip)
+!            
+!--        heat conductivity Î»S between air and wall ( W mâ2 Kâ1 )
+           surf_usm_h%lambda_surf(m) = surface_params(ilambdas,ip)
+!            
+!--        roughness relative to concrete
+           surf_usm_h%roughness_wall(m) = surface_params(irough,ip)
+!            
+!--        Surface skin layer heat capacity (J mâ2 Kâ1 )
+           surf_usm_h%c_surface(m) = surface_params(icsurf,ip)
+!            
+!--        wall material parameters:
+!--        thickness of the wall (m)
+!--        missing values are replaced by default value for category
+           IF ( surf_usm_h%thickness_wall(m) <= 0.001_wp )  THEN
+                surf_usm_h%thickness_wall(m) = surface_params(ithick,ip)
+           ENDIF
+!            
+!--        volumetric heat capacity rho*C of the wall ( J mâ3 Kâ1 )
+           surf_usm_h%rho_c_wall(:,m) = surface_params(irhoC,ip)
+!            
+!--        thermal conductivity Î»H of the wall (W mâ1 Kâ1 )
+           surf_usm_h%lambda_h(:,m) = surface_params(ilambdah,ip)
+
+        ENDDO
+!
+!--     For vertical surface elements ( 0 -- northward-facing, 1 -- southward-facing,
+!--     2 -- eastward-facing, 3 -- westward-facing )
+        DO  l = 0, 3
+           DO  m = 1, surf_usm_v(l)%ns
+              i  = surf_usm_v(l)%i(m)
+              j  = surf_usm_v(l)%j(m)
+              kw = surf_usm_v(l)%k(m)
+
+              IF ( l == 3 )  THEN ! westward facing
+                 iw = i
+                 jw = j
+                 ii = 6
+                 ij = 3
+              ELSEIF ( l == 2 )  THEN
+                 iw = i-1
+                 jw = j
+                 ii = 6
+                 ij = 3
+              ELSEIF ( l == 1 )  THEN
+                 iw = i
+                 jw = j
+                 ii = 12
+                 ij = 9
+              ELSEIF ( l == 0 )  THEN
+                 iw = i
+                 jw = j-1
+                 ii = 12
+                 ij = 9
+              ENDIF
+
+              IF ( kw <= usm_par(ii,jw,iw) )  THEN
+!--              pedestrant zone
+                 IF ( usm_par(ii+1,jw,iw) == 0 )  THEN
+                     surf_usm_v(l)%surface_types(m)  = pedestrant_category   !< default category for wall surface in pedestrant zone
+                     surf_usm_v(l)%albedo_surf(m)    = -1.0_wp
+                     surf_usm_v(l)%thickness_wall(m) = -1.0_wp
+                 ELSE
+                     surf_usm_v(l)%surface_types(m)  = usm_par(ii+1,jw,iw)
+                     surf_usm_v(l)%albedo_surf(m)    = usm_val(ij,jw,iw)
+                     surf_usm_v(l)%thickness_wall(m) = usm_val(ij+1,jw,iw)
+                 ENDIF
+              ELSE IF ( kw <= usm_par(ii+2,jw,iw) )  THEN
+!--              wall zone
+                 IF ( usm_par(ii+3,jw,iw) == 0 )  THEN
+                     surf_usm_v(l)%surface_types(m)  = wall_category         !< default category for wall surface
+                     surf_usm_v(l)%albedo_surf(m)    = -1.0_wp
+                     surf_usm_v(l)%thickness_wall(m) = -1.0_wp
+                 ELSE
+                     surf_usm_v(l)%surface_types(m)  = usm_par(ii+3,jw,iw)
+                     surf_usm_v(l)%albedo_surf(m)    = usm_val(ij+2,jw,iw)
+                     surf_usm_v(l)%thickness_wall(m) = usm_val(ij+3,jw,iw)
+                 ENDIF
+              ELSE IF ( kw <= usm_par(ii+4,jw,iw) )  THEN
+!--              roof zone
+                 IF ( usm_par(ii+5,jw,iw) == 0 )  THEN
+                     surf_usm_v(l)%surface_types(m)  = roof_category         !< default category for roof surface
+                     surf_usm_v(l)%albedo_surf(m)    = -1.0_wp
+                     surf_usm_v(l)%thickness_wall(m) = -1.0_wp
+                 ELSE
+                     surf_usm_v(l)%surface_types(m)  = usm_par(ii+5,jw,iw)
+                     surf_usm_v(l)%albedo_surf(m)    = usm_val(ij+4,jw,iw)
+                     surf_usm_v(l)%thickness_wall(m) = usm_val(ij+5,jw,iw)
+                 ENDIF
+              ELSE
+!--              something wrong
+                 CALL message( 'usm_read_urban_surface', 'PA0505', 1, 2, 0, 6, 0 )
+              ENDIF
+
+!
+!--           Find the type position
+              it = surf_usm_v(l)%surface_types(m)
+              ip = -99999
+              DO k = 1, n_surface_types
+                 IF ( surface_type_codes(k) == it )  THEN
                     ip = k
                     EXIT
-                ENDIF
-            ENDDO
-            IF ( ip == -99999 )  THEN
-!--             wall category not found
-                WRITE (message_string, "(A,I5,A,3I5)") 'wall category ', it, ' not found  for i,j,k=', iw,jw,kw
-                CALL message( 'usm_read_urban_surface', 'PA0506', 1, 2, 0, 6, 0 )
-            ENDIF
-            
-!--         Fill out the parameters of the wall
-!--         wall surface:
-            
-!--         albedo
-            IF ( albedo_surf(l) < 0.0_wp )  THEN
-                albedo_surf(l) = surface_params(ialbedo, ip)
-            ENDIF
-            
-!--         emissivity of the wall
-            emiss_surf(l) = surface_params(iemiss, ip)
-            
-!--         heat conductivity Î»S between air and wall ( W mâ2 Kâ1 )
-            lambda_surf(l) = surface_params(ilambdas, ip)
-            
-!--         roughness relative to concrete
-            roughness_wall(l) = surface_params(irough, ip)
-            
-!--         Surface skin layer heat capacity (J mâ2 Kâ1 )
-            c_surface(l) = surface_params(icsurf, ip)
-            
-!--         wall material parameters:
-            
-!--         thickness of the wall (m)
-!--         missing values are replaced by default value for category
-            IF ( thickness_wall(l) <= 0.001_wp )  THEN
-                thickness_wall(l) = surface_params(ithick, ip)
-            ENDIF
-            
-!--         volumetric heat capacity rho*C of the wall ( J mâ3 Kâ1 )
-            rho_c_wall(:,l) = surface_params(irhoC, ip)
-            
-!--         thermal conductivity Î»H of the wall (W mâ1 Kâ1 )
-            lambda_h(:,l) = surface_params(ilambdah, ip)
-            
+                 ENDIF
+              ENDDO
+              IF ( ip == -99999 )  THEN
+!--              wall category not found
+                 WRITE (message_string, "(A,I5,A,3I5)") 'wall category ', it,  &
+                                        ' not found  for i,j,k=', iw,jw,kw
+                 CALL message( 'usm_read_urban_surface', 'PA0506', 1, 2, 0, 6, 0 )
+              ENDIF
+!
+!--           Albedo
+              IF ( surf_usm_v(l)%albedo_surf(m) < 0.0_wp )  THEN
+                 surf_usm_v(l)%albedo_surf(m) = surface_params(ialbedo,ip)
+              ENDIF
+!
+!--           emissivity of the wall
+              surf_usm_v(l)%emiss_surf(m) = surface_params(iemiss,ip)
+!            
+!--           heat conductivity Î»S between air and wall ( W mâ2 Kâ1 )
+              surf_usm_v(l)%lambda_surf(m) = surface_params(ilambdas,ip)
+!            
+!--           roughness relative to concrete
+              surf_usm_v(l)%roughness_wall(m) = surface_params(irough,ip)
+!            
+!--           Surface skin layer heat capacity (J mâ2 Kâ1 )
+              surf_usm_v(l)%c_surface(m) = surface_params(icsurf,ip)
+!            
+!--           wall material parameters:
+!--           thickness of the wall (m)
+!--           missing values are replaced by default value for category
+              IF ( surf_usm_v(l)%thickness_wall(m) <= 0.001_wp )  THEN
+                   surf_usm_v(l)%thickness_wall(m) = surface_params(ithick,ip)
+              ENDIF
+!            
+!--           volumetric heat capacity rho*C of the wall ( J mâ3 Kâ1 )
+              surf_usm_v(l)%rho_c_wall(:,m) = surface_params(irhoC,ip)
+!            
+!--           thermal conductivity Î»H of the wall (W mâ1 Kâ1 )
+              surf_usm_v(l)%lambda_h(:,m) = surface_params(ilambdah,ip)
+
+           ENDDO
         ENDDO
 
@@ -3900,5 +4715,5 @@
         IMPLICIT NONE
 
-        INTEGER(iwp)                          :: i, j, k, l, d      !< running indices
+        INTEGER(iwp)                          :: i, j, k, l, d, m   !< running indices
         
         REAL(wp)                              :: pt1                !< temperature at first grid box adjacent to surface
@@ -3924,188 +4739,277 @@
         
         exn(:) = (hyp(nzub:nzut) / 100000.0_wp )**0.286_wp          !< Exner function
+!        
+!--     First, treat horizontal surface elements
+
+        DO  m = 1, surf_usm_h%ns
+!
+!--        Get indices of respective grid point
+           i = surf_usm_h%i(m)
+           j = surf_usm_h%j(m)
+           k = surf_usm_h%k(m)
+!
+!--        TODO - how to calculate lambda_surface for horizontal surfaces
+!--        (lambda_surface is set according to stratification in land surface model)
+!--        MS: ???
+           IF ( surf_usm_h%ol(m) >= 0.0_wp )  THEN
+              lambda_surface = surf_usm_h%lambda_surf(m)
+           ELSE
+              lambda_surface = surf_usm_h%lambda_surf(m)
+           ENDIF
             
-!--    
-        DO l = startenergy, endenergy
-!--         Calculate frequently used parameters
-            d = surfl(id,l)
-            k = surfl(iz,l)
-            j = surfl(iy,l)
-            i = surfl(ix,l)
-
-!--         TODO - how to calculate lambda_surface for horizontal surfaces
-!--         (lambda_surface is set according to stratification in land surface model)
-            IF ( ol(j,i) >= 0.0_wp )  THEN
-                lambda_surface = lambda_surf(l)
-            ELSE
-                lambda_surface = lambda_surf(l)
-            ENDIF
+           pt1  = pt(k,j,i)
+!
+!--        calculate rho * cp coefficient at surface layer
+           rho_cp  = cp * hyp(k) / ( r_d * pt1 * exn(k) )
+!
+!--        Calculate aerodyamic resistance. 
+!--        Calculation for horizontal surfaces follows LSM formulation
+!--        pt, us, ts are not available for the prognostic time step,
+!--        data from the last time step is used here.
+               
+           r_a = ( pt1 - t_surf_h(m) / exn(k) ) /                              &
+                 ( surf_usm_h%ts(m) * surf_usm_h%us(m) + 1.0E-10_wp )
+                
+!--        make sure that the resistance does not drop to zero
+           IF ( ABS(r_a) < 1.0E-10_wp )  r_a = 1.0E-10_wp
+                
+!--        the parameterization is developed originally for larger scales
+!--        (compare with remark in TUF-3D)
+!--        our first experiences show that the parameterization underestimates
+!--        r_a in meter resolution.
+!--        temporary solution - multiplication by magic constant :-(.
+           r_a = r_a * ra_horiz_coef
+                
+!--        factor for shf_eb
+           f_shf  = rho_cp / r_a
+        
+!--        add LW up so that it can be removed in prognostic equation
+           surf_usm_h%rad_net_l(m) = surf_usm_h%rad_in_sw(m)  -                &
+                                     surf_usm_h%rad_out_sw(m) +                &
+                                     surf_usm_h%rad_in_lw(m)  -                &
+                                     surf_usm_h%rad_out_lw(m)
+
+!--        numerator of the prognostic equation
+           coef_1 = surf_usm_h%rad_net_l(m) +                                  & 
+                   ( 3.0_wp + 1.0_wp ) * surf_usm_h%emiss_surf(m) * sigma_sb * &
+                                       t_surf_h(m) ** 4 +                      &  
+                                       f_shf * pt1 +                           &
+                                       lambda_surface * t_wall_h(nzb_wall,m)
+
+!--        denominator of the prognostic equation
+           coef_2 = 4.0_wp * surf_usm_h%emiss_surf(m) * sigma_sb *            &
+                             t_surf_h(m) ** 3                                 &
+                           + lambda_surface + f_shf / exn(k)
+
+!--        implicit solution when the surface layer has no heat capacity,
+!--        otherwise use RK3 scheme.
+           t_surf_h_p(m) = ( coef_1 * dt_3d * tsc(2) +                        &
+                             surf_usm_h%c_surface(m) * t_surf_h(m) ) /        & 
+                           ( surf_usm_h%c_surface(m) + coef_2 * dt_3d * tsc(2) ) 
+
+!--        add RK3 term
+           t_surf_h_p(m) = t_surf_h_p(m) + dt_3d * tsc(3) *                   &
+                           surf_usm_h%tt_surface_m(m)
             
-            pt1  = pt(k,j,i)
-
-!--         calculate rho * cp coefficient at surface layer
-            rho_cp  = cp * hyp(k) / ( r_d * pt1 * exn(k) )
-
-!--         calculate aerodyamic resistance. 
-            IF ( d == iroof )  THEN
-!--             calculation for horizontal surfaces follows LSM formulation
-!--             pt, us, ts are not available for the prognostic time step,
-!--             data from the last time step is used here.
+!--        calculate true tendency
+           stend = ( t_surf_h_p(m) - t_surf_h(m) - dt_3d * tsc(3) *           &
+                     surf_usm_h%tt_surface_m(m)) / ( dt_3d  * tsc(2) )
+
+!--        calculate t_surf tendencies for the next Runge-Kutta step
+           IF ( timestep_scheme(1:5) == 'runge' )  THEN
+              IF ( intermediate_timestep_count == 1 )  THEN
+                 surf_usm_h%tt_surface_m(m) = stend
+              ELSEIF ( intermediate_timestep_count <                          &
+                        intermediate_timestep_count_max )  THEN
+                 surf_usm_h%tt_surface_m(m) = -9.5625_wp * stend +            &
+                                     5.3125_wp * surf_usm_h%tt_surface_m(m)
+              ENDIF
+           ENDIF
+
+!--        in case of fast changes in the skin temperature, it is required to
+!--        update the radiative fluxes in order to keep the solution stable
+           IF ( ABS( t_surf_h_p(m) - t_surf_h(m) ) > 1.0_wp )  THEN
+              force_radiation_call_l = .TRUE.
+           ENDIF
+!           
+!--        for horizontal surfaces is pt(nzb_s_inner(j,i),j,i) = pt_surf.
+!--        there is no equivalent surface gridpoint for vertical surfaces.
+!--        pt(k,j,i) is calculated for all directions in diffusion_s
+!--        using surface and wall heat fluxes
+           pt(k-1,j,i) = t_surf_h_p(m) / exn(k)  ! not for vertical surfaces
+
+!--        calculate fluxes
+!--        rad_net_l is never used!           
+           surf_usm_h%rad_net_l(m) = surf_usm_h%rad_net_l(m) +                &
+                                     3.0_wp * sigma_sb *                      &
+                                     t_surf_h(m)**4 - 4.0_wp * sigma_sb *     &
+                                     t_surf_h(m)**3 * t_surf_h_p(m)
+           surf_usm_h%wghf_eb(m)   = lambda_surface *                         &
+                                      ( t_surf_h_p(m) - t_wall_h(nzb_wall,m) )
+!
+!--        ground/wall/roof surface heat flux
+           surf_usm_h%wshf_eb(m)   = - f_shf  * ( pt1 - t_surf_h_p(m) )
+!           
+!--        store kinematic surface heat fluxes for utilization in other processes
+!--        diffusion_s, surface_layer_fluxes,...
+           surf_usm_h%shf(m) = surf_usm_h%wshf_eb(m) / rho_cp
+
+       ENDDO
+!
+!--    Now, treat vertical surface elements
+       DO  l = 0, 3
+          DO  m = 1, surf_usm_v(l)%ns
+!
+!--          Get indices of respective grid point
+             i = surf_usm_v(l)%i(m)
+             j = surf_usm_v(l)%j(m)
+             k = surf_usm_v(l)%k(m)
+!
+!--          TODO - how to calculate lambda_surface for horizontal (??? do you mean verical ???) surfaces
+!--          (lambda_surface is set according to stratification in land surface model).
+!--          Please note, for vertical surfaces no ol is defined, since 
+!--          stratification is not considered in this case.
+             lambda_surface = surf_usm_v(l)%lambda_surf(m)
+            
+             pt1  = pt(k,j,i)
+!
+!--          calculate rho * cp coefficient at surface layer
+             rho_cp  = cp * hyp(k) / ( r_d * pt1 * exn(k) )
+
+!--          Calculation of r_a for vertical surfaces
+!--
+!--          heat transfer coefficient for forced convection along vertical walls
+!--          follows formulation in TUF3d model (Krayenhoff & Voogt, 2006)
+!--            
+!--          H = httc (Tsfc - Tair)
+!--          httc = rw * (11.8 + 4.2 * Ueff) - 4.0
+!--            
+!--                rw: wall patch roughness relative to 1.0 for concrete
+!--                Ueff: effective wind speed
+!--                - 4.0 is a reduction of Rowley et al (1930) formulation based on
+!--                Cole and Sturrock (1977)
+!--           
+!--                Ucan: Canyon wind speed
+!--                wstar: convective velocity
+!--                Qs: surface heat flux
+!--                zH: height of the convective layer
+!--                wstar = (g/Tcan*Qs*zH)**(1./3.)
                 
-                r_a = (pt1 - t_surf(l)/exn(k)) / (ts(j,i) * us(j,i) + 1.0E-10_wp)
+!--          Effective velocity components must always 
+!--          be defined at scalar grid point. The wall normal component is 
+!--          obtained by simple linear interpolation. ( An alternative would
+!--          be an logarithmic interpolation. )
+             u1 = ( u(k,j,i) + u(k,j,i+1) ) * 0.5_wp
+             v1 = ( v(k,j,i) + v(k,j+1,i) ) * 0.5_wp
+             w1 = ( w(k,j,i) + w(k-1,j,i) ) * 0.5_wp
                 
-!--             make sure that the resistance does not drop to zero
-                IF ( ABS(r_a) < 1.0E-10_wp )  r_a = 1.0E-10_wp
-                
-!--             the parameterization is developed originally for larger scales
-!--             (compare with remark in TUF-3D)
-!--             our first experiences show that the parameterization underestimates
-!--             r_a in meter resolution.
-!--             temporary solution - multiplication by magic constant :-(.
-                r_a = r_a * ra_horiz_coef
-                
-!--             factor for shf_eb
-                f_shf  = rho_cp / r_a
-            ELSE
-!--             calculation of r_a for vertical surfaces
-!--
-!--             heat transfer coefficient for forced convection along vertical walls
-!--             follows formulation in TUF3d model (Krayenhoff & Voogt, 2006)
-!--            
-!--             H = httc (Tsfc - Tair)
-!--             httc = rw * (11.8 + 4.2 * Ueff) - 4.0
-!--            
-!--                   rw: wall patch roughness relative to 1.0 for concrete
-!--                   Ueff: effective wind speed
-!--                   - 4.0 is a reduction of Rowley et al (1930) formulation based on
-!--                   Cole and Sturrock (1977)
-!--            
-!--                   Ucan: Canyon wind speed
-!--                   wstar: convective velocity
-!--                   Qs: surface heat flux
-!--                   zH: height of the convective layer
-!--                   wstar = (g/Tcan*Qs*zH)**(1./3.)
-                
-!--             staggered grid needs to be taken into consideration
-                IF ( d == inorth )  THEN
-                    u1 = (u(k,j,i)+u(k,j,i+1))*0.5_wp
-                    v1 = v(k,j+1,i)
-                ELSE IF ( d == isouth )  THEN
-                    u1 = (u(k,j,i)+u(k,j,i+1))*0.5_wp
-                    v1 = v(k,j,i)
-                ELSE IF ( d == ieast )  THEN
-                    u1 = u(k,j,i+1)
-                    v1 = (v(k,j,i)+v(k,j+1,i))*0.5_wp
-                ELSE IF ( d == iwest )  THEN
-                    u1 = u(k,j,i)
-                    v1 = (v(k,j,i)+v(k,j+1,i))*0.5_wp
-                ELSE
-                    STOP
-                ENDIF
-                w1 = (w(k,j,i)+w(k-1,j,i))*0.5_wp
-                
-                Ueff = SQRT(u1**2 + v1**2 + w1**2)
-                httc = roughness_wall(l) * (11.8 + 4.2 * Ueff) - 4.0
-                f_shf  = httc
-            ENDIF
-        
-!--         add LW up so that it can be removed in prognostic equation
-            rad_net_l(l) = surfinsw(l) - surfoutsw(l) + surfinlw(l) - surfoutlw(l)
-
-!--         numerator of the prognostic equation
-            coef_1 = rad_net_l(l) +    &    ! coef +1 corresponds to -lwout included in calculation of radnet_l
-                     (3.0_wp+1.0_wp) * emiss_surf(l) * sigma_sb * t_surf(l) ** 4 +      &  
-                     f_shf  * pt1 +                                                     &
-                     lambda_surface * t_wall(nzb_wall,l)
-
-!--         denominator of the prognostic equation
-            coef_2 = 4.0_wp * emiss_surf(l) * sigma_sb * t_surf(l) ** 3                 &
-                         + lambda_surface + f_shf / exn(k)
-
-!--         implicit solution when the surface layer has no heat capacity,
-!--         otherwise use RK3 scheme.
-            t_surf_p(l) = ( coef_1 * dt_3d * tsc(2) + c_surface(l) * t_surf(l) ) /      & 
-                              ( c_surface(l) + coef_2 * dt_3d * tsc(2) ) 
-
-!--         add RK3 term
-            t_surf_p(l) = t_surf_p(l) + dt_3d * tsc(3) * tt_surface_m(l)
+             Ueff   = SQRT( u1**2 + v1**2 + w1**2 )
+             httc   = surf_usm_v(l)%roughness_wall(m) *                       &
+                       ( 11.8_wp + 4.2_wp * Ueff ) - 4.0_wp
+             f_shf  = httc
+
+!--          add LW up so that it can be removed in prognostic equation
+             surf_usm_v(l)%rad_net_l(m) = surf_usm_v(l)%rad_in_sw(m)  -        &
+                                          surf_usm_v(l)%rad_out_sw(m) +        &
+                                          surf_usm_v(l)%rad_in_lw(m)  -        &
+                                          surf_usm_v(l)%rad_out_lw(m)
+
+!--           numerator of the prognostic equation
+              coef_1 = surf_usm_v(l)%rad_net_l(m) +                            & ! coef +1 corresponds to -lwout included in calculation of radnet_l
+               ( 3.0_wp + 1.0_wp ) * surf_usm_v(l)%emiss_surf(m) * sigma_sb *  &
+                                     t_surf_v(l)%t(m) ** 4 +                   &  
+                                     f_shf * pt1 +                             &
+                                     lambda_surface * t_wall_v(l)%t(nzb_wall,m)
+
+!--           denominator of the prognostic equation
+              coef_2 = 4.0_wp * surf_usm_v(l)%emiss_surf(m) * sigma_sb *       &
+                                t_surf_v(l)%t(m) ** 3                          &
+                              + lambda_surface + f_shf / exn(k)
+
+!--           implicit solution when the surface layer has no heat capacity,
+!--           otherwise use RK3 scheme.
+              t_surf_v_p(l)%t(m) = ( coef_1 * dt_3d * tsc(2) +                 &
+                             surf_usm_v(l)%c_surface(m) * t_surf_v(l)%t(m) ) / & 
+                           ( surf_usm_v(l)%c_surface(m) + coef_2 * dt_3d * tsc(2) ) 
+
+!--           add RK3 term
+              t_surf_v_p(l)%t(m) = t_surf_v_p(l)%t(m) + dt_3d * tsc(3) *       &
+                                surf_usm_v(l)%tt_surface_m(m)
             
-!--         calculate true tendency
-            stend = (t_surf_p(l) - t_surf(l) - dt_3d * tsc(3) * tt_surface_m(l)) / (dt_3d  * tsc(2))
-
-!--         calculate t_surf tendencies for the next Runge-Kutta step
-            IF ( timestep_scheme(1:5) == 'runge' )  THEN
-                IF ( intermediate_timestep_count == 1 )  THEN
-                    tt_surface_m(l) = stend
-                ELSEIF ( intermediate_timestep_count <                                  &
-                         intermediate_timestep_count_max )  THEN
-                    tt_surface_m(l) = -9.5625_wp * stend + 5.3125_wp                    &
-                                       * tt_surface_m(l)
-                ENDIF
-            ENDIF
-
-!--         in case of fast changes in the skin temperature, it is required to
-!--         update the radiative fluxes in order to keep the solution stable
-            IF ( ABS( t_surf_p(l) - t_surf(l) ) > 1.0_wp )  THEN
-               force_radiation_call_l = .TRUE.
-            ENDIF
-            
-!--         for horizontal surfaces is pt(nzb_s_inner(j,i),j,i) = pt_surf.
-!--         there is no equivalent surface gridpoint for vertical surfaces.
-!--         pt(k,j,i) is calculated for all directions in diffusion_s
-!--         using surface and wall heat fluxes
-            IF ( d == iroof )  THEN
-               pt(nzb_s_inner(j,i),j,i) = t_surf_p(l) / exn(k)
-            ENDIF
-
-!--         calculate fluxes
-!--         rad_net_l is never used!           
-            rad_net_l(l)     = rad_net_l(l) + 3.0_wp * sigma_sb                         &
-                                * t_surf(l)**4 - 4.0_wp * sigma_sb                      &
-                                * t_surf(l)**3 * t_surf_p(l)
-            wghf_eb(l)       = lambda_surface * (t_surf_p(l) - t_wall(nzb_wall,l))
-
-!--         ground/wall/roof surface heat flux
-            wshf_eb(l)  = - f_shf  * ( pt1 - t_surf_p(l) )
-            
-!--         store kinematic surface heat fluxes for utilization in other processes
-!--         diffusion_s, surface_layer_fluxes,...
-            IF ( d == iroof )  THEN
-!--             shf is used in diffusion_s and also
-!--             for calculation of surface layer fluxes
-!--             update for horizontal surfaces
-                shf(j,i) = wshf_eb(l) / rho_cp
-            ELSE
-!--             surface heat flux for vertical surfaces
-!--             used in diffusion_s
-                wshf(l) = wshf_eb(l) / rho_cp
-            ENDIF
+!--           calculate true tendency
+              stend = ( t_surf_v_p(l)%t(m) - t_surf_v(l)%t(m) - dt_3d * tsc(3) *&
+                        surf_usm_v(l)%tt_surface_m(m) ) / ( dt_3d  * tsc(2) )
+
+!--           calculate t_surf tendencies for the next Runge-Kutta step
+              IF ( timestep_scheme(1:5) == 'runge' )  THEN
+                 IF ( intermediate_timestep_count == 1 )  THEN
+                    surf_usm_v(l)%tt_surface_m(m) = stend
+                 ELSEIF ( intermediate_timestep_count <                        &
+                          intermediate_timestep_count_max )  THEN
+                    surf_usm_v(l)%tt_surface_m(m) = -9.5625_wp * stend +       &
+                                     5.3125_wp * surf_usm_h%tt_surface_m(m)
+                 ENDIF
+              ENDIF
+
+!--           in case of fast changes in the skin temperature, it is required to
+!--           update the radiative fluxes in order to keep the solution stable
+              IF ( ABS( t_surf_v_p(l)%t(m) - t_surf_v(l)%t(m) ) > 1.0_wp )  THEN
+                 force_radiation_call_l = .TRUE.
+              ENDIF
+
+!--           calculate fluxes
+!--           rad_net_l is never used!           
+              surf_usm_v(l)%rad_net_l(m) = surf_usm_v(l)%rad_net_l(m) +        &
+                                     3.0_wp * sigma_sb *                       &
+                                     t_surf_v(l)%t(m)**4 - 4.0_wp * sigma_sb * &
+                                     t_surf_v(l)%t(m)**3 * t_surf_v_p(l)%t(m)
+
+              surf_usm_v(l)%wghf_eb(m)   = lambda_surface *                    &
+                                     ( t_surf_v_p(l)%t(m) - t_wall_v(l)%t(nzb_wall,m) )
+
+!--           ground/wall/roof surface heat flux
+              surf_usm_v(l)%wshf_eb(m)   = - f_shf  * ( pt1 - t_surf_v_p(l)%t(m) )
+
+!           
+!--           store kinematic surface heat fluxes for utilization in other processes
+!--           diffusion_s, surface_layer_fluxes,...
+              surf_usm_v(l)%shf(m) = surf_usm_v(l)%wshf_eb(m) / rho_cp
+
+           ENDDO
 
         ENDDO
-        
-        
+!
+!--     Add-up anthropogenic heat, for now only at upward-facing surfaces
         IF ( usm_anthropogenic_heat  .AND.  &
              intermediate_timestep_count == intermediate_timestep_count_max )  THEN
-!--         application of the additional anthropogenic heat sources
-!--         we considere the traffic for now so all heat is absorbed
-!--         to the first layer, generalization would be worth
+!--        application of the additional anthropogenic heat sources
+!--        we considere the traffic for now so all heat is absorbed
+!--        to the first layer, generalization would be worth. 
             
-!--         calculation of actual profile coefficient
-!--         ??? check time_since_reference_point ???
-            dtime = mod(simulated_time + time_utc_init, 24.0_wp*3600.0_wp)
-            dhour = INT(dtime/3600.0_wp)
-!--         linear interpolation of coeficient
-            acoef = (REAL(dhour+1,wp)-dtime/3600.0_wp)*aheatprof(dhour) + (dtime/3600.0_wp-REAL(dhour,wp))*aheatprof(dhour+1)
-            DO i = nxl, nxr
-                DO j = nys, nyn
-                    IF ( aheat(j,i) > 0.0_wp )  THEN
-!--                     TODO the increase of pt in box i,j,nzb_s_inner(j,i)+1 in time dt_3d 
-!--                     given to anthropogenic heat aheat*acoef (W*m-2)
-!--                     k = nzb_s_inner(j,i)+1
-!--                     pt(k,j,i) = pt(k,j,i) + aheat(j,i)*acoef*dt_3d/(exn(k)*rho_cp*dz)
-!--                     Instead of this, we can adjust shf in case AH only at surface
-                        shf(j,i) = shf(j,i) + aheat(j,i)*acoef * ddx * ddy / rho_cp
-                    ENDIF
-                ENDDO
-            ENDDO
+!--        calculation of actual profile coefficient
+!--        ??? check time_since_reference_point ???
+           dtime = mod(simulated_time + time_utc_init, 24.0_wp*3600.0_wp)
+           dhour = INT(dtime/3600.0_wp)
+!--        linear interpolation of coeficient
+           acoef = (REAL(dhour+1,wp)-dtime/3600.0_wp)*aheatprof(dhour) + (dtime/3600.0_wp-REAL(dhour,wp))*aheatprof(dhour+1)
+
+           DO m = 1, surf_usm_h%ns
+!
+!--           Get indices of respective grid point
+              i = surf_usm_h%i(m)
+              j = surf_usm_h%j(m)
+              k = surf_usm_h%k(m)
+
+              IF ( aheat(j,i) > 0.0_wp )  THEN
+!--              TODO the increase of pt in box i,j,nzb_s_inner(j,i)+1 in time dt_3d 
+!--              given to anthropogenic heat aheat*acoef (W*m-2)
+!--              k = nzb_s_inner(j,i)+1
+!--              pt(k,j,i) = pt(k,j,i) + aheat(j,i)*acoef*dt_3d/(exn(k)*rho_cp*dz)
+!--              Instead of this, we can adjust shf in case AH only at surface
+                 surf_usm_h%shf(m) = surf_usm_h%shf(m) +                       &
+                                   aheat(j,i) * acoef * ddx * ddy / rho_cp
+              ENDIF
+           ENDDO
+
         ENDIF
         
@@ -4113,16 +5017,15 @@
 !--     get the borders from neighbours
         CALL exchange_horiz( pt, nbgp )
-        CALL exchange_horiz_2d( shf )
-
-
-!--    calculation of force_radiation_call:
-!--    Make logical OR for all processes.
-!--    Force radiation call if at least one processor forces it.
-       IF ( intermediate_timestep_count == intermediate_timestep_count_max-1 )          &
-       THEN
+
+
+!--     calculation of force_radiation_call:
+!--     Make logical OR for all processes.
+!--     Force radiation call if at least one processor forces it.
+        IF ( intermediate_timestep_count == intermediate_timestep_count_max-1 )&
+        THEN
 #if defined( __parallel )
           IF ( collective_wait )  CALL MPI_BARRIER( comm2d, ierr )
-              CALL mpi_allreduce( force_radiation_call_l, force_radiation_call,         &
-                                  1, MPI_LOGICAL, MPI_LOR, comm2d, ierr )
+          CALL MPI_ALLREDUCE( force_radiation_call_l, force_radiation_call,    &
+                              1, MPI_LOGICAL, MPI_LOR, comm2d, ierr )
 #else
           force_radiation_call = force_radiation_call_l
@@ -4130,5 +5033,4 @@
           force_radiation_call_l = .FALSE.
        ENDIF
-
 
     END SUBROUTINE usm_surface_energy_balance
@@ -4149,77 +5051,32 @@
       
 #if defined( __nopointer )
-       t_surf    = t_surf_p
-       t_wall    = t_wall_p
+       t_surf_h    = t_surf_h_p
+       t_wall_h    = t_wall_h_p
+       t_surf_v    = t_surf_v_p
+       t_wall_v    = t_wall_v_p
 #else
        SELECT CASE ( mod_count )
           CASE ( 0 )
-             t_surf  => t_surf_1; t_surf_p  => t_surf_2
-             t_wall     => t_wall_1;    t_wall_p     => t_wall_2
+!
+!--          Horizontal surfaces
+             t_surf_h  => t_surf_h_1; t_surf_h_p  => t_surf_h_2
+             t_wall_h     => t_wall_h_1;    t_wall_h_p     => t_wall_h_2
+!
+!--          Vertical surfaces
+             t_surf_v  => t_surf_v_1; t_surf_v_p  => t_surf_v_2
+             t_wall_v     => t_wall_v_1;    t_wall_v_p     => t_wall_v_2
           CASE ( 1 )
-             t_surf  => t_surf_2; t_surf_p  => t_surf_1
-             t_wall     => t_wall_2;    t_wall_p     => t_wall_1
+!
+!--          Horizontal surfaces
+             t_surf_h  => t_surf_h_2; t_surf_h_p  => t_surf_h_1
+             t_wall_h     => t_wall_h_2;    t_wall_h_p     => t_wall_h_1
+!
+!--          Vertical surfaces
+             t_surf_v  => t_surf_v_2; t_surf_v_p  => t_surf_v_1
+             t_wall_v     => t_wall_v_2;    t_wall_v_p     => t_wall_v_1
        END SELECT
 #endif
         
     END SUBROUTINE usm_swap_timelevel
-
-
-!------------------------------------------------------------------------------!
-! Description:
-! ------------
-!
-!> This function applies the kinematic wall heat fluxes
-!> for walls in four directions for all gridboxes in urban layer.
-!> It is called out from subroutine prognostic_equations.
-!> TODO Compare performance with cycle runnig l=startwall,endwall...
-!------------------------------------------------------------------------------!
-    SUBROUTINE usm_wall_heat_flux
-    
-        IMPLICIT NONE
-
-        INTEGER(iwp)              ::  i,j,k,d,l             !< running indices
-        
-        DO l = startenergy, endenergy
-            j = surfl(iy,l)
-            i = surfl(ix,l)
-            k = surfl(iz,l)
-            d = surfl(id,l)
-            tend(k,j,i) = tend(k,j,i) + wshf(l) * ddxy2(d)
-        ENDDO
-
-    END SUBROUTINE usm_wall_heat_flux
- 
- 
-!------------------------------------------------------------------------------!
-! Description:
-! ------------
-!
-!> This function applies the kinematic wall heat fluxes
-!> for walls in four directions around the gridbox i,j.
-!> It is called out from subroutine prognostic_equations.
-!------------------------------------------------------------------------------!
-    SUBROUTINE usm_wall_heat_flux_ij(i,j) 
-    
-        IMPLICIT NONE
-
-        INTEGER(iwp), INTENT(in)  ::  i,j                   !< indices of grid box
-        INTEGER(iwp)              ::  ii,jj,k,d,l
-        
-        DO l = startenergy, endenergy
-            jj = surfl(iy,l)
-            ii = surfl(ix,l)
-            IF ( ii == i  .AND.  jj == j ) THEN
-               k = surfl(iz,l)
-               IF ( k >=  nzb_s_inner(j,i)+1  .AND.  k <=  nzb_s_outer(j,i) ) THEN
-                  d = surfl(id,l)
-                  IF ( d >= 1 .and. d <= 4 )   THEN
-                     tend(k,j,i) = tend(k,j,i) + wshf(l) * ddxy2(d)
-                  ENDIF
-               ENDIF
-            ENDIF
-        ENDDO
-
-    END SUBROUTINE usm_wall_heat_flux_ij
- 
 
 !------------------------------------------------------------------------------!
@@ -4242,15 +5099,64 @@
        DO  i = 0, io_blocks-1
           IF ( i == io_group )  THEN
-             WRITE ( 14 )  't_surf                        '
+
+             WRITE ( 14 )  't_surf_h                      '
 #if defined( __nopointer )             
-             WRITE ( 14 )  t_surf
+             WRITE ( 14 )  t_surf_h
 #else
-             WRITE ( 14 )  t_surf_1
+             WRITE ( 14 )  t_surf_h_1
 #endif
-             WRITE ( 14 )  't_wall                        '
+             WRITE ( 14 )  't_surf_v(0)                   '
 #if defined( __nopointer )             
-             WRITE ( 14 )  t_wall
+             WRITE ( 14 )  t_surf_v(0)%t
 #else
-             WRITE ( 14 )  t_wall_1
+             WRITE ( 14 )  t_surf_v_1(0)%t
+#endif
+             WRITE ( 14 )  't_surf_v(1)                   '
+#if defined( __nopointer )             
+             WRITE ( 14 )  t_surf_v(1)%t
+#else
+             WRITE ( 14 )  t_surf_v_1(1)%t
+#endif
+             WRITE ( 14 )  't_surf_v(2)                   '
+#if defined( __nopointer )             
+             WRITE ( 14 )  t_surf_v(2)%t
+#else
+             WRITE ( 14 )  t_surf_v_1(2)%t
+#endif
+             WRITE ( 14 )  't_surf_v(3)                   '
+#if defined( __nopointer )             
+             WRITE ( 14 )  t_surf_v(3)%t
+#else
+             WRITE ( 14 )  t_surf_v_1(3)%t
+#endif
+             WRITE ( 14 )  't_wall_h                      '
+#if defined( __nopointer )             
+             WRITE ( 14 )  t_wall_h
+#else
+             WRITE ( 14 )  t_wall_h_1
+#endif
+             WRITE ( 14 )  't_wall_v(0)                   '
+#if defined( __nopointer )             
+             WRITE ( 14 )  t_wall_v(0)%t
+#else
+             WRITE ( 14 )  t_wall_v_1(0)%t
+#endif
+             WRITE ( 14 )  't_wall_v(1)                   '
+#if defined( __nopointer )             
+             WRITE ( 14 )  t_wall_v(1)%t
+#else
+             WRITE ( 14 )  t_wall_v_1(1)%t
+#endif
+             WRITE ( 14 )  't_wall_v(2)                   '
+#if defined( __nopointer )             
+             WRITE ( 14 )  t_wall_v(2)%t
+#else
+             WRITE ( 14 )  t_wall_v_1(2)%t
+#endif
+             WRITE ( 14 )  't_wall_v(3)                   '
+#if defined( __nopointer )             
+             WRITE ( 14 )  t_wall_v(3)%t
+#else
+             WRITE ( 14 )  t_wall_v_1(3)%t
 #endif
              WRITE ( 14 )  '*** end usm ***               '
Index: /palm/trunk/SOURCE/user_data_output_2d.f90
===================================================================
--- /palm/trunk/SOURCE/user_data_output_2d.f90	(revision 2231)
+++ /palm/trunk/SOURCE/user_data_output_2d.f90	(revision 2232)
@@ -20,5 +20,6 @@
 ! Current revisions:
 ! -----------------
-! 
+! Example code added for accessing output quantities stored on surface-data
+! types
 ! 
 ! Former revisions:
@@ -61,4 +62,6 @@
     USE kinds
 
+    USE surface_mod
+
     USE user
 
@@ -68,8 +71,9 @@
     CHARACTER (LEN=*) ::  variable !< 
 
-    INTEGER(iwp) ::  av !< 
-    INTEGER(iwp) ::  i  !< 
-    INTEGER(iwp) ::  j  !< 
-    INTEGER(iwp) ::  k  !< 
+    INTEGER(iwp) ::  av     !< flag to control data output of instantaneous or time-averaged data
+    INTEGER(iwp) ::  i      !< grid index along x-direction
+    INTEGER(iwp) ::  j      !< grid index along y-direction
+    INTEGER(iwp) ::  k      !< grid index along z-direction
+    INTEGER(iwp) ::  m      !< running index surface elements
     INTEGER(iwp) ::  nzb_do !< lower limit of the domain (usually nzb)
     INTEGER(iwp) ::  nzt_do !< upper limit of the domain (usually nzt+1)
@@ -110,4 +114,37 @@
 !
 !          grid = 'zu'
+!
+!--    In case two-dimensional surface variables are outputted, the user
+!--    has to access related surface-type. Uncomment and extend following lines
+!--    appropriately (example output of vertical surface momentum flux of u-
+!--    component). Please note, surface elements can be distributed over 
+!--    several data type, depending on their respective surface properties.
+!       CASE ( 'usws_xy' )
+!          IF ( av == 0 )  THEN
+!
+!--           Horizontal default-type surfaces
+!             DO  m = 1, surf_def_h(0)%ns
+!                i = surf_def_h(0)%i(m)
+!                j = surf_def_h(0)%j(m)
+!                local_pf(i,j,1) = surf_def_h(0)%usws(m)
+!             ENDDO
+!
+!--           Horizontal natural-type surfaces
+!             DO  m = 1, surf_lsm_h%ns
+!                i = surf_lsm_h%i(m)
+!                j = surf_lsm_h%j(m)
+!                local_pf(i,j,1) = surf_lsm_h%usws(m)
+!             ENDDO
+!
+!--           Horizontal urban-type surfaces
+!             DO  m = 1, surf_usm_h%ns
+!                i = surf_usm_h%i(m)
+!                j = surf_usm_h%j(m)
+!                local_pf(i,j,1) = surf_usm_h%usws(m)
+!             ENDDO
+!          ENDIF
+!
+!          grid = 'zu'
+!--       
 
 
Index: /palm/trunk/SOURCE/user_init_3d_model.f90
===================================================================
--- /palm/trunk/SOURCE/user_init_3d_model.f90	(revision 2231)
+++ /palm/trunk/SOURCE/user_init_3d_model.f90	(revision 2232)
@@ -20,5 +20,5 @@
 ! Current revisions:
 ! -----------------
-! 
+! +surface_mod
 ! 
 ! Former revisions:
@@ -58,4 +58,6 @@
     
     USE kinds
+
+    USE surface_mod
     
     USE user
Index: /palm/trunk/SOURCE/user_init_grid.f90
===================================================================
--- /palm/trunk/SOURCE/user_init_grid.f90	(revision 2231)
+++ /palm/trunk/SOURCE/user_init_grid.f90	(revision 2232)
@@ -20,5 +20,6 @@
 ! Current revisions:
 ! -----------------
-! 
+! +Generic tunnel added
+! +Example of setting user-defined topography
 ! 
 ! Former revisions:
@@ -55,5 +56,5 @@
 !> Execution of user-defined grid initializing actions
 !------------------------------------------------------------------------------!
- SUBROUTINE user_init_grid( nzb_local )
+ SUBROUTINE user_init_grid( topo_3d )
  
 
@@ -68,5 +69,8 @@
     IMPLICIT NONE
 
-    INTEGER(iwp), DIMENSION(nysg:nyng,nxlg:nxrg) ::  nzb_local   !< 
+    INTEGER(iwp)                                           ::  k_topo      !< topography top index
+    INTEGER(iwp), DIMENSION(nzb:nzt+1,nysg:nyng,nxlg:nxrg) ::  topo_3d     !< 3D topography field
+
+    REAL(wp) ::  h_topo !< user-defined topography height
 
 !
@@ -78,5 +82,5 @@
     SELECT CASE ( TRIM( topography ) )
 
-       CASE ( 'flat', 'single_building', 'single_street_canyon' )
+       CASE ( 'flat', 'single_building', 'single_street_canyon', 'tunnel' )
 !
 !--       Not allowed here since these are the standard cases used in init_grid.
@@ -88,4 +92,21 @@
           message_string = 'topography "' // topography // '" not available yet'
           CALL message( 'user_init_grid', 'UI0005', 1, 2, 0, 6, 0 )
+!
+!--       The user is allowed to set surface-mounted as well as non-surface
+!--       mounted topography (e.g. overhanging structures). For both, use 
+!--       3D array topo_3d and set bit 0. The convention is: bit is zero inside 
+!--       topography, bit is 1 for atmospheric grid point. 
+!--       The following example shows how to prescribe sine-like topography 
+!--       along x-direction with amplitude of 10 * dz and wavelength 10 * dy.
+!           DO  i = nxlg, nxrg
+!              h_topo = 10.0_wp * dz * (SIN(3.14_wp*0.5_wp)*i*dx / ( 5.0_wp * dy ) )**2
+! 
+!              k_topo = MINLOC( ABS( zw - h_topo ), 1 ) - 1
+! 
+!              topo_3d(k_topo+1:nzt+1,:,i) =                                     &
+!                                          IBSET( topo_3d(k_topo+1:nzt+1,:,i), 0 ) 
+!           ENDDO 
+! 
+!           CALL exchange_horiz_int( topo_3d, nbgp )
 
        CASE DEFAULT
@@ -100,4 +121,6 @@
 
 
+
+
  END SUBROUTINE user_init_grid
 
Index: /palm/trunk/SOURCE/user_init_land_surface.f90
===================================================================
--- /palm/trunk/SOURCE/user_init_land_surface.f90	(revision 2231)
+++ /palm/trunk/SOURCE/user_init_land_surface.f90	(revision 2232)
@@ -20,5 +20,6 @@
 ! Current revisions:
 ! -----------------
-! 
+! Load surface_mod
+! Add simple example how to access surface data type
 ! 
 ! Former revisions:
@@ -60,15 +61,21 @@
     
     USE pegrid
-    
+
+    USE surface_mod    
+
     USE user
 
     IMPLICIT NONE
 
-    INTEGER(iwp) :: i   !< running index
-    INTEGER(iwp) :: j   !< running index
+    INTEGER(iwp) ::  i  !< grid index
+    INTEGER(iwp) ::  j  !< grid index
+    INTEGER(iwp) ::  m  !< running index on 1D wall-type grid
 
 !
-!-- Here the user-defined land surface initialization actions follow:
-
+!-- Here the user-defined land surface initialization actions follow.
+!-- Example: set roughness length at natural land-surface
+!     DO  m = 1, surf_lsm_h%ns
+!        surf_lsm_h%z0(m) = 0.1_wp
+!     ENDDO
 
 
Index: /palm/trunk/SOURCE/user_init_urban_surface.f90
===================================================================
--- /palm/trunk/SOURCE/user_init_urban_surface.f90	(revision 2231)
+++ /palm/trunk/SOURCE/user_init_urban_surface.f90	(revision 2232)
@@ -21,5 +21,6 @@
 ! Current revisions:
 ! -----------------
-! 
+! Load surface_mod
+! Add simple example how to access surface data type
 ! 
 ! Former revisions:
@@ -50,4 +51,6 @@
 
     USE urban_surface_mod
+
+    USE surface_mod    
     
     USE user
@@ -55,9 +58,14 @@
     IMPLICIT NONE
 
-    INTEGER(iwp) ::  i  !< running index
-    INTEGER(iwp) ::  j  !< running index
+    INTEGER(iwp) ::  i  !< grid index
+    INTEGER(iwp) ::  j  !< grid index
+    INTEGER(iwp) ::  m  !< running index on 1D wall-type grid
 
 !
-!-- Here the user-defined urban surface initialization actions follow:
+!-- Here the user-defined urban surface initialization actions follow.
+!-- Example: set roughness length at urban surface
+!     DO  m = 1, surf_usm_h%ns
+!        surf_usm_h%z0(m) = 0.1_wp
+!     ENDDO
 
 
Index: /palm/trunk/SOURCE/user_statistics.f90
===================================================================
--- /palm/trunk/SOURCE/user_statistics.f90	(revision 2231)
+++ /palm/trunk/SOURCE/user_statistics.f90	(revision 2232)
@@ -20,5 +20,5 @@
 ! Current revisions:
 ! -----------------
-! 
+! Ajdustments for new topography masking
 ! 
 ! Former revisions:
@@ -111,12 +111,14 @@
 !       DO  i = nxl, nxr
 !          DO  j = nys, nyn
-!             DO  k = nzb_s_inner(j,i)+1, nzt
+!             DO  k = nzb+1, nzt
 !!
 !!--             Sample on how to calculate the profile of the resolved-scale
 !!--             horizontal momentum flux u*v*
-!                sums_l(k,pr_palm+1,tn) = sums_l(k,pr_palm+1,tn) +               &
-!                      ( 0.5_wp * ( u(k,j,i) + u(k,j,i+1) ) - hom(k,1,1,sr) ) *     &
-!                      ( 0.5_wp * ( v(k,j,i) + v(k,j+1,i) ) - hom(k,1,2,sr) )       &
-!                                                 * rmask(j,i,sr)
+!                sums_l(k,pr_palm+1,tn) = sums_l(k,pr_palm+1,tn) +             &
+!                      ( 0.5_wp * ( u(k,j,i) + u(k,j,i+1) ) - hom(k,1,1,sr) ) *&
+!                      ( 0.5_wp * ( v(k,j,i) + v(k,j+1,i) ) - hom(k,1,2,sr) )  &
+!                                     * rmask(j,i,sr)                          &
+!                                     * MERGE( 1.0_wp, 0.0_wp,                 &
+!                                              BTEST( wall_flags_0(k,j,i), 0 ) )
 !!
 !!--             Further profiles can be defined and calculated by increasing
Index: lm/trunk/SOURCE/wall_fluxes.f90
===================================================================
--- /palm/trunk/SOURCE/wall_fluxes.f90	(revision 2231)
+++ 	(revision )
@@ -1,752 +1,0 @@
-!> @file wall_fluxes.f90
-!------------------------------------------------------------------------------!
-! This file is part of PALM.
-!
-! PALM is free software: you can redistribute it and/or modify it under the
-! terms of the GNU General Public License as published by the Free Software
-! Foundation, either version 3 of the License, or (at your option) any later
-! version.
-!
-! PALM is distributed in the hope that it will be useful, but WITHOUT ANY
-! WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
-! A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
-!
-! You should have received a copy of the GNU General Public License along with
-! PALM. If not, see <http://www.gnu.org/licenses/>.
-!
-! Copyright 1997-2017 Leibniz Universitaet Hannover
-!------------------------------------------------------------------------------!
-!
-! Current revisions:
-! -----------------
-! 
-! 
-! Former revisions:
-! -----------------
-! $Id$
-!
-! 2118 2017-01-17 16:38:49Z raasch
-! OpenACC versions of subroutines removed
-! 
-! 2000 2016-08-20 18:09:15Z knoop
-! Forced header and separation lines into 80 columns
-! 
-! 1873 2016-04-18 14:50:06Z maronga
-! Module renamed (removed _mod)
-! 
-! 
-! 1850 2016-04-08 13:29:27Z maronga
-! Module renamed
-! 
-! 
-! 1691 2015-10-26 16:17:44Z maronga
-! Renamed rif_min and rif_max with zeta_min and zeta_max, respectively.
-! 
-! 1682 2015-10-07 23:56:08Z knoop
-! Code annotations made doxygen readable 
-! 
-! 1374 2014-04-25 12:55:07Z raasch
-! pt removed from acc-present-list
-! 
-! 1353 2014-04-08 15:21:23Z heinze
-! REAL constants provided with KIND-attribute
-!
-! 1320 2014-03-20 08:40:49Z raasch
-! ONLY-attribute added to USE-statements,
-! kind-parameters added to all INTEGER and REAL declaration statements, 
-! kinds are defined in new module kinds, 
-! old module precision_kind is removed,
-! revision history before 2012 removed,
-! comment fields (!:) to be used for variable explanations added to
-! all variable declaration statements 
-!
-! 1257 2013-11-08 15:18:40Z raasch
-! openacc loop and loop vector clauses removed
-!
-! 1153 2013-05-10 14:33:08Z raasch
-! code adjustments of accelerator version required by PGI 12.3 / CUDA 5.0
-!
-! 1128 2013-04-12 06:19:32Z raasch
-! loop index bounds in accelerator version replaced by i_left, i_right, j_south,
-! j_north
-!
-! 1036 2012-10-22 13:43:42Z raasch
-! code put under GPL (PALM 3.9)
-!
-! 1015 2012-09-27 09:23:24Z raasch
-! accelerator version (*_acc) added
-!
-! Initial version (2007/03/07)
-!
-! Description:
-! ------------
-!> Calculates momentum fluxes at vertical walls assuming Monin-Obukhov
-!> similarity.
-!> Indices: usvs a=1, vsus b=1, wsvs c1=1, wsus c2=1 (other=0).
-!> The all-gridpoint version of wall_fluxes_e is not used so far, because
-!> it gives slightly different results from the ij-version for some unknown
-!> reason.
-!>
-!> @todo Rename rif to zeta throughout the routine
-!------------------------------------------------------------------------------!
- MODULE wall_fluxes_mod
- 
-    PRIVATE
-    PUBLIC wall_fluxes, wall_fluxes_e
-    
-    INTERFACE wall_fluxes
-       MODULE PROCEDURE wall_fluxes
-       MODULE PROCEDURE wall_fluxes_ij
-    END INTERFACE wall_fluxes
-    
-    INTERFACE wall_fluxes_e
-       MODULE PROCEDURE wall_fluxes_e
-       MODULE PROCEDURE wall_fluxes_e_ij
-    END INTERFACE wall_fluxes_e
- 
- CONTAINS
-
-!------------------------------------------------------------------------------!
-! Description:
-! ------------
-!> Call for all grid points
-!------------------------------------------------------------------------------!
-    SUBROUTINE wall_fluxes( wall_flux, a, b, c1, c2, nzb_uvw_inner,            &
-                            nzb_uvw_outer, wall )
-
-       USE arrays_3d,                                                          &
-           ONLY:  rif_wall, u, v, w, z0, pt
-       
-       USE control_parameters,                                                 &
-           ONLY:  g, kappa, zeta_max, zeta_min
-       
-       USE grid_variables,                                                     &
-           ONLY:  dx, dy
-       
-       USE indices,                                                            &
-           ONLY:  nxl, nxlg, nxr, nxrg, nyn, nyng, nys, nysg, nzb, nzt
-       
-       USE kinds
-       
-       USE statistics,                                                         &
-           ONLY:  hom
-
-       IMPLICIT NONE
-
-       INTEGER(iwp) ::  i            !< 
-       INTEGER(iwp) ::  j            !< 
-       INTEGER(iwp) ::  k            !< 
-       INTEGER(iwp) ::  wall_index   !< 
-
-       INTEGER(iwp),                                                           &
-          DIMENSION(nysg:nyng,nxlg:nxrg) ::                                    &
-             nzb_uvw_inner   !< 
-       INTEGER(iwp),                                                           &
-          DIMENSION(nysg:nyng,nxlg:nxrg) ::                                    &
-             nzb_uvw_outer   !< 
-       
-       REAL(wp) ::  a           !< 
-       REAL(wp) ::  b           !< 
-       REAL(wp) ::  c1          !< 
-       REAL(wp) ::  c2          !< 
-       REAL(wp) ::  h1          !< 
-       REAL(wp) ::  h2          !< 
-       REAL(wp) ::  zp          !< 
-       REAL(wp) ::  pts         !< 
-       REAL(wp) ::  pt_i        !< 
-       REAL(wp) ::  rifs        !< 
-       REAL(wp) ::  u_i         !< 
-       REAL(wp) ::  v_i         !< 
-       REAL(wp) ::  us_wall     !< 
-       REAL(wp) ::  vel_total   !< 
-       REAL(wp) ::  ws          !< 
-       REAL(wp) ::  wspts       !< 
-
-       REAL(wp),                                                               &
-          DIMENSION(nysg:nyng,nxlg:nxrg) ::                                    &
-             wall   !< 
-       
-       REAL(wp),                                                               &
-          DIMENSION(nzb:nzt+1,nys:nyn,nxl:nxr) ::                              &
-             wall_flux   !< 
-
-
-       zp         = 0.5_wp * ( (a+c1) * dy + (b+c2) * dx )
-       wall_flux  = 0.0_wp
-       wall_index = NINT( a+ 2*b + 3*c1 + 4*c2 )
-
-       DO  i = nxl, nxr
-          DO  j = nys, nyn
-
-             IF ( wall(j,i) /= 0.0_wp )  THEN
-!
-!--             All subsequent variables are computed for the respective
-!--             location where the respective flux is defined.
-                DO  k = nzb_uvw_inner(j,i)+1, nzb_uvw_outer(j,i)
-
-!
-!--                (1) Compute rifs, u_i, v_i, ws, pt' and w'pt'
-                   rifs  = rif_wall(k,j,i,wall_index)
-
-                   u_i   = a * u(k,j,i) + c1 * 0.25_wp *                       &
-                           ( u(k+1,j,i+1) + u(k+1,j,i) + u(k,j,i+1) + u(k,j,i) )
-
-                   v_i   = b * v(k,j,i) + c2 * 0.25_wp *                       &
-                           ( v(k+1,j+1,i) + v(k+1,j,i) + v(k,j+1,i) + v(k,j,i) )
-
-                   ws    = ( c1 + c2 ) * w(k,j,i) + 0.25_wp * (                &
-                     a * ( w(k-1,j,i-1) + w(k-1,j,i) + w(k,j,i-1) + w(k,j,i) ) &
-                   + b * ( w(k-1,j-1,i) + w(k-1,j,i) + w(k,j-1,i) + w(k,j,i) ) &
-                                                              )
-                   pt_i  = 0.5_wp * ( pt(k,j,i) + a *  pt(k,j,i-1) +           &
-                                   b * pt(k,j-1,i) + ( c1 + c2 ) * pt(k+1,j,i) )
-
-                   pts   = pt_i - hom(k,1,4,0)
-                   wspts = ws * pts
-
-!
-!--                (2) Compute wall-parallel absolute velocity vel_total
-                   vel_total = SQRT( ws**2 + (a+c1) * u_i**2 + (b+c2) * v_i**2 )
-
-!
-!--                (3) Compute wall friction velocity us_wall
-                   IF ( rifs >= 0.0_wp )  THEN
-
-!
-!--                   Stable stratification (and neutral)
-                      us_wall = kappa * vel_total / ( LOG( zp / z0(j,i) ) +    &
-                                         5.0_wp * rifs * ( zp - z0(j,i) ) / zp &
-                                                    )
-                   ELSE
-
-!
-!--                   Unstable stratification
-                      h1 = SQRT( SQRT( 1.0_wp - 16.0_wp * rifs ) )
-                      h2 = SQRT( SQRT( 1.0_wp - 16.0_wp * rifs * z0(j,i) / zp ) )
-
-                      us_wall = kappa * vel_total / (                          &
-                           LOG( zp / z0(j,i) ) -                               &
-                           LOG( ( 1.0_wp + h1 )**2 * ( 1.0_wp + h1**2 ) / (    &
-                                ( 1.0_wp + h2 )**2 * ( 1.0_wp + h2**2 )   ) ) +&
-                                2.0_wp * ( ATAN( h1 ) - ATAN( h2 ) )           &
-                                                    )
-                   ENDIF
-
-!
-!--                (4) Compute zp/L (corresponds to neutral Richardson flux
-!--                    number rifs)
-                   rifs = -1.0_wp * zp * kappa * g * wspts /                   &
-                          ( pt_i * ( us_wall**3 + 1E-30 ) )
-
-!
-!--                Limit the value range of the Richardson numbers.
-!--                This is necessary for very small velocities (u,w --> 0),
-!--                because the absolute value of rif can then become very
-!--                large, which in consequence would result in very large
-!--                shear stresses and very small momentum fluxes (both are
-!--                generally unrealistic).
-                   IF ( rifs < zeta_min )  rifs = zeta_min
-                   IF ( rifs > zeta_max )  rifs = zeta_max
-
-!
-!--                (5) Compute wall_flux (u'v', v'u', w'v', or w'u')
-                   IF ( rifs >= 0.0_wp )  THEN
-
-!
-!--                   Stable stratification (and neutral)
-                      wall_flux(k,j,i) = kappa *                               &
-                              ( a*u(k,j,i) + b*v(k,j,i) + (c1+c2)*w(k,j,i) ) / &
-                              (  LOG( zp / z0(j,i) ) +                         &
-                                 5.0_wp * rifs * ( zp - z0(j,i) ) / zp         &
-                              )
-                   ELSE
-
-!
-!--                   Unstable stratification
-                      h1 = SQRT( SQRT( 1.0_wp - 16.0_wp * rifs ) )
-                      h2 = SQRT( SQRT( 1.0_wp - 16.0_wp * rifs * z0(j,i) / zp ) )
-
-                      wall_flux(k,j,i) = kappa *                               &
-                           ( a*u(k,j,i) + b*v(k,j,i) + (c1+c2)*w(k,j,i) ) / (  &
-                           LOG( zp / z0(j,i) ) -                               &
-                           LOG( ( 1.0_wp + h1 )**2 * ( 1.0_wp + h1**2 ) / (    &
-                                ( 1.0_wp + h2 )**2 * ( 1.0_wp + h2**2 )   ) ) +&
-                                2.0_wp * ( ATAN( h1 ) - ATAN( h2 ) )           &
-                                                                            )
-                   ENDIF
-                   wall_flux(k,j,i) = -wall_flux(k,j,i) * us_wall
-
-!
-!--                store rifs for next time step
-                   rif_wall(k,j,i,wall_index) = rifs
-
-                ENDDO
-
-             ENDIF
-
-          ENDDO
-       ENDDO
-
-    END SUBROUTINE wall_fluxes
-
-
-!------------------------------------------------------------------------------!
-! Description:
-! ------------
-!> Call for all grid point i,j
-!------------------------------------------------------------------------------!
-    SUBROUTINE wall_fluxes_ij( i, j, nzb_w, nzt_w, wall_flux, a, b, c1, c2 )
-
-       USE arrays_3d,                                                          &
-           ONLY:  rif_wall, pt, u, v, w, z0
-       
-       USE control_parameters,                                                 &
-           ONLY:  g, kappa, zeta_max, zeta_min
-       
-       USE grid_variables,                                                     &
-           ONLY:  dx, dy
-       
-       USE indices,                                                            &
-           ONLY:  nzb, nzt
-       
-       USE kinds
-       
-       USE statistics,                                                         &
-           ONLY:  hom
-
-       IMPLICIT NONE
-
-       INTEGER(iwp) ::  i            !< 
-       INTEGER(iwp) ::  j            !< 
-       INTEGER(iwp) ::  k            !< 
-       INTEGER(iwp) ::  nzb_w        !< 
-       INTEGER(iwp) ::  nzt_w        !< 
-       INTEGER(iwp) ::  wall_index   !< 
-       
-       REAL(wp) ::  a           !< 
-       REAL(wp) ::  b           !< 
-       REAL(wp) ::  c1          !< 
-       REAL(wp) ::  c2          !< 
-       REAL(wp) ::  h1          !< 
-       REAL(wp) ::  h2          !< 
-       REAL(wp) ::  zp          !< 
-       REAL(wp) ::  pts         !< 
-       REAL(wp) ::  pt_i        !< 
-       REAL(wp) ::  rifs        !< 
-       REAL(wp) ::  u_i         !< 
-       REAL(wp) ::  v_i         !< 
-       REAL(wp) ::  us_wall     !< 
-       REAL(wp) ::  vel_total   !< 
-       REAL(wp) ::  ws          !< 
-       REAL(wp) ::  wspts       !< 
-
-       REAL(wp), DIMENSION(nzb:nzt+1) ::  wall_flux   !< 
-
-
-       zp         = 0.5_wp * ( (a+c1) * dy + (b+c2) * dx )
-       wall_flux  = 0.0_wp
-       wall_index = NINT( a+ 2*b + 3*c1 + 4*c2 )
-
-!
-!--    All subsequent variables are computed for the respective location where 
-!--    the respective flux is defined.
-       DO  k = nzb_w, nzt_w
-
-!
-!--       (1) Compute rifs, u_i, v_i, ws, pt' and w'pt'
-          rifs  = rif_wall(k,j,i,wall_index)
-
-          u_i   = a * u(k,j,i) + c1 * 0.25_wp *                                &
-                  ( u(k+1,j,i+1) + u(k+1,j,i) + u(k,j,i+1) + u(k,j,i) )
-
-          v_i   = b * v(k,j,i) + c2 * 0.25_wp *                                &
-                  ( v(k+1,j+1,i) + v(k+1,j,i) + v(k,j+1,i) + v(k,j,i) )
-
-          ws    = ( c1 + c2 ) * w(k,j,i) + 0.25_wp * (                         &
-                     a * ( w(k-1,j,i-1) + w(k-1,j,i) + w(k,j,i-1) + w(k,j,i) ) &
-                   + b * ( w(k-1,j-1,i) + w(k-1,j,i) + w(k,j-1,i) + w(k,j,i) ) &
-                                                     )
-          pt_i  = 0.5_wp * ( pt(k,j,i) + a *  pt(k,j,i-1) + b * pt(k,j-1,i)    &
-                          + ( c1 + c2 ) * pt(k+1,j,i) )
-
-          pts   = pt_i - hom(k,1,4,0)
-          wspts = ws * pts
-
-!
-!--       (2) Compute wall-parallel absolute velocity vel_total
-          vel_total = SQRT( ws**2 + ( a+c1 ) * u_i**2 + ( b+c2 ) * v_i**2 )
-
-!
-!--       (3) Compute wall friction velocity us_wall
-          IF ( rifs >= 0.0_wp )  THEN
-
-!
-!--          Stable stratification (and neutral)
-             us_wall = kappa * vel_total / ( LOG( zp / z0(j,i) ) +             &
-                                         5.0_wp * rifs * ( zp - z0(j,i) ) / zp &
-                                           )
-          ELSE
-
-!
-!--          Unstable stratification
-             h1 = SQRT( SQRT( 1.0_wp - 16.0_wp * rifs ) )
-             h2 = SQRT( SQRT( 1.0_wp - 16.0_wp * rifs * z0(j,i) / zp ) )
-
-             us_wall = kappa * vel_total / (                                   &
-                  LOG( zp / z0(j,i) ) -                                        &
-                  LOG( ( 1.0_wp + h1 )**2 * ( 1.0_wp + h1**2 ) / (             &
-                       ( 1.0_wp + h2 )**2 * ( 1.0_wp + h2**2 )   ) ) +         &
-                       2.0_wp * ( ATAN( h1 ) - ATAN( h2 ) )                    &
-                                           )
-          ENDIF
-
-!
-!--       (4) Compute zp/L (corresponds to neutral Richardson flux number 
-!--           rifs)
-          rifs = -1.0_wp * zp * kappa * g * wspts /                            &
-                  ( pt_i * (us_wall**3 + 1E-30) )
-
-!
-!--       Limit the value range of the Richardson numbers.
-!--       This is necessary for very small velocities (u,w --> 0), because
-!--       the absolute value of rif can then become very large, which in
-!--       consequence would result in very large shear stresses and very
-!--       small momentum fluxes (both are generally unrealistic).
-          IF ( rifs < zeta_min )  rifs = zeta_min
-          IF ( rifs > zeta_max )  rifs = zeta_max
-
-!
-!--       (5) Compute wall_flux (u'v', v'u', w'v', or w'u')
-          IF ( rifs >= 0.0_wp )  THEN
-
-!
-!--          Stable stratification (and neutral)
-             wall_flux(k) = kappa *                                            &
-                            ( a*u(k,j,i) + b*v(k,j,i) + (c1+c2)*w(k,j,i) ) /   &
-                            (  LOG( zp / z0(j,i) ) +                           &
-                               5.0_wp * rifs * ( zp - z0(j,i) ) / zp           &
-                            )
-          ELSE
-
-!
-!--          Unstable stratification
-             h1 = SQRT( SQRT( 1.0_wp - 16.0_wp * rifs ) )
-             h2 = SQRT( SQRT( 1.0_wp - 16.0_wp * rifs * z0(j,i) / zp ) )
-
-             wall_flux(k) = kappa *                                            &
-                  ( a*u(k,j,i) + b*v(k,j,i) + (c1+c2)*w(k,j,i) ) / (           &
-                  LOG( zp / z0(j,i) ) -                                        &
-                  LOG( ( 1.0_wp + h1 )**2 * ( 1.0_wp + h1**2 ) / (             &
-                       ( 1.0_wp + h2 )**2 * ( 1.0_wp + h2**2 )   ) ) +         &
-                       2.0_wp * ( ATAN( h1 ) - ATAN( h2 ) )                    &
-                                                                   )
-          ENDIF
-          wall_flux(k) = -wall_flux(k) * us_wall
-
-!
-!--       store rifs for next time step
-          rif_wall(k,j,i,wall_index) = rifs
-
-       ENDDO
-
-    END SUBROUTINE wall_fluxes_ij
-
-
-
-!------------------------------------------------------------------------------!
-! Description:
-! ------------
-!> Call for all grid points
-!> Calculates momentum fluxes at vertical walls for routine production_e
-!> assuming Monin-Obukhov similarity.
-!> Indices: usvs a=1, vsus b=1, wsvs c1=1, wsus c2=1 (other=0).
-!------------------------------------------------------------------------------!
-
-    SUBROUTINE wall_fluxes_e( wall_flux, a, b, c1, c2, wall )
-
-
-       USE arrays_3d,                                                          &
-           ONLY:  rif_wall, u, v, w, z0
-       
-       USE control_parameters,                                                 &
-           ONLY:  kappa
-       
-       USE grid_variables,                                                     &
-           ONLY:  dx, dy
-       
-       USE indices,                                                            &
-           ONLY:  nxl, nxlg, nxr, nxrg, nyn, nyng, nys, nysg, nzb,             &
-                  nzb_diff_s_inner, nzb_diff_s_outer, nzt
-       
-       USE kinds
-
-       IMPLICIT NONE
-
-       INTEGER(iwp) ::  i            !< 
-       INTEGER(iwp) ::  j            !< 
-       INTEGER(iwp) ::  k            !< 
-       INTEGER(iwp) ::  kk           !< 
-       INTEGER(iwp) ::  wall_index   !< 
-       
-       REAL(wp) ::  a           !< 
-       REAL(wp) ::  b           !< 
-       REAL(wp) ::  c1          !< 
-       REAL(wp) ::  c2          !< 
-       REAL(wp) ::  h1          !< 
-       REAL(wp) ::  h2          !< 
-       REAL(wp) ::  u_i         !< 
-       REAL(wp) ::  v_i         !< 
-       REAL(wp) ::  us_wall     !< 
-       REAL(wp) ::  vel_total   !< 
-       REAL(wp) ::  vel_zp      !< 
-       REAL(wp) ::  ws          !< 
-       REAL(wp) ::  zp          !< 
-       REAL(wp) ::  rifs        !< 
-
-       REAL(wp),                                                               &
-          DIMENSION(nysg:nyng,nxlg:nxrg) ::                                    &
-             wall   !< 
-       
-       REAL(wp),                                                               &
-          DIMENSION(nzb:nzt+1,nys:nyn,nxl:nxr) ::                              &
-             wall_flux   !< 
-
-
-       zp         = 0.5_wp * ( (a+c1) * dy + (b+c2) * dx )
-       wall_flux  = 0.0_wp
-       wall_index = NINT( a+ 2*b + 3*c1 + 4*c2 )
-
-       DO  i = nxl, nxr
-          DO  j = nys, nyn
-
-             IF ( wall(j,i) /= 0.0_wp )  THEN
-!
-!--             All subsequent variables are computed for scalar locations.
-                DO  k = nzb_diff_s_inner(j,i)-1, nzb_diff_s_outer(j,i)-2
-!
-!--                (1) Compute rifs, u_i, v_i, and ws
-                   IF ( k == nzb_diff_s_inner(j,i)-1 )  THEN
-                      kk = nzb_diff_s_inner(j,i)-1
-                   ELSE
-                      kk = k-1
-                   ENDIF
-                   rifs  = 0.5_wp * (      rif_wall(k,j,i,wall_index) +        &
-                                      a  * rif_wall(k,j,i+1,1)        +        &
-                                      b  * rif_wall(k,j+1,i,2)        +        &
-                                      c1 * rif_wall(kk,j,i,3)         +        &
-                                      c2 * rif_wall(kk,j,i,4)                  &
-                                    )
-
-                   u_i   = 0.5_wp * ( u(k,j,i) + u(k,j,i+1) )
-                   v_i   = 0.5_wp * ( v(k,j,i) + v(k,j+1,i) )
-                   ws    = 0.5_wp * ( w(k,j,i) + w(k-1,j,i) )
-!
-!--                (2) Compute wall-parallel absolute velocity vel_total and
-!--                interpolate appropriate velocity component vel_zp.
-                   vel_total = SQRT( ws**2 + (a+c1) * u_i**2 + (b+c2) * v_i**2 )
-                   vel_zp    = 0.5_wp * ( a * u_i + b * v_i + (c1+c2) * ws )
-!
-!--                (3) Compute wall friction velocity us_wall
-                   IF ( rifs >= 0.0_wp )  THEN
-
-!
-!--                   Stable stratification (and neutral)
-                      us_wall = kappa * vel_total / ( LOG( zp / z0(j,i) ) +    &
-                                         5.0_wp * rifs * ( zp - z0(j,i) ) / zp &
-                                                    )
-                   ELSE
-
-!
-!--                   Unstable stratification
-                      h1 = SQRT( SQRT( 1.0_wp - 16.0_wp * rifs ) )
-                      h2 = SQRT( SQRT( 1.0_wp - 16.0_wp * rifs * z0(j,i) / zp ) )
-
-                      us_wall = kappa * vel_total / (                          &
-                           LOG( zp / z0(j,i) ) -                               &
-                           LOG( ( 1.0_wp + h1 )**2 * ( 1.0_wp + h1**2 ) / (    &
-                                ( 1.0_wp + h2 )**2 * ( 1.0_wp + h2**2 )   ) ) +&
-                                2.0_wp * ( ATAN( h1 ) - ATAN( h2 ) )           &
-                                                    )
-                   ENDIF
-
-!
-!--                Skip step (4) of wall_fluxes, because here rifs is already
-!--                available from (1)
-!
-!--                (5) Compute wall_flux (u'v', v'u', w'v', or w'u')
-
-                   IF ( rifs >= 0.0_wp )  THEN
-
-!
-!--                   Stable stratification (and neutral)
-                      wall_flux(k,j,i) = kappa * vel_zp / ( LOG( zp/z0(j,i) ) +&
-                                         5.0_wp * rifs * ( zp-z0(j,i) ) / zp )
-                   ELSE
-
-!
-!--                   Unstable stratification
-                      h1 = SQRT( SQRT( 1.0_wp - 16.0_wp * rifs ) )
-                      h2 = SQRT( SQRT( 1.0_wp - 16.0_wp * rifs * z0(j,i) / zp ) )
-
-                      wall_flux(k,j,i) = kappa * vel_zp / (                    &
-                           LOG( zp / z0(j,i) ) -                               &
-                           LOG( ( 1.0_wp + h1 )**2 * ( 1.0_wp + h1**2 ) / (    &
-                                ( 1.0_wp + h2 )**2 * ( 1.0_wp + h2**2 )   ) ) +&
-                                2.0_wp * ( ATAN( h1 ) - ATAN( h2 ) )           &
-                                                          )
-                   ENDIF
-                   wall_flux(k,j,i) = - wall_flux(k,j,i) * us_wall
-
-                ENDDO
-
-             ENDIF
-
-          ENDDO
-       ENDDO
-
-    END SUBROUTINE wall_fluxes_e
-
-
-!------------------------------------------------------------------------------!
-! Description:
-! ------------
-!> Call for grid point i,j
-!------------------------------------------------------------------------------!
-    SUBROUTINE wall_fluxes_e_ij( i, j, nzb_w, nzt_w, wall_flux, a, b, c1, c2 )
-
-       USE arrays_3d,                                                          &
-           ONLY:  rif_wall, u, v, w, z0
-       
-       USE control_parameters,                                                 &
-           ONLY:  kappa
-       
-       USE grid_variables,                                                     &
-           ONLY:  dx, dy
-       
-       USE indices,                                                            &
-           ONLY:  nzb, nzt
-       
-       USE kinds
-
-       IMPLICIT NONE
-
-       INTEGER(iwp) ::  i            !< 
-       INTEGER(iwp) ::  j            !< 
-       INTEGER(iwp) ::  k            !< 
-       INTEGER(iwp) ::  kk           !< 
-       INTEGER(iwp) ::  nzb_w        !< 
-       INTEGER(iwp) ::  nzt_w        !< 
-       INTEGER(iwp) ::  wall_index   !< 
-       
-       REAL(wp) ::  a           !< 
-       REAL(wp) ::  b           !< 
-       REAL(wp) ::  c1          !< 
-       REAL(wp) ::  c2          !< 
-       REAL(wp) ::  h1          !< 
-       REAL(wp) ::  h2          !< 
-       REAL(wp) ::  u_i         !< 
-       REAL(wp) ::  v_i         !< 
-       REAL(wp) ::  us_wall     !< 
-       REAL(wp) ::  vel_total   !< 
-       REAL(wp) ::  vel_zp      !< 
-       REAL(wp) ::  ws          !< 
-       REAL(wp) ::  zp          !< 
-       REAL(wp) ::  rifs        !< 
-
-       REAL(wp), DIMENSION(nzb:nzt+1) ::  wall_flux   !< 
-
-
-       zp         = 0.5_wp * ( (a+c1) * dy + (b+c2) * dx )
-       wall_flux  = 0.0_wp
-       wall_index = NINT( a+ 2*b + 3*c1 + 4*c2 )
-
-!
-!--    All subsequent variables are computed for scalar locations.
-       DO  k = nzb_w, nzt_w
-
-!
-!--       (1) Compute rifs, u_i, v_i, and ws
-          IF ( k == nzb_w )  THEN
-             kk = nzb_w
-          ELSE
-             kk = k-1
-          ENDIF
-          rifs  = 0.5_wp * (      rif_wall(k,j,i,wall_index) +                 &
-                             a  * rif_wall(k,j,i+1,1)        +                 &
-                             b  * rif_wall(k,j+1,i,2)        +                 &
-                             c1 * rif_wall(kk,j,i,3)         +                 &
-                             c2 * rif_wall(kk,j,i,4)                           &
-                           )
-
-          u_i   = 0.5_wp * ( u(k,j,i) + u(k,j,i+1) )
-          v_i   = 0.5_wp * ( v(k,j,i) + v(k,j+1,i) )
-          ws    = 0.5_wp * ( w(k,j,i) + w(k-1,j,i) )
-!
-!--       (2) Compute wall-parallel absolute velocity vel_total and
-!--       interpolate appropriate velocity component vel_zp.
-          vel_total = SQRT( ws**2 + (a+c1) * u_i**2 + (b+c2) * v_i**2 )
-          vel_zp    = 0.5_wp * ( a * u_i + b * v_i + (c1+c2) * ws )
-!
-!--       (3) Compute wall friction velocity us_wall
-          IF ( rifs >= 0.0_wp )  THEN
-
-!
-!--          Stable stratification (and neutral)
-             us_wall = kappa * vel_total / ( LOG( zp / z0(j,i) ) +             &
-                                         5.0_wp * rifs * ( zp - z0(j,i) ) / zp &
-                                           )
-          ELSE
-
-!
-!--          Unstable stratification
-             h1 = SQRT( SQRT( 1.0_wp - 16.0_wp * rifs ) )
-             h2 = SQRT( SQRT( 1.0_wp - 16.0_wp * rifs * z0(j,i) / zp ) )
-
-             us_wall = kappa * vel_total / (                                   &
-                  LOG( zp / z0(j,i) ) -                                        &
-                  LOG( ( 1.0_wp + h1 )**2 * ( 1.0_wp + h1**2 ) / (             &
-                       ( 1.0_wp + h2 )**2 * ( 1.0_wp + h2**2 )   ) ) +         &
-                       2.0_wp * ( ATAN( h1 ) - ATAN( h2 ) )                    &
-                                           )
-          ENDIF
-
-!
-!--       Skip step (4) of wall_fluxes, because here rifs is already
-!--       available from (1)
-!
-!--       (5) Compute wall_flux (u'v', v'u', w'v', or w'u')
-!--       First interpolate the velocity (this is different from 
-!--       subroutine wall_fluxes because fluxes in subroutine 
-!--       wall_fluxes_e are defined at scalar locations).
-          vel_zp = 0.5_wp * (       a * ( u(k,j,i) + u(k,j,i+1) ) +            &
-                                    b * ( v(k,j,i) + v(k,j+1,i) ) +            &
-                              (c1+c2) * ( w(k,j,i) + w(k-1,j,i) )              &
-                            )
-
-          IF ( rifs >= 0.0_wp )  THEN
-
-!
-!--          Stable stratification (and neutral)
-             wall_flux(k) = kappa *  vel_zp /                                  &
-                     ( LOG( zp/z0(j,i) ) + 5.0_wp * rifs * ( zp-z0(j,i) ) / zp )
-          ELSE
-
-!
-!--          Unstable stratification
-             h1 = SQRT( SQRT( 1.0_wp - 16.0_wp * rifs ) )
-             h2 = SQRT( SQRT( 1.0_wp - 16.0_wp * rifs * z0(j,i) / zp ) )
-
-             wall_flux(k) = kappa * vel_zp / (                                 &
-                  LOG( zp / z0(j,i) ) -                                        &
-                  LOG( ( 1.0_wp + h1 )**2 * ( 1.0_wp + h1**2 ) / (             &
-                       ( 1.0_wp + h2 )**2 * ( 1.0_wp + h2**2 )   ) ) +         &
-                       2.0_wp * ( ATAN( h1 ) - ATAN( h2 ) )                    &
-                                             )
-          ENDIF
-          wall_flux(k) = - wall_flux(k) * us_wall
-
-       ENDDO
-
-    END SUBROUTINE wall_fluxes_e_ij
-
- END MODULE wall_fluxes_mod
Index: /palm/trunk/SOURCE/wind_turbine_model_mod.f90
===================================================================
--- /palm/trunk/SOURCE/wind_turbine_model_mod.f90	(revision 2231)
+++ /palm/trunk/SOURCE/wind_turbine_model_mod.f90	(revision 2232)
@@ -20,5 +20,5 @@
 ! Current revisions:
 ! -----------------
-! 
+! Adjustments to new topography concept
 ! 
 ! Former revisions:
@@ -86,5 +86,5 @@
     USE indices,                                                               &
         ONLY:  nbgp, nx, nxl, nxlg, nxr, nxrg, ny, nyn, nyng, nys, nysg, nz,   &
-               nzb, nzb_u_inner, nzb_v_inner, nzb_w_inner, nzt
+               nzb, nzt, wall_flags_0
 
     USE kinds
@@ -1358,4 +1358,5 @@
        INTEGER(iwp) ::  ii, jj, kk       !<
     
+       REAL(wp)     ::  flag               !< flag to mask topography grid points
        REAL(wp)     ::  sin_rot, cos_rot   !<
        REAL(wp)     ::  sin_yaw, cos_yaw   !<
@@ -1971,8 +1972,13 @@
                 DO j = MAX( nys, j_hub(inot) - j_smear(inot) ),                &
                         MIN( nyn, j_hub(inot) + j_smear(inot) )
-                   DO k = MAX( nzb_u_inner(j,i)+1, k_hub(inot) - k_smear(inot) ), &
-                                k_hub(inot) + k_smear(inot)
+!                    DO k = MAX( nzb_u_inner(j,i)+1, k_hub(inot) - k_smear(inot) ), &
+!                                 k_hub(inot) + k_smear(inot)
+                   DO  k = nzb+1, k_hub(inot) + k_smear(inot)
                       DO ring = 1, nrings(inot)
                          DO rseg = 1, nsegs(ring,inot)
+!
+!--                         Predetermine flag to mask topography
+                            flag = MERGE( 1.0_wp, 0.0_wp, BTEST( wall_flags_0(k,j,i), 1 ) )
+      
 !
 !--                         Determine the square of the distance between the
@@ -1995,20 +2001,23 @@
 !--                         squared distances <= eps_min2:
                             IF ( dist_u_3d <= eps_min2 ) THEN
-                            thrust(k,j,i) = thrust(k,j,i) +                    &
-                                            thrust_ring(ring,rseg) *           &
-                                            ( ( pol_a * dist_u_3d - pol_b ) *  & 
-                                             dist_u_3d + 1.0_wp ) * eps_factor
+                               thrust(k,j,i) = thrust(k,j,i) +                     &
+                                               thrust_ring(ring,rseg) *            &
+                                               ( ( pol_a * dist_u_3d - pol_b ) *   & 
+                                                dist_u_3d + 1.0_wp ) * eps_factor *&
+                                                                       flag
                             ENDIF
                             IF ( dist_v_3d <= eps_min2 ) THEN
-                            torque_y(k,j,i) = torque_y(k,j,i) +                &
-                                              torque_ring_y(ring,rseg) *       &
-                                              ( ( pol_a * dist_v_3d - pol_b ) *&
-                                               dist_v_3d + 1.0_wp ) * eps_factor
+                               torque_y(k,j,i) = torque_y(k,j,i) +                    &
+                                                 torque_ring_y(ring,rseg) *           &
+                                                 ( ( pol_a * dist_v_3d - pol_b ) *    &
+                                                  dist_v_3d + 1.0_wp ) * eps_factor * &
+                                                                         flag
                             ENDIF
                             IF ( dist_w_3d <= eps_min2 ) THEN
-                            torque_z(k,j,i) = torque_z(k,j,i) +                &
-                                              torque_ring_z(ring,rseg) *       &
-                                              ( ( pol_a * dist_w_3d - pol_b ) *&
-                                               dist_w_3d + 1.0_wp ) * eps_factor
+                               torque_z(k,j,i) = torque_z(k,j,i) +                    &
+                                                 torque_ring_z(ring,rseg) *           &
+                                                 ( ( pol_a * dist_w_3d - pol_b ) *    &
+                                                  dist_w_3d + 1.0_wp ) * eps_factor * &
+                                                                         flag
                             ENDIF
 
@@ -2018,18 +2027,21 @@
 !
 !--                   Rotation of force components:
-                      rot_tend_x(k,j,i) = rot_tend_x(k,j,i) +                  &
+                      rot_tend_x(k,j,i) = rot_tend_x(k,j,i) + (                &
                                       thrust(k,j,i)*rotx(inot,1) +             &
                                       torque_y(k,j,i)*roty(inot,1) +           &
-                                      torque_z(k,j,i)*rotz(inot,1)
+                                      torque_z(k,j,i)*rotz(inot,1)             &
+                                                              ) * flag
                                 
-                      rot_tend_y(k,j,i) = rot_tend_y(k,j,i) +                  &
+                      rot_tend_y(k,j,i) = rot_tend_y(k,j,i) + (                &
                                       thrust(k,j,i)*rotx(inot,2) +             &
                                       torque_y(k,j,i)*roty(inot,2) +           &
-                                      torque_z(k,j,i)*rotz(inot,2)
+                                      torque_z(k,j,i)*rotz(inot,2)             &
+                                                              ) * flag
                                 
-                      rot_tend_z(k,j,i) = rot_tend_z(k,j,i) +                  &
+                      rot_tend_z(k,j,i) = rot_tend_z(k,j,i) + (                &
                                       thrust(k,j,i)*rotx(inot,3) +             &
                                       torque_y(k,j,i)*roty(inot,3) +           &
-                                      torque_z(k,j,i)*rotz(inot,3)                               
+                                      torque_z(k,j,i)*rotz(inot,3)             &
+                                                              ) * flag                    
 
                    ENDDO        ! End of loop over k
@@ -2424,5 +2436,5 @@
              DO  i = nxlg, nxrg
                 DO  j = nysg, nyng
-                   DO  k = nzb_u_inner(j,i)+1, k_hub(1) + k_smear(1)
+                   DO  k = nzb+1, k_hub(1) + k_smear(1)
 !
 !--                   Calculate the thrust generated by the nacelle and the tower
@@ -2432,6 +2444,8 @@
                                          SIGN( u(k,j,i)**2 , u(k,j,i) ) 
                                                    
-                      tend(k,j,i) = tend(k,j,i) - rot_tend_x(k,j,i)            &
-                                  - tend_nac_x - tend_tow_x
+                      tend(k,j,i) = tend(k,j,i) + ( - rot_tend_x(k,j,i)        &
+                                  - tend_nac_x - tend_tow_x )                  &
+                                      * MERGE( 1.0_wp, 0.0_wp,                 &
+                                               BTEST( wall_flags_0(k,j,i), 1 ) )
                    ENDDO
                 ENDDO
@@ -2445,11 +2459,13 @@
              DO  i = nxlg, nxrg
                 DO  j = nysg, nyng
-                   DO  k = nzb_v_inner(j,i)+1, k_hub(1) + k_smear(1)
+                   DO  k = nzb+1, k_hub(1) + k_smear(1)
                       tend_nac_y = 0.5_wp * nac_cd_surf(k,j,i) *               &
                                          SIGN( v(k,j,i)**2 , v(k,j,i) )     
                       tend_tow_y   = 0.5_wp * tow_cd_surf(k,j,i) *             &
                                          SIGN( v(k,j,i)**2 , v(k,j,i) )                      
-                      tend(k,j,i) = tend(k,j,i) - rot_tend_y(k,j,i)            &
-                                  - tend_nac_y - tend_tow_y
+                      tend(k,j,i) = tend(k,j,i) + ( - rot_tend_y(k,j,i)        &
+                                  - tend_nac_y - tend_tow_y )                  &
+                                      * MERGE( 1.0_wp, 0.0_wp,                 &
+                                               BTEST( wall_flags_0(k,j,i), 2 ) )
                    ENDDO
                 ENDDO
@@ -2463,6 +2479,8 @@
              DO  i = nxlg, nxrg
                 DO  j = nysg, nyng
-                   DO  k = nzb_w_inner(j,i)+1,  k_hub(1) + k_smear(1)
-                      tend(k,j,i) = tend(k,j,i) - rot_tend_z(k,j,i)
+                   DO  k = nzb+1,  k_hub(1) + k_smear(1)
+                      tend(k,j,i) = tend(k,j,i) - rot_tend_z(k,j,i)            &
+                                      * MERGE( 1.0_wp, 0.0_wp,                 &
+                                               BTEST( wall_flags_0(k,j,i), 3 ) )
                    ENDDO
                 ENDDO
@@ -2506,5 +2524,5 @@
           IF ( simulated_time >= time_turbine_on )  THEN
 
-             DO  k = nzb_u_inner(j,i)+1,  k_hub(1) + k_smear(1)
+             DO  k = nzb+1,  k_hub(1) + k_smear(1)
 !
 !--             Calculate the thrust generated by the nacelle and the tower 
@@ -2513,6 +2531,8 @@
                 tend_tow_x   = 0.5_wp * tow_cd_surf(k,j,i) *                   &
                                    SIGN( u(k,j,i)**2 , u(k,j,i) ) 
-                tend(k,j,i) = tend(k,j,i) - rot_tend_x(k,j,i)                  &
-                            - tend_nac_x - tend_tow_x
+                tend(k,j,i) = tend(k,j,i) + ( - rot_tend_x(k,j,i)              &
+                            - tend_nac_x - tend_tow_x )                        &
+                                      * MERGE( 1.0_wp, 0.0_wp,                 &
+                                               BTEST( wall_flags_0(k,j,i), 1 ) )
              ENDDO
           ENDIF
@@ -2522,11 +2542,13 @@
 !--       Apply the y-component of the force to the v-component of the flow:
           IF ( simulated_time >= time_turbine_on )  THEN
-             DO  k = nzb_v_inner(j,i)+1,  k_hub(1) + k_smear(1)
+             DO  k = nzb+1,  k_hub(1) + k_smear(1)
                 tend_nac_y = 0.5_wp * nac_cd_surf(k,j,i) *                     &
                                    SIGN( v(k,j,i)**2 , v(k,j,i) )     
                 tend_tow_y   = 0.5_wp * tow_cd_surf(k,j,i) *                   &
                                    SIGN( v(k,j,i)**2 , v(k,j,i) )                      
-                tend(k,j,i) = tend(k,j,i) - rot_tend_y(k,j,i)                  &
-                            - tend_nac_y - tend_tow_y
+                tend(k,j,i) = tend(k,j,i) + ( - rot_tend_y(k,j,i)              &
+                            - tend_nac_y - tend_tow_y )                        &
+                                      * MERGE( 1.0_wp, 0.0_wp,                 &
+                                               BTEST( wall_flags_0(k,j,i), 2 ) )
              ENDDO
           ENDIF
@@ -2536,6 +2558,8 @@
 !--       Apply the z-component of the force to the w-component of the flow:
           IF ( simulated_time >= time_turbine_on )  THEN
-             DO  k = nzb_w_inner(j,i)+1,  k_hub(1) + k_smear(1)
-                tend(k,j,i) = tend(k,j,i) - rot_tend_z(k,j,i)
+             DO  k = nzb+1,  k_hub(1) + k_smear(1)
+                tend(k,j,i) = tend(k,j,i) - rot_tend_z(k,j,i)                  &
+                                      * MERGE( 1.0_wp, 0.0_wp,                 &
+                                               BTEST( wall_flags_0(k,j,i), 3 ) )
              ENDDO
           ENDIF
Index: /palm/trunk/SOURCE/write_3d_binary.f90
===================================================================
--- /palm/trunk/SOURCE/write_3d_binary.f90	(revision 2231)
+++ /palm/trunk/SOURCE/write_3d_binary.f90	(revision 2232)
@@ -20,5 +20,6 @@
 ! Current revisions:
 ! -----------------
-! 
+! Adjustments to new surface concept - move output of surface varariables
+! to surface_mod
 ! 
 ! Former revisions:
@@ -112,10 +113,7 @@
 
     USE arrays_3d,                                                             &
-        ONLY:  e, kh, km, ol, p, pt, q, ql, qc, nr, nrs, nrsws, nrswst,        &
-               prr, precipitation_amount, qr,                                  &
-               qrs, qrsws, qrswst, qs, qsws, qswst, s, sa, ssws, sswst,        &
-               saswsb, saswst, rif_wall, shf, ss, ts, tswst, u, u_m_l, u_m_n,  &
-               u_m_r, u_m_s, us, usws, uswst, v, v_m_l, v_m_n, v_m_r, v_m_s,   &
-               vpt, vsws, vswst, w, w_m_l, w_m_n, w_m_r, w_m_s, z0, z0h, z0q
+        ONLY:  e, kh, km, p, pt, q, ql, qc, nr, prr, precipitation_amount, qr, &
+               s, sa, u, u_m_l, u_m_n, u_m_r, u_m_s, v, v_m_l, v_m_n, v_m_r,   &
+               v_m_s, vpt, w, w_m_l, w_m_n, w_m_r, w_m_s
         
     USE averaging
@@ -142,8 +140,11 @@
         ONLY:  spectrum_x, spectrum_y
 
+    USE surface_mod,                                                           &
+        ONLY :  surface_write_restart_data
+
+
     IMPLICIT NONE
 
     CHARACTER (LEN=10) ::  binary_version   !< 
-
 
 !
@@ -164,5 +165,4 @@
 !--            Also, the list of arrays to be read in read_3d_binary must be
 !--            adjusted accordingly.
-
     WRITE ( 14 )  'e                   ';  WRITE ( 14 )  e
     IF ( ALLOCATED( e_av ) )  THEN
@@ -178,5 +178,4 @@
        WRITE ( 14 )  'lwp_av              ';  WRITE ( 14 )  lwp_av
     ENDIF
-    WRITE ( 14 )  'ol                  ';  WRITE ( 14 )  ol
     WRITE ( 14 )  'p                   ';  WRITE ( 14 )  p
     IF ( ALLOCATED( p_av ) )  THEN
@@ -226,23 +225,14 @@
                    WRITE ( 14 )  'nr_av               ';  WRITE ( 14 )  nr_av
                 ENDIF
-                WRITE ( 14 )  'nrs                 ';  WRITE ( 14 )  nrs
-                WRITE ( 14 )  'nrsws               ';  WRITE ( 14 )  nrsws
-                WRITE ( 14 )  'nrswst              ';  WRITE ( 14 )  nrswst
                 WRITE ( 14 )  'qr                  ';  WRITE ( 14 )  qr
                 IF ( ALLOCATED( qr_av ) )  THEN
                    WRITE ( 14 )  'qr_av               ';  WRITE ( 14 )  qr_av
                 ENDIF
-                WRITE ( 14 )  'qrs                 ';  WRITE ( 14 )  qrs
-                WRITE ( 14 )  'qrsws               ';  WRITE ( 14 )  qrsws
-                WRITE ( 14 )  'qrswst              ';  WRITE ( 14 )  qrswst
              ENDIF
           ENDIF
        ENDIF
-       WRITE ( 14 )  'qs                  ';  WRITE ( 14 )  qs
-       WRITE ( 14 )  'qsws                ';  WRITE ( 14 )  qsws
        IF ( ALLOCATED( qsws_av ) )  THEN
           WRITE ( 14 )  'qsws_av             ';  WRITE ( 14 )  qsws_av
        ENDIF
-       WRITE ( 14 )  'qswst               ';  WRITE ( 14 ) qswst
     ENDIF
     IF ( passive_scalar )  THEN
@@ -251,10 +241,7 @@
           WRITE ( 14 )  's_av                ';  WRITE ( 14 )  s_av
        ENDIF
-       WRITE ( 14 )  'ss                  ';  WRITE ( 14 )  ss
-       WRITE ( 14 )  'ssws                ';  WRITE ( 14 )  ssws
        IF ( ALLOCATED( ssws_av ) )  THEN
           WRITE ( 14 )  'ssws_av             ';  WRITE ( 14 )  ssws_av
        ENDIF
-       WRITE ( 14 )  'sswst               ';  WRITE ( 14 ) sswst
     ENDIF    
     IF ( ocean )  THEN
@@ -266,6 +253,4 @@
           WRITE ( 14 )  'sa_av               ';  WRITE ( 14 )  sa_av
        ENDIF
-       WRITE ( 14 )  'saswsb              ';  WRITE ( 14 )  saswsb
-       WRITE ( 14 )  'saswst              ';  WRITE ( 14 )  saswst
     ENDIF
     IF ( ALLOCATED( ql_c_av ) )  THEN
@@ -287,11 +272,7 @@
                                            WRITE ( 14 )  seq_random_array
     ENDIF
-    IF ( topography /= 'flat' )  THEN
-       WRITE ( 14 )  'rif_wall            ';  WRITE ( 14 )  rif_wall
-    ENDIF
     IF ( ALLOCATED( s_av ) )  THEN
        WRITE ( 14 )  's_av                ';  WRITE ( 14 )  s_av
     ENDIF
-    WRITE ( 14 )  'shf                 ';  WRITE ( 14 )  shf
     IF ( ALLOCATED( shf_av ) )  THEN
        WRITE ( 14 )  'shf_av              ';  WRITE ( 14 )  shf_av
@@ -301,9 +282,7 @@
        WRITE ( 14 )  'spectrum_y          ';  WRITE ( 14 )  spectrum_y
     ENDIF
-    WRITE ( 14 )  'ts                  ';  WRITE ( 14 )  ts
     IF ( ALLOCATED( ts_av ) )  THEN
        WRITE ( 14 )  'ts_av               ';  WRITE ( 14 )  ts_av
     ENDIF
-    WRITE ( 14 )  'tswst               ';  WRITE ( 14 )  tswst
     WRITE ( 14 )  'u                   ';  WRITE ( 14 )  u
     IF ( ALLOCATED( u_av ) )  THEN
@@ -322,7 +301,4 @@
        WRITE ( 14 )  'u_m_s               ';  WRITE ( 14 )  u_m_s
     ENDIF
-    WRITE ( 14 )  'us                  ';  WRITE ( 14 )  us
-    WRITE ( 14 )  'usws                ';  WRITE ( 14 )  usws
-    WRITE ( 14 )  'uswst               ';  WRITE ( 14 )  uswst
     IF ( ALLOCATED( us_av ) )  THEN
        WRITE ( 14 )  'us_av               ';  WRITE ( 14 )  us_av
@@ -350,6 +326,4 @@
        ENDIF
     ENDIF
-    WRITE ( 14 )  'vsws                ';  WRITE ( 14 )  vsws
-    WRITE ( 14 )  'vswst               ';  WRITE ( 14 )  vswst
     WRITE ( 14 )  'w                   ';  WRITE ( 14 )  w
     IF ( ALLOCATED( w_av ) )  THEN
@@ -368,13 +342,10 @@
        WRITE ( 14 )  'w_m_s               ';  WRITE ( 14 )  w_m_s
     ENDIF
-    WRITE ( 14 )  'z0                  ';  WRITE ( 14 )  z0
     IF ( ALLOCATED( z0_av ) )  THEN
        WRITE ( 14 )  'z0_av               ';  WRITE ( 14 )  z0_av
     ENDIF
-    WRITE ( 14 )  'z0h                 ';  WRITE ( 14 )  z0h
     IF ( ALLOCATED( z0h_av ) )  THEN
        WRITE ( 14 )  'z0h_av              ';  WRITE ( 14 )  z0h_av
     ENDIF
-    WRITE ( 14 )  'z0q                 ';  WRITE ( 14 )  z0q
     IF ( ALLOCATED( z0q_av ) )  THEN
        WRITE ( 14 )  'z0q_av              ';  WRITE ( 14 )  z0q_av
@@ -385,4 +356,6 @@
     WRITE ( 14 )  '*** end ***         '
 
+    CALL surface_write_restart_data
+
  END SUBROUTINE write_3d_binary
  
Index: /palm/trunk/SOURCE/write_var_list.f90
===================================================================
--- /palm/trunk/SOURCE/write_var_list.f90	(revision 2231)
+++ /palm/trunk/SOURCE/write_var_list.f90	(revision 2232)
@@ -20,5 +20,8 @@
 ! Current revisions:
 ! -----------------
-! 
+! Replace wall_qflux, wall_sflux by wall_humidityflux and wall_scalarflux; add
+! wall_salinityflux
+! +tunnel_height, tunnel_lenth, tunnel_width_x, tunnel_width_y, 
+! tunnel_wall_depth
 ! 
 ! Former revisions:
@@ -614,4 +617,14 @@
     WRITE ( 14 )  'tsc                           '
     WRITE ( 14 )  tsc
+    WRITE ( 14 )  'tunnel_height                 '
+    WRITE ( 14 )  tunnel_height
+    WRITE ( 14 )  'tunnel_length                 '
+    WRITE ( 14 )  tunnel_length
+    WRITE ( 14 )  'tunnel_width_x                '
+    WRITE ( 14 )  tunnel_width_x
+    WRITE ( 14 )  'tunnel_width_y                '
+    WRITE ( 14 )  tunnel_width_y
+    WRITE ( 14 )  'tunnel_wall_depth             '
+    WRITE ( 14 )  tunnel_wall_depth
     WRITE ( 14 )  'collision_turbulence          '
     WRITE ( 14 )  collision_turbulence
@@ -680,8 +693,10 @@
     WRITE ( 14 )  'wall_heatflux                 '
     WRITE ( 14 )  wall_heatflux
-    WRITE ( 14 )  'wall_qflux                    '
-    WRITE ( 14 )  wall_qflux
-    WRITE ( 14 )  'wall_sflux                    '
-    WRITE ( 14 )  wall_sflux
+    WRITE ( 14 )  'wall_humidityflux             '
+    WRITE ( 14 )  wall_humidityflux
+    WRITE ( 14 )  'wall_scalarflux               '
+    WRITE ( 14 )  wall_scalarflux
+    WRITE ( 14 )  'wall_salinityflux             '
+    WRITE ( 14 )  wall_salinityflux
     WRITE ( 14 )  'w_max                         '
     WRITE ( 14 )  w_max
@@ -694,4 +709,5 @@
     WRITE ( 14 )  'z0h_factor                    '
     WRITE ( 14 )  z0h_factor  
+
 !
 !-- Set the end-of-file mark
