psmile_gauss_setup.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_gauss_setup
00009 !
00010 ! !INTERFACE:
00011 
00012       subroutine psmile_gauss_setup (grid_id, ierror)
00013 !
00014 ! !USES:
00015 !
00016       use prism_constants
00017       use psmile, dummy_interface => psmile_gauss_setup
00018       use psmile_grid_reduced_gauss
00019 
00020       implicit none
00021 !
00022 ! !INPUT PARAMETERS:
00023 !
00024       integer, intent (in)                :: grid_id
00025 !
00026 ! !OUTPUT PARAMETERS:
00027 !
00028       integer, intent (out)               :: ierror
00029 
00030 !     Returns the error code of PSMILe_MG_first_level;
00031 !             ierror = 0 : No error
00032 !             ierror > 0 : Severe error
00033 !
00034 ! !LOCAL VARIABLES
00035 !
00036       type(grid), pointer                 :: gp
00037 !
00038 !  ... for Gaussian reduced grids
00039 !
00040       integer                             :: j, n, i
00041       integer                             :: leny, lenz
00042       type (block_info), pointer          :: local_block_info(:)
00043 !
00044 !  ... for error parameters
00045 !
00046       integer, parameter                  :: nerrp = 2
00047       integer                             :: ierrp (nerrp)
00048 !
00049 ! !DESCRIPTION:
00050 !
00051 ! Subroutine "PSMILe_gauss_setup" computes the auxiliary grid
00052 ! for search on reduced Gauss grids. In addition, it collect
00053 ! corner and point (method) data from neighbouring processes
00054 ! and builts the face and star arrays for reduced gauss grids,
00055 ! which are used to construct the stencils for linear and
00056 ! bicuibis interpolation.
00057 !
00058 !
00059 ! !REVISION HISTORY:
00060 !
00061 !   Date      Programmer   Description
00062 ! ----------  ----------   -----------
00063 ! 05.12.02    R. Redler    created
00064 ! 09.01.11    M. Hanke     rewrote computation of aux. grid
00065 !
00066 !EOP
00067 !----------------------------------------------------------------------
00068 !
00069 !  $Id: psmile_gauss_setup.F90 3010 2011-03-10 13:26:49Z hanke $
00070 !  $Author: hanke $
00071 !
00072    Character(len=len_cvs_string), save :: mycvs = 
00073        '$Id: psmile_gauss_setup.F90 3010 2011-03-10 13:26:49Z hanke $'
00074 !
00075 !----------------------------------------------------------------------
00076 
00077 #ifdef VERBOSE
00078       print *, trim(ch_id), ': psmile_gauss_setup: grid_id', grid_id
00079       call psmile_flushstd
00080 #endif /* VERBOSE */
00081 !
00082 !  Initialization
00083 !
00084       ierror = 0
00085 
00086       gp => Grids(grid_id)
00087 
00088 ! from mg_setup
00089 
00090       lenz = gp%grid_shape(2,3)-gp%grid_shape(1,3)+1
00091 
00092       if ( associated(gp%extent) ) then ! partitions are defined
00093 
00094          leny = size(gp%extent(:,1))
00095 
00096 #ifdef DEBUG
00097          print *, trim(ch_id), ': psmile_gauss_setup: we have ', leny, ' partitions.'
00098 #endif /* DEBUG */
00099 
00100 
00101       else ! we have to assume only one global grid partition
00102 
00103 #ifdef DEBUG
00104          print *, trim(ch_id), ': psmile_gauss_setup: we assume to have only one global grid partition'
00105 #endif /* DEBUG */
00106 
00107          leny = size(gp%nbr_points_per_lat)
00108 
00109          allocate(gp%extent(leny,2), gp%partition(leny,2), STAT = ierror)
00110          if ( ierror > 0 ) then
00111             ierrp (1) = ierror
00112             ierrp (2) = 2*leny
00113             ierror = PRISM_Error_Alloc
00114             call psmile_error ( ierror, 'partition and extent', &
00115                  ierrp, 2, __FILE__, __LINE__ )
00116             return
00117          endif
00118 
00119          gp%extent(:,1) = gp%nbr_points_per_lat(:)
00120          gp%partition(1,1) = 0
00121 
00122          do n = 2, leny
00123             gp%partition(n,1) = sum(gp%nbr_points_per_lat(1:n-1))
00124          enddo
00125 
00126          gp%extent(:,2) = lenz
00127          gp%partition(:,2) = 0
00128 
00129       endif ! ( associated(gp%extent) )
00130       
00131       ! generate the auxiliary grid (used by the multigrid search instead of the reduced gauss grid)
00132       call psmile_gauss_gen_aux_grid (grid_id)
00133       ! generate a mapping between the auxiliary grid and the reduced gauss grid
00134       call psmile_gauss_gen_aux_grid_map (grid_id)
00135 
00136       Allocate (gp%gcorner_pointer, STAT = ierror)
00137       if ( ierror > 0 ) then
00138          ierrp (1) = ierror
00139          ierrp (2) = leny*2
00140          ierror = PRISM_Error_Alloc
00141          call psmile_error ( ierror, 'gcorner_pointer', &
00142               ierrp, 2, __FILE__, __LINE__ )
00143          return
00144       endif
00145 
00146       gp%gcorner_pointer%corner_shape = &
00147                         reshape ((/1,size (gp%reduced_gauss_data%aux_corners(1)%vector)/2,   &
00148                                    1,size (gp%reduced_gauss_data%aux_corners(2)%vector)/2,   &
00149                                    1,size (gp%reduced_gauss_data%aux_corners(3)%vector)/2/), &
00150                                  (/2,ndim_3d/))
00151       gp%gcorner_pointer%corner_datatype = gp%corner_pointer%corner_datatype
00152       gp%gcorner_pointer%corners_dble(1)%vector => gp%reduced_gauss_data%aux_corners(1)%vector
00153       gp%gcorner_pointer%corners_dble(2)%vector => gp%reduced_gauss_data%aux_corners(2)%vector
00154       gp%gcorner_pointer%corners_dble(3)%vector => gp%reduced_gauss_data%aux_corners(3)%vector
00155 !
00156 !===> Generate some additional data on the blocks of the local partition (used for optimisation)
00157 !
00158       allocate (local_block_info(size (gp%partition, 1)))
00159       if ( ierror > 0 ) then
00160          ierrp (1) = ierror
00161          ierrp (2) = size (gp%partition, 1)
00162          ierror = PRISM_Error_Alloc
00163          call psmile_error ( ierror, 'local_block_info', &
00164               ierrp, 2, __FILE__, __LINE__ )
00165          return
00166       endif
00167 
00168       local_block_info(:)%global_1d_start_idx = gp%partition(:,1) + 1
00169       local_block_info(:)%global_1d_end_idx = gp%partition(:,1) + gp%extent(:,1)
00170 
00171       local_block_info(:)%local_1d_start_idx =                           &
00172          psmile_gauss_1d_global_to_local(grid_id, gp%partition(:,1) + 1, &
00173                                          size (gp%partition, 1),         &
00174                                          psmile_undef, .false.)
00175 
00176       local_block_info(:)%local_1d_end_idx =                          &
00177          psmile_gauss_1d_global_to_local(grid_id, gp%partition(:,1) + &
00178                                          gp%extent(:,1),              &
00179                                          size (gp%partition, 1),      &
00180                                          psmile_undef, .false.)
00181 
00182       do i = 1, size (gp%partition, 1)
00183 
00184          local_block_info(i)%global_3d_start_idx = &
00185             psmile_gauss_local_1d_to_3d(grid_id, local_block_info(i)%local_1d_start_idx)
00186             
00187          local_block_info(i)%global_3d_end_idx = &
00188             psmile_gauss_local_1d_to_3d(grid_id, local_block_info(i)%local_1d_end_idx)
00189       enddo ! i
00190       
00191       gp%reduced_gauss_data%local_block_info => local_block_info
00192       nullify (local_block_info)
00193 !
00194 !===> Define range of auxiliary grid (needed in tricu and trili interpolation)
00195 !  nbr_lats = leny
00196 !  points_per_lat = gp%extent
00197 !
00198       Allocate (gp%g_irange(leny,2), STAT = ierror)
00199       if ( ierror > 0 ) then
00200          ierrp (1) = ierror
00201          ierrp (2) = leny * 2
00202          ierror = PRISM_Error_Alloc
00203          call psmile_error ( ierror, 'g_irange', &
00204               ierrp, 2, __FILE__, __LINE__ )
00205          return
00206       endif
00207 !
00208       gp%g_irange(1,1) = 1
00209       gp%g_irange(1,2) = gp%extent(1,1)
00210 
00211 !cdir vector
00212       do j = 2, leny
00213          gp%g_irange(j,1) = gp%g_irange(j-1,2) + 1
00214          gp%g_irange(j,2) = gp%g_irange(j-1,2) + gp%extent(j,1)
00215       enddo
00216 
00217       ! construct face and star array and collect corner information
00218       ! from neighbouring processes
00219 
00220       call psmile_gauss_get_neighbours ( grid_id, ierror )
00221 
00222       !
00223       !===> Free Memory
00224       !
00225       if ( associated(gp%get_list) ) then
00226          do n = 0, Comps(gp%comp_id)%size-1
00227             if (associated(gp%get_list(n)%vector)) &
00228                 deallocate(gp%get_list(n)%vector)
00229          enddo
00230          deallocate (gp%get_list)
00231       endif
00232 
00233       if ( associated(gp%put_list) ) then
00234          do n = 0, Comps(gp%comp_id)%size-1
00235             if (associated(gp%put_list(n)%vector)) &
00236                 deallocate(gp%put_list(n)%vector)
00237          enddo
00238          deallocate (gp%put_list)
00239       endif
00240 !
00241 !===> All done
00242 !
00243 #ifdef VERBOSE
00244       print *, trim(ch_id), ': psmile_gauss_setup eof: grid_id',&
00245                              grid_id, ', ierror =', ierror
00246 
00247       call psmile_flushstd
00248 #endif /* VERBOSE */
00249 
00250       end subroutine psmile_gauss_setup

Generated on 18 Mar 2011 for Oasis4 by  doxygen 1.6.1