Oasis3 4.0.2
remap_gauswgt.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 a modified version
00009 C     of SCRIP 1.4 remap_ditswgt.f in order to weight a neighbour by
00010 C     exp[-1/2 * d^^2/sigma^^2] where d is the distance between the source
00011 C     and the target points and sigma^^2=VAR*dm^^2, where dm is the
00012 C     average distance between the source grid points and VAR is a value 
00013 C     given by the user.
00014 C
00015 C     Additional Modifications:
00016 C       - restrict types are written in capital letters
00017 C       - bug line 429: bin_lons(3,n) instead of bin_lons(2,n)
00018 C
00019 C     Modified by            D. Declat,  CERFACS              27.06.2002
00020 C***********************************************************************
00021 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
00022 !
00023 !     this module contains necessary routines for performing an 
00024 !     interpolation using a distance-weighted average of n nearest
00025 !     neighbors.
00026 !
00027 !-----------------------------------------------------------------------
00028 !
00029 !     CVS:$Id: remap_gauswgt.f 2826 2010-12-10 11:14:21Z valcke $
00030 !
00031 !     Copyright (c) 1997, 1998 the Regents of the University of 
00032 !       California.
00033 !
00034 !     This software and ancillary information (herein called software) 
00035 !     called SCRIP is made available under the terms described here.  
00036 !     The software has been approved for release with associated 
00037 !     LA-CC Number 98-45.
00038 !
00039 !     Unless otherwise indicated, this software has been authored
00040 !     by an employee or employees of the University of California,
00041 !     operator of the Los Alamos National Laboratory under Contract
00042 !     No. W-7405-ENG-36 with the U.S. Department of Energy.  The U.S.
00043 !     Government has rights to use, reproduce, and distribute this
00044 !     software.  The public may copy and use this software without
00045 !     charge, provided that this Notice and any statement of authorship
00046 !     are reproduced on all copies.  Neither the Government nor the
00047 !     University makes any warranty, express or implied, or assumes
00048 !     any liability or responsibility for the use of this software.
00049 !
00050 !     If software is modified to produce derivative works, such modified
00051 !     software should be clearly marked, so as not to confuse it with 
00052 !     the version available from Los Alamos National Laboratory.
00053 !
00054 !***********************************************************************
00055 
00056       module remap_gaussian_weight
00057 
00058 !-----------------------------------------------------------------------
00059 
00060       use kinds_mod     ! defines common data types
00061       use constants     ! defines common constants
00062       use grids         ! module containing grid info
00063       use remap_vars    ! module containing remap info
00064 
00065       implicit none
00066 
00067 !-----------------------------------------------------------------------
00068 !
00069 !     module variables
00070 !
00071 !-----------------------------------------------------------------------
00072 
00073       real (kind=dbl_kind), dimension(:), allocatable, save ::
00074      &     coslat, sinlat, ! cosine, sine of grid lats (for distance)
00075      &     coslon, sinlon, ! cosine, sine of grid lons (for distance)
00076      &     wgtstmp         ! an array to hold the link weight
00077 
00078 !***********************************************************************
00079 
00080       contains
00081 
00082 !***********************************************************************
00083 
00084       subroutine remap_gauswgt (lextrapdone, num_neighbors, rl_varmul)
00085 
00086 !-----------------------------------------------------------------------
00087 !
00088 !     this routine computes the inverse-distance weights for a
00089 !     nearest-neighbor interpolation.
00090 !
00091 !-----------------------------------------------------------------------
00092 
00093       LOGICAL ::
00094      &           lextrapdone   ! logical, true if EXTRAP done on field
00095 
00096       REAL (kind=real_kind) ::
00097      $    rl_varmul             ! Gaussian variance
00098 
00099       INTEGER (kind=int_kind) ::
00100      &       num_neighbors     ! number of neighbours
00101 
00102 !-----------------------------------------------------------------------
00103 !
00104 !     local variables
00105 !
00106 !-----------------------------------------------------------------------
00107 
00108       logical (kind=log_kind), dimension(num_neighbors) ::
00109      &     nbr_mask        ! mask at nearest neighbors
00110       
00111       integer (kind=int_kind) :: n,
00112      &     dst_add,        ! destination address
00113      &     nmap            ! index of current map being computed
00114 
00115       integer (kind=int_kind), dimension(num_neighbors) ::
00116      &     nbr_add         ! source address at nearest neighbors
00117 
00118       real (kind=dbl_kind), dimension(num_neighbors) ::
00119      &     nbr_dist        ! angular distance four nearest neighbors
00120 
00121       real (kind=dbl_kind) ::
00122      &     coslat_dst,     ! cos(lat) of destination grid point
00123      &     coslon_dst,     ! cos(lon) of destination grid point
00124      &     sinlat_dst,     ! sin(lat) of destination grid point
00125      &     sinlon_dst,     ! sin(lon) of destination grid point
00126      &     dist_tot,       ! sum of neighbor distances (for normalizing)
00127      &     dist_average    ! average distance between the source points
00128       logical (kind=log_kind) :: ll_allmask, ll_nnei
00129       real (kind=dbl_kind) ::
00130      &        distance ,plat,plon,src_latsnn, arg   ! angular distance
00131       real (kind=dbl_kind), dimension (1) :: wgts_new
00132       integer (kind=int_kind) :: min_add_out, max_add_out, 
00133      &        srch_add, src_addnn
00134 !-----------------------------------------------------------------------
00135 !
00136       IF (nlogprt .GE. 2) THEN
00137          WRITE (UNIT = nulou,FMT = *)' '
00138          WRITE (UNIT = nulou,FMT = *)'Entering routine remap_gauswgt'
00139          CALL FLUSH(nulou)
00140       ENDIF
00141 !-----------------------------------------------------------------------
00142 !
00143 !     compute mappings from grid1 to grid2
00144 !
00145 !-----------------------------------------------------------------------
00146 
00147       nmap = 1
00148 
00149       !***
00150       !*** allocate wgtstmp to be consistent with store_link interface
00151       !***
00152 
00153       allocate (wgtstmp(num_wts))
00154 
00155       !***
00156       !*** compute cos, sin of lat/lon on source grid for distance
00157       !*** calculations
00158       !***
00159 
00160       allocate (coslat(grid1_size), coslon(grid1_size),
00161      &          sinlat(grid1_size), sinlon(grid1_size))
00162 
00163       coslat = cos(grid1_center_lat)
00164       coslon = cos(grid1_center_lon)
00165       sinlat = sin(grid1_center_lat)
00166       sinlon = sin(grid1_center_lon)
00167 
00168       !***
00169       !*** compute the average of the distances between the source points
00170       !*** 
00171 
00172       call grid_dist_average(grid1_size,
00173      &                       coslat, coslon,
00174      &                       sinlat, sinlon,
00175      &                       dist_average)
00176       !***
00177       !*** loop over destination grid 
00178       !***
00179 
00180       grid_loop1: do dst_add = 1, grid2_size
00181 
00182         if (.not. grid2_mask(dst_add)) cycle grid_loop1
00183 
00184         coslat_dst = cos(grid2_center_lat(dst_add))
00185         coslon_dst = cos(grid2_center_lon(dst_add))
00186         sinlat_dst = sin(grid2_center_lat(dst_add))
00187         sinlon_dst = sin(grid2_center_lon(dst_add))
00188 
00189         !***
00190         !*** find nearest grid points on source grid and
00191         !*** distances to each point
00192         !***
00193 
00194         call grid_search_nbrg(nbr_add, nbr_dist, 
00195      &                        min_add_out, max_add_out,
00196      &                        grid2_center_lat(dst_add),
00197      &                        grid2_center_lon(dst_add),
00198      &                        coslat_dst, coslon_dst, 
00199      &                        sinlat_dst, sinlon_dst,
00200      &                        bin_addr1, 
00201      &                        dist_average,  num_neighbors, rl_varmul)
00202 
00203         !***
00204         !*** compute weights based on inverse distance
00205         !*** if mask is false, eliminate those points
00206         !***
00207 
00208         dist_tot = zero
00209         do n=1,num_neighbors
00210           if ((grid1_mask(nbr_add(n))) .or.
00211      &        (.not. grid1_mask(nbr_add(n)) .and. lextrapdone)) THEN
00212             nbr_dist(n) = one/nbr_dist(n)
00213             dist_tot = dist_tot + nbr_dist(n)
00214             nbr_mask(n) = .true.
00215           else
00216             nbr_mask(n) = .false.
00217           endif
00218         end do
00219 
00220         !***
00221         !*** normalize weights and store the link
00222         !***
00223 
00224         do n=1,num_neighbors
00225           if (nbr_mask(n)) then
00226             wgtstmp(1) = nbr_dist(n)/dist_tot
00227             call store_link_nbr(nbr_add(n), dst_add, wgtstmp, nmap)
00228             grid2_frac(dst_add) = one
00229           endif
00230         end do
00231         ll_nnei = .false.
00232         IF (ll_nnei) THEN
00233             ll_allmask= .true.
00234             do n=1,num_neighbors
00235               if (nbr_mask(n)) then
00236                   ll_allmask=.false.
00237               endif
00238             end do
00239             if ( ll_allmask) THEN
00240                 IF (nlogprt .GE. 2) THEN
00241                     WRITE(nulou,*)'ll_allmask true',src_addnn
00242                     CALL FLUSH(nulou)
00243                 ENDIF
00244                 src_latsnn = bignum
00245                 do srch_add = min_add_out,max_add_out
00246                   if (grid1_mask(srch_add) .or.
00247      &                (.not. grid1_mask(srch_add) 
00248      &                .and. lextrapdone)) THEN
00249                       arg = coslat_dst*cos(grid1_center_lat(srch_add))*
00250      &                (coslon_dst*cos(grid1_center_lon(srch_add)) +
00251      &                sinlon_dst*sin(grid1_center_lon(srch_add)))+
00252      &                sinlat_dst*sin(grid1_center_lat(srch_add))
00253                       IF (arg < -1.0d0) THEN
00254                           arg = -1.0d0
00255                       ELSE IF (arg > 1.0d0) THEN
00256                           arg = 1.0d0
00257                       END IF
00258                       distance=acos(arg)
00259                       
00260                       if (distance < src_latsnn) then
00261                           src_addnn = srch_add
00262                           src_latsnn = distance
00263                       endif
00264                   endif
00265                 end do
00266                 wgts_new(1) = 1.
00267                 grid2_frac(dst_add) = one
00268                 call store_link_nbr(src_addnn,dst_add ,wgts_new, nmap)
00269             endif
00270         endif
00271             
00272       end do grid_loop1
00273 
00274       deallocate (coslat, coslon, sinlat, sinlon)
00275 
00276 !-----------------------------------------------------------------------
00277 !
00278 !     compute mappings from grid2 to grid1 if necessary
00279 !
00280 !-----------------------------------------------------------------------
00281 
00282       if (num_maps > 1) then
00283 
00284       nmap = 2
00285 
00286       !***
00287       !*** compute cos, sin of lat/lon on source grid for distance
00288       !*** calculations
00289       !***
00290 
00291       allocate (coslat(grid2_size), coslon(grid2_size),
00292      &          sinlat(grid2_size), sinlon(grid2_size))
00293 
00294       coslat = cos(grid2_center_lat)
00295       coslon = cos(grid2_center_lon)
00296       sinlat = sin(grid2_center_lat)
00297       sinlon = sin(grid2_center_lon)
00298 
00299       !***
00300       !*** compute the average of the distances between the source points
00301       !*** 
00302 
00303       call grid_dist_average(grid2_size,
00304      &                       coslat, coslon,
00305      &                       sinlat, sinlon,
00306      &                       dist_average)
00307 
00308       !***
00309       !*** loop over destination grid 
00310       !***
00311 
00312       grid_loop2: do dst_add = 1, grid1_size
00313 
00314         if (.not. grid1_mask(dst_add)) cycle grid_loop2
00315 
00316         coslat_dst = cos(grid1_center_lat(dst_add))
00317         coslon_dst = cos(grid1_center_lon(dst_add))
00318         sinlat_dst = sin(grid1_center_lat(dst_add))
00319         sinlon_dst = sin(grid1_center_lon(dst_add))
00320 
00321         !***
00322         !*** find four nearest grid points on source grid and
00323         !*** distances to each point
00324         !***
00325 
00326         call grid_search_nbrg(nbr_add, nbr_dist, 
00327      &                        min_add_out, max_add_out,
00328      &                        grid1_center_lat(dst_add),
00329      &                        grid1_center_lon(dst_add),
00330      &                        coslat_dst, coslon_dst, 
00331      &                        sinlat_dst, sinlon_dst,
00332      &                        bin_addr2, 
00333      &                        dist_average, num_neighbors, rl_varmul)
00334 
00335         !***
00336         !*** compute weights based on inverse distance
00337         !*** if mask is false, eliminate those points
00338         !***
00339 
00340         dist_tot = zero
00341         do n=1,num_neighbors
00342           if (grid2_mask(nbr_add(n))) then
00343             nbr_dist(n) = one/nbr_dist(n)
00344             dist_tot = dist_tot + nbr_dist(n)
00345             nbr_mask(n) = .true.
00346           else
00347             nbr_mask(n) = .false.
00348           endif
00349         end do
00350 
00351         !***
00352         !*** normalize weights and store the link
00353         !***
00354 
00355         do n=1,num_neighbors
00356           if (nbr_mask(n)) then
00357             wgtstmp(1) = nbr_dist(n)/dist_tot
00358             call store_link_nbr(dst_add, nbr_add(n), wgtstmp, nmap)
00359             grid1_frac(dst_add) = one
00360           endif
00361         end do
00362 
00363         IF (ll_nnei) THEN
00364             ll_allmask= .true.
00365             do n=1,num_neighbors
00366               if (nbr_mask(n)) then
00367                   ll_allmask=.false.
00368               endif
00369             end do
00370             if ( ll_allmask) then
00371                 PRINT*, 'll_allmask true',src_addnn   
00372                 src_latsnn = bignum
00373                 do srch_add = min_add_out,max_add_out
00374                   if (grid2_mask(srch_add) .or.
00375      &                (.not. grid2_mask(srch_add) 
00376      &                .and. lextrapdone)) THEN
00377                       arg = coslat_dst*cos(grid2_center_lat(srch_add))*
00378      &                (coslon_dst*cos(grid2_center_lon(srch_add)) +
00379      &                sinlon_dst*sin(grid2_center_lon(srch_add)))+
00380      &                sinlat_dst*sin(grid2_center_lat(srch_add))
00381                       IF (arg < -1.0d0) THEN
00382                           arg = -1.0d0
00383                       ELSE IF (arg > 1.0d0) THEN
00384                           arg = 1.0d0
00385                       END IF
00386                       distance=acos(arg)
00387 
00388                       if (distance < src_latsnn) then
00389                           src_addnn = srch_add
00390                           src_latsnn = distance
00391                       endif
00392                   endif
00393                 end do
00394                 wgts_new = 1.
00395                 grid1_frac(dst_add) = one
00396                 call store_link_nbr(dst_add, src_addnn, wgts_new, nmap)
00397             endif
00398         endif
00399       end do grid_loop2
00400 
00401       deallocate (coslat, coslon, sinlat, sinlon)
00402 
00403       endif
00404 
00405       deallocate(wgtstmp)
00406 !
00407       IF (nlogprt .GE. 2) THEN
00408          WRITE (UNIT = nulou,FMT = *)' '
00409          WRITE (UNIT = nulou,FMT = *)'Leaving routine remap_gauswgt'
00410          CALL FLUSH(nulou)
00411       ENDIF
00412 !
00413 !-----------------------------------------------------------------------
00414 
00415       end subroutine remap_gauswgt
00416 
00417 !***********************************************************************
00418 
00419       subroutine grid_search_nbrg(nbr_add, nbr_dist, min_add, max_add, 
00420      &               plat, plon,  
00421      &               coslat_dst, coslon_dst, sinlat_dst, sinlon_dst,
00422      &               src_bin_add, dst_average,
00423      $               num_neighbors, rl_varmul)
00424 
00425 !-----------------------------------------------------------------------
00426 !
00427 !     this routine finds the closest num_neighbor points to a search 
00428 !     point and computes a distance to each of the neighbors.
00429 !
00430 !-----------------------------------------------------------------------
00431 
00432 !-----------------------------------------------------------------------
00433 !
00434 !     input variables
00435 !
00436 !-----------------------------------------------------------------------
00437 
00438       integer (kind=int_kind), dimension(:,:), intent(in) ::
00439      &        src_bin_add ! search bins for restricting search
00440 
00441       real (kind=dbl_kind), intent(in) ::
00442      &        plat,         ! latitude  of the search point
00443      &        plon,         ! longitude of the search point
00444      &        coslat_dst,   ! cos(lat)  of the search point
00445      &        coslon_dst,   ! cos(lon)  of the search point
00446      &        sinlat_dst,   ! sin(lat)  of the search point
00447      &        sinlon_dst,   ! sin(lon)  of the search point
00448      &        dst_average   ! average distance between the source points
00449 
00450       REAL (kind=real_kind), intent(in) ::
00451      &        rl_varmul     ! Gaussian variance
00452 
00453       INTEGER (kind=int_kind) ::
00454      &       num_neighbors     ! number of neighbours
00455 
00456 !-----------------------------------------------------------------------
00457 !
00458 !     output variables
00459 !
00460 !-----------------------------------------------------------------------
00461 
00462       integer (kind=int_kind), dimension(num_neighbors), intent(out) ::
00463      &        nbr_add  ! address of each of the closest points
00464 
00465       real (kind=dbl_kind), dimension(num_neighbors), intent(out) ::
00466      &        nbr_dist ! distance to each of the closest points
00467 
00468       integer (kind=int_kind),intent(out) :: min_add, max_add 
00469 
00470 !-----------------------------------------------------------------------
00471 !
00472 !     local variables
00473 !
00474 !-----------------------------------------------------------------------
00475 
00476       integer (kind=int_kind) :: n, nmax, nadd, nchk, ! dummy indices
00477      &        nm1, np1, i, j, ip1, im1, jp1, jm1
00478 
00479       real (kind=dbl_kind) ::
00480      &        distance, arg      ! angular distance
00481 
00482       real (kind=dbl_kind) ::
00483      &        variance      ! variance for the gaussian FUNCTION
00484 
00485 
00486 !-----------------------------------------------------------------------
00487 !
00488 !     loop over source grid and find nearest neighbors
00489 !
00490 !-----------------------------------------------------------------------
00491 
00492       !***
00493       !*** restrict the search using search bins
00494       !*** expand the bins to catch neighbors
00495       !***
00496 
00497       select case (restrict_type)
00498       case('LATITUDE')
00499 
00500         do n=1,num_srch_bins
00501           if (plat >= bin_lats(1,n) .and. plat <= bin_lats(2,n)) then
00502             min_add = src_bin_add(1,n)
00503             max_add = src_bin_add(2,n)
00504 
00505             nm1 = max(n-1,1)
00506             np1 = min(n+1,num_srch_bins)
00507 
00508             min_add = min(min_add,src_bin_add(1,nm1))
00509             max_add = max(max_add,src_bin_add(2,nm1))
00510             min_add = min(min_add,src_bin_add(1,np1))
00511             max_add = max(max_add,src_bin_add(2,np1))
00512           endif
00513         end do
00514 
00515       case('LATLON')
00516 
00517         n = 0
00518         nmax = nint(sqrt(real(num_srch_bins)))
00519         do j=1,nmax
00520         jp1 = min(j+1,nmax)
00521         jm1 = max(j-1,1)
00522         do i=1,nmax
00523           ip1 = min(i+1,nmax)
00524           im1 = max(i-1,1)
00525 
00526           n = n+1
00527           if (plat >= bin_lats(1,n) .and. plat <= bin_lats(2,n) .and.
00528      &        plon >= bin_lons(1,n) .and. plon <= bin_lons(2,n)) then
00529             min_add = src_bin_add(1,n)
00530             max_add = src_bin_add(2,n)
00531 
00532             nm1 = (jm1-1)*nmax + im1
00533             np1 = (jp1-1)*nmax + ip1
00534             nm1 = max(nm1,1)
00535             np1 = min(np1,num_srch_bins)
00536 
00537             min_add = min(min_add,src_bin_add(1,nm1))
00538             max_add = max(max_add,src_bin_add(2,nm1))
00539             min_add = min(min_add,src_bin_add(1,np1))
00540             max_add = max(max_add,src_bin_add(2,np1))
00541           endif
00542         end do
00543         end do
00544 
00545       end select
00546 
00547       !***
00548       !*** initialize distance and address arrays
00549       !***
00550 
00551       nbr_add = 0
00552       nbr_dist = bignum
00553       variance = rl_varmul*dst_average*dst_average
00554       do nadd=min_add,max_add
00555 
00556         !***
00557         !*** find distance to this point
00558         !***
00559         arg = sinlat_dst*sinlat(nadd) +
00560      &        coslat_dst*coslat(nadd)*
00561      &       (coslon_dst*coslon(nadd) +
00562      &        sinlon_dst*sinlon(nadd))
00563         IF (arg < -1.0d0) THEN
00564             arg = -1.0d0
00565         ELSE IF (arg > 1.0d0) THEN
00566             arg = 1.0d0
00567         END IF
00568         distance = acos(arg)
00569         !distance = min(500., distance) !ts-sv
00570         !distance = exp(.5*distance*distance/variance)
00571         !***
00572         !*** store the address and distance if this is one of the
00573         !*** smallest four so far
00574         !***
00575 
00576         check_loop: do nchk=1,num_neighbors
00577           if (distance .lt. nbr_dist(nchk)) THEN
00578             do n=num_neighbors,nchk+1,-1
00579               nbr_add(n) = nbr_add(n-1)
00580               nbr_dist(n) = nbr_dist(n-1)
00581             end do
00582             nbr_add(nchk) = nadd
00583             nbr_dist(nchk) = distance
00584             exit check_loop
00585           endif
00586         end do check_loop
00587 
00588       end do
00589 
00590       exp_loop: do nchk=1,num_neighbors
00591           nbr_dist(nchk) = 
00592      &     exp(.5*nbr_dist(nchk)*nbr_dist(nchk)/variance)
00593       end do exp_loop
00594 
00595 !-----------------------------------------------------------------------
00596 
00597       end subroutine grid_search_nbrg 
00598 
00599 !***********************************************************************
00600 
00601       subroutine store_link_nbr(add1, add2, weights, nmap)
00602 
00603 !-----------------------------------------------------------------------
00604 !
00605 !     this routine stores the address and weight for this link in
00606 !     the appropriate address and weight arrays and resizes those
00607 !     arrays if necessary.
00608 !
00609 !-----------------------------------------------------------------------
00610 
00611 !-----------------------------------------------------------------------
00612 !
00613 !     input variables
00614 !
00615 !-----------------------------------------------------------------------
00616 
00617       integer (kind=int_kind), intent(in) ::
00618      &        add1,  ! address on grid1
00619      &        add2,  ! address on grid2
00620      &        nmap   ! identifies which direction for mapping
00621 
00622       real (kind=dbl_kind), dimension(:), intent(in) ::
00623      &        weights ! array of remapping weights for this link
00624 
00625 !-----------------------------------------------------------------------
00626 !
00627 !     increment number of links and check to see if remap arrays need
00628 !     to be increased to accomodate the new link.  then store the
00629 !     link.
00630 !
00631 !-----------------------------------------------------------------------
00632 
00633       select case (nmap)
00634       case(1)
00635 
00636         num_links_map1  = num_links_map1 + 1
00637 
00638         if (num_links_map1 > max_links_map1) 
00639      &     call resize_remap_vars(1,resize_increment)
00640 
00641         grid1_add_map1(num_links_map1) = add1
00642         grid2_add_map1(num_links_map1) = add2
00643         wts_map1    (:,num_links_map1) = weights
00644 
00645       case(2)
00646 
00647         num_links_map2  = num_links_map2 + 1
00648 
00649         if (num_links_map2 > max_links_map2) 
00650      &     call resize_remap_vars(2,resize_increment)
00651 
00652         grid1_add_map2(num_links_map2) = add1
00653         grid2_add_map2(num_links_map2) = add2
00654         wts_map2    (:,num_links_map2) = weights
00655 
00656       end select
00657 
00658 !-----------------------------------------------------------------------
00659 
00660       end subroutine store_link_nbr
00661 
00662 !***********************************************************************
00663 
00664       subroutine grid_dist_average(grid_size,
00665      &                             coslat_grid, coslon_grid,
00666      &                             sinlat_grid, sinlon_grid,
00667      &                             dist_average)
00668 
00669 !-----------------------------------------------------------------------
00670 !
00671 !     this routine computes the average distance between the points of a
00672 !     grid.
00673 !
00674 !-----------------------------------------------------------------------
00675 
00676 !-----------------------------------------------------------------------
00677 !
00678 !     output variables
00679 !
00680 !-----------------------------------------------------------------------
00681 
00682       real (kind=dbl_kind), intent(out) ::
00683      &        dist_average ! distance to each of the closest points
00684 
00685 !-----------------------------------------------------------------------
00686 !
00687 !     input variables
00688 !
00689 !-----------------------------------------------------------------------
00690 
00691       integer (kind=int_kind), intent(in) ::
00692      &        grid_size  
00693 
00694       real (kind=dbl_kind), dimension(:), intent(in) ::
00695      &        coslat_grid,   ! cos(lat)  of the grid points
00696      &        coslon_grid,   ! cos(lon)  of the grid points
00697      &        sinlat_grid,   ! sin(lat)  of the grid points
00698      &        sinlon_grid    ! sin(lon)  of the grid points
00699       REAL (kind=dbl_kind) :: arg
00700 
00701 !-----------------------------------------------------------------------
00702 !
00703 !     local variables
00704 !
00705 !-----------------------------------------------------------------------
00706 
00707       integer (kind=int_kind) :: i
00708 !
00709       IF (nlogprt .GE. 2) THEN
00710          WRITE (UNIT = nulou,FMT = *)' '
00711          WRITE (UNIT = nulou,FMT = *)
00712      &       'Entering routine remap_dist_average'
00713          CALL FLUSH(nulou)
00714       ENDIF
00715 !
00716 !-----------------------------------------------------------------------
00717 !
00718 !     compute the distance over the grid and average
00719 !
00720 !-----------------------------------------------------------------------
00721 
00722       dist_average = 0.0
00723       DO i = 1, grid_size
00724         IF (i .eq. 1) THEN
00725             arg = sinlat_grid(grid_size)*sinlat_grid(i) +
00726      &          coslat_grid(grid_size)*coslat_grid(i)*
00727      &          (coslon_grid(grid_size)*coslon_grid(i) +
00728      &          sinlon_grid(grid_size)*sinlon_grid(i))
00729             IF (arg < -1.0d0) THEN
00730                 arg = -1.0d0
00731             ELSE IF (arg > 1.0d0) THEN
00732                 arg = 1.0d0
00733             END IF           
00734             dist_average = dist_average + acos(arg)
00735 
00736             arg = sinlat_grid(i)*sinlat_grid(i+1) +
00737      &          coslat_grid(i)*coslat_grid(i+1)*
00738      &          (coslon_grid(i)*coslon_grid(i+1) +
00739      &          sinlon_grid(i)*sinlon_grid(i+1))
00740             IF (arg < -1.0d0) THEN
00741                 arg = -1.0d0
00742             ELSE IF (arg > 1.0d0) THEN
00743                 arg = 1.0d0
00744             END IF 
00745             dist_average = dist_average + acos(arg)
00746              
00747         ELSE IF (i .eq. grid_size) THEN
00748             arg = sinlat_grid(i-1)*sinlat_grid(i) +
00749      &          coslat_grid(i-1)*coslat_grid(i)*
00750      &          (coslon_grid(i-1)*coslon_grid(i) +
00751      &          sinlon_grid(i-1)*sinlon_grid(i))
00752             IF (arg < -1.0d0) THEN
00753                 arg = -1.0d0
00754             ELSE IF (arg > 1.0d0) THEN
00755                 arg = 1.0d0
00756             END IF 
00757             dist_average = dist_average + acos(arg)
00758 
00759             arg = sinlat_grid(i)*sinlat_grid(1) +
00760      &          coslat_grid(i)*coslat_grid(1)*
00761      &          (coslon_grid(i)*coslon_grid(1) +
00762      &          sinlon_grid(i)*sinlon_grid(1))
00763             IF (arg < -1.0d0) THEN
00764                 arg = -1.0d0
00765             ELSE IF (arg > 1.0d0) THEN
00766                 arg = 1.0d0
00767             END IF 
00768             dist_average = dist_average + acos(arg)
00769             
00770         ELSE
00771             arg = sinlat_grid(i-1)*sinlat_grid(i) +
00772      &          coslat_grid(i-1)*coslat_grid(i)*
00773      &          (coslon_grid(i-1)*coslon_grid(i) +
00774      &          sinlon_grid(i-1)*sinlon_grid(i))
00775             IF (arg < -1.0d0) THEN
00776                 arg = -1.0d0
00777             ELSE IF (arg > 1.0d0) THEN
00778                 arg = 1.0d0
00779             END IF             
00780             dist_average = dist_average + acos(arg)
00781 
00782             arg = sinlat_grid(i)*sinlat_grid(i+1) +
00783      &          coslat_grid(i)*coslat_grid(i+1)*
00784      &          (coslon_grid(i)*coslon_grid(i+1) +
00785      &          sinlon_grid(i)*sinlon_grid(i+1))
00786             IF (arg < -1.0d0) THEN
00787                 arg = -1.0d0
00788             ELSE IF (arg > 1.0d0) THEN
00789                 arg = 1.0d0
00790             END IF              
00791             dist_average = dist_average + acos(arg)             
00792         END IF
00793       END DO
00794       dist_average = dist_average / (2*grid_size)
00795 !
00796       IF (nlogprt .GE. 2) THEN
00797          WRITE (UNIT = nulou,FMT = *)' '
00798          WRITE (UNIT = nulou,FMT = *)
00799      &       'Leaving routine remap_dist_average'
00800          CALL FLUSH(nulou)
00801       ENDIF
00802 !
00803       END subroutine grid_dist_average
00804 
00805 !***********************************************************************
00806 
00807       end module remap_gaussian_weight
00808 
00809 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
00810 
 All Data Structures Namespaces Files Functions Variables Defines