diff --git a/makefile b/makefile
index e36063b21f51e4d3a8e88e96593d4e2bc051e039..a9f87d3ba74a6fa4714d422ca0af62d903a53483 100644
--- a/makefile
+++ b/makefile
@@ -10,7 +10,7 @@ ifeq ($(COMPILER),gnu)
   FC = gfortran
 endif 
 
-OBJ_F90 = sfx_phys_const.o sfx_common.o sfx_config.o sfx_io.o sfx_data.o sfx_surface.o sfx_log_param.o sfx_log.o sfx_most_param.o sfx_most.o sfx_most_snow_param.o sfx_most_snow.o sfx_sheba_param.o sfx_sheba.o sfx_esm_param.o sfx_esm.o sfx_run.o sfx_main.o
+OBJ_F90 = sfx_phys_const.o sfx_common.o  sfx_io.o sfx_data.o  sfx_z0m_all_surface.o sfx_surface.o sfx_config.o sfx_log_param.o sfx_log.o sfx_most_param.o sfx_most.o sfx_most_snow_param.o sfx_most_snow.o sfx_sheba_param.o sfx_sheba.o sfx_esm_param.o sfx_esm.o sfx_run.o sfx_main.o
 OBJ_F =
 OBJ = $(OBJ_F90) $(OBJ_F)
 
diff --git a/srcF/sfx_most_snow.f90 b/srcF/sfx_most_snow.f90
index 9b022d15391c318540b722c49fa46358359caf95..008fd65742551386c28fe5134941f030d661b55d 100644
--- a/srcF/sfx_most_snow.f90
+++ b/srcF/sfx_most_snow.f90
@@ -24,6 +24,7 @@ module sfx_most_snow
     public :: get_surface_fluxes
     public :: get_surface_fluxes_vec
     public :: get_psi
+    integer z0m_id
     ! --------------------------------------------------------------------------------
 
     ! --------------------------------------------------------------------------------
@@ -91,6 +92,7 @@ contains
         real :: Tsemi   !< semi-sum of potential temperature at 'h' and at surface [K]
         real :: dQ      !< difference between humidity at 'h' and at surface [g/g]
         real :: z0_m    !< surface aerodynamic roughness (should be < 0 for water bodies surface)
+        real :: z0_map    !< surface aerodynamic roughness (should be < 0 for water bodies surface)
         ! ----------------------------------------------------------------------------
 
         ! --- local variables
@@ -121,7 +123,7 @@ contains
 		real S_mean, Lsnow
 	    real z0_s, h_salt
                 
-	
+	   
 		integer surface_type    !< surface type = (ocean || land)
 
 
@@ -153,8 +155,14 @@ contains
         dT = meteo%dT
         dQ = meteo%dQ
         h = meteo%h
-        z0_m = meteo%z0_m
+        !z0_m = meteo%z0_m
+        z0_map = meteo%z0_m
 
+        
+        call get_dynamic_roughness_definition(surface_type, ocean_z0m_id, land_z0m_id, lake_z0m_id, snow_z0m_id, &
+        forest_z0m_id, usersf_z0m_id, z0m_id)
+        
+        call get_dynamic_roughness_all(z0_m, u_dyn0, U, depth, h, numerics%maxiters_charnock, z0_map, z0m_id)
         ! --- define surface type
         if (z0_m < 0.0) then
             surface_type = surface_ocean
diff --git a/srcF/sfx_surface.f90 b/srcF/sfx_surface.f90
index 55329333be8a4326b204448185dcace6f9bbf329..a7c9b37d21db7d002fdc2222a3e663cfa68817d3 100644
--- a/srcF/sfx_surface.f90
+++ b/srcF/sfx_surface.f90
@@ -6,6 +6,7 @@ module sfx_surface
     ! modules used
     ! --------------------------------------------------------------------------------
     use sfx_phys_const
+    use sfx_z0m_all_surface
     ! --------------------------------------------------------------------------------
 
     ! directives list
