psmile_srch_nneigh_irreg2_real.F90

Go to the documentation of this file.
00001 !-----------------------------------------------------------------------
00002 ! Copyright 2006-2010, NEC Europe Ltd., London, UK.
00003 ! All rights reserved. Use is subject to OASIS4 license terms.
00004 !-----------------------------------------------------------------------
00005 !BOP
00006 !
00007 !
00008 ! !ROUTINE: PSMILe_srch_nneigh_irreg2_real
00009 !
00010 subroutine psmile_srch_nneigh_irreg2_real (grid_id,         &
00011                 search_mode, mask_ind,                      &
00012                 sin_values, cos_values,                     &
00013                 grid_valid_shape,                           &
00014                 z_coords, coords_shape,                     &
00015                 neighbors_3d, nloc, num_neigh,              &
00016                 sin_search, cos_search, z_search,           &
00017                 dist_real, dim1, extra_search, jbeg, jend,  &
00018                 mask_array, mask_shape, mask_available,     &
00019                 ierror)
00020 !
00021 ! !USES:
00022 !
00023   use PRISM_constants
00024 !
00025   use PSMILe ! , dummy_interface => PSMILe_srch_nneigh_irreg2_real
00026 #ifdef DEBUG_TRACE
00027   use psmile_debug_trace
00028 #endif
00029 
00030   implicit none
00031 !
00032 ! !INPUT PARAMETERS:
00033 !
00034       Integer, Intent (In)            :: grid_id
00035 !
00036 !    Info on the component in which the donor cells
00037 !    should be searched.
00038 !
00039       Integer, Intent (In)            :: search_mode
00040 !
00041 !     Specifies the search mode for nearest neigbours with
00042 !        search_mode = 3 : Full 3d-search
00043 !        search_mode = 2 : Search in 2d-hyperplane (1st 2nd direction lon, lat)
00044 !        search_mode = 1 : Search in 1d-plane
00045 !
00046 !
00047 !     to exclude target points which are already completed
00048 !
00049       Integer, Intent (In)            :: grid_valid_shape (2, ndim_3d)
00050 !
00051 !     Specifies the valid block shape for the "ndim_3d"-dimensional block
00052 
00053       Real, Intent (In)               :: sin_values     (grid_valid_shape(1,1): 
00054                                                          grid_valid_shape(2,1), 
00055                                                          grid_valid_shape(1,2): 
00056                                                          grid_valid_shape(2,2),2)
00057       Real, Intent (In)               :: cos_values     (grid_valid_shape(1,1): 
00058                                                          grid_valid_shape(2,1), 
00059                                                          grid_valid_shape(1,2): 
00060                                                          grid_valid_shape(2,2),2)
00061 !
00062 !     Sin/Cos values of Longitudes and Latitudes (x_coords, y_coords)
00063 !
00064       Integer, Intent (In)            :: coords_shape (2, ndim_3d)
00065 
00066 !     Dimension of coordinates (method) x_coords, ...
00067 
00068       Real, Intent (In)               :: z_coords(coords_shape(1,3): 
00069                                                   coords_shape(2,3))
00070 !     vertical local coordinates 
00071 
00072       Integer, Intent (In)            :: nloc
00073 !
00074 !     Second dimension of neighbors array "neighbors_3d" and
00075 !     Total number of locations to be transferred
00076 !
00077       Integer, Intent (In)            :: num_neigh
00078 !
00079 !     Number of neighbors to be searched.
00080 !     Last dimension of neighbors array "neighbors_3d" and
00081 !     number of neighbors to be searched.
00082 !
00083       Integer,          Intent (In)   :: jbeg, jend
00084 !
00085 !     Shape of input arrays
00086 !
00087       Logical, Intent (In)            :: mask_ind(jbeg:jend)
00088 !
00089       Real, Intent (In)               :: sin_search (jbeg:jend, 2)
00090 !
00091 !     Sin values of the points for which the nearest neighbours
00092 !     should be searched.
00093 !
00094       Real, Intent (In)               :: cos_search (jbeg:jend, 2)
00095 !
00096 !     Cos values of the points for which the nearest neighbours
00097 !     should be searched.
00098 !
00099       Real, Intent (In)               :: z_search (jbeg:jend)
00100 !
00101 !     Z values of the points for which the nearest neighbours
00102 !     should be searched.
00103 !
00104       Integer, Intent (In)            :: dim1 (2)
00105 !
00106 !     Dimensions of "dist_real" in first direction 
00107 !
00108       Type (Extra_search_info), Intent(In) :: extra_search
00109 !
00110 !     Indices of the extra points in entire list of all points to be
00111 !     searched
00112 !
00113       Integer, Intent (In)            :: mask_shape (2, ndim_3d)
00114 !
00115 !    Dimension of (method) mask array
00116 !
00117       Logical, Intent (In)            :: mask_array (mask_shape (1,1): 
00118                                                      mask_shape (2,1), 
00119                                                      mask_shape (1,2): 
00120                                                      mask_shape (2,2), 
00121                                                      mask_shape (1,3): 
00122                                                      mask_shape (2,3))
00123 !    Mask of the method
00124 !
00125       Logical, Intent (In)            :: mask_available
00126 !
00127 !    Is mask specified in array "mask_array" ?
00128 !    mask_available = .false. : Mask is not available
00129 !                     .true.  : Mask is     available
00130 !
00131 ! !INPUT/OUTPUT PARAMETERS:
00132 !
00133       Real, Intent (InOut)             :: dist_real (dim1(1):dim1(2), num_neigh)
00134 !
00135 !    Initial distances and final distances
00136 !
00137       Integer,           Intent (Out) :: neighbors_3d (ndim_3d, nloc, num_neigh)
00138 
00139 !     Indices of neighbor locations (interpolation bases)
00140 !     Index array for points that have been found
00141 !
00142 ! !OUTPUT PARAMETERS:
00143 !
00144       Integer, Intent (Out)            :: ierror
00145 
00146 !    Returns the error code of PSMILE_Neigh_nearx_sub_irreg2_real;
00147 !            ierror = 0 : No error
00148 !            ierror > 0 : Severe error!
00149 !
00150 ! !DEFINED PARAMETERS:
00151 !
00152 !  real_earth = Earth radius in meter
00153 !
00154   Real, Parameter                 :: real_earth = 6400000.0
00155 !
00156   Real, Parameter                 :: acosp1 =  1.0
00157   Real, Parameter                 :: acosm1 = -1.0
00158 
00159   Integer, Parameter              :: lon = 1
00160   Integer, Parameter              :: lat = 2
00161 !
00162 ! !LOCAL VARIABLES
00163 !
00164   Real                            :: dist ((grid_valid_shape(2,1)-grid_valid_shape(1,1)+1) * 
00165                                            (grid_valid_shape(2,2)-grid_valid_shape(1,2)+1))
00166 
00167   Real                            :: val, fac
00168 
00169   Integer, Pointer                :: indices (:)
00170 
00171   Integer                         :: leni
00172   Integer                         :: i, j, k, n
00173   Integer                         :: ii, jj, kk
00174   Integer                         :: jpart, jind, ind
00175   Integer                         :: iloc(1)
00176 !
00177 ! !DESCRIPTION:
00178 !
00179 ! Subroutine "PSMILe_srch_nneigh_irreg2_real" searches the next "num_neigh"
00180 ! nearest neighbours on the method-grid with brut force but evaluating
00181 ! the distances to all source points.
00182 !
00183 ! !REVISION HISTORY:
00184 !
00185 !   Date      Programmer   Description
00186 ! ----------  ----------   -----------
00187 ! 05/02/01    R. Redler    created
00188 !
00189 !EOP
00190 !----------------------------------------------------------------------
00191 !
00192 !  Initialization
00193 
00194 #ifdef VERBOSE
00195   print 9990, trim(ch_id)
00196 
00197   call psmile_flushstd
00198 #endif /* VERBOSE */
00199 
00200   ierror = 0
00201   indices => extra_search%indices
00202 !
00203 ! jind = loop index in compact vector "sin_search", "cos_search",
00204 !        "z_search" and "dist_real"
00205 !
00206 ! ind  = Corresponding index in "neighbors_3d"
00207 !
00208   leni = grid_valid_shape(2,1) - grid_valid_shape(1,1) + 1
00209 
00210   do jpart = jbeg, jend, 5000
00211 !cdir vector loopcnt=5000
00212   do jind = jpart, min (jend, jpart+5000-1)
00213 
00214      if ( mask_ind(jind) ) then
00215 
00216      ! distance from source to target point
00217 
00218      fac = real_earth + z_search (jind)
00219 
00220      do j = grid_valid_shape(1,2), grid_valid_shape(2,2)
00221         do i = grid_valid_shape(1,1), grid_valid_shape(2,1)
00222 
00223            val =    sin_values(i,j,lat) * sin_search(jind, lat)    &
00224                 +   cos_values(i,j,lat) * cos_search(jind, lat)    &
00225                 *  (cos_values(i,j,lon) * cos_search(jind, lon)    &
00226                 +   sin_values(i,j,lon) * sin_search(jind, lon))
00227 
00228            val = min (acosp1, val)
00229            val = max (acosm1, val)
00230 
00231            if ( mask_available ) then
00232               if ( mask_array(i,j,1) ) then
00233                  dist ((j-grid_valid_shape(1,2))*leni + &
00234                         i-grid_valid_shape(1,1)+1) =    &
00235                         fac * acos (val)
00236               else
00237                  dist ((j-grid_valid_shape(1,2))*leni + &
00238                         i-grid_valid_shape(1,1)+1) = huge(fac)
00239               endif
00240            else
00241               dist((j-grid_valid_shape(1,2))*leni + &
00242                     i-grid_valid_shape(1,1)+1) = fac * acos (val)
00243            endif
00244 
00245         enddo
00246      enddo
00247 
00248      ! To Do: Find closest level in k
00249 
00250      kk = 1
00251 
00252      ind = indices(jind)
00253 
00254      do n = 1, num_neigh
00255 
00256         iloc(:) = minloc(dist)
00257 
00258 #ifdef MINLOCFIX
00259         if (iloc(1) == 0) iloc(1) = 1
00260 #endif /* MINLOCFIX */
00261 
00262         jj = (iloc(1)-1)/leni+1
00263         ii = iloc(1) - (jj-1)*leni
00264         
00265         neighbors_3d (1, ind, n) = ii + grid_valid_shape(1,1) - 1
00266         neighbors_3d (2, ind, n) = jj + grid_valid_shape(1,2) - 1
00267         neighbors_3d (3, ind, n) = kk + grid_valid_shape(1,3) - 1
00268 
00269         if ( search_mode == 2 ) then
00270            dist_real(jind, n) = abs(dist(iloc(1)))
00271         else
00272            dist_real(jind, n) = sqrt(dist(iloc(1))*dist(iloc(1)) + &
00273                                     ( z_search (jind)-z_coords(k) )**2)
00274         endif
00275 
00276      enddo
00277 
00278      endif
00279 
00280   end do
00281   end do ! jind
00282  
00283   !
00284   !===> All done
00285   !
00286 
00287 #ifdef VERBOSE
00288   print 9980, trim(ch_id), ierror
00289 
00290   call psmile_flushstd
00291 #endif /* VERBOSE */
00292   !
00293   !  Formats:
00294   !
00295 9990 format (1x, a, ': psmile_srch_nneigh_irreg2_real')
00296 9980 format (1x, a, ': psmile_srch_nneigh_irreg2_real: eof, ierror =', i3)
00297 
00298 end subroutine PSMILe_srch_nneigh_irreg2_real

Generated on 18 Mar 2011 for Oasis4 by  doxygen 1.6.1