Oasis3 4.0.2
grids.f
Go to the documentation of this file.
00001 C****
00002 C                    ************************
00003 C                    *     OASIS MODULE     *
00004 C                    *     ------------     *
00005 C                    ************************
00006 C****
00007 C***********************************************************************
00008 C     This module belongs to the SCRIP library. It is modified to run
00009 C     within OASIS. 
00010 C     Modifications:
00011 C       - routine does not read SCRIP grid description files, but gets 
00012 C         arrays from the calling routine
00013 C       - unit conversion : only from degrees (OASIS unit) to radians
00014 C       - some allocated array will be freed in the end to allow multiple
00015 C         calls of SCRIP
00016 C       - map-methods and restriction-types are written in capital letters
00017 C       - added bin definition for reduced grid
00018 C
00019 C     Modified by            V. Gayler,  M&D                  20.09.2001
00020 C     Modified by            D. Declat,  CERFACS              27.06.2002
00021 C***********************************************************************
00022 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
00023 !
00024 !     This module reads in and initializes two grids for remapping.
00025 !     NOTE: grid1 must be the master grid -- the grid that determines
00026 !           which cells participate (e.g. land mask) and the fractional
00027 !           area of grid2 cells that participate in the remapping.
00028 !
00029 !-----------------------------------------------------------------------
00030 !
00031 !     CVS:$Id: grids.f 2826 2010-12-10 11:14:21Z valcke $
00032 !
00033 !     Copyright (c) 1997, 1998 the Regents of the University of 
00034 !       California.
00035 !
00036 !     This software and ancillary information (herein called software) 
00037 !     called SCRIP is made available under the terms described here.  
00038 !     The software has been approved for release with associated 
00039 !     LA-CC Number 98-45.
00040 !
00041 !     Unless otherwise indicated, this software has been authored
00042 !     by an employee or employees of the University of California,
00043 !     operator of the Los Alamos National Laboratory under Contract
00044 !     No. W-7405-ENG-36 with the U.S. Department of Energy.  The U.S.
00045 !     Government has rights to use, reproduce, and distribute this
00046 !     software.  The public may copy and use this software without
00047 !     charge, provided that this Notice and any statement of authorship
00048 !     are reproduced on all copies.  Neither the Government nor the
00049 !     University makes any warranty, express or implied, or assumes
00050 !     any liability or responsibility for the use of this software.
00051 !
00052 !     If software is modified to produce derivative works, such modified
00053 !     software should be clearly marked, so as not to confuse it with 
00054 !     the version available from Los Alamos National Laboratory.
00055 !
00056 !***********************************************************************
00057 
00058       module grids
00059 
00060 !-----------------------------------------------------------------------
00061 
00062       use kinds_mod    ! defines data types
00063       use constants    ! common constants
00064       use iounits      ! I/O unit manager
00065       USE mod_unit
00066       USE mod_printing
00067 
00068       implicit none
00069 
00070 !-----------------------------------------------------------------------
00071 !
00072 !     variables that describe each grid
00073 !
00074 !-----------------------------------------------------------------------
00075 
00076       integer (kind=int_kind), save ::
00077      &             grid1_size, grid2_size, ! total points on each grid
00078      &             grid1_rank, grid2_rank, ! rank of each grid
00079      &             grid1_corners, grid2_corners ! number of corners
00080                                                 ! for each grid cell
00081 
00082       integer (kind=int_kind), dimension(:), allocatable, save ::
00083      &             grid1_dims, grid2_dims  ! size of each grid dimension
00084 
00085       character(char_len), save :: 
00086      &             grid1_name, grid2_name  ! name for each grid
00087 
00088       character (char_len), save :: 
00089      &             grid1_units, ! units for grid coords (degs/radians)
00090      &             grid2_units  ! units for grid coords
00091 
00092       real (kind=dbl_kind), parameter ::
00093      &      deg2rad = pi/180.   ! conversion for deg to rads
00094 
00095 !-----------------------------------------------------------------------
00096 !
00097 !     grid coordinates and masks
00098 !
00099 !-----------------------------------------------------------------------
00100 
00101       logical (kind=log_kind), dimension(:), allocatable, save ::
00102      &             grid1_mask,        ! flag which cells participate
00103      &             grid2_mask         ! flag which cells participate
00104 
00105       real (kind=dbl_kind), dimension(:), allocatable, save ::
00106      &             grid1_center_lat,  ! lat/lon coordinates for
00107      &             grid1_center_lon,  ! each grid center in radians
00108      &             grid2_center_lat, 
00109      &             grid2_center_lon,
00110      &             grid1_area,        ! tot area of each grid1 cell
00111      &             grid2_area,        ! tot area of each grid2 cell
00112      &             grid1_area_in,     ! area of grid1 cell from file
00113      &             grid2_area_in,     ! area of grid2 cell from file
00114      &             grid1_frac,        ! fractional area of grid cells
00115      &             grid2_frac         ! participating in remapping
00116 
00117       real (kind=dbl_kind), dimension(:,:), allocatable, save ::
00118      &             grid1_corner_lat,  ! lat/lon coordinates for
00119      &             grid1_corner_lon,  ! each grid corner in radians
00120      &             grid2_corner_lat, 
00121      &             grid2_corner_lon
00122 
00123       logical (kind=log_kind), save ::
00124      &             luse_grid_centers ! use centers for bounding boxes
00125      &,            luse_grid1_area   ! use area from grid file
00126      &,            luse_grid2_area   ! use area from grid file
00127 
00128       real (kind=dbl_kind), dimension(:,:), allocatable, save ::
00129      &             grid1_bound_box,  ! lat/lon bounding box for use
00130      &             grid2_bound_box   ! in restricting grid searches
00131 
00132 !-----------------------------------------------------------------------
00133 !
00134 !     bins for restricting searches
00135 !
00136 !-----------------------------------------------------------------------
00137 
00138       character (char_len), save ::
00139      &        restrict_type  ! type of bins to use
00140 
00141       integer (kind=int_kind), save ::
00142      &        num_srch_bins,  ! num of bins for restricted srch
00143      &        num_srch_red    ! num of bins for reduced case
00144 
00145       integer (kind=int_kind), dimension(:,:), allocatable, save ::
00146      &        bin_addr1, ! min,max adds for grid1 cells in this lat bin
00147      &        bin_addr2  ! min,max adds for grid2 cells in this lat bin
00148       integer (kind=int_kind), dimension(:,:), allocatable, save ::
00149      &        bin_addr1_r  ! min,max adds for red grid1 cells
00150 
00151       real(kind=dbl_kind), dimension(:,:), allocatable, save ::
00152      &        bin_lats   ! min,max latitude for each search bin
00153      &,       bin_lons   ! min,max longitude for each search bin
00154       real(kind=dbl_kind), dimension(:,:), allocatable, save ::
00155      &        bin_lats_r ! min,max lat for each search bin for red grid
00156      &,       bin_lons_r ! min,max lon for each search bin for red grid
00157 
00158 !***********************************************************************
00159 
00160       contains
00161 
00162 !***********************************************************************
00163 
00164       subroutine grid_init(m_method, rst_type, n_srch_bins,
00165      $                     src_size, dst_size, src_dims, dst_dims, 
00166      &                     src_rank, dst_rank, ncrn_src, ncrn_dst,
00167      &                     src_mask, dst_mask, src_name, dst_name,
00168      &                     src_lat,  src_lon,  dst_lat,  dst_lon,
00169      &                     src_corner_lat, src_corner_lon,
00170      &                     dst_corner_lat, dst_corner_lon)
00171 
00172 !-----------------------------------------------------------------------
00173 !
00174 !     this routine gets grid info from routine scriprmp and makes any
00175 !     necessary changes (e.g. for 0,2pi longitude range)
00176 !
00177 !-----------------------------------------------------------------------
00178 
00179 !-----------------------------------------------------------------------
00180 !
00181 !     input variables
00182 !
00183 !-----------------------------------------------------------------------
00184 
00185       integer (kind=int_kind), intent(in) ::
00186      &     n_srch_bins,         ! num of bins for restricted srch
00187      &     src_size,            ! source grid size
00188      &     dst_size,            ! target grid size
00189      &     src_rank,            ! source grid rank
00190      &     dst_rank,            ! target grid rank
00191      &     src_dims(src_rank),  ! source grid dimensions
00192      &     dst_dims(dst_rank),  ! target grid dimensions
00193      &     ncrn_src,            ! number of corners of a source grid cell
00194      &     ncrn_dst,            ! number of corners of a target grid cell
00195      &     src_mask(src_size),  ! source grid mask (master mask)
00196      &     dst_mask(dst_size)   ! target grid mask 
00197 
00198       character*8, intent(in) ::
00199      &     m_method,            ! remapping method
00200      &     rst_type,            ! restriction type
00201      &     src_name,            ! source grid name
00202      &     dst_name             ! target grid name
00203 
00204       real (kind=real_kind), intent (in) ::
00205      &     src_lat(src_size), ! source grid latitudes
00206      &     src_lon(src_size), ! sourde grid longitudes
00207      &     dst_lat(dst_size),   ! target grid latitudes
00208      &     dst_lon(dst_size),   ! target grid longitudes
00209      &     src_corner_lat(ncrn_src,src_size), 
00210      &     src_corner_lon(ncrn_src,src_size), 
00211      &     dst_corner_lat(ncrn_dst,dst_size), 
00212      &     dst_corner_lon(ncrn_dst,dst_size) 
00213 
00214 !-----------------------------------------------------------------------
00215 !
00216 !     local variables
00217 !
00218 !-----------------------------------------------------------------------
00219 
00220       integer (kind=int_kind) :: 
00221      &  n      ! loop counter
00222      &, nele   ! element loop counter
00223      &, i,j    ! logical 2d addresses
00224      &, ip1,jp1
00225      &, n_add, e_add, ne_add
00226      &, nx, ny
00227 
00228       real (kind=dbl_kind) :: 
00229      &  dlat, dlon          ! lat/lon intervals for search bins
00230 
00231       real (kind=dbl_kind), dimension(4) ::
00232      &  tmp_lats, tmp_lons  ! temps for computing bounding boxes
00233 !
00234 !-----------------------------------------------------------------------
00235 !
00236       IF (nlogprt .GE. 2) THEN
00237          WRITE (UNIT = nulou,FMT = *)' '
00238          WRITE (UNIT = nulou,FMT = *)'Entering routine grid_init'
00239          WRITE (UNIT = nulou,FMT = *)' '
00240          CALL FLUSH(nulou)
00241       ENDIF
00242 !
00243 !-----------------------------------------------------------------------
00244 !
00245 !     allocate grid coordinates/masks and read data
00246 !
00247 !-----------------------------------------------------------------------
00248       
00249       select case(m_method)
00250       case ('CONSERV')
00251         luse_grid_centers = .false.
00252       case ('BILINEAR')
00253         luse_grid_centers = .true.
00254       case ('BICUBIC')
00255         luse_grid_centers = .true.
00256       case ('DISTWGT')
00257         luse_grid_centers = .true.
00258       case ('GAUSWGT')
00259         luse_grid_centers = .true.
00260       case default
00261         stop 'unknown mapping method'
00262       end select
00263 
00264       allocate( grid1_mask      (src_size),
00265      &          grid2_mask      (dst_size),
00266      &          grid1_center_lat(src_size), 
00267      &          grid1_center_lon(src_size),
00268      &          grid2_center_lat(dst_size), 
00269      &          grid2_center_lon(dst_size),
00270      &          grid1_area      (src_size),
00271      &          grid2_area      (dst_size),
00272      &          grid1_frac      (src_size),
00273      &          grid2_frac      (dst_size),
00274      &          grid1_dims      (src_rank),
00275      &          grid2_dims      (dst_rank),
00276      &          grid1_bound_box (4       , src_size),
00277      &          grid2_bound_box (4       , dst_size))
00278 
00279       if (.not. luse_grid_centers) then
00280         allocate( grid1_corner_lat(ncrn_src, src_size),
00281      &            grid1_corner_lon(ncrn_src, src_size),
00282      &            grid2_corner_lat(ncrn_dst, dst_size),
00283      &            grid2_corner_lon(ncrn_dst, dst_size))
00284       endif
00285 
00286 !-----------------------------------------------------------------------
00287 !
00288 !     copy input data to module data
00289 !
00290 !-----------------------------------------------------------------------
00291       
00292       restrict_type    = rst_type
00293       num_srch_bins    = n_srch_bins
00294       grid1_size       = src_size
00295       grid2_size       = dst_size
00296       grid1_dims       = src_dims
00297       grid2_dims       = dst_dims 
00298       grid1_rank       = src_rank
00299       grid2_rank       = dst_rank
00300       grid1_corners    = ncrn_src
00301       grid2_corners    = ncrn_dst
00302       grid1_name       = src_name
00303       grid2_name       = dst_name
00304       grid1_center_lat = src_lat
00305       grid1_center_lon = src_lon
00306       grid2_center_lat = dst_lat
00307       grid2_center_lon = dst_lon
00308 
00309       if (.not. luse_grid_centers) then
00310         grid1_corner_lat = src_corner_lat
00311         grid1_corner_lon = src_corner_lon
00312         grid2_corner_lat = dst_corner_lat
00313         grid2_corner_lon = dst_corner_lon
00314       endif
00315 
00316 c      if (luse_grid1_area) then
00317 c        grid1_area_in
00318 c      endif
00319 c      if (luse_grid2_area) then
00320 c        grid2_area_in
00321 c      endif
00322 
00323       grid1_area = zero
00324       grid1_frac = zero
00325       grid2_area = zero
00326       grid2_frac = zero
00327 
00328 
00329 !-----------------------------------------------------------------------
00330 !
00331 !     initialize logical mask and convert lat/lon units if required
00332 !
00333 !-----------------------------------------------------------------------
00334       where (src_mask == 1)
00335         grid1_mask = .true.
00336       elsewhere
00337         grid1_mask = .false.
00338       endwhere
00339 
00340       where (dst_mask == 1)
00341         grid2_mask = .true.
00342       elsewhere
00343         grid2_mask = .false.
00344       endwhere
00345 
00346 C
00347 C* -- convert unit from degrees (OASIS unit) to radians
00348 C
00349       grid1_center_lat = grid1_center_lat*deg2rad
00350       grid1_center_lon = grid1_center_lon*deg2rad
00351       grid2_center_lat = grid2_center_lat*deg2rad
00352       grid2_center_lon = grid2_center_lon*deg2rad
00353 
00354       if (.not. luse_grid_centers) then
00355         grid1_corner_lat = grid1_corner_lat*deg2rad
00356         grid1_corner_lon = grid1_corner_lon*deg2rad
00357         grid2_corner_lat = grid2_corner_lat*deg2rad
00358         grid2_corner_lon = grid2_corner_lon*deg2rad
00359       endif
00360 
00361       grid1_units='radians'
00362       grid2_units='radians'
00363 !-----------------------------------------------------------------------
00364 !
00365 !     convert longitudes to 0,2pi interval
00366 !
00367 !-----------------------------------------------------------------------
00368 
00369       where (grid1_center_lon .gt. pi2)  grid1_center_lon =
00370      &                                   grid1_center_lon - pi2
00371       where (grid1_center_lon .lt. zero) grid1_center_lon =
00372      &                                   grid1_center_lon + pi2
00373       where (grid2_center_lon .gt. pi2)  grid2_center_lon =
00374      &                                   grid2_center_lon - pi2
00375       where (grid2_center_lon .lt. zero) grid2_center_lon =
00376      &                                   grid2_center_lon + pi2
00377 
00378       if (.not. luse_grid_centers) then
00379         where (grid1_corner_lon .gt. pi2)  grid1_corner_lon =
00380      &                                     grid1_corner_lon - pi2
00381         where (grid1_corner_lon .lt. zero) grid1_corner_lon =
00382      &                                     grid1_corner_lon + pi2
00383         where (grid2_corner_lon .gt. pi2)  grid2_corner_lon =
00384      &                                     grid2_corner_lon - pi2
00385         where (grid2_corner_lon .lt. zero) grid2_corner_lon =
00386      &                                     grid2_corner_lon + pi2
00387       endif
00388 !-----------------------------------------------------------------------
00389 !
00390 !     make sure input latitude range is within the machine values
00391 !     for +/- pi/2 
00392 !
00393 !-----------------------------------------------------------------------
00394 
00395       where (grid1_center_lat >  pih) grid1_center_lat =  pih
00396       where (grid1_center_lat < -pih) grid1_center_lat = -pih
00397       where (grid2_center_lat >  pih) grid2_center_lat =  pih
00398       where (grid2_center_lat < -pih) grid2_center_lat = -pih
00399 
00400       if (.not. luse_grid_centers) then
00401         where (grid1_corner_lat >  pih) grid1_corner_lat =  pih
00402         where (grid1_corner_lat < -pih) grid1_corner_lat = -pih
00403         where (grid2_corner_lat >  pih) grid2_corner_lat =  pih
00404         where (grid2_corner_lat < -pih) grid2_corner_lat = -pih
00405       endif
00406 
00407 !-----------------------------------------------------------------------
00408 !
00409 !     compute bounding boxes for restricting future grid searches
00410 !
00411 !-----------------------------------------------------------------------
00412 
00413       if (.not. luse_grid_centers) then
00414 
00415         grid1_bound_box(1,:) = minval(grid1_corner_lat, DIM=1)
00416         grid1_bound_box(2,:) = maxval(grid1_corner_lat, DIM=1)
00417         grid1_bound_box(3,:) = minval(grid1_corner_lon, DIM=1)
00418         grid1_bound_box(4,:) = maxval(grid1_corner_lon, DIM=1)
00419 
00420         grid2_bound_box(1,:) = minval(grid2_corner_lat, DIM=1)
00421         grid2_bound_box(2,:) = maxval(grid2_corner_lat, DIM=1)
00422         grid2_bound_box(3,:) = minval(grid2_corner_lon, DIM=1)
00423         grid2_bound_box(4,:) = maxval(grid2_corner_lon, DIM=1)
00424       else
00425 
00426         nx = grid1_dims(1)
00427         ny = grid1_dims(2)
00428 
00429         do n=1,grid1_size
00430 
00431           !*** find N,S and NE points to this grid point
00432 
00433           j = (n - 1)/nx +1
00434           i = n - (j-1)*nx
00435 
00436           if (i < nx) then
00437             ip1 = i + 1
00438           else
00439             !*** assume cyclic
00440             ip1 = 1
00441             !*** but if it is not, correct
00442             e_add = (j - 1)*nx + ip1
00443             if (abs(grid1_center_lat(e_add) - 
00444      &              grid1_center_lat(n   )) > pih) then
00445               ip1 = i
00446             endif
00447           endif
00448 
00449           if (j < ny) then
00450             jp1 = j+1
00451           else
00452             !*** assume cyclic
00453             jp1 = 1
00454             !*** but if it is not, correct
00455             n_add = (jp1 - 1)*nx + i
00456             if (abs(grid1_center_lat(n_add) - 
00457      &              grid1_center_lat(n   )) > pih) then
00458               jp1 = j
00459             endif
00460           endif
00461 
00462           n_add = (jp1 - 1)*nx + i
00463           e_add = (j - 1)*nx + ip1
00464           ne_add = (jp1 - 1)*nx + ip1
00465 
00466           !*** find N,S and NE lat/lon coords and check bounding box
00467 
00468           tmp_lats(1) = grid1_center_lat(n)
00469           tmp_lats(2) = grid1_center_lat(e_add)
00470           tmp_lats(3) = grid1_center_lat(ne_add)
00471           tmp_lats(4) = grid1_center_lat(n_add)
00472 
00473           tmp_lons(1) = grid1_center_lon(n)
00474           tmp_lons(2) = grid1_center_lon(e_add)
00475           tmp_lons(3) = grid1_center_lon(ne_add)
00476           tmp_lons(4) = grid1_center_lon(n_add)
00477 
00478           grid1_bound_box(1,n) = minval(tmp_lats)
00479           grid1_bound_box(2,n) = maxval(tmp_lats)
00480           grid1_bound_box(3,n) = minval(tmp_lons)
00481           grid1_bound_box(4,n) = maxval(tmp_lons)
00482         end do
00483 
00484         nx = grid2_dims(1)
00485         ny = grid2_dims(2)
00486 
00487         do n=1,grid2_size
00488 
00489           !*** find N,S and NE points to this grid point
00490 
00491           j = (n - 1)/nx +1
00492           i = n - (j-1)*nx
00493 
00494           if (i < nx) then
00495             ip1 = i + 1
00496           else
00497             !*** assume cyclic
00498             ip1 = 1
00499             !*** but if it is not, correct
00500             e_add = (j - 1)*nx + ip1
00501             if (abs(grid2_center_lat(e_add) - 
00502      &              grid2_center_lat(n   )) > pih) then
00503               ip1 = i
00504             endif
00505           endif
00506 
00507           if (j < ny) then
00508             jp1 = j+1
00509           else
00510             !*** assume cyclic
00511             jp1 = 1
00512             !*** but if it is not, correct
00513             n_add = (jp1 - 1)*nx + i
00514             if (abs(grid2_center_lat(n_add) - 
00515      &              grid2_center_lat(n   )) > pih) then
00516               jp1 = j
00517             endif
00518           endif
00519 
00520           n_add = (jp1 - 1)*nx + i
00521           e_add = (j - 1)*nx + ip1
00522           ne_add = (jp1 - 1)*nx + ip1
00523 
00524           !*** find N,S and NE lat/lon coords and check bounding box
00525 
00526           tmp_lats(1) = grid2_center_lat(n)
00527           tmp_lats(2) = grid2_center_lat(e_add)
00528           tmp_lats(3) = grid2_center_lat(ne_add)
00529           tmp_lats(4) = grid2_center_lat(n_add)
00530 
00531           tmp_lons(1) = grid2_center_lon(n)
00532           tmp_lons(2) = grid2_center_lon(e_add)
00533           tmp_lons(3) = grid2_center_lon(ne_add)
00534           tmp_lons(4) = grid2_center_lon(n_add)
00535 
00536           grid2_bound_box(1,n) = minval(tmp_lats)
00537           grid2_bound_box(2,n) = maxval(tmp_lats)
00538           grid2_bound_box(3,n) = minval(tmp_lons)
00539           grid2_bound_box(4,n) = maxval(tmp_lons)
00540         end do
00541 
00542       endif
00543 
00544       where (abs(grid1_bound_box(4,:) - grid1_bound_box(3,:)) > pi)
00545         grid1_bound_box(3,:) = zero
00546         grid1_bound_box(4,:) = pi2
00547       end where
00548 
00549       where (abs(grid2_bound_box(4,:) - grid2_bound_box(3,:)) > pi)
00550         grid2_bound_box(3,:) = zero
00551         grid2_bound_box(4,:) = pi2
00552       end where
00553 
00554       !***
00555       !*** try to check for cells that overlap poles
00556       !***
00557 
00558       where (grid1_center_lat > grid1_bound_box(2,:))
00559      &  grid1_bound_box(2,:) = pih
00560 
00561       where (grid1_center_lat < grid1_bound_box(1,:))
00562      &  grid1_bound_box(1,:) = -pih
00563 
00564       where (grid2_center_lat > grid2_bound_box(2,:))
00565      &  grid2_bound_box(2,:) = pih
00566 
00567       where (grid2_center_lat < grid2_bound_box(1,:))
00568      &  grid2_bound_box(1,:) = -pih
00569 
00570 !-----------------------------------------------------------------------
00571 !
00572 !     set up and assign address ranges to search bins in order to 
00573 !     further restrict later searches
00574 !
00575 !-----------------------------------------------------------------------
00576 
00577       select case (restrict_type)
00578 
00579       case ('LATITUDE')
00580         write(stdout,*) 'Using latitude bins to restrict search.'
00581 
00582         allocate(bin_addr1(2,num_srch_bins))
00583         allocate(bin_addr2(2,num_srch_bins))
00584         allocate(bin_lats (2,num_srch_bins))
00585         allocate(bin_lons (2,num_srch_bins))
00586 
00587         dlat = pi/num_srch_bins
00588 
00589         do n=1,num_srch_bins
00590           bin_lats(1,n) = (n-1)*dlat - pih
00591           bin_lats(2,n) =     n*dlat - pih
00592           bin_lons(1,n) = zero
00593           bin_lons(2,n) = pi2
00594           bin_addr1(1,n) = grid1_size + 1
00595           bin_addr1(2,n) = 0
00596           bin_addr2(1,n) = grid2_size + 1
00597           bin_addr2(2,n) = 0
00598         end do
00599 
00600         do nele=1,grid1_size
00601           do n=1,num_srch_bins
00602             if (grid1_bound_box(1,nele) <= bin_lats(2,n) .and.
00603      &          grid1_bound_box(2,nele) >= bin_lats(1,n)) then
00604               bin_addr1(1,n) = min(nele,bin_addr1(1,n))
00605               bin_addr1(2,n) = max(nele,bin_addr1(2,n))
00606             endif
00607           end do
00608         end do
00609 
00610         do nele=1,grid2_size
00611           do n=1,num_srch_bins
00612             if (grid2_bound_box(1,nele) <= bin_lats(2,n) .and.
00613      &          grid2_bound_box(2,nele) >= bin_lats(1,n)) then
00614               bin_addr2(1,n) = min(nele,bin_addr2(1,n))
00615               bin_addr2(2,n) = max(nele,bin_addr2(2,n))
00616             endif
00617           end do
00618         end do
00619 
00620       case ('LATLON')
00621         write(stdout,*) 'Using lat/lon boxes to restrict search.'
00622 
00623         dlat = pi /num_srch_bins
00624         dlon = pi2/num_srch_bins
00625 
00626         allocate(bin_addr1(2,num_srch_bins*num_srch_bins))
00627         allocate(bin_addr2(2,num_srch_bins*num_srch_bins))
00628         allocate(bin_lats (2,num_srch_bins*num_srch_bins))
00629         allocate(bin_lons (2,num_srch_bins*num_srch_bins))
00630 
00631         n = 0
00632         do j=1,num_srch_bins
00633           do i=1,num_srch_bins
00634             n = n + 1
00635             
00636             bin_lats(1,n) = (j-1)*dlat - pih
00637             bin_lats(2,n) =     j*dlat - pih
00638             bin_lons(1,n) = (i-1)*dlon
00639             bin_lons(2,n) =     i*dlon
00640             bin_addr1(1,n) = grid1_size + 1
00641             bin_addr1(2,n) = 0
00642             bin_addr2(1,n) = grid2_size + 1
00643             bin_addr2(2,n) = 0
00644           end do
00645         end do
00646         
00647         num_srch_bins = num_srch_bins**2
00648 
00649         do nele=1,grid1_size
00650           do n=1,num_srch_bins
00651             if (grid1_bound_box(1,nele) <= bin_lats(2,n) .and.
00652      &          grid1_bound_box(2,nele) >= bin_lats(1,n) .and.
00653      &          grid1_bound_box(3,nele) <= bin_lons(2,n) .and.
00654      &          grid1_bound_box(4,nele) >= bin_lons(1,n)) then
00655                 bin_addr1(1,n) = min(nele,bin_addr1(1,n))
00656                 bin_addr1(2,n) = max(nele,bin_addr1(2,n))
00657             endif
00658           end do
00659         end do
00660 
00661         do nele=1,grid2_size
00662           do n=1,num_srch_bins
00663             if (grid2_bound_box(1,nele) <= bin_lats(2,n) .and.
00664      &          grid2_bound_box(2,nele) >= bin_lats(1,n) .and.
00665      &          grid2_bound_box(3,nele) <= bin_lons(2,n) .and.
00666      &          grid2_bound_box(4,nele) >= bin_lons(1,n)) then
00667                 bin_addr2(1,n) = min(nele,bin_addr2(1,n))
00668                 bin_addr2(2,n) = max(nele,bin_addr2(2,n))
00669             endif
00670           end do
00671         end do
00672 
00673       case ('REDUCED')
00674         write(stdout,*) 
00675      &  '|  Using reduced bins to restrict search. Reduced grids with'
00676         write(stdout,*) 
00677      &  '| a maximum of 500*NBRBINS latitude circles can be treated'
00678 
00679         allocate(bin_addr2(2,num_srch_bins))
00680         allocate(bin_lats (2,num_srch_bins))
00681         allocate(bin_lons (2,num_srch_bins))
00682         allocate(bin_addr1_r(4,500*num_srch_bins))
00683         allocate(bin_lats_r (2,500*num_srch_bins))
00684         allocate(bin_lons_r (2,500*num_srch_bins))
00685 
00686         dlat = pi/num_srch_bins
00687 
00688         do n=1,num_srch_bins
00689           bin_lats(1,n) = (n-1)*dlat - pih
00690           bin_lats(2,n) =     n*dlat - pih
00691           bin_lons(1,n) = zero
00692           bin_lons(2,n) = pi2
00693           bin_addr2(1,n) = grid2_size + 1
00694           bin_addr2(2,n) = 0
00695         end do
00696 
00697         do nele=1,grid2_size
00698           do n=1,num_srch_bins
00699             if (grid2_bound_box(1,nele) <= bin_lats(2,n) .and.
00700      &          grid2_bound_box(2,nele) >= bin_lats(1,n)) then
00701               bin_addr2(1,n) = min(nele,bin_addr2(1,n))
00702               bin_addr2(2,n) = max(nele,bin_addr2(2,n))
00703             endif
00704           end do
00705         end DO
00706 
00707 
00708         bin_addr1_r(1,1) = 0
00709         bin_lats_r(1,1) = grid1_center_lat(1)
00710         num_srch_red = 1
00711         do nele=1,grid1_size-1
00712           if (grid1_center_lat(nele+1) ==  
00713      &        grid1_center_lat(nele)) THEN
00714               bin_addr1_r(2,num_srch_red) = nele+1
00715           else IF (grid1_center_lat(nele+1) /=  
00716      &        grid1_center_lat(nele)) THEN 
00717               bin_addr1_r(1,num_srch_red+1) = nele+1
00718               bin_lats_r(2,num_srch_red) = grid1_center_lat(nele+1)
00719               bin_lats_r(1,num_srch_red+1) = 
00720      &            bin_lats_r(2,num_srch_red)
00721               num_srch_red = num_srch_red+1
00722           ENDIF
00723         end DO
00724         
00725         DO nele = 1,num_srch_red-1
00726           bin_addr1_r(3,nele)=bin_addr1_r(1,nele+1)
00727           bin_addr1_r(4,nele)=bin_addr1_r(2,nele+1)
00728         enddo
00729         bin_addr1_r(3,num_srch_red) = bin_addr1_r(1,num_srch_red-1)
00730         bin_addr1_r(4,num_srch_red) = bin_addr1_r(2,num_srch_red-1)
00731 
00732       case default
00733         stop 'unknown search restriction method'
00734       end select
00735 !
00736       IF (nlogprt .GE. 2) THEN
00737          WRITE (UNIT = nulou,FMT = *)' '
00738          WRITE (UNIT = nulou,FMT = *)'Leaving routine grid_init'
00739          WRITE (UNIT = nulou,FMT = *)' '
00740          CALL FLUSH(nulou)
00741       ENDIF
00742 ! 
00743 !-----------------------------------------------------------------------
00744 
00745       end subroutine grid_init
00746 
00747 !***********************************************************************
00748 
00749       subroutine free_grids
00750 
00751 !-----------------------------------------------------------------------
00752 !
00753 !     subroutine to deallocate allocated arrays
00754 !
00755 !----------------------------------------------------------------------- 
00756 !
00757       IF (nlogprt .GE. 2) THEN
00758          WRITE (UNIT = nulou,FMT = *)' '
00759          WRITE (UNIT = nulou,FMT = *)'Entering routine free_grid'
00760          WRITE (UNIT = nulou,FMT = *)' '
00761          CALL FLUSH(nulou)
00762       ENDIF
00763 ! 
00764       deallocate(grid1_mask, grid2_mask, 
00765      &    grid1_center_lat, grid1_center_lon,
00766      &    grid2_center_lat, grid2_center_lon,
00767      &    grid1_area, grid2_area,
00768      &    grid1_frac, grid2_frac,
00769      &    grid1_dims, grid2_dims)
00770 
00771       IF (restrict_TYPE == 'REDUCED') then
00772           deallocate( grid1_bound_box, grid2_bound_box,
00773      &        bin_addr1_r, bin_addr2,
00774      &        bin_lons, bin_lats,
00775      &        bin_lats_r, bin_lons_r)
00776       else
00777           deallocate( grid1_bound_box, grid2_bound_box,
00778      &        bin_addr1, bin_addr2,
00779      &        bin_lats, bin_lons)
00780       endif
00781 
00782       if (.not. luse_grid_centers) then
00783         deallocate(grid1_corner_lat, grid1_corner_lon,
00784      &             grid2_corner_lat, grid2_corner_lon)
00785       ENDIF
00786 !
00787       IF (nlogprt .GE. 2) THEN
00788          WRITE (UNIT = nulou,FMT = *)' '
00789          WRITE (UNIT = nulou,FMT = *)'Leaving routine free_grid'
00790          WRITE (UNIT = nulou,FMT = *)' '
00791          CALL FLUSH(nulou)
00792       ENDIF
00793 !-----------------------------------------------------------------------
00794 
00795       end subroutine free_grids
00796 
00797 !***********************************************************************
00798 
00799       end module grids
00800 
00801 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
00802 
 All Data Structures Namespaces Files Functions Variables Defines