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