/[MITgcm]/MITgcm_contrib/verification_other/atm_gray/code_gray/diffusivity_mod.F90
ViewVC logotype

Contents of /MITgcm_contrib/verification_other/atm_gray/code_gray/diffusivity_mod.F90

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.2 - (show annotations) (download)
Wed May 8 23:55:45 2013 UTC (13 years, 6 months ago) by jmc
Branch: MAIN
CVS Tags: HEAD
Changes since 1.1: +2 -2 lines
FILE REMOVED
updated to use new pkg "atm_phys" (instead of "mypackage" + code in local
  dir "code_gray")

1
2 module diffusivity_mod
3
4 !=======================================================================
5 !
6 ! DIFFUSIVITY MODULE
7 !
8 ! Routines for computing atmospheric diffusivities in the
9 ! planetary boundary layer and in the free atmosphere
10 !
11 !=======================================================================
12
13
14 use gcm_params_mod, only: gcm_LEN_MBUF, gcm_SQZ_R, gcm_stdMsgUnit
15 use constants_mod, only : grav, vonkarm, cp_air, rdgas, rvgas
16
17 !use fms_mod, only: error_mesg, FATAL, file_exist, &
18 ! check_nml_error, open_namelist_file, &
19 ! mpp_pe, mpp_root_pe, close_file, stdlog, &
20 ! write_version_number
21
22 use monin_obukhov_mod, only : mo_diff
23
24 implicit none
25 private
26
27 ! public interfaces
28 !=======================================================================
29
30 public diffusivity, pbl_depth, molecular_diff
31
32 !=======================================================================
33
34 ! form of iterfaces
35
36 !=======================================================================
37 ! subroutine diffusivity (t, q, u, v, p_full, p_half, z_full, z_half,
38 ! u_star, b_star, h, k_m, k_t)
39
40 ! input:
41
42 ! t : real, dimension(:,:,:) -- (:,:,pressure), third index running
43 ! from top of atmosphere to bottom
44 ! temperature (K)
45 !
46 ! q : real, dimension(:,:,:)
47 ! water vapor specific humidity (nondimensional)
48 !
49 ! u : real, dimension(:,:)
50 ! zonal wind (m/s)
51 !
52 ! v : real, dimension(:,:,:)
53 ! meridional wind (m/s)
54 !
55 ! z_full : real, dimension(:,:,:
56 ! height of full levels (m)
57 ! 1 = top of atmosphere; size(p_half,3) = surface
58 ! size(z_full,3) = size(t,3)
59 !
60 ! z_half : real, dimension(:,:,:)
61 ! height of half levels (m)
62 ! size(z_half,3) = size(t,3) +1
63 ! z_half(:,:,size(z_half,3)) must be height of surface!
64 ! (if you are not using eta-model)
65 !
66 ! u_star: real, dimension(:,:)
67 ! friction velocity (m/s)
68 !
69 ! b_star: real, dimension(:,:)
70 ! buoyancy scale (m/s**2)
71
72 ! (u_star and b_star can be obtained by calling
73 ! mo_drag in monin_obukhov_mod)
74
75 ! output:
76
77 ! h : real, dimension(:,:,)
78 ! depth of planetary boundary layer (m)
79 !
80 ! k_m : real, dimension(:,:,:)
81 ! diffusivity for momentum (m**2/s)
82 !
83 ! defined at half-levels
84 ! size(k_m,3) should be at least as large as size(t,3)
85 ! only the returned values at
86 ! levels 2 to size(t,3) are meaningful
87 ! other values will be returned as zero
88 !
89 ! k_t : real, dimension(:,:,:)
90 ! diffusivity for temperature and scalars (m**2/s)
91 !
92 !
93 !=======================================================================
94
95
96 !--------------------- version number ----------------------------------
97
98 character(len=128) :: version = '$Id: diffusivity_mod.F90,v 1.1 2012/09/11 03:53:05 jmc Exp $'
99 character(len=128) :: tag = '$Name: $'
100
101 !=======================================================================
102
103 ! DEFAULT VALUES OF NAMELIST PARAMETERS:
104
105 logical :: fixed_depth = .false.
106 logical :: do_virtual_non_mcm = .false. ! applies only to non-'mcm' pbl scheme
107 real :: depth_0 = 5000.0
108 real :: frac_inner = 0.1
109 real :: rich_crit_pbl = 1.0
110 real :: entr_ratio = 0.2
111 real :: parcel_buoy = 2.0
112 real :: znom = 1000.0
113 logical :: free_atm_diff = .false.
114 logical :: free_atm_skyhi_diff = .false.
115 logical :: pbl_mcm = .false.
116 real :: rich_crit_diff = 0.25
117 real :: mix_len = 30.
118 real :: rich_prandtl = 1.00
119 real :: background_m = 0.0
120 real :: background_t = 0.0
121 logical :: ampns = .false. ! include delta z factor in
122 ! defining ri ?
123 real :: ampns_max = 1.0E20 ! limit to reduction factor
124 ! applied to ri due to delta z
125 ! factor
126
127 namelist /diffusivity_nml/ fixed_depth, depth_0, frac_inner,&
128 rich_crit_pbl, entr_ratio, parcel_buoy,&
129 znom, free_atm_diff, free_atm_skyhi_diff,&
130 pbl_mcm, rich_crit_diff, mix_len, rich_prandtl,&
131 background_m, background_t, ampns, ampns_max, &
132 do_virtual_non_mcm
133
134 !=======================================================================
135
136 ! OTHER MODULE VARIABLES
137
138 real :: small = 1.e-04
139 real :: gcp = grav/cp_air
140 logical :: init = .false.
141 real :: beta = 1.458e-06
142 real :: rbop1 = 110.4
143 real :: rbop2 = 1.405
144
145 real, parameter :: d608 = (rvgas-rdgas)/rdgas
146
147
148 contains
149
150 !=======================================================================
151
152 subroutine diffusivity_init(myThid)
153
154 integer, intent(in) :: myThid
155 integer :: unit, ierr, io
156
157 integer :: iUnit
158 CHARACTER*(gcm_LEN_MBUF) :: msgBuf
159
160 !------------------- read namelist input -------------------------------
161
162 ! read namelist and copy to logfile
163
164 ! _BARRIER
165 ! _BEGIN_MASTER(myThid)
166 CALL BARRIER(myThid)
167 IF ( myThid.EQ.1 ) THEN
168
169 WRITE(msgBuf,'(A)') 'DIFFUSIVITY_INIT: opening data.atm_gray'
170 CALL PRINT_MESSAGE( msgBuf, gcm_stdMsgUnit, gcm_SQZ_R, myThid )
171 CALL OPEN_COPY_DATA_FILE( &
172 'data.atm_gray', 'DIFFUSIVITY_INIT', &
173 iUnit, &
174 myThid )
175 ! Read parameters from open data file
176 READ(UNIT=iUnit,NML=diffusivity_nml)
177 WRITE(msgBuf,'(A)') &
178 'DIFFUSIVITY_INIT: finished reading data.atm_gray'
179 CALL PRINT_MESSAGE( msgBuf, gcm_stdMsgUnit, gcm_SQZ_R, myThid )
180 ! Close the open data file
181 CLOSE(iUnit)
182
183 ! if (file_exist('input.nml')) then
184 ! unit = open_namelist_file ()
185 ! ierr=1; do while (ierr /= 0)
186 ! read (unit, nml=diffusivity_nml, iostat=io, end=10)
187 ! ierr = check_nml_error(io,'diffusivity_nml')
188 ! enddo
189 ! 10 call close_file (unit)
190
191 !------------------- dummy checks --------------------------------------
192 if (frac_inner .le. 0. .or. frac_inner .ge. 1.) &
193 CALL PRINT_ERROR( 'diffusivity_init'// &
194 'frac_inner must be between 0 and 1', myThid)
195 ! call error_mesg ('diffusivity_init', &
196 ! 'frac_inner must be between 0 and 1', FATAL)
197 if (rich_crit_pbl .lt. 0.) &
198 CALL PRINT_ERROR( 'diffusivity_init'// &
199 'rich_crit_pbl must be greater than or equal to zero', myThid )
200 ! call error_mesg ('diffusivity_init', &
201 ! 'rich_crit_pbl must be greater than or equal to zero', FATAL)
202 if (entr_ratio .lt. 0.) &
203 CALL PRINT_ERROR( 'diffusivity_init'// &
204 'entr_ratio must be greater than or equal to zero', myThid )
205 ! call error_mesg ('diffusivity_init', &
206 ! 'entr_ratio must be greater than or equal to zero', FATAL)
207 if (znom .le. 0.) &
208 CALL PRINT_ERROR( 'diffusivity_init'// &
209 'znom must be greater than zero', myThid )
210 ! call error_mesg ('diffusivity_init', &
211 ! 'znom must be greater than zero', FATAL)
212 if (.not.free_atm_diff .and. free_atm_skyhi_diff)&
213 CALL PRINT_ERROR( 'diffusivity_init'// &
214 'free_atm_diff must be set to true if '//&
215 'free_atm_skyhi_diff = .true.', myThid )
216 ! call error_mesg ('diffusivity_init', &
217 ! 'free_atm_diff must be set to true if '//&
218 ! 'free_atm_skyhi_diff = .true.', FATAL)
219 if (rich_crit_diff .le. 0.) &
220 CALL PRINT_ERROR( 'diffusivity_init'// &
221 'rich_crit_diff must be greater than zero', myThid )
222 ! call error_mesg ('diffusivity_init', &
223 ! 'rich_crit_diff must be greater than zero', FATAL)
224 if (mix_len .lt. 0.) &
225 CALL PRINT_ERROR( 'diffusivity_init'// &
226 'mix_len must be greater than or equal to zero', myThid )
227 ! call error_mesg ('diffusivity_init', &
228 ! 'mix_len must be greater than or equal to zero', FATAL)
229 if (rich_prandtl .lt. 0.) &
230 CALL PRINT_ERROR( 'diffusivity_init'// &
231 'rich_prandtl must be greater than or equal to zero', myThid )
232 ! call error_mesg ('diffusivity_init', &
233 ! 'rich_prandtl must be greater than or equal to zero', FATAL)
234 if (background_m .lt. 0.) &
235 CALL PRINT_ERROR( 'diffusivity_init'// &
236 'background_m must be greater than or equal to zero', myThid )
237 ! call error_mesg ('diffusivity_init', &
238 ! 'background_m must be greater than or equal to zero', FATAL)
239 if (background_t .lt. 0.) &
240 CALL PRINT_ERROR( 'diffusivity_init'// &
241 'background_t must be greater than or equal to zero', myThid )
242 ! call error_mesg ('diffusivity_init', &
243 ! 'background_t must be greater than or equal to zero', FATAL)
244 if (ampns_max .lt. 1.) &
245 CALL PRINT_ERROR( 'diffusivity_init'// &
246 'ampns_max must be greater than or equal to one', myThid )
247 ! call error_mesg ('diffusivity_init', &
248 ! 'ampns_max must be greater than or equal to one', FATAL)
249 if (ampns .and. .not. free_atm_skyhi_diff) &
250 CALL PRINT_ERROR( 'diffusivity_init'// &
251 'ampns is only valid when free_atm_skyhi_diff is & also true', myThid )
252 ! call error_mesg ('diffusivity_init', &
253 ! 'ampns is only valid when free_atm_skyhi_diff is &
254 ! & also true', FATAL)
255
256 ! endif !end of reading input.nml
257
258 !---------- output namelist to log-------------------------------------
259
260 ! call write_version_number(version, tag)
261 ! if ( mpp_pe() == mpp_root_pe() ) write (stdlog(), nml=diffusivity_nml)
262
263 init = .true.
264
265 ENDIF
266 CALL BARRIER(myThid)
267
268 return
269 end subroutine diffusivity_init
270
271 !=======================================================================
272
273 subroutine diffusivity(t, q, u, v, p_full, p_half, z_full, z_half, &
274 u_star, b_star, h, k_m, k_t, myThid, kbot)
275
276 real, intent(in), dimension(:,:,:) :: t, q, u, v
277 real, intent(in), dimension(:,:,:) :: p_full, p_half
278 real, intent(in), dimension(:,:,:) :: z_full, z_half
279 real, intent(in), dimension(:,:) :: u_star, b_star
280 real, intent(inout), dimension(:,:,:) :: k_m, k_t
281 real, intent(out), dimension(:,:) :: h
282 integer, intent (in) :: myThid
283 integer, intent(in), optional, dimension(:,:) :: kbot
284
285 real, dimension(size(t,1),size(t,2),size(t,3)) :: svcp,z_full_ag, &
286 k_m_save, k_t_save
287 real, dimension(size(t,1),size(t,2),size(t,3)+1):: z_half_ag
288 real, dimension(size(t,1),size(t,2)) :: z_surf
289 integer :: i,j,k,nlev,nlat,nlon
290
291 if(.not.init) call diffusivity_init(myThid)
292
293 nlev = size(t,3)
294
295 k_m_save = k_m
296 k_t_save = k_t
297
298 !compute height of surface
299 if (present(kbot)) then
300 nlat = size(t,2)
301 nlon = size(t,1)
302 do j=1,nlat
303 do i=1,nlon
304 z_surf(i,j) = z_half(i,j,kbot(i,j)+1)
305 enddo
306 enddo
307 else
308 z_surf(:,:) = z_half(:,:,nlev+1)
309 end if
310
311
312 !compute density profile, and heights relative to surface
313 do k = 1, nlev
314
315 z_full_ag(:,:,k) = z_full(:,:,k) - z_surf(:,:)
316 z_half_ag(:,:,k) = z_half(:,:,k) - z_surf(:,:)
317
318 if (do_virtual_non_mcm) then
319 svcp(:,:,k) = t(:,:,k)*(1. + d608*q(:,:,k)) + gcp*(z_full_ag(:,:,k))
320 else
321 svcp(:,:,k) = t(:,:,k) + gcp*(z_full_ag(:,:,k))
322 endif
323
324 end do
325 z_half_ag(:,:,nlev+1) = z_half(:,:,nlev+1) - z_surf(:,:)
326
327
328 if(fixed_depth) then
329 h = depth_0
330 else
331 call pbl_depth(svcp,u,v,z_full_ag,u_star,b_star,h, myThid, kbot=kbot)
332 end if
333
334 if(pbl_mcm) then
335 call diffusivity_pbl_mcm (u,v, t, p_full, p_half, &
336 z_full_ag, z_half_ag, h, k_m, k_t, myThid)
337 else
338 call diffusivity_pbl (svcp, u, v, z_half_ag, h, u_star, b_star,&
339 k_m, k_t, myThid, kbot=kbot)
340 end if
341 if(free_atm_diff) &
342 call diffusivity_free (svcp, u, v, z_full_ag, z_half_ag, h, k_m, k_t, myThid)
343
344 k_m = k_m + k_m_save
345 k_t = k_t + k_t_save
346
347 !NOTE THAT THIS LINE MUST FOLLOW DIFFUSIVITY_FREE SO THAT ENTRAINMENT
348 !K's DO NOT GET OVERWRITTEN IN DIFFUSIVITY_FREE SUBROUTINE
349 if(entr_ratio .gt. 0. .and. .not. fixed_depth) &
350 call diffusivity_entr(svcp,z_full_ag,h,u_star,b_star,k_m,k_t, myThid)
351
352 !set background diffusivities
353 if(background_m.gt.0.0) k_m = max(k_m,background_m)
354 if(background_t.gt.0.0) k_t = max(k_t,background_t)
355
356
357 return
358 end subroutine diffusivity
359
360 !=======================================================================
361
362 subroutine pbl_depth(t, u, v, z, u_star, b_star, h, myThid, kbot)
363
364
365 real, intent(in) , dimension(:,:,:) :: t, u, v, z
366 real, intent(in) , dimension(:,:) :: u_star,b_star
367 real, intent(out), dimension(:,:) :: h
368 integer, intent(in) :: myThid
369 integer,intent(in) , optional, dimension(:,:) :: kbot
370
371 real, dimension(size(t,1),size(t,2),size(t,3)) :: rich
372 real, dimension(size(t,1),size(t,2)) :: ws,k_t_ref,&
373 h_inner,tbot
374 real :: rich1, rich2,&
375 h1,h2,svp,t1,t2
376 integer, dimension(size(t,1),size(t,2)) :: ibot
377 integer :: i,j,k,nlon,&
378 nlat, nlev
379
380 nlev = size(t,3)
381 nlat = size(t,2)
382 nlon = size(t,1)
383
384 !assign ibot, compute tbot (virtual temperature at lowest level)
385 if (present(kbot)) then
386 ibot(:,:) = kbot
387 do j = 1,nlat
388 do i = 1,nlon
389 tbot(i,j) = t(i,j,ibot(i,j))
390 enddo
391 enddo
392 else
393 ibot(:,:) = nlev
394 tbot(:,:) = t(:,:,nlev)
395 end if
396
397
398 !compute richardson number for use in pbl depth of neutral/stable side
399 do k = 1,nlev
400 rich(:,:,k) = z(:,:,k)*grav*(t(:,:,k)-tbot(:,:))/tbot(:,:)&
401 /(u(:,:,k)*u(:,:,k) + v(:,:,k)*v(:,:,k) + small )
402 end do
403
404 !compute ws to be used in evaluating parcel buoyancy
405 !ws = u_star / phi(h_inner,u_star,b_star) . To find phi
406 !a call to mo_diff is made.
407
408 h_inner(:,:)=frac_inner*znom
409 call mo_diff(h_inner, u_star, b_star, ws, k_t_ref, myThid )
410 ws = max(small,ws/vonkarm/h_inner)
411
412
413 do j = 1, nlat
414 do i = 1, nlon
415
416 !do neutral or stable case
417 if (b_star(i,j).le.0.) then
418
419 h1 = z(i,j,ibot(i,j))
420 h(i,j) = h1
421 rich1 = rich(i,j,ibot(i,j))
422 do k = ibot(i,j)-1, 1, -1
423 rich2 = rich(i,j,k)
424 h2 = z(i,j,k)
425 if(rich2.gt.rich_crit_pbl) then
426 h(i,j) = h2 + (h1 - h2)*(rich2 - rich_crit_pbl)&
427 /(rich2 - rich1 )
428 go to 10
429 endif
430 rich1 = rich2
431 h1 = h2
432 enddo
433
434 !do unstable case
435 else
436
437 svp = tbot(i,j)*(1.+ &
438 (parcel_buoy*u_star(i,j)*b_star(i,j)/grav/ws(i,j)) )
439 h1 = z(i,j,ibot(i,j))
440 h(i,j) = h1
441 t1 = tbot(i,j)
442 do k = ibot(i,j)-1 , 1, -1
443 h2 = z(i,j,k)
444 t2 = t(i,j,k)
445 if (t2.gt.svp) then
446 h(i,j) = h2 + (h1 - h2)*(t2 - svp)/(t2 - t1 )
447 go to 10
448 end if
449 h1 = h2
450 t1 = t2
451 enddo
452
453 end if
454 10 continue
455 enddo
456 enddo
457
458 return
459 end subroutine pbl_depth
460
461 !=======================================================================
462
463 subroutine diffusivity_pbl(t, u, v, z_half, h, u_star, b_star, &
464 k_m, k_t, myThid, kbot)
465
466 real, intent(in) , dimension(:,:,:) :: t, u, v, z_half
467 real, intent(in) , dimension(:,:) :: h, u_star, b_star
468 real, intent(inout) , dimension(:,:,:) :: k_m, k_t
469 integer, intent (in) :: myThid
470 integer, intent(in) , optional, dimension(:,:) :: kbot
471
472 real, dimension(size(t,1),size(t,2)) :: h_inner, k_m_ref,&
473 k_t_ref, factor
474 real, dimension(size(t,1),size(t,2),size(t,3)+1) :: zm
475 real :: h_inner_max
476 integer :: i,j, k, kk, nlev
477
478
479 nlev = size(t,3)
480
481 !assign z_half to zm, and set to zero any values of zm < 0.
482 !the setting to zero is necessary so that when using eta model
483 !below ground half levels will have zero k_m and k_t
484 zm = z_half
485 if (present(kbot)) then
486 where(zm < 0.)
487 zm = 0.
488 end where
489 end if
490
491 h_inner = frac_inner*h
492 h_inner_max = maxval(h_inner)
493
494 kk = nlev
495 do k = 2, nlev
496 if( minval(zm(:,:,k)) < h_inner_max) then
497 kk = k
498 exit
499 end if
500 end do
501
502 k_m = 0.0
503 k_t = 0.0
504
505 call mo_diff(h_inner , u_star, b_star, k_m_ref , k_t_ref, myThid )
506 call mo_diff(zm(:,:,kk:nlev), u_star, b_star, k_m(:,:,kk:nlev), k_t(:,:,kk:nlev), &
507 myThid )
508
509 do k = 2, nlev
510 where(zm(:,:,k) >= h_inner .and. zm(:,:,k) < h)
511 factor = (zm(:,:,k)/h_inner)* &
512 (1.0 - (zm(:,:,k) - h_inner)/(h - h_inner))**2
513 k_m(:,:,k) = k_m_ref*factor
514 k_t(:,:,k) = k_t_ref*factor
515 end where
516 end do
517
518 return
519 end subroutine diffusivity_pbl
520
521 !=======================================================================
522
523 subroutine diffusivity_pbl_mcm(u, v, t, p_full, p_half, z_full, z_half, &
524 h, k_m, k_t, myThid)
525
526 real, intent(in) , dimension(:,:,:) :: u, v, t, z_full, z_half
527 real, intent(in) , dimension(:,:,:) :: p_full, p_half
528 real, intent(in) , dimension(:,:) :: h
529 real, intent(inout) , dimension(:,:,:) :: k_m, k_t
530 integer, intent(in) :: myThid
531
532 integer :: k, nlev
533 real, dimension(size(z_full,1),size(z_full,2)) :: elmix, htcrit
534 real, dimension(size(z_full,1),size(z_full,2)) :: delta_u, delta_v, delta_z
535
536 real :: htcrit_ss
537 real :: h_ss
538 real, dimension(size(z_full,1),size(z_full,2)) :: sig_half, z_half_ss, elmix_ss
539
540 ! htcrit_ss = height at which mixing length is a maximum (75m)
541
542
543 ! h_ss = height at which mixing length vanishes (4900m)
544 ! elmix_ss = mixing length
545
546 ! Define some constants:
547 ! salaps = standard atmospheric lapse rate (K/m)
548 ! tsfc = idealized global mean surface temperature (15C)
549 real :: tsfc = 288.16
550 real :: salaps = -6.5e-3
551
552 nlev = size(z_full,3)
553
554 k_m = 0.
555
556 h_ss = depth_0
557 htcrit_ss = frac_inner*h_ss
558
559 do k = 2, nlev
560
561 ! TK mods 8/13/01: (code derived from SS)
562 ! Compute the height of each half level assuming a constant
563 ! standard lapse rate using the above procedure.
564 ! WARNING: These should be used with caution. They will
565 ! have large errors above the tropopause.
566
567 ! In order to determine the height, the layer mean temperature
568 ! from the surface to that level is required. A surface
569 ! temperature of 15 deg Celsius and a standard lapse rate of
570 ! -6.5 deg/km will be used to estimate an average temperature
571 ! profile.
572
573 sig_half = p_half(:,:,k)/p_half(:,:,nlev+1)
574 z_half_ss = -rdgas * .5*(tsfc+tsfc*(sig_half**(-rdgas*salaps/grav))) * alog(sig_half)/grav
575
576 !compute mixing length as in SS (no geographical variation)
577 elmix_ss = 0.
578
579 where (z_half_ss < htcrit_ss .and. z_half_ss > 0.)
580 elmix_ss = vonkarm*z_half_ss
581 endwhere
582 where (z_half_ss >= htcrit_ss .and. z_half_ss < h_ss)
583 elmix_ss = vonkarm*htcrit_ss*(h_ss-z_half_ss)/(h_ss-htcrit_ss)
584 endwhere
585
586 delta_z = rdgas*0.5*(t(:,:,k)+t(:,:,k-1))*(p_full(:,:,k)-p_full(:,:,k-1))/&
587 (grav*p_half(:,:,k))
588 delta_u = u(:,:,k-1) - u(:,:,k)
589 delta_v = v(:,:,k-1) - v(:,:,k)
590
591 k_m(:,:,k) = elmix_ss * elmix_ss *&
592 sqrt(delta_u*delta_u + delta_v*delta_v)/delta_z
593
594 end do
595
596 k_t = k_m
597
598 return
599 end subroutine diffusivity_pbl_mcm
600
601 !=======================================================================
602
603 subroutine diffusivity_free(t, u, v, z, zz, h, k_m, k_t, myThid)
604
605 real, intent(in) , dimension(:,:,:) :: t, u, v, z, zz
606 real, intent(in) , dimension(:,:) :: h
607 real, intent(inout) , dimension(:,:,:) :: k_m, k_t
608 integer, intent(in) :: myThid
609
610 real, dimension(size(t,1),size(t,2)) :: dz, b, speed2, rich, fri, &
611 alpz, fri2
612 integer :: k
613
614 do k = 2, size(t,3)
615
616 !----------------------------------------------------------------------
617 ! define the richardson number. set it to zero if it is negative. save
618 ! a copy of it for later use (rich2).
619 !----------------------------------------------------------------------
620 dz = z(:,:,k-1) - z(:,:,k)
621 b = grav*(t(:,:,k-1)-t(:,:,k))/t(:,:,k)
622 speed2 = (u(:,:,k-1) - u(:,:,k))**2 + (v(:,:,k-1) - v(:,:,k))**2
623 rich= b*dz/(speed2+small)
624 rich = max(rich, 0.0)
625
626 if (free_atm_skyhi_diff) then
627 !---------------------------------------------------------------------
628 ! limit the standard richardson number to between 0 and the critical
629 ! value (rich2). compute the richardson number factor needed in the
630 ! eddy mixing coefficient using this standard richardson number.
631 !---------------------------------------------------------------------
632 where (rich(:,:) >= rich_crit_diff)
633 fri2(:,:) = 0.0
634 elsewhere
635 fri2(:,:) = (1.0 - rich/rich_crit_diff)**2
636 endwhere
637 endif
638
639 !---------------------------------------------------------------------
640 ! if ampns is activated, compute the delta z factor. define rich
641 ! including this factor.
642 !---------------------------------------------------------------------
643 if (ampns) then
644 alpz(:,:) = MIN ( (1. + 1.e-04*(dz(:,:)**1.5)), ampns_max)
645 rich(:,:) = rich(:,:) / alpz(:,:)
646 endif
647
648 !---------------------------------------------------------------------
649 ! compute the richardson number factor to be used in the eddy
650 ! mixing coefficient. if ampns is on, this value includes it; other-
651 ! wise it does not.
652 !---------------------------------------------------------------------
653 fri(:,:) = (1.0 - rich/rich_crit_diff)**2
654
655 !---------------------------------------------------------------------
656 ! compute the eddy mixing coefficients in the free atmosphere ( zz
657 ! > h). in the non-ampns case, values are obtained only when the
658 ! standard richardson number is sub-critical; in the ampns case values
659 ! are obtained only when the richardson number computed with the
660 ! ampns factor is sub critical. when the ampns factor is activated,
661 ! it is also included in the mixing coefficient. the value of mixing
662 ! for temperature, etc. is reduced dependent on the ri stability
663 ! factor calculated without the ampns factor.
664 !---------------------------------------------------------------------
665 if (free_atm_skyhi_diff) then
666
667 !---------------------------------------------------------------------
668 ! this is the skyhi-like formulation -- possible ampns factor, ratio
669 ! of k_m to k_t defined based on computed stability factor.
670 !---------------------------------------------------------------------
671 if (ampns) then
672 where (rich < rich_crit_diff .and. zz(:,:,k) > h)
673 k_m(:,:,k) = mix_len*mix_len*sqrt(speed2)*fri(:,:)* &
674 ( 1. + 1.e-04*(dz(:,:)**1.5))/dz
675 k_t(:,:,k) = k_m(:,:,k)* (0.1 + 0.9*fri2(:,:))
676 end where
677 else
678 where (rich < rich_crit_diff .and. zz(:,:,k) > h)
679 k_m(:,:,k) = mix_len*mix_len*sqrt(speed2)*fri(:,:)/dz
680 k_t(:,:,k) = k_m(:,:,k)* (0.1 + 0.9*fri2(:,:))
681 end where
682 endif
683 else
684
685 !---------------------------------------------------------------------
686 ! this is the non-skyhi-like formulation -- no ampns factor, ratio
687 ! of k_m to k_t defined by rich_prandtl.
688 !---------------------------------------------------------------------
689 where (rich < rich_crit_diff .and. zz(:,:,k) > h)
690 k_t(:,:,k) = mix_len*mix_len*sqrt(speed2)*fri(:,:)/dz
691 k_m(:,:,k) = k_t(:,:,k)*rich_prandtl
692 end where
693 end if
694 end do
695
696
697 end subroutine diffusivity_free
698
699 !=======================================================================
700
701 subroutine molecular_diff ( temp, press, k_m, k_t, myThid)
702
703 real, intent(in), dimension (:,:,:) :: temp, press
704 real, intent(inout), dimension (:,:,:) :: k_m, k_t
705 integer, intent(in) :: myThid
706
707 real, dimension (size(temp,1), size(temp,2)) :: temp_half, &
708 rho_half, rbop2d
709 integer :: k
710
711 !---------------------------------------------------------------------
712
713 do k=2,size(temp,3)
714 temp_half(:,:) = 0.5*(temp(:,:,k) + temp(:,:,k-1))
715 rho_half(:,:) = press(:,:,k)/(rdgas*temp_half(:,:) )
716 rbop2d(:,:) = beta*temp_half(:,:)*sqrt(temp_half(:,:))/ &
717 (rho_half(:,:)*(temp_half(:,:)+rbop1))
718 k_m(:,:,k) = rbop2d(:,:)
719 k_t(:,:,k) = rbop2d(:,:)*rbop2
720 end do
721
722 k_m(:,:,1) = 0.0
723 k_t(:,:,1) = 0.0
724
725
726
727 end subroutine molecular_diff
728
729
730
731 !=======================================================================
732
733 subroutine diffusivity_entr(t, z, h, u_star, b_star, k_m, k_t, myThid)
734
735 real, intent(in) , dimension(:,:,:) :: t, z
736 real, intent(in) , dimension(:,:) :: h, u_star, b_star
737 real, intent(inout) , dimension(:,:,:) :: k_m, k_t
738 integer, intent(in) :: myThid
739
740 integer :: k, nlev
741
742 nlev=size(t,3)
743
744 do k = 2,nlev
745 where (b_star .gt. 0. .and. z(:,:,k-1) .gt. h .and. &
746 z(:,:,k) .le. h)
747 k_t(:,:,k) = (z(:,:,k-1)-z(:,:,k))*entr_ratio*t(:,:,k)* &
748 u_star*b_star/grav/max(small,t(:,:,k-1)-t(:,:,k))
749 k_m(:,:,k) = k_t(:,:,k)
750 end where
751 enddo
752 end subroutine diffusivity_entr
753
754 !=======================================================================
755
756 end module diffusivity_mod
757

  ViewVC Help
Powered by ViewVC 1.1.22