source: lmdz_wrf/WRFV3/phys/module_cam_bl_eddy_diff.F @ 1

Last change on this file since 1 was 1, checked in by lfita, 10 years ago
  • -- --- Opening of the WRF+LMDZ coupling repository --- -- -

WRF: version v3.3
LMDZ: version v1818

More details in:

File size: 224.4 KB
Line 
1#define WRF_PORT
2
3module eddy_diff
4
5  !--------------------------------------------------------------------------------- !
6  !                                                                                  !
7  ! The University of Washington Moist Turbulence Scheme to compute eddy diffusion   !
8  ! coefficients associated with dry and moist turbulences in the whole              !
9  ! atmospheric layers.                                                              !
10  !                                                                                  !
11  ! For detailed description of the code and its performances, see                   !
12  !                                                                                  !
13  ! 1.'A new moist turbulence parametrization in the Community Atmosphere Model'     !
14  !    by Christopher S. Bretherton and Sungsu Park. J. Climate. 2009. 22. 3422-3448 !
15  ! 2.'The University of Washington shallow convection and moist turbulence schemes  !
16  !    and their impact on climate simulations with the Community Atmosphere Model'  !
17  !    by Sungsu Park and Christopher S. Bretherton. J. Climate. 2009. 22. 3449-3469 !
18  !                                                                                  !
19  ! For questions on the scheme and code, send an email to                           !
20  !     Sungsu Park      at sungsup@ucar.edu (tel: 303-497-1375)                     !
21  !     Chris Bretherton at breth@washington.edu                                     !
22  !                                                                                  !
23  ! Developed by Chris Bretherton at the University of Washington, Seattle, WA.      !
24  !              Sungsu Park      at the CGD/NCAR, Boulder, CO.                      !
25  ! Last coded on May.2006, Dec.2009 by Sungsu Park.                                 !
26  !                                                                                  ! 
27  !--------------------------------------------------------------------------------- !
28
29  use diffusion_solver, only : vdiff_selector
30#ifndef WRF_PORT
31  use cam_history,      only : outfld, addfld, phys_decomp
32  use cam_logfile,      only : iulog
33  use ppgrid,           only : pver
34#else
35  use module_cam_support,   only: iulog, pver,outfld, addfld, phys_decomp 
36#endif
37
38  implicit none
39  private
40  save
41
42  public init_eddy_diff
43  public compute_eddy_diff
44
45  type(vdiff_selector)        :: fieldlist_wet                  ! Logical switches for moist mixing ratio diffusion
46  type(vdiff_selector)        :: fieldlist_dry                  ! Logical switches for dry   mixing ratio diffusion
47  integer,          parameter :: r8 = selected_real_kind(12)    ! 8 byte real
48
49  ! --------------------------------- !
50  ! PBL Parameters used in the UW PBL !
51  ! --------------------------------- !
52
53  character,        parameter :: sftype         = 'l'           ! Method for calculating saturation fraction
54
55  character(len=4), parameter :: choice_evhc    = 'maxi'        ! 'orig',   'ramp',   'maxi'   : recommended to be used with choice_radf
56  character(len=6), parameter :: choice_radf    = 'maxi'        ! 'orig',   'ramp',   'maxi'   : recommended to be used with choice_evhc
57  character(len=6), parameter :: choice_SRCL    = 'nonamb'      ! 'origin', 'remove', 'nonamb'
58 
59  character(len=6), parameter :: choice_tunl    = 'rampcl'      ! 'origin', 'rampsl'(Sungsu), 'rampcl'(Chris)
60  real(r8),         parameter :: ctunl          =  2._r8        !  Maximum asympt leng = ctunl*tunl when choice_tunl = 'rampsl(cl)' [ no unit ]
61  character(len=6), parameter :: choice_leng    = 'origin'      ! 'origin', 'takemn'
62  real(r8),         parameter :: cleng          =  3._r8        !  Order of 'leng' when choice_leng = 'origin' [ no unit ]
63  character(len=6), parameter :: choice_tkes    = 'ibprod'      ! 'ibprod' (include tkes in computing bprod), 'ebprod'(exclude)
64
65  ! Parameters for 'sedimenttaion-entrainment feedback' for liquid stratus
66  ! If .false.,  no sedimentation entrainment feedback ( i.e., use default evhc )
67
68  logical,          parameter :: id_sedfact     = .false.
69  real(r8),         parameter :: ased           =  9._r8        !  Valid only when id_sedfact = .true.
70
71  ! --------------------------------------------------------------------------------------------------- !
72  ! Parameters governing entrainment efficiency A = a1l(i)*evhc, evhc = 1 + a2l * a3l * L * ql / jt2slv !
73  ! Here, 'ql' is cloud-top LWC and 'jt2slv' is the jump in 'slv' across                                !
74  ! the cloud-top entrainment zone ( across two grid layers to consider full mixture )                  !
75  ! --------------------------------------------------------------------------------------------------- !
76
77  real(r8),         parameter :: a1l            =   0.10_r8     ! Dry entrainment efficiency for TKE closure
78                                                                ! a1l = 0.2*tunl*erat^-1.5, where erat = <e>/wstar^2 for dry CBL =  0.3.
79
80  real(r8),         parameter :: a1i            =   0.2_r8      ! Dry entrainment efficiency for wstar closure
81  real(r8),         parameter :: ccrit          =   0.5_r8      ! Minimum allowable sqrt(tke)/wstar. Used in solving cubic equation for 'ebrk'
82  real(r8),         parameter :: wstar3factcrit =   0.5_r8      ! 1/wstar3factcrit is the maximally allowed enhancement of 'wstar3' due to entrainment.
83
84  real(r8),         parameter :: a2l            =   30._r8      ! Moist entrainment enhancement param (recommended range : 10~30 )
85  real(r8),         parameter :: a3l            =   0.8_r8      ! Approximation to a complicated thermodynamic parameters
86
87  real(r8),         parameter :: jbumin         =   .001_r8     ! Minimum buoyancy jump at an entrainment jump, [m/s2]
88  real(r8),         parameter :: evhcmax        =   10._r8      ! Upper limit of evaporative enhancement factor
89
90  real(r8),         parameter :: ustar_min      =   0.01_r8     ! Minimum permitted value of ustar [ m/s ]
91  real(r8),         parameter :: onet           =   1._r8/3._r8 ! 1/3 power in wind gradient expression [ no unit ]
92#ifndef WRF_PORT
93  !pver is not a parameter in cam_support module in WRF, therefore ncvmax cannot be equated to pver as parameter
94  integer,          parameter :: ncvmax         =   pver        ! Max numbers of CLs (good to set to 'pver')
95#endif
96  integer                     :: ncvmax                         ! Max numbers of CLs (good to set to 'pver') !Pver is not a parameter in cam_support module
97  real(r8),         parameter :: qmin           =   1.e-5_r8    ! Minimum grid-mean LWC counted as clouds [kg/kg]
98  real(r8),         parameter :: ntzero         =   1.e-12_r8   ! Not zero (small positive number used in 's2')
99  real(r8),         parameter :: b1             =   5.8_r8      ! TKE dissipation D = e^3/(b1*leng), e = b1*W.
100  real(r8)                    :: b123                           ! b1**(2/3)
101  real(r8),         parameter :: tunl           =   0.085_r8    ! Asympt leng = tunl*(turb lay depth)
102  real(r8),         parameter :: alph1          =   0.5562_r8   ! alph1~alph5 : Galperin instability function parameters
103  real(r8),         parameter :: alph2          =  -4.3640_r8   !               These coefficients are used to calculate
104  real(r8),         parameter :: alph3          = -34.6764_r8   !               'sh' and 'sm' from 'gh'.
105  real(r8),         parameter :: alph4          =  -6.1272_r8   !
106  real(r8),         parameter :: alph5          =   0.6986_r8   !
107  real(r8),         parameter :: ricrit         =   0.19_r8     ! Critical Richardson number for turbulence. Can be any value >= 0.19.
108  real(r8),         parameter :: ae             =   1._r8       ! TKE transport efficiency [no unit]
109  real(r8),         parameter :: rinc           =  -0.04_r8     ! Minimum W/<W> used for CL merging test
110  real(r8),         parameter :: wpertmin       =   1.e-6_r8    ! Minimum PBL eddy vertical velocity perturbation
111  real(r8),         parameter :: wfac           =   1._r8       ! Ratio of 'wpert' to sqrt(tke) for CL.
112  real(r8),         parameter :: tfac           =   1._r8       ! Ratio of 'tpert' to (w't')/wpert for CL. Same ratio also used for q
113  real(r8),         parameter :: fak            =   8.5_r8      ! Constant in surface temperature excess for stable STL. [ no unit ]         
114  real(r8),         parameter :: rcapmin        =   0.1_r8      ! Minimum allowable e/<e> in a CL
115  real(r8),         parameter :: rcapmax        =   2.0_r8      ! Maximum allowable e/<e> in a CL
116  real(r8),         parameter :: tkemax         =  20._r8       ! TKE is capped at tkemax [m2/s2]
117  real(r8),         parameter :: lambda         =   0.5_r8      ! Under-relaxation factor ( 0 < lambda =< 1 )
118
119  logical,          parameter :: use_kvf        =  .false.      ! .true. (.false.) : initialize kvh/kvm =  kvf ( 0. )
120  logical,          parameter :: use_dw_surf    =  .true.       ! Used in 'zisocl'. Default is 'true'
121                                                                ! If 'true', surface interfacial energy does not contribute to the CL mean
122                                                                !            stbility functions after finishing merging.     For this case,
123                                                                !           'dl2n2_surf' is only used for a merging test based on 'l2n2'
124                                                                ! If 'false',surface interfacial enery explicitly contribute to    CL mean
125                                                                !            stability functions after finishing merging.    For this case,
126                                                                !           'dl2n2_surf' and 'dl2s2_surf' are directly used for calculating
127                                                                !            surface interfacial layer energetics
128
129  logical,          parameter :: set_qrlzero    =  .false.      ! .true. ( .false.) : turning-off ( on) radiative-turbulence interaction by setting qrl = 0.
130
131  ! ------------------------------------- !
132  ! PBL Parameters not used in the UW PBL !
133  ! ------------------------------------- !
134
135  real(r8),         parameter :: pblmaxp        =  4.e4_r8      ! PBL max depth in pressure units.
136  real(r8),         parameter :: zkmin          =  0.01_r8      ! Minimum kneutral*f(ri).
137  real(r8),         parameter :: betam          = 15.0_r8       ! Constant in wind gradient expression.
138  real(r8),         parameter :: betas          =  5.0_r8       ! Constant in surface layer gradient expression.
139  real(r8),         parameter :: betah          = 15.0_r8       ! Constant in temperature gradient expression.
140  real(r8),         parameter :: fakn           =  7.2_r8       ! Constant in turbulent prandtl number.
141  real(r8),         parameter :: ricr           =  0.3_r8       ! Critical richardson number.
142  real(r8),         parameter :: sffrac         =  0.1_r8       ! Surface layer fraction of boundary layer
143  real(r8),         parameter :: binm           =  betam*sffrac ! betam * sffrac
144  real(r8),         parameter :: binh           =  betah*sffrac ! betah * sffrac
145
146  ! ------------------------------------------------------- !
147  ! PBL constants set using values from other parts of code !
148  ! ------------------------------------------------------- !
149
150  real(r8)                    :: cpair                          ! Specific heat of dry air
151  real(r8)                    :: rair                           ! Gas const for dry air
152  real(r8)                    :: zvir                           ! rh2o/rair - 1
153  real(r8)                    :: latvap                         ! Latent heat of vaporization
154  real(r8)                    :: latice                         ! Latent heat of fusion
155  real(r8)                    :: latsub                         ! Latent heat of sublimation
156  real(r8)                    :: g                              ! Gravitational acceleration
157  real(r8)                    :: vk                             ! Von Karman's constant
158  real(r8)                    :: ccon                           ! fak * sffrac * vk
159
160  integer                     :: ntop_turb                      ! Top interface level to which turbulent vertical diffusion is applied ( = 1 )
161  integer                     :: nbot_turb                      ! Bottom interface level to which turbulent vertical diff is applied ( = pver )
162
163  real(r8), allocatable       :: ml2(:)                         ! Mixing lengths squared. Not used in the UW PBL. Used for computing free air diffusivity.
164
165  CONTAINS
166
167  !============================================================================ !
168  !                                                                             !
169  !============================================================================ !
170 
171  subroutine init_eddy_diff( kind, pver, gravx, cpairx, rairx, zvirx, &
172                             latvapx, laticex, ntop_eddy, nbot_eddy, hypm, vkx )
173    !---------------------------------------------------------------- !
174    ! Purpose:                                                        !
175    ! Initialize time independent constants/variables of PBL package. !
176    !---------------------------------------------------------------- !
177    use diffusion_solver, only: init_vdiff, vdiff_select
178#ifndef WRF_PORT
179    use cam_history,      only: outfld, addfld, phys_decomp
180#else
181    use module_cam_support,   only: outfld, addfld, phys_decomp 
182#endif
183    implicit none
184    ! --------- !
185    ! Arguments !
186    ! --------- !
187    integer,  intent(in) :: kind       ! Kind of reals being passed in
188    integer,  intent(in) :: pver       ! Number of vertical layers
189    integer,  intent(in) :: ntop_eddy  ! Top interface level to which eddy vertical diffusivity is applied ( = 1 )
190    integer,  intent(in) :: nbot_eddy  ! Bottom interface level to which eddy vertical diffusivity is applied ( = pver )
191    real(r8), intent(in) :: gravx      ! Acceleration of gravity
192    real(r8), intent(in) :: cpairx     ! Specific heat of dry air
193    real(r8), intent(in) :: rairx      ! Gas constant for dry air
194    real(r8), intent(in) :: zvirx      ! rh2o/rair - 1
195    real(r8), intent(in) :: latvapx    ! Latent heat of vaporization
196    real(r8), intent(in) :: laticex    ! Latent heat of fusion
197    real(r8), intent(in) :: hypm(pver) ! Reference pressures at midpoints
198    real(r8), intent(in) :: vkx        ! Von Karman's constant
199
200    character(128)       :: errstring  ! Error status for init_vdiff
201    integer              :: k          ! Vertical loop index
202
203    !As pver is not parameter in the cam_support module in WRF, a value to ncvmax is given here
204    ncvmax = pver        ! Max numbers of CLs (good to set to 'pver')
205
206    if( kind .ne. r8 ) then
207        write(iulog,*) 'wrong KIND of reals passed to init_diffusvity -- exiting.'
208        stop 'init_eddy_diff'
209    endif
210
211    ! --------------- !
212    ! Basic constants !
213    ! --------------- !
214
215    cpair     = cpairx
216    rair      = rairx
217    g         = gravx
218    zvir      = zvirx
219    latvap    = latvapx
220    latice    = laticex
221    latsub    = latvap + latice
222    vk        = vkx
223    ccon      = fak*sffrac*vk
224    ntop_turb = ntop_eddy
225    nbot_turb = nbot_eddy
226    b123      = b1**(2._r8/3._r8)
227
228    ! Set the square of the mixing lengths. Only for CAM3 HB PBL scheme.
229    ! Not used for UW moist PBL. Used for free air eddy diffusivity.
230
231#if 0
232    allocate(ml2(pver+1))
233    ml2(1:ntop_turb) = 0._r8
234    do k = ntop_turb + 1, nbot_turb
235       ml2(k) = 30.0_r8**2
236    end do
237    ml2(nbot_turb+1:pver+1) = 0._r8
238#endif
239   
240    ! Initialize diffusion solver module
241
242    call init_vdiff(r8, 1, rair, g, fieldlist_wet, fieldlist_dry, errstring)
243
244    ! Select the fields which will be diffused
245
246    if(vdiff_select(fieldlist_wet,'s').ne.'')   write(iulog,*) 'error: ', vdiff_select(fieldlist_wet,'s')
247    if(vdiff_select(fieldlist_wet,'q',1).ne.'') write(iulog,*) 'error: ', vdiff_select(fieldlist_wet,'q',1)
248    if(vdiff_select(fieldlist_wet,'u').ne.'')   write(iulog,*) 'error: ', vdiff_select(fieldlist_wet,'u')
249    if(vdiff_select(fieldlist_wet,'v').ne.'')   write(iulog,*) 'error: ', vdiff_select(fieldlist_wet,'v')
250
251    ! ------------------------------------------------------------------- !
252    ! Writing outputs for detailed analysis of UW moist turbulence scheme !
253    ! ------------------------------------------------------------------- !
254
255    call addfld('UW_errorPBL',      'm2/s',    1,      'A',  'Error function of UW PBL',                              phys_decomp )
256    call addfld('UW_n2',            's-2',     pver,   'A',  'Buoyancy Frequency, LI',                                phys_decomp )
257    call addfld('UW_s2',            's-2',     pver,   'A',  'Shear Frequency, LI',                                   phys_decomp )
258    call addfld('UW_ri',            'no',      pver,   'A',  'Interface Richardson Number, I',                        phys_decomp )
259    call addfld('UW_sfuh',          'no',      pver,   'A',  'Upper-Half Saturation Fraction, L',                     phys_decomp )
260    call addfld('UW_sflh',          'no',      pver,   'A',  'Lower-Half Saturation Fraction, L',                     phys_decomp )
261    call addfld('UW_sfi',           'no',      pver+1, 'A',  'Interface Saturation Fraction, I',                      phys_decomp )
262    call addfld('UW_cldn',          'no',      pver,   'A',  'Cloud Fraction, L',                                     phys_decomp )
263    call addfld('UW_qrl',           'g*W/m2',  pver,   'A',  'LW cooling rate, L',                                    phys_decomp )
264    call addfld('UW_ql',            'kg/kg',   pver,   'A',  'ql(LWC), L',                                            phys_decomp )
265    call addfld('UW_chu',           'g*kg/J',  pver+1, 'A',  'Buoyancy Coefficient, chu, I',                          phys_decomp )
266    call addfld('UW_chs',           'g*kg/J',  pver+1, 'A',  'Buoyancy Coefficient, chs, I',                          phys_decomp )
267    call addfld('UW_cmu',           'g/kg/kg', pver+1, 'A',  'Buoyancy Coefficient, cmu, I',                          phys_decomp )
268    call addfld('UW_cms',           'g/kg/kg', pver+1, 'A',  'Buoyancy Coefficient, cms, I',                          phys_decomp )   
269    call addfld('UW_tke',           'm2/s2',   pver+1, 'A',  'TKE, I',                                                phys_decomp )
270    call addfld('UW_wcap',          'm2/s2',   pver+1, 'A',  'Wcap, I',                                               phys_decomp )       
271    call addfld('UW_bprod',         'm2/s3',   pver+1, 'A',  'Buoyancy production, I',                                phys_decomp )
272    call addfld('UW_sprod',         'm2/s3',   pver+1, 'A',  'Shear production, I',                                   phys_decomp )   
273    call addfld('UW_kvh',           'm2/s',    pver+1, 'A',  'Eddy diffusivity of heat, I',                           phys_decomp )
274    call addfld('UW_kvm',           'm2/s',    pver+1, 'A',  'Eddy diffusivity of uv, I',                             phys_decomp )
275    call addfld('UW_pblh',          'm',       1,      'A',  'PBLH, 1',                                               phys_decomp )
276    call addfld('UW_pblhp',         'Pa',      1,      'A',  'PBLH pressure, 1',                                      phys_decomp )
277    call addfld('UW_tpert',         'K',       1,      'A',  'Convective T excess, 1',                                phys_decomp )
278    call addfld('UW_qpert',         'kg/kg',   1,      'A',  'Convective qt excess, I',                               phys_decomp )
279    call addfld('UW_wpert',         'm/s',     1,      'A',  'Convective W excess, I',                                phys_decomp )
280    call addfld('UW_ustar',         'm/s',     1,      'A',  'Surface Frictional Velocity, 1',                        phys_decomp )
281    call addfld('UW_tkes',          'm2/s2',   1,      'A',  'Surface TKE, 1',                                        phys_decomp )
282    call addfld('UW_minpblh',       'm',       1,      'A',  'Minimum PBLH, 1',                                       phys_decomp )
283    call addfld('UW_turbtype',      'no',      pver+1, 'A',  'Interface Turbulence Type, I',                          phys_decomp )   
284    call addfld('UW_kbase_o',       'no',      ncvmax, 'A',  'Initial CL Base Exterbal Interface Index, CL',          phys_decomp )
285    call addfld('UW_ktop_o',        'no',      ncvmax, 'A',  'Initial Top Exterbal Interface Index, CL',              phys_decomp )
286    call addfld('UW_ncvfin_o',      '#',       1,      'A',  'Initial Total Number of CL regimes, CL',                phys_decomp )
287    call addfld('UW_kbase_mg',      'no',      ncvmax, 'A',  'kbase after merging, CL',                               phys_decomp )
288    call addfld('UW_ktop_mg',       'no',      ncvmax, 'A',  'ktop after merging, CL',                                phys_decomp )
289    call addfld('UW_ncvfin_mg',     '#',       1,      'A',  'ncvfin after merging, CL',                              phys_decomp )
290    call addfld('UW_kbase_f',       'no',      ncvmax, 'A',  'Final kbase with SRCL, CL',                             phys_decomp )
291    call addfld('UW_ktop_f',        'no',      ncvmax, 'A',  'Final ktop with SRCL, CL',                              phys_decomp )
292    call addfld('UW_ncvfin_f',      '#',       1,      'A',  'Final ncvfin with SRCL, CL',                            phys_decomp )
293    call addfld('UW_wet',           'm/s',     ncvmax, 'A',  'Entrainment rate at CL top, CL',                        phys_decomp )
294    call addfld('UW_web',           'm/s',     ncvmax, 'A',  'Entrainment rate at CL base, CL',                       phys_decomp )
295    call addfld('UW_jtbu',          'm/s2',    ncvmax, 'A',  'Buoyancy jump across CL top, CL',                       phys_decomp )
296    call addfld('UW_jbbu',          'm/s2',    ncvmax, 'A',  'Buoyancy jump across CL base, CL',                      phys_decomp )
297    call addfld('UW_evhc',          'no',      ncvmax, 'A',  'Evaporative enhancement factor, CL',                    phys_decomp )
298    call addfld('UW_jt2slv',        'J/kg',    ncvmax, 'A',  'slv jump for evhc, CL',                                 phys_decomp )
299    call addfld('UW_n2ht',          's-2',     ncvmax, 'A',  'n2 at just below CL top interface, CL',                 phys_decomp )
300    call addfld('UW_n2hb',          's-2',     ncvmax, 'A',  'n2 at just above CL base interface',                    phys_decomp )
301    call addfld('UW_lwp',           'kg/m2',   ncvmax, 'A',  'LWP in the CL top layer, CL',                           phys_decomp )
302    call addfld('UW_optdepth',      'no',      ncvmax, 'A',  'Optical depth of the CL top layer, CL',                 phys_decomp )
303    call addfld('UW_radfrac',       'no',      ncvmax, 'A',  'Fraction of radiative cooling confined in the CL top',  phys_decomp )
304    call addfld('UW_radf',          'm2/s3',   ncvmax, 'A',  'Buoyancy production at the CL top by radf, I',          phys_decomp )       
305    call addfld('UW_wstar',         'm/s',     ncvmax, 'A',  'Convective velocity, Wstar, CL',                        phys_decomp )
306    call addfld('UW_wstar3fact',    'no',      ncvmax, 'A',  'Enhancement of wstar3 due to entrainment, CL',          phys_decomp )
307    call addfld('UW_ebrk',          'm2/s2',   ncvmax, 'A',  'CL-averaged TKE, CL',                                   phys_decomp )
308    call addfld('UW_wbrk',          'm2/s2',   ncvmax, 'A',  'CL-averaged W, CL',                                     phys_decomp )
309    call addfld('UW_lbrk',          'm',       ncvmax, 'A',  'CL internal thickness, CL',                             phys_decomp )
310    call addfld('UW_ricl',          'no',      ncvmax, 'A',  'CL-averaged Ri, CL',                                    phys_decomp )
311    call addfld('UW_ghcl',          'no',      ncvmax, 'A',  'CL-averaged gh, CL',                                    phys_decomp )
312    call addfld('UW_shcl',          'no',      ncvmax, 'A',  'CL-averaged sh, CL',                                    phys_decomp )
313    call addfld('UW_smcl',          'no',      ncvmax, 'A',  'CL-averaged sm, CL',                                    phys_decomp )
314    call addfld('UW_gh',            'no',      pver+1, 'A',  'gh at all interfaces, I',                               phys_decomp )
315    call addfld('UW_sh',            'no',      pver+1, 'A',  'sh at all interfaces, I',                               phys_decomp )
316    call addfld('UW_sm',            'no',      pver+1, 'A',  'sm at all interfaces, I',                               phys_decomp )
317    call addfld('UW_ria',           'no',      pver+1, 'A',  'ri at all interfaces, I',                               phys_decomp )
318    call addfld('UW_leng',          'm/s',     pver+1, 'A',  'Turbulence length scale, I',                            phys_decomp )
319
320  return
321
322  end subroutine init_eddy_diff
323
324  !=============================================================================== !
325  !                                                                                !
326  !=============================================================================== !
327 
328  subroutine compute_eddy_diff( lchnk  ,                                                            &
329                                pcols  , pver   , ncol     , t       , qv       , ztodt   ,         &
330                                ql     , qi     , s        , rpdel   , cldn     , qrl     , wsedl , &
331                                z      , zi     , pmid     , pi      , u        , v       ,         &
332                                taux   , tauy   , shflx    , qflx    , wstarent , nturb   ,         &
333                                ustar  , pblh   , kvm_in   , kvh_in  , kvm_out  , kvh_out , kvq   , &
334                                cgh    , cgs    , tpert    , qpert   , wpert    , tke     , bprod , &
335                                sprod  , sfi    , qsat     , kvinit  ,                              &
336                                tauresx, tauresy, ksrftms  ,                                        &
337                                ipbl   , kpblh  , wstarPBL , turbtype, sm_aw )
338       
339    !-------------------------------------------------------------------- !
340    ! Purpose: Interface to compute eddy diffusivities.                   !
341    !          Eddy diffusivities are calculated in a fully implicit way  !
342    !          through iteration process.                                 !   
343    ! Author:  Sungsu Park. August. 2006.                                 !
344    !                       May.    2008.                                 !
345    !-------------------------------------------------------------------- !
346    use diffusion_solver, only: compute_vdiff
347#ifndef WRF_PORT
348    use cam_history,      only: outfld, addfld, phys_decomp
349  ! use physics_types,    only: physics_state
350    use phys_debug_util,  only: phys_debug_col
351    use time_manager,     only: is_first_step, get_nstep
352#else
353    use module_cam_support,   only: outfld, addfld, phys_decomp
354#endif
355
356    implicit none
357
358  ! type(physics_state)     :: state                     ! Physics state variables
359
360    ! --------------- !
361    ! Input Variables !
362    ! --------------- !
363
364    integer,  intent(in)    :: lchnk   
365    integer,  intent(in)    :: pcols                     ! Number of atmospheric columns [ # ]
366    integer,  intent(in)    :: pver                      ! Number of atmospheric layers  [ # ]
367    integer,  intent(in)    :: ncol                      ! Number of atmospheric columns [ # ]
368    integer,  intent(in)    :: nturb                     ! Number of iteration steps for calculating eddy diffusivity [ # ]
369    logical,  intent(in)    :: wstarent                  ! .true. means use the 'wstar' entrainment closure.
370    logical,  intent(in)    :: kvinit                    ! 'true' means time step = 1 : used for initializing kvh, kvm (uses kvf or zero)
371    real(r8), intent(in)    :: ztodt                     ! Physics integration time step 2 delta-t [ s ]
372    real(r8), intent(in)    :: t(pcols,pver)             ! Temperature [K]
373    real(r8), intent(in)    :: qv(pcols,pver)            ! Water vapor  specific humidity [ kg/kg ]
374    real(r8), intent(in)    :: ql(pcols,pver)            ! Liquid water specific humidity [ kg/kg ]
375    real(r8), intent(in)    :: qi(pcols,pver)            ! Ice specific humidity [ kg/kg ]
376    real(r8), intent(in)    :: s(pcols,pver)             ! Dry static energy [ J/kg ]
377    real(r8), intent(in)    :: rpdel(pcols,pver)         ! 1./pdel where 'pdel' is thickness of the layer [ Pa ]
378    real(r8), intent(in)    :: cldn(pcols,pver)          ! Stratiform cloud fraction [ fraction ]
379    real(r8), intent(in)    :: qrl(pcols,pver)           ! LW cooling rate
380    real(r8), intent(in)    :: wsedl(pcols,pver)         ! Sedimentation velocity of liquid stratus cloud droplet [ m/s ]
381    real(r8), intent(in)    :: z(pcols,pver)             ! Layer mid-point height above surface [ m ]
382    real(r8), intent(in)    :: zi(pcols,pver+1)          ! Interface height above surface [ m ]
383    real(r8), intent(in)    :: pmid(pcols,pver)          ! Layer mid-point pressure [ Pa ]
384    real(r8), intent(in)    :: pi(pcols,pver+1)          ! Interface pressure [ Pa ]
385    real(r8), intent(in)    :: u(pcols,pver)             ! Zonal velocity [ m/s ]
386    real(r8), intent(in)    :: v(pcols,pver)             ! Meridional velocity [ m/s ]
387    real(r8), intent(in)    :: taux(pcols)               ! Zonal wind stress at surface [ N/m2 ]
388    real(r8), intent(in)    :: tauy(pcols)               ! Meridional wind stress at surface [ N/m2 ]
389    real(r8), intent(in)    :: shflx(pcols)              ! Sensible heat flux at surface [ unit ? ]
390    real(r8), intent(in)    :: qflx(pcols)               ! Water vapor flux at surface [ unit ? ]
391    real(r8), intent(in)    :: kvm_in(pcols,pver+1)      ! kvm saved from last timestep [ m2/s ]
392    real(r8), intent(in)    :: kvh_in(pcols,pver+1)      ! kvh saved from last timestep [ m2/s ]
393    real(r8), intent(in)    :: ksrftms(pcols)            ! Surface drag coefficient of turbulent mountain stress [ unit ? ]
394
395    ! ---------------- !
396    ! Output Variables !
397    ! ---------------- !
398
399    real(r8), intent(out)   :: kvm_out(pcols,pver+1)     ! Eddy diffusivity for momentum [ m2/s ]
400    real(r8), intent(out)   :: kvh_out(pcols,pver+1)     ! Eddy diffusivity for heat [ m2/s ]
401    real(r8), intent(out)   :: kvq(pcols,pver+1)         ! Eddy diffusivity for constituents, moisture and tracers [ m2/s ] (note not having '_out')
402    real(r8), intent(out)   :: ustar(pcols)              ! Surface friction velocity [ m/s ]
403    real(r8), intent(out)   :: pblh(pcols)               ! PBL top height [ m ]
404    real(r8), intent(out)   :: cgh(pcols,pver+1)         ! Counter-gradient term for heat [ J/kg/m ]
405    real(r8), intent(out)   :: cgs(pcols,pver+1)         ! Counter-gradient star [ cg/flux ]
406    real(r8), intent(out)   :: tpert(pcols)              ! Convective temperature excess [ K ]
407    real(r8), intent(out)   :: qpert(pcols)              ! Convective humidity excess [ kg/kg ]
408    real(r8), intent(out)   :: wpert(pcols)              ! Turbulent velocity excess [ m/s ]
409    real(r8), intent(out)   :: tke(pcols,pver+1)         ! Turbulent kinetic energy [ m2/s2 ]
410    real(r8), intent(out)   :: bprod(pcols,pver+1)       ! Buoyancy production [ m2/s3 ]
411    real(r8), intent(out)   :: sprod(pcols,pver+1)       ! Shear production [ m2/s3 ]
412    real(r8), intent(out)   :: sfi(pcols,pver+1)         ! Interfacial layer saturation fraction [ fraction ]
413    real(r8), intent(out)   :: turbtype(pcols,pver+1)    ! Turbulence type identifier at all interfaces [ no unit ]
414    real(r8), intent(out)   :: sm_aw(pcols,pver+1)       ! Normalized Galperin instability function for momentum [ no unit ]
415                                                         ! This is 1 when neutral condition (Ri=0), 4.964 for maximum unstable case, and 0 when Ri > Ricrit=0.19.
416    real(r8), intent(out)   :: ipbl(pcols)               ! If 1, PBL is CL, while if 0, PBL is STL.
417    real(r8), intent(out)   :: kpblh(pcols)              ! Layer index containing PBL top within or at the base interface
418    real(r8), intent(out)   :: wstarPBL(pcols)           ! Convective velocity within PBL [ m/s ]
419
420    ! ---------------------- !
421    ! Input-Output Variables !
422    ! ---------------------- !
423
424    real(r8), intent(inout) :: tauresx(pcols)            ! Residual stress to be added in vdiff to correct for turb
425    real(r8), intent(inout) :: tauresy(pcols)            ! Stress mismatch between sfc and atm accumulated in prior timesteps
426
427    ! --------------- !
428    ! Local Variables !
429    ! --------------- !
430
431    integer                    icol
432    integer                    i, k, iturb, status
433    integer,  external      :: qsat
434    character(128)          :: errstring                 ! Error status for compute_vdiff
435
436    real(r8)                :: tautotx(pcols)            ! Total stress including tms
437    real(r8)                :: tautoty(pcols)            ! Total stress including tms
438    real(r8)                :: kvf(pcols,pver+1)         ! Free atmospheric eddy diffusivity [ m2/s ]
439    real(r8)                :: kvm(pcols,pver+1)         ! Eddy diffusivity for momentum [ m2/s ]
440    real(r8)                :: kvh(pcols,pver+1)         ! Eddy diffusivity for heat [ m2/s ]
441    real(r8)                :: kvm_preo(pcols,pver+1)    ! Eddy diffusivity for momentum [ m2/s ]
442    real(r8)                :: kvh_preo(pcols,pver+1)    ! Eddy diffusivity for heat [ m2/s ]
443    real(r8)                :: kvm_pre(pcols,pver+1)     ! Eddy diffusivity for momentum [ m2/s ]
444    real(r8)                :: kvh_pre(pcols,pver+1)     ! Eddy diffusivity for heat [ m2/s ]
445    real(r8)                :: errorPBL(pcols)           ! Error function showing whether PBL produced convergent solution or not. [ unit ? ]
446    real(r8)                :: s2(pcols,pver)            ! Shear squared, defined at interfaces except surface [ s-2 ]
447    real(r8)                :: n2(pcols,pver)            ! Buoyancy frequency, defined at interfaces except surface [ s-2 ]
448    real(r8)                :: ri(pcols,pver)            ! Richardson number, 'n2/s2', defined at interfaces except surface [ s-2 ]
449    real(r8)                :: pblhp(pcols)              ! PBL top pressure [ Pa ]
450    real(r8)                :: minpblh(pcols)            ! Minimum PBL height based on surface stress
451
452    real(r8)                :: qt(pcols,pver)            ! Total specific humidity [ kg/kg ]
453    real(r8)                :: sfuh(pcols,pver)          ! Saturation fraction in upper half-layer [ fraction ]
454    real(r8)                :: sflh(pcols,pver)          ! Saturation fraction in lower half-layer [ fraction ]
455    real(r8)                :: sl(pcols,pver)            ! Liquid water static energy [ J/kg ]
456    real(r8)                :: slv(pcols,pver)           ! Liquid water virtual static energy [ J/kg ]
457    real(r8)                :: slslope(pcols,pver)       ! Slope of 'sl' in each layer
458    real(r8)                :: qtslope(pcols,pver)       ! Slope of 'qt' in each layer
459    real(r8)                :: rrho(pcols)               ! Density at the lowest layer
460    real(r8)                :: qvfd(pcols,pver)          ! Specific humidity for diffusion [ kg/kg ]
461    real(r8)                :: tfd(pcols,pver)           ! Temperature for diffusion [ K ]
462    real(r8)                :: slfd(pcols,pver)          ! Liquid static energy [ J/kg ]
463    real(r8)                :: qtfd(pcols,pver)          ! Total specific humidity [ kg/kg ]
464    real(r8)                :: qlfd(pcols,pver)          ! Liquid water specific humidity for diffusion [ kg/kg ]
465    real(r8)                :: ufd(pcols,pver)           ! U-wind for diffusion [ m/s ]
466    real(r8)                :: vfd(pcols,pver)           ! V-wind for diffusion [ m/s ]
467
468    ! Buoyancy coefficients : w'b' = ch * w'sl' + cm * w'qt'
469
470    real(r8)                :: chu(pcols,pver+1)         ! Heat buoyancy coef for dry states, defined at each interface, finally.
471    real(r8)                :: chs(pcols,pver+1)         ! Heat buoyancy coef for sat states, defined at each interface, finally.
472    real(r8)                :: cmu(pcols,pver+1)         ! Moisture buoyancy coef for dry states, defined at each interface, finally.
473    real(r8)                :: cms(pcols,pver+1)         ! Moisture buoyancy coef for sat states, defined at each interface, finally.
474
475    real(r8)                :: jnk1d(pcols)
476    real(r8)                :: jnk2d(pcols,pver+1) 
477    real(r8)                :: zero(pcols)
478    real(r8)                :: zero2d(pcols,pver+1)
479    real(r8)                :: es(1)                     ! Saturation vapor pressure
480    real(r8)                :: qs(1)                     ! Saturation specific humidity
481    real(r8)                :: gam(1)                    ! (L/cp)*dqs/dT
482    real(r8)                :: ep2, templ, temps
483
484    ! ------------------------------- !
485    ! Variables for diagnostic output !
486    ! ------------------------------- !
487
488    real(r8)                :: tkes(pcols)               ! TKE at surface interface [ m2/s2 ]
489    real(r8)                :: kbase_o(pcols,ncvmax)     ! Original external base interface index of CL from 'exacol'
490    real(r8)                :: ktop_o(pcols,ncvmax)      ! Original external top  interface index of CL from 'exacol'
491    real(r8)                :: ncvfin_o(pcols)           ! Original number of CLs from 'exacol'
492    real(r8)                :: kbase_mg(pcols,ncvmax)    ! 'kbase' after extending-merging from 'zisocl'
493    real(r8)                :: ktop_mg(pcols,ncvmax)     ! 'ktop' after extending-merging from 'zisocl'
494    real(r8)                :: ncvfin_mg(pcols)          ! 'ncvfin' after extending-merging from 'zisocl'
495    real(r8)                :: kbase_f(pcols,ncvmax)     ! Final 'kbase' after extending-merging & including SRCL
496    real(r8)                :: ktop_f(pcols,ncvmax)      ! Final 'ktop' after extending-merging & including SRCL
497    real(r8)                :: ncvfin_f(pcols)           ! Final 'ncvfin' after extending-merging & including SRCL
498    real(r8)                :: wet(pcols,ncvmax)         ! Entrainment rate at the CL top  [ m/s ]
499    real(r8)                :: web(pcols,ncvmax)         ! Entrainment rate at the CL base [ m/s ]. Set to zero if CL is based at surface.
500    real(r8)                :: jtbu(pcols,ncvmax)        ! Buoyancy jump across the CL top  [ m/s2 ] 
501    real(r8)                :: jbbu(pcols,ncvmax)        ! Buoyancy jump across the CL base [ m/s2 ] 
502    real(r8)                :: evhc(pcols,ncvmax)        ! Evaporative enhancement factor at the CL top
503    real(r8)                :: jt2slv(pcols,ncvmax)      ! Jump of slv ( across two layers ) at CL top used only for evhc [ J/kg ]
504    real(r8)                :: n2ht(pcols,ncvmax)        ! n2 defined at the CL top  interface but using sfuh(kt)   instead of sfi(kt) [ s-2 ]
505    real(r8)                :: n2hb(pcols,ncvmax)        ! n2 defined at the CL base interface but using sflh(kb-1) instead of sfi(kb) [ s-2 ]
506    real(r8)                :: lwp(pcols,ncvmax)         ! LWP in the CL top layer [ kg/m2 ]
507    real(r8)                :: opt_depth(pcols,ncvmax)   ! Optical depth of the CL top layer
508    real(r8)                :: radinvfrac(pcols,ncvmax)  ! Fraction of radiative cooling confined in the top portion of CL top layer
509    real(r8)                :: radf(pcols,ncvmax)        ! Buoyancy production at the CL top due to LW radiative cooling [ m2/s3 ]
510    real(r8)                :: wstar(pcols,ncvmax)       ! Convective velocity in each CL [ m/s ]
511    real(r8)                :: wstar3fact(pcols,ncvmax)  ! Enhancement of 'wstar3' due to entrainment (inverse) [ no unit ]
512    real(r8)                :: ebrk(pcols,ncvmax)        ! Net mean TKE of CL including entrainment effect [ m2/s2 ]
513    real(r8)                :: wbrk(pcols,ncvmax)        ! Net mean normalized TKE (W) of CL, 'ebrk/b1' including entrainment effect [ m2/s2 ]
514    real(r8)                :: lbrk(pcols,ncvmax)        ! Energetic internal thickness of CL [m]
515    real(r8)                :: ricl(pcols,ncvmax)        ! CL internal mean Richardson number
516    real(r8)                :: ghcl(pcols,ncvmax)        ! Half of normalized buoyancy production of CL
517    real(r8)                :: shcl(pcols,ncvmax)        ! Galperin instability function of heat-moisture of CL
518    real(r8)                :: smcl(pcols,ncvmax)        ! Galperin instability function of mementum of CL
519    real(r8)                :: ghi(pcols,pver+1)         ! Half of normalized buoyancy production at all interfaces
520    real(r8)                :: shi(pcols,pver+1)         ! Galperin instability function of heat-moisture at all interfaces
521    real(r8)                :: smi(pcols,pver+1)         ! Galperin instability function of heat-moisture at all interfaces
522    real(r8)                :: rii(pcols,pver+1)         ! Interfacial Richardson number defined at all interfaces
523    real(r8)                :: lengi(pcols,pver+1)       ! Turbulence length scale at all interfaces [ m ]
524    real(r8)                :: wcap(pcols,pver+1)        ! Normalized TKE at all interfaces [ m2/s2 ]
525
526    ! ---------- !
527    ! Initialize !
528    ! ---------- !
529
530    zero(:)     = 0._r8
531    zero2d(:,:) = 0._r8
532
533    ! ----------------------- !
534    ! Main Computation Begins !
535    ! ----------------------- !
536
537    ufd(:ncol,:)  = u(:ncol,:)
538    vfd(:ncol,:)  = v(:ncol,:)
539    tfd(:ncol,:)  = t(:ncol,:)
540    qvfd(:ncol,:) = qv(:ncol,:)
541    qlfd(:ncol,:) = ql(:ncol,:)
542   
543    do iturb = 1, nturb
544
545     ! Compute total stress by including 'tms'.
546     ! Here, in computing 'tms', we can use either iteratively changed 'ufd,vfd' or the
547     ! initially given 'u,v' to the PBL scheme. Note that normal stress, 'taux, tauy'
548     ! are not changed by iteration. In order to treat 'tms' in a fully implicit way,
549     ! I am using updated wind, here.
550
551       tautotx(:ncol) = taux(:ncol) - ksrftms(:ncol) * ufd(:ncol,pver)
552       tautoty(:ncol) = tauy(:ncol) - ksrftms(:ncol) * vfd(:ncol,pver)
553
554     ! Calculate (qt,sl,n2,s2,ri) from a given set of (t,qv,ql,qi,u,v)
555
556       call trbintd( &
557                     pcols    , pver    , ncol  , z       , ufd     , vfd     , tfd   , pmid    , &
558                     tautotx  , tautoty , ustar , rrho    , s2      , n2      , ri    , zi      , &
559                     pi       , cldn    , qtfd  , qvfd    , qlfd    , qi      , sfi   , sfuh    , &
560                     sflh     , slfd    , slv   , slslope , qtslope , chs     , chu   , cms     , &
561                     cmu      , minpblh , qsat )
562
563     ! Save initial (i.e., before iterative diffusion) profile of (qt,sl) at each iteration.         
564     ! Only necessary for (qt,sl) not (u,v) because (qt,sl) are newly calculated variables.
565
566       if( iturb .eq. 1 ) then
567           qt(:ncol,:) = qtfd(:ncol,:)
568           sl(:ncol,:) = slfd(:ncol,:)
569       endif
570
571     ! Get free atmosphere exchange coefficients. This 'kvf' is not used in UW moist PBL scheme
572
573       if( use_kvf )call austausch_atm( pcols, pver, ncol, ri, s2, kvf )
574
575     ! Initialize kvh/kvm to send to caleddy, depending on model timestep and iteration number
576     ! This is necessary for 'wstar-based' entrainment closure.
577
578       if( iturb .eq. 1 ) then
579           if( kvinit ) then
580           ! First iteration of first model timestep : Use free tropospheric value or zero.
581             if( use_kvf ) then
582                 kvh(:ncol,:) = kvf(:ncol,:)
583                 kvm(:ncol,:) = kvf(:ncol,:)
584             else
585                 kvh(:ncol,:) = 0._r8
586                 kvm(:ncol,:) = 0._r8
587             endif
588           else
589             ! First iteration on any model timestep except the first : Use value from previous timestep
590             kvh(:ncol,:) = kvh_in(:ncol,:)
591             kvm(:ncol,:) = kvm_in(:ncol,:)
592           endif
593       else
594        ! Not the first iteration : Use from previous iteration
595          kvh(:ncol,:) = kvh_out(:ncol,:)
596          kvm(:ncol,:) = kvm_out(:ncol,:)
597       endif
598
599     ! Calculate eddy diffusivity (kvh_out,kvm_out) and (tke,bprod,sprod) using
600     ! a given (kvh,kvm) which are used only for initializing (bprod,sprod)  at
601     ! the first part of caleddy. (bprod,sprod) are fully updated at the end of
602     ! caleddy after calculating (kvh_out,kvm_out)
603
604       call caleddy( pcols     , pver      , ncol      ,                     &
605                     slfd      , qtfd      , qlfd      , slv      ,ufd     , &
606                     vfd       , pi        , z         , zi       ,          &
607                     qflx      , shflx     , slslope   , qtslope  ,          &
608                     chu       , chs       , cmu       , cms      ,sfuh    , &
609                     sflh      , n2        , s2        , ri       ,rrho    , &
610                     pblh      , ustar     ,                                 &
611                     kvh       , kvm       , kvh_out   , kvm_out  ,          &
612                     tpert     , qpert     , qrl       , kvf      , tke    , &
613                     wstarent  , bprod     , sprod     , minpblh  , wpert  , &
614                     tkes      , turbtype  , sm_aw     ,                     &
615                     kbase_o   , ktop_o    , ncvfin_o  ,                     &
616                     kbase_mg  , ktop_mg   , ncvfin_mg ,                     &                 
617                     kbase_f   , ktop_f    , ncvfin_f  ,                     &                 
618                     wet       , web       , jtbu      , jbbu     ,          &
619                     evhc      , jt2slv    , n2ht      , n2hb     ,          &
620                     lwp       , opt_depth , radinvfrac, radf     ,          &
621                     wstar     , wstar3fact,                                 &
622                     ebrk      , wbrk      , lbrk      , ricl     , ghcl   , &
623                     shcl      , smcl      , ghi       , shi      , smi    , &
624                     rii       , lengi     , wcap      , pblhp    , cldn   , &
625                     ipbl      , kpblh     , wsedl )
626
627     ! Calculate errorPBL to check whether PBL produced convergent solutions or not.
628
629       if( iturb .eq. nturb ) then
630           do i = 1, ncol
631              errorPBL(i) = 0._r8
632              do k = 1, pver
633                 errorPBL(i) = errorPBL(i) + ( kvh(i,k) - kvh_out(i,k) )**2
634              end do
635              errorPBL(i) = sqrt(errorPBL(i)/pver)
636           end do
637       end if
638
639     ! Eddy diffusivities which will be used for the initialization of (bprod,
640     ! sprod) in 'caleddy' at the next iteration step.
641
642       if( iturb .gt. 1 .and. iturb .lt. nturb ) then
643           kvm_out(:ncol,:) = lambda * kvm_out(:ncol,:) + ( 1._r8 - lambda ) * kvm(:ncol,:)
644           kvh_out(:ncol,:) = lambda * kvh_out(:ncol,:) + ( 1._r8 - lambda ) * kvh(:ncol,:)
645       endif
646
647     ! Set nonlocal terms to zero for flux diagnostics, since not used by caleddy.
648
649       cgh(:ncol,:) = 0._r8
650       cgs(:ncol,:) = 0._r8     
651
652       if( iturb .lt. nturb ) then
653
654         ! Each time we diffuse the original state
655
656           slfd(:ncol,:)  = sl(:ncol,:)
657           qtfd(:ncol,:)  = qt(:ncol,:)
658           ufd(:ncol,:)   = u(:ncol,:)
659           vfd(:ncol,:)   = v(:ncol,:)
660
661         ! Diffuse initial profile of each time step using a given (kvh_out,kvm_out)
662         ! In the below 'compute_vdiff', (slfd,qtfd,ufd,vfd) are 'inout' variables.
663
664           call compute_vdiff( lchnk   ,                                                  &
665                               pcols   , pver     , 1        , ncol         , pmid      , &
666                               pi      , rpdel    , t        , ztodt        , taux      , &
667                               tauy    , shflx    , qflx     , ntop_turb    , nbot_turb , &
668                               kvh_out , kvm_out  , kvh_out  , cgs          , cgh       , &
669                               zi      , ksrftms  , zero     , fieldlist_wet,             &
670                               ufd     , vfd      , qtfd     , slfd         ,             &
671                               jnk1d   , jnk1d    , jnk2d    , jnk1d        , errstring , &
672                               tauresx , tauresy  , 0        , .false. )
673
674         ! Retrieve (tfd,qvfd,qlfd) from (slfd,qtfd) in order to
675         ! use 'trbintd' at the next iteration.
676         
677          do k = 1, pver
678             do i = 1, ncol
679              ! ----------------------------------------------------- !
680              ! Compute the condensate 'qlfd' in the updated profiles !
681              ! ----------------------------------------------------- ! 
682              ! Option.1 : Assume grid-mean condensate is homogeneously diffused by the moist turbulence scheme.
683              !            This should bs used if 'pseudodiff = .false.' in vertical_diffusion.F90.
684              ! Modification : Need to be check whether below is correct in the presence of ice, qi.       
685              !                I should understand why the variation of ice, qi is neglected during diffusion.
686                templ     = ( slfd(i,k) - g*z(i,k) ) / cpair
687                status    =   qsat( templ, pmid(i,k), es(1), qs(1), gam(1), 1 )
688                ep2       =  .622_r8
689                temps     =   templ + ( qtfd(i,k) - qs(1) ) / ( cpair / latvap + latvap * qs(1) / ( rair * templ**2 ) )
690                status    =   qsat( temps, pmid(i,k), es(1), qs(1), gam(1), 1 )
691                qlfd(i,k) =   max( qtfd(i,k) - qi(i,k) - qs(1) ,0._r8 )
692              ! Option.2 : Assume condensate is not diffused by the moist turbulence scheme.
693              !            This should bs used if 'pseudodiff = .true.'  in vertical_diffusion.F90.       
694              ! qlfd(i,k) = ql(i,k)
695              ! ----------------------------- !
696              ! Compute the other 'qvfd, tfd' !
697              ! ----------------------------- !
698                qvfd(i,k) = max( 0._r8, qtfd(i,k) - qi(i,k) - qlfd(i,k) )
699                tfd(i,k)  = ( slfd(i,k) + latvap * qlfd(i,k) + latsub * qi(i,k) - g*z(i,k)) / cpair
700             end do
701          end do
702       endif
703
704     ! Debug
705     ! icol = phys_debug_col(lchnk)
706     ! if( icol > 0 .and. get_nstep() .ge. 1 ) then
707     !     write(iulog,*) ' '
708     !     write(iulog,*) 'eddy_diff debug at the end of iteration'
709     !     write(iulog,*) 't,     qv,     ql,     cld,     u,     v'
710     !     do k = pver-3, pver
711     !        write (iulog,*) k, tfd(icol,k), qvfd(icol,k), qlfd(icol,k), cldn(icol,k), ufd(icol,k), vfd(icol,k)
712     !     end do
713     ! endif
714     ! Debug
715
716    end do  ! End of 'iturb' iteration
717
718    kvq(:ncol,:) = kvh_out(:ncol,:)
719
720  ! Compute 'wstar' within the PBL for use in the future convection scheme.
721
722    do i = 1, ncol
723       if( ipbl(i) .eq. 1._r8 ) then
724           wstarPBL(i) = max( 0._r8, wstar(i,1) )
725       else
726           wstarPBL(i) = 0._r8
727       endif
728    end do
729
730    ! --------------------------------------------------------------- !
731    ! Writing for detailed diagnostic analysis of UW moist PBL scheme !
732    ! --------------------------------------------------------------- !
733
734    call outfld( 'UW_errorPBL',    errorPBL,   pcols,   lchnk )
735
736    call outfld( 'UW_n2',          n2,         pcols,   lchnk )
737    call outfld( 'UW_s2',          s2,         pcols,   lchnk )
738    call outfld( 'UW_ri',          ri,         pcols,   lchnk )
739
740    call outfld( 'UW_sfuh',        sfuh,       pcols,   lchnk )
741    call outfld( 'UW_sflh',        sflh,       pcols,   lchnk )
742    call outfld( 'UW_sfi',         sfi,        pcols,   lchnk )
743
744    call outfld( 'UW_cldn',        cldn,       pcols,   lchnk )
745    call outfld( 'UW_qrl',         qrl,        pcols,   lchnk )
746    call outfld( 'UW_ql',          qlfd,       pcols,   lchnk )
747
748    call outfld( 'UW_chu',         chu,        pcols,   lchnk )
749    call outfld( 'UW_chs',         chs,        pcols,   lchnk )
750    call outfld( 'UW_cmu',         cmu,        pcols,   lchnk )
751    call outfld( 'UW_cms',         cms,        pcols,   lchnk )
752
753    call outfld( 'UW_tke',         tke,        pcols,   lchnk )
754    call outfld( 'UW_wcap',        wcap,       pcols,   lchnk )
755    call outfld( 'UW_bprod',       bprod,      pcols,   lchnk )
756    call outfld( 'UW_sprod',       sprod,      pcols,   lchnk )
757
758    call outfld( 'UW_kvh',         kvh_out,    pcols,   lchnk )
759    call outfld( 'UW_kvm',         kvm_out,    pcols,   lchnk )
760
761    call outfld( 'UW_pblh',        pblh,       pcols,   lchnk )
762    call outfld( 'UW_pblhp',       pblhp,      pcols,   lchnk )
763    call outfld( 'UW_tpert',       tpert,      pcols,   lchnk )
764    call outfld( 'UW_qpert',       qpert,      pcols,   lchnk )
765    call outfld( 'UW_wpert',       wpert,      pcols,   lchnk )
766
767    call outfld( 'UW_ustar',       ustar,      pcols,   lchnk )
768    call outfld( 'UW_tkes',        tkes,       pcols,   lchnk )
769    call outfld( 'UW_minpblh',     minpblh,    pcols,   lchnk )
770
771    call outfld( 'UW_turbtype',    turbtype,   pcols,   lchnk )
772
773    call outfld( 'UW_kbase_o',     kbase_o,    pcols,   lchnk )
774    call outfld( 'UW_ktop_o',      ktop_o,     pcols,   lchnk )
775    call outfld( 'UW_ncvfin_o',    ncvfin_o,   pcols,   lchnk )
776
777    call outfld( 'UW_kbase_mg',    kbase_mg,   pcols,   lchnk )
778    call outfld( 'UW_ktop_mg',     ktop_mg,    pcols,   lchnk )
779    call outfld( 'UW_ncvfin_mg',   ncvfin_mg,  pcols,   lchnk )
780
781    call outfld( 'UW_kbase_f',     kbase_f,    pcols,   lchnk )
782    call outfld( 'UW_ktop_f',      ktop_f,     pcols,   lchnk )
783    call outfld( 'UW_ncvfin_f',    ncvfin_f,   pcols,   lchnk )
784
785    call outfld( 'UW_wet',         wet,        pcols,   lchnk )
786    call outfld( 'UW_web',         web,        pcols,   lchnk )
787    call outfld( 'UW_jtbu',        jtbu,       pcols,   lchnk )
788    call outfld( 'UW_jbbu',        jbbu,       pcols,   lchnk )
789    call outfld( 'UW_evhc',        evhc,       pcols,   lchnk )
790    call outfld( 'UW_jt2slv',      jt2slv,     pcols,   lchnk )
791    call outfld( 'UW_n2ht',        n2ht,       pcols,   lchnk )
792    call outfld( 'UW_n2hb',        n2hb,       pcols,   lchnk )
793    call outfld( 'UW_lwp',         lwp,        pcols,   lchnk )
794    call outfld( 'UW_optdepth',    opt_depth,  pcols,   lchnk )
795    call outfld( 'UW_radfrac',     radinvfrac, pcols,   lchnk )
796    call outfld( 'UW_radf',        radf,       pcols,   lchnk )
797    call outfld( 'UW_wstar',       wstar,      pcols,   lchnk )
798    call outfld( 'UW_wstar3fact',  wstar3fact, pcols,   lchnk )
799    call outfld( 'UW_ebrk',        ebrk,       pcols,   lchnk )
800    call outfld( 'UW_wbrk',        wbrk,       pcols,   lchnk )
801    call outfld( 'UW_lbrk',        lbrk,       pcols,   lchnk )
802    call outfld( 'UW_ricl',        ricl,       pcols,   lchnk )
803    call outfld( 'UW_ghcl',        ghcl,       pcols,   lchnk )
804    call outfld( 'UW_shcl',        shcl,       pcols,   lchnk )
805    call outfld( 'UW_smcl',        smcl,       pcols,   lchnk )
806
807    call outfld( 'UW_gh',          ghi,        pcols,   lchnk )
808    call outfld( 'UW_sh',          shi,        pcols,   lchnk )
809    call outfld( 'UW_sm',          smi,        pcols,   lchnk )
810    call outfld( 'UW_ria',         rii,        pcols,   lchnk )
811    call outfld( 'UW_leng',        lengi,      pcols,   lchnk )
812
813    return
814   
815  end subroutine compute_eddy_diff
816
817  !=============================================================================== !
818  !                                                                                !
819  !=============================================================================== !
820 
821  subroutine sfdiag( pcols   , pver    , ncol    , qt      , ql      , sl      , &
822                     pi      , pm      , zi      , cld     , sfi     , sfuh    , &
823                     sflh    , slslope , qtslope , qsat )
824    !----------------------------------------------------------------------- !
825    !                                                                        !
826    ! Purpose: Interface for calculating saturation fractions  at upper and  !
827    !          lower-half layers, & interfaces for use by turbulence scheme  !
828    !                                                                        !
829    ! Method : Various but 'l' should be chosen for consistency.             !
830    !                                                                        !
831    ! Author : B. Stevens and C. Bretherton (August 2000)                    !
832    !          Sungsu Park. August 2006.                                     !
833    !                       May.   2008.                                     !
834    !                                                                        ! 
835    ! S.Park : The computed saturation fractions are repeatedly              !
836    !          used to compute buoyancy coefficients in'trbintd' & 'caleddy'.! 
837    !----------------------------------------------------------------------- !
838
839    implicit none       
840
841    ! --------------- !
842    ! Input arguments !
843    ! --------------- !
844
845    integer,  external    :: qsat
846
847    integer,  intent(in)  :: pcols               ! Number of atmospheric columns   
848    integer,  intent(in)  :: pver                ! Number of atmospheric layers   
849    integer,  intent(in)  :: ncol                ! Number of atmospheric columns   
850
851    real(r8), intent(in)  :: sl(pcols,pver)      ! Liquid water static energy [ J/kg ]
852    real(r8), intent(in)  :: qt(pcols,pver)      ! Total water specific humidity [ kg/kg ]
853    real(r8), intent(in)  :: ql(pcols,pver)      ! Liquid water specific humidity [ kg/kg ]
854    real(r8), intent(in)  :: pi(pcols,pver+1)    ! Interface pressures [ Pa ]
855    real(r8), intent(in)  :: pm(pcols,pver)      ! Layer mid-point pressures [ Pa ]
856    real(r8), intent(in)  :: zi(pcols,pver+1)    ! Interface heights [ m ]
857    real(r8), intent(in)  :: cld(pcols,pver)     ! Stratiform cloud fraction [ fraction ]
858    real(r8), intent(in)  :: slslope(pcols,pver) ! Slope of 'sl' in each layer
859    real(r8), intent(in)  :: qtslope(pcols,pver) ! Slope of 'qt' in each layer
860
861    ! ---------------- !
862    ! Output arguments !
863    ! ---------------- !
864
865    real(r8), intent(out) :: sfi(pcols,pver+1)   ! Interfacial layer saturation fraction [ fraction ]
866    real(r8), intent(out) :: sfuh(pcols,pver)    ! Saturation fraction in upper half-layer [ fraction ]
867    real(r8), intent(out) :: sflh(pcols,pver)    ! Saturation fraction in lower half-layer [ fraction ]
868
869    ! --------------- !
870    ! Local Variables !
871    ! --------------- !
872
873    integer               :: i                   ! Longitude index
874    integer               :: k                   ! Vertical index
875    integer               :: km1                 ! k-1
876    integer               :: status              ! Status returned by function calls
877    real(r8)              :: sltop, slbot        ! sl at top/bot of grid layer
878    real(r8)              :: qttop, qtbot        ! qt at top/bot of grid layer
879    real(r8)              :: tltop(1), tlbot(1)  ! Liquid water temperature at top/bot of grid layer
880    real(r8)              :: qxtop, qxbot        ! Sat excess at top/bot of grid layer
881    real(r8)              :: qxm                 ! Sat excess at midpoint
882    real(r8)              :: es(1)               ! Saturation vapor pressure
883    real(r8)              :: qs(1)               ! Saturation spec. humidity
884    real(r8)              :: gam(1)              ! (L/cp)*dqs/dT
885    real(r8)              :: cldeff(pcols,pver)  ! Effective Cloud Fraction [ fraction ]
886
887    ! ----------------------- !
888    ! Main Computation Begins !
889    ! ----------------------- !
890
891    sfi(1:ncol,:)    = 0._r8
892    sfuh(1:ncol,:)   = 0._r8
893    sflh(1:ncol,:)   = 0._r8
894    cldeff(1:ncol,:) = 0._r8
895
896    select case (sftype)
897    case ('d')
898       ! ----------------------------------------------------------------------- !
899       ! Simply use the given stratus fraction ('horizontal' cloud partitioning) !
900       ! ----------------------------------------------------------------------- !
901       do k = ntop_turb + 1, nbot_turb
902          km1 = k - 1
903          do i = 1, ncol
904             sfuh(i,k) = cld(i,k)
905             sflh(i,k) = cld(i,k)
906             sfi(i,k)  = 0.5_r8 * ( sflh(i,km1) + min( sflh(i,km1), sfuh(i,k) ) )
907          end do
908       end do
909       do i = 1, ncol
910          sfi(i,pver+1) = sflh(i,pver)
911       end do
912    case ('l')
913       ! ------------------------------------------ !
914       ! Use modified stratus fraction partitioning !
915       ! ------------------------------------------ !
916       do k = ntop_turb + 1, nbot_turb
917          km1 = k - 1
918          do i = 1, ncol
919             cldeff(i,k) = cld(i,k)
920             sfuh(i,k)   = cld(i,k)
921             sflh(i,k)   = cld(i,k)
922             if( ql(i,k) .lt. qmin ) then
923                 sfuh(i,k) = 0._r8
924                 sflh(i,k) = 0._r8
925             end if
926           ! Modification : The contribution of ice should be carefully considered.
927             if( choice_evhc .eq. 'ramp' .or. choice_radf .eq. 'ramp' ) then
928                 cldeff(i,k) = cld(i,k) * min( ql(i,k) / qmin, 1._r8 )
929                 sfuh(i,k)   = cldeff(i,k)
930                 sflh(i,k)   = cldeff(i,k)
931             elseif( choice_evhc .eq. 'maxi' .or. choice_radf .eq. 'maxi' ) then
932                 cldeff(i,k) = cld(i,k)
933                 sfuh(i,k)   = cldeff(i,k)
934                 sflh(i,k)   = cldeff(i,k)
935             endif
936           ! At the stratus top, take the minimum interfacial saturation fraction
937             sfi(i,k) = 0.5_r8 * ( sflh(i,km1) + min( sfuh(i,k), sflh(i,km1) ) )
938           ! Modification : Currently sfi at the top and surface interfaces are set to be zero.
939           !                Also, sfuh and sflh in the top model layer is set to be zero.
940           !                However, I may need to set
941           !                         do i = 1, ncol
942           !                            sfi(i,pver+1) = sflh(i,pver)
943           !                         end do
944           !                for treating surface-based fog.
945           ! OK. I added below block similar to the other cases.
946          end do
947       end do
948       do i = 1, ncol
949          sfi(i,pver+1) = sflh(i,pver)
950       end do
951    case ('u')
952       ! ------------------------------------------------------------------------- !
953       ! Use unsaturated buoyancy - since sfi, sfuh, sflh have already been zeroed !
954       ! nothing more need be done for this case.                                  !
955       ! ------------------------------------------------------------------------- !
956    case ('z')
957       ! ------------------------------------------------------------------------- !
958       ! Calculate saturation fraction based on whether the air just above or just !
959       ! below the interface is saturated, i.e. with vertical cloud partitioning.  !
960       ! The saturation fraction of the interfacial layer between mid-points k and !
961       ! k+1 is computed by averaging the saturation fraction   of the half-layers !
962       ! above and below the interface,  with a special provision   for cloud tops !
963       ! (more cloud in the half-layer below than in the half-layer above).In each !
964       ! half-layer, vertical partitioning of  cloud based on the slopes diagnosed !
965       ! above is used.     Loop down through the layers, computing the saturation !
966       ! fraction in each half-layer (sfuh for upper half, sflh for lower half).   !
967       ! Once sfuh(i,k) is computed, use with sflh(i,k-1) to determine  saturation !
968       ! fraction sfi(i,k) for interfacial layer k-0.5.                            !
969       ! This is 'not' chosen for full consistent treatment of stratus fraction in !
970       ! all physics schemes.                                                      !
971       ! ------------------------------------------------------------------------- !
972       do k = ntop_turb + 1, nbot_turb
973          km1 = k - 1
974          do i = 1, ncol
975           ! Compute saturation excess at the mid-point of layer k
976             sltop    = sl(i,k) + slslope(i,k) * ( pi(i,k) - pm(i,k) )     
977             qttop    = qt(i,k) + qtslope(i,k) * ( pi(i,k) - pm(i,k) )
978             tltop(1) = ( sltop - g * zi(i,k) ) / cpair
979             status   = qsat( tltop(1), pi(i,k), es(1), qs(1), gam(1), 1 )
980             qxtop    = qttop - qs(1)
981             slbot    = sl(i,k) + slslope(i,k) * ( pi(i,k+1) - pm(i,k) )     
982             qtbot    = qt(i,k) + qtslope(i,k) * ( pi(i,k+1) - pm(i,k) )
983             tlbot(1) = ( slbot - g * zi(i,k+1) ) / cpair
984             status   = qsat( tlbot(1), pi(i,k+1), es(1), qs(1), gam(1), 1 )
985             qxbot    = qtbot - qs(1)
986             qxm      = qxtop + ( qxbot - qxtop ) * ( pm(i,k) - pi(i,k) ) / ( pi(i,k+1) - pi(i,k) )
987           ! Find the saturation fraction sfuh(i,k) of the upper half of layer k.
988             if( ( qxtop .lt. 0._r8 ) .and. ( qxm .lt. 0._r8 ) ) then
989                   sfuh(i,k) = 0._r8
990             else if( ( qxtop .gt. 0._r8 ) .and. ( qxm .gt. 0._r8 ) ) then
991                   sfuh(i,k) = 1._r8 
992             else ! Either qxm < 0 and qxtop > 0 or vice versa
993                   sfuh(i,k) = max( qxtop, qxm ) / abs( qxtop - qxm )
994             end if
995           ! Combine with sflh(i) (still for layer k-1) to get interfac layer saturation fraction
996             sfi(i,k) = 0.5_r8 * ( sflh(i,k-1) + min( sflh(i,k-1), sfuh(i,k) ) )
997           ! Update sflh to be for the lower half of layer k.             
998             if( ( qxbot .lt. 0._r8 ) .and. ( qxm .lt. 0._r8 ) ) then
999                   sflh(i,k) = 0._r8
1000             else if( ( qxbot .gt. 0._r8 ) .and. ( qxm .gt. 0._r8 ) ) then
1001                   sflh(i,k) = 1._r8
1002             else ! Either qxm < 0 and qxbot > 0 or vice versa
1003                   sflh(i,k) = max( qxbot, qxm ) / abs( qxbot - qxm )
1004             end if
1005          end do  ! i
1006       end do ! k
1007       do i = 1, ncol
1008          sfi(i,pver+1) = sflh(i,pver)  ! Saturation fraction in the lowest half-layer.
1009       end do
1010    end select
1011
1012  return
1013  end subroutine sfdiag
1014 
1015  !=============================================================================== !
1016  !                                                                                !
1017  !=============================================================================== !
1018 
1019  subroutine trbintd( pcols   , pver    , ncol    ,                               &
1020                      z       , u       , v       ,                               &
1021                      t       , pmid    , taux    ,                               &
1022                      tauy    , ustar   , rrho    ,                               &
1023                      s2      , n2      , ri      ,                               &
1024                      zi      , pi      , cld     ,                               &
1025                      qt      , qv      , ql      , qi      , sfi     , sfuh    , &
1026                      sflh    , sl      , slv     , slslope , qtslope ,           &
1027                      chs     , chu     , cms     , cmu     , minpblh , qsat )
1028    !----------------------------------------------------------------------- !
1029    ! Purpose: Calculate buoyancy coefficients at all interfaces including   !
1030    !          surface. Also, computes the profiles of ( sl,qt,n2,s2,ri ).   !
1031    !          Note that (n2,s2,ri) are defined at each interfaces except    !
1032    !          surface.                                                      !
1033    !                                                                        !
1034    ! Author: B. Stevens  ( Extracted from pbldiff, August, 2000 )           !
1035    !         Sungsu Park ( August 2006, May. 2008 )                         !
1036    !----------------------------------------------------------------------- !
1037
1038    implicit none
1039
1040    ! --------------- !
1041    ! Input arguments !
1042    ! --------------- !
1043
1044    integer,  intent(in)  :: pcols                            ! Number of atmospheric columns   
1045    integer,  intent(in)  :: pver                             ! Number of atmospheric layers   
1046    integer,  intent(in)  :: ncol                             ! Number of atmospheric columns
1047    real(r8), intent(in)  :: z(pcols,pver)                    ! Layer mid-point height above surface [ m ]
1048    real(r8), intent(in)  :: u(pcols,pver)                    ! Layer mid-point u [ m/s ]
1049    real(r8), intent(in)  :: v(pcols,pver)                    ! Layer mid-point v [ m/s ]
1050    real(r8), intent(in)  :: t(pcols,pver)                    ! Layer mid-point temperature [ K ]
1051    real(r8), intent(in)  :: pmid(pcols,pver)                 ! Layer mid-point pressure [ Pa ]
1052    real(r8), intent(in)  :: taux(pcols)                      ! Surface u stress [ N/m2 ]
1053    real(r8), intent(in)  :: tauy(pcols)                      ! Surface v stress [ N/m2 ]
1054    real(r8), intent(in)  :: zi(pcols,pver+1)                 ! Interface height [ m ]
1055    real(r8), intent(in)  :: pi(pcols,pver+1)                 ! Interface pressure [ Pa ]
1056    real(r8), intent(in)  :: cld(pcols,pver)                  ! Stratus fraction
1057    real(r8), intent(in)  :: qv(pcols,pver)                   ! Water vapor specific humidity [ kg/kg ]
1058    real(r8), intent(in)  :: ql(pcols,pver)                   ! Liquid water specific humidity [ kg/kg ]
1059    real(r8), intent(in)  :: qi(pcols,pver)                   ! Ice water specific humidity [ kg/kg ]
1060    integer,  external    :: qsat
1061
1062    ! ---------------- !
1063    ! Output arguments !
1064    ! ---------------- !
1065
1066    real(r8), intent(out) :: ustar(pcols)                     ! Surface friction velocity [ m/s ]
1067    real(r8), intent(out) :: s2(pcols,pver)                   ! Interfacial ( except surface ) shear squared [ s-2 ]
1068    real(r8), intent(out) :: n2(pcols,pver)                   ! Interfacial ( except surface ) buoyancy frequency [ s-2 ]
1069    real(r8), intent(out) :: ri(pcols,pver)                   ! Interfacial ( except surface ) Richardson number, 'n2/s2'
1070 
1071    real(r8), intent(out) :: qt(pcols,pver)                   ! Total specific humidity [ kg/kg ]
1072    real(r8), intent(out) :: sfi(pcols,pver+1)                ! Interfacial layer saturation fraction [ fraction ]
1073    real(r8), intent(out) :: sfuh(pcols,pver)                 ! Saturation fraction in upper half-layer [ fraction ]
1074    real(r8), intent(out) :: sflh(pcols,pver)                 ! Saturation fraction in lower half-layer [ fraction ]
1075    real(r8), intent(out) :: sl(pcols,pver)                   ! Liquid water static energy [ J/kg ]
1076    real(r8), intent(out) :: slv(pcols,pver)                  ! Liquid water virtual static energy [ J/kg ]
1077   
1078    real(r8), intent(out) :: chu(pcols,pver+1)                ! Heat buoyancy coef for dry states at all interfaces, finally. [ unit ? ]
1079    real(r8), intent(out) :: chs(pcols,pver+1)                ! heat buoyancy coef for sat states at all interfaces, finally. [ unit ? ]
1080    real(r8), intent(out) :: cmu(pcols,pver+1)                ! Moisture buoyancy coef for dry states at all interfaces, finally. [ unit ? ]
1081    real(r8), intent(out) :: cms(pcols,pver+1)                ! Moisture buoyancy coef for sat states at all interfaces, finally. [ unit ? ]
1082    real(r8), intent(out) :: slslope(pcols,pver)              ! Slope of 'sl' in each layer
1083    real(r8), intent(out) :: qtslope(pcols,pver)              ! Slope of 'qt' in each layer
1084    real(r8), intent(out) :: rrho(pcols)                      ! 1./bottom level density [ m3/kg ]
1085    real(r8), intent(out) :: minpblh(pcols)                   ! Minimum PBL height based on surface stress [ m ]
1086 
1087    ! --------------- !
1088    ! Local Variables !
1089    ! --------------- !
1090
1091    integer               :: i                                ! Longitude index
1092    integer               :: k, km1                           ! Level index
1093    integer               :: status                           ! Status returned by function calls
1094
1095    real(r8)              :: qs(pcols,pver)                   ! Saturation specific humidity
1096    real(r8)              :: es(pcols,pver)                   ! Saturation vapor pressure
1097    real(r8)              :: gam(pcols,pver)                  ! (l/cp)*(d(qs)/dT)
1098    real(r8)              :: rdz                              ! 1 / (delta z) between midpoints
1099    real(r8)              :: dsldz                            ! 'delta sl / delta z' at interface
1100    real(r8)              :: dqtdz                            ! 'delta qt / delta z' at interface
1101    real(r8)              :: ch                               ! 'sfi' weighted ch at the interface
1102    real(r8)              :: cm                               ! 'sfi' weighted cm at the interface
1103    real(r8)              :: bfact                            ! Buoyancy factor in n2 calculations
1104    real(r8)              :: product                          ! Intermediate vars used to find slopes
1105    real(r8)              :: dsldp_a, dqtdp_a                 ! Slopes across interface above
1106    real(r8)              :: dsldp_b(pcols), dqtdp_b(pcols)   ! Slopes across interface below
1107
1108    ! ----------------------- !
1109    ! Main Computation Begins !
1110    ! ----------------------- !
1111
1112    ! Compute ustar, and kinematic surface fluxes from surface energy fluxes
1113
1114    do i = 1, ncol
1115       rrho(i)    = rair * t(i,pver) / pmid(i,pver)
1116       ustar(i)   = max( sqrt( sqrt( taux(i)**2 + tauy(i)**2 ) * rrho(i) ), ustar_min )
1117       minpblh(i) = 100.0_r8 * ustar(i)                       ! By construction, 'minpblh' is larger than 1 [m] when 'ustar_min = 0.01'.
1118    end do
1119
1120    ! Calculate conservative scalars (qt,sl,slv) and buoyancy coefficients at the layer mid-points.
1121    ! Note that 'ntop_turb = 1', 'nbot_turb = pver'
1122
1123    do k = ntop_turb, nbot_turb
1124       status = qsat( t(1,k), pmid(1,k), es(1,k), qs(1,k), gam(1,k), ncol )
1125       do i = 1, ncol
1126          qt(i,k)  = qv(i,k) + ql(i,k) + qi(i,k)
1127          sl(i,k)  = cpair * t(i,k) + g * z(i,k) - latvap * ql(i,k) - latsub * qi(i,k)
1128          slv(i,k) = sl(i,k) * ( 1._r8 + zvir * qt(i,k) )
1129        ! Thermodynamic coefficients for buoyancy flux - in this loop these are
1130        ! calculated at mid-points; later,  they will be averaged to interfaces,
1131        ! where they will ultimately be used.  At the surface, the coefficients
1132        ! are taken from the lowest mid point.
1133          bfact    = g / ( t(i,k) * ( 1._r8 + zvir * qv(i,k) - ql(i,k) - qi(i,k) ) )
1134          chu(i,k) = ( 1._r8 + zvir * qt(i,k) ) * bfact / cpair
1135          chs(i,k) = ( ( 1._r8 + ( 1._r8 + zvir ) * gam(i,k) * cpair * t(i,k) / latvap ) / ( 1._r8 + gam(i,k) ) ) * bfact / cpair
1136          cmu(i,k) = zvir * bfact * t(i,k)
1137          cms(i,k) = latvap * chs(i,k)  -  bfact * t(i,k)
1138       end do
1139    end do
1140
1141    do i = 1, ncol
1142       chu(i,pver+1) = chu(i,pver)
1143       chs(i,pver+1) = chs(i,pver)
1144       cmu(i,pver+1) = cmu(i,pver)
1145       cms(i,pver+1) = cms(i,pver)
1146    end do
1147
1148    ! Compute slopes of conserved variables sl, qt within each layer k.
1149    ! 'a' indicates the 'above' gradient from layer k-1 to layer k and
1150    ! 'b' indicates the 'below' gradient from layer k   to layer k+1.
1151    ! We take a smaller (in absolute value)  of these gradients as the
1152    ! slope within layer k. If they have opposite signs,   gradient in
1153    ! layer k is taken to be zero. I should re-consider whether   this
1154    ! profile reconstruction is the best or not.
1155    ! This is similar to the profile reconstruction used in the UWShCu.
1156
1157    do i = 1, ncol
1158     ! Slopes at endpoints determined by extrapolation
1159       slslope(i,pver) = ( sl(i,pver) - sl(i,pver-1) ) / ( pmid(i,pver) - pmid(i,pver-1) )
1160       qtslope(i,pver) = ( qt(i,pver) - qt(i,pver-1) ) / ( pmid(i,pver) - pmid(i,pver-1) )
1161       slslope(i,1)    = ( sl(i,2) - sl(i,1) ) / ( pmid(i,2) - pmid(i,1) )
1162       qtslope(i,1)    = ( qt(i,2) - qt(i,1) ) / ( pmid(i,2) - pmid(i,1) )
1163       dsldp_b(i)      = slslope(i,1)
1164       dqtdp_b(i)      = qtslope(i,1)
1165    end do
1166
1167    do k = 2, pver - 1
1168       do i = 1, ncol
1169          dsldp_a    = dsldp_b(i)
1170          dqtdp_a    = dqtdp_b(i)
1171          dsldp_b(i) = ( sl(i,k+1) - sl(i,k) ) / ( pmid(i,k+1) - pmid(i,k) )
1172          dqtdp_b(i) = ( qt(i,k+1) - qt(i,k) ) / ( pmid(i,k+1) - pmid(i,k) )
1173          product    = dsldp_a * dsldp_b(i)
1174          if( product .le. 0._r8 ) then
1175              slslope(i,k) = 0._r8
1176          else if( product .gt. 0._r8 .and. dsldp_a .lt. 0._r8 ) then
1177              slslope(i,k) = max( dsldp_a, dsldp_b(i) )
1178          else if( product .gt. 0._r8 .and. dsldp_a .gt. 0._r8 ) then
1179              slslope(i,k) = min( dsldp_a, dsldp_b(i) )
1180          end if
1181          product = dqtdp_a*dqtdp_b(i)
1182          if( product .le. 0._r8 ) then
1183              qtslope(i,k) = 0._r8
1184          else if( product .gt. 0._r8 .and. dqtdp_a .lt. 0._r8 ) then
1185              qtslope(i,k) = max( dqtdp_a, dqtdp_b(i) )
1186          else if( product .gt. 0._r8 .and. dqtdp_a .gt. 0._r8 ) then
1187              qtslope(i,k) = min( dqtdp_a, dqtdp_b(i) )
1188          end if
1189       end do ! i
1190    end do ! k
1191
1192    !  Compute saturation fraction at the interfacial layers for use in buoyancy
1193    !  flux computation.
1194
1195    call sfdiag( pcols  , pver    , ncol    , qt      , ql      , sl      , &
1196                 pi     , pmid    , zi      , cld     , sfi     , sfuh    , &
1197                 sflh   , slslope , qtslope , qsat )
1198
1199    ! Calculate buoyancy coefficients at all interfaces (1:pver+1) and (n2,s2,ri)
1200    ! at all interfaces except surface. Note 'nbot_turb = pver', 'ntop_turb = 1'.
1201    ! With the previous definition of buoyancy coefficients at the surface, the
1202    ! resulting buoyancy coefficients at the top and surface interfaces becomes
1203    ! identical to the buoyancy coefficients at the top and bottom layers. Note
1204    ! that even though the dimension of (s2,n2,ri) is 'pver',  they are defined
1205    ! at interfaces ( not at the layer mid-points ) except the surface.
1206
1207    do k = nbot_turb, ntop_turb + 1, -1
1208       km1 = k - 1
1209       do i = 1, ncol
1210          rdz      = 1._r8 / ( z(i,km1) - z(i,k) )
1211          dsldz    = ( sl(i,km1) - sl(i,k) ) * rdz
1212          dqtdz    = ( qt(i,km1) - qt(i,k) ) * rdz
1213          chu(i,k) = ( chu(i,km1) + chu(i,k) ) * 0.5_r8
1214          chs(i,k) = ( chs(i,km1) + chs(i,k) ) * 0.5_r8
1215          cmu(i,k) = ( cmu(i,km1) + cmu(i,k) ) * 0.5_r8
1216          cms(i,k) = ( cms(i,km1) + cms(i,k) ) * 0.5_r8
1217          ch       = chu(i,k) * ( 1._r8 - sfi(i,k) ) + chs(i,k) * sfi(i,k)
1218          cm       = cmu(i,k) * ( 1._r8 - sfi(i,k) ) + cms(i,k) * sfi(i,k)
1219          n2(i,k)  = ch * dsldz +  cm * dqtdz
1220          s2(i,k)  = ( ( u(i,km1) - u(i,k) )**2 + ( v(i,km1) - v(i,k) )**2) * rdz**2
1221          s2(i,k)  = max( ntzero, s2(i,k) )
1222          ri(i,k)  = n2(i,k) / s2(i,k)
1223       end do
1224    end do
1225    do i = 1, ncol
1226       n2(i,1) = n2(i,2)
1227       s2(i,1) = s2(i,2)
1228       ri(i,1) = ri(i,2)
1229    end do
1230
1231  return
1232
1233  end subroutine trbintd
1234
1235  !=============================================================================== !
1236  !                                                                                !
1237  !=============================================================================== !
1238 
1239  subroutine austausch_atm( pcols, pver, ncol, ri, s2, kvf )
1240
1241    !---------------------------------------------------------------------- !
1242    !                                                                       !
1243    ! Purpose: Computes exchange coefficients for free turbulent flows.     !
1244    !          This is not used in the UW moist turbulence scheme.          !
1245    !                                                                       !
1246    ! Method:                                                               !
1247    !                                                                       !
1248    ! The free atmosphere diffusivities are based on standard mixing length !
1249    ! forms for the neutral diffusivity multiplied by functns of Richardson !
1250    ! number. K = l^2 * |dV/dz| * f(Ri). The same functions are used for    !
1251    ! momentum, potential temperature, and constitutents.                   !
1252    !                                                                       !
1253    ! The stable Richardson num function (Ri>0) is taken from Holtslag and  !
1254    ! Beljaars (1989), ECMWF proceedings. f = 1 / (1 + 10*Ri*(1 + 8*Ri))    !
1255    ! The unstable Richardson number function (Ri<0) is taken from  CCM1.   !
1256    ! f = sqrt(1 - 18*Ri)                                                   !
1257    !                                                                       !
1258    ! Author: B. Stevens (rewrite, August 2000)                             !
1259    !                                                                       !
1260    !---------------------------------------------------------------------- !
1261    implicit none
1262   
1263    ! --------------- !
1264    ! Input arguments !
1265    ! --------------- !
1266
1267    integer,  intent(in)  :: pcols                ! Number of atmospheric columns   
1268    integer,  intent(in)  :: pver                 ! Number of atmospheric layers   
1269    integer,  intent(in)  :: ncol                 ! Number of atmospheric columns
1270
1271    real(r8), intent(in)  :: s2(pcols,pver)       ! Shear squared
1272    real(r8), intent(in)  :: ri(pcols,pver)       ! Richardson no
1273
1274    ! ---------------- !
1275    ! Output arguments !
1276    ! ---------------- !
1277
1278    real(r8), intent(out) :: kvf(pcols,pver+1)    ! Eddy diffusivity for heat and tracers
1279
1280    ! --------------- !
1281    ! Local Variables !
1282    ! --------------- !
1283
1284    real(r8)              :: fofri                ! f(ri)
1285    real(r8)              :: kvn                  ! Neutral Kv
1286
1287    integer               :: i                    ! Longitude index
1288    integer               :: k                    ! Vertical index
1289
1290    ! ----------------------- !
1291    ! Main Computation Begins !
1292    ! ----------------------- !
1293
1294    kvf(:ncol,:)           = 0.0_r8
1295    kvf(:ncol,pver+1)      = 0.0_r8
1296    kvf(:ncol,1:ntop_turb) = 0.0_r8
1297
1298    ! Compute the free atmosphere vertical diffusion coefficients: kvh = kvq = kvm.
1299
1300    do k = ntop_turb + 1, nbot_turb
1301       do i = 1, ncol
1302          if( ri(i,k) < 0.0_r8 ) then
1303              fofri = sqrt( max( 1._r8 - 18._r8 * ri(i,k), 0._r8 ) )
1304          else
1305              fofri = 1.0_r8 / ( 1.0_r8 + 10.0_r8 * ri(i,k) * ( 1.0_r8 + 8.0_r8 * ri(i,k) ) )   
1306          end if
1307          kvn = ml2(k) * sqrt(s2(i,k))
1308          kvf(i,k) = max( zkmin, kvn * fofri )
1309       end do
1310    end do
1311
1312    return
1313
1314    end subroutine austausch_atm
1315
1316    ! ---------------------------------------------------------------------------- !
1317    !                                                                              !
1318    ! The University of Washington Moist Turbulence Scheme                         !
1319    !                                                                              !
1320    ! Authors : Chris Bretherton at the University of Washington, Seattle, WA      !
1321    !           Sungsu Park at the CGD/NCAR, Boulder, CO                           !
1322    !                                                                              !
1323    ! ---------------------------------------------------------------------------- !
1324
1325    subroutine caleddy( pcols        , pver         , ncol        ,                             &
1326                        sl           , qt           , ql          , slv        , u            , &
1327                        v            , pi           , z           , zi         ,                &
1328                        qflx         , shflx        , slslope     , qtslope    ,                &
1329                        chu          , chs          , cmu         , cms        , sfuh         , &
1330                        sflh         , n2           , s2          , ri         , rrho         , &
1331                        pblh         , ustar        ,                                           &
1332                        kvh_in       , kvm_in       , kvh         , kvm        ,                &
1333                        tpert        , qpert        , qrlin       , kvf        , tke          , &
1334                        wstarent     , bprod        , sprod       , minpblh    , wpert        , &
1335                        tkes         , turbtype_f   , sm_aw       ,                             &
1336                        kbase_o      , ktop_o       , ncvfin_o    ,                             &
1337                        kbase_mg     , ktop_mg      , ncvfin_mg   ,                             &
1338                        kbase_f      , ktop_f       , ncvfin_f    ,                             &
1339                        wet_CL       , web_CL       , jtbu_CL     , jbbu_CL    ,                &
1340                        evhc_CL      , jt2slv_CL    , n2ht_CL     , n2hb_CL    , lwp_CL       , &
1341                        opt_depth_CL , radinvfrac_CL, radf_CL     , wstar_CL   , wstar3fact_CL, &
1342                        ebrk         , wbrk         , lbrk        , ricl       , ghcl         , &
1343                        shcl         , smcl         ,                                           &
1344                        gh_a         , sh_a         , sm_a        , ri_a       , leng         , &
1345                        wcap         , pblhp        , cld         , ipbl       , kpblh        , &
1346                        wsedl        )
1347
1348    !--------------------------------------------------------------------------------- !
1349    !                                                                                  !
1350    ! Purpose : This is a driver routine to compute eddy diffusion coefficients        !
1351    !           for heat (sl), momentum (u, v), moisture (qt), and other  trace        !
1352    !           constituents.   This scheme uses first order closure for stable        !
1353    !           turbulent layers (STL). For convective layers (CL), entrainment        !
1354    !           closure is used at the CL external interfaces, which is coupled        !
1355    !           to the diagnosis of a CL regime mean TKE from the instantaneous        !
1356    !           thermodynamic and velocity profiles.   The CLs are diagnosed by        !
1357    !           extending original CL layers of moist static instability   into        !
1358    !           adjacent weakly stably stratified interfaces,   stopping if the        !
1359    !           stability is too strong.   This allows a realistic depiction of        !
1360    !           dry convective boundary layers with a downgradient approach.           !
1361    !                                                                                  !   
1362    ! NOTE:     This routine currently assumes ntop_turb = 1, nbot_turb = pver         !
1363    !           ( turbulent diffusivities computed at all interior interfaces )        !
1364    !           and will require modification to handle a different ntop_turb.         !
1365    !                                                                                  !
1366    ! Authors:  Sungsu Park and Chris Bretherton. 08/2006, 05/2008.                    !
1367    !                                                                                  !
1368    ! For details, see                                                                 !
1369    !                                                                                  !
1370    ! 1. 'A new moist turbulence parametrization in the Community Atmosphere Model'    !
1371    !     by Christopher S. Bretherton & Sungsu Park. J. Climate. 22. 3422-3448. 2009. !
1372    !                                                                                  !
1373    ! 2. 'The University of Washington shallow convection and moist turbulence schemes !
1374    !     and their impact on climate simulations with the Community Atmosphere Model' !
1375    !     by Sungsu Park & Christopher S. Bretherton. J. Climate. 22. 3449-3469. 2009. !
1376    !                                                                                  !
1377    ! For questions on the scheme and code, send an email to                           !
1378    !     sungsup@ucar.edu or breth@washington.edu                                     !
1379    !                                                                                  !
1380    !--------------------------------------------------------------------------------- !
1381
1382    ! ---------------- !
1383    ! Inputs variables !
1384    ! ---------------- !
1385
1386    implicit none
1387
1388    integer,  intent(in) :: pcols                     ! Number of atmospheric columns   
1389    integer,  intent(in) :: pver                      ! Number of atmospheric layers   
1390    integer,  intent(in) :: ncol                      ! Number of atmospheric columns   
1391    real(r8), intent(in) :: u(pcols,pver)             ! U wind [ m/s ]
1392    real(r8), intent(in) :: v(pcols,pver)             ! V wind [ m/s ]
1393    real(r8), intent(in) :: sl(pcols,pver)            ! Liquid water static energy, cp * T + g * z - Lv * ql - Ls * qi [ J/kg ]
1394    real(r8), intent(in) :: slv(pcols,pver)           ! Liquid water virtual static energy, sl * ( 1 + 0.608 * qt ) [ J/kg ]
1395    real(r8), intent(in) :: qt(pcols,pver)            ! Total speccific humidity  qv + ql + qi [ kg/kg ]
1396    real(r8), intent(in) :: ql(pcols,pver)            ! Liquid water specific humidity [ kg/kg ]
1397    real(r8), intent(in) :: pi(pcols,pver+1)          ! Interface pressures [ Pa ]
1398    real(r8), intent(in) :: z(pcols,pver)             ! Layer midpoint height above surface [ m ]
1399    real(r8), intent(in) :: zi(pcols,pver+1)          ! Interface height above surface, i.e., zi(pver+1) = 0 all over the globe [ m ]
1400    real(r8), intent(in) :: chu(pcols,pver+1)         ! Buoyancy coeffi. unsaturated sl (heat) coef. at all interfaces. [ unit ? ]
1401    real(r8), intent(in) :: chs(pcols,pver+1)         ! Buoyancy coeffi. saturated sl (heat) coef. at all interfaces. [ unit ? ]
1402    real(r8), intent(in) :: cmu(pcols,pver+1)         ! Buoyancy coeffi. unsaturated qt (moisture) coef. at all interfaces [ unit ? ]
1403    real(r8), intent(in) :: cms(pcols,pver+1)         ! Buoyancy coeffi. saturated qt (moisture) coef. at all interfaces [ unit ? ]
1404    real(r8), intent(in) :: sfuh(pcols,pver)          ! Saturation fraction in upper half-layer [ fraction ]
1405    real(r8), intent(in) :: sflh(pcols,pver)          ! Saturation fraction in lower half-layer [ fraction ]
1406    real(r8), intent(in) :: n2(pcols,pver)            ! Interfacial (except surface) moist buoyancy frequency [ s-2 ]
1407    real(r8), intent(in) :: s2(pcols,pver)            ! Interfacial (except surface) shear frequency [ s-2 ]
1408    real(r8), intent(in) :: ri(pcols,pver)            ! Interfacial (except surface) Richardson number
1409    real(r8), intent(in) :: qflx(pcols)               ! Kinematic surface constituent ( water vapor ) flux [ kg/m2/s ]
1410    real(r8), intent(in) :: shflx(pcols)              ! Kinematic surface heat flux [ unit ? ]
1411    real(r8), intent(in) :: slslope(pcols,pver)       ! Slope of 'sl' in each layer [ J/kg/Pa ]
1412    real(r8), intent(in) :: qtslope(pcols,pver)       ! Slope of 'qt' in each layer [ kg/kg/Pa ]
1413    real(r8), intent(in) :: qrlin(pcols,pver)         ! Input grid-mean LW heating rate : [ K/s ] * cpair * dp = [ W/kg*Pa ]
1414    real(r8), intent(in) :: wsedl(pcols,pver)         ! Sedimentation velocity of liquid stratus cloud droplet [ m/s ]
1415    real(r8), intent(in) :: ustar(pcols)              ! Surface friction velocity [ m/s ]
1416    real(r8), intent(in) :: rrho(pcols)               ! 1./bottom mid-point density. Specific volume [ m3/kg ]
1417    real(r8), intent(in) :: kvf(pcols,pver+1)         ! Free atmosphere eddy diffusivity [ m2/s ]
1418    logical,  intent(in) :: wstarent                  ! Switch for choosing wstar3 entrainment parameterization
1419    real(r8), intent(in) :: minpblh(pcols)            ! Minimum PBL height based on surface stress [ m ]
1420    real(r8), intent(in) :: kvh_in(pcols,pver+1)      ! kvh saved from last timestep or last iterative step [ m2/s ]
1421    real(r8), intent(in) :: kvm_in(pcols,pver+1)      ! kvm saved from last timestep or last iterative step [ m2/s ]
1422    real(r8), intent(in) :: cld(pcols,pver)           ! Stratus Cloud Fraction [ fraction ]
1423
1424    ! ---------------- !
1425    ! Output variables !
1426    ! ---------------- !
1427
1428    real(r8), intent(out) :: kvh(pcols,pver+1)        ! Eddy diffusivity for heat, moisture, and tracers [ m2/s ]
1429    real(r8), intent(out) :: kvm(pcols,pver+1)        ! Eddy diffusivity for momentum [ m2/s ]
1430    real(r8), intent(out) :: pblh(pcols)              ! PBL top height [ m ]
1431    real(r8), intent(out) :: pblhp(pcols)             ! PBL top height pressure [ Pa ]
1432    real(r8), intent(out) :: tpert(pcols)             ! Convective temperature excess [ K ]
1433    real(r8), intent(out) :: qpert(pcols)             ! Convective humidity excess [ kg/kg ]
1434    real(r8), intent(out) :: wpert(pcols)             ! Turbulent velocity excess [ m/s ]
1435    real(r8), intent(out) :: tke(pcols,pver+1)        ! Turbulent kinetic energy [ m2/s2 ], 'tkes' at surface, pver+1.
1436    real(r8), intent(out) :: bprod(pcols,pver+1)      ! Buoyancy production [ m2/s3 ],     'bflxs' at surface, pver+1.
1437    real(r8), intent(out) :: sprod(pcols,pver+1)      ! Shear production [ m2/s3 ], (ustar(i)**3)/(vk*z(i,pver))  at surface, pver+1.
1438    real(r8), intent(out) :: turbtype_f(pcols,pver+1) ! Turbulence type at each interface:
1439                                                      ! 0. = Non turbulence interface
1440                                                      ! 1. = Stable turbulence interface
1441                                                      ! 2. = CL interior interface ( if bflxs > 0, surface is this )
1442                                                      ! 3. = Bottom external interface of CL
1443                                                      ! 4. = Top external interface of CL.
1444                                                      ! 5. = Double entraining CL external interface
1445    real(r8), intent(out) :: sm_aw(pcols,pver+1)      ! Galperin instability function of momentum for use in the microphysics [ no unit ]
1446    real(r8), intent(out) :: ipbl(pcols)              ! If 1, PBL is CL, while if 0, PBL is STL.
1447    real(r8), intent(out) :: kpblh(pcols)             ! Layer index containing PBL within or at the base interface
1448
1449    ! --------------------------- !
1450    ! Diagnostic output variables !
1451    ! --------------------------- !
1452
1453    real(r8) :: tkes(pcols)                           ! TKE at surface [ m2/s2 ]
1454    real(r8) :: kbase_o(pcols,ncvmax)                 ! Original external base interface index of CL just after 'exacol'
1455    real(r8) :: ktop_o(pcols,ncvmax)                  ! Original external top  interface index of CL just after 'exacol'
1456    real(r8) :: ncvfin_o(pcols)                       ! Original number of CLs just after 'exacol'
1457    real(r8) :: kbase_mg(pcols,ncvmax)                ! kbase  just after extending-merging (after 'zisocl') but without SRCL
1458    real(r8) :: ktop_mg(pcols,ncvmax)                 ! ktop   just after extending-merging (after 'zisocl') but without SRCL
1459    real(r8) :: ncvfin_mg(pcols)                      ! ncvfin just after extending-merging (after 'zisocl') but without SRCL
1460    real(r8) :: kbase_f(pcols,ncvmax)                 ! Final kbase  after adding SRCL
1461    real(r8) :: ktop_f(pcols,ncvmax)                  ! Final ktop   after adding SRCL
1462    real(r8) :: ncvfin_f(pcols)                       ! Final ncvfin after adding SRCL
1463    real(r8) :: wet_CL(pcols,ncvmax)                  ! Entrainment rate at the CL top [ m/s ]
1464    real(r8) :: web_CL(pcols,ncvmax)                  ! Entrainment rate at the CL base [ m/s ]
1465    real(r8) :: jtbu_CL(pcols,ncvmax)                 ! Buoyancy jump across the CL top [ m/s2 ] 
1466    real(r8) :: jbbu_CL(pcols,ncvmax)                 ! Buoyancy jump across the CL base [ m/s2 ] 
1467    real(r8) :: evhc_CL(pcols,ncvmax)                 ! Evaporative enhancement factor at the CL top
1468    real(r8) :: jt2slv_CL(pcols,ncvmax)               ! Jump of slv ( across two layers ) at CL top for use only in evhc [ J/kg ]
1469    real(r8) :: n2ht_CL(pcols,ncvmax)                 ! n2 defined at the CL top  interface but using sfuh(kt)   instead of sfi(kt) [ s-2 ]
1470    real(r8) :: n2hb_CL(pcols,ncvmax)                 ! n2 defined at the CL base interface but using sflh(kb-1) instead of sfi(kb) [ s-2 ]
1471    real(r8) :: lwp_CL(pcols,ncvmax)                  ! LWP in the CL top layer [ kg/m2 ]
1472    real(r8) :: opt_depth_CL(pcols,ncvmax)            ! Optical depth of the CL top layer
1473    real(r8) :: radinvfrac_CL(pcols,ncvmax)           ! Fraction of LW radiative cooling confined in the top portion of CL
1474    real(r8) :: radf_CL(pcols,ncvmax)                 ! Buoyancy production at the CL top due to radiative cooling [ m2/s3 ]
1475    real(r8) :: wstar_CL(pcols,ncvmax)                ! Convective velocity of CL including entrainment contribution finally [ m/s ]
1476    real(r8) :: wstar3fact_CL(pcols,ncvmax)           ! "wstar3fact" of CL. Entrainment enhancement of wstar3 (inverse)
1477
1478    real(r8) :: gh_a(pcols,pver+1)                    ! Half of normalized buoyancy production, -l2n2/2e. [ no unit ]
1479    real(r8) :: sh_a(pcols,pver+1)                    ! Galperin instability function of heat-moisture at all interfaces [ no unit ]
1480    real(r8) :: sm_a(pcols,pver+1)                    ! Galperin instability function of momentum      at all interfaces [ no unit ]
1481    real(r8) :: ri_a(pcols,pver+1)                    ! Interfacial Richardson number                  at all interfaces [ no unit ]
1482
1483    real(r8) :: ebrk(pcols,ncvmax)                    ! Net CL mean TKE [ m2/s2 ]
1484    real(r8) :: wbrk(pcols,ncvmax)                    ! Net CL mean normalized TKE [ m2/s2 ]
1485    real(r8) :: lbrk(pcols,ncvmax)                    ! Net energetic integral thickness of CL [ m ]
1486    real(r8) :: ricl(pcols,ncvmax)                    ! Mean Richardson number of CL ( l2n2/l2s2 )
1487    real(r8) :: ghcl(pcols,ncvmax)                    ! Half of normalized buoyancy production of CL                 
1488    real(r8) :: shcl(pcols,ncvmax)                    ! Instability function of heat and moisture of CL
1489    real(r8) :: smcl(pcols,ncvmax)                    ! Instability function of momentum of CL
1490
1491    real(r8) :: leng(pcols,pver+1)                    ! Turbulent length scale [ m ], 0 at the surface.
1492    real(r8) :: wcap(pcols,pver+1)                    ! Normalized TKE [m2/s2], 'tkes/b1' at the surface and 'tke/b1' at
1493                                                      ! the top/bottom entrainment interfaces of CL assuming no transport.
1494    ! ------------------------ !
1495    ! Local Internal Variables !
1496    ! ------------------------ !
1497
1498    logical :: belongcv(pcols,pver+1)                 ! True for interfaces in a CL (both interior and exterior are included)
1499    logical :: belongst(pcols,pver+1)                 ! True for stable turbulent layer interfaces (STL)
1500    logical :: in_CL                                  ! True if interfaces k,k+1 both in same CL.
1501    logical :: extend                                 ! True when CL is extended in zisocl
1502    logical :: extend_up                              ! True when CL is extended upward in zisocl
1503    logical :: extend_dn                              ! True when CL is extended downward in zisocl
1504
1505    integer :: i                                      ! Longitude index
1506    integer :: k                                      ! Vertical index
1507    integer :: ks                                     ! Vertical index
1508    integer :: ncvfin(pcols)                          ! Total number of CL in column
1509    integer :: ncvf                                   ! Total number of CL in column prior to adding SRCL
1510    integer :: ncv                                    ! Index of current CL
1511    integer :: ncvnew                                 ! Index of added SRCL appended after regular CLs from 'zisocl'
1512    integer :: ncvsurf                                ! If nonzero, CL index based on surface (usually 1, but can be > 1 when SRCL is based at sfc)
1513    integer :: kbase(pcols,ncvmax)                    ! Vertical index of CL base interface
1514    integer :: ktop(pcols,ncvmax)                     ! Vertical index of CL top interface
1515    integer :: kb, kt                                 ! kbase and ktop for current CL
1516    integer :: ktblw                                  ! ktop of the CL located at just below the current CL
1517    integer :: turbtype(pcols,pver+1)                 ! Interface turbulence type :
1518                                                      ! 0 = Non turbulence interface
1519                                                      ! 1 = Stable turbulence interface
1520                                                      ! 2 = CL interior interface ( if bflxs > 0, sfc is this )
1521                                                      ! 3 = Bottom external interface of CL
1522                                                      ! 4 = Top external interface of CL
1523                                                      ! 5 = Double entraining CL external interface
1524    integer  :: ktopbl(pcols)                         ! PBL top height or interface index
1525    real(r8) :: bflxs(pcols)                          ! Surface buoyancy flux [ m2/s3 ]
1526    real(r8) :: rcap                                  ! 'tke/ebrk' at all interfaces of CL. Set to 1 at the CL entrainment interfaces
1527    real(r8) :: jtzm                                  ! Interface layer thickness of CL top interface [ m ]
1528    real(r8) :: jtsl                                  ! Jump of s_l across CL top interface [ J/kg ]
1529    real(r8) :: jtqt                                  ! Jump of q_t across CL top interface [ kg/kg ]
1530    real(r8) :: jtbu                                  ! Jump of buoyancy across CL top interface [ m/s2 ]
1531    real(r8) :: jtu                                   ! Jump of u across CL top interface [ m/s ]
1532    real(r8) :: jtv                                   ! Jump of v across CL top interface [ m/s ]
1533    real(r8) :: jt2slv                                ! Jump of slv ( across two layers ) at CL top for use only in evhc [ J/kg ]
1534    real(r8) :: radf                                  ! Buoyancy production at the CL top due to radiative cooling [ m2/s3 ]
1535    real(r8) :: jbzm                                  ! Interface layer thickness of CL base interface [ m ]
1536    real(r8) :: jbsl                                  ! Jump of s_l across CL base interface [ J/kg ]
1537    real(r8) :: jbqt                                  ! Jump of q_t across CL top interface [ kg/kg ]
1538    real(r8) :: jbbu                                  ! Jump of buoyancy across CL base interface [ m/s2 ]
1539    real(r8) :: jbu                                   ! Jump of u across CL base interface [ m/s ]
1540    real(r8) :: jbv                                   ! Jump of v across CL base interface [ m/s ]
1541    real(r8) :: ch                                    ! Buoyancy coefficients defined at the CL top and base interfaces using CL internal
1542    real(r8) :: cm                                    ! sfuh(kt) and sflh(kb-1) instead of sfi(kt) and sfi(kb), respectively. These are
1543                                                      ! used for entrainment calculation at CL external interfaces and SRCL identification.
1544    real(r8) :: n2ht                                  ! n2 defined at the CL top  interface but using sfuh(kt)   instead of sfi(kt) [ s-2 ]
1545    real(r8) :: n2hb                                  ! n2 defined at the CL base interface but using sflh(kb-1) instead of sfi(kb) [ s-2 ]
1546    real(r8) :: n2htSRCL                              ! n2 defined at the upper-half layer of SRCL. This is used only for identifying SRCL.
1547                                                      ! n2htSRCL use SRCL internal slope sl and qt as well as sfuh(kt) instead of sfi(kt) [ s-2 ]
1548    real(r8) :: gh                                    ! Half of normalized buoyancy production ( -l2n2/2e ) [ no unit ]
1549    real(r8) :: sh                                    ! Galperin instability function for heat and moisture
1550    real(r8) :: sm                                    ! Galperin instability function for momentum
1551    real(r8) :: lbulk                                 ! Depth of turbulent layer, Master length scale (not energetic length)
1552    real(r8) :: dzht                                  ! Thickness of top    half-layer [ m ]
1553    real(r8) :: dzhb                                  ! Thickness of bottom half-layer [ m ]
1554    real(r8) :: rootp                                 ! Sqrt(net CL-mean TKE including entrainment contribution) [ m/s ]     
1555    real(r8) :: evhc                                  ! Evaporative enhancement factor: (1+E) with E = evap. cool. efficiency [ no unit ]
1556    real(r8) :: kentr                                 ! Effective entrainment diffusivity 'wet*dz', 'web*dz' [ m2/s ]
1557    real(r8) :: lwp                                   ! Liquid water path in the layer kt [ kg/m2 ]
1558    real(r8) :: opt_depth                             ! Optical depth of the layer kt [ no unit ]
1559    real(r8) :: radinvfrac                            ! Fraction of LW cooling in the layer kt concentrated at the CL top [ no unit ]
1560    real(r8) :: wet                                   ! CL top entrainment rate [ m/s ]
1561    real(r8) :: web                                   ! CL bot entrainment rate [ m/s ]. Set to zero if CL is based at surface.
1562    real(r8) :: vyt                                   ! n2ht/n2 at the CL top  interface
1563    real(r8) :: vyb                                   ! n2hb/n2 at the CL base interface
1564    real(r8) :: vut                                   ! Inverse Ri (=s2/n2) at the CL top  interface
1565    real(r8) :: vub                                   ! Inverse Ri (=s2/n2) at the CL base interface
1566    real(r8) :: fact                                  ! Factor relating TKE generation to entrainment [ no unit ]
1567    real(r8) :: trma                                  ! Intermediate variables used for solving quadratic ( for gh from ri )
1568    real(r8) :: trmb                                  ! and cubic equations ( for ebrk: the net CL mean TKE )
1569    real(r8) :: trmc                                  !
1570    real(r8) :: trmp                                  !
1571    real(r8) :: trmq                                  !
1572    real(r8) :: qq                                    !
1573    real(r8) :: det                                   !
1574    real(r8) :: gg                                    ! Intermediate variable used for calculating stability functions of
1575                                                      ! SRCL or SBCL based at the surface with bflxs > 0.
1576    real(r8) :: dzhb5                                 ! Half thickness of the bottom-most layer of current CL regime
1577    real(r8) :: dzht5                                 ! Half thickness of the top-most layer of adjacent CL regime just below current CL
1578    real(r8) :: qrlw(pcols,pver)                      ! Local grid-mean LW heating rate : [K/s] * cpair * dp = [ W/kg*Pa ]
1579
1580    real(r8) :: cldeff(pcols,pver)                    ! Effective stratus fraction
1581    real(r8) :: qleff                                 ! Used for computing evhc
1582    real(r8) :: tunlramp                              ! Ramping tunl
1583    real(r8) :: leng_imsi                             ! For Kv = max(Kv_STL, Kv_entrain)
1584    real(r8) :: tke_imsi                              !
1585    real(r8) :: kvh_imsi                              !
1586    real(r8) :: kvm_imsi                              !
1587    real(r8) :: alph4exs                              ! For extended stability function in the stable regime
1588    real(r8) :: ghmin                                 !   
1589
1590    real(r8) :: sedfact                               ! For 'sedimentation-entrainment feedback'
1591
1592    ! Local variables specific for 'wstar' entrainment closure
1593
1594    real(r8) :: cet                                   ! Proportionality coefficient between wet and wstar3
1595    real(r8) :: ceb                                   ! Proportionality coefficient between web and wstar3
1596    real(r8) :: wstar                                 ! Convective velocity for CL [ m/s ]
1597    real(r8) :: wstar3                                ! Cubed convective velocity for CL [ m3/s3 ]
1598    real(r8) :: wstar3fact                            ! 1/(relative change of wstar^3 by entrainment)
1599    real(r8) :: rmin                                  ! sqrt(p)
1600    real(r8) :: fmin                                  ! f(rmin), where f(r) = r^3 - 3*p*r - 2q
1601    real(r8) :: rcrit                                 ! ccrit*wstar
1602    real(r8) :: fcrit                                 ! f(rcrit)
1603    logical     noroot                                ! True if f(r) has no root r > rcrit
1604
1605    !-----------------------!
1606    ! Start of Main Program !
1607    !-----------------------!
1608   
1609    ! Option: Turn-off LW radiative-turbulence interaction in PBL scheme
1610    !         by setting qrlw = 0.  Logical parameter 'set_qrlzero'  was
1611    !         defined in the first part of 'eddy_diff.F90' module.
1612
1613    if( set_qrlzero ) then
1614        qrlw(:,:) = 0._r8
1615    else
1616        qrlw(:ncol,:pver) = qrlin(:ncol,:pver)
1617    endif
1618
1619    ! Define effective stratus fraction using the grid-mean ql.
1620    ! Modification : The contribution of ice should be carefully considered.
1621    !                This should be done in combination with the 'qrlw' and
1622    !                overlapping assumption of liquid and ice stratus.
1623
1624    do k = 1, pver
1625       do i = 1, ncol
1626          if( choice_evhc .eq. 'ramp' .or. choice_radf .eq. 'ramp' ) then
1627              cldeff(i,k) = cld(i,k) * min( ql(i,k) / qmin, 1._r8 )
1628          else
1629              cldeff(i,k) = cld(i,k)
1630          endif
1631       end do
1632    end do
1633
1634    ! For an extended stability function in the stable regime, re-define
1635    ! alph4exe and ghmin. This is for future work.
1636
1637    if( ricrit .eq. 0.19_r8 ) then
1638        alph4exs = alph4
1639        ghmin    = -3.5334_r8
1640    elseif( ricrit .gt. 0.19_r8 ) then
1641        alph4exs = -2._r8 * b1 * alph2 / ( alph3 - 2._r8 * b1 * alph5 ) / ricrit
1642        ghmin    = -1.e10_r8
1643    else
1644        write(iulog,*) 'Error : ricrit should be larger than 0.19 in UW PBL'       
1645        stop
1646    endif
1647
1648    !
1649    ! Initialization of Diagnostic Output
1650    !
1651
1652    do i = 1, ncol
1653       wet_CL(i,:ncvmax)        = 0._r8
1654       web_CL(i,:ncvmax)        = 0._r8
1655       jtbu_CL(i,:ncvmax)       = 0._r8
1656       jbbu_CL(i,:ncvmax)       = 0._r8
1657       evhc_CL(i,:ncvmax)       = 0._r8
1658       jt2slv_CL(i,:ncvmax)     = 0._r8
1659       n2ht_CL(i,:ncvmax)       = 0._r8
1660       n2hb_CL(i,:ncvmax)       = 0._r8                   
1661       lwp_CL(i,:ncvmax)        = 0._r8
1662       opt_depth_CL(i,:ncvmax)  = 0._r8
1663       radinvfrac_CL(i,:ncvmax) = 0._r8
1664       radf_CL(i,:ncvmax)       = 0._r8
1665       wstar_CL(i,:ncvmax)      = 0._r8         
1666       wstar3fact_CL(i,:ncvmax) = 0._r8
1667       ricl(i,:ncvmax)          = 0._r8
1668       ghcl(i,:ncvmax)          = 0._r8
1669       shcl(i,:ncvmax)          = 0._r8
1670       smcl(i,:ncvmax)          = 0._r8
1671       ebrk(i,:ncvmax)          = 0._r8
1672       wbrk(i,:ncvmax)          = 0._r8
1673       lbrk(i,:ncvmax)          = 0._r8
1674       gh_a(i,:pver+1)          = 0._r8
1675       sh_a(i,:pver+1)          = 0._r8
1676       sm_a(i,:pver+1)          = 0._r8
1677       ri_a(i,:pver+1)          = 0._r8
1678       sm_aw(i,:pver+1)         = 0._r8
1679       ipbl(i)                  = 0._r8
1680       kpblh(i)                 = real(pver,r8)
1681    end do 
1682
1683    ! kvh and kvm are stored over timesteps in 'vertical_diffusion.F90' and
1684    ! passed in as kvh_in and kvm_in.  However,  at the first timestep they
1685    ! need to be computed and these are done just before calling 'caleddy'.   
1686    ! kvm and kvh are also stored over iterative time step in the first part
1687    ! of 'eddy_diff.F90'
1688
1689    do k = 1, pver + 1
1690       do i = 1, ncol
1691        ! Initialize kvh and kvm to zero or kvf
1692          if( use_kvf ) then
1693              kvh(i,k) = kvf(i,k)
1694              kvm(i,k) = kvf(i,k)
1695          else
1696              kvh(i,k) = 0._r8
1697              kvm(i,k) = 0._r8
1698          end if
1699        ! Zero diagnostic quantities for the new diffusion step.
1700          wcap(i,k) = 0._r8
1701          leng(i,k) = 0._r8
1702          tke(i,k)  = 0._r8
1703          turbtype(i,k) = 0
1704       end do
1705    end do
1706
1707    ! Initialize 'bprod' [ m2/s3 ] and 'sprod' [ m2/s3 ] at all interfaces.
1708    ! Note this initialization is a hybrid initialization since 'n2' [s-2] and 's2' [s-2]
1709    ! are calculated from the given current initial profile, while 'kvh_in' [m2/s] and
1710    ! 'kvm_in' [m2/s] are from the previous iteration or previous time step.
1711    ! This initially guessed 'bprod' and 'sprod' will be updated at the end of this
1712    ! 'caleddy' subroutine for diagnostic output.
1713    ! This computation of 'brpod,sprod' below is necessary for wstar-based entrainment closure.
1714
1715    do k = 2, pver
1716       do i = 1, ncol
1717            bprod(i,k) = -kvh_in(i,k) * n2(i,k)
1718            sprod(i,k) =  kvm_in(i,k) * s2(i,k)
1719       end do
1720    end do
1721
1722    ! Set 'bprod' and 'sprod' at top and bottom interface.
1723    ! In calculating 'surface' (actually lowest half-layer) buoyancy flux,
1724    ! 'chu' at surface is defined to be the same as 'chu' at the mid-point
1725    ! of lowest model layer (pver) at the end of 'trbind'. The same is for
1726    ! the other buoyancy coefficients.  'sprod(i,pver+1)'  is defined in a
1727    ! consistent way as the definition of 'tkes' in the original code.
1728    ! ( Important Option ) If I want to isolate surface buoyancy flux from
1729    ! the other parts of CL regimes energetically even though bflxs > 0,
1730    ! all I should do is to re-define 'bprod(i,pver+1)=0' in the below 'do'
1731    ! block. Additionally for merging test of extending SBCL based on 'l2n2'
1732    ! in 'zisocl', I should use 'l2n2 = - wint / sh'  for similar treatment
1733    ! as previous code. All other parts of the code  are fully consistently
1734    ! treated by these change only.
1735    ! My future general convection scheme will use bflxs(i).
1736
1737    do i = 1, ncol
1738       bprod(i,1) = 0._r8 ! Top interface
1739       sprod(i,1) = 0._r8 ! Top interface
1740       ch = chu(i,pver+1) * ( 1._r8 - sflh(i,pver) ) + chs(i,pver+1) * sflh(i,pver)   
1741       cm = cmu(i,pver+1) * ( 1._r8 - sflh(i,pver) ) + cms(i,pver+1) * sflh(i,pver)   
1742       bflxs(i) = ch * shflx(i) * rrho(i) + cm * qflx(i) * rrho(i)
1743       if( choice_tkes .eq. 'ibprod' ) then
1744           bprod(i,pver+1) = bflxs(i)
1745       else
1746           bprod(i,pver+1) = 0._r8
1747       endif
1748       sprod(i,pver+1) = (ustar(i)**3)/(vk*z(i,pver))
1749    end do
1750
1751    ! Initially identify CL regimes in 'exacol'
1752    !    ktop  : Interface index of the CL top  external interface
1753    !    kbase : Interface index of the CL base external interface
1754    !    ncvfin: Number of total CLs
1755    ! Note that if surface buoyancy flux is positive ( bflxs = bprod(i,pver+1) > 0 ),
1756    ! surface interface is identified as an internal interface of CL. However, even
1757    ! though bflxs <= 0, if 'pver' interface is a CL internal interface (ri(pver)<0),
1758    ! surface interface is identified as an external interface of CL. If bflxs =< 0
1759    ! and ri(pver) >= 0, then surface interface is identified as a stable turbulent
1760    ! intereface (STL) as shown at the end of 'caleddy'. Even though a 'minpblh' is
1761    ! passed into 'exacol', it is not used in the 'exacol'.
1762
1763    call exacol( pcols, pver, ncol, ri, bflxs, minpblh, zi, ktop, kbase, ncvfin )
1764
1765    ! Diagnostic output of CL interface indices before performing 'extending-merging'
1766    ! of CL regimes in 'zisocl'
1767    do i = 1, ncol
1768    do k = 1, ncvmax
1769       kbase_o(i,k) = real(kbase(i,k),r8)
1770       ktop_o(i,k)  = real(ktop(i,k),r8)
1771       ncvfin_o(i)  = real(ncvfin(i),r8)
1772    end do
1773    end do
1774
1775    ! ----------------------------------- !
1776    ! Perform calculation for each column !
1777    ! ----------------------------------- !
1778
1779    do i = 1, ncol
1780
1781       ! Define Surface Interfacial Layer TKE, 'tkes'.
1782       ! In the current code, 'tkes' is used as representing TKE of surface interfacial
1783       ! layer (low half-layer of surface-based grid layer). In the code, when bflxs>0,
1784       ! surface interfacial layer is assumed to be energetically  coupled to the other
1785       ! parts of the CL regime based at the surface. In this sense, it is conceptually
1786       ! more reasonable to include both 'bprod' and 'sprod' in the definition of 'tkes'.
1787       ! Since 'tkes' cannot be negative, it is lower bounded by small positive number.
1788       ! Note that inclusion of 'bprod' in the definition of 'tkes' may increase 'ebrk'
1789       ! and 'wstar3', and eventually, 'wet' at the CL top, especially when 'bflxs>0'.
1790       ! This might help to solve the problem of too shallow PBLH over the overcast Sc
1791       ! regime. If I want to exclude 'bprod(i,pver+1)' in calculating 'tkes' even when
1792       ! bflxs > 0, all I should to do is to set 'bprod(i,pver+1) = 0' in the above
1793       ! initialization 'do' loop (explained above), NOT changing the formulation of
1794       ! tkes(i) in the below block. This is because for consistent treatment in the
1795       ! other parts of the code also.
1796 
1797     ! tkes(i) = (b1*vk*z(i,pver)*sprod(i,pver+1))**(2._r8/3._r8)
1798       tkes(i) = max(b1*vk*z(i,pver)*(bprod(i,pver+1)+sprod(i,pver+1)), 1.e-7_r8)**(2._r8/3._r8)
1799       tkes(i) = min(tkes(i), tkemax)
1800       tke(i,pver+1)  = tkes(i)
1801       wcap(i,pver+1) = tkes(i)/b1
1802
1803       ! Extend and merge the initially identified CLs, relabel the CLs, and calculate
1804       ! CL internal mean energetics and stability functions in 'zisocl'.
1805       ! The CL nearest to the surface is CL(1) and the CL index, ncv, increases
1806       ! with height. The following outputs are from 'zisocl'. Here, the dimension
1807       ! of below outputs are (pcols,ncvmax) (except the 'ncvfin(pcols)' and
1808       ! 'belongcv(pcols,pver+1)) and 'ncv' goes from 1 to 'ncvfin'.
1809       ! For 'ncv = ncvfin+1, ncvmax', below output are already initialized to be zero.
1810       !      ncvfin       : Total number of CLs
1811       !      kbase(ncv)   : Base external interface index of CL
1812       !      ktop         : Top  external interface index of CL
1813       !      belongcv     : True if the interface (either internal or external) is CL 
1814       !      ricl         : Mean Richardson number of internal CL
1815       !      ghcl         : Normalized buoyancy production '-l2n2/2e' [no unit] of internal CL
1816       !      shcl         : Galperin instability function of heat-moisture of internal CL
1817       !      smcl         : Galperin instability function of momentum of internal CL
1818       !      lbrk, <l>int : Thickness of (energetically) internal CL (lint, [m])
1819       !      wbrk, <W>int : Mean normalized TKE of internal CL  ([m2/s2])
1820       !      ebrk, <e>int : Mean TKE of internal CL (b1*wbrk,[m2/s2])
1821       ! The ncvsurf is an identifier saying which CL regime is based at the surface.
1822       ! If 'ncvsurf=1', then the first CL regime is based at the surface. If surface
1823       ! interface is not a part of CL (neither internal nor external), 'ncvsurf = 0'.
1824       ! After identifying and including SRCLs into the normal CL regimes (where newly
1825       ! identified SRCLs are simply appended to the normal CL regimes using regime
1826       ! indices of 'ncvfin+1','ncvfin+2' (as will be shown in the below SRCL part),..
1827       ! where 'ncvfin' is the final CL regime index produced after extending-merging
1828       ! in 'zisocl' but before adding SRCLs), if any newly identified SRCL (e.g.,
1829       ! 'ncvfin+1') is based at surface, then 'ncvsurf = ncvfin+1'. Thus 'ncvsurf' can
1830       ! be 0, 1, or >1. 'ncvsurf' can be a useful diagnostic output.   
1831
1832       ncvsurf = 0
1833       if( ncvfin(i) .gt. 0 ) then
1834           call zisocl( pcols  , pver     , i        ,           &
1835                        z      , zi       , n2       , s2      , &
1836                        bprod  , sprod    , bflxs    , tkes    , &
1837                        ncvfin , kbase    , ktop     , belongcv, &
1838                        ricl   , ghcl     , shcl     , smcl    , &
1839                        lbrk   , wbrk     , ebrk     ,           &
1840                        extend , extend_up, extend_dn )
1841           if( kbase(i,1) .eq. pver + 1 ) ncvsurf = 1
1842       else
1843           belongcv(i,:) = .false.
1844       endif
1845
1846       ! Diagnostic output after finishing extending-merging process in 'zisocl'
1847       ! Since we are adding SRCL additionally, we need to print out these here.
1848
1849       do k = 1, ncvmax
1850          kbase_mg(i,k) = real(kbase(i,k))
1851          ktop_mg(i,k)  = real(ktop(i,k))
1852          ncvfin_mg(i)  = real(ncvfin(i))
1853       end do
1854
1855       ! ----------------------- !
1856       ! Identification of SRCLs !
1857       ! ----------------------- !
1858
1859     ! Modification : This cannot identify the 'cirrus' layer due to the condition of
1860     !                ql(i,k) .gt. qmin. This should be modified in future to identify
1861     !                a single thin cirrus layer. 
1862     !                Instead of ql, we may use cldn in future, including ice
1863     !                contribution.
1864
1865       ! ------------------------------------------------------------------------------ !
1866       ! Find single-layer radiatively-driven cloud-topped convective layers (SRCLs).   !
1867       ! SRCLs extend through a single model layer k, with entrainment at the top and   !
1868       ! bottom interfaces, unless bottom interface is the surface.                     !
1869       ! The conditions for an SRCL is identified are:                                  !
1870       !                                                                                !
1871       !   1. Cloud in the layer, k : ql(i,k) .gt. qmin = 1.e-5 [ kg/kg ]               !
1872       !   2. No cloud in the above layer (else assuming that some fraction of the LW   !
1873       !      flux divergence in layer k is concentrated at just below top interface    !
1874       !      of layer k is invalid). Then, this condition might be sensitive to the    !
1875       !      vertical resolution of grid.                                              !
1876       !   3. LW radiative cooling (SW heating is assumed uniformly distributed through !
1877       !      layer k, so not relevant to buoyancy production) in the layer k. However, !
1878       !      SW production might also contribute, which may be considered in a future. !
1879       !   4. Internal stratification 'n2ht' of upper-half layer should be unstable.    !
1880       !      The 'n2ht' is pure internal stratification of upper half layer, obtained  !
1881       !      using internal slopes of sl, qt in layer k (in contrast to conventional   !
1882       !      interfacial slope) and saturation fraction in the upper-half layer,       !
1883       !      sfuh(k) (in contrast to sfi(k)).                                          !
1884       !   5. Top and bottom interfaces not both in the same existing convective layer. !
1885       !      If SRCL is within the previouisly identified CL regimes, we don't define  !
1886       !      a new SRCL.                                                               !
1887       !   6. k >= ntop_turb + 1 = 2                                                    !
1888       !   7. Ri at the top interface > ricrit = 0.19 (otherwise turbulent mixing will  !
1889       !      broadly distribute the cloud top in the vertical, preventing localized    !
1890       !      radiative destabilization at the top interface).                          !
1891       !                                                                                !
1892       ! Note if 'k = pver', it identifies a surface-based single fog layer, possibly,  !
1893       ! warm advection fog. Note also the CL regime index of SRCLs itself increases    !
1894       ! with height similar to the regular CLs indices identified from 'zisocl'.       !
1895       ! ------------------------------------------------------------------------------ !
1896
1897       ncv  = 1
1898       ncvf = ncvfin(i)
1899
1900       if( choice_SRCL .eq. 'remove' ) goto 222
1901
1902       do k = nbot_turb, ntop_turb + 1, -1 ! 'k = pver, 2, -1' is a layer index.
1903
1904          if( ql(i,k) .gt. qmin .and. ql(i,k-1) .lt. qmin .and. qrlw(i,k) .lt. 0._r8 &
1905                                .and. ri(i,k) .ge. ricrit ) then
1906
1907              ! In order to avoid any confliction with the treatment of ambiguous layer,
1908              ! I need to impose an additional constraint that ambiguous layer cannot be
1909              ! SRCL. So, I added constraint that 'k+1' interface (base interface of k
1910              ! layer) should not be a part of previously identified CL. Since 'belongcv'
1911              ! is even true for external entrainment interfaces, below constraint is
1912              ! fully sufficient.
1913 
1914              if( choice_SRCL .eq. 'nonamb' .and. belongcv(i,k+1) ) then
1915                  go to 220
1916              endif
1917
1918              ch = ( 1._r8 - sfuh(i,k) ) * chu(i,k) + sfuh(i,k) * chs(i,k)
1919              cm = ( 1._r8 - sfuh(i,k) ) * cmu(i,k) + sfuh(i,k) * cms(i,k)
1920
1921              n2htSRCL = ch * slslope(i,k) + cm * qtslope(i,k)
1922
1923              if( n2htSRCL .le. 0._r8 ) then
1924
1925                  ! Test if bottom and top interfaces are part of the pre-existing CL.
1926                  ! If not, find appropriate index for the new SRCL. Note that this
1927                  ! calculation makes use of 'ncv set' obtained from 'zisocl'. The
1928                  ! 'in_CL' is a parameter testing whether the new SRCL is already
1929                  ! within the pre-existing CLs (.true.) or not (.false.).
1930
1931                  in_CL = .false.
1932
1933                  do while ( ncv .le. ncvf )
1934                     if( ktop(i,ncv) .le. k ) then
1935                        if( kbase(i,ncv) .gt. k ) then
1936                            in_CL = .true.
1937                        endif
1938                        exit             ! Exit from 'do while' loop if SRCL is within the CLs.
1939                     else
1940                        ncv = ncv + 1    ! Go up one CL
1941                     end if
1942                  end do ! ncv
1943
1944                  if( .not. in_CL ) then ! SRCL is not within the pre-existing CLs.
1945
1946                     ! Identify a new SRCL and add it to the pre-existing CL regime group.
1947
1948                     ncvfin(i)       =  ncvfin(i) + 1
1949                     ncvnew          =  ncvfin(i)
1950                     ktop(i,ncvnew)  =  k
1951                     kbase(i,ncvnew) =  k+1
1952                     belongcv(i,k)   = .true.
1953                     belongcv(i,k+1) = .true.
1954
1955                     ! Calculate internal energy of SRCL. There is no internal energy if
1956                     ! SRCL is elevated from the surface. Also, we simply assume neutral
1957                     ! stability function. Note that this assumption of neutral stability
1958                     ! does not influence numerical calculation- stability functions here
1959                     ! are just for diagnostic output. In general SRCLs other than a SRCL
1960                     ! based at surface with bflxs <= 0, there is no other way but to use
1961                     ! neutral stability function.  However, in case of SRCL based at the
1962                     ! surface,  we can explicitly calculate non-zero stability functions           
1963                     ! in a consistent way.   Even though stability functions of SRCL are
1964                     ! just diagnostic outputs not influencing numerical calculations, it
1965                     ! would be informative to write out correct reasonable values rather
1966                     ! than simply assuming neutral stability. I am doing this right now.
1967                     ! Similar calculations were done for the SBCL and when surface inter
1968                     ! facial layer was merged by overlying CL in 'ziscol'.
1969
1970                     if( k .lt. pver ) then
1971
1972                         wbrk(i,ncvnew) = 0._r8
1973                         ebrk(i,ncvnew) = 0._r8
1974                         lbrk(i,ncvnew) = 0._r8
1975                         ghcl(i,ncvnew) = 0._r8
1976                         shcl(i,ncvnew) = 0._r8
1977                         smcl(i,ncvnew) = 0._r8
1978                         ricl(i,ncvnew) = 0._r8
1979
1980                     else ! Surface-based fog
1981
1982                         if( bflxs(i) .gt. 0._r8 ) then    ! Incorporate surface TKE into CL interior energy
1983                                                           ! It is likely that this case cannot exist  since
1984                                                           ! if surface buoyancy flux is positive,  it would
1985                                                           ! have been identified as SBCL in 'zisocl' ahead.
1986                             ebrk(i,ncvnew) = tkes(i)
1987                             lbrk(i,ncvnew) = z(i,pver)
1988                             wbrk(i,ncvnew) = tkes(i) / b1   
1989       
1990                             write(iulog,*) 'Major mistake in SRCL: bflxs > 0 for surface-based SRCL'
1991                             write(iulog,*) 'bflxs = ', bflxs(i)
1992                             write(iulog,*) 'ncvfin_o = ', ncvfin_o(i)
1993                             write(iulog,*) 'ncvfin_mg = ', ncvfin_mg(i)
1994                             do ks = 1, ncvmax
1995                                write(iulog,*) 'ncv =', ks, ' ', kbase_o(i,ks), ktop_o(i,ks), kbase_mg(i,ks), ktop_mg(i,ks)
1996                             end do
1997                             stop
1998
1999                         else                              ! Don't incorporate surface interfacial TKE into CL interior energy
2000
2001                             ebrk(i,ncvnew) = 0._r8
2002                             lbrk(i,ncvnew) = 0._r8
2003                             wbrk(i,ncvnew) = 0._r8
2004
2005                         endif
2006
2007                         ! Calculate stability functions (ghcl, shcl, smcl, ricl) explicitly
2008                         ! using an reverse procedure starting from tkes(i). Note that it is
2009                         ! possible to calculate stability functions even when bflxs < 0.
2010                         ! Previous code just assumed neutral stability functions. Note that
2011                         ! since alph5 = 0.7 > 0, alph3 = -35 < 0, the denominator of gh  is
2012                         ! always positive if bflxs > 0. However, if bflxs < 0,  denominator
2013                         ! can be zero. For this case, we provide a possible maximum negative
2014                         ! value (the most stable state) to gh. Note also tkes(i) is always a
2015                         ! positive value by a limiter. Also, sprod(i,pver+1) > 0 by limiter.
2016                         
2017                         gg = 0.5_r8 * vk * z(i,pver) * bprod(i,pver+1) / ( tkes(i)**(3._r8/2._r8) )
2018                         if( abs(alph5-gg*alph3) .le. 1.e-7_r8 ) then
2019                           ! gh = -0.28_r8
2020                           ! gh = -3.5334_r8
2021                             gh = ghmin
2022                         else   
2023                             gh = gg / ( alph5 - gg * alph3 )
2024                         end if
2025                       ! gh = min(max(gh,-0.28_r8),0.0233_r8)
2026                       ! gh = min(max(gh,-3.5334_r8),0.0233_r8)
2027                         gh = min(max(gh,ghmin),0.0233_r8)
2028                         ghcl(i,ncvnew) =  gh
2029                         shcl(i,ncvnew) =  max(0._r8,alph5/(1._r8+alph3*gh))
2030                         smcl(i,ncvnew) =  max(0._r8,(alph1 + alph2*gh)/(1._r8+alph3*gh)/(1._r8+alph4exs*gh))
2031                         ricl(i,ncvnew) = -(smcl(i,ncvnew)/shcl(i,ncvnew))*(bprod(i,pver+1)/sprod(i,pver+1))
2032
2033                       ! 'ncvsurf' is CL regime index based at the surface. If there is no
2034                       ! such regime, then 'ncvsurf = 0'.
2035   
2036                         ncvsurf = ncvnew
2037
2038                      end if
2039
2040                  end if
2041
2042              end if
2043
2044          end if
2045
2046   220 continue   
2047
2048       end do ! End of 'k' loop where 'k' is a grid layer index running from 'pver' to 2
2049
2050   222 continue
2051
2052       ! -------------------------------------------------------------------------- !
2053       ! Up to this point, we identified all kinds of CL regimes :                  !
2054       !   1. A SBCL. By construction, 'bflxs > 0' for SBCL.                        !
2055       !   2. Surface-based CL with multiple layers and 'bflxs =< 0'                !
2056       !   3. Surface-based CL with multiple layers and 'bflxs > 0'                 !
2057       !   4. Regular elevated CL with two entraining interfaces                    !
2058       !   5. SRCLs. If SRCL is based at surface, it will be bflxs < 0.             !
2059       ! '1-4' were identified from 'zisocl' while '5' were identified separately   !
2060       ! after performing 'zisocl'. CL regime index of '1-4' increases with height  !
2061       ! ( e.g., CL = 1 is the CL regime nearest to the surface ) while CL regime   !
2062       ! index of SRCL is simply appended after the final index of CL regimes from  !
2063       ! 'zisocl'. However, CL regime indices of SRCLs itself increases with height !
2064       ! when there are multiple SRCLs, similar to the regular CLs from 'zisocl'.   !
2065       ! -------------------------------------------------------------------------- !
2066
2067       ! Diagnostic output of final CL regimes indices
2068       
2069       do k = 1, ncvmax
2070          kbase_f(i,k) = real(kbase(i,k))
2071          ktop_f(i,k)  = real(ktop(i,k))
2072          ncvfin_f(i)  = real(ncvfin(i))
2073       end do
2074
2075       ! ---------------------------------------- !
2076       ! Perform do loop for individual CL regime !
2077       ! ---------------------------------------- ! -------------------------------- !
2078       ! For individual CLs, compute                                                 !
2079       !   1. Entrainment rates at the CL top and (if any) base interfaces using     !
2080       !      appropriate entrainment closure (current code use 'wstar' closure).    !
2081       !   2. Net CL mean (i.e., including entrainment contribution) TKE (ebrk)      !
2082       !      and normalized TKE (wbrk).                                             !
2083       !   3. TKE (tke) and normalized TKE (wcap) profiles at all CL interfaces.     !
2084       !   4. ( kvm, kvh ) profiles at all CL interfaces.                            !
2085       !   5. ( bprod, sprod ) profiles at all CL interfaces.                        !
2086       ! Also calculate                                                              !
2087       !   1. PBL height as the top external interface of surface-based CL, if any.  !
2088       !   2. Characteristic excesses of convective 'updraft velocity (wpert)',      !
2089       !      'temperature (tpert)', and 'moisture (qpert)' in the surface-based CL, !
2090       !      if any, for use in the separate convection scheme.                     !
2091       ! If there is no surface-based CL, 'PBL height' and 'convective excesses' are !
2092       ! calculated later from surface-based STL (Stable Turbulent Layer) properties.!
2093       ! --------------------------------------------------------------------------- !
2094
2095       ktblw = 0
2096       do ncv = 1, ncvfin(i)
2097
2098          kt = ktop(i,ncv)
2099          kb = kbase(i,ncv)
2100          ! Check whether surface interface is energetically interior or not.
2101          if( kb .eq. (pver+1) .and. bflxs(i) .le. 0._r8 ) then
2102              lbulk = zi(i,kt) - z(i,pver)
2103          else
2104              lbulk = zi(i,kt) - zi(i,kb)
2105          end if
2106
2107          ! Calculate 'turbulent length scale (leng)' and 'normalized TKE (wcap)'
2108          ! at all CL interfaces except the surface.  Note that below 'wcap' at
2109          ! external interfaces are not correct. However, it does not influence
2110          ! numerical calculation and correct normalized TKE at the entraining
2111          ! interfaces will be re-calculated at the end of this 'do ncv' loop.
2112
2113          do k = min(kb,pver), kt, -1
2114             if( choice_tunl .eq. 'rampcl' ) then
2115               ! In order to treat the case of 'ricl(i,ncv) >> 0' of surface-based SRCL
2116               ! with 'bflxs(i) < 0._r8', I changed ricl(i,ncv) -> min(0._r8,ricl(i,ncv))
2117               ! in the below exponential. This is necessary to prevent the model crash
2118               ! by too large values (e.g., 700) of ricl(i,ncv)   
2119                 tunlramp = ctunl*tunl*(1._r8-(1._r8-1._r8/ctunl)*exp(min(0._r8,ricl(i,ncv))))
2120                 tunlramp = min(max(tunlramp,tunl),ctunl*tunl)
2121             elseif( choice_tunl .eq. 'rampsl' ) then
2122                 tunlramp = ctunl*tunl
2123               ! tunlramp = 0.765_r8
2124             else
2125                 tunlramp = tunl
2126             endif
2127             if( choice_leng .eq. 'origin' ) then
2128                 leng(i,k) = ( (vk*zi(i,k))**(-cleng) + (tunlramp*lbulk)**(-cleng) )**(-1._r8/cleng)
2129               ! leng(i,k) = vk*zi(i,k) / (1._r8+vk*zi(i,k)/(tunlramp*lbulk))
2130             else
2131                 leng(i,k) = min( vk*zi(i,k), tunlramp*lbulk )             
2132             endif
2133             wcap(i,k) = (leng(i,k)**2) * (-shcl(i,ncv)*n2(i,k)+smcl(i,ncv)*s2(i,k))
2134          end do ! k
2135
2136          ! Calculate basic cross-interface variables ( jump condition ) across the
2137          ! base external interface of CL.
2138
2139          if( kb .lt. pver+1 ) then
2140
2141              jbzm = z(i,kb-1) - z(i,kb)                                      ! Interfacial layer thickness [m]
2142              jbsl = sl(i,kb-1) - sl(i,kb)                                    ! Interfacial jump of 'sl' [J/kg]
2143              jbqt = qt(i,kb-1) - qt(i,kb)                                    ! Interfacial jump of 'qt' [kg/kg]
2144              jbbu = n2(i,kb) * jbzm                                          ! Interfacial buoyancy jump [m/s2] considering saturation ( > 0 )
2145              jbbu = max(jbbu,jbumin)                                         ! Set minimum buoyancy jump, jbumin = 1.e-3
2146              jbu  = u(i,kb-1) - u(i,kb)                                      ! Interfacial jump of 'u' [m/s]
2147              jbv  = v(i,kb-1) - v(i,kb)                                      ! Interfacial jump of 'v' [m/s]
2148              ch   = (1._r8 -sflh(i,kb-1))*chu(i,kb) + sflh(i,kb-1)*chs(i,kb) ! Buoyancy coefficient just above the base interface
2149              cm   = (1._r8 -sflh(i,kb-1))*cmu(i,kb) + sflh(i,kb-1)*cms(i,kb) ! Buoyancy coefficient just above the base interface
2150              n2hb = (ch*jbsl + cm*jbqt)/jbzm                                 ! Buoyancy frequency [s-2] just above the base interface
2151              vyb  = n2hb*jbzm/jbbu                                           ! Ratio of 'n2hb/n2' at 'kb' interface
2152              vub  = min(1._r8,(jbu**2+jbv**2)/(jbbu*jbzm) )                  ! Ratio of 's2/n2 = 1/Ri' at 'kb' interface
2153
2154          else
2155
2156            ! Below setting is necessary for consistent treatment when 'kb' is at the surface.
2157              jbbu = 0._r8
2158              n2hb = 0._r8
2159              vyb  = 0._r8
2160              vub  = 0._r8
2161              web  = 0._r8
2162
2163          end if
2164
2165          ! Calculate basic cross-interface variables ( jump condition ) across the
2166          ! top external interface of CL. The meanings of variables are similar to
2167          ! the ones at the base interface.
2168
2169          jtzm = z(i,kt-1) - z(i,kt)
2170          jtsl = sl(i,kt-1) - sl(i,kt)
2171          jtqt = qt(i,kt-1) - qt(i,kt)
2172          jtbu = n2(i,kt)*jtzm                                                ! Note : 'jtbu' is guaranteed positive by definition of CL top.
2173          jtbu = max(jtbu,jbumin)                                             ! But threshold it anyway to be sure.
2174          jtu  = u(i,kt-1) - u(i,kt)
2175          jtv  = v(i,kt-1) - v(i,kt)
2176          ch   = (1._r8 -sfuh(i,kt))*chu(i,kt) + sfuh(i,kt)*chs(i,kt)
2177          cm   = (1._r8 -sfuh(i,kt))*cmu(i,kt) + sfuh(i,kt)*cms(i,kt)
2178          n2ht = (ch*jtsl + cm*jtqt)/jtzm                       
2179          vyt  = n2ht*jtzm/jtbu                                 
2180          vut  = min(1._r8,(jtu**2+jtv**2)/(jtbu*jtzm))             
2181
2182          ! Evaporative enhancement factor of entrainment rate at the CL top interface, evhc.
2183          ! We take the full inversion strength to be 'jt2slv = slv(i,kt-2)-slv(i,kt)'
2184          ! where 'kt-1' is in the ambiguous layer. However, for a cloud-topped CL overlain
2185          ! by another CL, it is possible that 'slv(i,kt-2) < slv(i,kt)'. To avoid negative
2186          ! or excessive evhc, we lower-bound jt2slv and upper-bound evhc.  Note 'jtslv' is
2187          ! used only for calculating 'evhc' : when calculating entrainment rate,   we will
2188          ! use normal interfacial buoyancy jump across CL top interface.
2189
2190          evhc   = 1._r8
2191          jt2slv = 0._r8
2192
2193        ! Modification : I should check whether below 'jbumin' produces reasonable limiting value.   
2194        !                In addition, our current formulation does not consider ice contribution.
2195
2196          if( choice_evhc .eq. 'orig' ) then
2197
2198              if( ql(i,kt) .gt. qmin .and. ql(i,kt-1) .lt. qmin ) then
2199                  jt2slv = slv(i,max(kt-2,1)) - slv(i,kt)
2200                  jt2slv = max( jt2slv, jbumin*slv(i,kt-1)/g )
2201                  evhc   = 1._r8 + a2l * a3l * latvap * ql(i,kt) / jt2slv
2202                  evhc   = min( evhc, evhcmax )
2203              end if
2204
2205          elseif( choice_evhc .eq. 'ramp' ) then
2206
2207              jt2slv = slv(i,max(kt-2,1)) - slv(i,kt)
2208              jt2slv = max( jt2slv, jbumin*slv(i,kt-1)/g )
2209              evhc   = 1._r8 + max(cldeff(i,kt)-cldeff(i,kt-1),0._r8) * a2l * a3l * latvap * ql(i,kt) / jt2slv
2210              evhc   = min( evhc, evhcmax )
2211
2212          elseif( choice_evhc .eq. 'maxi' ) then
2213
2214              qleff  = max( ql(i,kt-1), ql(i,kt) )
2215              jt2slv = slv(i,max(kt-2,1)) - slv(i,kt)
2216              jt2slv = max( jt2slv, jbumin*slv(i,kt-1)/g )
2217              evhc   = 1._r8 + a2l * a3l * latvap * qleff / jt2slv
2218              evhc   = min( evhc, evhcmax )
2219
2220          endif
2221
2222          ! Calculate cloud-top radiative cooling contribution to buoyancy production.
2223          ! Here,  'radf' [m2/s3] is additional buoyancy flux at the CL top interface
2224          ! associated with cloud-top LW cooling being mainly concentrated near the CL
2225          ! top interface ( just below CL top interface ).  Contribution of SW heating
2226          ! within the cloud is not included in this radiative buoyancy production
2227          ! since SW heating is more broadly distributed throughout the CL top layer.
2228
2229          lwp        = 0._r8
2230          opt_depth  = 0._r8
2231          radinvfrac = 0._r8
2232          radf       = 0._r8
2233
2234          if( choice_radf .eq. 'orig' ) then
2235
2236              if( ql(i,kt) .gt. qmin .and. ql(i,kt-1) .lt. qmin ) then
2237
2238                  lwp       = ql(i,kt) * ( pi(i,kt+1) - pi(i,kt) ) / g
2239                  opt_depth = 156._r8 * lwp  ! Estimated LW optical depth in the CL top layer
2240
2241                  ! Approximate LW cooling fraction concentrated at the inversion by using
2242                  ! polynomial approx to exact formula 1-2/opt_depth+2/(exp(opt_depth)-1))
2243
2244                  radinvfrac  = opt_depth * ( 4._r8 + opt_depth ) / ( 6._r8 * ( 4._r8 + opt_depth ) + opt_depth**2 )
2245                  radf        = qrlw(i,kt) / ( pi(i,kt) - pi(i,kt+1) ) ! Cp*radiative cooling = [ W/kg ]
2246                  radf        = max( radinvfrac * radf * ( zi(i,kt) - zi(i,kt+1) ), 0._r8 ) * chs(i,kt)
2247                ! We can disable cloud LW cooling contribution to turbulence by uncommenting:
2248                ! radf = 0._r8
2249
2250              end if
2251
2252          elseif( choice_radf .eq. 'ramp' ) then
2253
2254                  lwp         = ql(i,kt) * ( pi(i,kt+1) - pi(i,kt) ) / g
2255                  opt_depth   = 156._r8 * lwp  ! Estimated LW optical depth in the CL top layer
2256                  radinvfrac  = opt_depth * ( 4._r8 + opt_depth ) / ( 6._r8 * ( 4._r8 + opt_depth ) + opt_depth**2 )
2257                  radinvfrac  = max(cldeff(i,kt)-cldeff(i,kt-1),0._r8) * radinvfrac
2258                  radf        = qrlw(i,kt) / ( pi(i,kt) - pi(i,kt+1) ) ! Cp*radiative cooling [W/kg]
2259                  radf        = max( radinvfrac * radf * ( zi(i,kt) - zi(i,kt+1) ), 0._r8 ) * chs(i,kt)
2260
2261          elseif( choice_radf .eq. 'maxi' ) then
2262
2263                ! Radiative flux divergence both in 'kt' and 'kt-1' layers are included
2264                ! 1. From 'kt' layer
2265                  lwp         = ql(i,kt) * ( pi(i,kt+1) - pi(i,kt) ) / g
2266                  opt_depth   = 156._r8 * lwp  ! Estimated LW optical depth in the CL top layer
2267                  radinvfrac  = opt_depth * ( 4._r8 + opt_depth ) / ( 6._r8 * ( 4._r8 + opt_depth ) + opt_depth**2 )
2268                  radf        = max( radinvfrac * qrlw(i,kt) / ( pi(i,kt) - pi(i,kt+1) ) * ( zi(i,kt) - zi(i,kt+1) ), 0._r8 )
2269                ! 2. From 'kt-1' layer and add the contribution from 'kt' layer
2270                  lwp         = ql(i,kt-1) * ( pi(i,kt) - pi(i,kt-1) ) / g
2271                  opt_depth   = 156._r8 * lwp  ! Estimated LW optical depth in the CL top layer
2272                  radinvfrac  = opt_depth * ( 4._r8 + opt_depth ) / ( 6._r8 * ( 4._r8 + opt_depth) + opt_depth**2 )
2273                  radf        = radf + max( radinvfrac * qrlw(i,kt-1) / ( pi(i,kt-1) - pi(i,kt) ) * ( zi(i,kt-1) - zi(i,kt) ), 0._r8 )
2274                  radf        = max( radf, 0._r8 ) * chs(i,kt)
2275
2276          endif
2277
2278          ! ------------------------------------------------------------------- !
2279          ! Calculate 'wstar3' by summing buoyancy productions within CL from   !
2280          !   1. Interior buoyancy production ( bprod: fcn of TKE )             !
2281          !   2. Cloud-top radiative cooling                                    !
2282          !   3. Surface buoyancy flux contribution only when bflxs > 0.        !
2283          !      Note that master length scale, lbulk, has already been         !
2284          !      corrctly defined at the first part of this 'do ncv' loop       !
2285          !      considering the sign of bflxs.                                 !
2286          ! This 'wstar3' is used for calculation of entrainment rate.          !
2287          ! Note that this 'wstar3' formula does not include shear production   !
2288          ! and the effect of drizzle, which should be included later.          !
2289          ! Q : Strictly speaking, in calculating interior buoyancy production, !
2290          !     the use of 'bprod' is not correct, since 'bprod' is not correct !
2291          !     value but initially guessed value.   More reasonably, we should !
2292          !     use '-leng(i,k)*sqrt(b1*wcap(i,k))*shcl(i,ncv)*n2(i,k)' instead !
2293          !     of 'bprod(i,k)', although this is still an  approximation since !
2294          !     tke(i,k) is not exactly 'b1*wcap(i,k)'  due to a transport term.!
2295          !     However since iterative calculation will be performed after all,!
2296          !     below might also be OK. But I should test this alternative.     !
2297          ! ------------------------------------------------------------------- !     
2298
2299          dzht   = zi(i,kt)  - z(i,kt)     ! Thickness of CL top half-layer
2300          dzhb   = z(i,kb-1) - zi(i,kb)    ! Thickness of CL bot half-layer
2301          wstar3 = radf * dzht
2302          do k = kt + 1, kb - 1 ! If 'kt = kb - 1', this loop will not be performed.
2303               wstar3 =  wstar3 + bprod(i,k) * ( z(i,k-1) - z(i,k) )
2304             ! Below is an alternative which may speed up convergence.
2305             ! However, for interfaces merged into original CL, it can
2306             ! be 'wcap(i,k)<0' since 'n2(i,k)>0'.  Thus, I should use
2307             ! the above original one.
2308             ! wstar3 =  wstar3 - leng(i,k)*sqrt(b1*wcap(i,k))*shcl(i,ncv)*n2(i,k)* &
2309             !                    (z(i,k-1) - z(i,k))
2310          end do     
2311          if( kb .eq. (pver+1) .and. bflxs(i) .gt. 0._r8 ) then
2312             wstar3 = wstar3 + bflxs(i) * dzhb
2313           ! wstar3 = wstar3 + bprod(i,pver+1) * dzhb
2314          end if   
2315          wstar3 = max( 2.5_r8 * wstar3, 0._r8 )
2316   
2317          ! -------------------------------------------------------------- !
2318          ! Below single block is for 'sedimentation-entrainment feedback' !
2319          ! -------------------------------------------------------------- !         
2320
2321          if( id_sedfact ) then
2322            ! wsed    = 7.8e5_r8*(ql(i,kt)/ncliq(i,kt))**(2._r8/3._r8)
2323              sedfact = exp(-ased*wsedl(i,kt)/(wstar3**(1._r8/3._r8)+1.e-6))
2324              if( choice_evhc .eq. 'orig' ) then
2325                  if (ql(i,kt).gt.qmin .and. ql(i,kt-1).lt.qmin) then
2326                      jt2slv = slv(i,max(kt-2,1)) - slv(i,kt)
2327                      jt2slv = max(jt2slv, jbumin*slv(i,kt-1)/g)
2328                      evhc = 1._r8+sedfact*a2l*a3l*latvap*ql(i,kt) / jt2slv
2329                      evhc = min(evhc,evhcmax)
2330                  end if
2331              elseif( choice_evhc .eq. 'ramp' ) then
2332                  jt2slv = slv(i,max(kt-2,1)) - slv(i,kt)
2333                  jt2slv = max(jt2slv, jbumin*slv(i,kt-1)/g)
2334                  evhc = 1._r8+max(cldeff(i,kt)-cldeff(i,kt-1),0._r8)*sedfact*a2l*a3l*latvap*ql(i,kt) / jt2slv
2335                  evhc = min(evhc,evhcmax)
2336              elseif( choice_evhc .eq. 'maxi' ) then
2337                  qleff  = max(ql(i,kt-1),ql(i,kt))
2338                  jt2slv = slv(i,max(kt-2,1)) - slv(i,kt)
2339                  jt2slv = max(jt2slv, jbumin*slv(i,kt-1)/g)
2340                  evhc = 1._r8+sedfact*a2l*a3l*latvap*qleff / jt2slv
2341                  evhc = min(evhc,evhcmax)
2342              endif
2343          endif
2344
2345          ! -------------------------------------------------------------------------- !
2346          ! Now diagnose CL top and bottom entrainment rates (and the contribution of  !
2347          ! top/bottom entrainments to wstar3) using entrainment closures of the form  !
2348          !                                                                            !       
2349          !                   wet = cet*wstar3, web = ceb*wstar3                       !
2350          !                                                                            !
2351          ! where cet and ceb depend on the entrainment interface jumps, ql, etc.      !
2352          ! No entrainment is diagnosed unless the wstar3 > 0. Note '1/wstar3fact' is  !
2353          ! a factor indicating the enhancement of wstar3 due to entrainment process.  !
2354          ! Q : Below setting of 'wstar3fact = max(..,0.5)'might prevent the possible  !
2355          !     case when buoyancy consumption by entrainment is  stronger than cloud  !
2356          !     top radiative cooling production. Is that OK ? No.  According to bulk  !
2357          !     modeling study, entrainment buoyancy consumption was always a certain  !
2358          !     fraction of other net productions, rather than a separate sum.  Thus,  !
2359          !     below max limit of wstar3fact is correct.   'wstar3fact = max(.,0.5)'  !
2360          !     prevents unreasonable enhancement of CL entrainment rate by cloud-top  !
2361          !     entrainment instability, CTEI.                                         !
2362          ! Q : Use of the same dry entrainment coefficient, 'a1i' both at the CL  top !
2363          !     and base interfaces may result in too small 'wstar3' and 'ebrk' below, !
2364          !     as was seen in my generalized bulk modeling study. This should be re-  !
2365          !     considered later                                                       !
2366          ! -------------------------------------------------------------------------- !
2367         
2368          if( wstar3 .gt. 0._r8 ) then
2369              cet = a1i * evhc / ( jtbu * lbulk )
2370              if( kb .eq. pver + 1 ) then
2371                  wstar3fact = max( 1._r8 + 2.5_r8 * cet * n2ht * jtzm * dzht, wstar3factcrit )
2372              else   
2373                  ceb = a1i / ( jbbu * lbulk )
2374                  wstar3fact = max( 1._r8 + 2.5_r8 * cet * n2ht * jtzm * dzht &
2375                                          + 2.5_r8 * ceb * n2hb * jbzm * dzhb, wstar3factcrit )
2376              end if
2377              wstar3 = wstar3 / wstar3fact       
2378          else ! wstar3 == 0
2379              wstar3fact = 0._r8 ! This is just for dianostic output
2380              cet        = 0._r8
2381              ceb        = 0._r8
2382          end if
2383
2384          ! ---------------------------------------------------------------------------- !
2385          ! Calculate net CL mean TKE including entrainment contribution by solving a    !
2386          ! canonical cubic equation. The solution of cubic equ. is 'rootp**2 = ebrk'    !
2387          ! where 'ebrk' originally (before solving cubic eq.) was interior CL mean TKE, !
2388          ! but after solving cubic equation,  it is replaced by net CL mean TKE in the  !
2389          ! same variable 'ebrk'.                                                        !
2390          ! ---------------------------------------------------------------------------- !
2391          ! Solve cubic equation (canonical form for analytic solution)                  !
2392          !   r^3 - 3*trmp*r - 2*trmq = 0,   r = sqrt<e>                                 !
2393          ! to estimate <e> for CL, derived from layer-mean TKE balance:                 !
2394          !                                                                              !
2395          !   <e>^(3/2)/(b_1*<l>) \approx <B + S>   (*)                                  !
2396          !   <B+S> = (<B+S>_int * l_int + <B+S>_et * dzt + <B+S>_eb * dzb)/lbulk        !
2397          !   <B+S>_int = <e>^(1/2)/(b_1*<l>)*<e>_int                                    !
2398          !   <B+S>_et  = (-vyt+vut)*wet*jtbu + radf                                     !
2399          !   <B+S>_eb  = (-vyb+vub)*web*jbbu                                            !
2400          !                                                                              !
2401          ! where:                                                                       !
2402          !   <> denotes a vertical avg (over the whole CL unless indicated)             !
2403          !   l_int (called lbrk below) is aggregate thickness of interior CL layers     !
2404          !   dzt = zi(i,kt)-z(i,kt)   is thickness of top entrainment layer             !
2405          !   dzb = z(i,kb-1)-zi(i,kb) is thickness of bot entrainment layer             !
2406          !   <e>_int (called ebrk below) is the CL-mean TKE if only interior            !
2407          !                               interfaces contributed.                        !
2408          !   wet, web                  are top. bottom entrainment rates                !
2409          !                                                                              !
2410          ! For a single-level radiatively-driven convective layer, there are no         !
2411          ! interior interfaces so 'ebrk' = 'lbrk' = 0. If the CL goes to the            !
2412          ! surface, 'vyb' and 'vub' are set to zero before and 'ebrk' and 'lbrk'        !
2413          ! have already incorporated the surface interfacial layer contribution,        !
2414          ! so the same formulas still apply.                                            !
2415          !                                                                              !
2416          ! In the original formulation based on TKE,                                    !
2417          !    wet*jtbu = a1l*evhc*<e>^3/2/leng(i,kt)                                    !
2418          !    web*jbbu = a1l*<e>^3/2/leng(i,kt)                                         !
2419          !                                                                              !
2420          ! In the wstar formulation                                                     !
2421          !    wet*jtbu = a1i*evhc*wstar3/lbulk                                          !
2422          !    web*jbbu = a1i*wstar3/lbulk,                                              !
2423          ! ---------------------------------------------------------------------------- !
2424
2425          fact = ( evhc * ( -vyt + vut ) * dzht + ( -vyb + vub ) * dzhb * leng(i,kb) / leng(i,kt) ) / lbulk
2426
2427          if( wstarent ) then
2428
2429              ! (Option 1) 'wstar' entrainment formulation
2430              ! Here trmq can have either sign, and will usually be nonzero even for non-
2431              ! cloud topped CLs.  If trmq > 0, there will be two positive roots r; we take
2432              ! the larger one. Why ? If necessary, we limit entrainment and wstar to prevent
2433              ! a solution with r < ccrit*wstar ( Why ? ) where we take ccrit = 0.5.
2434
2435              trma = 1._r8         
2436              trmp = ebrk(i,ncv) * ( lbrk(i,ncv) / lbulk ) / 3._r8 + ntzero
2437              trmq = 0.5_r8 * b1 * ( leng(i,kt)  / lbulk ) * ( radf * dzht + a1i * fact * wstar3 )
2438
2439              ! Check if there is an acceptable root with r > rcrit = ccrit*wstar.
2440              ! To do this, first find local minimum fmin of the cubic f(r) at sqrt(p),
2441              ! and value fcrit = f(rcrit).
2442
2443              rmin  = sqrt(trmp)
2444              fmin  = rmin * ( rmin * rmin - 3._r8 * trmp ) - 2._r8 * trmq
2445              wstar = wstar3**onet
2446              rcrit = ccrit * wstar
2447              fcrit = rcrit * ( rcrit * rcrit - 3._r8 * trmp ) - 2._r8 * trmq
2448
2449              ! No acceptable root exists (noroot = .true.) if either:
2450              !    1) rmin < rcrit (in which case cubic is monotone increasing for r > rcrit)
2451              !       and f(rcrit) > 0.
2452              ! or 2) rmin > rcrit (in which case min of f(r) in r > rcrit is at rmin)
2453              !       and f(rmin) > 0. 
2454              ! In this case, we reduce entrainment and wstar3 such that r/wstar = ccrit;
2455              ! this changes the coefficients of the cubic.   It might be informative to
2456              ! check when and how many 'noroot' cases occur,  since when 'noroot',   we
2457              ! will impose arbitrary limit on 'wstar3, wet, web, and ebrk' using ccrit.
2458
2459              noroot = ( ( rmin .lt. rcrit ) .and. ( fcrit .gt. 0._r8 ) ) &
2460                  .or. ( ( rmin .ge. rcrit ) .and. ( fmin  .gt. 0._r8 ) )
2461              if( noroot ) then ! Solve cubic for r
2462                  trma = 1._r8 - b1 * ( leng(i,kt) / lbulk ) * a1i * fact / ccrit**3
2463                  trma = max( trma, 0.5_r8 )  ! Limit entrainment enhancement of ebrk
2464                  trmp = trmp / trma
2465                  trmq = 0.5_r8 * b1 * ( leng(i,kt) / lbulk ) * radf * dzht / trma
2466              end if   ! noroot
2467
2468              ! Solve the cubic equation
2469
2470              qq = trmq**2 - trmp**3
2471              if( qq .ge. 0._r8 ) then
2472                  rootp = ( trmq + sqrt(qq) )**(1._r8/3._r8) + ( max( trmq - sqrt(qq), 0._r8 ) )**(1._r8/3._r8)
2473              else
2474                  rootp = 2._r8 * sqrt(trmp) * cos( acos( trmq / sqrt(trmp**3) ) / 3._r8 )
2475              end if
2476 
2477              ! Adjust 'wstar3' only if there is 'noroot'.
2478              ! And calculate entrainment rates at the top and base interfaces.
2479
2480              if( noroot )  wstar3 = ( rootp / ccrit )**3     ! Adjust wstar3
2481              wet = cet * wstar3                              ! Find entrainment rates
2482              if( kb .lt. pver + 1 ) web = ceb * wstar3       ! When 'kb.eq.pver+1', it was set to web=0.
2483
2484          else !
2485
2486              ! (Option.2) wstarentr = .false. Use original entrainment formulation.
2487              ! trmp > 0 if there are interior interfaces in CL, trmp = 0 otherwise.
2488              ! trmq > 0 if there is cloudtop radiative cooling, trmq = 0 otherwise.
2489             
2490              trma = 1._r8 - b1 * a1l * fact
2491              trma = max( trma, 0.5_r8 )  ! Prevents runaway entrainment instability
2492              trmp = ebrk(i,ncv) * ( lbrk(i,ncv) / lbulk ) / ( 3._r8 * trma )
2493              trmq = 0.5_r8 * b1 * ( leng(i,kt)  / lbulk ) * radf * dzht / trma
2494
2495              qq = trmq**2 - trmp**3
2496              if( qq .ge. 0._r8 ) then
2497                  rootp = ( trmq + sqrt(qq) )**(1._r8/3._r8) + ( max( trmq - sqrt(qq), 0._r8 ) )**(1._r8/3._r8)
2498              else ! Also part of case 3
2499                  rootp = 2._r8 * sqrt(trmp) * cos( acos( trmq / sqrt(trmp**3) ) / 3._r8 )
2500              end if   ! qq
2501
2502             ! Find entrainment rates and limit them by free-entrainment values a1l*sqrt(e)
2503
2504              wet = a1l * rootp * min( evhc * rootp**2 / ( leng(i,kt) * jtbu ), 1._r8 )   
2505              if( kb .lt. pver + 1 ) web = a1l * rootp * min( evhc * rootp**2 / ( leng(i,kb) * jbbu ), 1._r8 )
2506
2507          end if ! wstarentr
2508
2509          ! ---------------------------------------------------- !
2510          ! Finally, get the net CL mean TKE and normalized TKE  !
2511          ! ---------------------------------------------------- !
2512
2513          ebrk(i,ncv) = rootp**2
2514          ebrk(i,ncv) = min(ebrk(i,ncv),tkemax) ! Limit CL-avg TKE used for entrainment
2515          wbrk(i,ncv) = ebrk(i,ncv)/b1 
2516       
2517          ! The only way ebrk = 0 is for SRCL which are actually radiatively cooled
2518          ! at top interface. In this case, we remove 'convective' label from the
2519          ! interfaces around this layer. This case should now be impossible, so
2520          ! we flag it. Q: I can't understand why this case is impossible now. Maybe,
2521          ! due to various limiting procedures used in solving cubic equation ?
2522          ! In case of SRCL, 'ebrk' should be positive due to cloud top LW radiative
2523          ! cooling contribution, although 'ebrk(internal)' of SRCL before including
2524          ! entrainment contribution (which include LW cooling contribution also) is
2525          ! zero.
2526
2527          if( ebrk(i,ncv) .le. 0._r8 ) then
2528              write(iulog,*) 'CALEDDY: Warning, CL with zero TKE, i, kt, kb ', i, kt, kb
2529              belongcv(i,kt) = .false.
2530              belongcv(i,kb) = .false.
2531          end if
2532         
2533          ! ----------------------------------------------------------------------- !
2534          ! Calculate complete TKE profiles at all CL interfaces, capped by tkemax. !
2535          ! We approximate TKE = <e> at entrainment interfaces. However when CL is  !
2536          ! based at surface, correct 'tkes' will be inserted to tke(i,pver+1).     !
2537          ! Note that this approximation at CL external interfaces do not influence !
2538          ! numerical calculation since 'e' at external interfaces are not used  in !
2539          ! actual numerical calculation afterward. In addition in order to extract !
2540          ! correct TKE averaged over the PBL in the cumulus scheme,it is necessary !
2541          ! to set e = <e> at the top entrainment interface.  Since net CL mean TKE !
2542          ! 'ebrk' obtained by solving cubic equation already includes tkes  ( tkes !
2543          ! is included when bflxs > 0 but not when bflxs <= 0 into internal ebrk ),!
2544          ! 'tkes' should be written to tke(i,pver+1)                               !
2545          ! ----------------------------------------------------------------------- !
2546
2547          ! 1. At internal interfaces         
2548          do k = kb - 1, kt + 1, -1
2549             rcap = ( b1 * ae + wcap(i,k) / wbrk(i,ncv) ) / ( b1 * ae + 1._r8 )
2550             rcap = min( max(rcap,rcapmin), rcapmax )
2551             tke(i,k) = ebrk(i,ncv) * rcap
2552             tke(i,k) = min( tke(i,k), tkemax )
2553             kvh(i,k) = leng(i,k) * sqrt(tke(i,k)) * shcl(i,ncv)
2554             kvm(i,k) = leng(i,k) * sqrt(tke(i,k)) * smcl(i,ncv)
2555             bprod(i,k) = -kvh(i,k) * n2(i,k)
2556             sprod(i,k) =  kvm(i,k) * s2(i,k)
2557             turbtype(i,k) = 2                     ! CL interior interfaces.
2558             sm_aw(i,k) = smcl(i,ncv)/alph1        ! Diagnostic output for microphysics
2559          end do
2560
2561          ! 2. At CL top entrainment interface
2562          kentr = wet * jtzm
2563          kvh(i,kt) = kentr
2564          kvm(i,kt) = kentr
2565          bprod(i,kt) = -kentr * n2ht + radf       ! I must use 'n2ht' not 'n2'
2566          sprod(i,kt) =  kentr * s2(i,kt)
2567          turbtype(i,kt) = 4                       ! CL top entrainment interface
2568          trmp = -b1 * ae / ( 1._r8 + b1 * ae )
2569          trmq = -(bprod(i,kt)+sprod(i,kt))*b1*leng(i,kt)/(1._r8+b1*ae)/(ebrk(i,ncv)**(3._r8/2._r8))
2570          rcap = compute_cubic(0._r8,trmp,trmq)**2._r8
2571          rcap = min( max(rcap,rcapmin), rcapmax )
2572          tke(i,kt)  = ebrk(i,ncv) * rcap
2573          tke(i,kt)  = min( tke(i,kt), tkemax )
2574          sm_aw(i,kt) = smcl(i,ncv) / alph1        ! Diagnostic output for microphysics
2575
2576          ! 3. At CL base entrainment interface and double entraining interfaces
2577          ! When current CL base is also the top interface of CL regime below,
2578          ! simply add the two contributions for calculating eddy diffusivity
2579          ! and buoyancy/shear production. Below code correctly works because
2580          ! we (CL regime index) always go from surface upward.
2581
2582          if( kb .lt. pver + 1 ) then
2583
2584              kentr = web * jbzm
2585
2586              if( kb .ne. ktblw ) then
2587
2588                  kvh(i,kb) = kentr
2589                  kvm(i,kb) = kentr
2590                  bprod(i,kb) = -kvh(i,kb)*n2hb     ! I must use 'n2hb' not 'n2'
2591                  sprod(i,kb) =  kvm(i,kb)*s2(i,kb)
2592                  turbtype(i,kb) = 3                ! CL base entrainment interface
2593                  trmp = -b1*ae/(1._r8+b1*ae)
2594                  trmq = -(bprod(i,kb)+sprod(i,kb))*b1*leng(i,kb)/(1._r8+b1*ae)/(ebrk(i,ncv)**(3._r8/2._r8))
2595                  rcap = compute_cubic(0._r8,trmp,trmq)**2._r8
2596                  rcap = min( max(rcap,rcapmin), rcapmax )
2597                  tke(i,kb)  = ebrk(i,ncv) * rcap
2598                  tke(i,kb)  = min( tke(i,kb),tkemax )
2599
2600              else
2601                 
2602                  kvh(i,kb) = kvh(i,kb) + kentr
2603                  kvm(i,kb) = kvm(i,kb) + kentr
2604                ! dzhb5 : Half thickness of the lowest  layer of  current CL regime
2605                ! dzht5 : Half thickness of the highest layer of adjacent CL regime just below current CL.
2606                  dzhb5 = z(i,kb-1) - zi(i,kb)
2607                  dzht5 = zi(i,kb) - z(i,kb)
2608                  bprod(i,kb) = ( dzht5*bprod(i,kb) - dzhb5*kentr*n2hb )     / ( dzhb5 + dzht5 )
2609                  sprod(i,kb) = ( dzht5*sprod(i,kb) + dzhb5*kentr*s2(i,kb) ) / ( dzhb5 + dzht5 )
2610                  trmp = -b1*ae/(1._r8+b1*ae)
2611                  trmq = -kentr*(s2(i,kb)-n2hb)*b1*leng(i,kb)/(1._r8+b1*ae)/(ebrk(i,ncv)**(3._r8/2._r8))
2612                  rcap = compute_cubic(0._r8,trmp,trmq)**2._r8
2613                  rcap = min( max(rcap,rcapmin), rcapmax )
2614                  tke_imsi = ebrk(i,ncv) * rcap
2615                  tke_imsi = min( tke_imsi, tkemax )
2616                  tke(i,kb)  = ( dzht5*tke(i,kb) + dzhb5*tke_imsi ) / ( dzhb5 + dzht5 )               
2617                  tke(i,kb)  = min(tke(i,kb),tkemax)
2618                  turbtype(i,kb) = 5                ! CL double entraining interface     
2619                 
2620              end if
2621
2622           else
2623
2624             ! If CL base interface is surface, compute similarly using wcap(i,kb)=tkes/b1   
2625             ! Even when bflx < 0, use the same formula in order to impose consistency of
2626             ! tke(i,kb) at bflx = 0._r8
2627 
2628             rcap = (b1*ae + wcap(i,kb)/wbrk(i,ncv))/(b1*ae + 1._r8)
2629             rcap = min( max(rcap,rcapmin), rcapmax )
2630             tke(i,kb) = ebrk(i,ncv) * rcap
2631             tke(i,kb) = min( tke(i,kb),tkemax )
2632
2633          end if
2634
2635          ! For double entraining interface, simply use smcl(i,ncv) of the overlying CL.
2636          ! Below 'sm_aw' is a diagnostic output for use in the microphysics.
2637          ! When 'kb' is surface, 'sm' will be over-written later below.
2638
2639          sm_aw(i,kb) = smcl(i,ncv)/alph1             
2640
2641          ! Calculate wcap at all interfaces of CL. Put a  minimum threshold on TKE
2642          ! to prevent possible division by zero.  'wcap' at CL internal interfaces
2643          ! are already calculated in the first part of 'do ncv' loop correctly.
2644          ! When 'kb.eq.pver+1', below formula produces the identical result to the
2645          ! 'tkes(i)/b1' if leng(i,kb) is set to vk*z(i,pver). Note  wcap(i,pver+1)
2646          ! is already defined as 'tkes(i)/b1' at the first part of caleddy.
2647         
2648          wcap(i,kt) = (bprod(i,kt)+sprod(i,kt))*leng(i,kt)/sqrt(max(tke(i,kt),1.e-6_r8))
2649          if( kb .lt. pver + 1 ) then
2650              wcap(i,kb) = (bprod(i,kb)+sprod(i,kb))*leng(i,kb)/sqrt(max(tke(i,kb),1.e-6_r8))
2651          end if
2652
2653          ! Save the index of upper external interface of current CL-regime in order to
2654          ! handle the case when this interface is also the lower external interface of
2655          ! CL-regime located just above.
2656
2657          ktblw = kt
2658
2659          ! Diagnostic Output
2660
2661          wet_CL(i,ncv)        = wet
2662          web_CL(i,ncv)        = web
2663          jtbu_CL(i,ncv)       = jtbu
2664          jbbu_CL(i,ncv)       = jbbu
2665          evhc_CL(i,ncv)       = evhc
2666          jt2slv_CL(i,ncv)     = jt2slv
2667          n2ht_CL(i,ncv)       = n2ht
2668          n2hb_CL(i,ncv)       = n2hb         
2669          lwp_CL(i,ncv)        = lwp
2670          opt_depth_CL(i,ncv)  = opt_depth
2671          radinvfrac_CL(i,ncv) = radinvfrac
2672          radf_CL(i,ncv)       = radf
2673          wstar_CL(i,ncv)      = wstar         
2674          wstar3fact_CL(i,ncv) = wstar3fact         
2675
2676       end do        ! ncv
2677 
2678       ! Calculate PBL height and characteristic cumulus excess for use in the
2679       ! cumulus convection shceme. Also define turbulence type at the surface
2680       ! when the lowest CL is based at the surface. These are just diagnostic
2681       ! outputs, not influencing numerical calculation of current PBL scheme.
2682       ! If the lowest CL is based at the surface, define the PBL depth as the
2683       ! CL top interface. The same rule is applied for all CLs including SRCL.
2684
2685       if( ncvsurf .gt. 0 ) then
2686
2687           ktopbl(i) = ktop(i,ncvsurf)
2688           pblh(i)   = zi(i, ktopbl(i))
2689           pblhp(i)  = pi(i, ktopbl(i))
2690           wpert(i)  = max(wfac*sqrt(ebrk(i,ncvsurf)),wpertmin)
2691           tpert(i)  = max(abs(shflx(i)*rrho(i)/cpair)*tfac/wpert(i),0._r8)
2692           qpert(i)  = max(abs(qflx(i)*rrho(i))*tfac/wpert(i),0._r8)
2693
2694           if( bflxs(i) .gt. 0._r8 ) then
2695               turbtype(i,pver+1) = 2 ! CL interior interface
2696           else
2697               turbtype(i,pver+1) = 3 ! CL external base interface
2698           endif
2699
2700           ipbl(i)  = 1._r8
2701           kpblh(i) = ktopbl(i) - 1._r8
2702
2703       end if ! End of the calculationf of te properties of surface-based CL.
2704
2705       ! -------------------------------------------- !
2706       ! Treatment of Stable Turbulent Regime ( STL ) !
2707       ! -------------------------------------------- !
2708
2709       ! Identify top and bottom most (internal) interfaces of STL except surface.
2710       ! Also, calculate 'turbulent length scale (leng)' at each STL interfaces.     
2711
2712       belongst(i,1) = .false.   ! k = 1 (top interface) is assumed non-turbulent
2713       do k = 2, pver            ! k is an interface index
2714          belongst(i,k) = ( ri(i,k) .lt. ricrit ) .and. ( .not. belongcv(i,k) )
2715          if( belongst(i,k) .and. ( .not. belongst(i,k-1) ) ) then
2716              kt = k             ! Top interface index of STL
2717          elseif( .not. belongst(i,k) .and. belongst(i,k-1) ) then
2718              kb = k - 1         ! Base interface index of STL
2719              lbulk = z(i,kt-1) - z(i,kb)
2720              do ks = kt, kb
2721                 if( choice_tunl .eq. 'rampcl' ) then
2722                     tunlramp = tunl
2723                 elseif( choice_tunl .eq. 'rampsl' ) then
2724                    tunlramp = max( 1.e-3_r8, ctunl * tunl * exp(-log(ctunl)*ri(i,ks)/ricrit) )
2725                  ! tunlramp = 0.065_r8 + 0.7_r8 * exp(-20._r8*ri(i,ks))
2726                 else
2727                    tunlramp = tunl
2728                 endif
2729                 if( choice_leng .eq. 'origin' ) then
2730                     leng(i,ks) = ( (vk*zi(i,ks))**(-cleng) + (tunlramp*lbulk)**(-cleng) )**(-1._r8/cleng)
2731                   ! leng(i,ks) = vk*zi(i,ks) / (1._r8+vk*zi(i,ks)/(tunlramp*lbulk))
2732                 else
2733                     leng(i,ks) = min( vk*zi(i,ks), tunlramp*lbulk )             
2734                 endif
2735              end do
2736          end if
2737       end do ! k
2738
2739       ! Now look whether STL extends to ground.  If STL extends to surface,
2740       ! re-define master length scale,'lbulk' including surface interfacial
2741       ! layer thickness, and re-calculate turbulent length scale, 'leng' at
2742       ! all STL interfaces again. Note that surface interface is assumed to
2743       ! always be STL if it is not CL.   
2744       
2745       belongst(i,pver+1) = .not. belongcv(i,pver+1)
2746
2747       if( belongst(i,pver+1) ) then     ! kb = pver+1 (surface  STL)
2748
2749           turbtype(i,pver+1) = 1        ! Surface is STL interface
2750         
2751           if( belongst(i,pver) ) then   ! STL includes interior
2752             ! 'kt' already defined above as the top interface of STL
2753               lbulk = z(i,kt-1)         
2754           else                          ! STL with no interior turbulence
2755               kt = pver+1
2756               lbulk = z(i,kt-1)
2757           end if
2758
2759           ! PBL height : Layer mid-point just above the highest STL interface
2760           ! Note in contrast to the surface based CL regime where  PBL height
2761           ! was defined at the top external interface, PBL height of  surface
2762           ! based STL is defined as the layer mid-point.
2763
2764           ktopbl(i) = kt - 1
2765           pblh(i)   = z(i,ktopbl(i))
2766           pblhp(i)  = 0.5_r8 * ( pi(i,ktopbl(i)) + pi(i,ktopbl(i)+1) )         
2767
2768           ! Re-calculate turbulent length scale including surface interfacial
2769           ! layer contribution to lbulk.
2770
2771           do ks = kt, pver
2772              if( choice_tunl .eq. 'rampcl' ) then
2773                  tunlramp = tunl
2774              elseif( choice_tunl .eq. 'rampsl' ) then
2775                  tunlramp = max(1.e-3_r8,ctunl*tunl*exp(-log(ctunl)*ri(i,ks)/ricrit))
2776                ! tunlramp = 0.065_r8 + 0.7_r8 * exp(-20._r8*ri(i,ks))
2777              else
2778                  tunlramp = tunl
2779              endif
2780              if( choice_leng .eq. 'origin' ) then
2781                  leng(i,ks) = ( (vk*zi(i,ks))**(-cleng) + (tunlramp*lbulk)**(-cleng) )**(-1._r8/cleng)
2782                ! leng(i,ks) = vk*zi(i,ks) / (1._r8+vk*zi(i,ks)/(tunlramp*lbulk))
2783              else
2784                  leng(i,ks) = min( vk*zi(i,ks), tunlramp*lbulk )             
2785              endif
2786           end do ! ks
2787
2788           ! Characteristic cumulus excess of surface-based STL.
2789           ! We may be able to use ustar for wpert.
2790
2791           wpert(i) = 0._r8
2792           tpert(i) = max(shflx(i)*rrho(i)/cpair*fak/ustar(i),0._r8) ! CCM stable-layer forms
2793           qpert(i) = max(qflx(i)*rrho(i)*fak/ustar(i),0._r8)
2794
2795           ipbl(i)  = 0._r8
2796           kpblh(i) = ktopbl(i)
2797
2798       end if
2799
2800       ! Calculate stability functions and energetics at the STL interfaces
2801       ! except the surface. Note that tke(i,pver+1) and wcap(i,pver+1) are
2802       ! already calculated in the first part of 'caleddy', kvm(i,pver+1) &
2803       ! kvh(i,pver+1) were already initialized to be zero, bprod(i,pver+1)
2804       ! & sprod(i,pver+1) were direcly calculated from the bflxs and ustar.
2805       ! Note transport term is assumed to be negligible at STL interfaces.
2806           
2807       do k = 2, pver
2808
2809          if( belongst(i,k) ) then
2810
2811              turbtype(i,k) = 1    ! STL interfaces
2812              trma = alph3*alph4exs*ri(i,k) + 2._r8*b1*(alph2-alph4exs*alph5*ri(i,k))
2813              trmb = (alph3+alph4exs)*ri(i,k) + 2._r8*b1*(-alph5*ri(i,k)+alph1)
2814              trmc = ri(i,k)
2815              det = max(trmb*trmb-4._r8*trma*trmc,0._r8)
2816              ! Sanity Check
2817              if( det .lt. 0._r8 ) then
2818                  write(iulog,*) 'The det < 0. for the STL in UW eddy_diff'             
2819                  stop
2820              end if                 
2821              gh = (-trmb + sqrt(det))/(2._r8*trma)
2822            ! gh = min(max(gh,-0.28_r8),0.0233_r8)
2823            ! gh = min(max(gh,-3.5334_r8),0.0233_r8)
2824              gh = min(max(gh,ghmin),0.0233_r8)
2825              sh = max(0._r8,alph5/(1._r8+alph3*gh))
2826              sm = max(0._r8,(alph1 + alph2*gh)/(1._r8+alph3*gh)/(1._r8+alph4exs*gh))
2827
2828              tke(i,k)   = b1*(leng(i,k)**2)*(-sh*n2(i,k)+sm*s2(i,k))
2829              tke(i,k)   = min(tke(i,k),tkemax)
2830              wcap(i,k)  = tke(i,k)/b1
2831              kvh(i,k)   = leng(i,k) * sqrt(tke(i,k)) * sh
2832              kvm(i,k)   = leng(i,k) * sqrt(tke(i,k)) * sm
2833              bprod(i,k) = -kvh(i,k) * n2(i,k)
2834              sprod(i,k) =  kvm(i,k) * s2(i,k)
2835
2836              sm_aw(i,k) = sm/alph1     ! This is diagnostic output for use in the microphysics             
2837
2838          end if
2839
2840       end do  ! k
2841
2842       ! --------------------------------------------------- !
2843       ! End of treatment of Stable Turbulent Regime ( STL ) !
2844       ! --------------------------------------------------- !
2845
2846       ! --------------------------------------------------------------- !
2847       ! Re-computation of eddy diffusivity at the entrainment interface !
2848       ! assuming that it is purely STL (0<Ri<0.19). Note even Ri>0.19,  !
2849       ! turbulent can exist at the entrainment interface since 'Sh,Sm'  !
2850       ! do not necessarily go to zero even when Ri>0.19. Since Ri can   !
2851       ! be fairly larger than 0.19 at the entrainment interface, I      !
2852       ! should set minimum value of 'tke' to be 0. in order to prevent  !
2853       ! sqrt(tke) from being imaginary.                                 !
2854       ! --------------------------------------------------------------- !
2855
2856       ! goto 888
2857
2858         do k = 2, pver
2859
2860         if( ( turbtype(i,k) .eq. 3 ) .or. ( turbtype(i,k) .eq. 4 ) .or. &
2861             ( turbtype(i,k) .eq. 5 ) ) then
2862
2863             trma = alph3*alph4exs*ri(i,k) + 2._r8*b1*(alph2-alph4exs*alph5*ri(i,k))
2864             trmb = (alph3+alph4exs)*ri(i,k) + 2._r8*b1*(-alph5*ri(i,k)+alph1)
2865             trmc = ri(i,k)
2866             det  = max(trmb*trmb-4._r8*trma*trmc,0._r8)
2867             gh   = (-trmb + sqrt(det))/(2._r8*trma)
2868           ! gh   = min(max(gh,-0.28_r8),0.0233_r8)
2869           ! gh   = min(max(gh,-3.5334_r8),0.0233_r8)
2870             gh   = min(max(gh,ghmin),0.0233_r8)
2871             sh   = max(0._r8,alph5/(1._r8+alph3*gh))
2872             sm   = max(0._r8,(alph1 + alph2*gh)/(1._r8+alph3*gh)/(1._r8+alph4exs*gh))
2873
2874             lbulk = z(i,k-1) - z(i,k)
2875
2876             if( choice_tunl .eq. 'rampcl' ) then
2877                 tunlramp = tunl
2878             elseif( choice_tunl .eq. 'rampsl' ) then
2879                 tunlramp = max(1.e-3_r8,ctunl*tunl*exp(-log(ctunl)*ri(i,k)/ricrit))
2880               ! tunlramp = 0.065_r8 + 0.7_r8*exp(-20._r8*ri(i,k))
2881             else
2882                 tunlramp = tunl
2883             endif
2884             if( choice_leng .eq. 'origin' ) then
2885                 leng_imsi = ( (vk*zi(i,k))**(-cleng) + (tunlramp*lbulk)**(-cleng) )**(-1._r8/cleng)
2886               ! leng_imsi = vk*zi(i,k) / (1._r8+vk*zi(i,k)/(tunlramp*lbulk))
2887             else
2888                 leng_imsi = min( vk*zi(i,k), tunlramp*lbulk )             
2889             endif
2890
2891             tke_imsi = b1*(leng_imsi**2)*(-sh*n2(i,k)+sm*s2(i,k))
2892             tke_imsi = min(max(tke_imsi,0._r8),tkemax)
2893             kvh_imsi = leng_imsi * sqrt(tke_imsi) * sh
2894             kvm_imsi = leng_imsi * sqrt(tke_imsi) * sm
2895
2896             if( kvh(i,k) .lt. kvh_imsi ) then
2897                 kvh(i,k)   =  kvh_imsi
2898                 kvm(i,k)   =  kvm_imsi
2899                 leng(i,k)  = leng_imsi
2900                 tke(i,k)   =  tke_imsi
2901                 wcap(i,k)  =  tke_imsi / b1
2902                 bprod(i,k) = -kvh_imsi * n2(i,k)
2903                 sprod(i,k) =  kvm_imsi * s2(i,k)
2904                 sm_aw(i,k) =  sm/alph1     ! This is diagnostic output for use in the microphysics             
2905                 turbtype(i,k) = 1          ! This was added on Dec.10.2009 for use in microphysics.
2906             endif
2907
2908         end if
2909
2910         end do
2911
2912 ! 888   continue
2913
2914       ! ------------------------------------------------------------------ !
2915       ! End of recomputation of eddy diffusivity at entrainment interfaces !
2916       ! ------------------------------------------------------------------ !
2917
2918       ! As an option, we can impose a certain minimum back-ground diffusivity.
2919
2920       ! do k = 1, pver+1
2921       !    kvh(i,k) = max(0.01_r8,kvh(i,k))
2922       !    kvm(i,k) = max(0.01_r8,kvm(i,k))
2923       ! enddo
2924 
2925       ! --------------------------------------------------------------------- !
2926       ! Diagnostic Output                                                     !
2927       ! Just for diagnostic purpose, calculate stability functions at  each   !
2928       ! interface including surface. Instead of assuming neutral stability,   !
2929       ! explicitly calculate stability functions using an reverse procedure   !
2930       ! starting from tkes(i) similar to the case of SRCL and SBCL in zisocl. !
2931       ! Note that it is possible to calculate stability functions even when   !
2932       ! bflxs < 0. Note that this inverse method allows us to define Ri even  !
2933       ! at the surface. Note also tkes(i) and sprod(i,pver+1) are always      !
2934       ! positive values by limiters (e.g., ustar_min = 0.01).                 !
2935       ! Dec.12.2006 : Also just for diagnostic output, re-set                 !
2936       ! 'bprod(i,pver+1)= bflxs(i)' here. Note that this setting does not     !
2937       ! influence numerical calculation at all - it is just for diagnostic    !
2938       ! output.                                                               !
2939       ! --------------------------------------------------------------------- !
2940
2941       bprod(i,pver+1) = bflxs(i)
2942             
2943       gg = 0.5_r8*vk*z(i,pver)*bprod(i,pver+1)/(tkes(i)**(3._r8/2._r8))
2944       if( abs(alph5-gg*alph3) .le. 1.e-7_r8 ) then
2945         ! gh = -0.28_r8
2946           if( bprod(i,pver+1) .gt. 0._r8 ) then
2947               gh = -3.5334_r8
2948           else
2949               gh = ghmin
2950           endif
2951       else   
2952           gh = gg/(alph5-gg*alph3)
2953       end if
2954
2955     ! gh = min(max(gh,-0.28_r8),0.0233_r8)
2956       if( bprod(i,pver+1) .gt. 0._r8 ) then
2957           gh = min(max(gh,-3.5334_r8),0.0233_r8)
2958       else
2959           gh = min(max(gh,ghmin),0.0233_r8)
2960       endif
2961
2962       gh_a(i,pver+1) = gh     
2963       sh_a(i,pver+1) = max(0._r8,alph5/(1._r8+alph3*gh))
2964       if( bprod(i,pver+1) .gt. 0._r8 ) then       
2965           sm_a(i,pver+1) = max(0._r8,(alph1+alph2*gh)/(1._r8+alph3*gh)/(1._r8+alph4*gh))
2966       else
2967           sm_a(i,pver+1) = max(0._r8,(alph1+alph2*gh)/(1._r8+alph3*gh)/(1._r8+alph4exs*gh))
2968       endif
2969       sm_aw(i,pver+1) = sm_a(i,pver+1)/alph1
2970       ri_a(i,pver+1)  = -(sm_a(i,pver+1)/sh_a(i,pver+1))*(bprod(i,pver+1)/sprod(i,pver+1))
2971
2972       do k = 1, pver
2973          if( ri(i,k) .lt. 0._r8 ) then
2974              trma = alph3*alph4*ri(i,k) + 2._r8*b1*(alph2-alph4*alph5*ri(i,k))
2975              trmb = (alph3+alph4)*ri(i,k) + 2._r8*b1*(-alph5*ri(i,k)+alph1)
2976              trmc = ri(i,k)
2977              det  = max(trmb*trmb-4._r8*trma*trmc,0._r8)
2978              gh   = (-trmb + sqrt(det))/(2._r8*trma)
2979              gh   = min(max(gh,-3.5334_r8),0.0233_r8)
2980              gh_a(i,k) = gh
2981              sh_a(i,k) = max(0._r8,alph5/(1._r8+alph3*gh))
2982              sm_a(i,k) = max(0._r8,(alph1+alph2*gh)/(1._r8+alph3*gh)/(1._r8+alph4*gh))
2983              ri_a(i,k) = ri(i,k)
2984          else
2985              if( ri(i,k) .gt. ricrit ) then
2986                  gh_a(i,k) = ghmin
2987                  sh_a(i,k) = 0._r8
2988                  sm_a(i,k) = 0._r8
2989                  ri_a(i,k) = ri(i,k)
2990              else
2991                  trma = alph3*alph4exs*ri(i,k) + 2._r8*b1*(alph2-alph4exs*alph5*ri(i,k))
2992                  trmb = (alph3+alph4exs)*ri(i,k) + 2._r8*b1*(-alph5*ri(i,k)+alph1)
2993                  trmc = ri(i,k)
2994                  det  = max(trmb*trmb-4._r8*trma*trmc,0._r8)
2995                  gh   = (-trmb + sqrt(det))/(2._r8*trma)
2996                  gh   = min(max(gh,ghmin),0.0233_r8)
2997                  gh_a(i,k) = gh
2998                  sh_a(i,k) = max(0._r8,alph5/(1._r8+alph3*gh))
2999                  sm_a(i,k) = max(0._r8,(alph1+alph2*gh)/(1._r8+alph3*gh)/(1._r8+alph4exs*gh))
3000                  ri_a(i,k) = ri(i,k)
3001              endif
3002          endif
3003
3004       end do
3005
3006       do k = 1, pver + 1
3007          turbtype_f(i,k) = real(turbtype(i,k))
3008       end do
3009
3010    end do   ! End of column index loop, i
3011
3012    return
3013
3014    end subroutine caleddy
3015
3016    !============================================================================== !
3017    !                                                                               !
3018    !============================================================================== !
3019
3020    subroutine exacol( pcols, pver, ncol, ri, bflxs, minpblh, zi, ktop, kbase, ncvfin )
3021
3022    ! ---------------------------------------------------------------------------- !
3023    ! Object : Find unstable CL regimes and determine the indices                  !
3024    !          kbase, ktop which delimit these unstable layers :                   !
3025    !          ri(kbase) > 0 and ri(ktop) > 0, but ri(k) < 0 for ktop < k < kbase. !
3026    ! Author : Chris  Bretherton 08/2000,                                          !
3027    !          Sungsu Park       08/2006, 11/2008                                  !
3028    !----------------------------------------------------------------------------- !
3029
3030    implicit none
3031
3032    ! --------------- !
3033    ! Input variables !
3034    ! --------------- !
3035
3036    integer,  intent(in) :: pcols                  ! Number of atmospheric columns   
3037    integer,  intent(in) :: pver                   ! Number of atmospheric vertical layers   
3038    integer,  intent(in) :: ncol                   ! Number of atmospheric columns   
3039
3040    real(r8), intent(in) :: ri(pcols,pver)         ! Moist gradient Richardson no.
3041    real(r8), intent(in) :: bflxs(pcols)           ! Buoyancy flux at surface
3042    real(r8), intent(in) :: minpblh(pcols)         ! Minimum PBL height based on surface stress
3043    real(r8), intent(in) :: zi(pcols,pver+1)       ! Interface heights
3044
3045    ! ---------------- !
3046    ! Output variables !     
3047    ! ---------------- !
3048
3049    integer, intent(out) :: kbase(pcols,ncvmax)    ! External interface index of CL base
3050    integer, intent(out) :: ktop(pcols,ncvmax)     ! External interface index of CL top
3051    integer, intent(out) :: ncvfin(pcols)          ! Total number of CLs
3052
3053    ! --------------- !
3054    ! Local variables !
3055    ! --------------- !
3056
3057    integer              :: i
3058    integer              :: k
3059    integer              :: ncv
3060    real(r8)             :: rimaxentr
3061    real(r8)             :: riex(pver+1)           ! Column Ri profile extended to surface
3062
3063    ! ----------------------- !
3064    ! Main Computation Begins !
3065    ! ----------------------- !
3066
3067    do i = 1, ncol
3068       ncvfin(i) = 0
3069       do ncv = 1, ncvmax
3070          ktop(i,ncv)  = 0
3071          kbase(i,ncv) = 0
3072       end do
3073    end do
3074
3075    ! ------------------------------------------------------ !
3076    ! Find CL regimes starting from the surface going upward !
3077    ! ------------------------------------------------------ !
3078   
3079    rimaxentr = 0._r8   
3080   
3081    do i = 1, ncol
3082
3083       riex(2:pver) = ri(i,2:pver)
3084
3085       ! Below allows consistent treatment of surface and other interfaces.
3086       ! Simply, if surface buoyancy flux is positive, Ri of surface is set to be negative.
3087
3088       riex(pver+1) = rimaxentr - bflxs(i)
3089
3090       ncv = 0
3091       k   = pver + 1 ! Work upward from surface interface
3092
3093       do while ( k .gt. ntop_turb + 1 )
3094
3095        ! Below means that if 'bflxs > 0' (do not contain '=' sign), surface
3096        ! interface is energetically interior surface.
3097       
3098          if( riex(k) .lt. rimaxentr ) then
3099
3100              ! Identify a new CL
3101
3102              ncv = ncv + 1
3103
3104              ! First define 'kbase' as the first interface below the lower-most unstable interface
3105              ! Thus, Richardson number at 'kbase' is positive.
3106
3107              kbase(i,ncv) = min(k+1,pver+1)
3108
3109              ! Decrement k until top unstable level
3110
3111              do while( riex(k) .lt. rimaxentr .and. k .gt. ntop_turb + 1 )
3112                 k = k - 1
3113              end do
3114
3115              ! ktop is the first interface above upper-most unstable interface
3116              ! Thus, Richardson number at 'ktop' is positive.
3117
3118              ktop(i,ncv) = k
3119             
3120          else
3121
3122              ! Search upward for a CL.
3123
3124              k = k - 1
3125
3126          end if
3127
3128       end do ! End of CL regime finding for each atmospheric column
3129
3130       ncvfin(i) = ncv   
3131
3132    end do  ! End of atmospheric column do loop
3133
3134    return
3135
3136    end subroutine exacol
3137
3138    !============================================================================== !
3139    !                                                                               !
3140    !============================================================================== !
3141   
3142    subroutine zisocl( pcols  , pver  , long ,                                 &
3143                       z      , zi    , n2   ,  s2      ,                      &
3144                       bprod  , sprod , bflxs,  tkes    ,                      &
3145                       ncvfin , kbase , ktop ,  belongcv,                      &
3146                       ricl   , ghcl  , shcl ,  smcl    ,                      &
3147                       lbrk   , wbrk  , ebrk ,  extend  , extend_up, extend_dn )
3148
3149    !------------------------------------------------------------------------ !
3150    ! Object : This 'zisocl' vertically extends original CLs identified from  !
3151    !          'exacol' using a merging test based on either 'wint' or 'l2n2' !
3152    !          and identify new CL regimes. Similar to the case of 'exacol',  !
3153    !          CL regime index increases with height.  After identifying new  !
3154    !          CL regimes ( kbase, ktop, ncvfin ),calculate CL internal mean  !
3155    !          energetics (lbrk : energetic thickness integral, wbrk, ebrk )  !
3156    !          and stability functions (ricl, ghcl, shcl, smcl) by including  !
3157    !          surface interfacial layer contribution when bflxs > 0.   Note  !
3158    !          that there are two options in the treatment of the energetics  !
3159    !          of surface interfacial layer (use_dw_surf= 'true' or 'false')  !
3160    ! Author : Sungsu Park 08/2006, 11/2008                                   !
3161    !------------------------------------------------------------------------ !
3162
3163    implicit none
3164
3165    ! --------------- !   
3166    ! Input variables !
3167    ! --------------- !
3168
3169    integer,  intent(in)   :: long                    ! Longitude of the column
3170    integer,  intent(in)   :: pcols                   ! Number of atmospheric columns   
3171    integer,  intent(in)   :: pver                    ! Number of atmospheric vertical layers   
3172    real(r8), intent(in)   :: z(pcols, pver)          ! Layer mid-point height [ m ]
3173    real(r8), intent(in)   :: zi(pcols, pver+1)       ! Interface height [ m ]
3174    real(r8), intent(in)   :: n2(pcols, pver)         ! Buoyancy frequency at interfaces except surface [ s-2 ]
3175    real(r8), intent(in)   :: s2(pcols, pver)         ! Shear frequency at interfaces except surface [ s-2 ]
3176    real(r8), intent(in)   :: bprod(pcols,pver+1)     ! Buoyancy production [ m2/s3 ]. bprod(i,pver+1) = bflxs
3177    real(r8), intent(in)   :: sprod(pcols,pver+1)     ! Shear production [ m2/s3 ]. sprod(i,pver+1) = usta**3/(vk*z(i,pver))
3178    real(r8), intent(in)   :: bflxs(pcols)            ! Surface buoyancy flux [ m2/s3 ]. bprod(i,pver+1) = bflxs
3179    real(r8), intent(in)   :: tkes(pcols)             ! TKE at the surface [ s2/s2 ]
3180
3181    ! ---------------------- !
3182    ! Input/output variables !
3183    ! ---------------------- !
3184
3185    integer, intent(inout) :: kbase(pcols,ncvmax)     ! Base external interface index of CL
3186    integer, intent(inout) :: ktop(pcols,ncvmax)      ! Top external interface index of CL
3187    integer, intent(inout) :: ncvfin(pcols)           ! Total number of CLs
3188
3189    ! ---------------- !
3190    ! Output variables !
3191    ! ---------------- !
3192
3193    logical,  intent(out) :: belongcv(pcols,pver+1)   ! True if interface is in a CL ( either internal or external )
3194    real(r8), intent(out) :: ricl(pcols,ncvmax)       ! Mean Richardson number of internal CL
3195    real(r8), intent(out) :: ghcl(pcols,ncvmax)       ! Half of normalized buoyancy production of internal CL
3196    real(r8), intent(out) :: shcl(pcols,ncvmax)       ! Galperin instability function of heat-moisture of internal CL
3197    real(r8), intent(out) :: smcl(pcols,ncvmax)       ! Galperin instability function of momentum of internal CL
3198    real(r8), intent(out) :: lbrk(pcols,ncvmax)       ! Thickness of (energetically) internal CL ( lint, [m] )
3199    real(r8), intent(out) :: wbrk(pcols,ncvmax)       ! Mean normalized TKE of internal CL  [ m2/s2 ]
3200    real(r8), intent(out) :: ebrk(pcols,ncvmax)       ! Mean TKE of internal CL ( b1*wbrk, [m2/s2] )
3201
3202    ! ------------------ !
3203    ! Internal variables !
3204    ! ------------------ !
3205
3206    logical               :: extend                   ! True when CL is extended in zisocl
3207    logical               :: extend_up                ! True when CL is extended upward in zisocl
3208    logical               :: extend_dn                ! True when CL is extended downward in zisocl
3209    logical               :: bottom                   ! True when CL base is at surface ( kb = pver + 1 )
3210
3211    integer               :: i                        ! Local index for the longitude
3212    integer               :: ncv                      ! CL Index increasing with height
3213    integer               :: incv
3214    integer               :: k
3215    integer               :: kb                       ! Local index for kbase
3216    integer               :: kt                       ! Local index for ktop
3217    integer               :: ncvinit                  ! Value of ncv at routine entrance
3218    integer               :: cntu                     ! Number of merged CLs during upward   extension of individual CL
3219    integer               :: cntd                     ! Number of merged CLs during downward extension of individual CL
3220    integer               :: kbinc                    ! Index for incorporating underlying CL
3221    integer               :: ktinc                    ! Index for incorporating  overlying CL
3222
3223    real(r8)              :: wint                     ! Normalized TKE of internal CL
3224    real(r8)              :: dwinc                    ! Normalized TKE of CL external interfaces
3225    real(r8)              :: dw_surf                  ! Normalized TKE of surface interfacial layer
3226    real(r8)              :: dzinc
3227    real(r8)              :: gh
3228    real(r8)              :: sh
3229    real(r8)              :: sm
3230    real(r8)              :: gh_surf                  ! Half of normalized buoyancy production in surface interfacial layer
3231    real(r8)              :: sh_surf                  ! Galperin instability function in surface interfacial layer 
3232    real(r8)              :: sm_surf                  ! Galperin instability function in surface interfacial layer
3233    real(r8)              :: l2n2                     ! Vertical integral of 'l^2N^2' over CL. Include thickness product
3234    real(r8)              :: l2s2                     ! Vertical integral of 'l^2S^2' over CL. Include thickness product
3235    real(r8)              :: dl2n2                    ! Vertical integration of 'l^2*N^2' of CL external interfaces
3236    real(r8)              :: dl2s2                    ! Vertical integration of 'l^2*S^2' of CL external interfaces
3237    real(r8)              :: dl2n2_surf               ! 'dl2n2' defined in the surface interfacial layer
3238    real(r8)              :: dl2s2_surf               ! 'dl2s2' defined in the surface interfacial layer 
3239    real(r8)              :: lint                     ! Thickness of (energetically) internal CL
3240    real(r8)              :: dlint                    ! Interfacial layer thickness of CL external interfaces
3241    real(r8)              :: dlint_surf               ! Surface interfacial layer thickness
3242    real(r8)              :: lbulk                    ! Master Length Scale : Whole CL thickness from top to base external interface
3243    real(r8)              :: lz                       ! Turbulent length scale
3244    real(r8)              :: ricll                    ! Mean Richardson number of internal CL
3245    real(r8)              :: trma
3246    real(r8)              :: trmb
3247    real(r8)              :: trmc
3248    real(r8)              :: det
3249    real(r8)              :: zbot                     ! Height of CL base
3250    real(r8)              :: l2rat                    ! Square of ratio of actual to initial CL (not used)
3251    real(r8)              :: gg                       ! Intermediate variable used for calculating stability functions of SBCL
3252    real(r8)              :: tunlramp                 ! Ramping tunl
3253
3254    ! ----------------------- !
3255    ! Main Computation Begins !
3256    ! ----------------------- !
3257
3258    i = long
3259
3260    ! Initialize main output variables
3261   
3262    do k = 1, ncvmax
3263       ricl(i,k) = 0._r8
3264       ghcl(i,k) = 0._r8
3265       shcl(i,k) = 0._r8
3266       smcl(i,k) = 0._r8
3267       lbrk(i,k) = 0._r8
3268       wbrk(i,k) = 0._r8
3269       ebrk(i,k) = 0._r8
3270    end do
3271    extend    = .false.
3272    extend_up = .false.
3273    extend_dn = .false.
3274
3275    ! ----------------------------------------------------------- !
3276    ! Loop over each CL to see if any of them need to be extended !
3277    ! ----------------------------------------------------------- !
3278
3279    ncv = 1
3280
3281    do while( ncv .le. ncvfin(i) )
3282
3283       ncvinit = ncv
3284       cntu    = 0
3285       cntd    = 0
3286       kb      = kbase(i,ncv)
3287       kt      = ktop(i,ncv)
3288       
3289       ! ---------------------------------------------------------------------------- !
3290       ! Calculation of CL interior energetics including surface before extension     !
3291       ! ---------------------------------------------------------------------------- !
3292       ! Note that the contribution of interior interfaces (not surface) to 'wint' is !
3293       ! accounted by using '-sh*l2n2 + sm*l2s2' while the contribution of surface is !
3294       ! accounted by using 'dwsurf = tkes/b1' when bflxs > 0. This approach is fully !
3295       ! reasonable. Another possible alternative,  which seems to be also consistent !
3296       ! is to calculate 'dl2n2_surf'  and  'dl2s2_surf' of surface interfacial layer !
3297       ! separately, and this contribution is explicitly added by initializing 'l2n2' !
3298       ! 'l2s2' not by zero, but by 'dl2n2_surf' and 'ds2n2_surf' below.  At the same !
3299       ! time, 'dwsurf' should be excluded in 'wint' calculation below. The only diff.!
3300       ! between two approaches is that in case of the latter approach, contributions !
3301       ! of surface interfacial layer to the CL mean stability function (ri,gh,sh,sm) !
3302       ! are explicitly included while the first approach is not. In this sense,  the !
3303       ! second approach seems to be more conceptually consistent,   but currently, I !
3304       ! (Sungsu) will keep the first default approach. There is a switch             !
3305       ! 'use_dw_surf' at the first part of eddy_diff.F90 chosing one of              !
3306       ! these two options.                                                           !
3307       ! ---------------------------------------------------------------------------- !
3308       
3309       ! ------------------------------------------------------ !   
3310       ! Step 0: Calculate surface interfacial layer energetics !
3311       ! ------------------------------------------------------ !
3312
3313       lbulk      = zi(i,kt) - zi(i,kb)
3314       dlint_surf = 0._r8
3315       dl2n2_surf = 0._r8
3316       dl2s2_surf = 0._r8
3317       dw_surf    = 0._r8
3318       if( kb .eq. pver+1 ) then
3319
3320           if( bflxs(i) .gt. 0._r8 ) then
3321
3322               ! Calculate stability functions of surface interfacial layer
3323               ! from the given 'bprod(i,pver+1)' and 'sprod(i,pver+1)' using
3324               ! inverse approach. Since alph5>0 and alph3<0, denominator of
3325               ! gg is always positive if bprod(i,pver+1)>0.               
3326
3327               gg    = 0.5_r8*vk*z(i,pver)*bprod(i,pver+1)/(tkes(i)**(3._r8/2._r8))
3328               gh    = gg/(alph5-gg*alph3)
3329             ! gh    = min(max(gh,-0.28_r8),0.0233_r8)
3330               gh    = min(max(gh,-3.5334_r8),0.0233_r8)
3331               sh    = alph5/(1._r8+alph3*gh)
3332               sm    = (alph1 + alph2*gh)/(1._r8+alph3*gh)/(1._r8+alph4*gh)
3333               ricll = min(-(sm/sh)*(bprod(i,pver+1)/sprod(i,pver+1)),ricrit)
3334
3335               ! Calculate surface interfacial layer contribution to CL internal
3336               ! energetics. By construction, 'dw_surf = -dl2n2_surf + ds2n2_surf'
3337               ! is exactly satisfied, which corresponds to assuming turbulent
3338               ! length scale of surface interfacial layer = vk * z(i,pver). Note
3339               ! 'dl2n2_surf','dl2s2_surf','dw_surf' include thickness product.   
3340
3341               dlint_surf = z(i,pver)
3342               dl2n2_surf = -vk*(z(i,pver)**2)*bprod(i,pver+1)/(sh*sqrt(tkes(i)))
3343               dl2s2_surf =  vk*(z(i,pver)**2)*sprod(i,pver+1)/(sm*sqrt(tkes(i)))
3344               dw_surf    = (tkes(i)/b1)*z(i,pver)
3345
3346           else
3347
3348               ! Note that this case can happen when surface is an external
3349               ! interface of CL.
3350               lbulk = zi(i,kt) - z(i,pver)
3351
3352           end if
3353
3354       end if
3355           
3356       ! ------------------------------------------------------ !   
3357       ! Step 1: Include surface interfacial layer contribution !
3358       ! ------------------------------------------------------ !
3359       
3360       lint = dlint_surf
3361       l2n2 = dl2n2_surf
3362       l2s2 = dl2s2_surf         
3363       wint = dw_surf
3364       if( use_dw_surf ) then
3365           l2n2 = 0._r8
3366           l2s2 = 0._r8
3367       else
3368           wint = 0._r8
3369       end if   
3370       
3371       ! --------------------------------------------------------------------------------- !
3372       ! Step 2. Include the contribution of 'pure internal interfaces' other than surface !
3373       ! --------------------------------------------------------------------------------- !
3374       
3375       if( kt .lt. kb - 1 ) then ! The case of non-SBCL.
3376                             
3377           do k = kb - 1, kt + 1, -1       
3378              if( choice_tunl .eq. 'rampcl' ) then
3379                ! Modification : I simply used the average tunlramp between the two limits.
3380                  tunlramp = 0.5_r8*(1._r8+ctunl)*tunl
3381              elseif( choice_tunl .eq. 'rampsl' ) then
3382                  tunlramp = ctunl*tunl
3383                ! tunlramp = 0.765_r8
3384              else
3385                  tunlramp = tunl
3386              endif
3387              if( choice_leng .eq. 'origin' ) then
3388                  lz = ( (vk*zi(i,k))**(-cleng) + (tunlramp*lbulk)**(-cleng) )**(-1._r8/cleng)
3389                ! lz = vk*zi(i,k) / (1._r8+vk*zi(i,k)/(tunlramp*lbulk))
3390              else
3391                  lz = min( vk*zi(i,k), tunlramp*lbulk )             
3392              endif
3393              dzinc = z(i,k-1) - z(i,k)
3394              l2n2  = l2n2 + lz*lz*n2(i,k)*dzinc
3395              l2s2  = l2s2 + lz*lz*s2(i,k)*dzinc
3396              lint  = lint + dzinc
3397           end do
3398
3399           ! Calculate initial CL stability functions (gh,sh,sm) and net
3400           ! internal energy of CL including surface contribution if any.
3401
3402         ! Modification : It seems that below cannot be applied when ricrit > 0.19.
3403         !                May need future generalization.
3404
3405           ricll = min(l2n2/max(l2s2,ntzero),ricrit) ! Mean Ri of internal CL
3406           trma  = alph3*alph4*ricll+2._r8*b1*(alph2-alph4*alph5*ricll)
3407           trmb  = ricll*(alph3+alph4)+2._r8*b1*(-alph5*ricll+alph1)
3408           trmc  = ricll
3409           det   = max(trmb*trmb-4._r8*trma*trmc,0._r8)
3410           gh    = (-trmb + sqrt(det))/2._r8/trma
3411         ! gh    = min(max(gh,-0.28_r8),0.0233_r8)
3412           gh    = min(max(gh,-3.5334_r8),0.0233_r8)
3413           sh    = alph5/(1._r8+alph3*gh)
3414           sm    = (alph1 + alph2*gh)/(1._r8+alph3*gh)/(1._r8+alph4*gh)
3415           wint  = wint - sh*l2n2 + sm*l2s2
3416
3417       else ! The case of SBCL
3418 
3419           ! If there is no pure internal interface, use only surface interfacial
3420           ! values. However, re-set surface interfacial values such  that it can
3421           ! be used in the merging tests (either based on 'wint' or 'l2n2')  and
3422           ! in such that surface interfacial energy is not double-counted.
3423           ! Note that regardless of the choise of 'use_dw_surf', below should be
3424           ! kept as it is below, for consistent merging test of extending SBCL.
3425       
3426           lint = dlint_surf
3427           l2n2 = dl2n2_surf
3428           l2s2 = dl2s2_surf
3429           wint = dw_surf
3430
3431           ! Aug.29.2006 : Only for the purpose of merging test of extending SRCL
3432           ! based on 'l2n2', re-define 'l2n2' of surface interfacial layer using
3433           ! 'wint'. This part is designed for similar treatment of merging as in
3434           ! the original 'eddy_diff.F90' code,  where 'l2n2' of SBCL was defined
3435           ! as 'l2n2 = - wint / sh'. Note that below block is used only when (1)
3436           ! surface buoyancy production 'bprod(i,pver+1)' is NOT included in the
3437           ! calculation of surface TKE in the initialization of 'bprod(i,pver+1)'
3438           ! in the main subroutine ( even though bflxs > 0 ), and (2) to force
3439           ! current scheme be similar to the previous scheme in the treatment of 
3440           ! extending-merging test of SBCL based on 'l2n2'. Otherwise below line
3441           ! must be commented out. Note at this stage, correct non-zero value of
3442           ! 'sh' has been already computed.     
3443
3444           if( choice_tkes .eq. 'ebprod' ) then
3445               l2n2 = - wint / sh
3446           endif
3447           
3448       endif
3449           
3450       ! Set consistent upper limits on 'l2n2' and 'l2s2'. Below limits are
3451       ! reasonable since l2n2 of CL interior interface is always negative.
3452
3453       l2n2 = -min(-l2n2, tkemax*lint/(b1*sh))
3454       l2s2 =  min( l2s2, tkemax*lint/(b1*sm))
3455       
3456       ! Note that at this stage, ( gh, sh, sm )  are the values of surface
3457       ! interfacial layer if there is no pure internal interface, while if
3458       ! there is pure internal interface, ( gh, sh, sm ) are the values of
3459       ! pure CL interfaces or the values that include both the CL internal
3460       ! interfaces and surface interfaces, depending on the 'use_dw_surf'.       
3461       
3462       ! ----------------------------------------------------------------------- !
3463       ! Perform vertical extension-merging process                              !
3464       ! ----------------------------------------------------------------------- !
3465       ! During the merging process, we assumed ( lbulk, sh, sm ) of CL external !
3466       ! interfaces are the same as the ones of the original merging CL. This is !
3467       ! an inevitable approximation since we don't know  ( sh, sm ) of external !
3468       ! interfaces at this stage.     Note that current default merging test is !
3469       ! purely based on buoyancy production without including shear production, !
3470       ! since we used 'l2n2' instead of 'wint' as a merging parameter. However, !
3471       ! merging test based on 'wint' maybe conceptually more attractable.       !
3472       ! Downward CL merging process is identical to the upward merging process, !
3473       ! but when the base of extended CL reaches to the surface, surface inter  !
3474       ! facial layer contribution to the energetic of extended CL must be done  !
3475       ! carefully depending on the sign of surface buoyancy flux. The contribu  !
3476       ! tion of surface interfacial layer energetic is included to the internal !
3477       ! energetics of merging CL only when bflxs > 0.                           !
3478       ! ----------------------------------------------------------------------- !
3479       
3480       ! ---------------------------- !
3481       ! Step 1. Extend the CL upward !
3482       ! ---------------------------- !
3483       
3484       extend = .false.    ! This will become .true. if CL top or base is extended
3485
3486       ! Calculate contribution of potentially incorporable CL top interface
3487
3488       if( choice_tunl .eq. 'rampcl' ) then
3489           tunlramp = 0.5_r8*(1._r8+ctunl)*tunl
3490       elseif( choice_tunl .eq. 'rampsl' ) then
3491           tunlramp = ctunl*tunl
3492         ! tunlramp = 0.765_r8
3493       else
3494           tunlramp = tunl
3495       endif
3496       if( choice_leng .eq. 'origin' ) then
3497           lz = ( (vk*zi(i,kt))**(-cleng) + (tunlramp*lbulk)**(-cleng) )**(-1._r8/cleng)
3498         ! lz = vk*zi(i,kt) / (1._r8+vk*zi(i,kt)/(tunlramp*lbulk))
3499       else
3500           lz = min( vk*zi(i,kt), tunlramp*lbulk )             
3501       endif
3502
3503       dzinc = z(i,kt-1)-z(i,kt)
3504       dl2n2 = lz*lz*n2(i,kt)*dzinc
3505       dl2s2 = lz*lz*s2(i,kt)*dzinc
3506       dwinc = -sh*dl2n2 + sm*dl2s2
3507
3508       ! ------------ !
3509       ! Merging Test !
3510       ! ------------ !
3511 
3512     ! do while (  dwinc .gt. ( rinc*dzinc*wint/(lint+(1._r8-rinc)*dzinc)) )  ! Merging test based on wint
3513     ! do while ( -dl2n2 .gt. (-rinc*dzinc*l2n2/(lint+(1._r8-rinc)*dzinc)) )  ! Merging test based on l2n2
3514       do while ( -dl2n2 .gt. (-rinc*l2n2/(1._r8-rinc)) .and. kt-1 .gt. ntop_turb )                     ! Integral merging test
3515
3516          ! Add contribution of top external interface to interior energy.
3517          ! Note even when we chose 'use_dw_surf='true.', the contribution
3518          ! of surface interfacial layer to 'l2n2' and 'l2s2' are included
3519          ! here. However it is not double counting of surface interfacial
3520          ! energy : surface interfacial layer energy is counted in 'wint'
3521          ! formula and 'l2n2' is just used for performing merging test in
3522          ! this 'do while' loop.     
3523
3524          lint = lint + dzinc
3525          l2n2 = l2n2 + dl2n2
3526          l2n2 = -min(-l2n2, tkemax*lint/(b1*sh))
3527          l2s2 = l2s2 + dl2s2
3528          wint = wint + dwinc
3529
3530          ! Extend top external interface of CL upward after merging
3531
3532          kt        = kt - 1
3533          extend    = .true.
3534          extend_up = .true.
3535          if( kt .eq. ntop_turb ) then
3536              write(iulog,*) 'zisocl: Error: Tried to extend CL to the model top'
3537              stop
3538          end if
3539
3540          ! If the top external interface of extending CL is the same as the
3541          ! top interior interface of the overlying CL, overlying CL will be
3542          ! automatically merged. Then,reduce total number of CL regime by 1.
3543          ! and increase 'cntu'(number of merged CLs during upward extension)
3544          ! by 1.
3545 
3546          ktinc = kbase(i,ncv+cntu+1) - 1  ! Lowest interior interface of overlying CL
3547
3548          if( kt .eq. ktinc ) then
3549
3550              do k = kbase(i,ncv+cntu+1) - 1, ktop(i,ncv+cntu+1) + 1, -1
3551
3552                 if( choice_tunl .eq. 'rampcl' ) then
3553                     tunlramp = 0.5_r8*(1._r8+ctunl)*tunl
3554                 elseif( choice_tunl .eq. 'rampsl' ) then
3555                     tunlramp = ctunl*tunl
3556                   ! tunlramp = 0.765_r8
3557                 else
3558                     tunlramp = tunl
3559                 endif
3560                 if( choice_leng .eq. 'origin' ) then
3561                     lz = ( (vk*zi(i,k))**(-cleng) + (tunlramp*lbulk)**(-cleng) )**(-1._r8/cleng)
3562                   ! lz = vk*zi(i,k) / (1._r8+vk*zi(i,k)/(tunlramp*lbulk))
3563                 else
3564                     lz = min( vk*zi(i,k), tunlramp*lbulk )             
3565                 endif
3566
3567                 dzinc = z(i,k-1)-z(i,k)
3568                 dl2n2 = lz*lz*n2(i,k)*dzinc
3569                 dl2s2 = lz*lz*s2(i,k)*dzinc
3570                 dwinc = -sh*dl2n2 + sm*dl2s2
3571
3572                 lint = lint + dzinc
3573                 l2n2 = l2n2 + dl2n2
3574                 l2n2 = -min(-l2n2, tkemax*lint/(b1*sh))
3575                 l2s2 = l2s2 + dl2s2
3576                 wint = wint + dwinc
3577
3578              end do
3579
3580              kt        = ktop(i,ncv+cntu+1)
3581              ncvfin(i) = ncvfin(i) - 1
3582              cntu      = cntu + 1
3583       
3584          end if
3585
3586          ! Again, calculate the contribution of potentially incorporatable CL
3587          ! top external interface of CL regime.
3588
3589          if( choice_tunl .eq. 'rampcl' ) then
3590              tunlramp = 0.5_r8*(1._r8+ctunl)*tunl
3591          elseif( choice_tunl .eq. 'rampsl' ) then
3592              tunlramp = ctunl*tunl
3593            ! tunlramp = 0.765_r8
3594          else
3595              tunlramp = tunl
3596          endif
3597          if( choice_leng .eq. 'origin' ) then
3598              lz = ( (vk*zi(i,kt))**(-cleng) + (tunlramp*lbulk)**(-cleng) )**(-1._r8/cleng)
3599            ! lz = vk*zi(i,kt) / (1._r8+vk*zi(i,kt)/(tunlramp*lbulk))
3600          else
3601              lz = min( vk*zi(i,kt), tunlramp*lbulk )             
3602          endif
3603
3604          dzinc = z(i,kt-1)-z(i,kt)
3605          dl2n2 = lz*lz*n2(i,kt)*dzinc
3606          dl2s2 = lz*lz*s2(i,kt)*dzinc
3607          dwinc = -sh*dl2n2 + sm*dl2s2
3608
3609       end do   ! End of upward merging test 'do while' loop
3610
3611       ! Update CL interface indices appropriately if any CL was merged.
3612       ! Note that below only updated the interface index of merged CL,
3613       ! not the original merging CL.  Updates of 'kbase' and 'ktop' of
3614       ! the original merging CL  will be done after finishing downward
3615       ! extension also later.
3616
3617       if( cntu .gt. 0 ) then
3618           do incv = 1, ncvfin(i) - ncv
3619              kbase(i,ncv+incv) = kbase(i,ncv+cntu+incv)
3620              ktop(i,ncv+incv)  = ktop(i,ncv+cntu+incv)
3621           end do
3622       end if
3623
3624       ! ------------------------------ !
3625       ! Step 2. Extend the CL downward !
3626       ! ------------------------------ !
3627       
3628       if( kb .ne. pver + 1 ) then
3629
3630           ! Calculate contribution of potentially incorporable CL base interface
3631
3632           if( choice_tunl .eq. 'rampcl' ) then
3633               tunlramp = 0.5_r8*(1._r8+ctunl)*tunl
3634           elseif( choice_tunl .eq. 'rampsl' ) then
3635               tunlramp = ctunl*tunl
3636             ! tunlramp = 0.765_r8
3637           else
3638               tunlramp = tunl
3639           endif
3640           if( choice_leng .eq. 'origin' ) then
3641               lz = ( (vk*zi(i,kb))**(-cleng) + (tunlramp*lbulk)**(-cleng) )**(-1._r8/cleng)
3642             ! lz = vk*zi(i,kb) / (1._r8+vk*zi(i,kb)/(tunlramp*lbulk))
3643           else
3644               lz = min( vk*zi(i,kb), tunlramp*lbulk )             
3645           endif
3646
3647           dzinc = z(i,kb-1)-z(i,kb)
3648           dl2n2 = lz*lz*n2(i,kb)*dzinc
3649           dl2s2 = lz*lz*s2(i,kb)*dzinc
3650           dwinc = -sh*dl2n2 + sm*dl2s2
3651
3652           ! ------------ !
3653           ! Merging test !
3654           ! ------------ !
3655
3656           ! In the below merging tests, I must keep '.and.(kb.ne.pver+1)',   
3657           ! since 'kb' is continuously updated within the 'do while' loop 
3658           ! whenever CL base is merged.
3659
3660         ! do while( (  dwinc .gt. ( rinc*dzinc*wint/(lint+(1._r8-rinc)*dzinc)) ) &  ! Merging test based on wint
3661         ! do while( ( -dl2n2 .gt. (-rinc*dzinc*l2n2/(lint+(1._r8-rinc)*dzinc)) ) &  ! Merging test based on l2n2
3662         !             .and.(kb.ne.pver+1))
3663           do while( ( -dl2n2 .gt. (-rinc*l2n2/(1._r8-rinc)) ) &                     ! Integral merging test
3664                       .and.(kb.ne.pver+1))
3665
3666              ! Add contributions from interfacial layer kb to CL interior
3667
3668              lint = lint + dzinc
3669              l2n2 = l2n2 + dl2n2
3670              l2n2 = -min(-l2n2, tkemax*lint/(b1*sh))
3671              l2s2 = l2s2 + dl2s2
3672              wint = wint + dwinc
3673
3674              ! Extend the base external interface of CL downward after merging
3675
3676              kb        =  kb + 1
3677              extend    = .true.
3678              extend_dn = .true.
3679
3680              ! If the base external interface of extending CL is the same as the
3681              ! base interior interface of the underlying CL, underlying CL  will
3682              ! be automatically merged. Then, reduce total number of CL by 1.
3683              ! For a consistent treatment with 'upward' extension,  I should use
3684              ! 'kbinc = kbase(i,ncv-1) - 1' instead of 'ktop(i,ncv-1) + 1' below.
3685              ! However, it seems that these two methods produce the same results.
3686              ! Note also that in contrast to upward merging, the decrease of ncv
3687              ! should be performed here.
3688              ! Note that below formula correctly works even when upperlying CL
3689              ! regime incorporates below SBCL.
3690
3691              kbinc = 0
3692              if( ncv .gt. 1 ) kbinc = ktop(i,ncv-1) + 1
3693              if( kb .eq. kbinc ) then
3694
3695                  do k =  ktop(i,ncv-1) + 1, kbase(i,ncv-1) - 1
3696
3697                     if( choice_tunl .eq. 'rampcl' ) then
3698                         tunlramp = 0.5_r8*(1._r8+ctunl)*tunl
3699                     elseif( choice_tunl .eq. 'rampsl' ) then
3700                         tunlramp = ctunl*tunl
3701                       ! tunlramp = 0.765_r8
3702                     else
3703                         tunlramp = tunl
3704                     endif
3705                     if( choice_leng .eq. 'origin' ) then
3706                         lz = ( (vk*zi(i,k))**(-cleng) + (tunlramp*lbulk)**(-cleng) )**(-1._r8/cleng)
3707                       ! lz = vk*zi(i,k) / (1._r8+vk*zi(i,k)/(tunlramp*lbulk))
3708                     else
3709                         lz = min( vk*zi(i,k), tunlramp*lbulk )             
3710                     endif
3711
3712                     dzinc = z(i,k-1)-z(i,k)
3713                     dl2n2 = lz*lz*n2(i,k)*dzinc
3714                     dl2s2 = lz*lz*s2(i,k)*dzinc
3715                     dwinc = -sh*dl2n2 + sm*dl2s2
3716
3717                     lint = lint + dzinc
3718                     l2n2 = l2n2 + dl2n2
3719                     l2n2 = -min(-l2n2, tkemax*lint/(b1*sh))
3720                     l2s2 = l2s2 + dl2s2
3721                     wint = wint + dwinc
3722
3723                  end do
3724
3725                  ! We are incorporating interior of CL ncv-1, so merge
3726                  ! this CL into the current CL.
3727
3728                  kb        = kbase(i,ncv-1)
3729                  ncv       = ncv - 1
3730                  ncvfin(i) = ncvfin(i) -1
3731                  cntd      = cntd + 1
3732
3733              end if
3734
3735              ! Calculate the contribution of potentially incorporatable CL
3736              ! base external interface. Calculate separately when the base
3737              ! of extended CL is surface and non-surface.
3738             
3739              if( kb .eq. pver + 1 ) then
3740
3741                  if( bflxs(i) .gt. 0._r8 ) then
3742                      ! Calculate stability functions of surface interfacial layer
3743                      gg = 0.5_r8*vk*z(i,pver)*bprod(i,pver+1)/(tkes(i)**(3._r8/2._r8))
3744                      gh_surf = gg/(alph5-gg*alph3)
3745                    ! gh_surf = min(max(gh_surf,-0.28_r8),0.0233_r8)
3746                      gh_surf = min(max(gh_surf,-3.5334_r8),0.0233_r8)
3747                      sh_surf = alph5/(1._r8+alph3*gh_surf)
3748                      sm_surf = (alph1 + alph2*gh_surf)/(1._r8+alph3*gh_surf)/(1._r8+alph4*gh_surf)
3749                      ! Calculate surface interfacial layer contribution. By construction,
3750                      ! it exactly becomes 'dw_surf = -dl2n2_surf + ds2n2_surf' 
3751                      dlint_surf = z(i,pver)
3752                      dl2n2_surf = -vk*(z(i,pver)**2._r8)*bprod(i,pver+1)/(sh_surf*sqrt(tkes(i)))
3753                      dl2s2_surf =  vk*(z(i,pver)**2._r8)*sprod(i,pver+1)/(sm_surf*sqrt(tkes(i)))
3754                      dw_surf = (tkes(i)/b1)*z(i,pver)
3755                  else
3756                      dlint_surf = 0._r8
3757                      dl2n2_surf = 0._r8
3758                      dl2s2_surf = 0._r8
3759                      dw_surf = 0._r8
3760                  end if
3761                  ! If (kb.eq.pver+1), updating of CL internal energetics should be
3762                  ! performed here inside of 'do while' loop, since 'do while' loop
3763                  ! contains the constraint of '.and.(kb.ne.pver+1)',so updating of
3764                  ! CL internal energetics cannot be performed within this do while
3765                  ! loop when kb.eq.pver+1. Even though I updated all 'l2n2','l2s2',
3766                  ! 'wint' below, only the updated 'wint' is used in the following
3767                  ! numerical calculation.               
3768                  lint = lint + dlint_surf
3769                  l2n2 = l2n2 + dl2n2_surf
3770                  l2n2 = -min(-l2n2, tkemax*lint/(b1*sh))
3771                  l2s2 = l2s2 + dl2s2_surf
3772                  wint = wint + dw_surf               
3773               
3774              else
3775
3776                  if( choice_tunl .eq. 'rampcl' ) then
3777                      tunlramp = 0.5_r8*(1._r8+ctunl)*tunl
3778                  elseif( choice_tunl .eq. 'rampsl' ) then
3779                      tunlramp = ctunl*tunl
3780                    ! tunlramp = 0.765_r8
3781                  else
3782                      tunlramp = tunl
3783                  endif
3784                  if( choice_leng .eq. 'origin' ) then
3785                      lz = ( (vk*zi(i,kb))**(-cleng) + (tunlramp*lbulk)**(-cleng) )**(-1._r8/cleng)
3786                    ! lz = vk*zi(i,kb) / (1._r8+vk*zi(i,kb)/(tunlramp*lbulk))
3787                  else
3788                      lz = min( vk*zi(i,kb), tunlramp*lbulk )             
3789                  endif
3790
3791                  dzinc = z(i,kb-1)-z(i,kb)
3792                  dl2n2 = lz*lz*n2(i,kb)*dzinc
3793                  dl2s2 = lz*lz*s2(i,kb)*dzinc
3794                  dwinc = -sh*dl2n2 + sm*dl2s2
3795
3796              end if
3797
3798          end do ! End of merging test 'do while' loop
3799
3800          if( (kb.eq.pver+1) .and. (ncv.ne.1) ) then
3801               write(iulog,*) 'Major mistake zisocl: the CL based at surface is not indexed 1'
3802               stop
3803          end if
3804
3805       end if   ! Done with bottom extension of CL
3806
3807       ! Update CL interface indices appropriately if any CL was merged.
3808       ! Note that below only updated the interface index of merged CL,
3809       ! not the original merging CL.  Updates of 'kbase' and 'ktop' of
3810       ! the original merging CL  will be done later below. I should
3811       ! check in detail if below index updating is correct or not.   
3812
3813       if( cntd .gt. 0 ) then
3814           do incv = 1, ncvfin(i) - ncv
3815              kbase(i,ncv+incv) = kbase(i,ncvinit+incv)
3816              ktop(i,ncv+incv)  = ktop(i,ncvinit+incv)
3817           end do
3818       end if
3819
3820       ! Sanity check for positive wint.
3821
3822       if( wint .lt. 0.01_r8 ) then
3823           wint = 0.01_r8
3824       end if
3825
3826       ! -------------------------------------------------------------------------- !
3827       ! Finally update CL mean internal energetics including surface contribution  !
3828       ! after finishing all the CL extension-merging process.  As mentioned above, !
3829       ! there are two possible ways in the treatment of surface interfacial layer, !
3830       ! either through 'dw_surf' or 'dl2n2_surf and dl2s2_surf' by setting logical !
3831       ! variable 'use_dw_surf' =.true. or .false.    In any cases, we should avoid !
3832       ! double counting of surface interfacial layer and one single consistent way !
3833       ! should be used throughout the program.                                     !
3834       ! -------------------------------------------------------------------------- !
3835
3836       if( extend ) then
3837
3838           ktop(i,ncv)  = kt
3839           kbase(i,ncv) = kb
3840
3841           ! ------------------------------------------------------ !   
3842           ! Step 1: Include surface interfacial layer contribution !
3843           ! ------------------------------------------------------ !       
3844         
3845           lbulk      = zi(i,kt) - zi(i,kb)
3846           dlint_surf = 0._r8
3847           dl2n2_surf = 0._r8
3848           dl2s2_surf = 0._r8
3849           dw_surf    = 0._r8
3850           if( kb .eq. pver + 1 ) then
3851               if( bflxs(i) .gt. 0._r8 ) then
3852                   ! Calculate stability functions of surface interfacial layer
3853                   gg = 0.5_r8*vk*z(i,pver)*bprod(i,pver+1)/(tkes(i)**(3._r8/2._r8))
3854                   gh = gg/(alph5-gg*alph3)
3855                 ! gh = min(max(gh,-0.28_r8),0.0233_r8)
3856                   gh = min(max(gh,-3.5334_r8),0.0233_r8)
3857                   sh = alph5/(1._r8+alph3*gh)
3858                   sm = (alph1 + alph2*gh)/(1._r8+alph3*gh)/(1._r8+alph4*gh)
3859                   ! Calculate surface interfacial layer contribution. By construction,
3860                   ! it exactly becomes 'dw_surf = -dl2n2_surf + ds2n2_surf' 
3861                   dlint_surf = z(i,pver)
3862                   dl2n2_surf = -vk*(z(i,pver)**2._r8)*bprod(i,pver+1)/(sh*sqrt(tkes(i)))
3863                   dl2s2_surf =  vk*(z(i,pver)**2._r8)*sprod(i,pver+1)/(sm*sqrt(tkes(i)))
3864                   dw_surf    = (tkes(i)/b1)*z(i,pver)
3865               else
3866                   lbulk = zi(i,kt) - z(i,pver)
3867               end if
3868           end if
3869           lint = dlint_surf
3870           l2n2 = dl2n2_surf
3871           l2s2 = dl2s2_surf
3872           wint = dw_surf
3873           if( use_dw_surf ) then
3874               l2n2 = 0._r8
3875               l2s2 = 0._r8
3876           else
3877               wint = 0._r8
3878           end if   
3879       
3880           ! -------------------------------------------------------------- !
3881           ! Step 2. Include the contribution of 'pure internal interfaces' !
3882           ! -------------------------------------------------------------- !
3883         
3884           do k = kt + 1, kb - 1
3885              if( choice_tunl .eq. 'rampcl' ) then
3886                  tunlramp = 0.5_r8*(1._r8+ctunl)*tunl
3887              elseif( choice_tunl .eq. 'rampsl' ) then
3888                  tunlramp = ctunl*tunl
3889                ! tunlramp = 0.765_r8
3890              else
3891                  tunlramp = tunl
3892              endif
3893              if( choice_leng .eq. 'origin' ) then
3894                  lz = ( (vk*zi(i,k))**(-cleng) + (tunlramp*lbulk)**(-cleng) )**(-1._r8/cleng)
3895                ! lz = vk*zi(i,k) / (1._r8+vk*zi(i,k)/(tunlramp*lbulk))
3896              else
3897                  lz = min( vk*zi(i,k), tunlramp*lbulk )             
3898              endif
3899              dzinc = z(i,k-1) - z(i,k)
3900              lint = lint + dzinc
3901              l2n2 = l2n2 + lz*lz*n2(i,k)*dzinc
3902              l2s2 = l2s2 + lz*lz*s2(i,k)*dzinc
3903           end do
3904
3905           ricll = min(l2n2/max(l2s2,ntzero),ricrit)
3906           trma = alph3*alph4*ricll+2._r8*b1*(alph2-alph4*alph5*ricll)
3907           trmb = ricll*(alph3+alph4)+2._r8*b1*(-alph5*ricll+alph1)
3908           trmc = ricll
3909           det = max(trmb*trmb-4._r8*trma*trmc,0._r8)
3910           gh = (-trmb + sqrt(det))/2._r8/trma
3911         ! gh = min(max(gh,-0.28_r8),0.0233_r8)
3912           gh = min(max(gh,-3.5334_r8),0.0233_r8)
3913           sh = alph5 / (1._r8+alph3*gh)
3914           sm = (alph1 + alph2*gh)/(1._r8+alph3*gh)/(1._r8+alph4*gh)
3915           ! Even though the 'wint' after finishing merging was positive, it is
3916           ! possible that re-calculated 'wint' here is negative.  In this case,
3917           ! correct 'wint' to be a small positive number
3918           wint = max( wint - sh*l2n2 + sm*l2s2, 0.01_r8 )
3919
3920       end if
3921
3922       ! ---------------------------------------------------------------------- !
3923       ! Calculate final output variables of each CL (either has merged or not) !
3924       ! ---------------------------------------------------------------------- !
3925
3926       lbrk(i,ncv) = lint
3927       wbrk(i,ncv) = wint/lint
3928       ebrk(i,ncv) = b1*wbrk(i,ncv)
3929       ebrk(i,ncv) = min(ebrk(i,ncv),tkemax)
3930       ricl(i,ncv) = ricll
3931       ghcl(i,ncv) = gh
3932       shcl(i,ncv) = sh
3933       smcl(i,ncv) = sm
3934
3935       ! Increment counter for next CL. I should check if the increament of 'ncv'
3936       ! below is reasonable or not, since whenever CL is merged during downward
3937       ! extension process, 'ncv' is lowered down continuously within 'do' loop.
3938       ! But it seems that below 'ncv = ncv + 1' is perfectly correct.
3939
3940       ncv = ncv + 1
3941
3942    end do                   ! End of loop over each CL regime, ncv.
3943
3944    ! ---------------------------------------------------------- !
3945    ! Re-initialize external interface indices which are not CLs !
3946    ! ---------------------------------------------------------- !
3947
3948    do ncv = ncvfin(i) + 1, ncvmax
3949       ktop(i,ncv)  = 0
3950       kbase(i,ncv) = 0
3951    end do
3952
3953    ! ------------------------------------------------ !
3954    ! Update CL interface identifiers, 'belongcv'      !
3955    ! CL external interfaces are also identified as CL !
3956    ! ------------------------------------------------ !
3957
3958    do k = 1, pver + 1
3959       belongcv(i,k) = .false.
3960    end do
3961
3962    do ncv = 1, ncvfin(i)
3963       do k = ktop(i,ncv), kbase(i,ncv)
3964          belongcv(i,k) = .true.
3965       end do
3966    end do
3967
3968    return
3969
3970    end subroutine zisocl
3971
3972    real(r8) function compute_cubic(a,b,c)
3973    ! ------------------------------------------------------------------------- !
3974    ! Solve canonical cubic : x^3 + a*x^2 + b*x + c = 0,  x = sqrt(e)/sqrt(<e>) !
3975    ! Set x = max(xmin,x) at the end                                            !
3976    ! ------------------------------------------------------------------------- !
3977    implicit none
3978    real(r8), intent(in)     :: a, b, c
3979    real(r8)  qq, rr, dd, theta, aa, bb, x1, x2, x3
3980    real(r8), parameter      :: xmin = 1.e-2_r8
3981   
3982    qq = (a**2-3._r8*b)/9._r8
3983    rr = (2._r8*a**3 - 9._r8*a*b + 27._r8*c)/54._r8
3984   
3985    dd = rr**2 - qq**3
3986    if( dd .le. 0._r8 ) then
3987        theta = acos(rr/qq**(3._r8/2._r8))
3988        x1 = -2._r8*sqrt(qq)*cos(theta/3._r8) - a/3._r8
3989        x2 = -2._r8*sqrt(qq)*cos((theta+2._r8*3.141592)/3._r8) - a/3._r8
3990        x3 = -2._r8*sqrt(qq)*cos((theta-2._r8*3.141592)/3._r8) - a/3._r8
3991        compute_cubic = max(max(max(x1,x2),x3),xmin)       
3992        return
3993    else
3994        if( rr .ge. 0._r8 ) then
3995            aa = -(sqrt(rr**2-qq**3)+rr)**(1._r8/3._r8)
3996        else
3997            aa =  (sqrt(rr**2-qq**3)-rr)**(1._r8/3._r8)
3998        endif
3999        if( aa .eq. 0._r8 ) then
4000            bb = 0._r8
4001        else
4002            bb = qq/aa
4003        endif
4004        compute_cubic = max((aa+bb)-a/3._r8,xmin)
4005        return
4006    endif
4007
4008    return
4009    end function compute_cubic
4010
4011END MODULE eddy_diff
Note: See TracBrowser for help on using the repository browser.