CCPP SciDoc v7.0.0  v7.0.0
Common Community Physics Package Developed at DTC
 
Loading...
Searching...
No Matches
sfc_diag.f
1
3
5 module sfc_diag
6 contains
7
13 subroutine sfc_diag_run (im,xlat_d,xlon_d, &
14 & lsm,lsm_ruc,grav,cp,eps,epsm1,con_rocp, &
15 & con_karman, &
16 & shflx,cdq,wind, &
17 & usfco,vsfco,icplocn2atm, &
18 & zf,ps,u1,v1,t1,q1,prslki,evap,fm,fh,fm10,fh2, &
19 & ust,tskin,qsurf,thsfc_loc,diag_flux,diag_log, &
20 & use_lake_model,iopt_lake,iopt_lake_clm, &
21 & lake_t2m,lake_q2m,use_lake2m, &
22 & f10m,u10m,v10m,t2m,q2m,dpt2m,errmsg,errflg &
23 & )
24!
25 use machine , only : kind_phys, kind_dbl_prec
26 use funcphys, only : fpvs
27 use physcons, only : con_t0c
28 implicit none
29!
30 integer, intent(in) :: im, lsm, lsm_ruc, iopt_lake, iopt_lake_clm
31 logical, intent(in) :: use_lake2m
32 integer, intent(in) :: icplocn2atm
33 logical, intent(in) :: thsfc_loc ! Flag for reference pot. temp.
34 logical, intent(in) :: diag_flux ! Flag for flux method in 2-m diagnostics
35 logical, intent(in) :: diag_log ! Flag for 2-m log diagnostics under stable conditions
36 real(kind=kind_phys), intent(in) :: grav,cp,eps,epsm1,con_rocp
37 real(kind=kind_phys), intent(in) :: con_karman
38 real(kind=kind_phys), dimension(:), intent( in) :: &
39 & zf, ps, u1, v1, t1, q1, ust, tskin, &
40 & usfco, vsfco, &
41 & qsurf, prslki, evap, fm, fh, fm10, fh2, &
42 & shflx, cdq, wind, xlat_d, xlon_d
43 real(kind=kind_phys), dimension(:), intent(out) :: &
44 & f10m, u10m, v10m, t2m, q2m, dpt2m
45 real(kind=kind_phys), dimension(:), intent(in), optional :: &
46 & lake_t2m, lake_q2m
47 integer, dimension(:), intent(in) :: use_lake_model
48 character(len=*), intent(out) :: errmsg
49 integer, intent(out) :: errflg
50!
51! locals
52!
53 real (kind_phys), parameter :: zero = 0._kind_dbl_prec
54 real (kind_phys), parameter :: one = 1._kind_dbl_prec
55 real (kind_phys), parameter :: qmin=1.0e-8
56 integer :: k,i
57
58 logical :: debug_print
59 real(kind=kind_phys) :: q1c, qv, tem, qv1, th2m, x2m, rho
60 real(kind=kind_phys) :: dt, dq, qsfcmr, qsfcprox, ff, fac, dz1
61 real(kind=kind_phys) :: t2_alt, q2_alt
62 real(kind=kind_phys) :: thcon, cqs, chs, chs2, cqs2
63 real(kind=kind_phys) :: testptlat, testptlon
64 logical :: have_2m
65!
66 real(kind=kind_phys) :: fhi, qss, wrk
67! real(kind=kind_phys) sig2k, fhi, qss
68!
69! real, parameter :: g=grav
70!
71 ! Initialize CCPP error handling variables
72 errmsg = ''
73 errflg = 0
74
75 !--
76 testptlat = 35.3_kind_phys
77 testptlon = 273.0_kind_phys
78 !--
79 debug_print = .false.
80!
81! estimate sigma ** k at 2 m
82!
83! sig2k = 1. - 4. * g * 2. / (cp * 280.)
84!
85! initialize variables. all units are supposedly m.k.s. unless specified
86! ps is in pascals
87!
88!!
89
90 do i = 1, im
91 f10m(i) = fm10(i) / fm(i)
92 if (icplocn2atm ==0) then
93 u10m(i) = f10m(i) * u1(i)
94 v10m(i) = f10m(i) * v1(i)
95 else if (icplocn2atm ==1) then
96 u10m(i) = usfco(i)+f10m(i) * (u1(i)-usfco(i))
97 v10m(i) = vsfco(i)+f10m(i) * (v1(i)-vsfco(i))
98 endif
99 have_2m = use_lake_model(i)>0 .and. use_lake2m .and. &
100 & iopt_lake==iopt_lake_clm
101 if(have_2m) then
102 t2m(i) = lake_t2m(i)
103 q2m(i) = lake_q2m(i)
104 endif
105 fhi = fh2(i) / fh(i)
106 wrk = 1.0 - fhi
107
108 if(lsm /= lsm_ruc) then
109 !-- original method
110 if(have_2m) then
111 ! already have 2m T & Q from lake
112 else
113 if(thsfc_loc) then ! Use local potential temperature
114 t2m(i)=tskin(i)*wrk + t1(i)*prslki(i)*fhi - (grav+grav)/cp
115 else ! Use potential temperature referenced to 1000 hPa
116 t2m(i) = tskin(i)*wrk + t1(i)*fhi - (grav+grav)/cp
117 endif
118 if(evap(i) >= 0.) then ! for evaporation>0, use inferred qsurf to deduce q2m
119 q2m(i) = qsurf(i)*wrk + max(qmin,q1(i))*fhi
120 else ! for dew formation, use saturated q at tskin
121 qss = fpvs(tskin(i))
122 qss = eps * qss/(ps(i) + epsm1 * qss)
123 q2m(i) = qss*wrk + max(qmin,q1(i))*fhi
124 endif
125 endif
126 qss = fpvs(t2m(i))
127 qss = eps * qss / (ps(i) + epsm1 * qss)
128 q2m(i) = min(q2m(i),qss)
129 else
130 !RUC lsm
131 thcon = (1.e5_kind_phys/ps(i))**con_rocp
132 !-- make sure 1st level q is not higher than saturated value
133 qss = fpvs(t1(i))
134 qss = eps * qss / (ps(i) + epsm1 * qss)
135 q1c = min(q1(i),qss) ! lev 1 spec. humidity
136
137 qv1 = q1c / (one - q1c) ! lev 1 mixing ratio
138 qsfcmr = qsurf(i)/(one - qsurf(i)) ! surface mixing ratio
139 chs = cdq(i) * wind(i)
140 cqs = chs
141 chs2 = ust(i)*con_karman/fh2(i)
142 cqs2 = chs2
143 qsfcprox = max(qmin,qv1 + evap(i)/cqs) ! surface mix. ratio computed from the flux
144
145 ruc_have_2m: if(.not.have_2m) then
146 if(diag_flux) then
147 !-- flux method
148 th2m = tskin(i)*thcon - shflx(i)/chs2
149 t2m(i) = th2m/thcon
150 x2m = max(qmin,qsfcprox - evap(i)/cqs2) ! mix. ratio
151 q2m(i) = x2m/(one + x2m) ! spec. humidity
152 else
153 t2m(i) = tskin(i)*wrk + t1(i)*fhi - (grav+grav)/cp
154 q2m(i) = qsurf(i)*wrk + max(qmin,q1c)*fhi
155 endif ! flux method
156
157 if(diag_log) then
158 !-- Alternative logarithmic diagnostics:
159 dt = t1(i) - tskin(i)
160 dq = qv1 - qsfcmr
161 dz1= zf(i) ! level of atm. forcing
162 IF (dt > zero) THEN
163 ff = min(max(one-dt/10._kind_phys,0.01_kind_phys), one)
164 !for now, set zt = 0.05
165 fac = log((2._kind_phys +.05_kind_phys)/(0.05_kind_phys + &
166 & ff))/log((dz1 + .05_kind_phys)/(0.05_kind_phys + ff))
167 t2_alt = tskin(i) + fac * dt
168 ELSE
169 !no alternatives (yet) for unstable conditions
170 t2_alt = t2m(i)
171 ENDIF
172
173 IF (dq > zero) THEN
174 ff = min(max(one-dq/0.003_kind_phys,0.01_kind_phys), one)
175 !-- for now, set zt = 0.05
176 fac = log((2._kind_phys +.05_kind_phys)/(0.05_kind_phys + &
177 & ff))/log((dz1 + .05_kind_phys)/(0.05_kind_phys + ff))
178 q2_alt = qsfcmr + fac * dq ! mix. ratio
179 q2_alt = q2_alt/(one + q2_alt) ! spec. humidity
180 ELSE
181 !no alternatives (yet) for unstable conditions
182 q2_alt = q2m(i)
183 ENDIF
184 !-- Note: use of alternative diagnostics will make
185 ! it cooler and drier with stable stratification
186 t2m(i) = t2_alt
187 q2m(i) = q2_alt
188 endif ! log method for stable regime
189
190 !-- check that T2m values lie in the range between tskin and t1
191 x2m = max(min(tskin(i),t1(i)) , t2m(i))
192 t2m(i) = min(max(tskin(i),t1(i)) , x2m)
193 !-- check that Q2m values lie in the range between qsurf and q1
194 x2m = max(min(qsurf(i),q1c) , q2m(i))
195 q2m(i) = min(max(qsurf(i),q1c) , x2m)
196
197 !-- make sure q2m is not oversaturated
198 qss = fpvs(t2m(i))
199 qss = eps * qss/(ps(i) + epsm1 * qss)
200 q2m(i) = min(q2m(i),qss)
201
202 if(diag_flux) then
203 !-- from WRF, applied in HRRR - Jimy Dudhia
204 ! Limit Q2m diagnostic to no more than 5 percent higher than lowest level value
205 ! This prevents unrealistic values when QFX is not mostly surface
206 ! flux because calculation is based on surface flux only.
207 ! Problems occurred in transition periods and weak winds and vegetation source
208 q2m(i) = min(q2m(i),1.05_kind_dbl_prec*q1c) ! works if qsurf > q1c, evaporation
209 endif
210 endif ruc_have_2m
211
212
213 !-- Compute dew point, using vapor pressure
214 qv = max(qmin,(q2m(i)/(1.-q2m(i))))
215 tem = max(ps(i) * qv/( eps - epsm1 *qv), qmin)
216 dpt2m(i) = 243.5_kind_dbl_prec/( ( 17.67_kind_dbl_prec / &
217 & log(tem/611.2_kind_dbl_prec) ) - one) + con_t0c
218 dpt2m(i) = min(dpt2m(i),t2m(i))
219
220
221 if (debug_print) then
222 !-- diagnostics for a test point with known lat/lon
223 if (abs(xlat_d(i)-testptlat).lt.0.2 .and. &
224 & abs(xlon_d(i)-testptlon).lt.0.2)then
225 print 100,'(ruc_lsm_diag) i=',i, &
226 & ' lat,lon=',xlat_d(i),xlon_d(i),'zf ',zf(i), &
227 & 'tskin ',tskin(i),'t2m ',t2m(i),'t1',t1(i),'shflx',shflx(i),&
228 & 'qsurf ',qsurf(i),'qsfcprox ',qsfcprox,'q2m ',q2m(i), &
229 & 'q1 ',q1(i),'evap ',evap(i),'dpt2m ',dpt2m(i), &
230 & 'chs2 ',chs2,'cqs2 ',cqs2,'cqs ',cqs,'cdq',cdq(i)
231 endif
232 endif
233 100 format (";;; ",a,i4,a,2f14.7/(4(a10,'='es11.4)))
234 endif ! RUC LSM
235 enddo
236
237 return
238 end subroutine sfc_diag_run
240
241 end module sfc_diag
subroutine shflx(nsoil, smc, smcmax, dt, yy, zz1, zsoil, zbot, psisat, bexp, df1, ice, quartz, csoil, vegtyp, shdfac, lheatstrg, stc, t1, tbot, sh2o, ssoil)
This subroutine updates the temperature state of the soil column based on the thermal diffusion equat...
Definition sflx.f:3315
subroutine sfc_diag_run(im, xlat_d, xlon_d, lsm, lsm_ruc, grav, cp, eps, epsm1, con_rocp, con_karman, shflx, cdq, wind, usfco, vsfco, icplocn2atm, zf, ps, u1, v1, t1, q1, prslki, evap, fm, fh, fm10, fh2, ust, tskin, qsurf, thsfc_loc, diag_flux, diag_log, use_lake_model, iopt_lake, iopt_lake_clm, lake_t2m, lake_q2m, use_lake2m, f10m, u10m, v10m, t2m, q2m, dpt2m, errmsg, errflg)
Definition sfc_diag.f:24
This module contain the RUC land surface model driver.
Definition lsm_ruc.F90:5
This module contains the land surface diagnose calcualtion.
Definition sfc_diag.f:5