diff --git a/CMakeLists.txt b/CMakeLists.txt index 7304bb44d286676181f42cfd59babecc94f68240..277b8a64ccf8ff9e3aa48a89706c5012f7bea8aa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -69,6 +69,7 @@ set(SOURCES_F srcF/sfx_run.f90 srcF/sfx_phys_const.f90 srcF/sfx_surface.f90 + srcF/sfx_thermal_roughness.f90 srcF/sfx_most.f90 srcF/sfx_most_param.f90 srcF/sfx_sheba.f90 diff --git a/srcF/sfx_surface.f90 b/srcF/sfx_surface.f90 index 79ebca981a43d1dc6b1bfe91a939f78aacc26b59..8b808f596881aa2f2ce54f3b2275897609c4920a 100644 --- a/srcF/sfx_surface.f90 +++ b/srcF/sfx_surface.f90 @@ -132,6 +132,7 @@ contains surface_param%B_max_land = B_max_land end subroutine set_c_struct_sfx_surface_param_values #endif + ! charnock roughness definition ! -------------------------------------------------------------------------------- subroutine get_charnock_roughness(z0_m, u_dyn0, U, h, maxiters) diff --git a/srcF/sfx_thermal_roughness.f90 b/srcF/sfx_thermal_roughness.f90 new file mode 100644 index 0000000000000000000000000000000000000000..04755f763e1c847fcaff4ec8b5d049086c3fee3e --- /dev/null +++ b/srcF/sfx_thermal_roughness.f90 @@ -0,0 +1,141 @@ +module sfx_thermal_roughness + !< @brief surface thermal roughness parameterizations + + ! modules used + ! -------------------------------------------------------------------------------- + use sfx_phys_const + use sfx_surface + ! -------------------------------------------------------------------------------- + + ! directives list + ! -------------------------------------------------------------------------------- + implicit none + ! -------------------------------------------------------------------------------- + + ! public interface + ! -------------------------------------------------------------------------------- + public :: get_thermal_roughness_kl + public :: get_thermal_roughness_cz + public :: get_thermal_roughness_zi + public :: get_thermal_roughness_ca + ! -------------------------------------------------------------------------------- + + ! -------------------------------------------------------------------------------- + real, parameter, private :: kappa = 0.40 !< von Karman constant [n/d] + ! -------------------------------------------------------------------------------- + +contains + + + ! thermal roughness definition by (Kazakov, Lykosov) + ! -------------------------------------------------------------------------------- + subroutine get_thermal_roughness_kl(z0_t, B, & + z0_m, Re, surface_type) + ! ---------------------------------------------------------------------------- + real, intent(out) :: z0_t !< thermal roughness [m] + real, intent(out) :: B !< = log(z0_m / z0_t) [n/d] + + real, intent(in) :: z0_m !< aerodynamic roughness [m] + real, intent(in) :: Re !< roughness Reynolds number [n/d] + integer, intent(in) :: surface_type !< = [ocean] || [land] || [lake] + ! ---------------------------------------------------------------------------- + + ! --- local variables + ! ---------------------------------------------------------------------------- + + !--- define B = log(z0_m / z0_t) + if (Re <= Re_rough_min) then + B = B1_rough * alog(B3_rough * Re) + B2_rough + else + ! *: B4 takes into account Re value at z' ~ O(10) z0 + B = B4_rough * (Re**B2_rough) + end if + + ! --- apply max restriction based on surface type + if (surface_type == surface_ocean) then + B = min(B, B_max_ocean) + else if (surface_type == surface_lake) then + B = min(B, B_max_lake) + else if (surface_type == surface_land) then + B = min(B, B_max_land) + end if + + ! --- define roughness [thermal] + z0_t = z0_m / exp(B) + + end subroutine + ! -------------------------------------------------------------------------------- + + ! thermal roughness definition by (Chen, F., Zhang, Y., 2009) + ! -------------------------------------------------------------------------------- + subroutine get_thermal_roughness_cz(z0_t, B, & + z0_m, Re, surface_type) + ! ---------------------------------------------------------------------------- + real, intent(out) :: z0_t !< thermal roughness [m] + real, intent(out) :: B !< = log(z0_m / z0_t) [n/d] + + real, intent(in) :: z0_m !< aerodynamic roughness [m] + real, intent(in) :: Re !< roughness Reynolds number [n/d] + integer, intent(in) :: surface_type !< = [ocean] || [land] || [lake] + + ! --- local variables + ! ---------------------------------------------------------------------------- + + !--- define B = log(z0_m / z0_t) + B = (kappa * 10.0**(-0.4 * z0_m / 0.07)) * (Re**0.45) + + ! --- define roughness [thermal] + z0_t = z0_m / exp(B) + + end subroutine + ! -------------------------------------------------------------------------------- + + ! thermal roughness definition by (Zilitinkevich, S., 1995) + ! -------------------------------------------------------------------------------- + subroutine get_thermal_roughness_zi(z0_t, B, & + z0_m, Re, surface_type) + ! ---------------------------------------------------------------------------- + real, intent(out) :: z0_t !< thermal roughness [m] + real, intent(out) :: B !< = log(z0_m / z0_t) [n/d] + + real, intent(in) :: z0_m !< aerodynamic roughness [m] + real, intent(in) :: Re !< roughness Reynolds number [n/d] + integer, intent(in) :: surface_type !< = [ocean] || [land] || [lake] + + ! --- local variables + ! ---------------------------------------------------------------------------- + + !--- define B = log(z0_m / z0_t) + B = 0.1 * kappa * (Re**0.5) + + ! --- define roughness [thermal] + z0_t = z0_m / exp(B) + + end subroutine + ! -------------------------------------------------------------------------------- + + ! thermal roughness definition by (Cahill, A.T., Parlange, M.B., Albertson, J.D., 1997) + ! -------------------------------------------------------------------------------- + subroutine get_thermal_roughness_ca(z0_t, B, & + z0_m, Re, surface_type) + ! ---------------------------------------------------------------------------- + real, intent(out) :: z0_t !< thermal roughness [m] + real, intent(out) :: B !< = log(z0_m / z0_t) [n/d] + + real, intent(in) :: z0_m !< aerodynamic roughness [m] + real, intent(in) :: Re !< roughness Reynolds number [n/d] + integer, intent(in) :: surface_type !< = [ocean] || [land] || [lake] + + ! --- local variables + ! ---------------------------------------------------------------------------- + + !--- define B = log(z0_m / z0_t) + B = 2.46 * (Re**0.25) - 3.8 + + ! --- define roughness [thermal] + z0_t = z0_m / exp(B) + + end subroutine + ! -------------------------------------------------------------------------------- + +end module sfx_thermal_roughness