@@ -20,6 +21,8 @@ module sfx_surface
 #endif
     public :: get_charnock_roughness
     public :: get_thermal_roughness
+    public :: get_dynamic_roughness_all
+    public :: get_dynamic_roughness_definition
     ! --------------------------------------------------------------------------------
 
 
@@ -28,12 +31,39 @@ module sfx_surface
     integer, public, parameter :: surface_land = 1      !< land surface
     integer, public, parameter :: surface_lake = 2      !< lake surface
     integer, public, parameter :: surface_snow = 3      !< snow covered surface
+    integer, public, parameter :: surface_forest = 4      !< snow covered surface
+    integer, public, parameter :: surface_user = 5      !< snow covered surface
 
     character(len = 16), parameter :: surface_ocean_tag = 'ocean'
     character(len = 16), parameter :: surface_land_tag = 'land'
     character(len = 16), parameter :: surface_lake_tag = 'lake'
     character(len = 16), parameter :: surface_snow_tag = 'snow'
+    character(len = 16), parameter :: surface_forest_tag = 'forest'
+    character(len = 16), parameter :: surface_user_tag = 'user'
 
+
+    integer, public, parameter :: z0m_ch = 0 
+    integer, public, parameter :: z0m_fe = 1   
+    integer, public, parameter :: z0m_ow = 2  
+    integer, public, parameter :: z0m_map = 3      
+    integer, public, parameter :: z0m_user = 4 
+
+
+    character(len = 16), parameter :: z0m_tag_ch = 'charnock'
+    character(len = 16), parameter :: z0m_tag_fe = 'fetch'
+    character(len = 16), parameter :: z0m_tag_ow = 'owen'
+    character(len = 16), parameter :: z0m_tag_map = 'map'
+    character(len = 16), parameter :: z0m_tag_user = 'user'
+    
+
+    integer, public, parameter :: ocean_z0m_id = z0m_ch     !< ocean surface
+    integer, public, parameter :: land_z0m_id = z0m_map        !< land surface
+    integer, public, parameter :: lake_z0m_id = z0m_fe        !< lake surface
+    integer, public, parameter :: snow_z0m_id = z0m_ow        !< snow covered surface    
+    integer, public, parameter :: forest_z0m_id = z0m_map     !< forest csurface  
+    integer, public, parameter :: usersf_z0m_id = z0m_map       !< user surface  
+
+    real, public, parameter :: depth = 1.0
     ! --------------------------------------------------------------------------------
     real, parameter, private :: kappa = 0.40         !< von Karman constant [n/d]
     ! --------------------------------------------------------------------------------
@@ -42,12 +72,12 @@ module sfx_surface
     !<     z0 = Re_visc_min * (nu / u_dyn) + gamma_c * (u_dyn^2 / g)
     ! --------------------------------------------------------------------------------
     
-    real, parameter :: gamma_c = 0.0144
-    real, parameter :: Re_visc_min = 0.111
+    !real, parameter :: gamma_c = 0.0144
+    !real, parameter :: Re_visc_min = 0.111
 
-    real, parameter :: h_charnock = 10.0
-    real, parameter :: c1_charnock = log(h_charnock * (g / gamma_c))
-    real, parameter :: c2_charnock = Re_visc_min * nu_air * (g / gamma_c)
+    !real, parameter :: h_charnock = 10.0
+    !real, parameter :: c1_charnock = log(h_charnock * (g / gamma_c))
+    !real, parameter :: c2_charnock = Re_visc_min * nu_air * (g / gamma_c)
     ! --------------------------------------------------------------------------------
 
     !< Re fully roughness minimum value [n/d]
@@ -85,6 +115,10 @@ contains
             id = surface_lake
         else if (trim(tag) == trim(surface_snow_tag)) then
             id = surface_snow
+        else if (trim(tag) == trim(surface_forest_tag)) then
+            id = surface_forest
+        else if (trim(tag) == trim(surface_user_tag)) then
+            id = surface_user
         end if
 
     end function
