PageRenderTime 52ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 1ms

/WPS/metgrid/src/process_domain_module.F

http://github.com/jbeezley/wrf-fire
FORTRAN Legacy | 2839 lines | 1753 code | 456 blank | 630 comment | 397 complexity | 2d29f8bcd4bc0d9d1f57c097777cb2a6 MD5 | raw file
Possible License(s): AGPL-1.0

Large files files are truncated, but you can click here to view the full file

  1. module process_domain_module
  2. contains
  3. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  4. ! Name: process_domain
  5. !
  6. ! Purpose:
  7. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  8. subroutine process_domain(n, extra_row, extra_col)
  9. use date_pack
  10. use gridinfo_module
  11. use interp_option_module
  12. use misc_definitions_module
  13. use module_debug
  14. use storage_module
  15. implicit none
  16. ! Arguments
  17. integer, intent(in) :: n
  18. logical, intent(in) :: extra_row, extra_col
  19. ! Local variables
  20. integer :: i, t, dyn_opt, &
  21. we_dom_s, we_dom_e, sn_dom_s, sn_dom_e, &
  22. we_patch_s, we_patch_e, we_patch_stag_s, we_patch_stag_e, &
  23. sn_patch_s, sn_patch_e, sn_patch_stag_s, sn_patch_stag_e, &
  24. we_mem_s, we_mem_e, we_mem_stag_s, we_mem_stag_e, &
  25. sn_mem_s, sn_mem_e, sn_mem_stag_s, sn_mem_stag_e, &
  26. idiff, n_times, &
  27. west_east_dim, south_north_dim, bottom_top_dim, map_proj, &
  28. is_water, is_lake, is_ice, is_urban, i_soilwater, &
  29. grid_id, parent_id, i_parent_start, j_parent_start, &
  30. i_parent_end, j_parent_end, parent_grid_ratio, sub_x, sub_y, num_land_cat, process_bdy_width
  31. real :: cen_lat, moad_cen_lat, cen_lon, stand_lon, truelat1, truelat2, &
  32. dom_dx, dom_dy, pole_lat, pole_lon
  33. real, dimension(16) :: corner_lats, corner_lons
  34. real, pointer, dimension(:,:) :: landmask
  35. real, pointer, dimension(:,:) :: xlat, xlon, xlat_u, xlon_u, xlat_v, xlon_v
  36. logical, allocatable, dimension(:) :: got_this_field, got_const_field
  37. character (len=19) :: valid_date, temp_date
  38. character (len=128) :: title, mminlu
  39. character (len=128), allocatable, dimension(:) :: output_flags, td_output_flags
  40. ! Compute number of times that we will process
  41. call geth_idts(end_date(n), start_date(n), idiff)
  42. call mprintf((idiff < 0),ERROR,'Ending date is earlier than starting date in namelist for domain %i.', i1=n)
  43. n_times = idiff / interval_seconds
  44. ! Check that the interval evenly divides the range of times to process
  45. call mprintf((mod(idiff, interval_seconds) /= 0),WARN, &
  46. 'In namelist, interval_seconds does not evenly divide '// &
  47. '(end_date - start_date) for domain %i. Only %i time periods '// &
  48. 'will be processed.', i1=n, i2=n_times)
  49. ! Initialize the storage module
  50. call mprintf(.true.,LOGFILE,'Initializing storage module')
  51. call storage_init()
  52. !
  53. ! Do time-independent processing
  54. !
  55. call get_static_fields(n, dyn_opt, west_east_dim, south_north_dim, bottom_top_dim, map_proj, &
  56. we_dom_s, we_dom_e, sn_dom_s, sn_dom_e, &
  57. we_patch_s, we_patch_e, &
  58. we_patch_stag_s, we_patch_stag_e, &
  59. sn_patch_s, sn_patch_e, &
  60. sn_patch_stag_s, sn_patch_stag_e, &
  61. we_mem_s, we_mem_e, we_mem_stag_s, we_mem_stag_e, &
  62. sn_mem_s, sn_mem_e, sn_mem_stag_s, sn_mem_stag_e, &
  63. mminlu, num_land_cat, is_water, is_lake, is_ice, is_urban, i_soilwater, &
  64. grid_id, parent_id, &
  65. i_parent_start, j_parent_start, i_parent_end, j_parent_end, &
  66. parent_grid_ratio, sub_x, sub_y, &
  67. cen_lat, moad_cen_lat, cen_lon, stand_lon, truelat1, truelat2, &
  68. pole_lat, pole_lon, dom_dx, dom_dy, landmask, xlat, xlon, xlat_u, xlon_u, &
  69. xlat_v, xlon_v, corner_lats, corner_lons, title)
  70. allocate(output_flags(num_entries))
  71. allocate(got_const_field(num_entries))
  72. do i=1,num_entries
  73. output_flags(i) = ' '
  74. got_const_field(i) = .false.
  75. end do
  76. ! This call is to process the constant met fields (SST or SEAICE, for example)
  77. ! That we process constant fields is indicated by the first argument
  78. call process_single_met_time(.true., temp_date, n, extra_row, extra_col, xlat, xlon, &
  79. xlat_u, xlon_u, xlat_v, xlon_v, landmask, &
  80. title, dyn_opt, &
  81. west_east_dim, south_north_dim, &
  82. we_dom_s, we_dom_e, sn_dom_s, sn_dom_e, &
  83. we_patch_s, we_patch_e, we_patch_stag_s, we_patch_stag_e, &
  84. sn_patch_s, sn_patch_e, sn_patch_stag_s, sn_patch_stag_e, &
  85. we_mem_s, we_mem_e, we_mem_stag_s, we_mem_stag_e, &
  86. sn_mem_s, sn_mem_e, sn_mem_stag_s, sn_mem_stag_e, &
  87. got_const_field, &
  88. map_proj, mminlu, num_land_cat, is_water, is_lake, is_ice, is_urban, i_soilwater, &
  89. grid_id, parent_id, i_parent_start, &
  90. j_parent_start, i_parent_end, j_parent_end, dom_dx, dom_dy, &
  91. cen_lat, moad_cen_lat, cen_lon, stand_lon, truelat1, truelat2, &
  92. pole_lat, pole_lon, parent_grid_ratio, sub_x, sub_y, &
  93. corner_lats, corner_lons, output_flags, 0)
  94. !
  95. ! Begin time-dependent processing
  96. !
  97. allocate(td_output_flags(num_entries))
  98. allocate(got_this_field (num_entries))
  99. ! Loop over all times to be processed for this domain
  100. do t=0,n_times
  101. call geth_newdate(valid_date, trim(start_date(n)), t*interval_seconds)
  102. temp_date = ' '
  103. if (mod(interval_seconds,3600) == 0) then
  104. write(temp_date,'(a13)') valid_date(1:10)//'_'//valid_date(12:13)
  105. else if (mod(interval_seconds,60) == 0) then
  106. write(temp_date,'(a16)') valid_date(1:10)//'_'//valid_date(12:16)
  107. else
  108. write(temp_date,'(a19)') valid_date(1:10)//'_'//valid_date(12:19)
  109. end if
  110. call mprintf(.true.,STDOUT, ' Processing %s', s1=trim(temp_date))
  111. call mprintf(.true.,LOGFILE, 'Preparing to process output time %s', s1=temp_date)
  112. do i=1,num_entries
  113. td_output_flags(i) = output_flags(i)
  114. got_this_field(i) = got_const_field(i)
  115. end do
  116. if (t > 0) then
  117. process_bdy_width = process_only_bdy
  118. else
  119. process_bdy_width = 0
  120. end if
  121. call process_single_met_time(.false., temp_date, n, extra_row, extra_col, xlat, xlon, &
  122. xlat_u, xlon_u, xlat_v, xlon_v, landmask, &
  123. title, dyn_opt, &
  124. west_east_dim, south_north_dim, &
  125. we_dom_s, we_dom_e, sn_dom_s, sn_dom_e, &
  126. we_patch_s, we_patch_e, we_patch_stag_s, we_patch_stag_e, &
  127. sn_patch_s, sn_patch_e, sn_patch_stag_s, sn_patch_stag_e, &
  128. we_mem_s, we_mem_e, we_mem_stag_s, we_mem_stag_e, &
  129. sn_mem_s, sn_mem_e, sn_mem_stag_s, sn_mem_stag_e, &
  130. got_this_field, &
  131. map_proj, mminlu, num_land_cat, is_water, is_lake, is_ice, is_urban, i_soilwater, &
  132. grid_id, parent_id, i_parent_start, &
  133. j_parent_start, i_parent_end, j_parent_end, dom_dx, dom_dy, &
  134. cen_lat, moad_cen_lat, cen_lon, stand_lon, truelat1, truelat2, &
  135. pole_lat, pole_lon, parent_grid_ratio, sub_x, sub_y, &
  136. corner_lats, corner_lons, td_output_flags, process_bdy_width)
  137. end do ! Loop over n_times
  138. deallocate(td_output_flags)
  139. deallocate(got_this_field)
  140. deallocate(output_flags)
  141. deallocate(got_const_field)
  142. call storage_delete_all()
  143. end subroutine process_domain
  144. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  145. ! Name: get_static_fields
  146. !
  147. ! Purpose:
  148. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  149. subroutine get_static_fields(n, dyn_opt, west_east_dim, south_north_dim, bottom_top_dim, &
  150. map_proj, &
  151. we_dom_s, we_dom_e, sn_dom_s, sn_dom_e, &
  152. we_patch_s, we_patch_e, we_patch_stag_s, we_patch_stag_e, &
  153. sn_patch_s, sn_patch_e, sn_patch_stag_s, sn_patch_stag_e, &
  154. we_mem_s, we_mem_e, we_mem_stag_s, we_mem_stag_e, &
  155. sn_mem_s, sn_mem_e, sn_mem_stag_s, sn_mem_stag_e, &
  156. mminlu, num_land_cat, is_water, is_lake, is_ice, is_urban, i_soilwater, &
  157. grid_id, parent_id, &
  158. i_parent_start, j_parent_start, i_parent_end, j_parent_end, &
  159. parent_grid_ratio, sub_x, sub_y, &
  160. cen_lat, moad_cen_lat, cen_lon, stand_lon, truelat1, truelat2, &
  161. pole_lat, pole_lon, dom_dx, dom_dy, landmask, xlat, xlon, xlat_u, xlon_u, &
  162. xlat_v, xlon_v, corner_lats, corner_lons, title)
  163. use gridinfo_module
  164. use input_module
  165. use llxy_module
  166. use parallel_module
  167. use storage_module
  168. use module_debug
  169. implicit none
  170. ! Arguments
  171. integer, intent(in) :: n
  172. integer, intent(inout) :: dyn_opt, west_east_dim, south_north_dim, bottom_top_dim, &
  173. map_proj, &
  174. we_dom_s, we_dom_e, sn_dom_s, sn_dom_e, &
  175. we_patch_s, we_patch_e, we_patch_stag_s, we_patch_stag_e, &
  176. sn_patch_s, sn_patch_e, sn_patch_stag_s, sn_patch_stag_e, &
  177. we_mem_s, we_mem_e, we_mem_stag_s, we_mem_stag_e, &
  178. sn_mem_s, sn_mem_e, sn_mem_stag_s, sn_mem_stag_e, &
  179. is_water, is_lake, is_ice, is_urban, i_soilwater, grid_id, parent_id, &
  180. i_parent_start, j_parent_start, i_parent_end, j_parent_end, &
  181. parent_grid_ratio, sub_x, sub_y, num_land_cat
  182. real, pointer, dimension(:,:) :: landmask
  183. real, intent(inout) :: cen_lat, moad_cen_lat, cen_lon, stand_lon, truelat1, truelat2, &
  184. dom_dx, dom_dy, pole_lat, pole_lon
  185. real, pointer, dimension(:,:) :: xlat, xlon, xlat_u, xlon_u, xlat_v, xlon_v
  186. real, dimension(16), intent(out) :: corner_lats, corner_lons
  187. character (len=128), intent(inout) :: title, mminlu
  188. ! Local variables
  189. integer :: istatus, i, j, k, sp1, ep1, sp2, ep2, sp3, ep3, &
  190. lh_mult, rh_mult, bh_mult, th_mult
  191. integer :: we_mem_subgrid_s, we_mem_subgrid_e, &
  192. sn_mem_subgrid_s, sn_mem_subgrid_e
  193. integer :: we_patch_subgrid_s, we_patch_subgrid_e, &
  194. sn_patch_subgrid_s, sn_patch_subgrid_e
  195. real, pointer, dimension(:,:,:) :: real_array
  196. character (len=3) :: memorder
  197. character (len=128) :: grid_type, datestr, cname, stagger, cunits, cdesc
  198. character (len=128), dimension(3) :: dimnames
  199. type (fg_input) :: field
  200. logical :: is_subgrid
  201. ! Initialize the input module to read static input data for this domain
  202. call mprintf(.true.,LOGFILE,'Opening static input file.')
  203. call input_init(n, istatus)
  204. call mprintf((istatus /= 0),ERROR, 'input_init(): Error opening input for domain %i.', i1=n)
  205. ! Read global attributes from the static data input file
  206. call mprintf(.true.,LOGFILE,'Reading static global attributes.')
  207. call read_global_attrs(title, datestr, grid_type, dyn_opt, west_east_dim, &
  208. south_north_dim, bottom_top_dim, &
  209. we_patch_s, we_patch_e, we_patch_stag_s, we_patch_stag_e, &
  210. sn_patch_s, sn_patch_e, sn_patch_stag_s, sn_patch_stag_e, &
  211. map_proj, mminlu, num_land_cat, &
  212. is_water, is_lake, is_ice, is_urban, i_soilwater, &
  213. grid_id, parent_id, i_parent_start, &
  214. j_parent_start, i_parent_end, j_parent_end, dom_dx, dom_dy, &
  215. cen_lat, moad_cen_lat, cen_lon, stand_lon, truelat1, &
  216. truelat2, pole_lat, pole_lon, parent_grid_ratio, &
  217. corner_lats, corner_lons, sub_x, sub_y)
  218. we_dom_s = 1
  219. sn_dom_s = 1
  220. if (grid_type(1:1) == 'C') then
  221. we_dom_e = west_east_dim - 1
  222. sn_dom_e = south_north_dim - 1
  223. else if (grid_type(1:1) == 'E') then
  224. we_dom_e = west_east_dim
  225. sn_dom_e = south_north_dim
  226. end if
  227. ! Given the full dimensions of this domain, find out the range of indices
  228. ! that will be worked on by this processor. This information is given by
  229. ! my_minx, my_miny, my_maxx, my_maxy
  230. call parallel_get_tile_dims(west_east_dim, south_north_dim)
  231. ! Must figure out patch dimensions from info in parallel module
  232. if (nprocs > 1 .and. .not. do_tiled_input) then
  233. we_patch_s = my_minx
  234. we_patch_stag_s = my_minx
  235. we_patch_e = my_maxx - 1
  236. sn_patch_s = my_miny
  237. sn_patch_stag_s = my_miny
  238. sn_patch_e = my_maxy - 1
  239. if (gridtype == 'C') then
  240. if (my_x /= nproc_x - 1) then
  241. we_patch_e = we_patch_e + 1
  242. we_patch_stag_e = we_patch_e
  243. else
  244. we_patch_stag_e = we_patch_e + 1
  245. end if
  246. if (my_y /= nproc_y - 1) then
  247. sn_patch_e = sn_patch_e + 1
  248. sn_patch_stag_e = sn_patch_e
  249. else
  250. sn_patch_stag_e = sn_patch_e + 1
  251. end if
  252. else if (gridtype == 'E') then
  253. we_patch_e = we_patch_e + 1
  254. sn_patch_e = sn_patch_e + 1
  255. we_patch_stag_e = we_patch_e
  256. sn_patch_stag_e = sn_patch_e
  257. end if
  258. end if
  259. ! Compute multipliers for halo width; these must be 0/1
  260. if (my_x /= 0) then
  261. lh_mult = 1
  262. else
  263. lh_mult = 0
  264. end if
  265. if (my_x /= (nproc_x-1)) then
  266. rh_mult = 1
  267. else
  268. rh_mult = 0
  269. end if
  270. if (my_y /= 0) then
  271. bh_mult = 1
  272. else
  273. bh_mult = 0
  274. end if
  275. if (my_y /= (nproc_y-1)) then
  276. th_mult = 1
  277. else
  278. th_mult = 0
  279. end if
  280. we_mem_s = we_patch_s - HALO_WIDTH*lh_mult
  281. we_mem_e = we_patch_e + HALO_WIDTH*rh_mult
  282. sn_mem_s = sn_patch_s - HALO_WIDTH*bh_mult
  283. sn_mem_e = sn_patch_e + HALO_WIDTH*th_mult
  284. we_mem_stag_s = we_patch_stag_s - HALO_WIDTH*lh_mult
  285. we_mem_stag_e = we_patch_stag_e + HALO_WIDTH*rh_mult
  286. sn_mem_stag_s = sn_patch_stag_s - HALO_WIDTH*bh_mult
  287. sn_mem_stag_e = sn_patch_stag_e + HALO_WIDTH*th_mult
  288. ! Initialize a proj_info type for the destination grid projection. This will
  289. ! primarily be used for rotating Earth-relative winds to grid-relative winds
  290. call set_domain_projection(map_proj, stand_lon, truelat1, truelat2, &
  291. dom_dx, dom_dy, dom_dx, dom_dy, west_east_dim, &
  292. south_north_dim, real(west_east_dim)/2., &
  293. real(south_north_dim)/2.,cen_lat, cen_lon, &
  294. cen_lat, cen_lon)
  295. ! Read static fields using the input module; we know that there are no more
  296. ! fields to be read when read_next_field() returns a non-zero status.
  297. istatus = 0
  298. do while (istatus == 0)
  299. call read_next_field(sp1, ep1, sp2, ep2, sp3, ep3, cname, cunits, cdesc, &
  300. memorder, stagger, dimnames, is_subgrid, &
  301. real_array, istatus)
  302. if (istatus == 0) then
  303. call mprintf(.true.,LOGFILE, 'Read in static field %s.',s1=cname)
  304. ! We will also keep copies in core of the lat/lon arrays, for use in
  305. ! interpolation of the met fields to the model grid.
  306. ! For now, we assume that the lat/lon arrays will have known field names
  307. if (index(cname, 'XLAT_M') /= 0 .and. &
  308. len_trim(cname) == len_trim('XLAT_M')) then
  309. allocate(xlat(we_mem_s:we_mem_e,sn_mem_s:sn_mem_e))
  310. xlat(we_patch_s:we_patch_e,sn_patch_s:sn_patch_e) = real_array(:,:,1)
  311. call exchange_halo_r(xlat, &
  312. we_mem_s, we_mem_e, sn_mem_s, sn_mem_e, 1, 1, &
  313. we_patch_s, we_patch_e, sn_patch_s, sn_patch_e, 1, 1)
  314. else if (index(cname, 'XLONG_M') /= 0 .and. &
  315. len_trim(cname) == len_trim('XLONG_M')) then
  316. allocate(xlon(we_mem_s:we_mem_e,sn_mem_s:sn_mem_e))
  317. xlon(we_patch_s:we_patch_e,sn_patch_s:sn_patch_e) = real_array(:,:,1)
  318. call exchange_halo_r(xlon, &
  319. we_mem_s, we_mem_e, sn_mem_s, sn_mem_e, 1, 1, &
  320. we_patch_s, we_patch_e, sn_patch_s, sn_patch_e, 1, 1)
  321. else if (index(cname, 'XLAT_U') /= 0 .and. &
  322. len_trim(cname) == len_trim('XLAT_U')) then
  323. allocate(xlat_u(we_mem_stag_s:we_mem_stag_e,sn_mem_s:sn_mem_e))
  324. xlat_u(we_patch_stag_s:we_patch_stag_e,sn_patch_s:sn_patch_e) = real_array(:,:,1)
  325. call exchange_halo_r(xlat_u, &
  326. we_mem_stag_s, we_mem_stag_e, sn_mem_s, sn_mem_e, 1, 1, &
  327. we_patch_stag_s, we_patch_stag_e, sn_patch_s, sn_patch_e, 1, 1)
  328. else if (index(cname, 'XLONG_U') /= 0 .and. &
  329. len_trim(cname) == len_trim('XLONG_U')) then
  330. allocate(xlon_u(we_mem_stag_s:we_mem_stag_e,sn_mem_s:sn_mem_e))
  331. xlon_u(we_patch_stag_s:we_patch_stag_e,sn_patch_s:sn_patch_e) = real_array(:,:,1)
  332. call exchange_halo_r(xlon_u, &
  333. we_mem_stag_s, we_mem_stag_e, sn_mem_s, sn_mem_e, 1, 1, &
  334. we_patch_stag_s, we_patch_stag_e, sn_patch_s, sn_patch_e, 1, 1)
  335. else if (index(cname, 'XLAT_V') /= 0 .and. &
  336. len_trim(cname) == len_trim('XLAT_V')) then
  337. allocate(xlat_v(we_mem_s:we_mem_e,sn_mem_stag_s:sn_mem_stag_e))
  338. xlat_v(we_patch_s:we_patch_e,sn_patch_stag_s:sn_patch_stag_e) = real_array(:,:,1)
  339. call exchange_halo_r(xlat_v, &
  340. we_mem_s, we_mem_e, sn_mem_stag_s, sn_mem_stag_e, 1, 1, &
  341. we_patch_s, we_patch_e, sn_patch_stag_s, sn_patch_stag_e, 1, 1)
  342. else if (index(cname, 'XLONG_V') /= 0 .and. &
  343. len_trim(cname) == len_trim('XLONG_V')) then
  344. allocate(xlon_v(we_mem_s:we_mem_e,sn_mem_stag_s:sn_mem_stag_e))
  345. xlon_v(we_patch_s:we_patch_e,sn_patch_stag_s:sn_patch_stag_e) = real_array(:,:,1)
  346. call exchange_halo_r(xlon_v, &
  347. we_mem_s, we_mem_e, sn_mem_stag_s, sn_mem_stag_e, 1, 1, &
  348. we_patch_s, we_patch_e, sn_patch_stag_s, sn_patch_stag_e, 1, 1)
  349. else if (index(cname, 'LANDMASK') /= 0 .and. &
  350. len_trim(cname) == len_trim('LANDMASK')) then
  351. allocate(landmask(we_mem_s:we_mem_e,sn_mem_s:sn_mem_e))
  352. landmask(we_patch_s:we_patch_e,sn_patch_s:sn_patch_e) = real_array(:,:,1)
  353. call exchange_halo_r(landmask, &
  354. we_mem_s, we_mem_e, sn_mem_s, sn_mem_e, 1, 1, &
  355. we_patch_s, we_patch_e, sn_patch_s, sn_patch_e, 1, 1)
  356. end if
  357. we_mem_subgrid_s = (we_mem_s + HALO_WIDTH*lh_mult - 1)*sub_x - HALO_WIDTH*lh_mult + 1
  358. we_mem_subgrid_e = (we_mem_e + (1-rh_mult) - HALO_WIDTH*rh_mult )*sub_x + HALO_WIDTH*rh_mult
  359. we_patch_subgrid_s = (we_patch_s - 1)*sub_x + 1
  360. we_patch_subgrid_e = (we_patch_e + (1-rh_mult) )*sub_x
  361. sn_mem_subgrid_s = (sn_mem_s + HALO_WIDTH*bh_mult - 1)*sub_y - HALO_WIDTH*bh_mult + 1
  362. sn_mem_subgrid_e = (sn_mem_e + (1-th_mult) - HALO_WIDTH*th_mult )*sub_y + HALO_WIDTH*th_mult
  363. sn_patch_subgrid_s = (sn_patch_s - 1)*sub_y + 1
  364. sn_patch_subgrid_e = (sn_patch_e + (1-th_mult) )*sub_y
  365. ! Having read in a field, we write each level individually to the
  366. ! storage module; levels will be reassembled later on when they
  367. ! are written.
  368. do k=sp3,ep3
  369. field%header%sr_x=sub_x
  370. field%header%sr_y=sub_y
  371. field%header%is_subgrid=is_subgrid
  372. field%header%version = 1
  373. field%header%date = start_date(n)
  374. field%header%time_dependent = .false.
  375. field%header%mask_field = .false.
  376. field%header%forecast_hour = 0.0
  377. field%header%fg_source = 'geogrid_model'
  378. field%header%field = cname
  379. field%header%units = cunits
  380. field%header%description = cdesc
  381. field%header%vertical_coord = dimnames(3)
  382. field%header%vertical_level = k
  383. field%header%array_order = memorder
  384. field%header%is_wind_grid_rel = .true.
  385. field%header%array_has_missing_values = .false.
  386. if (gridtype == 'C') then
  387. if (is_subgrid) then
  388. field%map%stagger = M
  389. field%header%dim1(1) = we_mem_subgrid_s
  390. field%header%dim1(2) = we_mem_subgrid_e
  391. field%header%dim2(1) = sn_mem_subgrid_s
  392. field%header%dim2(2) = sn_mem_subgrid_e
  393. else if (trim(stagger) == 'M') then
  394. field%map%stagger = M
  395. field%header%dim1(1) = we_mem_s
  396. field%header%dim1(2) = we_mem_e
  397. field%header%dim2(1) = sn_mem_s
  398. field%header%dim2(2) = sn_mem_e
  399. else if (trim(stagger) == 'U') then
  400. field%map%stagger = U
  401. field%header%dim1(1) = we_mem_stag_s
  402. field%header%dim1(2) = we_mem_stag_e
  403. field%header%dim2(1) = sn_mem_s
  404. field%header%dim2(2) = sn_mem_e
  405. else if (trim(stagger) == 'V') then
  406. field%map%stagger = V
  407. field%header%dim1(1) = we_mem_s
  408. field%header%dim1(2) = we_mem_e
  409. field%header%dim2(1) = sn_mem_stag_s
  410. field%header%dim2(2) = sn_mem_stag_e
  411. end if
  412. else if (gridtype == 'E') then
  413. if (trim(stagger) == 'M') then
  414. field%map%stagger = HH
  415. else if (trim(stagger) == 'V') then
  416. field%map%stagger = VV
  417. end if
  418. field%header%dim1(1) = we_mem_s
  419. field%header%dim1(2) = we_mem_e
  420. field%header%dim2(1) = sn_mem_s
  421. field%header%dim2(2) = sn_mem_e
  422. end if
  423. allocate(field%valid_mask)
  424. if (is_subgrid) then
  425. allocate(field%r_arr(we_mem_subgrid_s:we_mem_subgrid_e,&
  426. sn_mem_subgrid_s:sn_mem_subgrid_e))
  427. field%r_arr(we_patch_subgrid_s:we_patch_subgrid_e,sn_patch_subgrid_s:sn_patch_subgrid_e) = &
  428. real_array(sp1:ep1,sp2:ep2,k)
  429. call exchange_halo_r(field%r_arr, &
  430. we_mem_subgrid_s, we_mem_subgrid_e, sn_mem_subgrid_s, sn_mem_subgrid_e, 1, 1, &
  431. we_patch_subgrid_s, we_patch_subgrid_e, sn_patch_subgrid_s, sn_patch_subgrid_e, 1, 1)
  432. call bitarray_create(field%valid_mask, &
  433. (we_mem_subgrid_e-we_mem_subgrid_s)+1, &
  434. (sn_mem_subgrid_e-sn_mem_subgrid_s)+1)
  435. do j=1,(sn_mem_subgrid_e-sn_mem_subgrid_s)+1
  436. do i=1,(we_mem_subgrid_e-we_mem_subgrid_s)+1
  437. call bitarray_set(field%valid_mask, i, j)
  438. end do
  439. end do
  440. else if (field%map%stagger == M .or. &
  441. field%map%stagger == HH .or. &
  442. field%map%stagger == VV) then
  443. allocate(field%r_arr(we_mem_s:we_mem_e,&
  444. sn_mem_s:sn_mem_e))
  445. field%r_arr(we_patch_s:we_patch_e,sn_patch_s:sn_patch_e) = real_array(sp1:ep1,sp2:ep2,k)
  446. call exchange_halo_r(field%r_arr, &
  447. we_mem_s, we_mem_e, sn_mem_s, sn_mem_e, 1, 1, &
  448. we_patch_s, we_patch_e, sn_patch_s, sn_patch_e, 1, 1)
  449. call bitarray_create(field%valid_mask, &
  450. (we_mem_e-we_mem_s)+1, &
  451. (sn_mem_e-sn_mem_s)+1)
  452. do j=1,(sn_mem_e-sn_mem_s)+1
  453. do i=1,(we_mem_e-we_mem_s)+1
  454. call bitarray_set(field%valid_mask, i, j)
  455. end do
  456. end do
  457. else if (field%map%stagger == U) then
  458. allocate(field%r_arr(we_mem_stag_s:we_mem_stag_e,&
  459. sn_mem_s:sn_mem_e))
  460. field%r_arr(we_patch_stag_s:we_patch_stag_e,sn_patch_s:sn_patch_e) = real_array(sp1:ep1,sp2:ep2,k)
  461. call exchange_halo_r(field%r_arr, &
  462. we_mem_stag_s, we_mem_stag_e, sn_mem_s, sn_mem_e, 1, 1, &
  463. we_patch_stag_s, we_patch_stag_e, sn_patch_s, sn_patch_e, 1, 1)
  464. call bitarray_create(field%valid_mask, &
  465. (we_mem_stag_e-we_mem_stag_s)+1, &
  466. (sn_mem_e-sn_mem_s)+1)
  467. do j=1,(sn_mem_e-sn_mem_s)+1
  468. do i=1,(we_mem_stag_e-we_mem_stag_s)+1
  469. call bitarray_set(field%valid_mask, i, j)
  470. end do
  471. end do
  472. else if (field%map%stagger == V) then
  473. allocate(field%r_arr(we_mem_s:we_mem_e,&
  474. sn_mem_stag_s:sn_mem_stag_e))
  475. field%r_arr(we_patch_s:we_patch_e,sn_patch_stag_s:sn_patch_stag_e) = real_array(sp1:ep1,sp2:ep2,k)
  476. call exchange_halo_r(field%r_arr, &
  477. we_mem_s, we_mem_e, sn_mem_stag_s, sn_mem_stag_e, 1, 1, &
  478. we_patch_s, we_patch_e, sn_patch_stag_s, sn_patch_stag_e, 1, 1)
  479. call bitarray_create(field%valid_mask, &
  480. (we_mem_e-we_mem_s)+1, &
  481. (sn_mem_stag_e-sn_mem_stag_s)+1)
  482. do j=1,(sn_mem_stag_e-sn_mem_stag_s)+1
  483. do i=1,(we_mem_e-we_mem_s)+1
  484. call bitarray_set(field%valid_mask, i, j)
  485. end do
  486. end do
  487. end if
  488. nullify(field%modified_mask)
  489. call storage_put_field(field)
  490. end do
  491. end if
  492. end do
  493. ! Done reading all static fields for this domain
  494. call input_close()
  495. end subroutine get_static_fields
  496. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  497. ! Name: process_single_met_time
  498. !
  499. ! Purpose:
  500. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  501. subroutine process_single_met_time(do_const_processing, &
  502. temp_date, n, extra_row, extra_col, xlat, xlon, &
  503. xlat_u, xlon_u, xlat_v, xlon_v, landmask, &
  504. title, dyn_opt, &
  505. west_east_dim, south_north_dim, &
  506. we_domain_s, we_domain_e, sn_domain_s, sn_domain_e, &
  507. we_patch_s, we_patch_e, we_patch_stag_s, we_patch_stag_e, &
  508. sn_patch_s, sn_patch_e, sn_patch_stag_s, sn_patch_stag_e, &
  509. we_mem_s, we_mem_e, we_mem_stag_s, we_mem_stag_e, &
  510. sn_mem_s, sn_mem_e, sn_mem_stag_s, sn_mem_stag_e, &
  511. got_this_field, &
  512. map_proj, mminlu, num_land_cat, is_water, is_lake, is_ice, is_urban, i_soilwater, &
  513. grid_id, parent_id, i_parent_start, &
  514. j_parent_start, i_parent_end, j_parent_end, dom_dx, dom_dy, &
  515. cen_lat, moad_cen_lat, cen_lon, stand_lon, truelat1, truelat2, &
  516. pole_lat, pole_lon, parent_grid_ratio, sub_x, sub_y, &
  517. corner_lats, corner_lons, output_flags, process_bdy_width)
  518. use bitarray_module
  519. use gridinfo_module
  520. use interp_module
  521. use interp_option_module
  522. use llxy_module
  523. use misc_definitions_module
  524. use module_debug
  525. use output_module
  526. use parallel_module
  527. use read_met_module
  528. use rotate_winds_module
  529. use storage_module
  530. implicit none
  531. ! Arguments
  532. logical, intent(in) :: do_const_processing
  533. integer, intent(in) :: n, dyn_opt, west_east_dim, south_north_dim, map_proj, &
  534. we_domain_s, we_domain_e, sn_domain_s, sn_domain_e, &
  535. we_patch_s, we_patch_e, we_patch_stag_s, we_patch_stag_e, &
  536. sn_patch_s, sn_patch_e, sn_patch_stag_s, sn_patch_stag_e, &
  537. we_mem_s, we_mem_e, we_mem_stag_s, we_mem_stag_e, &
  538. sn_mem_s, sn_mem_e, sn_mem_stag_s, sn_mem_stag_e, &
  539. is_water, is_lake, is_ice, is_urban, i_soilwater, &
  540. grid_id, parent_id, i_parent_start, j_parent_start, &
  541. i_parent_end, j_parent_end, parent_grid_ratio, sub_x, sub_y, num_land_cat, &
  542. process_bdy_width
  543. ! BUG: Should we be passing these around as pointers, or just declare them as arrays?
  544. real, pointer, dimension(:,:) :: landmask
  545. real, intent(in) :: dom_dx, dom_dy, cen_lat, moad_cen_lat, cen_lon, stand_lon, &
  546. truelat1, truelat2, pole_lat, pole_lon
  547. real, dimension(16), intent(in) :: corner_lats, corner_lons
  548. real, pointer, dimension(:,:) :: xlat, xlon, xlat_u, xlon_u, xlat_v, xlon_v
  549. logical, intent(in) :: extra_row, extra_col
  550. logical, dimension(:), intent(inout) :: got_this_field
  551. character (len=19), intent(in) :: temp_date
  552. character (len=128), intent(in) :: mminlu
  553. character (len=128), dimension(:), intent(inout) :: output_flags
  554. ! BUG: Move this constant to misc_definitions_module?
  555. integer, parameter :: BDR_WIDTH = 3
  556. ! Local variables
  557. integer :: istatus, iqstatus, fg_idx, idx, idxt, i, j, bottom_top_dim, &
  558. sm1, em1, sm2, em2, sm3, em3, &
  559. sp1, ep1, sp2, ep2, sp3, ep3, &
  560. sd1, ed1, sd2, ed2, sd3, ed3, &
  561. u_idx, bdr_wdth
  562. integer :: nmet_flags
  563. integer :: num_metgrid_soil_levs
  564. integer, pointer, dimension(:) :: soil_levels
  565. real :: rx, ry
  566. real :: threshold
  567. logical :: do_gcell_interp
  568. integer, pointer, dimension(:) :: u_levels, v_levels
  569. real, pointer, dimension(:,:) :: halo_slab
  570. real, pointer, dimension(:,:,:) :: real_array
  571. character (len=19) :: output_date
  572. character (len=128) :: cname, title
  573. character (len=MAX_FILENAME_LEN) :: input_name
  574. character (len=128), allocatable, dimension(:) :: met_flags
  575. type (fg_input) :: field, u_field, v_field
  576. type (met_data) :: fg_data
  577. ! For this time, we need to process all first-guess filename roots. When we
  578. ! hit a root containing a '*', we assume we have hit the end of the list
  579. fg_idx = 1
  580. if (do_const_processing) then
  581. input_name = constants_name(fg_idx)
  582. else
  583. input_name = fg_name(fg_idx)
  584. end if
  585. do while (input_name /= '*')
  586. call mprintf(.true.,STDOUT, ' %s', s1=input_name)
  587. call mprintf(.true.,LOGFILE, 'Getting input fields from %s', s1=input_name)
  588. ! Do a first pass through this fg source to get all mask fields used
  589. ! during interpolation
  590. call get_interp_masks(trim(input_name), do_const_processing, temp_date)
  591. istatus = 0
  592. ! Initialize the module for reading in the met fields
  593. call read_met_init(trim(input_name), do_const_processing, temp_date, istatus)
  594. if (istatus == 0) then
  595. ! Process all fields and levels from the current file; read_next_met_field()
  596. ! will return a non-zero status when there are no more fields to be read.
  597. do while (istatus == 0)
  598. call read_next_met_field(fg_data, istatus)
  599. if (istatus == 0) then
  600. ! Find index into fieldname, interp_method, masked, and fill_missing
  601. ! of the current field
  602. idxt = num_entries + 1
  603. do idx=1,num_entries
  604. if ((index(fieldname(idx), trim(fg_data%field)) /= 0) .and. &
  605. (len_trim(fieldname(idx)) == len_trim(fg_data%field))) then
  606. got_this_field(idx) = .true.
  607. if (index(input_name,trim(from_input(idx))) /= 0 .or. &
  608. (from_input(idx) == '*' .and. idxt == num_entries + 1)) then
  609. idxt = idx
  610. end if
  611. end if
  612. end do
  613. idx = idxt
  614. if (idx > num_entries) idx = num_entries ! The last entry is a default
  615. ! Do we need to rename this field?
  616. if (output_name(idx) /= ' ') then
  617. fg_data%field = output_name(idx)(1:9)
  618. idxt = num_entries + 1
  619. do idx=1,num_entries
  620. if ((index(fieldname(idx), trim(fg_data%field)) /= 0) .and. &
  621. (len_trim(fieldname(idx)) == len_trim(fg_data%field))) then
  622. got_this_field(idx) = .true.
  623. if (index(input_name,trim(from_input(idx))) /= 0 .or. &
  624. (from_input(idx) == '*' .and. idxt == num_entries + 1)) then
  625. idxt = idx
  626. end if
  627. end if
  628. end do
  629. idx = idxt
  630. if (idx > num_entries) idx = num_entries ! The last entry is a default
  631. end if
  632. ! Do a simple check to see whether this is a global dataset
  633. ! Note that we do not currently support regional Gaussian grids
  634. if ((fg_data%iproj == PROJ_LATLON .and. abs(fg_data%nx * fg_data%deltalon - 360.) < 0.0001) &
  635. .or. (fg_data%iproj == PROJ_GAUSS)) then
  636. bdr_wdth = BDR_WIDTH
  637. allocate(halo_slab(1-BDR_WIDTH:fg_data%nx+BDR_WIDTH,1:fg_data%ny))
  638. halo_slab(1:fg_data%nx, 1:fg_data%ny) = &
  639. fg_data%slab(1:fg_data%nx, 1:fg_data%ny)
  640. halo_slab(1-BDR_WIDTH:0, 1:fg_data%ny) = &
  641. fg_data%slab(fg_data%nx-BDR_WIDTH+1:fg_data%nx, 1:fg_data%ny)
  642. halo_slab(fg_data%nx+1:fg_data%nx+BDR_WIDTH, 1:fg_data%ny) = &
  643. fg_data%slab(1:BDR_WIDTH, 1:fg_data%ny)
  644. deallocate(fg_data%slab)
  645. else
  646. bdr_wdth = 0
  647. halo_slab => fg_data%slab
  648. nullify(fg_data%slab)
  649. end if
  650. call mprintf(.true.,LOGFILE,'Processing %s at level %f.',s1=fg_data%field,f1=fg_data%xlvl)
  651. call push_source_projection(fg_data%iproj, fg_data%xlonc, fg_data%truelat1, &
  652. fg_data%truelat2, fg_data%dx, fg_data%dy, fg_data%deltalat, &
  653. fg_data%deltalon, fg_data%starti, fg_data%startj, &
  654. fg_data%startlat, fg_data%startlon, earth_radius=fg_data%earth_radius*1000.)
  655. ! Initialize fg_input structure to store the field
  656. field%header%version = 1
  657. field%header%date = fg_data%hdate//' '
  658. if (do_const_processing) then
  659. field%header%time_dependent = .false.
  660. else
  661. field%header%time_dependent = .true.
  662. end if
  663. field%header%forecast_hour = fg_data%xfcst
  664. field%header%fg_source = 'FG'
  665. field%header%field = ' '
  666. field%header%field(1:9) = fg_data%field
  667. field%header%units = ' '
  668. field%header%units(1:25) = fg_data%units
  669. field%header%description = ' '
  670. field%header%description(1:46) = fg_data%desc
  671. call get_z_dim_name(fg_data%field,field%header%vertical_coord)
  672. field%header%vertical_level = nint(fg_data%xlvl)
  673. field%header%sr_x = sub_x
  674. field%header%sr_y = sub_y
  675. field%header%is_subgrid = .false.
  676. field%header%array_order = 'XY '
  677. field%header%is_wind_grid_rel = fg_data%is_wind_grid_rel
  678. field%header%array_has_missing_values = .false.
  679. nullify(field%r_arr)
  680. nullify(field%valid_mask)
  681. nullify(field%modified_mask)
  682. if (output_this_field(idx) .and. flag_in_output(idx) /= ' ') then
  683. output_flags(idx) = flag_in_output(idx)
  684. end if
  685. ! If we should not output this field, just list it as a mask field
  686. if (output_this_field(idx)) then
  687. field%header%mask_field = .false.
  688. else
  689. field%header%mask_field = .true.
  690. end if
  691. !
  692. ! Before actually doing any interpolation to the model grid, we must check
  693. ! whether we will be using the average_gcell interpolator that averages all
  694. ! source points in each model grid cell
  695. !
  696. do_gcell_interp = .false.
  697. if (index(interp_method(idx),'average_gcell') /= 0) then
  698. call get_gcell_threshold(interp_method(idx), threshold, istatus)
  699. if (istatus == 0) then
  700. if (fg_data%dx == 0. .and. fg_data%dy == 0. .and. &
  701. fg_data%deltalat /= 0. .and. fg_data%deltalon /= 0.) then
  702. fg_data%dx = abs(fg_data%deltalon)
  703. fg_data%dy = abs(fg_data%deltalat)
  704. else
  705. ! BUG: Need to more correctly handle dx/dy in meters.
  706. fg_data%dx = fg_data%dx / 111000. ! Convert meters to approximate degrees
  707. fg_data%dy = fg_data%dy / 111000.
  708. end if
  709. if (gridtype == 'C') then
  710. if (threshold*max(fg_data%dx,fg_data%dy)*111. <= max(dom_dx,dom_dy)/1000.) &
  711. do_gcell_interp = .true.
  712. else if (gridtype == 'E') then
  713. if (threshold*max(fg_data%dx,fg_data%dy) <= max(dom_dx,dom_dy)) &
  714. do_gcell_interp = .true.
  715. end if
  716. end if
  717. end if
  718. ! Interpolate to U staggering
  719. if (output_stagger(idx) == U) then
  720. call storage_query_field(field, iqstatus)
  721. if (iqstatus == 0) then
  722. call storage_get_field(field, iqstatus)
  723. call mprintf((iqstatus /= 0),ERROR,'Queried field %s at level %i and found it,'// &
  724. ' but could not get data.',s1=fg_data%field,i1=nint(fg_data%xlvl))
  725. if (associated(field%modified_mask)) then
  726. call bitarray_destroy(field%modified_mask)
  727. nullify(field%modified_mask)
  728. end if
  729. else
  730. allocate(field%valid_mask)
  731. call bitarray_create(field%valid_mask, we_mem_stag_e-we_mem_stag_s+1, sn_mem_e-sn_mem_s+1)
  732. end if
  733. ! Save a copy of the fg_input structure for the U field so that we can find it later
  734. if (is_u_field(idx)) call dup(field, u_field)
  735. allocate(field%modified_mask)
  736. call bitarray_create(field%modified_mask, we_mem_stag_e-we_mem_stag_s+1, sn_mem_e-sn_mem_s+1)
  737. if (do_const_processing .or. field%header%time_dependent) then
  738. call interp_met_field(input_name, fg_data%field, U, M, &
  739. field, xlat_u, xlon_u, we_mem_stag_s, we_mem_stag_e, sn_mem_s, sn_mem_e, &
  740. we_domain_s, we_domain_e, sn_domain_s, sn_domain_e, &
  741. halo_slab, 1-bdr_wdth, fg_data%nx+bdr_wdth, 1, fg_data%ny, bdr_wdth, do_gcell_interp, &
  742. field%modified_mask, process_bdy_width)
  743. else
  744. call mprintf(.true.,INFORM,' - already processed this field from constant file.')
  745. end if
  746. ! Interpolate to V staggering
  747. else if (output_stagger(idx) == V) then
  748. call storage_query_field(field, iqstatus)
  749. if (iqstatus == 0) then
  750. call storage_get_field(field, iqstatus)
  751. call mprintf((iqstatus /= 0),ERROR,'Queried field %s at level %i and found it,'// &
  752. ' but could not get data.',s1=fg_data%field,i1=nint(fg_data%xlvl))
  753. if (associated(field%modified_mask)) then
  754. call bitarray_destroy(field%modified_mask)
  755. nullify(field%modified_mask)
  756. end if
  757. else
  758. allocate(field%valid_mask)
  759. call bitarray_create(field%valid_mask, we_mem_e-we_mem_s+1, sn_mem_stag_e-sn_mem_stag_s+1)
  760. end if
  761. ! Save a copy of the fg_input structure for the V field so that we can find it later
  762. if (is_v_field(idx)) call dup(field, v_field)
  763. allocate(field%modified_mask)
  764. call bitarray_create(field%modified_mask, we_mem_e-we_mem_s+1, sn_mem_stag_e-sn_mem_stag_s+1)
  765. if (do_const_processing .or. field%header%time_dependent) then
  766. call interp_met_field(input_name, fg_data%field, V, M, &
  767. field, xlat_v, xlon_v, we_mem_s, we_mem_e, sn_mem_stag_s, sn_mem_stag_e, &
  768. we_domain_s, we_domain_e, sn_domain_s, sn_domain_e, &
  769. halo_slab, 1-bdr_wdth, fg_data%nx+bdr_wdth, 1, fg_data%ny, bdr_wdth, do_gcell_interp, &
  770. field%modified_mask, process_bdy_width)
  771. else
  772. call mprintf(.true.,INFORM,' - already processed this field from constant file.')
  773. end if
  774. ! Interpolate to VV staggering
  775. else if (output_stagger(idx) == VV) then
  776. call storage_query_field(field, iqstatus)
  777. if (iqstatus == 0) then
  778. call storage_get_field(field, iqstatus)
  779. call mprintf((iqstatus /= 0),ERROR,'Queried field %s at level %i and found it,'// &
  780. ' but could not get data.',s1=fg_data%field,i1=nint(fg_data%xlvl))
  781. if (associated(field%modified_mask)) then
  782. call bitarray_destroy(field%modified_mask)
  783. nullify(field%modified_mask)
  784. end if
  785. else
  786. allocate(field%valid_mask)
  787. call bitarray_create(field%valid_mask, we_mem_e-we_mem_s+1, sn_mem_e-sn_mem_s+1)
  788. end if
  789. ! Save a copy of the fg_input structure for the U field so that we can find it later
  790. if (is_u_field(idx)) call dup(field, u_field)
  791. ! Save a copy of the fg_input structure for the V field so that we can find it later
  792. if (is_v_field(idx)) call dup(field, v_field)
  793. allocate(field%modified_mask)
  794. call bitarray_create(field%modified_mask, we_mem_e-we_mem_s+1, sn_mem_e-sn_mem_s+1)
  795. if (do_const_processing .or. field%header%time_dependent) then
  796. call interp_met_field(input_name, fg_data%field, VV, M, &
  797. field, xlat_v, xlon_v, we_mem_s, we_mem_e, sn_mem_s, sn_mem_e, &
  798. we_domain_s, we_domain_e, sn_domain_s, sn_domain_e, &
  799. halo_slab, 1-bdr_wdth, fg_data%nx+bdr_wdth, 1, fg_data%ny, bdr_wdth, do_gcell_interp, &
  800. field%modified_mask, process_bdy_width)
  801. else
  802. call mprintf(.true.,INFORM,' - already processed this field from constant file.')
  803. end if
  804. ! All other fields interpolated to M staggering for C grid, H staggering for E grid
  805. else
  806. call storage_query_field(field, iqstatus)
  807. if (iqstatus == 0) then
  808. call storage_get_field(field, iqstatus)
  809. call mprintf((iqstatus /= 0),ERROR,'Queried field %s at level %i and found it,'// &
  810. ' but could not get data.',s1=fg_data%field,i1=nint(fg_data%xlvl))
  811. if (associated(field%modified_mask)) then
  812. call bitarray_destroy(field%modified_mask)
  813. nullify(field%modified_mask)
  814. end if
  815. else
  816. allocate(field%valid_mask)
  817. call bitarray_create(field%valid_mask, we_mem_e-we_mem_s+1, sn_mem_e-sn_mem_s+1)
  818. end if
  819. allocate(field%modified_mask)
  820. call bitarray_create(field%modified_mask, we_mem_e-we_mem_s+1, sn_mem_e-sn_mem_s+1)
  821. if (do_const_processing .or. field%header%time_dependent) then
  822. if (gridtype == 'C') then
  823. call interp_met_field(input_name, fg_data%field, M, M, &
  824. field, xlat, xlon, we_mem_s, we_mem_e, sn_mem_s, sn_mem_e, &
  825. we_domain_s, we_domain_e, sn_domain_s, sn_domain_e, &
  826. halo_slab, 1-bdr_wdth, fg_data%nx+bdr_wdth, 1, fg_data%ny, bdr_wdth, do_gcell_interp, &
  827. field%modified_mask, process_bdy_width, landmask)
  828. else if (gridtype == 'E') then
  829. call interp_met_field(input_name, fg_data%field, HH, M, &
  830. field, xlat, xlon, we_mem_s, we_mem_e, sn_mem_s, sn_mem_e, &
  831. we_domain_s, we_domain_e, sn_domain_s, sn_domain_e, &
  832. halo_slab, 1-bdr_wdth, fg_data%nx+bdr_wdth, 1, fg_data%ny, bdr_wdth, do_gcell_interp, &
  833. field%modified_mask, process_bdy_width, landmask)
  834. end if
  835. else
  836. call mprintf(.true.,INFORM,' - already processed this field from constant file.')
  837. end if
  838. end if
  839. call bitarray_merge(field%valid_mask, field%modified_mask)
  840. deallocate(halo_slab)
  841. ! Store the interpolated field
  842. call storage_put_f

Large files files are truncated, but you can click here to view the full file