Skip to content
Snippets Groups Projects
agrif_user.F90 63 KiB
Newer Older
Guillaume Samson's avatar
Guillaume Samson committed
         ! Check zoom position along j:
         ! ----------------------------
         IF ( jmin >= jmax ) THEN
            CALL ctl_stop( 'STOP', 'AGRIF zoom jmin must be < jmax' )
         ENDIF

         IF ( Agrif_Parent(l_NFold) ) THEN
            IF ( l_NFold ) THEN ! North-Fold 
               lk_north = .FALSE.
               ! Checks:
               IF ( jmax/=Agrif_Parent(Nj0glo)+1-Agrif_Parent(nbghostcells_y_s)) THEN 
                  WRITE(ctmp1, 9000) ' AGRIF zoom has a North-Fold, jmax must = ', &
                  Agrif_Parent(Nj0glo) + 1 - Agrif_Parent(nbghostcells_y_s)
                  CALL ctl_stop( 'STOP', ctmp1 )
               ENDIF
            ENDIF
         ELSE
            IF ( jmax>Agrif_Parent(Nj0glo)-Agrif_Parent(nbghostcells_y_s)) THEN 
               WRITE(ctmp1, 9000) ' AGRIF zoom jmax must be <= ', &
               Agrif_Parent(Nj0glo) - Agrif_Parent(nbghostcells_y_s)
               CALL ctl_stop( 'STOP', ctmp1 )
            ENDIF
            IF ( jmax==Agrif_Parent(Nj0glo)-Agrif_Parent(nbghostcells_y_s) ) lk_north = .FALSE. 
         ENDIF

         IF ( jmin<2-Agrif_Parent(nbghostcells_y_s)) THEN 
            WRITE(ctmp1, 9000) ' AGRIF zoom jmin must be >= ', &
            2 - Agrif_Parent(nbghostcells_y_s)
            CALL ctl_stop( 'STOP', ctmp1 )
         ENDIF
         IF ( jmin==2-Agrif_Parent(nbghostcells_y_s) ) lk_south = .FALSE. 

      ELSE ! Root grid
         lk_west  = .FALSE. ; lk_east  = .FALSE.
         lk_north = .FALSE. ; lk_south = .FALSE.
      ENDIF
  
      ! Set ghost cells including over Parent grid: 
      nbghostcells_x_w = nbghostcells
      nbghostcells_x_e = nbghostcells
      nbghostcells_y_s = nbghostcells
      nbghostcells_y_n = nbghostcells

      IF (.NOT.lk_west ) nbghostcells_x_w = 1
      IF (.NOT.lk_east ) nbghostcells_x_e = 1
      IF (.NOT.lk_south) nbghostcells_y_s = 1
      IF (.NOT.lk_north) nbghostcells_y_n = 1

      IF ( l_Iperio ) THEN
         nbghostcells_x_w = 0 ; nbghostcells_x_e = 0
      ENDIF
      IF ( l_NFold ) THEN
         nbghostcells_y_n = 0
      ENDIF
      
      IF ( .NOT.Agrif_Root() ) THEN ! Check expected grid size: 
         IF( (.NOT.ln_vert_remap).AND.(jpkglo>Agrif_Parent(jpkglo)) )   CALL ctl_stop( 'STOP',    &
           &   'AGRIF children must have less or equal number of vertical levels without ln_vert_remap defined' ) 
         IF( Ni0glo /= nbcellsx + nbghostcells_x_w + nbghostcells_x_e ) CALL ctl_stop( 'STOP',    &
           &   'AGRIF children requires jpiglo == nbcellsx + nbghostcells_x_w + nbghostcells_x_e' )
         IF( Nj0glo /= nbcellsy + nbghostcells_y_s + nbghostcells_y_n ) CALL ctl_stop( 'STOP',    &
           &   'AGRIF children requires jpjglo == nbcellsy + nbghostcells_y_s + nbghostcells_y_n' )
         IF( ln_use_jattr )   CALL ctl_stop( 'STOP', 'AGRIF children requires ln_use_jattr = .false. ' )

         IF(lwp) THEN                     ! Control print
            WRITE(numout,*)
            WRITE(numout,*) 'AGRIF boundaries and ghost cells:'
            WRITE(numout,*) 'lk_west' , lk_west
            WRITE(numout,*) 'lk_east' , lk_east
            WRITE(numout,*) 'lk_south', lk_south
            WRITE(numout,*) 'lk_north', lk_north
            WRITE(numout,*) 'nbghostcells_y_s', nbghostcells_y_s
            WRITE(numout,*) 'nbghostcells_y_n', nbghostcells_y_n
            WRITE(numout,*) 'nbghostcells_x_w', nbghostcells_x_w
            WRITE(numout,*) 'nbghostcells_x_e', nbghostcells_x_e
         ENDIF
      ENDIF

