123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385 |
- MODULE obs_inter_sup
- !!=====================================================================
- !! *** MODULE obs_inter_sup ***
- !! Observation diagnostics: Support for interpolation
- !!=====================================================================
- !!----------------------------------------------------------------------
- !! obs_int_comm_3d : Get 3D interpolation stencil
- !! obs_int_comm_2d : Get 2D interpolation stencil
- !!---------------------------------------------------------------------
- !! * Modules used
- USE wrk_nemo ! Memory Allocation
- USE par_kind ! Precision variables
- USE dom_oce ! Domain variables
- USE mpp_map ! Map of processor points
- USE lib_mpp ! MPP stuff
- USE obs_mpp ! MPP stuff for observations
- USE obs_grid ! Grid tools
- USE in_out_manager ! I/O stuff
- IMPLICIT NONE
- !! * Routine accessibility
- PRIVATE
-
- PUBLIC obs_int_comm_3d, & ! Get 3D interpolation stencil
- & obs_int_comm_2d ! Get 2D interpolation stencil
-
- !!----------------------------------------------------------------------
- !! NEMO/OPA 3.3 , NEMO Consortium (2010)
- !! $Id: obs_inter_sup.F90 3294 2012-01-28 16:44:18Z rblod $
- !! Software governed by the CeCILL licence (NEMOGCM/NEMO_CeCILL.txt)
- !!----------------------------------------------------------------------
- CONTAINS
- SUBROUTINE obs_int_comm_3d( kptsi, kptsj, kobs, kpk, kgrdi, kgrdj, &
- & pval, pgval, kproc )
- !!----------------------------------------------------------------------
- !! *** ROUTINE obs_int_comm_3d ***
- !!
- !! ** Purpose : Get 3D interpolation stencil
- !!
- !! ** Method : Either on-demand communication with
- !! obs_int_comm_3d_global
- !! or local memory with
- !! obs_int_comm_3D_local
- !! depending on ln_global_grid
- !!
- !! ** Action :
- !!
- !! History :
- !! ! 08-02 (K. Mogensen) Original code
- !!----------------------------------------------------------------------
- !! * Arguments
- INTEGER, INTENT(IN) :: kptsi ! Number of i horizontal points per stencil
- INTEGER, INTENT(IN) :: kptsj ! Number of j horizontal points per stencil
- INTEGER, INTENT(IN) :: kobs ! Local number of observations
- INTEGER, INTENT(IN) :: kpk ! Number of levels
- INTEGER, DIMENSION(kptsi,kptsj,kobs), INTENT(IN) :: &
- & kgrdi, & ! i,j indicies for each stencil
- & kgrdj
- INTEGER, OPTIONAL, DIMENSION(kptsi,kptsj,kobs), INTENT(IN) :: &
- & kproc ! Precomputed processor for each i,j,iobs points
- REAL(KIND=wp), DIMENSION(jpi,jpj,kpk), INTENT(IN) ::&
- & pval ! Local 3D array to extract data from
- REAL(KIND=wp), DIMENSION(kptsi,kptsj,kpk,kobs), INTENT(OUT) ::&
- & pgval ! Stencil at each point
- !! * Local declarations
-
- IF (ln_grid_global) THEN
-
- IF (PRESENT(kproc)) THEN
- CALL obs_int_comm_3d_global( kptsi, kptsj, kobs, kpk, kgrdi, &
- & kgrdj, pval, pgval, kproc=kproc )
- ELSE
- CALL obs_int_comm_3d_global( kptsi, kptsj, kobs, kpk, kgrdi, &
- & kgrdj, pval, pgval )
- ENDIF
- ELSE
- CALL obs_int_comm_3d_local( kptsi, kptsj, kobs, kpk, kgrdi, kgrdj, &
- & pval, pgval )
- ENDIF
- END SUBROUTINE obs_int_comm_3d
- SUBROUTINE obs_int_comm_2d( kptsi, kptsj, kobs, kgrdi, kgrdj, pval, pgval, &
- & kproc )
- !!----------------------------------------------------------------------
- !! *** ROUTINE obs_int_comm_2d ***
- !!
- !! ** Purpose : Get 2D interpolation stencil
- !!
- !! ** Method : Call to obs_int_comm_3d
- !!
- !! ** Action :
- !!
- !! History :
- !! ! 08-02 (K. Mogensen) Original code
- !!----------------------------------------------------------------------
- !!
- !! * Arguments
- INTEGER, INTENT(IN) :: kptsi ! Number of i horizontal points per stencil
- INTEGER, INTENT(IN) :: kptsj ! Number of j horizontal points per stencil
- INTEGER, INTENT(IN) :: kobs ! Local number of observations
- INTEGER, DIMENSION(kptsi,kptsj,kobs), INTENT(IN) :: &
- & kgrdi, & ! i,j indicies for each stencil
- & kgrdj
- INTEGER, OPTIONAL, DIMENSION(kptsi,kptsj,kobs), INTENT(IN) :: &
- & kproc ! Precomputed processor for each i,j,iobs points
- REAL(KIND=wp), DIMENSION(jpi,jpj), INTENT(IN) ::&
- & pval ! Local 3D array to extra data from
- REAL(KIND=wp), DIMENSION(kptsi,kptsj,kobs), INTENT(OUT) ::&
- & pgval ! Stencil at each point
- !! * Local declarations
- REAL(KIND=wp), POINTER, DIMENSION(:,:,:) :: zval
- REAL(KIND=wp), DIMENSION(kptsi,kptsj,1,kobs) ::&
- & zgval
- ! Check workspace array and set-up pointer
- CALL wrk_alloc(jpi,jpj,1,zval)
- ! Set up local "3D" buffer
- zval(:,:,1) = pval(:,:)
- ! Call the 3D version
- IF (PRESENT(kproc)) THEN
- CALL obs_int_comm_3d( kptsi, kptsj, kobs, 1, kgrdi, kgrdj, zval, &
- & zgval, kproc=kproc )
- ELSE
- CALL obs_int_comm_3d( kptsi, kptsj, kobs, 1, kgrdi, kgrdj, zval, &
- & zgval )
- ENDIF
- ! Copy "3D" data back to 2D
- pgval(:,:,:) = zgval(:,:,1,:)
- ! 'Release' workspace array back to pool
- CALL wrk_dealloc(jpi,jpj,1,zval)
- END SUBROUTINE obs_int_comm_2d
- SUBROUTINE obs_int_comm_3d_global( kptsi, kptsj, kobs, kpk, kgrdi, kgrdj, &
- & pval, pgval, kproc )
- !!----------------------------------------------------------------------
- !! *** ROUTINE obs_int_comm_3d_global ***
- !!
- !! ** Purpose : Get 3D interpolation stencil (global version)
- !!
- !! ** Method : On-demand communication where each processor send its
- !! list of (i,j) of points to all processors and receive
- !! the corresponding values
- !!
- !! ** Action :
- !!
- !! History :
- !! ! 08-02 (K. Mogensen) Original code
- !!----------------------------------------------------------------------
- !! * Arguments
- INTEGER, INTENT(IN) :: kptsi ! Number of i horizontal points per stencil
- INTEGER, INTENT(IN) :: kptsj ! Number of j horizontal points per stencil
- INTEGER, INTENT(IN) :: kobs ! Local number of observations
- INTEGER, INTENT(IN) :: kpk ! Number of levels
- INTEGER, DIMENSION(kptsi,kptsj,kobs), INTENT(IN) :: &
- & kgrdi, & ! i,j indicies for each stencil
- & kgrdj
- INTEGER, OPTIONAL, DIMENSION(kptsi,kptsj,kobs), INTENT(IN) :: &
- & kproc ! Precomputed processor for each i,j,iobs points
- REAL(KIND=wp), DIMENSION(jpi,jpj,kpk), INTENT(IN) ::&
- & pval ! Local 3D array to extract data from
- REAL(KIND=wp), DIMENSION(kptsi,kptsj,kpk,kobs), INTENT(OUT) ::&
- & pgval ! Stencil at each point
- !! * Local declarations
- REAL(KIND=wp), DIMENSION(:,:), ALLOCATABLE :: &
- & zsend, &
- & zrecv
- INTEGER, DIMENSION(:), ALLOCATABLE :: &
- & igrdij_send, &
- & igrdij_recv
- INTEGER, DIMENSION(kptsi,kptsj,kobs) :: &
- & iorder, &
- & iproc
- INTEGER :: nplocal(jpnij)
- INTEGER :: npglobal(jpnij)
- INTEGER :: ji
- INTEGER :: jj
- INTEGER :: jk
- INTEGER :: jp
- INTEGER :: jobs
- INTEGER :: it
- INTEGER :: itot
- INTEGER :: ii
- INTEGER :: ij
- ! Check valid points
-
- IF ( ( MAXVAL(kgrdi) > jpiglo ) .OR. ( MINVAL(kgrdi) < 1 ) .OR. &
- & ( MAXVAL(kgrdj) > jpjglo ) .OR. ( MINVAL(kgrdj) < 1 ) ) THEN
-
- CALL ctl_stop( 'Error in obs_int_comm_3d_global', &
- & 'Point outside global domain' )
-
- ENDIF
- ! Count number of points on each processors
- nplocal(:) = 0
- IF (PRESENT(kproc)) THEN
- iproc(:,:,:) = kproc(:,:,:)
- DO jobs = 1, kobs
- DO jj = 1, kptsj
- DO ji = 1, kptsi
- nplocal(iproc(ji,jj,jobs)) = nplocal(iproc(ji,jj,jobs)) + 1
- END DO
- END DO
- END DO
- ELSE
- DO jobs = 1, kobs
- DO jj = 1, kptsj
- DO ji = 1, kptsi
- iproc(ji,jj,jobs) = mppmap(kgrdi(ji,jj,jobs),&
- & kgrdj(ji,jj,jobs))
- nplocal(iproc(ji,jj,jobs)) = nplocal(iproc(ji,jj,jobs)) + 1
- END DO
- END DO
- END DO
- ENDIF
- ! Send local number of points and receive points on current domain
- CALL mpp_alltoall_int( 1, nplocal, npglobal )
- ! Allocate message parsing workspace
- itot = SUM(npglobal)
- ALLOCATE( &
- & igrdij_send(kptsi*kptsj*kobs*2), &
- & igrdij_recv(itot*2), &
- & zsend(kpk,itot), &
- & zrecv(kpk,kptsi*kptsj*kobs) &
- & )
- ! Pack buffers for list of points
- it = 0
- DO jp = 1, jpnij
- DO jobs = 1, kobs
- DO jj = 1, kptsj
- DO ji = 1, kptsi
- IF ( iproc(ji,jj,jobs) == jp ) THEN
- it = it + 1
- iorder(ji,jj,jobs) = it
- igrdij_send(2*it-1) = kgrdi(ji,jj,jobs)
- igrdij_send(2*it ) = kgrdj(ji,jj,jobs)
- ENDIF
- END DO
- END DO
- END DO
- END DO
- ! Send and recieve buffers for list of points
- CALL mpp_alltoallv_int( igrdij_send, kptsi*kptsj*kobs*2, nplocal(:)*2, &
- & igrdij_recv, itot*2, npglobal(:)*2 )
- ! Pack interpolation data to be sent
- DO ji = 1, itot
- ii = mi1(igrdij_recv(2*ji-1))
- ij = mj1(igrdij_recv(2*ji))
- DO jk = 1, kpk
- zsend(jk,ji) = pval(ii,ij,jk)
- END DO
- END DO
- ! Re-adjust sizes
- nplocal(:) = kpk*nplocal(:)
- npglobal(:) = kpk*npglobal(:)
- ! Send and receive data for interpolation stencil
- CALL mpp_alltoallv_real( zsend, kpk*itot, npglobal, &
- & zrecv, kpk*kptsi*kptsj*kobs, nplocal )
- ! Copy the received data into output data structure
-
- DO jobs = 1, kobs
- DO jj = 1, kptsj
- DO ji = 1, kptsi
- it = iorder(ji,jj,jobs)
- DO jk = 1, kpk
- pgval(ji,jj,jk,jobs) = zrecv(jk,it)
- END DO
- END DO
- END DO
- END DO
- ! Deallocate message parsing workspace
- DEALLOCATE( &
- & igrdij_send, &
- & igrdij_recv, &
- & zsend, &
- & zrecv &
- & )
- END SUBROUTINE obs_int_comm_3d_global
-
- SUBROUTINE obs_int_comm_3d_local( kptsi, kptsj, kobs, kpk, kgrdi, kgrdj, &
- & pval, pgval )
- !!----------------------------------------------------------------------
- !! *** ROUTINE obs_int_comm_3d_global ***
- !!
- !! ** Purpose : Get 3D interpolation stencil (global version)
- !!
- !! ** Method : On-demand communication where each processor send its
- !! list of (i,j) of points to all processors and receive
- !! the corresponding values
- !!
- !! ** Action :
- !!
- !! History :
- !! ! 08-02 (K. Mogensen) Original code
- !!----------------------------------------------------------------------
- !! * Arguments
- INTEGER, INTENT(IN) :: kptsi ! Number of i horizontal points per stencil
- INTEGER, INTENT(IN) :: kptsj ! Number of j horizontal points per stencil
- INTEGER, INTENT(IN) :: kobs ! Local number of observations
- INTEGER, INTENT(IN) :: kpk ! Number of levels
- INTEGER, DIMENSION(kptsi,kptsj,kobs), INTENT(IN) :: &
- & kgrdi, & ! i,j indicies for each stencil
- & kgrdj
- REAL(KIND=wp), DIMENSION(jpi,jpj,kpk), INTENT(IN) ::&
- & pval ! Local 3D array to extract data from
- REAL(KIND=wp), DIMENSION(kptsi,kptsj,kpk,kobs), INTENT(OUT) ::&
- & pgval ! Stencil at each point
- !! * Local declarations
- INTEGER :: ji
- INTEGER :: jj
- INTEGER :: jk
- INTEGER :: jobs
- ! Check valid points
- IF ( ( MAXVAL(kgrdi) > jpi ) .OR. ( MINVAL(kgrdi) < 1 ) .OR. &
- & ( MAXVAL(kgrdj) > jpj ) .OR. ( MINVAL(kgrdj) < 1 ) ) THEN
-
- CALL ctl_stop( 'Error in obs_int_comm_3d_local', &
- & 'Point outside local domain' )
-
- ENDIF
- ! Copy local data
- DO jobs = 1, kobs
- DO jj = 1, kptsj
- DO ji = 1, kptsi
- DO jk = 1, kpk
- pgval(ji,jj,jk,jobs) = &
- & pval(kgrdi(ji,jj,jobs),kgrdj(ji,jj,jobs),jk)
- END DO
- END DO
- END DO
- END DO
- END SUBROUTINE obs_int_comm_3d_local
- END MODULE obs_inter_sup
-
|