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

Generated on 18 Mar 2011 for Oasis4 by  doxygen 1.6.1