diff --git a/CMakeLists.txt b/CMakeLists.txt
index f2d4ef2d87474b1f0c9a93b69ec46842bd77127f..1ea93b8d37358c65720167f2e88ec66082241da7 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -48,6 +48,7 @@ set(SOURCES
     obl_k_epsilon.f90
     obl_pph.f90
     obl_pph_dyn.f90
+    obl_most.f90
     obl_fluxes.f90
     obl_scm.f90
     obl_main.f90
diff --git a/obl_config.f90 b/obl_config.f90
index 24efc529eda2c1520fef9fe58e6f00ff27d655fc..cf81293d674c98ceae89b6da1115975cb0595216 100644
--- a/obl_config.f90
+++ b/obl_config.f90
@@ -35,10 +35,12 @@ module obl_config
     integer, parameter :: obl_model_pph = 0             !< pacanowski-philander 
     integer, parameter :: obl_model_pph_dyn = 1         !< pacanowski-philander (dynamic)
     integer, parameter :: obl_model_k_epsilon = 2       !< k-epsilon
+    integer, parameter :: obl_model_most = 3            !< most scheme
 
     character(len = 16), parameter :: obl_model_pph_tag = 'pph'
     character(len = 16), parameter :: obl_model_pph_dyn_tag = 'pph-dyn'
     character(len = 16), parameter :: obl_model_k_epsilon_tag = 'k-epsilon'
+    character(len = 16), parameter :: obl_model_most_tag = 'most'
 
 
 contains
@@ -97,6 +99,8 @@ contains
             id = obl_model_pph_dyn
         else if (trim(tag) == trim(obl_model_k_epsilon_tag)) then
             id = obl_model_k_epsilon
+        else if (trim(tag) == trim(obl_model_most_tag)) then
+            id = obl_model_most
         end if
 
     end function
@@ -113,6 +117,8 @@ contains
             tag = obl_model_pph_dyn_tag
         else if (id == obl_model_k_epsilon) then
             tag = obl_model_k_epsilon_tag
+        else if (id == obl_model_most) then
+            tag = obl_model_most_tag
         end if 
 
     end function
diff --git a/obl_main.f90 b/obl_main.f90
index a9786c7e72c4c2b14b8a9251697f33890a4f24f6..9a63c122b6fc243c572e45d7ba498117fc460d27 100644
--- a/obl_main.f90
+++ b/obl_main.f90
@@ -41,6 +41,11 @@ program obl_main
         init_turbulence_closure_k_epsilon => init_turbulence_closure, & 
         advance_turbulence_closure_k_epsilon => advance_turbulence_closure, &
         TKE_init, EPS_init, TKE_bc, EPS_bc
+    use obl_most, only: mostParamType, &
+        set_config_param_most => set_config_param, &
+        define_stability_functions_most => define_stability_functions, &
+        init_turbulence_closure_most => init_turbulence_closure, & 
+        advance_turbulence_closure_most => advance_turbulence_closure
     use obl_io_plt
     use io
     use io_metadata
@@ -69,6 +74,7 @@ program obl_main
     type(pphParamType) :: param_pph
     type(pphDynParamType) :: param_pph_dyn
     type(kepsilonParamType) :: param_k_epsilon
+    type(mostParamType) :: param_most
 
     !< boundary conditions data
     type(oblBcType) :: bc
@@ -131,6 +137,7 @@ program obl_main
     !<      = obl_model_pph, pacanowski-philander
     !<      = obl_model_pph_dyn, pacanowski-philander (dynamic)
     !<      = obl_model_k_epsilon, k-epsilon
+    !<      = obl_model_most, MOST scheme
     obl_model_id = obl_model_k_epsilon
 
     !< default output = 1, (netcdf)
@@ -153,7 +160,7 @@ program obl_main
             write(*, *) '    builtin setup [key] = kato (default) || papa-fluxes || papa-meteo || cbl || cyclone'
             write(*, *) '    use configuration file [filename]'
             write(*, *) ' --model [key]'
-            write(*, *) '    [key] = pph || pph-dyn || k-epsilon (default)'
+            write(*, *) '    [key] = pph || pph-dyn || k-epsilon (default) || most'
             return
         end if
 
@@ -297,6 +304,9 @@ program obl_main
     else if (obl_model_id.eq.obl_model_k_epsilon) then
         call define_stability_functions_k_epsilon(param_k_epsilon, bc, grid)
         call init_turbulence_closure_k_epsilon(param_k_epsilon, bc, grid)
+    else if (obl_model_id.eq.obl_model_most) then
+        call define_stability_functions_most(param_most, bc, grid)
+        call init_turbulence_closure_most(param_most, bc, grid)
     endif
     ! ---------------------------------------------------------------------------- 
 
@@ -326,6 +336,9 @@ program obl_main
         else if (obl_model_id.eq.obl_model_k_epsilon) then
             call define_stability_functions_k_epsilon(param_k_epsilon, bc, grid)
             call advance_turbulence_closure_k_epsilon(param_k_epsilon, bc, grid, dt)
+        else if (obl_model_id.eq.obl_model_most) then
+            call define_stability_functions_most(param_most, bc, grid)
+            call advance_turbulence_closure_most(param_most, bc, grid, dt)
         endif
         ! ----------------------------------------------------------------------------
 
diff --git a/obl_most.f90 b/obl_most.f90
new file mode 100644
index 0000000000000000000000000000000000000000..d493864f63f6c4a5efdadaf63171760cc085e363
--- /dev/null
+++ b/obl_most.f90
@@ -0,0 +1,374 @@
+#include "obl_def.fi"
+
+module obl_most
+    !< @brief MOST based scheme
+    ! --------------------------------------------------------------------------------
+
+    ! modules used
+    ! --------------------------------------------------------------------------------
+#ifdef USE_CONFIG_PARSER
+    use iso_c_binding, only: C_NULL_CHAR
+    use config_parser
+#endif
+
+    use obl_grid
+    use obl_bc
+    use obl_turb_common
+
+    ! directives list
+    ! --------------------------------------------------------------------------------
+    implicit none
+    private
+
+    ! public interface
+    ! --------------------------------------------------------------------------------
+    public :: init_turbulence_closure
+    public :: advance_turbulence_closure
+    public :: define_stability_functions
+
+    public :: get_eddy_viscosity, get_eddy_diffusivity
+    public :: get_eddy_viscosity_vec, get_eddy_diffusivity_vec
+
+    public :: set_config_param
+    ! --------------------------------------------------------------------------------
+
+    !> @brief MOST scheme parameters
+    type, public :: mostParamType
+        real :: Ri_g_cr = 0.20      !< critical gradient Richardson number [n/d]
+
+        !< stability functions in unstable case
+        real :: Ri_g_m = -0.20
+        real :: Ri_g_h = -1.0
+
+        real :: a_m = 16.0
+        real :: b_m = 1.26
+        real :: c_m = 8.38
+
+        real :: a_h = 16.0
+        real :: b_h = -28.86
+        real :: c_h = 98.96
+        !< 
+
+        real :: Km_b = 0.0001       !< background eddy viscosity, [m**2 / s]  
+        real :: Kh_b = 0.00005      !< background eddy diffusivity, [m**2 / s]
+
+        real :: kappa = 0.4         !< von Karman constant, [n/d]
+        real :: PrT0 = 1.0          !< neutral Prandtl number, [n/d]
+
+        real :: c_S2_min = 1e-5     !< min shear frequency, [(1/s)**2]
+    end type
+
+    contains
+
+
+    ! --------------------------------------------------------------------------------
+    subroutine define_stability_functions(param, bc, grid)
+        !< @brief advance stability functions: N**2, S**2, Ri-gradient
+        ! ----------------------------------------------------------------------------
+        use obl_state
+
+        type(mostParamType), intent(in) :: param
+        type(oblBcType), intent(in) :: bc
+        type (gridDataType), intent(in) :: grid
+        ! --------------------------------------------------------------------------------
+
+        call get_N2(N2, Rho, bc%rho_dyn0, bc%rho_dynH, & 
+            param%kappa, param%PrT0, grid)
+        call get_S2(S2, U, V, bc%U_dyn0, bc%U_dynH, &
+            param%kappa, grid)
+        call get_Ri_gradient(Ri_grad, N2, S2, param%c_S2_min, grid)
+    end subroutine
+
+    ! --------------------------------------------------------------------------------
+    subroutine init_turbulence_closure(param, bc, grid)
+        !< @brief advance turbulence closure
+        ! ----------------------------------------------------------------------------
+        use obl_state
+
+        type(mostParamType), intent(in) :: param
+        type(oblBcType), intent(in) :: bc
+        type (gridDataType), intent(in) :: grid
+        ! --------------------------------------------------------------------------------
+
+        call get_eddy_viscosity(Km, Ri_grad, S2, bc%U_dynH, param, grid)
+        call get_eddy_diffusivity(Kh, Ri_grad, S2, bc%U_dynH, param, grid)
+    end subroutine
+
+    ! --------------------------------------------------------------------------------
+    subroutine advance_turbulence_closure(param, bc, grid, dt)
+        !< @brief advance turbulence closure
+        ! ----------------------------------------------------------------------------
+        use obl_state
+
+        type(mostParamType), intent(in) :: param
+        type(oblBcType), intent(in) :: bc
+        type (gridDataType), intent(in) :: grid
+        real, intent(in) :: dt
+        ! --------------------------------------------------------------------------------
+
+        call get_TKE_production(TKE_production, Km, S2, grid)
+        call get_TKE_buoyancy(TKE_buoyancy, Kh, N2, grid)
+
+        call get_eddy_viscosity(Km, Ri_grad, S2, bc%U_dynH, param, grid)
+        call get_eddy_diffusivity(Kh, Ri_grad, S2, bc%U_dynH, param, grid)
+    end subroutine
+    
+    ! --------------------------------------------------------------------------------
+    subroutine get_eddy_viscosity(Km, Ri_grad, S2, U_dynH, param, grid)
+        !< @brief calculate eddy viscosity on grid
+        ! ----------------------------------------------------------------------------
+        type(mostParamType), intent(in) :: param
+        type (gridDataType), intent(in) :: grid
+
+        real, dimension(grid%cz), intent(in) :: Ri_grad      !< Richardson gradient number
+        real, dimension(grid%cz), intent(in) :: S2           !< square of shear frequency [1 / s**2] 
+        real, intent(in) :: U_dynH                     !< surface velocity scale [m/s] 
+        real, dimension(grid%cz), intent(out) :: Km          !< eddy viscosity, [m**2 / s]
+
+        real, dimension(grid%cz) :: depth
+        integer :: k
+        ! --------------------------------------------------------------------------------
+
+        do k = 1, grid%cz 
+            depth(k) = grid%zpos + grid%height - grid%z(k)
+        end do
+
+        call get_eddy_viscosity_vec(Km, Ri_grad, S2, U_dynH, param, depth, grid%cz)
+    end subroutine
+
+    subroutine get_eddy_viscosity_vec(Km, Ri_grad, S2, U_dynH, param, depth, n)
+        !< @brief calculate eddy viscosity
+        ! ----------------------------------------------------------------------------
+        type(mostParamType), intent(in) :: param
+
+        integer, intent(in) :: n                       !< vector size
+        real, dimension(n), intent(in) :: Ri_grad      !< Richardson gradient number 
+        real, dimension(n), intent(in) :: S2           !< square of shear frequency [1 / s**2] 
+        real, intent(in) :: U_dynH                     !< surface velocity scale [m/s]
+        real, dimension(n), intent(in) :: depth        !< depth coordinates, [m] 
+        real, dimension(n), intent(out) :: Km          !< eddy viscosity, [m**2 / s]
+
+        real :: l_m
+        real :: g_m
+        integer :: k
+        ! --------------------------------------------------------------------------------
+    
+        do k = 1, n
+            if (Ri_grad(k) >= 0.0) then
+                !< stable case
+                Km(k) = param%Km_b 
+                if (Ri_grad(k) <= param%Ri_g_cr) then
+                    l_m = param%kappa * depth(k) * (1.0 - Ri_grad(k) / param%Ri_g_cr)
+                    Km(k) = Km(k) + l_m * l_m * sqrt(S2(k))
+                endif
+            else 
+                !< unstable case
+                if (Ri_grad(k) >= param%Ri_g_m) then
+                    g_m = (1.0 - param%a_m * Ri_grad(k))**0.25
+                else
+                    g_m = (param%b_m - param%c_m * Ri_grad(k))**(1.0 / 3.0)
+                endif
+                l_m = param%kappa * depth(k) * g_m
+                Km(k) = l_m * l_m * sqrt(max(S2(k), param%c_S2_min))
+            endif
+        end do
+    end subroutine
+
+    ! --------------------------------------------------------------------------------
+    subroutine get_eddy_diffusivity(Kh, Ri_grad, S2, U_dynH, param, grid)
+        !< @brief calculate eddy diffusivity on grid
+        ! ----------------------------------------------------------------------------
+        type(mostParamType), intent(in) :: param
+        type (gridDataType), intent(in) :: grid
+
+        real, dimension(grid%cz), intent(in) :: Ri_grad      !< Richardson gradient number 
+        real, dimension(grid%cz), intent(in) :: S2           !< square of shear frequency [1 / s**2]
+        real, intent(in) :: U_dynH                           !< surface velocity scale [m/s] 
+        real, dimension(grid%cz), intent(out) :: Kh          !< eddy diffusivity, [m**2 / s]
+
+        real, dimension(grid%cz) :: depth
+        integer :: k
+        ! --------------------------------------------------------------------------------
+
+        do k = 1, grid%cz 
+            depth(k) = grid%zpos + grid%height - grid%z(k)
+        end do
+        
+        call get_eddy_diffusivity_vec(Kh, Ri_grad, S2, U_dynH, param, depth, grid%cz)
+    end subroutine
+
+    subroutine get_eddy_diffusivity_vec(Kh, Ri_grad, S2, U_dynH, param, depth, n)
+        !< @brief calculate eddy diffusivity
+        ! ----------------------------------------------------------------------------
+        type(mostParamType), intent(in) :: param
+
+        integer, intent(in) :: n                       !< vector size
+        real, dimension(n), intent(in) :: Ri_grad      !< Richardson gradient number 
+        real, dimension(n), intent(in) :: S2           !< square of shear frequency [1 / s**2]
+        real, intent(in) :: U_dynH                     !< surface velocity scale [m/s]
+        real, dimension(n), intent(in) :: depth        !< depth coordinates, [m]  
+        real, dimension(n), intent(out) :: Kh          !< eddy diffusivity, [m**2 / s]
+        
+        real :: l_m, l_h
+        real :: g_m, g_h
+        integer :: k
+        ! --------------------------------------------------------------------------------
+
+        do k = 1, n
+            if (Ri_grad(k) >= 0.0) then
+                !< stable case
+                Kh(k) = param%Kh_b 
+                if (Ri_grad(k) <= param%Ri_g_cr) then
+                    l_m = param%kappa * depth(k) * (1.0 - Ri_grad(k) / param%Ri_g_cr)
+                    Kh(k) = Kh(k) + (1.0 / param%PrT0) * l_m * l_m * sqrt(S2(k))
+                endif
+            else 
+                !< unstable case
+                if (Ri_grad(k) >= param%Ri_g_h) then
+                    g_m = (1.0 - param%a_m * Ri_grad(k))**0.25
+                    g_h = (1.0 - param%a_h * Ri_grad(k))**0.5
+                else
+                    g_m = (param%b_m - param%c_m * Ri_grad(k))**(1.0 / 3.0)
+                    g_h = (param%b_h - param%c_h * Ri_grad(k))**(1.0 / 3.0)
+                endif
+                l_m = param%kappa * depth(k) * g_m
+                l_h = param%kappa * depth(k) * g_h
+                Kh(k) = (1.0 / param%PrT0) * l_m * l_h * sqrt(max(S2(k), param%c_S2_min))
+            endif
+        end do
+    end subroutine
+
+    ! --------------------------------------------------------------------------------
+    subroutine set_config_param(param, tag, ierr)
+        !< @brief set turbulence closure parameters
+        ! ----------------------------------------------------------------------------
+        type(mostParamType), intent(out) :: param
+        integer, intent(out) :: ierr
+
+        character(len = *), intent(in) :: tag
+
+        integer :: status
+        ! --------------------------------------------------------------------------------
+
+        ierr = 0        ! = OK
+
+#ifdef USE_CONFIG_PARSER
+        call c_config_is_varname(trim(tag)//".Ri_g_cr"//C_NULL_CHAR, status)
+        if (status /= 0) then
+            call c_config_get_float(trim(tag)//".Ri_g_cr"//C_NULL_CHAR, param%Ri_g_cr, status)
+            if (status == 0) then
+                ierr = 1        ! signal ERROR
+                return
+            end if
+        endif
+        call c_config_is_varname(trim(tag)//".Ri_g_m"//C_NULL_CHAR, status)
+        if (status /= 0) then
+            call c_config_get_float(trim(tag)//".Ri_g_m"//C_NULL_CHAR, param%Ri_g_m, status)
+            if (status == 0) then
+                ierr = 1        ! signal ERROR
+                return
+            end if
+        endif
+        call c_config_is_varname(trim(tag)//".Ri_g_h"//C_NULL_CHAR, status)
+        if (status /= 0) then
+            call c_config_get_float(trim(tag)//".Ri_g_h"//C_NULL_CHAR, param%Ri_g_h, status)
+            if (status == 0) then
+                ierr = 1        ! signal ERROR
+                return
+            end if
+        endif
+        call c_config_is_varname(trim(tag)//".a_m"//C_NULL_CHAR, status)
+        if (status /= 0) then
+            call c_config_get_float(trim(tag)//".a_m"//C_NULL_CHAR, param%a_m, status)
+            if (status == 0) then
+                ierr = 1        ! signal ERROR
+                return
+            end if
+        endif
+        call c_config_is_varname(trim(tag)//".b_m"//C_NULL_CHAR, status)
+        if (status /= 0) then
+            call c_config_get_float(trim(tag)//".b_m"//C_NULL_CHAR, param%b_m, status)
+            if (status == 0) then
+                ierr = 1        ! signal ERROR
+                return
+            end if
+        endif
+        call c_config_is_varname(trim(tag)//".c_m"//C_NULL_CHAR, status)
+        if (status /= 0) then
+            call c_config_get_float(trim(tag)//".c_m"//C_NULL_CHAR, param%c_m, status)
+            if (status == 0) then
+                ierr = 1        ! signal ERROR
+                return
+            end if
+        endif
+        call c_config_is_varname(trim(tag)//".a_h"//C_NULL_CHAR, status)
+        if (status /= 0) then
+            call c_config_get_float(trim(tag)//".a_h"//C_NULL_CHAR, param%a_h, status)
+            if (status == 0) then
+                ierr = 1        ! signal ERROR
+                return
+            end if
+        endif
+        call c_config_is_varname(trim(tag)//".b_h"//C_NULL_CHAR, status)
+        if (status /= 0) then
+            call c_config_get_float(trim(tag)//".b_h"//C_NULL_CHAR, param%b_h, status)
+            if (status == 0) then
+                ierr = 1        ! signal ERROR
+                return
+            end if
+        endif
+        call c_config_is_varname(trim(tag)//".c_h"//C_NULL_CHAR, status)
+        if (status /= 0) then
+            call c_config_get_float(trim(tag)//".c_h"//C_NULL_CHAR, param%c_h, status)
+            if (status == 0) then
+                ierr = 1        ! signal ERROR
+                return
+            end if
+        endif
+        call c_config_is_varname(trim(tag)//".Km_b"//C_NULL_CHAR, status)
+        if (status /= 0) then
+            call c_config_get_float(trim(tag)//".Km_b"//C_NULL_CHAR, param%Km_b, status)
+            if (status == 0) then
+                ierr = 1        ! signal ERROR
+                return
+            end if
+        endif
+        call c_config_is_varname(trim(tag)//".Kh_b"//C_NULL_CHAR, status)
+        if (status /= 0) then
+            call c_config_get_float(trim(tag)//".Kh_b"//C_NULL_CHAR, param%Kh_b, status)
+            if (status == 0) then
+                ierr = 1        ! signal ERROR
+                return
+            end if
+        endif
+        call c_config_is_varname(trim(tag)//".kappa"//C_NULL_CHAR, status)
+        if (status /= 0) then
+            call c_config_get_float(trim(tag)//".kappa"//C_NULL_CHAR, param%kappa, status)
+            if (status == 0) then
+                ierr = 1        ! signal ERROR
+                return
+            end if
+        endif
+        call c_config_is_varname(trim(tag)//".PrT0"//C_NULL_CHAR, status)
+        if (status /= 0) then
+            call c_config_get_float(trim(tag)//".PrT0"//C_NULL_CHAR, param%PrT0, status)
+            if (status == 0) then
+                ierr = 1        ! signal ERROR
+                return
+            end if
+        endif
+        call c_config_is_varname(trim(tag)//".c_S2_min"//C_NULL_CHAR, status)
+        if (status /= 0) then
+            call c_config_get_float(trim(tag)//".c_S2_min"//C_NULL_CHAR, param%c_S2_min, status)
+            if (status == 0) then
+                ierr = 1        ! signal ERROR
+                return
+            end if
+        endif
+#else
+        !> *: just skipping setup without configuration file
+#endif
+
+    end subroutine
+    
+end module