-
Notifications
You must be signed in to change notification settings - Fork 180
Expand file tree
/
Copy patheddy_diff.F90
More file actions
3310 lines (2833 loc) · 179 KB
/
Copy patheddy_diff.F90
File metadata and controls
3310 lines (2833 loc) · 179 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
module eddy_diff
!--------------------------------------------------------------------------------- !
! !
! The University of Washington Moist Turbulence Scheme to compute eddy diffusion !
! coefficients associated with dry and moist turbulences in the whole !
! atmospheric layers. !
! !
! For detailed description of the code and its performances, see !
! !
! 1.'A new moist turbulence parametrization in the Community Atmosphere Model' !
! by Christopher S. Bretherton and Sungsu Park. J. Climate. 2009. 22. 3422-3448 !
! 2.'The University of Washington shallow convection and moist turbulence schemes !
! and their impact on climate simulations with the Community Atmosphere Model' !
! by Sungsu Park and Christopher S. Bretherton. J. Climate. 2009. 22. 3449-3469 !
! !
! For questions on the scheme and code, send an email to !
! Sungsu Park at sungsup@ucar.edu (tel: 303-497-1375) !
! Chris Bretherton at breth@washington.edu !
! !
! Developed by Chris Bretherton at the University of Washington, Seattle, WA. !
! Sungsu Park at the CGD/NCAR, Boulder, CO. !
! Last coded on May.2006, Dec.2009 by Sungsu Park. !
! !
!--------------------------------------------------------------------------------- !
use wv_saturation, only: qsat
implicit none
private
save
public :: init_eddy_diff
public :: trbintd
public :: caleddy
public :: ncvmax
integer, parameter :: r8 = selected_real_kind(12) ! 8 byte real
integer, parameter :: i4 = selected_int_kind( 6) ! 4 byte integer
! --------------------------------- !
! PBL Parameters used in the UW PBL !
! --------------------------------- !
character, parameter :: sftype = 'l' ! Method for calculating saturation fraction
character(len=4), parameter :: choice_evhc = 'maxi' ! 'orig', 'ramp', 'maxi' : recommended to be used with choice_radf
character(len=6), parameter :: choice_radf = 'maxi' ! 'orig', 'ramp', 'maxi' : recommended to be used with choice_evhc
character(len=6), parameter :: choice_SRCL = 'nonamb' ! 'origin', 'remove', 'nonamb'
character(len=6), parameter :: choice_tunl = 'rampcl' ! 'origin', 'rampsl'(Sungsu), 'rampcl'(Chris)
real(r8), parameter :: ctunl = 2._r8 ! Maximum asympt leng = ctunl*tunl when choice_tunl = 'rampsl(cl)'
! [ no unit ]
character(len=6), parameter :: choice_leng = 'origin' ! 'origin', 'takemn'
real(r8), parameter :: cleng = 3._r8 ! Order of 'leng' when choice_leng = 'origin' [ no unit ]
character(len=6), parameter :: choice_tkes = 'ibprod' ! 'ibprod' (include tkes in computing bprod), 'ebprod'(exclude)
real(r8) :: lbulk_max = 40.e3_r8 ! Maximum master length scale designed to address issues in the
! upper atmosphere where vertical model resolution is coarse [ m ].
! In order not to disturb turbulence characteristics in the lower
! troposphere, this should be set at least larger than ~ a few km.
real(r8), allocatable :: leng_max(:) ! Maximum length scale designed to address issues in the upper
! atmosphere.
! Parameters for 'sedimentation-entrainment feedback' for liquid stratus
! If .false., no sedimentation entrainment feedback ( i.e., use default evhc )
logical, parameter :: id_sedfact = .false.
real(r8), parameter :: ased = 9._r8 ! Valid only when id_sedfact = .true.
! --------------------------------------------------------------------------------------------------- !
! Parameters governing entrainment efficiency A = a1l(i)*evhc, evhc = 1 + a2l * a3l * L * ql / jt2slv !
! Here, 'ql' is cloud-top LWC and 'jt2slv' is the jump in 'slv' across !
! the cloud-top entrainment zone ( across two grid layers to consider full mixture ) !
! --------------------------------------------------------------------------------------------------- !
real(r8), parameter :: a1l = 0.10_r8 ! Dry entrainment efficiency for TKE closure
! a1l = 0.2*tunl*erat^-1.5,
! where erat = <e>/wstar^2 for dry CBL = 0.3.
real(r8), parameter :: a1i = 0.2_r8 ! Dry entrainment efficiency for wstar closure
real(r8), parameter :: ccrit = 0.5_r8 ! Minimum allowable sqrt(tke)/wstar.
! Used in solving cubic equation for 'ebrk'
real(r8), parameter :: wstar3factcrit = 0.5_r8 ! 1/wstar3factcrit is the maximally allowed enhancement of
! 'wstar3' due to entrainment.
real(r8) :: a2l ! Moist entrainment enhancement param (recommended range : 10~30 )
real(r8), parameter :: a3l = 0.8_r8 ! Approximation to a complicated thermodynamic parameters
real(r8), parameter :: jbumin = .001_r8 ! Minimum buoyancy jump at an entrainment jump, [m/s2]
real(r8), parameter :: evhcmax = 10._r8 ! Upper limit of evaporative enhancement factor
real(r8), parameter :: onet = 1._r8/3._r8 ! 1/3 power in wind gradient expression [ no unit ]
integer :: ncvmax ! Max numbers of CLs (good to set to 'pver')
real(r8), parameter :: qmin = 1.e-5_r8 ! Minimum grid-mean LWC counted as clouds [kg/kg]
real(r8), parameter :: ntzero = 1.e-12_r8 ! Not zero (small positive number used in 's2')
real(r8), parameter :: b1 = 5.8_r8 ! TKE dissipation D = e^3/(b1*leng), e = b1*W.
real(r8) :: b123 ! b1**(2/3)
real(r8), parameter :: tunl = 0.085_r8 ! Asympt leng = tunl*(turb lay depth)
real(r8), parameter :: alph1 = 0.5562_r8 ! alph1~alph5 : Galperin instability function parameters
real(r8), parameter :: alph2 = -4.3640_r8 ! These coefficients are used to calculate
real(r8), parameter :: alph3 = -34.6764_r8 ! 'sh' and 'sm' from 'gh'.
real(r8), parameter :: alph4 = -6.1272_r8 !
real(r8), parameter :: alph5 = 0.6986_r8 !
real(r8), parameter :: ricrit = 0.19_r8 ! Critical Richardson number for turbulence.
! Can be any value >= 0.19.
real(r8), parameter :: ae = 1._r8 ! TKE transport efficiency [no unit]
real(r8), parameter :: rinc = -0.04_r8 ! Minimum W/<W> used for CL merging test
real(r8), parameter :: wpertmin = 1.e-6_r8 ! Minimum PBL eddy vertical velocity perturbation
real(r8), parameter :: wfac = 1._r8 ! Ratio of 'wpert' to sqrt(tke) for CL.
real(r8), parameter :: tfac = 1._r8 ! Ratio of 'tpert' to (w't')/wpert for CL.
! Same ratio also used for q
real(r8), parameter :: fak = 8.5_r8 ! Constant in surface temperature excess for stable STL.
! [ no unit ]
real(r8), parameter :: rcapmin = 0.1_r8 ! Minimum allowable e/<e> in a CL
real(r8), parameter :: rcapmax = 2.0_r8 ! Maximum allowable e/<e> in a CL
real(r8), parameter :: tkemax = 20._r8 ! TKE is capped at tkemax [m2/s2]
logical, parameter :: use_dw_surf = .true. ! Used in 'zisocl'. Default is 'true'
! If 'true', surface interfacial energy does not contribute
! to the CL mean stability functions after finishing merging.
! For this case, 'dl2n2_surf' is only used for a merging test
! based on 'l2n2'
! If 'false',surface interfacial enery explicitly contribute to
! CL mean stability functions after finishing merging.
! For this case, 'dl2n2_surf' and 'dl2s2_surf' are directly used
! for calculating surface interfacial layer energetics
logical, parameter :: set_qrlzero = .false. ! .true. ( .false.) : turning-off ( on) radiative-turbulence
! interaction by setting qrl = 0.
! ------------------------------------------------------- !
! PBL constants set using values from other parts of code !
! ------------------------------------------------------- !
real(r8) :: cpair ! Specific heat of dry air
real(r8) :: rair ! Gas const for dry air
real(r8) :: zvir ! rh2o/rair - 1
real(r8) :: latvap ! Latent heat of vaporization
real(r8) :: latice ! Latent heat of fusion
real(r8) :: latsub ! Latent heat of sublimation
real(r8) :: g ! Gravitational acceleration
real(r8) :: vk ! Von Karman's constant
integer :: ntop_turb ! Top interface level to which turbulent vertical diffusion
! is applied ( = 1 )
integer :: nbot_turb ! Bottom interface level to which turbulent vertical diff
! is applied ( = pver )
CONTAINS
!============================================================================ !
! !
!============================================================================ !
subroutine init_eddy_diff( pver, gravx, cpairx, rairx, zvirx, &
latvapx, laticex, ntop_eddy, nbot_eddy, vkx, &
eddy_lbulk_max, leng_max_in, &
eddy_moist_entrain_a2l, errstring)
!---------------------------------------------------------------- !
! Purpose: !
! Initialize time independent constants/variables of PBL package. !
!---------------------------------------------------------------- !
! --------- !
! Arguments !
! --------- !
integer, intent(in) :: pver ! Number of vertical layers
integer, intent(in) :: ntop_eddy ! Top interface level to which eddy vertical diffusivity is applied ( = 1 )
integer, intent(in) :: nbot_eddy ! Bottom interface level to which eddy vertical diffusivity is applied ( = pver )
real(r8), intent(in) :: gravx ! Acceleration of gravity
real(r8), intent(in) :: cpairx ! Specific heat of dry air
real(r8), intent(in) :: rairx ! Gas constant for dry air
real(r8), intent(in) :: zvirx ! rh2o/rair - 1
real(r8), intent(in) :: latvapx ! Latent heat of vaporization
real(r8), intent(in) :: laticex ! Latent heat of fusion
real(r8), intent(in) :: vkx ! Von Karman's constant
real(r8), intent(in) :: eddy_lbulk_max ! Maximum master length scale
real(r8), intent(in) :: leng_max_in(pver) ! Maximum length scale for upper atmosphere
real(r8), intent(in) :: eddy_moist_entrain_a2l ! Moist entrainment enhancement param
character(len=*), intent(out) :: errstring
integer :: k ! Vertical loop index
errstring = ""
! --------------- !
! Basic constants !
! --------------- !
ncvmax = pver
cpair = cpairx
rair = rairx
g = gravx
zvir = zvirx
latvap = latvapx
latice = laticex
latsub = latvap + latice
vk = vkx
ntop_turb = ntop_eddy
nbot_turb = nbot_eddy
b123 = b1**(2._r8/3._r8)
a2l = eddy_moist_entrain_a2l
lbulk_max = eddy_lbulk_max
allocate(leng_max(pver))
leng_max = leng_max_in
end subroutine init_eddy_diff
!=============================================================================== !
! !
!=============================================================================== !
subroutine sfdiag( pcols , pver , ncol , qt , ql , sl , &
pi , pm , zi , cld , sfi , sfuh , &
sflh , slslope , qtslope )
!----------------------------------------------------------------------- !
! !
! Purpose: Interface for calculating saturation fractions at upper and !
! lower-half layers, & interfaces for use by turbulence scheme !
! !
! Method : Various but 'l' should be chosen for consistency. !
! !
! Author : B. Stevens and C. Bretherton (August 2000) !
! Sungsu Park. August 2006. !
! May. 2008. !
! !
! S.Park : The computed saturation fractions are repeatedly !
! used to compute buoyancy coefficients in'trbintd' & 'caleddy'.!
!----------------------------------------------------------------------- !
implicit none
! --------------- !
! Input arguments !
! --------------- !
integer, intent(in) :: pcols ! Number of atmospheric columns
integer, intent(in) :: pver ! Number of atmospheric layers
integer, intent(in) :: ncol ! Number of atmospheric columns
real(r8), intent(in) :: sl(pcols,pver) ! Liquid water static energy [ J/kg ]
real(r8), intent(in) :: qt(pcols,pver) ! Total water specific humidity [ kg/kg ]
real(r8), intent(in) :: ql(pcols,pver) ! Liquid water specific humidity [ kg/kg ]
real(r8), intent(in) :: pi(pcols,pver+1) ! Interface pressures [ Pa ]
real(r8), intent(in) :: pm(pcols,pver) ! Layer mid-point pressures [ Pa ]
real(r8), intent(in) :: zi(pcols,pver+1) ! Interface heights [ m ]
real(r8), intent(in) :: cld(pcols,pver) ! Stratiform cloud fraction [ fraction ]
real(r8), intent(in) :: slslope(pcols,pver) ! Slope of 'sl' in each layer
real(r8), intent(in) :: qtslope(pcols,pver) ! Slope of 'qt' in each layer
! ---------------- !
! Output arguments !
! ---------------- !
real(r8), intent(out) :: sfi(pcols,pver+1) ! Interfacial layer saturation fraction [ fraction ]
real(r8), intent(out) :: sfuh(pcols,pver) ! Saturation fraction in upper half-layer [ fraction ]
real(r8), intent(out) :: sflh(pcols,pver) ! Saturation fraction in lower half-layer [ fraction ]
! --------------- !
! Local Variables !
! --------------- !
integer :: i ! Longitude index
integer :: k ! Vertical index
integer :: km1 ! k-1
integer :: status ! Status returned by function calls
real(r8) :: sltop, slbot ! sl at top/bot of grid layer
real(r8) :: qttop, qtbot ! qt at top/bot of grid layer
real(r8) :: tltop, tlbot ! Liquid water temperature at top/bot of grid layer
real(r8) :: qxtop, qxbot ! Sat excess at top/bot of grid layer
real(r8) :: qxm ! Sat excess at midpoint
real(r8) :: es ! Saturation vapor pressure
real(r8) :: qs ! Saturation spec. humidity
real(r8) :: cldeff(pcols,pver) ! Effective Cloud Fraction [ fraction ]
! ----------------------- !
! Main Computation Begins !
! ----------------------- !
sfi(1:ncol,:) = 0._r8
sfuh(1:ncol,:) = 0._r8
sflh(1:ncol,:) = 0._r8
cldeff(1:ncol,:) = 0._r8
select case (sftype)
case ('d')
! ----------------------------------------------------------------------- !
! Simply use the given stratus fraction ('horizontal' cloud partitioning) !
! ----------------------------------------------------------------------- !
do k = ntop_turb + 1, nbot_turb
km1 = k - 1
do i = 1, ncol
sfuh(i,k) = cld(i,k)
sflh(i,k) = cld(i,k)
sfi(i,k) = 0.5_r8 * ( sflh(i,km1) + min( sflh(i,km1), sfuh(i,k) ) )
end do
end do
do i = 1, ncol
sfi(i,pver+1) = sflh(i,pver)
end do
case ('l')
! ------------------------------------------ !
! Use modified stratus fraction partitioning !
! ------------------------------------------ !
do k = ntop_turb + 1, nbot_turb
km1 = k - 1
do i = 1, ncol
cldeff(i,k) = cld(i,k)
sfuh(i,k) = cld(i,k)
sflh(i,k) = cld(i,k)
if( ql(i,k) .lt. qmin ) then
sfuh(i,k) = 0._r8
sflh(i,k) = 0._r8
end if
! Modification : The contribution of ice should be carefully considered.
if( choice_evhc .eq. 'ramp' .or. choice_radf .eq. 'ramp' ) then
cldeff(i,k) = cld(i,k) * min( ql(i,k) / qmin, 1._r8 )
sfuh(i,k) = cldeff(i,k)
sflh(i,k) = cldeff(i,k)
elseif( choice_evhc .eq. 'maxi' .or. choice_radf .eq. 'maxi' ) then
cldeff(i,k) = cld(i,k)
sfuh(i,k) = cldeff(i,k)
sflh(i,k) = cldeff(i,k)
endif
! At the stratus top, take the minimum interfacial saturation fraction
sfi(i,k) = 0.5_r8 * ( sflh(i,km1) + min( sfuh(i,k), sflh(i,km1) ) )
! Modification : Currently sfi at the top and surface interfaces are set to be zero.
! Also, sfuh and sflh in the top model layer is set to be zero.
! However, I may need to set
! do i = 1, ncol
! sfi(i,pver+1) = sflh(i,pver)
! end do
! for treating surface-based fog.
! OK. I added below block similar to the other cases.
end do
end do
do i = 1, ncol
sfi(i,pver+1) = sflh(i,pver)
end do
case ('u')
! ------------------------------------------------------------------------- !
! Use unsaturated buoyancy - since sfi, sfuh, sflh have already been zeroed !
! nothing more need be done for this case. !
! ------------------------------------------------------------------------- !
case ('z')
! ------------------------------------------------------------------------- !
! Calculate saturation fraction based on whether the air just above or just !
! below the interface is saturated, i.e. with vertical cloud partitioning. !
! The saturation fraction of the interfacial layer between mid-points k and !
! k+1 is computed by averaging the saturation fraction of the half-layers !
! above and below the interface, with a special provision for cloud tops !
! (more cloud in the half-layer below than in the half-layer above).In each !
! half-layer, vertical partitioning of cloud based on the slopes diagnosed !
! above is used. Loop down through the layers, computing the saturation !
! fraction in each half-layer (sfuh for upper half, sflh for lower half). !
! Once sfuh(i,k) is computed, use with sflh(i,k-1) to determine saturation !
! fraction sfi(i,k) for interfacial layer k-0.5. !
! This is 'not' chosen for full consistent treatment of stratus fraction in !
! all physics schemes. !
! ------------------------------------------------------------------------- !
do k = ntop_turb + 1, nbot_turb
km1 = k - 1
do i = 1, ncol
! Compute saturation excess at the mid-point of layer k
sltop = sl(i,k) + slslope(i,k) * ( pi(i,k) - pm(i,k) )
qttop = qt(i,k) + qtslope(i,k) * ( pi(i,k) - pm(i,k) )
tltop = ( sltop - g * zi(i,k) ) / cpair
call qsat( tltop, pi(i,k), es, qs)
qxtop = qttop - qs
slbot = sl(i,k) + slslope(i,k) * ( pi(i,k+1) - pm(i,k) )
qtbot = qt(i,k) + qtslope(i,k) * ( pi(i,k+1) - pm(i,k) )
tlbot = ( slbot - g * zi(i,k+1) ) / cpair
call qsat( tlbot, pi(i,k+1), es, qs)
qxbot = qtbot - qs
qxm = qxtop + ( qxbot - qxtop ) * ( pm(i,k) - pi(i,k) ) / ( pi(i,k+1) - pi(i,k) )
! Find the saturation fraction sfuh(i,k) of the upper half of layer k.
if( ( qxtop .lt. 0._r8 ) .and. ( qxm .lt. 0._r8 ) ) then
sfuh(i,k) = 0._r8
else if( ( qxtop .gt. 0._r8 ) .and. ( qxm .gt. 0._r8 ) ) then
sfuh(i,k) = 1._r8
else ! Either qxm < 0 and qxtop > 0 or vice versa
sfuh(i,k) = max( qxtop, qxm ) / abs( qxtop - qxm )
end if
! Combine with sflh(i) (still for layer k-1) to get interfac layer saturation fraction
sfi(i,k) = 0.5_r8 * ( sflh(i,k-1) + min( sflh(i,k-1), sfuh(i,k) ) )
! Update sflh to be for the lower half of layer k.
if( ( qxbot .lt. 0._r8 ) .and. ( qxm .lt. 0._r8 ) ) then
sflh(i,k) = 0._r8
else if( ( qxbot .gt. 0._r8 ) .and. ( qxm .gt. 0._r8 ) ) then
sflh(i,k) = 1._r8
else ! Either qxm < 0 and qxbot > 0 or vice versa
sflh(i,k) = max( qxbot, qxm ) / abs( qxbot - qxm )
end if
end do ! i
end do ! k
do i = 1, ncol
sfi(i,pver+1) = sflh(i,pver) ! Saturation fraction in the lowest half-layer.
end do
end select
return
end subroutine sfdiag
!=============================================================================== !
! !
!=============================================================================== !
subroutine trbintd( pcols , pver , ncol , &
z , u , v , &
t , pmid , &
s2 , n2 , ri , &
zi , pi , cld , &
qt , qv , ql , qi , sfi , sfuh , &
sflh , sl , slv , slslope , qtslope , &
chs , chu , cms , cmu )
!----------------------------------------------------------------------- !
! Purpose: Calculate buoyancy coefficients at all interfaces including !
! surface. Also, computes the profiles of ( sl,qt,n2,s2,ri ). !
! Note that (n2,s2,ri) are defined at each interfaces except !
! surface. !
! !
! Author: B. Stevens ( Extracted from pbldiff, August, 2000 ) !
! Sungsu Park ( August 2006, May. 2008 ) !
!----------------------------------------------------------------------- !
implicit none
! --------------- !
! Input arguments !
! --------------- !
integer, intent(in) :: pcols ! Number of atmospheric columns
integer, intent(in) :: pver ! Number of atmospheric layers
integer, intent(in) :: ncol ! Number of atmospheric columns
real(r8), intent(in) :: z(pcols,pver) ! Layer mid-point height above surface [ m ]
real(r8), intent(in) :: u(pcols,pver) ! Layer mid-point u [ m/s ]
real(r8), intent(in) :: v(pcols,pver) ! Layer mid-point v [ m/s ]
real(r8), intent(in) :: t(pcols,pver) ! Layer mid-point temperature [ K ]
real(r8), intent(in) :: pmid(pcols,pver) ! Layer mid-point pressure [ Pa ]
real(r8), intent(in) :: zi(pcols,pver+1) ! Interface height [ m ]
real(r8), intent(in) :: pi(pcols,pver+1) ! Interface pressure [ Pa ]
real(r8), intent(in) :: cld(pcols,pver) ! Stratus fraction
real(r8), intent(in) :: qv(pcols,pver) ! Water vapor specific humidity [ kg/kg ]
real(r8), intent(in) :: ql(pcols,pver) ! Liquid water specific humidity [ kg/kg ]
real(r8), intent(in) :: qi(pcols,pver) ! Ice water specific humidity [ kg/kg ]
! ---------------- !
! Output arguments !
! ---------------- !
real(r8), intent(out) :: s2(pcols,pver) ! Interfacial ( except surface ) shear squared [ s-2 ]
real(r8), intent(out) :: n2(pcols,pver) ! Interfacial ( except surface ) buoyancy frequency [ s-2 ]
real(r8), intent(out) :: ri(pcols,pver) ! Interfacial ( except surface ) Richardson number, 'n2/s2'
real(r8), intent(out) :: qt(pcols,pver) ! Total specific humidity [ kg/kg ]
real(r8), intent(out) :: sfi(pcols,pver+1) ! Interfacial layer saturation fraction [ fraction ]
real(r8), intent(out) :: sfuh(pcols,pver) ! Saturation fraction in upper half-layer [ fraction ]
real(r8), intent(out) :: sflh(pcols,pver) ! Saturation fraction in lower half-layer [ fraction ]
real(r8), intent(out) :: sl(pcols,pver) ! Liquid water static energy [ J/kg ]
real(r8), intent(out) :: slv(pcols,pver) ! Liquid water virtual static energy [ J/kg ]
real(r8), intent(out) :: chu(pcols,pver+1) ! Heat buoyancy coef for dry states at all interfaces, finally.
! [ unit ? ]
real(r8), intent(out) :: chs(pcols,pver+1) ! heat buoyancy coef for sat states at all interfaces, finally.
! [ unit ? ]
real(r8), intent(out) :: cmu(pcols,pver+1) ! Moisture buoyancy coef for dry states at all interfaces, finally.
! [ unit ? ]
real(r8), intent(out) :: cms(pcols,pver+1) ! Moisture buoyancy coef for sat states at all interfaces, finally.
! [ unit ? ]
real(r8), intent(out) :: slslope(pcols,pver) ! Slope of 'sl' in each layer
real(r8), intent(out) :: qtslope(pcols,pver) ! Slope of 'qt' in each layer
! --------------- !
! Local Variables !
! --------------- !
integer :: i ! Longitude index
integer :: k, km1 ! Level index
integer :: status ! Status returned by function calls
real(r8) :: qs(pcols,pver) ! Saturation specific humidity
real(r8) :: es(pcols,pver) ! Saturation vapor pressure
real(r8) :: gam(pcols,pver) ! (l/cp)*(d(qs)/dT)
real(r8) :: rdz ! 1 / (delta z) between midpoints
real(r8) :: dsldz ! 'delta sl / delta z' at interface
real(r8) :: dqtdz ! 'delta qt / delta z' at interface
real(r8) :: ch ! 'sfi' weighted ch at the interface
real(r8) :: cm ! 'sfi' weighted cm at the interface
real(r8) :: bfact ! Buoyancy factor in n2 calculations
real(r8) :: product ! Intermediate vars used to find slopes
real(r8) :: dsldp_a, dqtdp_a ! Slopes across interface above
real(r8) :: dsldp_b(pcols), dqtdp_b(pcols) ! Slopes across interface below
! ----------------------- !
! Main Computation Begins !
! ----------------------- !
! Calculate conservative scalars (qt,sl,slv) and buoyancy coefficients at the layer mid-points.
! Note that 'ntop_turb = 1', 'nbot_turb = pver'
do k = ntop_turb, nbot_turb
call qsat( t(1:ncol,k), pmid(1:ncol,k), es(1:ncol,k), qs(1:ncol,k), ncol, gam=gam(1:ncol,k))
do i = 1, ncol
qt(i,k) = qv(i,k) + ql(i,k) + qi(i,k)
sl(i,k) = cpair * t(i,k) + g * z(i,k) - latvap * ql(i,k) - latsub * qi(i,k)
slv(i,k) = sl(i,k) * ( 1._r8 + zvir * qt(i,k) )
! Thermodynamic coefficients for buoyancy flux - in this loop these are
! calculated at mid-points; later, they will be averaged to interfaces,
! where they will ultimately be used. At the surface, the coefficients
! are taken from the lowest mid point.
bfact = g / ( t(i,k) * ( 1._r8 + zvir * qv(i,k) - ql(i,k) - qi(i,k) ) )
chu(i,k) = ( 1._r8 + zvir * qt(i,k) ) * bfact / cpair
chs(i,k) = ( ( 1._r8 + ( 1._r8 + zvir ) * gam(i,k) * cpair * t(i,k) / latvap ) / ( 1._r8 + gam(i,k) ) ) * bfact / cpair
cmu(i,k) = zvir * bfact * t(i,k)
cms(i,k) = latvap * chs(i,k) - bfact * t(i,k)
end do
end do
do i = 1, ncol
chu(i,pver+1) = chu(i,pver)
chs(i,pver+1) = chs(i,pver)
cmu(i,pver+1) = cmu(i,pver)
cms(i,pver+1) = cms(i,pver)
end do
! Compute slopes of conserved variables sl, qt within each layer k.
! 'a' indicates the 'above' gradient from layer k-1 to layer k and
! 'b' indicates the 'below' gradient from layer k to layer k+1.
! We take a smaller (in absolute value) of these gradients as the
! slope within layer k. If they have opposite signs, gradient in
! layer k is taken to be zero. I should re-consider whether this
! profile reconstruction is the best or not.
! This is similar to the profile reconstruction used in the UWShCu.
do i = 1, ncol
! Slopes at endpoints determined by extrapolation
slslope(i,pver) = ( sl(i,pver) - sl(i,pver-1) ) / ( pmid(i,pver) - pmid(i,pver-1) )
qtslope(i,pver) = ( qt(i,pver) - qt(i,pver-1) ) / ( pmid(i,pver) - pmid(i,pver-1) )
slslope(i,1) = ( sl(i,2) - sl(i,1) ) / ( pmid(i,2) - pmid(i,1) )
qtslope(i,1) = ( qt(i,2) - qt(i,1) ) / ( pmid(i,2) - pmid(i,1) )
dsldp_b(i) = slslope(i,1)
dqtdp_b(i) = qtslope(i,1)
end do
do k = 2, pver - 1
do i = 1, ncol
dsldp_a = dsldp_b(i)
dqtdp_a = dqtdp_b(i)
dsldp_b(i) = ( sl(i,k+1) - sl(i,k) ) / ( pmid(i,k+1) - pmid(i,k) )
dqtdp_b(i) = ( qt(i,k+1) - qt(i,k) ) / ( pmid(i,k+1) - pmid(i,k) )
product = dsldp_a * dsldp_b(i)
if( product .le. 0._r8 ) then
slslope(i,k) = 0._r8
else if( product .gt. 0._r8 .and. dsldp_a .lt. 0._r8 ) then
slslope(i,k) = max( dsldp_a, dsldp_b(i) )
else if( product .gt. 0._r8 .and. dsldp_a .gt. 0._r8 ) then
slslope(i,k) = min( dsldp_a, dsldp_b(i) )
end if
product = dqtdp_a*dqtdp_b(i)
if( product .le. 0._r8 ) then
qtslope(i,k) = 0._r8
else if( product .gt. 0._r8 .and. dqtdp_a .lt. 0._r8 ) then
qtslope(i,k) = max( dqtdp_a, dqtdp_b(i) )
else if( product .gt. 0._r8 .and. dqtdp_a .gt. 0._r8 ) then
qtslope(i,k) = min( dqtdp_a, dqtdp_b(i) )
end if
end do ! i
end do ! k
! Compute saturation fraction at the interfacial layers for use in buoyancy
! flux computation.
call sfdiag( pcols , pver , ncol , qt , ql , sl , &
pi , pmid , zi , cld , sfi , sfuh , &
sflh , slslope , qtslope )
! Calculate buoyancy coefficients at all interfaces (1:pver+1) and (n2,s2,ri)
! at all interfaces except surface. Note 'nbot_turb = pver', 'ntop_turb = 1'.
! With the previous definition of buoyancy coefficients at the surface, the
! resulting buoyancy coefficients at the top and surface interfaces becomes
! identical to the buoyancy coefficients at the top and bottom layers. Note
! that even though the dimension of (s2,n2,ri) is 'pver', they are defined
! at interfaces ( not at the layer mid-points ) except the surface.
do k = nbot_turb, ntop_turb + 1, -1
km1 = k - 1
do i = 1, ncol
rdz = 1._r8 / ( z(i,km1) - z(i,k) )
dsldz = ( sl(i,km1) - sl(i,k) ) * rdz
dqtdz = ( qt(i,km1) - qt(i,k) ) * rdz
chu(i,k) = ( chu(i,km1) + chu(i,k) ) * 0.5_r8
chs(i,k) = ( chs(i,km1) + chs(i,k) ) * 0.5_r8
cmu(i,k) = ( cmu(i,km1) + cmu(i,k) ) * 0.5_r8
cms(i,k) = ( cms(i,km1) + cms(i,k) ) * 0.5_r8
ch = chu(i,k) * ( 1._r8 - sfi(i,k) ) + chs(i,k) * sfi(i,k)
cm = cmu(i,k) * ( 1._r8 - sfi(i,k) ) + cms(i,k) * sfi(i,k)
n2(i,k) = ch * dsldz + cm * dqtdz
s2(i,k) = ( ( u(i,km1) - u(i,k) )**2 + ( v(i,km1) - v(i,k) )**2) * rdz**2
s2(i,k) = max( ntzero, s2(i,k) )
ri(i,k) = n2(i,k) / s2(i,k)
end do
end do
do i = 1, ncol
n2(i,1) = n2(i,2)
s2(i,1) = s2(i,2)
ri(i,1) = ri(i,2)
end do
return
end subroutine trbintd
! ---------------------------------------------------------------------------- !
! !
! The University of Washington Moist Turbulence Scheme !
! !
! Authors : Chris Bretherton at the University of Washington, Seattle, WA !
! Sungsu Park at the CGD/NCAR, Boulder, CO !
! !
! ---------------------------------------------------------------------------- !
subroutine caleddy( pcols , pver , ncol , &
sl , qt , ql , slv , u , &
v , pi , z , zi , &
qflx , shflx , slslope , qtslope , &
chu , chs , cmu , cms , sfuh , &
sflh , n2 , s2 , ri , rrho , &
pblh , ustar , &
kvh_in , kvm_in , kvh , kvm , &
tpert , qpert , qrlin , kvf , tke , &
wstarent , bprod , sprod , minpblh , wpert , &
tkes , went , turbtype , &
kbase_o , ktop_o , ncvfin_o , &
kbase_mg , ktop_mg , ncvfin_mg , &
kbase_f , ktop_f , ncvfin_f , &
wet_CL , web_CL , jtbu_CL , jbbu_CL , &
evhc_CL , jt2slv_CL , n2ht_CL , n2hb_CL , lwp_CL , &
opt_depth_CL , radinvfrac_CL, radf_CL , wstar_CL , wstar3fact_CL, &
ebrk , wbrk , lbrk , ricl , ghcl , &
shcl , smcl , &
gh_a , sh_a , sm_a , ri_a , leng , &
wcap , pblhp , cld , ipbl , kpblh , &
wsedl , wsed_CL , warnstring , errstring)
!--------------------------------------------------------------------------------- !
! !
! Purpose : This is a driver routine to compute eddy diffusion coefficients !
! for heat (sl), momentum (u, v), moisture (qt), and other trace !
! constituents. This scheme uses first order closure for stable !
! turbulent layers (STL). For convective layers (CL), entrainment !
! closure is used at the CL external interfaces, which is coupled !
! to the diagnosis of a CL regime mean TKE from the instantaneous !
! thermodynamic and velocity profiles. The CLs are diagnosed by !
! extending original CL layers of moist static instability into !
! adjacent weakly stably stratified interfaces, stopping if the !
! stability is too strong. This allows a realistic depiction of !
! dry convective boundary layers with a downgradient approach. !
! !
! NOTE: This routine currently assumes ntop_turb = 1, nbot_turb = pver !
! ( turbulent diffusivities computed at all interior interfaces ) !
! and will require modification to handle a different ntop_turb. !
! !
! Authors: Sungsu Park and Chris Bretherton. 08/2006, 05/2008. !
! !
! For details, see !
! !
! 1. 'A new moist turbulence parametrization in the Community Atmosphere Model' !
! by Christopher S. Bretherton & Sungsu Park. J. Climate. 22. 3422-3448. 2009. !
! !
! 2. 'The University of Washington shallow convection and moist turbulence schemes !
! and their impact on climate simulations with the Community Atmosphere Model' !
! by Sungsu Park & Christopher S. Bretherton. J. Climate. 22. 3449-3469. 2009. !
! !
! For questions on the scheme and code, send an email to !
! sungsup@ucar.edu or breth@washington.edu !
! !
!--------------------------------------------------------------------------------- !
use pbl_utils, only: &
compute_radf ! Subroutine for computing radf
! ---------------- !
! Inputs variables !
! ---------------- !
implicit none
integer, intent(in) :: pcols ! Number of atmospheric columns
integer, intent(in) :: pver ! Number of atmospheric layers
integer, intent(in) :: ncol ! Number of atmospheric columns
real(r8), intent(in) :: u(pcols,pver) ! U wind [ m/s ]
real(r8), intent(in) :: v(pcols,pver) ! V wind [ m/s ]
real(r8), intent(in) :: sl(pcols,pver) ! Liquid water static energy, cp * T + g * z - Lv * ql - Ls * qi [ J/kg ]
real(r8), intent(in) :: slv(pcols,pver) ! Liquid water virtual static energy, sl * ( 1 + 0.608 * qt ) [ J/kg ]
real(r8), intent(in) :: qt(pcols,pver) ! Total speccific humidity qv + ql + qi [ kg/kg ]
real(r8), intent(in) :: ql(pcols,pver) ! Liquid water specific humidity [ kg/kg ]
real(r8), intent(in) :: pi(pcols,pver+1) ! Interface pressures [ Pa ]
real(r8), intent(in) :: z(pcols,pver) ! Layer midpoint height above surface [ m ]
real(r8), intent(in) :: zi(pcols,pver+1) ! Interface height above surface, i.e., zi(pver+1) = 0 all over the globe
! [ m ]
real(r8), intent(in) :: chu(pcols,pver+1) ! Buoyancy coeffi. unsaturated sl (heat) coef. at all interfaces.
! [ unit ? ]
real(r8), intent(in) :: chs(pcols,pver+1) ! Buoyancy coeffi. saturated sl (heat) coef. at all interfaces.
! [ unit ? ]
real(r8), intent(in) :: cmu(pcols,pver+1) ! Buoyancy coeffi. unsaturated qt (moisture) coef. at all interfaces
! [ unit ? ]
real(r8), intent(in) :: cms(pcols,pver+1) ! Buoyancy coeffi. saturated qt (moisture) coef. at all interfaces
! [ unit ? ]
real(r8), intent(in) :: sfuh(pcols,pver) ! Saturation fraction in upper half-layer [ fraction ]
real(r8), intent(in) :: sflh(pcols,pver) ! Saturation fraction in lower half-layer [ fraction ]
real(r8), intent(in) :: n2(pcols,pver) ! Interfacial (except surface) moist buoyancy frequency [ s-2 ]
real(r8), intent(in) :: s2(pcols,pver) ! Interfacial (except surface) shear frequency [ s-2 ]
real(r8), intent(in) :: ri(pcols,pver) ! Interfacial (except surface) Richardson number
real(r8), intent(in) :: qflx(pcols) ! Kinematic surface constituent ( water vapor ) flux [ kg/m2/s ]
real(r8), intent(in) :: shflx(pcols) ! Kinematic surface heat flux [ unit ? ]
real(r8), intent(in) :: slslope(pcols,pver) ! Slope of 'sl' in each layer [ J/kg/Pa ]
real(r8), intent(in) :: qtslope(pcols,pver) ! Slope of 'qt' in each layer [ kg/kg/Pa ]
real(r8), intent(in) :: qrlin(pcols,pver) ! Input grid-mean LW heating rate : [ K/s ] * cpair * dp = [ W/kg*Pa ]
real(r8), intent(in) :: wsedl(pcols,pver) ! Sedimentation velocity of liquid stratus cloud droplet [ m/s ]
real(r8), intent(in) :: ustar(pcols) ! Surface friction velocity [ m/s ]
real(r8), intent(in) :: rrho(pcols) ! 1./bottom mid-point density. Specific volume [ m3/kg ]
real(r8), intent(in) :: kvf(pcols,pver+1) ! Free atmosphere eddy diffusivity [ m2/s ]
logical, intent(in) :: wstarent ! Switch for choosing wstar3 entrainment parameterization
real(r8), intent(in) :: minpblh(pcols) ! Minimum PBL height based on surface stress [ m ]
real(r8), intent(in) :: kvh_in(pcols,pver+1) ! kvh saved from last timestep or last iterative step [ m2/s ]
real(r8), intent(in) :: kvm_in(pcols,pver+1) ! kvm saved from last timestep or last iterative step [ m2/s ]
real(r8), intent(in) :: cld(pcols,pver) ! Stratus Cloud Fraction [ fraction ]
! ---------------- !
! Output variables !
! ---------------- !
real(r8), intent(out) :: kvh(pcols,pver+1) ! Eddy diffusivity for heat, moisture, and tracers [ m2/s ]
real(r8), intent(out) :: kvm(pcols,pver+1) ! Eddy diffusivity for momentum [ m2/s ]
real(r8), intent(out) :: pblh(pcols) ! PBL top height [ m ]
real(r8), intent(out) :: pblhp(pcols) ! PBL top height pressure [ Pa ]
real(r8), intent(out) :: tpert(pcols) ! Convective temperature excess [ K ]
real(r8), intent(out) :: qpert(pcols) ! Convective humidity excess [ kg/kg ]
real(r8), intent(out) :: wpert(pcols) ! Turbulent velocity excess [ m/s ]
real(r8), intent(out) :: tkes(pcols) ! TKE at surface [ m2/s2 ]
real(r8), intent(out) :: went(pcols) ! Entrainment rate at the PBL top interface [ m/s ]
real(r8), intent(out) :: tke(pcols,pver+1) ! Turbulent kinetic energy [ m2/s2 ], 'tkes' at surface, pver+1.
real(r8), intent(out) :: bprod(pcols,pver+1) ! Buoyancy production [ m2/s3 ], 'bflxs' at surface, pver+1.
real(r8), intent(out) :: sprod(pcols,pver+1) ! Shear production [ m2/s3 ], (ustar(i)**3)/(vk*z(i,pver))
! at surface, pver+1.
integer(i4), intent(out) :: turbtype(pcols,pver+1) ! Turbulence type at each interface:
! 0. = Non turbulence interface
! 1. = Stable turbulence interface
! 2. = CL interior interface ( if bflxs > 0, surface is this )
! 3. = Bottom external interface of CL
! 4. = Top external interface of CL.
! 5. = Double entraining CL external interface
integer(i4), intent(out) :: ipbl(pcols) ! If 1, PBL is CL, while if 0, PBL is STL.
integer(i4), intent(out) :: kpblh(pcols) ! Layer index containing PBL within or at the base interface
real(r8), intent(out) :: wsed_CL(pcols,ncvmax) ! Sedimentation velocity at the top of each CL [ m/s ]
character(len=*), intent(out) :: warnstring
character(len=*), intent(out) :: errstring
! --------------------------- !
! Diagnostic output variables !
! --------------------------- !
real(r8) :: kbase_o(pcols,ncvmax) ! Original external base interface index of CL just after 'exacol'
real(r8) :: ktop_o(pcols,ncvmax) ! Original external top interface index of CL just after 'exacol'
real(r8) :: ncvfin_o(pcols) ! Original number of CLs just after 'exacol'
real(r8) :: kbase_mg(pcols,ncvmax) ! kbase just after extending-merging (after 'zisocl') but without SRCL
real(r8) :: ktop_mg(pcols,ncvmax) ! ktop just after extending-merging (after 'zisocl') but without SRCL
real(r8) :: ncvfin_mg(pcols) ! ncvfin just after extending-merging (after 'zisocl') but without SRCL
real(r8) :: kbase_f(pcols,ncvmax) ! Final kbase after adding SRCL
real(r8) :: ktop_f(pcols,ncvmax) ! Final ktop after adding SRCL
real(r8) :: ncvfin_f(pcols) ! Final ncvfin after adding SRCL
real(r8) :: wet_CL(pcols,ncvmax) ! Entrainment rate at the CL top [ m/s ]
real(r8) :: web_CL(pcols,ncvmax) ! Entrainment rate at the CL base [ m/s ]
real(r8) :: jtbu_CL(pcols,ncvmax) ! Buoyancy jump across the CL top [ m/s2 ]
real(r8) :: jbbu_CL(pcols,ncvmax) ! Buoyancy jump across the CL base [ m/s2 ]
real(r8) :: evhc_CL(pcols,ncvmax) ! Evaporative enhancement factor at the CL top
real(r8) :: jt2slv_CL(pcols,ncvmax) ! Jump of slv ( across two layers ) at CL top for use only in evhc [ J/kg ]
real(r8) :: n2ht_CL(pcols,ncvmax) ! n2 defined at the CL top interface
! but using sfuh(kt) instead of sfi(kt) [ s-2 ]
real(r8) :: n2hb_CL(pcols,ncvmax) ! n2 defined at the CL base interface
! but using sflh(kb-1) instead of sfi(kb) [ s-2 ]
real(r8) :: lwp_CL(pcols,ncvmax) ! LWP in the CL top layer [ kg/m2 ]
real(r8) :: opt_depth_CL(pcols,ncvmax) ! Optical depth of the CL top layer
real(r8) :: radinvfrac_CL(pcols,ncvmax) ! Fraction of LW radiative cooling confined in the top portion of CL
real(r8) :: radf_CL(pcols,ncvmax) ! Buoyancy production at the CL top due to radiative cooling [ m2/s3 ]
real(r8) :: wstar_CL(pcols,ncvmax) ! Convective velocity of CL including entrainment contribution finally [ m/s ]
real(r8) :: wstar3fact_CL(pcols,ncvmax) ! "wstar3fact" of CL. Entrainment enhancement of wstar3 (inverse)
real(r8) :: gh_a(pcols,pver+1) ! Half of normalized buoyancy production, -l2n2/2e. [ no unit ]
real(r8) :: sh_a(pcols,pver+1) ! Galperin instability function of heat-moisture at all interfaces [ no unit ]
real(r8) :: sm_a(pcols,pver+1) ! Galperin instability function of momentum at all interfaces [ no unit ]
real(r8) :: ri_a(pcols,pver+1) ! Interfacial Richardson number at all interfaces [ no unit ]
real(r8) :: ebrk(pcols,ncvmax) ! Net CL mean TKE [ m2/s2 ]
real(r8) :: wbrk(pcols,ncvmax) ! Net CL mean normalized TKE [ m2/s2 ]
real(r8) :: lbrk(pcols,ncvmax) ! Net energetic integral thickness of CL [ m ]
real(r8) :: ricl(pcols,ncvmax) ! Mean Richardson number of CL ( l2n2/l2s2 )
real(r8) :: ghcl(pcols,ncvmax) ! Half of normalized buoyancy production of CL
real(r8) :: shcl(pcols,ncvmax) ! Instability function of heat and moisture of CL
real(r8) :: smcl(pcols,ncvmax) ! Instability function of momentum of CL
real(r8) :: leng(pcols,pver+1) ! Turbulent length scale [ m ], 0 at the surface.
real(r8) :: wcap(pcols,pver+1) ! Normalized TKE [m2/s2], 'tkes/b1' at the surface and 'tke/b1' at
! the top/bottom entrainment interfaces of CL assuming no transport.
! ------------------------ !
! Local Internal Variables !
! ------------------------ !
logical :: belongcv(pcols,pver+1) ! True for interfaces in a CL (both interior and exterior are included)
logical :: belongst(pcols,pver+1) ! True for stable turbulent layer interfaces (STL)
logical :: in_CL ! True if interfaces k,k+1 both in same CL.
logical :: extend ! True when CL is extended in zisocl
logical :: extend_up ! True when CL is extended upward in zisocl
logical :: extend_dn ! True when CL is extended downward in zisocl
integer :: i ! Longitude index
integer :: k ! Vertical index
integer :: ks ! Vertical index
integer :: ncvfin(pcols) ! Total number of CL in column
integer :: ncvf ! Total number of CL in column prior to adding SRCL
integer :: ncv ! Index of current CL
integer :: ncvnew ! Index of added SRCL appended after regular CLs from 'zisocl'
integer :: ncvsurf ! If nonzero, CL index based on surface
! (usually 1, but can be > 1 when SRCL is based at sfc)
integer :: kbase(pcols,ncvmax) ! Vertical index of CL base interface
integer :: ktop(pcols,ncvmax) ! Vertical index of CL top interface
integer :: kb, kt ! kbase and ktop for current CL
integer :: ktblw ! ktop of the CL located at just below the current CL
integer :: ktopbl(pcols) ! PBL top height or interface index
real(r8) :: bflxs(pcols) ! Surface buoyancy flux [ m2/s3 ]
real(r8) :: rcap ! 'tke/ebrk' at all interfaces of CL.
! Set to 1 at the CL entrainment interfaces
real(r8) :: jtzm ! Interface layer thickness of CL top interface [ m ]
real(r8) :: jtsl ! Jump of s_l across CL top interface [ J/kg ]
real(r8) :: jtqt ! Jump of q_t across CL top interface [ kg/kg ]
real(r8) :: jtbu ! Jump of buoyancy across CL top interface [ m/s2 ]
real(r8) :: jtu ! Jump of u across CL top interface [ m/s ]
real(r8) :: jtv ! Jump of v across CL top interface [ m/s ]
real(r8) :: jt2slv ! Jump of slv ( across two layers ) at CL top for use only in evhc [ J/kg ]
real(r8) :: radf ! Buoyancy production at the CL top due to radiative cooling [ m2/s3 ]
real(r8) :: jbzm ! Interface layer thickness of CL base interface [ m ]
real(r8) :: jbsl ! Jump of s_l across CL base interface [ J/kg ]
real(r8) :: jbqt ! Jump of q_t across CL top interface [ kg/kg ]
real(r8) :: jbbu ! Jump of buoyancy across CL base interface [ m/s2 ]
real(r8) :: jbu ! Jump of u across CL base interface [ m/s ]
real(r8) :: jbv ! Jump of v across CL base interface [ m/s ]
real(r8) :: ch ! Buoyancy coefficients defined at the CL top and base interfaces
! using CL internal
real(r8) :: cm ! sfuh(kt) and sflh(kb-1) instead of sfi(kt) and sfi(kb), respectively.
! These are used for entrainment calculation at CL external interfaces
! and SRCL identification.
real(r8) :: n2ht ! n2 defined at the CL top interface
! but using sfuh(kt) instead of sfi(kt) [ s-2 ]
real(r8) :: n2hb ! n2 defined at the CL base interface
! but using sflh(kb-1) instead of sfi(kb) [ s-2 ]
real(r8) :: n2htSRCL ! n2 defined at the upper-half layer of SRCL.
! This is used only for identifying SRCL.
! n2htSRCL use SRCL internal slope sl and qt
! as well as sfuh(kt) instead of sfi(kt) [ s-2 ]
real(r8) :: gh ! Half of normalized buoyancy production ( -l2n2/2e ) [ no unit ]
real(r8) :: sh ! Galperin instability function for heat and moisture
real(r8) :: sm ! Galperin instability function for momentum
real(r8) :: lbulk ! Depth of turbulent layer, Master length scale (not energetic length)
real(r8) :: dzht ! Thickness of top half-layer [ m ]
real(r8) :: dzhb ! Thickness of bottom half-layer [ m ]
real(r8) :: rootp ! Sqrt(net CL-mean TKE including entrainment contribution) [ m/s ]
real(r8) :: evhc ! Evaporative enhancement factor: (1+E)
! with E = evap. cool. efficiency [ no unit ]
real(r8) :: kentr ! Effective entrainment diffusivity 'wet*dz', 'web*dz' [ m2/s ]
real(r8) :: lwp ! Liquid water path in the layer kt [ kg/m2 ]
real(r8) :: opt_depth ! Optical depth of the layer kt [ no unit ]
real(r8) :: radinvfrac ! Fraction of LW cooling in the layer kt
! concentrated at the CL top [ no unit ]
real(r8) :: wet ! CL top entrainment rate [ m/s ]
real(r8) :: web ! CL bot entrainment rate [ m/s ]. Set to zero if CL is based at surface.
real(r8) :: vyt ! n2ht/n2 at the CL top interface
real(r8) :: vyb ! n2hb/n2 at the CL base interface
real(r8) :: vut ! Inverse Ri (=s2/n2) at the CL top interface
real(r8) :: vub ! Inverse Ri (=s2/n2) at the CL base interface
real(r8) :: fact ! Factor relating TKE generation to entrainment [ no unit ]
real(r8) :: trma ! Intermediate variables used for solving quadratic ( for gh from ri )
real(r8) :: trmb ! and cubic equations ( for ebrk: the net CL mean TKE )
real(r8) :: trmc !
real(r8) :: trmp !
real(r8) :: trmq !
real(r8) :: qq !
real(r8) :: det !
real(r8) :: gg ! Intermediate variable used for calculating stability functions of
! SRCL or SBCL based at the surface with bflxs > 0.
real(r8) :: dzhb5 ! Half thickness of the bottom-most layer of current CL regime
real(r8) :: dzht5 ! Half thickness of the top-most layer of adjacent CL regime
! just below current CL
real(r8) :: qrlw(pcols,pver) ! Local grid-mean LW heating rate : [K/s] * cpair * dp = [ W/kg*Pa ]
real(r8) :: cldeff(pcols,pver) ! Effective stratus fraction
real(r8) :: qleff ! Used for computing evhc
real(r8) :: tunlramp ! Ramping tunl
real(r8) :: leng_imsi ! For Kv = max(Kv_STL, Kv_entrain)
real(r8) :: tke_imsi !
real(r8) :: kvh_imsi !
real(r8) :: kvm_imsi !
real(r8) :: alph4exs ! For extended stability function in the stable regime
real(r8) :: ghmin !
real(r8) :: sedfact ! For 'sedimentation-entrainment feedback'
! Local variables specific for 'wstar' entrainment closure
real(r8) :: cet ! Proportionality coefficient between wet and wstar3
real(r8) :: ceb ! Proportionality coefficient between web and wstar3
real(r8) :: wstar ! Convective velocity for CL [ m/s ]
real(r8) :: wstar3 ! Cubed convective velocity for CL [ m3/s3 ]
real(r8) :: wstar3fact ! 1/(relative change of wstar^3 by entrainment)
real(r8) :: rmin ! sqrt(p)
real(r8) :: fmin ! f(rmin), where f(r) = r^3 - 3*p*r - 2q
real(r8) :: rcrit ! ccrit*wstar
real(r8) :: fcrit ! f(rcrit)
logical noroot ! True if f(r) has no root r > rcrit
character(128) :: temp_string
!-----------------------!
! Start of Main Program !
!-----------------------!
warnstring = ""
errstring = ""
! Option: Turn-off LW radiative-turbulence interaction in PBL scheme
! by setting qrlw = 0. Logical parameter 'set_qrlzero' was
! defined in the first part of 'eddy_diff.F90' module.
if( set_qrlzero ) then
qrlw(:,:) = 0._r8
else
qrlw(:ncol,:pver) = qrlin(:ncol,:pver)
endif
! Define effective stratus fraction using the grid-mean ql.
! Modification : The contribution of ice should be carefully considered.
! This should be done in combination with the 'qrlw' and
! overlapping assumption of liquid and ice stratus.
do k = 1, pver
do i = 1, ncol
if( choice_evhc .eq. 'ramp' .or. choice_radf .eq. 'ramp' ) then
cldeff(i,k) = cld(i,k) * min( ql(i,k) / qmin, 1._r8 )
else
cldeff(i,k) = cld(i,k)
endif
end do
end do
! For an extended stability function in the stable regime, re-define
! alph4exe and ghmin. This is for future work.
if( ricrit .eq. 0.19_r8 ) then
alph4exs = alph4
ghmin = -3.5334_r8
elseif( ricrit .gt. 0.19_r8 ) then
alph4exs = -2._r8 * b1 * alph2 / ( alph3 - 2._r8 * b1 * alph5 ) / ricrit
ghmin = -1.e10_r8
else
errstring = 'ricrit should be larger than 0.19 in UW PBL'
return
endif
!
! Initialization of Diagnostic Output
!
do i = 1, ncol
went(i) = 0._r8
wet_CL(i,:ncvmax) = 0._r8
web_CL(i,:ncvmax) = 0._r8
jtbu_CL(i,:ncvmax) = 0._r8
jbbu_CL(i,:ncvmax) = 0._r8
evhc_CL(i,:ncvmax) = 0._r8
jt2slv_CL(i,:ncvmax) = 0._r8
n2ht_CL(i,:ncvmax) = 0._r8
n2hb_CL(i,:ncvmax) = 0._r8
lwp_CL(i,:ncvmax) = 0._r8
opt_depth_CL(i,:ncvmax) = 0._r8
radinvfrac_CL(i,:ncvmax) = 0._r8
radf_CL(i,:ncvmax) = 0._r8
wstar_CL(i,:ncvmax) = 0._r8
wstar3fact_CL(i,:ncvmax) = 0._r8
ricl(i,:ncvmax) = 0._r8
ghcl(i,:ncvmax) = 0._r8
shcl(i,:ncvmax) = 0._r8
smcl(i,:ncvmax) = 0._r8
ebrk(i,:ncvmax) = 0._r8
wbrk(i,:ncvmax) = 0._r8
lbrk(i,:ncvmax) = 0._r8
gh_a(i,:pver+1) = 0._r8
sh_a(i,:pver+1) = 0._r8