psmile_mg_search.F90

Go to the documentation of this file.
00001 !-----------------------------------------------------------------------
00002 ! Copyright 2006-2010, NEC Europe Ltd., London, UK.
00003 ! Copyright 2011, DKRZ, Hamburg, Germany.
00004 ! All rights reserved. Use is subject to OASIS4 license terms.
00005 !-----------------------------------------------------------------------
00006 !BOP
00007 !
00008 ! !ROUTINE: psmile_mg_search
00009 !
00010 ! !INTERFACE:
00011 
00012       subroutine psmile_mg_search (comp_info, grid_id, search_data, &
00013                                    requires_conserv_remap, found,   &
00014                                    locations, len, tol, ierror)
00015 !
00016 ! !USES:
00017 !
00018       use PRISM_constants
00019       use PSMILe, dummy_interface => psmile_mg_search
00020       use psmile_grid, only : get_num_independent_dims
00021 
00022       implicit none
00023 !
00024 ! !INPUT PARAMETERS:
00025 !
00026       Type (Enddef_comp), Intent (In)           :: comp_info
00027 !
00028 !     Information on the component
00029 !
00030       Integer, Intent (In)                      :: grid_id
00031 !
00032 !     Local grid id
00033 !
00034       Double Precision, Intent (In)             :: tol
00035 !
00036 !     Absolute tolerance for search of "identical" points
00037 !     TOL >= 0.0
00038 !
00039       Logical, Intent (In)                      :: requires_conserv_remap
00040 !
00041 !     Are the results later used for conservative remapping (only
00042 !     significant for reduced gaussian grids)
00043 !
00044 !
00045 ! !INPUT/OUTPUT PARAMETERS:
00046 !
00047       Type (Enddef_search_data), Intent (InOut) :: search_data
00048 !
00049 !     Data on the points to be searched
00050 !
00051 ! !OUTPUT PARAMETERS:
00052 !
00053       Type (integer_vector), Intent (Out)       :: found     (search_data%npart, ndim_3d)
00054       Type (integer_vector), Intent (Out)       :: locations (search_data%npart, ndim_3d)
00055                                                
00056       Integer, Intent (Out)                     :: len  (search_data%npart, ndim_3d)
00057                                                
00058       Integer, Intent (Out)                     :: ierror
00059 
00060 !     Returns the error code of psmile_mg_search;
00061 !             ierror = 0 : No error
00062 !             ierror > 0 : Severe error
00063 !
00064 ! !LOCAL VARIABLES
00065 !
00066       Integer                     :: i
00067       Real                        :: rtol
00068 #if defined ( PRISM_QUAD_TYPE )
00069       Real (kind=PRISM_QUAD_TYPE) :: qtol
00070 #endif
00071 !
00072 !     ... for grids and components
00073 !
00074       Integer                     :: nlev1
00075       Integer                     :: datatype
00076 !
00077 !     ... for intersections
00078 !
00079       Integer                     :: ipart, npart
00080 !
00081 !     ... locations searched
00082 !
00083       Integer                     :: n_vec
00084 !
00085 !     ... for error parameters
00086 !
00087       Integer, parameter          :: nerrp = 2
00088       Integer                     :: ierrp (nerrp)
00089 !
00090 ! !DESCRIPTION:
00091 !
00092 ! Subroutine "psmile_mg_search" creates the found and locations arrays and filles them
00093 ! with the inital results of the multigrid search
00094 !
00095 !
00096 ! !REVISION HISTORY:
00097 !
00098 !   Date      Programmer   Description
00099 ! ----------  ----------   -----------
00100 ! 03.07.21    H. Ritzdorf  created as psmile_search_donor_cells
00101 ! 03.05.2011  M. Hanke     created by moving parts of psmile_search_donor_cells
00102 !                          to this new files/routine
00103 !
00104 !EOP
00105 !----------------------------------------------------------------------
00106 !
00107 ! $Id: psmile_mg_search.F90 3215 2011-06-07 10:00:41Z coquart $
00108 ! $Author: coquart $
00109 !
00110    Character(len=len_cvs_string), save :: mycvs = 
00111        '$Id: psmile_mg_search.F90 3215 2011-06-07 10:00:41Z coquart $'
00112 !
00113 !----------------------------------------------------------------------
00114 !
00115 !  Initialization
00116 !
00117 #ifdef VERBOSE
00118       print 9990, trim(ch_id)
00119       call psmile_flushstd
00120 #endif /* VERBOSE */
00121 
00122       rtol = tol
00123 
00124 #if defined ( PRISM_QUAD_TYPE )
00125       qtol = tol
00126 #endif
00127 
00128       datatype  = Grids(grid_id)%corner_pointer%corner_datatype
00129 
00130       npart = search_data%npart
00131       nlev1 = - (Grids(grid_id)%nlev + 1) ! Outside
00132 
00133       ! for reduced gauss grids an auxiliary grid of type PRISM_Reglonlatvrt
00134       ! is used for the search
00135       if (Grids(grid_id)%grid_type == PRISM_Gaussreduced_regvrt) then
00136          n_vec = get_num_independent_dims(PRISM_Reglonlatvrt)
00137       else
00138          n_vec = get_num_independent_dims(Grids(grid_id)%grid_type)
00139       endif
00140 
00141 ! -----------------------------------------------------------------------
00142 !      calculate the size of the found and location arrays
00143 !      and allocate them depending on number of independent
00144 !      of the local grid type
00145 ! -----------------------------------------------------------------------
00146 
00147       select case ( n_vec )
00148 
00149       case (ndim_3d) ! 3 independent dimension
00150                      ! regular in all 3 directions
00151 
00152 !    len (ipart, i) = Length of last dimension of vectors
00153 !                     found (ipart,i) and locations (ipart,i)
00154 !                   = Number of coordinates to be searched in each direction
00155 !
00156 
00157 
00158          ! check whether the remote grid is among the supported grid types
00159          if ( .not. any (search_data%grid_type == (/PRISM_Reglonlatvrt,     &
00160                                                     PRISM_Irrlonlat_regvrt, &
00161                                                     PRISM_Irrlonlatvrt,     &
00162                                                     PRISM_Gaussreduced_regvrt/))) then
00163             ierrp (1) = search_data%grid_type
00164             ierror = PRISM_Error_Internal
00165 
00166             call psmile_error ( ierror, 'unsupported grid type', &
00167                                 ierrp, 1, __FILE__, __LINE__ )
00168          endif
00169 
00170          ! compute the size of the found and location arrays
00171          ! 1 vector for each direction of the source grid
00172          do ipart = 1, npart
00173             len (ipart,:) = search_data%dim_size(:,ipart)
00174          enddo
00175 
00176          ! For reduced gauss grids in combination with conservative remapping we have
00177          ! two points per cell (lower left and upper right).
00178          ! In order for the multigrid search to take all points into account we need
00179          ! to extent the search range.
00180          if ( search_data%grid_type == PRISM_Gaussreduced_regvrt .and. &
00181               requires_conserv_remap) then
00182 
00183 ! TODO: Isn't the doubling already done in dim_size?
00184             len(:,1) = 2 * len(:,1)
00185             len(:,2) = len(:,1)
00186 
00187             search_data%range(2, 1, 1:npart) = 2 * search_data%range(2, 1, 1:npart) - &
00188                                                    search_data%range(1, 1, 1:npart) + 1
00189             search_data%shape(2, 1, 1:npart) = search_data%range(2, 1, 1:npart)
00190          endif
00191 
00192          ! allocate the found and location arrays
00193          do ipart = 1, npart
00194 
00195             do i = 1, ndim_3d
00196                Allocate (found(ipart,i)%vector(len(ipart,i)), &
00197                          locations(ipart,i)%vector(len(ipart,i)), STAT = ierror)
00198                if ( ierror > 0 ) then
00199                   ierrp (1) = ierror
00200                   ierrp (2) = 2*len (ipart, i)
00201                   ierror = PRISM_Error_Alloc
00202                   call psmile_error ( ierror, 'found(ipart,i)%vector, locations(ipart,i)%vector', &
00203                                       ierrp, 2, __FILE__, __LINE__ )
00204                   return
00205                endif
00206             enddo
00207          end do ! ipart
00208 
00209          ! initalise found and locations arrays
00210          do ipart = 1, npart
00211             do i = 1, ndim_3d
00212                found    (ipart,i)%vector (:) = nlev1
00213                locations(ipart,i)%vector (:) = 0
00214             end do
00215          end do ! ipart
00216 
00217       case (ndim_2d) ! 2 independent dimesions
00218                      ! Irregular in lonlat   direction
00219                      ! Regular   in vertical direction
00220 
00221 !    len (ipart, i) = Length of last dimension of vectors
00222 !                     found (ipart,i) and locations (ipart,i)
00223 !                   = Number of coordinates to be searched with
00224 !                     len (ipart, 1) = Number in lonlat direction
00225 !                     len (ipart, 2) = Number in z      direction
00226 
00227          ! compute the size of the found and location arrays depending on the
00228          ! number of independent dimension of the target grid type
00229          ! 2 vectors for lonlat and z direction of the source grid
00230          if (get_num_independent_dims(search_data%grid_type) == ndim_3d) then
00231 
00232             do ipart = 1, npart
00233                len(ipart,1) = product (search_data%dim_size(1:2,ipart))
00234                len(ipart,2) = search_data%dim_size(3, ipart)
00235             enddo
00236 
00237          else
00238 
00239             do ipart = 1, npart
00240                len(ipart,1) = search_data%dim_size(1, ipart)
00241                len(ipart,2) = search_data%dim_size(3, ipart)
00242             end do
00243 
00244          endif
00245 
00246          ! For reduced gauss grids in combination with conservative remapping we have
00247          ! two points per cell (lower left and upper right).
00248          ! In order for the multigrid search to take all points into account we need
00249          ! to extent the search range.
00250          if ( search_data%grid_type == PRISM_Gaussreduced_regvrt .and. &
00251               requires_conserv_remap) then
00252 
00253             search_data%range(2, 1, 1:npart) = 2 * search_data%range(2, 1, 1:npart) - &
00254                                                    search_data%range(1, 1, 1:npart) + 1
00255             search_data%shape(2, 1, 1:npart) = search_data%range(2, 1, 1:npart)
00256          endif
00257 
00258          do ipart = 1, npart
00259             Allocate (found(ipart,1)%vector(len(ipart,1)), &
00260                       locations(ipart,1)%vector(ndim_2d*len(ipart,1)), &
00261                       found(ipart,2)%vector(len(ipart,2)), &
00262                       locations(ipart,2)%vector(len(ipart,2)), STAT = ierror)
00263             if ( ierror > 0 ) then
00264                ierrp (1) = ierror
00265                ierrp (2) = (ndim_2d+1) * len(ipart,1) + 2*len (ipart,2)
00266                ierror = PRISM_Error_Alloc
00267                call psmile_error ( ierror, 'found(ipart,1:2)%vector, locations(ipart,1:2)%vector', &
00268                                    ierrp, 2, __FILE__, __LINE__ )
00269                return
00270             endif
00271             Nullify (found(ipart,3)%vector, locations(ipart,3)%vector)
00272          end do ! ipart
00273 
00274          do ipart = 1, npart
00275             found    (ipart,1)%vector (:) = nlev1
00276             found    (ipart,2)%vector (:) = nlev1
00277 
00278             locations(ipart,1)%vector (:) = 0
00279             locations(ipart,2)%vector (:) = 0
00280          end do ! ipart
00281 
00282       case (ndim_1d) ! 1 independent dimension
00283                      ! Irregular in lonlat and vertical direction
00284 
00285 !    len (ipart, i) = Length of last dimension of vectors
00286 !                     found (ipart,i) and locations (ipart,i)
00287 !                   = Number of coordinates to be searched
00288 
00289           ierrp (1) = Grids(grid_id)%grid_type
00290           ierror = PRISM_Error_Internal
00291 
00292           call psmile_error ( ierror, 'untested part of the code', &
00293                               ierrp, 1, __FILE__, __LINE__ )
00294 
00295 
00296          ! compute the size of the found and location arrays
00297          ! 1 vector for all directions
00298          do ipart = 1, npart
00299             len(ipart,1) = product(search_data%range (2,1:ndim_3d,ipart) - &
00300                                    search_data%range (1,1:ndim_3d,ipart) + 1)
00301          end do
00302 
00303          do ipart = 1, npart
00304             Allocate (found(ipart,1)%vector(len(ipart,1)), &
00305                       locations(ipart,1)%vector(ndim_3d*len(ipart,1)), STAT = ierror)
00306             if ( ierror > 0 ) then
00307                ierrp (1) = ierror
00308                ierrp (2) = (ndim_3d+1)*len(ipart,1)
00309                ierror = PRISM_Error_Alloc
00310                call psmile_error ( ierror, 'found(ipart,1)%vector, locations(ipart,1)%vector', &
00311                                    ierrp, 2, __FILE__, __LINE__ )
00312                return
00313             endif
00314             Nullify (found(ipart,2)%vector, locations(ipart,2)%vector, &
00315                      found(ipart,3)%vector, locations(ipart,3)%vector)
00316          end do ! ipart
00317 
00318          do ipart = 1, npart
00319             found    (ipart,1)%vector (:) = nlev1
00320             locations(ipart,1)%vector (:) = 0
00321          end do ! ipart
00322 
00323       case DEFAULT
00324 !
00325           ierrp (1) = Grids(grid_id)%grid_type
00326           ierror = PRISM_Error_Internal
00327 
00328           call psmile_error ( ierror, 'unsupported grid type', &
00329                               ierrp, 1, __FILE__, __LINE__ )
00330 
00331       end select ! n_vec
00332 
00333 ! -----------------------------------------------------------------------
00334 !      Do the search on the multigrid and afterwards the actual search
00335 !      + everything else there is to do
00336 ! -----------------------------------------------------------------------
00337       
00338       select case ( n_vec )
00339 
00340       case (ndim_3d) ! 3 independent dimension
00341                      ! regular in all 3 directions
00342 
00343          ! Search locations separately in all 3 directions
00344          if (datatype == MPI_REAL) then
00345 
00346             do ipart = 1, npart
00347                do i = 1, ndim_3d
00348                   call psmile_mg_search_1d_real (grid_id, i,            &
00349                               found(ipart,i)%vector,                    &
00350                               locations(ipart,i)%vector,                &
00351                               search_data%search_real(i, ipart)%vector, &
00352                               search_data%dim_size(i, ipart), rtol, ierror)
00353                   if (ierror > 0) return
00354                end do
00355             end do ! ipart
00356 
00357          else if (datatype == MPI_DOUBLE_PRECISION) then
00358 
00359             do ipart = 1, npart
00360                do i = 1, ndim_3d
00361                   call psmile_mg_search_1d_dble (grid_id, i,            &
00362                               found(ipart,i)%vector,                    &
00363                               locations(ipart,i)%vector,                &
00364                               search_data%search_dble(i, ipart)%vector, &
00365                               search_data%dim_size(i, ipart), tol, ierror)
00366                   if (ierror > 0) return
00367                end do
00368             end do ! ipart
00369 
00370 #if defined ( PRISM_QUAD_TYPE )
00371          else if (datatype == MPI_REAL16) then
00372 
00373             do ipart = 1, npart
00374                do i = 1, ndim_3d
00375                   call psmile_mg_search_1d_quad (grid_id, i,            &
00376                               found(ipart,i)%vector,                    &
00377                               locations(ipart,i)%vector,                &
00378                               search_data%search_quad(i, ipart)%vector, &
00379                               search_data%dim_size(i, ipart), qtol, ierror)
00380                   if (ierror > 0) return
00381                end do
00382             end do ! ipart
00383 
00384 #endif
00385          endif
00386 
00387       case (ndim_2d) !    2 independent dimesions
00388                      !    Irregular in lonlat   direction
00389                      !    Regular   in vertical direction
00390 
00391          if (datatype == MPI_REAL) then
00392 
00393             do ipart = 1, npart
00394                call psmile_mg_search_2d_real (grid_id,                       &
00395                            found(ipart,1)%vector, locations(ipart,1)%vector, &
00396                            len  (ipart,1), search_data, ipart, rtol, ierror)
00397                if (ierror > 0) return
00398 
00399                call psmile_mg_search_1d_real (grid_id, 3,            &
00400                            found    (ipart,2)%vector,                &
00401                            locations(ipart,2)%vector,                &
00402                            search_data%search_real(3, ipart)%vector, &
00403                            search_data%dim_size(3, ipart), rtol, ierror)
00404                if (ierror > 0) return
00405             end do
00406 
00407          else if (datatype == MPI_DOUBLE_PRECISION) then
00408 
00409             do ipart = 1, npart
00410 
00411 #ifdef DEBUG
00412            PRINT*, TRIM(ch_id), ' intersection :',ipart
00413            call psmile_flushstd
00414 #endif
00415                call psmile_mg_search_2d_dble (grid_id,                       &
00416                            found(ipart,1)%vector, locations(ipart,1)%vector, &
00417                            len  (ipart,1), search_data, ipart, tol, ierror)
00418                if (ierror > 0) return
00419 
00420                call psmile_mg_search_1d_dble (grid_id, 3,                    &
00421                            found(ipart,2)%vector, locations(ipart,2)%vector, &
00422                            search_data%search_dble(3, ipart)%vector,         &
00423                            search_data%dim_size(3, ipart), tol, ierror)
00424                if (ierror > 0) return
00425             end do
00426 
00427 #if defined ( PRISM_QUAD_TYPE )
00428          else if (datatype == MPI_REAL16) then
00429 
00430             do ipart = 1, npart
00431                call psmile_mg_search_2d_quad (grid_id,                       &
00432                            found(ipart,1)%vector, locations(ipart,1)%vector, &
00433                            len  (ipart,1), search_data, ipart, qtol, ierror)
00434                if (ierror > 0) return
00435 
00436                call psmile_mg_search_1d_quad (grid_id, 3,                    &
00437                            found(ipart,2)%vector, locations(ipart,2)%vector, &
00438                            search_data%search_quad(3, ipart)%vector,         &
00439                            search_data%dim_size(3, ipart), qtol, ierror)
00440                if (ierror > 0) return
00441             end do
00442 
00443 #endif
00444          endif
00445 
00446       case (ndim_1d) ! 1 independent dimension
00447                      ! Irregular in lonlat   and vertical direction
00448 
00449          if (datatype == MPI_REAL) then
00450 
00451             call psmile_mg_search_3d_real (comp_info,      &
00452                         found(:, 1), locations (:, 1),     &
00453                         len  (:, 1), search_data, grid_id, &
00454                         rtol, ierror)
00455             if (ierror > 0) return
00456 
00457          else if (datatype == MPI_DOUBLE_PRECISION) then
00458 
00459             call psmile_mg_search_3d_dble (comp_info,      &
00460                         found(:, 1), locations (:, 1),     &
00461                         len  (:, 1), search_data, grid_id, &
00462                         tol, ierror)
00463             if (ierror > 0) return
00464 
00465 #if defined ( PRISM_QUAD_TYPE )
00466          else if (datatype == MPI_REAL16) then
00467 
00468             call psmile_mg_search_3d_quad (comp_info,      &
00469                         found(:, 1), locations (:, 1),     &
00470                         len  (:, 1), search_data, grid_id, &
00471                         qtol, ierror)
00472             if (ierror > 0) return
00473 
00474 #endif
00475          endif
00476 
00477       end select ! n_vec
00478 !
00479 !===> All done
00480 !
00481 #ifdef VERBOSE
00482       print 9980, trim(ch_id), ierror
00483 
00484       call psmile_flushstd
00485 #endif /* VERBOSE */
00486 !
00487       return
00488 !
00489 !  Formats:
00490 !
00491 9990 format (1x, a, ': psmile_mg_search:')
00492 9980 format (1x, a, ': psmile_mg_search: eof  ierror =', i4)
00493 
00494       end subroutine psmile_mg_search

Generated on 1 Dec 2011 for Oasis4 by  doxygen 1.6.1