*IF DEF,S40_1A                                                             SJC0F305.3      
C ******************************COPYRIGHT******************************    GTS2F400.9037   
C (c) CROWN COPYRIGHT 1995, METEOROLOGICAL OFFICE, All Rights Reserved.    GTS2F400.9038   
C                                                                          GTS2F400.9039   
C Use, duplication or disclosure of this code is subject to the            GTS2F400.9040   
C restrictions as set forth in the contract.                               GTS2F400.9041   
C                                                                          GTS2F400.9042   
C                Meteorological Office                                     GTS2F400.9043   
C                London Road                                               GTS2F400.9044   
C                BRACKNELL                                                 GTS2F400.9045   
C                Berkshire UK                                              GTS2F400.9046   
C                RG12 2SZ                                                  GTS2F400.9047   
C                                                                          GTS2F400.9048   
C If no contract has been raised with this copy of the code, the use,      GTS2F400.9049   
C duplication or disclosure of it is strictly prohibited.  Permission      GTS2F400.9050   
C to do so must first be obtained in writing from the Head of Numerical    GTS2F400.9051   
C Modelling at the above address.                                          GTS2F400.9052   
C ******************************COPYRIGHT******************************    GTS2F400.9053   
C                                                                          GTS2F400.9054   
!+ C grid upwind ice advection scheme for use in slab models.              SLBIADV.3      
!                                                                          SLBIADV.4      
! Subroutine Interface:                                                    SLBIADV.5      

      subroutine slab_ice_advect(                                           2,2SLBIADV.6      
     & icols,jrows,jrowsm1,lglobal                                         SLBIADV.7      
     &,delta_lat,delta_long,timestep,a                                     SLBIADV.8      
     &,uice,vice,hmask,umask,icy                                           SLBIADV.9      
     &,cos_p_latitude,cos_u_latitude,sin_u_latitude                        SLBIADV.10     
     &,aice,hice,hsnow,areas                                               SJC1F400.272    
     & )                                                                   SLBIADV.12     
                                                                           SLBIADV.13     
      IMPLICIT NONE                                                        SLBIADV.14     
!                                                                          SLBIADV.15     
! Description:                                                             SLBIADV.16     
!   Advects ice thickness, compactness and snow depth on Arakawa           SLBIADV.17     
!   C grid for slab ocean model using upwind advection.                    SLBIADV.18     
!                                                                          SLBIADV.19     
! Method:                                                                  SLBIADV.20     
! First copy primary variables to wrokspace to avoid data dependency.      SLBIADV.21     
! Each point in the grid is treated in turn with extra loops for the       SLBIADV.22     
! first and last rows. The area of each grid square and the length of      SLBIADV.23     
! each face is calculated using spherical geometry. The sign of the        SLBIADV.24     
! velocities on each face is used to determine the upwind value of         SLBIADV.25     
! the primary fields being advected (ice depth, ice fraction and snow      SLBIADV.26     
! depth) and increments due to advection accross each face are             SLBIADV.27     
! determined (and masked so that land is not advected). These facial       SLBIADV.28     
! increments are combined to give a change in each property for the        SLBIADV.29     
! grid box. The same process is then carried out for the polar rows.       SLBIADV.30     
!                                                                          SLBIADV.31     
! Current Code Owner: J F Thomson                                          SLBIADV.32     
!                                                                          SLBIADV.33     
! History:                                                                 SLBIADV.34     
! Version   Date     Comment                                               SLBIADV.35     
! -------   ----     -------                                               SLBIADV.36     
!  3.4     26/06/94  Original code. J.F.Thomson                            SLBIADV.37     
!  4.0               Diagnose grid box areas and correct masking.          SJC1F400.273    
!                     J.F.Crossley                                         SJC1F400.274    
!                                                                          SLBIADV.38     
! Code Description:                                                        SLBIADV.39     
!   Language: FORTRAN 77 + common extensions.                              SLBIADV.40     
!   This code is written to UMDP3 v6 programming standards.                SLBIADV.41     
!                                                                          SLBIADV.42     
! System component covered:                                                SLBIADV.43     
! System Task:              P40                                            SLBIADV.44     
!                                                                          SLBIADV.45     
! Declarations:                                                            SLBIADV.46     
!   These are of the form:-                                                SLBIADV.47     
!                                                                          SLBIADV.48     
! Global variables (*CALLed COMDECKs etc...):                              SLBIADV.49     
                                                                           SLBIADV.50     
