grids.f 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831
  1. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  2. !
  3. ! This module reads in and initializes two grids for remapping.
  4. ! NOTE: grid1 must be the master grid -- the grid that determines
  5. ! which cells participate (e.g. land mask) and the fractional
  6. ! area of grid2 cells that participate in the remapping.
  7. !
  8. !-----------------------------------------------------------------------
  9. !
  10. ! CVS:$Id: grids.f,v 1.6 2001/08/21 21:06:41 pwjones Exp $
  11. !
  12. ! Copyright (c) 1997, 1998 the Regents of the University of
  13. ! California.
  14. !
  15. ! This software and ancillary information (herein called software)
  16. ! called SCRIP is made available under the terms described here.
  17. ! The software has been approved for release with associated
  18. ! LA-CC Number 98-45.
  19. !
  20. ! Unless otherwise indicated, this software has been authored
  21. ! by an employee or employees of the University of California,
  22. ! operator of the Los Alamos National Laboratory under Contract
  23. ! No. W-7405-ENG-36 with the U.S. Department of Energy. The U.S.
  24. ! Government has rights to use, reproduce, and distribute this
  25. ! software. The public may copy and use this software without
  26. ! charge, provided that this Notice and any statement of authorship
  27. ! are reproduced on all copies. Neither the Government nor the
  28. ! University makes any warranty, express or implied, or assumes
  29. ! any liability or responsibility for the use of this software.
  30. !
  31. ! If software is modified to produce derivative works, such modified
  32. ! software should be clearly marked, so as not to confuse it with
  33. ! the version available from Los Alamos National Laboratory.
  34. !
  35. !***********************************************************************
  36. module grids
  37. !-----------------------------------------------------------------------
  38. use kinds_mod ! defines data types
  39. use constants ! common constants
  40. use iounits ! I/O unit manager
  41. use netcdf_mod ! netCDF stuff
  42. implicit none
  43. !-----------------------------------------------------------------------
  44. !
  45. ! variables that describe each grid
  46. !
  47. !-----------------------------------------------------------------------
  48. integer (kind=int_kind), save ::
  49. & grid1_size, grid2_size, ! total points on each grid
  50. & grid1_rank, grid2_rank, ! rank of each grid
  51. & grid1_corners, grid2_corners ! number of corners
  52. ! for each grid cell
  53. integer (kind=int_kind), dimension(:), allocatable, save ::
  54. & grid1_dims, grid2_dims ! size of each grid dimension
  55. character(char_len), save ::
  56. & grid1_name, grid2_name ! name for each grid
  57. character (char_len), save ::
  58. & grid1_units, ! units for grid coords (degs/radians)
  59. & grid2_units ! units for grid coords
  60. real (kind=dbl_kind), parameter ::
  61. & deg2rad = pi/180. ! conversion for deg to rads
  62. !-----------------------------------------------------------------------
  63. !
  64. ! grid coordinates and masks
  65. !
  66. !-----------------------------------------------------------------------
  67. logical (kind=log_kind), dimension(:), allocatable, save ::
  68. & grid1_mask, ! flag which cells participate
  69. & grid2_mask ! flag which cells participate
  70. real (kind=dbl_kind), dimension(:), allocatable, save ::
  71. & grid1_center_lat, ! lat/lon coordinates for
  72. & grid1_center_lon, ! each grid center in radians
  73. & grid2_center_lat,
  74. & grid2_center_lon,
  75. & grid1_area, ! tot area of each grid1 cell
  76. & grid2_area, ! tot area of each grid2 cell
  77. & grid1_area_in, ! area of grid1 cell from file
  78. & grid2_area_in, ! area of grid2 cell from file
  79. & grid1_frac, ! fractional area of grid cells
  80. & grid2_frac ! participating in remapping
  81. real (kind=dbl_kind), dimension(:,:), allocatable, save ::
  82. & grid1_corner_lat, ! lat/lon coordinates for
  83. & grid1_corner_lon, ! each grid corner in radians
  84. & grid2_corner_lat,
  85. & grid2_corner_lon
  86. logical (kind=log_kind), save ::
  87. & luse_grid_centers ! use centers for bounding boxes
  88. &, luse_grid1_area ! use area from grid file
  89. &, luse_grid2_area ! use area from grid file
  90. real (kind=dbl_kind), dimension(:,:), allocatable, save ::
  91. & grid1_bound_box, ! lat/lon bounding box for use
  92. & grid2_bound_box ! in restricting grid searches
  93. !-----------------------------------------------------------------------
  94. !
  95. ! bins for restricting searches
  96. !
  97. !-----------------------------------------------------------------------
  98. character (char_len), save ::
  99. & restrict_type ! type of bins to use
  100. integer (kind=int_kind), save ::
  101. & num_srch_bins ! num of bins for restricted srch
  102. integer (kind=int_kind), dimension(:,:), allocatable, save ::
  103. & bin_addr1, ! min,max adds for grid1 cells in this lat bin
  104. & bin_addr2 ! min,max adds for grid2 cells in this lat bin
  105. real(kind=dbl_kind), dimension(:,:), allocatable, save ::
  106. & bin_lats ! min,max latitude for each search bin
  107. &, bin_lons ! min,max longitude for each search bin
  108. !***********************************************************************
  109. contains
  110. !***********************************************************************
  111. subroutine grid_init(grid1_file, grid2_file)
  112. !-----------------------------------------------------------------------
  113. !
  114. ! this routine reads grid info from grid files and makes any
  115. ! necessary changes (e.g. for 0,2pi longitude range)
  116. !
  117. !-----------------------------------------------------------------------
  118. !-----------------------------------------------------------------------
  119. !
  120. ! input variables
  121. !
  122. !-----------------------------------------------------------------------
  123. character(char_len), intent(in) ::
  124. & grid1_file, grid2_file ! grid data files
  125. !-----------------------------------------------------------------------
  126. !
  127. ! local variables
  128. !
  129. !-----------------------------------------------------------------------
  130. integer (kind=int_kind) ::
  131. & n ! loop counter
  132. &, nele ! element loop counter
  133. &, iunit ! unit number for opening files
  134. &, i,j ! logical 2d addresses
  135. &, ip1,jp1
  136. &, n_add, e_add, ne_add
  137. &, nx, ny
  138. integer (kind=int_kind) ::
  139. & ncstat, ! netCDF status variable
  140. & nc_grid1_id, ! netCDF grid file id
  141. & nc_grid2_id, ! netCDF grid file id
  142. & nc_grid1size_id, ! netCDF grid size dim id
  143. & nc_grid2size_id, ! netCDF grid size dim id
  144. & nc_grid1corn_id, ! netCDF grid corner dim id
  145. & nc_grid2corn_id, ! netCDF grid corner dim id
  146. & nc_grid1rank_id, ! netCDF grid rank dim id
  147. & nc_grid2rank_id, ! netCDF grid rank dim id
  148. & nc_grid1area_id, ! netCDF grid rank dim id
  149. & nc_grid2area_id, ! netCDF grid rank dim id
  150. & nc_grid1dims_id, ! netCDF grid dimension size id
  151. & nc_grid2dims_id, ! netCDF grid dimension size id
  152. & nc_grd1imask_id, ! netCDF grid imask var id
  153. & nc_grd2imask_id, ! netCDF grid imask var id
  154. & nc_grd1crnrlat_id, ! netCDF grid corner lat var id
  155. & nc_grd2crnrlat_id, ! netCDF grid corner lat var id
  156. & nc_grd1crnrlon_id, ! netCDF grid corner lon var id
  157. & nc_grd2crnrlon_id, ! netCDF grid corner lon var id
  158. & nc_grd1cntrlat_id, ! netCDF grid center lat var id
  159. & nc_grd2cntrlat_id, ! netCDF grid center lat var id
  160. & nc_grd1cntrlon_id, ! netCDF grid center lon var id
  161. & nc_grd2cntrlon_id ! netCDF grid center lon var id
  162. integer (kind=int_kind), dimension(:), allocatable ::
  163. & imask ! integer mask read from file
  164. real (kind=dbl_kind) ::
  165. & dlat,dlon ! lat/lon intervals for search bins
  166. real (kind=dbl_kind), dimension(4) ::
  167. & tmp_lats, tmp_lons ! temps for computing bounding boxes
  168. !-----------------------------------------------------------------------
  169. !
  170. ! open grid files and read grid size/name data
  171. !
  172. !-----------------------------------------------------------------------
  173. ncstat = nf_open(grid1_file, NF_NOWRITE, nc_grid1_id)
  174. call netcdf_error_handler(ncstat)
  175. ncstat = nf_open(grid2_file, NF_NOWRITE, nc_grid2_id)
  176. call netcdf_error_handler(ncstat)
  177. ncstat = nf_inq_dimid(nc_grid1_id, 'grid_size', nc_grid1size_id)
  178. call netcdf_error_handler(ncstat)
  179. ncstat = nf_inq_dimlen(nc_grid1_id, nc_grid1size_id, grid1_size)
  180. call netcdf_error_handler(ncstat)
  181. ncstat = nf_inq_dimid(nc_grid2_id, 'grid_size', nc_grid2size_id)
  182. call netcdf_error_handler(ncstat)
  183. ncstat = nf_inq_dimlen(nc_grid2_id, nc_grid2size_id, grid2_size)
  184. call netcdf_error_handler(ncstat)
  185. ncstat = nf_inq_dimid(nc_grid1_id, 'grid_rank', nc_grid1rank_id)
  186. call netcdf_error_handler(ncstat)
  187. ncstat = nf_inq_dimlen(nc_grid1_id, nc_grid1rank_id, grid1_rank)
  188. call netcdf_error_handler(ncstat)
  189. ncstat = nf_inq_dimid(nc_grid2_id, 'grid_rank', nc_grid2rank_id)
  190. call netcdf_error_handler(ncstat)
  191. ncstat = nf_inq_dimlen(nc_grid2_id, nc_grid2rank_id, grid2_rank)
  192. call netcdf_error_handler(ncstat)
  193. ncstat = nf_inq_dimid(nc_grid1_id,'grid_corners',nc_grid1corn_id)
  194. call netcdf_error_handler(ncstat)
  195. ncstat = nf_inq_dimlen(nc_grid1_id,nc_grid1corn_id,grid1_corners)
  196. call netcdf_error_handler(ncstat)
  197. ncstat = nf_inq_dimid(nc_grid2_id,'grid_corners',nc_grid2corn_id)
  198. call netcdf_error_handler(ncstat)
  199. ncstat = nf_inq_dimlen(nc_grid2_id,nc_grid2corn_id,grid2_corners)
  200. call netcdf_error_handler(ncstat)
  201. allocate( grid1_dims(grid1_rank),
  202. & grid2_dims(grid2_rank))
  203. ncstat = nf_get_att_text(nc_grid1_id, nf_global, 'title',
  204. & grid1_name)
  205. call netcdf_error_handler(ncstat)
  206. ncstat = nf_get_att_text(nc_grid2_id, nf_global, 'title',
  207. & grid2_name)
  208. call netcdf_error_handler(ncstat)
  209. !-----------------------------------------------------------------------
  210. !
  211. ! allocate grid coordinates/masks and read data
  212. !
  213. !-----------------------------------------------------------------------
  214. allocate( grid1_mask (grid1_size),
  215. & grid2_mask (grid2_size),
  216. & grid1_center_lat(grid1_size),
  217. & grid1_center_lon(grid1_size),
  218. & grid2_center_lat(grid2_size),
  219. & grid2_center_lon(grid2_size),
  220. & grid1_area (grid1_size),
  221. & grid2_area (grid2_size),
  222. & grid1_frac (grid1_size),
  223. & grid2_frac (grid2_size),
  224. & grid1_corner_lat(grid1_corners, grid1_size),
  225. & grid1_corner_lon(grid1_corners, grid1_size),
  226. & grid2_corner_lat(grid2_corners, grid2_size),
  227. & grid2_corner_lon(grid2_corners, grid2_size),
  228. & grid1_bound_box (4 , grid1_size),
  229. & grid2_bound_box (4 , grid2_size))
  230. allocate(imask(grid1_size))
  231. ncstat = nf_inq_varid(nc_grid1_id, 'grid_dims', nc_grid1dims_id)
  232. call netcdf_error_handler(ncstat)
  233. ncstat = nf_inq_varid(nc_grid1_id, 'grid_imask', nc_grd1imask_id)
  234. call netcdf_error_handler(ncstat)
  235. ncstat = nf_inq_varid(nc_grid1_id, 'grid_center_lat',
  236. & nc_grd1cntrlat_id)
  237. call netcdf_error_handler(ncstat)
  238. ncstat = nf_inq_varid(nc_grid1_id, 'grid_center_lon',
  239. & nc_grd1cntrlon_id)
  240. call netcdf_error_handler(ncstat)
  241. ncstat = nf_inq_varid(nc_grid1_id, 'grid_corner_lat',
  242. & nc_grd1crnrlat_id)
  243. call netcdf_error_handler(ncstat)
  244. ncstat = nf_inq_varid(nc_grid1_id, 'grid_corner_lon',
  245. & nc_grd1crnrlon_id)
  246. call netcdf_error_handler(ncstat)
  247. ncstat = nf_get_var_int(nc_grid1_id, nc_grid1dims_id, grid1_dims)
  248. call netcdf_error_handler(ncstat)
  249. ncstat = nf_get_var_int(nc_grid1_id, nc_grd1imask_id, imask)
  250. call netcdf_error_handler(ncstat)
  251. ncstat = nf_get_var_double(nc_grid1_id, nc_grd1cntrlat_id,
  252. & grid1_center_lat)
  253. call netcdf_error_handler(ncstat)
  254. ncstat = nf_get_var_double(nc_grid1_id, nc_grd1cntrlon_id,
  255. & grid1_center_lon)
  256. call netcdf_error_handler(ncstat)
  257. ncstat = nf_get_var_double(nc_grid1_id, nc_grd1crnrlat_id,
  258. & grid1_corner_lat)
  259. call netcdf_error_handler(ncstat)
  260. ncstat = nf_get_var_double(nc_grid1_id, nc_grd1crnrlon_id,
  261. & grid1_corner_lon)
  262. call netcdf_error_handler(ncstat)
  263. if (luse_grid1_area) then
  264. allocate (grid1_area_in(grid1_size))
  265. ncstat = nf_inq_varid(nc_grid1_id, 'grid_area', nc_grid1area_id)
  266. call netcdf_error_handler(ncstat)
  267. ncstat = nf_get_var_double(nc_grid1_id, nc_grid1area_id,
  268. & grid1_area_in)
  269. call netcdf_error_handler(ncstat)
  270. endif
  271. grid1_area = zero
  272. grid1_frac = zero
  273. !-----------------------------------------------------------------------
  274. !
  275. ! initialize logical mask and convert lat/lon units if required
  276. !
  277. !-----------------------------------------------------------------------
  278. where (imask == 1)
  279. grid1_mask = .true.
  280. elsewhere
  281. grid1_mask = .false.
  282. endwhere
  283. deallocate(imask)
  284. grid1_units = ' '
  285. ncstat = nf_get_att_text(nc_grid1_id, nc_grd1cntrlat_id, 'units',
  286. & grid1_units)
  287. call netcdf_error_handler(ncstat)
  288. select case (grid1_units(1:7))
  289. case ('degrees')
  290. grid1_center_lat = grid1_center_lat*deg2rad
  291. grid1_center_lon = grid1_center_lon*deg2rad
  292. case ('radians')
  293. !*** no conversion necessary
  294. case default
  295. print *,'unknown units supplied for grid1 center lat/lon: '
  296. print *,'proceeding assuming radians'
  297. end select
  298. grid1_units = ' '
  299. ncstat = nf_get_att_text(nc_grid1_id, nc_grd1crnrlat_id, 'units',
  300. & grid1_units)
  301. call netcdf_error_handler(ncstat)
  302. select case (grid1_units(1:7))
  303. case ('degrees')
  304. grid1_corner_lat = grid1_corner_lat*deg2rad
  305. grid1_corner_lon = grid1_corner_lon*deg2rad
  306. case ('radians')
  307. !*** no conversion necessary
  308. case default
  309. print *,'unknown units supplied for grid1 corner lat/lon: '
  310. print *,'proceeding assuming radians'
  311. end select
  312. ncstat = nf_close(nc_grid1_id)
  313. call netcdf_error_handler(ncstat)
  314. !-----------------------------------------------------------------------
  315. !
  316. ! read data for grid 2
  317. !
  318. !-----------------------------------------------------------------------
  319. allocate(imask(grid2_size))
  320. ncstat = nf_inq_varid(nc_grid2_id, 'grid_dims', nc_grid2dims_id)
  321. call netcdf_error_handler(ncstat)
  322. ncstat = nf_inq_varid(nc_grid2_id, 'grid_imask', nc_grd2imask_id)
  323. call netcdf_error_handler(ncstat)
  324. ncstat = nf_inq_varid(nc_grid2_id, 'grid_center_lat',
  325. & nc_grd2cntrlat_id)
  326. call netcdf_error_handler(ncstat)
  327. ncstat = nf_inq_varid(nc_grid2_id, 'grid_center_lon',
  328. & nc_grd2cntrlon_id)
  329. call netcdf_error_handler(ncstat)
  330. ncstat = nf_inq_varid(nc_grid2_id, 'grid_corner_lat',
  331. & nc_grd2crnrlat_id)
  332. call netcdf_error_handler(ncstat)
  333. ncstat = nf_inq_varid(nc_grid2_id, 'grid_corner_lon',
  334. & nc_grd2crnrlon_id)
  335. call netcdf_error_handler(ncstat)
  336. ncstat = nf_get_var_int(nc_grid2_id, nc_grid2dims_id, grid2_dims)
  337. call netcdf_error_handler(ncstat)
  338. ncstat = nf_get_var_int(nc_grid2_id, nc_grd2imask_id, imask)
  339. call netcdf_error_handler(ncstat)
  340. ncstat = nf_get_var_double(nc_grid2_id, nc_grd2cntrlat_id,
  341. & grid2_center_lat)
  342. call netcdf_error_handler(ncstat)
  343. ncstat = nf_get_var_double(nc_grid2_id, nc_grd2cntrlon_id,
  344. & grid2_center_lon)
  345. call netcdf_error_handler(ncstat)
  346. ncstat = nf_get_var_double(nc_grid2_id, nc_grd2crnrlat_id,
  347. & grid2_corner_lat)
  348. call netcdf_error_handler(ncstat)
  349. ncstat = nf_get_var_double(nc_grid2_id, nc_grd2crnrlon_id,
  350. & grid2_corner_lon)
  351. call netcdf_error_handler(ncstat)
  352. if (luse_grid2_area) then
  353. allocate (grid2_area_in(grid2_size))
  354. ncstat = nf_inq_varid(nc_grid2_id, 'grid_area', nc_grid2area_id)
  355. call netcdf_error_handler(ncstat)
  356. ncstat = nf_get_var_double(nc_grid2_id, nc_grid2area_id,
  357. & grid2_area_in)
  358. call netcdf_error_handler(ncstat)
  359. endif
  360. grid2_area = zero
  361. grid2_frac = zero
  362. !-----------------------------------------------------------------------
  363. !
  364. ! initialize logical mask and convert lat/lon units if required
  365. !
  366. !-----------------------------------------------------------------------
  367. where (imask == 1)
  368. grid2_mask = .true.
  369. elsewhere
  370. grid2_mask = .false.
  371. endwhere
  372. deallocate(imask)
  373. grid2_units = ' '
  374. ncstat = nf_get_att_text(nc_grid2_id, nc_grd2cntrlat_id, 'units',
  375. & grid2_units)
  376. call netcdf_error_handler(ncstat)
  377. select case (grid2_units(1:7))
  378. case ('degrees')
  379. grid2_center_lat = grid2_center_lat*deg2rad
  380. grid2_center_lon = grid2_center_lon*deg2rad
  381. case ('radians')
  382. !*** no conversion necessary
  383. case default
  384. print *,'unknown units supplied for grid2 center lat/lon: '
  385. print *,'proceeding assuming radians'
  386. end select
  387. grid2_units = ' '
  388. ncstat = nf_get_att_text(nc_grid2_id, nc_grd2crnrlat_id, 'units',
  389. & grid2_units)
  390. call netcdf_error_handler(ncstat)
  391. select case (grid2_units(1:7))
  392. case ('degrees')
  393. grid2_corner_lat = grid2_corner_lat*deg2rad
  394. grid2_corner_lon = grid2_corner_lon*deg2rad
  395. case ('radians')
  396. !*** no conversion necessary
  397. case default
  398. print *,'no units supplied for grid2 corner lat/lon: '
  399. print *,'proceeding assuming radians'
  400. end select
  401. ncstat = nf_close(nc_grid2_id)
  402. call netcdf_error_handler(ncstat)
  403. !-----------------------------------------------------------------------
  404. !
  405. ! convert longitudes to 0,2pi interval
  406. !
  407. !-----------------------------------------------------------------------
  408. where (grid1_center_lon .gt. pi2) grid1_center_lon =
  409. & grid1_center_lon - pi2
  410. where (grid1_center_lon .lt. zero) grid1_center_lon =
  411. & grid1_center_lon + pi2
  412. where (grid2_center_lon .gt. pi2) grid2_center_lon =
  413. & grid2_center_lon - pi2
  414. where (grid2_center_lon .lt. zero) grid2_center_lon =
  415. & grid2_center_lon + pi2
  416. where (grid1_corner_lon .gt. pi2) grid1_corner_lon =
  417. & grid1_corner_lon - pi2
  418. where (grid1_corner_lon .lt. zero) grid1_corner_lon =
  419. & grid1_corner_lon + pi2
  420. where (grid2_corner_lon .gt. pi2) grid2_corner_lon =
  421. & grid2_corner_lon - pi2
  422. where (grid2_corner_lon .lt. zero) grid2_corner_lon =
  423. & grid2_corner_lon + pi2
  424. !-----------------------------------------------------------------------
  425. !
  426. ! make sure input latitude range is within the machine values
  427. ! for +/- pi/2
  428. !
  429. !-----------------------------------------------------------------------
  430. where (grid1_center_lat > pih) grid1_center_lat = pih
  431. where (grid1_corner_lat > pih) grid1_corner_lat = pih
  432. where (grid1_center_lat < -pih) grid1_center_lat = -pih
  433. where (grid1_corner_lat < -pih) grid1_corner_lat = -pih
  434. where (grid2_center_lat > pih) grid2_center_lat = pih
  435. where (grid2_corner_lat > pih) grid2_corner_lat = pih
  436. where (grid2_center_lat < -pih) grid2_center_lat = -pih
  437. where (grid2_corner_lat < -pih) grid2_corner_lat = -pih
  438. !-----------------------------------------------------------------------
  439. !
  440. ! compute bounding boxes for restricting future grid searches
  441. !
  442. !-----------------------------------------------------------------------
  443. if (.not. luse_grid_centers) then
  444. grid1_bound_box(1,:) = minval(grid1_corner_lat, DIM=1)
  445. grid1_bound_box(2,:) = maxval(grid1_corner_lat, DIM=1)
  446. grid1_bound_box(3,:) = minval(grid1_corner_lon, DIM=1)
  447. grid1_bound_box(4,:) = maxval(grid1_corner_lon, DIM=1)
  448. grid2_bound_box(1,:) = minval(grid2_corner_lat, DIM=1)
  449. grid2_bound_box(2,:) = maxval(grid2_corner_lat, DIM=1)
  450. grid2_bound_box(3,:) = minval(grid2_corner_lon, DIM=1)
  451. grid2_bound_box(4,:) = maxval(grid2_corner_lon, DIM=1)
  452. else
  453. nx = grid1_dims(1)
  454. ny = grid1_dims(2)
  455. do n=1,grid1_size
  456. !*** find N,S and NE points to this grid point
  457. j = (n - 1)/nx +1
  458. i = n - (j-1)*nx
  459. if (i < nx) then
  460. ip1 = i + 1
  461. else
  462. !*** assume cyclic
  463. ip1 = 1
  464. !*** but if it is not, correct
  465. e_add = (j - 1)*nx + ip1
  466. if (abs(grid1_center_lat(e_add) -
  467. & grid1_center_lat(n )) > pih) then
  468. ip1 = i
  469. endif
  470. endif
  471. if (j < ny) then
  472. jp1 = j+1
  473. else
  474. !*** assume cyclic
  475. jp1 = 1
  476. !*** but if it is not, correct
  477. n_add = (jp1 - 1)*nx + i
  478. if (abs(grid1_center_lat(n_add) -
  479. & grid1_center_lat(n )) > pih) then
  480. jp1 = j
  481. endif
  482. endif
  483. n_add = (jp1 - 1)*nx + i
  484. e_add = (j - 1)*nx + ip1
  485. ne_add = (jp1 - 1)*nx + ip1
  486. !*** find N,S and NE lat/lon coords and check bounding box
  487. tmp_lats(1) = grid1_center_lat(n)
  488. tmp_lats(2) = grid1_center_lat(e_add)
  489. tmp_lats(3) = grid1_center_lat(ne_add)
  490. tmp_lats(4) = grid1_center_lat(n_add)
  491. tmp_lons(1) = grid1_center_lon(n)
  492. tmp_lons(2) = grid1_center_lon(e_add)
  493. tmp_lons(3) = grid1_center_lon(ne_add)
  494. tmp_lons(4) = grid1_center_lon(n_add)
  495. grid1_bound_box(1,n) = minval(tmp_lats)
  496. grid1_bound_box(2,n) = maxval(tmp_lats)
  497. grid1_bound_box(3,n) = minval(tmp_lons)
  498. grid1_bound_box(4,n) = maxval(tmp_lons)
  499. end do
  500. nx = grid2_dims(1)
  501. ny = grid2_dims(2)
  502. do n=1,grid2_size
  503. !*** find N,S and NE points to this grid point
  504. j = (n - 1)/nx +1
  505. i = n - (j-1)*nx
  506. if (i < nx) then
  507. ip1 = i + 1
  508. else
  509. !*** assume cyclic
  510. ip1 = 1
  511. !*** but if it is not, correct
  512. e_add = (j - 1)*nx + ip1
  513. if (abs(grid2_center_lat(e_add) -
  514. & grid2_center_lat(n )) > pih) then
  515. ip1 = i
  516. endif
  517. endif
  518. if (j < ny) then
  519. jp1 = j+1
  520. else
  521. !*** assume cyclic
  522. jp1 = 1
  523. !*** but if it is not, correct
  524. n_add = (jp1 - 1)*nx + i
  525. if (abs(grid2_center_lat(n_add) -
  526. & grid2_center_lat(n )) > pih) then
  527. jp1 = j
  528. endif
  529. endif
  530. n_add = (jp1 - 1)*nx + i
  531. e_add = (j - 1)*nx + ip1
  532. ne_add = (jp1 - 1)*nx + ip1
  533. !*** find N,S and NE lat/lon coords and check bounding box
  534. tmp_lats(1) = grid2_center_lat(n)
  535. tmp_lats(2) = grid2_center_lat(e_add)
  536. tmp_lats(3) = grid2_center_lat(ne_add)
  537. tmp_lats(4) = grid2_center_lat(n_add)
  538. tmp_lons(1) = grid2_center_lon(n)
  539. tmp_lons(2) = grid2_center_lon(e_add)
  540. tmp_lons(3) = grid2_center_lon(ne_add)
  541. tmp_lons(4) = grid2_center_lon(n_add)
  542. grid2_bound_box(1,n) = minval(tmp_lats)
  543. grid2_bound_box(2,n) = maxval(tmp_lats)
  544. grid2_bound_box(3,n) = minval(tmp_lons)
  545. grid2_bound_box(4,n) = maxval(tmp_lons)
  546. end do
  547. endif
  548. where (abs(grid1_bound_box(4,:) - grid1_bound_box(3,:)) > pi)
  549. grid1_bound_box(3,:) = zero
  550. grid1_bound_box(4,:) = pi2
  551. end where
  552. where (abs(grid2_bound_box(4,:) - grid2_bound_box(3,:)) > pi)
  553. grid2_bound_box(3,:) = zero
  554. grid2_bound_box(4,:) = pi2
  555. end where
  556. !***
  557. !*** try to check for cells that overlap poles
  558. !***
  559. where (grid1_center_lat > grid1_bound_box(2,:))
  560. & grid1_bound_box(2,:) = pih
  561. where (grid1_center_lat < grid1_bound_box(1,:))
  562. & grid1_bound_box(1,:) = -pih
  563. where (grid2_center_lat > grid2_bound_box(2,:))
  564. & grid2_bound_box(2,:) = pih
  565. where (grid2_center_lat < grid2_bound_box(1,:))
  566. & grid2_bound_box(1,:) = -pih
  567. !-----------------------------------------------------------------------
  568. !
  569. ! set up and assign address ranges to search bins in order to
  570. ! further restrict later searches
  571. !
  572. !-----------------------------------------------------------------------
  573. select case (restrict_type)
  574. case ('latitude')
  575. write(stdout,*) 'Using latitude bins to restrict search.'
  576. allocate(bin_addr1(2,num_srch_bins))
  577. allocate(bin_addr2(2,num_srch_bins))
  578. allocate(bin_lats (2,num_srch_bins))
  579. allocate(bin_lons (2,num_srch_bins))
  580. dlat = pi/num_srch_bins
  581. do n=1,num_srch_bins
  582. bin_lats(1,n) = (n-1)*dlat - pih
  583. bin_lats(2,n) = n*dlat - pih
  584. bin_lons(1,n) = zero
  585. bin_lons(2,n) = pi2
  586. bin_addr1(1,n) = grid1_size + 1
  587. bin_addr1(2,n) = 0
  588. bin_addr2(1,n) = grid2_size + 1
  589. bin_addr2(2,n) = 0
  590. end do
  591. do nele=1,grid1_size
  592. do n=1,num_srch_bins
  593. if (grid1_bound_box(1,nele) <= bin_lats(2,n) .and.
  594. & grid1_bound_box(2,nele) >= bin_lats(1,n)) then
  595. bin_addr1(1,n) = min(nele,bin_addr1(1,n))
  596. bin_addr1(2,n) = max(nele,bin_addr1(2,n))
  597. endif
  598. end do
  599. end do
  600. do nele=1,grid2_size
  601. do n=1,num_srch_bins
  602. if (grid2_bound_box(1,nele) <= bin_lats(2,n) .and.
  603. & grid2_bound_box(2,nele) >= bin_lats(1,n)) then
  604. bin_addr2(1,n) = min(nele,bin_addr2(1,n))
  605. bin_addr2(2,n) = max(nele,bin_addr2(2,n))
  606. endif
  607. end do
  608. end do
  609. case ('latlon')
  610. write(stdout,*) 'Using lat/lon boxes to restrict search.'
  611. dlat = pi /num_srch_bins
  612. dlon = pi2/num_srch_bins
  613. allocate(bin_addr1(2,num_srch_bins*num_srch_bins))
  614. allocate(bin_addr2(2,num_srch_bins*num_srch_bins))
  615. allocate(bin_lats (2,num_srch_bins*num_srch_bins))
  616. allocate(bin_lons (2,num_srch_bins*num_srch_bins))
  617. n = 0
  618. do j=1,num_srch_bins
  619. do i=1,num_srch_bins
  620. n = n + 1
  621. bin_lats(1,n) = (j-1)*dlat - pih
  622. bin_lats(2,n) = j*dlat - pih
  623. bin_lons(1,n) = (i-1)*dlon
  624. bin_lons(2,n) = i*dlon
  625. bin_addr1(1,n) = grid1_size + 1
  626. bin_addr1(2,n) = 0
  627. bin_addr2(1,n) = grid2_size + 1
  628. bin_addr2(2,n) = 0
  629. end do
  630. end do
  631. num_srch_bins = num_srch_bins**2
  632. do nele=1,grid1_size
  633. do n=1,num_srch_bins
  634. if (grid1_bound_box(1,nele) <= bin_lats(2,n) .and.
  635. & grid1_bound_box(2,nele) >= bin_lats(1,n) .and.
  636. & grid1_bound_box(3,nele) <= bin_lons(2,n) .and.
  637. & grid1_bound_box(4,nele) >= bin_lons(1,n)) then
  638. bin_addr1(1,n) = min(nele,bin_addr1(1,n))
  639. bin_addr1(2,n) = max(nele,bin_addr1(2,n))
  640. endif
  641. end do
  642. end do
  643. do nele=1,grid2_size
  644. do n=1,num_srch_bins
  645. if (grid2_bound_box(1,nele) <= bin_lats(2,n) .and.
  646. & grid2_bound_box(2,nele) >= bin_lats(1,n) .and.
  647. & grid2_bound_box(3,nele) <= bin_lons(2,n) .and.
  648. & grid2_bound_box(4,nele) >= bin_lons(1,n)) then
  649. bin_addr2(1,n) = min(nele,bin_addr2(1,n))
  650. bin_addr2(2,n) = max(nele,bin_addr2(2,n))
  651. endif
  652. end do
  653. end do
  654. case default
  655. stop 'unknown search restriction method'
  656. end select
  657. !-----------------------------------------------------------------------
  658. end subroutine grid_init
  659. !***********************************************************************
  660. end module grids
  661. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!