PageRenderTime 75ms CodeModel.GetById 34ms RepoModel.GetById 0ms app.codeStats 1ms

/wrfv2_fire/frame/module_domain.F

https://github.com/jbeezley/wrf-fire
FORTRAN Legacy | 2991 lines | 1853 code | 300 blank | 838 comment | 9 complexity | 53f37e7c7f8d2d3bdfec4dc967189278 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. !WRF:DRIVER_LAYER:DOMAIN_OBJECT
  2. !
  3. ! Following are the routines contained within this MODULE:
  4. ! alloc_and_configure_domain 1. Allocate the space for a single domain (constants
  5. ! and null terminate pointers).
  6. ! 2. Connect the domains as a linked list.
  7. ! 3. Store all of the domain constants.
  8. ! 4. CALL alloc_space_field.
  9. ! alloc_space_field 1. Allocate space for the gridded data required for
  10. ! each domain.
  11. ! dealloc_space_domain 1. Reconnect linked list nodes since the current
  12. ! node is removed.
  13. ! 2. CALL dealloc_space_field.
  14. ! 3. Deallocate single domain.
  15. ! dealloc_space_field 1. Deallocate each of the fields for a particular
  16. ! domain.
  17. ! first_loc_integer 1. Find the first incidence of a particular
  18. ! domain identifier from an array of domain
  19. ! identifiers.
  20. MODULE module_domain
  21. USE module_driver_constants
  22. USE module_machine
  23. USE module_configure
  24. USE module_wrf_error
  25. USE module_utility
  26. USE module_domain_type
  27. ! In WRFV3, the module_domain_type is defined
  28. ! in a separaate source file, frame/module_domain_type.F
  29. ! This enables splitting off the alloc_space_field routine
  30. ! into a separate file, reducing the size of module_domain
  31. ! Now that a "domain" TYPE exists, we can use it to store a few pointers
  32. ! to this type. These are primarily for use in traversing the linked list.
  33. ! The "head_grid" is always the pointer to the first domain that is
  34. ! allocated. This is available and is not to be changed. The others are
  35. ! just temporary pointers.
  36. TYPE(domain) , POINTER :: head_grid , new_grid , next_grid , old_grid
  37. ! To facilitate an easy integration of each of the domains that are on the
  38. ! same level, we have an array for the head pointer for each level. This
  39. ! removed the need to search through the linked list at each time step to
  40. ! find which domains are to be active.
  41. TYPE domain_levels
  42. TYPE(domain) , POINTER :: first_domain
  43. END TYPE domain_levels
  44. TYPE(domain_levels) , DIMENSION(max_levels) :: head_for_each_level
  45. ! Use this to support debugging features, giving easy access to clock, etc.
  46. TYPE(domain), POINTER :: current_grid
  47. LOGICAL, SAVE :: current_grid_set = .FALSE.
  48. ! internal routines
  49. PRIVATE domain_time_test_print
  50. PRIVATE test_adjust_io_timestr
  51. INTERFACE get_ijk_from_grid
  52. MODULE PROCEDURE get_ijk_from_grid1, get_ijk_from_grid2
  53. END INTERFACE
  54. INTEGER, PARAMETER :: max_hst_mods = 200
  55. CONTAINS
  56. SUBROUTINE adjust_domain_dims_for_move( grid , dx, dy )
  57. IMPLICIT NONE
  58. TYPE( domain ), POINTER :: grid
  59. INTEGER, INTENT(IN) :: dx, dy
  60. data_ordering : SELECT CASE ( model_data_order )
  61. CASE ( DATA_ORDER_XYZ )
  62. grid%sm31 = grid%sm31 + dx
  63. grid%em31 = grid%em31 + dx
  64. grid%sm32 = grid%sm32 + dy
  65. grid%em32 = grid%em32 + dy
  66. grid%sp31 = grid%sp31 + dx
  67. grid%ep31 = grid%ep31 + dx
  68. grid%sp32 = grid%sp32 + dy
  69. grid%ep32 = grid%ep32 + dy
  70. grid%sd31 = grid%sd31 + dx
  71. grid%ed31 = grid%ed31 + dx
  72. grid%sd32 = grid%sd32 + dy
  73. grid%ed32 = grid%ed32 + dy
  74. CASE ( DATA_ORDER_YXZ )
  75. grid%sm31 = grid%sm31 + dy
  76. grid%em31 = grid%em31 + dy
  77. grid%sm32 = grid%sm32 + dx
  78. grid%em32 = grid%em32 + dx
  79. grid%sp31 = grid%sp31 + dy
  80. grid%ep31 = grid%ep31 + dy
  81. grid%sp32 = grid%sp32 + dx
  82. grid%ep32 = grid%ep32 + dx
  83. grid%sd31 = grid%sd31 + dy
  84. grid%ed31 = grid%ed31 + dy
  85. grid%sd32 = grid%sd32 + dx
  86. grid%ed32 = grid%ed32 + dx
  87. CASE ( DATA_ORDER_ZXY )
  88. grid%sm32 = grid%sm32 + dx
  89. grid%em32 = grid%em32 + dx
  90. grid%sm33 = grid%sm33 + dy
  91. grid%em33 = grid%em33 + dy
  92. grid%sp32 = grid%sp32 + dx
  93. grid%ep32 = grid%ep32 + dx
  94. grid%sp33 = grid%sp33 + dy
  95. grid%ep33 = grid%ep33 + dy
  96. grid%sd32 = grid%sd32 + dx
  97. grid%ed32 = grid%ed32 + dx
  98. grid%sd33 = grid%sd33 + dy
  99. grid%ed33 = grid%ed33 + dy
  100. CASE ( DATA_ORDER_ZYX )
  101. grid%sm32 = grid%sm32 + dy
  102. grid%em32 = grid%em32 + dy
  103. grid%sm33 = grid%sm33 + dx
  104. grid%em33 = grid%em33 + dx
  105. grid%sp32 = grid%sp32 + dy
  106. grid%ep32 = grid%ep32 + dy
  107. grid%sp33 = grid%sp33 + dx
  108. grid%ep33 = grid%ep33 + dx
  109. grid%sd32 = grid%sd32 + dy
  110. grid%ed32 = grid%ed32 + dy
  111. grid%sd33 = grid%sd33 + dx
  112. grid%ed33 = grid%ed33 + dx
  113. CASE ( DATA_ORDER_XZY )
  114. grid%sm31 = grid%sm31 + dx
  115. grid%em31 = grid%em31 + dx
  116. grid%sm33 = grid%sm33 + dy
  117. grid%em33 = grid%em33 + dy
  118. grid%sp31 = grid%sp31 + dx
  119. grid%ep31 = grid%ep31 + dx
  120. grid%sp33 = grid%sp33 + dy
  121. grid%ep33 = grid%ep33 + dy
  122. grid%sd31 = grid%sd31 + dx
  123. grid%ed31 = grid%ed31 + dx
  124. grid%sd33 = grid%sd33 + dy
  125. grid%ed33 = grid%ed33 + dy
  126. CASE ( DATA_ORDER_YZX )
  127. grid%sm31 = grid%sm31 + dy
  128. grid%em31 = grid%em31 + dy
  129. grid%sm33 = grid%sm33 + dx
  130. grid%em33 = grid%em33 + dx
  131. grid%sp31 = grid%sp31 + dy
  132. grid%ep31 = grid%ep31 + dy
  133. grid%sp33 = grid%sp33 + dx
  134. grid%ep33 = grid%ep33 + dx
  135. grid%sd31 = grid%sd31 + dy
  136. grid%ed31 = grid%ed31 + dy
  137. grid%sd33 = grid%sd33 + dx
  138. grid%ed33 = grid%ed33 + dx
  139. END SELECT data_ordering
  140. #if 0
  141. CALL dealloc_space_field ( grid )
  142. CALL alloc_space_field ( grid, grid%id , 1 , 2 , .FALSE. , &
  143. grid%sd31, grid%ed31, grid%sd32, grid%ed32, grid%sd33, grid%ed33, &
  144. grid%sm31, grid%em31, grid%sm32, grid%em32, grid%sm33, grid%em33, &
  145. grid%sp31, grid%ep31, grid%sp32, grid%ep32, grid%sp33, grid%ep33, &
  146. grid%sp31x, grid%ep31x, grid%sp32x, grid%ep32x, grid%sp33x, grid%ep33x, &
  147. grid%sp31y, grid%ep31y, grid%sp32y, grid%ep32y, grid%sp33y, grid%ep33y, &
  148. grid%sm31x, grid%em31x, grid%sm32x, grid%em32x, grid%sm33x, grid%em33x, & ! x-xpose
  149. grid%sm31y, grid%em31y, grid%sm32y, grid%em32y, grid%sm33y, grid%em33y & ! y-xpose
  150. )
  151. #endif
  152. RETURN
  153. END SUBROUTINE adjust_domain_dims_for_move
  154. #if 1
  155. SUBROUTINE get_ijk_from_grid1 ( grid , &
  156. ids, ide, jds, jde, kds, kde, &
  157. ims, ime, jms, jme, kms, kme, &
  158. ips, ipe, jps, jpe, kps, kpe, &
  159. imsx, imex, jmsx, jmex, kmsx, kmex, &
  160. ipsx, ipex, jpsx, jpex, kpsx, kpex, &
  161. imsy, imey, jmsy, jmey, kmsy, kmey, &
  162. ipsy, ipey, jpsy, jpey, kpsy, kpey )
  163. IMPLICIT NONE
  164. TYPE( domain ), INTENT (IN) :: grid
  165. INTEGER, INTENT(OUT) :: &
  166. ids, ide, jds, jde, kds, kde, &
  167. ims, ime, jms, jme, kms, kme, &
  168. ips, ipe, jps, jpe, kps, kpe, &
  169. imsx, imex, jmsx, jmex, kmsx, kmex, &
  170. ipsx, ipex, jpsx, jpex, kpsx, kpex, &
  171. imsy, imey, jmsy, jmey, kmsy, kmey, &
  172. ipsy, ipey, jpsy, jpey, kpsy, kpey
  173. CALL get_ijk_from_grid2 ( grid , &
  174. ids, ide, jds, jde, kds, kde, &
  175. ims, ime, jms, jme, kms, kme, &
  176. ips, ipe, jps, jpe, kps, kpe )
  177. data_ordering : SELECT CASE ( model_data_order )
  178. CASE ( DATA_ORDER_XYZ )
  179. imsx = grid%sm31x ; imex = grid%em31x ; jmsx = grid%sm32x ; jmex = grid%em32x ; kmsx = grid%sm33x ; kmex = grid%em33x ;
  180. ipsx = grid%sp31x ; ipex = grid%ep31x ; jpsx = grid%sp32x ; jpex = grid%ep32x ; kpsx = grid%sp33x ; kpex = grid%ep33x ;
  181. imsy = grid%sm31y ; imey = grid%em31y ; jmsy = grid%sm32y ; jmey = grid%em32y ; kmsy = grid%sm33y ; kmey = grid%em33y ;
  182. ipsy = grid%sp31y ; ipey = grid%ep31y ; jpsy = grid%sp32y ; jpey = grid%ep32y ; kpsy = grid%sp33y ; kpey = grid%ep33y ;
  183. CASE ( DATA_ORDER_YXZ )
  184. imsx = grid%sm32x ; imex = grid%em32x ; jmsx = grid%sm31x ; jmex = grid%em31x ; kmsx = grid%sm33x ; kmex = grid%em33x ;
  185. ipsx = grid%sp32x ; ipex = grid%ep32x ; jpsx = grid%sp31x ; jpex = grid%ep31x ; kpsx = grid%sp33x ; kpex = grid%ep33x ;
  186. imsy = grid%sm32y ; imey = grid%em32y ; jmsy = grid%sm31y ; jmey = grid%em31y ; kmsy = grid%sm33y ; kmey = grid%em33y ;
  187. ipsy = grid%sp32y ; ipey = grid%ep32y ; jpsy = grid%sp31y ; jpey = grid%ep31y ; kpsy = grid%sp33y ; kpey = grid%ep33y ;
  188. CASE ( DATA_ORDER_ZXY )
  189. imsx = grid%sm32x ; imex = grid%em32x ; jmsx = grid%sm33x ; jmex = grid%em33x ; kmsx = grid%sm31x ; kmex = grid%em31x ;
  190. ipsx = grid%sp32x ; ipex = grid%ep32x ; jpsx = grid%sp33x ; jpex = grid%ep33x ; kpsx = grid%sp31x ; kpex = grid%ep31x ;
  191. imsy = grid%sm32y ; imey = grid%em32y ; jmsy = grid%sm33y ; jmey = grid%em33y ; kmsy = grid%sm31y ; kmey = grid%em31y ;
  192. ipsy = grid%sp32y ; ipey = grid%ep32y ; jpsy = grid%sp33y ; jpey = grid%ep33y ; kpsy = grid%sp31y ; kpey = grid%ep31y ;
  193. CASE ( DATA_ORDER_ZYX )
  194. imsx = grid%sm33x ; imex = grid%em33x ; jmsx = grid%sm32x ; jmex = grid%em32x ; kmsx = grid%sm31x ; kmex = grid%em31x ;
  195. ipsx = grid%sp33x ; ipex = grid%ep33x ; jpsx = grid%sp32x ; jpex = grid%ep32x ; kpsx = grid%sp31x ; kpex = grid%ep31x ;
  196. imsy = grid%sm33y ; imey = grid%em33y ; jmsy = grid%sm32y ; jmey = grid%em32y ; kmsy = grid%sm31y ; kmey = grid%em31y ;
  197. ipsy = grid%sp33y ; ipey = grid%ep33y ; jpsy = grid%sp32y ; jpey = grid%ep32y ; kpsy = grid%sp31y ; kpey = grid%ep31y ;
  198. CASE ( DATA_ORDER_XZY )
  199. imsx = grid%sm31x ; imex = grid%em31x ; jmsx = grid%sm33x ; jmex = grid%em33x ; kmsx = grid%sm32x ; kmex = grid%em32x ;
  200. ipsx = grid%sp31x ; ipex = grid%ep31x ; jpsx = grid%sp33x ; jpex = grid%ep33x ; kpsx = grid%sp32x ; kpex = grid%ep32x ;
  201. imsy = grid%sm31y ; imey = grid%em31y ; jmsy = grid%sm33y ; jmey = grid%em33y ; kmsy = grid%sm32y ; kmey = grid%em32y ;
  202. ipsy = grid%sp31y ; ipey = grid%ep31y ; jpsy = grid%sp33y ; jpey = grid%ep33y ; kpsy = grid%sp32y ; kpey = grid%ep32y ;
  203. CASE ( DATA_ORDER_YZX )
  204. imsx = grid%sm33x ; imex = grid%em33x ; jmsx = grid%sm31x ; jmex = grid%em31x ; kmsx = grid%sm32x ; kmex = grid%em32x ;
  205. ipsx = grid%sp33x ; ipex = grid%ep33x ; jpsx = grid%sp31x ; jpex = grid%ep31x ; kpsx = grid%sp32x ; kpex = grid%ep32x ;
  206. imsy = grid%sm33y ; imey = grid%em33y ; jmsy = grid%sm31y ; jmey = grid%em31y ; kmsy = grid%sm32y ; kmey = grid%em32y ;
  207. ipsy = grid%sp33y ; ipey = grid%ep33y ; jpsy = grid%sp31y ; jpey = grid%ep31y ; kpsy = grid%sp32y ; kpey = grid%ep32y ;
  208. END SELECT data_ordering
  209. END SUBROUTINE get_ijk_from_grid1
  210. SUBROUTINE get_ijk_from_grid2 ( grid , &
  211. ids, ide, jds, jde, kds, kde, &
  212. ims, ime, jms, jme, kms, kme, &
  213. ips, ipe, jps, jpe, kps, kpe )
  214. IMPLICIT NONE
  215. TYPE( domain ), INTENT (IN) :: grid
  216. INTEGER, INTENT(OUT) :: &
  217. ids, ide, jds, jde, kds, kde, &
  218. ims, ime, jms, jme, kms, kme, &
  219. ips, ipe, jps, jpe, kps, kpe
  220. data_ordering : SELECT CASE ( model_data_order )
  221. CASE ( DATA_ORDER_XYZ )
  222. ids = grid%sd31 ; ide = grid%ed31 ; jds = grid%sd32 ; jde = grid%ed32 ; kds = grid%sd33 ; kde = grid%ed33 ;
  223. ims = grid%sm31 ; ime = grid%em31 ; jms = grid%sm32 ; jme = grid%em32 ; kms = grid%sm33 ; kme = grid%em33 ;
  224. ips = grid%sp31 ; ipe = grid%ep31 ; jps = grid%sp32 ; jpe = grid%ep32 ; kps = grid%sp33 ; kpe = grid%ep33 ;
  225. CASE ( DATA_ORDER_YXZ )
  226. ids = grid%sd32 ; ide = grid%ed32 ; jds = grid%sd31 ; jde = grid%ed31 ; kds = grid%sd33 ; kde = grid%ed33 ;
  227. ims = grid%sm32 ; ime = grid%em32 ; jms = grid%sm31 ; jme = grid%em31 ; kms = grid%sm33 ; kme = grid%em33 ;
  228. ips = grid%sp32 ; ipe = grid%ep32 ; jps = grid%sp31 ; jpe = grid%ep31 ; kps = grid%sp33 ; kpe = grid%ep33 ;
  229. CASE ( DATA_ORDER_ZXY )
  230. ids = grid%sd32 ; ide = grid%ed32 ; jds = grid%sd33 ; jde = grid%ed33 ; kds = grid%sd31 ; kde = grid%ed31 ;
  231. ims = grid%sm32 ; ime = grid%em32 ; jms = grid%sm33 ; jme = grid%em33 ; kms = grid%sm31 ; kme = grid%em31 ;
  232. ips = grid%sp32 ; ipe = grid%ep32 ; jps = grid%sp33 ; jpe = grid%ep33 ; kps = grid%sp31 ; kpe = grid%ep31 ;
  233. CASE ( DATA_ORDER_ZYX )
  234. ids = grid%sd33 ; ide = grid%ed33 ; jds = grid%sd32 ; jde = grid%ed32 ; kds = grid%sd31 ; kde = grid%ed31 ;
  235. ims = grid%sm33 ; ime = grid%em33 ; jms = grid%sm32 ; jme = grid%em32 ; kms = grid%sm31 ; kme = grid%em31 ;
  236. ips = grid%sp33 ; ipe = grid%ep33 ; jps = grid%sp32 ; jpe = grid%ep32 ; kps = grid%sp31 ; kpe = grid%ep31 ;
  237. CASE ( DATA_ORDER_XZY )
  238. ids = grid%sd31 ; ide = grid%ed31 ; jds = grid%sd33 ; jde = grid%ed33 ; kds = grid%sd32 ; kde = grid%ed32 ;
  239. ims = grid%sm31 ; ime = grid%em31 ; jms = grid%sm33 ; jme = grid%em33 ; kms = grid%sm32 ; kme = grid%em32 ;
  240. ips = grid%sp31 ; ipe = grid%ep31 ; jps = grid%sp33 ; jpe = grid%ep33 ; kps = grid%sp32 ; kpe = grid%ep32 ;
  241. CASE ( DATA_ORDER_YZX )
  242. ids = grid%sd33 ; ide = grid%ed33 ; jds = grid%sd31 ; jde = grid%ed31 ; kds = grid%sd32 ; kde = grid%ed32 ;
  243. ims = grid%sm33 ; ime = grid%em33 ; jms = grid%sm31 ; jme = grid%em31 ; kms = grid%sm32 ; kme = grid%em32 ;
  244. ips = grid%sp33 ; ipe = grid%ep33 ; jps = grid%sp31 ; jpe = grid%ep31 ; kps = grid%sp32 ; kpe = grid%ep32 ;
  245. END SELECT data_ordering
  246. END SUBROUTINE get_ijk_from_grid2
  247. ! return the values for subgrid whose refinement is in grid%sr
  248. ! note when using this routine, it does not affect K. For K
  249. ! (vertical), it just returns what get_ijk_from_grid does
  250. SUBROUTINE get_ijk_from_subgrid ( grid , &
  251. ids0, ide0, jds0, jde0, kds0, kde0, &
  252. ims0, ime0, jms0, jme0, kms0, kme0, &
  253. ips0, ipe0, jps0, jpe0, kps0, kpe0 )
  254. TYPE( domain ), INTENT (IN) :: grid
  255. INTEGER, INTENT(OUT) :: &
  256. ids0, ide0, jds0, jde0, kds0, kde0, &
  257. ims0, ime0, jms0, jme0, kms0, kme0, &
  258. ips0, ipe0, jps0, jpe0, kps0, kpe0
  259. ! Local
  260. INTEGER :: &
  261. ids, ide, jds, jde, kds, kde, &
  262. ims, ime, jms, jme, kms, kme, &
  263. ips, ipe, jps, jpe, kps, kpe
  264. CALL get_ijk_from_grid ( grid , &
  265. ids, ide, jds, jde, kds, kde, &
  266. ims, ime, jms, jme, kms, kme, &
  267. ips, ipe, jps, jpe, kps, kpe )
  268. ids0 = ids
  269. ide0 = ide * grid%sr_x
  270. ims0 = (ims-1)*grid%sr_x+1
  271. ime0 = ime * grid%sr_x
  272. ips0 = (ips-1)*grid%sr_x+1
  273. ipe0 = ipe * grid%sr_x
  274. jds0 = jds
  275. jde0 = jde * grid%sr_y
  276. jms0 = (jms-1)*grid%sr_y+1
  277. jme0 = jme * grid%sr_y
  278. jps0 = (jps-1)*grid%sr_y+1
  279. jpe0 = jpe * grid%sr_y
  280. kds0 = kds
  281. kde0 = kde
  282. kms0 = kms
  283. kme0 = kme
  284. kps0 = kps
  285. kpe0 = kpe
  286. RETURN
  287. END SUBROUTINE get_ijk_from_subgrid
  288. #endif
  289. ! Default version ; Otherwise module containing interface to DM library will provide
  290. SUBROUTINE wrf_patch_domain( id , domdesc , parent, parent_id , parent_domdesc , &
  291. sd1 , ed1 , sp1 , ep1 , sm1 , em1 , &
  292. sd2 , ed2 , sp2 , ep2 , sm2 , em2 , &
  293. sd3 , ed3 , sp3 , ep3 , sm3 , em3 , &
  294. sp1x , ep1x , sm1x , em1x , &
  295. sp2x , ep2x , sm2x , em2x , &
  296. sp3x , ep3x , sm3x , em3x , &
  297. sp1y , ep1y , sm1y , em1y , &
  298. sp2y , ep2y , sm2y , em2y , &
  299. sp3y , ep3y , sm3y , em3y , &
  300. bdx , bdy , bdy_mask )
  301. !<DESCRIPTION>
  302. ! Wrf_patch_domain is called as part of the process of initiating a new
  303. ! domain. Based on the global domain dimension information that is
  304. ! passed in it computes the patch and memory dimensions on this
  305. ! distributed-memory process for parallel compilation when DM_PARALLEL is
  306. ! defined in configure.wrf. In this case, it relies on an external
  307. ! communications package-contributed routine, wrf_dm_patch_domain. For
  308. ! non-parallel compiles, it returns the patch and memory dimensions based
  309. ! on the entire domain. In either case, the memory dimensions will be
  310. ! larger than the patch dimensions, since they allow for distributed
  311. ! memory halo regions (DM_PARALLEL only) and for boundary regions around
  312. ! the domain (used for idealized cases only). The width of the boundary
  313. ! regions to be accommodated is passed in as bdx and bdy.
  314. !
  315. ! The bdy_mask argument is a four-dimensional logical array, each element
  316. ! of which is set to true for any boundaries that this process's patch
  317. ! contains (all four are true in the non-DM_PARALLEL case) and false
  318. ! otherwise. The indices into the bdy_mask are defined in
  319. ! frame/module_state_description.F. P_XSB corresponds boundary that
  320. ! exists at the beginning of the X-dimension; ie. the western boundary;
  321. ! P_XEB to the boundary that corresponds to the end of the X-dimension
  322. ! (east). Likewise for Y (south and north respectively).
  323. !
  324. ! The correspondence of the first, second, and third dimension of each
  325. ! set (domain, memory, and patch) with the coordinate axes of the model
  326. ! domain is based on the setting of the variable model_data_order, which
  327. ! comes into this routine through USE association of
  328. ! module_driver_constants in the enclosing module of this routine,
  329. ! module_domain. Model_data_order is defined by the Registry, based on
  330. ! the dimspec entries which associate dimension specifiers (e.g. 'k') in
  331. ! the Registry with a coordinate axis and specify which dimension of the
  332. ! arrays they represent. For WRF, the sd1 , ed1 , sp1 , ep1 , sm1 , and
  333. ! em1 correspond to the starts and ends of the global, patch, and memory
  334. ! dimensions in X; those with 2 specify Z (vertical); and those with 3
  335. ! specify Y. Note that the WRF convention is to overdimension to allow
  336. ! for staggered fields so that sd<em>n</em>:ed<em>n</em> are the starts
  337. ! and ends of the staggered domains in X. The non-staggered grid runs
  338. ! sd<em>n</em>:ed<em>n</em>-1. The extra row or column on the north or
  339. ! east boundaries is not used for non-staggered fields.
  340. !
  341. ! The domdesc and parent_domdesc arguments are for external communication
  342. ! packages (e.g. RSL) that establish and return to WRF integer handles
  343. ! for referring to operations on domains. These descriptors are not set
  344. ! or used otherwise and they are opaque, which means they are never
  345. ! accessed or modified in WRF; they are only only passed between calls to
  346. ! the external package.
  347. !</DESCRIPTION>
  348. USE module_machine
  349. IMPLICIT NONE
  350. LOGICAL, DIMENSION(4), INTENT(OUT) :: bdy_mask
  351. INTEGER, INTENT(IN) :: sd1 , ed1 , sd2 , ed2 , sd3 , ed3 , bdx , bdy
  352. INTEGER, INTENT(OUT) :: sp1 , ep1 , sp2 , ep2 , sp3 , ep3 , & ! z-xpose (std)
  353. sm1 , em1 , sm2 , em2 , sm3 , em3
  354. INTEGER, INTENT(OUT) :: sp1x , ep1x , sp2x , ep2x , sp3x , ep3x , & ! x-xpose
  355. sm1x , em1x , sm2x , em2x , sm3x , em3x
  356. INTEGER, INTENT(OUT) :: sp1y , ep1y , sp2y , ep2y , sp3y , ep3y , & ! y-xpose
  357. sm1y , em1y , sm2y , em2y , sm3y , em3y
  358. INTEGER, INTENT(IN) :: id , parent_id , parent_domdesc
  359. INTEGER, INTENT(INOUT) :: domdesc
  360. TYPE(domain), POINTER :: parent
  361. !local data
  362. INTEGER spec_bdy_width
  363. CALL nl_get_spec_bdy_width( 1, spec_bdy_width )
  364. #ifndef DM_PARALLEL
  365. bdy_mask = .true. ! only one processor so all 4 boundaries are there
  366. ! this is a trivial version -- 1 patch per processor;
  367. ! use version in module_dm to compute for DM
  368. sp1 = sd1 ; sp2 = sd2 ; sp3 = sd3
  369. ep1 = ed1 ; ep2 = ed2 ; ep3 = ed3
  370. SELECT CASE ( model_data_order )
  371. CASE ( DATA_ORDER_XYZ )
  372. sm1 = sp1 - bdx ; em1 = ep1 + bdx
  373. sm2 = sp2 - bdy ; em2 = ep2 + bdy
  374. sm3 = sp3 ; em3 = ep3
  375. CASE ( DATA_ORDER_YXZ )
  376. sm1 = sp1 - bdy ; em1 = ep1 + bdy
  377. sm2 = sp2 - bdx ; em2 = ep2 + bdx
  378. sm3 = sp3 ; em3 = ep3
  379. CASE ( DATA_ORDER_ZXY )
  380. sm1 = sp1 ; em1 = ep1
  381. sm2 = sp2 - bdx ; em2 = ep2 + bdx
  382. sm3 = sp3 - bdy ; em3 = ep3 + bdy
  383. CASE ( DATA_ORDER_ZYX )
  384. sm1 = sp1 ; em1 = ep1
  385. sm2 = sp2 - bdy ; em2 = ep2 + bdy
  386. sm3 = sp3 - bdx ; em3 = ep3 + bdx
  387. CASE ( DATA_ORDER_XZY )
  388. sm1 = sp1 - bdx ; em1 = ep1 + bdx
  389. sm2 = sp2 ; em2 = ep2
  390. sm3 = sp3 - bdy ; em3 = ep3 + bdy
  391. CASE ( DATA_ORDER_YZX )
  392. sm1 = sp1 - bdy ; em1 = ep1 + bdy
  393. sm2 = sp2 ; em2 = ep2
  394. sm3 = sp3 - bdx ; em3 = ep3 + bdx
  395. END SELECT
  396. sm1x = sm1 ; em1x = em1 ! just copy
  397. sm2x = sm2 ; em2x = em2
  398. sm3x = sm3 ; em3x = em3
  399. sm1y = sm1 ; em1y = em1 ! just copy
  400. sm2y = sm2 ; em2y = em2
  401. sm3y = sm3 ; em3y = em3
  402. ! assigns mostly just to suppress warning messages that INTENT OUT vars not assigned
  403. sp1x = sp1 ; ep1x = ep1 ; sp2x = sp2 ; ep2x = ep2 ; sp3x = sp3 ; ep3x = ep3
  404. sp1y = sp1 ; ep1y = ep1 ; sp2y = sp2 ; ep2y = ep2 ; sp3y = sp3 ; ep3y = ep3
  405. #else
  406. ! This is supplied by the package specific version of module_dm, which
  407. ! is supplied by the external package and copied into the src directory
  408. ! when the code is compiled. The cp command will be found in the externals
  409. ! target of the configure.wrf file for this architecture. Eg: for RSL
  410. ! routine is defined in external/RSL/module_dm.F .
  411. ! Note, it would be very nice to be able to pass parent to this routine;
  412. ! however, there doesn't seem to be a way to do that in F90. That is because
  413. ! to pass a pointer to a domain structure, this call requires an interface
  414. ! definition for wrf_dm_patch_domain (otherwise it will try to convert the
  415. ! pointer to something). In order to provide an interface definition, we
  416. ! would need to either USE module_dm or use an interface block. In either
  417. ! case it generates a circular USE reference, since module_dm uses
  418. ! module_domain. JM 20020416
  419. CALL wrf_dm_patch_domain( id , domdesc , parent_id , parent_domdesc , &
  420. sd1 , ed1 , sp1 , ep1 , sm1 , em1 , &
  421. sd2 , ed2 , sp2 , ep2 , sm2 , em2 , &
  422. sd3 , ed3 , sp3 , ep3 , sm3 , em3 , &
  423. sp1x , ep1x , sm1x , em1x , &
  424. sp2x , ep2x , sm2x , em2x , &
  425. sp3x , ep3x , sm3x , em3x , &
  426. sp1y , ep1y , sm1y , em1y , &
  427. sp2y , ep2y , sm2y , em2y , &
  428. sp3y , ep3y , sm3y , em3y , &
  429. bdx , bdy )
  430. SELECT CASE ( model_data_order )
  431. CASE ( DATA_ORDER_XYZ )
  432. bdy_mask( P_XSB ) = ( sd1 <= sp1 .AND. sp1 <= sd1+spec_bdy_width-1 )
  433. bdy_mask( P_YSB ) = ( sd2 <= sp2 .AND. sp2 <= sd2+spec_bdy_width-1 )
  434. bdy_mask( P_XEB ) = ( ed1-spec_bdy_width-1 <= ep1 .AND. ep1 <= ed1 )
  435. bdy_mask( P_YEB ) = ( ed2-spec_bdy_width-1 <= ep2 .AND. ep2 <= ed2 )
  436. CASE ( DATA_ORDER_YXZ )
  437. bdy_mask( P_XSB ) = ( sd2 <= sp2 .AND. sp2 <= sd2+spec_bdy_width-1 )
  438. bdy_mask( P_YSB ) = ( sd1 <= sp1 .AND. sp1 <= sd1+spec_bdy_width-1 )
  439. bdy_mask( P_XEB ) = ( ed2-spec_bdy_width-1 <= ep2 .AND. ep2 <= ed2 )
  440. bdy_mask( P_YEB ) = ( ed1-spec_bdy_width-1 <= ep1 .AND. ep1 <= ed1 )
  441. CASE ( DATA_ORDER_ZXY )
  442. bdy_mask( P_XSB ) = ( sd2 <= sp2 .AND. sp2 <= sd2+spec_bdy_width-1 )
  443. bdy_mask( P_YSB ) = ( sd3 <= sp3 .AND. sp3 <= sd3+spec_bdy_width-1 )
  444. bdy_mask( P_XEB ) = ( ed2-spec_bdy_width-1 <= ep2 .AND. ep2 <= ed2 )
  445. bdy_mask( P_YEB ) = ( ed3-spec_bdy_width-1 <= ep3 .AND. ep3 <= ed3 )
  446. CASE ( DATA_ORDER_ZYX )
  447. bdy_mask( P_XSB ) = ( sd3 <= sp3 .AND. sp3 <= sd3+spec_bdy_width-1 )
  448. bdy_mask( P_YSB ) = ( sd2 <= sp2 .AND. sp2 <= sd2+spec_bdy_width-1 )
  449. bdy_mask( P_XEB ) = ( ed3-spec_bdy_width-1 <= ep3 .AND. ep3 <= ed3 )
  450. bdy_mask( P_YEB ) = ( ed2-spec_bdy_width-1 <= ep2 .AND. ep2 <= ed2 )
  451. CASE ( DATA_ORDER_XZY )
  452. bdy_mask( P_XSB ) = ( sd1 <= sp1 .AND. sp1 <= sd1+spec_bdy_width-1 )
  453. bdy_mask( P_YSB ) = ( sd3 <= sp3 .AND. sp3 <= sd3+spec_bdy_width-1 )
  454. bdy_mask( P_XEB ) = ( ed1-spec_bdy_width-1 <= ep1 .AND. ep1 <= ed1 )
  455. bdy_mask( P_YEB ) = ( ed3-spec_bdy_width-1 <= ep3 .AND. ep3 <= ed3 )
  456. CASE ( DATA_ORDER_YZX )
  457. bdy_mask( P_XSB ) = ( sd3 <= sp3 .AND. sp3 <= sd3+spec_bdy_width-1 )
  458. bdy_mask( P_YSB ) = ( sd1 <= sp1 .AND. sp1 <= sd1+spec_bdy_width-1 )
  459. bdy_mask( P_XEB ) = ( ed3-spec_bdy_width-1 <= ep3 .AND. ep3 <= ed3 )
  460. bdy_mask( P_YEB ) = ( ed1-spec_bdy_width-1 <= ep1 .AND. ep1 <= ed1 )
  461. END SELECT
  462. #endif
  463. RETURN
  464. END SUBROUTINE wrf_patch_domain
  465. !
  466. SUBROUTINE alloc_and_configure_domain ( domain_id , grid , parent, kid )
  467. !<DESCRIPTION>
  468. ! This subroutine is used to allocate a domain data structure of
  469. ! TYPE(DOMAIN) pointed to by the argument <em>grid</em>, link it into the
  470. ! nested domain hierarchy, and set it's configuration information from
  471. ! the appropriate settings in the WRF namelist file. Specifically, if the
  472. ! domain being allocated and configured is nest, the <em>parent</em>
  473. ! argument will point to the already existing domain data structure for
  474. ! the parent domain and the <em>kid</em> argument will be set to an
  475. ! integer indicating which child of the parent this grid will be (child
  476. ! indices start at 1). If this is the top-level domain, the parent and
  477. ! kid arguments are ignored. <b>WRF domains may have multiple children
  478. ! but only ever have one parent.</b>
  479. !
  480. ! The <em>domain_id</em> argument is the
  481. ! integer handle by which this new domain will be referred; it comes from
  482. ! the grid_id setting in the namelist, and these grid ids correspond to
  483. ! the ordering of settings in the namelist, starting with 1 for the
  484. ! top-level domain. The id of 1 always corresponds to the top-level
  485. ! domain. and these grid ids correspond to the ordering of settings in
  486. ! the namelist, starting with 1 for the top-level domain.
  487. !
  488. ! Model_data_order is provide by USE association of
  489. ! module_driver_constants and is set from dimspec entries in the
  490. ! Registry.
  491. !
  492. ! The allocation of the TYPE(DOMAIN) itself occurs in this routine.
  493. ! However, the numerous multi-dimensional arrays that make up the members
  494. ! of the domain are allocated in the call to alloc_space_field, after
  495. ! wrf_patch_domain has been called to determine the dimensions in memory
  496. ! that should be allocated. It bears noting here that arrays and code
  497. ! that indexes these arrays are always global, regardless of how the
  498. ! model is decomposed over patches. Thus, when arrays are allocated on a
  499. ! given process, the start and end of an array dimension are the global
  500. ! indices of the start and end of that process's subdomain.
  501. !
  502. ! Configuration information for the domain (that is, information from the
  503. ! namelist) is added by the call to <a href=med_add_config_info_to_grid.html>med_add_config_info_to_grid</a>, defined
  504. ! in share/mediation_wrfmain.F.
  505. !</DESCRIPTION>
  506. IMPLICIT NONE
  507. ! Input data.
  508. INTEGER , INTENT(IN) :: domain_id
  509. TYPE( domain ) , POINTER :: grid
  510. TYPE( domain ) , POINTER :: parent
  511. INTEGER , INTENT(IN) :: kid ! which kid of parent am I?
  512. ! Local data.
  513. INTEGER :: sd1 , ed1 , sp1 , ep1 , sm1 , em1
  514. INTEGER :: sd2 , ed2 , sp2 , ep2 , sm2 , em2
  515. INTEGER :: sd3 , ed3 , sp3 , ep3 , sm3 , em3
  516. INTEGER :: sd1x , ed1x , sp1x , ep1x , sm1x , em1x
  517. INTEGER :: sd2x , ed2x , sp2x , ep2x , sm2x , em2x
  518. INTEGER :: sd3x , ed3x , sp3x , ep3x , sm3x , em3x
  519. INTEGER :: sd1y , ed1y , sp1y , ep1y , sm1y , em1y
  520. INTEGER :: sd2y , ed2y , sp2y , ep2y , sm2y , em2y
  521. INTEGER :: sd3y , ed3y , sp3y , ep3y , sm3y , em3y
  522. TYPE(domain) , POINTER :: new_grid
  523. INTEGER :: i
  524. INTEGER :: parent_id , parent_domdesc , new_domdesc
  525. INTEGER :: bdyzone_x , bdyzone_y
  526. INTEGER :: nx, ny
  527. ! This next step uses information that is listed in the registry as namelist_derived
  528. ! to properly size the domain and the patches; this in turn is stored in the new_grid
  529. ! data structure
  530. data_ordering : SELECT CASE ( model_data_order )
  531. CASE ( DATA_ORDER_XYZ )
  532. CALL nl_get_s_we( domain_id , sd1 )
  533. CALL nl_get_e_we( domain_id , ed1 )
  534. CALL nl_get_s_sn( domain_id , sd2 )
  535. CALL nl_get_e_sn( domain_id , ed2 )
  536. CALL nl_get_s_vert( domain_id , sd3 )
  537. CALL nl_get_e_vert( domain_id , ed3 )
  538. nx = ed1-sd1+1
  539. ny = ed2-sd2+1
  540. CASE ( DATA_ORDER_YXZ )
  541. CALL nl_get_s_sn( domain_id , sd1 )
  542. CALL nl_get_e_sn( domain_id , ed1 )
  543. CALL nl_get_s_we( domain_id , sd2 )
  544. CALL nl_get_e_we( domain_id , ed2 )
  545. CALL nl_get_s_vert( domain_id , sd3 )
  546. CALL nl_get_e_vert( domain_id , ed3 )
  547. nx = ed2-sd2+1
  548. ny = ed1-sd1+1
  549. CASE ( DATA_ORDER_ZXY )
  550. CALL nl_get_s_vert( domain_id , sd1 )
  551. CALL nl_get_e_vert( domain_id , ed1 )
  552. CALL nl_get_s_we( domain_id , sd2 )
  553. CALL nl_get_e_we( domain_id , ed2 )
  554. CALL nl_get_s_sn( domain_id , sd3 )
  555. CALL nl_get_e_sn( domain_id , ed3 )
  556. nx = ed2-sd2+1
  557. ny = ed3-sd3+1
  558. CASE ( DATA_ORDER_ZYX )
  559. CALL nl_get_s_vert( domain_id , sd1 )
  560. CALL nl_get_e_vert( domain_id , ed1 )
  561. CALL nl_get_s_sn( domain_id , sd2 )
  562. CALL nl_get_e_sn( domain_id , ed2 )
  563. CALL nl_get_s_we( domain_id , sd3 )
  564. CALL nl_get_e_we( domain_id , ed3 )
  565. nx = ed3-sd3+1
  566. ny = ed2-sd2+1
  567. CASE ( DATA_ORDER_XZY )
  568. CALL nl_get_s_we( domain_id , sd1 )
  569. CALL nl_get_e_we( domain_id , ed1 )
  570. CALL nl_get_s_vert( domain_id , sd2 )
  571. CALL nl_get_e_vert( domain_id , ed2 )
  572. CALL nl_get_s_sn( domain_id , sd3 )
  573. CALL nl_get_e_sn( domain_id , ed3 )
  574. nx = ed1-sd1+1
  575. ny = ed3-sd3+1
  576. CASE ( DATA_ORDER_YZX )
  577. CALL nl_get_s_sn( domain_id , sd1 )
  578. CALL nl_get_e_sn( domain_id , ed1 )
  579. CALL nl_get_s_vert( domain_id , sd2 )
  580. CALL nl_get_e_vert( domain_id , ed2 )
  581. CALL nl_get_s_we( domain_id , sd3 )
  582. CALL nl_get_e_we( domain_id , ed3 )
  583. nx = ed3-sd3+1
  584. ny = ed1-sd1+1
  585. END SELECT data_ordering
  586. IF ( num_time_levels > 3 ) THEN
  587. WRITE ( wrf_err_message , * ) 'alloc_and_configure_domain: ', &
  588. 'Incorrect value for num_time_levels ', num_time_levels
  589. CALL wrf_error_fatal ( TRIM ( wrf_err_message ) )
  590. ENDIF
  591. IF (ASSOCIATED(parent)) THEN
  592. parent_id = parent%id
  593. parent_domdesc = parent%domdesc
  594. ELSE
  595. parent_id = -1
  596. parent_domdesc = -1
  597. ENDIF
  598. ! provided by application, WRF defines in share/module_bc.F
  599. CALL get_bdyzone_x( bdyzone_x )
  600. CALL get_bdyzone_y( bdyzone_y )
  601. ALLOCATE ( new_grid )
  602. ALLOCATE( new_grid%head_statevars )
  603. NULLIFY( new_grid%head_statevars%next)
  604. new_grid%tail_statevars => new_grid%head_statevars
  605. ALLOCATE ( new_grid%parents( max_parents ) )
  606. ALLOCATE ( new_grid%nests( max_nests ) )
  607. NULLIFY( new_grid%sibling )
  608. DO i = 1, max_nests
  609. NULLIFY( new_grid%nests(i)%ptr )
  610. ENDDO
  611. NULLIFY (new_grid%next)
  612. NULLIFY (new_grid%same_level)
  613. NULLIFY (new_grid%i_start)
  614. NULLIFY (new_grid%j_start)
  615. NULLIFY (new_grid%i_end)
  616. NULLIFY (new_grid%j_end)
  617. ALLOCATE( new_grid%domain_clock )
  618. new_grid%domain_clock_created = .FALSE.
  619. ALLOCATE( new_grid%alarms( MAX_WRF_ALARMS ) ) ! initialize in setup_timekeeping
  620. ALLOCATE( new_grid%alarms_created( MAX_WRF_ALARMS ) )
  621. DO i = 1, MAX_WRF_ALARMS
  622. new_grid%alarms_created( i ) = .FALSE.
  623. ENDDO
  624. new_grid%time_set = .FALSE.
  625. new_grid%is_intermediate = .FALSE.
  626. new_grid%have_displayed_alloc_stats = .FALSE.
  627. ! set up the pointers that represent the nest hierarchy
  628. ! set this up *prior* to calling the patching or allocation
  629. ! routines so that implementations of these routines can
  630. ! traverse the nest hierarchy (through the root head_grid)
  631. ! if they need to
  632. IF ( domain_id .NE. 1 ) THEN
  633. new_grid%parents(1)%ptr => parent
  634. new_grid%num_parents = 1
  635. parent%nests(kid)%ptr => new_grid
  636. new_grid%child_of_parent(1) = kid ! note assumption that nest can have only 1 parent
  637. parent%num_nests = parent%num_nests + 1
  638. END IF
  639. new_grid%id = domain_id ! this needs to be assigned prior to calling wrf_patch_domain
  640. CALL wrf_patch_domain( domain_id , new_domdesc , parent, parent_id, parent_domdesc , &
  641. sd1 , ed1 , sp1 , ep1 , sm1 , em1 , & ! z-xpose dims
  642. sd2 , ed2 , sp2 , ep2 , sm2 , em2 , & ! (standard)
  643. sd3 , ed3 , sp3 , ep3 , sm3 , em3 , &
  644. sp1x , ep1x , sm1x , em1x , & ! x-xpose dims
  645. sp2x , ep2x , sm2x , em2x , &
  646. sp3x , ep3x , sm3x , em3x , &
  647. sp1y , ep1y , sm1y , em1y , & ! y-xpose dims
  648. sp2y , ep2y , sm2y , em2y , &
  649. sp3y , ep3y , sm3y , em3y , &
  650. bdyzone_x , bdyzone_y , new_grid%bdy_mask &
  651. )
  652. new_grid%domdesc = new_domdesc
  653. new_grid%num_nests = 0
  654. new_grid%num_siblings = 0
  655. new_grid%num_parents = 0
  656. new_grid%max_tiles = 0
  657. new_grid%num_tiles_spec = 0
  658. new_grid%nframes = 0 ! initialize the number of frames per file (array assignment)
  659. #if (EM_CORE == 1)
  660. new_grid%stepping_to_time = .FALSE.
  661. new_grid%adaptation_domain = 1
  662. new_grid%last_step_updated = -1
  663. #endif
  664. CALL alloc_space_field ( new_grid, domain_id , 3 , 3 , .FALSE. , &
  665. sd1, ed1, sd2, ed2, sd3, ed3, &
  666. sm1, em1, sm2, em2, sm3, em3, &
  667. sp1, ep1, sp2, ep2, sp3, ep3, &
  668. sp1x, ep1x, sp2x, ep2x, sp3x, ep3x, &
  669. sp1y, ep1y, sp2y, ep2y, sp3y, ep3y, &
  670. sm1x, em1x, sm2x, em2x, sm3x, em3x, & ! x-xpose
  671. sm1y, em1y, sm2y, em2y, sm3y, em3y & ! y-xpose
  672. )
  673. #if MOVE_NESTS
  674. !set these here, after alloc_space_field, which initializes vc_i, vc_j to zero
  675. new_grid%xi = -1.0
  676. new_grid%xj = -1.0
  677. new_grid%vc_i = -1.0
  678. new_grid%vc_j = -1.0
  679. #endif
  680. new_grid%sd31 = sd1
  681. new_grid%ed31 = ed1
  682. new_grid%sp31 = sp1
  683. new_grid%ep31 = ep1
  684. new_grid%sm31 = sm1
  685. new_grid%em31 = em1
  686. new_grid%sd32 = sd2
  687. new_grid%ed32 = ed2
  688. new_grid%sp32 = sp2
  689. new_grid%ep32 = ep2
  690. new_grid%sm32 = sm2
  691. new_grid%em32 = em2
  692. new_grid%sd33 = sd3
  693. new_grid%ed33 = ed3
  694. new_grid%sp33 = sp3
  695. new_grid%ep33 = ep3
  696. new_grid%sm33 = sm3
  697. new_grid%em33 = em3
  698. new_grid%sp31x = sp1x
  699. new_grid%ep31x = ep1x
  700. new_grid%sm31x = sm1x
  701. new_grid%em31x = em1x
  702. new_grid%sp32x = sp2x
  703. new_grid%ep32x = ep2x
  704. new_grid%sm32x = sm2x
  705. new_grid%em32x = em2x
  706. new_grid%sp33x = sp3x
  707. new_grid%ep33x = ep3x
  708. new_grid%sm33x = sm3x
  709. new_grid%em33x = em3x
  710. new_grid%sp31y = sp1y
  711. new_grid%ep31y = ep1y
  712. new_grid%sm31y = sm1y
  713. new_grid%em31y = em1y
  714. new_grid%sp32y = sp2y
  715. new_grid%ep32y = ep2y
  716. new_grid%sm32y = sm2y
  717. new_grid%em32y = em2y
  718. new_grid%sp33y = sp3y
  719. new_grid%ep33y = ep3y
  720. new_grid%sm33y = sm3y
  721. new_grid%em33y = em3y
  722. SELECT CASE ( model_data_order )
  723. CASE ( DATA_ORDER_XYZ )
  724. new_grid%sd21 = sd1 ; new_grid%sd22 = sd2 ;
  725. new_grid%ed21 = ed1 ; new_grid%ed22 = ed2 ;
  726. new_grid%sp21 = sp1 ; new_grid%sp22 = sp2 ;
  727. new_grid%ep21 = ep1 ; new_grid%ep22 = ep2 ;
  728. new_grid%sm21 = sm1 ; new_grid%sm22 = sm2 ;
  729. new_grid%em21 = em1 ; new_grid%em22 = em2 ;
  730. new_grid%sd11 = sd1
  731. new_grid%ed11 = ed1
  732. new_grid%sp11 = sp1
  733. new_grid%ep11 = ep1
  734. new_grid%sm11 = sm1
  735. new_grid%em11 = em1
  736. CASE ( DATA_ORDER_YXZ )
  737. new_grid%sd21 = sd1 ; new_grid%sd22 = sd2 ;
  738. new_grid%ed21 = ed1 ; new_grid%ed22 = ed2 ;
  739. new_grid%sp21 = sp1 ; new_grid%sp22 = sp2 ;
  740. new_grid%ep21 = ep1 ; new_grid%ep22 = ep2 ;
  741. new_grid%sm21 = sm1 ; new_grid%sm22 = sm2 ;
  742. new_grid%em21 = em1 ; new_grid%em22 = em2 ;
  743. new_grid%sd11 = sd1
  744. new_grid%ed11 = ed1
  745. new_grid%sp11 = sp1
  746. new_grid%ep11 = ep1
  747. new_grid%sm11 = sm1
  748. new_grid%em11 = em1
  749. CASE ( DATA_ORDER_ZXY )
  750. new_grid%sd21 = sd2 ; new_grid%sd22 = sd3 ;
  751. new_grid%ed21 = ed2 ; new_grid%ed22 = ed3 ;
  752. new_grid%sp21 = sp2 ; new_grid%sp22 = sp3 ;
  753. new_grid%ep21 = ep2 ; new_grid%ep22 = ep3 ;
  754. new_grid%sm21 = sm2 ; new_grid%sm22 = sm3 ;
  755. new_grid%em21 = em2 ; new_grid%em22 = em3 ;
  756. new_grid%sd11 = sd2
  757. new_grid%ed11 = ed2
  758. new_grid%sp11 = sp2
  759. new_grid%ep11 = ep2
  760. new_grid%sm11 = sm2
  761. new_grid%em11 = em2
  762. CASE ( DATA_ORDER_ZYX )
  763. new_grid%sd21 = sd2 ; new_grid%sd22 = sd3 ;
  764. new_grid%ed21 = ed2 ; new_grid%ed22 = ed3 ;
  765. new_grid%sp21 = sp2 ; new_grid%sp22 = sp3 ;
  766. new_grid%ep21 = ep2 ; new_grid%ep22 = ep3 ;
  767. new_grid%sm21 = sm2 ; new_grid%sm22 = sm3 ;
  768. new_grid%em21 = em2 ; new_grid%em22 = em3 ;
  769. new_grid%sd11 = sd2
  770. new_grid%ed11 = ed2
  771. new_grid%sp11 = sp2
  772. new_grid%ep11 = ep2
  773. new_grid%sm11 = sm2
  774. new_grid%em11 = em2
  775. CASE ( DATA_ORDER_XZY )
  776. new_grid%sd21 = sd1 ; new_grid%sd22 = sd3 ;
  777. new_grid%ed21 = ed1 ; new_grid%ed22 = ed3 ;
  778. new_grid%sp21 = sp1 ; new_grid%sp22 = sp3 ;
  779. new_grid%ep21 = ep1 ; new_grid%ep22 = ep3 ;
  780. new_grid%sm21 = sm1 ; new_grid%sm22 = sm3 ;
  781. new_grid%em21 = em1 ; new_grid%em22 = em3 ;
  782. new_grid%sd11 = sd1
  783. new_grid%ed11 = ed1
  784. new_grid%sp11 = sp1
  785. new_grid%ep11 = ep1
  786. new_grid%sm11 = sm1
  787. new_grid%em11 = em1
  788. CASE ( DATA_ORDER_YZX )
  789. new_grid%sd21 = sd1 ; new_grid%sd22 = sd3 ;
  790. new_grid%ed21 = ed1 ; new_grid%ed22 = ed3 ;
  791. new_grid%sp21 = sp1 ; new_grid%sp22 = sp3 ;
  792. new_grid%ep21 = ep1 ; new_grid%ep22 = ep3 ;
  793. new_grid%sm21 = sm1 ; new_grid%sm22 = sm3 ;
  794. new_grid%em21 = em1 ; new_grid%em22 = em3 ;
  795. new_grid%sd11 = sd1
  796. new_grid%ed11 = ed1
  797. new_grid%sp11 = sp1
  798. new_grid%ep11 = ep1
  799. new_grid%sm11 = sm1
  800. new_grid%em11 = em1
  801. END SELECT
  802. CALL med_add_config_info_to_grid ( new_grid ) ! this is a mediation layer routine
  803. ! Some miscellaneous state that is in the Registry but not namelist data
  804. new_grid%tiled = .false.
  805. new_grid%patched = .false.
  806. NULLIFY(new_grid%mapping)
  807. ! This next set of includes causes all but the namelist_derived variables to be
  808. ! properly assigned to the new_grid record
  809. grid => new_grid
  810. ! Allocate storage for time series metadata
  811. ALLOCATE( grid%lattsloc( grid%max_ts_locs ) )
  812. ALLOCATE( grid%lontsloc( grid%max_ts_locs ) )
  813. ALLOCATE( grid%nametsloc( grid%max_ts_locs ) )
  814. ALLOCATE( grid%desctsloc( grid%max_ts_locs ) )
  815. ALLOCATE( grid%itsloc( grid%max_ts_locs ) )
  816. ALLOCATE( grid%jtsloc( grid%max_ts_locs ) )
  817. ALLOCATE( grid%id_tsloc( grid%max_ts_locs ) )
  818. ALLOCATE( grid%ts_filename( grid%max_ts_locs ) )
  819. grid%ntsloc = 0
  820. grid%ntsloc_domain = 0
  821. #if (EM_CORE == 1)
  822. ! Allocate storage for track metadata
  823. ALLOCATE( grid%track_time_in( grid%track_loc_in ) )
  824. ALLOCATE( grid%track_lat_in( grid%track_loc_in ) )
  825. ALLOCATE( grid%track_lon_in( grid%track_loc_in ) )
  826. ALLOCATE( grid%track_time_domain( grid%track_loc_in ) )
  827. ALLOCATE( grid%track_lat_domain( grid%track_loc_in ) )
  828. ALLOCATE( grid%track_lon_domain( grid%track_loc_in ) )
  829. ALLOCATE( grid%track_i( grid%track_loc_in ) )
  830. ALLOCATE( grid%track_j( grid%track_loc_in ) )
  831. grid%track_loc = 0
  832. grid%track_loc_domain = 0
  833. grid%track_have_calculated = .FALSE.
  834. grid%track_have_input = .FALSE.
  835. #endif
  836. #ifdef DM_PARALLEL
  837. CALL wrf_get_dm_communicator ( grid%communicator )
  838. CALL wrf_dm_define_comms( grid )
  839. #endif
  840. END SUBROUTINE alloc_and_configure_domain
  841. SUBROUTINE get_fieldstr(ix,c,instr,outstr,noutstr,noerr)
  842. IMPLICIT NONE
  843. INTEGER, INTENT(IN) :: ix
  844. CHARACTER*(*), INTENT(IN) :: c
  845. CHARACTER*(*), INTENT(IN) :: instr
  846. CHARACTER*(*), INTENT(OUT) :: outstr
  847. INTEGER, INTENT(IN) :: noutstr ! length of outstr
  848. LOGICAL, INTENT(INOUT) :: noerr ! status
  849. !local
  850. INTEGER, PARAMETER :: MAX_DEXES = 100
  851. INTEGER I, PREV, IDEX
  852. INTEGER DEXES(MAX_DEXES)
  853. outstr = ""
  854. prev = 1
  855. dexes(1) = 1
  856. DO i = 2,MAX_DEXES
  857. idex = INDEX(instr(prev:LEN(TRIM(instr))),c)
  858. IF ( idex .GT. 0 ) THEN
  859. dexes(i) = idex+prev
  860. prev = dexes(i)+1
  861. ELSE
  862. dexes(i) = LEN(TRIM(instr))+2
  863. ENDIF
  864. ENDDO
  865. IF ( (dexes(ix+1)-2)-(dexes(ix)) .GT. noutstr ) THEN
  866. noerr = .FALSE. ! would overwrite
  867. ELSE IF( dexes(ix) .EQ. dexes(ix+1) ) THEN
  868. noerr = .FALSE. ! not found
  869. ELSE
  870. outstr = instr(dexes(ix):(dexes(ix+1)-2))
  871. noerr = noerr .AND. .TRUE.
  872. ENDIF
  873. END SUBROUTINE get_fieldstr
  874. SUBROUTINE change_to_lower_case(instr,outstr)
  875. CHARACTER*(*) ,INTENT(IN) :: instr
  876. CHARACTER*(*) ,INTENT(OUT) :: outstr
  877. !Local
  878. CHARACTER*1 :: c
  879. INTEGER ,PARAMETER :: upper_to_lower =IACHAR('a')-IACHAR('A')
  880. INTEGER :: i,n,n1
  881. !
  882. outstr = ' '
  883. N = len(instr)
  884. N1 = len(outstr)
  885. N = MIN(N,N1)
  886. outstr(1:N) = instr(1:N)
  887. DO i=1,N
  888. c = instr(i:i)
  889. if('A'<=c .and. c <='Z') outstr(i:i)=achar(iachar(c)+upper_to_lower)
  890. ENDDO
  891. RETURN
  892. END SUBROUTINE change_to_lower_case
  893. !
  894. SUBROUTINE modify_io_masks1 ( grid , id )
  895. IMPLICIT NONE
  896. #include "streams.h"
  897. INTEGER , INTENT(IN ) :: id
  898. TYPE(domain), POINTER :: grid
  899. ! Local
  900. TYPE(fieldlist), POINTER :: p, q
  901. INTEGER, PARAMETER :: read_unit = 10
  902. LOGICAL, EXTERNAL :: wrf_dm_on_monitor
  903. CHARACTER*256 :: fname, inln, mess, dname, t1, lookee
  904. CHARACTER*256 :: fieldlst
  905. CHARACTER*1 :: op, strmtyp
  906. CHARACTER*3 :: strmid
  907. CHARACTER*10 :: strmtyp_name
  908. INTEGER :: io_status
  909. INTEGER :: strmtyp_int, count_em
  910. INTEGER :: lineno, fieldno, istrm, retval, itrace
  911. LOGICAL :: keepgoing, noerr, gavewarning, ignorewarning, found
  912. LOGICAL, SAVE :: you_warned_me = .FALSE.
  913. LOGICAL, SAVE :: you_warned_me2(max_hst_mods,max_domains) = .FALSE.
  914. gavewarning = .FALSE.
  915. CALL nl_get_iofields_filename( id, fname )
  916. IF ( grid%is_intermediate ) RETURN ! short circuit
  917. IF ( TRIM(fname) .EQ. "NONE_SPECIFIED" ) RETURN ! short circuit
  918. IF ( wrf_dm_on_monitor() ) THEN
  919. OPEN ( UNIT = read_unit , &
  920. FILE = TRIM(fname) , &
  921. FORM = "FORMATTED" , &
  922. STATUS = "OLD" , &
  923. IOSTAT = io_status )
  924. IF ( io_status .EQ. 0 ) THEN ! only on success
  925. keepgoing = .TRUE.
  926. lineno = 0
  927. count_em = 0 ! Count the total number of fields
  928. DO WHILE ( keepgoing )
  929. READ(UNIT=read_unit,FMT='(A)',IOSTAT=io_status) inln
  930. keepgoing = (io_status .EQ. 0) .AND. (LEN(TRIM(inln)) .GT. 0)
  931. IF ( keepgoing ) THEN
  932. lineno = lineno + 1
  933. IF ( .NOT. LEN(TRIM(inln)) .LT. LEN(inln) ) THEN
  934. WRITE(mess,*)'W A R N I N G : Line ',lineno,' of ',TRIM(fname),' is too long. Limit is ',LEN(inln),' characters.'
  935. gavewarning = .TRUE.
  936. ENDIF
  937. IF ( INDEX(inln,'#') .EQ. 0 ) THEN ! skip comments, which is a # anywhere on line
  938. IF ( keepgoing ) THEN
  939. noerr = .TRUE.
  940. CALL get_fieldstr(1,':',inln,op,1,noerr) ! + is add, - is remove
  941. IF ( TRIM(op) .NE. '+' .AND. TRIM(op) .NE. '-' ) THEN
  942. WRITE(mess,*)'W A R N I N G : unknown operation ',TRIM(op),' (should be + or -). Line ',lineno
  943. gavewarning = .TRUE.
  944. ENDIF
  945. CALL get_fieldstr(2,':',inln,t1,1,noerr) ! i is input, h is history
  946. CALL change_to_lower_case(t1,strmtyp)
  947. SELECT CASE (TRIM(strmtyp))
  948. CASE ('h')
  949. strmtyp_name = 'history'
  950. strmtyp_int = first_history
  951. CASE ('i')
  952. strmtyp_name = 'input'
  953. strmtyp_int = first_input
  954. CASE DEFAULT
  955. WRITE(mess,*)'W A…

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