PageRenderTime 53ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 1ms

/wrfv2_fire/dyn_em/module_initialize_real.F

https://github.com/jbeezley/wrf-fire
FORTRAN Legacy | 6042 lines | 3975 code | 1083 blank | 984 comment | 36 complexity | 0c1a13b5e2da8ab3fb4da9ef56917932 MD5 | raw file
Possible License(s): AGPL-1.0
  1. !REAL:MODEL_LAYER:INITIALIZATION
  2. #ifndef VERT_UNIT
  3. ! This MODULE holds the routines which are used to perform various initializations
  4. ! for the individual domains, specifically for the Eulerian, mass-based coordinate.
  5. !-----------------------------------------------------------------------
  6. MODULE module_initialize_real
  7. USE module_bc
  8. USE module_configure
  9. USE module_domain
  10. USE module_io_domain
  11. USE module_model_constants
  12. USE module_state_description
  13. USE module_timing
  14. USE module_soil_pre
  15. USE module_date_time
  16. USE module_llxy
  17. #ifdef DM_PARALLEL
  18. USE module_dm
  19. USE module_comm_dm, ONLY : &
  20. HALO_EM_INIT_1_sub &
  21. ,HALO_EM_INIT_2_sub &
  22. ,HALO_EM_INIT_3_sub &
  23. ,HALO_EM_INIT_4_sub &
  24. ,HALO_EM_INIT_5_sub &
  25. ,HALO_EM_VINTERP_UV_1_sub
  26. #endif
  27. REAL , SAVE :: p_top_save
  28. INTEGER :: internal_time_loop
  29. CONTAINS
  30. !-------------------------------------------------------------------
  31. SUBROUTINE init_domain ( grid )
  32. IMPLICIT NONE
  33. ! Input space and data. No gridded meteorological data has been stored, though.
  34. ! TYPE (domain), POINTER :: grid
  35. TYPE (domain) :: grid
  36. ! Local data.
  37. INTEGER :: idum1, idum2
  38. CALL set_scalar_indices_from_config ( head_grid%id , idum1, idum2 )
  39. CALL init_domain_rk( grid &
  40. !
  41. #include "actual_new_args.inc"
  42. !
  43. )
  44. END SUBROUTINE init_domain
  45. !-------------------------------------------------------------------
  46. SUBROUTINE init_domain_rk ( grid &
  47. !
  48. #include "dummy_new_args.inc"
  49. !
  50. )
  51. USE module_optional_input
  52. IMPLICIT NONE
  53. ! Input space and data. No gridded meteorological data has been stored, though.
  54. ! TYPE (domain), POINTER :: grid
  55. TYPE (domain) :: grid
  56. #include "dummy_new_decl.inc"
  57. TYPE (grid_config_rec_type) :: config_flags
  58. ! Local domain indices and counters.
  59. INTEGER :: num_veg_cat , num_soil_top_cat , num_soil_bot_cat
  60. INTEGER :: loop , num_seaice_changes
  61. INTEGER :: ids, ide, jds, jde, kds, kde, &
  62. ims, ime, jms, jme, kms, kme, &
  63. its, ite, jts, jte, kts, kte, &
  64. ips, ipe, jps, jpe, kps, kpe, &
  65. i, j, k
  66. INTEGER :: imsx, imex, jmsx, jmex, kmsx, kmex, &
  67. ipsx, ipex, jpsx, jpex, kpsx, kpex, &
  68. imsy, imey, jmsy, jmey, kmsy, kmey, &
  69. ipsy, ipey, jpsy, jpey, kpsy, kpey
  70. INTEGER :: ns
  71. ! Local data
  72. INTEGER :: error
  73. INTEGER :: im, num_3d_m, num_3d_s
  74. REAL :: p_surf, p_level
  75. REAL :: cof1, cof2
  76. REAL :: qvf , qvf1 , qvf2 , pd_surf
  77. REAL :: p00 , t00 , a , tiso
  78. REAL :: hold_znw , ptemp
  79. REAL :: vap_pres_mb , sat_vap_pres_mb
  80. LOGICAL :: were_bad
  81. LOGICAL :: stretch_grid, dry_sounding, debug
  82. INTEGER IICOUNT
  83. REAL :: p_top_requested , temp
  84. INTEGER :: num_metgrid_levels
  85. REAL , DIMENSION(max_eta) :: eta_levels
  86. REAL :: max_dz
  87. ! INTEGER , PARAMETER :: nl_max = 1000
  88. ! REAL , DIMENSION(nl_max) :: grid%dn
  89. integer::oops1,oops2
  90. REAL :: zap_close_levels
  91. INTEGER :: force_sfc_in_vinterp
  92. INTEGER :: interp_type , lagrange_order , extrap_type , t_extrap_type
  93. LOGICAL :: lowest_lev_from_sfc , use_levels_below_ground , use_surface
  94. LOGICAL :: we_have_tavgsfc , we_have_tsk
  95. INTEGER :: lev500 , loop_count
  96. REAL :: zl , zu , pl , pu , z500 , dz500 , tvsfc , dpmu
  97. REAL :: pfu, pfd, phm
  98. LOGICAL , PARAMETER :: want_full_levels = .TRUE.
  99. LOGICAL , PARAMETER :: want_half_levels = .FALSE.
  100. CHARACTER (LEN=80) :: a_message
  101. REAL :: max_mf
  102. ! Excluded middle.
  103. LOGICAL :: any_valid_points
  104. INTEGER :: i_valid , j_valid
  105. !-- Carsel and Parrish [1988]
  106. REAL , DIMENSION(100) :: lqmi
  107. REAL :: t_start , t_end
  108. ! Dimension information stored in grid data structure.
  109. CALL cpu_time(t_start)
  110. CALL get_ijk_from_grid ( grid , &
  111. ids, ide, jds, jde, kds, kde, &
  112. ims, ime, jms, jme, kms, kme, &
  113. ips, ipe, jps, jpe, kps, kpe, &
  114. imsx, imex, jmsx, jmex, kmsx, kmex, &
  115. ipsx, ipex, jpsx, jpex, kpsx, kpex, &
  116. imsy, imey, jmsy, jmey, kmsy, kmey, &
  117. ipsy, ipey, jpsy, jpey, kpsy, kpey )
  118. its = ips ; ite = ipe ; jts = jps ; jte = jpe ; kts = kps ; kte = kpe
  119. CALL model_to_grid_config_rec ( grid%id , model_config_rec , config_flags )
  120. ! Send out a quick message about the time steps based on the map scale factors.
  121. IF ( ( internal_time_loop .EQ. 1 ) .AND. ( grid%id .EQ. 1 ) .AND. &
  122. ( .NOT. config_flags%map_proj .EQ. PROJ_CASSINI ) ) THEN
  123. max_mf = grid%msft(its,jts)
  124. DO j=jts,MIN(jde-1,jte)
  125. DO i=its,MIN(ide-1,ite)
  126. max_mf = MAX ( max_mf , grid%msft(i,j) )
  127. END DO
  128. END DO
  129. #if ( defined(DM_PARALLEL) && ! defined(STUBMPI) )
  130. max_mf = wrf_dm_max_real ( max_mf )
  131. #endif
  132. WRITE ( a_message , FMT='(A,F5.2,A)' ) 'Max map factor in domain 1 = ',max_mf, &
  133. '. Scale the dt in the model accordingly.'
  134. CALL wrf_message ( a_message )
  135. END IF
  136. ! Check to see if the boundary conditions are set properly in the namelist file.
  137. ! This checks for sufficiency and redundancy.
  138. CALL boundary_condition_check( config_flags, bdyzone, error, grid%id )
  139. ! Some sort of "this is the first time" initialization. Who knows.
  140. grid%step_number = 0
  141. grid%itimestep=0
  142. ! Pull in the info in the namelist to compare it to the input data.
  143. grid%real_data_init_type = model_config_rec%real_data_init_type
  144. ! To define the base state, we call a USER MODIFIED routine to set the three
  145. ! necessary constants: p00 (sea level pressure, Pa), t00 (sea level temperature, K),
  146. ! and A (temperature difference, from 1000 mb to 300 mb, K).
  147. CALL const_module_initialize ( p00 , t00 , a , tiso )
  148. ! Save these constants to write out in model output file
  149. grid%t00 = t00
  150. grid%p00 = p00
  151. grid%tlp = a
  152. grid%tiso = tiso
  153. ! Are there any hold-ups to us bypassing the middle of the domain? These
  154. ! holdups would be situations where we need data in the middle of the domain.
  155. ! FOr example, if this si the first time period, we need the full domain
  156. ! processed for ICs. Also, if there is some sort of gridded FDDA turned on, or
  157. ! if the SST update is activated, then we can't just blow off the middle of the
  158. ! domain all willy-nilly. Other cases of these hold-ups? Sure - what if the
  159. ! user wants to smooth the CG topo, we need several rows and columns available.
  160. ! What if the lat/lon proj is used, then we need to run a spectral filter on
  161. ! the topo. Both are killers when trying to ignore data in the middle of the
  162. ! domain.
  163. ! If hold_ups = .F., then there are no hold-ups to excluding the middle
  164. ! domain processing. If hold_ups = .T., then there are hold-ups, and we
  165. ! must process the middle of the domain.
  166. hold_ups = ( internal_time_loop .EQ. 1 ) .OR. &
  167. ( config_flags%grid_fdda .NE. 0 ) .OR. &
  168. ( config_flags%sst_update .EQ. 1 ) .OR. &
  169. ( config_flags%all_ic_times ) .OR. &
  170. ( config_flags%smooth_cg_topo ) .OR. &
  171. ( config_flags%map_proj .EQ. PROJ_CASSINI )
  172. ! There are a few checks that we need to do when the input data comes in with the middle
  173. ! excluded by WPS.
  174. IF ( flag_excluded_middle .NE. 0 ) THEN
  175. ! If this time period of data from WPS has the middle excluded, it had better be OK for
  176. ! us to have a hole.
  177. IF ( hold_ups ) THEN
  178. WRITE ( a_message,* ) 'None of the following are allowed to be TRUE : '
  179. CALL wrf_message ( a_message )
  180. WRITE ( a_message,* ) ' ( internal_time_loop .EQ. 1 ) ', ( internal_time_loop .EQ. 1 )
  181. CALL wrf_message ( a_message )
  182. WRITE ( a_message,* ) ' ( config_flags%grid_fdda .NE. 0 ) ', ( config_flags%grid_fdda .NE. 0 )
  183. CALL wrf_message ( a_message )
  184. WRITE ( a_message,* ) ' ( config_flags%sst_update .EQ. 1 ) ', ( config_flags%sst_update .EQ. 1 )
  185. CALL wrf_message ( a_message )
  186. WRITE ( a_message,* ) ' ( config_flags%all_ic_times ) ', ( config_flags%all_ic_times )
  187. CALL wrf_message ( a_message )
  188. WRITE ( a_message,* ) ' ( config_flags%smooth_cg_topo ) ', ( config_flags%smooth_cg_topo )
  189. CALL wrf_message ( a_message )
  190. WRITE ( a_message,* ) ' ( config_flags%map_proj .EQ. PROJ_CASSINI ) ', ( config_flags%map_proj .EQ. PROJ_CASSINI )
  191. CALL wrf_message ( a_message )
  192. WRITE ( a_message,* ) 'Problems, we cannot have excluded middle data from WPS'
  193. CALL wrf_error_fatal ( a_message )
  194. END IF
  195. ! Make sure that the excluded middle data from metgrid is "wide enough". We only have to check
  196. ! when the excluded middle was actually used in WPS.
  197. IF ( config_flags%spec_bdy_width .GT. flag_excluded_middle ) THEN
  198. WRITE ( a_message,* ) 'The WRF &bdy_control namelist.input spec_bdy_width = ', config_flags%spec_bdy_width
  199. CALL wrf_message ( a_message )
  200. WRITE ( a_message,* ) 'The WPS &metgrid namelist.wps process_only_bdy width = ',flag_excluded_middle
  201. CALL wrf_message ( a_message )
  202. WRITE ( a_message,* ) 'WPS process_only_bdy must be >= WRF spec_bdy_width'
  203. CALL wrf_error_fatal ( a_message )
  204. END IF
  205. END IF
  206. em_width = config_flags%spec_bdy_width
  207. ! We need to find if there are any valid non-excluded-middle points in this
  208. ! tile. If so, then we need to hang on to a valid i,j location.
  209. any_valid_points = .false.
  210. find_valid : DO j = jts,jte
  211. DO i = its,ite
  212. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  213. any_valid_points = .true.
  214. i_valid = i
  215. j_valid = j
  216. EXIT find_valid
  217. END DO
  218. END DO find_valid
  219. ! Replace traditional seaice field with optional seaice (AFWA source)
  220. IF ( flag_icefrac .EQ. 1 ) THEN
  221. DO j=jts,MIN(jde-1,jte)
  222. DO i=its,MIN(ide-1,ite)
  223. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  224. grid%xice(i,j) = grid%icefrac_gc(i,j)
  225. END DO
  226. END DO
  227. END IF
  228. ! Fix the snow (water equivalent depth, kg/m^2) and the snowh (physical snow
  229. ! depth, m) fields.
  230. IF ( ( flag_snow .EQ. 0 ) .AND. ( flag_snowh .EQ. 0 ) ) THEN
  231. DO j=jts,MIN(jde-1,jte)
  232. DO i=its,MIN(ide-1,ite)
  233. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  234. grid%snow(i,j) = 0.
  235. grid%snowh(i,j) = 0.
  236. END DO
  237. END DO
  238. ELSE IF ( ( flag_snow .EQ. 0 ) .AND. ( flag_snowh .EQ. 1 ) ) THEN
  239. DO j=jts,MIN(jde-1,jte)
  240. DO i=its,MIN(ide-1,ite)
  241. ! ( m -> kg/m^2 ) & ( reduce to liquid, 5:1 ratio )
  242. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  243. grid%snow(i,j) = grid%snowh(i,j) * 1000. / 5.
  244. END DO
  245. END DO
  246. ELSE IF ( ( flag_snow .EQ. 1 ) .AND. ( flag_snowh .EQ. 0 ) ) THEN
  247. DO j=jts,MIN(jde-1,jte)
  248. DO i=its,MIN(ide-1,ite)
  249. ! ( kg/m^2 -> m) & ( liquid to snow depth, 5:1 ratio )
  250. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  251. grid%snowh(i,j) = grid%snow(i,j) / 1000. * 5.
  252. END DO
  253. END DO
  254. END IF
  255. ! For backward compatibility, we might need to assign the map factors from
  256. ! what they were, to what they are.
  257. IF ( ( config_flags%polar ) .AND. ( flag_mf_xy .EQ. 1 ) ) THEN
  258. DO j=max(jds+1,jts),min(jde-1,jte)
  259. DO i=its,min(ide-1,ite)
  260. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  261. grid%msfvx_inv(i,j) = 1./grid%msfvx(i,j)
  262. END DO
  263. END DO
  264. IF(jts == jds) THEN
  265. DO i=its,ite
  266. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  267. grid%msfvx(i,jts) = 0.
  268. grid%msfvx_inv(i,jts) = 0.
  269. END DO
  270. END IF
  271. IF(jte == jde) THEN
  272. DO i=its,ite
  273. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  274. grid%msfvx(i,jte) = 0.
  275. grid%msfvx_inv(i,jte) = 0.
  276. END DO
  277. END IF
  278. ELSE IF ( ( config_flags%map_proj .EQ. PROJ_CASSINI ) .AND. ( flag_mf_xy .EQ. 1 ) ) THEN
  279. DO j=jts,jte
  280. DO i=its,min(ide-1,ite)
  281. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  282. grid%msfvx_inv(i,j) = 1./grid%msfvx(i,j)
  283. END DO
  284. END DO
  285. ELSE IF ( ( .NOT. config_flags%map_proj .EQ. PROJ_CASSINI ) .AND. ( flag_mf_xy .NE. 1 ) ) THEN
  286. DO j=jts,jte
  287. DO i=its,ite
  288. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  289. grid%msfvx(i,j) = grid%msfv(i,j)
  290. grid%msfvy(i,j) = grid%msfv(i,j)
  291. grid%msfux(i,j) = grid%msfu(i,j)
  292. grid%msfuy(i,j) = grid%msfu(i,j)
  293. grid%msftx(i,j) = grid%msft(i,j)
  294. grid%msfty(i,j) = grid%msft(i,j)
  295. ENDDO
  296. ENDDO
  297. DO j=jts,min(jde,jte)
  298. DO i=its,min(ide-1,ite)
  299. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  300. grid%msfvx_inv(i,j) = 1./grid%msfvx(i,j)
  301. END DO
  302. END DO
  303. ELSE IF ( ( .NOT. config_flags%map_proj .EQ. PROJ_CASSINI ) .AND. ( flag_mf_xy .EQ. 1 ) ) THEN
  304. IF ( grid%msfvx(its,jts) .EQ. 0 ) THEN
  305. CALL wrf_error_fatal ( 'Maybe you do not have the new map factors, try re-running geogrid' )
  306. END IF
  307. DO j=jts,min(jde,jte)
  308. DO i=its,min(ide-1,ite)
  309. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  310. grid%msfvx_inv(i,j) = 1./grid%msfvx(i,j)
  311. END DO
  312. END DO
  313. ELSE IF ( ( config_flags%map_proj .EQ. PROJ_CASSINI ) .AND. ( flag_mf_xy .NE. 1 ) ) THEN
  314. CALL wrf_error_fatal ( 'Neither SI data nor older metgrid data can initialize a global domain' )
  315. ENDIF
  316. ! Check to see what available surface temperatures we have.
  317. IF ( flag_tavgsfc .EQ. 1 ) THEN
  318. we_have_tavgsfc = .TRUE.
  319. ELSE
  320. we_have_tavgsfc = .FALSE.
  321. END IF
  322. IF ( flag_tsk .EQ. 1 ) THEN
  323. we_have_tsk = .TRUE.
  324. ELSE
  325. we_have_tsk = .FALSE.
  326. END IF
  327. IF ( config_flags%use_tavg_for_tsk ) THEN
  328. IF ( we_have_tsk .OR. we_have_tavgsfc ) THEN
  329. ! we are OK
  330. ELSE
  331. CALL wrf_error_fatal ( 'We either need TSK or TAVGSFC, verify these fields are coming from WPS' )
  332. END IF
  333. ! Since we require a skin temperature in the model, we can use the average 2-m temperature if provided.
  334. IF ( we_have_tavgsfc ) THEN
  335. DO j=jts,min(jde,jte)
  336. DO i=its,min(ide-1,ite)
  337. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  338. grid%tsk(i,j) = grid%tavgsfc(i,j)
  339. END DO
  340. END DO
  341. END IF
  342. END IF
  343. ! Is there any vertical interpolation to do? The "old" data comes in on the correct
  344. ! vertical locations already.
  345. IF ( flag_metgrid .EQ. 1 ) THEN ! <----- START OF VERTICAL INTERPOLATION PART ---->
  346. ! If this is data from the PINTERP program, it is emulating METGRID output.
  347. ! One of the caveats of this data is the way that the vertical structure is
  348. ! handled. We take the k=1 level and toss it (it is disposable), and we
  349. ! swap in the surface data. This is done for all of the 3d fields about
  350. ! which we show some interest: u, v, t, rh, ght, and p. For u, v, and rh,
  351. ! we assume no interesting vertical structure, and just assign the 1000 mb
  352. ! data. We directly use the 2-m temp for surface temp. We use the surface
  353. ! pressure field and the topography elevation for the lowest level of
  354. ! pressure and height, respectively.
  355. IF ( flag_pinterp .EQ. 1 ) THEN
  356. WRITE ( a_message , * ) 'Data from P_INTERP program, filling k=1 level with artificial surface fields.'
  357. CALL wrf_message ( a_message )
  358. DO j=jts,jte
  359. DO i=its,ite
  360. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  361. grid%u_gc(i,1,j) = grid%u_gc(i,2,j)
  362. grid%v_gc(i,1,j) = grid%v_gc(i,2,j)
  363. grid%rh_gc(i,1,j) = grid%rh_gc(i,2,j)
  364. grid%t_gc(i,1,j) = grid%t2(i,j)
  365. grid%ght_gc(i,1,j) = grid%ht(i,j)
  366. grid%p_gc(i,1,j) = grid%psfc(i,j)
  367. END DO
  368. END DO
  369. flag_psfc = 0
  370. END IF
  371. ! Variables that are named differently between SI and WPS.
  372. DO j = jts, MIN(jte,jde-1)
  373. DO i = its, MIN(ite,ide-1)
  374. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  375. grid%tsk(i,j) = grid%tsk_gc(i,j)
  376. grid%tmn(i,j) = grid%tmn_gc(i,j)
  377. grid%xlat(i,j) = grid%xlat_gc(i,j)
  378. grid%xlong(i,j) = grid%xlong_gc(i,j)
  379. grid%ht(i,j) = grid%ht_gc(i,j)
  380. END DO
  381. END DO
  382. ! A user could request that the most coarse grid has the
  383. ! topography along the outer boundary smoothed. This smoothing
  384. ! is similar to the coarse/nest interface. The outer rows and
  385. ! cols come from the existing large scale topo, and then the
  386. ! next several rows/cols are a linear ramp of the large scale
  387. ! model and the hi-res topo from WPS. We only do this for the
  388. ! coarse grid since we are going to make the interface consistent
  389. ! in the model betwixt the CG and FG domains.
  390. IF ( ( config_flags%smooth_cg_topo ) .AND. &
  391. ( grid%id .EQ. 1 ) .AND. &
  392. ( flag_soilhgt .EQ. 1) ) THEN
  393. CALL blend_terrain ( grid%toposoil , grid%ht , &
  394. ids , ide , jds , jde , 1 , 1 , &
  395. ims , ime , jms , jme , 1 , 1 , &
  396. ips , ipe , jps , jpe , 1 , 1 )
  397. END IF
  398. ! Filter the input topography if this is a polar projection.
  399. IF ( ( config_flags%polar ) .AND. ( grid%fft_filter_lat .GT. 90 ) ) THEN
  400. CALL wrf_error_fatal ( 'If the polar boundary condition is used, then fft_filter_lat must be set in namelist.input' )
  401. END IF
  402. IF ( config_flags%map_proj .EQ. PROJ_CASSINI ) THEN
  403. #if ( defined( DM_PARALLEL ) && ( ! defined( STUBMPI ) ) )
  404. ! We stick the topo and map fac in an unused 3d array. The map scale
  405. ! factor and computational latitude are passed along for the ride
  406. ! (part of the transpose process - we only do 3d arrays) to determine
  407. ! "how many" values are used to compute the mean. We want a number
  408. ! that is consistent with the original grid resolution.
  409. DO j = jts, MIN(jte,jde-1)
  410. DO k = kts, kte
  411. DO i = its, MIN(ite,ide-1)
  412. grid%t_init(i,k,j) = 1.
  413. END DO
  414. END DO
  415. DO i = its, MIN(ite,ide-1)
  416. grid%t_init(i,1,j) = grid%ht(i,j)
  417. grid%t_init(i,2,j) = grid%msftx(i,j)
  418. grid%t_init(i,3,j) = grid%clat(i,j)
  419. END DO
  420. END DO
  421. # include "XPOSE_POLAR_FILTER_TOPO_z2x.inc"
  422. ! Retrieve the 2d arrays for topo, map factors, and the
  423. ! computational latitude.
  424. DO j = jpsx, MIN(jpex,jde-1)
  425. DO i = ipsx, MIN(ipex,ide-1)
  426. grid%ht_xxx(i,j) = grid%t_xxx(i,1,j)
  427. grid%mf_xxx(i,j) = grid%t_xxx(i,2,j)
  428. grid%clat_xxx(i,j) = grid%t_xxx(i,3,j)
  429. END DO
  430. END DO
  431. ! Get a mean topo field that is consistent with the grid
  432. ! distance on each computational latitude loop.
  433. CALL filter_topo ( grid%ht_xxx , grid%clat_xxx , grid%mf_xxx , &
  434. grid%fft_filter_lat , &
  435. ids, ide, jds, jde, 1 , 1 , &
  436. imsx, imex, jmsx, jmex, 1, 1, &
  437. ipsx, ipex, jpsx, jpex, 1, 1 )
  438. ! Stick the filtered topo back into the dummy 3d array to
  439. ! transpose it back to "all z on a patch".
  440. DO j = jpsx, MIN(jpex,jde-1)
  441. DO i = ipsx, MIN(ipex,ide-1)
  442. grid%t_xxx(i,1,j) = grid%ht_xxx(i,j)
  443. END DO
  444. END DO
  445. # include "XPOSE_POLAR_FILTER_TOPO_x2z.inc"
  446. ! Get the un-transposed topo data.
  447. DO j = jts, MIN(jte,jde-1)
  448. DO i = its, MIN(ite,ide-1)
  449. grid%ht(i,j) = grid%t_init(i,1,j)
  450. END DO
  451. END DO
  452. #else
  453. CALL filter_topo ( grid%ht , grid%clat , grid%msftx , &
  454. grid%fft_filter_lat , &
  455. ids, ide, jds, jde, 1,1, &
  456. ims, ime, jms, jme, 1,1, &
  457. its, ite, jts, jte, 1,1 )
  458. #endif
  459. END IF
  460. ! If we have any input low-res surface pressure, we store it.
  461. IF ( flag_psfc .EQ. 1 ) THEN
  462. DO j = jts, MIN(jte,jde-1)
  463. DO i = its, MIN(ite,ide-1)
  464. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  465. grid%psfc_gc(i,j) = grid%psfc(i,j)
  466. grid%p_gc(i,1,j) = grid%psfc(i,j)
  467. END DO
  468. END DO
  469. END IF
  470. ! If we have the low-resolution surface elevation, stick that in the
  471. ! "input" locations of the 3d height. We still have the "hi-res" topo
  472. ! stuck in the grid%ht array. The grid%landmask if test is required as some sources
  473. ! have ZERO elevation over water (thank you very much).
  474. IF ( flag_soilhgt .EQ. 1) THEN
  475. DO j = jts, MIN(jte,jde-1)
  476. DO i = its, MIN(ite,ide-1)
  477. ! IF ( grid%landmask(i,j) .GT. 0.5 ) THEN
  478. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  479. grid%ght_gc(i,1,j) = grid%toposoil(i,j)
  480. grid%ht_gc(i,j)= grid%toposoil(i,j)
  481. ! END IF
  482. END DO
  483. END DO
  484. END IF
  485. ! The number of vertical levels in the input data. There is no staggering for
  486. ! different variables.
  487. num_metgrid_levels = grid%num_metgrid_levels
  488. ! For UM data, swap incoming extra (theta-based) pressure with the standardly
  489. ! named (rho-based) pressure.
  490. IF ( flag_ptheta .EQ. 1 ) THEN
  491. DO j = jts, MIN(jte,jde-1)
  492. DO k = 1 , num_metgrid_levels
  493. DO i = its, MIN(ite,ide-1)
  494. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  495. ptemp = grid%p_gc(i,k,j)
  496. grid%p_gc(i,k,j) = grid%prho_gc(i,k,j)
  497. grid%prho_gc(i,k,j) = ptemp
  498. END DO
  499. END DO
  500. END DO
  501. ! For UM data, the "surface" and the "first hybrid" level for the theta-level data fields are the same.
  502. ! Average the surface (k=1) and the second hybrid level (k=num_metgrid_levels-1) to get the first hybrid
  503. ! layer. We only do this for the theta-level data: pressure, temperature, specific humidity, and
  504. ! geopotential height (i.e. we do not modify u, v, or the rho-based pressure).
  505. DO j = jts, MIN(jte,jde-1)
  506. DO i = its, MIN(ite,ide-1)
  507. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  508. grid% p_gc(i,num_metgrid_levels,j) = ( grid% p_gc(i,1,j) + grid% p_gc(i,num_metgrid_levels-1,j) ) * 0.5
  509. grid% t_gc(i,num_metgrid_levels,j) = ( grid% t_gc(i,1,j) + grid% t_gc(i,num_metgrid_levels-1,j) ) * 0.5
  510. grid% sh_gc(i,num_metgrid_levels,j) = ( grid% sh_gc(i,1,j) + grid% sh_gc(i,num_metgrid_levels-1,j) ) * 0.5
  511. grid%ght_gc(i,num_metgrid_levels,j) = ( grid%ght_gc(i,1,j) + grid%ght_gc(i,num_metgrid_levels-1,j) ) * 0.5
  512. END DO
  513. END DO
  514. END IF
  515. IF ( any_valid_points ) THEN
  516. ! Check for and semi-fix missing surface fields.
  517. IF ( grid%p_gc(i_valid,num_metgrid_levels,j_valid) .LT. grid%p_gc(i_valid,2,j_valid) ) THEN
  518. k = 2
  519. ELSE
  520. k = num_metgrid_levels
  521. END IF
  522. IF ( grid%t_gc(i_valid,1,j_valid) .EQ. -1.E30 ) THEN
  523. DO j = jts, MIN(jte,jde-1)
  524. DO i = its, MIN(ite,ide-1)
  525. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  526. grid%t_gc(i,1,j) = grid%t_gc(i,k,j)
  527. END DO
  528. END DO
  529. config_flags%use_surface = .FALSE.
  530. grid%use_surface = .FALSE.
  531. WRITE ( a_message , * ) 'Missing surface temp, replaced with closest level, use_surface set to false.'
  532. CALL wrf_message ( a_message )
  533. END IF
  534. IF ( grid%rh_gc(i_valid,1,j_valid) .EQ. -1.E30 ) THEN
  535. DO j = jts, MIN(jte,jde-1)
  536. DO i = its, MIN(ite,ide-1)
  537. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  538. grid%rh_gc(i,1,j) = grid%rh_gc(i,k,j)
  539. END DO
  540. END DO
  541. config_flags%use_surface = .FALSE.
  542. grid%use_surface = .FALSE.
  543. WRITE ( a_message , * ) 'Missing surface RH, replaced with closest level, use_surface set to false.'
  544. CALL wrf_message ( a_message )
  545. END IF
  546. IF ( grid%u_gc(i_valid,1,j_valid) .EQ. -1.E30 ) THEN
  547. DO j = jts, MIN(jte,jde-1)
  548. DO i = its, ite
  549. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  550. grid%u_gc(i,1,j) = grid%u_gc(i,k,j)
  551. END DO
  552. END DO
  553. config_flags%use_surface = .FALSE.
  554. grid%use_surface = .FALSE.
  555. WRITE ( a_message , * ) 'Missing surface u wind, replaced with closest level, use_surface set to false.'
  556. CALL wrf_message ( a_message )
  557. END IF
  558. IF ( grid%v_gc(i_valid,1,j_valid) .EQ. -1.E30 ) THEN
  559. DO j = jts, jte
  560. DO i = its, MIN(ite,ide-1)
  561. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  562. grid%v_gc(i,1,j) = grid%v_gc(i,k,j)
  563. END DO
  564. END DO
  565. config_flags%use_surface = .FALSE.
  566. grid%use_surface = .FALSE.
  567. WRITE ( a_message , * ) 'Missing surface v wind, replaced with closest level, use_surface set to false.'
  568. CALL wrf_message ( a_message )
  569. END IF
  570. ! Compute the mixing ratio from the input relative humidity.
  571. IF ( ( flag_qv .NE. 1 ) .AND. ( flag_sh .NE. 1 ) ) THEN
  572. IF ( grid%p_gc(i_valid,num_metgrid_levels,j_valid) .LT. grid%p_gc(i_valid,2,j_valid) ) THEN
  573. k = 2
  574. ELSE
  575. k = num_metgrid_levels
  576. END IF
  577. IF ( config_flags%rh2qv_method .eq. 1 ) THEN
  578. CALL rh_to_mxrat1(grid%rh_gc, grid%t_gc, grid%p_gc, grid%qv_gc , &
  579. config_flags%rh2qv_wrt_liquid , &
  580. config_flags%qv_max_p_safe , &
  581. config_flags%qv_max_flag , config_flags%qv_max_value , &
  582. config_flags%qv_min_p_safe , &
  583. config_flags%qv_min_flag , config_flags%qv_min_value , &
  584. ids , ide , jds , jde , 1 , num_metgrid_levels , &
  585. ims , ime , jms , jme , 1 , num_metgrid_levels , &
  586. its , ite , jts , jte , 1 , num_metgrid_levels )
  587. ELSE IF ( config_flags%rh2qv_method .eq. 2 ) THEN
  588. CALL rh_to_mxrat2(grid%rh_gc, grid%t_gc, grid%p_gc, grid%qv_gc , &
  589. config_flags%rh2qv_wrt_liquid , &
  590. config_flags%qv_max_p_safe , &
  591. config_flags%qv_max_flag , config_flags%qv_max_value , &
  592. config_flags%qv_min_p_safe , &
  593. config_flags%qv_min_flag , config_flags%qv_min_value , &
  594. ids , ide , jds , jde , 1 , num_metgrid_levels , &
  595. ims , ime , jms , jme , 1 , num_metgrid_levels , &
  596. its , ite , jts , jte , 1 , num_metgrid_levels )
  597. END IF
  598. ELSE IF ( flag_sh .EQ. 1 ) THEN
  599. IF ( grid%p_gc(i_valid,num_metgrid_levels,j_valid) .LT. grid%p_gc(i_valid,2,j_valid) ) THEN
  600. k = 2
  601. ELSE
  602. k = num_metgrid_levels
  603. END IF
  604. IF ( grid%sh_gc(i_valid,kts,j_valid) .LT. 1.e-6 ) THEN
  605. DO j = jts, MIN(jte,jde-1)
  606. DO i = its, MIN(ite,ide-1)
  607. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  608. grid%sh_gc(i,1,j) = grid%sh_gc(i,k,j)
  609. END DO
  610. END DO
  611. END IF
  612. DO j = jts, MIN(jte,jde-1)
  613. DO k = 1 , num_metgrid_levels
  614. DO i = its, MIN(ite,ide-1)
  615. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  616. grid%qv_gc(i,k,j) = grid%sh_gc(i,k,j) /( 1. - grid%sh_gc(i,k,j) )
  617. sat_vap_pres_mb = 0.6112*10.*EXP(17.67*(grid%t_gc(i,k,j)-273.15)/(grid%t_gc(i,k,j)-29.65))
  618. vap_pres_mb = grid%qv_gc(i,k,j) * grid%p_gc(i,k,j)/100. / (grid%qv_gc(i,k,j) + 0.622 )
  619. IF ( sat_vap_pres_mb .GT. 0 ) THEN
  620. grid%rh_gc(i,k,j) = ( vap_pres_mb / sat_vap_pres_mb ) * 100.
  621. ELSE
  622. grid%rh_gc(i,k,j) = 0.
  623. END IF
  624. END DO
  625. END DO
  626. END DO
  627. END IF
  628. ! Some data sets do not provide a 3d geopotential height field.
  629. IF ( grid%ght_gc(i_valid,grid%num_metgrid_levels/2,j_valid) .LT. 1 ) THEN
  630. DO j = jts, MIN(jte,jde-1)
  631. DO k = kts+1 , grid%num_metgrid_levels
  632. DO i = its, MIN(ite,ide-1)
  633. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  634. grid%ght_gc(i,k,j) = grid%ght_gc(i,k-1,j) - &
  635. R_d / g * 0.5 * ( grid%t_gc(i,k ,j) * ( 1 + 0.608 * grid%qv_gc(i,k ,j) ) + &
  636. grid%t_gc(i,k-1,j) * ( 1 + 0.608 * grid%qv_gc(i,k-1,j) ) ) * &
  637. LOG ( grid%p_gc(i,k,j) / grid%p_gc(i,k-1,j) )
  638. END DO
  639. END DO
  640. END DO
  641. END IF
  642. ! If the pressure levels in the middle of the atmosphere are upside down, then
  643. ! this is hybrid data. Computing the new surface pressure should use sfcprs2.
  644. IF ( grid%p_gc(i_valid,num_metgrid_levels/2,j_valid) .LT. grid%p_gc(i_valid,num_metgrid_levels/2+1,j_valid) ) THEN
  645. config_flags%sfcp_to_sfcp = .TRUE.
  646. END IF
  647. END IF
  648. ! Assign surface fields with original input values. If this is hybrid data,
  649. ! the values are not exactly representative. However - this is only for
  650. ! plotting purposes and such at the 0h of the forecast, so we are not all that
  651. ! worried.
  652. DO j = jts, min(jde-1,jte)
  653. DO i = its, min(ide,ite)
  654. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  655. grid%u10(i,j)=grid%u_gc(i,1,j)
  656. END DO
  657. END DO
  658. DO j = jts, min(jde,jte)
  659. DO i = its, min(ide-1,ite)
  660. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  661. grid%v10(i,j)=grid%v_gc(i,1,j)
  662. END DO
  663. END DO
  664. DO j = jts, min(jde-1,jte)
  665. DO i = its, min(ide-1,ite)
  666. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  667. grid%t2(i,j)=grid%t_gc(i,1,j)
  668. END DO
  669. END DO
  670. IF ( flag_qv .EQ. 1 ) THEN
  671. DO j = jts, min(jde-1,jte)
  672. DO i = its, min(ide-1,ite)
  673. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  674. grid%q2(i,j)=grid%qv_gc(i,1,j)
  675. END DO
  676. END DO
  677. END IF
  678. ! The requested ptop for real data cases.
  679. p_top_requested = grid%p_top_requested
  680. ! Compute the top pressure, grid%p_top. For isobaric data, this is just the
  681. ! top level. For the generalized vertical coordinate data, we find the
  682. ! max pressure on the top level. We have to be careful of two things:
  683. ! 1) the value has to be communicated, 2) the value can not increase
  684. ! at subsequent times from the initial value.
  685. IF ( internal_time_loop .EQ. 1 ) THEN
  686. CALL find_p_top ( grid%p_gc , grid%p_top , &
  687. ids , ide , jds , jde , 1 , num_metgrid_levels , &
  688. ims , ime , jms , jme , 1 , num_metgrid_levels , &
  689. its , ite , jts , jte , 1 , num_metgrid_levels )
  690. #if ( defined( DM_PARALLEL ) && ( ! defined( STUBMPI ) ) )
  691. grid%p_top = wrf_dm_max_real ( grid%p_top )
  692. #endif
  693. ! Compare the requested grid%p_top with the value available from the input data.
  694. IF ( p_top_requested .LT. grid%p_top ) THEN
  695. print *,'p_top_requested = ',p_top_requested
  696. print *,'allowable grid%p_top in data = ',grid%p_top
  697. CALL wrf_error_fatal ( 'p_top_requested < grid%p_top possible from data' )
  698. END IF
  699. ! The grid%p_top valus is the max of what is available from the data and the
  700. ! requested value. We have already compared <, so grid%p_top is directly set to
  701. ! the value in the namelist.
  702. grid%p_top = p_top_requested
  703. ! For subsequent times, we have to remember what the grid%p_top for the first
  704. ! time was. Why? If we have a generalized vert coordinate, the grid%p_top value
  705. ! could fluctuate.
  706. p_top_save = grid%p_top
  707. ELSE
  708. CALL find_p_top ( grid%p_gc , grid%p_top , &
  709. ids , ide , jds , jde , 1 , num_metgrid_levels , &
  710. ims , ime , jms , jme , 1 , num_metgrid_levels , &
  711. its , ite , jts , jte , 1 , num_metgrid_levels )
  712. #if ( defined( DM_PARALLEL ) && ( ! defined( STUBMPI ) ) )
  713. grid%p_top = wrf_dm_max_real ( grid%p_top )
  714. #endif
  715. IF ( grid%p_top .GT. p_top_save ) THEN
  716. print *,'grid%p_top from last time period = ',p_top_save
  717. print *,'grid%p_top from this time period = ',grid%p_top
  718. CALL wrf_error_fatal ( 'grid%p_top > previous value' )
  719. END IF
  720. grid%p_top = p_top_save
  721. ENDIF
  722. ! Get the monthly values interpolated to the current date for the traditional monthly
  723. ! fields of green-ness fraction and background albedo.
  724. CALL monthly_interp_to_date ( grid%greenfrac , current_date , grid%vegfra , &
  725. ids , ide , jds , jde , kds , kde , &
  726. ims , ime , jms , jme , kms , kme , &
  727. its , ite , jts , jte , kts , kte )
  728. CALL monthly_interp_to_date ( grid%albedo12m , current_date , grid%albbck , &
  729. ids , ide , jds , jde , kds , kde , &
  730. ims , ime , jms , jme , kms , kme , &
  731. its , ite , jts , jte , kts , kte )
  732. ! Get the min/max of each i,j for the monthly green-ness fraction.
  733. CALL monthly_min_max ( grid%greenfrac , grid%shdmin , grid%shdmax , &
  734. ids , ide , jds , jde , kds , kde , &
  735. ims , ime , jms , jme , kms , kme , &
  736. its , ite , jts , jte , kts , kte )
  737. ! The model expects the green-ness values in percent, not fraction.
  738. DO j = jts, MIN(jte,jde-1)
  739. DO i = its, MIN(ite,ide-1)
  740. grid%vegfra(i,j) = grid%vegfra(i,j) * 100.
  741. grid%shdmax(i,j) = grid%shdmax(i,j) * 100.
  742. grid%shdmin(i,j) = grid%shdmin(i,j) * 100.
  743. END DO
  744. END DO
  745. ! The model expects the albedo fields as a fraction, not a percent. Set the
  746. ! water values to 8%.
  747. DO j = jts, MIN(jte,jde-1)
  748. DO i = its, MIN(ite,ide-1)
  749. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  750. grid%albbck(i,j) = grid%albbck(i,j) / 100.
  751. grid%snoalb(i,j) = grid%snoalb(i,j) / 100.
  752. IF ( grid%landmask(i,j) .LT. 0.5 ) THEN
  753. grid%albbck(i,j) = 0.08
  754. grid%snoalb(i,j) = 0.08
  755. END IF
  756. END DO
  757. END DO
  758. ! Two ways to get the surface pressure. 1) If we have the low-res input surface
  759. ! pressure and the low-res topography, then we can do a simple hydrostatic
  760. ! relation. 2) Otherwise we compute the surface pressure from the sea-level
  761. ! pressure.
  762. ! Note that on output, grid%psfc is now hi-res. The low-res surface pressure and
  763. ! elevation are grid%psfc_gc and grid%ht_gc (same as grid%ght_gc(k=1)).
  764. IF ( ( flag_psfc .EQ. 1 ) .AND. &
  765. ( flag_soilhgt .EQ. 1 ) .AND. &
  766. ( flag_slp .EQ. 1 ) .AND. &
  767. ( .NOT. config_flags%sfcp_to_sfcp ) ) THEN
  768. WRITE(a_message,FMT='(A)') 'Using sfcprs3 to compute psfc'
  769. CALL wrf_message ( a_message )
  770. CALL sfcprs3(grid%ght_gc, grid%p_gc, grid%ht, &
  771. grid%pslv_gc, grid%psfc, &
  772. ids , ide , jds , jde , 1 , num_metgrid_levels , &
  773. ims , ime , jms , jme , 1 , num_metgrid_levels , &
  774. its , ite , jts , jte , 1 , num_metgrid_levels )
  775. ELSE IF ( ( flag_psfc .EQ. 1 ) .AND. &
  776. ( flag_soilhgt .EQ. 1 ) .AND. &
  777. ( config_flags%sfcp_to_sfcp ) ) THEN
  778. WRITE(a_message,FMT='(A)') 'Using sfcprs2 to compute psfc'
  779. CALL wrf_message ( a_message )
  780. CALL sfcprs2(grid%t_gc, grid%qv_gc, grid%ght_gc, grid%psfc_gc, grid%ht, &
  781. grid%tavgsfc, grid%p_gc, grid%psfc, we_have_tavgsfc, &
  782. ids , ide , jds , jde , 1 , num_metgrid_levels , &
  783. ims , ime , jms , jme , 1 , num_metgrid_levels , &
  784. its , ite , jts , jte , 1 , num_metgrid_levels )
  785. ELSE IF ( flag_slp .EQ. 1 ) THEN
  786. WRITE(a_message,FMT='(A)') 'Using sfcprs to compute psfc'
  787. CALL wrf_message ( a_message )
  788. CALL sfcprs (grid%t_gc, grid%qv_gc, grid%ght_gc, grid%pslv_gc, grid%ht, &
  789. grid%tavgsfc, grid%p_gc, grid%psfc, we_have_tavgsfc, &
  790. ids , ide , jds , jde , 1 , num_metgrid_levels , &
  791. ims , ime , jms , jme , 1 , num_metgrid_levels , &
  792. its , ite , jts , jte , 1 , num_metgrid_levels )
  793. ELSE
  794. WRITE(a_message,FMT='(3(A,I2),A,L1)') 'ERROR in psfc: flag_psfc = ',flag_psfc, &
  795. ', flag_soilhgt = ',flag_soilhgt , &
  796. ', flag_slp = ',flag_slp , &
  797. ', sfcp_to_sfcp = ',config_flags%sfcp_to_sfcp
  798. CALL wrf_message ( a_message )
  799. CALL wrf_error_fatal ( 'not enough info for a p sfc computation' )
  800. END IF
  801. ! If we have no input surface pressure, we'd better stick something in there.
  802. IF ( flag_psfc .NE. 1 ) THEN
  803. DO j = jts, MIN(jte,jde-1)
  804. DO i = its, MIN(ite,ide-1)
  805. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  806. grid%psfc_gc(i,j) = grid%psfc(i,j)
  807. grid%p_gc(i,1,j) = grid%psfc(i,j)
  808. END DO
  809. END DO
  810. END IF
  811. ! Integrate the mixing ratio to get the vapor pressure.
  812. CALL integ_moist ( grid%qv_gc , grid%p_gc , grid%pd_gc , grid%t_gc , grid%ght_gc , grid%intq_gc , &
  813. ids , ide , jds , jde , 1 , num_metgrid_levels , &
  814. ims , ime , jms , jme , 1 , num_metgrid_levels , &
  815. its , ite , jts , jte , 1 , num_metgrid_levels )
  816. ! If this is UM data, the same moisture removed from the "theta" level pressure data can
  817. ! be removed from the "rho" level pressures. This is an approximation. We'll revisit to
  818. ! see if this is a bad idea.
  819. IF ( flag_ptheta .EQ. 1 ) THEN
  820. DO j = jts, MIN(jte,jde-1)
  821. DO k = num_metgrid_levels-1 , 1 , -1
  822. DO i = its, MIN(ite,ide-1)
  823. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  824. ptemp = ((grid%p_gc(i,k,j) - grid%pd_gc(i,k,j)) + (grid%p_gc(i,k+1,j) - grid%pd_gc(i,k+1,j)))/2
  825. grid%pdrho_gc(i,k,j) = grid%prho_gc(i,k,j) - ptemp
  826. END DO
  827. END DO
  828. END DO
  829. END IF
  830. ! Compute the difference between the dry, total surface pressure (input) and the
  831. ! dry top pressure (constant).
  832. CALL p_dts ( grid%mu0 , grid%intq_gc , grid%psfc , grid%p_top , &
  833. ids , ide , jds , jde , 1 , num_metgrid_levels , &
  834. ims , ime , jms , jme , 1 , num_metgrid_levels , &
  835. its , ite , jts , jte , 1 , num_metgrid_levels )
  836. ! Compute the dry, hydrostatic surface pressure.
  837. CALL p_dhs ( grid%pdhs , grid%ht , p00 , t00 , a , &
  838. ids , ide , jds , jde , kds , kde , &
  839. ims , ime , jms , jme , kms , kme , &
  840. its , ite , jts , jte , kts , kte )
  841. ! Compute the eta levels if not defined already.
  842. IF ( grid%znw(1) .NE. 1.0 ) THEN
  843. eta_levels(1:kde) = model_config_rec%eta_levels(1:kde)
  844. max_dz = model_config_rec%max_dz
  845. CALL compute_eta ( grid%znw , &
  846. eta_levels , max_eta , max_dz , &
  847. grid%p_top , g , p00 , cvpm , a , r_d , cp , t00 , p1000mb , t0 , tiso , &
  848. ids , ide , jds , jde , kds , kde , &
  849. ims , ime , jms , jme , kms , kme , &
  850. its , ite , jts , jte , kts , kte )
  851. END IF
  852. IF ( config_flags%interp_theta ) THEN
  853. ! The input field is temperature, we want potential temp.
  854. CALL t_to_theta ( grid%t_gc , grid%p_gc , p00 , &
  855. ids , ide , jds , jde , 1 , num_metgrid_levels , &
  856. ims , ime , jms , jme , 1 , num_metgrid_levels , &
  857. its , ite , jts , jte , 1 , num_metgrid_levels )
  858. END IF
  859. IF ( flag_slp .EQ. 1 ) THEN
  860. ! On the eta surfaces, compute the dry pressure = mu eta, stored in
  861. ! grid%pb, since it is a pressure, and we don't need another kms:kme 3d
  862. ! array floating around. The grid%pb array is re-computed as the base pressure
  863. ! later after the vertical interpolations are complete.
  864. CALL p_dry ( grid%mu0 , grid%znw , grid%p_top , grid%pb , want_full_levels , &
  865. ids , ide , jds , jde , kds , kde , &
  866. ims , ime , jms , jme , kms , kme , &
  867. its , ite , jts , jte , kts , kte )
  868. ! All of the vertical interpolations are done in dry-pressure space. The
  869. ! input data has had the moisture removed (grid%pd_gc). The target levels (grid%pb)
  870. ! had the vapor pressure removed from the surface pressure, then they were
  871. ! scaled by the eta levels.
  872. interp_type = 2
  873. lagrange_order = grid%lagrange_order
  874. lowest_lev_from_sfc = .FALSE.
  875. use_levels_below_ground = .TRUE.
  876. use_surface = .TRUE.
  877. zap_close_levels = grid%zap_close_levels
  878. force_sfc_in_vinterp = 0
  879. t_extrap_type = grid%t_extrap_type
  880. extrap_type = 1
  881. ! For the height field, the lowest level pressure is the slp (approximately "dry"). The
  882. ! lowest level of the input height field (to be associated with slp) then is an array
  883. ! of zeros.
  884. DO j = jts, MIN(jte,jde-1)
  885. DO i = its, MIN(ite,ide-1)
  886. grid%psfc_gc(i,j) = grid%pd_gc(i,1,j)
  887. grid%pd_gc(i,1,j) = grid%pslv_gc(i,j) - ( grid%p_gc(i,1,j) - grid%pd_gc(i,1,j) )
  888. grid%ht_gc(i,j) = grid%ght_gc(i,1,j)
  889. grid%ght_gc(i,1,j) = 0.
  890. END DO
  891. END DO
  892. CALL vert_interp ( grid%ght_gc , grid%pd_gc , grid%ph0 , grid%pb , &
  893. num_metgrid_levels , 'Z' , &
  894. interp_type , lagrange_order , extrap_type , &
  895. lowest_lev_from_sfc , use_levels_below_ground , use_surface , &
  896. zap_close_levels , force_sfc_in_vinterp , &
  897. ids , ide , jds , jde , kds , kde , &
  898. ims , ime , jms , jme , kms , kme , &
  899. its , ite , jts , jte , kts , kte )
  900. ! Put things back to normal.
  901. DO j = jts, MIN(jte,jde-1)
  902. DO i = its, MIN(ite,ide-1)
  903. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  904. grid%pd_gc(i,1,j) = grid%psfc_gc(i,j)
  905. grid%ght_gc(i,1,j) = grid%ht_gc(i,j)
  906. END DO
  907. END DO
  908. END IF
  909. ! Now the rest of the variables on half-levels to inteprolate.
  910. CALL p_dry ( grid%mu0 , grid%znw , grid%p_top , grid%pb , want_half_levels , &
  911. ids , ide , jds , jde , kds , kde , &
  912. ims , ime , jms , jme , kms , kme , &
  913. its , ite , jts , jte , kts , kte )
  914. interp_type = grid%interp_type
  915. lagrange_order = grid%lagrange_order
  916. lowest_lev_from_sfc = grid%lowest_lev_from_sfc
  917. use_levels_below_ground = grid%use_levels_below_ground
  918. use_surface = grid%use_surface
  919. zap_close_levels = grid%zap_close_levels
  920. force_sfc_in_vinterp = grid%force_sfc_in_vinterp
  921. t_extrap_type = grid%t_extrap_type
  922. extrap_type = grid%extrap_type
  923. ! Interpolate RH, diagnose Qv later when have temp and pressure. Temporarily
  924. ! store this in the u_1 space, for later diagnosis into Qv and stored into moist.
  925. CALL vert_interp ( grid%rh_gc , grid%pd_gc , grid%u_1 , grid%pb , &
  926. num_metgrid_levels , 'Q' , &
  927. interp_type , lagrange_order , extrap_type , &
  928. lowest_lev_from_sfc , use_levels_below_ground , use_surface , &
  929. zap_close_levels , force_sfc_in_vinterp , &
  930. ids , ide , jds , jde , kds , kde , &
  931. ims , ime , jms , jme , kms , kme , &
  932. its , ite , jts , jte , kts , kte )
  933. ! Depending on the setting of interp_theta = T/F, t_gc is is either theta Xor
  934. ! temperature, and that means that the t_2 field is also the associated field.
  935. ! It is better to interpolate temperature and potential temperature in LOG(p),
  936. ! regardless of requested default.
  937. interp_type = 2
  938. CALL vert_interp ( grid%t_gc , grid%pd_gc , grid%t_2 , grid%pb , &
  939. num_metgrid_levels , 'T' , &
  940. interp_type , lagrange_order , t_extrap_type , &
  941. lowest_lev_from_sfc , use_levels_below_ground , use_surface , &
  942. zap_close_levels , force_sfc_in_vinterp , &
  943. ids , ide , jds , jde , kds , kde , &
  944. ims , ime , jms , jme , kms , kme , &
  945. its , ite , jts , jte , kts , kte )
  946. interp_type = grid%interp_type
  947. ! It is better to interpolate pressure in p regardless default options
  948. interp_type = 1
  949. CALL vert_interp ( grid%p_gc , grid%pd_gc , grid%p , grid%pb , &
  950. num_metgrid_levels , 'T' , &
  951. interp_type , lagrange_order , t_extrap_type , &
  952. lowest_lev_from_sfc , use_levels_below_ground , use_surface , &
  953. zap_close_levels , force_sfc_in_vinterp , &
  954. ids , ide , jds , jde , kds , kde , &
  955. ims , ime , jms , jme , kms , kme , &
  956. its , ite , jts , jte , kts , kte )
  957. interp_type = grid%interp_type
  958. ! Do not have full pressure on eta levels, get a first guess at Qv by using
  959. ! dry pressure. The use of u_1 (rh) and v_1 (temperature) is temporary.
  960. ! We fix the approximation to Qv after the total pressure is available on
  961. ! eta surfaces.
  962. grid%v_1 = grid%t_2
  963. IF ( config_flags%interp_theta ) THEN
  964. CALL theta_to_t ( grid%v_1 , grid%p , p00 , &
  965. ids , ide , jds , jde , kds , kde , &
  966. ims , ime , jms , jme , kms , kme , &
  967. its , ite , jts , jte , kts , kte )
  968. END IF
  969. IF ( config_flags%rh2qv_method .eq. 1 ) THEN
  970. CALL rh_to_mxrat1(grid%u_1, grid%v_1, grid%p , moist(:,:,:,P_QV) , &
  971. config_flags%rh2qv_wrt_liquid , &
  972. config_flags%qv_max_p_safe , &
  973. config_flags%qv_max_flag , config_flags%qv_max_value , &
  974. config_flags%qv_min_p_safe , &
  975. config_flags%qv_min_flag , config_flags%qv_min_value , &
  976. ids , ide , jds , jde , kds , kde , &
  977. ims , ime , jms , jme , kms , kme , &
  978. its , ite , jts , jte , kts , kte-1 )
  979. ELSE IF ( config_flags%rh2qv_method .eq. 2 ) THEN
  980. CALL rh_to_mxrat2(grid%u_1, grid%v_1, grid%p , moist(:,:,:,P_QV) , &
  981. config_flags%rh2qv_wrt_liquid , &
  982. config_flags%qv_max_p_safe , &
  983. config_flags%qv_max_flag , config_flags%qv_max_value , &
  984. config_flags%qv_min_p_safe , &
  985. config_flags%qv_min_flag , config_flags%qv_min_value , &
  986. ids , ide , jds , jde , kds , kde , &
  987. ims , ime , jms , jme , kms , kme , &
  988. its , ite , jts , jte , kts , kte-1 )
  989. END IF
  990. IF ( .NOT. config_flags%interp_theta ) THEN
  991. CALL t_to_theta ( grid%t_2 , grid%p , p00 , &
  992. ids , ide , jds , jde , kds , kde , &
  993. ims , ime , jms , jme , kms , kme , &
  994. its , ite , jts , jte , kts , kte )
  995. END IF
  996. num_3d_m = num_moist
  997. num_3d_s = num_scalar
  998. IF ( flag_qr .EQ. 1 ) THEN
  999. DO im = PARAM_FIRST_SCALAR, num_3d_m
  1000. IF ( im .EQ. P_QR ) THEN
  1001. CALL vert_interp ( grid%qr_gc , grid%pd_gc , moist(:,:,:,P_QR) , grid%pb , &
  1002. num_metgrid_levels , 'Q' , &
  1003. interp_type , lagrange_order , extrap_type , &
  1004. lowest_lev_from_sfc , use_levels_below_ground , use_surface , &
  1005. zap_close_levels , force_sfc_in_vinterp , &
  1006. ids , ide , jds , jde , kds , kde , &
  1007. ims , ime , jms , jme , kms , kme , &
  1008. its , ite , jts , jte , kts , kte )
  1009. END IF
  1010. END DO
  1011. END IF
  1012. IF ( flag_qc .EQ. 1 ) THEN
  1013. DO im = PARAM_FIRST_SCALAR, num_3d_m
  1014. IF ( im .EQ. P_QC ) THEN
  1015. CALL vert_interp ( grid%qc_gc , grid%pd_gc , moist(:,:,:,P_QC) , grid%pb , &
  1016. num_metgrid_levels , 'Q' , &
  1017. interp_type , lagrange_order , extrap_type , &
  1018. lowest_lev_from_sfc , use_levels_below_ground , use_surface , &
  1019. zap_close_levels , force_sfc_in_vinterp , &
  1020. ids , ide , jds , jde , kds , kde , &
  1021. ims , ime , jms , jme , kms , kme , &
  1022. its , ite , jts , jte , kts , kte )
  1023. END IF
  1024. END DO
  1025. END IF
  1026. IF ( flag_qi .EQ. 1 ) THEN
  1027. DO im = PARAM_FIRST_SCALAR, num_3d_m
  1028. IF ( im .EQ. P_QI ) THEN
  1029. CALL vert_interp ( grid%qi_gc , grid%pd_gc , moist(:,:,:,P_QI) , grid%pb , &
  1030. num_metgrid_levels , 'Q' , &
  1031. interp_type , lagrange_order , extrap_type , &
  1032. lowest_lev_from_sfc , use_levels_below_ground , use_surface , &
  1033. zap_close_levels , force_sfc_in_vinterp , &
  1034. ids , ide , jds , jde , kds , kde , &
  1035. ims , ime , jms , jme , kms , kme , &
  1036. its , ite , jts , jte , kts , kte )
  1037. END IF
  1038. END DO
  1039. END IF
  1040. IF ( flag_qs .EQ. 1 ) THEN
  1041. DO im = PARAM_FIRST_SCALAR, num_3d_m
  1042. IF ( im .EQ. P_QS ) THEN
  1043. CALL vert_interp ( grid%qs_gc , grid%pd_gc , moist(:,:,:,P_QS) , grid%pb , &
  1044. num_metgrid_levels , 'Q' , &
  1045. interp_type , lagrange_order , extrap_type , &
  1046. lowest_lev_from_sfc , use_levels_below_ground , use_surface , &
  1047. zap_close_levels , force_sfc_in_vinterp , &
  1048. ids , ide , jds , jde , kds , kde , &
  1049. ims , ime , jms , jme , kms , kme , &
  1050. its , ite , jts , jte , kts , kte )
  1051. END IF
  1052. END DO
  1053. END IF
  1054. IF ( flag_qg .EQ. 1 ) THEN
  1055. DO im = PARAM_FIRST_SCALAR, num_3d_m
  1056. IF ( im .EQ. P_QG ) THEN
  1057. CALL vert_interp ( grid%qg_gc , grid%pd_gc , moist(:,:,:,P_QG) , grid%pb , &
  1058. num_metgrid_levels , 'Q' , &
  1059. interp_type , lagrange_order , extrap_type , &
  1060. lowest_lev_from_sfc , use_levels_below_ground , use_surface , &
  1061. zap_close_levels , force_sfc_in_vinterp , &
  1062. ids , ide , jds , jde , kds , kde , &
  1063. ims , ime , jms , jme , kms , kme , &
  1064. its , ite , jts , jte , kts , kte )
  1065. END IF
  1066. END DO
  1067. END IF
  1068. IF ( flag_qh .EQ. 1 ) THEN
  1069. DO im = PARAM_FIRST_SCALAR, num_3d_m
  1070. IF ( im .EQ. P_QH ) THEN
  1071. CALL vert_interp ( grid%qh_gc , grid%pd_gc , moist(:,:,:,P_QH) , grid%pb , &
  1072. num_metgrid_levels , 'Q' , &
  1073. interp_type , lagrange_order , extrap_type , &
  1074. lowest_lev_from_sfc , use_levels_below_ground , use_surface , &
  1075. zap_close_levels , force_sfc_in_vinterp , &
  1076. ids , ide , jds , jde , kds , kde , &
  1077. ims , ime , jms , jme , kms , kme , &
  1078. its , ite , jts , jte , kts , kte )
  1079. END IF
  1080. END DO
  1081. END IF
  1082. IF ( flag_qni .EQ. 1 ) THEN
  1083. DO im = PARAM_FIRST_SCALAR, num_3d_s
  1084. IF ( im .EQ. P_QNI ) THEN
  1085. CALL vert_interp ( grid%qni_gc , grid%pd_gc , scalar(:,:,:,P_QNI) , grid%pb , &
  1086. num_metgrid_levels , 'Q' , &
  1087. interp_type , lagrange_order , extrap_type , &
  1088. lowest_lev_from_sfc , use_levels_below_ground , use_surface , &
  1089. zap_close_levels , force_sfc_in_vinterp , &
  1090. ids , ide , jds , jde , kds , kde , &
  1091. ims , ime , jms , jme , kms , kme , &
  1092. its , ite , jts , jte , kts , kte )
  1093. END IF
  1094. END DO
  1095. END IF
  1096. ! If this is UM data, put the dry rho-based pressure back into the dry pressure array.
  1097. ! Since the dry pressure is no longer needed, no biggy.
  1098. IF ( flag_ptheta .EQ. 1 ) THEN
  1099. DO j = jts, MIN(jte,jde-1)
  1100. DO k = 1 , num_metgrid_levels
  1101. DO i = its, MIN(ite,ide-1)
  1102. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  1103. grid%pd_gc(i,k,j) = grid%prho_gc(i,k,j)
  1104. END DO
  1105. END DO
  1106. END DO
  1107. END IF
  1108. #ifdef DM_PARALLEL
  1109. ips = its ; ipe = ite ; jps = jts ; jpe = jte ; kps = kts ; kpe = kte
  1110. ! For the U and V vertical interpolation, we need the pressure defined
  1111. ! at both the locations for the horizontal momentum, which we get by
  1112. ! averaging two pressure values (i and i-1 for U, j and j-1 for V). The
  1113. ! pressure field on input (grid%pd_gc) and the pressure of the new coordinate
  1114. ! (grid%pb) are both communicated with an 8 stencil.
  1115. # include "HALO_EM_VINTERP_UV_1.inc"
  1116. #endif
  1117. CALL vert_interp ( grid%u_gc , grid%pd_gc , grid%u_2 , grid%pb , &
  1118. num_metgrid_levels , 'U' , &
  1119. interp_type , lagrange_order , extrap_type , &
  1120. lowest_lev_from_sfc , use_levels_below_ground , use_surface , &
  1121. zap_close_levels , force_sfc_in_vinterp , &
  1122. ids , ide , jds , jde , kds , kde , &
  1123. ims , ime , jms , jme , kms , kme , &
  1124. its , ite , jts , jte , kts , kte )
  1125. CALL vert_interp ( grid%v_gc , grid%pd_gc , grid%v_2 , grid%pb , &
  1126. num_metgrid_levels , 'V' , &
  1127. interp_type , lagrange_order , extrap_type , &
  1128. lowest_lev_from_sfc , use_levels_below_ground , use_surface , &
  1129. zap_close_levels , force_sfc_in_vinterp , &
  1130. ids , ide , jds , jde , kds , kde , &
  1131. ims , ime , jms , jme , kms , kme , &
  1132. its , ite , jts , jte , kts , kte )
  1133. END IF ! <----- END OF VERTICAL INTERPOLATION PART ---->
  1134. ! Set the temperature of the inland lakes to tavgsfc if the temperature is available
  1135. ! and islake is > num_veg_cat
  1136. num_veg_cat = SIZE ( grid%landusef , DIM=2 )
  1137. CALL nl_get_iswater ( grid%id , grid%iswater )
  1138. CALL nl_get_islake ( grid%id , grid%islake )
  1139. IF ( grid%islake < 0 ) THEN
  1140. CALL wrf_debug ( 0 , 'Old data, no inland lake information')
  1141. DO j=jts,MIN(jde-1,jte)
  1142. DO i=its,MIN(ide-1,ite)
  1143. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  1144. IF ( ( ( grid%landusef(i,grid%iswater,j) >= 0.5 ) .OR. ( grid%lu_index(i,j) == grid%iswater ) ) .AND. &
  1145. ( ( grid%sst(i,j) .LT. 150 ) .OR. ( grid%sst(i,j) .GT. 400 ) ) ) THEN
  1146. IF ( we_have_tavgsfc ) THEN
  1147. grid%sst(i,j) = grid%tavgsfc(i,j)
  1148. END IF
  1149. IF ( ( grid%sst(i,j) .LT. 150 ) .OR. ( grid%sst(i,j) .GT. 400 ) ) THEN
  1150. grid%sst(i,j) = grid%tsk(i,j)
  1151. END IF
  1152. IF ( ( grid%sst(i,j) .LT. 150 ) .OR. ( grid%sst(i,j) .GT. 400 ) ) THEN
  1153. grid%sst(i,j) = grid%t2(i,j)
  1154. END IF
  1155. END IF
  1156. END DO
  1157. END DO
  1158. ELSE
  1159. IF ( we_have_tavgsfc ) THEN
  1160. CALL wrf_debug ( 0 , 'Using inland lakes with average surface temperature')
  1161. DO j=jts,MIN(jde-1,jte)
  1162. DO i=its,MIN(ide-1,ite)
  1163. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  1164. IF ( ( grid%landusef(i,grid%islake,j) >= 0.5 ) .OR. ( grid%lu_index(i,j) == grid%islake ) ) THEN
  1165. grid%sst(i,j) = grid%tavgsfc(i,j)
  1166. grid%tsk(i,j) = grid%tavgsfc(i,j)
  1167. END IF
  1168. IF ( ( grid%sst(i,j) .LT. 150 ) .OR. ( grid%sst(i,j) .GT. 400 ) ) THEN
  1169. grid%sst(i,j) = grid%t2(i,j)
  1170. END IF
  1171. END DO
  1172. END DO
  1173. ELSE ! We don't have tavgsfc
  1174. CALL wrf_debug ( 0 , 'No average surface temperature for use with inland lakes')
  1175. END IF
  1176. DO j=jts,MIN(jde-1,jte)
  1177. DO i=its,MIN(ide-1,ite)
  1178. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  1179. grid%landusef(i,grid%iswater,j) = grid%landusef(i,grid%iswater,j) + &
  1180. grid%landusef(i,grid%islake,j)
  1181. grid%landusef(i,grid%islake,j) = 0.
  1182. END DO
  1183. END DO
  1184. END IF
  1185. ! Save the grid%tsk field for later use in the sea ice surface temperature
  1186. ! for the Noah LSM scheme.
  1187. DO j = jts, MIN(jte,jde-1)
  1188. DO i = its, MIN(ite,ide-1)
  1189. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  1190. grid%tsk_save(i,j) = grid%tsk(i,j)
  1191. END DO
  1192. END DO
  1193. ! Protect against bad grid%tsk values over water by supplying grid%sst (if it is
  1194. ! available, and if the grid%sst is reasonable).
  1195. DO j = jts, MIN(jde-1,jte)
  1196. DO i = its, MIN(ide-1,ite)
  1197. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  1198. IF ( ( grid%landmask(i,j) .LT. 0.5 ) .AND. ( flag_sst .EQ. 1 ) .AND. &
  1199. ( grid%sst(i,j) .GT. 170. ) .AND. ( grid%sst(i,j) .LT. 400. ) ) THEN
  1200. grid%tsk(i,j) = grid%sst(i,j)
  1201. ENDIF
  1202. END DO
  1203. END DO
  1204. ! Take the data from the input file and store it in the variables that
  1205. ! use the WRF naming and ordering conventions.
  1206. DO j = jts, MIN(jte,jde-1)
  1207. DO i = its, MIN(ite,ide-1)
  1208. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  1209. IF ( grid%snow(i,j) .GE. 10. ) then
  1210. grid%snowc(i,j) = 1.
  1211. ELSE
  1212. grid%snowc(i,j) = 0.0
  1213. END IF
  1214. END DO
  1215. END DO
  1216. ! Set flag integers for presence of snowh and soilw fields
  1217. grid%ifndsnowh = flag_snowh
  1218. IF (num_sw_levels_input .GE. 1) THEN
  1219. grid%ifndsoilw = 1
  1220. ELSE
  1221. grid%ifndsoilw = 0
  1222. END IF
  1223. ! We require input data for the various LSM schemes.
  1224. enough_data : SELECT CASE ( model_config_rec%sf_surface_physics(grid%id) )
  1225. CASE ( LSMSCHEME, NOAHMPSCHEME )
  1226. IF ( num_st_levels_input .LT. 2 ) THEN
  1227. CALL wrf_error_fatal ( 'Not enough soil temperature data for Noah LSM scheme.')
  1228. END IF
  1229. CASE (RUCLSMSCHEME)
  1230. IF ( num_st_levels_input .LT. 2 ) THEN
  1231. CALL wrf_error_fatal ( 'Not enough soil temperature data for RUC LSM scheme.')
  1232. END IF
  1233. CASE (PXLSMSCHEME)
  1234. IF ( num_st_levels_input .LT. 2 ) THEN
  1235. CALL wrf_error_fatal ( 'Not enough soil temperature data for P-X LSM scheme.')
  1236. END IF
  1237. !---------- fds (06/2010) ---------------------------------
  1238. CASE (SSIBSCHEME)
  1239. IF ( num_st_levels_input .LT. 2 ) THEN
  1240. CALL wrf_error_fatal ( 'Not enough soil temperature data for SSIB LSM scheme.')
  1241. END IF
  1242. !--------------------------------------------------------
  1243. END SELECT enough_data
  1244. interpolate_soil_tmw : SELECT CASE ( model_config_rec%sf_surface_physics(grid%id) )
  1245. CASE ( SLABSCHEME , LSMSCHEME, NOAHMPSCHEME , RUCLSMSCHEME, PXLSMSCHEME, SSIBSCHEME )
  1246. CALL process_soil_real ( grid%tsk , grid%tmn , grid%tavgsfc, &
  1247. grid%landmask , grid%sst , grid%ht, grid%toposoil, &
  1248. st_input , sm_input , sw_input , &
  1249. st_levels_input , sm_levels_input , sw_levels_input , &
  1250. grid%zs , grid%dzs , grid%tslb , grid%smois , grid%sh2o , &
  1251. flag_sst , flag_tavgsfc, flag_soilhgt,&
  1252. flag_soil_layers, flag_soil_levels, &
  1253. ids , ide , jds , jde , kds , kde , &
  1254. ims , ime , jms , jme , kms , kme , &
  1255. its , ite , jts , jte , kts , kte , &
  1256. model_config_rec%sf_surface_physics(grid%id) , &
  1257. model_config_rec%num_soil_layers , &
  1258. model_config_rec%real_data_init_type , &
  1259. num_st_levels_input , num_sm_levels_input , num_sw_levels_input , &
  1260. num_st_levels_alloc , num_sm_levels_alloc , num_sw_levels_alloc )
  1261. END SELECT interpolate_soil_tmw
  1262. ! surface_input_source=1 => use data from static file (fractional category as input)
  1263. ! surface_input_source=2 => use data from grib file (dominant category as input)
  1264. ! surface_input_source=3 => use dominant data from static file (dominant category as input)
  1265. IF ( any_valid_points ) THEN
  1266. IF ( config_flags%surface_input_source .EQ. 1 ) THEN
  1267. ! Generate the vegetation and soil category information from the fractional input
  1268. ! data, or use the existing dominant category fields if they exist.
  1269. grid%vegcat (its,jts) = 0
  1270. grid%soilcat(its,jts) = 0
  1271. num_veg_cat = SIZE ( grid%landusef , DIM=2 )
  1272. num_soil_top_cat = SIZE ( grid%soilctop , DIM=2 )
  1273. num_soil_bot_cat = SIZE ( grid%soilcbot , DIM=2 )
  1274. CALL process_percent_cat_new ( grid%landmask , &
  1275. grid%landusef , grid%soilctop , grid%soilcbot , &
  1276. grid%isltyp , grid%ivgtyp , &
  1277. num_veg_cat , num_soil_top_cat , num_soil_bot_cat , &
  1278. ids , ide , jds , jde , kds , kde , &
  1279. ims , ime , jms , jme , kms , kme , &
  1280. its , ite , jts , jte , kts , kte , &
  1281. model_config_rec%iswater(grid%id) )
  1282. ! Make all the veg/soil parms the same so as not to confuse the developer.
  1283. DO j = jts , MIN(jde-1,jte)
  1284. DO i = its , MIN(ide-1,ite)
  1285. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  1286. grid%vegcat(i,j) = grid%ivgtyp(i,j)
  1287. grid%soilcat(i,j) = grid%isltyp(i,j)
  1288. END DO
  1289. END DO
  1290. ELSE IF ( config_flags%surface_input_source .EQ. 2 ) THEN
  1291. ! Do we have dominant soil and veg data from the input already?
  1292. IF ( grid%soilcat(i_valid,j_valid) .GT. 0.5 ) THEN
  1293. DO j = jts, MIN(jde-1,jte)
  1294. DO i = its, MIN(ide-1,ite)
  1295. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  1296. grid%isltyp(i,j) = NINT( grid%soilcat(i,j) )
  1297. END DO
  1298. END DO
  1299. END IF
  1300. IF ( grid%vegcat(i_valid,j_valid) .GT. 0.5 ) THEN
  1301. DO j = jts, MIN(jde-1,jte)
  1302. DO i = its, MIN(ide-1,ite)
  1303. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  1304. grid%ivgtyp(i,j) = NINT( grid%vegcat(i,j) )
  1305. END DO
  1306. END DO
  1307. END IF
  1308. ELSE IF ( config_flags%surface_input_source .EQ. 3 ) THEN
  1309. ! Do we have dominant soil and veg data from the static input already?
  1310. IF ( grid%sct_dom_gc(i_valid,j_valid) .GT. 0.5 ) THEN
  1311. DO j = jts, MIN(jde-1,jte)
  1312. DO i = its, MIN(ide-1,ite)
  1313. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  1314. grid%isltyp(i,j) = NINT( grid%sct_dom_gc(i,j) )
  1315. grid%soilcat(i,j) = grid%isltyp(i,j)
  1316. END DO
  1317. END DO
  1318. ELSE
  1319. WRITE ( a_message , * ) 'You have set surface_input_source = 3,'// &
  1320. ' but your geogrid data does not have valid dominant soil data.'
  1321. CALL wrf_error_fatal ( a_message )
  1322. END IF
  1323. IF ( grid%lu_index(i_valid,j_valid) .GT. 0.5 ) THEN
  1324. DO j = jts, MIN(jde-1,jte)
  1325. DO i = its, MIN(ide-1,ite)
  1326. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  1327. grid%ivgtyp(i,j) = NINT( grid%lu_index(i,j) )
  1328. grid%vegcat(i,j) = grid%ivgtyp(i,j)
  1329. END DO
  1330. END DO
  1331. ELSE
  1332. WRITE ( a_message , * ) 'You have set surface_input_source = 3,'//&
  1333. ' but your geogrid data does not have valid dominant land use data.'
  1334. CALL wrf_error_fatal ( a_message )
  1335. END IF
  1336. END IF
  1337. END IF
  1338. ! Adjustments for the seaice field PRIOR to the grid%tslb computations. This is
  1339. ! is for the 5-layer scheme.
  1340. num_veg_cat = SIZE ( grid%landusef , DIM=2 )
  1341. num_soil_top_cat = SIZE ( grid%soilctop , DIM=2 )
  1342. num_soil_bot_cat = SIZE ( grid%soilcbot , DIM=2 )
  1343. CALL nl_get_seaice_threshold ( grid%id , grid%seaice_threshold )
  1344. CALL nl_get_isice ( grid%id , grid%isice )
  1345. CALL nl_get_iswater ( grid%id , grid%iswater )
  1346. CALL adjust_for_seaice_pre ( grid%xice , grid%landmask , grid%tsk , grid%ivgtyp , grid%vegcat , grid%lu_index , &
  1347. grid%xland , grid%landusef , grid%isltyp , grid%soilcat , grid%soilctop , &
  1348. grid%soilcbot , grid%tmn , &
  1349. grid%seaice_threshold , &
  1350. config_flags%fractional_seaice, &
  1351. num_veg_cat , num_soil_top_cat , num_soil_bot_cat , &
  1352. grid%iswater , grid%isice , &
  1353. model_config_rec%sf_surface_physics(grid%id) , &
  1354. ids , ide , jds , jde , kds , kde , &
  1355. ims , ime , jms , jme , kms , kme , &
  1356. its , ite , jts , jte , kts , kte )
  1357. ! Land use assignment.
  1358. DO j = jts, MIN(jde-1,jte)
  1359. DO i = its, MIN(ide-1,ite)
  1360. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  1361. grid%lu_index(i,j) = grid%ivgtyp(i,j)
  1362. IF ( grid%lu_index(i,j) .NE. model_config_rec%iswater(grid%id) ) THEN
  1363. grid%landmask(i,j) = 1
  1364. grid%xland(i,j) = 1
  1365. ELSE
  1366. grid%landmask(i,j) = 0
  1367. grid%xland(i,j) = 2
  1368. END IF
  1369. END DO
  1370. END DO
  1371. ! Fix grid%tmn and grid%tsk.
  1372. fix_tsk_tmn : SELECT CASE ( model_config_rec%sf_surface_physics(grid%id) )
  1373. CASE ( SLABSCHEME , LSMSCHEME , NOAHMPSCHEME , RUCLSMSCHEME, PXLSMSCHEME, SSIBSCHEME )
  1374. DO j = jts, MIN(jde-1,jte)
  1375. DO i = its, MIN(ide-1,ite)
  1376. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  1377. IF ( ( grid%landmask(i,j) .LT. 0.5 ) .AND. ( flag_sst .EQ. 1 ) .AND. &
  1378. ( grid%sst(i,j) .GT. 170. ) .AND. ( grid%sst(i,j) .LT. 400. ) ) THEN
  1379. grid%tmn(i,j) = grid%sst(i,j)
  1380. grid%tsk(i,j) = grid%sst(i,j)
  1381. ELSE IF ( grid%landmask(i,j) .LT. 0.5 ) THEN
  1382. grid%tmn(i,j) = grid%tsk(i,j)
  1383. END IF
  1384. END DO
  1385. END DO
  1386. END SELECT fix_tsk_tmn
  1387. ! Is the grid%tsk reasonable?
  1388. IF ( internal_time_loop .NE. 1 ) THEN
  1389. DO j = jts, MIN(jde-1,jte)
  1390. DO i = its, MIN(ide-1,ite)
  1391. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  1392. IF ( grid%tsk(i,j) .LT. 170 .or. grid%tsk(i,j) .GT. 400. ) THEN
  1393. grid%tsk(i,j) = grid%t_2(i,1,j)
  1394. END IF
  1395. END DO
  1396. END DO
  1397. ELSE
  1398. DO j = jts, MIN(jde-1,jte)
  1399. DO i = its, MIN(ide-1,ite)
  1400. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  1401. IF ( grid%tsk(i,j) .LT. 170 .or. grid%tsk(i,j) .GT. 400. ) THEN
  1402. print *,'error in the grid%tsk'
  1403. print *,'i,j=',i,j
  1404. print *,'grid%landmask=',grid%landmask(i,j)
  1405. print *,'grid%tsk, grid%sst, grid%tmn=',grid%tsk(i,j),grid%sst(i,j),grid%tmn(i,j)
  1406. if(grid%tmn(i,j).gt.170. .and. grid%tmn(i,j).lt.400.)then
  1407. grid%tsk(i,j)=grid%tmn(i,j)
  1408. else if(grid%sst(i,j).gt.170. .and. grid%sst(i,j).lt.400.)then
  1409. grid%tsk(i,j)=grid%sst(i,j)
  1410. else
  1411. CALL wrf_error_fatal ( 'grid%tsk unreasonable' )
  1412. end if
  1413. END IF
  1414. END DO
  1415. END DO
  1416. END IF
  1417. ! Is the grid%tmn reasonable?
  1418. DO j = jts, MIN(jde-1,jte)
  1419. DO i = its, MIN(ide-1,ite)
  1420. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  1421. IF ( ( ( grid%tmn(i,j) .LT. 170. ) .OR. ( grid%tmn(i,j) .GT. 400. ) ) &
  1422. .AND. ( grid%landmask(i,j) .GT. 0.5 ) ) THEN
  1423. IF ( ( model_config_rec%sf_surface_physics(grid%id) .NE. LSMSCHEME ) .and. &
  1424. ( model_config_rec%sf_surface_physics(grid%id) .NE. NOAHMPSCHEME ) ) THEN
  1425. print *,'error in the grid%tmn'
  1426. print *,'i,j=',i,j
  1427. print *,'grid%landmask=',grid%landmask(i,j)
  1428. print *,'grid%tsk, grid%sst, grid%tmn=',grid%tsk(i,j),grid%sst(i,j),grid%tmn(i,j)
  1429. END IF
  1430. if(grid%tsk(i,j).gt.170. .and. grid%tsk(i,j).lt.400.)then
  1431. grid%tmn(i,j)=grid%tsk(i,j)
  1432. else if(grid%sst(i,j).gt.170. .and. grid%sst(i,j).lt.400.)then
  1433. grid%tmn(i,j)=grid%sst(i,j)
  1434. else
  1435. CALL wrf_error_fatal ( 'grid%tmn unreasonable' )
  1436. endif
  1437. END IF
  1438. END DO
  1439. END DO
  1440. ! Minimum soil values, residual, from RUC LSM scheme. For input from Noah or EC, and using
  1441. ! RUC LSM scheme, this must be subtracted from the input total soil moisture. For
  1442. ! input RUC data and using the Noah LSM scheme, this value must be added to the soil
  1443. ! moisture input.
  1444. lqmi(1:num_soil_top_cat) = &
  1445. (/0.045, 0.057, 0.065, 0.067, 0.034, 0.078, 0.10, &
  1446. 0.089, 0.095, 0.10, 0.070, 0.068, 0.078, 0.0, &
  1447. 0.004, 0.065 /)
  1448. ! 0.004, 0.065, 0.020, 0.004, 0.008 /) ! has extra levels for playa, lava, and white sand
  1449. ! At the initial time we care about values of soil moisture and temperature, other times are
  1450. ! ignored by the model, so we ignore them, too.
  1451. IF ( domain_ClockIsStartTime(grid) ) THEN
  1452. account_for_zero_soil_moisture : SELECT CASE ( model_config_rec%sf_surface_physics(grid%id) )
  1453. CASE ( LSMSCHEME , NOAHMPSCHEME )
  1454. iicount = 0
  1455. IF ( flag_soil_layers == 1 ) THEN
  1456. DO j = jts, MIN(jde-1,jte)
  1457. DO i = its, MIN(ide-1,ite)
  1458. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  1459. IF ( (grid%landmask(i,j).gt.0.5) .and. ( grid%tslb(i,1,j) .gt. 170 ) .and. &
  1460. ( grid%tslb(i,1,j) .lt. 400 ) .and. ( grid%smois(i,1,j) .lt. 0.005 ) ) then
  1461. print *,'Noah -> Noah: bad soil moisture at i,j = ',i,j,grid%smois(i,:,j)
  1462. iicount = iicount + 1
  1463. grid%smois(i,:,j) = 0.005
  1464. END IF
  1465. END DO
  1466. END DO
  1467. IF ( iicount .GT. 0 ) THEN
  1468. print *,'Noah -> Noah: total number of small soil moisture locations = ',iicount
  1469. END IF
  1470. ELSE IF ( flag_soil_levels == 1 ) THEN
  1471. DO j = jts, MIN(jde-1,jte)
  1472. DO i = its, MIN(ide-1,ite)
  1473. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  1474. grid%smois(i,:,j) = MAX ( grid%smois(i,:,j) , 0.005 )
  1475. ! grid%smois(i,:,j) = MAX ( grid%smois(i,:,j) + lqmi(grid%isltyp(i,j)) , 0.005 )
  1476. END DO
  1477. END DO
  1478. DO j = jts, MIN(jde-1,jte)
  1479. DO i = its, MIN(ide-1,ite)
  1480. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  1481. IF ( (grid%landmask(i,j).gt.0.5) .and. ( grid%tslb(i,1,j) .gt. 170 ) .and. &
  1482. ( grid%tslb(i,1,j) .lt. 400 ) .and. ( grid%smois(i,1,j) .lt. 0.005 ) ) then
  1483. print *,'RUC -> Noah: bad soil moisture at i,j = ',i,j,grid%smois(i,:,j)
  1484. iicount = iicount + 1
  1485. grid%smois(i,:,j) = 0.005
  1486. END IF
  1487. END DO
  1488. END DO
  1489. IF ( iicount .GT. 0 ) THEN
  1490. print *,'RUC -> Noah: total number of small soil moisture locations = ',iicount
  1491. END IF
  1492. END IF
  1493. CASE ( RUCLSMSCHEME )
  1494. iicount = 0
  1495. IF ( flag_soil_layers == 1 ) THEN
  1496. DO j = jts, MIN(jde-1,jte)
  1497. DO i = its, MIN(ide-1,ite)
  1498. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  1499. grid%smois(i,:,j) = MAX ( grid%smois(i,:,j) , 0.005 )
  1500. ! grid%smois(i,:,j) = MAX ( grid%smois(i,:,j) - lqmi(grid%isltyp(i,j)) , 0.005 )
  1501. END DO
  1502. END DO
  1503. ELSE IF ( flag_soil_levels == 1 ) THEN
  1504. ! no op
  1505. END IF
  1506. CASE ( PXLSMSCHEME )
  1507. iicount = 0
  1508. IF ( flag_soil_layers == 1 ) THEN
  1509. ! no op
  1510. ELSE IF ( flag_soil_levels == 1 ) THEN
  1511. DO j = jts, MIN(jde-1,jte)
  1512. DO i = its, MIN(ide-1,ite)
  1513. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  1514. grid%smois(i,:,j) = MAX ( grid%smois(i,:,j) , 0.005 )
  1515. ! grid%smois(i,:,j) = MAX ( grid%smois(i,:,j) + lqmi(grid%isltyp(i,j)) , 0.005 )
  1516. END DO
  1517. END DO
  1518. END IF
  1519. END SELECT account_for_zero_soil_moisture
  1520. END IF
  1521. ! Is the grid%tslb reasonable?
  1522. IF ( internal_time_loop .NE. 1 ) THEN
  1523. DO j = jts, MIN(jde-1,jte)
  1524. DO ns = 1 , model_config_rec%num_soil_layers
  1525. DO i = its, MIN(ide-1,ite)
  1526. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  1527. IF ( grid%tslb(i,ns,j) .LT. 170 .or. grid%tslb(i,ns,j) .GT. 400. ) THEN
  1528. grid%tslb(i,ns,j) = grid%t_2(i,1,j)
  1529. grid%smois(i,ns,j) = 0.3
  1530. END IF
  1531. END DO
  1532. END DO
  1533. END DO
  1534. ELSE
  1535. DO j = jts, MIN(jde-1,jte)
  1536. DO i = its, MIN(ide-1,ite)
  1537. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  1538. IF ( ( ( grid%tslb(i,1,j) .LT. 170. ) .OR. ( grid%tslb(i,1,j) .GT. 400. ) ) .AND. &
  1539. ( grid%landmask(i,j) .GT. 0.5 ) ) THEN
  1540. IF ( ( model_config_rec%sf_surface_physics(grid%id) .NE. LSMSCHEME ) .AND. &
  1541. ( model_config_rec%sf_surface_physics(grid%id) .NE. NOAHMPSCHEME ) .AND. &
  1542. ( model_config_rec%sf_surface_physics(grid%id) .NE. RUCLSMSCHEME ).AND. &
  1543. ( model_config_rec%sf_surface_physics(grid%id) .NE. SSIBSCHEME ).AND. & !fds
  1544. ( model_config_rec%sf_surface_physics(grid%id) .NE. PXLSMSCHEME ) ) THEN
  1545. print *,'error in the grid%tslb'
  1546. print *,'i,j=',i,j
  1547. print *,'grid%landmask=',grid%landmask(i,j)
  1548. print *,'grid%tsk, grid%sst, grid%tmn=',grid%tsk(i,j),grid%sst(i,j),grid%tmn(i,j)
  1549. print *,'grid%tslb = ',grid%tslb(i,:,j)
  1550. print *,'old grid%smois = ',grid%smois(i,:,j)
  1551. grid%smois(i,1,j) = 0.3
  1552. grid%smois(i,2,j) = 0.3
  1553. grid%smois(i,3,j) = 0.3
  1554. grid%smois(i,4,j) = 0.3
  1555. END IF
  1556. IF ( (grid%tsk(i,j).GT.170. .AND. grid%tsk(i,j).LT.400.) .AND. &
  1557. (grid%tmn(i,j).GT.170. .AND. grid%tmn(i,j).LT.400.) ) THEN
  1558. fake_soil_temp : SELECT CASE ( model_config_rec%sf_surface_physics(grid%id) )
  1559. CASE ( SLABSCHEME )
  1560. DO ns = 1 , model_config_rec%num_soil_layers
  1561. grid%tslb(i,ns,j) = ( grid%tsk(i,j)*(3.0 - grid%zs(ns)) + &
  1562. grid%tmn(i,j)*(0.0 - grid%zs(ns)) ) /(3.0 - 0.0)
  1563. END DO
  1564. CASE ( LSMSCHEME , NOAHMPSCHEME , RUCLSMSCHEME, PXLSMSCHEME, SSIBSCHEME )
  1565. ! CALL wrf_error_fatal ( 'Assigned constant soil moisture to 0.3, stopping')
  1566. DO ns = 1 , model_config_rec%num_soil_layers
  1567. grid%tslb(i,ns,j) = ( grid%tsk(i,j)*(3.0 - grid%zs(ns)) + &
  1568. grid%tmn(i,j)*(0.0 - grid%zs(ns)) ) /(3.0 - 0.0)
  1569. END DO
  1570. END SELECT fake_soil_temp
  1571. else if(grid%tsk(i,j).gt.170. .and. grid%tsk(i,j).lt.400.)then
  1572. CALL wrf_error_fatal ( 'grid%tslb unreasonable 1' )
  1573. DO ns = 1 , model_config_rec%num_soil_layers
  1574. grid%tslb(i,ns,j)=grid%tsk(i,j)
  1575. END DO
  1576. else if(grid%sst(i,j).gt.170. .and. grid%sst(i,j).lt.400.)then
  1577. CALL wrf_error_fatal ( 'grid%tslb unreasonable 2' )
  1578. DO ns = 1 , model_config_rec%num_soil_layers
  1579. grid%tslb(i,ns,j)=grid%sst(i,j)
  1580. END DO
  1581. else if(grid%tmn(i,j).gt.170. .and. grid%tmn(i,j).lt.400.)then
  1582. CALL wrf_error_fatal ( 'grid%tslb unreasonable 3' )
  1583. DO ns = 1 , model_config_rec%num_soil_layers
  1584. grid%tslb(i,ns,j)=grid%tmn(i,j)
  1585. END DO
  1586. else
  1587. CALL wrf_error_fatal ( 'grid%tslb unreasonable 4' )
  1588. endif
  1589. END IF
  1590. END DO
  1591. END DO
  1592. END IF
  1593. ! Adjustments for the seaice field AFTER the grid%tslb computations. This is
  1594. ! is for the Noah LSM scheme.
  1595. num_veg_cat = SIZE ( grid%landusef , DIM=2 )
  1596. num_soil_top_cat = SIZE ( grid%soilctop , DIM=2 )
  1597. num_soil_bot_cat = SIZE ( grid%soilcbot , DIM=2 )
  1598. CALL nl_get_seaice_threshold ( grid%id , grid%seaice_threshold )
  1599. CALL nl_get_isice ( grid%id , grid%isice )
  1600. CALL nl_get_iswater ( grid%id , grid%iswater )
  1601. CALL adjust_for_seaice_post ( grid%xice , grid%landmask , grid%tsk , grid%tsk_save , &
  1602. grid%ivgtyp , grid%vegcat , grid%lu_index , &
  1603. grid%xland , grid%landusef , grid%isltyp , grid%soilcat , &
  1604. grid%soilctop , &
  1605. grid%soilcbot , grid%tmn , grid%vegfra , &
  1606. grid%tslb , grid%smois , grid%sh2o , &
  1607. grid%seaice_threshold , &
  1608. grid%sst,flag_sst, &
  1609. config_flags%fractional_seaice, &
  1610. num_veg_cat , num_soil_top_cat , num_soil_bot_cat , &
  1611. model_config_rec%num_soil_layers , &
  1612. grid%iswater , grid%isice , &
  1613. model_config_rec%sf_surface_physics(grid%id) , &
  1614. ids , ide , jds , jde , kds , kde , &
  1615. ims , ime , jms , jme , kms , kme , &
  1616. its , ite , jts , jte , kts , kte )
  1617. ! Let us make sure (again) that the grid%landmask and the veg/soil categories match.
  1618. oops1=0
  1619. oops2=0
  1620. DO j = jts, MIN(jde-1,jte)
  1621. DO i = its, MIN(ide-1,ite)
  1622. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  1623. IF ( ( ( grid%landmask(i,j) .LT. 0.5 ) .AND. &
  1624. ( grid%ivgtyp(i,j) .NE. config_flags%iswater .OR. grid%isltyp(i,j) .NE. 14 ) ) .OR. &
  1625. ( ( grid%landmask(i,j) .GT. 0.5 ) .AND. &
  1626. ( grid%ivgtyp(i,j) .EQ. config_flags%iswater .OR. grid%isltyp(i,j) .EQ. 14 ) ) ) THEN
  1627. IF ( grid%tslb(i,1,j) .GT. 1. ) THEN
  1628. oops1=oops1+1
  1629. grid%ivgtyp(i,j) = 5
  1630. grid%isltyp(i,j) = 8
  1631. grid%landmask(i,j) = 1
  1632. grid%xland(i,j) = 1
  1633. ELSE IF ( grid%sst(i,j) .GT. 1. ) THEN
  1634. oops2=oops2+1
  1635. grid%ivgtyp(i,j) = config_flags%iswater
  1636. grid%isltyp(i,j) = 14
  1637. grid%landmask(i,j) = 0
  1638. grid%xland(i,j) = 2
  1639. ELSE
  1640. print *,'the grid%landmask and soil/veg cats do not match'
  1641. print *,'i,j=',i,j
  1642. print *,'grid%landmask=',grid%landmask(i,j)
  1643. print *,'grid%ivgtyp=',grid%ivgtyp(i,j)
  1644. print *,'grid%isltyp=',grid%isltyp(i,j)
  1645. print *,'iswater=', config_flags%iswater
  1646. print *,'grid%tslb=',grid%tslb(i,:,j)
  1647. print *,'grid%sst=',grid%sst(i,j)
  1648. CALL wrf_error_fatal ( 'mismatch_landmask_ivgtyp' )
  1649. END IF
  1650. END IF
  1651. END DO
  1652. END DO
  1653. if (oops1.gt.0) then
  1654. print *,'points artificially set to land : ',oops1
  1655. endif
  1656. if(oops2.gt.0) then
  1657. print *,'points artificially set to water: ',oops2
  1658. endif
  1659. ! fill grid%sst array with grid%tsk if missing in real input (needed for time-varying grid%sst in wrf)
  1660. DO j = jts, MIN(jde-1,jte)
  1661. DO i = its, MIN(ide-1,ite)
  1662. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  1663. IF ( flag_sst .NE. 1 ) THEN
  1664. grid%sst(i,j) = grid%tsk(i,j)
  1665. ENDIF
  1666. END DO
  1667. END DO
  1668. !tgs set snoalb to land value if the water point is covered with ice
  1669. DO j = jts, MIN(jde-1,jte)
  1670. DO i = its, MIN(ide-1,ite)
  1671. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  1672. IF ( grid%ivgtyp(i,j) .EQ. config_flags%isice) THEN
  1673. grid%snoalb(i,j) = 0.75
  1674. ENDIF
  1675. END DO
  1676. END DO
  1677. ! From the full level data, we can get the half levels, reciprocals, and layer
  1678. ! thicknesses. These are all defined at half level locations, so one less level.
  1679. ! We allow the vertical coordinate to *accidently* come in upside down. We want
  1680. ! the first full level to be the ground surface.
  1681. ! Check whether grid%znw (full level) data are truly full levels. If not, we need to adjust them
  1682. ! to be full levels.
  1683. ! in this test, we check if grid%znw(1) is neither 0 nor 1 (within a tolerance of 10**-5)
  1684. were_bad = .false.
  1685. IF ( ( (grid%znw(1).LT.(1-1.E-5) ) .OR. ( grid%znw(1).GT.(1+1.E-5) ) ).AND. &
  1686. ( (grid%znw(1).LT.(0-1.E-5) ) .OR. ( grid%znw(1).GT.(0+1.E-5) ) ) ) THEN
  1687. were_bad = .true.
  1688. print *,'Your grid%znw input values are probably half-levels. '
  1689. print *,grid%znw
  1690. print *,'WRF expects grid%znw values to be full levels. '
  1691. print *,'Adjusting now to full levels...'
  1692. ! We want to ignore the first value if it's negative
  1693. IF (grid%znw(1).LT.0) THEN
  1694. grid%znw(1)=0
  1695. END IF
  1696. DO k=2,kde
  1697. grid%znw(k)=2*grid%znw(k)-grid%znw(k-1)
  1698. END DO
  1699. END IF
  1700. ! Let's check our changes
  1701. IF ( ( ( grid%znw(1) .LT. (1-1.E-5) ) .OR. ( grid%znw(1) .GT. (1+1.E-5) ) ).AND. &
  1702. ( ( grid%znw(1) .LT. (0-1.E-5) ) .OR. ( grid%znw(1) .GT. (0+1.E-5) ) ) ) THEN
  1703. print *,'The input grid%znw height values were half-levels or erroneous. '
  1704. print *,'Attempts to treat the values as half-levels and change them '
  1705. print *,'to valid full levels failed.'
  1706. CALL wrf_error_fatal("bad grid%znw values from input files")
  1707. ELSE IF ( were_bad ) THEN
  1708. print *,'...adjusted. grid%znw array now contains full eta level values. '
  1709. ENDIF
  1710. IF ( grid%znw(1) .LT. grid%znw(kde) ) THEN
  1711. DO k=1, kde/2
  1712. hold_znw = grid%znw(k)
  1713. grid%znw(k)=grid%znw(kde+1-k)
  1714. grid%znw(kde+1-k)=hold_znw
  1715. END DO
  1716. END IF
  1717. DO k=1, kde-1
  1718. grid%dnw(k) = grid%znw(k+1) - grid%znw(k)
  1719. grid%rdnw(k) = 1./grid%dnw(k)
  1720. grid%znu(k) = 0.5*(grid%znw(k+1)+grid%znw(k))
  1721. END DO
  1722. ! Now the same sort of computations with the half eta levels, even ANOTHER
  1723. ! level less than the one above.
  1724. DO k=2, kde-1
  1725. grid%dn(k) = 0.5*(grid%dnw(k)+grid%dnw(k-1))
  1726. grid%rdn(k) = 1./grid%dn(k)
  1727. grid%fnp(k) = .5* grid%dnw(k )/grid%dn(k)
  1728. grid%fnm(k) = .5* grid%dnw(k-1)/grid%dn(k)
  1729. END DO
  1730. ! Scads of vertical coefficients.
  1731. cof1 = (2.*grid%dn(2)+grid%dn(3))/(grid%dn(2)+grid%dn(3))*grid%dnw(1)/grid%dn(2)
  1732. cof2 = grid%dn(2) /(grid%dn(2)+grid%dn(3))*grid%dnw(1)/grid%dn(3)
  1733. grid%cf1 = grid%fnp(2) + cof1
  1734. grid%cf2 = grid%fnm(2) - cof1 - cof2
  1735. grid%cf3 = cof2
  1736. grid%cfn = (.5*grid%dnw(kde-1)+grid%dn(kde-1))/grid%dn(kde-1)
  1737. grid%cfn1 = -.5*grid%dnw(kde-1)/grid%dn(kde-1)
  1738. ! Inverse grid distances.
  1739. grid%rdx = 1./config_flags%dx
  1740. grid%rdy = 1./config_flags%dy
  1741. ! Some of the many weird geopotential initializations that we'll see today: grid%ph0 is total,
  1742. ! and grid%ph_2 is a perturbation from the base state geopotential. We set the base geopotential
  1743. ! at the lowest level to terrain elevation * gravity.
  1744. DO j=jts,jte
  1745. DO i=its,ite
  1746. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  1747. grid%ph0(i,1,j) = grid%ht(i,j) * g
  1748. grid%ph_2(i,1,j) = 0.
  1749. END DO
  1750. END DO
  1751. ! Base state potential temperature and inverse density (alpha = 1/rho) from
  1752. ! the half eta levels and the base-profile surface pressure. Compute 1/rho
  1753. ! from equation of state. The potential temperature is a perturbation from t0.
  1754. DO j = jts, MIN(jte,jde-1)
  1755. DO i = its, MIN(ite,ide-1)
  1756. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  1757. ! Base state pressure is a function of eta level and terrain, only, plus
  1758. ! the hand full of constants: p00 (sea level pressure, Pa), t00 (sea level
  1759. ! temperature, K), and A (temperature difference, from 1000 mb to 300 mb, K).
  1760. p_surf = p00 * EXP ( -t00/a + ( (t00/a)**2 - 2.*g*grid%ht(i,j)/a/r_d ) **0.5 )
  1761. DO k = 1, kte-1
  1762. grid%php(i,k,j) = grid%znw(k)*(p_surf - grid%p_top) + grid%p_top ! temporary, full lev base pressure
  1763. grid%pb(i,k,j) = grid%znu(k)*(p_surf - grid%p_top) + grid%p_top
  1764. temp = MAX ( tiso, t00 + A*LOG(grid%pb(i,k,j)/p00) )
  1765. ! temp = t00 + A*LOG(grid%pb(i,k,j)/p00)
  1766. grid%t_init(i,k,j) = temp*(p00/grid%pb(i,k,j))**(r_d/cp) - t0
  1767. grid%alb(i,k,j) = (r_d/p1000mb)*(grid%t_init(i,k,j)+t0)*(grid%pb(i,k,j)/p1000mb)**cvpm
  1768. END DO
  1769. ! Base state mu is defined as base state surface pressure minus grid%p_top
  1770. grid%mub(i,j) = p_surf - grid%p_top
  1771. ! Dry surface pressure is defined as the following (this mu is from the input file
  1772. ! computed from the dry pressure). Here the dry pressure is just reconstituted.
  1773. pd_surf = grid%mu0(i,j) + grid%p_top
  1774. ! Integrate base geopotential, starting at terrain elevation. This assures that
  1775. ! the base state is in exact hydrostatic balance with respect to the model equations.
  1776. ! This field is on full levels.
  1777. grid%phb(i,1,j) = grid%ht(i,j) * g
  1778. IF (grid%hypsometric_opt == 1) THEN
  1779. DO k = 2,kte
  1780. grid%phb(i,k,j) = grid%phb(i,k-1,j) - grid%dnw(k-1)*grid%mub(i,j)*grid%alb(i,k-1,j)
  1781. END DO
  1782. ELSE IF (grid%hypsometric_opt == 2) THEN
  1783. DO k = 2,kte
  1784. pfu = grid%mub(i,j)*grid%znw(k) + grid%p_top
  1785. pfd = grid%mub(i,j)*grid%znw(k-1) + grid%p_top
  1786. phm = grid%mub(i,j)*grid%znu(k-1) + grid%p_top
  1787. grid%phb(i,k,j) = grid%phb(i,k-1,j) + grid%alb(i,k-1,j)*phm*LOG(pfd/pfu)
  1788. END DO
  1789. ELSE
  1790. CALL wrf_error_fatal( 'initialize_real: hypsometric_opt should be 1 or 2' )
  1791. END IF
  1792. END DO
  1793. END DO
  1794. ! Fill in the outer rows and columns to allow us to be sloppy.
  1795. IF ( ite .EQ. ide ) THEN
  1796. i = ide
  1797. DO j = jts, MIN(jde-1,jte)
  1798. grid%mub(i,j) = grid%mub(i-1,j)
  1799. grid%mu_2(i,j) = grid%mu_2(i-1,j)
  1800. DO k = 1, kte-1
  1801. grid%pb(i,k,j) = grid%pb(i-1,k,j)
  1802. grid%t_init(i,k,j) = grid%t_init(i-1,k,j)
  1803. grid%alb(i,k,j) = grid%alb(i-1,k,j)
  1804. END DO
  1805. DO k = 1, kte
  1806. grid%phb(i,k,j) = grid%phb(i-1,k,j)
  1807. END DO
  1808. END DO
  1809. END IF
  1810. IF ( jte .EQ. jde ) THEN
  1811. j = jde
  1812. DO i = its, ite
  1813. grid%mub(i,j) = grid%mub(i,j-1)
  1814. grid%mu_2(i,j) = grid%mu_2(i,j-1)
  1815. DO k = 1, kte-1
  1816. grid%pb(i,k,j) = grid%pb(i,k,j-1)
  1817. grid%t_init(i,k,j) = grid%t_init(i,k,j-1)
  1818. grid%alb(i,k,j) = grid%alb(i,k,j-1)
  1819. END DO
  1820. DO k = 1, kte
  1821. grid%phb(i,k,j) = grid%phb(i,k,j-1)
  1822. END DO
  1823. END DO
  1824. END IF
  1825. ! Compute the perturbation dry pressure (grid%mub + grid%mu_2 + ptop = dry grid%psfc).
  1826. DO j = jts, min(jde-1,jte)
  1827. DO i = its, min(ide-1,ite)
  1828. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  1829. grid%mu_2(i,j) = grid%mu0(i,j) - grid%mub(i,j)
  1830. END DO
  1831. END DO
  1832. ! Fill in the outer rows and columns to allow us to be sloppy.
  1833. IF ( ite .EQ. ide ) THEN
  1834. i = ide
  1835. DO j = jts, MIN(jde-1,jte)
  1836. grid%mu_2(i,j) = grid%mu_2(i-1,j)
  1837. END DO
  1838. END IF
  1839. IF ( jte .EQ. jde ) THEN
  1840. j = jde
  1841. DO i = its, ite
  1842. grid%mu_2(i,j) = grid%mu_2(i,j-1)
  1843. END DO
  1844. END IF
  1845. lev500 = 0
  1846. DO j = jts, min(jde-1,jte)
  1847. DO i = its, min(ide-1,ite)
  1848. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  1849. ! Assign the potential temperature (perturbation from t0) and qv on all the mass
  1850. ! point locations.
  1851. DO k = 1 , kde-1
  1852. grid%t_2(i,k,j) = grid%t_2(i,k,j) - t0
  1853. END DO
  1854. dpmu = 10001.
  1855. loop_count = 0
  1856. DO WHILE ( ( ABS(dpmu) .GT. 10. ) .AND. &
  1857. ( loop_count .LT. 5 ) )
  1858. loop_count = loop_count + 1
  1859. ! Integrate the hydrostatic equation (from the RHS of the bigstep vertical momentum
  1860. ! equation) down from the top to get the pressure perturbation. First get the pressure
  1861. ! perturbation, moisture, and inverse density (total and perturbation) at the top-most level.
  1862. k = kte-1
  1863. qvf1 = 0.5*(moist(i,k,j,P_QV)+moist(i,k,j,P_QV))
  1864. qvf2 = 1./(1.+qvf1)
  1865. qvf1 = qvf1*qvf2
  1866. grid%p(i,k,j) = - 0.5*(grid%mu_2(i,j)+qvf1*grid%mub(i,j))/grid%rdnw(k)/qvf2
  1867. qvf = 1. + rvovrd*moist(i,k,j,P_QV)
  1868. grid%alt(i,k,j) = (r_d/p1000mb)*(grid%t_2(i,k,j)+t0)*qvf&
  1869. *(((grid%p(i,k,j)+grid%pb(i,k,j))/p1000mb)**cvpm)
  1870. grid%al(i,k,j) = grid%alt(i,k,j) - grid%alb(i,k,j)
  1871. grid%p_hyd(i,k,j) = grid%p(i,k,j) + grid%pb(i,k,j)
  1872. ! Now, integrate down the column to compute the pressure perturbation, and diagnose the two
  1873. ! inverse density fields (total and perturbation).
  1874. DO k=kte-2,1,-1
  1875. qvf1 = 0.5*(moist(i,k,j,P_QV)+moist(i,k+1,j,P_QV))
  1876. qvf2 = 1./(1.+qvf1)
  1877. qvf1 = qvf1*qvf2
  1878. grid%p(i,k,j) = grid%p(i,k+1,j) - (grid%mu_2(i,j) + qvf1*grid%mub(i,j))/qvf2/grid%rdn(k+1)
  1879. qvf = 1. + rvovrd*moist(i,k,j,P_QV)
  1880. grid%alt(i,k,j) = (r_d/p1000mb)*(grid%t_2(i,k,j)+t0)*qvf* &
  1881. (((grid%p(i,k,j)+grid%pb(i,k,j))/p1000mb)**cvpm)
  1882. grid%al(i,k,j) = grid%alt(i,k,j) - grid%alb(i,k,j)
  1883. grid%p_hyd(i,k,j) = grid%p(i,k,j) + grid%pb(i,k,j)
  1884. END DO
  1885. #if 1
  1886. ! This is the hydrostatic equation used in the model after the small timesteps. In
  1887. ! the model, grid%al (inverse density) is computed from the geopotential.
  1888. IF (grid%hypsometric_opt == 1) THEN
  1889. DO k = 2,kte
  1890. grid%ph_2(i,k,j) = grid%ph_2(i,k-1,j) - &
  1891. grid%dnw(k-1) * ( (grid%mub(i,j)+grid%mu_2(i,j))*grid%al(i,k-1,j) &
  1892. + grid%mu_2(i,j)*grid%alb(i,k-1,j) )
  1893. grid%ph0(i,k,j) = grid%ph_2(i,k,j) + grid%phb(i,k,j)
  1894. END DO
  1895. ELSE IF (grid%hypsometric_opt == 2) THEN
  1896. ! Alternative hydrostatic eq.: dZ = -al*p*dLOG(p), where p is dry pressure.
  1897. ! Note that al*p approximates Rd*T and dLOG(p) does z.
  1898. ! Here T varies mostly linear with z, the first-order integration produces better result.
  1899. grid%ph_2(i,1,j) = grid%phb(i,1,j)
  1900. DO k = 2,kte
  1901. pfu = grid%mu0(i,j)*grid%znw(k) + grid%p_top
  1902. pfd = grid%mu0(i,j)*grid%znw(k-1) + grid%p_top
  1903. phm = grid%mu0(i,j)*grid%znu(k-1) + grid%p_top
  1904. grid%ph_2(i,k,j) = grid%ph_2(i,k-1,j) + grid%alt(i,k-1,j)*phm*LOG(pfd/pfu)
  1905. END DO
  1906. DO k = 1,kte
  1907. grid%ph_2(i,k,j) = grid%ph_2(i,k,j) - grid%phb(i,k,j)
  1908. END DO
  1909. END IF
  1910. #else
  1911. ! Get the perturbation geopotential from the 3d height array from WPS.
  1912. DO k = 2,kte
  1913. grid%ph_2(i,k,j) = grid%ph0(i,k,j)*g - grid%phb(i,k,j)
  1914. END DO
  1915. #endif
  1916. ! Adjust the column pressure so that the computed 500 mb height is close to the
  1917. ! input value (of course, not when we are doing hybrid input).
  1918. IF ( ( flag_metgrid .EQ. 1 ) .AND. ( i .EQ. i_valid ) .AND. ( j .EQ. j_valid ) ) THEN
  1919. DO k = 1 , num_metgrid_levels
  1920. IF ( ABS ( grid%p_gc(i,k,j) - 50000. ) .LT. 1. ) THEN
  1921. lev500 = k
  1922. EXIT
  1923. END IF
  1924. END DO
  1925. END IF
  1926. ! We only do the adjustment of height if we have the input data on pressure
  1927. ! surfaces, and folks have asked to do this option.
  1928. IF ( ( flag_metgrid .EQ. 1 ) .AND. &
  1929. ( flag_ptheta .EQ. 0 ) .AND. &
  1930. ( config_flags%adjust_heights ) .AND. &
  1931. ( lev500 .NE. 0 ) ) THEN
  1932. DO k = 2 , kte-1
  1933. ! Get the pressures on the full eta levels (grid%php is defined above as
  1934. ! the full-lev base pressure, an easy array to use for 3d space).
  1935. pl = grid%php(i,k ,j) + &
  1936. ( grid%p(i,k-1 ,j) * ( grid%znw(k ) - grid%znu(k ) ) + &
  1937. grid%p(i,k ,j) * ( grid%znu(k-1 ) - grid%znw(k ) ) ) / &
  1938. ( grid%znu(k-1 ) - grid%znu(k ) )
  1939. pu = grid%php(i,k+1,j) + &
  1940. ( grid%p(i,k-1+1,j) * ( grid%znw(k +1) - grid%znu(k+1) ) + &
  1941. grid%p(i,k +1,j) * ( grid%znu(k-1+1) - grid%znw(k+1) ) ) / &
  1942. ( grid%znu(k-1+1) - grid%znu(k+1) )
  1943. ! If these pressure levels trap 500 mb, use them to interpolate
  1944. ! to the 500 mb level of the computed height.
  1945. IF ( ( pl .GE. 50000. ) .AND. ( pu .LT. 50000. ) ) THEN
  1946. zl = ( grid%ph_2(i,k ,j) + grid%phb(i,k ,j) ) / g
  1947. zu = ( grid%ph_2(i,k+1,j) + grid%phb(i,k+1,j) ) / g
  1948. z500 = ( zl * ( LOG(50000.) - LOG(pu ) ) + &
  1949. zu * ( LOG(pl ) - LOG(50000.) ) ) / &
  1950. ( LOG(pl) - LOG(pu) )
  1951. ! z500 = ( zl * ( (50000.) - (pu ) ) + &
  1952. ! zu * ( (pl ) - (50000.) ) ) / &
  1953. ! ( (pl) - (pu) )
  1954. ! Compute the difference of the 500 mb heights (computed minus input), and
  1955. ! then the change in grid%mu_2. The grid%php is still full-levels, base pressure.
  1956. dz500 = z500 - grid%ght_gc(i,lev500,j)
  1957. tvsfc = ((grid%t_2(i,1,j)+t0)*((grid%p(i,1,j)+grid%php(i,1,j))/p1000mb)**(r_d/cp)) * &
  1958. (1.+0.6*moist(i,1,j,P_QV))
  1959. dpmu = ( grid%php(i,1,j) + grid%p(i,1,j) ) * EXP ( g * dz500 / ( r_d * tvsfc ) )
  1960. dpmu = dpmu - ( grid%php(i,1,j) + grid%p(i,1,j) )
  1961. grid%mu_2(i,j) = grid%mu_2(i,j) - dpmu
  1962. EXIT
  1963. END IF
  1964. END DO
  1965. ELSE
  1966. dpmu = 0.
  1967. END IF
  1968. END DO
  1969. END DO
  1970. END DO
  1971. ! If this is data from the SI, then we probably do not have the original
  1972. ! surface data laying around. Note that these are all the lowest levels
  1973. ! of the respective 3d arrays. For surface pressure, we assume that the
  1974. ! vertical gradient of grid%p prime is zilch. This is not all that important.
  1975. ! These are filled in so that the various plotting routines have something
  1976. ! to play with at the initial time for the model.
  1977. IF ( flag_metgrid .NE. 1 ) THEN
  1978. DO j = jts, min(jde-1,jte)
  1979. DO i = its, min(ide,ite)
  1980. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  1981. grid%u10(i,j)=grid%u_2(i,1,j)
  1982. END DO
  1983. END DO
  1984. DO j = jts, min(jde,jte)
  1985. DO i = its, min(ide-1,ite)
  1986. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  1987. grid%v10(i,j)=grid%v_2(i,1,j)
  1988. END DO
  1989. END DO
  1990. DO j = jts, min(jde-1,jte)
  1991. DO i = its, min(ide-1,ite)
  1992. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  1993. p_surf = p00 * EXP ( -t00/a + ( (t00/a)**2 - 2.*g*grid%ht(i,j)/a/r_d ) **0.5 )
  1994. grid%psfc(i,j)=p_surf + grid%p(i,1,j)
  1995. grid%q2(i,j)=moist(i,1,j,P_QV)
  1996. grid%th2(i,j)=grid%t_2(i,1,j)+300.
  1997. grid%t2(i,j)=grid%th2(i,j)*(((grid%p(i,1,j)+grid%pb(i,1,j))/p00)**(r_d/cp))
  1998. END DO
  1999. END DO
  2000. ! If this data is from WPS, then we have previously assigned the surface
  2001. ! data for u, v, and t. If we have an input qv, welp, we assigned that one,
  2002. ! too. Now we pick up the left overs, and if RH came in - we assign the
  2003. ! mixing ratio.
  2004. ELSE IF ( flag_metgrid .EQ. 1 ) THEN
  2005. DO j = jts, min(jde-1,jte)
  2006. DO i = its, min(ide-1,ite)
  2007. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  2008. ! p_surf = p00 * EXP ( -t00/a + ( (t00/a)**2 - 2.*g*grid%ht(i,j)/a/r_d ) **0.5 )
  2009. ! grid%psfc(i,j)=p_surf + grid%p(i,1,j)
  2010. grid%th2(i,j)=grid%t2(i,j)*(p00/(grid%p(i,1,j)+grid%pb(i,1,j)))**(r_d/cp)
  2011. END DO
  2012. END DO
  2013. IF ( flag_qv .NE. 1 ) THEN
  2014. DO j = jts, min(jde-1,jte)
  2015. DO i = its, min(ide-1,ite)
  2016. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  2017. ! grid%q2(i,j)=moist(i,1,j,P_QV)
  2018. grid%q2(i,j)=grid%qv_gc(i,1,j)
  2019. END DO
  2020. END DO
  2021. END IF
  2022. END IF
  2023. CALL cpu_time(t_end)
  2024. ! Set flag to denote that we are saving original values of HT, MUB, and
  2025. ! PHB for 2-way nesting and cycling.
  2026. grid%save_topo_from_real=1
  2027. ips = its ; ipe = ite ; jps = jts ; jpe = jte ; kps = kts ; kpe = kte
  2028. #ifdef DM_PARALLEL
  2029. # include "HALO_EM_INIT_1.inc"
  2030. # include "HALO_EM_INIT_2.inc"
  2031. # include "HALO_EM_INIT_3.inc"
  2032. # include "HALO_EM_INIT_4.inc"
  2033. # include "HALO_EM_INIT_5.inc"
  2034. #endif
  2035. RETURN
  2036. END SUBROUTINE init_domain_rk
  2037. !---------------------------------------------------------------------
  2038. SUBROUTINE const_module_initialize ( p00 , t00 , a , tiso )
  2039. USE module_configure
  2040. IMPLICIT NONE
  2041. ! For the real-data-cases only.
  2042. REAL , INTENT(OUT) :: p00 , t00 , a , tiso
  2043. CALL nl_get_base_pres ( 1 , p00 )
  2044. CALL nl_get_base_temp ( 1 , t00 )
  2045. CALL nl_get_base_lapse ( 1 , a )
  2046. CALL nl_get_iso_temp ( 1 , tiso )
  2047. END SUBROUTINE const_module_initialize
  2048. !-------------------------------------------------------------------
  2049. SUBROUTINE rebalance_driver ( grid )
  2050. IMPLICIT NONE
  2051. TYPE (domain) :: grid
  2052. CALL rebalance( grid &
  2053. !
  2054. #include "actual_new_args.inc"
  2055. !
  2056. )
  2057. END SUBROUTINE rebalance_driver
  2058. !---------------------------------------------------------------------
  2059. SUBROUTINE rebalance ( grid &
  2060. !
  2061. #include "dummy_new_args.inc"
  2062. !
  2063. )
  2064. IMPLICIT NONE
  2065. TYPE (domain) :: grid
  2066. #include "dummy_new_decl.inc"
  2067. TYPE (grid_config_rec_type) :: config_flags
  2068. REAL :: p_surf , pd_surf, p_surf_int , pb_int , ht_hold
  2069. REAL :: qvf , qvf1 , qvf2
  2070. REAL :: p00 , t00 , a , tiso
  2071. REAL , DIMENSION(:,:,:) , ALLOCATABLE :: t_init_int
  2072. ! Local domain indices and counters.
  2073. INTEGER :: num_veg_cat , num_soil_top_cat , num_soil_bot_cat
  2074. INTEGER :: &
  2075. ids, ide, jds, jde, kds, kde, &
  2076. ims, ime, jms, jme, kms, kme, &
  2077. its, ite, jts, jte, kts, kte, &
  2078. ips, ipe, jps, jpe, kps, kpe, &
  2079. i, j, k
  2080. REAL :: temp, temp_int
  2081. REAL :: pfu, pfd, phm
  2082. REAL :: w1, w2, z0, z1, z2
  2083. SELECT CASE ( model_data_order )
  2084. CASE ( DATA_ORDER_ZXY )
  2085. kds = grid%sd31 ; kde = grid%ed31 ;
  2086. ids = grid%sd32 ; ide = grid%ed32 ;
  2087. jds = grid%sd33 ; jde = grid%ed33 ;
  2088. kms = grid%sm31 ; kme = grid%em31 ;
  2089. ims = grid%sm32 ; ime = grid%em32 ;
  2090. jms = grid%sm33 ; jme = grid%em33 ;
  2091. kts = grid%sp31 ; kte = grid%ep31 ; ! note that tile is entire patch
  2092. its = grid%sp32 ; ite = grid%ep32 ; ! note that tile is entire patch
  2093. jts = grid%sp33 ; jte = grid%ep33 ; ! note that tile is entire patch
  2094. CASE ( DATA_ORDER_XYZ )
  2095. ids = grid%sd31 ; ide = grid%ed31 ;
  2096. jds = grid%sd32 ; jde = grid%ed32 ;
  2097. kds = grid%sd33 ; kde = grid%ed33 ;
  2098. ims = grid%sm31 ; ime = grid%em31 ;
  2099. jms = grid%sm32 ; jme = grid%em32 ;
  2100. kms = grid%sm33 ; kme = grid%em33 ;
  2101. its = grid%sp31 ; ite = grid%ep31 ; ! note that tile is entire patch
  2102. jts = grid%sp32 ; jte = grid%ep32 ; ! note that tile is entire patch
  2103. kts = grid%sp33 ; kte = grid%ep33 ; ! note that tile is entire patch
  2104. CASE ( DATA_ORDER_XZY )
  2105. ids = grid%sd31 ; ide = grid%ed31 ;
  2106. kds = grid%sd32 ; kde = grid%ed32 ;
  2107. jds = grid%sd33 ; jde = grid%ed33 ;
  2108. ims = grid%sm31 ; ime = grid%em31 ;
  2109. kms = grid%sm32 ; kme = grid%em32 ;
  2110. jms = grid%sm33 ; jme = grid%em33 ;
  2111. its = grid%sp31 ; ite = grid%ep31 ; ! note that tile is entire patch
  2112. kts = grid%sp32 ; kte = grid%ep32 ; ! note that tile is entire patch
  2113. jts = grid%sp33 ; jte = grid%ep33 ; ! note that tile is entire patch
  2114. END SELECT
  2115. ALLOCATE ( t_init_int(ims:ime,kms:kme,jms:jme) )
  2116. ! Fill config_flags the options for a particular domain
  2117. CALL model_to_grid_config_rec ( grid%id , model_config_rec , config_flags )
  2118. ! Some of the many weird geopotential initializations that we'll see today: grid%ph0 is total,
  2119. ! and grid%ph_2 is a perturbation from the base state geopotential. We set the base geopotential
  2120. ! at the lowest level to terrain elevation * gravity.
  2121. DO j=jts,jte
  2122. DO i=its,ite
  2123. grid%ph0(i,1,j) = grid%ht_fine(i,j) * g
  2124. grid%ph_2(i,1,j) = 0.
  2125. END DO
  2126. END DO
  2127. ! To define the base state, we call a USER MODIFIED routine to set the three
  2128. ! necessary constants: p00 (sea level pressure, Pa), t00 (sea level temperature, K),
  2129. ! and A (temperature difference, from 1000 mb to 300 mb, K), and constant stratosphere
  2130. ! temp (tiso, K) either from input file or from namelist (for backward compatibiliy).
  2131. IF ( config_flags%use_baseparam_fr_nml ) then
  2132. ! get these from namelist
  2133. CALL wrf_message('ndown: using namelist constants')
  2134. CALL const_module_initialize ( p00 , t00 , a , tiso )
  2135. ELSE
  2136. ! get these constants from model data
  2137. CALL wrf_message('ndown: using constants from file')
  2138. t00 = grid%t00
  2139. p00 = grid%p00
  2140. a = grid%tlp
  2141. tiso = grid%tiso
  2142. IF (t00 .LT. 100. .or. p00 .LT. 10000.) THEN
  2143. WRITE(wrf_err_message,*)&
  2144. 'ndown_em: did not find base state parameters in wrfout. Add use_baseparam_fr_nml = .t. in &dynamics and rerun'
  2145. CALL wrf_error_fatal(TRIM(wrf_err_message))
  2146. ENDIF
  2147. ENDIF
  2148. ! Base state potential temperature and inverse density (alpha = 1/rho) from
  2149. ! the half eta levels and the base-profile surface pressure. Compute 1/rho
  2150. ! from equation of state. The potential temperature is a perturbation from t0.
  2151. DO j = jts, MIN(jte,jde-1)
  2152. DO i = its, MIN(ite,ide-1)
  2153. ! Base state pressure is a function of eta level and terrain, only, plus
  2154. ! the hand full of constants: p00 (sea level pressure, Pa), t00 (sea level
  2155. ! temperature, K), and A (temperature difference, from 1000 mb to 300 mb, K).
  2156. ! The fine grid terrain is ht_fine, the interpolated is grid%ht.
  2157. p_surf = p00 * EXP ( -t00/a + ( (t00/a)**2 - 2.*g*grid%ht_fine(i,j)/a/r_d ) **0.5 )
  2158. p_surf_int = p00 * EXP ( -t00/a + ( (t00/a)**2 - 2.*g*grid%ht(i,j) /a/r_d ) **0.5 )
  2159. DO k = 1, kte-1
  2160. grid%pb(i,k,j) = grid%znu(k)*(p_surf - grid%p_top) + grid%p_top
  2161. pb_int = grid%znu(k)*(p_surf_int - grid%p_top) + grid%p_top
  2162. temp = MAX ( tiso, t00 + A*LOG(grid%pb(i,k,j)/p00) )
  2163. ! temp = t00 + A*LOG(pb/p00)
  2164. grid%t_init(i,k,j) = temp*(p00/grid%pb(i,k,j))**(r_d/cp) - t0
  2165. ! grid%t_init(i,k,j) = (t00 + A*LOG(grid%pb(i,k,j)/p00))*(p00/grid%pb(i,k,j))**(r_d/cp) - t0
  2166. temp_int = MAX ( tiso, t00 + A*LOG(pb_int /p00) )
  2167. t_init_int(i,k,j)= temp_int*(p00/pb_int )**(r_d/cp) - t0
  2168. ! t_init_int(i,k,j)= (t00 + A*LOG(pb_int /p00))*(p00/pb_int )**(r_d/cp) - t0
  2169. grid%alb(i,k,j) = (r_d/p1000mb)*(grid%t_init(i,k,j)+t0)*(grid%pb(i,k,j)/p1000mb)**cvpm
  2170. END DO
  2171. ! Base state mu is defined as base state surface pressure minus grid%p_top
  2172. grid%mub(i,j) = p_surf - grid%p_top
  2173. ! Dry surface pressure is defined as the following (this mu is from the input file
  2174. ! computed from the dry pressure). Here the dry pressure is just reconstituted.
  2175. pd_surf = ( grid%mub(i,j) + grid%mu_2(i,j) ) + grid%p_top
  2176. ! Integrate base geopotential, starting at terrain elevation. This assures that
  2177. ! the base state is in exact hydrostatic balance with respect to the model equations.
  2178. ! This field is on full levels.
  2179. grid%phb(i,1,j) = grid%ht_fine(i,j) * g
  2180. IF (grid%hypsometric_opt == 1) THEN
  2181. DO k = 2,kte
  2182. grid%phb(i,k,j) = grid%phb(i,k-1,j) - grid%dnw(k-1)*grid%mub(i,j)*grid%alb(i,k-1,j)
  2183. END DO
  2184. ELSE IF (grid%hypsometric_opt == 2) THEN
  2185. DO k = 2,kte
  2186. pfu = grid%mub(i,j)*grid%znw(k) + grid%p_top
  2187. pfd = grid%mub(i,j)*grid%znw(k-1) + grid%p_top
  2188. phm = grid%mub(i,j)*grid%znu(k-1) + grid%p_top
  2189. grid%phb(i,k,j) = grid%phb(i,k-1,j) + grid%alb(i,k-1,j)*phm*LOG(pfd/pfu)
  2190. END DO
  2191. ELSE
  2192. CALL wrf_error_fatal( 'initialize_real: hypsometric_opt should be 1 or 2' )
  2193. END IF
  2194. END DO
  2195. END DO
  2196. ! Replace interpolated terrain with fine grid values.
  2197. DO j = jts, MIN(jte,jde-1)
  2198. DO i = its, MIN(ite,ide-1)
  2199. grid%ht(i,j) = grid%ht_fine(i,j)
  2200. END DO
  2201. END DO
  2202. ! Perturbation fields.
  2203. DO j = jts, min(jde-1,jte)
  2204. DO i = its, min(ide-1,ite)
  2205. ! The potential temperature is THETAnest = THETAinterp + ( TBARnest - TBARinterp)
  2206. DO k = 1 , kde-1
  2207. grid%t_2(i,k,j) = grid%t_2(i,k,j) + ( grid%t_init(i,k,j) - t_init_int(i,k,j) )
  2208. END DO
  2209. ! Integrate the hydrostatic equation (from the RHS of the bigstep vertical momentum
  2210. ! equation) down from the top to get the pressure perturbation. First get the pressure
  2211. ! perturbation, moisture, and inverse density (total and perturbation) at the top-most level.
  2212. k = kte-1
  2213. qvf1 = 0.5*(moist(i,k,j,P_QV)+moist(i,k,j,P_QV))
  2214. qvf2 = 1./(1.+qvf1)
  2215. qvf1 = qvf1*qvf2
  2216. grid%p(i,k,j) = - 0.5*(grid%mu_2(i,j)+qvf1*grid%mub(i,j))/grid%rdnw(k)/qvf2
  2217. qvf = 1. + rvovrd*moist(i,k,j,P_QV)
  2218. grid%alt(i,k,j) = (r_d/p1000mb)*(grid%t_2(i,k,j)+t0)*qvf* &
  2219. (((grid%p(i,k,j)+grid%pb(i,k,j))/p1000mb)**cvpm)
  2220. grid%al(i,k,j) = grid%alt(i,k,j) - grid%alb(i,k,j)
  2221. ! Now, integrate down the column to compute the pressure perturbation, and diagnose the two
  2222. ! inverse density fields (total and perturbation).
  2223. DO k=kte-2,1,-1
  2224. qvf1 = 0.5*(moist(i,k,j,P_QV)+moist(i,k+1,j,P_QV))
  2225. qvf2 = 1./(1.+qvf1)
  2226. qvf1 = qvf1*qvf2
  2227. grid%p(i,k,j) = grid%p(i,k+1,j) - (grid%mu_2(i,j) + qvf1*grid%mub(i,j))/qvf2/grid%rdn(k+1)
  2228. qvf = 1. + rvovrd*moist(i,k,j,P_QV)
  2229. grid%alt(i,k,j) = (r_d/p1000mb)*(grid%t_2(i,k,j)+t0)*qvf* &
  2230. (((grid%p(i,k,j)+grid%pb(i,k,j))/p1000mb)**cvpm)
  2231. grid%al(i,k,j) = grid%alt(i,k,j) - grid%alb(i,k,j)
  2232. END DO
  2233. ! This is the hydrostatic equation used in the model after the small timesteps. In
  2234. ! the model, grid%al (inverse density) is computed from the geopotential.
  2235. IF (grid%hypsometric_opt == 1) THEN
  2236. DO k = 2,kte
  2237. grid%ph_2(i,k,j) = grid%ph_2(i,k-1,j) - &
  2238. grid%dnw(k-1) * ( (grid%mub(i,j)+grid%mu_2(i,j))*grid%al(i,k-1,j) &
  2239. + grid%mu_2(i,j)*grid%alb(i,k-1,j) )
  2240. grid%ph0(i,k,j) = grid%ph_2(i,k,j) + grid%phb(i,k,j)
  2241. END DO
  2242. ELSE IF (grid%hypsometric_opt == 2) THEN
  2243. ! Alternative hydrostatic eq.: dZ = -al*p*dLOG(p), where p is dry pressure.
  2244. ! Note that al*p approximates Rd*T and dLOG(p) does z.
  2245. ! Here T varies mostly linear with z, the first-order integration produces better result.
  2246. grid%ph_2(i,1,j) = grid%phb(i,1,j)
  2247. DO k = 2,kte
  2248. pfu = grid%mu0(i,j)*grid%znw(k) + grid%p_top
  2249. pfd = grid%mu0(i,j)*grid%znw(k-1) + grid%p_top
  2250. phm = grid%mu0(i,j)*grid%znu(k-1) + grid%p_top
  2251. grid%ph_2(i,k,j) = grid%ph_2(i,k-1,j) + grid%alt(i,k-1,j)*phm*LOG(pfd/pfu)
  2252. END DO
  2253. DO k = 1,kte
  2254. grid%ph_2(i,k,j) = grid%ph_2(i,k,j) - grid%phb(i,k,j)
  2255. END DO
  2256. END IF
  2257. ! update psfc in fine grid
  2258. z0 = grid%ph0(i,1,j)/g
  2259. z1 = 0.5*(grid%ph0(i,1,j)+grid%ph0(i,2,j))/g
  2260. z2 = 0.5*(grid%ph0(i,2,j)+grid%ph0(i,3,j))/g
  2261. w1 = (z0 - z2)/(z1 - z2)
  2262. w2 = 1. - w1
  2263. grid%psfc(i,j) = w1*(grid%p(i,1,j)+grid%pb(i,1,j))+w2*(grid%p(i,2,j)+grid%pb(i,2,j))
  2264. END DO
  2265. END DO
  2266. DEALLOCATE ( t_init_int )
  2267. ips = its ; ipe = ite ; jps = jts ; jpe = jte ; kps = kts ; kpe = kte
  2268. #ifdef DM_PARALLEL
  2269. # include "HALO_EM_INIT_1.inc"
  2270. # include "HALO_EM_INIT_2.inc"
  2271. # include "HALO_EM_INIT_3.inc"
  2272. # include "HALO_EM_INIT_4.inc"
  2273. # include "HALO_EM_INIT_5.inc"
  2274. #endif
  2275. END SUBROUTINE rebalance
  2276. !---------------------------------------------------------------------
  2277. RECURSIVE SUBROUTINE find_my_parent ( grid_ptr_in , grid_ptr_out , id_i_am , id_wanted , found_the_id )
  2278. ! RAR - Modified to correct problem in which the parent of a child domain could
  2279. ! not be found in the namelist. This condition typically occurs while using the
  2280. ! "allow_grid" namelist option when an inactive domain comes before an active
  2281. ! domain in the list, i.e., the domain number of the active domain is greater than
  2282. ! that of an inactive domain at the same level.
  2283. !
  2284. USE module_domain
  2285. TYPE(domain) , POINTER :: grid_ptr_in , grid_ptr_out
  2286. TYPE(domain) , POINTER :: grid_ptr_sibling
  2287. INTEGER :: id_wanted , id_i_am
  2288. INTEGER :: nest ! RAR
  2289. LOGICAL :: found_the_id
  2290. found_the_id = .FALSE.
  2291. grid_ptr_sibling => grid_ptr_in
  2292. nest = 0 ! RAR
  2293. DO WHILE ( ASSOCIATED ( grid_ptr_sibling ) )
  2294. IF ( grid_ptr_sibling%grid_id .EQ. id_wanted ) THEN
  2295. found_the_id = .TRUE.
  2296. grid_ptr_out => grid_ptr_sibling
  2297. RETURN
  2298. ! RAR ELSE IF ( grid_ptr_sibling%num_nests .GT. 0 ) THEN
  2299. ELSE IF ( grid_ptr_sibling%num_nests .GT. 0 .AND. nest .LT. grid_ptr_sibling%num_nests ) THEN
  2300. nest = nest + 1 ! RAR
  2301. grid_ptr_sibling => grid_ptr_sibling%nests(nest)%ptr ! RAR
  2302. CALL find_my_parent ( grid_ptr_sibling , grid_ptr_out , id_i_am , id_wanted , found_the_id )
  2303. IF (.NOT. found_the_id) grid_ptr_sibling => grid_ptr_sibling%parents(1)%ptr ! RAR
  2304. ELSE
  2305. grid_ptr_sibling => grid_ptr_sibling%sibling
  2306. END IF
  2307. END DO
  2308. END SUBROUTINE find_my_parent
  2309. !---------------------------------------------------------------------
  2310. RECURSIVE SUBROUTINE find_my_parent2 ( grid_ptr_in , grid_ptr_out , id_wanted , found_the_id )
  2311. USE module_domain
  2312. TYPE(domain) , POINTER :: grid_ptr_in
  2313. TYPE(domain) , POINTER :: grid_ptr_out
  2314. INTEGER , INTENT(IN ) :: id_wanted
  2315. LOGICAL , INTENT(OUT) :: found_the_id
  2316. ! Local
  2317. TYPE(domain) , POINTER :: grid_ptr_holder
  2318. INTEGER :: kid
  2319. ! Initializations
  2320. found_the_id = .FALSE.
  2321. grid_ptr_holder => grid_ptr_in
  2322. ! Have we found the correct location? If so, we can just pop back up with
  2323. ! the pointer to the right location (i.e. the parent), thank you very much.
  2324. IF ( id_wanted .EQ. grid_ptr_in%grid_id ) THEN
  2325. found_the_id = .TRUE.
  2326. grid_ptr_out => grid_ptr_in
  2327. ! We gotta keep looking.
  2328. ELSE
  2329. ! We drill down and process each nest from this domain. We don't have to
  2330. ! worry about siblings, as we are running over all of the kids for this parent,
  2331. ! so it amounts to the same set of domains being tested.
  2332. loop_over_all_kids : DO kid = 1 , grid_ptr_in%num_nests
  2333. IF ( ASSOCIATED ( grid_ptr_in%nests(kid)%ptr ) ) THEN
  2334. CALL find_my_parent2 ( grid_ptr_in%nests(kid)%ptr , grid_ptr_out , id_wanted , found_the_id )
  2335. IF ( found_the_id ) THEN
  2336. EXIT loop_over_all_kids
  2337. END IF
  2338. END IF
  2339. END DO loop_over_all_kids
  2340. END IF
  2341. END SUBROUTINE find_my_parent2
  2342. #endif
  2343. !---------------------------------------------------------------------
  2344. #ifdef VERT_UNIT
  2345. !This is a main program for a small unit test for the vertical interpolation.
  2346. program vint
  2347. implicit none
  2348. integer , parameter :: ij = 3
  2349. integer , parameter :: keta = 30
  2350. integer , parameter :: kgen =20
  2351. integer :: ids , ide , jds , jde , kds , kde , &
  2352. ims , ime , jms , jme , kms , kme , &
  2353. its , ite , jts , jte , kts , kte
  2354. integer :: generic
  2355. real , dimension(1:ij,kgen,1:ij) :: fo , po
  2356. real , dimension(1:ij,1:keta,1:ij) :: fn_calc , fn_interp , pn
  2357. integer, parameter :: interp_type = 1 ! 2
  2358. ! integer, parameter :: lagrange_order = 2 ! 1
  2359. integer :: lagrange_order
  2360. logical, parameter :: lowest_lev_from_sfc = .FALSE. ! .TRUE.
  2361. logical, parameter :: use_levels_below_ground = .FALSE. ! .TRUE.
  2362. logical, parameter :: use_surface = .FALSE. ! .TRUE.
  2363. real , parameter :: zap_close_levels = 500. ! 100.
  2364. integer, parameter :: force_sfc_in_vinterp = 0 ! 6
  2365. integer :: k
  2366. ids = 1 ; ide = ij ; jds = 1 ; jde = ij ; kds = 1 ; kde = keta
  2367. ims = 1 ; ime = ij ; jms = 1 ; jme = ij ; kms = 1 ; kme = keta
  2368. its = 1 ; ite = ij ; jts = 1 ; jte = ij ; kts = 1 ; kte = keta
  2369. generic = kgen
  2370. print *,' '
  2371. print *,'------------------------------------'
  2372. print *,'UNIT TEST FOR VERTICAL INTERPOLATION'
  2373. print *,'------------------------------------'
  2374. print *,' '
  2375. do lagrange_order = 1 , 2
  2376. print *,' '
  2377. print *,'------------------------------------'
  2378. print *,'Lagrange Order = ',lagrange_order
  2379. print *,'------------------------------------'
  2380. print *,' '
  2381. call fillitup ( fo , po , fn_calc , pn , &
  2382. ids , ide , jds , jde , kds , kde , &
  2383. ims , ime , jms , jme , kms , kme , &
  2384. its , ite , jts , jte , kts , kte , &
  2385. generic , lagrange_order )
  2386. print *,' '
  2387. print *,'Level Pressure Field'
  2388. print *,' (Pa) (generic)'
  2389. print *,'------------------------------------'
  2390. print *,' '
  2391. do k = 1 , generic
  2392. write (*,fmt='(i2,2x,f12.3,1x,g15.8)' ) &
  2393. k,po(2,k,2),fo(2,k,2)
  2394. end do
  2395. print *,' '
  2396. call vert_interp ( fo , po , fn_interp , pn , &
  2397. generic , 'T' , &
  2398. interp_type , lagrange_order , &
  2399. lowest_lev_from_sfc , use_levels_below_ground , use_surface , &
  2400. zap_close_levels , force_sfc_in_vinterp , &
  2401. ids , ide , jds , jde , kds , kde , &
  2402. ims , ime , jms , jme , kms , kme , &
  2403. its , ite , jts , jte , kts , kte )
  2404. print *,'Multi-Order Interpolator'
  2405. print *,'------------------------------------'
  2406. print *,' '
  2407. print *,'Level Pressure Field Field Field'
  2408. print *,' (Pa) Calc Interp Diff'
  2409. print *,'------------------------------------'
  2410. print *,' '
  2411. do k = kts , kte-1
  2412. write (*,fmt='(i2,2x,f12.3,1x,3(g15.7))' ) &
  2413. k,pn(2,k,2),fn_calc(2,k,2),fn_interp(2,k,2),fn_calc(2,k,2)-fn_interp(2,k,2)
  2414. end do
  2415. call vert_interp_old ( fo , po , fn_interp , pn , &
  2416. generic , 'T' , &
  2417. interp_type , lagrange_order , &
  2418. lowest_lev_from_sfc , use_levels_below_ground , use_surface , &
  2419. zap_close_levels , force_sfc_in_vinterp , &
  2420. ids , ide , jds , jde , kds , kde , &
  2421. ims , ime , jms , jme , kms , kme , &
  2422. its , ite , jts , jte , kts , kte )
  2423. print *,'Linear Interpolator'
  2424. print *,'------------------------------------'
  2425. print *,' '
  2426. print *,'Level Pressure Field Field Field'
  2427. print *,' (Pa) Calc Interp Diff'
  2428. print *,'------------------------------------'
  2429. print *,' '
  2430. do k = kts , kte-1
  2431. write (*,fmt='(i2,2x,f12.3,1x,3(g15.7))' ) &
  2432. k,pn(2,k,2),fn_calc(2,k,2),fn_interp(2,k,2),fn_calc(2,k,2)-fn_interp(2,k,2)
  2433. end do
  2434. end do
  2435. end program vint
  2436. subroutine wrf_error_fatal (string)
  2437. character (len=*) :: string
  2438. print *,string
  2439. stop
  2440. end subroutine wrf_error_fatal
  2441. subroutine fillitup ( fo , po , fn , pn , &
  2442. ids , ide , jds , jde , kds , kde , &
  2443. ims , ime , jms , jme , kms , kme , &
  2444. its , ite , jts , jte , kts , kte , &
  2445. generic , lagrange_order )
  2446. implicit none
  2447. integer , intent(in) :: ids , ide , jds , jde , kds , kde , &
  2448. ims , ime , jms , jme , kms , kme , &
  2449. its , ite , jts , jte , kts , kte
  2450. integer , intent(in) :: generic , lagrange_order
  2451. real , dimension(ims:ime,generic,jms:jme) , intent(out) :: fo , po
  2452. real , dimension(ims:ime,kms:kme,jms:jme) , intent(out) :: fn , pn
  2453. integer :: i , j , k
  2454. real , parameter :: piov2 = 3.14159265358 / 2.
  2455. k = 1
  2456. do j = jts , jte
  2457. do i = its , ite
  2458. po(i,k,j) = 102000.
  2459. end do
  2460. end do
  2461. do k = 2 , generic
  2462. do j = jts , jte
  2463. do i = its , ite
  2464. po(i,k,j) = ( 5000. * ( 1 - (k-1) ) + 100000. * ( (k-1) - (generic-1) ) ) / (1. - real(generic-1) )
  2465. end do
  2466. end do
  2467. end do
  2468. if ( lagrange_order .eq. 1 ) then
  2469. do k = 1 , generic
  2470. do j = jts , jte
  2471. do i = its , ite
  2472. fo(i,k,j) = po(i,k,j)
  2473. ! fo(i,k,j) = sin(po(i,k,j) * piov2 / 102000. )
  2474. end do
  2475. end do
  2476. end do
  2477. else if ( lagrange_order .eq. 2 ) then
  2478. do k = 1 , generic
  2479. do j = jts , jte
  2480. do i = its , ite
  2481. fo(i,k,j) = (((po(i,k,j)-5000.)/102000.)*((102000.-po(i,k,j))/102000.))*102000.
  2482. ! fo(i,k,j) = sin(po(i,k,j) * piov2 / 102000. )
  2483. end do
  2484. end do
  2485. end do
  2486. end if
  2487. !!!!!!!!!!!!
  2488. do k = kts , kte
  2489. do j = jts , jte
  2490. do i = its , ite
  2491. pn(i,k,j) = ( 5000. * ( 0 - (k-1) ) + 102000. * ( (k-1) - (kte-1) ) ) / (-1. * real(kte-1) )
  2492. end do
  2493. end do
  2494. end do
  2495. do k = kts , kte-1
  2496. do j = jts , jte
  2497. do i = its , ite
  2498. pn(i,k,j) = ( pn(i,k,j) + pn(i,k+1,j) ) /2.
  2499. end do
  2500. end do
  2501. end do
  2502. if ( lagrange_order .eq. 1 ) then
  2503. do k = kts , kte-1
  2504. do j = jts , jte
  2505. do i = its , ite
  2506. fn(i,k,j) = pn(i,k,j)
  2507. ! fn(i,k,j) = sin(pn(i,k,j) * piov2 / 102000. )
  2508. end do
  2509. end do
  2510. end do
  2511. else if ( lagrange_order .eq. 2 ) then
  2512. do k = kts , kte-1
  2513. do j = jts , jte
  2514. do i = its , ite
  2515. fn(i,k,j) = (((pn(i,k,j)-5000.)/102000.)*((102000.-pn(i,k,j))/102000.))*102000.
  2516. ! fn(i,k,j) = sin(pn(i,k,j) * piov2 / 102000. )
  2517. end do
  2518. end do
  2519. end do
  2520. end if
  2521. end subroutine fillitup
  2522. #endif
  2523. !---------------------------------------------------------------------
  2524. SUBROUTINE vert_interp ( fo , po , fnew , pnu , &
  2525. generic , var_type , &
  2526. interp_type , lagrange_order , extrap_type , &
  2527. lowest_lev_from_sfc , use_levels_below_ground , use_surface , &
  2528. zap_close_levels , force_sfc_in_vinterp , &
  2529. ids , ide , jds , jde , kds , kde , &
  2530. ims , ime , jms , jme , kms , kme , &
  2531. its , ite , jts , jte , kts , kte )
  2532. ! Vertically interpolate the new field. The original field on the original
  2533. ! pressure levels is provided, and the new pressure surfaces to interpolate to.
  2534. IMPLICIT NONE
  2535. INTEGER , INTENT(IN) :: interp_type , lagrange_order , extrap_type
  2536. LOGICAL , INTENT(IN) :: lowest_lev_from_sfc , use_levels_below_ground , use_surface
  2537. REAL , INTENT(IN) :: zap_close_levels
  2538. INTEGER , INTENT(IN) :: force_sfc_in_vinterp
  2539. INTEGER , INTENT(IN) :: ids , ide , jds , jde , kds , kde , &
  2540. ims , ime , jms , jme , kms , kme , &
  2541. its , ite , jts , jte , kts , kte
  2542. INTEGER , INTENT(IN) :: generic
  2543. CHARACTER (LEN=1) :: var_type
  2544. REAL , DIMENSION(ims:ime,generic,jms:jme) , INTENT(IN) :: fo , po
  2545. REAL , DIMENSION(ims:ime,kms:kme,jms:jme) , INTENT(IN) :: pnu
  2546. REAL , DIMENSION(ims:ime,kms:kme,jms:jme) , INTENT(OUT) :: fnew
  2547. REAL , DIMENSION(ims:ime,generic,jms:jme) :: forig , porig
  2548. REAL , DIMENSION(ims:ime,kms:kme,jms:jme) :: pnew
  2549. ! Local vars
  2550. INTEGER :: i , j , k , ko , kn , k1 , k2 , ko_1 , ko_2 , knext
  2551. INTEGER :: istart , iend , jstart , jend , kstart , kend
  2552. INTEGER , DIMENSION(ims:ime,kms:kme ) :: k_above , k_below
  2553. INTEGER , DIMENSION(ims:ime ) :: ks
  2554. INTEGER , DIMENSION(ims:ime ) :: ko_above_sfc
  2555. INTEGER :: count , zap , zap_below , zap_above , kst , kcount
  2556. INTEGER :: kinterp_start , kinterp_end , sfc_level
  2557. LOGICAL :: any_below_ground
  2558. REAL :: p1 , p2 , pn, hold
  2559. REAL , DIMENSION(1:generic) :: ordered_porig , ordered_forig
  2560. REAL , DIMENSION(kts:kte) :: ordered_pnew , ordered_fnew
  2561. ! Excluded middle.
  2562. LOGICAL :: any_valid_points
  2563. INTEGER :: i_valid , j_valid
  2564. LOGICAL :: flip_data_required
  2565. ! Horiontal loop bounds for different variable types.
  2566. IF ( var_type .EQ. 'U' ) THEN
  2567. istart = its
  2568. iend = ite
  2569. jstart = jts
  2570. jend = MIN(jde-1,jte)
  2571. kstart = kts
  2572. kend = kte-1
  2573. DO j = jstart,jend
  2574. DO k = 1,generic
  2575. DO i = MAX(ids+1,its) , MIN(ide-1,ite)
  2576. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  2577. porig(i,k,j) = ( po(i,k,j) + po(i-1,k,j) ) * 0.5
  2578. END DO
  2579. END DO
  2580. IF ( ids .EQ. its ) THEN
  2581. DO k = 1,generic
  2582. porig(its,k,j) = po(its,k,j)
  2583. END DO
  2584. END IF
  2585. IF ( ide .EQ. ite ) THEN
  2586. DO k = 1,generic
  2587. porig(ite,k,j) = po(ite-1,k,j)
  2588. END DO
  2589. END IF
  2590. DO k = kstart,kend
  2591. DO i = MAX(ids+1,its) , MIN(ide-1,ite)
  2592. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  2593. pnew(i,k,j) = ( pnu(i,k,j) + pnu(i-1,k,j) ) * 0.5
  2594. END DO
  2595. END DO
  2596. IF ( ids .EQ. its ) THEN
  2597. DO k = kstart,kend
  2598. pnew(its,k,j) = pnu(its,k,j)
  2599. END DO
  2600. END IF
  2601. IF ( ide .EQ. ite ) THEN
  2602. DO k = kstart,kend
  2603. pnew(ite,k,j) = pnu(ite-1,k,j)
  2604. END DO
  2605. END IF
  2606. END DO
  2607. ELSE IF ( var_type .EQ. 'V' ) THEN
  2608. istart = its
  2609. iend = MIN(ide-1,ite)
  2610. jstart = jts
  2611. jend = jte
  2612. kstart = kts
  2613. kend = kte-1
  2614. DO i = istart,iend
  2615. DO k = 1,generic
  2616. DO j = MAX(jds+1,jts) , MIN(jde-1,jte)
  2617. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  2618. porig(i,k,j) = ( po(i,k,j) + po(i,k,j-1) ) * 0.5
  2619. END DO
  2620. END DO
  2621. IF ( jds .EQ. jts ) THEN
  2622. DO k = 1,generic
  2623. porig(i,k,jts) = po(i,k,jts)
  2624. END DO
  2625. END IF
  2626. IF ( jde .EQ. jte ) THEN
  2627. DO k = 1,generic
  2628. porig(i,k,jte) = po(i,k,jte-1)
  2629. END DO
  2630. END IF
  2631. DO k = kstart,kend
  2632. DO j = MAX(jds+1,jts) , MIN(jde-1,jte)
  2633. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  2634. pnew(i,k,j) = ( pnu(i,k,j) + pnu(i,k,j-1) ) * 0.5
  2635. END DO
  2636. END DO
  2637. IF ( jds .EQ. jts ) THEN
  2638. DO k = kstart,kend
  2639. pnew(i,k,jts) = pnu(i,k,jts)
  2640. END DO
  2641. END IF
  2642. IF ( jde .EQ. jte ) THEN
  2643. DO k = kstart,kend
  2644. pnew(i,k,jte) = pnu(i,k,jte-1)
  2645. END DO
  2646. END IF
  2647. END DO
  2648. ELSE IF ( ( var_type .EQ. 'W' ) .OR. ( var_type .EQ. 'Z' ) ) THEN
  2649. istart = its
  2650. iend = MIN(ide-1,ite)
  2651. jstart = jts
  2652. jend = MIN(jde-1,jte)
  2653. kstart = kts
  2654. kend = kte
  2655. DO j = jstart,jend
  2656. DO k = 1,generic
  2657. DO i = istart,iend
  2658. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  2659. porig(i,k,j) = po(i,k,j)
  2660. END DO
  2661. END DO
  2662. DO k = kstart,kend
  2663. DO i = istart,iend
  2664. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  2665. pnew(i,k,j) = pnu(i,k,j)
  2666. END DO
  2667. END DO
  2668. END DO
  2669. ELSE IF ( ( var_type .EQ. 'T' ) .OR. ( var_type .EQ. 'Q' ) ) THEN
  2670. istart = its
  2671. iend = MIN(ide-1,ite)
  2672. jstart = jts
  2673. jend = MIN(jde-1,jte)
  2674. kstart = kts
  2675. kend = kte-1
  2676. DO j = jstart,jend
  2677. DO k = 1,generic
  2678. DO i = istart,iend
  2679. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  2680. porig(i,k,j) = po(i,k,j)
  2681. END DO
  2682. END DO
  2683. DO k = kstart,kend
  2684. DO i = istart,iend
  2685. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  2686. pnew(i,k,j) = pnu(i,k,j)
  2687. END DO
  2688. END DO
  2689. END DO
  2690. ELSE
  2691. istart = its
  2692. iend = MIN(ide-1,ite)
  2693. jstart = jts
  2694. jend = MIN(jde-1,jte)
  2695. kstart = kts
  2696. kend = kte-1
  2697. DO j = jstart,jend
  2698. DO k = 1,generic
  2699. DO i = istart,iend
  2700. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  2701. porig(i,k,j) = po(i,k,j)
  2702. END DO
  2703. END DO
  2704. DO k = kstart,kend
  2705. DO i = istart,iend
  2706. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  2707. pnew(i,k,j) = pnu(i,k,j)
  2708. END DO
  2709. END DO
  2710. END DO
  2711. END IF
  2712. ! We need to find if there are any valid non-excluded-middle points in this
  2713. ! tile. If so, then we need to hang on to a valid i,j location.
  2714. any_valid_points = .false.
  2715. find_valid : DO j = jstart , jend
  2716. DO i = istart , iend
  2717. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  2718. any_valid_points = .true.
  2719. i_valid = i
  2720. j_valid = j
  2721. EXIT find_valid
  2722. END DO
  2723. END DO find_valid
  2724. IF ( .NOT. any_valid_points ) THEN
  2725. RETURN
  2726. END IF
  2727. IF ( porig(i_valid,2,j_valid) .LT. porig(i_valid,generic,j_valid) ) THEN
  2728. flip_data_required = .true.
  2729. ELSE
  2730. flip_data_required = .false.
  2731. END IF
  2732. DO j = jstart , jend
  2733. ! The lowest level is the surface. Levels 2 through "generic" are supposed to
  2734. ! be "bottom-up". Flip if they are not. This is based on the input pressure
  2735. ! array.
  2736. IF ( flip_data_required ) THEN
  2737. DO kn = 2 , ( generic + 1 ) / 2
  2738. DO i = istart , iend
  2739. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  2740. hold = porig(i,kn,j)
  2741. porig(i,kn,j) = porig(i,generic+2-kn,j)
  2742. porig(i,generic+2-kn,j) = hold
  2743. forig(i,kn,j) = fo (i,generic+2-kn,j)
  2744. forig(i,generic+2-kn,j) = fo (i,kn,j)
  2745. END DO
  2746. END DO
  2747. DO i = istart , iend
  2748. forig(i,1,j) = fo (i,1,j)
  2749. END DO
  2750. IF ( MOD(generic,2) .EQ. 0 ) THEN
  2751. k=generic/2 + 1
  2752. DO i = istart , iend
  2753. forig(i,k,j) = fo (i,k,j)
  2754. END DO
  2755. END IF
  2756. ELSE
  2757. DO kn = 1 , generic
  2758. DO i = istart , iend
  2759. forig(i,kn,j) = fo (i,kn,j)
  2760. END DO
  2761. END DO
  2762. END IF
  2763. ! Skip all of the levels below ground in the original data based upon the surface pressure.
  2764. ! The ko_above_sfc is the index in the pressure array that is above the surface. If there
  2765. ! are no levels underground, this is index = 2. The remaining levels are eligible for use
  2766. ! in the vertical interpolation.
  2767. DO i = istart , iend
  2768. ko_above_sfc(i) = -1
  2769. END DO
  2770. DO ko = kstart+1 , generic
  2771. DO i = istart , iend
  2772. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  2773. IF ( ko_above_sfc(i) .EQ. -1 ) THEN
  2774. IF ( porig(i,1,j) .GT. porig(i,ko,j) ) THEN
  2775. ko_above_sfc(i) = ko
  2776. END IF
  2777. END IF
  2778. END DO
  2779. END DO
  2780. ! Piece together columns of the original input data. Pass the vertical columns to
  2781. ! the iterpolator.
  2782. DO i = istart , iend
  2783. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  2784. ! If the surface value is in the middle of the array, three steps: 1) do the
  2785. ! values below the ground (this is just to catch the occasional value that is
  2786. ! inconsistently below the surface based on input data), 2) do the surface level, then
  2787. ! 3) add in the levels that are above the surface. For the levels next to the surface,
  2788. ! we check to remove any levels that are "too close". When building the column of input
  2789. ! pressures, we also attend to the request for forcing the surface analysis to be used
  2790. ! in a few lower eta-levels.
  2791. ! Fill in the column from up to the level just below the surface with the input
  2792. ! presssure and the input field (orig or old, which ever). For an isobaric input
  2793. ! file, this data is isobaric.
  2794. ! How many levels have we skipped in the input column.
  2795. zap = 0
  2796. zap_below = 0
  2797. zap_above = 0
  2798. IF ( ko_above_sfc(i) .GT. 2 ) THEN
  2799. count = 1
  2800. DO ko = 2 , ko_above_sfc(i)-1
  2801. ordered_porig(count) = porig(i,ko,j)
  2802. ordered_forig(count) = forig(i,ko,j)
  2803. count = count + 1
  2804. END DO
  2805. ! Make sure the pressure just below the surface is not "too close", this
  2806. ! will cause havoc with the higher order interpolators. In case of a "too close"
  2807. ! instance, we toss out the offending level (NOT the surface one) by simply
  2808. ! decrementing the accumulating loop counter.
  2809. IF ( ordered_porig(count-1) - porig(i,1,j) .LT. zap_close_levels ) THEN
  2810. count = count -1
  2811. zap = 1
  2812. zap_below = 1
  2813. END IF
  2814. ! Add in the surface values.
  2815. ordered_porig(count) = porig(i,1,j)
  2816. ordered_forig(count) = forig(i,1,j)
  2817. count = count + 1
  2818. ! A usual way to do the vertical interpolation is to pay more attention to the
  2819. ! surface data. Why? Well it has about 20x the density as the upper air, so we
  2820. ! hope the analysis is better there. We more strongly use this data by artificially
  2821. ! tossing out levels above the surface that are beneath a certain number of prescribed
  2822. ! eta levels at this (i,j). The "zap" value is how many levels of input we are
  2823. ! removing, which is used to tell the interpolator how many valid values are in
  2824. ! the column. The "count" value is the increment to the index of levels, and is
  2825. ! only used for assignments.
  2826. IF ( force_sfc_in_vinterp .GT. 0 ) THEN
  2827. ! Get the pressure at the eta level. We want to remove all input pressure levels
  2828. ! between the level above the surface to the pressure at this eta surface. That
  2829. ! forces the surface value to be used through the selected eta level. Keep track
  2830. ! of two things: the level to use above the eta levels, and how many levels we are
  2831. ! skipping.
  2832. knext = ko_above_sfc(i)
  2833. find_level : DO ko = ko_above_sfc(i) , generic
  2834. IF ( porig(i,ko,j) .LE. pnew(i,force_sfc_in_vinterp,j) ) THEN
  2835. knext = ko
  2836. exit find_level
  2837. ELSE
  2838. zap = zap + 1
  2839. zap_above = zap_above + 1
  2840. END IF
  2841. END DO find_level
  2842. ! No request for special interpolation, so we just assign the next level to use
  2843. ! above the surface as, ta da, the first level above the surface. I know, wow.
  2844. ELSE
  2845. knext = ko_above_sfc(i)
  2846. END IF
  2847. ! One more time, make sure the pressure just above the surface is not "too close", this
  2848. ! will cause havoc with the higher order interpolators. In case of a "too close"
  2849. ! instance, we toss out the offending level above the surface (NOT the surface one) by simply
  2850. ! incrementing the loop counter. Here, count-1 is the surface level and knext is either
  2851. ! the next level up OR it is the level above the prescribed number of eta surfaces.
  2852. IF ( ordered_porig(count-1) - porig(i,knext,j) .LT. zap_close_levels ) THEN
  2853. kst = knext+1
  2854. zap = zap + 1
  2855. zap_above = zap_above + 1
  2856. ELSE
  2857. kst = knext
  2858. END IF
  2859. DO ko = kst , generic
  2860. ordered_porig(count) = porig(i,ko,j)
  2861. ordered_forig(count) = forig(i,ko,j)
  2862. count = count + 1
  2863. END DO
  2864. ! This is easy, the surface is the lowest level, just stick them in, in this order. OK,
  2865. ! there are a couple of subtleties. We have to check for that special interpolation that
  2866. ! skips some input levels so that the surface is used for the lowest few eta levels. Also,
  2867. ! we must make sure that we still do not have levels that are "too close" together.
  2868. ELSE
  2869. ! Initialize no input levels have yet been removed from consideration.
  2870. zap = 0
  2871. ! The surface is the lowest level, so it gets set right away to location 1.
  2872. ordered_porig(1) = porig(i,1,j)
  2873. ordered_forig(1) = forig(i,1,j)
  2874. ! We start filling in the array at loc 2, as in just above the level we just stored.
  2875. count = 2
  2876. ! Are we forcing the interpolator to skip valid input levels so that the
  2877. ! surface data is used through more levels? Essentially as above.
  2878. IF ( force_sfc_in_vinterp .GT. 0 ) THEN
  2879. knext = 2
  2880. find_level2: DO ko = 2 , generic
  2881. IF ( porig(i,ko,j) .LE. pnew(i,force_sfc_in_vinterp,j) ) THEN
  2882. knext = ko
  2883. exit find_level2
  2884. ELSE
  2885. zap = zap + 1
  2886. zap_above = zap_above + 1
  2887. END IF
  2888. END DO find_level2
  2889. ELSE
  2890. knext = 2
  2891. END IF
  2892. ! Fill in the data above the surface. The "knext" index is either the one
  2893. ! just above the surface OR it is the index associated with the level that
  2894. ! is just above the pressure at this (i,j) of the top eta level that is to
  2895. ! be directly impacted with the surface level in interpolation.
  2896. DO ko = knext , generic
  2897. IF ( ( ordered_porig(count-1) - porig(i,ko,j) .LT. zap_close_levels ) .AND. &
  2898. ( ko .LT. generic ) ) THEN
  2899. zap = zap + 1
  2900. zap_above = zap_above + 1
  2901. CYCLE
  2902. END IF
  2903. ordered_porig(count) = porig(i,ko,j)
  2904. ordered_forig(count) = forig(i,ko,j)
  2905. count = count + 1
  2906. END DO
  2907. END IF
  2908. ! Now get the column of the "new" pressure data. So, this one is easy.
  2909. DO kn = kstart , kend
  2910. ordered_pnew(kn) = pnew(i,kn,j)
  2911. END DO
  2912. ! How many levels (count) are we shipping to the Lagrange interpolator.
  2913. IF ( ( use_levels_below_ground ) .AND. ( use_surface ) ) THEN
  2914. ! Use all levels, including the input surface, and including the pressure
  2915. ! levels below ground. We know to stop when we have reached the top of
  2916. ! the input pressure data.
  2917. count = 0
  2918. find_how_many_1 : DO ko = 1 , generic
  2919. IF ( porig(i,generic,j) .EQ. ordered_porig(ko) ) THEN
  2920. count = count + 1
  2921. EXIT find_how_many_1
  2922. ELSE
  2923. count = count + 1
  2924. END IF
  2925. END DO find_how_many_1
  2926. kinterp_start = 1
  2927. kinterp_end = kinterp_start + count - 1
  2928. ELSE IF ( ( use_levels_below_ground ) .AND. ( .NOT. use_surface ) ) THEN
  2929. ! Use all levels (excluding the input surface) and including the pressure
  2930. ! levels below ground. We know to stop when we have reached the top of
  2931. ! the input pressure data.
  2932. count = 0
  2933. find_sfc_2 : DO ko = 1 , generic
  2934. IF ( porig(i,1,j) .EQ. ordered_porig(ko) ) THEN
  2935. sfc_level = ko
  2936. EXIT find_sfc_2
  2937. END IF
  2938. END DO find_sfc_2
  2939. DO ko = sfc_level , generic-1
  2940. ordered_porig(ko) = ordered_porig(ko+1)
  2941. ordered_forig(ko) = ordered_forig(ko+1)
  2942. END DO
  2943. ordered_porig(generic) = 1.E-5
  2944. ordered_forig(generic) = 1.E10
  2945. count = 0
  2946. find_how_many_2 : DO ko = 1 , generic
  2947. IF ( porig(i,generic,j) .EQ. ordered_porig(ko) ) THEN
  2948. count = count + 1
  2949. EXIT find_how_many_2
  2950. ELSE
  2951. count = count + 1
  2952. END IF
  2953. END DO find_how_many_2
  2954. kinterp_start = 1
  2955. kinterp_end = kinterp_start + count - 1
  2956. ELSE IF ( ( .NOT. use_levels_below_ground ) .AND. ( use_surface ) ) THEN
  2957. ! Use all levels above the input surface pressure.
  2958. kcount = ko_above_sfc(i)-1-zap_below
  2959. count = 0
  2960. DO ko = 1 , generic
  2961. IF ( porig(i,ko,j) .EQ. ordered_porig(kcount) ) THEN
  2962. ! write (6,fmt='(f11.3,f11.3,g11.5)') porig(i,ko,j),ordered_porig(kcount),ordered_forig(kcount)
  2963. kcount = kcount + 1
  2964. count = count + 1
  2965. ELSE
  2966. ! write (6,fmt='(f11.3 )') porig(i,ko,j)
  2967. END IF
  2968. END DO
  2969. kinterp_start = ko_above_sfc(i)-1-zap_below
  2970. kinterp_end = kinterp_start + count - 1
  2971. END IF
  2972. ! The polynomials are either in pressure or LOG(pressure).
  2973. IF ( interp_type .EQ. 1 ) THEN
  2974. CALL lagrange_setup ( var_type , interp_type , &
  2975. ordered_porig(kinterp_start:kinterp_end) , &
  2976. ordered_forig(kinterp_start:kinterp_end) , &
  2977. count , lagrange_order , extrap_type , &
  2978. ordered_pnew(kstart:kend) , ordered_fnew , kend-kstart+1 ,i,j)
  2979. ELSE
  2980. CALL lagrange_setup ( var_type , interp_type , &
  2981. LOG(ordered_porig(kinterp_start:kinterp_end)) , &
  2982. ordered_forig(kinterp_start:kinterp_end) , &
  2983. count , lagrange_order , extrap_type , &
  2984. LOG(ordered_pnew(kstart:kend)) , ordered_fnew , kend-kstart+1 ,i,j)
  2985. END IF
  2986. ! Save the computed data.
  2987. DO kn = kstart , kend
  2988. fnew(i,kn,j) = ordered_fnew(kn)
  2989. END DO
  2990. ! There may have been a request to have the surface data from the input field
  2991. ! to be assigned as to the lowest eta level. This assumes thin layers (usually
  2992. ! the isobaric original field has the surface from 2-m T and RH, and 10-m U and V).
  2993. IF ( lowest_lev_from_sfc ) THEN
  2994. fnew(i,1,j) = forig(i,ko_above_sfc(i)-1,j)
  2995. END IF
  2996. END DO
  2997. END DO
  2998. END SUBROUTINE vert_interp
  2999. !---------------------------------------------------------------------
  3000. SUBROUTINE vert_interp_old ( forig , po , fnew , pnu , &
  3001. generic , var_type , &
  3002. interp_type , lagrange_order , extrap_type , &
  3003. lowest_lev_from_sfc , use_levels_below_ground , use_surface , &
  3004. zap_close_levels , force_sfc_in_vinterp , &
  3005. ids , ide , jds , jde , kds , kde , &
  3006. ims , ime , jms , jme , kms , kme , &
  3007. its , ite , jts , jte , kts , kte )
  3008. ! Vertically interpolate the new field. The original field on the original
  3009. ! pressure levels is provided, and the new pressure surfaces to interpolate to.
  3010. IMPLICIT NONE
  3011. INTEGER , INTENT(IN) :: interp_type , lagrange_order , extrap_type
  3012. LOGICAL , INTENT(IN) :: lowest_lev_from_sfc , use_levels_below_ground , use_surface
  3013. REAL , INTENT(IN) :: zap_close_levels
  3014. INTEGER , INTENT(IN) :: force_sfc_in_vinterp
  3015. INTEGER , INTENT(IN) :: ids , ide , jds , jde , kds , kde , &
  3016. ims , ime , jms , jme , kms , kme , &
  3017. its , ite , jts , jte , kts , kte
  3018. INTEGER , INTENT(IN) :: generic
  3019. CHARACTER (LEN=1) :: var_type
  3020. REAL , DIMENSION(ims:ime,generic,jms:jme) , INTENT(IN) :: forig , po
  3021. REAL , DIMENSION(ims:ime,kms:kme,jms:jme) , INTENT(IN) :: pnu
  3022. REAL , DIMENSION(ims:ime,kms:kme,jms:jme) , INTENT(OUT) :: fnew
  3023. REAL , DIMENSION(ims:ime,generic,jms:jme) :: porig
  3024. REAL , DIMENSION(ims:ime,kms:kme,jms:jme) :: pnew
  3025. ! Local vars
  3026. INTEGER :: i , j , k , ko , kn , k1 , k2 , ko_1 , ko_2
  3027. INTEGER :: istart , iend , jstart , jend , kstart , kend
  3028. INTEGER , DIMENSION(ims:ime,kms:kme ) :: k_above , k_below
  3029. INTEGER , DIMENSION(ims:ime ) :: ks
  3030. INTEGER , DIMENSION(ims:ime ) :: ko_above_sfc
  3031. LOGICAL :: any_below_ground
  3032. REAL :: p1 , p2 , pn
  3033. integer vert_extrap
  3034. vert_extrap = 0
  3035. ! Horiontal loop bounds for different variable types.
  3036. IF ( var_type .EQ. 'U' ) THEN
  3037. istart = its
  3038. iend = ite
  3039. jstart = jts
  3040. jend = MIN(jde-1,jte)
  3041. kstart = kts
  3042. kend = kte-1
  3043. DO j = jstart,jend
  3044. DO k = 1,generic
  3045. DO i = MAX(ids+1,its) , MIN(ide-1,ite)
  3046. porig(i,k,j) = ( po(i,k,j) + po(i-1,k,j) ) * 0.5
  3047. END DO
  3048. END DO
  3049. IF ( ids .EQ. its ) THEN
  3050. DO k = 1,generic
  3051. porig(its,k,j) = po(its,k,j)
  3052. END DO
  3053. END IF
  3054. IF ( ide .EQ. ite ) THEN
  3055. DO k = 1,generic
  3056. porig(ite,k,j) = po(ite-1,k,j)
  3057. END DO
  3058. END IF
  3059. DO k = kstart,kend
  3060. DO i = MAX(ids+1,its) , MIN(ide-1,ite)
  3061. pnew(i,k,j) = ( pnu(i,k,j) + pnu(i-1,k,j) ) * 0.5
  3062. END DO
  3063. END DO
  3064. IF ( ids .EQ. its ) THEN
  3065. DO k = kstart,kend
  3066. pnew(its,k,j) = pnu(its,k,j)
  3067. END DO
  3068. END IF
  3069. IF ( ide .EQ. ite ) THEN
  3070. DO k = kstart,kend
  3071. pnew(ite,k,j) = pnu(ite-1,k,j)
  3072. END DO
  3073. END IF
  3074. END DO
  3075. ELSE IF ( var_type .EQ. 'V' ) THEN
  3076. istart = its
  3077. iend = MIN(ide-1,ite)
  3078. jstart = jts
  3079. jend = jte
  3080. kstart = kts
  3081. kend = kte-1
  3082. DO i = istart,iend
  3083. DO k = 1,generic
  3084. DO j = MAX(jds+1,jts) , MIN(jde-1,jte)
  3085. porig(i,k,j) = ( po(i,k,j) + po(i,k,j-1) ) * 0.5
  3086. END DO
  3087. END DO
  3088. IF ( jds .EQ. jts ) THEN
  3089. DO k = 1,generic
  3090. porig(i,k,jts) = po(i,k,jts)
  3091. END DO
  3092. END IF
  3093. IF ( jde .EQ. jte ) THEN
  3094. DO k = 1,generic
  3095. porig(i,k,jte) = po(i,k,jte-1)
  3096. END DO
  3097. END IF
  3098. DO k = kstart,kend
  3099. DO j = MAX(jds+1,jts) , MIN(jde-1,jte)
  3100. pnew(i,k,j) = ( pnu(i,k,j) + pnu(i,k,j-1) ) * 0.5
  3101. END DO
  3102. END DO
  3103. IF ( jds .EQ. jts ) THEN
  3104. DO k = kstart,kend
  3105. pnew(i,k,jts) = pnu(i,k,jts)
  3106. END DO
  3107. END IF
  3108. IF ( jde .EQ. jte ) THEN
  3109. DO k = kstart,kend
  3110. pnew(i,k,jte) = pnu(i,k,jte-1)
  3111. END DO
  3112. END IF
  3113. END DO
  3114. ELSE IF ( ( var_type .EQ. 'W' ) .OR. ( var_type .EQ. 'Z' ) ) THEN
  3115. istart = its
  3116. iend = MIN(ide-1,ite)
  3117. jstart = jts
  3118. jend = MIN(jde-1,jte)
  3119. kstart = kts
  3120. kend = kte
  3121. DO j = jstart,jend
  3122. DO k = 1,generic
  3123. DO i = istart,iend
  3124. porig(i,k,j) = po(i,k,j)
  3125. END DO
  3126. END DO
  3127. DO k = kstart,kend
  3128. DO i = istart,iend
  3129. pnew(i,k,j) = pnu(i,k,j)
  3130. END DO
  3131. END DO
  3132. END DO
  3133. ELSE IF ( ( var_type .EQ. 'T' ) .OR. ( var_type .EQ. 'Q' ) ) THEN
  3134. istart = its
  3135. iend = MIN(ide-1,ite)
  3136. jstart = jts
  3137. jend = MIN(jde-1,jte)
  3138. kstart = kts
  3139. kend = kte-1
  3140. DO j = jstart,jend
  3141. DO k = 1,generic
  3142. DO i = istart,iend
  3143. porig(i,k,j) = po(i,k,j)
  3144. END DO
  3145. END DO
  3146. DO k = kstart,kend
  3147. DO i = istart,iend
  3148. pnew(i,k,j) = pnu(i,k,j)
  3149. END DO
  3150. END DO
  3151. END DO
  3152. ELSE
  3153. istart = its
  3154. iend = MIN(ide-1,ite)
  3155. jstart = jts
  3156. jend = MIN(jde-1,jte)
  3157. kstart = kts
  3158. kend = kte-1
  3159. DO j = jstart,jend
  3160. DO k = 1,generic
  3161. DO i = istart,iend
  3162. porig(i,k,j) = po(i,k,j)
  3163. END DO
  3164. END DO
  3165. DO k = kstart,kend
  3166. DO i = istart,iend
  3167. pnew(i,k,j) = pnu(i,k,j)
  3168. END DO
  3169. END DO
  3170. END DO
  3171. END IF
  3172. DO j = jstart , jend
  3173. ! Skip all of the levels below ground in the original data based upon the surface pressure.
  3174. ! The ko_above_sfc is the index in the pressure array that is above the surface. If there
  3175. ! are no levels underground, this is index = 2. The remaining levels are eligible for use
  3176. ! in the vertical interpolation.
  3177. DO i = istart , iend
  3178. ko_above_sfc(i) = -1
  3179. END DO
  3180. DO ko = kstart+1 , kend
  3181. DO i = istart , iend
  3182. IF ( ko_above_sfc(i) .EQ. -1 ) THEN
  3183. IF ( porig(i,1,j) .GT. porig(i,ko,j) ) THEN
  3184. ko_above_sfc(i) = ko
  3185. END IF
  3186. END IF
  3187. END DO
  3188. END DO
  3189. ! Initialize interpolation location. These are the levels in the original pressure
  3190. ! data that are physically below and above the targeted new pressure level.
  3191. DO kn = kts , kte
  3192. DO i = its , ite
  3193. k_above(i,kn) = -1
  3194. k_below(i,kn) = -2
  3195. END DO
  3196. END DO
  3197. ! Starting location is no lower than previous found location. This is for O(n logn)
  3198. ! and not O(n^2), where n is the number of vertical levels to search.
  3199. DO i = its , ite
  3200. ks(i) = 1
  3201. END DO
  3202. ! Find trapping layer for interpolation. The kn index runs through all of the "new"
  3203. ! levels of data.
  3204. DO kn = kstart , kend
  3205. DO i = istart , iend
  3206. ! For each "new" level (kn), we search to find the trapping levels in the "orig"
  3207. ! data. Most of the time, the "new" levels are the eta surfaces, and the "orig"
  3208. ! levels are the input pressure levels.
  3209. found_trap_above : DO ko = ks(i) , generic-1
  3210. ! Because we can have levels in the interpolation that are not valid,
  3211. ! let's toss out any candidate orig pressure values that are below ground
  3212. ! based on the surface pressure. If the level =1, then this IS the surface
  3213. ! level, so we HAVE to keep that one, but maybe not the ones above. If the
  3214. ! level (ks) is NOT=1, then we have to just CYCLE our loop to find a legit
  3215. ! below-pressure value. If we are not below ground, then we choose two
  3216. ! neighboring levels to test whether they surround the new pressure level.
  3217. ! The input trapping levels that we are trying is the surface and the first valid
  3218. ! level above the surface.
  3219. IF ( ( ko .LT. ko_above_sfc(i) ) .AND. ( ko .EQ. 1 ) ) THEN
  3220. ko_1 = ko
  3221. ko_2 = ko_above_sfc(i)
  3222. ! The "below" level is underground, cycle until we get to a valid pressure
  3223. ! above ground.
  3224. ELSE IF ( ( ko .LT. ko_above_sfc(i) ) .AND. ( ko .NE. 1 ) ) THEN
  3225. CYCLE found_trap_above
  3226. ! The "below" level is above the surface, so we are in the clear to test these
  3227. ! two levels out.
  3228. ELSE
  3229. ko_1 = ko
  3230. ko_2 = ko+1
  3231. END IF
  3232. ! The test of the candidate levels: "below" has to have a larger pressure, and
  3233. ! "above" has to have a smaller pressure.
  3234. ! OK, we found the correct two surrounding levels. The locations are saved for use in the
  3235. ! interpolation.
  3236. IF ( ( porig(i,ko_1,j) .GE. pnew(i,kn,j) ) .AND. &
  3237. ( porig(i,ko_2,j) .LT. pnew(i,kn,j) ) ) THEN
  3238. k_above(i,kn) = ko_2
  3239. k_below(i,kn) = ko_1
  3240. ks(i) = ko_1
  3241. EXIT found_trap_above
  3242. ! What do we do is we need to extrapolate the data underground? This happens when the
  3243. ! lowest pressure that we have is physically "above" the new target pressure. Our
  3244. ! actions depend on the type of variable we are interpolating.
  3245. ELSE IF ( porig(i,1,j) .LT. pnew(i,kn,j) ) THEN
  3246. ! For horizontal winds and moisture, we keep a constant value under ground.
  3247. IF ( ( var_type .EQ. 'U' ) .OR. &
  3248. ( var_type .EQ. 'V' ) .OR. &
  3249. ( var_type .EQ. 'Q' ) ) THEN
  3250. k_above(i,kn) = 1
  3251. ks(i) = 1
  3252. ! For temperature and height, we extrapolate the data. Hopefully, we are not
  3253. ! extrapolating too far. For pressure level input, the eta levels are always
  3254. ! contained within the surface to p_top levels, so no extrapolation is ever
  3255. ! required.
  3256. ELSE IF ( ( var_type .EQ. 'Z' ) .OR. &
  3257. ( var_type .EQ. 'T' ) ) THEN
  3258. k_above(i,kn) = ko_above_sfc(i)
  3259. k_below(i,kn) = 1
  3260. ks(i) = 1
  3261. ! Just a catch all right now.
  3262. ELSE
  3263. k_above(i,kn) = 1
  3264. ks(i) = 1
  3265. END IF
  3266. EXIT found_trap_above
  3267. ! The other extrapolation that might be required is when we are going above the
  3268. ! top level of the input data. Usually this means we chose a P_PTOP value that
  3269. ! was inappropriate, and we should stop and let someone fix this mess.
  3270. ELSE IF ( porig(i,generic,j) .GT. pnew(i,kn,j) ) THEN
  3271. print *,'data is too high, try a lower p_top'
  3272. print *,'pnew=',pnew(i,kn,j)
  3273. print *,'porig=',porig(i,:,j)
  3274. CALL wrf_error_fatal ('requested p_top is higher than input data, lower p_top')
  3275. END IF
  3276. END DO found_trap_above
  3277. END DO
  3278. END DO
  3279. ! Linear vertical interpolation.
  3280. DO kn = kstart , kend
  3281. DO i = istart , iend
  3282. IF ( k_above(i,kn) .EQ. 1 ) THEN
  3283. fnew(i,kn,j) = forig(i,1,j)
  3284. ELSE
  3285. k2 = MAX ( k_above(i,kn) , 2)
  3286. k1 = MAX ( k_below(i,kn) , 1)
  3287. IF ( k1 .EQ. k2 ) THEN
  3288. CALL wrf_error_fatal ( 'identical values in the interp, bad for divisions' )
  3289. END IF
  3290. IF ( interp_type .EQ. 1 ) THEN
  3291. p1 = porig(i,k1,j)
  3292. p2 = porig(i,k2,j)
  3293. pn = pnew(i,kn,j)
  3294. ELSE IF ( interp_type .EQ. 2 ) THEN
  3295. p1 = ALOG(porig(i,k1,j))
  3296. p2 = ALOG(porig(i,k2,j))
  3297. pn = ALOG(pnew(i,kn,j))
  3298. END IF
  3299. IF ( ( p1-pn) * (p2-pn) > 0. ) THEN
  3300. ! CALL wrf_error_fatal ( 'both trapping pressures are on the same side of the new pressure' )
  3301. ! CALL wrf_debug ( 0 , 'both trapping pressures are on the same side of the new pressure' )
  3302. vert_extrap = vert_extrap + 1
  3303. END IF
  3304. fnew(i,kn,j) = ( forig(i,k1,j) * ( p2 - pn ) + &
  3305. forig(i,k2,j) * ( pn - p1 ) ) / &
  3306. ( p2 - p1 )
  3307. END IF
  3308. END DO
  3309. END DO
  3310. search_below_ground : DO kn = kstart , kend
  3311. any_below_ground = .FALSE.
  3312. DO i = istart , iend
  3313. IF ( k_above(i,kn) .EQ. 1 ) THEN
  3314. fnew(i,kn,j) = forig(i,1,j)
  3315. any_below_ground = .TRUE.
  3316. END IF
  3317. END DO
  3318. IF ( .NOT. any_below_ground ) THEN
  3319. EXIT search_below_ground
  3320. END IF
  3321. END DO search_below_ground
  3322. ! There may have been a request to have the surface data from the input field
  3323. ! to be assigned as to the lowest eta level. This assumes thin layers (usually
  3324. ! the isobaric original field has the surface from 2-m T and RH, and 10-m U and V).
  3325. DO i = istart , iend
  3326. IF ( lowest_lev_from_sfc ) THEN
  3327. fnew(i,1,j) = forig(i,ko_above_sfc(i),j)
  3328. END IF
  3329. END DO
  3330. END DO
  3331. print *,'VERT EXTRAP = ', vert_extrap
  3332. END SUBROUTINE vert_interp_old
  3333. !---------------------------------------------------------------------
  3334. SUBROUTINE lagrange_setup ( var_type , interp_type , all_x , all_y , all_dim , n , extrap_type , &
  3335. target_x , target_y , target_dim ,i,j)
  3336. ! We call a Lagrange polynomial interpolator. The parallel concerns are put off as this
  3337. ! is initially set up for vertical use. The purpose is an input column of pressure (all_x),
  3338. ! and the associated pressure level data (all_y). These are assumed to be sorted (ascending
  3339. ! or descending, no matter). The locations to be interpolated to are the pressures in
  3340. ! target_x, probably the new vertical coordinate values. The field that is output is the
  3341. ! target_y, which is defined at the target_x location. Mostly we expect to be 2nd order
  3342. ! overlapping polynomials, with only a single 2nd order method near the top and bottom.
  3343. ! When n=1, this is linear; when n=2, this is a second order interpolator.
  3344. IMPLICIT NONE
  3345. CHARACTER (LEN=1) :: var_type
  3346. INTEGER , INTENT(IN) :: interp_type , all_dim , n , extrap_type , target_dim
  3347. REAL, DIMENSION(all_dim) , INTENT(IN) :: all_x , all_y
  3348. REAL , DIMENSION(target_dim) , INTENT(IN) :: target_x
  3349. REAL , DIMENSION(target_dim) , INTENT(OUT) :: target_y
  3350. ! Brought in for debug purposes, all of the computations are in a single column.
  3351. INTEGER , INTENT(IN) :: i,j
  3352. ! Local vars
  3353. REAL , DIMENSION(n+1) :: x , y
  3354. REAL :: a , b
  3355. REAL :: target_y_1 , target_y_2
  3356. LOGICAL :: found_loc
  3357. INTEGER :: loop , loc_center_left , loc_center_right , ist , iend , target_loop
  3358. INTEGER :: vboundb , vboundt
  3359. ! Local vars for the problem of extrapolating theta below ground.
  3360. REAL :: temp_1 , temp_2 , temp_3 , temp_y
  3361. REAL :: depth_of_extrap_in_p , avg_of_extrap_p , temp_extrap_starting_point , dhdp , dh , dt
  3362. REAL , PARAMETER :: RovCp = rcp
  3363. REAL , PARAMETER :: CRC_const1 = 11880.516 ! m
  3364. REAL , PARAMETER :: CRC_const2 = 0.1902632 !
  3365. REAL , PARAMETER :: CRC_const3 = 0.0065 ! K/km
  3366. REAL, DIMENSION(all_dim) :: all_x_full
  3367. REAL , DIMENSION(target_dim) :: target_x_full
  3368. IF ( all_dim .LT. n+1 ) THEN
  3369. print *,'all_dim = ',all_dim
  3370. print *,'order = ',n
  3371. print *,'i,j = ',i,j
  3372. print *,'p array = ',all_x
  3373. print *,'f array = ',all_y
  3374. print *,'p target= ',target_x
  3375. CALL wrf_error_fatal ( 'troubles, the interpolating order is too large for this few input values' )
  3376. END IF
  3377. IF ( n .LT. 1 ) THEN
  3378. CALL wrf_error_fatal ( 'pal, linear is about as low as we go' )
  3379. END IF
  3380. ! We can pinch in the area of the higher order interpolation with vbound. If
  3381. ! vbound = 0, no pinching. If vbound = m, then we make the lower "m" and upper
  3382. ! "m" eta levels use a linear interpolation.
  3383. vboundb = 4
  3384. vboundt = 0
  3385. ! Loop over the list of target x and y values.
  3386. DO target_loop = 1 , target_dim
  3387. ! Find the two trapping x values, and keep the indices.
  3388. found_loc = .FALSE.
  3389. find_trap : DO loop = 1 , all_dim -1
  3390. a = target_x(target_loop) - all_x(loop)
  3391. b = target_x(target_loop) - all_x(loop+1)
  3392. IF ( a*b .LE. 0.0 ) THEN
  3393. loc_center_left = loop
  3394. loc_center_right = loop+1
  3395. found_loc = .TRUE.
  3396. EXIT find_trap
  3397. END IF
  3398. END DO find_trap
  3399. IF ( ( .NOT. found_loc ) .AND. ( target_x(target_loop) .GT. all_x(1) ) ) THEN
  3400. ! Get full pressure back so that our extrpolations make sense.
  3401. IF ( interp_type .EQ. 1 ) THEN
  3402. all_x_full = all_x
  3403. target_x_full = target_x
  3404. ELSE
  3405. all_x_full = EXP ( all_x )
  3406. target_x_full = EXP ( target_x )
  3407. END IF
  3408. ! Isothermal extrapolation.
  3409. IF ( ( extrap_type .EQ. 1 ) .AND. ( var_type .EQ. 'T' ) ) THEN
  3410. temp_1 = all_y(1) * ( all_x_full(1) / 100000. ) ** RovCp
  3411. target_y(target_loop) = temp_1 * ( 100000. / target_x_full(target_loop) ) ** RovCp
  3412. ! Standard atmosphere -6.5 K/km lapse rate for the extrapolation.
  3413. ELSE IF ( ( extrap_type .EQ. 2 ) .AND. ( var_type .EQ. 'T' ) ) THEN
  3414. depth_of_extrap_in_p = target_x_full(target_loop) - all_x_full(1)
  3415. avg_of_extrap_p = ( target_x_full(target_loop) + all_x_full(1) ) * 0.5
  3416. temp_extrap_starting_point = all_y(1) * ( all_x_full(1) / 100000. ) ** RovCp
  3417. dhdp = CRC_const1 * CRC_const2 * ( avg_of_extrap_p / 100. ) ** ( CRC_const2 - 1. )
  3418. dh = dhdp * ( depth_of_extrap_in_p / 100. )
  3419. dt = dh * CRC_const3
  3420. target_y(target_loop) = ( temp_extrap_starting_point + dt ) * ( 100000. / target_x_full(target_loop) ) ** RovCp
  3421. ! Adiabatic extrapolation for theta.
  3422. ELSE IF ( ( extrap_type .EQ. 3 ) .AND. ( var_type .EQ. 'T' ) ) THEN
  3423. target_y(target_loop) = all_y(1)
  3424. ! Wild extrapolation for non-temperature vars.
  3425. ELSE IF ( extrap_type .EQ. 1 ) THEN
  3426. target_y(target_loop) = ( all_y(2) * ( target_x(target_loop) - all_x(3) ) + &
  3427. all_y(3) * ( all_x(2) - target_x(target_loop) ) ) / &
  3428. ( all_x(2) - all_x(3) )
  3429. ! Use a constant value below ground.
  3430. ELSE IF ( extrap_type .EQ. 2 ) THEN
  3431. target_y(target_loop) = all_y(1)
  3432. ELSE IF ( extrap_type .EQ. 3 ) THEN
  3433. CALL wrf_error_fatal ( 'You are not allowed to use extrap_option #3 for any var except for theta.' )
  3434. END IF
  3435. CYCLE
  3436. ELSE IF ( .NOT. found_loc ) THEN
  3437. print *,'i,j = ',i,j
  3438. print *,'target pressure and value = ',target_x(target_loop),target_y(target_loop)
  3439. DO loop = 1 , all_dim
  3440. print *,'column of pressure and value = ',all_x(loop),all_y(loop)
  3441. END DO
  3442. CALL wrf_error_fatal ( 'troubles, could not find trapping x locations' )
  3443. END IF
  3444. ! Even or odd order? We can put the value in the middle if this is
  3445. ! an odd order interpolator. For the even guys, we'll do it twice
  3446. ! and shift the range one index, then get an average.
  3447. IF ( MOD(n,2) .NE. 0 ) THEN
  3448. IF ( ( loc_center_left -(((n+1)/2)-1) .GE. 1 ) .AND. &
  3449. ( loc_center_right+(((n+1)/2)-1) .LE. all_dim ) ) THEN
  3450. ist = loc_center_left -(((n+1)/2)-1)
  3451. iend = ist + n
  3452. CALL lagrange_interp ( all_x(ist:iend) , all_y(ist:iend) , n , target_x(target_loop) , target_y(target_loop) )
  3453. ELSE
  3454. IF ( .NOT. found_loc ) THEN
  3455. CALL wrf_error_fatal ( 'I doubt this will happen, I will only do 2nd order for now' )
  3456. END IF
  3457. END IF
  3458. ELSE IF ( ( MOD(n,2) .EQ. 0 ) .AND. &
  3459. ( ( target_loop .GE. 1 + vboundb ) .AND. ( target_loop .LE. target_dim - vboundt ) ) ) THEN
  3460. IF ( ( loc_center_left -(((n )/2)-1) .GE. 1 ) .AND. &
  3461. ( loc_center_right+(((n )/2) ) .LE. all_dim ) .AND. &
  3462. ( loc_center_left -(((n )/2) ) .GE. 1 ) .AND. &
  3463. ( loc_center_right+(((n )/2)-1) .LE. all_dim ) ) THEN
  3464. ist = loc_center_left -(((n )/2)-1)
  3465. iend = ist + n
  3466. CALL lagrange_interp ( all_x(ist:iend) , all_y(ist:iend) , n , target_x(target_loop) , target_y_1 )
  3467. ist = loc_center_left -(((n )/2) )
  3468. iend = ist + n
  3469. CALL lagrange_interp ( all_x(ist:iend) , all_y(ist:iend) , n , target_x(target_loop) , target_y_2 )
  3470. target_y(target_loop) = ( target_y_1 + target_y_2 ) * 0.5
  3471. ELSE IF ( ( loc_center_left -(((n )/2)-1) .GE. 1 ) .AND. &
  3472. ( loc_center_right+(((n )/2) ) .LE. all_dim ) ) THEN
  3473. ist = loc_center_left -(((n )/2)-1)
  3474. iend = ist + n
  3475. CALL lagrange_interp ( all_x(ist:iend) , all_y(ist:iend) , n , target_x(target_loop) , target_y(target_loop) )
  3476. ELSE IF ( ( loc_center_left -(((n )/2) ) .GE. 1 ) .AND. &
  3477. ( loc_center_right+(((n )/2)-1) .LE. all_dim ) ) THEN
  3478. ist = loc_center_left -(((n )/2) )
  3479. iend = ist + n
  3480. CALL lagrange_interp ( all_x(ist:iend) , all_y(ist:iend) , n , target_x(target_loop) , target_y(target_loop) )
  3481. ELSE
  3482. CALL wrf_error_fatal ( 'unauthorized area, you should not be here' )
  3483. END IF
  3484. ELSE IF ( MOD(n,2) .EQ. 0 ) THEN
  3485. ist = loc_center_left
  3486. iend = loc_center_right
  3487. CALL lagrange_interp ( all_x(ist:iend) , all_y(ist:iend) , 1 , target_x(target_loop) , target_y(target_loop) )
  3488. END IF
  3489. END DO
  3490. END SUBROUTINE lagrange_setup
  3491. !---------------------------------------------------------------------
  3492. SUBROUTINE lagrange_interp ( x , y , n , target_x , target_y )
  3493. ! Interpolation using Lagrange polynomials.
  3494. ! P(x) = f(x0)Ln0(x) + ... + f(xn)Lnn(x)
  3495. ! where Lnk(x) = (x -x0)(x -x1)...(x -xk-1)(x -xk+1)...(x -xn)
  3496. ! ---------------------------------------------
  3497. ! (xk-x0)(xk-x1)...(xk-xk-1)(xk-xk+1)...(xk-xn)
  3498. IMPLICIT NONE
  3499. INTEGER , INTENT(IN) :: n
  3500. REAL , DIMENSION(0:n) , INTENT(IN) :: x , y
  3501. REAL , INTENT(IN) :: target_x
  3502. REAL , INTENT(OUT) :: target_y
  3503. ! Local vars
  3504. INTEGER :: i , k
  3505. REAL :: numer , denom , Px
  3506. REAL , DIMENSION(0:n) :: Ln
  3507. Px = 0.
  3508. DO i = 0 , n
  3509. numer = 1.
  3510. denom = 1.
  3511. DO k = 0 , n
  3512. IF ( k .EQ. i ) CYCLE
  3513. numer = numer * ( target_x - x(k) )
  3514. denom = denom * ( x(i) - x(k) )
  3515. END DO
  3516. IF ( denom .NE. 0. ) THEN
  3517. Ln(i) = y(i) * numer / denom
  3518. Px = Px + Ln(i)
  3519. ENDIF
  3520. END DO
  3521. target_y = Px
  3522. END SUBROUTINE lagrange_interp
  3523. #ifndef VERT_UNIT
  3524. !---------------------------------------------------------------------
  3525. SUBROUTINE p_dry ( mu0 , eta , pdht , pdry , full_levs , &
  3526. ids , ide , jds , jde , kds , kde , &
  3527. ims , ime , jms , jme , kms , kme , &
  3528. its , ite , jts , jte , kts , kte )
  3529. ! Compute reference pressure and the reference mu.
  3530. IMPLICIT NONE
  3531. INTEGER , INTENT(IN) :: ids , ide , jds , jde , kds , kde , &
  3532. ims , ime , jms , jme , kms , kme , &
  3533. its , ite , jts , jte , kts , kte
  3534. LOGICAL :: full_levs
  3535. REAL , DIMENSION(ims:ime, jms:jme) , INTENT(IN) :: mu0
  3536. REAL , DIMENSION( kms:kme ) , INTENT(IN) :: eta
  3537. REAL :: pdht
  3538. REAL , DIMENSION(ims:ime,kms:kme,jms:jme) , INTENT(OUT) :: pdry
  3539. ! Local vars
  3540. INTEGER :: i , j , k
  3541. REAL , DIMENSION( kms:kme ) :: eta_h
  3542. IF ( full_levs ) THEN
  3543. DO j = jts , MIN ( jde-1 , jte )
  3544. DO k = kts , kte
  3545. DO i = its , MIN (ide-1 , ite )
  3546. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  3547. pdry(i,k,j) = eta(k) * mu0(i,j) + pdht
  3548. END DO
  3549. END DO
  3550. END DO
  3551. ELSE
  3552. DO k = kts , kte-1
  3553. eta_h(k) = ( eta(k) + eta(k+1) ) * 0.5
  3554. END DO
  3555. DO j = jts , MIN ( jde-1 , jte )
  3556. DO k = kts , kte-1
  3557. DO i = its , MIN (ide-1 , ite )
  3558. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  3559. pdry(i,k,j) = eta_h(k) * mu0(i,j) + pdht
  3560. END DO
  3561. END DO
  3562. END DO
  3563. END IF
  3564. END SUBROUTINE p_dry
  3565. !---------------------------------------------------------------------
  3566. SUBROUTINE p_dts ( pdts , intq , psfc , p_top , &
  3567. ids , ide , jds , jde , kds , kde , &
  3568. ims , ime , jms , jme , kms , kme , &
  3569. its , ite , jts , jte , kts , kte )
  3570. ! Compute difference between the dry, total surface pressure and the top pressure.
  3571. IMPLICIT NONE
  3572. INTEGER , INTENT(IN) :: ids , ide , jds , jde , kds , kde , &
  3573. ims , ime , jms , jme , kms , kme , &
  3574. its , ite , jts , jte , kts , kte
  3575. REAL , INTENT(IN) :: p_top
  3576. REAL , DIMENSION(ims:ime,jms:jme) , INTENT(IN) :: psfc
  3577. REAL , DIMENSION(ims:ime,jms:jme) , INTENT(IN) :: intq
  3578. REAL , DIMENSION(ims:ime,jms:jme) , INTENT(OUT) :: pdts
  3579. ! Local vars
  3580. INTEGER :: i , j , k
  3581. DO j = jts , MIN ( jde-1 , jte )
  3582. DO i = its , MIN (ide-1 , ite )
  3583. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  3584. pdts(i,j) = psfc(i,j) - intq(i,j) - p_top
  3585. END DO
  3586. END DO
  3587. END SUBROUTINE p_dts
  3588. !---------------------------------------------------------------------
  3589. SUBROUTINE p_dhs ( pdhs , ht , p0 , t0 , a , &
  3590. ids , ide , jds , jde , kds , kde , &
  3591. ims , ime , jms , jme , kms , kme , &
  3592. its , ite , jts , jte , kts , kte )
  3593. ! Compute dry, hydrostatic surface pressure.
  3594. IMPLICIT NONE
  3595. INTEGER , INTENT(IN) :: ids , ide , jds , jde , kds , kde , &
  3596. ims , ime , jms , jme , kms , kme , &
  3597. its , ite , jts , jte , kts , kte
  3598. REAL , DIMENSION(ims:ime, jms:jme) , INTENT(IN) :: ht
  3599. REAL , DIMENSION(ims:ime, jms:jme) , INTENT(OUT) :: pdhs
  3600. REAL , INTENT(IN) :: p0 , t0 , a
  3601. ! Local vars
  3602. INTEGER :: i , j , k
  3603. REAL , PARAMETER :: Rd = r_d
  3604. DO j = jts , MIN ( jde-1 , jte )
  3605. DO i = its , MIN (ide-1 , ite )
  3606. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  3607. pdhs(i,j) = p0 * EXP ( -t0/a + SQRT ( (t0/a)**2 - 2. * g * ht(i,j)/(a * Rd) ) )
  3608. END DO
  3609. END DO
  3610. END SUBROUTINE p_dhs
  3611. !---------------------------------------------------------------------
  3612. SUBROUTINE find_p_top ( p , p_top , &
  3613. ids , ide , jds , jde , kds , kde , &
  3614. ims , ime , jms , jme , kms , kme , &
  3615. its , ite , jts , jte , kts , kte )
  3616. ! Find the largest pressure in the top level. This is our p_top. We are
  3617. ! assuming that the top level is the location where the pressure is a minimum
  3618. ! for each column. In cases where the top surface is not isobaric, a
  3619. ! communicated value must be shared in the calling routine. Also in cases
  3620. ! where the top surface is not isobaric, care must be taken that the new
  3621. ! maximum pressure is not greater than the previous value. This test is
  3622. ! also handled in the calling routine.
  3623. IMPLICIT NONE
  3624. INTEGER , INTENT(IN) :: ids , ide , jds , jde , kds , kde , &
  3625. ims , ime , jms , jme , kms , kme , &
  3626. its , ite , jts , jte , kts , kte
  3627. REAL :: p_top
  3628. REAL , DIMENSION(ims:ime,kms:kme,jms:jme) , INTENT(IN) :: p
  3629. ! Local vars
  3630. INTEGER :: i , j , k, min_lev
  3631. i = its
  3632. j = jts
  3633. p_top = p(i,2,j)
  3634. min_lev = 2
  3635. DO k = 2 , kte
  3636. IF ( p_top .GT. p(i,k,j) ) THEN
  3637. p_top = p(i,k,j)
  3638. min_lev = k
  3639. END IF
  3640. END DO
  3641. k = min_lev
  3642. p_top = p(its,k,jts)
  3643. DO j = jts , MIN ( jde-1 , jte )
  3644. DO i = its , MIN (ide-1 , ite )
  3645. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  3646. p_top = MAX ( p_top , p(i,k,j) )
  3647. END DO
  3648. END DO
  3649. END SUBROUTINE find_p_top
  3650. !---------------------------------------------------------------------
  3651. SUBROUTINE t_to_theta ( t , p , p00 , &
  3652. ids , ide , jds , jde , kds , kde , &
  3653. ims , ime , jms , jme , kms , kme , &
  3654. its , ite , jts , jte , kts , kte )
  3655. ! Compute potential temperature from temperature and pressure.
  3656. IMPLICIT NONE
  3657. INTEGER , INTENT(IN) :: ids , ide , jds , jde , kds , kde , &
  3658. ims , ime , jms , jme , kms , kme , &
  3659. its , ite , jts , jte , kts , kte
  3660. REAL , INTENT(IN) :: p00
  3661. REAL , DIMENSION(ims:ime,kms:kme,jms:jme) , INTENT(IN) :: p
  3662. REAL , DIMENSION(ims:ime,kms:kme,jms:jme) , INTENT(INOUT) :: t
  3663. ! Local vars
  3664. INTEGER :: i , j , k
  3665. REAL , PARAMETER :: Rd = r_d
  3666. DO j = jts , MIN ( jde-1 , jte )
  3667. DO k = kts , kte
  3668. DO i = its , MIN (ide-1 , ite )
  3669. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  3670. t(i,k,j) = t(i,k,j) * ( p00 / p(i,k,j) ) ** (Rd / Cp)
  3671. END DO
  3672. END DO
  3673. END DO
  3674. END SUBROUTINE t_to_theta
  3675. !---------------------------------------------------------------------
  3676. SUBROUTINE theta_to_t ( t , p , p00 , &
  3677. ids , ide , jds , jde , kds , kde , &
  3678. ims , ime , jms , jme , kms , kme , &
  3679. its , ite , jts , jte , kts , kte )
  3680. ! Compute temperature from potential temp and pressure.
  3681. IMPLICIT NONE
  3682. INTEGER , INTENT(IN) :: ids , ide , jds , jde , kds , kde , &
  3683. ims , ime , jms , jme , kms , kme , &
  3684. its , ite , jts , jte , kts , kte
  3685. REAL , INTENT(IN) :: p00
  3686. REAL , DIMENSION(ims:ime,kms:kme,jms:jme) , INTENT(IN) :: p
  3687. REAL , DIMENSION(ims:ime,kms:kme,jms:jme) , INTENT(INOUT) :: t
  3688. ! Local vars
  3689. INTEGER :: i , j , k
  3690. REAL , PARAMETER :: Rd = r_d
  3691. CHARACTER (LEN=80) :: mess
  3692. DO j = jts , MIN ( jde-1 , jte )
  3693. DO k = kts , kte-1
  3694. DO i = its , MIN (ide-1 , ite )
  3695. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  3696. if ( p(i,k,j) .NE. 0. ) then
  3697. t(i,k,j) = t(i,k,j) / ( ( p00 / p(i,k,j) ) ** (Rd / Cp) )
  3698. else
  3699. WRITE(mess,*) 'Troubles in theta_to_t'
  3700. CALL wrf_debug(0,mess)
  3701. WRITE(mess,*) "i,j,k = ", i,j,k
  3702. CALL wrf_debug(0,mess)
  3703. WRITE(mess,*) "p(i,k,j) = ", p(i,k,j)
  3704. CALL wrf_debug(0,mess)
  3705. WRITE(mess,*) "t(i,k,j) = ", t(i,k,j)
  3706. CALL wrf_debug(0,mess)
  3707. endif
  3708. END DO
  3709. END DO
  3710. END DO
  3711. END SUBROUTINE theta_to_t
  3712. !---------------------------------------------------------------------
  3713. SUBROUTINE integ_moist ( q_in , p_in , pd_out , t_in , ght_in , intq , &
  3714. ids , ide , jds , jde , kds , kde , &
  3715. ims , ime , jms , jme , kms , kme , &
  3716. its , ite , jts , jte , kts , kte )
  3717. ! Integrate the moisture field vertically. Mostly used to get the total
  3718. ! vapor pressure, which can be subtracted from the total pressure to get
  3719. ! the dry pressure.
  3720. IMPLICIT NONE
  3721. INTEGER , INTENT(IN) :: ids , ide , jds , jde , kds , kde , &
  3722. ims , ime , jms , jme , kms , kme , &
  3723. its , ite , jts , jte , kts , kte
  3724. REAL , DIMENSION(ims:ime,kms:kme,jms:jme) , INTENT(IN) :: q_in , p_in , t_in , ght_in
  3725. REAL , DIMENSION(ims:ime,kms:kme,jms:jme) , INTENT(OUT) :: pd_out
  3726. REAL , DIMENSION(ims:ime, jms:jme) , INTENT(OUT) :: intq
  3727. ! Local vars
  3728. INTEGER :: i , j , k
  3729. INTEGER , DIMENSION(ims:ime) :: level_above_sfc
  3730. REAL , DIMENSION(ims:ime,jms:jme) :: psfc , tsfc , qsfc, zsfc
  3731. REAL , DIMENSION(ims:ime,kms:kme) :: q , p , t , ght, pd
  3732. REAL :: rhobar , qbar , dz
  3733. REAL :: p1 , p2 , t1 , t2 , q1 , q2 , z1, z2
  3734. LOGICAL :: upside_down
  3735. LOGICAL :: already_assigned_upside_down
  3736. REAL , PARAMETER :: Rd = r_d
  3737. ! Is the data upside down?
  3738. already_assigned_upside_down = .FALSE.
  3739. find_valid : DO j = jts , MIN ( jde-1 , jte )
  3740. DO i = its , MIN (ide-1 , ite )
  3741. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  3742. IF ( p_in(i,kts+1,j) .LT. p_in(i,kte,j) ) THEN
  3743. upside_down = .TRUE.
  3744. already_assigned_upside_down = .TRUE.
  3745. ELSE
  3746. upside_down = .FALSE.
  3747. already_assigned_upside_down = .TRUE.
  3748. END IF
  3749. EXIT find_valid
  3750. END DO
  3751. END DO find_valid
  3752. IF ( .NOT. already_assigned_upside_down ) THEN
  3753. upside_down = .FALSE.
  3754. END IF
  3755. ! Get a surface value, always the first level of a 3d field.
  3756. DO j = jts , MIN ( jde-1 , jte )
  3757. DO i = its , MIN (ide-1 , ite )
  3758. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  3759. psfc(i,j) = p_in(i,kts,j)
  3760. tsfc(i,j) = t_in(i,kts,j)
  3761. qsfc(i,j) = q_in(i,kts,j)
  3762. zsfc(i,j) = ght_in(i,kts,j)
  3763. END DO
  3764. END DO
  3765. DO j = jts , MIN ( jde-1 , jte )
  3766. ! Initialize the integrated quantity of moisture to zero.
  3767. DO i = its , MIN (ide-1 , ite )
  3768. intq(i,j) = 0.
  3769. END DO
  3770. IF ( upside_down ) THEN
  3771. DO i = its , MIN (ide-1 , ite )
  3772. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  3773. p(i,kts) = p_in(i,kts,j)
  3774. t(i,kts) = t_in(i,kts,j)
  3775. q(i,kts) = q_in(i,kts,j)
  3776. ght(i,kts) = ght_in(i,kts,j)
  3777. DO k = kts+1,kte
  3778. p(i,k) = p_in(i,kte+2-k,j)
  3779. t(i,k) = t_in(i,kte+2-k,j)
  3780. q(i,k) = q_in(i,kte+2-k,j)
  3781. ght(i,k) = ght_in(i,kte+2-k,j)
  3782. END DO
  3783. END DO
  3784. ELSE
  3785. DO i = its , MIN (ide-1 , ite )
  3786. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  3787. DO k = kts,kte
  3788. p(i,k) = p_in(i,k ,j)
  3789. t(i,k) = t_in(i,k ,j)
  3790. q(i,k) = q_in(i,k ,j)
  3791. ght(i,k) = ght_in(i,k ,j)
  3792. END DO
  3793. END DO
  3794. END IF
  3795. ! Find the first level above the ground. If all of the levels are above ground, such as
  3796. ! a terrain following lower coordinate, then the first level above ground is index #2.
  3797. DO i = its , MIN (ide-1 , ite )
  3798. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  3799. level_above_sfc(i) = -1
  3800. IF ( p(i,kts+1) .LT. psfc(i,j) ) THEN
  3801. level_above_sfc(i) = kts+1
  3802. ELSE
  3803. find_k : DO k = kts+1,kte-1
  3804. IF ( ( p(i,k )-psfc(i,j) .GE. 0. ) .AND. &
  3805. ( p(i,k+1)-psfc(i,j) .LT. 0. ) ) THEN
  3806. level_above_sfc(i) = k+1
  3807. EXIT find_k
  3808. END IF
  3809. END DO find_k
  3810. IF ( level_above_sfc(i) .EQ. -1 ) THEN
  3811. print *,'i,j = ',i,j
  3812. print *,'p = ',p(i,:)
  3813. print *,'p sfc = ',psfc(i,j)
  3814. CALL wrf_error_fatal ( 'Could not find level above ground')
  3815. END IF
  3816. END IF
  3817. END DO
  3818. DO i = its , MIN (ide-1 , ite )
  3819. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  3820. ! Account for the moisture above the ground.
  3821. pd(i,kte) = p(i,kte)
  3822. DO k = kte-1,level_above_sfc(i),-1
  3823. rhobar = ( p(i,k ) / ( Rd * t(i,k ) ) + &
  3824. p(i,k+1) / ( Rd * t(i,k+1) ) ) * 0.5
  3825. qbar = ( q(i,k ) + q(i,k+1) ) * 0.5
  3826. dz = ght(i,k+1) - ght(i,k)
  3827. intq(i,j) = intq(i,j) + g * qbar * rhobar / (1. + qbar) * dz
  3828. pd(i,k) = p(i,k) - intq(i,j)
  3829. END DO
  3830. ! Account for the moisture between the surface and the first level up.
  3831. IF ( ( p(i,level_above_sfc(i)-1)-psfc(i,j) .GE. 0. ) .AND. &
  3832. ( p(i,level_above_sfc(i) )-psfc(i,j) .LT. 0. ) .AND. &
  3833. ( level_above_sfc(i) .GT. kts ) ) THEN
  3834. p1 = psfc(i,j)
  3835. p2 = p(i,level_above_sfc(i))
  3836. t1 = tsfc(i,j)
  3837. t2 = t(i,level_above_sfc(i))
  3838. q1 = qsfc(i,j)
  3839. q2 = q(i,level_above_sfc(i))
  3840. z1 = zsfc(i,j)
  3841. z2 = ght(i,level_above_sfc(i))
  3842. rhobar = ( p1 / ( Rd * t1 ) + &
  3843. p2 / ( Rd * t2 ) ) * 0.5
  3844. qbar = ( q1 + q2 ) * 0.5
  3845. dz = z2 - z1
  3846. IF ( dz .GT. 0.1 ) THEN
  3847. intq(i,j) = intq(i,j) + g * qbar * rhobar / (1. + qbar) * dz
  3848. END IF
  3849. ! Fix the underground values.
  3850. DO k = level_above_sfc(i)-1,kts+1,-1
  3851. pd(i,k) = p(i,k) - intq(i,j)
  3852. END DO
  3853. END IF
  3854. pd(i,kts) = psfc(i,j) - intq(i,j)
  3855. END DO
  3856. IF ( upside_down ) THEN
  3857. DO i = its , MIN (ide-1 , ite )
  3858. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  3859. pd_out(i,kts,j) = pd(i,kts)
  3860. DO k = kts+1,kte
  3861. pd_out(i,kte+2-k,j) = pd(i,k)
  3862. END DO
  3863. END DO
  3864. ELSE
  3865. DO i = its , MIN (ide-1 , ite )
  3866. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  3867. DO k = kts,kte
  3868. pd_out(i,k,j) = pd(i,k)
  3869. END DO
  3870. END DO
  3871. END IF
  3872. END DO
  3873. END SUBROUTINE integ_moist
  3874. !---------------------------------------------------------------------
  3875. SUBROUTINE rh_to_mxrat2(rh, t, p, q , wrt_liquid , &
  3876. qv_max_p_safe , &
  3877. qv_max_flag , qv_max_value , &
  3878. qv_min_p_safe , &
  3879. qv_min_flag , qv_min_value , &
  3880. ids , ide , jds , jde , kds , kde , &
  3881. ims , ime , jms , jme , kms , kme , &
  3882. its , ite , jts , jte , kts , kte )
  3883. ! This subroutine computes mixing ratio (q, kg/kg) from basic variables
  3884. ! pressure (p, Pa), temperature (t, K) and relative humidity (rh, 0-100%).
  3885. ! Phase transition, liquid water to ice, occurs over (0,-23) temperature range (Celcius).
  3886. ! Formulation used here is based on:
  3887. ! WMO, General meteorological standards and recommended practices,
  3888. ! Appendix A, WMO Technical Regulations, WMO-No. 49, corrigendum,
  3889. ! August 2000. --TKW 03/30/2011
  3890. IMPLICIT NONE
  3891. INTEGER , INTENT(IN) :: ids , ide , jds , jde , kds , kde , &
  3892. ims , ime , jms , jme , kms , kme , &
  3893. its , ite , jts , jte , kts , kte
  3894. LOGICAL , INTENT(IN) :: wrt_liquid
  3895. REAL , INTENT(IN) :: qv_max_p_safe , qv_max_flag , qv_max_value
  3896. REAL , INTENT(IN) :: qv_min_p_safe , qv_min_flag , qv_min_value
  3897. REAL , DIMENSION(ims:ime,kms:kme,jms:jme) , INTENT(IN) :: p , t
  3898. REAL , DIMENSION(ims:ime,kms:kme,jms:jme) , INTENT(INOUT) :: rh
  3899. REAL , DIMENSION(ims:ime,kms:kme,jms:jme) , INTENT(OUT) :: q
  3900. ! Local vars
  3901. REAL, PARAMETER :: T0K = 273.16
  3902. REAL, PARAMETER :: Tice = T0K - 23.0
  3903. REAL, PARAMETER :: cfe = 1.0/(23.0*23.0)
  3904. REAL, PARAMETER :: eps = 0.622
  3905. ! Coefficients for esat over liquid water
  3906. REAL, PARAMETER :: cw1 = 10.79574
  3907. REAL, PARAMETER :: cw2 = -5.02800
  3908. REAL, PARAMETER :: cw3 = 1.50475E-4
  3909. REAL, PARAMETER :: cw4 = 0.42873E-3
  3910. REAL, PARAMETER :: cw5 = 0.78614
  3911. ! Coefficients for esat over ice
  3912. REAL, PARAMETER :: ci1 = -9.09685
  3913. REAL, PARAMETER :: ci2 = -3.56654
  3914. REAL, PARAMETER :: ci3 = 0.87682
  3915. REAL, PARAMETER :: ci4 = 0.78614
  3916. REAL, PARAMETER :: Tn = 273.16
  3917. ! 1 ppm is a reasonable estimate for minimum QV even for stratospheric altitudes
  3918. REAL, PARAMETER :: QV_MIN = 1.e-6
  3919. ! Maximum allowed QV is computed under the extreme condition:
  3920. ! Saturated at 40 degree in Celcius and 1000 hPa
  3921. REAL, PARAMETER :: QV_MAX = 0.045
  3922. ! Need to constrain WVP in the stratosphere where pressure
  3923. ! is low but tempearure is hot (warm)
  3924. ! Maximum ratio of e/p, = q/(0.622+q)
  3925. REAL, PARAMETER :: EP_MAX = QV_MAX/(eps+QV_MAX)
  3926. INTEGER :: i , j , k
  3927. REAL :: ew , q1 , t1
  3928. REAL :: ta, tb, pw3, pw4, pwr
  3929. REAL :: es, esw, esi, wvp, pmb, wvpmax
  3930. DO j = jts , MIN ( jde-1 , jte )
  3931. DO k = kts , kte
  3932. DO i = its , MIN (ide-1 , ite )
  3933. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  3934. rh(i,k,j) = MIN ( MAX ( rh(i,k,j) , 0. ) , 100. )
  3935. END DO
  3936. END DO
  3937. END DO
  3938. IF ( wrt_liquid ) THEN
  3939. DO j = jts , MIN ( jde-1 , jte )
  3940. DO k = kts , kte
  3941. DO i = its , MIN (ide-1 , ite )
  3942. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  3943. Ta=Tn/T(i,k,j)
  3944. Tb=T(i,k,j)/Tn
  3945. pw3 = -8.2969*(Tb-1.0)
  3946. pw4 = 4.76955*(1.0-Ta)
  3947. pwr = cw1*(1.0-Ta) + cw2*LOG10(Tb) + cw3*(1.0-10.0**pw3) + cw4*(10.0**pw4-1.0) + cw5
  3948. es = 10.0**pwr ! Saturation WVP
  3949. wvp = 0.01*rh(i,k,j)*es ! Actual WVP
  3950. pmb = p(i,k,j)/100.
  3951. wvpmax = EP_MAX*pmb ! Prevents unrealistic QV in the stratosphere
  3952. wvp = MIN(wvp,wvpmax)
  3953. q(i,k,j) = eps*wvp/(pmb-wvp)
  3954. END DO
  3955. END DO
  3956. END DO
  3957. ELSE
  3958. DO j = jts , MIN ( jde-1 , jte )
  3959. DO k = kts , kte
  3960. DO i = its , MIN (ide-1 , ite )
  3961. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  3962. Ta=Tn/T(i,k,j)
  3963. Tb=T(i,k,j)/Tn
  3964. IF (t(i,k,j) >= T0K) THEN ! Over liquid water
  3965. pw3 = -8.2969*(Tb-1.0)
  3966. pw4 = 4.76955*(1.0-Ta)
  3967. pwr = cw1*(1.0-Ta) + cw2*LOG10(Tb) + cw3*(1.0-10.0**pw3) + cw4*(10.0**pw4-1.0) + cw5
  3968. es = 10.0**pwr
  3969. wvp = 0.01*rh(i,k,j)*es
  3970. ELSE IF (t(i,k,j) <= Tice) THEN ! Over ice
  3971. pwr = ci1*(Ta-1.0) + ci2*LOG10(Ta) + ci3*(1.0-Tb) + ci4
  3972. es = 10.0**pwr
  3973. wvp = 0.01*rh(i,k,j)*es
  3974. ELSE ! Mixed
  3975. pw3 = -8.2969*(Tb-1.0)
  3976. pw4 = 4.76955*(1.0-Ta)
  3977. pwr = cw1*(1.0-Ta) + cw2*LOG10(Tb) + cw3*(1.0-10.0**pw3) + cw4*(10.0**pw4-1.0) + cw5
  3978. esw = 10.0**pwr ! Over liquid water
  3979. pwr = ci1*(Ta-1.0) + ci2*LOG10(Ta) + ci3*(1.0-Tb) + ci4
  3980. esi = 10.0**pwr ! Over ice
  3981. es = esi + (esw-esi)*cfe*(T(i,k,j)-Tice)*(T(i,k,j)-Tice)
  3982. wvp = 0.01*rh(i,k,j)*es
  3983. END IF
  3984. pmb = p(i,k,j)/100.
  3985. wvpmax = EP_MAX*pmb ! Prevents unrealistic QV in the stratosphere
  3986. wvp = MIN(wvp,wvpmax)
  3987. q(i,k,j) = eps*wvp/(pmb-wvp)
  3988. END DO
  3989. END DO
  3990. END DO
  3991. END IF
  3992. ! For pressures above a defined level, reasonable Qv values should be
  3993. ! a certain value or smaller. If they are larger than this, the input data
  3994. ! probably had "missing" RH, and we filled in some values. This is an
  3995. ! attempt to catch those. Also, set the minimum value for the entire
  3996. ! domain that is above the selected pressure level.
  3997. DO j = jts , MIN ( jde-1 , jte )
  3998. DO k = kts , kte
  3999. DO i = its , MIN (ide-1 , ite )
  4000. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  4001. IF ( p(i,k,j) .LT. qv_max_p_safe ) THEN
  4002. IF ( q(i,k,j) .GT. qv_max_flag ) THEN
  4003. q(i,k,j) = qv_max_value
  4004. END IF
  4005. END IF
  4006. IF ( p(i,k,j) .LT. qv_min_p_safe ) THEN
  4007. IF ( q(i,k,j) .LT. qv_min_flag ) THEN
  4008. q(i,k,j) = qv_min_value
  4009. END IF
  4010. END IF
  4011. END DO
  4012. END DO
  4013. END DO
  4014. END SUBROUTINE rh_to_mxrat2
  4015. !---------------------------------------------------------------------
  4016. SUBROUTINE rh_to_mxrat1(rh, t, p, q , wrt_liquid , &
  4017. qv_max_p_safe , &
  4018. qv_max_flag , qv_max_value , &
  4019. qv_min_p_safe , &
  4020. qv_min_flag , qv_min_value , &
  4021. ids , ide , jds , jde , kds , kde , &
  4022. ims , ime , jms , jme , kms , kme , &
  4023. its , ite , jts , jte , kts , kte )
  4024. IMPLICIT NONE
  4025. INTEGER , INTENT(IN) :: ids , ide , jds , jde , kds , kde , &
  4026. ims , ime , jms , jme , kms , kme , &
  4027. its , ite , jts , jte , kts , kte
  4028. LOGICAL , INTENT(IN) :: wrt_liquid
  4029. REAL , INTENT(IN) :: qv_max_p_safe , qv_max_flag , qv_max_value
  4030. REAL , INTENT(IN) :: qv_min_p_safe , qv_min_flag , qv_min_value
  4031. REAL , DIMENSION(ims:ime,kms:kme,jms:jme) , INTENT(IN) :: p , t
  4032. REAL , DIMENSION(ims:ime,kms:kme,jms:jme) , INTENT(INOUT) :: rh
  4033. REAL , DIMENSION(ims:ime,kms:kme,jms:jme) , INTENT(OUT) :: q
  4034. ! Local vars
  4035. INTEGER :: i , j , k
  4036. REAL :: ew , q1 , t1
  4037. REAL, PARAMETER :: T_REF = 0.0
  4038. REAL, PARAMETER :: MW_AIR = 28.966
  4039. REAL, PARAMETER :: MW_VAP = 18.0152
  4040. REAL, PARAMETER :: A0 = 6.107799961
  4041. REAL, PARAMETER :: A1 = 4.436518521e-01
  4042. REAL, PARAMETER :: A2 = 1.428945805e-02
  4043. REAL, PARAMETER :: A3 = 2.650648471e-04
  4044. REAL, PARAMETER :: A4 = 3.031240396e-06
  4045. REAL, PARAMETER :: A5 = 2.034080948e-08
  4046. REAL, PARAMETER :: A6 = 6.136820929e-11
  4047. REAL, PARAMETER :: ES0 = 6.1121
  4048. REAL, PARAMETER :: C1 = 9.09718
  4049. REAL, PARAMETER :: C2 = 3.56654
  4050. REAL, PARAMETER :: C3 = 0.876793
  4051. REAL, PARAMETER :: EIS = 6.1071
  4052. REAL :: RHS
  4053. REAL, PARAMETER :: TF = 273.16
  4054. REAL :: TK
  4055. REAL :: ES
  4056. REAL :: QS
  4057. REAL, PARAMETER :: EPS = 0.622
  4058. REAL, PARAMETER :: SVP1 = 0.6112
  4059. REAL, PARAMETER :: SVP2 = 17.67
  4060. REAL, PARAMETER :: SVP3 = 29.65
  4061. REAL, PARAMETER :: SVPT0 = 273.15
  4062. CHARACTER (LEN=80) :: mess
  4063. ! This subroutine computes mixing ratio (q, kg/kg) from basic variables
  4064. ! pressure (p, Pa), temperature (t, K) and relative humidity (rh, 1-100%).
  4065. ! The reference temperature (t_ref, C) is used to describe the temperature
  4066. ! at which the liquid and ice phase change occurs.
  4067. DO j = jts , MIN ( jde-1 , jte )
  4068. DO k = kts , kte-1
  4069. DO i = its , MIN (ide-1 , ite )
  4070. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  4071. rh(i,k,j) = MIN ( MAX ( rh(i,k,j) , 0. ) , 100. )
  4072. END DO
  4073. END DO
  4074. END DO
  4075. IF ( wrt_liquid ) THEN
  4076. DO j = jts , MIN ( jde-1 , jte )
  4077. DO k = kts , kte-1
  4078. DO i = its , MIN (ide-1 , ite )
  4079. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  4080. ! es is reduced by RH here to avoid problems in low-pressure cases
  4081. if (t(i,k,j) .ne. 0.) then
  4082. es=.01*rh(i,k,j)*svp1*10.*EXP(svp2*(t(i,k,j)-svpt0)/(t(i,k,j)-svp3))
  4083. IF (es .ge. p(i,k,j)/100.)THEN
  4084. q(i,k,j)=0.0
  4085. WRITE(mess,*) 'Warning: vapor pressure exceeds total pressure, setting Qv to 0'
  4086. CALL wrf_debug(0,mess)
  4087. ELSE
  4088. q(i,k,j)=eps*es/(p(i,k,j)/100.-es)
  4089. ENDIF
  4090. else
  4091. q(i,k,j)=0.0
  4092. WRITE(mess,*) 't(i,j,k) was 0 at ', i,j,k,', setting Qv to 0'
  4093. CALL wrf_debug(0,mess)
  4094. endif
  4095. END DO
  4096. END DO
  4097. END DO
  4098. ELSE
  4099. DO j = jts , MIN ( jde-1 , jte )
  4100. DO k = kts , kte-1
  4101. DO i = its , MIN (ide-1 , ite )
  4102. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  4103. t1 = t(i,k,j) - 273.16
  4104. ! Obviously dry.
  4105. IF ( t1 .lt. -200. ) THEN
  4106. q(i,k,j) = 0
  4107. ELSE
  4108. ! First compute the ambient vapor pressure of water
  4109. ! Liquid phase t > 0 C
  4110. IF ( t1 .GE. t_ref ) THEN
  4111. ew = a0 + t1 * (a1 + t1 * (a2 + t1 * (a3 + t1 * (a4 + t1 * (a5 + t1 * a6)))))
  4112. ! Mixed phase -47 C < t < 0 C
  4113. ELSE IF ( ( t1 .LT. t_ref ) .AND. ( t1 .GE. -47. ) ) THEN
  4114. ew = es0 * exp(17.67 * t1 / ( t1 + 243.5))
  4115. ! Ice phase t < -47 C
  4116. ELSE IF ( t1 .LT. -47. ) THEN
  4117. tk = t(i,k,j)
  4118. rhs = -c1 * (tf / tk - 1.) - c2 * alog10(tf / tk) + &
  4119. c3 * (1. - tk / tf) + alog10(eis)
  4120. ew = 10. ** rhs
  4121. END IF
  4122. ! Now sat vap pres obtained compute local vapor pressure
  4123. ew = MAX ( ew , 0. ) * rh(i,k,j) * 0.01
  4124. ! Now compute the specific humidity using the partial vapor
  4125. ! pressures of water vapor (ew) and dry air (p-ew). The
  4126. ! constants assume that the pressure is in hPa, so we divide
  4127. ! the pressures by 100.
  4128. q1 = mw_vap * ew
  4129. q1 = q1 / (q1 + mw_air * (p(i,k,j)/100. - ew))
  4130. q(i,k,j) = q1 / (1. - q1 )
  4131. END IF
  4132. END DO
  4133. END DO
  4134. END DO
  4135. END IF
  4136. ! For pressures above a defined level, reasonable Qv values should be
  4137. ! a certain value or smaller. If they are larger than this, the input data
  4138. ! probably had "missing" RH, and we filled in some values. This is an
  4139. ! attempt to catch those. Also, set the minimum value for the entire
  4140. ! domain that is above the selected pressure level.
  4141. DO j = jts , MIN ( jde-1 , jte )
  4142. DO k = kts , kte-1
  4143. DO i = its , MIN (ide-1 , ite )
  4144. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  4145. IF ( p(i,k,j) .LT. qv_max_p_safe ) THEN
  4146. IF ( q(i,k,j) .GT. qv_max_flag ) THEN
  4147. q(i,k,j) = qv_max_value
  4148. END IF
  4149. END IF
  4150. IF ( p(i,k,j) .LT. qv_min_p_safe ) THEN
  4151. IF ( q(i,k,j) .LT. qv_min_flag ) THEN
  4152. q(i,k,j) = qv_min_value
  4153. END IF
  4154. END IF
  4155. END DO
  4156. END DO
  4157. END DO
  4158. END SUBROUTINE rh_to_mxrat1
  4159. !---------------------------------------------------------------------
  4160. SUBROUTINE compute_eta ( znw , &
  4161. eta_levels , max_eta , max_dz , &
  4162. p_top , g , p00 , cvpm , a , r_d , cp , t00 , p1000mb , t0 , tiso , &
  4163. ids , ide , jds , jde , kds , kde , &
  4164. ims , ime , jms , jme , kms , kme , &
  4165. its , ite , jts , jte , kts , kte )
  4166. ! Compute eta levels, either using given values from the namelist (hardly
  4167. ! a computation, yep, I know), or assuming a constant dz above the PBL,
  4168. ! knowing p_top and the number of eta levels.
  4169. IMPLICIT NONE
  4170. INTEGER , INTENT(IN) :: ids , ide , jds , jde , kds , kde , &
  4171. ims , ime , jms , jme , kms , kme , &
  4172. its , ite , jts , jte , kts , kte
  4173. REAL , INTENT(IN) :: max_dz
  4174. REAL , INTENT(IN) :: p_top , g , p00 , cvpm , a , r_d , cp , t00 , p1000mb , t0 , tiso
  4175. INTEGER , INTENT(IN) :: max_eta
  4176. REAL , DIMENSION (max_eta) , INTENT(IN) :: eta_levels
  4177. REAL , DIMENSION (kts:kte) , INTENT(OUT) :: znw
  4178. ! Local vars
  4179. INTEGER :: k
  4180. REAL :: mub , t_init , p_surf , pb, ztop, ztop_pbl , dz , temp
  4181. REAL , DIMENSION(kts:kte) :: dnw
  4182. INTEGER , PARAMETER :: prac_levels = 17
  4183. INTEGER :: loop , loop1
  4184. REAL , DIMENSION(prac_levels) :: znw_prac , znu_prac , dnw_prac
  4185. REAL , DIMENSION(kts:kte) :: alb , phb
  4186. ! Gee, do the eta levels come in from the namelist?
  4187. IF ( ABS(eta_levels(1)+1.) .GT. 0.0000001 ) THEN
  4188. ! Check to see if the array is oriented OK, we can easily fix an upside down oops.
  4189. IF ( ( ABS(eta_levels(1 )-1.) .LT. 0.0000001 ) .AND. &
  4190. ( ABS(eta_levels(kde)-0.) .LT. 0.0000001 ) ) THEN
  4191. DO k = kds+1 , kde-1
  4192. znw(k) = eta_levels(k)
  4193. END DO
  4194. znw( 1) = 1.
  4195. znw(kde) = 0.
  4196. ELSE IF ( ( ABS(eta_levels(kde)-1.) .LT. 0.0000001 ) .AND. &
  4197. ( ABS(eta_levels(1 )-0.) .LT. 0.0000001 ) ) THEN
  4198. DO k = kds+1 , kde-1
  4199. znw(k) = eta_levels(kde+1-k)
  4200. END DO
  4201. znw( 1) = 1.
  4202. znw(kde) = 0.
  4203. ELSE
  4204. CALL wrf_error_fatal ( 'First eta level should be 1.0 and the last 0.0 in namelist' )
  4205. END IF
  4206. ! Check to see if the input full-level eta array is monotonic.
  4207. DO k = kds , kde-1
  4208. IF ( znw(k) .LE. znw(k+1) ) THEN
  4209. PRINT *,'eta on full levels is not monotonic'
  4210. PRINT *,'eta (',k,') = ',znw(k)
  4211. PRINT *,'eta (',k+1,') = ',znw(k+1)
  4212. CALL wrf_error_fatal ( 'Fix non-monotonic "eta_levels" in the namelist.input file' )
  4213. END IF
  4214. END DO
  4215. ! Compute eta levels assuming a constant delta z above the PBL.
  4216. ELSE
  4217. ! Compute top of the atmosphere with some silly levels. We just want to
  4218. ! integrate to get a reasonable value for ztop. We use the planned PBL-esque
  4219. ! levels, and then just coarse resolution above that. We know p_top, and we
  4220. ! have the base state vars.
  4221. p_surf = p00
  4222. znw_prac = (/ 1.000 , 0.993 , 0.983 , 0.970 , 0.954 , 0.934 , 0.909 , &
  4223. 0.88 , 0.8 , 0.7 , 0.6 , 0.5 , 0.4 , 0.3 , 0.2 , 0.1 , 0.0 /)
  4224. DO k = 1 , prac_levels - 1
  4225. znu_prac(k) = ( znw_prac(k) + znw_prac(k+1) ) * 0.5
  4226. dnw_prac(k) = znw_prac(k+1) - znw_prac(k)
  4227. END DO
  4228. DO k = 1, prac_levels-1
  4229. pb = znu_prac(k)*(p_surf - p_top) + p_top
  4230. temp = MAX ( tiso, t00 + A*LOG(pb/p00) )
  4231. ! temp = t00 + A*LOG(pb/p00)
  4232. t_init = temp*(p00/pb)**(r_d/cp) - t0
  4233. alb(k) = (r_d/p1000mb)*(t_init+t0)*(pb/p1000mb)**cvpm
  4234. END DO
  4235. ! Base state mu is defined as base state surface pressure minus p_top
  4236. mub = p_surf - p_top
  4237. ! Integrate base geopotential, starting at terrain elevation.
  4238. phb(1) = 0.
  4239. DO k = 2,prac_levels
  4240. phb(k) = phb(k-1) - dnw_prac(k-1)*mub*alb(k-1)
  4241. END DO
  4242. ! So, now we know the model top in meters. Get the average depth above the PBL
  4243. ! of each of the remaining levels. We are going for a constant delta z thickness.
  4244. ztop = phb(prac_levels) / g
  4245. ztop_pbl = phb(8 ) / g
  4246. dz = ( ztop - ztop_pbl ) / REAL ( kde - 8 )
  4247. ! Standard levels near the surface so no one gets in trouble.
  4248. DO k = 1 , 8
  4249. znw(k) = znw_prac(k)
  4250. END DO
  4251. ! Using d phb(k)/ d eta(k) = -mub * alb(k), eqn 2.9
  4252. ! Skamarock et al, NCAR TN 468. Use full levels, so
  4253. ! use twice the thickness.
  4254. DO k = 8, kte-1-2
  4255. pb = znw(k) * (p_surf - p_top) + p_top
  4256. temp = MAX ( tiso, t00 + A*LOG(pb/p00) )
  4257. ! temp = t00 + A*LOG(pb/p00)
  4258. t_init = temp*(p00/pb)**(r_d/cp) - t0
  4259. alb(k) = (r_d/p1000mb)*(t_init+t0)*(pb/p1000mb)**cvpm
  4260. znw(k+1) = znw(k) - dz*g / ( mub*alb(k) )
  4261. END DO
  4262. znw(kte-2) = 0.000
  4263. ! There is some iteration. We want the top level, ztop, to be
  4264. ! consistent with the delta z, and we want the half level values
  4265. ! to be consistent with the eta levels. The inner loop to 10 gets
  4266. ! the eta levels very accurately, but has a residual at the top, due
  4267. ! to dz changing. We reset dz five times, and then things seem OK.
  4268. DO loop1 = 1 , 5
  4269. DO loop = 1 , 10
  4270. DO k = 8, kte-1-2
  4271. pb = (znw(k)+znw(k+1))*0.5 * (p_surf - p_top) + p_top
  4272. temp = MAX ( tiso, t00 + A*LOG(pb/p00) )
  4273. ! temp = t00 + A*LOG(pb/p00)
  4274. t_init = temp*(p00/pb)**(r_d/cp) - t0
  4275. alb(k) = (r_d/p1000mb)*(t_init+t0)*(pb/p1000mb)**cvpm
  4276. znw(k+1) = znw(k) - dz*g / ( mub*alb(k) )
  4277. END DO
  4278. IF ( ( loop1 .EQ. 5 ) .AND. ( loop .EQ. 10 ) ) THEN
  4279. print *,'Converged znw(kte) should be about 0.0 = ',znw(kte-2)
  4280. END IF
  4281. znw(kte-2) = 0.000
  4282. END DO
  4283. ! Here is where we check the eta levels values we just computed.
  4284. DO k = 1, kde-1-2
  4285. pb = (znw(k)+znw(k+1))*0.5 * (p_surf - p_top) + p_top
  4286. temp = MAX ( tiso, t00 + A*LOG(pb/p00) )
  4287. ! temp = t00 + A*LOG(pb/p00)
  4288. t_init = temp*(p00/pb)**(r_d/cp) - t0
  4289. alb(k) = (r_d/p1000mb)*(t_init+t0)*(pb/p1000mb)**cvpm
  4290. END DO
  4291. phb(1) = 0.
  4292. DO k = 2,kde-2
  4293. phb(k) = phb(k-1) - (znw(k)-znw(k-1)) * mub*alb(k-1)
  4294. END DO
  4295. ! Reset the model top and the dz, and iterate.
  4296. ztop = phb(kde-2)/g
  4297. ztop_pbl = phb(8)/g
  4298. dz = ( ztop - ztop_pbl ) / REAL ( (kde-2) - 8 )
  4299. END DO
  4300. IF ( dz .GT. max_dz ) THEN
  4301. print *,'z (m) = ',phb(1)/g
  4302. do k = 2 ,kte-2
  4303. print *,'z (m) and dz (m) = ',phb(k)/g,(phb(k)-phb(k-1))/g
  4304. end do
  4305. print *,'dz (m) above fixed eta levels = ',dz
  4306. print *,'namelist max_dz (m) = ',max_dz
  4307. print *,'namelist p_top (Pa) = ',p_top
  4308. CALL wrf_debug ( 0, 'You need one of three things:' )
  4309. CALL wrf_debug ( 0, '1) More eta levels to reduce the dz: e_vert' )
  4310. CALL wrf_debug ( 0, '2) A lower p_top so your total height is reduced: p_top_requested')
  4311. CALL wrf_debug ( 0, '3) Increase the maximum allowable eta thickness: max_dz')
  4312. CALL wrf_debug ( 0, 'All are namelist options')
  4313. CALL wrf_error_fatal ( 'dz above fixed eta levels is too large')
  4314. END IF
  4315. ! Add those 2 levels back into the middle, just above the 8 levels
  4316. ! that semi define a boundary layer. After we open up the levels,
  4317. ! then we just linearly interpolate in znw. So now levels 1-8 are
  4318. ! specified as the fixed boundary layer levels given in this routine.
  4319. ! The top levels, 12 through kte are those computed. The middle
  4320. ! levels 9, 10, and 11 are equi-spaced in znw, and are each 1/2 the
  4321. ! the znw thickness of levels 11 through 12.
  4322. DO k = kte-2 , 9 , -1
  4323. znw(k+2) = znw(k)
  4324. END DO
  4325. znw( 9) = 0.75 * znw( 8) + 0.25 * znw(12)
  4326. znw(10) = 0.50 * znw( 8) + 0.50 * znw(12)
  4327. znw(11) = 0.25 * znw( 8) + 0.75 * znw(12)
  4328. END IF
  4329. END SUBROUTINE compute_eta
  4330. !---------------------------------------------------------------------
  4331. SUBROUTINE monthly_min_max ( field_in , field_min , field_max , &
  4332. ids , ide , jds , jde , kds , kde , &
  4333. ims , ime , jms , jme , kms , kme , &
  4334. its , ite , jts , jte , kts , kte )
  4335. ! Plow through each month, find the max, min values for each i,j.
  4336. IMPLICIT NONE
  4337. INTEGER , INTENT(IN) :: ids , ide , jds , jde , kds , kde , &
  4338. ims , ime , jms , jme , kms , kme , &
  4339. its , ite , jts , jte , kts , kte
  4340. REAL , DIMENSION(ims:ime,12,jms:jme) , INTENT(IN) :: field_in
  4341. REAL , DIMENSION(ims:ime, jms:jme) , INTENT(OUT) :: field_min , field_max
  4342. ! Local vars
  4343. INTEGER :: i , j , l
  4344. REAL :: minner , maxxer
  4345. DO j = jts , MIN(jde-1,jte)
  4346. DO i = its , MIN(ide-1,ite)
  4347. minner = field_in(i,1,j)
  4348. maxxer = field_in(i,1,j)
  4349. DO l = 2 , 12
  4350. IF ( field_in(i,l,j) .LT. minner ) THEN
  4351. minner = field_in(i,l,j)
  4352. END IF
  4353. IF ( field_in(i,l,j) .GT. maxxer ) THEN
  4354. maxxer = field_in(i,l,j)
  4355. END IF
  4356. END DO
  4357. field_min(i,j) = minner
  4358. field_max(i,j) = maxxer
  4359. END DO
  4360. END DO
  4361. END SUBROUTINE monthly_min_max
  4362. !---------------------------------------------------------------------
  4363. SUBROUTINE monthly_interp_to_date ( field_in , date_str , field_out , &
  4364. ids , ide , jds , jde , kds , kde , &
  4365. ims , ime , jms , jme , kms , kme , &
  4366. its , ite , jts , jte , kts , kte )
  4367. ! Linrarly in time interpolate data to a current valid time. The data is
  4368. ! assumed to come in "monthly", valid at the 15th of every month.
  4369. IMPLICIT NONE
  4370. INTEGER , INTENT(IN) :: ids , ide , jds , jde , kds , kde , &
  4371. ims , ime , jms , jme , kms , kme , &
  4372. its , ite , jts , jte , kts , kte
  4373. CHARACTER (LEN=24) , INTENT(IN) :: date_str
  4374. REAL , DIMENSION(ims:ime,12,jms:jme) , INTENT(IN) :: field_in
  4375. REAL , DIMENSION(ims:ime, jms:jme) , INTENT(OUT) :: field_out
  4376. ! Local vars
  4377. INTEGER :: i , j , l
  4378. INTEGER , DIMENSION(0:13) :: middle
  4379. INTEGER :: target_julyr , target_julday , target_date
  4380. INTEGER :: julyr , julday , int_month , month1 , month2
  4381. REAL :: gmt
  4382. CHARACTER (LEN=4) :: yr
  4383. CHARACTER (LEN=2) :: mon , day15
  4384. WRITE(day15,FMT='(I2.2)') 15
  4385. DO l = 1 , 12
  4386. WRITE(mon,FMT='(I2.2)') l
  4387. CALL get_julgmt ( date_str(1:4)//'-'//mon//'-'//day15//'_'//'00:00:00.0000' , julyr , julday , gmt )
  4388. middle(l) = julyr*1000 + julday
  4389. END DO
  4390. l = 0
  4391. middle(l) = middle( 1) - 31
  4392. l = 13
  4393. middle(l) = middle(12) + 31
  4394. CALL get_julgmt ( date_str , target_julyr , target_julday , gmt )
  4395. target_date = target_julyr * 1000 + target_julday
  4396. find_month : DO l = 0 , 12
  4397. IF ( ( middle(l) .LT. target_date ) .AND. ( middle(l+1) .GE. target_date ) ) THEN
  4398. DO j = jts , MIN ( jde-1 , jte )
  4399. DO i = its , MIN (ide-1 , ite )
  4400. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  4401. int_month = l
  4402. IF ( ( int_month .EQ. 0 ) .OR. ( int_month .EQ. 12 ) ) THEN
  4403. month1 = 12
  4404. month2 = 1
  4405. ELSE
  4406. month1 = int_month
  4407. month2 = month1 + 1
  4408. END IF
  4409. field_out(i,j) = ( field_in(i,month2,j) * ( target_date - middle(l) ) + &
  4410. field_in(i,month1,j) * ( middle(l+1) - target_date ) ) / &
  4411. ( middle(l+1) - middle(l) )
  4412. END DO
  4413. END DO
  4414. EXIT find_month
  4415. END IF
  4416. END DO find_month
  4417. END SUBROUTINE monthly_interp_to_date
  4418. !---------------------------------------------------------------------
  4419. SUBROUTINE sfcprs (t, q, height, pslv, ter, avgsfct, p, &
  4420. psfc, ez_method, &
  4421. ids , ide , jds , jde , kds , kde , &
  4422. ims , ime , jms , jme , kms , kme , &
  4423. its , ite , jts , jte , kts , kte )
  4424. ! Computes the surface pressure using the input height,
  4425. ! temperature and q (already computed from relative
  4426. ! humidity) on p surfaces. Sea level pressure is used
  4427. ! to extrapolate a first guess.
  4428. IMPLICIT NONE
  4429. REAL, PARAMETER :: gamma = 6.5E-3
  4430. REAL, PARAMETER :: pconst = 10000.0
  4431. REAL, PARAMETER :: Rd = r_d
  4432. REAL, PARAMETER :: TC = svpt0 + 17.5
  4433. REAL, PARAMETER :: gammarg = gamma * Rd / g
  4434. REAL, PARAMETER :: rov2 = Rd / 2.
  4435. INTEGER , INTENT(IN) :: ids , ide , jds , jde , kds , kde , &
  4436. ims , ime , jms , jme , kms , kme , &
  4437. its , ite , jts , jte , kts , kte
  4438. LOGICAL , INTENT ( IN ) :: ez_method
  4439. REAL , DIMENSION (ims:ime,kms:kme,jms:jme) , INTENT(IN ):: t, q, height, p
  4440. REAL , DIMENSION (ims:ime, jms:jme) , INTENT(IN ):: pslv , ter, avgsfct
  4441. REAL , DIMENSION (ims:ime, jms:jme) , INTENT(OUT):: psfc
  4442. INTEGER :: i
  4443. INTEGER :: j
  4444. INTEGER :: k
  4445. INTEGER , DIMENSION (its:ite,jts:jte) :: k500 , k700 , k850
  4446. LOGICAL :: l1
  4447. LOGICAL :: l2
  4448. LOGICAL :: l3
  4449. LOGICAL :: OK
  4450. REAL :: gamma78 ( its:ite,jts:jte )
  4451. REAL :: gamma57 ( its:ite,jts:jte )
  4452. REAL :: ht ( its:ite,jts:jte )
  4453. REAL :: p1 ( its:ite,jts:jte )
  4454. REAL :: t1 ( its:ite,jts:jte )
  4455. REAL :: t500 ( its:ite,jts:jte )
  4456. REAL :: t700 ( its:ite,jts:jte )
  4457. REAL :: t850 ( its:ite,jts:jte )
  4458. REAL :: tfixed ( its:ite,jts:jte )
  4459. REAL :: tsfc ( its:ite,jts:jte )
  4460. REAL :: tslv ( its:ite,jts:jte )
  4461. ! We either compute the surface pressure from a time averaged surface temperature
  4462. ! (what we will call the "easy way"), or we try to remove the diurnal impact on the
  4463. ! surface temperature (what we will call the "other way"). Both are essentially
  4464. ! corrections to a sea level pressure with a high-resolution topography field.
  4465. IF ( ez_method ) THEN
  4466. DO j = jts , MIN(jde-1,jte)
  4467. DO i = its , MIN(ide-1,ite)
  4468. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  4469. psfc(i,j) = pslv(i,j) * ( 1.0 + gamma * ter(i,j) / avgsfct(i,j) ) ** ( - g / ( Rd * gamma ) )
  4470. END DO
  4471. END DO
  4472. ELSE
  4473. ! Find the locations of the 850, 700 and 500 mb levels.
  4474. k850 = 0 ! find k at: P=850
  4475. k700 = 0 ! P=700
  4476. k500 = 0 ! P=500
  4477. i = its
  4478. j = jts
  4479. DO k = kts+1 , kte
  4480. IF (NINT(p(i,k,j)) .EQ. 85000) THEN
  4481. k850(i,j) = k
  4482. ELSE IF (NINT(p(i,k,j)) .EQ. 70000) THEN
  4483. k700(i,j) = k
  4484. ELSE IF (NINT(p(i,k,j)) .EQ. 50000) THEN
  4485. k500(i,j) = k
  4486. END IF
  4487. END DO
  4488. IF ( ( k850(i,j) .EQ. 0 ) .OR. ( k700(i,j) .EQ. 0 ) .OR. ( k500(i,j) .EQ. 0 ) ) THEN
  4489. DO j = jts , MIN(jde-1,jte)
  4490. DO i = its , MIN(ide-1,ite)
  4491. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  4492. psfc(i,j) = pslv(i,j) * ( 1.0 + gamma * ter(i,j) / t(i,1,j) ) ** ( - g / ( Rd * gamma ) )
  4493. END DO
  4494. END DO
  4495. RETURN
  4496. #if 0
  4497. ! Possibly it is just that we have a generalized vertical coord, so we do not
  4498. ! have the values exactly. Do a simple assignment to a close vertical level.
  4499. DO j = jts , MIN(jde-1,jte)
  4500. DO i = its , MIN(ide-1,ite)
  4501. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  4502. DO k = kts+1 , kte-1
  4503. IF ( ( p(i,k,j) - 85000. ) * ( p(i,k+1,j) - 85000. ) .LE. 0.0 ) THEN
  4504. k850(i,j) = k
  4505. END IF
  4506. IF ( ( p(i,k,j) - 70000. ) * ( p(i,k+1,j) - 70000. ) .LE. 0.0 ) THEN
  4507. k700(i,j) = k
  4508. END IF
  4509. IF ( ( p(i,k,j) - 50000. ) * ( p(i,k+1,j) - 50000. ) .LE. 0.0 ) THEN
  4510. k500(i,j) = k
  4511. END IF
  4512. END DO
  4513. END DO
  4514. END DO
  4515. ! If we *still* do not have the k levels, punt. I mean, we did try.
  4516. OK = .TRUE.
  4517. DO j = jts , MIN(jde-1,jte)
  4518. DO i = its , MIN(ide-1,ite)
  4519. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  4520. IF ( ( k850(i,j) .EQ. 0 ) .OR. ( k700(i,j) .EQ. 0 ) .OR. ( k500(i,j) .EQ. 0 ) ) THEN
  4521. OK = .FALSE.
  4522. PRINT '(A)','(i,j) = ',i,j,' Error in finding p level for 850, 700 or 500 hPa.'
  4523. DO K = kts+1 , kte
  4524. PRINT '(A,I3,A,F10.2,A)','K = ',k,' PRESSURE = ',p(i,k,j),' Pa'
  4525. END DO
  4526. PRINT '(A)','Expected 850, 700, and 500 mb values, at least.'
  4527. END IF
  4528. END DO
  4529. END DO
  4530. IF ( .NOT. OK ) THEN
  4531. CALL wrf_error_fatal ( 'wrong pressure levels' )
  4532. END IF
  4533. #endif
  4534. ! We are here if the data is isobaric and we found the levels for 850, 700,
  4535. ! and 500 mb right off the bat.
  4536. ELSE
  4537. DO j = jts , MIN(jde-1,jte)
  4538. DO i = its , MIN(ide-1,ite)
  4539. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  4540. k850(i,j) = k850(its,jts)
  4541. k700(i,j) = k700(its,jts)
  4542. k500(i,j) = k500(its,jts)
  4543. END DO
  4544. END DO
  4545. END IF
  4546. ! The 850 hPa level of geopotential height is called something special.
  4547. DO j = jts , MIN(jde-1,jte)
  4548. DO i = its , MIN(ide-1,ite)
  4549. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  4550. ht(i,j) = height(i,k850(i,j),j)
  4551. END DO
  4552. END DO
  4553. ! The variable ht is now -ter/ht(850 hPa). The plot thickens.
  4554. DO j = jts , MIN(jde-1,jte)
  4555. DO i = its , MIN(ide-1,ite)
  4556. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  4557. ht(i,j) = -ter(i,j) / ht(i,j)
  4558. END DO
  4559. END DO
  4560. ! Make an isothermal assumption to get a first guess at the surface
  4561. ! pressure. This is to tell us which levels to use for the lapse
  4562. ! rates in a bit.
  4563. DO j = jts , MIN(jde-1,jte)
  4564. DO i = its , MIN(ide-1,ite)
  4565. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  4566. psfc(i,j) = pslv(i,j) * (pslv(i,j) / p(i,k850(i,j),j)) ** ht(i,j)
  4567. END DO
  4568. END DO
  4569. ! Get a pressure more than pconst Pa above the surface - p1. The
  4570. ! p1 is the top of the level that we will use for our lapse rate
  4571. ! computations.
  4572. DO j = jts , MIN(jde-1,jte)
  4573. DO i = its , MIN(ide-1,ite)
  4574. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  4575. IF ( ( psfc(i,j) - 95000. ) .GE. 0. ) THEN
  4576. p1(i,j) = 85000.
  4577. ELSE IF ( ( psfc(i,j) - 70000. ) .GE. 0. ) THEN
  4578. p1(i,j) = psfc(i,j) - pconst
  4579. ELSE
  4580. p1(i,j) = 50000.
  4581. END IF
  4582. END DO
  4583. END DO
  4584. ! Compute virtual temperatures for k850, k700, and k500 layers. Now
  4585. ! you see why we wanted Q on pressure levels, it all is beginning
  4586. ! to make sense.
  4587. DO j = jts , MIN(jde-1,jte)
  4588. DO i = its , MIN(ide-1,ite)
  4589. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  4590. t850(i,j) = t(i,k850(i,j),j) * (1. + 0.608 * q(i,k850(i,j),j))
  4591. t700(i,j) = t(i,k700(i,j),j) * (1. + 0.608 * q(i,k700(i,j),j))
  4592. t500(i,j) = t(i,k500(i,j),j) * (1. + 0.608 * q(i,k500(i,j),j))
  4593. END DO
  4594. END DO
  4595. ! Compute lapse rates between these three levels. These are
  4596. ! environmental values for each (i,j).
  4597. DO j = jts , MIN(jde-1,jte)
  4598. DO i = its , MIN(ide-1,ite)
  4599. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  4600. gamma78(i,j) = ALOG(t850(i,j) / t700(i,j)) / ALOG (p(i,k850(i,j),j) / p(i,k700(i,j),j) )
  4601. gamma57(i,j) = ALOG(t700(i,j) / t500(i,j)) / ALOG (p(i,k700(i,j),j) / p(i,k500(i,j),j) )
  4602. END DO
  4603. END DO
  4604. DO j = jts , MIN(jde-1,jte)
  4605. DO i = its , MIN(ide-1,ite)
  4606. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  4607. IF ( ( psfc(i,j) - 95000. ) .GE. 0. ) THEN
  4608. t1(i,j) = t850(i,j)
  4609. ELSE IF ( ( psfc(i,j) - 85000. ) .GE. 0. ) THEN
  4610. t1(i,j) = t700(i,j) * (p1(i,j) / (p(i,k700(i,j),j))) ** gamma78(i,j)
  4611. ELSE IF ( ( psfc(i,j) - 70000. ) .GE. 0.) THEN
  4612. t1(i,j) = t500(i,j) * (p1(i,j) / (p(i,k500(i,j),j))) ** gamma57(i,j)
  4613. ELSE
  4614. t1(i,j) = t500(i,j)
  4615. ENDIF
  4616. END DO
  4617. END DO
  4618. ! From our temperature way up in the air, we extrapolate down to
  4619. ! the sea level to get a guess at the sea level temperature.
  4620. DO j = jts , MIN(jde-1,jte)
  4621. DO i = its , MIN(ide-1,ite)
  4622. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  4623. tslv(i,j) = t1(i,j) * (pslv(i,j) / p1(i,j)) ** gammarg
  4624. END DO
  4625. END DO
  4626. ! The new surface temperature is computed from the with new sea level
  4627. ! temperature, just using the elevation and a lapse rate. This lapse
  4628. ! rate is -6.5 K/km.
  4629. DO j = jts , MIN(jde-1,jte)
  4630. DO i = its , MIN(ide-1,ite)
  4631. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  4632. tsfc(i,j) = tslv(i,j) - gamma * ter(i,j)
  4633. END DO
  4634. END DO
  4635. ! A small correction to the sea-level temperature, in case it is too warm.
  4636. DO j = jts , MIN(jde-1,jte)
  4637. DO i = its , MIN(ide-1,ite)
  4638. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  4639. tfixed(i,j) = tc - 0.005 * (tsfc(i,j) - tc) ** 2
  4640. END DO
  4641. END DO
  4642. DO j = jts , MIN(jde-1,jte)
  4643. DO i = its , MIN(ide-1,ite)
  4644. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  4645. l1 = tslv(i,j) .LT. tc
  4646. l2 = tsfc(i,j) .LE. tc
  4647. l3 = .NOT. l1
  4648. IF ( l2 .AND. l3 ) THEN
  4649. tslv(i,j) = tc
  4650. ELSE IF ( ( .NOT. l2 ) .AND. l3 ) THEN
  4651. tslv(i,j) = tfixed(i,j)
  4652. END IF
  4653. END DO
  4654. END DO
  4655. ! Finally, we can get to the surface pressure.
  4656. DO j = jts , MIN(jde-1,jte)
  4657. DO i = its , MIN(ide-1,ite)
  4658. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  4659. p1(i,j) = - ter(i,j) * g / ( rov2 * ( tsfc(i,j) + tslv(i,j) ) )
  4660. psfc(i,j) = pslv(i,j) * EXP ( p1(i,j) )
  4661. END DO
  4662. END DO
  4663. END IF
  4664. ! Surface pressure and sea-level pressure are the same at sea level.
  4665. ! DO j = jts , MIN(jde-1,jte)
  4666. ! DO i = its , MIN(ide-1,ite)
  4667. ! IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  4668. ! IF ( ABS ( ter(i,j) ) .LT. 0.1 ) THEN
  4669. ! psfc(i,j) = pslv(i,j)
  4670. ! END IF
  4671. ! END DO
  4672. ! END DO
  4673. END SUBROUTINE sfcprs
  4674. !---------------------------------------------------------------------
  4675. SUBROUTINE sfcprs2(t, q, height, psfc_in, ter, avgsfct, p, &
  4676. psfc, ez_method, &
  4677. ids , ide , jds , jde , kds , kde , &
  4678. ims , ime , jms , jme , kms , kme , &
  4679. its , ite , jts , jte , kts , kte )
  4680. ! Computes the surface pressure using the input height,
  4681. ! temperature and q (already computed from relative
  4682. ! humidity) on p surfaces. Sea level pressure is used
  4683. ! to extrapolate a first guess.
  4684. IMPLICIT NONE
  4685. REAL, PARAMETER :: Rd = r_d
  4686. INTEGER , INTENT(IN) :: ids , ide , jds , jde , kds , kde , &
  4687. ims , ime , jms , jme , kms , kme , &
  4688. its , ite , jts , jte , kts , kte
  4689. LOGICAL , INTENT ( IN ) :: ez_method
  4690. REAL , DIMENSION (ims:ime,kms:kme,jms:jme) , INTENT(IN ):: t, q, height, p
  4691. REAL , DIMENSION (ims:ime, jms:jme) , INTENT(IN ):: psfc_in , ter, avgsfct
  4692. REAL , DIMENSION (ims:ime, jms:jme) , INTENT(OUT):: psfc
  4693. INTEGER :: i
  4694. INTEGER :: j
  4695. INTEGER :: k
  4696. REAL :: tv_sfc_avg , tv_sfc , del_z
  4697. ! Compute the new surface pressure from the old surface pressure, and a
  4698. ! known change in elevation at the surface.
  4699. ! del_z = diff in surface topo, lo-res vs hi-res
  4700. ! psfc = psfc_in * exp ( g del_z / (Rd Tv_sfc ) )
  4701. IF ( ez_method ) THEN
  4702. DO j = jts , MIN(jde-1,jte)
  4703. DO i = its , MIN(ide-1,ite)
  4704. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  4705. tv_sfc_avg = avgsfct(i,j) * (1. + 0.608 * q(i,1,j))
  4706. del_z = height(i,1,j) - ter(i,j)
  4707. psfc(i,j) = psfc_in(i,j) * EXP ( g * del_z / ( Rd * tv_sfc_avg ) )
  4708. END DO
  4709. END DO
  4710. ELSE
  4711. DO j = jts , MIN(jde-1,jte)
  4712. DO i = its , MIN(ide-1,ite)
  4713. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  4714. tv_sfc = t(i,1,j) * (1. + 0.608 * q(i,1,j))
  4715. del_z = height(i,1,j) - ter(i,j)
  4716. psfc(i,j) = psfc_in(i,j) * EXP ( g * del_z / ( Rd * tv_sfc ) )
  4717. END DO
  4718. END DO
  4719. END IF
  4720. END SUBROUTINE sfcprs2
  4721. !---------------------------------------------------------------------
  4722. SUBROUTINE sfcprs3( height , p , ter , slp , psfc , &
  4723. ids , ide , jds , jde , kds , kde , &
  4724. ims , ime , jms , jme , kms , kme , &
  4725. its , ite , jts , jte , kts , kte )
  4726. ! Computes the surface pressure by vertically interpolating
  4727. ! linearly (or log) in z the pressure, to the targeted topography.
  4728. IMPLICIT NONE
  4729. INTEGER , INTENT(IN) :: ids , ide , jds , jde , kds , kde , &
  4730. ims , ime , jms , jme , kms , kme , &
  4731. its , ite , jts , jte , kts , kte
  4732. REAL , DIMENSION (ims:ime,kms:kme,jms:jme) , INTENT(IN ):: height, p
  4733. REAL , DIMENSION (ims:ime, jms:jme) , INTENT(IN ):: ter , slp
  4734. REAL , DIMENSION (ims:ime, jms:jme) , INTENT(OUT):: psfc
  4735. INTEGER :: i
  4736. INTEGER :: j
  4737. INTEGER :: k
  4738. LOGICAL :: found_loc
  4739. REAL :: zl , zu , pl , pu , zm
  4740. ! Loop over each grid point
  4741. DO j = jts , MIN(jde-1,jte)
  4742. DO i = its , MIN(ide-1,ite)
  4743. IF ( skip_middle_points_t ( ids , ide , jds , jde , i , j , em_width , hold_ups ) ) CYCLE
  4744. ! Special case where near the ocean level. Assume that the SLP is a good value.
  4745. IF ( ter(i,j) .LT. 50 ) THEN
  4746. psfc(i,j) = slp(i,j) + ( p(i,2,j)-p(i,3,j) ) / ( height(i,2,j)-height(i,3,j) ) * ter(i,j)
  4747. CYCLE
  4748. END IF
  4749. ! Find the trapping levels
  4750. found_loc = .FALSE.
  4751. ! Normal sort of scenario - the model topography is somewhere between
  4752. ! the height values of 1000 mb and the top of the model.
  4753. found_k_loc : DO k = kts+1 , kte-2
  4754. IF ( ( height(i,k ,j) .LE. ter(i,j) ) .AND. &
  4755. ( height(i,k+1,j) .GT. ter(i,j) ) ) THEN
  4756. zl = height(i,k ,j)
  4757. zu = height(i,k+1,j)
  4758. zm = ter(i,j)
  4759. pl = p(i,k ,j)
  4760. pu = p(i,k+1,j)
  4761. psfc(i,j) = EXP ( ( LOG(pl) * ( zm - zu ) + LOG(pu) * ( zl - zm ) ) / ( zl - zu ) )
  4762. found_loc = .TRUE.
  4763. EXIT found_k_loc
  4764. END IF
  4765. END DO found_k_loc
  4766. ! Interpolate betwixt slp and the first isobaric level above - this is probably the
  4767. ! usual thing over the ocean.
  4768. IF ( .NOT. found_loc ) THEN
  4769. IF ( slp(i,j) .GE. p(i,2,j) ) THEN
  4770. zl = 0.
  4771. zu = height(i,3,j)
  4772. zm = ter(i,j)
  4773. pl = slp(i,j)
  4774. pu = p(i,3,j)
  4775. psfc(i,j) = EXP ( ( LOG(pl) * ( zm - zu ) + LOG(pu) * ( zl - zm ) ) / ( zl - zu ) )
  4776. found_loc = .TRUE.
  4777. ELSE
  4778. found_slp_loc : DO k = kts+1 , kte-3
  4779. IF ( ( slp(i,j) .GE. p(i,k+1,j) ) .AND. &
  4780. ( slp(i,j) .LT. p(i,k ,j) ) ) THEN
  4781. zl = 0.
  4782. zu = height(i,k+1,j)
  4783. zm = ter(i,j)
  4784. pl = slp(i,j)
  4785. pu = p(i,k+1,j)
  4786. psfc(i,j) = EXP ( ( LOG(pl) * ( zm - zu ) + LOG(pu) * ( zl - zm ) ) / ( zl - zu ) )
  4787. found_loc = .TRUE.
  4788. EXIT found_slp_loc
  4789. END IF
  4790. END DO found_slp_loc
  4791. END IF
  4792. END IF
  4793. ! Did we do what we wanted done.
  4794. IF ( .NOT. found_loc ) THEN
  4795. print *,'i,j = ',i,j
  4796. print *,'p column = ',p(i,2:,j)
  4797. print *,'z column = ',height(i,2:,j)
  4798. print *,'model topo = ',ter(i,j)
  4799. CALL wrf_error_fatal ( ' probs with sfc p computation ' )
  4800. END IF
  4801. END DO
  4802. END DO
  4803. END SUBROUTINE sfcprs3
  4804. !---------------------------------------------------------------------
  4805. SUBROUTINE filter_topo ( ht_in , xlat , msftx , fft_filter_lat , &
  4806. ids , ide , jds , jde , kds , kde , &
  4807. ims , ime , jms , jme , kms , kme , &
  4808. its , ite , jts , jte , kts , kte )
  4809. IMPLICIT NONE
  4810. INTEGER , INTENT(IN) :: ids , ide , jds , jde , kds , kde , &
  4811. ims , ime , jms , jme , kms , kme , &
  4812. its , ite , jts , jte , kts , kte
  4813. REAL , INTENT(IN) :: fft_filter_lat
  4814. REAL , DIMENSION(ims:ime,jms:jme) , INTENT(INOUT) :: ht_in
  4815. REAL , DIMENSION(ims:ime,jms:jme) , INTENT(IN) :: xlat , msftx
  4816. ! Local vars
  4817. INTEGER :: i , j , j_lat_pos , j_lat_neg
  4818. INTEGER :: i_kicker , ik , i1, i2, i3, i4
  4819. REAL :: length_scale , sum
  4820. REAL , DIMENSION(its:ite,jts:jte) :: ht_out
  4821. ! The filtering is a simple average on a latitude loop. Possibly a LONG list of
  4822. ! numbers. We assume that ALL of the 2d arrays have been transposed so that
  4823. ! each patch has the entire domain size of the i-dim local.
  4824. IF ( ( its .NE. ids ) .OR. ( ite .NE. ide ) ) THEN
  4825. CALL wrf_error_fatal ( 'filtering assumes all values on X' )
  4826. END IF
  4827. ! Starting at the south pole, we find where the
  4828. ! grid distance is big enough, then go back a point. Continuing to the
  4829. ! north pole, we find the first small grid distance. These are the
  4830. ! computational latitude loops and the associated computational poles.
  4831. j_lat_neg = 0
  4832. j_lat_pos = jde + 1
  4833. loop_neg : DO j = jts , MIN(jde-1,jte)
  4834. IF ( xlat(its,j) .LT. 0.0 ) THEN
  4835. IF ( ABS(xlat(its,j)) .LT. fft_filter_lat ) THEN
  4836. j_lat_neg = j - 1
  4837. EXIT loop_neg
  4838. END IF
  4839. END IF
  4840. END DO loop_neg
  4841. loop_pos : DO j = jts , MIN(jde-1,jte)
  4842. IF ( xlat(its,j) .GT. 0.0 ) THEN
  4843. IF ( xlat(its,j) .GE. fft_filter_lat ) THEN
  4844. j_lat_pos = j
  4845. EXIT loop_pos
  4846. END IF
  4847. END IF
  4848. END DO loop_pos
  4849. ! Set output values to initial input topo values for whole patch.
  4850. DO j = jts , MIN(jde-1,jte)
  4851. DO i = its , MIN(ide-1,ite)
  4852. ht_out(i,j) = ht_in(i,j)
  4853. END DO
  4854. END DO
  4855. ! Filter the topo at the negative lats.
  4856. DO j = j_lat_neg , jts , -1
  4857. i_kicker = MIN( MAX ( NINT(msftx(its,j)) , 1 ) , (ide - ids) / 2 )
  4858. print *,'j = ' , j, ', kicker = ',i_kicker
  4859. DO i = its , MIN(ide-1,ite)
  4860. IF ( ( i - i_kicker .GE. its ) .AND. ( i + i_kicker .LE. ide-1 ) ) THEN
  4861. sum = 0.0
  4862. DO ik = 1 , i_kicker
  4863. sum = sum + ht_in(i+ik,j) + ht_in(i-ik,j)
  4864. END DO
  4865. ht_out(i,j) = ( ht_in(i,j) + sum ) / REAL ( 2 * i_kicker + 1 )
  4866. ELSE IF ( ( i - i_kicker .LT. its ) .AND. ( i + i_kicker .LE. ide-1 ) ) THEN
  4867. sum = 0.0
  4868. DO ik = 1 , i_kicker
  4869. sum = sum + ht_in(i+ik,j)
  4870. END DO
  4871. i1 = i - i_kicker + ide -1
  4872. i2 = ide-1
  4873. i3 = ids
  4874. i4 = i-1
  4875. DO ik = i1 , i2
  4876. sum = sum + ht_in(ik,j)
  4877. END DO
  4878. DO ik = i3 , i4
  4879. sum = sum + ht_in(ik,j)
  4880. END DO
  4881. ht_out(i,j) = ( ht_in(i,j) + sum ) / REAL ( 2 * i_kicker + 1 )
  4882. ELSE IF ( ( i - i_kicker .GE. its ) .AND. ( i + i_kicker .GT. ide-1 ) ) THEN
  4883. sum = 0.0
  4884. DO ik = 1 , i_kicker
  4885. sum = sum + ht_in(i-ik,j)
  4886. END DO
  4887. i1 = i+1
  4888. i2 = ide-1
  4889. i3 = ids
  4890. i4 = ids + ( i_kicker+i ) - ide
  4891. DO ik = i1 , i2
  4892. sum = sum + ht_in(ik,j)
  4893. END DO
  4894. DO ik = i3 , i4
  4895. sum = sum + ht_in(ik,j)
  4896. END DO
  4897. ht_out(i,j) = ( ht_in(i,j) + sum ) / REAL ( 2 * i_kicker + 1 )
  4898. END IF
  4899. END DO
  4900. END DO
  4901. ! Filter the topo at the positive lats.
  4902. DO j = j_lat_pos , MIN(jde-1,jte)
  4903. i_kicker = MIN( MAX ( NINT(msftx(its,j)) , 1 ) , (ide - ids) / 2 )
  4904. print *,'j = ' , j, ', kicker = ',i_kicker
  4905. DO i = its , MIN(ide-1,ite)
  4906. IF ( ( i - i_kicker .GE. its ) .AND. ( i + i_kicker .LE. ide-1 ) ) THEN
  4907. sum = 0.0
  4908. DO ik = 1 , i_kicker
  4909. sum = sum + ht_in(i+ik,j) + ht_in(i-ik,j)
  4910. END DO
  4911. ht_out(i,j) = ( ht_in(i,j) + sum ) / REAL ( 2 * i_kicker + 1 )
  4912. ELSE IF ( ( i - i_kicker .LT. its ) .AND. ( i + i_kicker .LE. ide-1 ) ) THEN
  4913. sum = 0.0
  4914. DO ik = 1 , i_kicker
  4915. sum = sum + ht_in(i+ik,j)
  4916. END DO
  4917. i1 = i - i_kicker + ide -1
  4918. i2 = ide-1
  4919. i3 = ids
  4920. i4 = i-1
  4921. DO ik = i1 , i2
  4922. sum = sum + ht_in(ik,j)
  4923. END DO
  4924. DO ik = i3 , i4
  4925. sum = sum + ht_in(ik,j)
  4926. END DO
  4927. ht_out(i,j) = ( ht_in(i,j) + sum ) / REAL ( 2 * i_kicker + 1 )
  4928. ELSE IF ( ( i - i_kicker .GE. its ) .AND. ( i + i_kicker .GT. ide-1 ) ) THEN
  4929. sum = 0.0
  4930. DO ik = 1 , i_kicker
  4931. sum = sum + ht_in(i-ik,j)
  4932. END DO
  4933. i1 = i+1
  4934. i2 = ide-1
  4935. i3 = ids
  4936. i4 = ids + ( i_kicker+i ) - ide
  4937. DO ik = i1 , i2
  4938. sum = sum + ht_in(ik,j)
  4939. END DO
  4940. DO ik = i3 , i4
  4941. sum = sum + ht_in(ik,j)
  4942. END DO
  4943. ht_out(i,j) = ( ht_in(i,j) + sum ) / REAL ( 2 * i_kicker + 1 )
  4944. END IF
  4945. END DO
  4946. END DO
  4947. ! Set output values to initial input topo values for whole patch.
  4948. DO j = jts , MIN(jde-1,jte)
  4949. DO i = its , MIN(ide-1,ite)
  4950. ht_in(i,j) = ht_out(i,j)
  4951. END DO
  4952. END DO
  4953. END SUBROUTINE filter_topo
  4954. !---------------------------------------------------------------------
  4955. SUBROUTINE init_module_initialize
  4956. END SUBROUTINE init_module_initialize
  4957. !---------------------------------------------------------------------
  4958. END MODULE module_initialize_real
  4959. #endif