FMS 2025.01-dev
Flexible Modeling System
Loading...
Searching...
No Matches
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
27module monin_obukhov_mod
28
29use constants_mod, only: grav, vonkarm
30use mpp_mod, only: input_nml_file
31use fms_mod, only: error_mesg, fatal, check_nml_error, &
32 mpp_pe, mpp_root_pe, stdlog, &
33 write_version_number
34use monin_obukhov_inter, only: monin_obukhov_diff, monin_obukhov_drag_1d, &
36use platform_mod, only: r4_kind, r8_kind
37implicit none
38private
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
51interface 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
55end interface
56
57
58!> @ingroup monin_obukhov_mod
59interface 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
66end interface
67
68!> @ingroup monin_obukhov_mod
69interface 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
76end interface
77
78!> @ingroup monin_obukhov_mod
79interface 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
84end interface
85
87 module procedure mo_integral_m_r4, mo_integral_m_r8
88end interface mo_integral_m
89
91 module procedure mo_integral_tq_r4, mo_integral_tq_r8
92end interface mo_integral_tq
93
95 module procedure mo_derivative_m_r4, mo_derivative_m_r8
96end interface mo_derivative_m
97
99 module procedure mo_derivative_t_r4, mo_derivative_t_r8
100end 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
113real(kind=r8_kind) :: rich_crit = 2.0_r8_kind
114real(kind=r8_kind) :: drag_min_heat = 1.0e-05_r8_kind
115real(kind=r8_kind) :: drag_min_moist = 1.0e-05_r8_kind
116real(kind=r8_kind) :: drag_min_mom = 1.0e-05_r8_kind
117logical :: neutral = .false.
118integer :: stable_option = 1
119real(kind=r8_kind) :: zeta_trans = 0.5_r8_kind
120logical :: new_mo_option = .false.
121
122
123namelist /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
131real(kind=r8_kind), parameter :: small = 1.0e-04_r8_kind
132real(kind=r8_kind) :: b_stab, r_crit, lambda, rich_trans
133real(kind=r8_kind) :: sqrt_drag_min_heat, sqrt_drag_min_moist, sqrt_drag_min_mom
134logical :: module_is_initialized = .false.
135
136
137contains
138
139!=======================================================================
140
141subroutine monin_obukhov_init
142
143integer :: 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
160if(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
164if(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
168if(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
172if(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
176if(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
180if(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
184b_stab = 1.0_r8_kind/rich_crit
185r_crit = 0.95_r8_kind*rich_crit ! convergence can get slow if one is
186 ! close to rich_crit
187
188sqrt_drag_min_heat = 0.0_r8_kind
189if(drag_min_heat.ne.0.0_r8_kind) sqrt_drag_min_heat = sqrt(drag_min_heat)
190
191sqrt_drag_min_moist = 0.0_r8_kind
192if(drag_min_moist.ne.0.0_r8_kind) sqrt_drag_min_moist = sqrt(drag_min_moist)
193
194sqrt_drag_min_mom = 0.0_r8_kind
195if(drag_min_mom.ne.0.0_r8_kind) sqrt_drag_min_mom = sqrt(drag_min_mom)
196
197lambda = 1.0_r8_kind + (5.0_r8_kind - b_stab)*zeta_trans ! used only if stable_option = 2
198rich_trans = zeta_trans/(1.0_r8_kind + 5.0_r8_kind*zeta_trans) ! used only if stable_option = 2
199
200module_is_initialized = .true.
201
202return
203end subroutine monin_obukhov_init
204
205!=======================================================================
206
207subroutine monin_obukhov_end
208
209module_is_initialized = .false.
210
211end subroutine monin_obukhov_end
212
213!=======================================================================
214
215#include "monin_obukhov_r4.fh"
216#include "monin_obukhov_r8.fh"
217
218end module monin_obukhov_mod
219!> @}
220! close documentation grouping
Compute surface drag coefficients.