From 1de9b15ad6d12d22814d9ef4c8c18eea76bf03df Mon Sep 17 00:00:00 2001
From: Evgeny Mortikov <evgeny.mortikov@gmail.com>
Date: Mon, 18 Dec 2023 04:39:00 +0300
Subject: [PATCH] separating 'surface' module for aerodynamics and thermal
 roughness calculation

---
 compile.sh                                  |  4 +-
 makefile                                    |  2 +-
 srcF/sfx_data.f90                           |  4 --
 srcF/sfx_def.fi                             |  2 +-
 srcF/sfx_esm.f90                            | 23 ++-----
 srcF/sfx_esm_param.f90                      | 19 ------
 srcF/sfx_log.f90                            | 21 +-----
 srcF/sfx_log_param.f90                      | 19 ------
 srcF/{sfx_roughness.f90 => sfx_surface.f90} | 73 +++++++++++++++++++--
 9 files changed, 79 insertions(+), 88 deletions(-)
 rename srcF/{sfx_roughness.f90 => sfx_surface.f90} (56%)

diff --git a/compile.sh b/compile.sh
index c04fab7..146d20b 100755
--- a/compile.sh
+++ b/compile.sh
@@ -4,7 +4,7 @@ gfortran -c -cpp -Wuninitialized srcF/sfx_phys_const.f90
 gfortran -c -cpp -Wuninitialized srcF/sfx_common.f90
 gfortran -c -cpp -Wuninitialized srcF/sfx_data.f90
 
-gfortran -c -cpp -Wuninitialized srcF/sfx_roughness.f90
+gfortran -c -cpp -Wuninitialized srcF/sfx_surface.f90
 
 gfortran -c -cpp -Wuninitialized srcF/sfx_log_param.f90
 gfortran -c -cpp -Wuninitialized srcF/sfx_log.f90
@@ -13,5 +13,5 @@ gfortran -c -cpp -Wuninitialized srcF/sfx_esm_param.f90
 gfortran -c -cpp -Wuninitialized srcF/sfx_esm.f90
 
 gfortran -c -cpp -Wuninitialized srcF/sfx_main.f90
-gfortran -o sfx.exe sfx_main.o sfx_log.o sfx_log_param.o sfx_esm.o sfx_esm_param.o sfx_roughness.o sfx_data.o sfx_common.o sfx_phys_const.o
+gfortran -o sfx.exe sfx_main.o sfx_log.o sfx_log_param.o sfx_esm.o sfx_esm_param.o sfx_surface.o sfx_data.o sfx_common.o sfx_phys_const.o
 rm *.o *.mod
diff --git a/makefile b/makefile
index 913ada0..f940f58 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_data.o sfx_roughness.o sfx_log_param.o sfx_log.o sfx_esm_param.o sfx_esm.o sfx_main.o
+OBJ_F90 = sfx_phys_const.o sfx_common.o sfx_data.o sfx_surface.o sfx_log_param.o sfx_log.o sfx_esm_param.o sfx_esm.o sfx_main.o
 OBJ_F =
 OBJ = $(OBJ_F90) $(OBJ_F)
 
diff --git a/srcF/sfx_data.f90 b/srcF/sfx_data.f90
index 5e252d7..c13ddc2 100644
--- a/srcF/sfx_data.f90
+++ b/srcF/sfx_data.f90
@@ -1,10 +1,6 @@
 module sfx_data
     !> @brief surface flux module data
 
-    ! macro defs.
-    ! --------------------------------------------------------------------------------
-    ! --------------------------------------------------------------------------------
-
     ! modules used
     ! --------------------------------------------------------------------------------
     ! --------------------------------------------------------------------------------
diff --git a/srcF/sfx_def.fi b/srcF/sfx_def.fi
index 6d90e99..2fc04b6 100644
--- a/srcF/sfx_def.fi
+++ b/srcF/sfx_def.fi
@@ -1,4 +1,4 @@
 ! sfx model macro definitions
 
-!#define SFX_FORCE_DEPRECATED_CODE
+!#define SFX_FORCE_DEPRECATED_ESM_CODE
 !#define SFX_CHECK_NAN
\ No newline at end of file
diff --git a/srcF/sfx_esm.f90 b/srcF/sfx_esm.f90
index dd38ce4..d1fef61 100644
--- a/srcF/sfx_esm.f90
+++ b/srcF/sfx_esm.f90
@@ -9,7 +9,7 @@ module sfx_esm
     use sfx_common
 #endif
     use sfx_data
