[589] | 1 | !WRF:DRIVER_LAYER:DOMAIN_OBJECT |
---|
| 2 | ! |
---|
| 3 | ! Following are the routines contained within this MODULE: |
---|
| 4 | |
---|
| 5 | ! alloc_and_configure_domain 1. Allocate the space for a single domain (constants |
---|
| 6 | ! and null terminate pointers). |
---|
| 7 | ! 2. Connect the domains as a linked list. |
---|
| 8 | ! 3. Store all of the domain constants. |
---|
| 9 | ! 4. CALL alloc_space_field. |
---|
| 10 | |
---|
| 11 | ! alloc_space_field 1. Allocate space for the gridded data required for |
---|
| 12 | ! each domain. |
---|
| 13 | |
---|
| 14 | ! dealloc_space_domain 1. Reconnect linked list nodes since the current |
---|
| 15 | ! node is removed. |
---|
| 16 | ! 2. CALL dealloc_space_field. |
---|
| 17 | ! 3. Deallocate single domain. |
---|
| 18 | |
---|
| 19 | ! dealloc_space_field 1. Deallocate each of the fields for a particular |
---|
| 20 | ! domain. |
---|
| 21 | |
---|
| 22 | ! first_loc_integer 1. Find the first incidence of a particular |
---|
| 23 | ! domain identifier from an array of domain |
---|
| 24 | ! identifiers. |
---|
| 25 | |
---|
| 26 | MODULE module_domain |
---|
| 27 | |
---|
| 28 | USE module_driver_constants |
---|
| 29 | USE module_machine |
---|
| 30 | USE module_configure |
---|
| 31 | USE module_wrf_error |
---|
| 32 | USE module_utility |
---|
| 33 | USE module_domain_type |
---|
| 34 | |
---|
| 35 | ! In WRFV3, the module_domain_type is defined |
---|
| 36 | ! in a separaate source file, frame/module_domain_type.F |
---|
| 37 | ! This enables splitting off the alloc_space_field routine |
---|
| 38 | ! into a separate file, reducing the size of module_domain |
---|
| 39 | |
---|
| 40 | ! Now that a "domain" TYPE exists, we can use it to store a few pointers |
---|
| 41 | ! to this type. These are primarily for use in traversing the linked list. |
---|
| 42 | ! The "head_grid" is always the pointer to the first domain that is |
---|
| 43 | ! allocated. This is available and is not to be changed. The others are |
---|
| 44 | ! just temporary pointers. |
---|
| 45 | |
---|
| 46 | TYPE(domain) , POINTER :: head_grid , new_grid , next_grid , old_grid |
---|
| 47 | |
---|
| 48 | ! To facilitate an easy integration of each of the domains that are on the |
---|
| 49 | ! same level, we have an array for the head pointer for each level. This |
---|
| 50 | ! removed the need to search through the linked list at each time step to |
---|
| 51 | ! find which domains are to be active. |
---|
| 52 | |
---|
| 53 | TYPE domain_levels |
---|
| 54 | TYPE(domain) , POINTER :: first_domain |
---|
| 55 | END TYPE domain_levels |
---|
| 56 | |
---|
| 57 | TYPE(domain_levels) , DIMENSION(max_levels) :: head_for_each_level |
---|
| 58 | |
---|
| 59 | ! Use this to support debugging features, giving easy access to clock, etc. |
---|
| 60 | TYPE(domain), POINTER :: current_grid |
---|
| 61 | LOGICAL, SAVE :: current_grid_set = .FALSE. |
---|
| 62 | |
---|
| 63 | ! internal routines |
---|
| 64 | PRIVATE domain_time_test_print |
---|
| 65 | PRIVATE test_adjust_io_timestr |
---|
| 66 | |
---|
| 67 | INTERFACE get_ijk_from_grid |
---|
| 68 | MODULE PROCEDURE get_ijk_from_grid1, get_ijk_from_grid2 |
---|
| 69 | END INTERFACE |
---|
| 70 | |
---|
| 71 | INTEGER, PARAMETER :: max_hst_mods = 200 |
---|
| 72 | |
---|
| 73 | CONTAINS |
---|
| 74 | |
---|
| 75 | SUBROUTINE adjust_domain_dims_for_move( grid , dx, dy ) |
---|
| 76 | IMPLICIT NONE |
---|
| 77 | |
---|
| 78 | TYPE( domain ), POINTER :: grid |
---|
| 79 | INTEGER, INTENT(IN) :: dx, dy |
---|
| 80 | |
---|
| 81 | data_ordering : SELECT CASE ( model_data_order ) |
---|
| 82 | CASE ( DATA_ORDER_XYZ ) |
---|
| 83 | grid%sm31 = grid%sm31 + dx |
---|
| 84 | grid%em31 = grid%em31 + dx |
---|
| 85 | grid%sm32 = grid%sm32 + dy |
---|
| 86 | grid%em32 = grid%em32 + dy |
---|
| 87 | grid%sp31 = grid%sp31 + dx |
---|
| 88 | grid%ep31 = grid%ep31 + dx |
---|
| 89 | grid%sp32 = grid%sp32 + dy |
---|
| 90 | grid%ep32 = grid%ep32 + dy |
---|
| 91 | grid%sd31 = grid%sd31 + dx |
---|
| 92 | grid%ed31 = grid%ed31 + dx |
---|
| 93 | grid%sd32 = grid%sd32 + dy |
---|
| 94 | grid%ed32 = grid%ed32 + dy |
---|
| 95 | |
---|
| 96 | CASE ( DATA_ORDER_YXZ ) |
---|
| 97 | grid%sm31 = grid%sm31 + dy |
---|
| 98 | grid%em31 = grid%em31 + dy |
---|
| 99 | grid%sm32 = grid%sm32 + dx |
---|
| 100 | grid%em32 = grid%em32 + dx |
---|
| 101 | grid%sp31 = grid%sp31 + dy |
---|
| 102 | grid%ep31 = grid%ep31 + dy |
---|
| 103 | grid%sp32 = grid%sp32 + dx |
---|
| 104 | grid%ep32 = grid%ep32 + dx |
---|
| 105 | grid%sd31 = grid%sd31 + dy |
---|
| 106 | grid%ed31 = grid%ed31 + dy |
---|
| 107 | grid%sd32 = grid%sd32 + dx |
---|
| 108 | grid%ed32 = grid%ed32 + dx |
---|
| 109 | |
---|
| 110 | CASE ( DATA_ORDER_ZXY ) |
---|
| 111 | grid%sm32 = grid%sm32 + dx |
---|
| 112 | grid%em32 = grid%em32 + dx |
---|
| 113 | grid%sm33 = grid%sm33 + dy |
---|
| 114 | grid%em33 = grid%em33 + dy |
---|
| 115 | grid%sp32 = grid%sp32 + dx |
---|
| 116 | grid%ep32 = grid%ep32 + dx |
---|
| 117 | grid%sp33 = grid%sp33 + dy |
---|
| 118 | grid%ep33 = grid%ep33 + dy |
---|
| 119 | grid%sd32 = grid%sd32 + dx |
---|
| 120 | grid%ed32 = grid%ed32 + dx |
---|
| 121 | grid%sd33 = grid%sd33 + dy |
---|
| 122 | grid%ed33 = grid%ed33 + dy |
---|
| 123 | |
---|
| 124 | CASE ( DATA_ORDER_ZYX ) |
---|
| 125 | grid%sm32 = grid%sm32 + dy |
---|
| 126 | grid%em32 = grid%em32 + dy |
---|
| 127 | grid%sm33 = grid%sm33 + dx |
---|
| 128 | grid%em33 = grid%em33 + dx |
---|
| 129 | grid%sp32 = grid%sp32 + dy |
---|
| 130 | grid%ep32 = grid%ep32 + dy |
---|
| 131 | grid%sp33 = grid%sp33 + dx |
---|
| 132 | grid%ep33 = grid%ep33 + dx |
---|
| 133 | grid%sd32 = grid%sd32 + dy |
---|
| 134 | grid%ed32 = grid%ed32 + dy |
---|
| 135 | grid%sd33 = grid%sd33 + dx |
---|
| 136 | grid%ed33 = grid%ed33 + dx |
---|
| 137 | |
---|
| 138 | CASE ( DATA_ORDER_XZY ) |
---|
| 139 | grid%sm31 = grid%sm31 + dx |
---|
| 140 | grid%em31 = grid%em31 + dx |
---|
| 141 | grid%sm33 = grid%sm33 + dy |
---|
| 142 | grid%em33 = grid%em33 + dy |
---|
| 143 | grid%sp31 = grid%sp31 + dx |
---|
| 144 | grid%ep31 = grid%ep31 + dx |
---|
| 145 | grid%sp33 = grid%sp33 + dy |
---|
| 146 | grid%ep33 = grid%ep33 + dy |
---|
| 147 | grid%sd31 = grid%sd31 + dx |
---|
| 148 | grid%ed31 = grid%ed31 + dx |
---|
| 149 | grid%sd33 = grid%sd33 + dy |
---|
| 150 | grid%ed33 = grid%ed33 + dy |
---|
| 151 | |
---|
| 152 | CASE ( DATA_ORDER_YZX ) |
---|
| 153 | grid%sm31 = grid%sm31 + dy |
---|
| 154 | grid%em31 = grid%em31 + dy |
---|
| 155 | grid%sm33 = grid%sm33 + dx |
---|
| 156 | grid%em33 = grid%em33 + dx |
---|
| 157 | grid%sp31 = grid%sp31 + dy |
---|
| 158 | grid%ep31 = grid%ep31 + dy |
---|
| 159 | grid%sp33 = grid%sp33 + dx |
---|
| 160 | grid%ep33 = grid%ep33 + dx |
---|
| 161 | grid%sd31 = grid%sd31 + dy |
---|
| 162 | grid%ed31 = grid%ed31 + dy |
---|
| 163 | grid%sd33 = grid%sd33 + dx |
---|
| 164 | grid%ed33 = grid%ed33 + dx |
---|
| 165 | |
---|
| 166 | END SELECT data_ordering |
---|
| 167 | |
---|
| 168 | #if 0 |
---|
| 169 | CALL dealloc_space_field ( grid ) |
---|
| 170 | |
---|
| 171 | CALL alloc_space_field ( grid, grid%id , 1 , 2 , .FALSE. , & |
---|
| 172 | grid%sd31, grid%ed31, grid%sd32, grid%ed32, grid%sd33, grid%ed33, & |
---|
| 173 | grid%sm31, grid%em31, grid%sm32, grid%em32, grid%sm33, grid%em33, & |
---|
| 174 | grid%sp31, grid%ep31, grid%sp32, grid%ep32, grid%sp33, grid%ep33, & |
---|
| 175 | grid%sp31x, grid%ep31x, grid%sp32x, grid%ep32x, grid%sp33x, grid%ep33x, & |
---|
| 176 | grid%sp31y, grid%ep31y, grid%sp32y, grid%ep32y, grid%sp33y, grid%ep33y, & |
---|
| 177 | grid%sm31x, grid%em31x, grid%sm32x, grid%em32x, grid%sm33x, grid%em33x, & ! x-xpose |
---|
| 178 | grid%sm31y, grid%em31y, grid%sm32y, grid%em32y, grid%sm33y, grid%em33y & ! y-xpose |
---|
| 179 | ) |
---|
| 180 | #endif |
---|
| 181 | |
---|
| 182 | RETURN |
---|
| 183 | END SUBROUTINE adjust_domain_dims_for_move |
---|
| 184 | |
---|
| 185 | #if 1 |
---|
| 186 | SUBROUTINE get_ijk_from_grid1 ( grid , & |
---|
| 187 | ids, ide, jds, jde, kds, kde, & |
---|
| 188 | ims, ime, jms, jme, kms, kme, & |
---|
| 189 | ips, ipe, jps, jpe, kps, kpe, & |
---|
| 190 | imsx, imex, jmsx, jmex, kmsx, kmex, & |
---|
| 191 | ipsx, ipex, jpsx, jpex, kpsx, kpex, & |
---|
| 192 | imsy, imey, jmsy, jmey, kmsy, kmey, & |
---|
| 193 | ipsy, ipey, jpsy, jpey, kpsy, kpey ) |
---|
| 194 | IMPLICIT NONE |
---|
| 195 | TYPE( domain ), INTENT (IN) :: grid |
---|
| 196 | INTEGER, INTENT(OUT) :: & |
---|
| 197 | ids, ide, jds, jde, kds, kde, & |
---|
| 198 | ims, ime, jms, jme, kms, kme, & |
---|
| 199 | ips, ipe, jps, jpe, kps, kpe, & |
---|
| 200 | imsx, imex, jmsx, jmex, kmsx, kmex, & |
---|
| 201 | ipsx, ipex, jpsx, jpex, kpsx, kpex, & |
---|
| 202 | imsy, imey, jmsy, jmey, kmsy, kmey, & |
---|
| 203 | ipsy, ipey, jpsy, jpey, kpsy, kpey |
---|
| 204 | |
---|
| 205 | CALL get_ijk_from_grid2 ( grid , & |
---|
| 206 | ids, ide, jds, jde, kds, kde, & |
---|
| 207 | ims, ime, jms, jme, kms, kme, & |
---|
| 208 | ips, ipe, jps, jpe, kps, kpe ) |
---|
| 209 | data_ordering : SELECT CASE ( model_data_order ) |
---|
| 210 | CASE ( DATA_ORDER_XYZ ) |
---|
| 211 | imsx = grid%sm31x ; imex = grid%em31x ; jmsx = grid%sm32x ; jmex = grid%em32x ; kmsx = grid%sm33x ; kmex = grid%em33x ; |
---|
| 212 | ipsx = grid%sp31x ; ipex = grid%ep31x ; jpsx = grid%sp32x ; jpex = grid%ep32x ; kpsx = grid%sp33x ; kpex = grid%ep33x ; |
---|
| 213 | imsy = grid%sm31y ; imey = grid%em31y ; jmsy = grid%sm32y ; jmey = grid%em32y ; kmsy = grid%sm33y ; kmey = grid%em33y ; |
---|
| 214 | ipsy = grid%sp31y ; ipey = grid%ep31y ; jpsy = grid%sp32y ; jpey = grid%ep32y ; kpsy = grid%sp33y ; kpey = grid%ep33y ; |
---|
| 215 | CASE ( DATA_ORDER_YXZ ) |
---|
| 216 | imsx = grid%sm32x ; imex = grid%em32x ; jmsx = grid%sm31x ; jmex = grid%em31x ; kmsx = grid%sm33x ; kmex = grid%em33x ; |
---|
| 217 | ipsx = grid%sp32x ; ipex = grid%ep32x ; jpsx = grid%sp31x ; jpex = grid%ep31x ; kpsx = grid%sp33x ; kpex = grid%ep33x ; |
---|
| 218 | imsy = grid%sm32y ; imey = grid%em32y ; jmsy = grid%sm31y ; jmey = grid%em31y ; kmsy = grid%sm33y ; kmey = grid%em33y ; |
---|
| 219 | ipsy = grid%sp32y ; ipey = grid%ep32y ; jpsy = grid%sp31y ; jpey = grid%ep31y ; kpsy = grid%sp33y ; kpey = grid%ep33y ; |
---|
| 220 | CASE ( DATA_ORDER_ZXY ) |
---|
| 221 | imsx = grid%sm32x ; imex = grid%em32x ; jmsx = grid%sm33x ; jmex = grid%em33x ; kmsx = grid%sm31x ; kmex = grid%em31x ; |
---|
| 222 | ipsx = grid%sp32x ; ipex = grid%ep32x ; jpsx = grid%sp33x ; jpex = grid%ep33x ; kpsx = grid%sp31x ; kpex = grid%ep31x ; |
---|
| 223 | imsy = grid%sm32y ; imey = grid%em32y ; jmsy = grid%sm33y ; jmey = grid%em33y ; kmsy = grid%sm31y ; kmey = grid%em31y ; |
---|
| 224 | ipsy = grid%sp32y ; ipey = grid%ep32y ; jpsy = grid%sp33y ; jpey = grid%ep33y ; kpsy = grid%sp31y ; kpey = grid%ep31y ; |
---|
| 225 | CASE ( DATA_ORDER_ZYX ) |
---|
| 226 | imsx = grid%sm33x ; imex = grid%em33x ; jmsx = grid%sm32x ; jmex = grid%em32x ; kmsx = grid%sm31x ; kmex = grid%em31x ; |
---|
| 227 | ipsx = grid%sp33x ; ipex = grid%ep33x ; jpsx = grid%sp32x ; jpex = grid%ep32x ; kpsx = grid%sp31x ; kpex = grid%ep31x ; |
---|
| 228 | imsy = grid%sm33y ; imey = grid%em33y ; jmsy = grid%sm32y ; jmey = grid%em32y ; kmsy = grid%sm31y ; kmey = grid%em31y ; |
---|
| 229 | ipsy = grid%sp33y ; ipey = grid%ep33y ; jpsy = grid%sp32y ; jpey = grid%ep32y ; kpsy = grid%sp31y ; kpey = grid%ep31y ; |
---|
| 230 | CASE ( DATA_ORDER_XZY ) |
---|
| 231 | imsx = grid%sm31x ; imex = grid%em31x ; jmsx = grid%sm33x ; jmex = grid%em33x ; kmsx = grid%sm32x ; kmex = grid%em32x ; |
---|
| 232 | ipsx = grid%sp31x ; ipex = grid%ep31x ; jpsx = grid%sp33x ; jpex = grid%ep33x ; kpsx = grid%sp32x ; kpex = grid%ep32x ; |
---|
| 233 | imsy = grid%sm31y ; imey = grid%em31y ; jmsy = grid%sm33y ; jmey = grid%em33y ; kmsy = grid%sm32y ; kmey = grid%em32y ; |
---|
| 234 | ipsy = grid%sp31y ; ipey = grid%ep31y ; jpsy = grid%sp33y ; jpey = grid%ep33y ; kpsy = grid%sp32y ; kpey = grid%ep32y ; |
---|
| 235 | CASE ( DATA_ORDER_YZX ) |
---|
| 236 | imsx = grid%sm33x ; imex = grid%em33x ; jmsx = grid%sm31x ; jmex = grid%em31x ; kmsx = grid%sm32x ; kmex = grid%em32x ; |
---|
| 237 | ipsx = grid%sp33x ; ipex = grid%ep33x ; jpsx = grid%sp31x ; jpex = grid%ep31x ; kpsx = grid%sp32x ; kpex = grid%ep32x ; |
---|
| 238 | imsy = grid%sm33y ; imey = grid%em33y ; jmsy = grid%sm31y ; jmey = grid%em31y ; kmsy = grid%sm32y ; kmey = grid%em32y ; |
---|
| 239 | ipsy = grid%sp33y ; ipey = grid%ep33y ; jpsy = grid%sp31y ; jpey = grid%ep31y ; kpsy = grid%sp32y ; kpey = grid%ep32y ; |
---|
| 240 | END SELECT data_ordering |
---|
| 241 | END SUBROUTINE get_ijk_from_grid1 |
---|
| 242 | |
---|
| 243 | SUBROUTINE get_ijk_from_grid2 ( grid , & |
---|
| 244 | ids, ide, jds, jde, kds, kde, & |
---|
| 245 | ims, ime, jms, jme, kms, kme, & |
---|
| 246 | ips, ipe, jps, jpe, kps, kpe ) |
---|
| 247 | |
---|
| 248 | IMPLICIT NONE |
---|
| 249 | |
---|
| 250 | TYPE( domain ), INTENT (IN) :: grid |
---|
| 251 | INTEGER, INTENT(OUT) :: & |
---|
| 252 | ids, ide, jds, jde, kds, kde, & |
---|
| 253 | ims, ime, jms, jme, kms, kme, & |
---|
| 254 | ips, ipe, jps, jpe, kps, kpe |
---|
| 255 | |
---|
| 256 | data_ordering : SELECT CASE ( model_data_order ) |
---|
| 257 | CASE ( DATA_ORDER_XYZ ) |
---|
| 258 | ids = grid%sd31 ; ide = grid%ed31 ; jds = grid%sd32 ; jde = grid%ed32 ; kds = grid%sd33 ; kde = grid%ed33 ; |
---|
| 259 | ims = grid%sm31 ; ime = grid%em31 ; jms = grid%sm32 ; jme = grid%em32 ; kms = grid%sm33 ; kme = grid%em33 ; |
---|
| 260 | ips = grid%sp31 ; ipe = grid%ep31 ; jps = grid%sp32 ; jpe = grid%ep32 ; kps = grid%sp33 ; kpe = grid%ep33 ; |
---|
| 261 | CASE ( DATA_ORDER_YXZ ) |
---|
| 262 | ids = grid%sd32 ; ide = grid%ed32 ; jds = grid%sd31 ; jde = grid%ed31 ; kds = grid%sd33 ; kde = grid%ed33 ; |
---|
| 263 | ims = grid%sm32 ; ime = grid%em32 ; jms = grid%sm31 ; jme = grid%em31 ; kms = grid%sm33 ; kme = grid%em33 ; |
---|
| 264 | ips = grid%sp32 ; ipe = grid%ep32 ; jps = grid%sp31 ; jpe = grid%ep31 ; kps = grid%sp33 ; kpe = grid%ep33 ; |
---|
| 265 | CASE ( DATA_ORDER_ZXY ) |
---|
| 266 | ids = grid%sd32 ; ide = grid%ed32 ; jds = grid%sd33 ; jde = grid%ed33 ; kds = grid%sd31 ; kde = grid%ed31 ; |
---|
| 267 | ims = grid%sm32 ; ime = grid%em32 ; jms = grid%sm33 ; jme = grid%em33 ; kms = grid%sm31 ; kme = grid%em31 ; |
---|
| 268 | ips = grid%sp32 ; ipe = grid%ep32 ; jps = grid%sp33 ; jpe = grid%ep33 ; kps = grid%sp31 ; kpe = grid%ep31 ; |
---|
| 269 | CASE ( DATA_ORDER_ZYX ) |
---|
| 270 | ids = grid%sd33 ; ide = grid%ed33 ; jds = grid%sd32 ; jde = grid%ed32 ; kds = grid%sd31 ; kde = grid%ed31 ; |
---|
| 271 | ims = grid%sm33 ; ime = grid%em33 ; jms = grid%sm32 ; jme = grid%em32 ; kms = grid%sm31 ; kme = grid%em31 ; |
---|
| 272 | ips = grid%sp33 ; ipe = grid%ep33 ; jps = grid%sp32 ; jpe = grid%ep32 ; kps = grid%sp31 ; kpe = grid%ep31 ; |
---|
| 273 | CASE ( DATA_ORDER_XZY ) |
---|
| 274 | ids = grid%sd31 ; ide = grid%ed31 ; jds = grid%sd33 ; jde = grid%ed33 ; kds = grid%sd32 ; kde = grid%ed32 ; |
---|
| 275 | ims = grid%sm31 ; ime = grid%em31 ; jms = grid%sm33 ; jme = grid%em33 ; kms = grid%sm32 ; kme = grid%em32 ; |
---|
| 276 | ips = grid%sp31 ; ipe = grid%ep31 ; jps = grid%sp33 ; jpe = grid%ep33 ; kps = grid%sp32 ; kpe = grid%ep32 ; |
---|
| 277 | CASE ( DATA_ORDER_YZX ) |
---|
| 278 | ids = grid%sd33 ; ide = grid%ed33 ; jds = grid%sd31 ; jde = grid%ed31 ; kds = grid%sd32 ; kde = grid%ed32 ; |
---|
| 279 | ims = grid%sm33 ; ime = grid%em33 ; jms = grid%sm31 ; jme = grid%em31 ; kms = grid%sm32 ; kme = grid%em32 ; |
---|
| 280 | ips = grid%sp33 ; ipe = grid%ep33 ; jps = grid%sp31 ; jpe = grid%ep31 ; kps = grid%sp32 ; kpe = grid%ep32 ; |
---|
| 281 | END SELECT data_ordering |
---|
| 282 | END SUBROUTINE get_ijk_from_grid2 |
---|
| 283 | |
---|
| 284 | ! return the values for subgrid whose refinement is in grid%sr |
---|
| 285 | ! note when using this routine, it does not affect K. For K |
---|
| 286 | ! (vertical), it just returns what get_ijk_from_grid does |
---|
| 287 | SUBROUTINE get_ijk_from_subgrid ( grid , & |
---|
| 288 | ids0, ide0, jds0, jde0, kds0, kde0, & |
---|
| 289 | ims0, ime0, jms0, jme0, kms0, kme0, & |
---|
| 290 | ips0, ipe0, jps0, jpe0, kps0, kpe0 ) |
---|
| 291 | TYPE( domain ), INTENT (IN) :: grid |
---|
| 292 | INTEGER, INTENT(OUT) :: & |
---|
| 293 | ids0, ide0, jds0, jde0, kds0, kde0, & |
---|
| 294 | ims0, ime0, jms0, jme0, kms0, kme0, & |
---|
| 295 | ips0, ipe0, jps0, jpe0, kps0, kpe0 |
---|
| 296 | ! Local |
---|
| 297 | INTEGER :: & |
---|
| 298 | ids, ide, jds, jde, kds, kde, & |
---|
| 299 | ims, ime, jms, jme, kms, kme, & |
---|
| 300 | ips, ipe, jps, jpe, kps, kpe |
---|
| 301 | CALL get_ijk_from_grid ( grid , & |
---|
| 302 | ids, ide, jds, jde, kds, kde, & |
---|
| 303 | ims, ime, jms, jme, kms, kme, & |
---|
| 304 | ips, ipe, jps, jpe, kps, kpe ) |
---|
| 305 | ids0 = ids |
---|
| 306 | ide0 = ide * grid%sr_x |
---|
| 307 | ims0 = (ims-1)*grid%sr_x+1 |
---|
| 308 | ime0 = ime * grid%sr_x |
---|
| 309 | ips0 = (ips-1)*grid%sr_x+1 |
---|
| 310 | ipe0 = ipe * grid%sr_x |
---|
| 311 | |
---|
| 312 | jds0 = jds |
---|
| 313 | jde0 = jde * grid%sr_y |
---|
| 314 | jms0 = (jms-1)*grid%sr_y+1 |
---|
| 315 | jme0 = jme * grid%sr_y |
---|
| 316 | jps0 = (jps-1)*grid%sr_y+1 |
---|
| 317 | jpe0 = jpe * grid%sr_y |
---|
| 318 | |
---|
| 319 | kds0 = kds |
---|
| 320 | kde0 = kde |
---|
| 321 | kms0 = kms |
---|
| 322 | kme0 = kme |
---|
| 323 | kps0 = kps |
---|
| 324 | kpe0 = kpe |
---|
| 325 | RETURN |
---|
| 326 | END SUBROUTINE get_ijk_from_subgrid |
---|
| 327 | #endif |
---|
| 328 | |
---|
| 329 | |
---|
| 330 | ! Default version ; Otherwise module containing interface to DM library will provide |
---|
| 331 | |
---|
| 332 | SUBROUTINE wrf_patch_domain( id , domdesc , parent, parent_id , parent_domdesc , & |
---|
| 333 | sd1 , ed1 , sp1 , ep1 , sm1 , em1 , & |
---|
| 334 | sd2 , ed2 , sp2 , ep2 , sm2 , em2 , & |
---|
| 335 | sd3 , ed3 , sp3 , ep3 , sm3 , em3 , & |
---|
| 336 | sp1x , ep1x , sm1x , em1x , & |
---|
| 337 | sp2x , ep2x , sm2x , em2x , & |
---|
| 338 | sp3x , ep3x , sm3x , em3x , & |
---|
| 339 | sp1y , ep1y , sm1y , em1y , & |
---|
| 340 | sp2y , ep2y , sm2y , em2y , & |
---|
| 341 | sp3y , ep3y , sm3y , em3y , & |
---|
| 342 | bdx , bdy , bdy_mask ) |
---|
| 343 | !<DESCRIPTION> |
---|
| 344 | ! Wrf_patch_domain is called as part of the process of initiating a new |
---|
| 345 | ! domain. Based on the global domain dimension information that is |
---|
| 346 | ! passed in it computes the patch and memory dimensions on this |
---|
| 347 | ! distributed-memory process for parallel compilation when DM_PARALLEL is |
---|
| 348 | ! defined in configure.wrf. In this case, it relies on an external |
---|
| 349 | ! communications package-contributed routine, wrf_dm_patch_domain. For |
---|
| 350 | ! non-parallel compiles, it returns the patch and memory dimensions based |
---|
| 351 | ! on the entire domain. In either case, the memory dimensions will be |
---|
| 352 | ! larger than the patch dimensions, since they allow for distributed |
---|
| 353 | ! memory halo regions (DM_PARALLEL only) and for boundary regions around |
---|
| 354 | ! the domain (used for idealized cases only). The width of the boundary |
---|
| 355 | ! regions to be accommodated is passed in as bdx and bdy. |
---|
| 356 | ! |
---|
| 357 | ! The bdy_mask argument is a four-dimensional logical array, each element |
---|
| 358 | ! of which is set to true for any boundaries that this process's patch |
---|
| 359 | ! contains (all four are true in the non-DM_PARALLEL case) and false |
---|
| 360 | ! otherwise. The indices into the bdy_mask are defined in |
---|
| 361 | ! frame/module_state_description.F. P_XSB corresponds boundary that |
---|
| 362 | ! exists at the beginning of the X-dimension; ie. the western boundary; |
---|
| 363 | ! P_XEB to the boundary that corresponds to the end of the X-dimension |
---|
| 364 | ! (east). Likewise for Y (south and north respectively). |
---|
| 365 | ! |
---|
| 366 | ! The correspondence of the first, second, and third dimension of each |
---|
| 367 | ! set (domain, memory, and patch) with the coordinate axes of the model |
---|
| 368 | ! domain is based on the setting of the variable model_data_order, which |
---|
| 369 | ! comes into this routine through USE association of |
---|
| 370 | ! module_driver_constants in the enclosing module of this routine, |
---|
| 371 | ! module_domain. Model_data_order is defined by the Registry, based on |
---|
| 372 | ! the dimspec entries which associate dimension specifiers (e.g. 'k') in |
---|
| 373 | ! the Registry with a coordinate axis and specify which dimension of the |
---|
| 374 | ! arrays they represent. For WRF, the sd1 , ed1 , sp1 , ep1 , sm1 , and |
---|
| 375 | ! em1 correspond to the starts and ends of the global, patch, and memory |
---|
| 376 | ! dimensions in X; those with 2 specify Z (vertical); and those with 3 |
---|
| 377 | ! specify Y. Note that the WRF convention is to overdimension to allow |
---|
| 378 | ! for staggered fields so that sd<em>n</em>:ed<em>n</em> are the starts |
---|
| 379 | ! and ends of the staggered domains in X. The non-staggered grid runs |
---|
| 380 | ! sd<em>n</em>:ed<em>n</em>-1. The extra row or column on the north or |
---|
| 381 | ! east boundaries is not used for non-staggered fields. |
---|
| 382 | ! |
---|
| 383 | ! The domdesc and parent_domdesc arguments are for external communication |
---|
| 384 | ! packages (e.g. RSL) that establish and return to WRF integer handles |
---|
| 385 | ! for referring to operations on domains. These descriptors are not set |
---|
| 386 | ! or used otherwise and they are opaque, which means they are never |
---|
| 387 | ! accessed or modified in WRF; they are only only passed between calls to |
---|
| 388 | ! the external package. |
---|
| 389 | !</DESCRIPTION> |
---|
| 390 | |
---|
| 391 | USE module_machine |
---|
| 392 | IMPLICIT NONE |
---|
| 393 | LOGICAL, DIMENSION(4), INTENT(OUT) :: bdy_mask |
---|
| 394 | INTEGER, INTENT(IN) :: sd1 , ed1 , sd2 , ed2 , sd3 , ed3 , bdx , bdy |
---|
| 395 | INTEGER, INTENT(OUT) :: sp1 , ep1 , sp2 , ep2 , sp3 , ep3 , & ! z-xpose (std) |
---|
| 396 | sm1 , em1 , sm2 , em2 , sm3 , em3 |
---|
| 397 | INTEGER, INTENT(OUT) :: sp1x , ep1x , sp2x , ep2x , sp3x , ep3x , & ! x-xpose |
---|
| 398 | sm1x , em1x , sm2x , em2x , sm3x , em3x |
---|
| 399 | INTEGER, INTENT(OUT) :: sp1y , ep1y , sp2y , ep2y , sp3y , ep3y , & ! y-xpose |
---|
| 400 | sm1y , em1y , sm2y , em2y , sm3y , em3y |
---|
| 401 | INTEGER, INTENT(IN) :: id , parent_id , parent_domdesc |
---|
| 402 | INTEGER, INTENT(INOUT) :: domdesc |
---|
| 403 | TYPE(domain), POINTER :: parent |
---|
| 404 | |
---|
| 405 | !local data |
---|
| 406 | |
---|
| 407 | INTEGER spec_bdy_width |
---|
| 408 | |
---|
| 409 | CALL nl_get_spec_bdy_width( 1, spec_bdy_width ) |
---|
| 410 | |
---|
| 411 | #ifndef DM_PARALLEL |
---|
| 412 | |
---|
| 413 | bdy_mask = .true. ! only one processor so all 4 boundaries are there |
---|
| 414 | |
---|
| 415 | ! this is a trivial version -- 1 patch per processor; |
---|
| 416 | ! use version in module_dm to compute for DM |
---|
| 417 | sp1 = sd1 ; sp2 = sd2 ; sp3 = sd3 |
---|
| 418 | ep1 = ed1 ; ep2 = ed2 ; ep3 = ed3 |
---|
| 419 | SELECT CASE ( model_data_order ) |
---|
| 420 | CASE ( DATA_ORDER_XYZ ) |
---|
| 421 | sm1 = sp1 - bdx ; em1 = ep1 + bdx |
---|
| 422 | sm2 = sp2 - bdy ; em2 = ep2 + bdy |
---|
| 423 | sm3 = sp3 ; em3 = ep3 |
---|
| 424 | CASE ( DATA_ORDER_YXZ ) |
---|
| 425 | sm1 = sp1 - bdy ; em1 = ep1 + bdy |
---|
| 426 | sm2 = sp2 - bdx ; em2 = ep2 + bdx |
---|
| 427 | sm3 = sp3 ; em3 = ep3 |
---|
| 428 | CASE ( DATA_ORDER_ZXY ) |
---|
| 429 | sm1 = sp1 ; em1 = ep1 |
---|
| 430 | sm2 = sp2 - bdx ; em2 = ep2 + bdx |
---|
| 431 | sm3 = sp3 - bdy ; em3 = ep3 + bdy |
---|
| 432 | CASE ( DATA_ORDER_ZYX ) |
---|
| 433 | sm1 = sp1 ; em1 = ep1 |
---|
| 434 | sm2 = sp2 - bdy ; em2 = ep2 + bdy |
---|
| 435 | sm3 = sp3 - bdx ; em3 = ep3 + bdx |
---|
| 436 | CASE ( DATA_ORDER_XZY ) |
---|
| 437 | sm1 = sp1 - bdx ; em1 = ep1 + bdx |
---|
| 438 | sm2 = sp2 ; em2 = ep2 |
---|
| 439 | sm3 = sp3 - bdy ; em3 = ep3 + bdy |
---|
| 440 | CASE ( DATA_ORDER_YZX ) |
---|
| 441 | sm1 = sp1 - bdy ; em1 = ep1 + bdy |
---|
| 442 | sm2 = sp2 ; em2 = ep2 |
---|
| 443 | sm3 = sp3 - bdx ; em3 = ep3 + bdx |
---|
| 444 | END SELECT |
---|
| 445 | sm1x = sm1 ; em1x = em1 ! just copy |
---|
| 446 | sm2x = sm2 ; em2x = em2 |
---|
| 447 | sm3x = sm3 ; em3x = em3 |
---|
| 448 | sm1y = sm1 ; em1y = em1 ! just copy |
---|
| 449 | sm2y = sm2 ; em2y = em2 |
---|
| 450 | sm3y = sm3 ; em3y = em3 |
---|
| 451 | ! assigns mostly just to suppress warning messages that INTENT OUT vars not assigned |
---|
| 452 | sp1x = sp1 ; ep1x = ep1 ; sp2x = sp2 ; ep2x = ep2 ; sp3x = sp3 ; ep3x = ep3 |
---|
| 453 | sp1y = sp1 ; ep1y = ep1 ; sp2y = sp2 ; ep2y = ep2 ; sp3y = sp3 ; ep3y = ep3 |
---|
| 454 | |
---|
| 455 | #else |
---|
| 456 | ! This is supplied by the package specific version of module_dm, which |
---|
| 457 | ! is supplied by the external package and copied into the src directory |
---|
| 458 | ! when the code is compiled. The cp command will be found in the externals |
---|
| 459 | ! target of the configure.wrf file for this architecture. Eg: for RSL |
---|
| 460 | ! routine is defined in external/RSL/module_dm.F . |
---|
| 461 | ! Note, it would be very nice to be able to pass parent to this routine; |
---|
| 462 | ! however, there doesn't seem to be a way to do that in F90. That is because |
---|
| 463 | ! to pass a pointer to a domain structure, this call requires an interface |
---|
| 464 | ! definition for wrf_dm_patch_domain (otherwise it will try to convert the |
---|
| 465 | ! pointer to something). In order to provide an interface definition, we |
---|
| 466 | ! would need to either USE module_dm or use an interface block. In either |
---|
| 467 | ! case it generates a circular USE reference, since module_dm uses |
---|
| 468 | ! module_domain. JM 20020416 |
---|
| 469 | |
---|
| 470 | CALL wrf_dm_patch_domain( id , domdesc , parent_id , parent_domdesc , & |
---|
| 471 | sd1 , ed1 , sp1 , ep1 , sm1 , em1 , & |
---|
| 472 | sd2 , ed2 , sp2 , ep2 , sm2 , em2 , & |
---|
| 473 | sd3 , ed3 , sp3 , ep3 , sm3 , em3 , & |
---|
| 474 | sp1x , ep1x , sm1x , em1x , & |
---|
| 475 | sp2x , ep2x , sm2x , em2x , & |
---|
| 476 | sp3x , ep3x , sm3x , em3x , & |
---|
| 477 | sp1y , ep1y , sm1y , em1y , & |
---|
| 478 | sp2y , ep2y , sm2y , em2y , & |
---|
| 479 | sp3y , ep3y , sm3y , em3y , & |
---|
| 480 | bdx , bdy ) |
---|
| 481 | |
---|
| 482 | SELECT CASE ( model_data_order ) |
---|
| 483 | CASE ( DATA_ORDER_XYZ ) |
---|
| 484 | bdy_mask( P_XSB ) = ( sd1 <= sp1 .AND. sp1 <= sd1+spec_bdy_width-1 ) |
---|
| 485 | bdy_mask( P_YSB ) = ( sd2 <= sp2 .AND. sp2 <= sd2+spec_bdy_width-1 ) |
---|
| 486 | bdy_mask( P_XEB ) = ( ed1-spec_bdy_width-1 <= ep1 .AND. ep1 <= ed1 ) |
---|
| 487 | bdy_mask( P_YEB ) = ( ed2-spec_bdy_width-1 <= ep2 .AND. ep2 <= ed2 ) |
---|
| 488 | CASE ( DATA_ORDER_YXZ ) |
---|
| 489 | bdy_mask( P_XSB ) = ( sd2 <= sp2 .AND. sp2 <= sd2+spec_bdy_width-1 ) |
---|
| 490 | bdy_mask( P_YSB ) = ( sd1 <= sp1 .AND. sp1 <= sd1+spec_bdy_width-1 ) |
---|
| 491 | bdy_mask( P_XEB ) = ( ed2-spec_bdy_width-1 <= ep2 .AND. ep2 <= ed2 ) |
---|
| 492 | bdy_mask( P_YEB ) = ( ed1-spec_bdy_width-1 <= ep1 .AND. ep1 <= ed1 ) |
---|
| 493 | CASE ( DATA_ORDER_ZXY ) |
---|
| 494 | bdy_mask( P_XSB ) = ( sd2 <= sp2 .AND. sp2 <= sd2+spec_bdy_width-1 ) |
---|
| 495 | bdy_mask( P_YSB ) = ( sd3 <= sp3 .AND. sp3 <= sd3+spec_bdy_width-1 ) |
---|
| 496 | bdy_mask( P_XEB ) = ( ed2-spec_bdy_width-1 <= ep2 .AND. ep2 <= ed2 ) |
---|
| 497 | bdy_mask( P_YEB ) = ( ed3-spec_bdy_width-1 <= ep3 .AND. ep3 <= ed3 ) |
---|
| 498 | CASE ( DATA_ORDER_ZYX ) |
---|
| 499 | bdy_mask( P_XSB ) = ( sd3 <= sp3 .AND. sp3 <= sd3+spec_bdy_width-1 ) |
---|
| 500 | bdy_mask( P_YSB ) = ( sd2 <= sp2 .AND. sp2 <= sd2+spec_bdy_width-1 ) |
---|
| 501 | bdy_mask( P_XEB ) = ( ed3-spec_bdy_width-1 <= ep3 .AND. ep3 <= ed3 ) |
---|
| 502 | bdy_mask( P_YEB ) = ( ed2-spec_bdy_width-1 <= ep2 .AND. ep2 <= ed2 ) |
---|
| 503 | CASE ( DATA_ORDER_XZY ) |
---|
| 504 | bdy_mask( P_XSB ) = ( sd1 <= sp1 .AND. sp1 <= sd1+spec_bdy_width-1 ) |
---|
| 505 | bdy_mask( P_YSB ) = ( sd3 <= sp3 .AND. sp3 <= sd3+spec_bdy_width-1 ) |
---|
| 506 | bdy_mask( P_XEB ) = ( ed1-spec_bdy_width-1 <= ep1 .AND. ep1 <= ed1 ) |
---|
| 507 | bdy_mask( P_YEB ) = ( ed3-spec_bdy_width-1 <= ep3 .AND. ep3 <= ed3 ) |
---|
| 508 | CASE ( DATA_ORDER_YZX ) |
---|
| 509 | bdy_mask( P_XSB ) = ( sd3 <= sp3 .AND. sp3 <= sd3+spec_bdy_width-1 ) |
---|
| 510 | bdy_mask( P_YSB ) = ( sd1 <= sp1 .AND. sp1 <= sd1+spec_bdy_width-1 ) |
---|
| 511 | bdy_mask( P_XEB ) = ( ed3-spec_bdy_width-1 <= ep3 .AND. ep3 <= ed3 ) |
---|
| 512 | bdy_mask( P_YEB ) = ( ed1-spec_bdy_width-1 <= ep1 .AND. ep1 <= ed1 ) |
---|
| 513 | END SELECT |
---|
| 514 | |
---|
| 515 | #endif |
---|
| 516 | |
---|
| 517 | RETURN |
---|
| 518 | END SUBROUTINE wrf_patch_domain |
---|
| 519 | ! |
---|
| 520 | SUBROUTINE alloc_and_configure_domain ( domain_id , grid , parent, kid ) |
---|
| 521 | |
---|
| 522 | !<DESCRIPTION> |
---|
| 523 | ! This subroutine is used to allocate a domain data structure of |
---|
| 524 | ! TYPE(DOMAIN) pointed to by the argument <em>grid</em>, link it into the |
---|
| 525 | ! nested domain hierarchy, and set it's configuration information from |
---|
| 526 | ! the appropriate settings in the WRF namelist file. Specifically, if the |
---|
| 527 | ! domain being allocated and configured is nest, the <em>parent</em> |
---|
| 528 | ! argument will point to the already existing domain data structure for |
---|
| 529 | ! the parent domain and the <em>kid</em> argument will be set to an |
---|
| 530 | ! integer indicating which child of the parent this grid will be (child |
---|
| 531 | ! indices start at 1). If this is the top-level domain, the parent and |
---|
| 532 | ! kid arguments are ignored. <b>WRF domains may have multiple children |
---|
| 533 | ! but only ever have one parent.</b> |
---|
| 534 | ! |
---|
| 535 | ! The <em>domain_id</em> argument is the |
---|
| 536 | ! integer handle by which this new domain will be referred; it comes from |
---|
| 537 | ! the grid_id setting in the namelist, and these grid ids correspond to |
---|
| 538 | ! the ordering of settings in the namelist, starting with 1 for the |
---|
| 539 | ! top-level domain. The id of 1 always corresponds to the top-level |
---|
| 540 | ! domain. and these grid ids correspond to the ordering of settings in |
---|
| 541 | ! the namelist, starting with 1 for the top-level domain. |
---|
| 542 | ! |
---|
| 543 | ! Model_data_order is provide by USE association of |
---|
| 544 | ! module_driver_constants and is set from dimspec entries in the |
---|
| 545 | ! Registry. |
---|
| 546 | ! |
---|
| 547 | ! The allocation of the TYPE(DOMAIN) itself occurs in this routine. |
---|
| 548 | ! However, the numerous multi-dimensional arrays that make up the members |
---|
| 549 | ! of the domain are allocated in the call to alloc_space_field, after |
---|
| 550 | ! wrf_patch_domain has been called to determine the dimensions in memory |
---|
| 551 | ! that should be allocated. It bears noting here that arrays and code |
---|
| 552 | ! that indexes these arrays are always global, regardless of how the |
---|
| 553 | ! model is decomposed over patches. Thus, when arrays are allocated on a |
---|
| 554 | ! given process, the start and end of an array dimension are the global |
---|
| 555 | ! indices of the start and end of that process's subdomain. |
---|
| 556 | ! |
---|
| 557 | ! Configuration information for the domain (that is, information from the |
---|
| 558 | ! namelist) is added by the call to <a href=med_add_config_info_to_grid.html>med_add_config_info_to_grid</a>, defined |
---|
| 559 | ! in share/mediation_wrfmain.F. |
---|
| 560 | !</DESCRIPTION> |
---|
| 561 | |
---|
| 562 | IMPLICIT NONE |
---|
| 563 | |
---|
| 564 | ! Input data. |
---|
| 565 | |
---|
| 566 | INTEGER , INTENT(IN) :: domain_id |
---|
| 567 | TYPE( domain ) , POINTER :: grid |
---|
| 568 | TYPE( domain ) , POINTER :: parent |
---|
| 569 | INTEGER , INTENT(IN) :: kid ! which kid of parent am I? |
---|
| 570 | |
---|
| 571 | ! Local data. |
---|
| 572 | INTEGER :: sd1 , ed1 , sp1 , ep1 , sm1 , em1 |
---|
| 573 | INTEGER :: sd2 , ed2 , sp2 , ep2 , sm2 , em2 |
---|
| 574 | INTEGER :: sd3 , ed3 , sp3 , ep3 , sm3 , em3 |
---|
| 575 | |
---|
| 576 | INTEGER :: sd1x , ed1x , sp1x , ep1x , sm1x , em1x |
---|
| 577 | INTEGER :: sd2x , ed2x , sp2x , ep2x , sm2x , em2x |
---|
| 578 | INTEGER :: sd3x , ed3x , sp3x , ep3x , sm3x , em3x |
---|
| 579 | |
---|
| 580 | INTEGER :: sd1y , ed1y , sp1y , ep1y , sm1y , em1y |
---|
| 581 | INTEGER :: sd2y , ed2y , sp2y , ep2y , sm2y , em2y |
---|
| 582 | INTEGER :: sd3y , ed3y , sp3y , ep3y , sm3y , em3y |
---|
| 583 | |
---|
| 584 | TYPE(domain) , POINTER :: new_grid |
---|
| 585 | INTEGER :: i |
---|
| 586 | INTEGER :: parent_id , parent_domdesc , new_domdesc |
---|
| 587 | INTEGER :: bdyzone_x , bdyzone_y |
---|
| 588 | INTEGER :: nx, ny |
---|
| 589 | |
---|
| 590 | |
---|
| 591 | ! This next step uses information that is listed in the registry as namelist_derived |
---|
| 592 | ! to properly size the domain and the patches; this in turn is stored in the new_grid |
---|
| 593 | ! data structure |
---|
| 594 | |
---|
| 595 | |
---|
| 596 | data_ordering : SELECT CASE ( model_data_order ) |
---|
| 597 | CASE ( DATA_ORDER_XYZ ) |
---|
| 598 | |
---|
| 599 | CALL nl_get_s_we( domain_id , sd1 ) |
---|
| 600 | CALL nl_get_e_we( domain_id , ed1 ) |
---|
| 601 | CALL nl_get_s_sn( domain_id , sd2 ) |
---|
| 602 | CALL nl_get_e_sn( domain_id , ed2 ) |
---|
| 603 | CALL nl_get_s_vert( domain_id , sd3 ) |
---|
| 604 | CALL nl_get_e_vert( domain_id , ed3 ) |
---|
| 605 | nx = ed1-sd1+1 |
---|
| 606 | ny = ed2-sd2+1 |
---|
| 607 | |
---|
| 608 | CASE ( DATA_ORDER_YXZ ) |
---|
| 609 | |
---|
| 610 | CALL nl_get_s_sn( domain_id , sd1 ) |
---|
| 611 | CALL nl_get_e_sn( domain_id , ed1 ) |
---|
| 612 | CALL nl_get_s_we( domain_id , sd2 ) |
---|
| 613 | CALL nl_get_e_we( domain_id , ed2 ) |
---|
| 614 | CALL nl_get_s_vert( domain_id , sd3 ) |
---|
| 615 | CALL nl_get_e_vert( domain_id , ed3 ) |
---|
| 616 | nx = ed2-sd2+1 |
---|
| 617 | ny = ed1-sd1+1 |
---|
| 618 | |
---|
| 619 | CASE ( DATA_ORDER_ZXY ) |
---|
| 620 | |
---|
| 621 | CALL nl_get_s_vert( domain_id , sd1 ) |
---|
| 622 | CALL nl_get_e_vert( domain_id , ed1 ) |
---|
| 623 | CALL nl_get_s_we( domain_id , sd2 ) |
---|
| 624 | CALL nl_get_e_we( domain_id , ed2 ) |
---|
| 625 | CALL nl_get_s_sn( domain_id , sd3 ) |
---|
| 626 | CALL nl_get_e_sn( domain_id , ed3 ) |
---|
| 627 | nx = ed2-sd2+1 |
---|
| 628 | ny = ed3-sd3+1 |
---|
| 629 | |
---|
| 630 | CASE ( DATA_ORDER_ZYX ) |
---|
| 631 | |
---|
| 632 | CALL nl_get_s_vert( domain_id , sd1 ) |
---|
| 633 | CALL nl_get_e_vert( domain_id , ed1 ) |
---|
| 634 | CALL nl_get_s_sn( domain_id , sd2 ) |
---|
| 635 | CALL nl_get_e_sn( domain_id , ed2 ) |
---|
| 636 | CALL nl_get_s_we( domain_id , sd3 ) |
---|
| 637 | CALL nl_get_e_we( domain_id , ed3 ) |
---|
| 638 | nx = ed3-sd3+1 |
---|
| 639 | ny = ed2-sd2+1 |
---|
| 640 | |
---|
| 641 | CASE ( DATA_ORDER_XZY ) |
---|
| 642 | |
---|
| 643 | CALL nl_get_s_we( domain_id , sd1 ) |
---|
| 644 | CALL nl_get_e_we( domain_id , ed1 ) |
---|
| 645 | CALL nl_get_s_vert( domain_id , sd2 ) |
---|
| 646 | CALL nl_get_e_vert( domain_id , ed2 ) |
---|
| 647 | CALL nl_get_s_sn( domain_id , sd3 ) |
---|
| 648 | CALL nl_get_e_sn( domain_id , ed3 ) |
---|
| 649 | nx = ed1-sd1+1 |
---|
| 650 | ny = ed3-sd3+1 |
---|
| 651 | |
---|
| 652 | CASE ( DATA_ORDER_YZX ) |
---|
| 653 | |
---|
| 654 | CALL nl_get_s_sn( domain_id , sd1 ) |
---|
| 655 | CALL nl_get_e_sn( domain_id , ed1 ) |
---|
| 656 | CALL nl_get_s_vert( domain_id , sd2 ) |
---|
| 657 | CALL nl_get_e_vert( domain_id , ed2 ) |
---|
| 658 | CALL nl_get_s_we( domain_id , sd3 ) |
---|
| 659 | CALL nl_get_e_we( domain_id , ed3 ) |
---|
| 660 | nx = ed3-sd3+1 |
---|
| 661 | ny = ed1-sd1+1 |
---|
| 662 | |
---|
| 663 | END SELECT data_ordering |
---|
| 664 | |
---|
| 665 | IF ( num_time_levels > 3 ) THEN |
---|
| 666 | WRITE ( wrf_err_message , * ) 'alloc_and_configure_domain: ', & |
---|
| 667 | 'Incorrect value for num_time_levels ', num_time_levels |
---|
| 668 | CALL wrf_error_fatal ( TRIM ( wrf_err_message ) ) |
---|
| 669 | ENDIF |
---|
| 670 | |
---|
| 671 | IF (ASSOCIATED(parent)) THEN |
---|
| 672 | parent_id = parent%id |
---|
| 673 | parent_domdesc = parent%domdesc |
---|
| 674 | ELSE |
---|
| 675 | parent_id = -1 |
---|
| 676 | parent_domdesc = -1 |
---|
| 677 | ENDIF |
---|
| 678 | |
---|
| 679 | ! provided by application, WRF defines in share/module_bc.F |
---|
| 680 | CALL get_bdyzone_x( bdyzone_x ) |
---|
| 681 | CALL get_bdyzone_y( bdyzone_y ) |
---|
| 682 | |
---|
| 683 | ALLOCATE ( new_grid ) |
---|
| 684 | ALLOCATE( new_grid%head_statevars ) |
---|
| 685 | new_grid%head_statevars%Ndim = 0 |
---|
| 686 | NULLIFY( new_grid%head_statevars%next) |
---|
| 687 | new_grid%tail_statevars => new_grid%head_statevars |
---|
| 688 | |
---|
| 689 | ALLOCATE ( new_grid%parents( max_parents ) ) |
---|
| 690 | ALLOCATE ( new_grid%nests( max_nests ) ) |
---|
| 691 | NULLIFY( new_grid%sibling ) |
---|
| 692 | DO i = 1, max_nests |
---|
| 693 | NULLIFY( new_grid%nests(i)%ptr ) |
---|
| 694 | ENDDO |
---|
| 695 | NULLIFY (new_grid%next) |
---|
| 696 | NULLIFY (new_grid%same_level) |
---|
| 697 | NULLIFY (new_grid%i_start) |
---|
| 698 | NULLIFY (new_grid%j_start) |
---|
| 699 | NULLIFY (new_grid%i_end) |
---|
| 700 | NULLIFY (new_grid%j_end) |
---|
| 701 | ALLOCATE( new_grid%domain_clock ) |
---|
| 702 | new_grid%domain_clock_created = .FALSE. |
---|
| 703 | ALLOCATE( new_grid%alarms( MAX_WRF_ALARMS ) ) ! initialize in setup_timekeeping |
---|
| 704 | ALLOCATE( new_grid%alarms_created( MAX_WRF_ALARMS ) ) |
---|
| 705 | DO i = 1, MAX_WRF_ALARMS |
---|
| 706 | new_grid%alarms_created( i ) = .FALSE. |
---|
| 707 | ENDDO |
---|
| 708 | new_grid%time_set = .FALSE. |
---|
| 709 | new_grid%is_intermediate = .FALSE. |
---|
| 710 | new_grid%have_displayed_alloc_stats = .FALSE. |
---|
| 711 | |
---|
| 712 | new_grid%tiling_latch = .FALSE. ! 20121003 |
---|
| 713 | |
---|
| 714 | ! set up the pointers that represent the nest hierarchy |
---|
| 715 | ! set this up *prior* to calling the patching or allocation |
---|
| 716 | ! routines so that implementations of these routines can |
---|
| 717 | ! traverse the nest hierarchy (through the root head_grid) |
---|
| 718 | ! if they need to |
---|
| 719 | |
---|
| 720 | |
---|
| 721 | IF ( domain_id .NE. 1 ) THEN |
---|
| 722 | new_grid%parents(1)%ptr => parent |
---|
| 723 | new_grid%num_parents = 1 |
---|
| 724 | parent%nests(kid)%ptr => new_grid |
---|
| 725 | new_grid%child_of_parent(1) = kid ! note assumption that nest can have only 1 parent |
---|
| 726 | parent%num_nests = parent%num_nests + 1 |
---|
| 727 | END IF |
---|
| 728 | new_grid%id = domain_id ! this needs to be assigned prior to calling wrf_patch_domain |
---|
| 729 | |
---|
| 730 | CALL wrf_patch_domain( domain_id , new_domdesc , parent, parent_id, parent_domdesc , & |
---|
| 731 | |
---|
| 732 | sd1 , ed1 , sp1 , ep1 , sm1 , em1 , & ! z-xpose dims |
---|
| 733 | sd2 , ed2 , sp2 , ep2 , sm2 , em2 , & ! (standard) |
---|
| 734 | sd3 , ed3 , sp3 , ep3 , sm3 , em3 , & |
---|
| 735 | |
---|
| 736 | sp1x , ep1x , sm1x , em1x , & ! x-xpose dims |
---|
| 737 | sp2x , ep2x , sm2x , em2x , & |
---|
| 738 | sp3x , ep3x , sm3x , em3x , & |
---|
| 739 | |
---|
| 740 | sp1y , ep1y , sm1y , em1y , & ! y-xpose dims |
---|
| 741 | sp2y , ep2y , sm2y , em2y , & |
---|
| 742 | sp3y , ep3y , sm3y , em3y , & |
---|
| 743 | |
---|
| 744 | bdyzone_x , bdyzone_y , new_grid%bdy_mask & |
---|
| 745 | ) |
---|
| 746 | |
---|
| 747 | |
---|
| 748 | new_grid%domdesc = new_domdesc |
---|
| 749 | new_grid%num_nests = 0 |
---|
| 750 | new_grid%num_siblings = 0 |
---|
| 751 | new_grid%num_parents = 0 |
---|
| 752 | new_grid%max_tiles = 0 |
---|
| 753 | new_grid%num_tiles_spec = 0 |
---|
| 754 | new_grid%nframes = 0 ! initialize the number of frames per file (array assignment) |
---|
| 755 | #if (EM_CORE == 1) |
---|
| 756 | new_grid%stepping_to_time = .FALSE. |
---|
| 757 | new_grid%adaptation_domain = 1 |
---|
| 758 | new_grid%last_step_updated = -1 |
---|
| 759 | #endif |
---|
| 760 | |
---|
| 761 | CALL alloc_space_field ( new_grid, domain_id , 3 , 3 , .FALSE. , & |
---|
| 762 | sd1, ed1, sd2, ed2, sd3, ed3, & |
---|
| 763 | sm1, em1, sm2, em2, sm3, em3, & |
---|
| 764 | sp1, ep1, sp2, ep2, sp3, ep3, & |
---|
| 765 | sp1x, ep1x, sp2x, ep2x, sp3x, ep3x, & |
---|
| 766 | sp1y, ep1y, sp2y, ep2y, sp3y, ep3y, & |
---|
| 767 | sm1x, em1x, sm2x, em2x, sm3x, em3x, & ! x-xpose |
---|
| 768 | sm1y, em1y, sm2y, em2y, sm3y, em3y & ! y-xpose |
---|
| 769 | ) |
---|
| 770 | #if MOVE_NESTS |
---|
| 771 | !set these here, after alloc_space_field, which initializes vc_i, vc_j to zero |
---|
| 772 | new_grid%xi = -1.0 |
---|
| 773 | new_grid%xj = -1.0 |
---|
| 774 | new_grid%vc_i = -1.0 |
---|
| 775 | new_grid%vc_j = -1.0 |
---|
| 776 | #endif |
---|
| 777 | |
---|
| 778 | new_grid%sd31 = sd1 |
---|
| 779 | new_grid%ed31 = ed1 |
---|
| 780 | new_grid%sp31 = sp1 |
---|
| 781 | new_grid%ep31 = ep1 |
---|
| 782 | new_grid%sm31 = sm1 |
---|
| 783 | new_grid%em31 = em1 |
---|
| 784 | new_grid%sd32 = sd2 |
---|
| 785 | new_grid%ed32 = ed2 |
---|
| 786 | new_grid%sp32 = sp2 |
---|
| 787 | new_grid%ep32 = ep2 |
---|
| 788 | new_grid%sm32 = sm2 |
---|
| 789 | new_grid%em32 = em2 |
---|
| 790 | new_grid%sd33 = sd3 |
---|
| 791 | new_grid%ed33 = ed3 |
---|
| 792 | new_grid%sp33 = sp3 |
---|
| 793 | new_grid%ep33 = ep3 |
---|
| 794 | new_grid%sm33 = sm3 |
---|
| 795 | new_grid%em33 = em3 |
---|
| 796 | |
---|
| 797 | new_grid%sp31x = sp1x |
---|
| 798 | new_grid%ep31x = ep1x |
---|
| 799 | new_grid%sm31x = sm1x |
---|
| 800 | new_grid%em31x = em1x |
---|
| 801 | new_grid%sp32x = sp2x |
---|
| 802 | new_grid%ep32x = ep2x |
---|
| 803 | new_grid%sm32x = sm2x |
---|
| 804 | new_grid%em32x = em2x |
---|
| 805 | new_grid%sp33x = sp3x |
---|
| 806 | new_grid%ep33x = ep3x |
---|
| 807 | new_grid%sm33x = sm3x |
---|
| 808 | new_grid%em33x = em3x |
---|
| 809 | |
---|
| 810 | new_grid%sp31y = sp1y |
---|
| 811 | new_grid%ep31y = ep1y |
---|
| 812 | new_grid%sm31y = sm1y |
---|
| 813 | new_grid%em31y = em1y |
---|
| 814 | new_grid%sp32y = sp2y |
---|
| 815 | new_grid%ep32y = ep2y |
---|
| 816 | new_grid%sm32y = sm2y |
---|
| 817 | new_grid%em32y = em2y |
---|
| 818 | new_grid%sp33y = sp3y |
---|
| 819 | new_grid%ep33y = ep3y |
---|
| 820 | new_grid%sm33y = sm3y |
---|
| 821 | new_grid%em33y = em3y |
---|
| 822 | |
---|
| 823 | SELECT CASE ( model_data_order ) |
---|
| 824 | CASE ( DATA_ORDER_XYZ ) |
---|
| 825 | new_grid%sd21 = sd1 ; new_grid%sd22 = sd2 ; |
---|
| 826 | new_grid%ed21 = ed1 ; new_grid%ed22 = ed2 ; |
---|
| 827 | new_grid%sp21 = sp1 ; new_grid%sp22 = sp2 ; |
---|
| 828 | new_grid%ep21 = ep1 ; new_grid%ep22 = ep2 ; |
---|
| 829 | new_grid%sm21 = sm1 ; new_grid%sm22 = sm2 ; |
---|
| 830 | new_grid%em21 = em1 ; new_grid%em22 = em2 ; |
---|
| 831 | new_grid%sd11 = sd1 |
---|
| 832 | new_grid%ed11 = ed1 |
---|
| 833 | new_grid%sp11 = sp1 |
---|
| 834 | new_grid%ep11 = ep1 |
---|
| 835 | new_grid%sm11 = sm1 |
---|
| 836 | new_grid%em11 = em1 |
---|
| 837 | CASE ( DATA_ORDER_YXZ ) |
---|
| 838 | new_grid%sd21 = sd1 ; new_grid%sd22 = sd2 ; |
---|
| 839 | new_grid%ed21 = ed1 ; new_grid%ed22 = ed2 ; |
---|
| 840 | new_grid%sp21 = sp1 ; new_grid%sp22 = sp2 ; |
---|
| 841 | new_grid%ep21 = ep1 ; new_grid%ep22 = ep2 ; |
---|
| 842 | new_grid%sm21 = sm1 ; new_grid%sm22 = sm2 ; |
---|
| 843 | new_grid%em21 = em1 ; new_grid%em22 = em2 ; |
---|
| 844 | new_grid%sd11 = sd1 |
---|
| 845 | new_grid%ed11 = ed1 |
---|
| 846 | new_grid%sp11 = sp1 |
---|
| 847 | new_grid%ep11 = ep1 |
---|
| 848 | new_grid%sm11 = sm1 |
---|
| 849 | new_grid%em11 = em1 |
---|
| 850 | CASE ( DATA_ORDER_ZXY ) |
---|
| 851 | new_grid%sd21 = sd2 ; new_grid%sd22 = sd3 ; |
---|
| 852 | new_grid%ed21 = ed2 ; new_grid%ed22 = ed3 ; |
---|
| 853 | new_grid%sp21 = sp2 ; new_grid%sp22 = sp3 ; |
---|
| 854 | new_grid%ep21 = ep2 ; new_grid%ep22 = ep3 ; |
---|
| 855 | new_grid%sm21 = sm2 ; new_grid%sm22 = sm3 ; |
---|
| 856 | new_grid%em21 = em2 ; new_grid%em22 = em3 ; |
---|
| 857 | new_grid%sd11 = sd2 |
---|
| 858 | new_grid%ed11 = ed2 |
---|
| 859 | new_grid%sp11 = sp2 |
---|
| 860 | new_grid%ep11 = ep2 |
---|
| 861 | new_grid%sm11 = sm2 |
---|
| 862 | new_grid%em11 = em2 |
---|
| 863 | CASE ( DATA_ORDER_ZYX ) |
---|
| 864 | new_grid%sd21 = sd2 ; new_grid%sd22 = sd3 ; |
---|
| 865 | new_grid%ed21 = ed2 ; new_grid%ed22 = ed3 ; |
---|
| 866 | new_grid%sp21 = sp2 ; new_grid%sp22 = sp3 ; |
---|
| 867 | new_grid%ep21 = ep2 ; new_grid%ep22 = ep3 ; |
---|
| 868 | new_grid%sm21 = sm2 ; new_grid%sm22 = sm3 ; |
---|
| 869 | new_grid%em21 = em2 ; new_grid%em22 = em3 ; |
---|
| 870 | new_grid%sd11 = sd2 |
---|
| 871 | new_grid%ed11 = ed2 |
---|
| 872 | new_grid%sp11 = sp2 |
---|
| 873 | new_grid%ep11 = ep2 |
---|
| 874 | new_grid%sm11 = sm2 |
---|
| 875 | new_grid%em11 = em2 |
---|
| 876 | CASE ( DATA_ORDER_XZY ) |
---|
| 877 | new_grid%sd21 = sd1 ; new_grid%sd22 = sd3 ; |
---|
| 878 | new_grid%ed21 = ed1 ; new_grid%ed22 = ed3 ; |
---|
| 879 | new_grid%sp21 = sp1 ; new_grid%sp22 = sp3 ; |
---|
| 880 | new_grid%ep21 = ep1 ; new_grid%ep22 = ep3 ; |
---|
| 881 | new_grid%sm21 = sm1 ; new_grid%sm22 = sm3 ; |
---|
| 882 | new_grid%em21 = em1 ; new_grid%em22 = em3 ; |
---|
| 883 | new_grid%sd11 = sd1 |
---|
| 884 | new_grid%ed11 = ed1 |
---|
| 885 | new_grid%sp11 = sp1 |
---|
| 886 | new_grid%ep11 = ep1 |
---|
| 887 | new_grid%sm11 = sm1 |
---|
| 888 | new_grid%em11 = em1 |
---|
| 889 | CASE ( DATA_ORDER_YZX ) |
---|
| 890 | new_grid%sd21 = sd1 ; new_grid%sd22 = sd3 ; |
---|
| 891 | new_grid%ed21 = ed1 ; new_grid%ed22 = ed3 ; |
---|
| 892 | new_grid%sp21 = sp1 ; new_grid%sp22 = sp3 ; |
---|
| 893 | new_grid%ep21 = ep1 ; new_grid%ep22 = ep3 ; |
---|
| 894 | new_grid%sm21 = sm1 ; new_grid%sm22 = sm3 ; |
---|
| 895 | new_grid%em21 = em1 ; new_grid%em22 = em3 ; |
---|
| 896 | new_grid%sd11 = sd1 |
---|
| 897 | new_grid%ed11 = ed1 |
---|
| 898 | new_grid%sp11 = sp1 |
---|
| 899 | new_grid%ep11 = ep1 |
---|
| 900 | new_grid%sm11 = sm1 |
---|
| 901 | new_grid%em11 = em1 |
---|
| 902 | END SELECT |
---|
| 903 | |
---|
| 904 | CALL med_add_config_info_to_grid ( new_grid ) ! this is a mediation layer routine |
---|
| 905 | |
---|
| 906 | ! Some miscellaneous state that is in the Registry but not namelist data |
---|
| 907 | |
---|
| 908 | new_grid%tiled = .false. |
---|
| 909 | new_grid%patched = .false. |
---|
| 910 | NULLIFY(new_grid%mapping) |
---|
| 911 | |
---|
| 912 | ! This next set of includes causes all but the namelist_derived variables to be |
---|
| 913 | ! properly assigned to the new_grid record |
---|
| 914 | |
---|
| 915 | grid => new_grid |
---|
| 916 | |
---|
| 917 | ! Allocate storage for time series metadata |
---|
| 918 | ALLOCATE( grid%lattsloc( grid%max_ts_locs ) ) |
---|
| 919 | ALLOCATE( grid%lontsloc( grid%max_ts_locs ) ) |
---|
| 920 | ALLOCATE( grid%nametsloc( grid%max_ts_locs ) ) |
---|
| 921 | ALLOCATE( grid%desctsloc( grid%max_ts_locs ) ) |
---|
| 922 | ALLOCATE( grid%itsloc( grid%max_ts_locs ) ) |
---|
| 923 | ALLOCATE( grid%jtsloc( grid%max_ts_locs ) ) |
---|
| 924 | ALLOCATE( grid%id_tsloc( grid%max_ts_locs ) ) |
---|
| 925 | ALLOCATE( grid%ts_filename( grid%max_ts_locs ) ) |
---|
| 926 | grid%ntsloc = 0 |
---|
| 927 | grid%ntsloc_domain = 0 |
---|
| 928 | |
---|
| 929 | #if WRFMEAS |
---|
| 930 | ! L. Fita, LMD. May 2014 |
---|
| 931 | ALLOCATE( grid%latlidarloc( grid%max_lidar_locs ) ) |
---|
| 932 | ALLOCATE( grid%lonlidarloc( grid%max_lidar_locs ) ) |
---|
| 933 | ALLOCATE( grid%namelidarloc( grid%max_lidar_locs ) ) |
---|
| 934 | ALLOCATE( grid%desclidarloc( grid%max_lidar_locs ) ) |
---|
| 935 | ALLOCATE( grid%ilidarloc( grid%max_lidar_locs ) ) |
---|
| 936 | ALLOCATE( grid%jlidarloc( grid%max_lidar_locs ) ) |
---|
| 937 | ALLOCATE( grid%id_lidarloc( grid%max_lidar_locs ) ) |
---|
| 938 | ALLOCATE( grid%lidar_filename( grid%max_lidar_locs ) ) |
---|
| 939 | grid%nlidarloc = 0 |
---|
| 940 | grid%nlidarloc_domain = 0 |
---|
| 941 | #endif |
---|
| 942 | |
---|
| 943 | #if (EM_CORE == 1) |
---|
| 944 | ! Allocate storage for track metadata |
---|
| 945 | ALLOCATE( grid%track_time_in( grid%track_loc_in ) ) |
---|
| 946 | ALLOCATE( grid%track_lat_in( grid%track_loc_in ) ) |
---|
| 947 | ALLOCATE( grid%track_lon_in( grid%track_loc_in ) ) |
---|
| 948 | |
---|
| 949 | ALLOCATE( grid%track_time_domain( grid%track_loc_in ) ) |
---|
| 950 | ALLOCATE( grid%track_lat_domain( grid%track_loc_in ) ) |
---|
| 951 | ALLOCATE( grid%track_lon_domain( grid%track_loc_in ) ) |
---|
| 952 | ALLOCATE( grid%track_i( grid%track_loc_in ) ) |
---|
| 953 | ALLOCATE( grid%track_j( grid%track_loc_in ) ) |
---|
| 954 | |
---|
| 955 | grid%track_loc = 0 |
---|
| 956 | grid%track_loc_domain = 0 |
---|
| 957 | grid%track_have_calculated = .FALSE. |
---|
| 958 | grid%track_have_input = .FALSE. |
---|
| 959 | #endif |
---|
| 960 | #ifdef DM_PARALLEL |
---|
| 961 | CALL wrf_get_dm_communicator ( grid%communicator ) |
---|
| 962 | CALL wrf_dm_define_comms( grid ) |
---|
| 963 | #endif |
---|
| 964 | |
---|
| 965 | #if ( NMM_CORE==1 ) |
---|
| 966 | grid%interp_mp = .not. ( size(grid%f_ice)>1 .or. size(grid%f_rain)>1 .or. size(grid%f_rimef)>1 ) |
---|
| 967 | #else |
---|
| 968 | grid%interp_mp = .true. |
---|
| 969 | #endif |
---|
| 970 | |
---|
| 971 | END SUBROUTINE alloc_and_configure_domain |
---|
| 972 | |
---|
| 973 | SUBROUTINE get_fieldstr(ix,c,instr,outstr,noutstr,noerr) |
---|
| 974 | IMPLICIT NONE |
---|
| 975 | INTEGER, INTENT(IN) :: ix |
---|
| 976 | CHARACTER*(*), INTENT(IN) :: c |
---|
| 977 | CHARACTER*(*), INTENT(IN) :: instr |
---|
| 978 | CHARACTER*(*), INTENT(OUT) :: outstr |
---|
| 979 | INTEGER, INTENT(IN) :: noutstr ! length of outstr |
---|
| 980 | LOGICAL, INTENT(INOUT) :: noerr ! status |
---|
| 981 | !local |
---|
| 982 | INTEGER, PARAMETER :: MAX_DEXES = 100 |
---|
| 983 | INTEGER I, PREV, IDEX |
---|
| 984 | INTEGER DEXES(MAX_DEXES) |
---|
| 985 | outstr = "" |
---|
| 986 | prev = 1 |
---|
| 987 | dexes(1) = 1 |
---|
| 988 | DO i = 2,MAX_DEXES |
---|
| 989 | idex = INDEX(instr(prev:LEN(TRIM(instr))),c) |
---|
| 990 | IF ( idex .GT. 0 ) THEN |
---|
| 991 | dexes(i) = idex+prev |
---|
| 992 | prev = dexes(i)+1 |
---|
| 993 | ELSE |
---|
| 994 | dexes(i) = LEN(TRIM(instr))+2 |
---|
| 995 | ENDIF |
---|
| 996 | ENDDO |
---|
| 997 | |
---|
| 998 | IF ( (dexes(ix+1)-2)-(dexes(ix)) .GT. noutstr ) THEN |
---|
| 999 | noerr = .FALSE. ! would overwrite |
---|
| 1000 | ELSE IF( dexes(ix) .EQ. dexes(ix+1) ) THEN |
---|
| 1001 | noerr = .FALSE. ! not found |
---|
| 1002 | ELSE |
---|
| 1003 | outstr = instr(dexes(ix):(dexes(ix+1)-2)) |
---|
| 1004 | noerr = noerr .AND. .TRUE. |
---|
| 1005 | ENDIF |
---|
| 1006 | END SUBROUTINE get_fieldstr |
---|
| 1007 | |
---|
| 1008 | SUBROUTINE change_to_lower_case(instr,outstr) |
---|
| 1009 | CHARACTER*(*) ,INTENT(IN) :: instr |
---|
| 1010 | CHARACTER*(*) ,INTENT(OUT) :: outstr |
---|
| 1011 | !Local |
---|
| 1012 | CHARACTER*1 :: c |
---|
| 1013 | INTEGER ,PARAMETER :: upper_to_lower =IACHAR('a')-IACHAR('A') |
---|
| 1014 | INTEGER :: i,n,n1 |
---|
| 1015 | ! |
---|
| 1016 | outstr = ' ' |
---|
| 1017 | N = len(instr) |
---|
| 1018 | N1 = len(outstr) |
---|
| 1019 | N = MIN(N,N1) |
---|
| 1020 | outstr(1:N) = instr(1:N) |
---|
| 1021 | DO i=1,N |
---|
| 1022 | c = instr(i:i) |
---|
| 1023 | if('A'<=c .and. c <='Z') outstr(i:i)=achar(iachar(c)+upper_to_lower) |
---|
| 1024 | ENDDO |
---|
| 1025 | RETURN |
---|
| 1026 | END SUBROUTINE change_to_lower_case |
---|
| 1027 | |
---|
| 1028 | ! |
---|
| 1029 | SUBROUTINE modify_io_masks1 ( grid , id ) |
---|
| 1030 | IMPLICIT NONE |
---|
| 1031 | #include "streams.h" |
---|
| 1032 | INTEGER , INTENT(IN ) :: id |
---|
| 1033 | TYPE(domain), POINTER :: grid |
---|
| 1034 | ! Local |
---|
| 1035 | TYPE(fieldlist), POINTER :: p, q |
---|
| 1036 | INTEGER, PARAMETER :: read_unit = 10 |
---|
| 1037 | LOGICAL, EXTERNAL :: wrf_dm_on_monitor |
---|
| 1038 | CHARACTER*256 :: fname, inln, mess, dname, t1, lookee |
---|
| 1039 | CHARACTER*256 :: fieldlst |
---|
| 1040 | CHARACTER*1 :: op, strmtyp |
---|
| 1041 | CHARACTER*3 :: strmid |
---|
| 1042 | CHARACTER*10 :: strmtyp_name |
---|
| 1043 | INTEGER :: io_status |
---|
| 1044 | INTEGER :: strmtyp_int, count_em |
---|
| 1045 | INTEGER :: lineno, fieldno, istrm, retval, itrace |
---|
| 1046 | LOGICAL :: keepgoing, noerr, gavewarning, ignorewarning, found |
---|
| 1047 | LOGICAL, SAVE :: you_warned_me = .FALSE. |
---|
| 1048 | LOGICAL, SAVE :: you_warned_me2(max_hst_mods,max_domains) = .FALSE. |
---|
| 1049 | |
---|
| 1050 | gavewarning = .FALSE. |
---|
| 1051 | |
---|
| 1052 | CALL nl_get_iofields_filename( id, fname ) |
---|
| 1053 | |
---|
| 1054 | IF ( grid%is_intermediate ) RETURN ! short circuit |
---|
| 1055 | IF ( TRIM(fname) .EQ. "NONE_SPECIFIED" ) RETURN ! short circuit |
---|
| 1056 | |
---|
| 1057 | IF ( wrf_dm_on_monitor() ) THEN |
---|
| 1058 | OPEN ( UNIT = read_unit , & |
---|
| 1059 | FILE = TRIM(fname) , & |
---|
| 1060 | FORM = "FORMATTED" , & |
---|
| 1061 | STATUS = "OLD" , & |
---|
| 1062 | IOSTAT = io_status ) |
---|
| 1063 | IF ( io_status .EQ. 0 ) THEN ! only on success |
---|
| 1064 | keepgoing = .TRUE. |
---|
| 1065 | lineno = 0 |
---|
| 1066 | count_em = 0 ! Count the total number of fields |
---|
| 1067 | DO WHILE ( keepgoing ) |
---|
| 1068 | READ(UNIT=read_unit,FMT='(A)',IOSTAT=io_status) inln |
---|
| 1069 | keepgoing = (io_status .EQ. 0) .AND. (LEN(TRIM(inln)) .GT. 0) |
---|
| 1070 | IF ( keepgoing ) THEN |
---|
| 1071 | lineno = lineno + 1 |
---|
| 1072 | IF ( .NOT. LEN(TRIM(inln)) .LT. LEN(inln) ) THEN |
---|
| 1073 | WRITE(mess,*)'W A R N I N G : Line ',lineno,' of ',TRIM(fname),' is too long. Limit is ',LEN(inln),' characters.' |
---|
| 1074 | gavewarning = .TRUE. |
---|
| 1075 | ENDIF |
---|
| 1076 | IF ( INDEX(inln,'#') .EQ. 0 ) THEN ! skip comments, which is a # anywhere on line |
---|
| 1077 | IF ( keepgoing ) THEN |
---|
| 1078 | noerr = .TRUE. |
---|
| 1079 | CALL get_fieldstr(1,':',inln,op,1,noerr) ! + is add, - is remove |
---|
| 1080 | IF ( TRIM(op) .NE. '+' .AND. TRIM(op) .NE. '-' ) THEN |
---|
| 1081 | WRITE(mess,*)'W A R N I N G : unknown operation ',TRIM(op),' (should be + or -). Line ',lineno |
---|
| 1082 | gavewarning = .TRUE. |
---|
| 1083 | ENDIF |
---|
| 1084 | CALL get_fieldstr(2,':',inln,t1,1,noerr) ! i is input, h is history |
---|
| 1085 | CALL change_to_lower_case(t1,strmtyp) |
---|
| 1086 | |
---|
| 1087 | SELECT CASE (TRIM(strmtyp)) |
---|
| 1088 | CASE ('h') |
---|
| 1089 | strmtyp_name = 'history' |
---|
| 1090 | strmtyp_int = first_history |
---|
| 1091 | CASE ('i') |
---|
| 1092 | strmtyp_name = 'input' |
---|
| 1093 | strmtyp_int = first_input |
---|
| 1094 | CASE DEFAULT |
---|
| 1095 | WRITE(mess,*)'W A R N I N G : unknown stream type ',TRIM(strmtyp),'. Line ',lineno |
---|
| 1096 | gavewarning = .TRUE. |
---|
| 1097 | END SELECT |
---|
| 1098 | |
---|
| 1099 | CALL get_fieldstr(3,':',inln,strmid,3,noerr) ! number of stream (main input and hist are 0) |
---|
| 1100 | READ(strmid,'(I3)') istrm |
---|
| 1101 | IF ( istrm .LT. 0 .OR. istrm .GT. last_history ) THEN |
---|
| 1102 | WRITE(mess,*)'W A R N I N G : invalid stream id ',istrm,' (should be 0 <= id <= ',last_history,'). Line ',lineno |
---|
| 1103 | gavewarning = .TRUE. |
---|
| 1104 | ENDIF |
---|
| 1105 | CALL get_fieldstr(4,':',inln,fieldlst,1024,noerr) ! get list of fields |
---|
| 1106 | IF ( noerr ) THEN |
---|
| 1107 | fieldno = 1 |
---|
| 1108 | CALL get_fieldstr(fieldno,',',fieldlst,t1,256,noerr) |
---|
| 1109 | CALL change_to_lower_case(t1,lookee) |
---|
| 1110 | DO WHILE ( noerr ) ! linear search, blargh... |
---|
| 1111 | p => grid%head_statevars%next |
---|
| 1112 | found = .FALSE. |
---|
| 1113 | count_em = count_em + 1 |
---|
| 1114 | DO WHILE ( ASSOCIATED( p ) ) |
---|
| 1115 | |
---|
| 1116 | IF ( p%Ndim .EQ. 4 .AND. p%scalar_array ) THEN |
---|
| 1117 | |
---|
| 1118 | DO itrace = PARAM_FIRST_SCALAR , p%num_table(grid%id) |
---|
| 1119 | CALL change_to_lower_case( p%dname_table( grid%id, itrace ) , dname ) |
---|
| 1120 | |
---|
| 1121 | IF ( TRIM(dname) .EQ. TRIM(lookee) ) & |
---|
| 1122 | CALL warn_me_or_set_mask (id, istrm, lineno, strmtyp_int, count_em, op, & |
---|
| 1123 | strmtyp_name, dname, fname, lookee, & |
---|
| 1124 | p%streams_table(grid%id,itrace)%stream, & |
---|
| 1125 | mess, found, you_warned_me2) |
---|
| 1126 | ENDDO |
---|
| 1127 | ELSE |
---|
| 1128 | IF ( p%Ntl .GT. 0 ) THEN |
---|
| 1129 | CALL change_to_lower_case(p%DataName(1:LEN(TRIM(p%DataName))-2),dname) |
---|
| 1130 | ELSE |
---|
| 1131 | CALL change_to_lower_case(p%DataName,dname) |
---|
| 1132 | ENDIF |
---|
| 1133 | |
---|
| 1134 | IF ( TRIM(dname) .EQ. TRIM(lookee) ) & |
---|
| 1135 | CALL warn_me_or_set_mask (id, istrm, lineno, strmtyp_int, count_em, op, & |
---|
| 1136 | strmtyp_name, dname, fname, lookee, & |
---|
| 1137 | p%streams, mess, found, you_warned_me2) |
---|
| 1138 | ENDIF |
---|
| 1139 | p => p%next |
---|
| 1140 | ENDDO |
---|
| 1141 | IF ( .NOT. found ) THEN |
---|
| 1142 | WRITE(mess,*)'W A R N I N G : Unable to modify mask for ',TRIM(lookee),& |
---|
| 1143 | '. Variable not found. File: ',TRIM(fname),' at line ',lineno |
---|
| 1144 | CALL wrf_message(mess) |
---|
| 1145 | gavewarning = .TRUE. |
---|
| 1146 | ENDIF |
---|
| 1147 | fieldno = fieldno + 1 |
---|
| 1148 | CALL get_fieldstr(fieldno,',',fieldlst,t1,256,noerr) |
---|
| 1149 | CALL change_to_lower_case(t1,lookee) |
---|
| 1150 | ENDDO |
---|
| 1151 | ELSE |
---|
| 1152 | WRITE(mess,*)'W A R N I N G : Problem reading ',TRIM(fname),' at line ',lineno |
---|
| 1153 | CALL wrf_message(mess) |
---|
| 1154 | gavewarning = .TRUE. |
---|
| 1155 | ENDIF |
---|
| 1156 | ENDIF ! keepgoing |
---|
| 1157 | ENDIF ! skip comments |
---|
| 1158 | ENDIF ! keepgoing |
---|
| 1159 | ENDDO |
---|
| 1160 | ELSE |
---|
| 1161 | WRITE(mess,*)'W A R N I N G : Problem opening ',TRIM(fname) |
---|
| 1162 | CALL wrf_message(mess) |
---|
| 1163 | gavewarning = .TRUE. |
---|
| 1164 | ENDIF |
---|
| 1165 | CLOSE( read_unit ) |
---|
| 1166 | IF ( gavewarning ) THEN |
---|
| 1167 | CALL nl_get_ignore_iofields_warning(1,ignorewarning) |
---|
| 1168 | IF ( .NOT. ignorewarning ) THEN |
---|
| 1169 | CALL wrf_message(mess) |
---|
| 1170 | WRITE(mess,*)'modify_io_masks: problems reading ',TRIM(fname) |
---|
| 1171 | CALL wrf_message(mess) |
---|
| 1172 | CALL wrf_error_fatal('Set ignore_iofields_warn to true in namelist to ignore') |
---|
| 1173 | ELSE |
---|
| 1174 | IF ( .NOT. you_warned_me ) THEN |
---|
| 1175 | if ( .NOT. you_warned_me2(count_em,id) ) CALL wrf_message(mess) ! Don't repeat the W A R N I N G message |
---|
| 1176 | WRITE(mess,*)'Ignoring problems reading ',TRIM(fname) |
---|
| 1177 | CALL wrf_message(mess) |
---|
| 1178 | CALL wrf_message('Continuing. To make this a fatal error, set ignore_iofields_warn to false in namelist' ) |
---|
| 1179 | CALL wrf_message(' ') |
---|
| 1180 | you_warned_me = .TRUE. |
---|
| 1181 | ENDIF |
---|
| 1182 | ENDIF |
---|
| 1183 | ENDIF |
---|
| 1184 | ENDIF ! wrf_dm_on_monitor |
---|
| 1185 | |
---|
| 1186 | #ifdef DM_PARALLEL |
---|
| 1187 | ! broadcast the new masks to the other tasks |
---|
| 1188 | p => grid%head_statevars%next |
---|
| 1189 | DO WHILE ( ASSOCIATED( p ) ) |
---|
| 1190 | IF ( p%Ndim .EQ. 4 .AND. p%scalar_array ) THEN |
---|
| 1191 | |
---|
| 1192 | DO itrace = PARAM_FIRST_SCALAR , p%num_table(grid%id) |
---|
| 1193 | CALL wrf_dm_bcast_integer( p%streams_table(grid%id,itrace)%stream, IO_MASK_SIZE ) |
---|
| 1194 | ENDDO |
---|
| 1195 | |
---|
| 1196 | ELSE |
---|
| 1197 | CALL wrf_dm_bcast_integer( p%streams, IO_MASK_SIZE ) |
---|
| 1198 | ENDIF |
---|
| 1199 | p => p%next |
---|
| 1200 | ENDDO |
---|
| 1201 | #endif |
---|
| 1202 | |
---|
| 1203 | END SUBROUTINE modify_io_masks1 |
---|
| 1204 | |
---|
| 1205 | SUBROUTINE warn_me_or_set_mask (id, istrm, lineno, strmtyp_int, count_em, op, & |
---|
| 1206 | strmtyp_name, dname, fname, lookee, & |
---|
| 1207 | p_stream, mess, found, you_warned_me2) |
---|
| 1208 | |
---|
| 1209 | IMPLICIT NONE |
---|
| 1210 | |
---|
| 1211 | ! See if a field that is requested to be added to or removed from the I/O stream |
---|
| 1212 | ! is already present or absent |
---|
| 1213 | ! If the requested action has already been done, write a warning message |
---|
| 1214 | ! If not, satisfy the request |
---|
| 1215 | |
---|
| 1216 | INTEGER, INTENT(IN ) :: id, istrm, lineno, strmtyp_int |
---|
| 1217 | INTEGER, INTENT(IN ) :: p_stream(*), count_em |
---|
| 1218 | CHARACTER*1, INTENT(IN ) :: op |
---|
| 1219 | CHARACTER*10, INTENT(IN ) :: strmtyp_name |
---|
| 1220 | CHARACTER*256, INTENT(IN ) :: dname, fname, lookee |
---|
| 1221 | CHARACTER*256, INTENT(OUT) :: mess |
---|
| 1222 | LOGICAL, INTENT(OUT) :: found |
---|
| 1223 | LOGICAL, INTENT(INOUT) :: you_warned_me2(max_hst_mods,max_domains) |
---|
| 1224 | ! Local |
---|
| 1225 | INTEGER :: retval |
---|
| 1226 | |
---|
| 1227 | found = .TRUE. |
---|
| 1228 | IF ( TRIM(op) .EQ. '+' ) THEN |
---|
| 1229 | CALL get_mask( p_stream, strmtyp_int + istrm - 1, retval ) |
---|
| 1230 | IF ( retval .NE. 0 ) THEN |
---|
| 1231 | WRITE(mess,*) 'Domain ',id, ' W A R N I N G : Variable ',TRIM(lookee),' already on ', & |
---|
| 1232 | TRIM(strmtyp_name), ' stream ',istrm, '. File: ', TRIM(fname),' at line ',lineno |
---|
| 1233 | ELSE |
---|
| 1234 | WRITE(mess,*) 'Domain ', id, ' Setting ', TRIM(strmtyp_name), ' stream ',istrm,' for ', & |
---|
| 1235 | TRIM(DNAME) ; CALL wrf_debug(1,mess) |
---|
| 1236 | CALL set_mask( p_stream, strmtyp_int + istrm - 1 ) |
---|
| 1237 | ENDIF |
---|
| 1238 | ELSE IF ( TRIM(op) .EQ. '-' ) THEN |
---|
| 1239 | CALL get_mask( p_stream, strmtyp_int + istrm - 1, retval ) |
---|
| 1240 | IF ( retval .EQ. 0 ) THEN |
---|
| 1241 | WRITE(mess,*) 'Domain ',id, ' W A R N I N G : Variable ',TRIM(lookee),' already off ', & |
---|
| 1242 | TRIM(strmtyp_name), ' stream ',istrm, '. File: ',TRIM(fname),' at line ',lineno |
---|
| 1243 | ELSE |
---|
| 1244 | WRITE(mess,*) 'Domain ', id, ' Resetting ', TRIM(strmtyp_name), ' stream ',istrm,' for ', & |
---|
| 1245 | TRIM(DNAME) ; CALL wrf_debug(1,mess) |
---|
| 1246 | CALL reset_mask( p_stream, strmtyp_int + istrm - 1) |
---|
| 1247 | ENDIF |
---|
| 1248 | ENDIF |
---|
| 1249 | IF ( count_em > max_hst_mods ) THEN |
---|
| 1250 | WRITE(mess,*)'ERROR module_domain: Array size for you_warned_me2 is fixed at ',max_hst_mods |
---|
| 1251 | CALL wrf_message(mess) |
---|
| 1252 | CALL wrf_error_fatal('Did you really type > max_hst_mods fields into ', TRIM(fname) ,' ?') |
---|
| 1253 | ELSE |
---|
| 1254 | IF ( .NOT. you_warned_me2(count_em,id) ) THEN |
---|
| 1255 | CALL wrf_message(mess) ! Write warning message once for each field |
---|
| 1256 | you_warned_me2(count_em,id) = .TRUE. |
---|
| 1257 | ENDIF |
---|
| 1258 | ENDIF |
---|
| 1259 | |
---|
| 1260 | END SUBROUTINE warn_me_or_set_mask |
---|
| 1261 | |
---|
| 1262 | ! This routine ALLOCATEs the required space for the meteorological fields |
---|
| 1263 | ! for a specific domain. The fields are simply ALLOCATEd as an -1. They |
---|
| 1264 | ! are referenced as wind, temperature, moisture, etc. in routines that are |
---|
| 1265 | ! below this top-level of data allocation and management (in the solve routine |
---|
| 1266 | ! and below). |
---|
| 1267 | |
---|
| 1268 | SUBROUTINE alloc_space_field ( grid, id, setinitval_in , tl_in , inter_domain_in , & |
---|
| 1269 | sd31, ed31, sd32, ed32, sd33, ed33, & |
---|
| 1270 | sm31 , em31 , sm32 , em32 , sm33 , em33 , & |
---|
| 1271 | sp31 , ep31 , sp32 , ep32 , sp33 , ep33 , & |
---|
| 1272 | sp31x, ep31x, sp32x, ep32x, sp33x, ep33x, & |
---|
| 1273 | sp31y, ep31y, sp32y, ep32y, sp33y, ep33y, & |
---|
| 1274 | sm31x, em31x, sm32x, em32x, sm33x, em33x, & |
---|
| 1275 | sm31y, em31y, sm32y, em32y, sm33y, em33y ) |
---|
| 1276 | |
---|
| 1277 | USE module_alloc_space_0, ONLY : alloc_space_field_core_0 |
---|
| 1278 | USE module_alloc_space_1, ONLY : alloc_space_field_core_1 |
---|
| 1279 | USE module_alloc_space_2, ONLY : alloc_space_field_core_2 |
---|
| 1280 | USE module_alloc_space_3, ONLY : alloc_space_field_core_3 |
---|
| 1281 | USE module_alloc_space_4, ONLY : alloc_space_field_core_4 |
---|
| 1282 | USE module_alloc_space_5, ONLY : alloc_space_field_core_5 |
---|
| 1283 | USE module_alloc_space_6, ONLY : alloc_space_field_core_6 |
---|
| 1284 | USE module_alloc_space_7, ONLY : alloc_space_field_core_7 |
---|
| 1285 | USE module_alloc_space_8, ONLY : alloc_space_field_core_8 |
---|
| 1286 | USE module_alloc_space_9, ONLY : alloc_space_field_core_9 |
---|
| 1287 | |
---|
| 1288 | IMPLICIT NONE |
---|
| 1289 | |
---|
| 1290 | ! Input data. |
---|
| 1291 | |
---|
| 1292 | TYPE(domain) , POINTER :: grid |
---|
| 1293 | INTEGER , INTENT(IN) :: id |
---|
| 1294 | INTEGER , INTENT(IN) :: setinitval_in ! 3 = everything, 1 = arrays only, 0 = none |
---|
| 1295 | INTEGER , INTENT(IN) :: sd31, ed31, sd32, ed32, sd33, ed33 |
---|
| 1296 | INTEGER , INTENT(IN) :: sm31, em31, sm32, em32, sm33, em33 |
---|
| 1297 | INTEGER , INTENT(IN) :: sp31, ep31, sp32, ep32, sp33, ep33 |
---|
| 1298 | INTEGER , INTENT(IN) :: sp31x, ep31x, sp32x, ep32x, sp33x, ep33x |
---|
| 1299 | INTEGER , INTENT(IN) :: sp31y, ep31y, sp32y, ep32y, sp33y, ep33y |
---|
| 1300 | INTEGER , INTENT(IN) :: sm31x, em31x, sm32x, em32x, sm33x, em33x |
---|
| 1301 | INTEGER , INTENT(IN) :: sm31y, em31y, sm32y, em32y, sm33y, em33y |
---|
| 1302 | |
---|
| 1303 | ! this argument is a bitmask. First bit is time level 1, second is time level 2, and so on. |
---|
| 1304 | ! e.g. to set both 1st and second time level, use 3 |
---|
| 1305 | ! to set only 1st use 1 |
---|
| 1306 | ! to set only 2st use 2 |
---|
| 1307 | INTEGER , INTENT(IN) :: tl_in |
---|
| 1308 | |
---|
| 1309 | ! true if the allocation is for an intermediate domain (for nesting); only certain fields allocated |
---|
| 1310 | ! false otherwise (all allocated, modulo tl above) |
---|
| 1311 | LOGICAL , INTENT(IN) :: inter_domain_in |
---|
| 1312 | |
---|
| 1313 | ! Local |
---|
| 1314 | INTEGER(KIND=8) num_bytes_allocated |
---|
| 1315 | INTEGER idum1, idum2 |
---|
| 1316 | |
---|
| 1317 | #if (EM_CORE == 1) |
---|
| 1318 | IF ( grid%id .EQ. 1 ) CALL wrf_message ( & |
---|
| 1319 | 'DYNAMICS OPTION: Eulerian Mass Coordinate ') |
---|
| 1320 | #endif |
---|
| 1321 | #if (NMM_CORE == 1) |
---|
| 1322 | IF ( grid%id .EQ. 1 ) & |
---|
| 1323 | CALL wrf_message ( 'DYNAMICS OPTION: nmm dyncore' ) |
---|
| 1324 | #endif |
---|
| 1325 | #if (COAMPS_CORE == 1) |
---|
| 1326 | IF ( grid%id .EQ. 1 ) & |
---|
| 1327 | CALL wrf_message ( 'DYNAMICS OPTION: coamps dyncore' ) |
---|
| 1328 | #endif |
---|
| 1329 | |
---|
| 1330 | CALL set_scalar_indices_from_config( id , idum1 , idum2 ) |
---|
| 1331 | |
---|
| 1332 | num_bytes_allocated = 0 |
---|
| 1333 | |
---|
| 1334 | ! now separate modules to reduce the size of module_domain that the compiler sees |
---|
| 1335 | CALL alloc_space_field_core_0 ( grid, id, setinitval_in , tl_in , inter_domain_in , num_bytes_allocated , & |
---|
| 1336 | sd31, ed31, sd32, ed32, sd33, ed33, & |
---|
| 1337 | sm31 , em31 , sm32 , em32 , sm33 , em33 , & |
---|
| 1338 | sp31 , ep31 , sp32 , ep32 , sp33 , ep33 , & |
---|
| 1339 | sp31x, ep31x, sp32x, ep32x, sp33x, ep33x, & |
---|
| 1340 | sp31y, ep31y, sp32y, ep32y, sp33y, ep33y, & |
---|
| 1341 | sm31x, em31x, sm32x, em32x, sm33x, em33x, & |
---|
| 1342 | sm31y, em31y, sm32y, em32y, sm33y, em33y ) |
---|
| 1343 | CALL alloc_space_field_core_1 ( grid, id, setinitval_in , tl_in , inter_domain_in , num_bytes_allocated , & |
---|
| 1344 | sd31, ed31, sd32, ed32, sd33, ed33, & |
---|
| 1345 | sm31 , em31 , sm32 , em32 , sm33 , em33 , & |
---|
| 1346 | sp31 , ep31 , sp32 , ep32 , sp33 , ep33 , & |
---|
| 1347 | sp31x, ep31x, sp32x, ep32x, sp33x, ep33x, & |
---|
| 1348 | sp31y, ep31y, sp32y, ep32y, sp33y, ep33y, & |
---|
| 1349 | sm31x, em31x, sm32x, em32x, sm33x, em33x, & |
---|
| 1350 | sm31y, em31y, sm32y, em32y, sm33y, em33y ) |
---|
| 1351 | CALL alloc_space_field_core_2 ( grid, id, setinitval_in , tl_in , inter_domain_in , num_bytes_allocated , & |
---|
| 1352 | sd31, ed31, sd32, ed32, sd33, ed33, & |
---|
| 1353 | sm31 , em31 , sm32 , em32 , sm33 , em33 , & |
---|
| 1354 | sp31 , ep31 , sp32 , ep32 , sp33 , ep33 , & |
---|
| 1355 | sp31x, ep31x, sp32x, ep32x, sp33x, ep33x, & |
---|
| 1356 | sp31y, ep31y, sp32y, ep32y, sp33y, ep33y, & |
---|
| 1357 | sm31x, em31x, sm32x, em32x, sm33x, em33x, & |
---|
| 1358 | sm31y, em31y, sm32y, em32y, sm33y, em33y ) |
---|
| 1359 | CALL alloc_space_field_core_3 ( grid, id, setinitval_in , tl_in , inter_domain_in , num_bytes_allocated , & |
---|
| 1360 | sd31, ed31, sd32, ed32, sd33, ed33, & |
---|
| 1361 | sm31 , em31 , sm32 , em32 , sm33 , em33 , & |
---|
| 1362 | sp31 , ep31 , sp32 , ep32 , sp33 , ep33 , & |
---|
| 1363 | sp31x, ep31x, sp32x, ep32x, sp33x, ep33x, & |
---|
| 1364 | sp31y, ep31y, sp32y, ep32y, sp33y, ep33y, & |
---|
| 1365 | sm31x, em31x, sm32x, em32x, sm33x, em33x, & |
---|
| 1366 | sm31y, em31y, sm32y, em32y, sm33y, em33y ) |
---|
| 1367 | CALL alloc_space_field_core_4 ( grid, id, setinitval_in , tl_in , inter_domain_in , num_bytes_allocated , & |
---|
| 1368 | sd31, ed31, sd32, ed32, sd33, ed33, & |
---|
| 1369 | sm31 , em31 , sm32 , em32 , sm33 , em33 , & |
---|
| 1370 | sp31 , ep31 , sp32 , ep32 , sp33 , ep33 , & |
---|
| 1371 | sp31x, ep31x, sp32x, ep32x, sp33x, ep33x, & |
---|
| 1372 | sp31y, ep31y, sp32y, ep32y, sp33y, ep33y, & |
---|
| 1373 | sm31x, em31x, sm32x, em32x, sm33x, em33x, & |
---|
| 1374 | sm31y, em31y, sm32y, em32y, sm33y, em33y ) |
---|
| 1375 | CALL alloc_space_field_core_5 ( grid, id, setinitval_in , tl_in , inter_domain_in , num_bytes_allocated , & |
---|
| 1376 | sd31, ed31, sd32, ed32, sd33, ed33, & |
---|
| 1377 | sm31 , em31 , sm32 , em32 , sm33 , em33 , & |
---|
| 1378 | sp31 , ep31 , sp32 , ep32 , sp33 , ep33 , & |
---|
| 1379 | sp31x, ep31x, sp32x, ep32x, sp33x, ep33x, & |
---|
| 1380 | sp31y, ep31y, sp32y, ep32y, sp33y, ep33y, & |
---|
| 1381 | sm31x, em31x, sm32x, em32x, sm33x, em33x, & |
---|
| 1382 | sm31y, em31y, sm32y, em32y, sm33y, em33y ) |
---|
| 1383 | CALL alloc_space_field_core_6 ( grid, id, setinitval_in , tl_in , inter_domain_in , num_bytes_allocated , & |
---|
| 1384 | sd31, ed31, sd32, ed32, sd33, ed33, & |
---|
| 1385 | sm31 , em31 , sm32 , em32 , sm33 , em33 , & |
---|
| 1386 | sp31 , ep31 , sp32 , ep32 , sp33 , ep33 , & |
---|
| 1387 | sp31x, ep31x, sp32x, ep32x, sp33x, ep33x, & |
---|
| 1388 | sp31y, ep31y, sp32y, ep32y, sp33y, ep33y, & |
---|
| 1389 | sm31x, em31x, sm32x, em32x, sm33x, em33x, & |
---|
| 1390 | sm31y, em31y, sm32y, em32y, sm33y, em33y ) |
---|
| 1391 | CALL alloc_space_field_core_7 ( grid, id, setinitval_in , tl_in , inter_domain_in , num_bytes_allocated , & |
---|
| 1392 | sd31, ed31, sd32, ed32, sd33, ed33, & |
---|
| 1393 | sm31 , em31 , sm32 , em32 , sm33 , em33 , & |
---|
| 1394 | sp31 , ep31 , sp32 , ep32 , sp33 , ep33 , & |
---|
| 1395 | sp31x, ep31x, sp32x, ep32x, sp33x, ep33x, & |
---|
| 1396 | sp31y, ep31y, sp32y, ep32y, sp33y, ep33y, & |
---|
| 1397 | sm31x, em31x, sm32x, em32x, sm33x, em33x, & |
---|
| 1398 | sm31y, em31y, sm32y, em32y, sm33y, em33y ) |
---|
| 1399 | CALL alloc_space_field_core_8 ( grid, id, setinitval_in , tl_in , inter_domain_in , num_bytes_allocated , & |
---|
| 1400 | sd31, ed31, sd32, ed32, sd33, ed33, & |
---|
| 1401 | sm31 , em31 , sm32 , em32 , sm33 , em33 , & |
---|
| 1402 | sp31 , ep31 , sp32 , ep32 , sp33 , ep33 , & |
---|
| 1403 | sp31x, ep31x, sp32x, ep32x, sp33x, ep33x, & |
---|
| 1404 | sp31y, ep31y, sp32y, ep32y, sp33y, ep33y, & |
---|
| 1405 | sm31x, em31x, sm32x, em32x, sm33x, em33x, & |
---|
| 1406 | sm31y, em31y, sm32y, em32y, sm33y, em33y ) |
---|
| 1407 | CALL alloc_space_field_core_9 ( grid, id, setinitval_in , tl_in , inter_domain_in , num_bytes_allocated , & |
---|
| 1408 | sd31, ed31, sd32, ed32, sd33, ed33, & |
---|
| 1409 | sm31 , em31 , sm32 , em32 , sm33 , em33 , & |
---|
| 1410 | sp31 , ep31 , sp32 , ep32 , sp33 , ep33 , & |
---|
| 1411 | sp31x, ep31x, sp32x, ep32x, sp33x, ep33x, & |
---|
| 1412 | sp31y, ep31y, sp32y, ep32y, sp33y, ep33y, & |
---|
| 1413 | sm31x, em31x, sm32x, em32x, sm33x, em33x, & |
---|
| 1414 | sm31y, em31y, sm32y, em32y, sm33y, em33y ) |
---|
| 1415 | |
---|
| 1416 | IF ( .NOT. grid%have_displayed_alloc_stats ) THEN |
---|
| 1417 | ! we do not want to see this message more than once, as can happen with the allocation and |
---|
| 1418 | ! deallocation of intermediate domains used in nesting. |
---|
| 1419 | WRITE(wrf_err_message,*)& |
---|
| 1420 | 'alloc_space_field: domain ',id,', ',num_bytes_allocated,' bytes allocated' |
---|
| 1421 | CALL wrf_debug( 0, wrf_err_message ) |
---|
| 1422 | grid%have_displayed_alloc_stats = .TRUE. |
---|
| 1423 | ENDIF |
---|
| 1424 | |
---|
| 1425 | |
---|
| 1426 | grid%alloced_sd31=sd31 |
---|
| 1427 | grid%alloced_ed31=ed31 |
---|
| 1428 | grid%alloced_sd32=sd32 |
---|
| 1429 | grid%alloced_ed32=ed32 |
---|
| 1430 | grid%alloced_sd33=sd33 |
---|
| 1431 | grid%alloced_ed33=ed33 |
---|
| 1432 | grid%alloced_sm31=sm31 |
---|
| 1433 | grid%alloced_em31=em31 |
---|
| 1434 | grid%alloced_sm32=sm32 |
---|
| 1435 | grid%alloced_em32=em32 |
---|
| 1436 | grid%alloced_sm33=sm33 |
---|
| 1437 | grid%alloced_em33=em33 |
---|
| 1438 | grid%alloced_sm31x=sm31x |
---|
| 1439 | grid%alloced_em31x=em31x |
---|
| 1440 | grid%alloced_sm32x=sm32x |
---|
| 1441 | grid%alloced_em32x=em32x |
---|
| 1442 | grid%alloced_sm33x=sm33x |
---|
| 1443 | grid%alloced_em33x=em33x |
---|
| 1444 | grid%alloced_sm31y=sm31y |
---|
| 1445 | grid%alloced_em31y=em31y |
---|
| 1446 | grid%alloced_sm32y=sm32y |
---|
| 1447 | grid%alloced_em32y=em32y |
---|
| 1448 | grid%alloced_sm33y=sm33y |
---|
| 1449 | grid%alloced_em33y=em33y |
---|
| 1450 | |
---|
| 1451 | grid%allocated=.TRUE. |
---|
| 1452 | |
---|
| 1453 | END SUBROUTINE alloc_space_field |
---|
| 1454 | |
---|
| 1455 | ! Ensure_space_field allocates a grid's arrays if they are not yet |
---|
| 1456 | ! allocated. If they were already allocated, then it deallocates and |
---|
| 1457 | ! reallocates them if they were allocated with different dimensions. |
---|
| 1458 | ! If they were already allocated with the requested dimensions, then |
---|
| 1459 | ! ensure_space_field does nothing. |
---|
| 1460 | |
---|
| 1461 | SUBROUTINE ensure_space_field ( grid, id, setinitval_in , tl_in , inter_domain_in , & |
---|
| 1462 | sd31, ed31, sd32, ed32, sd33, ed33, & |
---|
| 1463 | sm31 , em31 , sm32 , em32 , sm33 , em33 , & |
---|
| 1464 | sp31 , ep31 , sp32 , ep32 , sp33 , ep33 , & |
---|
| 1465 | sp31x, ep31x, sp32x, ep32x, sp33x, ep33x, & |
---|
| 1466 | sp31y, ep31y, sp32y, ep32y, sp33y, ep33y, & |
---|
| 1467 | sm31x, em31x, sm32x, em32x, sm33x, em33x, & |
---|
| 1468 | sm31y, em31y, sm32y, em32y, sm33y, em33y ) |
---|
| 1469 | |
---|
| 1470 | IMPLICIT NONE |
---|
| 1471 | |
---|
| 1472 | ! Input data. |
---|
| 1473 | |
---|
| 1474 | TYPE(domain) , POINTER :: grid |
---|
| 1475 | INTEGER , INTENT(IN) :: id |
---|
| 1476 | INTEGER , INTENT(IN) :: setinitval_in ! 3 = everything, 1 = arrays only, 0 = none |
---|
| 1477 | INTEGER , INTENT(IN) :: sd31, ed31, sd32, ed32, sd33, ed33 |
---|
| 1478 | INTEGER , INTENT(IN) :: sm31, em31, sm32, em32, sm33, em33 |
---|
| 1479 | INTEGER , INTENT(IN) :: sp31, ep31, sp32, ep32, sp33, ep33 |
---|
| 1480 | INTEGER , INTENT(IN) :: sp31x, ep31x, sp32x, ep32x, sp33x, ep33x |
---|
| 1481 | INTEGER , INTENT(IN) :: sp31y, ep31y, sp32y, ep32y, sp33y, ep33y |
---|
| 1482 | INTEGER , INTENT(IN) :: sm31x, em31x, sm32x, em32x, sm33x, em33x |
---|
| 1483 | INTEGER , INTENT(IN) :: sm31y, em31y, sm32y, em32y, sm33y, em33y |
---|
| 1484 | |
---|
| 1485 | ! this argument is a bitmask. First bit is time level 1, second is time level 2, and so on. |
---|
| 1486 | ! e.g. to set both 1st and second time level, use 3 |
---|
| 1487 | ! to set only 1st use 1 |
---|
| 1488 | ! to set only 2st use 2 |
---|
| 1489 | INTEGER , INTENT(IN) :: tl_in |
---|
| 1490 | |
---|
| 1491 | ! true if the allocation is for an intermediate domain (for nesting); only certain fields allocated |
---|
| 1492 | ! false otherwise (all allocated, modulo tl above) |
---|
| 1493 | LOGICAL , INTENT(IN) :: inter_domain_in |
---|
| 1494 | LOGICAL :: size_changed |
---|
| 1495 | |
---|
| 1496 | size_changed= .not. ( & |
---|
| 1497 | grid%alloced_sd31 .eq. sd31 .and. grid%alloced_ed31 .eq. ed31 .and. & |
---|
| 1498 | grid%alloced_sd32 .eq. sd32 .and. grid%alloced_ed32 .eq. ed32 .and. & |
---|
| 1499 | grid%alloced_sd33 .eq. sd33 .and. grid%alloced_ed33 .eq. ed33 .and. & |
---|
| 1500 | grid%alloced_sm31 .eq. sm31 .and. grid%alloced_em31 .eq. em31 .and. & |
---|
| 1501 | grid%alloced_sm32 .eq. sm32 .and. grid%alloced_em32 .eq. em32 .and. & |
---|
| 1502 | grid%alloced_sm33 .eq. sm33 .and. grid%alloced_em33 .eq. em33 .and. & |
---|
| 1503 | grid%alloced_sm31x .eq. sm31x .and. grid%alloced_em31x .eq. em31x .and. & |
---|
| 1504 | grid%alloced_sm32x .eq. sm32x .and. grid%alloced_em32x .eq. em32x .and. & |
---|
| 1505 | grid%alloced_sm33x .eq. sm33x .and. grid%alloced_em33x .eq. em33x .and. & |
---|
| 1506 | grid%alloced_sm31y .eq. sm31y .and. grid%alloced_em31y .eq. em31y .and. & |
---|
| 1507 | grid%alloced_sm32y .eq. sm32y .and. grid%alloced_em32y .eq. em32y .and. & |
---|
| 1508 | grid%alloced_sm33y .eq. sm33y .and. grid%alloced_em33y .eq. em33y & |
---|
| 1509 | ) |
---|
| 1510 | if(.not. grid%allocated .or. size_changed) then |
---|
| 1511 | if(.not. grid%allocated) then |
---|
| 1512 | call wrf_debug(1,'ensure_space_field: calling alloc_space_field because a grid was not allocated.') |
---|
| 1513 | else |
---|
| 1514 | if(size_changed) & |
---|
| 1515 | call wrf_debug(1,'ensure_space_field: deallocating and reallocating a grid because grid size changed.') |
---|
| 1516 | end if |
---|
| 1517 | if(grid%allocated) & |
---|
| 1518 | call dealloc_space_field( grid ) |
---|
| 1519 | call alloc_space_field ( grid, id, setinitval_in , tl_in , inter_domain_in , & |
---|
| 1520 | sd31, ed31, sd32, ed32, sd33, ed33, & |
---|
| 1521 | sm31 , em31 , sm32 , em32 , sm33 , em33 , & |
---|
| 1522 | sp31 , ep31 , sp32 , ep32 , sp33 , ep33 , & |
---|
| 1523 | sp31x, ep31x, sp32x, ep32x, sp33x, ep33x, & |
---|
| 1524 | sp31y, ep31y, sp32y, ep32y, sp33y, ep33y, & |
---|
| 1525 | sm31x, em31x, sm32x, em32x, sm33x, em33x, & |
---|
| 1526 | sm31y, em31y, sm32y, em32y, sm33y, em33y ) |
---|
| 1527 | end if |
---|
| 1528 | |
---|
| 1529 | END SUBROUTINE ensure_space_field |
---|
| 1530 | |
---|
| 1531 | ! This routine is used to DEALLOCATE space for a single domain and remove |
---|
| 1532 | ! it from the linked list. First the pointers in the linked list are fixed |
---|
| 1533 | ! (so the one in the middle can be removed). Then the domain itself is |
---|
| 1534 | ! DEALLOCATEd via a call to domain_destroy(). |
---|
| 1535 | |
---|
| 1536 | SUBROUTINE dealloc_space_domain ( id ) |
---|
| 1537 | |
---|
| 1538 | IMPLICIT NONE |
---|
| 1539 | |
---|
| 1540 | ! Input data. |
---|
| 1541 | |
---|
| 1542 | INTEGER , INTENT(IN) :: id |
---|
| 1543 | |
---|
| 1544 | ! Local data. |
---|
| 1545 | |
---|
| 1546 | TYPE(domain) , POINTER :: grid |
---|
| 1547 | LOGICAL :: found |
---|
| 1548 | |
---|
| 1549 | ! Initializations required to start the routine. |
---|
| 1550 | |
---|
| 1551 | grid => head_grid |
---|
| 1552 | old_grid => head_grid |
---|
| 1553 | found = .FALSE. |
---|
| 1554 | |
---|
| 1555 | ! The identity of the domain to delete is based upon the "id". |
---|
| 1556 | ! We search all of the possible grids. It is required to find a domain |
---|
| 1557 | ! otherwise it is a fatal error. |
---|
| 1558 | |
---|
| 1559 | find_grid : DO WHILE ( ASSOCIATED(grid) ) |
---|
| 1560 | IF ( grid%id == id ) THEN |
---|
| 1561 | found = .TRUE. |
---|
| 1562 | old_grid%next => grid%next |
---|
| 1563 | CALL domain_destroy( grid ) |
---|
| 1564 | EXIT find_grid |
---|
| 1565 | END IF |
---|
| 1566 | old_grid => grid |
---|
| 1567 | grid => grid%next |
---|
| 1568 | END DO find_grid |
---|
| 1569 | |
---|
| 1570 | IF ( .NOT. found ) THEN |
---|
| 1571 | WRITE ( wrf_err_message , * ) 'module_domain: ', & |
---|
| 1572 | 'dealloc_space_domain: Could not de-allocate grid id ',id |
---|
| 1573 | CALL wrf_error_fatal ( TRIM( wrf_err_message ) ) |
---|
| 1574 | END IF |
---|
| 1575 | |
---|
| 1576 | END SUBROUTINE dealloc_space_domain |
---|
| 1577 | |
---|
| 1578 | |
---|
| 1579 | |
---|
| 1580 | ! This routine is used to DEALLOCATE space for a single domain type. |
---|
| 1581 | ! First, the field data are all removed through a CALL to the |
---|
| 1582 | ! dealloc_space_field routine. Then the pointer to the domain |
---|
| 1583 | ! itself is DEALLOCATEd. |
---|
| 1584 | |
---|
| 1585 | SUBROUTINE domain_destroy ( grid ) |
---|
| 1586 | |
---|
| 1587 | IMPLICIT NONE |
---|
| 1588 | |
---|
| 1589 | ! Input data. |
---|
| 1590 | |
---|
| 1591 | TYPE(domain) , POINTER :: grid |
---|
| 1592 | |
---|
| 1593 | CALL dealloc_space_field ( grid ) |
---|
| 1594 | CALL dealloc_linked_lists( grid ) |
---|
| 1595 | DEALLOCATE( grid%parents ) |
---|
| 1596 | DEALLOCATE( grid%nests ) |
---|
| 1597 | ! clean up time manager bits |
---|
| 1598 | CALL domain_clock_destroy( grid ) |
---|
| 1599 | CALL domain_alarms_destroy( grid ) |
---|
| 1600 | IF ( ASSOCIATED( grid%i_start ) ) THEN |
---|
| 1601 | DEALLOCATE( grid%i_start ) |
---|
| 1602 | ENDIF |
---|
| 1603 | IF ( ASSOCIATED( grid%i_end ) ) THEN |
---|
| 1604 | DEALLOCATE( grid%i_end ) |
---|
| 1605 | ENDIF |
---|
| 1606 | IF ( ASSOCIATED( grid%j_start ) ) THEN |
---|
| 1607 | DEALLOCATE( grid%j_start ) |
---|
| 1608 | ENDIF |
---|
| 1609 | IF ( ASSOCIATED( grid%j_end ) ) THEN |
---|
| 1610 | DEALLOCATE( grid%j_end ) |
---|
| 1611 | ENDIF |
---|
| 1612 | IF ( ASSOCIATED( grid%itsloc ) ) THEN |
---|
| 1613 | DEALLOCATE( grid%itsloc ) |
---|
| 1614 | ENDIF |
---|
| 1615 | IF ( ASSOCIATED( grid%jtsloc ) ) THEN |
---|
| 1616 | DEALLOCATE( grid%jtsloc ) |
---|
| 1617 | ENDIF |
---|
| 1618 | IF ( ASSOCIATED( grid%id_tsloc ) ) THEN |
---|
| 1619 | DEALLOCATE( grid%id_tsloc ) |
---|
| 1620 | ENDIF |
---|
| 1621 | IF ( ASSOCIATED( grid%lattsloc ) ) THEN |
---|
| 1622 | DEALLOCATE( grid%lattsloc ) |
---|
| 1623 | ENDIF |
---|
| 1624 | IF ( ASSOCIATED( grid%lontsloc ) ) THEN |
---|
| 1625 | DEALLOCATE( grid%lontsloc ) |
---|
| 1626 | ENDIF |
---|
| 1627 | IF ( ASSOCIATED( grid%nametsloc ) ) THEN |
---|
| 1628 | DEALLOCATE( grid%nametsloc ) |
---|
| 1629 | ENDIF |
---|
| 1630 | IF ( ASSOCIATED( grid%desctsloc ) ) THEN |
---|
| 1631 | DEALLOCATE( grid%desctsloc ) |
---|
| 1632 | ENDIF |
---|
| 1633 | IF ( ASSOCIATED( grid%ts_filename ) ) THEN |
---|
| 1634 | DEALLOCATE( grid%ts_filename ) |
---|
| 1635 | ENDIF |
---|
| 1636 | |
---|
| 1637 | #if WRFMEAS |
---|
| 1638 | ! L. Fita, LMD. May 2014 |
---|
| 1639 | IF ( ASSOCIATED( grid%ilidarloc ) ) THEN |
---|
| 1640 | DEALLOCATE( grid%ilidarloc ) |
---|
| 1641 | ENDIF |
---|
| 1642 | IF ( ASSOCIATED( grid%jlidarloc ) ) THEN |
---|
| 1643 | DEALLOCATE( grid%jlidarloc ) |
---|
| 1644 | ENDIF |
---|
| 1645 | IF ( ASSOCIATED( grid%id_lidarloc ) ) THEN |
---|
| 1646 | DEALLOCATE( grid%id_lidarloc ) |
---|
| 1647 | ENDIF |
---|
| 1648 | IF ( ASSOCIATED( grid%latlidarloc ) ) THEN |
---|
| 1649 | DEALLOCATE( grid%latlidarloc ) |
---|
| 1650 | ENDIF |
---|
| 1651 | IF ( ASSOCIATED( grid%lonlidarloc ) ) THEN |
---|
| 1652 | DEALLOCATE( grid%lonlidarloc ) |
---|
| 1653 | ENDIF |
---|
| 1654 | IF ( ASSOCIATED( grid%namelidarloc ) ) THEN |
---|
| 1655 | DEALLOCATE( grid%namelidarloc ) |
---|
| 1656 | ENDIF |
---|
| 1657 | IF ( ASSOCIATED( grid%desclidarloc ) ) THEN |
---|
| 1658 | DEALLOCATE( grid%desclidarloc ) |
---|
| 1659 | ENDIF |
---|
| 1660 | IF ( ASSOCIATED( grid%lidar_filename ) ) THEN |
---|
| 1661 | DEALLOCATE( grid%lidar_filename ) |
---|
| 1662 | ENDIF |
---|
| 1663 | #endif |
---|
| 1664 | |
---|
| 1665 | #if (EM_CORE == 1) |
---|
| 1666 | IF ( ASSOCIATED( grid%track_time_in ) ) THEN |
---|
| 1667 | DEALLOCATE( grid%track_time_in ) |
---|
| 1668 | ENDIF |
---|
| 1669 | |
---|
| 1670 | IF ( ASSOCIATED( grid%track_lat_in ) ) THEN |
---|
| 1671 | DEALLOCATE( grid%track_lat_in ) |
---|
| 1672 | ENDIF |
---|
| 1673 | |
---|
| 1674 | IF ( ASSOCIATED( grid%track_lon_in ) ) THEN |
---|
| 1675 | DEALLOCATE( grid%track_lon_in ) |
---|
| 1676 | ENDIF |
---|
| 1677 | |
---|
| 1678 | IF ( ASSOCIATED( grid%track_i ) ) THEN |
---|
| 1679 | DEALLOCATE( grid%track_i ) |
---|
| 1680 | ENDIF |
---|
| 1681 | |
---|
| 1682 | IF ( ASSOCIATED( grid%track_j ) ) THEN |
---|
| 1683 | DEALLOCATE( grid%track_j ) |
---|
| 1684 | ENDIF |
---|
| 1685 | |
---|
| 1686 | IF ( ASSOCIATED( grid%track_time_domain ) ) THEN |
---|
| 1687 | DEALLOCATE( grid%track_time_domain ) |
---|
| 1688 | ENDIF |
---|
| 1689 | |
---|
| 1690 | IF ( ASSOCIATED( grid%track_lat_domain ) ) THEN |
---|
| 1691 | DEALLOCATE( grid%track_lat_domain ) |
---|
| 1692 | ENDIF |
---|
| 1693 | |
---|
| 1694 | IF ( ASSOCIATED( grid%track_lon_domain ) ) THEN |
---|
| 1695 | DEALLOCATE( grid%track_lon_domain ) |
---|
| 1696 | ENDIF |
---|
| 1697 | #endif |
---|
| 1698 | DEALLOCATE( grid ) |
---|
| 1699 | NULLIFY( grid ) |
---|
| 1700 | |
---|
| 1701 | END SUBROUTINE domain_destroy |
---|
| 1702 | |
---|
| 1703 | SUBROUTINE dealloc_linked_lists ( grid ) |
---|
| 1704 | IMPLICIT NONE |
---|
| 1705 | TYPE(domain), POINTER :: grid |
---|
| 1706 | TYPE(fieldlist), POINTER :: p, q |
---|
| 1707 | p => grid%head_statevars |
---|
| 1708 | DO WHILE ( ASSOCIATED( p ) ) |
---|
| 1709 | q => p ; p => p%next ; DEALLOCATE(q) |
---|
| 1710 | ENDDO |
---|
| 1711 | NULLIFY(grid%head_statevars) ; NULLIFY( grid%tail_statevars) |
---|
| 1712 | #if (DA_CORE != 1) |
---|
| 1713 | IF ( .NOT. grid%is_intermediate ) THEN |
---|
| 1714 | ALLOCATE( grid%head_statevars ) |
---|
| 1715 | NULLIFY( grid%head_statevars%next) |
---|
| 1716 | grid%tail_statevars => grid%head_statevars |
---|
| 1717 | ENDIF |
---|
| 1718 | #endif |
---|
| 1719 | END SUBROUTINE dealloc_linked_lists |
---|
| 1720 | |
---|
| 1721 | RECURSIVE SUBROUTINE show_nest_subtree ( grid ) |
---|
| 1722 | TYPE(domain), POINTER :: grid |
---|
| 1723 | INTEGER myid |
---|
| 1724 | INTEGER kid |
---|
| 1725 | IF ( .NOT. ASSOCIATED( grid ) ) RETURN |
---|
| 1726 | myid = grid%id |
---|
| 1727 | DO kid = 1, max_nests |
---|
| 1728 | IF ( ASSOCIATED( grid%nests(kid)%ptr ) ) THEN |
---|
| 1729 | IF ( grid%nests(kid)%ptr%id .EQ. myid ) THEN |
---|
| 1730 | CALL wrf_error_fatal( 'show_nest_subtree: nest hierarchy corrupted' ) |
---|
| 1731 | ENDIF |
---|
| 1732 | CALL show_nest_subtree( grid%nests(kid)%ptr ) |
---|
| 1733 | ENDIF |
---|
| 1734 | ENDDO |
---|
| 1735 | END SUBROUTINE show_nest_subtree |
---|
| 1736 | |
---|
| 1737 | |
---|
| 1738 | ! |
---|
| 1739 | |
---|
| 1740 | ! This routine DEALLOCATEs each gridded field for this domain. For each type of |
---|
| 1741 | ! different array (1d, 2d, 3d, etc.), the space for each pointer is DEALLOCATEd |
---|
| 1742 | ! for every -1 (i.e., each different meteorological field). |
---|
| 1743 | |
---|
| 1744 | SUBROUTINE dealloc_space_field ( grid ) |
---|
| 1745 | |
---|
| 1746 | IMPLICIT NONE |
---|
| 1747 | |
---|
| 1748 | ! Input data. |
---|
| 1749 | |
---|
| 1750 | TYPE(domain) , POINTER :: grid |
---|
| 1751 | |
---|
| 1752 | ! Local data. |
---|
| 1753 | |
---|
| 1754 | INTEGER :: ierr |
---|
| 1755 | |
---|
| 1756 | # include <deallocs.inc> |
---|
| 1757 | |
---|
| 1758 | END SUBROUTINE dealloc_space_field |
---|
| 1759 | |
---|
| 1760 | ! |
---|
| 1761 | ! |
---|
| 1762 | RECURSIVE SUBROUTINE find_grid_by_id ( id, in_grid, result_grid ) |
---|
| 1763 | IMPLICIT NONE |
---|
| 1764 | INTEGER, INTENT(IN) :: id |
---|
| 1765 | TYPE(domain), POINTER :: in_grid |
---|
| 1766 | TYPE(domain), POINTER :: result_grid |
---|
| 1767 | ! <DESCRIPTION> |
---|
| 1768 | ! This is a recursive subroutine that traverses the domain hierarchy rooted |
---|
| 1769 | ! at the input argument <em>in_grid</em>, a pointer to TYPE(domain), and returns |
---|
| 1770 | ! a pointer to the domain matching the integer argument <em>id</em> if it exists. |
---|
| 1771 | ! |
---|
| 1772 | ! </DESCRIPTION> |
---|
| 1773 | TYPE(domain), POINTER :: grid_ptr |
---|
| 1774 | INTEGER :: kid |
---|
| 1775 | LOGICAL :: found |
---|
| 1776 | found = .FALSE. |
---|
| 1777 | NULLIFY(result_grid) |
---|
| 1778 | IF ( ASSOCIATED( in_grid ) ) THEN |
---|
| 1779 | IF ( in_grid%id .EQ. id ) THEN |
---|
| 1780 | result_grid => in_grid |
---|
| 1781 | ELSE |
---|
| 1782 | grid_ptr => in_grid |
---|
| 1783 | DO WHILE ( ASSOCIATED( grid_ptr ) .AND. .NOT. found ) |
---|
| 1784 | DO kid = 1, max_nests |
---|
| 1785 | IF ( ASSOCIATED( grid_ptr%nests(kid)%ptr ) .AND. .NOT. found ) THEN |
---|
| 1786 | CALL find_grid_by_id ( id, grid_ptr%nests(kid)%ptr, result_grid ) |
---|
| 1787 | IF ( ASSOCIATED( result_grid ) ) THEN |
---|
| 1788 | IF ( result_grid%id .EQ. id ) found = .TRUE. |
---|
| 1789 | ENDIF |
---|
| 1790 | ENDIF |
---|
| 1791 | ENDDO |
---|
| 1792 | IF ( .NOT. found ) grid_ptr => grid_ptr%sibling |
---|
| 1793 | ENDDO |
---|
| 1794 | ENDIF |
---|
| 1795 | ENDIF |
---|
| 1796 | RETURN |
---|
| 1797 | END SUBROUTINE find_grid_by_id |
---|
| 1798 | |
---|
| 1799 | |
---|
| 1800 | FUNCTION first_loc_integer ( array , search ) RESULT ( loc ) |
---|
| 1801 | |
---|
| 1802 | IMPLICIT NONE |
---|
| 1803 | |
---|
| 1804 | ! Input data. |
---|
| 1805 | |
---|
| 1806 | INTEGER , INTENT(IN) , DIMENSION(:) :: array |
---|
| 1807 | INTEGER , INTENT(IN) :: search |
---|
| 1808 | |
---|
| 1809 | ! Output data. |
---|
| 1810 | |
---|
| 1811 | INTEGER :: loc |
---|
| 1812 | |
---|
| 1813 | !<DESCRIPTION> |
---|
| 1814 | ! This routine is used to find a specific domain identifier in an array |
---|
| 1815 | ! of domain identifiers. |
---|
| 1816 | ! |
---|
| 1817 | !</DESCRIPTION> |
---|
| 1818 | |
---|
| 1819 | ! Local data. |
---|
| 1820 | |
---|
| 1821 | INTEGER :: loop |
---|
| 1822 | |
---|
| 1823 | loc = -1 |
---|
| 1824 | find : DO loop = 1 , SIZE(array) |
---|
| 1825 | IF ( search == array(loop) ) THEN |
---|
| 1826 | loc = loop |
---|
| 1827 | EXIT find |
---|
| 1828 | END IF |
---|
| 1829 | END DO find |
---|
| 1830 | |
---|
| 1831 | END FUNCTION first_loc_integer |
---|
| 1832 | ! |
---|
| 1833 | SUBROUTINE init_module_domain |
---|
| 1834 | END SUBROUTINE init_module_domain |
---|
| 1835 | |
---|
| 1836 | |
---|
| 1837 | ! <DESCRIPTION> |
---|
| 1838 | ! |
---|
| 1839 | ! The following routines named domain_*() are convenience routines that |
---|
| 1840 | ! eliminate many duplicated bits of code. They provide shortcuts for the |
---|
| 1841 | ! most common operations on the domain_clock field of TYPE(domain). |
---|
| 1842 | ! |
---|
| 1843 | ! </DESCRIPTION> |
---|
| 1844 | |
---|
| 1845 | FUNCTION domain_get_current_time ( grid ) RESULT ( current_time ) |
---|
| 1846 | IMPLICIT NONE |
---|
| 1847 | ! <DESCRIPTION> |
---|
| 1848 | ! This convenience function returns the current time for domain grid. |
---|
| 1849 | ! |
---|
| 1850 | ! </DESCRIPTION> |
---|
| 1851 | TYPE(domain), INTENT(IN) :: grid |
---|
| 1852 | ! result |
---|
| 1853 | TYPE(WRFU_Time) :: current_time |
---|
| 1854 | ! locals |
---|
| 1855 | INTEGER :: rc |
---|
| 1856 | CALL WRFU_ClockGet( grid%domain_clock, CurrTime=current_time, & |
---|
| 1857 | rc=rc ) |
---|
| 1858 | IF ( rc /= WRFU_SUCCESS ) THEN |
---|
| 1859 | CALL wrf_error_fatal ( & |
---|
| 1860 | 'domain_get_current_time: WRFU_ClockGet failed' ) |
---|
| 1861 | ENDIF |
---|
| 1862 | END FUNCTION domain_get_current_time |
---|
| 1863 | |
---|
| 1864 | |
---|
| 1865 | FUNCTION domain_get_start_time ( grid ) RESULT ( start_time ) |
---|
| 1866 | IMPLICIT NONE |
---|
| 1867 | ! <DESCRIPTION> |
---|
| 1868 | ! This convenience function returns the start time for domain grid. |
---|
| 1869 | ! |
---|
| 1870 | ! </DESCRIPTION> |
---|
| 1871 | TYPE(domain), INTENT(IN) :: grid |
---|
| 1872 | ! result |
---|
| 1873 | TYPE(WRFU_Time) :: start_time |
---|
| 1874 | ! locals |
---|
| 1875 | INTEGER :: rc |
---|
| 1876 | CALL WRFU_ClockGet( grid%domain_clock, StartTime=start_time, & |
---|
| 1877 | rc=rc ) |
---|
| 1878 | IF ( rc /= WRFU_SUCCESS ) THEN |
---|
| 1879 | CALL wrf_error_fatal ( & |
---|
| 1880 | 'domain_get_start_time: WRFU_ClockGet failed' ) |
---|
| 1881 | ENDIF |
---|
| 1882 | END FUNCTION domain_get_start_time |
---|
| 1883 | |
---|
| 1884 | |
---|
| 1885 | FUNCTION domain_get_stop_time ( grid ) RESULT ( stop_time ) |
---|
| 1886 | IMPLICIT NONE |
---|
| 1887 | ! <DESCRIPTION> |
---|
| 1888 | ! This convenience function returns the stop time for domain grid. |
---|
| 1889 | ! |
---|
| 1890 | ! </DESCRIPTION> |
---|
| 1891 | TYPE(domain), INTENT(IN) :: grid |
---|
| 1892 | ! result |
---|
| 1893 | TYPE(WRFU_Time) :: stop_time |
---|
| 1894 | ! locals |
---|
| 1895 | INTEGER :: rc |
---|
| 1896 | CALL WRFU_ClockGet( grid%domain_clock, StopTime=stop_time, & |
---|
| 1897 | rc=rc ) |
---|
| 1898 | IF ( rc /= WRFU_SUCCESS ) THEN |
---|
| 1899 | CALL wrf_error_fatal ( & |
---|
| 1900 | 'domain_get_stop_time: WRFU_ClockGet failed' ) |
---|
| 1901 | ENDIF |
---|
| 1902 | END FUNCTION domain_get_stop_time |
---|
| 1903 | |
---|
| 1904 | |
---|
| 1905 | FUNCTION domain_get_time_step ( grid ) RESULT ( time_step ) |
---|
| 1906 | IMPLICIT NONE |
---|
| 1907 | ! <DESCRIPTION> |
---|
| 1908 | ! This convenience function returns the time step for domain grid. |
---|
| 1909 | ! |
---|
| 1910 | ! </DESCRIPTION> |
---|
| 1911 | TYPE(domain), INTENT(IN) :: grid |
---|
| 1912 | ! result |
---|
| 1913 | TYPE(WRFU_TimeInterval) :: time_step |
---|
| 1914 | ! locals |
---|
| 1915 | INTEGER :: rc |
---|
| 1916 | CALL WRFU_ClockGet( grid%domain_clock, timeStep=time_step, & |
---|
| 1917 | rc=rc ) |
---|
| 1918 | IF ( rc /= WRFU_SUCCESS ) THEN |
---|
| 1919 | CALL wrf_error_fatal ( & |
---|
| 1920 | 'domain_get_time_step: WRFU_ClockGet failed' ) |
---|
| 1921 | ENDIF |
---|
| 1922 | END FUNCTION domain_get_time_step |
---|
| 1923 | |
---|
| 1924 | |
---|
| 1925 | FUNCTION domain_get_advanceCount ( grid ) RESULT ( advanceCount ) |
---|
| 1926 | IMPLICIT NONE |
---|
| 1927 | ! <DESCRIPTION> |
---|
| 1928 | ! This convenience function returns the time step for domain grid. |
---|
| 1929 | ! Also converts from INTEGER(WRFU_KIND_I8) to INTEGER. |
---|
| 1930 | ! |
---|
| 1931 | ! </DESCRIPTION> |
---|
| 1932 | TYPE(domain), INTENT(IN) :: grid |
---|
| 1933 | ! result |
---|
| 1934 | INTEGER :: advanceCount |
---|
| 1935 | ! locals |
---|
| 1936 | INTEGER(WRFU_KIND_I8) :: advanceCountLcl |
---|
| 1937 | INTEGER :: rc |
---|
| 1938 | CALL WRFU_ClockGet( grid%domain_clock, & |
---|
| 1939 | advanceCount=advanceCountLcl, & |
---|
| 1940 | rc=rc ) |
---|
| 1941 | IF ( rc /= WRFU_SUCCESS ) THEN |
---|
| 1942 | CALL wrf_error_fatal ( & |
---|
| 1943 | 'domain_get_advanceCount: WRFU_ClockGet failed' ) |
---|
| 1944 | ENDIF |
---|
| 1945 | advanceCount = advanceCountLcl |
---|
| 1946 | END FUNCTION domain_get_advanceCount |
---|
| 1947 | |
---|
| 1948 | |
---|
| 1949 | SUBROUTINE domain_alarms_destroy ( grid ) |
---|
| 1950 | IMPLICIT NONE |
---|
| 1951 | ! <DESCRIPTION> |
---|
| 1952 | ! This convenience routine destroys and deallocates all alarms associated |
---|
| 1953 | ! with grid. |
---|
| 1954 | ! |
---|
| 1955 | ! </DESCRIPTION> |
---|
| 1956 | TYPE(domain), INTENT(INOUT) :: grid |
---|
| 1957 | ! Local data. |
---|
| 1958 | INTEGER :: alarmid |
---|
| 1959 | |
---|
| 1960 | IF ( ASSOCIATED( grid%alarms ) .AND. & |
---|
| 1961 | ASSOCIATED( grid%alarms_created ) ) THEN |
---|
| 1962 | DO alarmid = 1, MAX_WRF_ALARMS |
---|
| 1963 | IF ( grid%alarms_created( alarmid ) ) THEN |
---|
| 1964 | CALL WRFU_AlarmDestroy( grid%alarms( alarmid ) ) |
---|
| 1965 | grid%alarms_created( alarmid ) = .FALSE. |
---|
| 1966 | ENDIF |
---|
| 1967 | ENDDO |
---|
| 1968 | DEALLOCATE( grid%alarms ) |
---|
| 1969 | NULLIFY( grid%alarms ) |
---|
| 1970 | DEALLOCATE( grid%alarms_created ) |
---|
| 1971 | NULLIFY( grid%alarms_created ) |
---|
| 1972 | ENDIF |
---|
| 1973 | END SUBROUTINE domain_alarms_destroy |
---|
| 1974 | |
---|
| 1975 | |
---|
| 1976 | SUBROUTINE domain_clock_destroy ( grid ) |
---|
| 1977 | IMPLICIT NONE |
---|
| 1978 | ! <DESCRIPTION> |
---|
| 1979 | ! This convenience routine destroys and deallocates the domain clock. |
---|
| 1980 | ! |
---|
| 1981 | ! </DESCRIPTION> |
---|
| 1982 | TYPE(domain), INTENT(INOUT) :: grid |
---|
| 1983 | IF ( ASSOCIATED( grid%domain_clock ) ) THEN |
---|
| 1984 | IF ( grid%domain_clock_created ) THEN |
---|
| 1985 | CALL WRFU_ClockDestroy( grid%domain_clock ) |
---|
| 1986 | grid%domain_clock_created = .FALSE. |
---|
| 1987 | ENDIF |
---|
| 1988 | DEALLOCATE( grid%domain_clock ) |
---|
| 1989 | NULLIFY( grid%domain_clock ) |
---|
| 1990 | ENDIF |
---|
| 1991 | END SUBROUTINE domain_clock_destroy |
---|
| 1992 | |
---|
| 1993 | |
---|
| 1994 | FUNCTION domain_last_time_step ( grid ) RESULT ( LAST_TIME ) |
---|
| 1995 | IMPLICIT NONE |
---|
| 1996 | ! <DESCRIPTION> |
---|
| 1997 | ! This convenience function returns .TRUE. if this is the last time |
---|
| 1998 | ! step for domain grid. Thanks to Tom Black. |
---|
| 1999 | ! |
---|
| 2000 | ! </DESCRIPTION> |
---|
| 2001 | TYPE(domain), INTENT(IN) :: grid |
---|
| 2002 | ! result |
---|
| 2003 | LOGICAL :: LAST_TIME |
---|
| 2004 | LAST_TIME = domain_get_stop_time( grid ) .EQ. & |
---|
| 2005 | ( domain_get_current_time( grid ) + & |
---|
| 2006 | domain_get_time_step( grid ) ) |
---|
| 2007 | END FUNCTION domain_last_time_step |
---|
| 2008 | |
---|
| 2009 | |
---|
| 2010 | |
---|
| 2011 | FUNCTION domain_clockisstoptime ( grid ) RESULT ( is_stop_time ) |
---|
| 2012 | IMPLICIT NONE |
---|
| 2013 | ! <DESCRIPTION> |
---|
| 2014 | ! This convenience function returns .TRUE. iff grid%clock has reached its |
---|
| 2015 | ! stop time. |
---|
| 2016 | ! |
---|
| 2017 | ! </DESCRIPTION> |
---|
| 2018 | TYPE(domain), INTENT(IN) :: grid |
---|
| 2019 | ! result |
---|
| 2020 | LOGICAL :: is_stop_time |
---|
| 2021 | INTEGER :: rc |
---|
| 2022 | is_stop_time = WRFU_ClockIsStopTime( grid%domain_clock , rc=rc ) |
---|
| 2023 | IF ( rc /= WRFU_SUCCESS ) THEN |
---|
| 2024 | CALL wrf_error_fatal ( & |
---|
| 2025 | 'domain_clockisstoptime: WRFU_ClockIsStopTime() failed' ) |
---|
| 2026 | ENDIF |
---|
| 2027 | END FUNCTION domain_clockisstoptime |
---|
| 2028 | |
---|
| 2029 | |
---|
| 2030 | |
---|
| 2031 | FUNCTION domain_clockisstopsubtime ( grid ) RESULT ( is_stop_subtime ) |
---|
| 2032 | IMPLICIT NONE |
---|
| 2033 | ! <DESCRIPTION> |
---|
| 2034 | ! This convenience function returns .TRUE. iff grid%clock has reached its |
---|
| 2035 | ! grid%stop_subtime. |
---|
| 2036 | ! |
---|
| 2037 | ! </DESCRIPTION> |
---|
| 2038 | TYPE(domain), INTENT(IN) :: grid |
---|
| 2039 | ! result |
---|
| 2040 | LOGICAL :: is_stop_subtime |
---|
| 2041 | INTEGER :: rc |
---|
| 2042 | TYPE(WRFU_TimeInterval) :: timeStep |
---|
| 2043 | TYPE(WRFU_Time) :: currentTime |
---|
| 2044 | LOGICAL :: positive_timestep |
---|
| 2045 | is_stop_subtime = .FALSE. |
---|
| 2046 | CALL domain_clock_get( grid, time_step=timeStep, & |
---|
| 2047 | current_time=currentTime ) |
---|
| 2048 | positive_timestep = ESMF_TimeIntervalIsPositive( timeStep ) |
---|
| 2049 | IF ( positive_timestep ) THEN |
---|
| 2050 | ! hack for bug in PGI 5.1-x |
---|
| 2051 | ! IF ( currentTime .GE. grid%stop_subtime ) THEN |
---|
| 2052 | IF ( ESMF_TimeGE( currentTime, grid%stop_subtime ) ) THEN |
---|
| 2053 | is_stop_subtime = .TRUE. |
---|
| 2054 | ENDIF |
---|
| 2055 | ELSE |
---|
| 2056 | ! hack for bug in PGI 5.1-x |
---|
| 2057 | ! IF ( currentTime .LE. grid%stop_subtime ) THEN |
---|
| 2058 | IF ( ESMF_TimeLE( currentTime, grid%stop_subtime ) ) THEN |
---|
| 2059 | is_stop_subtime = .TRUE. |
---|
| 2060 | ENDIF |
---|
| 2061 | ENDIF |
---|
| 2062 | END FUNCTION domain_clockisstopsubtime |
---|
| 2063 | |
---|
| 2064 | |
---|
| 2065 | |
---|
| 2066 | |
---|
| 2067 | FUNCTION domain_get_sim_start_time ( grid ) RESULT ( simulationStartTime ) |
---|
| 2068 | IMPLICIT NONE |
---|
| 2069 | ! <DESCRIPTION> |
---|
| 2070 | ! This convenience routine returns simulation start time for domain grid as |
---|
| 2071 | ! a time instant. |
---|
| 2072 | ! |
---|
| 2073 | ! If this is not a restart run, the start_time of head_grid%clock is returned |
---|
| 2074 | ! instead. |
---|
| 2075 | ! |
---|
| 2076 | ! Note that simulation start time remains constant through restarts while |
---|
| 2077 | ! the start_time of head_grid%clock always refers to the start time of the |
---|
| 2078 | ! current run (restart or otherwise). |
---|
| 2079 | ! |
---|
| 2080 | ! </DESCRIPTION> |
---|
| 2081 | TYPE(domain), INTENT(IN) :: grid |
---|
| 2082 | ! result |
---|
| 2083 | TYPE(WRFU_Time) :: simulationStartTime |
---|
| 2084 | ! Locals |
---|
| 2085 | INTEGER :: rc |
---|
| 2086 | INTEGER :: simulation_start_year, simulation_start_month, & |
---|
| 2087 | simulation_start_day, simulation_start_hour , & |
---|
| 2088 | simulation_start_minute, simulation_start_second |
---|
| 2089 | CALL nl_get_simulation_start_year ( 1, simulation_start_year ) |
---|
| 2090 | CALL nl_get_simulation_start_month ( 1, simulation_start_month ) |
---|
| 2091 | CALL nl_get_simulation_start_day ( 1, simulation_start_day ) |
---|
| 2092 | CALL nl_get_simulation_start_hour ( 1, simulation_start_hour ) |
---|
| 2093 | CALL nl_get_simulation_start_minute ( 1, simulation_start_minute ) |
---|
| 2094 | CALL nl_get_simulation_start_second ( 1, simulation_start_second ) |
---|
| 2095 | CALL WRFU_TimeSet( simulationStartTime, & |
---|
| 2096 | YY=simulation_start_year, & |
---|
| 2097 | MM=simulation_start_month, & |
---|
| 2098 | DD=simulation_start_day, & |
---|
| 2099 | H=simulation_start_hour, & |
---|
| 2100 | M=simulation_start_minute, & |
---|
| 2101 | S=simulation_start_second, & |
---|
| 2102 | rc=rc ) |
---|
| 2103 | IF ( rc /= WRFU_SUCCESS ) THEN |
---|
| 2104 | CALL nl_get_start_year ( 1, simulation_start_year ) |
---|
| 2105 | CALL nl_get_start_month ( 1, simulation_start_month ) |
---|
| 2106 | CALL nl_get_start_day ( 1, simulation_start_day ) |
---|
| 2107 | CALL nl_get_start_hour ( 1, simulation_start_hour ) |
---|
| 2108 | CALL nl_get_start_minute ( 1, simulation_start_minute ) |
---|
| 2109 | CALL nl_get_start_second ( 1, simulation_start_second ) |
---|
| 2110 | CALL wrf_debug( 150, "WARNING: domain_get_sim_start_time using head_grid start time from namelist" ) |
---|
| 2111 | CALL WRFU_TimeSet( simulationStartTime, & |
---|
| 2112 | YY=simulation_start_year, & |
---|
| 2113 | MM=simulation_start_month, & |
---|
| 2114 | DD=simulation_start_day, & |
---|
| 2115 | H=simulation_start_hour, & |
---|
| 2116 | M=simulation_start_minute, & |
---|
| 2117 | S=simulation_start_second, & |
---|
| 2118 | rc=rc ) |
---|
| 2119 | ENDIF |
---|
| 2120 | RETURN |
---|
| 2121 | END FUNCTION domain_get_sim_start_time |
---|
| 2122 | |
---|
| 2123 | FUNCTION domain_get_time_since_sim_start ( grid ) RESULT ( time_since_sim_start ) |
---|
| 2124 | IMPLICIT NONE |
---|
| 2125 | ! <DESCRIPTION> |
---|
| 2126 | ! This convenience function returns the time elapsed since start of |
---|
| 2127 | ! simulation for domain grid. |
---|
| 2128 | ! |
---|
| 2129 | ! Note that simulation start time remains constant through restarts while |
---|
| 2130 | ! the start_time of grid%clock always refers to the start time of the |
---|
| 2131 | ! current run (restart or otherwise). |
---|
| 2132 | ! |
---|
| 2133 | ! </DESCRIPTION> |
---|
| 2134 | TYPE(domain), INTENT(IN) :: grid |
---|
| 2135 | ! result |
---|
| 2136 | TYPE(WRFU_TimeInterval) :: time_since_sim_start |
---|
| 2137 | ! locals |
---|
| 2138 | TYPE(WRFU_Time) :: lcl_currtime, lcl_simstarttime |
---|
| 2139 | lcl_simstarttime = domain_get_sim_start_time( grid ) |
---|
| 2140 | lcl_currtime = domain_get_current_time ( grid ) |
---|
| 2141 | time_since_sim_start = lcl_currtime - lcl_simstarttime |
---|
| 2142 | END FUNCTION domain_get_time_since_sim_start |
---|
| 2143 | |
---|
| 2144 | |
---|
| 2145 | |
---|
| 2146 | |
---|
| 2147 | SUBROUTINE domain_clock_get( grid, current_time, & |
---|
| 2148 | current_timestr, & |
---|
| 2149 | current_timestr_frac, & |
---|
| 2150 | start_time, start_timestr, & |
---|
| 2151 | stop_time, stop_timestr, & |
---|
| 2152 | time_step, time_stepstr, & |
---|
| 2153 | time_stepstr_frac, & |
---|
| 2154 | advanceCount, & |
---|
| 2155 | currentDayOfYearReal, & |
---|
| 2156 | minutesSinceSimulationStart, & |
---|
| 2157 | timeSinceSimulationStart, & |
---|
| 2158 | simulationStartTime, & |
---|
| 2159 | simulationStartTimeStr ) |
---|
| 2160 | IMPLICIT NONE |
---|
| 2161 | TYPE(domain), INTENT(IN) :: grid |
---|
| 2162 | TYPE(WRFU_Time), INTENT( OUT), OPTIONAL :: current_time |
---|
| 2163 | CHARACTER (LEN=*), INTENT( OUT), OPTIONAL :: current_timestr |
---|
| 2164 | CHARACTER (LEN=*), INTENT( OUT), OPTIONAL :: current_timestr_frac |
---|
| 2165 | TYPE(WRFU_Time), INTENT( OUT), OPTIONAL :: start_time |
---|
| 2166 | CHARACTER (LEN=*), INTENT( OUT), OPTIONAL :: start_timestr |
---|
| 2167 | TYPE(WRFU_Time), INTENT( OUT), OPTIONAL :: stop_time |
---|
| 2168 | CHARACTER (LEN=*), INTENT( OUT), OPTIONAL :: stop_timestr |
---|
| 2169 | TYPE(WRFU_TimeInterval), INTENT( OUT), OPTIONAL :: time_step |
---|
| 2170 | CHARACTER (LEN=*), INTENT( OUT), OPTIONAL :: time_stepstr |
---|
| 2171 | CHARACTER (LEN=*), INTENT( OUT), OPTIONAL :: time_stepstr_frac |
---|
| 2172 | INTEGER, INTENT( OUT), OPTIONAL :: advanceCount |
---|
| 2173 | ! currentDayOfYearReal = 0.0 at 0Z on 1 January, 0.5 at 12Z on |
---|
| 2174 | ! 1 January, etc. |
---|
| 2175 | REAL, INTENT( OUT), OPTIONAL :: currentDayOfYearReal |
---|
| 2176 | ! Time at which simulation started. If this is not a restart run, |
---|
| 2177 | ! start_time is returned instead. |
---|
| 2178 | TYPE(WRFU_Time), INTENT( OUT), OPTIONAL :: simulationStartTime |
---|
| 2179 | CHARACTER (LEN=*), INTENT( OUT), OPTIONAL :: simulationStartTimeStr |
---|
| 2180 | ! time interval since start of simulation, includes effects of |
---|
| 2181 | ! restarting even when restart uses a different timestep |
---|
| 2182 | TYPE(WRFU_TimeInterval), INTENT( OUT), OPTIONAL :: timeSinceSimulationStart |
---|
| 2183 | ! minutes since simulation start date |
---|
| 2184 | REAL, INTENT( OUT), OPTIONAL :: minutesSinceSimulationStart |
---|
| 2185 | ! <DESCRIPTION> |
---|
| 2186 | ! This convenience routine returns clock information for domain grid in |
---|
| 2187 | ! various forms. The caller is responsible for ensuring that character |
---|
| 2188 | ! string actual arguments are big enough. |
---|
| 2189 | ! |
---|
| 2190 | ! </DESCRIPTION> |
---|
| 2191 | ! Locals |
---|
| 2192 | TYPE(WRFU_Time) :: lcl_currtime, lcl_stoptime, lcl_starttime |
---|
| 2193 | TYPE(WRFU_Time) :: lcl_simulationStartTime |
---|
| 2194 | TYPE(WRFU_TimeInterval) :: lcl_time_step, lcl_timeSinceSimulationStart |
---|
| 2195 | INTEGER :: days, seconds, Sn, Sd, rc |
---|
| 2196 | CHARACTER (LEN=256) :: tmp_str |
---|
| 2197 | CHARACTER (LEN=256) :: frac_str |
---|
| 2198 | REAL(WRFU_KIND_R8) :: currentDayOfYearR8 |
---|
| 2199 | IF ( PRESENT( start_time ) ) THEN |
---|
| 2200 | start_time = domain_get_start_time ( grid ) |
---|
| 2201 | ENDIF |
---|
| 2202 | IF ( PRESENT( start_timestr ) ) THEN |
---|
| 2203 | lcl_starttime = domain_get_start_time ( grid ) |
---|
| 2204 | CALL wrf_timetoa ( lcl_starttime, start_timestr ) |
---|
| 2205 | ENDIF |
---|
| 2206 | IF ( PRESENT( time_step ) ) THEN |
---|
| 2207 | time_step = domain_get_time_step ( grid ) |
---|
| 2208 | ENDIF |
---|
| 2209 | IF ( PRESENT( time_stepstr ) ) THEN |
---|
| 2210 | lcl_time_step = domain_get_time_step ( grid ) |
---|
| 2211 | CALL WRFU_TimeIntervalGet( lcl_time_step, & |
---|
| 2212 | timeString=time_stepstr, rc=rc ) |
---|
| 2213 | IF ( rc /= WRFU_SUCCESS ) THEN |
---|
| 2214 | CALL wrf_error_fatal ( & |
---|
| 2215 | 'domain_clock_get: WRFU_TimeIntervalGet() failed' ) |
---|
| 2216 | ENDIF |
---|
| 2217 | ENDIF |
---|
| 2218 | IF ( PRESENT( time_stepstr_frac ) ) THEN |
---|
| 2219 | lcl_time_step = domain_get_time_step ( grid ) |
---|
| 2220 | CALL WRFU_TimeIntervalGet( lcl_time_step, timeString=tmp_str, & |
---|
| 2221 | Sn=Sn, Sd=Sd, rc=rc ) |
---|
| 2222 | IF ( rc /= WRFU_SUCCESS ) THEN |
---|
| 2223 | CALL wrf_error_fatal ( & |
---|
| 2224 | 'domain_clock_get: WRFU_TimeIntervalGet() failed' ) |
---|
| 2225 | ENDIF |
---|
| 2226 | CALL fraction_to_string( Sn, Sd, frac_str ) |
---|
| 2227 | time_stepstr_frac = TRIM(tmp_str)//TRIM(frac_str) |
---|
| 2228 | ENDIF |
---|
| 2229 | IF ( PRESENT( advanceCount ) ) THEN |
---|
| 2230 | advanceCount = domain_get_advanceCount ( grid ) |
---|
| 2231 | ENDIF |
---|
| 2232 | ! This duplication avoids assignment of time-manager objects |
---|
| 2233 | ! which works now in ESMF 2.2.0 but may not work in the future |
---|
| 2234 | ! if these objects become "deep". We have already been bitten |
---|
| 2235 | ! by this when the clock objects were changed from "shallow" to |
---|
| 2236 | ! "deep". Once again, adherence to orthodox canonical form by |
---|
| 2237 | ! ESMF would avoid all this crap. |
---|
| 2238 | IF ( PRESENT( current_time ) ) THEN |
---|
| 2239 | current_time = domain_get_current_time ( grid ) |
---|
| 2240 | ENDIF |
---|
| 2241 | IF ( PRESENT( current_timestr ) ) THEN |
---|
| 2242 | lcl_currtime = domain_get_current_time ( grid ) |
---|
| 2243 | CALL wrf_timetoa ( lcl_currtime, current_timestr ) |
---|
| 2244 | ENDIF |
---|
| 2245 | ! current time string including fractional part, if present |
---|
| 2246 | IF ( PRESENT( current_timestr_frac ) ) THEN |
---|
| 2247 | lcl_currtime = domain_get_current_time ( grid ) |
---|
| 2248 | CALL wrf_timetoa ( lcl_currtime, tmp_str ) |
---|
| 2249 | CALL WRFU_TimeGet( lcl_currtime, Sn=Sn, Sd=Sd, rc=rc ) |
---|
| 2250 | IF ( rc /= WRFU_SUCCESS ) THEN |
---|
| 2251 | CALL wrf_error_fatal ( & |
---|
| 2252 | 'domain_clock_get: WRFU_TimeGet() failed' ) |
---|
| 2253 | ENDIF |
---|
| 2254 | CALL fraction_to_string( Sn, Sd, frac_str ) |
---|
| 2255 | current_timestr_frac = TRIM(tmp_str)//TRIM(frac_str) |
---|
| 2256 | ENDIF |
---|
| 2257 | IF ( PRESENT( stop_time ) ) THEN |
---|
| 2258 | stop_time = domain_get_stop_time ( grid ) |
---|
| 2259 | ENDIF |
---|
| 2260 | IF ( PRESENT( stop_timestr ) ) THEN |
---|
| 2261 | lcl_stoptime = domain_get_stop_time ( grid ) |
---|
| 2262 | CALL wrf_timetoa ( lcl_stoptime, stop_timestr ) |
---|
| 2263 | ENDIF |
---|
| 2264 | IF ( PRESENT( currentDayOfYearReal ) ) THEN |
---|
| 2265 | lcl_currtime = domain_get_current_time ( grid ) |
---|
| 2266 | CALL WRFU_TimeGet( lcl_currtime, dayOfYear_r8=currentDayOfYearR8, & |
---|
| 2267 | rc=rc ) |
---|
| 2268 | IF ( rc /= WRFU_SUCCESS ) THEN |
---|
| 2269 | CALL wrf_error_fatal ( & |
---|
| 2270 | 'domain_clock_get: WRFU_TimeGet(dayOfYear_r8) failed' ) |
---|
| 2271 | ENDIF |
---|
| 2272 | currentDayOfYearReal = REAL( currentDayOfYearR8 ) - 1.0 |
---|
| 2273 | ENDIF |
---|
| 2274 | IF ( PRESENT( simulationStartTime ) ) THEN |
---|
| 2275 | simulationStartTime = domain_get_sim_start_time( grid ) |
---|
| 2276 | ENDIF |
---|
| 2277 | IF ( PRESENT( simulationStartTimeStr ) ) THEN |
---|
| 2278 | lcl_simulationStartTime = domain_get_sim_start_time( grid ) |
---|
| 2279 | CALL wrf_timetoa ( lcl_simulationStartTime, simulationStartTimeStr ) |
---|
| 2280 | ENDIF |
---|
| 2281 | IF ( PRESENT( timeSinceSimulationStart ) ) THEN |
---|
| 2282 | timeSinceSimulationStart = domain_get_time_since_sim_start( grid ) |
---|
| 2283 | ENDIF |
---|
| 2284 | IF ( PRESENT( minutesSinceSimulationStart ) ) THEN |
---|
| 2285 | lcl_timeSinceSimulationStart = domain_get_time_since_sim_start( grid ) |
---|
| 2286 | CALL WRFU_TimeIntervalGet( lcl_timeSinceSimulationStart, & |
---|
| 2287 | D=days, S=seconds, Sn=Sn, Sd=Sd, rc=rc ) |
---|
| 2288 | IF ( rc /= WRFU_SUCCESS ) THEN |
---|
| 2289 | CALL wrf_error_fatal ( & |
---|
| 2290 | 'domain_clock_get: WRFU_TimeIntervalGet() failed' ) |
---|
| 2291 | ENDIF |
---|
| 2292 | ! get rid of hard-coded constants |
---|
| 2293 | minutesSinceSimulationStart = ( REAL( days ) * 24. * 60. ) + & |
---|
| 2294 | ( REAL( seconds ) / 60. ) |
---|
| 2295 | IF ( Sd /= 0 ) THEN |
---|
| 2296 | minutesSinceSimulationStart = minutesSinceSimulationStart + & |
---|
| 2297 | ( ( REAL( Sn ) / REAL( Sd ) ) / 60. ) |
---|
| 2298 | ENDIF |
---|
| 2299 | ENDIF |
---|
| 2300 | RETURN |
---|
| 2301 | END SUBROUTINE domain_clock_get |
---|
| 2302 | |
---|
| 2303 | FUNCTION domain_clockisstarttime ( grid ) RESULT ( is_start_time ) |
---|
| 2304 | IMPLICIT NONE |
---|
| 2305 | ! <DESCRIPTION> |
---|
| 2306 | ! This convenience function returns .TRUE. iff grid%clock is at its |
---|
| 2307 | ! start time. |
---|
| 2308 | ! |
---|
| 2309 | ! </DESCRIPTION> |
---|
| 2310 | TYPE(domain), INTENT(IN) :: grid |
---|
| 2311 | ! result |
---|
| 2312 | LOGICAL :: is_start_time |
---|
| 2313 | TYPE(WRFU_Time) :: start_time, current_time |
---|
| 2314 | CALL domain_clock_get( grid, current_time=current_time, & |
---|
| 2315 | start_time=start_time ) |
---|
| 2316 | is_start_time = ( current_time == start_time ) |
---|
| 2317 | END FUNCTION domain_clockisstarttime |
---|
| 2318 | |
---|
| 2319 | FUNCTION domain_clockissimstarttime ( grid ) RESULT ( is_sim_start_time ) |
---|
| 2320 | IMPLICIT NONE |
---|
| 2321 | ! <DESCRIPTION> |
---|
| 2322 | ! This convenience function returns .TRUE. iff grid%clock is at the |
---|
| 2323 | ! simulation start time. (It returns .FALSE. during a restart run.) |
---|
| 2324 | ! |
---|
| 2325 | ! </DESCRIPTION> |
---|
| 2326 | TYPE(domain), INTENT(IN) :: grid |
---|
| 2327 | ! result |
---|
| 2328 | LOGICAL :: is_sim_start_time |
---|
| 2329 | TYPE(WRFU_Time) :: simulationStartTime, current_time |
---|
| 2330 | CALL domain_clock_get( grid, current_time=current_time, & |
---|
| 2331 | simulationStartTime=simulationStartTime ) |
---|
| 2332 | is_sim_start_time = ( current_time == simulationStartTime ) |
---|
| 2333 | END FUNCTION domain_clockissimstarttime |
---|
| 2334 | |
---|
| 2335 | |
---|
| 2336 | |
---|
| 2337 | |
---|
| 2338 | SUBROUTINE domain_clock_create( grid, StartTime, & |
---|
| 2339 | StopTime, & |
---|
| 2340 | TimeStep ) |
---|
| 2341 | IMPLICIT NONE |
---|
| 2342 | TYPE(domain), INTENT(INOUT) :: grid |
---|
| 2343 | TYPE(WRFU_Time), INTENT(IN ) :: StartTime |
---|
| 2344 | TYPE(WRFU_Time), INTENT(IN ) :: StopTime |
---|
| 2345 | TYPE(WRFU_TimeInterval), INTENT(IN ) :: TimeStep |
---|
| 2346 | ! <DESCRIPTION> |
---|
| 2347 | ! This convenience routine creates the domain_clock for domain grid and |
---|
| 2348 | ! sets associated flags. |
---|
| 2349 | ! |
---|
| 2350 | ! </DESCRIPTION> |
---|
| 2351 | ! Locals |
---|
| 2352 | INTEGER :: rc |
---|
| 2353 | grid%domain_clock = WRFU_ClockCreate( TimeStep= TimeStep, & |
---|
| 2354 | StartTime=StartTime, & |
---|
| 2355 | StopTime= StopTime, & |
---|
| 2356 | rc=rc ) |
---|
| 2357 | IF ( rc /= WRFU_SUCCESS ) THEN |
---|
| 2358 | CALL wrf_error_fatal ( & |
---|
| 2359 | 'domain_clock_create: WRFU_ClockCreate() failed' ) |
---|
| 2360 | ENDIF |
---|
| 2361 | grid%domain_clock_created = .TRUE. |
---|
| 2362 | RETURN |
---|
| 2363 | END SUBROUTINE domain_clock_create |
---|
| 2364 | |
---|
| 2365 | |
---|
| 2366 | |
---|
| 2367 | SUBROUTINE domain_alarm_create( grid, alarm_id, interval, & |
---|
| 2368 | begin_time, end_time ) |
---|
| 2369 | USE module_utility |
---|
| 2370 | IMPLICIT NONE |
---|
| 2371 | TYPE(domain), POINTER :: grid |
---|
| 2372 | INTEGER, INTENT(IN) :: alarm_id |
---|
| 2373 | TYPE(WRFU_TimeInterval), INTENT(IN), OPTIONAL :: interval |
---|
| 2374 | TYPE(WRFU_TimeInterval), INTENT(IN), OPTIONAL :: begin_time |
---|
| 2375 | TYPE(WRFU_TimeInterval), INTENT(IN), OPTIONAL :: end_time |
---|
| 2376 | ! <DESCRIPTION> |
---|
| 2377 | ! This convenience routine creates alarm alarm_id for domain grid and |
---|
| 2378 | ! sets associated flags. |
---|
| 2379 | ! |
---|
| 2380 | ! </DESCRIPTION> |
---|
| 2381 | ! Locals |
---|
| 2382 | INTEGER :: rc |
---|
| 2383 | !$$$ TBH: Ideally, this could be simplified by passing all optional actual |
---|
| 2384 | !$$$ TBH: args into AlarmCreate. However, since operations are performed on |
---|
| 2385 | !$$$ TBH: the actual args in-place in the calls, they must be present for the |
---|
| 2386 | !$$$ TBH: operations themselves to be defined. Grrr... |
---|
| 2387 | LOGICAL :: interval_only, all_args, no_args |
---|
| 2388 | TYPE(WRFU_Time) :: startTime |
---|
| 2389 | interval_only = .FALSE. |
---|
| 2390 | all_args = .FALSE. |
---|
| 2391 | no_args = .FALSE. |
---|
| 2392 | IF ( ( .NOT. PRESENT( begin_time ) ) .AND. & |
---|
| 2393 | ( .NOT. PRESENT( end_time ) ) .AND. & |
---|
| 2394 | ( PRESENT( interval ) ) ) THEN |
---|
| 2395 | interval_only = .TRUE. |
---|
| 2396 | ELSE IF ( ( .NOT. PRESENT( begin_time ) ) .AND. & |
---|
| 2397 | ( .NOT. PRESENT( end_time ) ) .AND. & |
---|
| 2398 | ( .NOT. PRESENT( interval ) ) ) THEN |
---|
| 2399 | no_args = .TRUE. |
---|
| 2400 | ELSE IF ( ( PRESENT( begin_time ) ) .AND. & |
---|
| 2401 | ( PRESENT( end_time ) ) .AND. & |
---|
| 2402 | ( PRESENT( interval ) ) ) THEN |
---|
| 2403 | all_args = .TRUE. |
---|
| 2404 | ELSE |
---|
| 2405 | CALL wrf_error_fatal ( & |
---|
| 2406 | 'ERROR in domain_alarm_create: bad argument list' ) |
---|
| 2407 | ENDIF |
---|
| 2408 | CALL domain_clock_get( grid, start_time=startTime ) |
---|
| 2409 | IF ( interval_only ) THEN |
---|
| 2410 | grid%io_intervals( alarm_id ) = interval |
---|
| 2411 | grid%alarms( alarm_id ) = & |
---|
| 2412 | WRFU_AlarmCreate( clock=grid%domain_clock, & |
---|
| 2413 | RingInterval=interval, & |
---|
| 2414 | rc=rc ) |
---|
| 2415 | ELSE IF ( no_args ) THEN |
---|
| 2416 | grid%alarms( alarm_id ) = & |
---|
| 2417 | WRFU_AlarmCreate( clock=grid%domain_clock, & |
---|
| 2418 | RingTime=startTime, & |
---|
| 2419 | rc=rc ) |
---|
| 2420 | ELSE IF ( all_args ) THEN |
---|
| 2421 | grid%io_intervals( alarm_id ) = interval |
---|
| 2422 | grid%alarms( alarm_id ) = & |
---|
| 2423 | WRFU_AlarmCreate( clock=grid%domain_clock, & |
---|
| 2424 | RingTime=startTime + begin_time, & |
---|
| 2425 | RingInterval=interval, & |
---|
| 2426 | StopTime=startTime + end_time, & |
---|
| 2427 | rc=rc ) |
---|
| 2428 | ENDIF |
---|
| 2429 | IF ( rc /= WRFU_SUCCESS ) THEN |
---|
| 2430 | CALL wrf_error_fatal ( & |
---|
| 2431 | 'domain_alarm_create: WRFU_AlarmCreate() failed' ) |
---|
| 2432 | ENDIF |
---|
| 2433 | CALL WRFU_AlarmRingerOff( grid%alarms( alarm_id ) , rc=rc ) |
---|
| 2434 | IF ( rc /= WRFU_SUCCESS ) THEN |
---|
| 2435 | CALL wrf_error_fatal ( & |
---|
| 2436 | 'domain_alarm_create: WRFU_AlarmRingerOff() failed' ) |
---|
| 2437 | ENDIF |
---|
| 2438 | grid%alarms_created( alarm_id ) = .TRUE. |
---|
| 2439 | END SUBROUTINE domain_alarm_create |
---|
| 2440 | |
---|
| 2441 | |
---|
| 2442 | |
---|
| 2443 | SUBROUTINE domain_clock_set( grid, current_timestr, & |
---|
| 2444 | stop_timestr, & |
---|
| 2445 | time_step_seconds ) |
---|
| 2446 | IMPLICIT NONE |
---|
| 2447 | TYPE(domain), INTENT(INOUT) :: grid |
---|
| 2448 | CHARACTER (LEN=*), INTENT(IN ), OPTIONAL :: current_timestr |
---|
| 2449 | CHARACTER (LEN=*), INTENT(IN ), OPTIONAL :: stop_timestr |
---|
| 2450 | INTEGER, INTENT(IN ), OPTIONAL :: time_step_seconds |
---|
| 2451 | ! <DESCRIPTION> |
---|
| 2452 | ! This convenience routine sets clock information for domain grid. |
---|
| 2453 | ! The caller is responsible for ensuring that character string actual |
---|
| 2454 | ! arguments are big enough. |
---|
| 2455 | ! |
---|
| 2456 | ! </DESCRIPTION> |
---|
| 2457 | ! Locals |
---|
| 2458 | TYPE(WRFU_Time) :: lcl_currtime, lcl_stoptime |
---|
| 2459 | TYPE(WRFU_TimeInterval) :: tmpTimeInterval |
---|
| 2460 | INTEGER :: rc |
---|
| 2461 | IF ( PRESENT( current_timestr ) ) THEN |
---|
| 2462 | CALL wrf_atotime( current_timestr(1:19), lcl_currtime ) |
---|
| 2463 | CALL WRFU_ClockSet( grid%domain_clock, currTime=lcl_currtime, & |
---|
| 2464 | rc=rc ) |
---|
| 2465 | IF ( rc /= WRFU_SUCCESS ) THEN |
---|
| 2466 | CALL wrf_error_fatal ( & |
---|
| 2467 | 'domain_clock_set: WRFU_ClockSet(CurrTime) failed' ) |
---|
| 2468 | ENDIF |
---|
| 2469 | ENDIF |
---|
| 2470 | IF ( PRESENT( stop_timestr ) ) THEN |
---|
| 2471 | CALL wrf_atotime( stop_timestr(1:19), lcl_stoptime ) |
---|
| 2472 | CALL WRFU_ClockSet( grid%domain_clock, stopTime=lcl_stoptime, & |
---|
| 2473 | rc=rc ) |
---|
| 2474 | IF ( rc /= WRFU_SUCCESS ) THEN |
---|
| 2475 | CALL wrf_error_fatal ( & |
---|
| 2476 | 'domain_clock_set: WRFU_ClockSet(StopTime) failed' ) |
---|
| 2477 | ENDIF |
---|
| 2478 | ENDIF |
---|
| 2479 | IF ( PRESENT( time_step_seconds ) ) THEN |
---|
| 2480 | CALL WRFU_TimeIntervalSet( tmpTimeInterval, & |
---|
| 2481 | S=time_step_seconds, rc=rc ) |
---|
| 2482 | IF ( rc /= WRFU_SUCCESS ) THEN |
---|
| 2483 | CALL wrf_error_fatal ( & |
---|
| 2484 | 'domain_clock_set: WRFU_TimeIntervalSet failed' ) |
---|
| 2485 | ENDIF |
---|
| 2486 | CALL WRFU_ClockSet ( grid%domain_clock, & |
---|
| 2487 | timeStep=tmpTimeInterval, & |
---|
| 2488 | rc=rc ) |
---|
| 2489 | IF ( rc /= WRFU_SUCCESS ) THEN |
---|
| 2490 | CALL wrf_error_fatal ( & |
---|
| 2491 | 'domain_clock_set: WRFU_ClockSet(TimeStep) failed' ) |
---|
| 2492 | ENDIF |
---|
| 2493 | ENDIF |
---|
| 2494 | RETURN |
---|
| 2495 | END SUBROUTINE domain_clock_set |
---|
| 2496 | |
---|
| 2497 | |
---|
| 2498 | ! Debug routine to print key clock information. |
---|
| 2499 | ! Printed lines include pre_str. |
---|
| 2500 | SUBROUTINE domain_clockprint ( level, grid, pre_str ) |
---|
| 2501 | IMPLICIT NONE |
---|
| 2502 | INTEGER, INTENT( IN) :: level |
---|
| 2503 | TYPE(domain), INTENT( IN) :: grid |
---|
| 2504 | CHARACTER (LEN=*), INTENT( IN) :: pre_str |
---|
| 2505 | CALL wrf_clockprint ( level, grid%domain_clock, pre_str ) |
---|
| 2506 | RETURN |
---|
| 2507 | END SUBROUTINE domain_clockprint |
---|
| 2508 | |
---|
| 2509 | |
---|
| 2510 | ! Advance the clock associated with grid. |
---|
| 2511 | ! Also updates several derived time quantities in grid state. |
---|
| 2512 | SUBROUTINE domain_clockadvance ( grid ) |
---|
| 2513 | IMPLICIT NONE |
---|
| 2514 | TYPE(domain), INTENT(INOUT) :: grid |
---|
| 2515 | INTEGER :: rc |
---|
| 2516 | CALL domain_clockprint ( 250, grid, & |
---|
| 2517 | 'DEBUG domain_clockadvance(): before WRFU_ClockAdvance,' ) |
---|
| 2518 | CALL WRFU_ClockAdvance( grid%domain_clock, rc=rc ) |
---|
| 2519 | IF ( rc /= WRFU_SUCCESS ) THEN |
---|
| 2520 | CALL wrf_error_fatal ( & |
---|
| 2521 | 'domain_clockadvance: WRFU_ClockAdvance() failed' ) |
---|
| 2522 | ENDIF |
---|
| 2523 | CALL domain_clockprint ( 250, grid, & |
---|
| 2524 | 'DEBUG domain_clockadvance(): after WRFU_ClockAdvance,' ) |
---|
| 2525 | ! Update derived time quantities in grid state. |
---|
| 2526 | ! These are initialized in setup_timekeeping(). |
---|
| 2527 | CALL domain_clock_get( grid, minutesSinceSimulationStart=grid%xtime ) |
---|
| 2528 | CALL domain_clock_get( grid, currentDayOfYearReal=grid%julian ) |
---|
| 2529 | RETURN |
---|
| 2530 | END SUBROUTINE domain_clockadvance |
---|
| 2531 | |
---|
| 2532 | |
---|
| 2533 | |
---|
| 2534 | ! Set grid%gmt, grid%julday, and grid%julyr from simulation-start-date. |
---|
| 2535 | ! Set start_of_simulation to TRUE iff current_time == simulation_start_time |
---|
| 2536 | SUBROUTINE domain_setgmtetc ( grid, start_of_simulation ) |
---|
| 2537 | IMPLICIT NONE |
---|
| 2538 | TYPE (domain), INTENT(INOUT) :: grid |
---|
| 2539 | LOGICAL, INTENT( OUT) :: start_of_simulation |
---|
| 2540 | ! locals |
---|
| 2541 | CHARACTER (LEN=132) :: message |
---|
| 2542 | TYPE(WRFU_Time) :: simStartTime |
---|
| 2543 | INTEGER :: hr, mn, sec, ms, rc |
---|
| 2544 | CALL domain_clockprint(150, grid, & |
---|
| 2545 | 'DEBUG domain_setgmtetc(): get simStartTime from clock,') |
---|
| 2546 | CALL domain_clock_get( grid, simulationStartTime=simStartTime, & |
---|
| 2547 | simulationStartTimeStr=message ) |
---|
| 2548 | CALL WRFU_TimeGet( simStartTime, YY=grid%julyr, dayOfYear=grid%julday, & |
---|
| 2549 | H=hr, M=mn, S=sec, MS=ms, rc=rc) |
---|
| 2550 | IF ( rc /= WRFU_SUCCESS ) THEN |
---|
| 2551 | CALL wrf_error_fatal ( & |
---|
| 2552 | 'domain_setgmtetc: WRFU_TimeGet() failed' ) |
---|
| 2553 | ENDIF |
---|
| 2554 | WRITE( wrf_err_message , * ) 'DEBUG domain_setgmtetc(): simulation start time = [',TRIM( message ),']' |
---|
| 2555 | CALL wrf_debug( 150, TRIM(wrf_err_message) ) |
---|
| 2556 | grid%gmt=hr+real(mn)/60.+real(sec)/3600.+real(ms)/(1000*3600) |
---|
| 2557 | WRITE( wrf_err_message , * ) 'DEBUG domain_setgmtetc(): julyr,hr,mn,sec,ms,julday = ', & |
---|
| 2558 | grid%julyr,hr,mn,sec,ms,grid%julday |
---|
| 2559 | CALL wrf_debug( 150, TRIM(wrf_err_message) ) |
---|
| 2560 | WRITE( wrf_err_message , * ) 'DEBUG domain_setgmtetc(): gmt = ',grid%gmt |
---|
| 2561 | CALL wrf_debug( 150, TRIM(wrf_err_message) ) |
---|
| 2562 | start_of_simulation = domain_ClockIsSimStartTime(grid) |
---|
| 2563 | RETURN |
---|
| 2564 | END SUBROUTINE domain_setgmtetc |
---|
| 2565 | |
---|
| 2566 | |
---|
| 2567 | |
---|
| 2568 | ! Set pointer to current grid. |
---|
| 2569 | ! To begin with, current grid is not set. |
---|
| 2570 | SUBROUTINE set_current_grid_ptr( grid_ptr ) |
---|
| 2571 | IMPLICIT NONE |
---|
| 2572 | TYPE(domain), POINTER :: grid_ptr |
---|
| 2573 | !PRINT *,'DEBUG: begin set_current_grid_ptr()' |
---|
| 2574 | !IF ( ASSOCIATED( grid_ptr ) ) THEN |
---|
| 2575 | ! PRINT *,'DEBUG: set_current_grid_ptr(): current_grid is associated' |
---|
| 2576 | !ELSE |
---|
| 2577 | ! PRINT *,'DEBUG: set_current_grid_ptr(): current_grid is NOT associated' |
---|
| 2578 | !ENDIF |
---|
| 2579 | current_grid_set = .TRUE. |
---|
| 2580 | current_grid => grid_ptr |
---|
| 2581 | !PRINT *,'DEBUG: end set_current_grid_ptr()' |
---|
| 2582 | END SUBROUTINE set_current_grid_ptr |
---|
| 2583 | |
---|
| 2584 | |
---|
| 2585 | |
---|
| 2586 | !****************************************************************************** |
---|
| 2587 | ! From Uli Blahak (01 Dec 2006) |
---|
| 2588 | ! UB: Function to determine if the next time step is an alarm-timestep for a certain grid: |
---|
| 2589 | !****************************************************************************** |
---|
| 2590 | |
---|
| 2591 | LOGICAL FUNCTION Is_alarm_tstep( grid_clock, alarm ) |
---|
| 2592 | |
---|
| 2593 | IMPLICIT NONE |
---|
| 2594 | |
---|
| 2595 | TYPE (WRFU_Clock), INTENT(in) :: grid_clock |
---|
| 2596 | TYPE (WRFU_Alarm), INTENT(in) :: alarm |
---|
| 2597 | |
---|
| 2598 | LOGICAL :: pred1, pred2, pred3 |
---|
| 2599 | |
---|
| 2600 | Is_alarm_tstep = .FALSE. |
---|
| 2601 | |
---|
| 2602 | IF ( ASSOCIATED( alarm%alarmint ) ) THEN |
---|
| 2603 | IF ( alarm%alarmint%Enabled ) THEN |
---|
| 2604 | IF ( alarm%alarmint%RingIntervalSet ) THEN |
---|
| 2605 | pred1 = .FALSE. ; pred2 = .FALSE. ; pred3 = .FALSE. |
---|
| 2606 | IF ( alarm%alarmint%StopTimeSet ) THEN |
---|
| 2607 | PRED1 = ( grid_clock%clockint%CurrTime + grid_clock%clockint%TimeStep > & |
---|
| 2608 | alarm%alarmint%StopTime ) |
---|
| 2609 | ENDIF |
---|
| 2610 | IF ( alarm%alarmint%RingTimeSet ) THEN |
---|
| 2611 | PRED2 = ( ( alarm%alarmint%RingTime - & |
---|
| 2612 | grid_clock%clockint%TimeStep <= & |
---|
| 2613 | grid_clock%clockint%CurrTime ) & |
---|
| 2614 | .AND. ( grid_clock%clockint%CurrTime < alarm%alarmint%RingTime ) ) |
---|
| 2615 | ENDIF |
---|
| 2616 | IF ( alarm%alarmint%RingIntervalSet ) THEN |
---|
| 2617 | PRED3 = ( alarm%alarmint%PrevRingTime + & |
---|
| 2618 | alarm%alarmint%RingInterval <= & |
---|
| 2619 | grid_clock%clockint%CurrTime + grid_clock%clockint%TimeStep ) |
---|
| 2620 | ENDIF |
---|
| 2621 | IF ( ( .NOT. ( pred1 ) ) .AND. & |
---|
| 2622 | ( ( pred2 ) .OR. ( pred3 ) ) ) THEN |
---|
| 2623 | Is_alarm_tstep = .TRUE. |
---|
| 2624 | ENDIF |
---|
| 2625 | ELSE IF ( alarm%alarmint%RingTimeSet ) THEN |
---|
| 2626 | IF ( alarm%alarmint%RingTime -& |
---|
| 2627 | grid_clock%clockint%TimeStep <= & |
---|
| 2628 | grid_clock%clockint%CurrTime ) THEN |
---|
| 2629 | Is_alarm_tstep = .TRUE. |
---|
| 2630 | ENDIF |
---|
| 2631 | ENDIF |
---|
| 2632 | ENDIF |
---|
| 2633 | ENDIF |
---|
| 2634 | |
---|
| 2635 | END FUNCTION Is_alarm_tstep |
---|
| 2636 | |
---|
| 2637 | |
---|
| 2638 | #if (NMM_CORE==1) |
---|
| 2639 | !****************************************************************************** |
---|
| 2640 | ! Function to determine if the next NPHS time step is an alarm-timestep for |
---|
| 2641 | ! a certain grid: |
---|
| 2642 | ! NMM-only -- modify to check whether the next alarm coincides with the next |
---|
| 2643 | ! NPHS time step! |
---|
| 2644 | !****************************************************************************** |
---|
| 2645 | |
---|
| 2646 | LOGICAL FUNCTION Is_alarm_tstep_nphs( grid_clock, alarm, nphs ) |
---|
| 2647 | |
---|
| 2648 | IMPLICIT NONE |
---|
| 2649 | |
---|
| 2650 | TYPE (WRFU_Clock), INTENT(in) :: grid_clock |
---|
| 2651 | TYPE (WRFU_Alarm), INTENT(in) :: alarm |
---|
| 2652 | |
---|
| 2653 | LOGICAL :: pred1, pred2, pred3 |
---|
| 2654 | INTEGER :: nphs |
---|
| 2655 | |
---|
| 2656 | Is_alarm_tstep_nphs = .FALSE. |
---|
| 2657 | |
---|
| 2658 | IF ( ASSOCIATED( alarm%alarmint ) ) THEN |
---|
| 2659 | IF ( alarm%alarmint%Enabled ) THEN |
---|
| 2660 | IF ( alarm%alarmint%RingIntervalSet ) THEN |
---|
| 2661 | pred1 = .FALSE. ; pred2 = .FALSE. ; pred3 = .FALSE. |
---|
| 2662 | IF ( alarm%alarmint%StopTimeSet ) THEN |
---|
| 2663 | PRED1 = ( grid_clock%clockint%CurrTime + grid_clock%clockint%TimeStep*nphs > & |
---|
| 2664 | alarm%alarmint%StopTime ) |
---|
| 2665 | ENDIF |
---|
| 2666 | IF ( alarm%alarmint%RingTimeSet ) THEN |
---|
| 2667 | PRED2 = ( ( alarm%alarmint%RingTime - & |
---|
| 2668 | grid_clock%clockint%TimeStep <= & |
---|
| 2669 | grid_clock%clockint%CurrTime ) & |
---|
| 2670 | .AND. ( grid_clock%clockint%CurrTime < alarm%alarmint%RingTime ) ) |
---|
| 2671 | ENDIF |
---|
| 2672 | IF ( alarm%alarmint%RingIntervalSet ) THEN |
---|
| 2673 | PRED3 = ( alarm%alarmint%PrevRingTime + & |
---|
| 2674 | alarm%alarmint%RingInterval <= & |
---|
| 2675 | grid_clock%clockint%CurrTime + grid_clock%clockint%TimeStep*nphs ) |
---|
| 2676 | ENDIF |
---|
| 2677 | IF ( ( .NOT. ( pred1 ) ) .AND. & |
---|
| 2678 | ( ( pred2 ) .OR. ( pred3 ) ) ) THEN |
---|
| 2679 | Is_alarm_tstep_nphs = .TRUE. |
---|
| 2680 | ENDIF |
---|
| 2681 | ELSE IF ( alarm%alarmint%RingTimeSet ) THEN |
---|
| 2682 | IF ( alarm%alarmint%RingTime -& |
---|
| 2683 | grid_clock%clockint%TimeStep*nphs <= & |
---|
| 2684 | grid_clock%clockint%CurrTime ) THEN |
---|
| 2685 | Is_alarm_tstep_nphs = .TRUE. |
---|
| 2686 | ENDIF |
---|
| 2687 | ENDIF |
---|
| 2688 | ENDIF |
---|
| 2689 | ENDIF |
---|
| 2690 | |
---|
| 2691 | END FUNCTION Is_alarm_tstep_nphs |
---|
| 2692 | #endif |
---|
| 2693 | |
---|
| 2694 | |
---|
| 2695 | !****************************************************************************** |
---|
| 2696 | ! BEGIN TEST SECTION |
---|
| 2697 | ! Code in the test section is used to test domain methods. |
---|
| 2698 | ! This code should probably be moved elsewhere, eventually. |
---|
| 2699 | !****************************************************************************** |
---|
| 2700 | |
---|
| 2701 | ! Private utility routines for domain_time_test. |
---|
| 2702 | SUBROUTINE domain_time_test_print ( pre_str, name_str, res_str ) |
---|
| 2703 | IMPLICIT NONE |
---|
| 2704 | CHARACTER (LEN=*), INTENT(IN) :: pre_str |
---|
| 2705 | CHARACTER (LEN=*), INTENT(IN) :: name_str |
---|
| 2706 | CHARACTER (LEN=*), INTENT(IN) :: res_str |
---|
| 2707 | CHARACTER (LEN=512) :: out_str |
---|
| 2708 | WRITE (out_str, & |
---|
| 2709 | FMT="('DOMAIN_TIME_TEST ',A,': ',A,' = ',A)") & |
---|
| 2710 | TRIM(pre_str), TRIM(name_str), TRIM(res_str) |
---|
| 2711 | CALL wrf_debug( 0, TRIM(out_str) ) |
---|
| 2712 | END SUBROUTINE domain_time_test_print |
---|
| 2713 | |
---|
| 2714 | ! Test adjust_io_timestr |
---|
| 2715 | SUBROUTINE test_adjust_io_timestr( TI_h, TI_m, TI_s, & |
---|
| 2716 | CT_yy, CT_mm, CT_dd, CT_h, CT_m, CT_s, & |
---|
| 2717 | ST_yy, ST_mm, ST_dd, ST_h, ST_m, ST_s, & |
---|
| 2718 | res_str, testname ) |
---|
| 2719 | INTEGER, INTENT(IN) :: TI_H |
---|
| 2720 | INTEGER, INTENT(IN) :: TI_M |
---|
| 2721 | INTEGER, INTENT(IN) :: TI_S |
---|
| 2722 | INTEGER, INTENT(IN) :: CT_YY |
---|
| 2723 | INTEGER, INTENT(IN) :: CT_MM ! month |
---|
| 2724 | INTEGER, INTENT(IN) :: CT_DD ! day of month |
---|
| 2725 | INTEGER, INTENT(IN) :: CT_H |
---|
| 2726 | INTEGER, INTENT(IN) :: CT_M |
---|
| 2727 | INTEGER, INTENT(IN) :: CT_S |
---|
| 2728 | INTEGER, INTENT(IN) :: ST_YY |
---|
| 2729 | INTEGER, INTENT(IN) :: ST_MM ! month |
---|
| 2730 | INTEGER, INTENT(IN) :: ST_DD ! day of month |
---|
| 2731 | INTEGER, INTENT(IN) :: ST_H |
---|
| 2732 | INTEGER, INTENT(IN) :: ST_M |
---|
| 2733 | INTEGER, INTENT(IN) :: ST_S |
---|
| 2734 | CHARACTER (LEN=*), INTENT(IN) :: res_str |
---|
| 2735 | CHARACTER (LEN=*), INTENT(IN) :: testname |
---|
| 2736 | ! locals |
---|
| 2737 | TYPE(WRFU_TimeInterval) :: TI |
---|
| 2738 | TYPE(WRFU_Time) :: CT, ST |
---|
| 2739 | LOGICAL :: test_passed |
---|
| 2740 | INTEGER :: rc |
---|
| 2741 | CHARACTER(LEN=WRFU_MAXSTR) :: TI_str, CT_str, ST_str, computed_str |
---|
| 2742 | ! TI |
---|
| 2743 | CALL WRFU_TimeIntervalSet( TI, H=TI_H, M=TI_M, S=TI_S, rc=rc ) |
---|
| 2744 | CALL wrf_check_error( WRFU_SUCCESS, rc, & |
---|
| 2745 | 'FAIL: '//TRIM(testname)//'WRFU_TimeIntervalSet() ', & |
---|
| 2746 | __FILE__ , & |
---|
| 2747 | __LINE__ ) |
---|
| 2748 | CALL WRFU_TimeIntervalGet( TI, timeString=TI_str, rc=rc ) |
---|
| 2749 | CALL wrf_check_error( WRFU_SUCCESS, rc, & |
---|
| 2750 | 'FAIL: '//TRIM(testname)//'WRFU_TimeGet() ', & |
---|
| 2751 | __FILE__ , & |
---|
| 2752 | __LINE__ ) |
---|
| 2753 | ! CT |
---|
| 2754 | CALL WRFU_TimeSet( CT, YY=CT_YY, MM=CT_MM, DD=CT_DD , & |
---|
| 2755 | H=CT_H, M=CT_M, S=CT_S, rc=rc ) |
---|
| 2756 | CALL wrf_check_error( WRFU_SUCCESS, rc, & |
---|
| 2757 | 'FAIL: '//TRIM(testname)//'WRFU_TimeSet() ', & |
---|
| 2758 | __FILE__ , & |
---|
| 2759 | __LINE__ ) |
---|
| 2760 | CALL WRFU_TimeGet( CT, timeString=CT_str, rc=rc ) |
---|
| 2761 | CALL wrf_check_error( WRFU_SUCCESS, rc, & |
---|
| 2762 | 'FAIL: '//TRIM(testname)//'WRFU_TimeGet() ', & |
---|
| 2763 | __FILE__ , & |
---|
| 2764 | __LINE__ ) |
---|
| 2765 | ! ST |
---|
| 2766 | CALL WRFU_TimeSet( ST, YY=ST_YY, MM=ST_MM, DD=ST_DD , & |
---|
| 2767 | H=ST_H, M=ST_M, S=ST_S, rc=rc ) |
---|
| 2768 | CALL wrf_check_error( WRFU_SUCCESS, rc, & |
---|
| 2769 | 'FAIL: '//TRIM(testname)//'WRFU_TimeSet() ', & |
---|
| 2770 | __FILE__ , & |
---|
| 2771 | __LINE__ ) |
---|
| 2772 | CALL WRFU_TimeGet( ST, timeString=ST_str, rc=rc ) |
---|
| 2773 | CALL wrf_check_error( WRFU_SUCCESS, rc, & |
---|
| 2774 | 'FAIL: '//TRIM(testname)//'WRFU_TimeGet() ', & |
---|
| 2775 | __FILE__ , & |
---|
| 2776 | __LINE__ ) |
---|
| 2777 | ! Test |
---|
| 2778 | CALL adjust_io_timestr ( TI, CT, ST, computed_str ) |
---|
| 2779 | ! check result |
---|
| 2780 | test_passed = .FALSE. |
---|
| 2781 | IF ( LEN_TRIM(res_str) == LEN_TRIM(computed_str) ) THEN |
---|
| 2782 | IF ( res_str(1:LEN_TRIM(res_str)) == computed_str(1:LEN_TRIM(computed_str)) ) THEN |
---|
| 2783 | test_passed = .TRUE. |
---|
| 2784 | ENDIF |
---|
| 2785 | ENDIF |
---|
| 2786 | ! print result |
---|
| 2787 | IF ( test_passed ) THEN |
---|
| 2788 | WRITE(*,FMT='(A)') 'PASS: '//TRIM(testname) |
---|
| 2789 | ELSE |
---|
| 2790 | WRITE(*,*) 'FAIL: ',TRIM(testname),': adjust_io_timestr(', & |
---|
| 2791 | TRIM(TI_str),',',TRIM(CT_str),',',TRIM(ST_str),') expected <', & |
---|
| 2792 | TRIM(res_str),'> but computed <',TRIM(computed_str),'>' |
---|
| 2793 | ENDIF |
---|
| 2794 | END SUBROUTINE test_adjust_io_timestr |
---|
| 2795 | |
---|
| 2796 | ! Print lots of time-related information for testing and debugging. |
---|
| 2797 | ! Printed lines include pre_str and special string DOMAIN_TIME_TEST |
---|
| 2798 | ! suitable for grepping by test scripts. |
---|
| 2799 | ! Returns immediately unless self_test_domain has been set to .true. in |
---|
| 2800 | ! namelist /time_control/ . |
---|
| 2801 | SUBROUTINE domain_time_test ( grid, pre_str ) |
---|
| 2802 | IMPLICIT NONE |
---|
| 2803 | TYPE(domain), INTENT(IN) :: grid |
---|
| 2804 | CHARACTER (LEN=*), INTENT(IN) :: pre_str |
---|
| 2805 | ! locals |
---|
| 2806 | LOGICAL, SAVE :: one_time_tests_done = .FALSE. |
---|
| 2807 | REAL :: minutesSinceSimulationStart |
---|
| 2808 | INTEGER :: advance_count, rc |
---|
| 2809 | REAL :: currentDayOfYearReal |
---|
| 2810 | TYPE(WRFU_TimeInterval) :: timeSinceSimulationStart |
---|
| 2811 | TYPE(WRFU_Time) :: simulationStartTime |
---|
| 2812 | CHARACTER (LEN=512) :: res_str |
---|
| 2813 | LOGICAL :: self_test_domain |
---|
| 2814 | ! |
---|
| 2815 | ! NOTE: test_adjust_io_timestr() (see below) is a self-test that |
---|
| 2816 | ! prints PASS/FAIL/ERROR messages in a standard format. All |
---|
| 2817 | ! of the other tests should be strucutred the same way, |
---|
| 2818 | ! someday. |
---|
| 2819 | ! |
---|
| 2820 | CALL nl_get_self_test_domain( 1, self_test_domain ) |
---|
| 2821 | IF ( self_test_domain ) THEN |
---|
| 2822 | CALL domain_clock_get( grid, advanceCount=advance_count ) |
---|
| 2823 | WRITE ( res_str, FMT="(I8.8)" ) advance_count |
---|
| 2824 | CALL domain_time_test_print( pre_str, 'advanceCount', res_str ) |
---|
| 2825 | CALL domain_clock_get( grid, currentDayOfYearReal=currentDayOfYearReal ) |
---|
| 2826 | WRITE ( res_str, FMT='(F10.6)' ) currentDayOfYearReal |
---|
| 2827 | CALL domain_time_test_print( pre_str, 'currentDayOfYearReal', res_str ) |
---|
| 2828 | CALL domain_clock_get( grid, minutesSinceSimulationStart=minutesSinceSimulationStart ) |
---|
| 2829 | WRITE ( res_str, FMT='(F10.6)' ) minutesSinceSimulationStart |
---|
| 2830 | CALL domain_time_test_print( pre_str, 'minutesSinceSimulationStart', res_str ) |
---|
| 2831 | CALL domain_clock_get( grid, current_timestr=res_str ) |
---|
| 2832 | CALL domain_time_test_print( pre_str, 'current_timestr', res_str ) |
---|
| 2833 | CALL domain_clock_get( grid, current_timestr_frac=res_str ) |
---|
| 2834 | CALL domain_time_test_print( pre_str, 'current_timestr_frac', res_str ) |
---|
| 2835 | CALL domain_clock_get( grid, timeSinceSimulationStart=timeSinceSimulationStart ) |
---|
| 2836 | CALL WRFU_TimeIntervalGet( timeSinceSimulationStart, timeString=res_str, rc=rc ) |
---|
| 2837 | IF ( rc /= WRFU_SUCCESS ) THEN |
---|
| 2838 | CALL wrf_error_fatal ( & |
---|
| 2839 | 'domain_time_test: WRFU_TimeIntervalGet() failed' ) |
---|
| 2840 | ENDIF |
---|
| 2841 | CALL domain_time_test_print( pre_str, 'timeSinceSimulationStart', res_str ) |
---|
| 2842 | ! The following tests should only be done once, the first time this |
---|
| 2843 | ! routine is called. |
---|
| 2844 | IF ( .NOT. one_time_tests_done ) THEN |
---|
| 2845 | one_time_tests_done = .TRUE. |
---|
| 2846 | CALL domain_clock_get( grid, simulationStartTimeStr=res_str ) |
---|
| 2847 | CALL domain_time_test_print( pre_str, 'simulationStartTime', res_str ) |
---|
| 2848 | CALL domain_clock_get( grid, start_timestr=res_str ) |
---|
| 2849 | CALL domain_time_test_print( pre_str, 'start_timestr', res_str ) |
---|
| 2850 | CALL domain_clock_get( grid, stop_timestr=res_str ) |
---|
| 2851 | CALL domain_time_test_print( pre_str, 'stop_timestr', res_str ) |
---|
| 2852 | CALL domain_clock_get( grid, time_stepstr=res_str ) |
---|
| 2853 | CALL domain_time_test_print( pre_str, 'time_stepstr', res_str ) |
---|
| 2854 | CALL domain_clock_get( grid, time_stepstr_frac=res_str ) |
---|
| 2855 | CALL domain_time_test_print( pre_str, 'time_stepstr_frac', res_str ) |
---|
| 2856 | ! Test adjust_io_timestr() |
---|
| 2857 | ! CT = 2000-01-26_00:00:00 (current time) |
---|
| 2858 | ! ST = 2000-01-24_12:00:00 (start time) |
---|
| 2859 | ! TI = 00000_03:00:00 (time interval) |
---|
| 2860 | ! the resulting time string should be: |
---|
| 2861 | ! 2000-01-26_00:00:00 |
---|
| 2862 | CALL test_adjust_io_timestr( TI_h=3, TI_m=0, TI_s=0, & |
---|
| 2863 | CT_yy=2000, CT_mm=1, CT_dd=26, CT_h=0, CT_m=0, CT_s=0, & |
---|
| 2864 | ST_yy=2000, ST_mm=1, ST_dd=24, ST_h=12, ST_m=0, ST_s=0, & |
---|
| 2865 | res_str='2000-01-26_00:00:00', testname='adjust_io_timestr_1' ) |
---|
| 2866 | ! this should fail (and does) |
---|
| 2867 | ! CALL test_adjust_io_timestr( TI_h=3, TI_m=0, TI_s=0, & |
---|
| 2868 | ! CT_yy=2000, CT_mm=1, CT_dd=26, CT_h=0, CT_m=0, CT_s=0, & |
---|
| 2869 | ! ST_yy=2000, ST_mm=1, ST_dd=24, ST_h=12, ST_m=0, ST_s=0, & |
---|
| 2870 | ! res_str='2000-01-26_00:00:01', testname='adjust_io_timestr_FAIL1' ) |
---|
| 2871 | ENDIF |
---|
| 2872 | ENDIF |
---|
| 2873 | RETURN |
---|
| 2874 | END SUBROUTINE domain_time_test |
---|
| 2875 | |
---|
| 2876 | !****************************************************************************** |
---|
| 2877 | ! END TEST SECTION |
---|
| 2878 | !****************************************************************************** |
---|
| 2879 | |
---|
| 2880 | |
---|
| 2881 | END MODULE module_domain |
---|
| 2882 | |
---|
| 2883 | |
---|
| 2884 | ! The following routines are outside this module to avoid build dependences. |
---|
| 2885 | |
---|
| 2886 | |
---|
| 2887 | ! Get current time as a string (current time from clock attached to the |
---|
| 2888 | ! current_grid). Includes fractional part, if present. |
---|
| 2889 | ! Returns empty string if current_grid is not set or if timing has not yet |
---|
| 2890 | ! been set up on current_grid. |
---|
| 2891 | SUBROUTINE get_current_time_string( time_str ) |
---|
| 2892 | USE module_domain |
---|
| 2893 | IMPLICIT NONE |
---|
| 2894 | CHARACTER (LEN=*), INTENT(OUT) :: time_str |
---|
| 2895 | ! locals |
---|
| 2896 | INTEGER :: debug_level_lcl |
---|
| 2897 | !PRINT *,'DEBUG: begin get_current_time_string()' |
---|
| 2898 | time_str = '' |
---|
| 2899 | IF ( current_grid_set ) THEN |
---|
| 2900 | !$$$DEBUG |
---|
| 2901 | !PRINT *,'DEBUG: get_current_time_string(): checking association of current_grid...' |
---|
| 2902 | !IF ( ASSOCIATED( current_grid ) ) THEN |
---|
| 2903 | ! PRINT *,'DEBUG: get_current_time_string(): current_grid is associated' |
---|
| 2904 | !ELSE |
---|
| 2905 | ! PRINT *,'DEBUG: get_current_time_string(): current_grid is NOT associated' |
---|
| 2906 | !ENDIF |
---|
| 2907 | !$$$END DEBUG |
---|
| 2908 | IF ( current_grid%time_set ) THEN |
---|
| 2909 | !PRINT *,'DEBUG: get_current_time_string(): calling domain_clock_get()' |
---|
| 2910 | ! set debug_level to zero and clear current_grid_set to avoid recursion |
---|
| 2911 | CALL get_wrf_debug_level( debug_level_lcl ) |
---|
| 2912 | CALL set_wrf_debug_level ( 0 ) |
---|
| 2913 | current_grid_set = .FALSE. |
---|
| 2914 | CALL domain_clock_get( current_grid, current_timestr_frac=time_str ) |
---|
| 2915 | ! restore debug_level and current_grid_set |
---|
| 2916 | CALL set_wrf_debug_level ( debug_level_lcl ) |
---|
| 2917 | current_grid_set = .TRUE. |
---|
| 2918 | !PRINT *,'DEBUG: get_current_time_string(): back from domain_clock_get()' |
---|
| 2919 | ENDIF |
---|
| 2920 | ENDIF |
---|
| 2921 | !PRINT *,'DEBUG: end get_current_time_string()' |
---|
| 2922 | END SUBROUTINE get_current_time_string |
---|
| 2923 | |
---|
| 2924 | |
---|
| 2925 | ! Get current domain name as a string of form "d<NN>" where "<NN>" is |
---|
| 2926 | ! grid%id printed in two characters, with leading zero if needed ("d01", |
---|
| 2927 | ! "d02", etc.). |
---|
| 2928 | ! Return empty string if current_grid not set. |
---|
| 2929 | SUBROUTINE get_current_grid_name( grid_str ) |
---|
| 2930 | USE module_domain |
---|
| 2931 | IMPLICIT NONE |
---|
| 2932 | CHARACTER (LEN=*), INTENT(OUT) :: grid_str |
---|
| 2933 | grid_str = '' |
---|
| 2934 | IF ( current_grid_set ) THEN |
---|
| 2935 | WRITE(grid_str,FMT="('d',I2.2)") current_grid%id |
---|
| 2936 | ENDIF |
---|
| 2937 | END SUBROUTINE get_current_grid_name |
---|
| 2938 | |
---|
| 2939 | |
---|
| 2940 | ! moved these outside module domain to avoid circular reference from module_alloc_space which also uses |
---|
| 2941 | |
---|
| 2942 | SUBROUTINE get_ijk_from_grid_ext ( grid , & |
---|
| 2943 | ids, ide, jds, jde, kds, kde, & |
---|
| 2944 | ims, ime, jms, jme, kms, kme, & |
---|
| 2945 | ips, ipe, jps, jpe, kps, kpe, & |
---|
| 2946 | imsx, imex, jmsx, jmex, kmsx, kmex, & |
---|
| 2947 | ipsx, ipex, jpsx, jpex, kpsx, kpex, & |
---|
| 2948 | imsy, imey, jmsy, jmey, kmsy, kmey, & |
---|
| 2949 | ipsy, ipey, jpsy, jpey, kpsy, kpey ) |
---|
| 2950 | USE module_domain |
---|
| 2951 | IMPLICIT NONE |
---|
| 2952 | TYPE( domain ), INTENT (IN) :: grid |
---|
| 2953 | INTEGER, INTENT(OUT) :: & |
---|
| 2954 | ids, ide, jds, jde, kds, kde, & |
---|
| 2955 | ims, ime, jms, jme, kms, kme, & |
---|
| 2956 | ips, ipe, jps, jpe, kps, kpe, & |
---|
| 2957 | imsx, imex, jmsx, jmex, kmsx, kmex, & |
---|
| 2958 | ipsx, ipex, jpsx, jpex, kpsx, kpex, & |
---|
| 2959 | imsy, imey, jmsy, jmey, kmsy, kmey, & |
---|
| 2960 | ipsy, ipey, jpsy, jpey, kpsy, kpey |
---|
| 2961 | |
---|
| 2962 | CALL get_ijk_from_grid2 ( grid , & |
---|
| 2963 | ids, ide, jds, jde, kds, kde, & |
---|
| 2964 | ims, ime, jms, jme, kms, kme, & |
---|
| 2965 | ips, ipe, jps, jpe, kps, kpe ) |
---|
| 2966 | data_ordering : SELECT CASE ( model_data_order ) |
---|
| 2967 | CASE ( DATA_ORDER_XYZ ) |
---|
| 2968 | imsx = grid%sm31x ; imex = grid%em31x ; jmsx = grid%sm32x ; jmex = grid%em32x ; kmsx = grid%sm33x ; kmex = grid%em33x ; |
---|
| 2969 | ipsx = grid%sp31x ; ipex = grid%ep31x ; jpsx = grid%sp32x ; jpex = grid%ep32x ; kpsx = grid%sp33x ; kpex = grid%ep33x ; |
---|
| 2970 | imsy = grid%sm31y ; imey = grid%em31y ; jmsy = grid%sm32y ; jmey = grid%em32y ; kmsy = grid%sm33y ; kmey = grid%em33y ; |
---|
| 2971 | ipsy = grid%sp31y ; ipey = grid%ep31y ; jpsy = grid%sp32y ; jpey = grid%ep32y ; kpsy = grid%sp33y ; kpey = grid%ep33y ; |
---|
| 2972 | CASE ( DATA_ORDER_YXZ ) |
---|
| 2973 | imsx = grid%sm32x ; imex = grid%em32x ; jmsx = grid%sm31x ; jmex = grid%em31x ; kmsx = grid%sm33x ; kmex = grid%em33x ; |
---|
| 2974 | ipsx = grid%sp32x ; ipex = grid%ep32x ; jpsx = grid%sp31x ; jpex = grid%ep31x ; kpsx = grid%sp33x ; kpex = grid%ep33x ; |
---|
| 2975 | imsy = grid%sm32y ; imey = grid%em32y ; jmsy = grid%sm31y ; jmey = grid%em31y ; kmsy = grid%sm33y ; kmey = grid%em33y ; |
---|
| 2976 | ipsy = grid%sp32y ; ipey = grid%ep32y ; jpsy = grid%sp31y ; jpey = grid%ep31y ; kpsy = grid%sp33y ; kpey = grid%ep33y ; |
---|
| 2977 | CASE ( DATA_ORDER_ZXY ) |
---|
| 2978 | imsx = grid%sm32x ; imex = grid%em32x ; jmsx = grid%sm33x ; jmex = grid%em33x ; kmsx = grid%sm31x ; kmex = grid%em31x ; |
---|
| 2979 | ipsx = grid%sp32x ; ipex = grid%ep32x ; jpsx = grid%sp33x ; jpex = grid%ep33x ; kpsx = grid%sp31x ; kpex = grid%ep31x ; |
---|
| 2980 | imsy = grid%sm32y ; imey = grid%em32y ; jmsy = grid%sm33y ; jmey = grid%em33y ; kmsy = grid%sm31y ; kmey = grid%em31y ; |
---|
| 2981 | ipsy = grid%sp32y ; ipey = grid%ep32y ; jpsy = grid%sp33y ; jpey = grid%ep33y ; kpsy = grid%sp31y ; kpey = grid%ep31y ; |
---|
| 2982 | CASE ( DATA_ORDER_ZYX ) |
---|
| 2983 | imsx = grid%sm33x ; imex = grid%em33x ; jmsx = grid%sm32x ; jmex = grid%em32x ; kmsx = grid%sm31x ; kmex = grid%em31x ; |
---|
| 2984 | ipsx = grid%sp33x ; ipex = grid%ep33x ; jpsx = grid%sp32x ; jpex = grid%ep32x ; kpsx = grid%sp31x ; kpex = grid%ep31x ; |
---|
| 2985 | imsy = grid%sm33y ; imey = grid%em33y ; jmsy = grid%sm32y ; jmey = grid%em32y ; kmsy = grid%sm31y ; kmey = grid%em31y ; |
---|
| 2986 | ipsy = grid%sp33y ; ipey = grid%ep33y ; jpsy = grid%sp32y ; jpey = grid%ep32y ; kpsy = grid%sp31y ; kpey = grid%ep31y ; |
---|
| 2987 | CASE ( DATA_ORDER_XZY ) |
---|
| 2988 | imsx = grid%sm31x ; imex = grid%em31x ; jmsx = grid%sm33x ; jmex = grid%em33x ; kmsx = grid%sm32x ; kmex = grid%em32x ; |
---|
| 2989 | ipsx = grid%sp31x ; ipex = grid%ep31x ; jpsx = grid%sp33x ; jpex = grid%ep33x ; kpsx = grid%sp32x ; kpex = grid%ep32x ; |
---|
| 2990 | imsy = grid%sm31y ; imey = grid%em31y ; jmsy = grid%sm33y ; jmey = grid%em33y ; kmsy = grid%sm32y ; kmey = grid%em32y ; |
---|
| 2991 | ipsy = grid%sp31y ; ipey = grid%ep31y ; jpsy = grid%sp33y ; jpey = grid%ep33y ; kpsy = grid%sp32y ; kpey = grid%ep32y ; |
---|
| 2992 | CASE ( DATA_ORDER_YZX ) |
---|
| 2993 | imsx = grid%sm33x ; imex = grid%em33x ; jmsx = grid%sm31x ; jmex = grid%em31x ; kmsx = grid%sm32x ; kmex = grid%em32x ; |
---|
| 2994 | ipsx = grid%sp33x ; ipex = grid%ep33x ; jpsx = grid%sp31x ; jpex = grid%ep31x ; kpsx = grid%sp32x ; kpex = grid%ep32x ; |
---|
| 2995 | imsy = grid%sm33y ; imey = grid%em33y ; jmsy = grid%sm31y ; jmey = grid%em31y ; kmsy = grid%sm32y ; kmey = grid%em32y ; |
---|
| 2996 | ipsy = grid%sp33y ; ipey = grid%ep33y ; jpsy = grid%sp31y ; jpey = grid%ep31y ; kpsy = grid%sp32y ; kpey = grid%ep32y ; |
---|
| 2997 | END SELECT data_ordering |
---|
| 2998 | END SUBROUTINE get_ijk_from_grid_ext |
---|
| 2999 | |
---|
| 3000 | ! return the values for subgrid whose refinement is in grid%sr |
---|
| 3001 | ! note when using this routine, it does not affect K. For K |
---|
| 3002 | ! (vertical), it just returns what get_ijk_from_grid does |
---|
| 3003 | SUBROUTINE get_ijk_from_subgrid_ext ( grid , & |
---|
| 3004 | ids0, ide0, jds0, jde0, kds0, kde0, & |
---|
| 3005 | ims0, ime0, jms0, jme0, kms0, kme0, & |
---|
| 3006 | ips0, ipe0, jps0, jpe0, kps0, kpe0 ) |
---|
| 3007 | USE module_domain |
---|
| 3008 | IMPLICIT NONE |
---|
| 3009 | TYPE( domain ), INTENT (IN) :: grid |
---|
| 3010 | INTEGER, INTENT(OUT) :: & |
---|
| 3011 | ids0, ide0, jds0, jde0, kds0, kde0, & |
---|
| 3012 | ims0, ime0, jms0, jme0, kms0, kme0, & |
---|
| 3013 | ips0, ipe0, jps0, jpe0, kps0, kpe0 |
---|
| 3014 | ! Local |
---|
| 3015 | INTEGER :: & |
---|
| 3016 | ids, ide, jds, jde, kds, kde, & |
---|
| 3017 | ims, ime, jms, jme, kms, kme, & |
---|
| 3018 | ips, ipe, jps, jpe, kps, kpe |
---|
| 3019 | CALL get_ijk_from_grid ( grid , & |
---|
| 3020 | ids, ide, jds, jde, kds, kde, & |
---|
| 3021 | ims, ime, jms, jme, kms, kme, & |
---|
| 3022 | ips, ipe, jps, jpe, kps, kpe ) |
---|
| 3023 | ids0 = ids |
---|
| 3024 | ide0 = ide * grid%sr_x |
---|
| 3025 | ims0 = (ims-1)*grid%sr_x+1 |
---|
| 3026 | ime0 = ime * grid%sr_x |
---|
| 3027 | ips0 = (ips-1)*grid%sr_x+1 |
---|
| 3028 | ipe0 = ipe * grid%sr_x |
---|
| 3029 | |
---|
| 3030 | jds0 = jds |
---|
| 3031 | jde0 = jde * grid%sr_y |
---|
| 3032 | jms0 = (jms-1)*grid%sr_y+1 |
---|
| 3033 | jme0 = jme * grid%sr_y |
---|
| 3034 | jps0 = (jps-1)*grid%sr_y+1 |
---|
| 3035 | jpe0 = jpe * grid%sr_y |
---|
| 3036 | |
---|
| 3037 | kds0 = kds |
---|
| 3038 | kde0 = kde |
---|
| 3039 | kms0 = kms |
---|
| 3040 | kme0 = kme |
---|
| 3041 | kps0 = kps |
---|
| 3042 | kpe0 = kpe |
---|
| 3043 | RETURN |
---|
| 3044 | END SUBROUTINE get_ijk_from_subgrid_ext |
---|
| 3045 | |
---|
| 3046 | ! find the grid based on the id reference and return that |
---|
| 3047 | SUBROUTINE get_dims_from_grid_id ( id & |
---|
| 3048 | ,ds, de & |
---|
| 3049 | ,ms, me & |
---|
| 3050 | ,ps, pe & |
---|
| 3051 | ,mxs, mxe & |
---|
| 3052 | ,pxs, pxe & |
---|
| 3053 | ,mys, mye & |
---|
| 3054 | ,pys, pye ) |
---|
| 3055 | USE module_domain, ONLY : domain, head_grid, find_grid_by_id |
---|
| 3056 | IMPLICIT NONE |
---|
| 3057 | TYPE( domain ), POINTER :: grid |
---|
| 3058 | INTEGER, INTENT(IN ) :: id |
---|
| 3059 | INTEGER, DIMENSION(3), INTENT(INOUT) :: & |
---|
| 3060 | ds, de & |
---|
| 3061 | ,ms, me & |
---|
| 3062 | ,ps, pe & |
---|
| 3063 | ,mxs, mxe & |
---|
| 3064 | ,pxs, pxe & |
---|
| 3065 | ,mys, mye & |
---|
| 3066 | ,pys, pye |
---|
| 3067 | |
---|
| 3068 | !local |
---|
| 3069 | CHARACTER*256 mess |
---|
| 3070 | |
---|
| 3071 | NULLIFY( grid ) |
---|
| 3072 | CALL find_grid_by_id ( id, head_grid, grid ) |
---|
| 3073 | |
---|
| 3074 | IF ( ASSOCIATED(grid) ) THEN |
---|
| 3075 | ds(1) = grid%sd31 ; de(1) = grid%ed31 ; ds(2) = grid%sd32 ; de(2) = grid%ed32 ; ds(3) = grid%sd33 ; de(3) = grid%ed33 ; |
---|
| 3076 | ms(1) = grid%sm31 ; me(1) = grid%em31 ; ms(2) = grid%sm32 ; me(2) = grid%em32 ; ms(3) = grid%sm33 ; me(3) = grid%em33 ; |
---|
| 3077 | ps(1) = grid%sp31 ; pe(1) = grid%ep31 ; ps(2) = grid%sp32 ; pe(2) = grid%ep32 ; ps(3) = grid%sp33 ; pe(3) = grid%ep33 ; |
---|
| 3078 | mxs(1) = grid%sm31x ; mxe(1) = grid%em31x |
---|
| 3079 | mxs(2) = grid%sm32x ; mxe(2) = grid%em32x |
---|
| 3080 | mxs(3) = grid%sm33x ; mxe(3) = grid%em33x |
---|
| 3081 | pxs(1) = grid%sp31x ; pxe(1) = grid%ep31x |
---|
| 3082 | pxs(2) = grid%sp32x ; pxe(2) = grid%ep32x |
---|
| 3083 | pxs(3) = grid%sp33x ; pxe(3) = grid%ep33x |
---|
| 3084 | mys(1) = grid%sm31y ; mye(1) = grid%em31y |
---|
| 3085 | mys(2) = grid%sm32y ; mye(2) = grid%em32y |
---|
| 3086 | mys(3) = grid%sm33y ; mye(3) = grid%em33y |
---|
| 3087 | pys(1) = grid%sp31y ; pye(1) = grid%ep31y |
---|
| 3088 | pys(2) = grid%sp32y ; pye(2) = grid%ep32y |
---|
| 3089 | pys(3) = grid%sp33y ; pye(3) = grid%ep33y |
---|
| 3090 | ELSE |
---|
| 3091 | WRITE(mess,*)'internal error: get_ijk_from_grid_id: no such grid id:',id |
---|
| 3092 | CALL wrf_error_fatal(TRIM(mess)) |
---|
| 3093 | ENDIF |
---|
| 3094 | |
---|
| 3095 | END SUBROUTINE get_dims_from_grid_id |
---|
| 3096 | |
---|
| 3097 | ! find the grid based on the id reference and return that |
---|
| 3098 | SUBROUTINE get_ijk_from_grid_id ( id , & |
---|
| 3099 | ids, ide, jds, jde, kds, kde, & |
---|
| 3100 | ims, ime, jms, jme, kms, kme, & |
---|
| 3101 | ips, ipe, jps, jpe, kps, kpe, & |
---|
| 3102 | imsx, imex, jmsx, jmex, kmsx, kmex, & |
---|
| 3103 | ipsx, ipex, jpsx, jpex, kpsx, kpex, & |
---|
| 3104 | imsy, imey, jmsy, jmey, kmsy, kmey, & |
---|
| 3105 | ipsy, ipey, jpsy, jpey, kpsy, kpey ) |
---|
| 3106 | USE module_domain, ONLY : domain, head_grid, find_grid_by_id, get_ijk_from_grid |
---|
| 3107 | IMPLICIT NONE |
---|
| 3108 | TYPE( domain ), POINTER :: grid |
---|
| 3109 | INTEGER, INTENT(IN ) :: id |
---|
| 3110 | INTEGER, INTENT(OUT) :: & |
---|
| 3111 | ids, ide, jds, jde, kds, kde, & |
---|
| 3112 | ims, ime, jms, jme, kms, kme, & |
---|
| 3113 | ips, ipe, jps, jpe, kps, kpe, & |
---|
| 3114 | imsx, imex, jmsx, jmex, kmsx, kmex, & |
---|
| 3115 | ipsx, ipex, jpsx, jpex, kpsx, kpex, & |
---|
| 3116 | imsy, imey, jmsy, jmey, kmsy, kmey, & |
---|
| 3117 | ipsy, ipey, jpsy, jpey, kpsy, kpey |
---|
| 3118 | !local |
---|
| 3119 | CHARACTER*256 mess |
---|
| 3120 | |
---|
| 3121 | NULLIFY( grid ) |
---|
| 3122 | CALL find_grid_by_id ( id, head_grid, grid ) |
---|
| 3123 | |
---|
| 3124 | IF ( ASSOCIATED(grid) ) THEN |
---|
| 3125 | CALL get_ijk_from_grid ( grid , & |
---|
| 3126 | ids, ide, jds, jde, kds, kde, & |
---|
| 3127 | ims, ime, jms, jme, kms, kme, & |
---|
| 3128 | ips, ipe, jps, jpe, kps, kpe, & |
---|
| 3129 | imsx, imex, jmsx, jmex, kmsx, kmex, & |
---|
| 3130 | ipsx, ipex, jpsx, jpex, kpsx, kpex, & |
---|
| 3131 | imsy, imey, jmsy, jmey, kmsy, kmey, & |
---|
| 3132 | ipsy, ipey, jpsy, jpey, kpsy, kpey ) |
---|
| 3133 | ELSE |
---|
| 3134 | WRITE(mess,*)'internal error: get_ijk_from_grid_id: no such grid id:',id |
---|
| 3135 | CALL wrf_error_fatal(TRIM(mess)) |
---|
| 3136 | ENDIF |
---|
| 3137 | |
---|
| 3138 | END SUBROUTINE get_ijk_from_grid_id |
---|
| 3139 | |
---|
| 3140 | ! version of this routine that can be called from set_scalar_indices_from_config in |
---|
| 3141 | ! module_configure, which can not USE module_domain without creating a circular use assocaition |
---|
| 3142 | SUBROUTINE modify_io_masks ( id ) |
---|
| 3143 | USE module_domain, ONLY : domain, modify_io_masks1, head_grid, find_grid_by_id |
---|
| 3144 | IMPLICIT NONE |
---|
| 3145 | INTEGER, INTENT(IN) :: id |
---|
| 3146 | TYPE(domain), POINTER :: grid |
---|
| 3147 | CALL find_grid_by_id( id, head_grid, grid ) |
---|
| 3148 | IF ( ASSOCIATED( grid ) ) CALL modify_io_masks1( grid, id ) |
---|
| 3149 | RETURN |
---|
| 3150 | END SUBROUTINE modify_io_masks |
---|
| 3151 | |
---|