WAVEWATCH III  beta 0.0.1
scrip_grids.f
Go to the documentation of this file.
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 ! this grids.f has been modified from the version available from
36 ! Los Alamos National Laboratory.
37 ! modifications are marked with "NRL"
38 ! list of modifications:
39 ! - netcdf operations for reading from netcdf file removed
40 ! (major change)
41 ! - print statements added
42 ! - allocations removed (moved to scrip_wrapper subroutine)
43 ! - imask removed (this was an intermediate step from ncdf to
44 ! the logicals grid1_mask grid2_mask; creation of these
45 ! logicals is now handled by scrip_wrapper)
46 !
47 !***********************************************************************
48 
49  module scrip_grids
50 
51 !-----------------------------------------------------------------------
52 
53  use scrip_kindsmod ! defines data types
54  use scrip_errormod ! error tracking
55  use scrip_iounitsmod ! manages I/O units
56  use scrip_constants ! common constants
57 ! use SCRIP_NetcdfMod ! netCDF stuff
58 ! use netcdf ! netCDF library module
59 
60  implicit none
61 
62 !-----------------------------------------------------------------------
63 !
64 ! variables that describe each grid
65 !
66 !-----------------------------------------------------------------------
67 
68  integer (SCRIP_i4), save ::
69  & grid1_size, grid2_size, ! total points on each grid
70  & grid1_rank, grid2_rank, ! rank of each grid
71  & grid1_corners, grid2_corners ! number of corners
72  ! for each grid cell
73 
74  integer (SCRIP_i4), dimension(:), allocatable, save ::
75  & grid1_dims, grid2_dims ! size of each grid dimension
76 
77  character(SCRIP_charLength), save ::
78  & grid1_name, grid2_name ! name for each grid
79 
80  character (SCRIP_charLength), save ::
81  & grid1_units, ! units for grid coords (degs/radians)
82  & grid2_units ! units for grid coords
83 
84  real (scrip_r8), parameter ::
85  & deg2rad = pi/180. ! conversion for deg to rads
86 
87 !-----------------------------------------------------------------------
88 !
89 ! grid coordinates and masks
90 !
91 !-----------------------------------------------------------------------
92 
93  logical (SCRIP_logical), dimension(:), allocatable, target,save ::
94  & grid1_mask, ! flag which cells participate
95  & grid2_mask, ! flag which cells participate
96  & special_polar_cell1, ! cell with only 1 corner at pole
98 
99  integer (SCRIP_i4), dimension(:), allocatable, target,save ::
100  & grid1_imask, ! flag which cells participate
101  & grid2_imask ! flag which cells participate
102 
103  real (scrip_r8), dimension(:), allocatable, target, save ::
104  & grid1_center_lat, ! lat/lon coordinates for
105  & grid1_center_lon, ! each grid center in radians
108  & grid1_area, ! tot area of each grid1 cell
109  & grid2_area, ! tot area of each grid2 cell
110  & grid1_area_in, ! area of grid1 cell from file
111  & grid2_area_in, ! area of grid2 cell from file
112  & grid1_frac, ! fractional area of grid cells
113  & grid2_frac, ! participating in remapping
114  & grid1_centroid_lat,! Centroid of grid1 cell
116  & grid2_centroid_lat,! Centroid of grid2 cell
118 
119 
120  real (scrip_r8), dimension(:,:), allocatable, target, save ::
121  & grid1_corner_lat, ! lat/lon coordinates for
122  & grid1_corner_lon, ! each grid corner in radians
125 
126  logical (SCRIP_logical), save ::
127  & luse_grid_centers ! use centers for bounding boxes
128  &, luse_grid1_area ! use area from grid file
129  &, luse_grid2_area ! use area from grid file
130 
131  real (scrip_r8), dimension(:,:), allocatable, target, save ::
132  & grid1_bound_box, ! lat/lon bounding box for use
133  & grid2_bound_box ! in restricting grid searches
134 
135  integer (SCRIP_i4), save :: ! Cells overlapping the poles
136  ! (may be 0)
141 
142 
143 !-----------------------------------------------------------------------
144 !
145 ! bins for restricting searches
146 !
147 !-----------------------------------------------------------------------
148 
149  character (SCRIP_charLength), save ::
150  & restrict_type ! type of bins to use
151 
152  integer (SCRIP_i4), save ::
153  & num_srch_bins ! num of bins for restricted srch
154 
155  integer (SCRIP_i4), dimension(:,:), allocatable, save ::
156  & bin_addr1, ! min,max adds for grid1 cells in this lat bin
157  & bin_addr2 ! min,max adds for grid2 cells in this lat bin
158 
159  real(scrip_r8), dimension(:,:), allocatable, save ::
160  & bin_lats ! min,max latitude for each search bin
161  &, bin_lons ! min,max longitude for each search bin
162 
163 !-----------------------------------------------------------------------
164 !
165 ! Parameters for dealing with intersections in the polar region
166 !
167 !-----------------------------------------------------------------------
168 
169  real (scrip_r8), save ::
170  & north_thresh, ! threshold for coord transf.
171  & south_thresh ! threshold for coord transf.
172 
173 
174  !*** Number of subsegments used to represents edges near
175  !*** the polar regions - choose an odd number to avoid obvious
176  !*** degeneracies in intersection
177 
178  integer (SCRIP_i4), save ::
179  & npseg
180 
181 !***********************************************************************
182 
183  contains
184 
185 !***********************************************************************
186 
187  subroutine grid_init(errorCode,l_master,l_test)
188 
189 !-----------------------------------------------------------------------
190 !
191 ! this routine reads grid info from grid files and makes any
192 ! necessary changes (e.g. for 0,2pi longitude range)
193 !
194 !-----------------------------------------------------------------------
195 
196 !-----------------------------------------------------------------------
197 !
198 ! input variables
199 !
200 !-----------------------------------------------------------------------
201 
202  logical(SCRIP_Logical), intent(in) :: l_master ! Am I the master
203  ! processor (do I/O)?
204  logical(SCRIP_Logical), intent(in) :: l_test ! Whether to include
205  ! test output
206 
207 !-----------------------------------------------------------------------
208 !
209 ! output variables
210 !
211 !-----------------------------------------------------------------------
212 
213  integer (SCRIP_i4), intent(out) ::
214  & errorCode ! returned error code
215 
216 !-----------------------------------------------------------------------
217 !
218 ! local variables
219 !
220 !-----------------------------------------------------------------------
221 
222  integer (SCRIP_i4) ::
223  & n, ! loop counter
224  & nele, ! element loop counter
225  & i,j,
226  & ip1,jp1,
227  & n_add, e_add, ne_add,
228  & nx, ny, ncorners_at_pole
229 
230  integer (SCRIP_i4) ::
231  & zero_crossing, pi_crossing,
232  & grid1_add, grid2_add,
233  & corner, next_corn
234 
235  real (SCRIP_r8) ::
236  & beglon, beglat, endlon, endlat
237 
238  logical (SCRIP_logical) ::
239  & found
240 
241 !NRL integer (SCRIP_i4), dimension(:), allocatable ::
242 !NRL & imask ! integer mask read from file
243 
244  real (SCRIP_r8) ::
245  & dlat,dlon ! lat/lon intervals for search bins
246 
247  real (SCRIP_r8), dimension(4) ::
248  & tmp_lats, tmp_lons ! temps for computing bounding boxes
249 
250  character (9), parameter ::
251  & rtnName = 'grid_init'
252 
253  if(l_master.and.l_test)write(scrip_stdout,*)'subroutine grid_init'
254 
255 !NRL #####################################################
256 !NRL .....Begin part of code formerly handled by netcdf read
257 !NRL #####################################################
258 
259 !-----------------------------------------------------------------------
260 !
261 ! allocate grid coordinates/masks and read data
262 !
263 !-----------------------------------------------------------------------
264 
265  allocate(
266 !NRL & grid1_mask (grid1_size),
267 !NRL & grid2_mask (grid2_size),
270 !NRL & grid1_center_lat(grid1_size),
271 !NRL & grid1_center_lon(grid1_size),
272 !NRL & grid2_center_lat(grid2_size),
273 !NRL & grid2_center_lon(grid2_size),
280 !NRL & grid1_corner_lat(grid1_corners, grid1_size),
281 !NRL & grid1_corner_lon(grid1_corners, grid1_size),
282 !NRL & grid2_corner_lat(grid2_corners, grid2_size),
283 !NRL & grid2_corner_lon(grid2_corners, grid2_size),
290 
291 !NRL allocate(imask(grid1_size))
292 
293  grid1_area = zero
294  grid1_frac = zero
297 
298 !-----------------------------------------------------------------------
299 !
300 ! initialize logical mask and convert lat/lon units if required
301 !
302 !-----------------------------------------------------------------------
303 
304 !NRL where (imask == 1)
305 !NRL grid1_mask = .true.
306 !NRL elsewhere
307 !NRL grid1_mask = .false.
308 !NRL endwhere
309 !NRL deallocate(imask)
310 
311  select case (grid1_units(1:7))
312  case ('degrees')
313 
316 
317  case ('radians')
318 
319  !*** no conversion necessary
320 
321  case default
322 
323  print *,'unknown units supplied for grid1 center lat/lon: '
324  print *,'proceeding assuming radians'
325 
326  end select
327 
328  select case (grid1_units(1:7))
329  case ('degrees')
330 
333 
334  case ('radians')
335 
336  !*** no conversion necessary
337 
338  case default
339 
340  print *,'unknown units supplied for grid1 corner lat/lon: '
341  print *,'proceeding assuming radians'
342 
343  end select
344 
345 !-----------------------------------------------------------------------
346 !
347 ! read data for grid 2
348 !
349 !-----------------------------------------------------------------------
350 
351 !NRL allocate(imask(grid2_size))
352 
353  grid2_area = zero
354  grid2_frac = zero
357 
358 !-----------------------------------------------------------------------
359 !
360 ! initialize logical mask and convert lat/lon units if required
361 !
362 !-----------------------------------------------------------------------
363 
364 !NRL where (imask == 1)
365 !NRL grid2_mask = .true.
366 !NRL elsewhere
367 !NRL grid2_mask = .false.
368 !NRL endwhere
369 !NRL deallocate(imask)
370 
371  select case (grid2_units(1:7))
372  case ('degrees')
373 
376 
377  case ('radians')
378 
379  !*** no conversion necessary
380 
381  case default
382 
383  print *,'unknown units supplied for grid2 center lat/lon: '
384  print *,'proceeding assuming radians'
385 
386  end select
387 
388  select case (grid2_units(1:7))
389  case ('degrees')
390 
393 
394  case ('radians')
395 
396  !*** no conversion necessary
397 
398  case default
399 
400  print *,'no units supplied for grid2 corner lat/lon: '
401  print *,'proceeding assuming radians'
402 
403  end select
404 
405 !NRL #####################################################
406 !NRL .....End part of code formerly handled by netcdf read
407 !NRL #####################################################
408 
409 
410 !-----------------------------------------------------------------------
411 !
412 ! convert longitudes to 0,2pi interval
413 !
414 !-----------------------------------------------------------------------
415 
416  where (grid1_center_lon .gt. pi2) grid1_center_lon =
418  where (grid1_center_lon .lt. zero) grid1_center_lon =
420  where (grid2_center_lon .gt. pi2) grid2_center_lon =
422  where (grid2_center_lon .lt. zero) grid2_center_lon =
424  where (grid1_corner_lon .gt. pi2) grid1_corner_lon =
426  where (grid1_corner_lon .lt. zero) grid1_corner_lon =
428  where (grid2_corner_lon .gt. pi2) grid2_corner_lon =
430  where (grid2_corner_lon .lt. zero) grid2_corner_lon =
432 
433 !-----------------------------------------------------------------------
434 !
435 ! make sure input latitude range is within the machine values
436 ! for +/- pi/2
437 !
438 !-----------------------------------------------------------------------
439 
444 
449 
450 
451 !-----------------------------------------------------------------------
452 !
453 ! also, different grids consider the pole to be a slightly different
454 ! values (1.570796326789 vs 1.5707963267977). Find the closest
455 ! approach to the pole and if it is within a tolerance, move such
456 ! points that are practically at the pole to the pole to avoid
457 ! problems
458 !
459 !-----------------------------------------------------------------------
460 
461  where (abs(grid1_corner_lat-pih) < 1.e-03) grid1_corner_lat = pih
462  where (abs(grid1_corner_lat+pih) < 1.e-03) grid1_corner_lat = -pih
463  where (abs(grid2_corner_lat-pih) < 1.e-03) grid2_corner_lat = pih
464  where (abs(grid2_corner_lat+pih) < 1.e-03) grid2_corner_lat = -pih
465 
466 
467 !-----------------------------------------------------------------------
468 !
469 ! compute bounding boxes for restricting future grid searches
470 !
471 !-----------------------------------------------------------------------
472 
473  if (.not. luse_grid_centers) then
474  grid1_bound_box(1,:) = minval(grid1_corner_lat, dim=1)
475  grid1_bound_box(2,:) = maxval(grid1_corner_lat, dim=1)
476  grid1_bound_box(3,:) = minval(grid1_corner_lon, dim=1)
477  grid1_bound_box(4,:) = maxval(grid1_corner_lon, dim=1)
478 
479  grid2_bound_box(1,:) = minval(grid2_corner_lat, dim=1)
480  grid2_bound_box(2,:) = maxval(grid2_corner_lat, dim=1)
481  grid2_bound_box(3,:) = minval(grid2_corner_lon, dim=1)
482  grid2_bound_box(4,:) = maxval(grid2_corner_lon, dim=1)
483 
484  else
485 
486  nx = grid1_dims(1)
487  ny = grid1_dims(2)
488 
489  do n=1,grid1_size
490 
491  !*** find N,S and NE points to this grid point
492 
493  j = (n - 1)/nx +1
494  i = n - (j-1)*nx
495 
496  if (i < nx) then
497  ip1 = i + 1
498  else
499  !*** assume cyclic
500  ip1 = 1
501  !*** but if it is not, correct
502  e_add = (j - 1)*nx + ip1
503  if (abs(grid1_center_lat(e_add) -
504  & grid1_center_lat(n )) > pih) then
505  ip1 = i
506  endif
507  endif
508 
509  if (j < ny) then
510  jp1 = j+1
511  else
512  !*** assume cyclic
513  jp1 = 1
514  !*** but if it is not, correct
515  n_add = (jp1 - 1)*nx + i
516  if (abs(grid1_center_lat(n_add) -
517  & grid1_center_lat(n )) > pih) then
518  jp1 = j
519  endif
520  endif
521 
522  n_add = (jp1 - 1)*nx + i
523  e_add = (j - 1)*nx + ip1
524  ne_add = (jp1 - 1)*nx + ip1
525 
526  !*** find N,S and NE lat/lon coords and check bounding box
527 
528  tmp_lats(1) = grid1_center_lat(n)
529  tmp_lats(2) = grid1_center_lat(e_add)
530  tmp_lats(3) = grid1_center_lat(ne_add)
531  tmp_lats(4) = grid1_center_lat(n_add)
532 
533  tmp_lons(1) = grid1_center_lon(n)
534  tmp_lons(2) = grid1_center_lon(e_add)
535  tmp_lons(3) = grid1_center_lon(ne_add)
536  tmp_lons(4) = grid1_center_lon(n_add)
537 
538  grid1_bound_box(1,n) = minval(tmp_lats)
539  grid1_bound_box(2,n) = maxval(tmp_lats)
540  grid1_bound_box(3,n) = minval(tmp_lons)
541  grid1_bound_box(4,n) = maxval(tmp_lons)
542  end do
543 
544  nx = grid2_dims(1)
545  ny = grid2_dims(2)
546 
547  do n=1,grid2_size
548 
549  !*** find N,S and NE points to this grid point
550 
551  j = (n - 1)/nx +1
552  i = n - (j-1)*nx
553 
554  if (i < nx) then
555  ip1 = i + 1
556  else
557  !*** assume cyclic
558  ip1 = 1
559  !*** but if it is not, correct
560  e_add = (j - 1)*nx + ip1
561  if (abs(grid2_center_lat(e_add) -
562  & grid2_center_lat(n )) > pih) then
563  ip1 = i
564  endif
565  endif
566 
567  if (j < ny) then
568  jp1 = j+1
569  else
570  !*** assume cyclic
571  jp1 = 1
572  !*** but if it is not, correct
573  n_add = (jp1 - 1)*nx + i
574  if (abs(grid2_center_lat(n_add) -
575  & grid2_center_lat(n )) > pih) then
576  jp1 = j
577  endif
578  endif
579 
580  n_add = (jp1 - 1)*nx + i
581  e_add = (j - 1)*nx + ip1
582  ne_add = (jp1 - 1)*nx + ip1
583 
584  !*** find N,S and NE lat/lon coords and check bounding box
585 
586  tmp_lats(1) = grid2_center_lat(n)
587  tmp_lats(2) = grid2_center_lat(e_add)
588  tmp_lats(3) = grid2_center_lat(ne_add)
589  tmp_lats(4) = grid2_center_lat(n_add)
590 
591  tmp_lons(1) = grid2_center_lon(n)
592  tmp_lons(2) = grid2_center_lon(e_add)
593  tmp_lons(3) = grid2_center_lon(ne_add)
594  tmp_lons(4) = grid2_center_lon(n_add)
595 
596  grid2_bound_box(1,n) = minval(tmp_lats)
597  grid2_bound_box(2,n) = maxval(tmp_lats)
598  grid2_bound_box(3,n) = minval(tmp_lons)
599  grid2_bound_box(4,n) = maxval(tmp_lons)
600  end do
601 
602  endif
603 
604  where (abs(grid1_bound_box(4,:) - grid1_bound_box(3,:)) > pi)
605  grid1_bound_box(3,:) = zero
606  grid1_bound_box(4,:) = pi2
607  end where
608 
609  where (abs(grid2_bound_box(4,:) - grid2_bound_box(3,:)) > pi)
610  grid2_bound_box(3,:) = zero
611  grid2_bound_box(4,:) = pi2
612  end where
613 
614  where (grid1_center_lat > grid1_bound_box(2,:))
615  & grid1_bound_box(2,:) = pih
616 
617  where (grid1_center_lat < grid1_bound_box(1,:))
618  & grid1_bound_box(1,:) = -pih
619 
620  where (grid2_center_lat > grid2_bound_box(2,:))
621  & grid2_bound_box(2,:) = pih
622 
623  where (grid2_center_lat < grid2_bound_box(1,:))
624  & grid2_bound_box(1,:) = -pih
625 
626 
627  !***
628  !*** Check for cells that overlap poles and explicitly
629  !*** store their addresses
630  !***
631 
632  grid1_npole_cell = 0
633  grid1_spole_cell = 0
634 
635  do grid1_add = 1, grid1_size
636 
637  found = .false.
638  do corner = 1, grid1_corners
639  endlat = grid1_corner_lat(corner,grid1_add)
640  if (abs(abs(endlat)-pih) .lt. 1e-5) then
641  found = .true. ! cell has polar pnt; so pole is
642  ! not in the interior of the cell
643  exit
644  endif
645  enddo
646 
647  if (found) cycle
648 
649 
650  beglon = grid1_corner_lon(1,grid1_add)
651  zero_crossing = 0
652  pi_crossing = 0
653 
654  do corner = 1, grid1_corners
655  next_corn = mod(corner,grid1_corners) + 1
656  endlon = grid1_corner_lon(next_corn,grid1_add)
657 
658  if (abs(beglon-endlon) .gt. pi) then
659  zero_crossing = 1
660  else
661  if ((beglon .lt. pi .and. endlon .ge. pi) .or.
662  & (endlon .lt. pi .and. beglon .ge. pi)) then
663  pi_crossing = 1
664  endif
665  endif
666 
667  beglon = endlon
668  enddo
669 
670  if (zero_crossing .eq. 1 .and. pi_crossing .eq. 1) then
671 
672  !***
673  !*** We have a polar cell
674  !***
675 
676  if (grid1_center_lat(grid1_add) .gt. 0) then
677  grid1_npole_cell = grid1_add
678  else if (grid1_center_lat(grid1_add) .lt. 0) then
679  grid1_spole_cell = grid1_add
680  endif
681 
682  if (grid1_npole_cell .ne. 0 .and.
683  & grid1_spole_cell .ne. 0) then
684  exit
685  endif
686 
687  endif
688 
689  enddo
690 
691 
692 
693  grid2_npole_cell = 0
694  grid2_spole_cell = 0
695 
696  do grid2_add = 1, grid2_size
697 
698  found = .false.
699  do corner = 1, grid2_corners
700  endlat = grid2_corner_lat(corner,grid2_add)
701  if (abs(abs(endlat)-pih) .lt. 1e-5) then
702  found = .true. ! cell has polar pnt; so pole is
703  ! not in the interior of the cell
704  exit
705  endif
706  enddo
707 
708  if (found) cycle
709 
710  beglon = grid2_corner_lon(1,grid2_add)
711  zero_crossing = 0
712  pi_crossing = 0
713 
714  do corner = 1, grid2_corners
715  next_corn = mod(corner,grid2_corners) + 1
716  endlon = grid2_corner_lon(next_corn,grid2_add)
717 
718  if (abs(beglon-endlon) > pi) then
719  zero_crossing = 1
720  else
721  if ((beglon .lt. pi .and. endlon .ge. pi) .or.
722  & (endlon .lt. pi .and. beglon .ge. pi)) then
723  pi_crossing = 1
724  endif
725  endif
726 
727  beglon = endlon
728  enddo
729 
730  if (zero_crossing .eq. 1 .and. pi_crossing .eq. 1) then
731 
732  !***
733  !*** We have a polar cell
734  !***
735 
736  if (grid2_center_lat(grid2_add) .gt. 0) then
737  grid2_npole_cell = grid2_add
738  else if (grid2_center_lat(grid2_add) .lt. 0) then
739  grid2_spole_cell = grid2_add
740  endif
741 
742  if (grid2_npole_cell .ne. 0 .and.
743  & grid2_spole_cell .ne. 0) then
744  exit
745  endif
746 
747  endif
748 
749  enddo
750 
751 
752  special_polar_cell1 = .false.
753  do grid1_add = 1, grid1_size
754 
755  ncorners_at_pole = 0
756  do i = 1, grid1_corners
757  beglat = grid1_corner_lat(i,grid1_add)
758  if (abs(abs(beglat)-pih) .le. 1.e-5)
759  & ncorners_at_pole = ncorners_at_pole + 1
760  enddo
761 
762  if (ncorners_at_pole .eq. 1)
763  & special_polar_cell1(grid1_add) = .true.
764 
765  enddo
766 
767  special_polar_cell2 = .false.
768  do grid2_add = 1, grid2_size
769 
770  ncorners_at_pole = 0
771  do i = 1, grid2_corners
772  beglat = grid2_corner_lat(i,grid2_add)
773  if (abs(abs(beglat)-pih) .le. 1.e-5)
774  & ncorners_at_pole = ncorners_at_pole + 1
775  enddo
776 
777  if (ncorners_at_pole .eq. 1)
778  & special_polar_cell2(grid2_add) = .true.
779 
780  enddo
781 
782  if(l_master)print *, ' '
783  if(l_master)print *, 'Grid 1 size', grid1_size
784  if(l_master)print *, 'Grid 2 size', grid2_size
785 
786 
787 ! if(l_master)print *, 'grid1_npole_cell',grid1_npole_cell
788  if (grid1_npole_cell .gt. 0) then
789  do i = 1, grid1_corners
792  enddo
793  endif
794 ! if(l_master)print *, 'grid1_spole_cell',grid1_spole_cell
795  if (grid1_spole_cell .gt. 0) then
796  do i = 1, grid1_corners
799  enddo
800  endif
801 ! if(l_master)print *, 'grid2_npole_cell',grid2_npole_cell
802  if (grid2_npole_cell .gt. 0) then
803  do i = 1, grid2_corners
806  enddo
807  endif
808 ! if(l_master)print *, 'grid2_spole_cell',grid2_spole_cell
809  if (grid2_spole_cell .gt. 0) then
810  do i = 1, grid2_corners
813  enddo
814  endif
815  if(l_master)print *
816 
817 
818 !-----------------------------------------------------------------------
819 !
820 ! set up and assign address ranges to search bins in order to
821 ! further restrict later searches
822 !
823 !-----------------------------------------------------------------------
824 
825  select case (restrict_type)
826 
827  case ('latitude')
828  if(l_master.and.l_test)write(scrip_stdout,*)
829  & 'Using latitude bins to restrict search.'
830 
831  allocate(bin_addr1(2,num_srch_bins))
832  allocate(bin_addr2(2,num_srch_bins))
833  allocate(bin_lats(2,num_srch_bins))
834  allocate(bin_lons(2,num_srch_bins))
835 
836  dlat = pi/num_srch_bins
837 
838  do n=1,num_srch_bins
839  bin_lats(1,n) = (n-1)*dlat - pih
840  bin_lats(2,n) = n*dlat - pih
841  bin_lons(1,n) = zero
842  bin_lons(2,n) = pi2
843  bin_addr1(1,n) = grid1_size + 1
844  bin_addr1(2,n) = 0
845  bin_addr2(1,n) = grid2_size + 1
846  bin_addr2(2,n) = 0
847  end do
848 
849  do nele=1,grid1_size
850  do n=1,num_srch_bins
851  if (grid1_bound_box(1,nele) <= bin_lats(2,n) .and.
852  & grid1_bound_box(2,nele) >= bin_lats(1,n)) then
853  bin_addr1(1,n) = min(nele,bin_addr1(1,n))
854  bin_addr1(2,n) = max(nele,bin_addr1(2,n))
855  endif
856  end do
857  end do
858 
859  do nele=1,grid2_size
860  do n=1,num_srch_bins
861  if (grid2_bound_box(1,nele) <= bin_lats(2,n) .and.
862  & grid2_bound_box(2,nele) >= bin_lats(1,n)) then
863  bin_addr2(1,n) = min(nele,bin_addr2(1,n))
864  bin_addr2(2,n) = max(nele,bin_addr2(2,n))
865  endif
866  end do
867  end do
868 
869  case ('latlon')
870  if(l_master.and.l_test)write(scrip_stdout,*)
871  & 'Using lat/lon boxes to restrict search.'
872 
873  dlat = pi /num_srch_bins
874  dlon = pi2/num_srch_bins
875 
880 
881  n = 0
882  do j=1,num_srch_bins
883  do i=1,num_srch_bins
884  n = n + 1
885 
886  bin_lats(1,n) = (j-1)*dlat - pih
887  bin_lats(2,n) = j*dlat - pih
888  bin_lons(1,n) = (i-1)*dlon
889  bin_lons(2,n) = i*dlon
890  bin_addr1(1,n) = grid1_size + 1
891  bin_addr1(2,n) = 0
892  bin_addr2(1,n) = grid2_size + 1
893  bin_addr2(2,n) = 0
894  end do
895  end do
896 
898 
899  do nele=1,grid1_size
900  do n=1,num_srch_bins
901  if (grid1_bound_box(1,nele) <= bin_lats(2,n) .and.
902  & grid1_bound_box(2,nele) >= bin_lats(1,n) .and.
903  & grid1_bound_box(3,nele) <= bin_lons(2,n) .and.
904  & grid1_bound_box(4,nele) >= bin_lons(1,n)) then
905  bin_addr1(1,n) = min(nele,bin_addr1(1,n))
906  bin_addr1(2,n) = max(nele,bin_addr1(2,n))
907  endif
908  end do
909  end do
910 
911  do nele=1,grid2_size
912  do n=1,num_srch_bins
913  if (grid2_bound_box(1,nele) <= bin_lats(2,n) .and.
914  & grid2_bound_box(2,nele) >= bin_lats(1,n) .and.
915  & grid2_bound_box(3,nele) <= bin_lons(2,n) .and.
916  & grid2_bound_box(4,nele) >= bin_lons(1,n)) then
917  bin_addr2(1,n) = min(nele,bin_addr2(1,n))
918  bin_addr2(2,n) = max(nele,bin_addr2(2,n))
919  endif
920  end do
921  end do
922 
923  case default
924  stop 'unknown search restriction method'
925  end select
926 
927 !-----------------------------------------------------------------------
928 !
929 ! if area not read in, compute an area
930 !
931 !-----------------------------------------------------------------------
932 
933  if (.not. luse_grid1_area) then
935  & grid1_corner_lon, errorcode)
936 
937  if (scrip_errorcheck(errorcode, rtnname,
938  & 'error computing grid1 area')) return
939  endif
940 
941  if (.not. luse_grid2_area) then
943  & grid2_corner_lon, errorcode)
944 
945  if (scrip_errorcheck(errorcode, rtnname,
946  & 'error computing grid2 area')) return
947  endif
948 
949 !-----------------------------------------------------------------------
950 
951  end subroutine grid_init
952 
953 !***********************************************************************
954 !BOP
955 ! !IROUTINE: SCRIP_GridComputeArea -- computes grid cell areas
956 ! !INTERFACE:
957 
958  subroutine scrip_gridcomputearea(area, cornerLat, cornerLon,
959  & errorCode)
960 
961 ! !DESCRIPTION:
962 ! This routine computes a grid cell area based on corner lat/lon
963 ! coordinates. It is provided in the case that a user supplied
964 ! area is not available.
965 !
966 ! !REVISION HISTORY:
967 ! same as module
968 
969 ! !OUTPUT PARAMETERS:
970 
971  real (SCRIP_r8), dimension(:), intent(out) ::
972  & area ! computed area for each grid cell
973 
974  integer (SCRIP_i4), intent(out) ::
975  & errorcode ! returned error code
976 
977 ! !INPUT PARAMETERS:
978 
979  real (SCRIP_r8), dimension(:,:), intent(in) ::
980  & cornerlat, ! latitude of each cell corner
981  & cornerlon ! longitude of each cell corner
982 
983 !EOP
984 !BOC
985 !-----------------------------------------------------------------------
986 !
987 ! local variables
988 !
989 !-----------------------------------------------------------------------
990 
991  integer (SCRIP_i4) ::
992  & numcells, ! number of grid cells
993  & numcorners, ! number of corners in each cell
994  & ncell, ! loop index for grid cells
995  & ncorner, ! loop index for corners in each cell
996  & nextcorner ! next corner around cell perimeter
997 
998  real (SCRIP_r8) ::
999  & dphi ! delta(longitude) for this segment
1000 
1001 !-----------------------------------------------------------------------
1002 !
1003 ! determine size of grid and initialize
1004 !
1005 !-----------------------------------------------------------------------
1006 
1007  errorcode = scrip_success
1008 
1009  numcells = size(cornerlat, dim=2)
1010  numcorners = size(cornerlat, dim=1)
1011 
1012 !-----------------------------------------------------------------------
1013 !
1014 ! compute area for each cell by integrating around cell edge
1015 !
1016 !-----------------------------------------------------------------------
1017 
1018  do ncell=1,numcells
1019 
1020  area(ncell) = 0.0_scrip_r8
1021 
1022  do ncorner=1,numcorners
1023  nextcorner = mod(ncorner,numcorners) + 1
1024 
1025  !*** trapezoid rule - delta(Lon) is -0.5*dx
1026  dphi = cornerlon( ncorner,ncell) -
1027  & cornerlon(nextcorner,ncell)
1028  if (dphi > pi) then
1029  dphi = dphi - pi2
1030  else if (dphi < -pi) then
1031  dphi = dphi + pi2
1032  endif
1033  dphi = 0.5_scrip_r8*dphi
1034 
1035  area(ncell) = area(ncell) +
1036  & dphi*(sin(cornerlat( ncorner,ncell)) +
1037  & sin(cornerlat(nextcorner,ncell)))
1038  end do
1039 
1040  end do
1041 
1042 !-----------------------------------------------------------------------
1043 !EOC
1044 
1045  end subroutine scrip_gridcomputearea
1046 
1047 !***********************************************************************
1048 
1049  end module scrip_grids
1050 
1051 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
scrip_grids::grid2_centroid_lat
real(scrip_r8), dimension(:), allocatable, target, save grid2_centroid_lat
Definition: scrip_grids.f:103
scrip_grids::grid1_corners
integer(scrip_i4), save grid1_corners
Definition: scrip_grids.f:68
scrip_grids::grid1_mask
logical(scrip_logical), dimension(:), allocatable, target, save grid1_mask
Definition: scrip_grids.f:93
scrip_grids::grid1_centroid_lat
real(scrip_r8), dimension(:), allocatable, target, save grid1_centroid_lat
Definition: scrip_grids.f:103
scrip_grids::grid1_spole_cell
integer(scrip_i4), save grid1_spole_cell
Definition: scrip_grids.f:135
scrip_grids::grid2_units
character(scrip_charlength), save grid2_units
Definition: scrip_grids.f:80
scrip_grids::luse_grid2_area
logical(scrip_logical), save luse_grid2_area
Definition: scrip_grids.f:126
scrip_grids::grid2_centroid_lon
real(scrip_r8), dimension(:), allocatable, target, save grid2_centroid_lon
Definition: scrip_grids.f:103
scrip_grids::num_srch_bins
integer(scrip_i4), save num_srch_bins
Definition: scrip_grids.f:152
scrip_grids::grid2_rank
integer(scrip_i4), save grid2_rank
Definition: scrip_grids.f:68
scrip_grids::grid2_mask
logical(scrip_logical), dimension(:), allocatable, target, save grid2_mask
Definition: scrip_grids.f:93
scrip_grids::grid2_center_lat
real(scrip_r8), dimension(:), allocatable, target, save grid2_center_lat
Definition: scrip_grids.f:103
scrip_constants::pi2
real(kind=scrip_r8), parameter pi2
Definition: scrip_constants.f:50
scrip_grids::bin_lats
real(scrip_r8), dimension(:,:), allocatable, save bin_lats
Definition: scrip_grids.f:159
scrip_grids::deg2rad
real(scrip_r8), parameter deg2rad
Definition: scrip_grids.f:84
scrip_grids::grid1_rank
integer(scrip_i4), save grid1_rank
Definition: scrip_grids.f:68
scrip_grids::grid1_area
real(scrip_r8), dimension(:), allocatable, target, save grid1_area
Definition: scrip_grids.f:103
scrip_grids::north_thresh
real(scrip_r8), save north_thresh
Definition: scrip_grids.f:169
scrip_grids::grid1_npole_cell
integer(scrip_i4), save grid1_npole_cell
Definition: scrip_grids.f:135
scrip_grids::luse_grid_centers
logical(scrip_logical), save luse_grid_centers
Definition: scrip_grids.f:126
scrip_grids
Definition: scrip_grids.f:49
scrip_grids::scrip_gridcomputearea
subroutine scrip_gridcomputearea(area, cornerLat, cornerLon, errorCode)
Definition: scrip_grids.f:960
scrip_grids::special_polar_cell2
logical(scrip_logical), dimension(:), allocatable, target, save special_polar_cell2
Definition: scrip_grids.f:93
scrip_grids::restrict_type
character(scrip_charlength), save restrict_type
Definition: scrip_grids.f:149
scrip_grids::grid2_corners
integer(scrip_i4), save grid2_corners
Definition: scrip_grids.f:68
scrip_grids::grid1_area_in
real(scrip_r8), dimension(:), allocatable, target, save grid1_area_in
Definition: scrip_grids.f:103
scrip_constants::zero
real(kind=scrip_r8), parameter zero
Definition: scrip_constants.f:50
scrip_kindsmod::scrip_r8
integer, parameter, public scrip_r8
Definition: scrip_kindsmod.f90:38
scrip_grids::grid2_imask
integer(scrip_i4), dimension(:), allocatable, target, save grid2_imask
Definition: scrip_grids.f:99
scrip_grids::grid1_centroid_lon
real(scrip_r8), dimension(:), allocatable, target, save grid1_centroid_lon
Definition: scrip_grids.f:103
scrip_grids::grid1_bound_box
real(scrip_r8), dimension(:,:), allocatable, target, save grid1_bound_box
Definition: scrip_grids.f:131
scrip_grids::bin_lons
real(scrip_r8), dimension(:,:), allocatable, save bin_lons
Definition: scrip_grids.f:159
scrip_grids::grid2_corner_lat
real(scrip_r8), dimension(:,:), allocatable, target, save grid2_corner_lat
Definition: scrip_grids.f:120
scrip_grids::grid1_dims
integer(scrip_i4), dimension(:), allocatable, save grid1_dims
Definition: scrip_grids.f:74
scrip_grids::luse_grid1_area
logical(scrip_logical), save luse_grid1_area
Definition: scrip_grids.f:126
scrip_constants::pih
real(kind=scrip_r8), parameter pih
Definition: scrip_constants.f:50
scrip_grids::grid1_center_lon
real(scrip_r8), dimension(:), allocatable, target, save grid1_center_lon
Definition: scrip_grids.f:103
scrip_grids::grid2_npole_cell
integer(scrip_i4), save grid2_npole_cell
Definition: scrip_grids.f:135
scrip_grids::grid2_area
real(scrip_r8), dimension(:), allocatable, target, save grid2_area
Definition: scrip_grids.f:103
scrip_errormod::scrip_success
integer(scrip_i4), parameter, public scrip_success
Definition: scrip_errormod.f90:42
scrip_grids::grid1_corner_lat
real(scrip_r8), dimension(:,:), allocatable, target, save grid1_corner_lat
Definition: scrip_grids.f:120
scrip_grids::grid2_size
integer(scrip_i4), save grid2_size
Definition: scrip_grids.f:68
scrip_grids::grid1_name
character(scrip_charlength), save grid1_name
Definition: scrip_grids.f:77
scrip_grids::bin_addr2
integer(scrip_i4), dimension(:,:), allocatable, save bin_addr2
Definition: scrip_grids.f:155
scrip_grids::grid2_name
character(scrip_charlength), save grid2_name
Definition: scrip_grids.f:77
scrip_grids::grid_init
subroutine grid_init(errorCode, l_master, l_test)
Definition: scrip_grids.f:188
scrip_constants
Definition: scrip_constants.f:38
scrip_grids::grid2_area_in
real(scrip_r8), dimension(:), allocatable, target, save grid2_area_in
Definition: scrip_grids.f:103
scrip_grids::grid2_dims
integer(scrip_i4), dimension(:), allocatable, save grid2_dims
Definition: scrip_grids.f:74
scrip_grids::grid1_center_lat
real(scrip_r8), dimension(:), allocatable, target, save grid1_center_lat
Definition: scrip_grids.f:103
scrip_kindsmod
Definition: scrip_kindsmod.f90:3
scrip_grids::grid1_corner_lon
real(scrip_r8), dimension(:,:), allocatable, target, save grid1_corner_lon
Definition: scrip_grids.f:120
scrip_grids::npseg
integer(scrip_i4), save npseg
Definition: scrip_grids.f:178
scrip_errormod
Definition: scrip_errormod.f90:3
scrip_grids::south_thresh
real(scrip_r8), save south_thresh
Definition: scrip_grids.f:169
scrip_grids::grid1_size
integer(scrip_i4), save grid1_size
Definition: scrip_grids.f:68
scrip_grids::grid2_bound_box
real(scrip_r8), dimension(:,:), allocatable, target, save grid2_bound_box
Definition: scrip_grids.f:131
scrip_grids::grid2_corner_lon
real(scrip_r8), dimension(:,:), allocatable, target, save grid2_corner_lon
Definition: scrip_grids.f:120
scrip_grids::grid1_frac
real(scrip_r8), dimension(:), allocatable, target, save grid1_frac
Definition: scrip_grids.f:103
scrip_grids::grid1_imask
integer(scrip_i4), dimension(:), allocatable, target, save grid1_imask
Definition: scrip_grids.f:99
scrip_grids::grid1_units
character(scrip_charlength), save grid1_units
Definition: scrip_grids.f:80
scrip_grids::grid2_spole_cell
integer(scrip_i4), save grid2_spole_cell
Definition: scrip_grids.f:135
scrip_iounitsmod
Definition: scrip_iounitsmod.f90:3
scrip_constants::pi
real(kind=scrip_r8), parameter pi
Definition: scrip_constants.f:50
scrip_iounitsmod::scrip_stdout
integer(scrip_i4), parameter, public scrip_stdout
Definition: scrip_iounitsmod.f90:47
scrip_grids::special_polar_cell1
logical(scrip_logical), dimension(:), allocatable, target, save special_polar_cell1
Definition: scrip_grids.f:93
scrip_grids::grid2_frac
real(scrip_r8), dimension(:), allocatable, target, save grid2_frac
Definition: scrip_grids.f:103
scrip_errormod::scrip_errorcheck
logical(scrip_logical) function, public scrip_errorcheck(errorCode, rtnName, errorMsg)
Definition: scrip_errormod.f90:143
scrip_grids::bin_addr1
integer(scrip_i4), dimension(:,:), allocatable, save bin_addr1
Definition: scrip_grids.f:155
scrip_grids::grid2_center_lon
real(scrip_r8), dimension(:), allocatable, target, save grid2_center_lon
Definition: scrip_grids.f:103