-    use sfx_roughness
+    use sfx_surface
     use sfx_esm_param
     ! --------------------------------------------------------------------------------
 
@@ -53,7 +53,7 @@ contains
         ! ----------------------------------------------------------------------------
 
         do i = 1, n
-#ifdef SFX_FORCE_DEPRECATED_CODE
+#ifdef SFX_FORCE_DEPRECATED_ESM_CODE
 #else
             meteo_cell = meteoDataType(&
                     h = meteo%h(i), &
@@ -171,25 +171,10 @@ contains
             u_dyn0 = U * kappa / log(h0_m)
         end if
 
-        ! --- define B = log(z0_m / z0_h)
+        ! --- define thermal roughness & B = log(z0_m / z0_h)
         Re = u_dyn0 * z0_m / nu_air
-        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)
-        endif
-        if (surface_type == surface_land) then
-            B = min(B, B_max_land)
-        end if
+        call get_thermal_roughness(z0_t, B, z0_m, Re, surface_type)
 
-        ! --- define roughness [thermal]
-        z0_t = z0_m / exp(B)
         ! --- define relative height [thermal]
         h0_t = h / z0_t
 
diff --git a/srcF/sfx_esm_param.f90 b/srcF/sfx_esm_param.f90
index 0f9e253..76003ed 100644
--- a/srcF/sfx_esm_param.f90
+++ b/srcF/sfx_esm_param.f90
@@ -12,9 +12,6 @@ module sfx_esm_param
       implicit none
       ! --------------------------------------------------------------------------------
 
-      ! *: add lake surface & add surface type as input value
-      integer, public, parameter :: surface_ocean = 0     !> ocean surface
-      integer, public, parameter :: surface_land = 1      !> land surface
 
       !> von Karman constant [n/d]
       real, parameter :: kappa = 0.40
@@ -35,20 +32,4 @@ module sfx_esm_param
       !> --- max Ri-bulk value in stable case ( < 1 / beta_m )
       real, parameter ::  Rib_max = 0.9 / beta_m
 
-      !> Re fully roughness minimum value [n/d]
-      real, parameter ::  Re_rough_min = 16.3
-
-      !> roughness model coeff. [n/d]
-      !> --- transitional mode
-      !>     B = log(z0_m / z0_t) = B1 * log(B3 * Re) + B2
-      real, parameter :: B1_rough = 5.0 / 6.0
-      real, parameter :: B2_rough = 0.45
-      real, parameter :: B3_rough = kappa * Pr_m
-      !> --- fully rough mode (Re > Re_rough_min)
-      !>     B = B4 * Re^(B2)
-      real, parameter :: B4_rough =(0.14 * (30.0**B2_rough)) * (Pr_m**0.8)
-
-      real, parameter :: B_max_land = 2.0
-      real, parameter :: B_max_ocean = 8.0
-
 end module sfx_esm_param
diff --git a/srcF/sfx_log.f90 b/srcF/sfx_log.f90
index 225eb37..02e93b0 100644
--- a/srcF/sfx_log.f90
+++ b/srcF/sfx_log.f90
@@ -9,7 +9,7 @@ module sfx_log
     use sfx_common
 #endif
     use sfx_data
-    use sfx_roughness
+    use sfx_surface
     use sfx_log_param
     ! --------------------------------------------------------------------------------
 
@@ -160,25 +160,10 @@ contains
             u_dyn0 = U * kappa / log(h0_m)
         end if
 
-        ! --- define B = log(z0_m / z0_h)
+        ! --- define thermal roughness & B = log(z0_m / z0_h)
         Re = u_dyn0 * z0_m / nu_air
-        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)
-        endif
-        if (surface_type == surface_land) then
-            B = min(B, B_max_land)
-        end if
+        call get_thermal_roughness(z0_t, B, z0_m, Re, surface_type)
 
-        ! --- define roughness [thermal]
-        z0_t = z0_m / exp(B)
         ! --- define relative height [thermal]
         h0_t = h / z0_t
 
diff --git a/srcF/sfx_log_param.f90 b/srcF/sfx_log_param.f90
index 3918880..16d6e8d 100644
--- a/srcF/sfx_log_param.f90
+++ b/srcF/sfx_log_param.f90
@@ -12,29 +12,10 @@ module sfx_log_param
     implicit none
     ! --------------------------------------------------------------------------------
 
