SCALE-RM
scale_bulkflux.F90
Go to the documentation of this file.
1 !-------------------------------------------------------------------------------
10 !-------------------------------------------------------------------------------
11 #include "scalelib.h"
13  !-----------------------------------------------------------------------------
14  !
15  !++ used modules
16  !
17  use scale_precision
18  use scale_io
19  use scale_prof
20  !-----------------------------------------------------------------------------
21  implicit none
22  private
23  !-----------------------------------------------------------------------------
24  !
25  !++ Public procedure
26  !
27  public :: bulkflux_setup
28 
29  abstract interface
30  subroutine bc( &
31  Ustar, & ! (out)
32  tstar, & ! (out)
33  qstar, & ! (out)
34  uabs, & ! (out)
35  ra, & ! (out)
36  fracu10, & ! (out)
37  fract2, & ! (out)
38  fracq2, & ! (out)
39  t1, & ! (in)
40  t0, & ! (in)
41  p1, & ! (in)
42  p0, & ! (in)
43  q1, & ! (in)
44  q0, & ! (in)
45  u1, & ! (in)
46  v1, & ! (in)
47  z1, & ! (in)
48  pbl, & ! (in)
49  z0m, & ! (in)
50  z0h, & ! (in)
51  z0e ) ! (in)
52  use scale_precision
53  implicit none
54 
55  real(RP), intent(out) :: ustar ! friction velocity [m/s]
56  real(RP), intent(out) :: tstar ! friction temperature [K]
57  real(RP), intent(out) :: qstar ! friction mixing rate [kg/kg]
58  real(RP), intent(out) :: uabs ! modified absolute velocity [m/s]
59  real(RP), intent(out) :: ra ! Aerodynamic resistance (=1/Ce)
60  real(RP), intent(out) :: fracu10 ! calculation parameter for U10 [-]
61  real(RP), intent(out) :: fract2 ! calculation parameter for T2 [-]
62  real(RP), intent(out) :: fracq2 ! calculation parameter for Q2 [-]
63 
64  real(RP), intent(in) :: t1 ! tempearature at the lowest atmospheric layer [K]
65  real(RP), intent(in) :: t0 ! skin temperature [K]
66  real(RP), intent(in) :: p1 ! pressure at the lowest atmospheric layer [Pa]
67  real(RP), intent(in) :: p0 ! surface pressure [Pa]
68  real(RP), intent(in) :: q1 ! mixing ratio at the lowest atmospheric layer [kg/kg]
69  real(RP), intent(in) :: q0 ! surface mixing ratio [kg/kg]
70  real(RP), intent(in) :: u1 ! zonal wind at the lowest atmospheric layer [m/s]
71  real(RP), intent(in) :: v1 ! meridional wind at the lowest atmospheric layer [m/s]
72  real(RP), intent(in) :: z1 ! height at the lowest atmospheric layer [m]
73  real(RP), intent(in) :: pbl ! the top of atmospheric mixing layer [m]
74  real(RP), intent(in) :: z0m ! roughness length of momentum [m]
75  real(RP), intent(in) :: z0h ! roughness length of heat [m]
76  real(RP), intent(in) :: z0e ! roughness length of moisture [m]
77  end subroutine bc
78  end interface
79 
80  procedure(bc), pointer :: bulkflux => null()
81  public :: bulkflux
82 
83  !-----------------------------------------------------------------------------
84  !
85  !++ Public parameters & variables
86  !
87  !-----------------------------------------------------------------------------
88  !
89  !++ Private procedure
90  !
91  private :: bulkflux_u95
92  private :: bulkflux_b91w01
93  private :: fm_unstable
94  private :: fh_unstable
95  private :: fm_stable
96  private :: fh_stable
97 
98  !-----------------------------------------------------------------------------
99  !
100  !++ Private parameters & variables
101  !
102  character(len=H_SHORT), private :: bulkflux_type = 'B91W01' ! 'U95', 'B94', and 'B91W01'
103 
104  logical, private :: bulkflux_use_mean = .true.
105 
106  integer, private :: bulkflux_itr_sa_max = 5 ! maximum iteration number for successive approximation
107  integer, private :: bulkflux_itr_nr_max = 10 ! maximum iteration number for Newton-Raphson method
108 
109  real(RP), private :: bulkflux_err_min = 1.0e-3_rp ! minimum value of error
110 
111  real(RP), private :: bulkflux_wscf ! empirical scaling factor of Wstar (Beljaars 1994)
112 
113  ! limiter
114  real(RP), private :: bulkflux_uabs_min = 1.0e-2_rp ! minimum of Uabs [m/s]
115  real(RP), private :: bulkflux_wstar_min = 1.0e-4_rp ! minimum of W* [m/s]
116 
117  logical, private :: flag_w01
118 
119 contains
120 
121  !-----------------------------------------------------------------------------
122  !
123  !-----------------------------------------------------------------------------
124  subroutine bulkflux_setup( dx )
125  use scale_prc, only: &
126  prc_abort
127  implicit none
128  real(RP), intent(in) :: dx
129 
130  namelist / param_bulkflux / &
131  bulkflux_type, &
132  bulkflux_use_mean, &
133  bulkflux_itr_sa_max, &
134  bulkflux_itr_nr_max, &
135  bulkflux_err_min, &
136  bulkflux_wscf, &
137  bulkflux_uabs_min, &
138  bulkflux_wstar_min
139 
140  integer :: ierr
141  !---------------------------------------------------------------------------
142 
143  log_newline
144  log_info("BULKFLUX_setup",*) 'Setup'
145 
146  ! WSCF = 1.2 for dx > 1 km (Beljaars 1994)
147  ! lim_{dx->0} WSCF = 0 for LES (Fig. 6 Kitamura and Ito 2016 BLM)
148  bulkflux_wscf = 1.2_rp * min(dx*1.e-3_rp, 1.0_rp)
149 
150 
151  !--- read namelist
152  rewind(io_fid_conf)
153  read(io_fid_conf,nml=param_bulkflux,iostat=ierr)
154 
155  if( ierr < 0 ) then !--- missing
156  log_info("BULKFLUX_setup",*) 'Not found namelist. Default used.'
157  elseif( ierr > 0 ) then !--- fatal error
158  log_error("BULKFLUX_setup",*) 'Not appropriate names in namelist PARAM_BULKFLUX. Check!'
159  call prc_abort
160  endif
161  log_nml(param_bulkflux)
162 
163  log_newline
164  log_info("BULKFLUX_setup",*) 'Scheme for surface bulk flux : ', trim(bulkflux_type)
165  select case(bulkflux_type)
166  case('U95')
167  log_info_cont(*) '=> Uno et al.(1995)'
168  bulkflux => bulkflux_u95
169  case('B91W01')
170  log_info_cont(*) '=> Beljaars (1991) and Wilson (2001)'
171  flag_w01 = .true.
172  bulkflux => bulkflux_b91w01
173  case('B94')
174  log_info_cont(*) '=> Beljaars (1994)'
175  flag_w01 = .false.
176  bulkflux => bulkflux_b91w01
177  case default
178  log_error("BULKFLUX_setup",*) 'Unsupported BULKFLUX_type. STOP'
179  call prc_abort
180  end select
181 
182  return
183  end subroutine bulkflux_setup
184 
185  !-----------------------------------------------------------------------------
186  ! ref. Uno et al. (1995)
187  !-----------------------------------------------------------------------------
188  subroutine bulkflux_u95( &
189  Ustar, & ! (out)
190  tstar, & ! (out)
191  qstar, & ! (out)
192  uabs, & ! (out)
193  ra, & ! (out)
194  fracu10, & ! (out)
195  fract2, & ! (out)
196  fracq2, & ! (out)
197  t1, & ! (in)
198  t0, & ! (in)
199  p1, & ! (in)
200  p0, & ! (in)
201  q1, & ! (in)
202  q0, & ! (in)
203  u1, & ! (in)
204  v1, & ! (in)
205  z1, & ! (in)
206  pbl, & ! (in)
207  z0m, & ! (in)
208  z0h, & ! (in)
209  z0e ) ! (in)
210  use scale_const, only: &
211  grav => const_grav, &
212  karman => const_karman, &
213  rdry => const_rdry, &
214  cpdry => const_cpdry, &
215  pre00 => const_pre00
216  implicit none
217 
218  ! parameter
219  real(RP), parameter :: tPrn = 0.74_rp ! turbulent Prandtl number (Businger et al. 1971)
220  real(RP), parameter :: LFb = 9.4_rp ! Louis factor b (Louis 1979)
221  real(RP), parameter :: LFbp = 4.7_rp ! Louis factor b' (Louis 1979)
222  real(RP), parameter :: LFdm = 7.4_rp ! Louis factor d for momemtum (Louis 1979)
223  real(RP), parameter :: LFdh = 5.3_rp ! Louis factor d for heat (Louis 1979)
224 
225  ! argument
226  real(RP), intent(out) :: Ustar ! friction velocity [m/s]
227  real(RP), intent(out) :: Tstar ! friction temperature [K]
228  real(RP), intent(out) :: Qstar ! friction mixing rate [kg/kg]
229  real(RP), intent(out) :: Uabs ! modified absolute velocity [m/s]
230  real(RP), intent(out) :: Ra ! Aerodynamic resistance (=1/Ce)
231  real(RP), intent(out) :: FracU10 ! calculation parameter for U10 [-]
232  real(RP), intent(out) :: FracT2 ! calculation parameter for T2 [-]
233  real(RP), intent(out) :: FracQ2 ! calculation parameter for Q2 [-]
234 
235  real(RP), intent(in) :: T1 ! tempearature at the lowest atmospheric layer [K]
236  real(RP), intent(in) :: T0 ! skin temperature [K]
237  real(RP), intent(in) :: P1 ! pressure at the lowest atmospheric layer [Pa]
238  real(RP), intent(in) :: P0 ! surface pressure [Pa]
239  real(RP), intent(in) :: Q1 ! mixing ratio at the lowest atmospheric layer [kg/kg]
240  real(RP), intent(in) :: Q0 ! surface mixing ratio [kg/kg]
241  real(RP), intent(in) :: U1 ! zonal wind at the lowest atmospheric layer [m/s]
242  real(RP), intent(in) :: V1 ! meridional wind at the lowest atmospheric layer [m/s]
243  real(RP), intent(in) :: Z1 ! height at the lowest atmospheric layer [m]
244  real(RP), intent(in) :: PBL ! the top of atmospheric mixing layer [m]
245  real(RP), intent(in) :: Z0M ! roughness length of momentum [m]
246  real(RP), intent(in) :: Z0H ! roughness length of heat [m]
247  real(RP), intent(in) :: Z0E ! roughness length of moisture [m]
248 
249  ! work
250  real(RP) :: RiB0, RiB ! bulk Richardson number [-]
251  real(RP) :: C0Z1, C010, C002 ! initial drag coefficient [-]
252  real(RP) :: CmZ1, ChZ1, CqZ1, fmZ1, fhZ1, t0thZ1, q0qeZ1
253  real(RP) :: Cm10, fm10
254  real(RP) :: Cm02, Ch02, Cq02, fm02, fh02, t0th02, q0qe02
255  real(RP) :: TH1, TH0
256  real(RP) :: logZ1Z0M, log10Z0m, log02Z0m
257  real(RP) :: logZ0MZ0E
258  real(RP) :: logZ0MZ0H
259  !---------------------------------------------------------------------------
260 
261  logz1z0m = log( z1 / z0m )
262  log10z0m = log( 10.0_rp / z0m )
263  log02z0m = log( 2.0_rp / z0m )
264 
265  logz0mz0e = max( log( z0m/z0e ), 1.0_rp )
266  logz0mz0h = max( log( z0m/z0h ), 1.0_rp )
267 
268  uabs = max( sqrt( u1**2 + v1**2 ), bulkflux_uabs_min )
269  th1 = t1 * ( p0 / p1 )**( rdry / cpdry )
270  th0 = t0
271 
272  ! bulk Richardson number
273  rib0 = grav * z1 * ( th1 - th0 ) / ( th1 * uabs**2 )
274 
275  c0z1 = ( karman / logz1z0m )**2
276  c010 = ( karman / log10z0m )**2
277  c002 = ( karman / log02z0m )**2
278 
279  rib = rib0
280 
281  if( rib0 > 0.0_rp ) then
282  ! stable condition
283  fmz1 = 1.0_rp / ( 1.0_rp + lfbp * rib )**2
284  fhz1 = 1.0_rp / ( 1.0_rp + lfbp * rib )**2
285  fm10 = 1.0_rp / ( 1.0_rp + lfbp * rib )**2
286  fm02 = 1.0_rp / ( 1.0_rp + lfbp * rib )**2
287  fh02 = 1.0_rp / ( 1.0_rp + lfbp * rib )**2
288  else
289  ! unstable condition
290  fmz1 = 1.0_rp - lfb * rib / ( 1.0_rp + lfb * lfdm * c0z1 * sqrt( z1 / z0m ) * sqrt( abs( rib ) ) )
291  fhz1 = 1.0_rp - lfb * rib / ( 1.0_rp + lfb * lfdh * c0z1 * sqrt( z1 / z0m ) * sqrt( abs( rib ) ) )
292  fm10 = 1.0_rp - lfb * rib / ( 1.0_rp + lfb * lfdm * c010 * sqrt( 10.0_rp / z0m ) * sqrt( abs( rib ) ) )
293  fm02 = 1.0_rp - lfb * rib / ( 1.0_rp + lfb * lfdm * c002 * sqrt( 2.0_rp / z0m ) * sqrt( abs( rib ) ) )
294  fh02 = 1.0_rp - lfb * rib / ( 1.0_rp + lfb * lfdh * c002 * sqrt( 2.0_rp / z0m ) * sqrt( abs( rib ) ) )
295  end if
296 
297  t0thz1 = 1.0_rp / ( 1.0_rp + logz0mz0h / logz1z0m / sqrt( fmz1 ) * fhz1 )
298  q0qez1 = 1.0_rp / ( 1.0_rp + logz0mz0e / logz1z0m / sqrt( fmz1 ) * fhz1 )
299  t0th02 = 1.0_rp / ( 1.0_rp + logz0mz0h / log02z0m / sqrt( fm02 ) * fh02 )
300  q0qe02 = 1.0_rp / ( 1.0_rp + logz0mz0e / log02z0m / sqrt( fm02 ) * fh02 )
301 
302  rib = rib * t0thz1
303 
304  if( rib0 > 0.0_rp ) then
305  ! stable condition
306  fmz1 = 1.0_rp / ( 1.0_rp + lfbp * rib )**2
307  fhz1 = 1.0_rp / ( 1.0_rp + lfbp * rib )**2
308  fm10 = 1.0_rp / ( 1.0_rp + lfbp * rib )**2
309  fm02 = 1.0_rp / ( 1.0_rp + lfbp * rib )**2
310  fh02 = 1.0_rp / ( 1.0_rp + lfbp * rib )**2
311  else
312  ! unstable condition
313  fmz1 = 1.0_rp - lfb * rib / ( 1.0_rp + lfb * lfdm * c0z1 * sqrt( z1 / z0m ) * sqrt( abs( rib ) ) )
314  fhz1 = 1.0_rp - lfb * rib / ( 1.0_rp + lfb * lfdh * c0z1 * sqrt( z1 / z0m ) * sqrt( abs( rib ) ) )
315  fm10 = 1.0_rp - lfb * rib / ( 1.0_rp + lfb * lfdm * c010 * sqrt( 10.0_rp / z0m ) * sqrt( abs( rib ) ) )
316  fm02 = 1.0_rp - lfb * rib / ( 1.0_rp + lfb * lfdm * c002 * sqrt( 2.0_rp / z0m ) * sqrt( abs( rib ) ) )
317  fh02 = 1.0_rp - lfb * rib / ( 1.0_rp + lfb * lfdh * c002 * sqrt( 2.0_rp / z0m ) * sqrt( abs( rib ) ) )
318  end if
319 
320  t0thz1 = 1.0_rp / ( 1.0_rp + logz0mz0h / logz1z0m / sqrt( fmz1 ) * fhz1 )
321  q0qez1 = 1.0_rp / ( 1.0_rp + logz0mz0e / logz1z0m / sqrt( fmz1 ) * fhz1 )
322  t0th02 = 1.0_rp / ( 1.0_rp + logz0mz0h / log02z0m / sqrt( fm02 ) * fh02 )
323  q0qe02 = 1.0_rp / ( 1.0_rp + logz0mz0e / log02z0m / sqrt( fm02 ) * fh02 )
324 
325  cmz1 = c0z1 * fmz1
326  chz1 = c0z1 * fhz1 * t0thz1 / tprn
327  cqz1 = c0z1 * fhz1 * q0qez1 / tprn
328  cm10 = c010 * fm10
329  cm02 = c002 * fm02
330  ch02 = c002 * fh02 * t0th02 / tprn
331  cq02 = c002 * fh02 * q0qe02 / tprn
332 
333  ustar = sqrt( cmz1 ) * uabs
334  tstar = chz1 * uabs / ustar * ( th1 - th0 )
335  qstar = cqz1 * uabs / ustar * ( q1 - q0 )
336 
337  fracu10 = sqrt( cmz1 / cm10 )
338  fract2 = chz1 / ch02 * sqrt( cm02 / cmz1 )
339  fracq2 = cqz1 / cq02 * sqrt( cm02 / cmz1 )
340 
341  ra = 1.0_rp / ( cqz1 * uabs )
342 
343  return
344  end subroutine bulkflux_u95
345 
346  !-----------------------------------------------------------------------------
347  !
348  ! refs. Beljaars (1991) and Wilson (2001)
349  !
350  ! If you want to run with the original Beljaars scheme (Beljaars and Holtslag 1994),
351  ! you should fix the stability functions (fm_unstable, fh_unstable, fm_stable, and fh_stable).
352  !
353  ! Iteration method: refs. JMA-NHM Description Note II, Mar 2008
354  !
355  !-----------------------------------------------------------------------------
356 !OCL SERIAL
357  subroutine bulkflux_b91w01( &
358  Ustar, & ! (out)
359  tstar, & ! (out)
360  qstar, & ! (out)
361  uabs, & ! (out)
362  ra, & ! (out)
363  fracu10, & ! (out)
364  fract2, & ! (out)
365  fracq2, & ! (out)
366  t1, & ! (in)
367  t0, & ! (in)
368  p1, & ! (in)
369  p0, & ! (in)
370  q1, & ! (in)
371  q0, & ! (in)
372  u1, & ! (in)
373  v1, & ! (in)
374  z1, & ! (in)
375  pbl, & ! (in)
376  z0m, & ! (in)
377  z0h, & ! (in)
378  z0e ) ! (in)
379  use scale_const, only: &
380  grav => const_grav, &
381  karman => const_karman, &
382  rdry => const_rdry, &
383  cpdry => const_cpdry, &
384  epstvap => const_epstvap, &
385  eps => const_eps, &
386  pre00 => const_pre00
387  implicit none
388 
389  ! parameter
390  real(DP), parameter :: dIL = 1.0e-6_dp ! delta [1/m]
391 
392  ! argument
393  real(RP), intent(out) :: Ustar ! friction velocity [m/s]
394  real(RP), intent(out) :: Tstar ! friction temperature [K]
395  real(RP), intent(out) :: Qstar ! friction mixing rate [kg/kg]
396  real(RP), intent(out) :: Uabs ! modified absolute velocity [m/s]
397  real(RP), intent(out) :: Ra ! Aerodynamic resistance (=1/Ce)
398  real(RP), intent(out) :: FracU10 ! calculation parameter for U10 [-]
399  real(RP), intent(out) :: FracT2 ! calculation parameter for T2 [-]
400  real(RP), intent(out) :: FracQ2 ! calculation parameter for Q2 [-]
401 
402  real(RP), intent(in) :: T1 ! tempearature at the lowest atmospheric layer [K]
403  real(RP), intent(in) :: T0 ! skin temperature [K]
404  real(RP), intent(in) :: P1 ! pressure at the lowest atmospheric layer [Pa]
405  real(RP), intent(in) :: P0 ! surface pressure [Pa]
406  real(RP), intent(in) :: Q1 ! mixing ratio at the lowest atmospheric layer [kg/kg]
407  real(RP), intent(in) :: Q0 ! mixing ratio at surface [kg/kg]
408  real(RP), intent(in) :: U1 ! zonal wind at the lowest atmospheric layer [m/s]
409  real(RP), intent(in) :: V1 ! meridional wind at the lowest atmospheric layer [m/s]
410  real(RP), intent(in) :: Z1 ! height at the lowest atmospheric layer [m]
411  real(RP), intent(in) :: PBL ! the top of atmospheric mixing layer [m]
412  real(RP), intent(in) :: Z0M ! roughness length of momentum [m]
413  real(RP), intent(in) :: Z0H ! roughness length of heat [m]
414  real(RP), intent(in) :: Z0E ! roughness length of moisture [m]
415 
416  ! work
417  integer :: n
418 
419  real(DP) :: IL ! inversed Obukhov length [1/m]
420  real(DP) :: res ! residual
421  real(DP) :: dres ! d(residual)/dIL
422 
423  real(DP) :: RiB0 ! bulk Richardson number [no unit]
424  real(DP) :: Wstar, dWstar ! free convection velocity scale [m/s]
425 
426  real(DP) :: UabsUS, UabsS, UabsC
427  real(DP) :: dUabsUS, dUabsS
428 
429  real(DP) :: UstarUS, UstarS, UstarC
430  real(DP) :: TstarUS, TstarS, TstarC
431  real(DP) :: QstarUS, QstarS, QstarC
432 
433  real(DP) :: dUstarUS, dUstarS, dUstarC
434  real(DP) :: dTstarUS, dTstarS, dTstarC
435  real(DP) :: dQstarUS, dQstarS, dQstarC
436 
437  real(DP) :: FracU10US, FracU10S, FracU10C
438  real(DP) :: FracT2US, FracT2S, FracT2C
439  real(DP) :: FracQ2US, FracQ2S, FracQ2C
440 
441  real(DP) :: TH1, TH0, THM
442  real(DP) :: TV1, TV0, TVM
443  real(DP) :: QM
444  real(DP) :: sw, tmp
445 
446  real(DP) :: BFLX, dBFLX
447 
448  real(DP) :: DP_Z1, DP_Z0M, DP_Z0H, DP_Z0E
449  real(DP) :: log_Z1ovZ0M, log_Z1ovZ0H, log_Z1ovZ0E
450  real(DP) :: log_10ovZ0M, log_02ovZ0H, log_02ovZ0E
451 
452  real(DP) :: denoM, denoH, denoE
453  real(DP) :: RzM, RzH, RzE
454  !---------------------------------------------------------------------------
455 
456  ! convert to DP
457  if ( bulkflux_use_mean ) then
458  dp_z1 = real( z1*2.0_rp, kind=dp )
459  else
460  dp_z1 = real( z1, kind=dp )
461  end if
462  dp_z0m = real( z0m, kind=dp )
463  dp_z0h = real( z0h, kind=dp )
464  dp_z0e = real( z0e, kind=dp )
465 
466  uabsc = max( sqrt( u1**2 + v1**2 ), bulkflux_uabs_min )
467 
468  th1 = t1 * ( p0 / p1 )**( rdry / cpdry )
469  th0 = t0
470  thm = ( th1 + th0 ) * 0.5_rp
471  qm = ( q1 + q0 ) * 0.5_rp
472  tv1 = th1 * ( 1.0_dp + epstvap * q1 )
473  tv0 = th0 * ( 1.0_dp + epstvap * q0 )
474  tvm = ( tv1 + tv0 ) * 0.5_rp
475 
476  rzm = 1.0_dp - dp_z0m / dp_z1
477  rzh = 1.0_dp - dp_z0h / dp_z1
478  rze = 1.0_dp - dp_z0e / dp_z1
479 
480  ! make log constant
481  log_z1ovz0m = log( dp_z1 / dp_z0m )
482  log_z1ovz0h = log( dp_z1 / dp_z0h )
483  log_z1ovz0e = log( dp_z1 / dp_z0e )
484 
485  log_10ovz0m = log( 10.0_dp / dp_z0m )
486  log_02ovz0h = log( 2.0_dp / dp_z0h )
487  log_02ovz0e = log( 2.0_dp / dp_z0e )
488 
489  ! bulk Richardson number at initial step
490  rib0 = grav * dp_z1 * ( tv1 - tv0 ) / ( tvm * uabsc**2 )
491 
492  ! inversed Obukhov length at initial step
493  il = rib0 / dp_z1 * log_z1ovz0m**2 / log_z1ovz0h
494 
495  ! free convection velocity scale at initial step
496  wstar = bulkflux_wstar_min
497  dwstar = bulkflux_wstar_min
498 
499  ! Successive approximation
500  do n = 1, bulkflux_itr_sa_max
501  if ( bulkflux_use_mean ) then
502  denom = log_z1ovz0m &
503  - fmm_unstable(dp_z1,il) + fmm_unstable(dp_z0m,il) * dp_z0m / dp_z1 &
504  + rzm * ( fm_unstable(dp_z0m,il) - 1.0_dp )
505  denoh = log_z1ovz0h &
506  - fhm_unstable(dp_z1,il) + fhm_unstable(dp_z0h,il) * dp_z0h / dp_z1 &
507  + rzh * ( fh_unstable(dp_z0h,il) - 1.0_dp )
508  denoe = log_z1ovz0e &
509  - fhm_unstable(dp_z1,il) + fhm_unstable(dp_z0e,il) * dp_z0e / dp_z1 &
510  + rze * ( fh_unstable(dp_z0e,il) - 1.0_dp )
511  else
512  denom = log_z1ovz0m - fm_unstable(dp_z1,il) + fm_unstable(dp_z0m,il)
513  denoh = log_z1ovz0h - fh_unstable(dp_z1,il) + fh_unstable(dp_z0h,il)
514  denoe = log_z1ovz0e - fh_unstable(dp_z1,il) + fh_unstable(dp_z0e,il)
515  end if
516  ! unstable condition
517  uabsus = max( sqrt( u1**2 + v1**2 + (bulkflux_wscf*wstar)**2 ), real( BULKFLUX_Uabs_min, kind=DP ) )
518  ustarus = karman / denom * uabsus
519  tstarus = karman / denoh * ( th1 - th0 )
520  qstarus = karman / denoe * ( q1 - q0 )
521 ! UstarUS = KARMAN / ( log_Z1ovZ0M - fm_unstable(DP_Z1,IL) + fm_unstable(DP_Z0M,IL) ) * UabsUS
522 ! TstarUS = KARMAN / ( log_Z1ovZ0H - fh_unstable(DP_Z1,IL) + fh_unstable(DP_Z0H,IL) ) * ( TH1 - TH0 )
523 ! QstarUS = KARMAN / ( log_Z1ovZ0E - fh_unstable(DP_Z1,IL) + fh_unstable(DP_Z0E,IL) ) * ( Q1 - Q0 )
524 
525  ! stable condition
526  if ( bulkflux_use_mean ) then
527  denom = log_z1ovz0m &
528  - fmm_stable(dp_z1,il) + fmm_stable(dp_z0m,il) * dp_z0m / dp_z1 &
529  + rzm * ( fm_stable(dp_z0m,il) - 1.0_dp )
530  denoh = log_z1ovz0h &
531  - fhm_stable(dp_z1,il) + fhm_stable(dp_z0h,il) * dp_z0h / dp_z1 &
532  + rzh * ( fh_stable(dp_z0h,il) - 1.0_dp )
533  denoe = log_z1ovz0e &
534  - fhm_stable(dp_z1,il) + fhm_stable(dp_z0e,il) * dp_z0e / dp_z1 &
535  + rze * ( fh_stable(dp_z0e,il) - 1.0_dp )
536  else
537  denom = log_z1ovz0m - fm_stable(dp_z1,il) + fm_stable(dp_z0m,il)
538  denoh = log_z1ovz0h - fh_stable(dp_z1,il) + fh_stable(dp_z0h,il)
539  denoe = log_z1ovz0e - fh_stable(dp_z1,il) + fh_stable(dp_z0e,il)
540  end if
541  uabss = max( sqrt( u1**2 + v1**2 ), bulkflux_uabs_min )
542  ustars = karman / denom * uabss
543  tstars = karman / denoh * ( th1 - th0 )
544  qstars = karman / denoe * ( q1 - q0 )
545 ! UstarS = KARMAN / ( log_Z1ovZ0M - fm_stable(DP_Z1,IL) + fm_stable(DP_Z0M,IL) ) * UabsS
546 ! TstarS = KARMAN / ( log_Z1ovZ0H - fh_stable(DP_Z1,IL) + fh_stable(DP_Z0H,IL) ) * ( TH1 - TH0 )
547 ! QstarS = KARMAN / ( log_Z1ovZ0E - fh_stable(DP_Z1,IL) + fh_stable(DP_Z0E,IL) ) * ( Q1 - Q0 )
548 
549  sw = 0.5_dp - sign( 0.5_dp, il ) ! if unstable, sw = 1
550 
551  ustarc = ( sw ) * ustarus + ( 1.0_dp-sw ) * ustars
552  tstarc = ( sw ) * tstarus + ( 1.0_dp-sw ) * tstars
553  qstarc = ( sw ) * qstarus + ( 1.0_dp-sw ) * qstars
554 
555  ! estimate buoyancy flux
556  bflx = - ustarc * tstarc * ( 1.0_rp + epstvap * qm ) - epstvap * ustarc * qstarc * thm
557 
558  ! update free convection velocity scale
559  tmp = pbl * grav / t1 * bflx
560  sw = 0.5_dp + sign( 0.5_dp, tmp ) ! if tmp is plus, sw = 1
561 
562  wstar = ( tmp * sw )**( 1.0_dp / 3.0_dp )
563 
564  ! avoid zero division with UstarC = 0
565  sw = 0.5_dp + sign( 0.5_dp, abs( ustarc ) - eps )
566 
567  ustarc = ( sw ) * ustarc + ( 1.0_dp-sw ) * eps
568 
569  ! estimate the inversed Obukhov length
570  il = - karman * grav * bflx / ( ustarc**3 * thm )
571  end do
572 
573 
574  ! Newton-Raphson method
575  do n = 1, bulkflux_itr_nr_max
576  ! unstable condition
577  if ( bulkflux_use_mean ) then
578  denom = log_z1ovz0m &
579  - fmm_unstable(dp_z1,il) + fmm_unstable(dp_z0m,il) * dp_z0m / dp_z1 &
580  + rzm * ( fm_unstable(dp_z0m,il) - 1.0_dp )
581  denoh = log_z1ovz0h &
582  - fhm_unstable(dp_z1,il) + fhm_unstable(dp_z0h,il) * dp_z0h / dp_z1 &
583  + rzh * ( fh_unstable(dp_z0h,il) - 1.0_dp )
584  denoe = log_z1ovz0e &
585  - fhm_unstable(dp_z1,il) + fhm_unstable(dp_z0e,il) * dp_z0e / dp_z1 &
586  + rze * ( fh_unstable(dp_z0e,il) - 1.0_dp )
587  else
588  denom = log_z1ovz0m - fm_unstable(dp_z1,il) + fm_unstable(dp_z0m,il)
589  denoh = log_z1ovz0h - fh_unstable(dp_z1,il) + fh_unstable(dp_z0h,il)
590  denoe = log_z1ovz0e - fh_unstable(dp_z1,il) + fh_unstable(dp_z0e,il)
591  end if
592  uabsus = max( sqrt( u1**2 + v1**2 + (bulkflux_wscf*wstar)**2 ), real( BULKFLUX_Uabs_min, kind=DP ) )
593  ustarus = karman / denom * uabsus
594  tstarus = karman / denoh * ( th1 - th0 )
595  qstarus = karman / denoe * ( q1 - q0 )
596 ! UstarUS = KARMAN / ( log_Z1ovZ0M - fm_unstable(DP_Z1,IL) + fm_unstable(DP_Z0M,IL) ) * UabsUS
597 ! TstarUS = KARMAN / ( log_Z1ovZ0H - fh_unstable(DP_Z1,IL) + fh_unstable(DP_Z0H,IL) ) * ( TH1 - TH0 )
598 ! QstarUS = KARMAN / ( log_Z1ovZ0E - fh_unstable(DP_Z1,IL) + fh_unstable(DP_Z0E,IL) ) * ( Q1 - Q0 )
599 
600  ! stable condition
601  if ( bulkflux_use_mean ) then
602  denom = log_z1ovz0m &
603  - fmm_stable(dp_z1,il) + fmm_stable(dp_z0m,il) * dp_z0m / dp_z1 &
604  + rzm * ( fm_stable(dp_z0m,il) - 1.0_dp )
605  denoh = log_z1ovz0h &
606  - fhm_stable(dp_z1,il) + fhm_stable(dp_z0h,il) * dp_z0h / dp_z1 &
607  + rzh * ( fh_stable(dp_z0h,il) - 1.0_dp )
608  denoe = log_z1ovz0e &
609  - fhm_stable(dp_z1,il) + fhm_stable(dp_z0e,il) * dp_z0e / dp_z1 &
610  + rze * ( fh_stable(dp_z0e,il) - 1.0_dp )
611  else
612  denom = log_z1ovz0m - fm_stable(dp_z1,il) + fm_stable(dp_z0m,il)
613  denoh = log_z1ovz0h - fh_stable(dp_z1,il) + fh_stable(dp_z0h,il)
614  denoe = log_z1ovz0e - fh_stable(dp_z1,il) + fh_stable(dp_z0e,il)
615  end if
616  uabss = max( sqrt( u1**2 + v1**2 ), bulkflux_uabs_min )
617  ustars = karman / denom * uabss
618  tstars = karman / denoh * ( th1 - th0 )
619  qstars = karman / denoe * ( q1 - q0 )
620 ! UstarS = KARMAN / ( log_Z1ovZ0M - fm_stable(DP_Z1,IL) + fm_stable(DP_Z0M,IL) ) * UabsS
621 ! TstarS = KARMAN / ( log_Z1ovZ0H - fh_stable(DP_Z1,IL) + fh_stable(DP_Z0H,IL) ) * ( TH1 - TH0 )
622 ! QstarS = KARMAN / ( log_Z1ovZ0E - fh_stable(DP_Z1,IL) + fh_stable(DP_Z0E,IL) ) * ( Q1 - Q0 )
623 
624  sw = 0.5_dp - sign( 0.5_dp, il ) ! if unstable, sw = 1
625 
626  ustarc = ( sw ) * ustarus + ( 1.0_dp-sw ) * ustars
627  tstarc = ( sw ) * tstarus + ( 1.0_dp-sw ) * tstars
628  qstarc = ( sw ) * qstarus + ( 1.0_dp-sw ) * qstars
629 
630  ! estimate buoyancy flux
631  bflx = - ustarc * tstarc * ( 1.0_rp + epstvap * qm ) - epstvap * ustarc * qstarc * thm
632 
633  ! update free convection velocity scale
634  tmp = pbl * grav / t1 * bflx
635  sw = 0.5_dp + sign( 0.5_dp, tmp ) ! if tmp is plus, sw = 1
636 
637  wstar = ( tmp * sw )**( 1.0_dp / 3.0_dp )
638 
639  ! avoid zero division with UstarC = 0
640  sw = 0.5_dp + sign( 0.5_dp, abs( ustarc ) - eps )
641 
642  ustarc = ( sw ) * ustarc + ( 1.0_dp-sw ) * eps
643 
644  ! calculate residual
645  res = il + karman * grav * bflx / ( ustarc**3 * thm )
646 
647  ! unstable condition
648  if ( bulkflux_use_mean ) then
649  denom = log_z1ovz0m &
650  - fmm_unstable(dp_z1,il+dil) + fmm_unstable(dp_z0m,il+dil) * dp_z0m / dp_z1 &
651  + rzm * ( fm_unstable(dp_z0m,il+dil) - 1.0_dp )
652  denoh = log_z1ovz0h &
653  - fhm_unstable(dp_z1,il+dil) + fhm_unstable(dp_z0h,il+dil) * dp_z0h / dp_z1 &
654  + rzh * ( fh_unstable(dp_z0h,il+dil) - 1.0_dp )
655  denoe = log_z1ovz0e &
656  - fhm_unstable(dp_z1,il+dil) + fhm_unstable(dp_z0e,il+dil) * dp_z0e / dp_z1 &
657  + rze * ( fh_unstable(dp_z0e,il+dil) - 1.0_dp )
658  else
659  denom = log_z1ovz0m - fm_unstable(dp_z1,il+dil) + fm_unstable(dp_z0m,il+dil)
660  denoh = log_z1ovz0h - fh_unstable(dp_z1,il+dil) + fh_unstable(dp_z0h,il+dil)
661  denoe = log_z1ovz0e - fh_unstable(dp_z1,il+dil) + fh_unstable(dp_z0e,il+dil)
662  end if
663  duabsus = max( sqrt( u1**2 + v1**2 + (bulkflux_wscf*wstar)**2 ), real( BULKFLUX_Uabs_min, kind=DP ) )
664  dustarus = karman / denom * uabsus
665  dtstarus = karman / denoh * ( th1 - th0 )
666  dqstarus = karman / denoe * ( q1 - q0 )
667 ! dUstarUS = KARMAN / ( log_Z1ovZ0M - fm_unstable(DP_Z1,IL+dIL) + fm_unstable(DP_Z0M,IL+dIL) ) * dUabsUS
668 ! dTstarUS = KARMAN / ( log_Z1ovZ0H - fh_unstable(DP_Z1,IL+dIL) + fh_unstable(DP_Z0H,IL+dIL) ) * ( TH1 - TH0 )
669 ! dQstarUS = KARMAN / ( log_Z1ovZ0E - fh_unstable(DP_Z1,IL+dIL) + fh_unstable(DP_Z0E,IL+dIL) ) * ( Q1 - Q0 )
670 
671  ! stable condition
672  if ( bulkflux_use_mean ) then
673  denom = log_z1ovz0m &
674  - fmm_stable(dp_z1,il+dil) + fmm_stable(dp_z0m,il+dil) * dp_z0m / dp_z1 &
675  + rzm * ( fm_stable(dp_z0m,il+dil) - 1.0_dp )
676  denoh = log_z1ovz0h &
677  - fhm_stable(dp_z1,il+dil) + fhm_stable(dp_z0h,il+dil) * dp_z0h / dp_z1 &
678  + rzh * ( fh_stable(dp_z0h,il+dil) - 1.0_dp )
679  denoe = log_z1ovz0e &
680  - fhm_stable(dp_z1,il+dil) + fhm_stable(dp_z0e,il+dil) * dp_z0e / dp_z1 &
681  + rze * ( fh_stable(dp_z0e,il+dil) - 1.0_dp )
682  else
683  denom = log_z1ovz0m - fm_stable(dp_z1,il+dil) + fm_stable(dp_z0m,il+dil)
684  denoh = log_z1ovz0h - fh_stable(dp_z1,il+dil) + fh_stable(dp_z0h,il+dil)
685  denoe = log_z1ovz0e - fh_stable(dp_z1,il+dil) + fh_stable(dp_z0e,il+dil)
686  end if
687  duabss = max( sqrt( u1**2 + v1**2 ), bulkflux_uabs_min )
688  dustars = karman / denom * uabss
689  dtstars = karman / denoh * ( th1 - th0 )
690  dqstars = karman / denoe * ( q1 - q0 )
691 ! dUstarS = KARMAN / ( log_Z1ovZ0M - fm_stable(DP_Z1,IL+dIL) + fm_stable(DP_Z0M,IL+dIL) ) * dUabsS
692 ! dTstarS = KARMAN / ( log_Z1ovZ0H - fh_stable(DP_Z1,IL+dIL) + fh_stable(DP_Z0H,IL+dIL) ) * ( TH1 - TH0 )
693 ! dQstarS = KARMAN / ( log_Z1ovZ0E - fh_stable(DP_Z1,IL+dIL) + fh_stable(DP_Z0E,IL+dIL) ) * ( Q1 - Q0 )
694 
695  sw = 0.5_dp - sign( 0.5_dp, il+dil ) ! if unstable, sw = 1
696 
697  dustarc = ( sw ) * dustarus + ( 1.0_dp-sw ) * dustars
698  dtstarc = ( sw ) * dtstarus + ( 1.0_dp-sw ) * dtstars
699  dqstarc = ( sw ) * dqstarus + ( 1.0_dp-sw ) * dqstars
700 
701  ! estimate buoyancy flux
702  dbflx = - dustarc * dtstarc * ( 1.0_rp + epstvap * qm ) - epstvap * dustarc * dqstarc * thm
703 
704  ! update d(free convection velocity scale)
705  tmp = pbl * grav / t1 * dbflx
706  sw = 0.5_dp + sign( 0.5_dp, tmp ) ! if tmp is plus, sw = 1
707 
708  dwstar = ( tmp * sw )**( 1.0_dp / 3.0_dp )
709 
710  ! avoid zero division with dUstarC = 0
711  sw = 0.5_dp + sign( 0.5_dp, abs( dustarc ) - eps )
712 
713  dustarc = ( sw ) * dustarc + ( 1.0_dp-sw ) * eps
714 
715  ! calculate d(residual)/dIL
716  dres = 1.0_dp + karman * grav / ( thm * dil ) * ( dbflx / dustarc**3 - bflx / ustarc**3 )
717 
718  ! stop iteration to prevent numerical error
719  if( abs( dres ) < eps ) exit
720 
721  ! convergence test with error levels
722  if( abs( res/dres ) < bulkflux_err_min ) exit
723 
724  ! avoid sign changing
725  if( il * ( il - res / dres ) < 0.0_rp ) exit
726 
727  ! update the inversed Obukhov length
728  il = il - res / dres
729  end do
730 
731  ! Successive approximation after Newton-Raphson method
732  if( .NOT. abs( res/dres ) < bulkflux_err_min ) then
733  ! unstable condition
734  if ( bulkflux_use_mean ) then
735  denom = log_z1ovz0m &
736  - fmm_unstable(dp_z1,il) + fmm_unstable(dp_z0m,il) * dp_z0m / dp_z1 &
737  + rzm * ( fm_unstable(dp_z0m,il) - 1.0_dp )
738  denoh = log_z1ovz0h &
739  - fhm_unstable(dp_z1,il) + fhm_unstable(dp_z0h,il) * dp_z0h / dp_z1 &
740  + rzh * ( fh_unstable(dp_z0h,il) - 1.0_dp )
741  denoe = log_z1ovz0e &
742  - fhm_unstable(dp_z1,il) + fhm_unstable(dp_z0e,il) * dp_z0e / dp_z1 &
743  + rze * ( fh_unstable(dp_z0e,il) - 1.0_dp )
744  else
745  denom = log_z1ovz0m - fm_unstable(dp_z1,il) + fm_unstable(dp_z0m,il)
746  denoh = log_z1ovz0h - fh_unstable(dp_z1,il) + fh_unstable(dp_z0h,il)
747  denoe = log_z1ovz0e - fh_unstable(dp_z1,il) + fh_unstable(dp_z0e,il)
748  end if
749  uabsus = max( sqrt( u1**2 + v1**2 + (bulkflux_wscf*wstar)**2 ), real( BULKFLUX_Uabs_min, kind=DP ) )
750  ustarus = karman / denom * uabsus
751  tstarus = karman / denoh * ( th1 - th0 )
752  qstarus = karman / denoe * ( q1 - q0 )
753 ! UstarUS = KARMAN / ( log_Z1ovZ0M - fm_unstable(DP_Z1,IL) + fm_unstable(DP_Z0M,IL) ) * UabsUS
754 ! TstarUS = KARMAN / ( log_Z1ovZ0H - fh_unstable(DP_Z1,IL) + fh_unstable(DP_Z0H,IL) ) * ( TH1 - TH0 )
755 ! QstarUS = KARMAN / ( log_Z1ovZ0E - fh_unstable(DP_Z1,IL) + fh_unstable(DP_Z0E,IL) ) * ( Q1 - Q0 )
756 
757  ! stable condition
758  if ( bulkflux_use_mean ) then
759  denom = log_z1ovz0m &
760  - fmm_stable(dp_z1,il) + fmm_stable(dp_z0m,il) * dp_z0m / dp_z1 &
761  + rzm * ( fm_stable(dp_z0m,il) - 1.0_dp )
762  denoh = log_z1ovz0h &
763  - fhm_stable(dp_z1,il) + fhm_stable(dp_z0h,il) * dp_z0h / dp_z1 &
764  + rzh * ( fh_stable(dp_z0h,il) - 1.0_dp )
765  denoe = log_z1ovz0e &
766  - fhm_stable(dp_z1,il) + fhm_stable(dp_z0e,il) * dp_z0e / dp_z1 &
767  + rze * ( fh_stable(dp_z0e,il) - 1.0_dp )
768  else
769  denom = log_z1ovz0m - fm_stable(dp_z1,il) + fm_stable(dp_z0m,il)
770  denoh = log_z1ovz0h - fh_stable(dp_z1,il) + fh_stable(dp_z0h,il)
771  denoe = log_z1ovz0e - fh_stable(dp_z1,il) + fh_stable(dp_z0e,il)
772  end if
773  uabss = max( sqrt( u1**2 + v1**2 ), bulkflux_uabs_min )
774  ustars = karman / denom * uabss
775  tstars = karman / denoh * ( th1 - th0 )
776  qstars = karman / denoe * ( q1 - q0 )
777 ! UstarS = KARMAN / ( log_Z1ovZ0M - fm_stable(DP_Z1,IL) + fm_stable(DP_Z0M,IL) ) * UabsS
778 ! TstarS = KARMAN / ( log_Z1ovZ0H - fh_stable(DP_Z1,IL) + fh_stable(DP_Z0H,IL) ) * ( TH1 - TH0 )
779 ! QstarS = KARMAN / ( log_Z1ovZ0E - fh_stable(DP_Z1,IL) + fh_stable(DP_Z0E,IL) ) * ( Q1 - Q0 )
780 
781  sw = 0.5_dp - sign( 0.5_dp, il ) ! if unstable, sw = 1
782 
783  ustarc = ( sw ) * ustarus + ( 1.0_dp-sw ) * ustars
784  tstarc = ( sw ) * tstarus + ( 1.0_dp-sw ) * tstars
785  qstarc = ( sw ) * qstarus + ( 1.0_dp-sw ) * qstars
786 
787  ! estimate buoyancy flux
788  bflx = - ustarc * tstarc * ( 1.0_rp + epstvap * qm ) - epstvap * ustarc * qstarc * thm
789 
790  ! update free convection velocity scale
791  tmp = pbl * grav / t1 * bflx
792  sw = 0.5_dp + sign( 0.5_dp, tmp ) ! if tmp is plus, sw = 1
793 
794  wstar = ( tmp * sw )**( 1.0_dp / 3.0_dp )
795 
796  ! avoid zero division with UstarC = 0
797  sw = 0.5_dp + sign( 0.5_dp, abs( ustarc ) - eps )
798 
799  ustarc = ( sw ) * ustarc + ( 1.0_dp-sw ) * eps
800 
801  ! estimate the inversed Obukhov length
802  il = - karman * grav * bflx / ( ustarc**3 * thm )
803  end if
804 
805 
806  ! calculate Ustar, Tstar, and Qstar based on IL
807 
808  ! unstable condition
809  if ( bulkflux_use_mean ) then
810  denom = log_z1ovz0m &
811  - fmm_unstable(dp_z1,il) + fmm_unstable(dp_z0m,il) * dp_z0m / dp_z1 &
812  + rzm * ( fm_unstable(dp_z0m,il) - 1.0_dp )
813  denoh = log_z1ovz0h &
814  - fhm_unstable(dp_z1,il) + fhm_unstable(dp_z0h,il) * dp_z0h / dp_z1 &
815  + rzh * ( fh_unstable(dp_z0h,il) - 1.0_dp )
816  denoe = log_z1ovz0e &
817  - fhm_unstable(dp_z1,il) + fhm_unstable(dp_z0e,il) * dp_z0e / dp_z1 &
818  + rze * ( fh_unstable(dp_z0e,il) - 1.0_dp )
819  else
820  denom = log_z1ovz0m - fm_unstable(dp_z1,il) + fm_unstable(dp_z0m,il)
821  denoh = log_z1ovz0h - fh_unstable(dp_z1,il) + fh_unstable(dp_z0h,il)
822  denoe = log_z1ovz0e - fh_unstable(dp_z1,il) + fh_unstable(dp_z0e,il)
823  end if
824  uabsus = max( sqrt( u1**2 + v1**2 + (bulkflux_wscf*wstar)**2 ), real( BULKFLUX_Uabs_min, kind=DP ) )
825  ustarus = karman / denom * uabsus
826  tstarus = karman / denoh * ( th1 - th0 )
827  qstarus = karman / denoe * ( q1 - q0 )
828 ! UstarUS = KARMAN / ( log_Z1ovZ0M - fm_unstable(DP_Z1,IL) + fm_unstable(DP_Z0M,IL) ) * UabsUS
829 ! TstarUS = KARMAN / ( log_Z1ovZ0H - fh_unstable(DP_Z1,IL) + fh_unstable(DP_Z0H,IL) ) * ( TH1 - TH0 )
830 ! QstarUS = KARMAN / ( log_Z1ovZ0E - fh_unstable(DP_Z1,IL) + fh_unstable(DP_Z0E,IL) ) * ( Q1 - Q0 )
831 
832  fracu10us = ( log_10ovz0m - fm_unstable(10.0_dp,il) + fm_unstable(dp_z0m,il) ) &
833  / ( log_z1ovz0m - fm_unstable( dp_z1,il) + fm_unstable(dp_z0m,il) )
834  fract2us = ( log_02ovz0h - fm_unstable( 2.0_dp,il) + fm_unstable(dp_z0h,il) ) &
835  / ( log_z1ovz0h - fm_unstable( dp_z1,il) + fm_unstable(dp_z0h,il) )
836  fracq2us = ( log_02ovz0e - fm_unstable( 2.0_dp,il) + fm_unstable(dp_z0e,il) ) &
837  / ( log_z1ovz0e - fm_unstable( dp_z1,il) + fm_unstable(dp_z0e,il) )
838 
839  ! stable condition
840  if ( bulkflux_use_mean ) then
841  denom = log_z1ovz0m &
842  - fmm_stable(dp_z1,il) + fmm_stable(dp_z0m,il) * dp_z0m / dp_z1 &
843  + rzm * ( fm_stable(dp_z0m,il) - 1.0_dp )
844  denoh = log_z1ovz0h &
845  - fhm_stable(dp_z1,il) + fhm_stable(dp_z0h,il) * dp_z0h / dp_z1 &
846  + rzh * ( fh_stable(dp_z0h,il) - 1.0_dp )
847  denoe = log_z1ovz0e &
848  - fhm_stable(dp_z1,il) + fhm_stable(dp_z0e,il) * dp_z0e / dp_z1 &
849  + rze * ( fh_stable(dp_z0e,il) - 1.0_dp )
850  else
851  denom = log_z1ovz0m - fm_stable(dp_z1,il) + fm_stable(dp_z0m,il)
852  denoh = log_z1ovz0h - fh_stable(dp_z1,il) + fh_stable(dp_z0h,il)
853  denoe = log_z1ovz0e - fh_stable(dp_z1,il) + fh_stable(dp_z0e,il)
854  end if
855  uabss = max( sqrt( u1**2 + v1**2 ), bulkflux_uabs_min )
856  ustars = karman / denom * uabss
857  tstars = karman / denoh * ( th1 - th0 )
858  qstars = karman / denoe * ( q1 - q0 )
859 ! UstarS = KARMAN / ( log_Z1ovZ0M - fm_stable(DP_Z1,IL) + fm_stable(DP_Z0M,IL) ) * UabsS
860 ! TstarS = KARMAN / ( log_Z1ovZ0H - fh_stable(DP_Z1,IL) + fh_stable(DP_Z0H,IL) ) * ( TH1 - TH0 )
861 ! QstarS = KARMAN / ( log_Z1ovZ0E - fh_stable(DP_Z1,IL) + fh_stable(DP_Z0E,IL) ) * ( Q1 - Q0 )
862 
863  fracu10s = ( log_10ovz0m - fm_stable(10.0_dp,il) + fm_stable(dp_z0m,il) ) &
864  / ( log_z1ovz0m - fm_stable( dp_z1,il) + fm_stable(dp_z0m,il) )
865  fract2s = ( log_02ovz0h - fm_stable( 2.0_dp,il) + fm_stable(dp_z0h,il) ) &
866  / ( log_z1ovz0h - fm_stable( dp_z1,il) + fm_stable(dp_z0h,il) )
867  fracq2s = ( log_02ovz0e - fm_stable( 2.0_dp,il) + fm_stable(dp_z0e,il) ) &
868  / ( log_z1ovz0e - fm_stable( dp_z1,il) + fm_stable(dp_z0e,il) )
869 
870  sw = 0.5_dp - sign( 0.5_dp, il ) ! if unstable, sw = 1
871 
872  ustarc = ( sw ) * ustarus + ( 1.0_dp-sw ) * ustars
873  tstarc = ( sw ) * tstarus + ( 1.0_dp-sw ) * tstars
874  qstarc = ( sw ) * qstarus + ( 1.0_dp-sw ) * qstars
875  uabsc = ( sw ) * uabsus + ( 1.0_dp-sw ) * uabss
876  fracu10c = ( sw ) * fracu10us + ( 1.0_dp-sw ) * fracu10s
877  fract2c = ( sw ) * fract2us + ( 1.0_dp-sw ) * fract2s
878  fracq2c = ( sw ) * fracq2us + ( 1.0_dp-sw ) * fracq2s
879 
880  ! revert to RP
881  ustar = real( ustarc, kind=rp )
882  tstar = real( tstarc, kind=rp )
883  qstar = real( qstarc, kind=rp )
884  uabs = real( uabsc, kind=rp )
885  fracu10 = real( fracu10c, kind=rp )
886  fract2 = real( fract2c, kind=rp )
887  fracq2 = real( fracq2c, kind=rp )
888 
889  ra = max( ( q1 - q0 ) / real(UstarC * QstarC + EPS,kind=RP), eps )
890 
891 
892  return
893  end subroutine bulkflux_b91w01
894 
895  !-----------------------------------------------------------------------------
896  ! stability function for momemtum in unstable condition
897  function fm_unstable( Z, IL )
898  use scale_const, only: &
899  pi => const_pi
900  implicit none
901 
902  ! argument
903  real(DP), intent(in) :: Z
904  real(DP), intent(in) :: IL
905 
906  ! function
907  real(DP) :: fm_unstable
908 
909  ! Wilson (2001)
910  real(DP), parameter :: gamma = 3.6_dp
911 
912  ! works
913  real(DP) :: R
914  real(DP) :: r4R
915  !---------------------------------------------------------------------------
916 
917  r = min( z * il, 0.0_dp )
918 
919  if ( flag_w01 ) then
920  ! Wilson (2001)
921  fm_unstable = 3.0_dp * log( ( 1.0_dp + sqrt( 1.0_dp + gamma * (-r)**(2.0_dp/3.0_dp) ) ) * 0.5_dp )
922  else
923  ! Beljaars and Holtslag (1994), originally Paulson (1974) and Dyer (1974)
924  r4r = sqrt( sqrt( 1.0_dp - 16.0_dp * r ) )
925  fm_unstable = log( ( 1.0_dp + r4r )**2 * ( 1.0_dp + r4r * r4r ) * 0.125_dp ) - 2.0_dp * atan( r4r ) + pi * 0.5_dp
926  end if
927 
928  return
929  end function fm_unstable
930  function fmm_unstable( Z, IL )
931  use scale_const, only: &
932  pi => const_pi, &
933  eps => const_eps
934  implicit none
935 
936  ! argument
937  real(DP), intent(in) :: Z
938  real(DP), intent(in) :: IL
939 
940  ! function
941  real(DP) :: fmm_unstable
942 
943  ! Wilson (2001)
944  real(DP), parameter :: gamma = 3.6_dp
945 
946  ! works
947  real(DP) :: R
948  real(DP) :: f, r3
949  real(DP) :: r4R, r2R
950  !---------------------------------------------------------------------------
951 
952  r = min( z * il, 0.0_dp )
953 
954  if ( flag_w01 ) then
955  ! Wilson (2001)
956  r3 = (-r)**(1.0_dp/3.0_dp)
957  if ( r > -eps ) then
958  fmm_unstable = 9.0_dp / 20.0_dp * gamma * r3**2
959  else
960  f = sqrt( 1.0_dp + gamma * r3**2 )
961  fmm_unstable = 3.0_dp * log( ( 1.0_dp + f ) * 0.5_dp ) &
962  + 1.5_dp / ( sqrt(gamma)**3 * r) * asinh( sqrt(gamma) * r3 ) &
963  + 1.5_dp * f / ( gamma * r3**2 ) &
964  - 1.0_dp
965  end if
966  else
967  ! Beljaars and Holtslag (1994), originally Paulson (1974) and Dyer (1974)
968  if ( r > -eps ) then ! |R|<EPS, now R < 0
969  fmm_unstable = - 2.0_dp * r
970  else
971  r2r = sqrt( 1.0_dp - 16.0_dp * r )
972  r4r = sqrt( r2r )
973  fmm_unstable = log( ( 1.0_dp + r4r )**2 * ( 1.0_dp + r2r ) * 0.125_dp ) &
974  - 2.0_dp * atan( r4r ) &
975  + ( 1.0_dp - r4r*r2r ) / ( 12.0_dp * r ) &
976  + pi * 0.5_dp - 1.0_dp
977  end if
978  end if
979 
980  return
981  end function fmm_unstable
982 
983  !-----------------------------------------------------------------------------
984  ! stability function for heat/vapor in unstable condition
985  function fh_unstable( Z, IL )
986  implicit none
987 
988  ! argument
989  real(DP), intent(in) :: Z
990  real(DP), intent(in) :: IL
991 
992  ! function
993  real(DP) :: fh_unstable
994 
995  ! Wilson (2001)
996  real(DP), parameter :: Pt = 0.95_dp ! turbulent Prandtl number
997  real(DP), parameter :: gamma = 7.9_dp
998 
999  ! works
1000  real(DP) :: R
1001  !---------------------------------------------------------------------------
1002 
1003  r = min( z * il, 0.0_dp )
1004 
1005  if ( flag_w01 ) then
1006  ! Wilson (2001)
1007  fh_unstable = 3.0_dp * log( ( 1.0_dp + sqrt( 1.0_dp + gamma * (-r)**(2.0_dp/3.0_dp) ) ) * 0.5_dp ) * pt &
1008  + log( z ) * ( 1.0_dp - pt )
1009  else
1010  ! Beljaars and Holtslag (1994), originally Paulson (1974); Dyer (1974)
1011  fh_unstable = 2.0_dp * log( ( 1.0_dp + sqrt( 1.0_dp - 16.0_dp * r ) ) * 0.5_dp )
1012  end if
1013 
1014  return
1015  end function fh_unstable
1016  function fhm_unstable( Z, IL )
1017  use scale_const, only: &
1018  eps => const_eps
1019  implicit none
1020 
1021  ! argument
1022  real(DP), intent(in) :: Z
1023  real(DP), intent(in) :: IL
1024 
1025  ! function
1026  real(DP) :: fhm_unstable
1027 
1028  ! Wilson (2001)
1029  real(DP), parameter :: Pt = 0.95_dp ! turbulent Prandtl number
1030  real(DP), parameter :: gamma = 7.9_dp
1031 
1032  ! works
1033  real(DP) :: R
1034  real(DP) :: f, r3
1035  real(DP) :: r2R
1036  !---------------------------------------------------------------------------
1037 
1038  r = min( z * il, 0.0_dp )
1039 
1040  if ( flag_w01 ) then
1041  ! Wilson (2001)
1042  r3 = (-r)**(1.0_dp/3.0_dp)
1043  if ( r > -eps ) then
1044  fhm_unstable = 9.0_dp / 20.0_dp * gamma * r3**2
1045  else
1046  f = sqrt( 1.0_dp + gamma * r3**2 )
1047  fhm_unstable = 3.0_dp * log( ( 1.0_dp + f ) * 0.5_dp ) &
1048  + 1.5_dp / ( sqrt(gamma)**3 * r) * asinh( sqrt(gamma) * r3 ) &
1049  + 1.5_dp * f / ( gamma * r3**2 ) &
1050  - 1.0_dp
1051  fhm_unstable = fhm_unstable * pt + ( log( z ) - 1.0_dp ) * ( 1.0_dp - pt )
1052  end if
1053  else
1054  ! Beljaars and Holtslag (1994), originally Paulson (1974); Dyer (1974)
1055  if ( r > -eps ) then ! |R| < EPS, now R < 0
1056  fhm_unstable = - 4.0_dp * r
1057  else
1058  r2r = sqrt( 1.0_dp - 16.0_dp * r )
1059  fhm_unstable = 2.0_dp * log( ( 1.0_dp + r2r ) * 0.5_dp ) &
1060  + ( 1.0_dp - r2r ) / ( 8.0_dp * r ) &
1061  - 1.0_dp
1062  end if
1063  end if
1064 
1065  return
1066  end function fhm_unstable
1067 
1068  !-----------------------------------------------------------------------------
1069  ! stability function for momemtum in stable condition
1070  function fm_stable( Z, IL )
1071  implicit none
1072 
1073  ! argument
1074  real(DP), intent(in) :: Z
1075  real(DP), intent(in) :: IL
1076 
1077  ! function
1078  real(DP) :: fm_stable
1079 
1080  ! parameters of stability functions (Beljaars and Holtslag 1991)
1081  real(DP), parameter :: a = 1.0_dp
1082  real(DP), parameter :: b = 0.667_dp
1083  real(DP), parameter :: c = 5.0_dp
1084  real(DP), parameter :: d = 0.35_dp
1085 
1086  ! works
1087  real(DP) :: R
1088  !---------------------------------------------------------------------------
1089 
1090  r = max( z * il, 0.0_dp )
1091 
1092  ! Holtslag and DeBruin (1988)
1093 #if defined(PGI) || defined(SX)
1094  fm_stable = - a*r - b*( r - c/d )*exp( -min( d*r, 1.e+3_rp ) ) - b*c/d ! apply exp limiter
1095 #else
1096  fm_stable = - a*r - b*( r - c/d )*exp( -d*r ) - b*c/d
1097 #endif
1098 
1099  return
1100  end function fm_stable
1101  function fmm_stable( Z, IL )
1102  use scale_const, only: &
1103  eps => const_eps
1104  implicit none
1105 
1106  ! argument
1107  real(DP), intent(in) :: Z
1108  real(DP), intent(in) :: IL
1109 
1110  ! function
1111  real(DP) :: fmm_stable
1112 
1113  ! parameters of stability functions (Beljaars and Holtslag 1991)
1114  real(DP), parameter :: a = 1.0_dp
1115  real(DP), parameter :: b = 0.667_dp
1116  real(DP), parameter :: c = 5.0_dp
1117  real(DP), parameter :: d = 0.35_dp
1118 
1119  ! works
1120  real(DP) :: R
1121  !---------------------------------------------------------------------------
1122 
1123  r = max( z * il, 0.0_dp )
1124 
1125  ! Holtslag and DeBruin (1988)
1126  if ( r < eps ) then
1127  fmm_stable = - 0.5_dp * ( a + b * c + d ) * r
1128  else
1129  fmm_stable = b * ( d*r - c + 1.0_dp ) / ( d**2 * r ) &
1130 #if defined(__PGI) || defined(__ES2)
1131  ! apply exp limiter
1132  * exp( -min( d*r, 1.e+3_dp ) ) &
1133 #else
1134  * exp( -d*r ) &
1135 #endif
1136  - a * r * 0.5_dp &
1137  - b * ( c*d*r - c + 1.0_dp ) / ( d**2 * r )
1138  end if
1139 
1140  return
1141  end function fmm_stable
1142 
1143  !-----------------------------------------------------------------------------
1144  ! stability function for heat/vapor in stable condition
1145  function fh_stable( Z, IL )
1146  implicit none
1147 
1148  ! argument
1149  real(DP), intent(in) :: Z
1150  real(DP), intent(in) :: IL
1151 
1152  ! function
1153  real(DP) :: fh_stable
1154 
1155  ! parameters of stability functions (Beljaars and Holtslag 1991)
1156  real(DP), parameter :: a = 1.0_dp
1157  real(DP), parameter :: b = 0.667_dp
1158  real(DP), parameter :: c = 5.0_dp
1159  real(DP), parameter :: d = 0.35_dp
1160 
1161  ! works
1162  real(DP) :: R
1163  !---------------------------------------------------------------------------
1164 
1165  r = max( z * il, 0.0_dp )
1166 
1167  ! Beljaars and Holtslag (1991)
1168 #if defined(PGI) || defined(SX)
1169  fh_stable = 1.0_dp - ( 1.0_dp + 2.0_dp/3.0_dp * a*r )**1.5_dp - b*( r - c/d )*exp( -min( d*r, 1.e+3_rp ) ) - b*c/d ! apply exp limiter
1170 #else
1171  fh_stable = 1.0_dp - ( 1.0_dp + 2.0_dp/3.0_dp * a*r )**1.5_dp - b*( r - c/d )*exp( -d*r ) - b*c/d
1172 #endif
1173 
1174  return
1175  end function fh_stable
1176  function fhm_stable( Z, IL )
1177  use scale_const, only: &
1178  eps => const_eps
1179  implicit none
1180 
1181  ! argument
1182  real(DP), intent(in) :: Z
1183  real(DP), intent(in) :: IL
1184 
1185  ! function
1186  real(DP) :: fhm_stable
1187 
1188  ! parameters of stability functions (Beljaars and Holtslag 1991)
1189  real(DP), parameter :: a = 1.0_dp
1190  real(DP), parameter :: b = 0.667_dp
1191  real(DP), parameter :: c = 5.0_dp
1192  real(DP), parameter :: d = 0.35_dp
1193 
1194  ! works
1195  real(DP) :: R
1196  !---------------------------------------------------------------------------
1197 
1198  r = max( z * il, 0.0_dp )
1199 
1200  ! Beljaars and Holtslag (1991)
1201  if ( r < eps ) then
1202  fhm_stable = - 0.5_dp * ( a + b*c + b ) * r
1203  else
1204  fhm_stable = b * ( d*r - c + 1.0_dp ) / ( d**2 * r ) &
1205 #if defined(__PGI) || defined(__ES2)
1206  * exp( -min( d*r, 1.e+3_dp) ) &
1207 #else
1208  * exp( -d*r ) &
1209 #endif
1210  - 3.0_dp * sqrt( 1.0_dp + 2.0_dp*a*r/3.0_dp )**5 / ( 5.0_dp * a * r ) &
1211  - b * ( c*d*r - c + 1.0_dp ) / ( d**2 * r ) &
1212  + 0.6_rp / ( a * r ) + 1.0_dp
1213  end if
1214 
1215  return
1216  end function fhm_stable
1217 
1218 end module scale_bulkflux
real(rp), public const_cpdry
specific heat (dry air,constant pressure) [J/kg/K]
Definition: scale_const.F90:56
integer, public io_fid_conf
Config file ID.
Definition: scale_io.F90:55
real(rp), parameter, public const_karman
von Karman constant
Definition: scale_const.F90:50
real(rp), public const_rdry
specific gas constant (dry air) [J/kg/K]
Definition: scale_const.F90:55
real(rp), public const_pre00
pressure reference [Pa]
Definition: scale_const.F90:88
module PROCESS
Definition: scale_prc.F90:11
real(dp) function fmm_unstable(Z, IL)
procedure(bc), pointer, public bulkflux
real(rp), public const_grav
standard acceleration of gravity [m/s2]
Definition: scale_const.F90:46
real(rp), public const_epstvap
1 / epsilon - 1
Definition: scale_const.F90:70
subroutine, public prc_abort
Abort Process.
Definition: scale_prc.F90:338
module CONSTANT
Definition: scale_const.F90:11
module profiler
Definition: scale_prof.F90:11
module Surface bulk flux
real(rp), public const_eps
small number
Definition: scale_const.F90:33
module PRECISION
real(rp), public const_pi
pi
Definition: scale_const.F90:31
module STDIO
Definition: scale_io.F90:10
subroutine, public bulkflux_setup(dx)
integer, parameter, public rp
integer, parameter, public dp