! Subroutine arguments                                                     SLBIADV.51     
!   Scalar arguments with intent(in):                                      SLBIADV.52     
      integer icols          ! number of columns.                          SLBIADV.53     
      integer jrows          ! number of rows.                             SLBIADV.54     
      integer jrowsm1        ! number of rows minus 1.                     SLBIADV.55     
      logical lglobal        ! true for a global model.                    SLBIADV.56     
      real delta_lat         ! zonal grid spacing in degrees.              SLBIADV.57     
      real delta_long        ! meridional grid spacing in degrees.         SLBIADV.58     
      real timestep          ! timestep in seconds.                        SLBIADV.59     
      real a                 ! radius of earth in metres.                  SLBIADV.60     
                                                                           SLBIADV.61     
!   Array  arguments with intent(in):                                      SLBIADV.62     
      real uice(icols,jrowsm1)           ! zonal sea ice velocity.         SLBIADV.63     
      real vice(icols,jrowsm1)           ! meridional sea ice velocity.    SLBIADV.64     
      real hmask(icols,jrows)            ! 0.0 for ha land 1.0 for sea.    SJC1F400.275    
      real umask(icols,jrowsm1)          ! 0.0 for uv land 1.0 for sea.    SJC1F400.276    
      logical icy(icols,jrows)           ! true if ice is present.         SLBIADV.67     
      real cos_p_latitude(icols,jrows)   ! cos(latitude) at p points       SLBIADV.68     
      real cos_u_latitude(icols,jrowsm1) ! cos(latitude) at u points       SLBIADV.69     
      real sin_u_latitude(icols,jrowsm1) ! sin(latitude) at u points       SLBIADV.70     
                                                                           SLBIADV.71     
!   Scalar arguments with intent(InOut):                                   SLBIADV.72     
                                                                           SLBIADV.73     
!   Array  arguments with intent(InOut):                                   SLBIADV.74     
      real aice(icols,jrows)             ! ice compactness.                SLBIADV.75     
      real hice(icols,jrows)             ! ice thickness.                  SLBIADV.76     
      real hsnow(icols,jrows)            ! snow depth.                     SLBIADV.77     
                                                                           SLBIADV.78     
!   Scalar arguments with intent(out):                                     SLBIADV.79     
                                                                           SLBIADV.80     
!   Array  arguments with intent(out):                                     SLBIADV.81     
      real areas(icols,jrows)            ! grid box areas                  SJC1F400.277    
                                                                           SLBIADV.82     
! Local parameters:                                                        SLBIADV.83     
      real fract_pole           ! fraction of polar grid area/next row     SLBIADV.84     
      parameter ( fract_pole = 0.125 )                                     SLBIADV.85     
                                                                           SLBIADV.86     
! Local scalars:                                                           SLBIADV.87     
      real um,vm,ump,vmp        ! velocity components on each box face.    SLBIADV.88     
      real qinx,qinxp,qiny,qinyp! advective ice depth increments.          SLBIADV.89     
      real qinyp_pole, qiny_pole! advective ice depth incs (poles)         SLBIADV.90     
      real qax,qaxp,qay,qayp    ! advective ice fraction increments.       SLBIADV.91     
      real qayp_pole, qay_pole  ! advective ice fraction incs (poles)      SLBIADV.92     
      real qsx,qsxp,qsy,qsyp    ! advective snow depth increments          SLBIADV.93     
      real qsyp_pole, qsy_pole  ! advective snow depth incs (poles)        SLBIADV.94     
      real qijh,qija,qijs       ! grid box mean advective incs.            SLBIADV.95     
      real area                 ! grid box area in square metres.          SLBIADV.96     
      real facey,faceyp,facex,facexp ! lengths of faces in metres.         SLBIADV.97     
      logical lcheck            ! true if a surrounding point is icy.      SLBIADV.98     
      integer icolsm1           ! number of columns minus 1                SLBIADV.99     
      integer icolsm2           ! number of columns minus 2                SLBIADV.100    
      integer jrowsm2           ! number of rows minus 2                   SLBIADV.101    
      integer i,i1,i2           ! loop indices                             SLBIADV.102    
      integer j                 ! loop index                               SLBIADV.103    
                                                                           SLBIADV.104    