9000  FORMAT (a, i4)
      !
      !
   END SUBROUTINE agrif_nemo_init

   
# if ! defined key_mpi_off
   SUBROUTINE Agrif_InvLoc( indloc, nprocloc, i, indglob )
      !!----------------------------------------------------------------------
      !!                     *** ROUTINE Agrif_InvLoc ***
      !!----------------------------------------------------------------------
      USE dom_oce
      !!
      IMPLICIT NONE
      !
      INTEGER :: indglob, indloc, nprocloc, i
      !!----------------------------------------------------------------------
      !
      SELECT CASE( i )
      CASE(1)        ;   indglob = mig(indloc,nn_hls)
      CASE(2)        ;   indglob = mjg(indloc,nn_hls)
Guillaume Samson's avatar
Guillaume Samson committed
      CASE DEFAULT   ;   indglob = indloc
      END SELECT
      !
   END SUBROUTINE Agrif_InvLoc

   
   SUBROUTINE Agrif_get_proc_info( imin, imax, jmin, jmax )
      !!----------------------------------------------------------------------
      !!                 *** ROUTINE Agrif_get_proc_info ***
      !!----------------------------------------------------------------------
      USE par_oce
      !!
      IMPLICIT NONE
      !
      INTEGER, INTENT(out) :: imin, imax
      INTEGER, INTENT(out) :: jmin, jmax
      !!----------------------------------------------------------------------
      !
      imin = mig( 1 ,nn_hls)
      jmin = mjg( 1 ,nn_hls)
      imax = mig(jpi,nn_hls)
      jmax = mjg(jpj,nn_hls)
Guillaume Samson's avatar
Guillaume Samson committed
      ! 
   END SUBROUTINE Agrif_get_proc_info

   
   SUBROUTINE Agrif_estimate_parallel_cost(imin, imax,jmin, jmax, nbprocs, grid_cost)
      !!----------------------------------------------------------------------
      !!                 *** ROUTINE Agrif_estimate_parallel_cost ***
      !!----------------------------------------------------------------------
      USE par_oce
      !!
      IMPLICIT NONE
      !
      INTEGER,  INTENT(in)  :: imin, imax
      INTEGER,  INTENT(in)  :: jmin, jmax
      INTEGER,  INTENT(in)  :: nbprocs
      REAL(wp), INTENT(out) :: grid_cost
      !!----------------------------------------------------------------------
      !
      grid_cost = REAL(imax-imin+1,wp)*REAL(jmax-jmin+1,wp) / REAL(nbprocs,wp)
      !
   END SUBROUTINE Agrif_estimate_parallel_cost

