28 public :: bulkflux_diagnose_scales
29 public :: bulkflux_diagnose_surface
32 interface bulkflux_diagnose_scales
35 end interface bulkflux_diagnose_scales
37 interface bulkflux_diagnose_surface
38 module procedure bulkflux_diagnose_surface_0d
40 end interface bulkflux_diagnose_surface
50 Ustar, Tstar, Qstar, &
52 FracU10, FracT2, FracQ2, &
56 real(RP),
intent(in) :: T1
57 real(RP),
intent(in) :: T0
58 real(RP),
intent(in) :: P1
59 real(RP),
intent(in) :: P0
60 real(RP),
intent(in) :: Q1
61 real(RP),
intent(in) :: Q0
62 real(RP),
intent(in) :: Uabs
63 real(RP),
intent(in) :: Z1
64 real(RP),
intent(in) :: PBL
65 real(RP),
intent(in) :: Z0M
66 real(RP),
intent(in) :: Z0H
67 real(RP),
intent(in) :: Z0E
69 real(RP),
intent(out) :: Ustar
70 real(RP),
intent(out) :: Tstar
71 real(RP),
intent(out) :: Qstar
72 real(RP),
intent(out) :: Wstar
73 real(RP),
intent(out) :: RLmo
74 real(RP),
intent(out) :: Ra
75 real(RP),
intent(out) :: FracU10
76 real(RP),
intent(out) :: FracT2
77 real(RP),
intent(out) :: FracQ2
79 real(RP),
intent(in),
optional :: RLmo_in
80 real(RP),
intent(in),
optional :: Wstar_in
99 private :: bulkflux_u95
100 private :: bulkflux_b91w01
101 private :: pm_unstable
102 private :: fm_unstable
103 private :: fmm_unstable
104 private :: ph_unstable
105 private :: fh_unstable
106 private :: fhm_unstable
109 private :: fmm_stable
112 private :: fhm_stable
118 real(
dp),
parameter,
private :: eps = 1.e-16_dp
120 logical,
private :: bulkflux_nk2018 = .true.
122 integer,
private :: bulkflux_itr_sa_max = 5
123 integer,
private :: bulkflux_itr_nr_max = 10
126 real(
rp),
private :: bulkflux_wscf
130 real(
rp),
private :: bulkflux_uabs_min = 1.0e-2_rp
131 real(
rp),
private :: bulkflux_wstar_min = 1.0e-4_rp
135 logical,
private :: bulkflux_surfdiag_neutral = .true.
138 logical,
private :: flag_b71
139 logical,
private :: flag_w01
151 real(
rp),
intent(in) :: dx
153 namelist / param_bulkflux / &
156 bulkflux_itr_sa_max, &
157 bulkflux_itr_nr_max, &
160 bulkflux_wstar_min, &
161 bulkflux_surfdiag_neutral
167 log_info(
"BULKFLUX_setup",*)
'Setup'
171 bulkflux_wscf = 1.2_rp * min(dx*1.e-3_rp, 1.0_rp)
179 log_info(
"BULKFLUX_setup",*)
'Not found namelist. Default used.'
180 elseif( ierr > 0 )
then
181 log_error(
"BULKFLUX_setup",*)
'Not appropriate names in namelist PARAM_BULKFLUX. Check!'
184 log_nml(param_bulkflux)
187 log_info(
"BULKFLUX_setup",*)
'Scheme for surface bulk flux : ', trim(
bulkflux_type)
190 log_info_cont(*)
'=> Uno et al.(1995)'
195 log_info_cont(*)
'=> Businger et al. (1971)'
202 log_info_cont(*)
'=> Beljaars and Holtslag (1991) and Wilson (2001)'
209 log_info_cont(*)
'=> Beljaars and Holtslag (1991)'
216 log_error(
"BULKFLUX_setup",*)
'Unsupported BULKFLUX_type. STOP'
233 IA, IS, IE, JA, JS, JE, &
234 SFLX_MW, SFLX_MU, SFLX_MV, &
236 SFC_DENS, SFC_POTV, PBL, &
237 Ustar, Tstar, Qstar, &
247 integer,
intent(in) :: IA, IS, IE
248 integer,
intent(in) :: JA, JS, JE
250 real(RP),
intent(in) :: SFLX_MW (IA,JA)
251 real(RP),
intent(in) :: SFLX_MU (IA,JA)
252 real(RP),
intent(in) :: SFLX_MV (IA,JA)
253 real(RP),
intent(in) :: SFLX_SH (IA,JA)
254 real(RP),
intent(in) :: SFLX_QV (IA,JA)
255 real(RP),
intent(in) :: SFC_DENS(IA,JA)
256 real(RP),
intent(in) :: SFC_POTV(IA,JA)
257 real(RP),
intent(in) :: PBL (IA,JA)
259 real(RP),
intent(out) :: Ustar(IA,JA)
260 real(RP),
intent(out) :: Tstar(IA,JA)
261 real(RP),
intent(out) :: Qstar(IA,JA)
262 real(RP),
intent(out) :: Wstar(IA,JA)
263 real(RP),
intent(out) :: RLmo (IA,JA)
265 logical,
intent(in),
optional :: mask(IA,JA)
269 if (
present(mask) )
then
274 if ( mask(i,j) )
then
276 sflx_sh(i,j), sflx_qv(i,j), &
277 sfc_dens(i,j), sfc_potv(i,j), pbl(i,j), &
278 ustar(i,j), tstar(i,j), qstar(i,j), &
279 wstar(i,j), rlmo(i,j) )
290 sflx_sh(i,j), sflx_qv(i,j), &
291 sfc_dens(i,j), sfc_potv(i,j), pbl(i,j), &
292 ustar(i,j), tstar(i,j), qstar(i,j), &
293 wstar(i,j), rlmo(i,j) )
303 SFLX_MW, SFLX_MU, SFLX_MV, &
305 SFC_DENS, SFC_POTV, PBL, &
306 Ustar, Tstar, Qstar, &
316 real(RP),
intent(in) :: SFLX_MW
317 real(RP),
intent(in) :: SFLX_MU
318 real(RP),
intent(in) :: SFLX_MV
319 real(RP),
intent(in) :: SFLX_SH
320 real(RP),
intent(in) :: SFLX_QV
321 real(RP),
intent(in) :: SFC_DENS
322 real(RP),
intent(in) :: SFC_POTV
323 real(RP),
intent(in) :: PBL
325 real(RP),
intent(out) :: Ustar
326 real(RP),
intent(out) :: Tstar
327 real(RP),
intent(out) :: Qstar
328 real(RP),
intent(out) :: Wstar
329 real(RP),
intent(out) :: RLmo
331 real(RP) :: BFLX, tmp, sw
337 ustar = sqrt( sqrt( sflx_mw**2 + sflx_mu**2 + sflx_mv**2 ) / sfc_dens )
338 sw = 0.5_rp - sign( 0.5_rp, ustar - eps )
339 tstar = - sflx_sh / ( sfc_dens * ustar * cpdry + sw ) * ( 1.0_rp - sw )
340 qstar = - sflx_qv / ( sfc_dens * ustar + sw ) * ( 1.0_rp - sw )
341 bflx = - ustar * tstar - epstvap * ustar * qstar * sfc_potv
342 rlmo = - karman * grav * bflx / ( ustar**3 * sfc_potv + sw ) * ( 1.0_rp - sw )
344 tmp = pbl * grav / sfc_potv * bflx
345 sw = 0.5_rp + sign( 0.5_rp, tmp )
346 wstar = ( tmp * sw )**( 1.0_rp / 3.0_rp )
358 IA, IS, IE, JA, JS, JE, &
363 SFC_Z0M, SFC_Z0H, SFC_Z0E, &
366 FracU10, FracT2, FracQ2 )
368 integer,
intent(in) :: IA, IS, IE
369 integer,
intent(in) :: JA, JS, JE
371 real(RP),
intent(in) :: ATM_U (IA,JA)
372 real(RP),
intent(in) :: ATM_V (IA,JA)
373 real(RP),
intent(in) :: ATM_TEMP(IA,JA)
374 real(RP),
intent(in) :: ATM_QV (IA,JA)
375 real(RP),
intent(in) :: SFC_TEMP(IA,JA)
376 real(RP),
intent(in) :: SFC_QV (IA,JA)
377 real(RP),
intent(in) :: ATM_Z1 (IA,JA)
378 real(RP),
intent(in) :: SFC_Z0M (IA,JA)
379 real(RP),
intent(in) :: SFC_Z0H (IA,JA)
380 real(RP),
intent(in) :: SFC_Z0E (IA,JA)
382 real(RP),
intent(out) :: U10(IA,JA)
383 real(RP),
intent(out) :: V10(IA,JA)
384 real(RP),
intent(out) :: T2 (IA,JA)
385 real(RP),
intent(out) :: Q2 (IA,JA)
387 logical,
intent(in),
optional :: mask (IA,JA)
388 real(RP),
intent(in),
optional :: FracU10(IA,JA)
389 real(RP),
intent(in),
optional :: FracT2 (IA,JA)
390 real(RP),
intent(in),
optional :: FracQ2 (IA,JA)
394 if (
present(fracu10) )
then
395 if (
present(mask) )
then
400 if ( mask(i,j) )
then
401 call bulkflux_diagnose_surface_0d( atm_u(i,j), atm_v(i,j), &
402 atm_temp(i,j), atm_qv(i,j), &
403 sfc_temp(i,j), sfc_qv(i,j), &
405 sfc_z0m(i,j), sfc_z0h(i,j), sfc_z0e(i,j), &
406 u10(i,j), v10(i,j), t2(i,j), q2(i,j), &
407 fracu10(i,j), fract2(i,j), fracq2(i,j) )
418 call bulkflux_diagnose_surface_0d( atm_u(i,j), atm_v(i,j), &
419 atm_temp(i,j), atm_qv(i,j), &
420 sfc_temp(i,j), sfc_qv(i,j), &
422 sfc_z0m(i,j), sfc_z0h(i,j), sfc_z0e(i,j), &
423 u10(i,j), v10(i,j), t2(i,j), q2(i,j), &
424 fracu10(i,j), fract2(i,j), fracq2(i,j) )
430 if (
present(mask) )
then
435 if ( mask(i,j) )
then
436 call bulkflux_diagnose_surface_0d( atm_u(i,j), atm_v(i,j), &
437 atm_temp(i,j), atm_qv(i,j), &
438 sfc_temp(i,j), sfc_qv(i,j), &
440 sfc_z0m(i,j), sfc_z0h(i,j), sfc_z0e(i,j), &
441 u10(i,j), v10(i,j), t2(i,j), q2(i,j) )
452 call bulkflux_diagnose_surface_0d( atm_u(i,j), atm_v(i,j), &
453 atm_temp(i,j), atm_qv(i,j), &
454 sfc_temp(i,j), sfc_qv(i,j), &
456 sfc_z0m(i,j), sfc_z0h(i,j), sfc_z0e(i,j), &
457 u10(i,j), v10(i,j), t2(i,j), q2(i,j) )
467 subroutine bulkflux_diagnose_surface_0d( &
472 SFC_Z0M, SFC_Z0H, SFC_Z0E, &
474 FracU10, FracT2, FracQ2 )
477 real(RP),
intent(in) :: ATM_U
478 real(RP),
intent(in) :: ATM_V
479 real(RP),
intent(in) :: ATM_TEMP
480 real(RP),
intent(in) :: ATM_QV
481 real(RP),
intent(in) :: SFC_TEMP
482 real(RP),
intent(in) :: SFC_QV
483 real(RP),
intent(in) :: ATM_Z1
484 real(RP),
intent(in) :: SFC_Z0M
485 real(RP),
intent(in) :: SFC_Z0H
486 real(RP),
intent(in) :: SFC_Z0E
488 real(RP),
intent(out) :: U10
489 real(RP),
intent(out) :: V10
490 real(RP),
intent(out) :: T2
491 real(RP),
intent(out) :: Q2
493 real(RP),
intent(in),
optional :: FracU10
494 real(RP),
intent(in),
optional :: FracT2
495 real(RP),
intent(in),
optional :: FracQ2
497 real(RP) :: f10m, f2h, f2e
499 if ( bulkflux_surfdiag_neutral .or. ( .not.
present(fracu10) ) )
then
501 f10m = log( 10.0_rp / sfc_z0m ) / log( atm_z1 / sfc_z0m )
502 f2h = log( 2.0_rp / sfc_z0h ) / log( atm_z1 / sfc_z0h )
503 f2e = log( 2.0_rp / sfc_z0e ) / log( atm_z1 / sfc_z0e )
512 t2 = sfc_temp + ( atm_temp - sfc_temp ) * f2h
513 q2 = sfc_qv + ( atm_qv - sfc_qv ) * f2e
516 end subroutine bulkflux_diagnose_surface_0d
525 Ustar, Tstar, Qstar, &
527 FracU10, FracT2, FracQ2, &
530 real(RP),
intent(in) :: T1
531 real(RP),
intent(in) :: T0
532 real(RP),
intent(in) :: P1
533 real(RP),
intent(in) :: P0
534 real(RP),
intent(in) :: Q1
535 real(RP),
intent(in) :: Q0
536 real(RP),
intent(in) :: Uabs
537 real(RP),
intent(in) :: Z1
538 real(RP),
intent(in) :: PBL
539 real(RP),
intent(in) :: Z0M
540 real(RP),
intent(in) :: Z0H
541 real(RP),
intent(in) :: Z0E
543 real(RP),
intent(out) :: Ustar
544 real(RP),
intent(out) :: Tstar
545 real(RP),
intent(out) :: Qstar
546 real(RP),
intent(out) :: Wstar
547 real(RP),
intent(out) :: RLmo
548 real(RP),
intent(out) :: Ra
549 real(RP),
intent(out) :: FracU10
550 real(RP),
intent(out) :: FracT2
551 real(RP),
intent(out) :: FracQ2
553 real(RP),
intent(in),
optional :: RLmo_in
554 real(RP),
intent(in),
optional :: Wstar_in
564 ustar, tstar, qstar, &
566 fracu10, fract2, fracq2, &
568 case(
'B71',
'B91W01',
'B91')
569 call bulkflux_b91w01( &
575 ustar, tstar, qstar, &
577 fracu10, fract2, fracq2, &
588 subroutine bulkflux_u95( &
594 Ustar, Tstar, Qstar, &
596 FracU10, FracT2, FracQ2, &
608 real(RP),
parameter :: tPrn = 0.74_rp
609 real(RP),
parameter :: LFb = 9.4_rp
610 real(RP),
parameter :: LFbp = 4.7_rp
611 real(RP),
parameter :: LFdm = 7.4_rp
612 real(RP),
parameter :: LFdh = 5.3_rp
615 real(RP),
intent(in) :: T1
616 real(RP),
intent(in) :: T0
617 real(RP),
intent(in) :: P1
618 real(RP),
intent(in) :: P0
619 real(RP),
intent(in) :: Q1
620 real(RP),
intent(in) :: Q0
621 real(RP),
intent(in) :: Uabs
622 real(RP),
intent(in) :: Z1
623 real(RP),
intent(in) :: PBL
624 real(RP),
intent(in) :: Z0M
625 real(RP),
intent(in) :: Z0H
626 real(RP),
intent(in) :: Z0E
628 real(RP),
intent(out) :: Ustar
629 real(RP),
intent(out) :: Tstar
630 real(RP),
intent(out) :: Qstar
631 real(RP),
intent(out) :: Wstar
632 real(RP),
intent(out) :: RLmo
633 real(RP),
intent(out) :: Ra
634 real(RP),
intent(out) :: FracU10
635 real(RP),
intent(out) :: FracT2
636 real(RP),
intent(out) :: FracQ2
638 real(RP),
intent(in),
optional :: RLmo_in
639 real(RP),
intent(in),
optional :: Wstar_in
643 real(RP) :: RiB0, RiB
644 real(RP) :: C0Z1, C010, C002
645 real(RP) :: CmZ1, ChZ1, CqZ1, fmZ1, fhZ1, t0thZ1, q0qeZ1
646 real(RP) :: Cm10, fm10
647 real(RP) :: Cm02, Ch02, Cq02, fm02, fh02, t0th02, q0qe02
649 real(RP) :: logZ1Z0M, log10Z0m, log02Z0m
650 real(RP) :: logZ0MZ0E
651 real(RP) :: logZ0MZ0H
654 logz1z0m = log( z1 / z0m )
655 log10z0m = log( 10.0_rp / z0m )
656 log02z0m = log( 2.0_rp / z0m )
658 logz0mz0e = max( log( z0m/z0e ), 1.0_rp )
659 logz0mz0h = max( log( z0m/z0h ), 1.0_rp )
661 uabsw = max( uabs, bulkflux_uabs_min )
662 th1 = t1 * ( p0 / p1 )**( rdry / cpdry )
666 rib0 = grav * z1 * ( th1 - th0 ) / ( th1 * uabsw**2 )
668 c0z1 = ( karman / logz1z0m )**2
669 c010 = ( karman / log10z0m )**2
670 c002 = ( karman / log02z0m )**2
674 if( rib0 > 0.0_rp )
then
676 fmz1 = 1.0_rp / ( 1.0_rp + lfbp * rib )**2
677 fhz1 = 1.0_rp / ( 1.0_rp + lfbp * rib )**2
678 fm10 = 1.0_rp / ( 1.0_rp + lfbp * rib )**2
679 fm02 = 1.0_rp / ( 1.0_rp + lfbp * rib )**2
680 fh02 = 1.0_rp / ( 1.0_rp + lfbp * rib )**2
683 fmz1 = 1.0_rp - lfb * rib / ( 1.0_rp + lfb * lfdm * c0z1 * sqrt( z1 / z0m ) * sqrt( abs( rib ) ) )
684 fhz1 = 1.0_rp - lfb * rib / ( 1.0_rp + lfb * lfdh * c0z1 * sqrt( z1 / z0m ) * sqrt( abs( rib ) ) )
685 fm10 = 1.0_rp - lfb * rib / ( 1.0_rp + lfb * lfdm * c010 * sqrt( 10.0_rp / z0m ) * sqrt( abs( rib ) ) )
686 fm02 = 1.0_rp - lfb * rib / ( 1.0_rp + lfb * lfdm * c002 * sqrt( 2.0_rp / z0m ) * sqrt( abs( rib ) ) )
687 fh02 = 1.0_rp - lfb * rib / ( 1.0_rp + lfb * lfdh * c002 * sqrt( 2.0_rp / z0m ) * sqrt( abs( rib ) ) )
690 t0thz1 = 1.0_rp / ( 1.0_rp + logz0mz0h / logz1z0m / sqrt( fmz1 ) * fhz1 )
691 q0qez1 = 1.0_rp / ( 1.0_rp + logz0mz0e / logz1z0m / sqrt( fmz1 ) * fhz1 )
692 t0th02 = 1.0_rp / ( 1.0_rp + logz0mz0h / log02z0m / sqrt( fm02 ) * fh02 )
693 q0qe02 = 1.0_rp / ( 1.0_rp + logz0mz0e / log02z0m / sqrt( fm02 ) * fh02 )
697 if( rib0 > 0.0_rp )
then
699 fmz1 = 1.0_rp / ( 1.0_rp + lfbp * rib )**2
700 fhz1 = 1.0_rp / ( 1.0_rp + lfbp * rib )**2
701 fm10 = 1.0_rp / ( 1.0_rp + lfbp * rib )**2
702 fm02 = 1.0_rp / ( 1.0_rp + lfbp * rib )**2
703 fh02 = 1.0_rp / ( 1.0_rp + lfbp * rib )**2
706 fmz1 = 1.0_rp - lfb * rib / ( 1.0_rp + lfb * lfdm * c0z1 * sqrt( z1 / z0m ) * sqrt( abs( rib ) ) )
707 fhz1 = 1.0_rp - lfb * rib / ( 1.0_rp + lfb * lfdh * c0z1 * sqrt( z1 / z0m ) * sqrt( abs( rib ) ) )
708 fm10 = 1.0_rp - lfb * rib / ( 1.0_rp + lfb * lfdm * c010 * sqrt( 10.0_rp / z0m ) * sqrt( abs( rib ) ) )
709 fm02 = 1.0_rp - lfb * rib / ( 1.0_rp + lfb * lfdm * c002 * sqrt( 2.0_rp / z0m ) * sqrt( abs( rib ) ) )
710 fh02 = 1.0_rp - lfb * rib / ( 1.0_rp + lfb * lfdh * c002 * sqrt( 2.0_rp / z0m ) * sqrt( abs( rib ) ) )
713 t0thz1 = 1.0_rp / ( 1.0_rp + logz0mz0h / logz1z0m / sqrt( fmz1 ) * fhz1 )
714 q0qez1 = 1.0_rp / ( 1.0_rp + logz0mz0e / logz1z0m / sqrt( fmz1 ) * fhz1 )
715 t0th02 = 1.0_rp / ( 1.0_rp + logz0mz0h / log02z0m / sqrt( fm02 ) * fh02 )
716 q0qe02 = 1.0_rp / ( 1.0_rp + logz0mz0e / log02z0m / sqrt( fm02 ) * fh02 )
719 chz1 = c0z1 * fhz1 * t0thz1 / tprn
720 cqz1 = c0z1 * fhz1 * q0qez1 / tprn
723 ch02 = c002 * fh02 * t0th02 / tprn
724 cq02 = c002 * fh02 * q0qe02 / tprn
726 ustar = sqrt( cmz1 ) * uabsw
727 tstar = chz1 * uabsw / ustar * ( th1 - th0 )
728 qstar = cqz1 * uabsw / ustar * ( q1 - q0 )
729 if (
present(wstar_in) )
then
735 fracu10 = sqrt( cmz1 / cm10 )
736 fract2 = chz1 / ch02 * sqrt( cm02 / cmz1 )
737 fracq2 = cqz1 / cq02 * sqrt( cm02 / cmz1 )
739 rlmo = rib / z1 * karman * chz1 / ( cmz1 * sqrt( cmz1 ) )
741 ra = 1.0_rp / ( cqz1 * uabsw )
744 end subroutine bulkflux_u95
754 subroutine bulkflux_b91w01( &
760 Ustar, Tstar, Qstar, &
762 FracU10, FracT2, FracQ2, &
777 real(DP),
parameter :: dIL = 1.0e-6_dp
780 real(RP),
intent(in) :: T1
781 real(RP),
intent(in) :: T0
782 real(RP),
intent(in) :: P1
783 real(RP),
intent(in) :: P0
784 real(RP),
intent(in) :: Q1
785 real(RP),
intent(in) :: Q0
786 real(RP),
intent(in) :: Uabs
787 real(RP),
intent(in) :: Z1
788 real(RP),
intent(in) :: PBL
789 real(RP),
intent(in) :: Z0M
790 real(RP),
intent(in) :: Z0H
791 real(RP),
intent(in) :: Z0E
793 real(RP),
intent(out) :: Ustar
794 real(RP),
intent(out) :: Tstar
795 real(RP),
intent(out) :: Qstar
796 real(RP),
intent(out) :: Wstar
797 real(RP),
intent(out) :: RLmo
798 real(RP),
intent(out) :: Ra
799 real(RP),
intent(out) :: FracU10
800 real(RP),
intent(out) :: FracT2
801 real(RP),
intent(out) :: FracQ2
803 real(RP),
intent(in),
optional :: RLmo_in
804 real(RP),
intent(in),
optional :: Wstar_in
815 real(DP) :: UstarC, dUstarC
816 real(DP) :: TstarC, dTstarC
817 real(DP) :: QstarC, dQstarC
818 real(DP) :: WstarC, dWstar
820 real(DP) :: Rtot, CPtot
826 real(DP) :: BFLX, dBFLX
828 real(DP) :: DP_Z1, DP_Z0M, DP_Z0H, DP_Z0E
829 real(DP) :: log_Z1ovZ0M, log_Z1ovZ0H, log_Z1ovZ0E
831 real(DP) :: RzM, RzH, RzE
835 if ( bulkflux_nk2018 )
then
836 dp_z1 = real( z1*2.0_rp, kind=dp )
838 dp_z1 = real( z1, kind=dp )
840 dp_z0m = real( z0m, kind=dp )
841 dp_z0h = real( z0h, kind=dp )
842 dp_z0e = real( z0e, kind=dp )
844 uabsc = max( uabs, bulkflux_uabs_min )
846 rtot = rdry * ( 1.0_dp - q1 ) + rvap * q1
847 cptot = cpdry * ( 1.0_dp - q1 ) + cpvap * q1
848 th1 = t1 * ( p0 / p1 )**( rtot / cptot )
850 tv1 = th1 * ( 1.0_dp + epstvap * q1 )
851 tv0 = th0 * ( 1.0_dp + epstvap * q0 )
853 rzm = 1.0_dp - dp_z0m / dp_z1
854 rzh = 1.0_dp - dp_z0h / dp_z1
855 rze = 1.0_dp - dp_z0e / dp_z1
858 log_z1ovz0m = log( dp_z1 / dp_z0m )
859 log_z1ovz0h = log( dp_z1 / dp_z0h )
860 log_z1ovz0e = log( dp_z1 / dp_z0e )
864 if (
present(wstar_in) )
then
867 wstarc = bulkflux_wstar_min
870 if (
present(rlmo_in) )
then
874 rib0 = grav * dp_z1 * ( tv1 - tv0 ) / ( tv0 * uabsc**2 )
877 il = rib0 / dp_z1 * log_z1ovz0m**2 / log_z1ovz0h
881 do n = 1, bulkflux_itr_sa_max
884 il, uabsc, th1, th0, tv0, q1, q0, pbl, &
885 log_z1ovz0m, log_z1ovz0h, log_z1ovz0e, &
886 dp_z1, dp_z0m, dp_z0h, dp_z0e, &
889 ustarc, tstarc, qstarc, bflx )
892 il = - karman * grav * bflx / ( ustarc**3 * tv0 )
898 do n = 1, bulkflux_itr_nr_max
903 il, uabsc, th1, th0, tv0, q1, q0, pbl, &
904 log_z1ovz0m, log_z1ovz0h, log_z1ovz0e, &
905 dp_z1, dp_z0m, dp_z0h, dp_z0e, &
908 ustarc, tstarc, qstarc, bflx )
910 il2 = sign( abs(il) + dil, il )
912 il2, uabsc, th1, th0, tv0, q1, q0, pbl, &
913 log_z1ovz0m, log_z1ovz0h, log_z1ovz0e, &
914 dp_z1, dp_z0m, dp_z0h, dp_z0e, &
917 dustarc, dtstarc, dqstarc, dbflx )
919 res = il + karman * grav * bflx / ( ustarc**3 * tv0 )
922 dres = 1.0_dp + karman * grav / ( tv0 * sign(dil,il) ) * ( dbflx / dustarc**3 - bflx / ustarc**3 )
925 if( abs( dres ) < 1e-20_rp )
exit
928 if( abs( res/dres ) < abs(il * eps) )
exit
931 if( il * ( il - res / dres ) < 0.0_rp )
then
932 if ( abs(il) <= eps )
exit
941 if( .NOT. abs( res/dres ) < abs(il * eps) )
then
944 il, uabsc, th1, th0, tv0, q1, q0, pbl, &
945 log_z1ovz0m, log_z1ovz0h, log_z1ovz0e, &
946 dp_z1, dp_z0m, dp_z0h, dp_z0e, &
949 ustarc, tstarc, qstarc, bflx )
952 il = - karman * grav * bflx / ( ustarc**3 * tv0 )
958 il, uabsc, th1, th0, tv0, q1, q0, pbl, &
959 log_z1ovz0m, log_z1ovz0h, log_z1ovz0e, &
960 dp_z1, dp_z0m, dp_z0h, dp_z0e, &
963 ustarc, tstarc, qstarc, bflx, &
965 fract2 = fract2, fracq2 = fracq2 )
969 ustar = real( ustarc, kind=rp )
970 tstar = real( tstarc, kind=rp )
971 qstar = real( qstarc, kind=rp )
972 wstar = real( wstarc, kind=rp )
974 ra = max( ( q1 - q0 ) / real(ustarc * qstarc + eps,kind=rp), real(eps,kind=rp) )
976 rlmo = real(il, kind=rp)
979 end subroutine bulkflux_b91w01
982 IL, Uabs, TH1, TH0, TV0, Q1, Q0, PBL, &
983 log_Z1ovZ0M, log_Z1ovZ0H, log_Z1ovZ0E, &
984 DP_Z1, DP_Z0M, DP_Z0H, DP_Z0E, &
987 Ustar, Tstar, Qstar, BFLX, &
988 FracU10, FracT2, FracQ2 )
995 real(DP),
intent(in) :: IL
996 real(DP),
intent(in) :: Uabs
997 real(DP),
intent(in) :: TH1
998 real(DP),
intent(in) :: TH0
999 real(DP),
intent(in) :: TV0
1000 real(RP),
intent(in) :: Q1
1001 real(RP),
intent(in) :: Q0
1002 real(RP),
intent(in) :: PBL
1003 real(DP),
intent(in) :: log_Z1ovZ0M
1004 real(DP),
intent(in) :: log_Z1ovZ0H
1005 real(DP),
intent(in) :: log_Z1ovZ0E
1006 real(DP),
intent(in) :: DP_Z1
1007 real(DP),
intent(in) :: DP_Z0M
1008 real(DP),
intent(in) :: DP_Z0H
1009 real(DP),
intent(in) :: DP_Z0E
1010 real(DP),
intent(in) :: RzM
1011 real(DP),
intent(in) :: RzH
1012 real(DP),
intent(in) :: RzE
1014 real(DP),
intent(inout) :: Wstar
1016 real(DP),
intent(out) :: Ustar
1017 real(DP),
intent(out) :: Tstar
1018 real(DP),
intent(out) :: Qstar
1019 real(DP),
intent(out) :: BFLX
1021 real(RP),
intent(out),
optional :: FracU10
1022 real(RP),
intent(out),
optional :: FracT2
1023 real(RP),
intent(out),
optional :: FracQ2
1025 real(DP) :: denoM, denoH, denoE
1029 if ( il < 0.0_dp )
then
1031 if ( bulkflux_nk2018 )
then
1032 denom = log_z1ovz0m &
1033 - fmm_unstable(dp_z1,il) + fmm_unstable(dp_z0m,il) * dp_z0m / dp_z1 &
1034 + rzm * ( fm_unstable(dp_z0m,il) - 1.0_dp )
1035 tmp = fhm_unstable(dp_z1,il)
1036 denoh = log_z1ovz0h &
1037 - tmp + fhm_unstable(dp_z0h,il) * dp_z0h / dp_z1 &
1038 + rzh * ( fh_unstable(dp_z0h,il) - 1.0_dp )
1039 denoe = log_z1ovz0e &
1040 - tmp + fhm_unstable(dp_z0e,il) * dp_z0e / dp_z1 &
1041 + rze * ( fh_unstable(dp_z0e,il) - 1.0_dp )
1043 denom = log_z1ovz0m - fm_unstable(dp_z1,il) + fm_unstable(dp_z0m,il)
1044 tmp = fh_unstable(dp_z1,il)
1045 denoh = log_z1ovz0h - tmp + fh_unstable(dp_z0h,il)
1046 denoe = log_z1ovz0e - tmp + fh_unstable(dp_z0e,il)
1048 ustar = karman / denom * sqrt( uabs**2 + (bulkflux_wscf*wstar)**2 )
1049 tstar = karman / denoh * ( th1 - th0 )
1050 qstar = karman / denoe * ( q1 - q0 )
1051 if (
present(fracu10) )
then
1052 fracu10 = ( log(10.0_dp/dp_z0m) - fm_unstable(10.0_dp,il) + fm_unstable(dp_z0m,il) ) / denom
1053 tmp = fm_unstable(2.0_dp,il)
1054 fract2 = ( log(2.0_dp/dp_z0h) - tmp + fh_unstable(dp_z0h,il) ) / denoh
1055 fracq2 = ( log(2.0_dp/dp_z0e) - tmp + fh_unstable(dp_z0e,il) ) / denoe
1060 if ( bulkflux_nk2018 )
then
1061 denom = log_z1ovz0m &
1062 - fmm_stable(dp_z1,il) + fmm_stable(dp_z0m,il) * dp_z0m / dp_z1 &
1063 + rzm * ( fm_stable(dp_z0m,il) - 1.0_dp )
1064 tmp = fhm_stable(dp_z1,il)
1065 denoh = log_z1ovz0h &
1066 - tmp + fhm_stable(dp_z0h,il) * dp_z0h / dp_z1 &
1067 + rzh * ( fh_stable(dp_z0h,il) - 1.0_dp )
1068 denoe = log_z1ovz0e &
1069 - tmp + fhm_stable(dp_z0e,il) * dp_z0e / dp_z1 &
1070 + rze * ( fh_stable(dp_z0e,il) - 1.0_dp )
1072 denom = log_z1ovz0m - fm_stable(dp_z1,il) + fm_stable(dp_z0m,il)
1073 tmp = fh_stable(dp_z1,il)
1074 denoh = log_z1ovz0h - tmp + fh_stable(dp_z0h,il)
1075 denoe = log_z1ovz0e - tmp + fh_stable(dp_z0e,il)
1077 ustar = karman / denom * uabs
1078 tstar = karman / denoh * ( th1 - th0 )
1079 qstar = karman / denoe * ( q1 - q0 )
1080 if (
present(fracu10) )
then
1081 fracu10 = ( log(10.0_dp/dp_z0m) - fm_stable(10.0_dp,il) + fm_stable(dp_z0m,il) ) / denom
1082 tmp = fh_stable(2.0_dp,il)
1083 fract2 = ( log(2.0_dp/dp_z0h) - tmp + fh_stable(dp_z0h,il) ) / denoh
1084 fracq2 = ( log(2.0_dp/dp_z0e) - tmp + fh_stable(dp_z0e,il) ) / denoe
1090 bflx = - ustar * tstar - epstvap * ustar * qstar * tv0
1093 tmp = pbl * grav / tv0 * bflx
1094 sw = 0.5_dp + sign( 0.5_dp, tmp )
1095 wstar = ( tmp * sw )**( 1.0_dp / 3.0_dp )
1098 ustar = sign( max( abs(ustar), eps ), ustar )
1110 integer :: ka, ks, ke
1111 real(
rp),
intent(in) :: z(ka)
1112 real(
rp),
intent(in) :: il
1113 real(
rp),
intent(out) :: phi_m(ka)
1114 real(
rp),
intent(out) :: phi_h(ka)
1116 real(
dp) :: z_dp, il_dp
1120 if ( il > 0.0_rp )
then
1123 phi_m(k) = pm_stable( z_dp, il_dp )
1124 phi_h(k) = ph_stable( z_dp, il_dp )
1129 phi_m(k) = pm_unstable( z_dp, il_dp )
1130 phi_h(k) = ph_unstable( z_dp, il_dp )
1139 real(
dp) function pm_unstable( z, il )
1144 real(
dp),
intent(in) :: z
1145 real(
dp),
intent(in) :: il
1148 real(
dp),
parameter :: gamma = 3.6_dp
1154 r = min( z * il, 0.0_dp )
1156 if ( flag_b71 )
then
1158 pm_unstable = 1.0_dp / sqrt( sqrt( 1.0_dp - 15.0_dp * r ) )
1159 else if ( flag_w01 )
then
1161 pm_unstable = 1.0_dp / sqrt( 1.0_dp + gamma * (-r)**(2.0_dp/3.0_dp) )
1164 pm_unstable = 1.0_dp / sqrt( sqrt( 1.0_dp - 16.0_dp * r ) )
1168 end function pm_unstable
1171 real(dp) function fm_unstable( z, il )
1178 real(dp),
intent(in) :: z
1179 real(dp),
intent(in) :: il
1182 real(dp),
parameter :: gamma = 3.6_dp
1189 r = min( z * il, 0.0_dp )
1191 if ( flag_b71 )
then
1193 r4r = sqrt( sqrt( 1.0_dp - 15.0_dp * r ) )
1194 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
1195 elseif ( flag_w01 )
then
1197 fm_unstable = 3.0_dp * log( ( 1.0_dp + sqrt( 1.0_dp + gamma * (-r)**(2.0_dp/3.0_dp) ) ) * 0.5_dp )
1200 r4r = sqrt( sqrt( 1.0_dp - 16.0_dp * r ) )
1201 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
1205 end function fm_unstable
1206 real(dp) function fmm_unstable( z, il )
1213 real(dp),
intent(in) :: z
1214 real(dp),
intent(in) :: il
1217 real(dp),
parameter :: gamma = 3.6_dp
1222 real(dp) :: r4r, r2r
1225 r = min( z * il, 0.0_dp )
1227 if ( flag_b71 )
then
1229 if ( r > -eps )
then
1230 fmm_unstable = - 15.0_dp * r / 8.0_dp
1232 r2r = sqrt( 1.0_dp - 15.0_dp * r )
1234 fmm_unstable = log( ( 1.0_dp + r4r )**2 * ( 1.0_dp + r2r ) * 0.125_dp ) &
1235 - 2.0_dp * atan( r4r ) &
1236 + ( 1.0_dp - r4r*r2r ) / ( 12.0_dp * r ) &
1237 + pi * 0.5_dp - 1.0_dp
1239 else if ( flag_w01 )
then
1241 r3 = (-r)**(1.0_dp/3.0_dp)
1242 if ( r > -eps )
then
1243 fmm_unstable = 9.0_dp / 20.0_dp * gamma * r3**2
1245 f = sqrt( 1.0_dp + gamma * r3**2 )
1246 fmm_unstable = 3.0_dp * log( ( 1.0_dp + f ) * 0.5_dp ) &
1247 + 1.5_dp / ( sqrt(gamma)**3 * r) * asinh( sqrt(gamma) * r3 ) &
1248 + 1.5_dp * f / ( gamma * r3**2 ) &
1253 if ( r > -eps )
then
1254 fmm_unstable = - 2.0_dp * r
1256 r2r = sqrt( 1.0_dp - 16.0_dp * r )
1258 fmm_unstable = log( ( 1.0_dp + r4r )**2 * ( 1.0_dp + r2r ) * 0.125_dp ) &
1259 - 2.0_dp * atan( r4r ) &
1260 + ( 1.0_dp - r4r*r2r ) / ( 12.0_dp * r ) &
1261 + pi * 0.5_dp - 1.0_dp
1266 end function fmm_unstable
1270 real(dp) function ph_unstable( z, il )
1275 real(dp),
intent(in) :: z
1276 real(dp),
intent(in) :: il
1279 real(dp),
parameter :: ptb = 0.74_dp
1282 real(dp),
parameter :: ptw = 0.95_dp
1283 real(dp),
parameter :: gamma = 7.9_dp
1289 r = min( z * il, 0.0_dp )
1291 if ( flag_b71 )
then
1293 ph_unstable = ptb / sqrt( 1.0_dp - 9.0_dp * r )
1294 else if ( flag_w01 )
then
1296 ph_unstable = ptw / sqrt( 1.0_dp + gamma * (-r)**(2.0_dp/3.0_dp) )
1299 ph_unstable = 1.0_dp / sqrt( 1.0_dp - 16.0_dp * r )
1303 end function ph_unstable
1306 real(dp) function fh_unstable( z, il )
1311 real(dp),
intent(in) :: z
1312 real(dp),
intent(in) :: il
1315 real(dp),
parameter :: ptb = 0.74_dp
1318 real(dp),
parameter :: ptw = 0.95_dp
1319 real(dp),
parameter :: gamma = 7.9_dp
1325 r = min( z * il, 0.0_dp )
1327 if ( flag_b71 )
then
1329 fh_unstable = 2.0_dp * log( ( 1.0_dp + sqrt( 1.0_dp - 9.0_dp * r ) ) * 0.5_dp ) * ptb &
1330 + log( z ) * ( 1.0_dp - ptb )
1331 else if ( flag_w01 )
then
1333 fh_unstable = 3.0_dp * log( ( 1.0_dp + sqrt( 1.0_dp + gamma * (-r)**(2.0_dp/3.0_dp) ) ) * 0.5_dp ) * ptw &
1334 + log( z ) * ( 1.0_dp - ptw )
1337 fh_unstable = 2.0_dp * log( ( 1.0_dp + sqrt( 1.0_dp - 16.0_dp * r ) ) * 0.5_dp )
1341 end function fh_unstable
1342 real(dp) function fhm_unstable( z, il )
1347 real(dp),
intent(in) :: z
1348 real(dp),
intent(in) :: il
1351 real(dp),
parameter :: ptb = 0.74_dp
1354 real(dp),
parameter :: ptw = 0.95_dp
1355 real(dp),
parameter :: gamma = 7.9_dp
1363 r = min( z * il, 0.0_dp )
1365 if ( flag_b71 )
then
1367 if ( r > -eps )
then
1368 fhm_unstable = - 4.0_dp * r
1370 r2r = sqrt( 1.0_dp - 9.0_dp * r )
1371 fhm_unstable = 2.0_dp * log( ( 1.0_dp + r2r ) * 0.5_dp ) &
1372 + ( 1.0_dp - r2r ) / ( 4.5_dp * r ) &
1374 fhm_unstable = fhm_unstable * ptb + ( log( z ) - 1.0_dp ) * ( 1.0_dp - ptb )
1376 else if ( flag_w01 )
then
1378 r3 = (-r)**(1.0_dp/3.0_dp)
1379 if ( r > -eps )
then
1380 fhm_unstable = 9.0_dp / 20.0_dp * gamma * r3**2
1382 f = sqrt( 1.0_dp + gamma * r3**2 )
1383 fhm_unstable = 3.0_dp * log( ( 1.0_dp + f ) * 0.5_dp ) &
1384 + 1.5_dp / ( sqrt(gamma)**3 * r) * asinh( sqrt(gamma) * r3 ) &
1385 + 1.5_dp * f / ( gamma * r3**2 ) &
1387 fhm_unstable = fhm_unstable * ptw + ( log( z ) - 1.0_dp ) * ( 1.0_dp - ptw )
1391 if ( r > -eps )
then
1392 fhm_unstable = - 4.0_dp * r
1394 r2r = sqrt( 1.0_dp - 16.0_dp * r )
1395 fhm_unstable = 2.0_dp * log( ( 1.0_dp + r2r ) * 0.5_dp ) &
1396 + ( 1.0_dp - r2r ) / ( 8.0_dp * r ) &
1402 end function fhm_unstable
1406 real(dp) function pm_stable( z, il )
1411 real(dp),
intent(in) :: z
1412 real(dp),
intent(in) :: il
1415 real(dp),
parameter :: a = 1.0_dp
1416 real(dp),
parameter :: b = 0.667_dp
1417 real(dp),
parameter :: c = 5.0_dp
1418 real(dp),
parameter :: d = 0.35_dp
1424 r = max( z * il, 0.0_dp )
1426 if ( flag_b71 )
then
1428 pm_stable = 4.7_dp * r + 1.0_dp
1431 #if defined(NVIDIA) || defined(SX)
1432 pm_stable = a*r - b*( d*r - c - 1.0_dp )*r*exp( -min( d*r, 1.e+3_rp ) ) + 1.0_dp
1434 pm_stable = a*r - b*( d*r - c - 1.0_dp )*r*exp( -d*r ) + 1.0_dp
1439 end function pm_stable
1442 real(dp) function fm_stable( z, il )
1447 real(dp),
intent(in) :: z
1448 real(dp),
intent(in) :: il
1451 real(dp),
parameter :: a = 1.0_dp
1452 real(dp),
parameter :: b = 0.667_dp
1453 real(dp),
parameter :: c = 5.0_dp
1454 real(dp),
parameter :: d = 0.35_dp
1460 r = max( z * il, 0.0_dp )
1462 if ( flag_b71 )
then
1464 fm_stable = - 4.7_dp * r
1467 #if defined(NVIDIA) || defined(SX)
1468 fm_stable = - a*r - b*( r - c/d )*exp( -min( d*r, 1.e+3_rp ) ) - b*c/d
1470 fm_stable = - a*r - b*( r - c/d )*exp( -d*r ) - b*c/d
1475 end function fm_stable
1476 real(dp) function fmm_stable( z, il )
1481 real(dp),
intent(in) :: z
1482 real(dp),
intent(in) :: il
1485 real(dp),
parameter :: a = 1.0_dp
1486 real(dp),
parameter :: b = 0.667_dp
1487 real(dp),
parameter :: c = 5.0_dp
1488 real(dp),
parameter :: d = 0.35_dp
1494 r = max( z * il, 0.0_dp )
1496 if ( flag_b71 )
then
1498 fmm_stable = - 4.7_dp * 0.5_dp * r
1502 fmm_stable = - 0.5_dp * ( a + b * c + d ) * r
1504 fmm_stable = b * ( d*r - c + 1.0_dp ) / ( d**2 * r ) &
1505 #if defined(NVIDIA) || defined(SX)
1507 * exp( -min( d*r, 1.e+3_dp ) ) &
1512 - b * ( c*d*r - c + 1.0_dp ) / ( d**2 * r )
1517 end function fmm_stable
1521 real(dp) function ph_stable( z, il )
1526 real(dp),
intent(in) :: z
1527 real(dp),
intent(in) :: il
1530 real(dp),
parameter :: ptb = 0.74_dp
1533 real(dp),
parameter :: a = 1.0_dp
1534 real(dp),
parameter :: b = 0.667_dp
1535 real(dp),
parameter :: c = 5.0_dp
1536 real(dp),
parameter :: d = 0.35_dp
1542 r = max( z * il, 0.0_dp )
1544 if ( flag_b71 )
then
1546 ph_stable = 4.7_dp * r + ptb
1549 #if defined(NVIDIA) || defined(SX)
1550 ph_stable = 1.0_dp - a*r*sqrt( 1.0_dp + 2.0_dp/3.0_dp * a*r ) - b*r*( d*r - c - 1.0_dp )*exp( -min(d*r, 1.e+3_rp) )
1552 ph_stable = 1.0_dp - a*r*sqrt( 1.0_dp + 2.0_dp/3.0_dp * a*r ) - b*r*( d*r - c - 1.0_dp )*exp( -d*r )
1557 end function ph_stable
1560 real(dp) function fh_stable( z, il )
1565 real(dp),
intent(in) :: z
1566 real(dp),
intent(in) :: il
1569 real(dp),
parameter :: ptb = 0.74_dp
1572 real(dp),
parameter :: a = 1.0_dp
1573 real(dp),
parameter :: b = 0.667_dp
1574 real(dp),
parameter :: c = 5.0_dp
1575 real(dp),
parameter :: d = 0.35_dp
1581 r = max( z * il, 0.0_dp )
1583 if ( flag_b71 )
then
1585 fh_stable = - 4.7_dp * r &
1586 + log( z ) * ( 1.0_dp - ptb )
1589 #if defined(NVIDIA) || defined(SX)
1590 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
1592 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
1597 end function fh_stable
1598 real(dp) function fhm_stable( z, il )
1603 real(dp),
intent(in) :: z
1604 real(dp),
intent(in) :: il
1607 real(dp),
parameter :: ptb = 0.74_dp
1610 real(dp),
parameter :: a = 1.0_dp
1611 real(dp),
parameter :: b = 0.667_dp
1612 real(dp),
parameter :: c = 5.0_dp
1613 real(dp),
parameter :: d = 0.35_dp
1619 r = max( z * il, 0.0_dp )
1621 if ( flag_b71 )
then
1623 fhm_stable = - 4.7_dp * 0.5_dp * r &
1624 + ( log( z ) - 1.0_dp ) * ( 1.0_dp - ptb )
1628 fhm_stable = - 0.5_dp * ( a + b*c + b ) * r
1630 fhm_stable = b * ( d*r - c + 1.0_dp ) / ( d**2 * r ) &
1631 #if defined(NVIDIA) || defined(SX)
1632 * exp( -min( d*r, 1.e+3_dp) ) &
1636 - 3.0_dp * sqrt( 1.0_dp + 2.0_dp*a*r/3.0_dp )**5 / ( 5.0_dp * a * r ) &
1637 - b * ( c*d*r - c + 1.0_dp ) / ( d**2 * r ) &
1638 + 0.6_rp / ( a * r ) + 1.0_dp
1643 end function fhm_stable