! Local dynamic arrays:                                                    SLBIADV.105    
      real hice_init(icols,jrows) ! initial ice thickness.                 SLBIADV.106    
      real aice_init(icols,jrows) ! initial ice compactness.               SLBIADV.107    
      real hsno_init(icols,jrows) ! initial snow depth.                    SLBIADV.108    
                                                                           SLBIADV.109    
! Function & Subroutine calls:                                             SLBIADV.110    
                                                                           SLBIADV.111    
!- End of header                                                           SLBIADV.112    
! start executable code                                                    SLBIADV.113    
!                                                                          SLBIADV.114    
*IF DEF,TIMER                                                              SLBIADV.115    
      call timer('slbiadv',3)                                              SLBIADV.116    
*ENDIF                                                                     SLBIADV.117    
      icolsm1=icols-1                                                      SLBIADV.118    
      icolsm2=icols-2                                                      SLBIADV.119    
      jrowsm2=jrows-2                                                      SLBIADV.120    
      qinyp_pole=0.0                                                       SLBIADV.121    
      qiny_pole=0.0                                                        SLBIADV.122    
      qayp_pole=0.0                                                        SLBIADV.123    
      qay_pole=0.0                                                         SLBIADV.124    
      qsyp_pole=0.0                                                        SLBIADV.125    
      qsy_pole=0.0                                                         SLBIADV.126    
!                                                                          SLBIADV.127    
! Copy initial ice thickness, compactness and snow depth to workspace      SLBIADV.128    
      do j=1,jrows                                                         SLBIADV.129    
        do i=1,icols                                                       SLBIADV.130    
          hice_init(i,j) = hice(i,j)                                       SLBIADV.131    
          aice_init(i,j) = aice(i,j)                                       SLBIADV.132    
          hsno_init(i,j) = hsnow(i,j)                                      SLBIADV.133    
        end do                                                             SLBIADV.134    
      end do                                                               SLBIADV.135    
!                                                                          SLBIADV.136    
! Loop over grid advecting primary variables.                              SLBIADV.137    
      do j=1,jrowsm2                                                       SLBIADV.138    
        do i=1,icols                                                       SLBIADV.139    
          i1=i+1                                                           SLBIADV.140    
          i2=i+2                                                           SLBIADV.141    
          if (i1.gt.icols) i1=i1-icols                                     SLBIADV.142    
          if (i2.gt.icols) i2=i2-icols                                     SLBIADV.143    
          if ( hmask(i1,j+1).gt.0.1 ) then                                 SJC1F400.278    
            area   = ABS( a**2 * delta_long * (sin_u_latitude(i,j+1)       SJC1F400.279    
     &               -sin_u_latitude(i,j)) )                               SJC1F400.280    
            areas(i1,j+1) = area                                           SJC1F400.281    
          endif                                                            SJC1F400.282    
          lcheck = (icy(i,j+1).or.icy(i1,j+1).or.icy(i1,j)                 SLBIADV.144    
     &              .or.icy(i1,j+2).or.icy(i2,j+1))                        SLBIADV.145    
          if ( hmask(i1,j+1).gt.0.1 .and. lcheck ) then                    SLBIADV.146    
!                                                                          SLBIADV.147    
            facex  = ABS ( a * delta_lat )                                 SLBIADV.150    
            facexp = facex                                                 SLBIADV.151    
            facey  = ABS ( a*cos_u_latitude(i,j)*delta_long )              SLBIADV.152    
            faceyp = ABS ( a*cos_u_latitude(i,j+1)*delta_long )            SLBIADV.153    
!                                                                          SLBIADV.154    
            um  = uice(i,j)                                                SLBIADV.155    
            vm  = vice(i,j)                                                SLBIADV.156    
            ump = uice(i1,j)                                               SLBIADV.157    
            vmp = vice(i,j+1)                                              SLBIADV.158    