# endif

   SUBROUTINE nemo_mapping(ndim,ptx,pty,bounds,bounds_chunks,correction_required,nb_chunks)
      !!----------------------------------------------------------------------
      !!                   *** ROUTINE Nemo_mapping ***
      !!----------------------------------------------------------------------
      USE dom_oce
      !!
      IMPLICIT NONE
      !
      INTEGER :: ndim
      INTEGER :: ptx, pty
      INTEGER, DIMENSION(ndim,2,2) :: bounds
      INTEGER, DIMENSION(:,:,:,:), ALLOCATABLE :: bounds_chunks
      LOGICAL, DIMENSION(:), ALLOCATABLE :: correction_required
      INTEGER :: nb_chunks
      !
      INTEGER :: i

      IF (agrif_debug_interp) THEN
         DO i=1,ndim
            WRITE(*,*) 'direction = ',i,bounds(i,1,2),bounds(i,2,2)
         ENDDO
      ENDIF

      IF(( bounds(2,2,2) > jpjglo).AND. ( l_NFold )) THEN
         IF( bounds(2,1,2) <=jpjglo) THEN
            nb_chunks = 2
            ALLOCATE(bounds_chunks(nb_chunks,ndim,2,2))
            ALLOCATE(correction_required(nb_chunks))
            DO i = 1,nb_chunks
               bounds_chunks(i,:,:,:) = bounds
            END DO
        
      ! FIRST CHUNCK (for j<=jpjglo)   

      ! Original indices
            bounds_chunks(1,1,1,1) = bounds(1,1,2)
            bounds_chunks(1,1,2,1) = bounds(1,2,2)
            bounds_chunks(1,2,1,1) = bounds(2,1,2)
            bounds_chunks(1,2,2,1) = jpjglo

            bounds_chunks(1,1,1,2) = bounds(1,1,2)
            bounds_chunks(1,1,2,2) = bounds(1,2,2)
            bounds_chunks(1,2,1,2) = bounds(2,1,2)
            bounds_chunks(1,2,2,2) = jpjglo

      ! Correction required or not
            correction_required(1)=.FALSE.
       
      ! SECOND CHUNCK (for j>jpjglo)

      ! Original indices
            bounds_chunks(2,1,1,1) = bounds(1,1,2)
            bounds_chunks(2,1,2,1) = bounds(1,2,2)
            bounds_chunks(2,2,1,1) = jpjglo-2
            bounds_chunks(2,2,2,1) = bounds(2,2,2)

      ! Where to find them
      ! We use the relation TAB(ji,jj)=TAB(jpiglo-ji+2,jpjglo-2-(jj-jpjglo))

            IF( ptx == 2) THEN ! T, V points
               bounds_chunks(2,1,1,2) = jpiglo-bounds(1,2,2)+2
               bounds_chunks(2,1,2,2) = jpiglo-bounds(1,1,2)+2
            ELSE ! U, F points
               bounds_chunks(2,1,1,2) = jpiglo-bounds(1,2,2)+1
               bounds_chunks(2,1,2,2) = jpiglo-bounds(1,1,2)+1       
            ENDIF

            IF( pty == 2) THEN ! T, U points
               bounds_chunks(2,2,1,2) = jpjglo-2*nn_hls-(bounds(2,2,2) -jpjglo)
               bounds_chunks(2,2,2,2) = jpjglo-2*nn_hls-(jpjglo-2      -jpjglo)
            ELSE ! V, F points
               bounds_chunks(2,2,1,2) = jpjglo-2*nn_hls-1-(bounds(2,2,2) -jpjglo)
               bounds_chunks(2,2,2,2) = jpjglo-2*nn_hls-1-(jpjglo-2      -jpjglo)
            ENDIF
      ! Correction required or not
            correction_required(2)=.TRUE.

         ELSE
            nb_chunks = 1
            ALLOCATE(bounds_chunks(nb_chunks,ndim,2,2))
            ALLOCATE(correction_required(nb_chunks))
            DO i=1,nb_chunks
               bounds_chunks(i,:,:,:) = bounds
            END DO

            bounds_chunks(1,1,1,1) = bounds(1,1,2)
            bounds_chunks(1,1,2,1) = bounds(1,2,2)
            bounds_chunks(1,2,1,1) = bounds(2,1,2)
            bounds_chunks(1,2,2,1) = bounds(2,2,2)

            bounds_chunks(1,1,1,2) = jpiglo-bounds(1,2,2)+2
            bounds_chunks(1,1,2,2) = jpiglo-bounds(1,1,2)+2

            bounds_chunks(1,2,1,2) = jpjglo-2*nn_hls-(bounds(2,2,2)-jpjglo)
            bounds_chunks(1,2,2,2) = jpjglo-2*nn_hls-(bounds(2,1,2)-jpjglo)

            IF( ptx == 2) THEN ! T, V points
               bounds_chunks(1,1,1,2) = jpiglo-bounds(1,2,2)+2
               bounds_chunks(1,1,2,2) = jpiglo-bounds(1,1,2)+2
            ELSE ! U, F points
               bounds_chunks(1,1,1,2) = jpiglo-bounds(1,2,2)+1
               bounds_chunks(1,1,2,2) = jpiglo-bounds(1,1,2)+1    	
            ENDIF

            IF (pty == 2) THEN ! T, U points
               bounds_chunks(1,2,1,2) = jpjglo-2*nn_hls-(bounds(2,2,2) -jpjglo)
               bounds_chunks(1,2,2,2) = jpjglo-2*nn_hls-(bounds(2,1,2) -jpjglo)
            ELSE ! V, F points
               bounds_chunks(1,2,1,2) = jpjglo-2*nn_hls-1-(bounds(2,2,2) -jpjglo)
               bounds_chunks(1,2,2,2) = jpjglo-2*nn_hls-1-(bounds(2,1,2) -jpjglo)
            ENDIF

            correction_required(1)=.TRUE.          
         ENDIF

      ELSE IF ((bounds(1,1,2) < 1).AND.( l_Iperio )) THEN
         IF (bounds(1,2,2) > 0) THEN
            nb_chunks = 2
            ALLOCATE(correction_required(nb_chunks))
            correction_required=.FALSE.
            ALLOCATE(bounds_chunks(nb_chunks,ndim,2,2))
            DO i=1,nb_chunks
               bounds_chunks(i,:,:,:) = bounds
            END DO
              
            bounds_chunks(1,1,1,2) = bounds(1,1,2)+jpiglo-2*nn_hls
            bounds_chunks(1,1,2,2) = jpiglo-nn_hls
          
            bounds_chunks(1,1,1,1) = bounds(1,1,2)
            bounds_chunks(1,1,2,1) = nn_hls+1 
       
            bounds_chunks(2,1,1,2) = nn_hls+1 
            bounds_chunks(2,1,2,2) = bounds(1,2,2)
          
            bounds_chunks(2,1,1,1) = nn_hls+1 
            bounds_chunks(2,1,2,1) = bounds(1,2,2)
           
         ELSE
            nb_chunks = 1
            ALLOCATE(correction_required(nb_chunks))
            correction_required=.FALSE.
            ALLOCATE(bounds_chunks(nb_chunks,ndim,2,2))
            DO i=1,nb_chunks
               bounds_chunks(i,:,:,:) = bounds
            END DO    
            bounds_chunks(1,1,1,2) = bounds(1,1,2)+jpiglo-2*nn_hls
            bounds_chunks(1,1,2,2) = bounds(1,2,2)+jpiglo-2*nn_hls
          
            bounds_chunks(1,1,1,1) = bounds(1,1,2)
            bounds_chunks(1,1,2,1) = bounds(1,2,2)
         ENDIF
      ELSE
         nb_chunks=1  
         ALLOCATE(correction_required(nb_chunks))
         correction_required=.FALSE.
         ALLOCATE(bounds_chunks(nb_chunks,ndim,2,2))
         DO i=1,nb_chunks
            bounds_chunks(i,:,:,:) = bounds
         END DO
         bounds_chunks(1,1,1,2) = bounds(1,1,2)
         bounds_chunks(1,1,2,2) = bounds(1,2,2)
         bounds_chunks(1,2,1,2) = bounds(2,1,2)
         bounds_chunks(1,2,2,2) = bounds(2,2,2)
          
         bounds_chunks(1,1,1,1) = bounds(1,1,2)
         bounds_chunks(1,1,2,1) = bounds(1,2,2)
         bounds_chunks(1,2,1,1) = bounds(2,1,2)
         bounds_chunks(1,2,2,1) = bounds(2,2,2)              
      ENDIF
        
   END SUBROUTINE nemo_mapping

   FUNCTION agrif_external_switch_index(ptx,pty,i1,isens)

      USE dom_oce
      !
      IMPLICIT NONE

      INTEGER :: ptx, pty, i1, isens
      INTEGER :: agrif_external_switch_index
      !!----------------------------------------------------------------------

      IF( isens == 1 ) THEN
         IF( ptx == 2 ) THEN ! T, V points
            agrif_external_switch_index = jpiglo-i1+2
         ELSE ! U, F points
            agrif_external_switch_index = jpiglo-i1+1 
         ENDIF
      ELSE IF( isens ==2 ) THEN
         IF ( pty == 2 ) THEN ! T, U points
            agrif_external_switch_index = jpjglo-2*nn_hls-(i1 -jpjglo)
         ELSE ! V, F points
            agrif_external_switch_index = jpjglo-2*nn_hls-1-(i1 -jpjglo)
         ENDIF
      ENDIF

   END FUNCTION agrif_external_switch_index

   SUBROUTINE Correct_field(tab2d,i1,i2,j1,j2)
      !!----------------------------------------------------------------------
      !!                   *** ROUTINE Correct_field ***
      !!----------------------------------------------------------------------
      USE dom_oce
      USE agrif_oce
      !
      IMPLICIT NONE
      !
      INTEGER :: i1,i2,j1,j2
      REAL(wp), DIMENSION(i1:i2,j1:j2) :: tab2d
      !
      INTEGER :: i,j
      REAL(wp), DIMENSION(i1:i2,j1:j2) :: tab2dtemp
      !!----------------------------------------------------------------------

      tab2dtemp = tab2d

      IF( .NOT. use_sign_north ) THEN
         DO j=j1,j2
            DO i=i1,i2
               tab2d(i,j)=tab2dtemp(i2-(i-i1),j2-(j-j1))
            END DO
         END DO
      ELSE
         DO j=j1,j2
            DO i=i1,i2
               tab2d(i,j)=sign_north * tab2dtemp(i2-(i-i1),j2-(j-j1))
            END DO
         END DO
      ENDIF

   END SUBROUTINE Correct_field

#else
   SUBROUTINE Subcalledbyagrif
      !!----------------------------------------------------------------------
      !!                   *** ROUTINE Subcalledbyagrif ***
      !!----------------------------------------------------------------------
      WRITE(*,*) 'Impossible to be here'
   END SUBROUTINE Subcalledbyagrif
#endif