PageRenderTime 55ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/wrfv2_fire/dyn_em/nest_init_utils.F

http://github.com/jbeezley/wrf-fire
FORTRAN Legacy | 416 lines | 259 code | 67 blank | 90 comment | 1 complexity | c636ff88e4b88012042b731342f19319 MD5 | raw file
Possible License(s): AGPL-1.0
  1. SUBROUTINE init_domain_constants_em ( parent , nest )
  2. USE module_domain, ONLY : domain
  3. IMPLICIT NONE
  4. TYPE(domain) :: parent , nest
  5. INTEGER iswater, islake, isice, isurban, isoilwater, map_proj, julyr, julday
  6. REAL truelat1 , truelat2 , gmt , moad_cen_lat , stand_lon, pole_lat, pole_lon
  7. CHARACTER (LEN=256) :: char_junk
  8. ! single-value constants
  9. nest%p_top = parent%p_top
  10. nest%save_topo_from_real = parent%save_topo_from_real
  11. nest%cfn = parent%cfn
  12. nest%cfn1 = parent%cfn1
  13. nest%rdx = 1./nest%dx
  14. nest%rdy = 1./nest%dy
  15. ! nest%dts = nest%dt/float(nest%time_step_sound)
  16. nest%dtseps = parent%dtseps ! used in height model only?
  17. nest%resm = parent%resm ! used in height model only?
  18. nest%zetatop = parent%zetatop ! used in height model only?
  19. nest%cf1 = parent%cf1
  20. nest%cf2 = parent%cf2
  21. nest%cf3 = parent%cf3
  22. nest%gmt = parent%gmt
  23. nest%julyr = parent%julyr
  24. nest%julday = parent%julday
  25. nest%iswater = parent%iswater
  26. nest%isice = parent%isice
  27. nest%isurban = parent%isurban
  28. nest%islake = parent%islake
  29. nest%isoilwater = parent%isoilwater
  30. nest%mminlu = trim(parent%mminlu)
  31. nest%tiso = parent%tiso
  32. nest%tlp = parent%tlp
  33. nest%p00 = parent%p00
  34. nest%t00 = parent%t00
  35. CALL nl_get_mminlu ( 1, char_junk )
  36. CALL nl_get_iswater( 1, iswater )
  37. CALL nl_get_islake ( 1, islake )
  38. CALL nl_get_isice ( 1, isice )
  39. CALL nl_get_isurban( 1, isurban )
  40. CALL nl_get_isoilwater(1, isoilwater )
  41. CALL nl_get_truelat1 ( 1 , truelat1 )
  42. CALL nl_get_truelat2 ( 1 , truelat2 )
  43. CALL nl_get_moad_cen_lat ( 1 , moad_cen_lat )
  44. CALL nl_get_stand_lon ( 1 , stand_lon )
  45. CALL nl_get_pole_lat ( 1 , pole_lat )
  46. CALL nl_get_pole_lon ( 1 , pole_lon )
  47. CALL nl_get_map_proj ( 1 , map_proj )
  48. CALL nl_get_gmt ( 1 , gmt)
  49. CALL nl_get_julyr ( 1 , julyr)
  50. CALL nl_get_julday ( 1 , julday)
  51. IF ( nest%id .NE. 1 ) THEN
  52. CALL nl_set_gmt (nest%id, gmt)
  53. CALL nl_set_julyr (nest%id, julyr)
  54. CALL nl_set_julday (nest%id, julday)
  55. CALL nl_set_iswater ( nest%id, iswater )
  56. CALL nl_set_islake ( nest%id, islake )
  57. CALL nl_set_isice ( nest%id, isice )
  58. CALL nl_set_isurban ( nest%id, isurban )
  59. CALL nl_set_isoilwater ( nest%id, isoilwater )
  60. CALL nl_set_mminlu ( nest%id, char_junk )
  61. CALL nl_set_truelat1 ( nest%id , truelat1 )
  62. CALL nl_set_truelat2 ( nest%id , truelat2 )
  63. CALL nl_set_moad_cen_lat ( nest%id , moad_cen_lat )
  64. CALL nl_set_stand_lon ( nest%id , stand_lon )
  65. CALL nl_set_pole_lat ( nest%id , pole_lat )
  66. CALL nl_set_pole_lon ( nest%id , pole_lon )
  67. CALL nl_set_map_proj ( nest%id , map_proj )
  68. END IF
  69. nest%gmt = gmt
  70. nest%julday = julday
  71. nest%julyr = julyr
  72. nest%iswater = iswater
  73. nest%islake = islake
  74. nest%isice = isice
  75. nest%isoilwater = isoilwater
  76. nest%mminlu = trim(char_junk)
  77. nest%truelat1= truelat1
  78. nest%truelat2= truelat2
  79. nest%moad_cen_lat= moad_cen_lat
  80. nest%stand_lon= stand_lon
  81. nest%pole_lat= pole_lat
  82. nest%pole_lon= pole_lon
  83. nest%map_proj= map_proj
  84. nest%step_number = parent%step_number
  85. ! 1D constants (Z)
  86. nest%fnm = parent%fnm
  87. nest%fnp = parent%fnp
  88. nest%rdnw = parent%rdnw
  89. nest%rdn = parent%rdn
  90. nest%dnw = parent%dnw
  91. nest%dn = parent%dn
  92. nest%znu = parent%znu
  93. nest%znw = parent%znw
  94. nest%t_base = parent%t_base
  95. nest%u_base = parent%u_base
  96. nest%v_base = parent%v_base
  97. nest%qv_base = parent%qv_base
  98. nest%z_base = parent%z_base
  99. nest%dzs = parent%dzs
  100. nest%zs = parent%zs
  101. END SUBROUTINE init_domain_constants_em
  102. SUBROUTINE blend_terrain ( ter_interpolated , ter_input , &
  103. ids , ide , jds , jde , kds , kde , &
  104. ims , ime , jms , jme , kms , kme , &
  105. ips , ipe , jps , jpe , kps , kpe )
  106. USE module_configure
  107. IMPLICIT NONE
  108. INTEGER , INTENT(IN) :: ids , ide , jds , jde , kds , kde , &
  109. ims , ime , jms , jme , kms , kme , &
  110. ips , ipe , jps , jpe , kps , kpe
  111. REAL , DIMENSION(ims:ime,kms:kme,jms:jme) , INTENT(IN) :: ter_interpolated
  112. REAL , DIMENSION(ims:ime,kms:kme,jms:jme) , INTENT(INOUT) :: ter_input
  113. REAL , DIMENSION(ims:ime,kms:kme,jms:jme) :: ter_temp
  114. INTEGER :: i , j , k , spec_bdy_width
  115. REAL :: r_blend_zones
  116. INTEGER blend_cell, blend_width
  117. ! The fine grid elevation comes from the horizontally interpolated
  118. ! parent elevation for the first spec_bdy_width row/columns, so we need
  119. ! to get that value. We blend the coarse and fine in the next blend_width
  120. ! rows and columns. After that, in the interior, it is 100% fine grid.
  121. CALL nl_get_spec_bdy_width ( 1, spec_bdy_width)
  122. CALL nl_get_blend_width ( 1, blend_width)
  123. ! Initialize temp values to the nest ter elevation. This fills in the values
  124. ! that will not be modified below.
  125. DO j = jps , MIN(jpe, jde-1)
  126. DO k = kps , kpe
  127. DO i = ips , MIN(ipe, ide-1)
  128. ter_temp(i,k,j) = ter_input(i,k,j)
  129. END DO
  130. END DO
  131. END DO
  132. ! To avoid some tricky indexing, we fill in the values inside out. This allows
  133. ! us to overwrite incorrect assignments. There are replicated assignments, and
  134. ! there is much unnecessary "IF test inside of a loop" stuff. For a large
  135. ! domain, this is only a patch; for a small domain, this is not a biggy.
  136. r_blend_zones = 1./(blend_width+1)
  137. DO j = jps , MIN(jpe, jde-1)
  138. DO k = kps , kpe
  139. DO i = ips , MIN(ipe, ide-1)
  140. DO blend_cell = blend_width,1,-1
  141. IF ( ( i .EQ. spec_bdy_width + blend_cell ) .OR. ( j .EQ. spec_bdy_width + blend_cell ) .OR. &
  142. ( i .EQ. ide - spec_bdy_width - blend_cell ) .OR. ( j .EQ. jde - spec_bdy_width - blend_cell ) ) THEN
  143. ter_temp(i,k,j) = ( (blend_cell)*ter_input(i,k,j) + (blend_width+1-blend_cell)*ter_interpolated(i,k,j) ) &
  144. * r_blend_zones
  145. END IF
  146. ENDDO
  147. IF ( ( i .LE. spec_bdy_width ) .OR. ( j .LE. spec_bdy_width ) .OR. &
  148. ( i .GE. ide - spec_bdy_width ) .OR. ( j .GE. jde - spec_bdy_width ) ) THEN
  149. ter_temp(i,k,j) = ter_interpolated(i,k,j)
  150. END IF
  151. END DO
  152. END DO
  153. END DO
  154. ! Set nest elevation with temp values. All values not overwritten in the above
  155. ! loops have been previously set in the initial assignment.
  156. DO j = jps , MIN(jpe, jde-1)
  157. DO k = kps , kpe
  158. DO i = ips , MIN(ipe, ide-1)
  159. ter_input(i,k,j) = ter_temp(i,k,j)
  160. END DO
  161. END DO
  162. END DO
  163. END SUBROUTINE blend_terrain
  164. SUBROUTINE copy_3d_field ( ter_interpolated , ter_input , &
  165. ids , ide , jds , jde , kds , kde , &
  166. ims , ime , jms , jme , kms , kme , &
  167. ips , ipe , jps , jpe , kps , kpe )
  168. IMPLICIT NONE
  169. INTEGER , INTENT(IN) :: ids , ide , jds , jde , kds , kde , &
  170. ims , ime , jms , jme , kms , kme , &
  171. ips , ipe , jps , jpe , kps , kpe
  172. REAL , DIMENSION(ims:ime,kms:kme,jms:jme) , INTENT(OUT) :: ter_interpolated
  173. REAL , DIMENSION(ims:ime,kms:kme,jms:jme) , INTENT(IN) :: ter_input
  174. INTEGER :: i , j , k
  175. DO j = jps , MIN(jpe, jde-1)
  176. DO k = kps , kpe
  177. DO i = ips , MIN(ipe, ide-1)
  178. ter_interpolated(i,k,j) = ter_input(i,k,j)
  179. END DO
  180. END DO
  181. END DO
  182. END SUBROUTINE copy_3d_field
  183. SUBROUTINE adjust_tempqv ( mub, save_mub, znw, p_top, &
  184. th, pp, qv, &
  185. ids , ide , jds , jde , kds , kde , &
  186. ims , ime , jms , jme , kms , kme , &
  187. ips , ipe , jps , jpe , kps , kpe )
  188. !USE module_configure
  189. !USE module_domain
  190. USE module_model_constants
  191. !USE module_bc
  192. !USE module_io_domain
  193. !USE module_state_description
  194. !USE module_timing
  195. !USE module_soil_pre
  196. IMPLICIT NONE
  197. INTEGER , INTENT(IN) :: ids , ide , jds , jde , kds , kde , &
  198. ims , ime , jms , jme , kms , kme , &
  199. ips , ipe , jps , jpe , kps , kpe
  200. REAL , DIMENSION(ims:ime,jms:jme) , INTENT(IN) :: mub, save_mub
  201. REAL , DIMENSION(kms:kme) , INTENT(IN) :: znw
  202. REAL , DIMENSION(ims:ime,kms:kme,jms:jme) , INTENT(INOUT) :: th, pp, qv
  203. REAL , DIMENSION(ims:ime,kms:kme,jms:jme) :: p_old, p_new, rh
  204. REAL :: es,dth,tc,e,dth1
  205. INTEGER :: i , j , k
  206. real p_top
  207. ! p_old = full pressure before terrain blending; also compute initial RH
  208. ! which is going to be conserved during terrain blending
  209. DO j = jps , MIN(jpe, jde-1)
  210. DO k = kps , kpe-1
  211. DO i = ips , MIN(ipe, ide-1)
  212. p_old(i,k,j) = 0.5*(znw(k+1)+znw(k))*save_mub(i,j) + p_top + pp(i,k,j)
  213. tc = (th(i,k,j)+300.)*(p_old(i,k,j)/1.e5)**(2./7.) - 273.15
  214. es = 610.78*exp(17.0809*tc/(234.175+tc))
  215. e = qv(i,k,j)*p_old(i,k,j)/(0.622+qv(i,k,j))
  216. rh(i,k,j) = e/es
  217. END DO
  218. END DO
  219. END DO
  220. ! p_new = full pressure after terrain blending; also compute temperature correction and convert RH back to QV
  221. DO j = jps , MIN(jpe, jde-1)
  222. DO k = kps , kpe-1
  223. DO i = ips , MIN(ipe, ide-1)
  224. p_new(i,k,j) = 0.5*(znw(k+1)+znw(k))*mub(i,j) + p_top + pp(i,k,j)
  225. ! 2*(g/cp-6.5e-3)*R_dry/g = -191.86e-3
  226. dth1 = -191.86e-3*(th(i,k,j)+300.)/(p_new(i,k,j)+p_old(i,k,j))*(p_new(i,k,j)-p_old(i,k,j))
  227. dth = -191.86e-3*(th(i,k,j)+0.5*dth1+300.)/(p_new(i,k,j)+p_old(i,k,j))*(p_new(i,k,j)-p_old(i,k,j))
  228. th(i,k,j) = th(i,k,j)+dth
  229. tc = (th(i,k,j)+300.)*(p_new(i,k,j)/1.e5)**(2./7.) - 273.15
  230. es = 610.78*exp(17.0809*tc/(234.175+tc))
  231. e = rh(i,k,j)*es
  232. qv(i,k,j) = 0.622*e/(p_new(i,k,j)-e)
  233. END DO
  234. END DO
  235. END DO
  236. END SUBROUTINE adjust_tempqv
  237. SUBROUTINE input_terrain_rsmas ( grid , &
  238. ids , ide , jds , jde , kds , kde , &
  239. ims , ime , jms , jme , kms , kme , &
  240. ips , ipe , jps , jpe , kps , kpe )
  241. USE module_domain, ONLY : domain
  242. IMPLICIT NONE
  243. TYPE ( domain ) :: grid
  244. INTEGER , INTENT(IN) :: ids , ide , jds , jde , kds , kde , &
  245. ims , ime , jms , jme , kms , kme , &
  246. ips , ipe , jps , jpe , kps , kpe
  247. LOGICAL, EXTERNAL :: wrf_dm_on_monitor
  248. INTEGER :: i , j , k , myproc
  249. INTEGER, DIMENSION(256) :: ipath ! array for integer coded ascii for passing path down to get_terrain
  250. CHARACTER*256 :: message, message2
  251. CHARACTER*256 :: rsmas_data_path
  252. #if DM_PARALLEL
  253. ! Local globally sized arrays
  254. REAL , DIMENSION(ids:ide,jds:jde) :: ht_g, xlat_g, xlon_g
  255. #endif
  256. CALL wrf_get_myproc ( myproc )
  257. #if 0
  258. CALL domain_clock_get ( grid, current_timestr=message2 )
  259. WRITE ( message , FMT = '(A," HT before ",I3)' ) TRIM(message2), grid%id
  260. write(30+myproc,*)ipe-ips+1,jpe-jps+1,trim(message)
  261. do j = jps,jpe
  262. do i = ips,ipe
  263. write(30+myproc,*)grid%ht(i,j)
  264. enddo
  265. enddo
  266. #endif
  267. CALL nl_get_rsmas_data_path(1,rsmas_data_path)
  268. do i = 1, LEN(TRIM(rsmas_data_path))
  269. ipath(i) = ICHAR(rsmas_data_path(i:i))
  270. enddo
  271. #if ( defined( DM_PARALLEL ) && ( ! defined( STUBMPI ) ) )
  272. CALL wrf_patch_to_global_real ( grid%xlat , xlat_g , grid%domdesc, ' ' , 'xy' , &
  273. ids, ide-1 , jds , jde-1 , 1 , 1 , &
  274. ims, ime , jms , jme , 1 , 1 , &
  275. ips, ipe , jps , jpe , 1 , 1 )
  276. CALL wrf_patch_to_global_real ( grid%xlong , xlon_g , grid%domdesc, ' ' , 'xy' , &
  277. ids, ide-1 , jds , jde-1 , 1 , 1 , &
  278. ims, ime , jms , jme , 1 , 1 , &
  279. ips, ipe , jps , jpe , 1 , 1 )
  280. IF ( wrf_dm_on_monitor() ) THEN
  281. CALL get_terrain ( grid%dx/1000., xlat_g(ids:ide,jds:jde), xlon_g(ids:ide,jds:jde), ht_g(ids:ide,jds:jde), &
  282. ide-ids+1,jde-jds+1,ide-ids+1,jde-jds+1, ipath, LEN(TRIM(rsmas_data_path)) )
  283. WHERE ( ht_g(ids:ide,jds:jde) < -1000. ) ht_g(ids:ide,jds:jde) = 0.
  284. ENDIF
  285. CALL wrf_global_to_patch_real ( ht_g , grid%ht , grid%domdesc, ' ' , 'xy' , &
  286. ids, ide-1 , jds , jde-1 , 1 , 1 , &
  287. ims, ime , jms , jme , 1 , 1 , &
  288. ips, ipe , jps , jpe , 1 , 1 )
  289. #else
  290. CALL get_terrain ( grid%dx/1000., grid%xlat(ids:ide,jds:jde), grid%xlong(ids:ide,jds:jde), grid%ht(ids:ide,jds:jde), &
  291. ide-ids+1,jde-jds+1,ide-ids+1,jde-jds+1, ipath, LEN(TRIM(rsmas_data_path)) )
  292. WHERE ( grid%ht(ids:ide,jds:jde) < -1000. ) grid%ht(ids:ide,jds:jde) = 0.
  293. #endif
  294. #if 0
  295. CALL domain_clock_get ( grid, current_timestr=message2 )
  296. WRITE ( message , FMT = '(A," HT after ",I3)' ) TRIM(message2), grid%id
  297. write(30+myproc,*)ipe-ips+1,jpe-jps+1,trim(message)
  298. do j = jps,jpe
  299. do i = ips,ipe
  300. write(30+myproc,*)grid%ht(i,j)
  301. enddo
  302. enddo
  303. #endif
  304. END SUBROUTINE input_terrain_rsmas
  305. SUBROUTINE update_after_feedback_em ( grid &
  306. !
  307. #include "dummy_new_args.inc"
  308. !
  309. )
  310. !
  311. ! perform core specific updates, exchanges after
  312. ! model feedback (called from med_feedback_domain) -John
  313. !
  314. ! Driver layer modules
  315. USE module_domain, ONLY : domain, get_ijk_from_grid
  316. USE module_configure
  317. USE module_driver_constants
  318. USE module_machine
  319. USE module_tiles
  320. #ifdef DM_PARALLEL
  321. USE module_dm, ONLY : ntasks, ntasks_x, ntasks_y, itrace, local_communicator, mytask
  322. USE module_comm_dm, ONLY : HALO_EM_FEEDBACK_sub
  323. #else
  324. USE module_dm
  325. #endif
  326. USE module_bc
  327. ! Mediation layer modules
  328. ! Registry generated module
  329. USE module_state_description
  330. IMPLICIT NONE
  331. ! Subroutine interface block.
  332. TYPE(domain) , TARGET :: grid
  333. ! Definitions of dummy arguments
  334. #include <dummy_new_decl.inc>
  335. INTEGER :: ids , ide , jds , jde , kds , kde , &
  336. ims , ime , jms , jme , kms , kme , &
  337. ips , ipe , jps , jpe , kps , kpe
  338. CALL wrf_debug( 500, "entering update_after_feedback_em" )
  339. ! Obtain dimension information stored in the grid data structure.
  340. CALL get_ijk_from_grid ( grid , &
  341. ids, ide, jds, jde, kds, kde, &
  342. ims, ime, jms, jme, kms, kme, &
  343. ips, ipe, jps, jpe, kps, kpe )
  344. CALL wrf_debug( 500, "before HALO_EM_FEEDBACK.inc in update_after_feedback_em" )
  345. #ifdef DM_PARALLEL
  346. #include "HALO_EM_FEEDBACK.inc"
  347. #endif
  348. CALL wrf_debug( 500, "leaving update_after_feedback_em" )
  349. END SUBROUTINE update_after_feedback_em