!                                                                          SLBIADV.159    
            if (um.ge.0.)  qinx  = um*hice_init(i,j+1)*hmask(i,j+1)        SLBIADV.160    
            if (um.lt.0.)  qinx  = um*hice_init(i1,j+1)*hmask(i1,j+1)      SLBIADV.161    
            if (vm.ge.0.)  qiny  =-vm*hice_init(i1,j+1)*hmask(i1,j+1)      SJC1F400.283    
            if (vm.lt.0.)  qiny  =-vm*hice_init(i1,j)*hmask(i1,j)          SJC1F400.284    
            if (ump.ge.0.) qinxp =-ump*hice_init(i1,j+1)*hmask(i1,j+1)     SLBIADV.164    
            if (ump.lt.0.) qinxp =-ump*hice_init(i2,j+1)*hmask(i2,j+1)     SLBIADV.165    
            if (vmp.ge.0.) qinyp = vmp*hice_init(i1,j+2)*hmask(i1,j+2)     SJC1F400.285    
            if (vmp.lt.0.) qinyp = vmp*hice_init(i1,j+1)*hmask(i1,j+1)     SJC1F400.286    
            if (j.eq.1)    qiny_pole=qiny_pole-qiny*facey                  SLBIADV.168    
     &                               *timestep/(area*fract_pole)           SLBIADV.169    
            if (j.eq.1) areas(i1,j) = area*fract_pole                      SJC1F400.287    
            if (j.eq.jrowsm2)qinyp_pole=qinyp_pole-qinyp*faceyp            SLBIADV.170    
     &                               *timestep/(area*fract_pole)           SLBIADV.171    
            if (j.eq.jrowsm2) areas(i1,j+2) = area*fract_pole              SJC1F400.288    
!                                                                          SLBIADV.172    
            if (um.ge.0.)  qax  = um*aice_init(i,j+1)*hmask(i,j+1)         SLBIADV.173    
            if (um.lt.0.)  qax  = um*aice_init(i1,j+1)*hmask(i1,j+1)       SLBIADV.174    
            if (vm.ge.0.)  qay  =-vm*aice_init(i1,j+1)*hmask(i1,j+1)       SJC1F400.289    
            if (vm.lt.0.)  qay  =-vm*aice_init(i1,j)*hmask(i1,j)           SJC1F400.290    
            if (ump.ge.0.) qaxp =-ump*aice_init(i1,j+1)*hmask(i1,j+1)      SLBIADV.177    
            if (ump.lt.0.) qaxp =-ump*aice_init(i2,j+1)*hmask(i2,j+1)      SLBIADV.178    
            if (vmp.ge.0.) qayp = vmp*aice_init(i1,j+2)*hmask(i1,j+2)      SJC1F400.291    
            if (vmp.lt.0.) qayp = vmp*aice_init(i1,j+1)*hmask(i1,j+1)      SJC1F400.292    
            if (j.eq.1)    qay_pole=qay_pole-qay*facey                     SLBIADV.181    
     &                               *timestep/(area*fract_pole)           SLBIADV.182    
            if (j.eq.jrowsm2)qayp_pole=qayp_pole-qayp*faceyp               SLBIADV.183    
     &                               *timestep/(area*fract_pole)           SLBIADV.184    
!                                                                          SLBIADV.185    
            if (um.ge.0.)  qsx  = qax*hsno_init(i,j+1)                     SLBIADV.186    
            if (um.lt.0.)  qsx  = qax*hsno_init(i1,j+1)                    SLBIADV.187    
            if (vm.ge.0.)  qsy  = qay*hsno_init(i1,j+1)                    SLBIADV.188    
            if (vm.lt.0.)  qsy  = qay*hsno_init(i1,j)                      SLBIADV.189    
            if (ump.ge.0.) qsxp = qaxp*hsno_init(i1,j+1)                   SLBIADV.190    
            if (ump.lt.0.) qsxp = qaxp*hsno_init(i2,j+1)                   SLBIADV.191    
            if (vmp.ge.0.) qsyp = qayp*hsno_init(i1,j+2)                   SLBIADV.192    
            if (vmp.lt.0.) qsyp = qayp*hsno_init(i1,j+1)                   SLBIADV.193    
!                                                                          SLBIADV.194    
            qijh = hice(i1,j+1)                                            SLBIADV.195    
            qija = aice(i1,j+1)                                            SLBIADV.196    
            qijs = hsnow(i1,j+1)*qija                                      SLBIADV.197    
!                                                                          SLBIADV.198    
       hice(i1,j+1) = qijh + ( qinx*facex + qinxp*facexp + qiny*facey      SLBIADV.199    
     &      + qinyp*faceyp ) * timestep/area                               SLBIADV.200    
       aice(i1,j+1) = qija + ( qax*facex + qaxp*facexp + qay*facey         SLBIADV.201    
     &      + qayp*faceyp ) * timestep/area                                SLBIADV.202    
            if (aice(i1,j+1).gt.0.0) then                                  SLBIADV.203    
       hsnow(i1,j+1)= ( qijs + ( qsx*facex + qsxp*facexp + qsy*facey       SLBIADV.204    
     &        + qsyp*faceyp ) * timestep/area )/aice(i1,j+1)               SLBIADV.205    
              if (j.eq.1)    qsy_pole=qsy_pole-qsy*facey                   SLBIADV.206    
     &                                *timestep/(area*0.125)               SLBIADV.207    
              if (j.eq.jrowsm2)qsyp_pole=qsyp_pole-qsyp*faceyp             SLBIADV.208    
     &                                 *timestep/(area*0.125)              SLBIADV.209    
            endif                                                          SLBIADV.210    