@@ -103,10 +137,55 @@ contains
             tag = surface_lake_tag
         else if (id == surface_snow) then
             tag = surface_snow_tag
+        else if (id == surface_forest) then
+            tag = surface_forest_tag
+        else if (id == surface_user) then
+            tag = surface_user_tag
         end if 
 
     end function
 
+
+    function get_surface_z0m_id(tag_z0m) result(z0m_id)
+        implicit none
+        character(len=*), intent(in) :: tag_z0m
+        integer :: z0m_id
+
+        z0m_id = - 1
+        if (trim(tag_z0m) == trim(z0m_tag_ch)) then
+            z0m_id = z0m_ch
+        else if (trim(tag_z0m) == trim(z0m_tag_fe)) then
+            z0m_id = z0m_fe
+        else if (trim(tag_z0m) == trim(z0m_tag_ow)) then
+            z0m_id = z0m_ow
+        else if (trim(tag_z0m) == trim(z0m_tag_map)) then
+            z0m_id = z0m_map
+        else if (trim(tag_z0m) == trim(z0m_tag_user)) then
+            z0m_id = z0m_user
+        end if
+
+    end function
+
+    function get_surface_z0m_tag(z0m_id) result(tag_z0m)
+        implicit none
+        integer :: z0m_id
+        character(len=:), allocatable :: tag_z0m
+
+        tag_z0m = 'undefined'
+        if (z0m_id == z0m_ch) then
+            tag_z0m = z0m_tag_ch
+        else if (z0m_id == z0m_fe) then
+            tag_z0m =  z0m_tag_fe
+        else if (z0m_id == z0m_ow) then
+            tag_z0m = z0m_tag_ow
+        else if (z0m_id == z0m_map) then
+            tag_z0m = z0m_tag_map
+        else if (z0m_id == z0m_user) then
+            tag_z0m = z0m_tag_user
+        end if 
+     end function
+
+
 #if defined(INCLUDE_CXX)
     subroutine set_c_struct_sfx_surface_param_values(surface_param)
         use sfx_data
@@ -133,9 +212,77 @@ contains
     end subroutine set_c_struct_sfx_surface_param_values
 #endif
 
-    ! charnock roughness definition
+    ! dynamic roughness definition
     ! --------------------------------------------------------------------------------
