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

Annotation 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.1 - (hide annotations) (download)
Tue Sep 11 03:53:05 2012 UTC (14 years, 1 month ago) by jmc
Branch: MAIN
first check-in of 2 examples experiment using gray atmospheric physics

1 jmc 1.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.f90,v 1.4 2002/07/16 22:32:04 fms Exp $'
99     character(len=128) :: tag = '$Name: havana $'
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