!                                                                          SLBIADV.211    
          endif                                                            SLBIADV.212    
        end do                                                             SLBIADV.213    
      end do                                                               SLBIADV.214    
!                                                                          SLBIADV.215    
! Special code for polar rows.                                             SLBIADV.216    
      qiny_pole=qiny_pole/icols                                            SLBIADV.217    
      qinyp_pole=qinyp_pole/icols                                          SLBIADV.218    
      qay_pole=qay_pole/icols                                              SLBIADV.219    
      qayp_pole=qayp_pole/icols                                            SLBIADV.220    
      qsy_pole=qsy_pole/icols                                              SLBIADV.221    
      qsyp_pole=qsyp_pole/icols                                            SLBIADV.222    
! First row.                                                               SLBIADV.223    
      do i=1,icols                                                         SLBIADV.224    
        i1=i+1                                                             SLBIADV.225    
        i2=i+2                                                             SLBIADV.226    
        if (i1.gt.icols) i1=i1-icols                                       SLBIADV.227    
        if (i2.gt.icols) i2=i2-icols                                       SLBIADV.228    
        lcheck = (icy(i,1).or.icy(i1,1).or.icy(i1,2)                       SLBIADV.229    
     &            .or.icy(i2,1))                                           SLBIADV.230    
        if (hmask(i1,1).gt.0.1 .and. lcheck) then                          SLBIADV.231    
!                                                                          SLBIADV.232    
          qijh = hice(i1,1)                                                SLBIADV.233    
          qija = aice(i1,1)                                                SLBIADV.234    
          qijs = hsnow(i1,1)*qija                                          SLBIADV.235    
!                                                                          SLBIADV.236    
          hice(i1,1) = qijh + qiny_pole                                    SLBIADV.237    
          aice(i1,1) = qija + qay_pole                                     SLBIADV.238    
          if (aice(i1,1).gt.0.0)                                           SLBIADV.239    
     &     hsnow(i1,1)= ( qijs + qsy_pole ) / aice(i1,1)                   SLBIADV.240    
        endif                                                              SLBIADV.241    
      end do                                                               SLBIADV.242    
! Last row.                                                                SLBIADV.243    
      do i=1,icols                                                         SLBIADV.244    
        i1=i+1                                                             SLBIADV.245    
        i2=i+2                                                             SLBIADV.246    
        if (i1.gt.icols) i1=i1-icols                                       SLBIADV.247    
        if (i2.gt.icols) i2=i2-icols                                       SLBIADV.248    
        lcheck = (icy(i,jrows).or.icy(i1,jrows).or.icy(i1,jrowsm1)         SLBIADV.249    
     &            .or.icy(i2,jrows))                                       SLBIADV.250    
        if (hmask(i1,jrows).gt.0.1 .and. lcheck) then                      SLBIADV.251    
!                                                                          SLBIADV.252    
          qijh = hice(i1,jrows)                                            SLBIADV.253    
          qija = aice(i1,jrows)                                            SLBIADV.254    
          qijs = hsnow(i1,jrows)*qija                                      SLBIADV.255    
!                                                                          SLBIADV.256    
          hice(i1,jrows) = qijh + qinyp_pole                               SLBIADV.257    
          aice(i1,jrows) = qija + qayp_pole                                SLBIADV.258    
          if (aice(i1,jrows).gt.0.0)                                       SLBIADV.259    
     &      hsnow(i1,jrows)= ( qijs + qsyp_pole ) / aice(i1,jrows)         SLBIADV.260    
        endif                                                              SLBIADV.261    
      end do                                                               SLBIADV.262    
!                                                                          SLBIADV.263    
*IF DEF,TIMER                                                              SLBIADV.264    
      call timer('slbiadv',4)                                              SLBIADV.265    
*ENDIF                                                                     SLBIADV.266    
      return                                                               SLBIADV.267    
      end                                                                  SLBIADV.268    
*ENDIF                                                                     SLBIADV.269