-    ! *: add lake surface & add surface type as input value
-    integer, public, parameter :: surface_ocean = 0     !> ocean surface
-    integer, public, parameter :: surface_land = 1      !> land surface
 
     !> von Karman constant [n/d]
     real, parameter :: kappa = 0.40
     !> inverse Prandtl (turbulent) number in neutral conditions [n/d]
     real, parameter :: Pr_t_0_inv = 1.15
 
-    !> Re fully roughness minimum value [n/d]
-    real, parameter ::  Re_rough_min = 16.3
-
-    !> roughness model coeff. [n/d]
-    !> --- transitional mode
-    !>     B = log(z0_m / z0_t) = B1 * log(B3 * Re) + B2
-    real, parameter :: B1_rough = 5.0 / 6.0
-    real, parameter :: B2_rough = 0.45
-    real, parameter :: B3_rough = kappa * Pr_m
-    !> --- fully rough mode (Re > Re_rough_min)
-    !>     B = B4 * Re^(B2)
-    real, parameter :: B4_rough =(0.14 * (30.0**B2_rough)) * (Pr_m**0.8)
-
-    real, parameter :: B_max_land = 2.0
-    real, parameter :: B_max_ocean = 8.0
-
 end module sfx_log_param
diff --git a/srcF/sfx_roughness.f90 b/srcF/sfx_surface.f90
similarity index 56%
rename from srcF/sfx_roughness.f90
rename to srcF/sfx_surface.f90
index e5e5463..628626f 100644
--- a/srcF/sfx_roughness.f90
+++ b/srcF/sfx_surface.f90
@@ -1,6 +1,6 @@
 #include "sfx_def.fi"
 
-module sfx_roughness
+module sfx_surface
     !> @brief surface roughness parameterizations
 
     ! modules used
@@ -14,13 +14,20 @@ module sfx_roughness
     private
     ! --------------------------------------------------------------------------------
 
+    ! public interface
     ! --------------------------------------------------------------------------------
-    real, parameter :: kappa = 0.40         !> von Karman constant [n/d]
+    public :: get_charnock_roughness
+    public :: get_thermal_roughness
     ! --------------------------------------------------------------------------------
 
-    ! public interface
+
+    ! *: add surface type as input value
+    integer, public, parameter :: surface_ocean = 0     !> ocean surface
+    integer, public, parameter :: surface_land = 1      !> land surface
+    integer, public, parameter :: surface_lake = 2      !> lake surface
+
     ! --------------------------------------------------------------------------------
-    public :: get_charnock_roughness
+    real, parameter :: kappa = 0.40         !> von Karman constant [n/d]
     ! --------------------------------------------------------------------------------
 
     !> Charnock parameters
@@ -34,6 +41,23 @@ module sfx_roughness
     real, parameter :: c2_charnock = Re_visc_min * nu_air * c1_charnock
     ! --------------------------------------------------------------------------------
 
+    !> Re fully roughness minimum value [n/d]
+    real, parameter ::  Re_rough_min = 16.3
+
+    !> roughness model coeff. [n/d]
+    !> --- transitional mode
+    !>     B = log(z0_m / z0_t) = B1 * log(B3 * Re) + B2
+    real, parameter :: B1_rough = 5.0 / 6.0
+    real, parameter :: B2_rough = 0.45
+    real, parameter :: B3_rough = kappa * Pr_m
+    !> --- fully rough mode (Re > Re_rough_min)
+    !>     B = B4 * Re^(B2)
+    real, parameter :: B4_rough =(0.14 * (30.0**B2_rough)) * (Pr_m**0.8)
+
+    real, parameter :: B_max_land = 2.0
+    real, parameter :: B_max_ocean = 8.0
+    real, parameter :: B_max_lake = 8.0
+
 contains
 
     ! charnock roughness definition
@@ -83,4 +107,43 @@ contains
     end subroutine
     ! --------------------------------------------------------------------------------
 
-end module sfx_roughness
+    ! thermal roughness definition
+    ! --------------------------------------------------------------------------------
+    subroutine get_thermal_roughness(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
+    ! --------------------------------------------------------------------------------
+
+end module sfx_surface
-- 
GitLab