-    subroutine get_charnock_roughness(z0_m, u_dyn0, U, h, maxiters)
+      subroutine get_dynamic_roughness_definition(surface_type, ocean_z0m_id, land_z0m_id, lake_z0m_id, snow_z0m_id, &
+        forest_z0m_id, usersf_z0m_id, z0m_id)
+    ! ----------------------------------------------------------------------------
+        integer, intent(out) :: z0m_id              
+
+        integer, intent(in) :: surface_type             
+
+        integer, intent(in) :: ocean_z0m_id            
+        integer, intent(in) :: land_z0m_id             
+        integer, intent(in) :: lake_z0m_id
+        integer, intent(in) :: snow_z0m_id
+        integer, intent(in) :: forest_z0m_id
+        integer, intent(in) :: usersf_z0m_id
+    
+ ! ---------------------------------------------------------------------------
+
+    if (surface_type == surface_ocean) then
+     z0m_id = ocean_z0m_id
+    else if (surface_type == surface_land) then
+     z0m_id = land_z0m_id
+    else if (surface_type == surface_snow) then
+     z0m_id = snow_z0m_id
+    else if (surface_type == surface_lake) then
+    z0m_id = lake_z0m_id
+    else if (surface_type == surface_forest) then
+     z0m_id = forest_z0m_id
+    else if (surface_type == surface_user) then
+     z0m_id  = usersf_z0m_id
+    end if 
+ 
+ end subroutine
+
+    ! ----------------------------------------------------------------------------
+ subroutine get_dynamic_roughness_all(z0_m, u_dyn0, U, depth, h,&
+    maxiters, z0m_map, z0m_id)
+! ----------------------------------------------------------------------------
+       real, intent(out) :: z0_m           !< aerodynamic roughness [m]
+       real, intent(out) :: u_dyn0         !< dynamic velocity in neutral conditions [m/s]
+
+       real, intent(in) :: U               !< abs(wind speed) [m/s]
+       real, intent(in) :: depth           !< depth [m]
+       real, intent(in) :: h               !< constant flux layer height [m]
+       real, intent(in) :: z0m_map          !< aerodynamic roughness from map [m]
+       integer, intent(in) :: maxiters     !< maximum number of iterations
+       
+       integer, intent(in) :: z0m_id
+! ---------------------------------------------------------------------------
+
+        
+  if (z0m_id == z0m_ch) then
+      call get_dynamic_roughness_ch(z0_m, u_dyn0, U, h, maxiters)
+   else if (z0m_id == z0m_fe) then
+       call get_dynamic_roughness_fetch(z0_m, u_dyn0, U, depth, h, maxiters)
+   else if (z0m_id == z0m_ow) then
+       call get_dynamic_roughness_ow(z0_m, u_dyn0, U, h, maxiters)
+   else if (z0m_id == z0m_map) then
+       call get_dynamic_roughness_map(z0_m, u_dyn0, U, h, z0m_map)
+   else if (z0m_id == z0m_user) then
+       write(*, *) 'z0m_user'
+end if 
+
+end subroutine
+! --------------------------------------------------------------------------------  
+
+
+
+
+
+      subroutine get_charnock_roughness(z0_m, u_dyn0, U, h, maxiters)
         ! ----------------------------------------------------------------------------
         real, intent(out) :: z0_m           !< aerodynamic roughness [m]
         real, intent(out) :: u_dyn0         !< dynamic velocity in neutral conditions [m/s]
diff --git a/srcF/sfx_z0m_all.f90 b/srcF/sfx_z0m_all.f90
index c325e4d427b0e5d9b059731750bdd33c083e82bd..2dac487bc5de3f639948cf6b1d364f801593a5a0 100644
--- a/srcF/sfx_z0m_all.f90
+++ b/srcF/sfx_z0m_all.f90
@@ -168,16 +168,10 @@ module sfx_z0m_all
    
    ! ----------------------------------------------------------------------------
        subroutine get_dynamic_roughness_definition(surface_type, id_ocean, id_land, id_snow, id_lake, &
-        id_forest, id_user, ocean_z0m_id, land_z0m_id, lake_z0m_id, snow_z0m_id, &
-        forest_z0m_id, usersf_z0m_id)
+        id_forest, id_user, z0m_id)
      ! ----------------------------------------------------------------------------
-        real, intent(out) :: ocean_z0m_id              
-        real, intent(out) :: land_z0m_id                 
-        real, intent(out) :: lake_z0m_id  
-        real, intent(out) :: snow_z0m_id 
-        real, intent(out) :: forest_z0m_id  
-        real, intent(out) :: usersf_z0m_id 
-
+        real, intent(out) :: z0m_id              
+    
         real, intent(in) :: surface_type             
 
         real, intent(in) :: id_ocean              
@@ -190,17 +184,17 @@ module sfx_z0m_all
      ! ---------------------------------------------------------------------------
 
      if (surface_type == surface_ocean) then
-         ocean_z0m_id = id_ocean
+         z0m_id = id_ocean
      else if (surface_type == surface_land) then
-         land_z0m_id = id_land
+         z0m_id = id_land
      else if (surface_type == surface_snow) then
-         snow_z0m_id = id_snow
+         z0m_id = id_snow
      else if (surface_type == surface_lake) then
-        lake_z0m_id = id_lake
+        z0m_id = id_lake
      else if (surface_type == surface_forest) then
-         forest_z0m_id = id_forest
+         z0m_id = id_forest
      else if (surface_type == surface_user) then
-         usersf_z0m_id  = id_user
+         z0m_id  = id_user
      end if 
      
      end subroutine