BUGSrad
 All Classes Files Functions Variables
cloud_correlate.f90
Go to the documentation of this file.
1 
2 
3 ! CVS: $Id: cloud_correlate.F90,v 1.3 2005/11/22 22:32:22 norm Exp $
4 ! CVS: $Name: $
5 
7  use kinds
8  implicit none
9  real(kind=dbl_kind), PARAMETER :: MIN_CF = 1.0e-6 !Minimum layer cloud fraction considered cloudy
10  real(kind=dbl_kind), PARAMETER :: MIN_LC = 1.0 !Minimum correlation length in meters
11  !If L_c is smaller than this, random is assumed
12  contains
13 
14  subroutine bugs_ctot(nlen, len_loc, nlm, pl2,tl, acld, l_c, c_tot)
15  !Calculates the total cloud amount using the profile of cloud
16  !fraction acld and the correlation length l_c
17  integer (kind=int_kind), intent(in) :: &
18  nlen, & ! Length of total domain
19  len_loc, & ! Length of sub domain
20  nlm ! Number of layers
21  real (kind=dbl_kind), intent(in), dimension(nlen) :: &
22  l_c ! Correlation length
23  real(kind=dbl_kind), intent(in), dimension(nlen,nlm) :: &
24  tl, & ! Layer temperature
25  acld ! Radiative cloud fraction
26  real(kind=dbl_kind), intent(in), dimension(nlen,nlm+1) :: &
27  pl2 ! Level pressure
28  real(kind=dbl_kind), intent(out), dimension(nlen) :: &
29  c_tot ! Total cloud amount
30 
31  ! Local variables
32  integer(kind=int_kind) :: &
33  i_lay_a, i_lay_b, i_domain, ncloud, kcld, j ! Indices
34  integer(kind=int_kind), dimension(:), allocatable :: &
35  i_cld ! Indices of cloudy layers
36  real(kind=dbl_kind) :: &
37  z0, &
38  dz, &
39  alpha
40  real(kind=dbl_kind), dimension(nlm) :: &
41  z ! mid-layer heights estimated via hydrostatic equation
42  real(kind=dbl_kind), dimension(:), allocatable :: &
43  cloud, &
44  olap, &
45  cld_below ! Amount of cloud in each layer that lies under clear
46  ! sky, i.e., that contributes to total cloudiness
47 
48  do i_domain = 1, nlen
49  !Figure out the cloudy layers
50  ncloud = count(acld(i_domain,:) > min_cf)
51  if (ncloud == 0) then
52  !No cloud
53  c_tot(i_domain) = 0.
54  else if (ncloud == 1) then
55  !One cloudy layer
56  c_tot(i_domain) = maxval(acld(i_domain,:))
57  else
58  if (maxval(acld(i_domain,:)) >= 1.) then
59  c_tot(i_domain) = 1.0
60  else
61  !Multiple cloudy layers.
62  ! Get the mid-layer heights
63  ! Don't worry about actual surface elevation, since we only use dz's
64  z0 = 0.
65  do i_lay_a = nlm, 1, -1
66  dz = 29.286*log(pl2(i_domain,i_lay_a+1)/pl2(i_domain,i_lay_a))*tl(i_domain,i_lay_a)
67  z(i_lay_a) = z0 + dz/2.
68  z0 = z0 + dz
69  enddo
70 
71  !First figure out what layers the clouds are in
72  allocate(i_cld(ncloud),cloud(ncloud),olap(ncloud-1), cld_below(ncloud))
73  kcld = 0
74  do i_lay_a = 1, nlm
75  if (acld(i_domain,i_lay_a) > min_cf) then
76  kcld = kcld+1
77  i_cld(kcld) = i_lay_a
78  endif
79  enddo
80  !Second, condense the cloud fraction vector to remove any cloud-free layers
81  !and set up the olap and cld_below vectors
82  cloud(1) = acld(i_domain,i_cld(1))
83  do kcld = 2, ncloud
84  cloud(kcld) = acld(i_domain,i_cld(kcld))
85  !Overlap of this layer with prior
86  if (l_c(i_domain) < min_lc) then
87  !Pure random correlation between this pair of layers
88  olap(kcld-1) = cloud(kcld-1)*cloud(kcld)
89  else
90  dz=z(i_cld(kcld-1)) - z(i_cld(kcld))
91  alpha = exp(-dz/l_c(i_domain))
92  olap(kcld-1) = alpha*min(cloud(kcld-1),cloud(kcld)) + &
93  (1. - alpha)*cloud(kcld-1)*cloud(kcld)
94  endif
95  enddo
96 
97  !Third, compute the total cloud amount
98  cld_below(1) = cloud(1)
99  cld_below(2) = cloud(2) - olap(1)
100  do kcld = 3,ncloud
101  do j = kcld-1,1,-1
102  select case (kcld-j)
103  case(1)
104  cld_below(kcld) = cloud(kcld) - olap(kcld-1)
105  case(2:)
106  cld_below(kcld) = cld_below(kcld)*(1. - (cloud(j)-olap(j))/&
107  (1. - cloud(j+1)))
108  end select
109  enddo
110  enddo
111  c_tot(i_domain) = sum(cld_below)
112  deallocate(i_cld, cloud,olap, cld_below)
113  endif
114  endif
115  enddo
116  return
117  end subroutine bugs_ctot
118 
119 
120  subroutine bugs_cloudfit(len, nlm, c_tot, acld, &
121  c_maximal, cf_max, cf_random)
122  use kinds
123  implicit none
124 
125  integer (kind=int_kind), intent(in) :: &
126  len, & !Length of domain
127  nlm !Number of layers in each column
128  real (kind=dbl_kind), intent(in), dimension(len) :: &
129  c_tot !Total cloud fraction computed by bugs_ctot
130  real (kind=dbl_kind), intent(in), dimension(len,nlm) :: &
131  acld !Vector of cloud fractions for each column
132  real (kind=dbl_kind), intent(out), dimension(len) :: &
133  c_maximal !Fraction of column which is maximally overlapped
134  real (kind=dbl_kind), intent(out), dimension(len,nlm) :: &
135  cf_max, & !Vector of layer cloud fractions inside the maximally-overlapped column
136  cf_random !Vector of layer cloud fractions outside the maximally-overlapped column
137 
138 
139  !LOCAL VARIABLES
140  integer(kind=int_kind) :: i, j, nc
141 
142  real(kind=dbl_kind) :: min_frac, max_frac
143  real(kind=dbl_kind) :: prod, c_tot_max, cf_stacked, &
144  c_tot_calcd,tol,delta
145  real(kind=dbl_kind), dimension(nlm) :: cf_tmp
146  integer(kind=int_kind) :: frac_set
147 
148  !Use these below to reproduce original gs_olap results
149  real(kind=dbl_kind) :: cf_stacked_thresh, &
150  cf_stacked_min
151  integer(kind=int_kind) :: cf_stacked_min_set
152 
153  !Set tol
154  tol = 1.0e-5
155  do i = 1,len
156  !For each column, get the max and min nonzero cloud fractions
157  frac_set = 0
158  min_frac = 1.
159  max_frac = 0.
160  nc = 0
161  do j = 1, nlm
162  if (acld(i,j) > min_cf) then
163  frac_set = 1
164  nc = nc + 1
165  if (acld(i,j) < min_frac) then
166  min_frac = acld(i,j)
167  endif
168  if (acld(i,j) > max_frac) then
169  max_frac = acld(i,j)
170  endif
171  endif
172  enddo
173  if (frac_set == 0) then
174  !No nonzero cloud amount in column, clear sky
175  min_frac = 0.
176  max_frac = 0.
177  c_maximal(i) = 0.
178  cf_max(i,:) = 0.
179  cf_random(i,:) = 0.
180  else
181  !Min_frac and max_frac determined for this column
182 
183  !Determine c_tot for purely random sky (maximum c_tot possible for this sky)
184  prod = 1.
185  do j = 1, nlm
186  prod = prod*(1. - acld(i,j))
187  enddo
188  c_tot_max = 1. - prod
189  !Now determine the stacked (maximally overlapped) cloud fraction using c_tot to constrain
190  !Check to see if the actual c_tot is less than c_tot_max by a nonnegligible amount
191  !If so, run an iteration in which cf_stacked is incremented until c_tot_calcd
192  !is just less than c_tot. Note that cf_stacked is not allowed to exceed the maximum
193  !layer cloud fraction, max_frac
194  if (c_tot_max - c_tot(i) > tol) then
195  cf_stacked = 0.
196  c_tot_calcd = c_tot_max
197  delta = max_frac/1000.
198  do while (c_tot_calcd > c_tot(i) .and. cf_stacked <= max_frac)
199  !Compute c_tot_calcd for the given cf_stacked
200  prod = 1.
201  do j = 1, nlm
202  if (acld(i,j) > cf_stacked) then
203  prod = prod*(1. - acld(i,j))/(1. - cf_stacked)
204  endif
205  enddo
206  c_tot_calcd = cf_stacked + (1 - cf_stacked)*(1. - prod)
207  cf_stacked = cf_stacked + delta
208  enddo
209  if (cf_stacked > max_frac) then
210  !Reached end of iterations and c_tot_calcd is not less than c_tot
211  !Set cf_stacked to its maximum value. This makes c_tot_calcd as small
212  !as possible
213  cf_stacked = max_frac
214  else
215  !Good result, converged such that c_tot_calcd < c_tot before cf_stacked
216  !got too large.
217  !For good measure, back up half a step
218  cf_stacked = cf_stacked - delta/2.
219  endif
220  else
221  !The actual c_tot is greater than or equal to c_tot_max, so set cf_stacked to
222  !its minimum value. This makes c_tot_calcd as large as possible
223  !If only one cloud layer, must have cf_stacked = the cloud fraction in that
224  !layer. Otherwise (i.e., Nc > 1), we can have 0. overlap and cf_stacked = 0.
225  if (nc == 1) then
226  cf_stacked = min_frac
227  else
228  cf_stacked = 0.
229  endif
230  endif
231 
232  !To reproduce the original gsolap calcs
233  !Comment between here and the next comment to use constrained gsolap
234  ! cf_stacked_min = 1.
235  ! cf_stacked_thresh = 0.00
236  ! cf_stacked_min_set = 0
237 
238  ! do j = 1, nlm
239  ! if (acld(i,j) < cf_stacked_min .and. acld(i,j) > cf_stacked_thresh) then
240  ! cf_stacked_min = acld(i,j)
241  ! cf_stacked_min_set = 1
242  ! endif
243  ! enddo
244  ! if (cf_stacked_min_set == 0) then
245  ! cf_stacked = 0
246  ! else
247  ! cf_stacked = cf_stacked_min
248  ! endif
249  ! cf_stacked = 0. !Force random
250  !End reproduce original gsolap calcs
251 
252  c_maximal(i) = cf_stacked
253  do j = 1, nlm
254  if (acld(i,j) >= cf_stacked) then
255  cf_max(i,j) = cf_stacked
256  cf_random(i,j) = acld(i,j) - cf_stacked
257  else
258  cf_max(i,j) = acld(i,j)
259  cf_random(i,j) = 0.
260  endif
261  enddo
262  !If c_maximal is other than zero or 1, renormalize the cloud fractions
263  !to the range [0. - 1.]
264  if (c_maximal(i) > 0. .and. c_maximal(i) < 1.) then
265  cf_max(i,:) = cf_max(i,:)/c_maximal(i)
266  cf_random(i,:) = cf_random(i,:)/(1. - c_maximal(i))
267  endif
268 
269  !Diagnostic calc - comment out if not debugging
270  !prod = 1.
271  !do j = 1, nlm
272  ! if (acld(i,j) > cf_stacked) then
273  ! prod = prod*(1. - acld(i,j))/(1. - cf_stacked)
274  ! endif
275  !enddo
276  !c_tot_calcd = cf_stacked + (1 - cf_stacked)*(1. - prod)
277  endif
278  enddo
279  end subroutine bugs_cloudfit
280 
281 end module bugs_cloud_correlate