PageRenderTime 62ms CodeModel.GetById 28ms RepoModel.GetById 0ms app.codeStats 0ms

/wrfv2_fire/phys/module_fdda_psufddagd.F

http://github.com/jbeezley/wrf-fire
FORTRAN Legacy | 1288 lines | 885 code | 172 blank | 231 comment | 38 complexity | a954ca769b64aad37a55e85a99436c37 MD5 | raw file
Possible License(s): AGPL-1.0
  1. !wrf:model_layer:physics
  2. !
  3. !
  4. !
  5. MODULE module_fdda_psufddagd
  6. CONTAINS
  7. !
  8. !-------------------------------------------------------------------
  9. !
  10. SUBROUTINE fddagd(itimestep,dx,dt,xtime, &
  11. id,analysis_interval, end_fdda_hour, &
  12. if_no_pbl_nudging_uv, if_no_pbl_nudging_t, if_no_pbl_nudging_q, &
  13. if_zfac_uv, k_zfac_uv, if_zfac_t, k_zfac_t, if_zfac_q, k_zfac_q, &
  14. guv, gt, gq, if_ramping, dtramp_min, &
  15. grid_sfdda, &
  16. analysis_interval_sfc, end_fdda_hour_sfc, guv_sfc, gt_sfc, gq_sfc, &
  17. rinblw, &
  18. u3d,v3d,th3d,t3d, &
  19. qv3d, &
  20. p3d,pi3d, &
  21. u_ndg_old,v_ndg_old,t_ndg_old,q_ndg_old,mu_ndg_old, &
  22. u_ndg_new,v_ndg_new,t_ndg_new,q_ndg_new,mu_ndg_new, &
  23. u10_ndg_old, v10_ndg_old, t2_ndg_old, th2_ndg_old, q2_ndg_old, &
  24. rh_ndg_old, psl_ndg_old, ps_ndg_old, tob_ndg_old, odis_ndg_old, &
  25. u10_ndg_new, v10_ndg_new, t2_ndg_new, th2_ndg_new, q2_ndg_new, &
  26. rh_ndg_new, psl_ndg_new, ps_ndg_new, tob_ndg_new, odis_ndg_new, &
  27. RUNDGDTEN,RVNDGDTEN,RTHNDGDTEN,RQVNDGDTEN,RMUNDGDTEN,&
  28. pblh, ht, regime, znt, z, z_at_w, &
  29. ids,ide, jds,jde, kds,kde, &
  30. ims,ime, jms,jme, kms,kme, &
  31. its,ite, jts,jte, kts,kte )
  32. !-------------------------------------------------------------------
  33. implicit none
  34. !-------------------------------------------------------------------
  35. !
  36. ! This code was implemented by Aijun Deng (Penn State). The 3-D analysis nudging was comleted
  37. ! and released in December 2006. The surface analysis nudging capability was added and
  38. ! released in March 2009 with WRFV3.1.
  39. !
  40. !-- u3d 3d u-velocity staggered on u points
  41. !-- v3d 3d v-velocity staggered on v points
  42. !-- th3d 3d potential temperature (k)
  43. !-- t3d temperature (k)
  44. !-- qv3d 3d water vapor mixing ratio (kg/kg)
  45. !-- p3d 3d pressure (pa)
  46. !-- pi3d 3d exner function (dimensionless)
  47. !-- rundgdten staggered u tendency due to
  48. ! fdda grid nudging (m/s/s)
  49. !-- rvndgdten staggered v tendency due to
  50. ! fdda grid nudging (m/s/s)
  51. !-- rthndgdten theta tendency due to
  52. ! fdda grid nudging (K/s)
  53. !-- rqvndgdten qv tendency due to
  54. ! fdda grid nudging (kg/kg/s)
  55. !-- rmundgdten mu tendency due to
  56. ! fdda grid nudging (Pa/s)
  57. !-- ids start index for i in domain
  58. !-- ide end index for i in domain
  59. !-- jds start index for j in domain
  60. !-- jde end index for j in domain
  61. !-- kds start index for k in domain
  62. !-- kde end index for k in domain
  63. !-- ims start index for i in memory
  64. !-- ime end index for i in memory
  65. !-- jms start index for j in memory
  66. !-- jme end index for j in memory
  67. !-- kms start index for k in memory
  68. !-- kme end index for k in memory
  69. !-- its start index for i in tile
  70. !-- ite end index for i in tile
  71. !-- jts start index for j in tile
  72. !-- jte end index for j in tile
  73. !-- kts start index for k in tile
  74. !-- kte end index for k in tile
  75. !-------------------------------------------------------------------
  76. !
  77. INTEGER, INTENT(IN) :: itimestep, analysis_interval, end_fdda_hour
  78. INTEGER, INTENT(IN) :: analysis_interval_sfc, end_fdda_hour_sfc
  79. INTEGER, INTENT(IN) :: grid_sfdda
  80. INTEGER, INTENT(IN) :: if_no_pbl_nudging_uv, if_no_pbl_nudging_t, &
  81. if_no_pbl_nudging_q
  82. INTEGER, INTENT(IN) :: if_zfac_uv, if_zfac_t, if_zfac_q
  83. INTEGER, INTENT(IN) :: k_zfac_uv, k_zfac_t, k_zfac_q
  84. INTEGER, INTENT(IN) :: if_ramping
  85. INTEGER , INTENT(IN) :: id
  86. REAL, INTENT(IN) :: DT, dx, xtime, dtramp_min
  87. INTEGER, INTENT(IN) :: ids,ide, jds,jde, kds,kde, &
  88. ims,ime, jms,jme, kms,kme, &
  89. its,ite, jts,jte, kts,kte
  90. REAL, DIMENSION( ims:ime, kms:kme, jms:jme ), &
  91. INTENT(IN) :: qv3d, &
  92. p3d, &
  93. pi3d, &
  94. th3d, &
  95. t3d, &
  96. z, &
  97. z_at_w
  98. REAL, DIMENSION( ims:ime, kms:kme, jms:jme ), &
  99. INTENT(INOUT) :: rundgdten, &
  100. rvndgdten, &
  101. rthndgdten, &
  102. rqvndgdten
  103. REAL, DIMENSION( ims:ime, jms:jme ), &
  104. INTENT(INOUT) :: rmundgdten
  105. REAL, DIMENSION( ims:ime, kms:kme, jms:jme ), &
  106. INTENT(IN) :: u_ndg_old, &
  107. v_ndg_old, &
  108. t_ndg_old, &
  109. q_ndg_old, &
  110. u_ndg_new, &
  111. v_ndg_new, &
  112. t_ndg_new, &
  113. q_ndg_new
  114. REAL, DIMENSION( ims:ime, jms:jme ), &
  115. INTENT(IN) :: u10_ndg_old, &
  116. v10_ndg_old, &
  117. t2_ndg_old, &
  118. th2_ndg_old, &
  119. q2_ndg_old, &
  120. rh_ndg_old, &
  121. psl_ndg_old, &
  122. ps_ndg_old, &
  123. u10_ndg_new, &
  124. v10_ndg_new, &
  125. t2_ndg_new, &
  126. th2_ndg_new, &
  127. q2_ndg_new, &
  128. rh_ndg_new, &
  129. psl_ndg_new, &
  130. ps_ndg_new
  131. REAL, DIMENSION( ims:ime, jms:jme ), &
  132. INTENT(IN) :: tob_ndg_old, &
  133. tob_ndg_new
  134. REAL, DIMENSION( ims:ime, jms:jme ), &
  135. INTENT(INOUT) :: mu_ndg_old, &
  136. mu_ndg_new
  137. REAL, DIMENSION( ims:ime, jms:jme ), &
  138. INTENT(IN) :: odis_ndg_old, odis_ndg_new
  139. REAL, DIMENSION( ims:ime, kms:kme, jms:jme ), &
  140. INTENT(IN) :: u3d, &
  141. v3d
  142. REAL, DIMENSION( ims:ime, jms:jme ), INTENT(IN) :: pblh, &
  143. ht, &
  144. regime, &
  145. znt
  146. REAL, INTENT(IN) :: guv, gt, gq
  147. REAL, INTENT(IN) :: guv_sfc, gt_sfc, gq_sfc, rinblw
  148. INTEGER :: i, j, k, itsu, jtsv, itf, jtf, ktf, i0, k0, j0
  149. REAL :: xtime_old, xtime_new, coef, val_analysis
  150. INTEGER :: kpbl, dbg_level
  151. REAL :: zpbl, zagl, zagl_bot, zagl_top, tfac, actual_end_fdda_min
  152. REAL, DIMENSION( its:ite, kts:kte, jts:jte, 4 ) :: wpbl ! 1: u, 2: v, 3: t, 4: q
  153. REAL, DIMENSION( kts:kte, 4 ) :: wzfac ! 1: u, 2: v, 3: t, 4: q
  154. LOGICAL , EXTERNAL :: wrf_dm_on_monitor
  155. CHARACTER (LEN=256) :: message
  156. INTEGER :: int4
  157. int4 = 1 ! 1: temporal interpolation. else: target nudging toward *_ndg_new values
  158. actual_end_fdda_min = end_fdda_hour*60.0
  159. IF( if_ramping == 1 .AND. dtramp_min > 0.0 ) &
  160. actual_end_fdda_min = end_fdda_hour*60.0 + ABS(dtramp_min)
  161. IF( xtime > actual_end_fdda_min ) THEN
  162. ! If xtime is greater than the end time, no need to calculate tendencies. Just set the tnedencies
  163. ! to zero to turn off nudging and return.
  164. DO j = jts, jte
  165. DO k = kts, kte
  166. DO i = its, ite
  167. RUNDGDTEN(i,k,j) = 0.0
  168. RVNDGDTEN(i,k,j) = 0.0
  169. RTHNDGDTEN(i,k,j) = 0.0
  170. RQVNDGDTEN(i,k,j) = 0.0
  171. IF( k .EQ. kts ) RMUNDGDTEN(i,j) = 0.
  172. ENDDO
  173. ENDDO
  174. ENDDO
  175. RETURN
  176. ENDIF
  177. IF( analysis_interval <= 0 )CALL wrf_error_fatal('In grid FDDA, gfdda_interval_m must be > 0')
  178. xtime_old = FLOOR(xtime/analysis_interval) * analysis_interval * 1.0
  179. xtime_new = xtime_old + analysis_interval
  180. IF( int4 == 1 ) THEN
  181. coef = (xtime-xtime_old)/(xtime_new-xtime_old)
  182. ELSE
  183. coef = 1.0 ! Nudging toward a target value (*_ndg_new values)
  184. ENDIF
  185. IF ( wrf_dm_on_monitor()) THEN
  186. CALL get_wrf_debug_level( dbg_level )
  187. IF( xtime-xtime_old < 0.5*dt/60.0 ) THEN
  188. IF( xtime < end_fdda_hour*60.0 ) THEN
  189. WRITE(message,'(a,i1,a,f10.3,a)') &
  190. 'D0',id,' 3-D analysis nudging reads new data at time = ', xtime, ' min.'
  191. CALL wrf_message( TRIM(message) )
  192. WRITE(message,'(a,i1,a,2f8.2,a)') &
  193. 'D0',id,' 3-D analysis nudging bracketing times = ', xtime_old, xtime_new, ' min.'
  194. CALL wrf_message( TRIM(message) )
  195. ENDIF
  196. actual_end_fdda_min = end_fdda_hour*60.0
  197. IF( if_ramping == 1 .AND. dtramp_min > 0.0 ) &
  198. actual_end_fdda_min = end_fdda_hour*60.0 + ABS(dtramp_min)
  199. IF( dbg_level .GE. 10 .AND. xtime <= actual_end_fdda_min ) THEN
  200. ! Find the mid point of the tile and print out the sample values
  201. i0 = (ite-its)/2+its
  202. j0 = (jte-jts)/2+jts
  203. IF( guv > 0.0 ) THEN
  204. DO k = kts, kte
  205. WRITE(message,'(a,i1,a,3i4,a,f10.4,a,f10.4)') &
  206. ' D0',id,' sample 3-D analysis values at i,k,j=', i0, k, j0, &
  207. ' u_ndg_old=', u_ndg_old(i0,k,j0), ' u_ndg_new=', u_ndg_new(i0,k,j0)
  208. CALL wrf_message( TRIM(message) )
  209. ENDDO
  210. WRITE(message,'(a,i1,a,3i4,a,f10.4,a,f10.4)') &
  211. ' D0',id,' sample 3-D analysis values at i,k,j=', i0, k, j0, &
  212. ' mu_ndg_old=', mu_ndg_old(i0,j0), ' mu_ndg_new=', mu_ndg_new(i0,j0)
  213. CALL wrf_message( TRIM(message) )
  214. DO k = kts, kte
  215. WRITE(message,'(a,i1,a,3i4,a,f10.4,a,f10.4)') &
  216. ' D0',id,' sample 3-D analysis values at i,k,j=', i0, k, j0, &
  217. ' v_ndg_old=', v_ndg_old(i0,k,j0), ' v_ndg_new=', v_ndg_new(i0,k,j0)
  218. CALL wrf_message( TRIM(message) )
  219. ENDDO
  220. ENDIF
  221. IF( gt > 0.0 ) THEN
  222. DO k = kts, kte
  223. WRITE(message,'(a,i1,a,3i4,a,f10.4,a,f10.4)') &
  224. ' D0',id,' sample 3-D analysis values at i,k,j=', i0, k, j0, &
  225. ' t_ndg_old=', t_ndg_old(i0,k,j0), ' t_ndg_new=', t_ndg_new(i0,k,j0)
  226. CALL wrf_message( TRIM(message) )
  227. ENDDO
  228. ENDIF
  229. IF( gq > 0.0 ) THEN
  230. DO k = kts, kte
  231. WRITE(message,'(a,i1,a,3i4,a,f10.4,a,f10.4)') &
  232. ' D0',id,' sample 3-D analysis values at i,k,j=', i0, k, j0, &
  233. ' q_ndg_old=', q_ndg_old(i0,k,j0), ' q_ndg_new=', q_ndg_new(i0,k,j0)
  234. CALL wrf_message( TRIM(message) )
  235. ENDDO
  236. ENDIF
  237. IF( int4 == 1 ) then
  238. WRITE(message,'(a,i1,a)') ' D0',id, &
  239. ' 3-D nudging towards the temporally interpolated analysis'
  240. ELSE
  241. WRITE(message,'(a,i1,a)') ' D0',id, &
  242. ' 3-D nudging towards the target analysis'
  243. ENDIF
  244. ENDIF
  245. ENDIF
  246. ENDIF
  247. jtsv=MAX0(jts,jds+1)
  248. itsu=MAX0(its,ids+1)
  249. jtf=MIN0(jte,jde-1)
  250. ktf=MIN0(kte,kde-1)
  251. itf=MIN0(ite,ide-1)
  252. !
  253. ! If the user-defined namelist switches (if_no_pbl_nudging_uv, if_no_pbl_nudging_t,
  254. ! if_no_pbl_nudging_q swithes) are set to 1, compute the weighting function, wpbl(:,k,:,:),
  255. ! based on the PBL depth. wpbl = 1 above the PBL and wpbl = 0 in the PBL. If all
  256. ! the switche are set to zero, wpbl = 1 (default value).
  257. !
  258. wpbl(:,:,:,:) = 1.0
  259. IF( if_no_pbl_nudging_uv == 1 .OR. grid_sfdda == 1 ) THEN
  260. DO j=jts,jtf
  261. DO i=itsu,itf
  262. kpbl = 1
  263. zpbl = 0.5 * ( pblh(i-1,j) + pblh(i,j) )
  264. loop_ku: DO k=kts,ktf
  265. ! zagl = 0.5 * ( z(i-1,k,j)-ht(i-1,j) + z(i,k,j)-ht(i,j) )
  266. zagl_bot = 0.5 * ( z_at_w(i-1,k, j)-ht(i-1,j) + z_at_w(i,k, j)-ht(i,j) )
  267. zagl_top = 0.5 * ( z_at_w(i-1,k+1,j)-ht(i-1,j) + z_at_w(i,k+1,j)-ht(i,j) )
  268. IF( zpbl >= zagl_bot .AND. zpbl < zagl_top ) THEN
  269. kpbl = k
  270. EXIT loop_ku
  271. ENDIF
  272. ENDDO loop_ku
  273. DO k=kts,ktf
  274. IF( k <= kpbl ) wpbl(i, k, j, 1) = 0.0
  275. IF( k == kpbl+1 ) wpbl(i, k, j, 1) = 0.1
  276. IF( k > kpbl+1 ) wpbl(i, k, j, 1) = 1.0
  277. ENDDO
  278. ENDDO
  279. ENDDO
  280. DO i=its,itf
  281. DO j=jtsv,jtf
  282. kpbl = 1
  283. zpbl = 0.5 * ( pblh(i,j-1) + pblh(i,j) )
  284. loop_kv: DO k=kts,ktf
  285. ! zagl = 0.5 * ( z(i,k,j-1)-ht(i,j-1) + z(i,k,j)-ht(i,j) )
  286. zagl_bot = 0.5 * ( z_at_w(i,k, j-1)-ht(i,j-1) + z_at_w(i,k, j)-ht(i,j) )
  287. zagl_top = 0.5 * ( z_at_w(i,k+1,j-1)-ht(i,j-1) + z_at_w(i,k+1,j)-ht(i,j) )
  288. IF( zpbl >= zagl_bot .AND. zpbl < zagl_top ) THEN
  289. kpbl = k
  290. EXIT loop_kv
  291. ENDIF
  292. ENDDO loop_kv
  293. DO k=kts,ktf
  294. IF( k <= kpbl ) wpbl(i, k, j, 2) = 0.0
  295. IF( k == kpbl+1 ) wpbl(i, k, j, 2) = 0.1
  296. IF( k > kpbl+1 ) wpbl(i, k, j, 2) = 1.0
  297. ENDDO
  298. ENDDO
  299. ENDDO
  300. ENDIF
  301. IF( if_no_pbl_nudging_t == 1 .OR. grid_sfdda == 1 ) THEN
  302. DO j=jts,jtf
  303. DO i=its,itf
  304. kpbl = 1
  305. zpbl = pblh(i,j)
  306. loop_kt: DO k=kts,ktf
  307. ! zagl = z(i,k,j)-ht(i,j)
  308. zagl_bot = z_at_w(i,k, j)-ht(i,j)
  309. zagl_top = z_at_w(i,k+1,j)-ht(i,j)
  310. IF( zpbl >= zagl_bot .AND. zpbl < zagl_top ) THEN
  311. kpbl = k
  312. EXIT loop_kt
  313. ENDIF
  314. ENDDO loop_kt
  315. DO k=kts,ktf
  316. IF( k <= kpbl ) wpbl(i, k, j, 3) = 0.0
  317. IF( k == kpbl+1 ) wpbl(i, k, j, 3) = 0.1
  318. IF( k > kpbl+1 ) wpbl(i, k, j, 3) = 1.0
  319. ENDDO
  320. ENDDO
  321. ENDDO
  322. ENDIF
  323. IF( if_no_pbl_nudging_q == 1 .OR. grid_sfdda == 1 ) THEN
  324. DO j=jts,jtf
  325. DO i=its,itf
  326. kpbl = 1
  327. zpbl = pblh(i,j)
  328. loop_kq: DO k=kts,ktf
  329. ! zagl = z(i,k,j)-ht(i,j)
  330. zagl_bot = z_at_w(i,k, j)-ht(i,j)
  331. zagl_top = z_at_w(i,k+1,j)-ht(i,j)
  332. IF( zpbl >= zagl_bot .AND. zpbl < zagl_top ) THEN
  333. kpbl = k
  334. EXIT loop_kq
  335. ENDIF
  336. ENDDO loop_kq
  337. DO k=kts,ktf
  338. IF( k <= kpbl ) wpbl(i, k, j, 4) = 0.0
  339. IF( k == kpbl+1 ) wpbl(i, k, j, 4) = 0.1
  340. IF( k > kpbl+1 ) wpbl(i, k, j, 4) = 1.0
  341. ENDDO
  342. ENDDO
  343. ENDDO
  344. ENDIF
  345. !
  346. ! If the user-defined namelist switches (if_zfac_uv, if_zfac_t,
  347. ! if_zfac_q swithes) are set to 1, compute the weighting function, wzfac(k,:),
  348. ! based on the namelist specified k values (k_zfac_uv, k_zfac_t and k_zfac_q) below which analysis
  349. ! nudging is turned off (wzfac = 1 above k_zfac_x and = 0 in below k_zfac_x). If all
  350. ! the switche are set to zero, wzfac = 1 (default value).
  351. !
  352. wzfac(:,:) = 1.0
  353. IF( if_zfac_uv == 1 ) THEN
  354. DO j=jts,jtf
  355. DO i=itsu,itf
  356. DO k=kts,ktf
  357. IF( k <= k_zfac_uv ) wzfac(k, 1:2) = 0.0
  358. IF( k == k_zfac_uv+1 ) wzfac(k, 1:2) = 0.1
  359. IF( k > k_zfac_uv+1 ) wzfac(k, 1:2) = 1.0
  360. ENDDO
  361. ENDDO
  362. ENDDO
  363. ENDIF
  364. IF( if_zfac_t == 1 ) THEN
  365. DO j=jts,jtf
  366. DO i=itsu,itf
  367. DO k=kts,ktf
  368. IF( k <= k_zfac_t ) wzfac(k, 3) = 0.0
  369. IF( k == k_zfac_t+1 ) wzfac(k, 3) = 0.1
  370. IF( k > k_zfac_t+1 ) wzfac(k, 3) = 1.0
  371. ENDDO
  372. ENDDO
  373. ENDDO
  374. ENDIF
  375. IF( if_zfac_q == 1 ) THEN
  376. DO j=jts,jtf
  377. DO i=itsu,itf
  378. DO k=kts,ktf
  379. IF( k <= k_zfac_q ) wzfac(k, 4) = 0.0
  380. IF( k == k_zfac_q+1 ) wzfac(k, 4) = 0.1
  381. IF( k > k_zfac_q+1 ) wzfac(k, 4) = 1.0
  382. ENDDO
  383. ENDDO
  384. ENDDO
  385. ENDIF
  386. !
  387. ! If if_ramping and dtramp_min are defined by user, comput a time weighting function, tfac,
  388. ! for analysis nudging so that at the end of the nudging period (which has to be at a
  389. ! analysis time) we ramp down the nudging coefficient, based on the use-defined sign of dtramp_min.
  390. !
  391. ! When dtramp_min is negative, ramping ends at end_fdda_hour and starts at
  392. ! end_fdda_hour-ABS(dtramp_min).
  393. !
  394. ! When dtramp_min is positive, ramping starts at end_fdda_hour and ends at
  395. ! end_fdda_hour+ABS(dtramp_min). In this case, the obs values are extrapolated using
  396. ! the obs tendency saved from the previous FDDA wondow. More specifically for extrapolation,
  397. ! coef (see codes below) is recalculated to reflect extrapolation during the ramping period.
  398. !
  399. tfac = 1.0
  400. IF( if_ramping == 1 .AND. ABS(dtramp_min) > 0.0 ) THEN
  401. IF( dtramp_min <= 0.0 ) THEN
  402. actual_end_fdda_min = end_fdda_hour*60.0
  403. ELSE
  404. actual_end_fdda_min = end_fdda_hour*60.0 + dtramp_min
  405. ENDIF
  406. IF( xtime < actual_end_fdda_min-ABS(dtramp_min) )THEN
  407. tfac = 1.0
  408. ELSEIF( xtime >= actual_end_fdda_min-ABS(dtramp_min) .AND. xtime <= actual_end_fdda_min )THEN
  409. tfac = ( actual_end_fdda_min - xtime ) / ABS(dtramp_min)
  410. IF( dtramp_min > 0.0 ) coef = (xtime-xtime_old+analysis_interval)/(analysis_interval*1.0)
  411. ELSE
  412. tfac = 0.0
  413. ENDIF
  414. ENDIF
  415. !
  416. ! Surface Analysis Nudging
  417. !
  418. IF( grid_sfdda == 1 ) THEN
  419. CALL SFDDAGD(itimestep,dx,dt,xtime, id, &
  420. analysis_interval_sfc, end_fdda_hour_sfc, guv_sfc, gt_sfc, gq_sfc, &
  421. rinblw, &
  422. u3d,v3d,th3d,t3d, &
  423. qv3d, &
  424. p3d,pi3d, &
  425. u10_ndg_old, v10_ndg_old, t2_ndg_old, th2_ndg_old, q2_ndg_old, &
  426. rh_ndg_old, psl_ndg_old, ps_ndg_old, tob_ndg_old, odis_ndg_old, &
  427. u10_ndg_new, v10_ndg_new, t2_ndg_new, th2_ndg_new, q2_ndg_new, &
  428. rh_ndg_new, psl_ndg_new, ps_ndg_new, tob_ndg_new, odis_ndg_new, &
  429. RUNDGDTEN,RVNDGDTEN,RTHNDGDTEN,RQVNDGDTEN,RMUNDGDTEN,&
  430. pblh, ht, regime, znt, z, z_at_w, &
  431. ids,ide, jds,jde, kds,kde, &
  432. ims,ime, jms,jme, kms,kme, &
  433. its,ite, jts,jte, kts,kte, wpbl, wzfac, if_ramping, dtramp_min, &
  434. actual_end_fdda_min, tfac )
  435. ENDIF
  436. !
  437. ! Compute 3-D nudging tendencies for u, v, t and q
  438. !
  439. DO j=jts,jtf
  440. DO k=kts,ktf
  441. DO i=itsu,itf
  442. val_analysis = u_ndg_old(i,k,j) *( 1.0 - coef ) + u_ndg_new(i,k,j) * coef
  443. RUNDGDTEN(i,k,j) = RUNDGDTEN(i,k,j) + guv * wpbl(i,k,j,1) * wzfac(k,1) * tfac * &
  444. ( val_analysis - u3d(i,k,j) )
  445. ENDDO
  446. ENDDO
  447. ENDDO
  448. DO j=jtsv,jtf
  449. DO k=kts,ktf
  450. DO i=its,itf
  451. val_analysis = v_ndg_old(i,k,j) *( 1.0 - coef ) + v_ndg_new(i,k,j) * coef
  452. RVNDGDTEN(i,k,j) = RVNDGDTEN(i,k,j) + guv * wpbl(i,k,j,2) * wzfac(k,2) * tfac * &
  453. ( val_analysis - v3d(i,k,j) )
  454. ENDDO
  455. ENDDO
  456. ENDDO
  457. DO j=jts,jtf
  458. DO k=kts,ktf
  459. DO i=its,itf
  460. val_analysis = t_ndg_old(i,k,j) *( 1.0 - coef ) + t_ndg_new(i,k,j) * coef
  461. RTHNDGDTEN(i,k,j) = RTHNDGDTEN(i,k,j) + gt * wpbl(i,k,j,3) * wzfac(k,3) * tfac * &
  462. ( val_analysis - th3d(i,k,j) + 300.0 )
  463. val_analysis = q_ndg_old(i,k,j) *( 1.0 - coef ) + q_ndg_new(i,k,j) * coef
  464. RQVNDGDTEN(i,k,j) = RQVNDGDTEN(i,k,j) + gq * wpbl(i,k,j,4) * wzfac(k,4) * tfac * &
  465. ( val_analysis - qv3d(i,k,j) )
  466. ENDDO
  467. ENDDO
  468. ENDDO
  469. END SUBROUTINE fddagd
  470. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  471. SUBROUTINE sfddagd(itimestep,dx,dt,xtime, &
  472. id, analysis_interval_sfc, end_fdda_hour_sfc, &
  473. guv_sfc, gt_sfc, gq_sfc, rinblw, &
  474. u3d,v3d,th3d,t3d, &
  475. qv3d, &
  476. p3d,pi3d, &
  477. u10_ndg_old, v10_ndg_old, t2_ndg_old, th2_ndg_old, q2_ndg_old, &
  478. rh_ndg_old, psl_ndg_old, ps_ndg_old, tob_ndg_old, odis_ndg_old, &
  479. u10_ndg_new, v10_ndg_new, t2_ndg_new, th2_ndg_new, q2_ndg_new, &
  480. rh_ndg_new, psl_ndg_new, ps_ndg_new, tob_ndg_new, odis_ndg_new, &
  481. RUNDGDTEN,RVNDGDTEN,RTHNDGDTEN,RQVNDGDTEN,RMUNDGDTEN, &
  482. pblh, ht, regime, znt, z, z_at_w, &
  483. ids,ide, jds,jde, kds,kde, &
  484. ims,ime, jms,jme, kms,kme, &
  485. its,ite, jts,jte, kts,kte, wpbl, wzfac, if_ramping, dtramp_min, &
  486. actual_end_fdda_min, tfac)
  487. !-------------------------------------------------------------------
  488. USE module_model_constants
  489. implicit none
  490. !-------------------------------------------------------------------
  491. !
  492. ! This code was implemented by Aijun Deng (Penn State). The 3-D analysis nudging was comleted
  493. ! and released in December 2006. The surface analysis nudging capability was added and
  494. ! released in March 2009 with WRFV3.1.
  495. !
  496. !-- u3d 3d u-velocity staggered on u points
  497. !-- v3d 3d v-velocity staggered on v points
  498. !-- th3d 3d potential temperature (k)
  499. !-- t3d temperature (k)
  500. !-- qv3d 3d water vapor mixing ratio (kg/kg)
  501. !-- p3d 3d pressure (pa)
  502. !-- pi3d 3d exner function (dimensionless)
  503. !-- rundgdten staggered u tendency due to
  504. ! fdda grid nudging (m/s/s)
  505. !-- rvndgdten staggered v tendency due to
  506. ! fdda grid nudging (m/s/s)
  507. !-- rthndgdten theta tendency due to
  508. ! fdda grid nudging (K/s)
  509. !-- rqvndgdten qv tendency due to
  510. ! fdda grid nudging (kg/kg/s)
  511. !-- rmundgdten mu tendency due to
  512. ! fdda grid nudging (Pa/s)
  513. !-- ids start index for i in domain
  514. !-- ide end index for i in domain
  515. !-- jds start index for j in domain
  516. !-- jde end index for j in domain
  517. !-- kds start index for k in domain
  518. !-- kde end index for k in domain
  519. !-- ims start index for i in memory
  520. !-- ime end index for i in memory
  521. !-- jms start index for j in memory
  522. !-- jme end index for j in memory
  523. !-- kms start index for k in memory
  524. !-- kme end index for k in memory
  525. !-- its start index for i in tile
  526. !-- ite end index for i in tile
  527. !-- jts start index for j in tile
  528. !-- jte end index for j in tile
  529. !-- kts start index for k in tile
  530. !-- kte end index for k in tile
  531. !-------------------------------------------------------------------
  532. !
  533. INTEGER, INTENT(IN) :: itimestep, analysis_interval_sfc, end_fdda_hour_sfc
  534. INTEGER , INTENT(IN) :: id
  535. REAL, INTENT(IN) :: dx,DT, xtime
  536. INTEGER, INTENT(IN) :: ids,ide, jds,jde, kds,kde, &
  537. ims,ime, jms,jme, kms,kme, &
  538. its,ite, jts,jte, kts,kte
  539. REAL, DIMENSION( ims:ime, kms:kme, jms:jme ), &
  540. INTENT(IN) :: qv3d, &
  541. p3d, &
  542. pi3d, &
  543. th3d, &
  544. t3d, &
  545. z, &
  546. z_at_w
  547. REAL, DIMENSION( ims:ime, kms:kme, jms:jme ), &
  548. INTENT(INOUT) :: rundgdten, &
  549. rvndgdten, &
  550. rthndgdten, &
  551. rqvndgdten
  552. REAL, DIMENSION( ims:ime, jms:jme ), &
  553. INTENT(INOUT) :: rmundgdten
  554. REAL, DIMENSION( ims:ime, jms:jme ), &
  555. INTENT(IN) :: u10_ndg_old, &
  556. v10_ndg_old, &
  557. t2_ndg_old, &
  558. th2_ndg_old, &
  559. q2_ndg_old, &
  560. rh_ndg_old, &
  561. psl_ndg_old, &
  562. ps_ndg_old, &
  563. u10_ndg_new, &
  564. v10_ndg_new, &
  565. t2_ndg_new, &
  566. th2_ndg_new, &
  567. q2_ndg_new, &
  568. rh_ndg_new, &
  569. psl_ndg_new, &
  570. ps_ndg_new
  571. REAL, DIMENSION( ims:ime, jms:jme ), &
  572. INTENT(IN) :: tob_ndg_old, &
  573. tob_ndg_new
  574. REAL, DIMENSION( ims:ime, kms:kme, jms:jme ), &
  575. INTENT(IN) :: u3d, &
  576. v3d
  577. REAL, DIMENSION( ims:ime, jms:jme ), &
  578. INTENT(IN) :: odis_ndg_old, odis_ndg_new
  579. REAL, DIMENSION( ims:ime, jms:jme ), INTENT(IN) :: pblh, &
  580. ht, &
  581. regime, &
  582. znt
  583. REAL, INTENT(IN) :: guv_sfc, gt_sfc, gq_sfc, rinblw
  584. INTEGER :: i, j, k, itsu, jtsv, itf, jtf, ktf, i0, j0
  585. REAL :: xtime_old_sfc, xtime_new_sfc, coef, val_analysis, es
  586. INTEGER :: kpbl, dbg_level
  587. REAL :: zpbl, zagl, zagl_bot, zagl_top, tfac, actual_end_fdda_min
  588. REAL, DIMENSION( its:ite, kts:kte, jts:jte, 4 ), &
  589. INTENT(IN) :: wpbl ! 1: u, 2: v, 3: t, 4: q
  590. REAL, DIMENSION( kts:kte, 4 ), &
  591. INTENT(IN) :: wzfac ! 1: u, 2: v, 3: t, 4: q
  592. REAL, DIMENSION( its:ite, jts:jte) :: wndcor_u, wndcor_v
  593. REAL, DIMENSION( its-2:ite+2, jts-2:jte+2) :: blw_old, blw_new
  594. REAL, DIMENSION( its:ite, kts:kte, jts:jte) :: qsat
  595. REAL :: m, b=1.8, blw, rindx, x
  596. REAL :: difz, wr14, wr1z, wr24, wr2z, wndfac, reg, znt0
  597. INTEGER, INTENT(IN) :: if_ramping
  598. REAL, INTENT(IN) :: dtramp_min
  599. LOGICAL , EXTERNAL :: wrf_dm_on_monitor
  600. CHARACTER (LEN=256) :: message
  601. INTEGER :: iwinds, idd, iqsat, int4
  602. iwinds = 1 ! 1: Scale the surface wind analysis to the lowest model level,
  603. ! if the first model half-layer is greater than 10 meters
  604. ! and we are in the free convection regime (REGIME=4.0). else: no
  605. idd = 1 ! 1: Obs data density correction is applied. else: no
  606. iqsat = 1 ! 1: Remove super saturation. eles: no
  607. int4 = 1 ! 1: temporal ionterpolation. else: target nudging toward *_ndg_new values
  608. IF( analysis_interval_sfc <= 0 )CALL wrf_error_fatal('In grid sfc FDDA, sgfdda_interval_m must be > 0')
  609. xtime_old_sfc = FLOOR(xtime/analysis_interval_sfc) * analysis_interval_sfc * 1.0
  610. xtime_new_sfc = xtime_old_sfc + analysis_interval_sfc
  611. IF( int4 == 1 ) THEN
  612. coef = (xtime-xtime_old_sfc)/(xtime_new_sfc-xtime_old_sfc) ! Temporal interpolation
  613. ELSE
  614. coef = 1.0 ! Nudging toward a target value (*_ndg_new values)
  615. ENDIF
  616. IF ( wrf_dm_on_monitor()) THEN
  617. CALL get_wrf_debug_level( dbg_level )
  618. IF( xtime-xtime_old_sfc < 0.5*dt/60.0 ) THEN
  619. IF( xtime < end_fdda_hour_sfc*60.0 ) THEN
  620. WRITE(message,'(a,i1,a,f10.3,a)') &
  621. 'D0',id,' surface analysis nudging reads new data at time = ', xtime, ' min.'
  622. CALL wrf_message( TRIM(message) )
  623. WRITE(message,'(a,i1,a,2f8.2,a)') &
  624. 'D0',id,' surface analysis nudging bracketing times = ', xtime_old_sfc, xtime_new_sfc, ' min.'
  625. CALL wrf_message( TRIM(message) )
  626. ENDIF
  627. IF( dbg_level .GE. 10 .AND. xtime <= actual_end_fdda_min ) THEN
  628. ! Find the mid point of the tile and print out the sample values
  629. i0 = (ite-its)/2+its
  630. j0 = (jte-jts)/2+jts
  631. IF( guv_sfc > 0.0 ) THEN
  632. WRITE(message,'(a,i1,a,2i4,a,f10.4,a,f10.4)') &
  633. ' D0',id,' sample surface analysis values at i,j=', i0, j0, &
  634. ' u10_ndg_old=', u10_ndg_old(i0,j0), ' u10_ndg_new=', u10_ndg_new(i0,j0)
  635. CALL wrf_message( TRIM(message) )
  636. WRITE(message,'(a,i1,a,2i4,a,f10.4,a,f10.4)') &
  637. ' D0',id,' sample surface analysis values at i,j=', i0, j0, &
  638. ' v10_ndg_old=', v10_ndg_old(i0,j0), ' v10_ndg_new=', v10_ndg_new(i0,j0)
  639. CALL wrf_message( TRIM(message) )
  640. ENDIF
  641. IF( gt_sfc > 0.0 ) THEN
  642. WRITE(message,'(a,i1,a,2i4,a,f10.4,a,f10.4)') &
  643. ' D0',id,' sample surface analysis values at i,j=', i0, j0, &
  644. ' th2_ndg_old=', th2_ndg_old(i0,j0), ' th2_ndg_new=', th2_ndg_new(i0,j0)
  645. CALL wrf_message( TRIM(message) )
  646. ENDIF
  647. IF( gq_sfc > 0.0 ) THEN
  648. WRITE(message,'(a,i1,a,2i4,a,f10.4,a,f10.4)') &
  649. ' D0',id,' sample surface analysis values at i,j=', i0, j0, &
  650. ' q2_ndg_old=', q2_ndg_old(i0,j0), ' q2_ndg_new=', q2_ndg_new(i0,j0)
  651. CALL wrf_message( TRIM(message) )
  652. ENDIF
  653. IF( iwinds == 1 ) &
  654. WRITE(message,'(a,i1,a)') ' D0',id, &
  655. ' surface wind analysis s scaled to the lowest model level, if dz1 > 10m and REGIME=4.'
  656. IF( idd == 1 ) &
  657. WRITE(message,'(a,i1,a)') ' D0',id, &
  658. ' obs data density is used for additional weighting function'
  659. IF( iqsat == 1 ) &
  660. WRITE(message,'(a,i1,a)') ' D0',id, &
  661. ' super saturation is not allowed for q analysis'
  662. IF( int4 == 1 ) then
  663. WRITE(message,'(a,i1,a)') ' D0',id, &
  664. ' surface nudging towards the temporally interpolated analysis'
  665. ELSE
  666. WRITE(message,'(a,i1,a)') ' D0',id, &
  667. ' surface nudging towards the target analysis'
  668. ENDIF
  669. ENDIF
  670. ENDIF
  671. ENDIF
  672. jtsv=MAX0(jts,jds+1)
  673. itsu=MAX0(its,ids+1)
  674. jtf=MIN0(jte,jde-1)
  675. ktf=MIN0(kte,kde-1)
  676. itf=MIN0(ite,ide-1)
  677. !
  678. ! Compute the vertical weighting function to scale the surface wind analysis to
  679. ! the lowest model level, if the first model half-layer is greater
  680. ! than 10 meters and we are in the free convection regime (REGIME=4.0).
  681. !
  682. IF( iwinds == 1 ) THEN
  683. wndcor_u(:,:) = 1.0
  684. DO j=jts,jtf
  685. DO i=itsu,itf
  686. reg = 0.5 * ( regime(i-1, j) + regime(i, j) )
  687. difz = 0.5 * ( z(i-1,1,j) - ht(i-1,j) &
  688. + z(i, 1,j) - ht(i, j) )
  689. IF( reg > 3.5 .AND. difz > 10.0 ) THEN
  690. znt0 = 0.5 * ( znt(i-1, j) + znt(i, j) )
  691. IF( znt0 <= 0.2) THEN
  692. wndcor_u(i,j) = 1.0+0.320*znt0**0.2
  693. ELSE
  694. wndcor_u(i,j) = 1.169+0.315*znt0
  695. ENDIF
  696. wr14 = log(40.0/0.05)
  697. wr1z = log(difz/0.05)
  698. wr24 = log(40.0/1.0)
  699. wr2z = log(difz/1.0)
  700. wndfac = 0.5*(WR1Z/WR14+WR2Z/WR24)
  701. wndcor_u(i,j) = wndfac*wndcor_u(i,j)
  702. ENDIF
  703. ENDDO
  704. ENDDO
  705. IF ( wrf_dm_on_monitor()) THEN
  706. IF( xtime-xtime_old_sfc < 0.5*dt/60.0 ) THEN
  707. IF( dbg_level .GE. 10 .AND. xtime <= actual_end_fdda_min ) THEN
  708. i0 = (ite-its)/2+its
  709. j0 = (jte-jts)/2+jts
  710. WRITE(message,'(a,i1,a,2i4,a,f10.4)') &
  711. ' D0',id,' sample wndcor_u values at i,j=', i0, j0, &
  712. ' wndcor_u=', wndcor_u(i0,j0)
  713. CALL wrf_message( TRIM(message) )
  714. ENDIF
  715. ENDIF
  716. ENDIF
  717. ELSE
  718. wndcor_u(:,:) = 1.0
  719. ENDIF
  720. IF( iwinds == 1 ) THEN
  721. wndcor_v(:,:) = 1.0
  722. DO j=jtsv,jtf
  723. DO i=its,itf
  724. reg = 0.5 * ( regime(i, j-1) + regime(i, j) )
  725. difz = 0.5 * ( z(i,1,j-1) - ht(i,j-1) &
  726. + z(i,1,j ) - ht(i,j ) )
  727. IF( reg > 3.5 .AND. difz > 10.0 ) THEN
  728. znt0 = 0.5 * ( znt(i, j-1) + znt(i, j) )
  729. IF( znt0 <= 0.2) THEN
  730. wndcor_v(i,j) = 1.0+0.320*znt0**0.2
  731. ELSE
  732. wndcor_v(i,j) = 1.169+0.315*znt0
  733. ENDIF
  734. wr14 = log(40.0/0.05)
  735. wr1z = log(difz/0.05)
  736. wr24 = log(40.0/1.0)
  737. wr2z = log(difz/1.0)
  738. wndfac = 0.5*(WR1Z/WR14+WR2Z/WR24)
  739. wndcor_v(i,j) = wndfac*wndcor_v(i,j)
  740. ENDIF
  741. ENDDO
  742. ENDDO
  743. IF ( wrf_dm_on_monitor()) THEN
  744. IF( xtime-xtime_old_sfc < 0.5*dt/60.0 ) THEN
  745. IF( dbg_level .GE. 10 .AND. xtime <= actual_end_fdda_min ) THEN
  746. i0 = (ite-its)/2+its
  747. j0 = (jte-jts)/2+jts
  748. WRITE(message,'(a,i1,a,2i4,a,f10.4)') &
  749. ' D0',id,' sample wndcor_v values at i,j=', i0, j0, &
  750. ' wndcor_v=', wndcor_v(i0,j0)
  751. CALL wrf_message( TRIM(message) )
  752. ENDIF
  753. ENDIF
  754. ENDIF
  755. ELSE
  756. wndcor_v(:,:) = 1.0
  757. ENDIF
  758. !
  759. ! Compute saturation mixing ratio so that nudging to a super-saturated state
  760. ! is not allowed.
  761. !
  762. IF( iqsat == 1 ) THEN
  763. DO j=jts,jtf
  764. DO k=kts,ktf
  765. DO i=its,itf
  766. es = SVP1*EXP(SVP2*(t3d(i,k,j)-SVPT0)/(t3d(i,k,j)-SVP3)) * 10.0 ! mb
  767. qsat(i,k,j) = EP_2*es/(p3d(i,k,j)/100.0-es)
  768. ENDDO
  769. ENDDO
  770. ENDDO
  771. IF ( wrf_dm_on_monitor()) THEN
  772. IF( xtime-xtime_old_sfc < 0.5*dt/60.0 ) THEN
  773. IF( dbg_level .GE. 10 .AND. xtime <= actual_end_fdda_min ) THEN
  774. i0 = (ite-its)/2+its
  775. j0 = (jte-jts)/2+jts
  776. DO k = kts, kte
  777. WRITE(message,'(a,i1,a,3i4,a,f10.4,a,f10.4)') &
  778. ' D0',id,' sample moisture values (g/kg) at i,k,j=', i0, k, j0, &
  779. ' qv3d=', qv3d(i0,k,j0)*1000.0, ' qsat=', qsat(i0,k,j0)*1000.0
  780. CALL wrf_message( TRIM(message) )
  781. ENDDO
  782. ENDIF
  783. ENDIF
  784. ENDIF
  785. ENDIF
  786. !
  787. ! Obs data density weighting.
  788. !
  789. IF( idd == 1 ) THEN
  790. IF( rinblw < 0.001 ) THEN
  791. IF ( wrf_dm_on_monitor()) THEN
  792. WRITE(message,'(a)') 'Error in rinblw, please specify a reasonable value ***'
  793. CALL wrf_message( TRIM(message) )
  794. ENDIF
  795. CALL wrf_error_fatal('In grid FDDA')
  796. ENDIF
  797. rindx = rinblw*1000.0/dx
  798. m = -0.8*2.0/rindx
  799. DO j=MAX(jts-2,jds),MIN(jte+2,jde-1)
  800. DO i=MAX(its-2,ids),MIN(ite+2,ide-1)
  801. IF( odis_ndg_old(i,j) < 0.5*rinblw ) THEN
  802. blw_old(i,j) = 1.0
  803. ELSE
  804. x = min( odis_ndg_old(i,j)*1000./dx, rindx )
  805. blw_old(i,j) = m * x + b
  806. ENDIF
  807. IF( odis_ndg_new(i,j) < 0.5*rinblw ) THEN
  808. blw_new(i,j) = 1.0
  809. ELSE
  810. x = min( odis_ndg_new(i,j)*1000./dx, rindx )
  811. blw_new(i,j) = m * x + b
  812. ENDIF
  813. ENDDO
  814. ENDDO
  815. ! Smoother applies one point outside the tile, but one point in from boundaries
  816. CALL smther(blw_old, its-2,ite+2, jts-2,jte+2, 1, &
  817. MAX(its-1,ids+1), MIN(ite+1,ide-2), MAX(jts-1,jds+1), MIN(jte+1,jde-2))
  818. CALL smther(blw_new, its-2,ite+2, jts-2,jte+2, 1, &
  819. MAX(its-1,ids+1), MIN(ite+1,ide-2), MAX(jts-1,jds+1), MIN(jte+1,jde-2))
  820. WHERE ( blw_old > 1.0)
  821. blw_old = 1.0
  822. END WHERE
  823. WHERE ( blw_new > 1.0)
  824. blw_new = 1.0
  825. END WHERE
  826. WHERE ( blw_old < 0.0)
  827. blw_old = 0.0
  828. END WHERE
  829. WHERE ( blw_new < 0.0)
  830. blw_new = 0.0
  831. END WHERE
  832. IF ( wrf_dm_on_monitor()) THEN
  833. IF( xtime-xtime_old_sfc < 0.5*dt/60.0 ) THEN
  834. IF( dbg_level .GE. 10 .AND. xtime <= actual_end_fdda_min ) THEN
  835. i0 = (ite-its)/2+its
  836. j0 = (jte-jts)/2+jts
  837. WRITE(message,'(a,i1,a,2i4,4(a,f10.4))') &
  838. ' D0',id,' sample blw values at i,j=', i0, j0, &
  839. ' odis_ndg_old=', odis_ndg_old(i0,j0), ' km odis_ndg_new=', odis_ndg_new(i0,j0), &
  840. ' km blw_old=', blw_old(i0,j0), ' blw_new=', blw_new(i0,j0)
  841. CALL wrf_message( TRIM(message) )
  842. ENDIF
  843. ENDIF
  844. ENDIF
  845. ENDIF
  846. !
  847. ! TFAC for surface analysis nudging
  848. !
  849. IF( xtime >= actual_end_fdda_min-ABS(dtramp_min) .AND. xtime <= actual_end_fdda_min &
  850. .AND. dtramp_min > 0.0 .AND. if_ramping == 1 ) &
  851. coef = (xtime-xtime_old_sfc+analysis_interval_sfc)/(analysis_interval_sfc*1.0)
  852. ! print*, 'coef =', xtime_old_sfc, xtime, xtime_new_sfc, coef
  853. !
  854. ! Compute surface analysis nudging tendencies for u, v, t and q
  855. !
  856. DO j=jts,jtf
  857. DO k=kts,ktf
  858. DO i=itsu,itf
  859. IF( idd == 1 ) THEN
  860. blw = 0.5* (blw_old(i-1,j)+blw_old(i,j)) * ( 1.0 - coef ) &
  861. + 0.5* (blw_new(i-1,j)+blw_new(i,j)) * coef
  862. ELSE
  863. blw = 1.0
  864. ENDIF
  865. val_analysis = u10_ndg_old(i,j) *( 1.0 - coef ) + u10_ndg_new(i,j) * coef
  866. val_analysis = val_analysis * wndcor_u(i,j)
  867. RUNDGDTEN(i,k,j) = guv_sfc * (1.0-wpbl(i,k,j,1)) * wzfac(k,1) * tfac * blw * &
  868. ( val_analysis - u3d(i,1,j) )
  869. ENDDO
  870. ENDDO
  871. ENDDO
  872. DO j=jtsv,jtf
  873. DO k=kts,ktf
  874. DO i=its,itf
  875. IF( idd == 1 ) THEN
  876. blw = 0.5* (blw_old(i,j-1)+blw_old(i,j)) * ( 1.0 - coef ) &
  877. + 0.5* (blw_new(i,j-1)+blw_new(i,j)) * coef
  878. ELSE
  879. blw = 1.0
  880. ENDIF
  881. val_analysis = v10_ndg_old(i,j) *( 1.0 - coef ) + v10_ndg_new(i,j) * coef
  882. val_analysis = val_analysis * wndcor_v(i,j)
  883. RVNDGDTEN(i,k,j) = guv_sfc * (1.0-wpbl(i,k,j,2)) * wzfac(k,2) * tfac * blw * &
  884. ( val_analysis - v3d(i,1,j) )
  885. ENDDO
  886. ENDDO
  887. ENDDO
  888. DO j=jts,jtf
  889. DO k=kts,ktf
  890. DO i=its,itf
  891. IF( idd == 1 ) THEN
  892. blw = blw_old(i,j) * ( 1.0 - coef ) + blw_new(i,j) * coef
  893. ELSE
  894. blw = 1.0
  895. ENDIF
  896. val_analysis = th2_ndg_old(i,j) *( 1.0 - coef ) + th2_ndg_new(i,j) * coef
  897. RTHNDGDTEN(i,k,j) = gt_sfc * (1.0-wpbl(i,k,j,3)) * wzfac(k,3) * tfac * blw * &
  898. ( val_analysis - th3d(i,1,j))
  899. val_analysis = q2_ndg_old(i,j) *( 1.0 - coef ) + q2_ndg_new(i,j) * coef
  900. IF( iqsat == 1 .AND. val_analysis > qsat(i,k,j) ) val_analysis = qsat(i,k,j)
  901. RQVNDGDTEN(i,k,j) = gq_sfc * (1.0-wpbl(i,k,j,4)) * wzfac(k,4) * tfac * blw * &
  902. ( val_analysis - qv3d(i,k,j) )
  903. ENDDO
  904. ENDDO
  905. ENDDO
  906. END SUBROUTINE sfddagd
  907. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  908. SUBROUTINE fddagdinit(id,rundgdten,rvndgdten,rthndgdten,rqvndgdten,rmundgdten,&
  909. run_hours, &
  910. if_no_pbl_nudging_uv, if_no_pbl_nudging_t, if_no_pbl_nudging_q, &
  911. if_zfac_uv, k_zfac_uv, if_zfac_t, k_zfac_t, if_zfac_q, k_zfac_q, &
  912. guv, gt, gq, if_ramping, dtramp_min, end_fdda_hour, &
  913. grid_sfdda, guv_sfc, gt_sfc, gq_sfc, &
  914. restart, allowed_to_read, &
  915. ids, ide, jds, jde, kds, kde, &
  916. ims, ime, jms, jme, kms, kme, &
  917. its, ite, jts, jte, kts, kte )
  918. !-------------------------------------------------------------------
  919. IMPLICIT NONE
  920. !-------------------------------------------------------------------
  921. !
  922. INTEGER , INTENT(IN) :: id
  923. LOGICAL, INTENT(IN) :: restart, allowed_to_read
  924. INTEGER, INTENT(IN) :: ids, ide, jds, jde, kds, kde, &
  925. ims, ime, jms, jme, kms, kme, &
  926. its, ite, jts, jte, kts, kte
  927. REAL, DIMENSION( ims:ime , kms:kme , jms:jme ), INTENT(OUT) :: &
  928. rundgdten, &
  929. rvndgdten, &
  930. rthndgdten, &
  931. rqvndgdten
  932. INTEGER, INTENT(IN) :: run_hours
  933. INTEGER, INTENT(IN) :: if_no_pbl_nudging_uv, if_no_pbl_nudging_t, &
  934. if_no_pbl_nudging_q, end_fdda_hour
  935. INTEGER, INTENT(IN) :: if_zfac_uv, if_zfac_t, if_zfac_q
  936. INTEGER, INTENT(IN) :: k_zfac_uv, k_zfac_t, k_zfac_q
  937. INTEGER, INTENT(IN) :: if_ramping, grid_sfdda
  938. REAL, INTENT(IN) :: dtramp_min
  939. REAL, INTENT(IN) :: guv, gt, gq
  940. REAL, INTENT(IN) :: guv_sfc, gt_sfc, gq_sfc
  941. REAL :: actual_end_fdda_min
  942. REAL, DIMENSION( ims:ime , jms:jme ), INTENT(OUT) :: rmundgdten
  943. INTEGER :: i, j, k
  944. LOGICAL , EXTERNAL :: wrf_dm_on_monitor
  945. CHARACTER (LEN=256) :: message
  946. IF ( wrf_dm_on_monitor() ) THEN
  947. IF( guv > 0.0 ) THEN
  948. WRITE(message,'(a,i1,a,e12.4)') &
  949. 'D0',id,' 3-D analysis nudging for wind is applied and Guv= ', guv
  950. CALL wrf_message(TRIM(message))
  951. ELSE IF( guv < 0.0 ) THEN
  952. CALL wrf_error_fatal('In grid FDDA, Guv must be positive.')
  953. ELSE
  954. WRITE(message,'(a,i1,a,e12.4)') &
  955. 'D0',id,' 3-D analysis nudging for wind is not applied and Guv= ', guv
  956. CALL wrf_message(TRIM(message))
  957. ENDIF
  958. IF( gt > 0.0 ) THEN
  959. WRITE(message,'(a,i1,a,e12.4)') &
  960. 'D0',id,' 3-D analysis nudging for temperature is applied and Gt= ', gt
  961. CALL wrf_message(TRIM(message))
  962. ELSE IF( gt < 0.0 ) THEN
  963. CALL wrf_error_fatal('In grid FDDA, Gt must be positive.')
  964. ELSE
  965. WRITE(message,'(a,i1,a,e12.4)') &
  966. 'D0',id,' 3-D analysis nudging for temperature is not applied and Gt= ', gt
  967. CALL wrf_message(TRIM(message))
  968. ENDIF
  969. IF( gq > 0.0 ) THEN
  970. WRITE(message,'(a,i1,a,e12.4)') &
  971. 'D0',id,' 3-D analysis nudging for water vapor mixing ratio is applied and Gq= ', gq
  972. CALL wrf_message(TRIM(message))
  973. ELSE IF( gq < 0.0 ) THEN
  974. CALL wrf_error_fatal('In grid FDDA, Gq must be positive.')
  975. ELSE
  976. WRITE(message,'(a,i1,a,e12.4)') &
  977. 'D0',id,' 3-D analysis nudging for water vapor mixing ratio is not applied and Gq= ', gq
  978. CALL wrf_message(TRIM(message))
  979. ENDIF
  980. IF( guv > 0.0 .AND. if_no_pbl_nudging_uv == 1 ) THEN
  981. WRITE(message,'(a,i1,a)') &
  982. 'D0',id,' 3-D analysis nudging for wind is turned off within the PBL.'
  983. CALL wrf_message(TRIM(message))
  984. ENDIF
  985. IF( gt > 0.0 .AND. if_no_pbl_nudging_t == 1 ) THEN
  986. WRITE(message,'(a,i1,a)') &
  987. 'D0',id,' 3-D analysis nudging for temperature is turned off within the PBL.'
  988. CALL wrf_message(TRIM(message))
  989. ENDIF
  990. IF( gq > 0.0 .AND. if_no_pbl_nudging_q == 1 ) THEN
  991. WRITE(message,'(a,i1,a)') &
  992. 'D0',id,' 3-D analysis nudging for water vapor mixing ratio is turned off within the PBL.'
  993. CALL wrf_message(TRIM(message))
  994. ENDIF
  995. IF( guv > 0.0 .AND. if_zfac_uv == 1 ) THEN
  996. WRITE(message,'(a,i1,a,i3)') &
  997. 'D0',id,' 3-D analysis nudging for wind is turned off below layer', k_zfac_uv
  998. CALL wrf_message(TRIM(message))
  999. ENDIF
  1000. IF( gt > 0.0 .AND. if_zfac_t == 1 ) THEN
  1001. WRITE(message,'(a,i1,a,i3)') &
  1002. 'D0',id,' 3-D analysis nudging for temperature is turned off below layer', k_zfac_t
  1003. CALL wrf_message(TRIM(message))
  1004. ENDIF
  1005. IF( gq > 0.0 .AND. if_zfac_q == 1 ) THEN
  1006. WRITE(message,'(a,i1,a,i3)') &
  1007. 'D0',id,' 3-D analysis nudging for water vapor mixing ratio is turned off below layer', &
  1008. k_zfac_q
  1009. CALL wrf_message(TRIM(message))
  1010. ENDIF
  1011. IF( grid_sfdda ==1 ) THEN
  1012. IF( guv_sfc > 0.0 ) THEN
  1013. WRITE(message,'(a,i1,a,e12.4)') &
  1014. 'D0',id,' surface analysis nudging for wind is applied and Guv_sfc= ', guv_sfc
  1015. CALL wrf_message(TRIM(message))
  1016. ELSE IF( guv_sfc < 0.0 ) THEN
  1017. CALL wrf_error_fatal('In grid FDDA, Guv_sfc must be positive.')
  1018. ELSE
  1019. WRITE(message,'(a,i1,a,e12.4)') &
  1020. 'D0',id,' surface analysis nudging for wind is not applied and Guv_sfc= ', guv_sfc
  1021. CALL wrf_message(TRIM(message))
  1022. ENDIF
  1023. IF( gt_sfc > 0.0 ) THEN
  1024. WRITE(message,'(a,i1,a,e12.4)') &
  1025. 'D0',id,' surface analysis nudging for temperature is applied and Gt_sfc= ', gt_sfc
  1026. CALL wrf_message(TRIM(message))
  1027. ELSE IF( gt_sfc < 0.0 ) THEN
  1028. CALL wrf_error_fatal('In grid FDDA, Gt_sfc must be positive.')
  1029. ELSE
  1030. WRITE(message,'(a,i1,a,e12.4)') &
  1031. 'D0',id,' surafce analysis nudging for temperature is not applied and Gt_sfc= ', gt_sfc
  1032. CALL wrf_message(TRIM(message))
  1033. ENDIF
  1034. IF( gq_sfc > 0.0 ) THEN
  1035. WRITE(message,'(a,i1,a,e12.4)') &
  1036. 'D0',id,' surface analysis nudging for water vapor mixing ratio is applied and Gq_sfc= ', gq_sfc
  1037. CALL wrf_message(TRIM(message))
  1038. ELSE IF( gq_sfc < 0.0 ) THEN
  1039. CALL wrf_error_fatal('In grid FDDA, Gq_sfc must be positive.')
  1040. ELSE
  1041. WRITE(message,'(a,i1,a,e12.4)') &
  1042. 'D0',id,' surface analysis nudging for water vapor mixing ratio is not applied and Gq_sfc= ', gq_sfc
  1043. CALL wrf_message(TRIM(message))
  1044. ENDIF
  1045. ENDIF
  1046. IF( if_ramping == 1 .AND. ABS(dtramp_min) > 0.0 ) THEN
  1047. IF( dtramp_min <= 0.0 ) THEN
  1048. actual_end_fdda_min = end_fdda_hour*60.0
  1049. ELSE
  1050. actual_end_fdda_min = end_fdda_hour*60.0 + ABS(dtramp_min)
  1051. ENDIF
  1052. IF( actual_end_fdda_min <= run_hours*60. ) THEN
  1053. WRITE(message,'(a,i1,a)') &
  1054. 'D0',id,' analysis nudging is ramped down near the end of the nudging period,'
  1055. CALL wrf_message(TRIM(message))
  1056. WRITE(message,'(a,f6.2,a,f6.2,a)') &
  1057. ' starting at ', (actual_end_fdda_min - ABS(dtramp_min))/60.0, &
  1058. 'h, ending at ', actual_end_fdda_min/60.0,'h.'
  1059. CALL wrf_message(TRIM(message))
  1060. ENDIF
  1061. ENDIF
  1062. ENDIF
  1063. IF(.not.restart) THEN
  1064. DO j = jts,jte
  1065. DO k = kts,kte
  1066. DO i = its,ite
  1067. rundgdten(i,k,j) = 0.
  1068. rvndgdten(i,k,j) = 0.
  1069. rthndgdten(i,k,j) = 0.
  1070. rqvndgdten(i,k,j) = 0.
  1071. if(k.eq.kts) rmundgdten(i,j) = 0.
  1072. ENDDO
  1073. ENDDO
  1074. ENDDO
  1075. ENDIF
  1076. END SUBROUTINE fddagdinit
  1077. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  1078. SUBROUTINE smther(slab, idimst, idimnd, jdimst, jdimnd, npass, ist, ind, jst, jnd)
  1079. !
  1080. ! PURPOSE: SPATIALLY SMOOTH DATA IN SLAB TO DAMPEN SHORT
  1081. ! WAVELENGTH COMPONENTS.
  1082. !
  1083. ! Implemented based on the same smoothing subroutine used in MM5, with modifications to
  1084. ! remove the extra loop that causes unneccessary desmoothing. Aijun Deng (Penn State),
  1085. ! December 2008
  1086. !
  1087. IMPLICIT NONE
  1088. INTEGER :: idimst, idimnd, jdimst, jdimnd, npass, ist, ind, jst, jnd
  1089. INTEGER :: i, j, k, kk
  1090. REAL :: avg
  1091. REAL, DIMENSION(idimst:idimnd, jdimst:jdimnd) :: SLAB
  1092. REAL, DIMENSION(idimst:idimnd, jdimst:jdimnd) :: SLAB_ORIG
  1093. REAL, DIMENSION(2) :: XNU
  1094. IF(NPASS.EQ.0)RETURN
  1095. XNU(1)=0.50
  1096. XNU(2)=-0.52
  1097. DO K=1,NPASS
  1098. KK = 2 - MOD(K,2)
  1099. DO J=JDIMST,JDIMND
  1100. DO I=IDIMST,IDIMND
  1101. SLAB_ORIG(I,J) = SLAB(I,J)
  1102. END DO
  1103. END DO
  1104. DO J=JST,JND
  1105. DO I=IST,IND
  1106. AVG = ( SLAB_ORIG(I+1,J ) + &
  1107. SLAB_ORIG(I-1,J ) + &
  1108. SLAB_ORIG(I ,J+1) + &
  1109. SLAB_ORIG(I ,J-1) ) * 0.25
  1110. SLAB(I,J)=SLAB_ORIG(I,J)+XNU(KK)*(AVG - SLAB_ORIG(I,J))
  1111. ENDDO
  1112. ENDDO
  1113. ENDDO
  1114. END SUBROUTINE smther
  1115. !-------------------------------------------------------------------
  1116. END MODULE module_fdda_psufddagd