FMS  2025.04
Flexible Modeling System
monin_obukhov.F90
1 !***********************************************************************
2 !* Apache License 2.0
3 !*
4 !* This file is part of the GFDL Flexible Modeling System (FMS).
5 !*
6 !* Licensed under the Apache License, Version 2.0 (the "License");
7 !* you may not use this file except in compliance with the License.
8 !* You may obtain a copy of the License at
9 !*
10 !* http://www.apache.org/licenses/LICENSE-2.0
11 !*
12 !* FMS is distributed in the hope that it will be useful, but WITHOUT
13 !* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied;
14 !* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
15 !* PARTICULAR PURPOSE. See the License for the specific language
16 !* governing permissions and limitations under the License.
17 !***********************************************************************
18 !> @defgroup monin_obukhov_mod monin_obukhov_mod
19 !> @ingroup monin_obukhov
20 !> @brief Routines for computing surface drag coefficients
21 !! from data at the lowest model level
22 !! and for computing the profile of fields
23 !! between the lowest model level and the ground
24 !! using Monin-Obukhov scaling
25 
26 module monin_obukhov_mod
27 
28 use constants_mod, only: grav, vonkarm
29 use mpp_mod, only: input_nml_file
30 use fms_mod, only: error_mesg, fatal, check_nml_error, &
31  mpp_pe, mpp_root_pe, stdlog, &
33 use monin_obukhov_inter, only: monin_obukhov_diff, monin_obukhov_drag_1d, &
35 use platform_mod, only: r4_kind, r8_kind
36 implicit none
37 private
38 
39 !=======================================================================
40  public :: monin_obukhov_init
41  public :: monin_obukhov_end
42  public :: mo_drag
43  public :: mo_profile
44  public :: mo_diff
45  public :: stable_mix
46 !=======================================================================
47 
48 !> @brief Compute surface drag coefficients
49 !> @ingroup monin_obukhov_mod
50 interface mo_drag
51  module procedure mo_drag_0d_r4, mo_drag_0d_r8
52  module procedure mo_drag_1d_r4, mo_drag_1d_r8
53  module procedure mo_drag_2d_r4, mo_drag_2d_r8
54 end interface
55 
56 
57 !> @ingroup monin_obukhov_mod
58 interface mo_profile
59  module procedure mo_profile_0d_r4, mo_profile_0d_r8
60  module procedure mo_profile_1d_r4, mo_profile_1d_r8
61  module procedure mo_profile_2d_r4, mo_profile_2d_r8
62  module procedure mo_profile_0d_n_r4, mo_profile_0d_n_r8
63  module procedure mo_profile_1d_n_r4, mo_profile_1d_n_r8
64  module procedure mo_profile_2d_n_r4, mo_profile_2d_n_r8
65 end interface
66 
67 !> @ingroup monin_obukhov_mod
68 interface mo_diff
69  module procedure mo_diff_0d_n_r4, mo_diff_0d_n_r8
70  module procedure mo_diff_0d_1_r4, mo_diff_0d_1_r8
71  module procedure mo_diff_1d_n_r4, mo_diff_1d_n_r8
72  module procedure mo_diff_1d_1_r4, mo_diff_1d_1_r8
73  module procedure mo_diff_2d_n_r4, mo_diff_2d_n_r8
74  module procedure mo_diff_2d_1_r4, mo_diff_2d_1_r8
75 end interface
76 
77 !> @ingroup monin_obukhov_mod
78 interface stable_mix
79  module procedure stable_mix_0d_r4, stable_mix_0d_r8
80  module procedure stable_mix_1d_r4, stable_mix_1d_r8
81  module procedure stable_mix_2d_r4, stable_mix_2d_r8
82  module procedure stable_mix_3d_r4, stable_mix_3d_r8
83 end interface
84 
85 interface mo_integral_m
86  module procedure mo_integral_m_r4, mo_integral_m_r8
87 end interface mo_integral_m
88 
89 interface mo_integral_tq
90  module procedure mo_integral_tq_r4, mo_integral_tq_r8
91 end interface mo_integral_tq
92 
93 interface mo_derivative_m
94  module procedure mo_derivative_m_r4, mo_derivative_m_r8
95 end interface mo_derivative_m
96 
97 interface mo_derivative_t
98  module procedure mo_derivative_t_r4, mo_derivative_t_r8
99 end interface mo_derivative_t
100 !> @addtogroup monin_obukhov_mod
101 !> @{
102 
103 !-----------------------------------------------------------------------
104 ! version number of this module
105 ! Include variable "version" to be written to log file.
106 #include<file_version.h>
107 
108 !=======================================================================
109 
110 ! DEFAULT VALUES OF NAMELIST PARAMETERS:
111 
112 real(kind=r8_kind) :: rich_crit = 2.0_r8_kind
113 real(kind=r8_kind) :: drag_min_heat = 1.0e-05_r8_kind
114 real(kind=r8_kind) :: drag_min_moist = 1.0e-05_r8_kind
115 real(kind=r8_kind) :: drag_min_mom = 1.0e-05_r8_kind
116 logical :: neutral = .false.
117 integer :: stable_option = 1
118 real(kind=r8_kind) :: zeta_trans = 0.5_r8_kind
119 logical :: new_mo_option = .false.
120 
121 
122 namelist /monin_obukhov_nml/ rich_crit, neutral, drag_min_heat, &
123  drag_min_moist, drag_min_mom, &
124  stable_option, zeta_trans, new_mo_option !miz
125 
126 !=======================================================================
127 
128 ! MODULE VARIABLES
129 
130 real(kind=r8_kind), parameter :: small = 1.0e-04_r8_kind
131 real(kind=r8_kind) :: b_stab, r_crit, lambda, rich_trans
132 real(kind=r8_kind) :: sqrt_drag_min_heat, sqrt_drag_min_moist, sqrt_drag_min_mom
133 logical :: module_is_initialized = .false.
134 
135 
136 contains
137 
138 !=======================================================================
139 
140 subroutine monin_obukhov_init
141 
142 integer :: ierr, io, logunit
143 
144 !------------------- read namelist input -------------------------------
145 
146  read (input_nml_file, nml=monin_obukhov_nml, iostat=io)
147  ierr = check_nml_error(io,"monin_obukhov_nml")
148 
149 !---------- output namelist to log-------------------------------------
150 
151  if ( mpp_pe() == mpp_root_pe() ) then
152  call write_version_number('MONIN_OBUKOV_MOD', version)
153  logunit = stdlog()
154  write (logunit, nml=monin_obukhov_nml)
155  endif
156 
157 !----------------------------------------------------------------------
158 
159 if(rich_crit.le.0.25_r8_kind) call error_mesg( &
160  'MONIN_OBUKHOV_INIT in MONIN_OBUKHOV_MOD', &
161  'rich_crit in monin_obukhov_mod must be > 0.25', fatal)
162 
163 if(drag_min_heat.le.0.0_r8_kind) call error_mesg( &
164  'MONIN_OBUKHOV_INIT in MONIN_OBUKHOV_MOD', &
165  'drag_min_heat in monin_obukhov_mod must be >= 0.0', fatal)
166 
167 if(drag_min_moist.le.0.0_r8_kind) call error_mesg( &
168  'MONIN_OBUKHOV_INIT in MONIN_OBUKHOV_MOD', &
169  'drag_min_moist in monin_obukhov_mod must be >= 0.0', fatal)
170 
171 if(drag_min_mom.le.0.0_r8_kind) call error_mesg( &
172  'MONIN_OBUKHOV_INIT in MONIN_OBUKHOV_MOD', &
173  'drag_min_mom in monin_obukhov_mod must be >= 0.0', fatal)
174 
175 if(stable_option < 1 .or. stable_option > 2) call error_mesg( &
176  'MONIN_OBUKHOV_INIT in MONIN_OBUKHOV_MOD', &
177  'the only allowable values of stable_option are 1 and 2', fatal)
178 
179 if(stable_option == 2 .and. zeta_trans < 0) call error_mesg( &
180  'MONIN_OBUKHOV_INIT in MONIN_OBUKHOV_MOD', &
181  'zeta_trans must be positive', fatal)
182 
183 b_stab = 1.0_r8_kind/rich_crit
184 r_crit = 0.95_r8_kind*rich_crit ! convergence can get slow if one is
185  ! close to rich_crit
186 
187 sqrt_drag_min_heat = 0.0_r8_kind
188 if(drag_min_heat.ne.0.0_r8_kind) sqrt_drag_min_heat = sqrt(drag_min_heat)
189 
190 sqrt_drag_min_moist = 0.0_r8_kind
191 if(drag_min_moist.ne.0.0_r8_kind) sqrt_drag_min_moist = sqrt(drag_min_moist)
192 
193 sqrt_drag_min_mom = 0.0_r8_kind
194 if(drag_min_mom.ne.0.0_r8_kind) sqrt_drag_min_mom = sqrt(drag_min_mom)
195 
196 lambda = 1.0_r8_kind + (5.0_r8_kind - b_stab)*zeta_trans ! used only if stable_option = 2
197 rich_trans = zeta_trans/(1.0_r8_kind + 5.0_r8_kind*zeta_trans) ! used only if stable_option = 2
198 
199 module_is_initialized = .true.
200 
201 return
202 end subroutine monin_obukhov_init
203 
204 !=======================================================================
205 
206 subroutine monin_obukhov_end
207 
208 module_is_initialized = .false.
209 
210 end subroutine monin_obukhov_end
211 
212 !=======================================================================
213 
214 #include "monin_obukhov_r4.fh"
215 #include "monin_obukhov_r8.fh"
216 
217 end module monin_obukhov_mod
218 !> @}
219 ! close documentation grouping
integer function, public check_nml_error(IOSTAT, NML_NAME)
Checks the iostat argument that is returned after reading a namelist and determines if the error code...
Definition: fms.F90:523
subroutine, public write_version_number(version, tag, unit)
Prints to the log file (or a specified unit) the version id string and tag name.
Definition: fms.F90:701
subroutine, public error_mesg(routine, message, level)
Print notes, warnings and error messages; terminates program for warning and error messages....
Definition: fms.F90:441
Compute surface drag coefficients.
integer function stdlog()
This function returns the current standard fortran unit numbers for log messages. Log messages,...
Definition: mpp_util.inc:58
integer function mpp_pe()
Returns processor ID.
Definition: mpp_util.inc:406