New URL for NEMO forge!   http://forge.nemo-ocean.eu

Since March 2022 along with NEMO 4.2 release, the code development moved to a self-hosted GitLab.
This present forge is now archived and remained online for history.
Changeset 9019 for branches/2017/dev_merge_2017/NEMOGCM/NEMO/OPA_SRC/DYN/dynzad.F90 – NEMO

Ignore:
Timestamp:
2017-12-13T15:58:53+01:00 (6 years ago)
Author:
timgraham
Message:

Merge of dev_CNRS_2017 into branch

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/2017/dev_merge_2017/NEMOGCM/NEMO/OPA_SRC/DYN/dynzad.F90

    r7753 r9019  
    55   !!====================================================================== 
    66   !! History :  OPA  ! 1991-01  (G. Madec) Original code 
    7    !!            7.0  ! 1991-11  (G. Madec) 
    8    !!            7.5  ! 1996-01  (G. Madec) statement function for e3 
    97   !!   NEMO     0.5  ! 2002-07  (G. Madec) Free form, F90 
    108   !!---------------------------------------------------------------------- 
     
    2220   USE lib_mpp        ! MPP library 
    2321   USE prtctl         ! Print control 
    24    USE wrk_nemo       ! Memory Allocation 
    2522   USE timing         ! Timing 
    2623 
     
    2926    
    3027   PUBLIC   dyn_zad       ! routine called by dynadv.F90 
    31    PUBLIC   dyn_zad_zts   ! routine called by dynadv.F90 
    3228 
    3329   !! * Substitutions 
    3430#  include "vectopt_loop_substitute.h90" 
    3531   !!---------------------------------------------------------------------- 
    36    !! NEMO/OPA 3.3 , NEMO Consortium (2010) 
     32   !! NEMO/OPA 4.0 , NEMO Consortium (2017) 
    3733   !! $Id$ 
    3834   !! Software governed by the CeCILL licence     (NEMOGCM/NEMO_CeCILL.txt) 
     
    5854      INTEGER, INTENT(in) ::   kt   ! ocean time-step inedx 
    5955      ! 
    60       INTEGER  ::   ji, jj, jk      ! dummy loop indices 
    61       REAL(wp) ::   zua, zva        ! temporary scalars 
    62       REAL(wp), POINTER, DIMENSION(:,:,:) ::  zwuw , zwvw 
    63       REAL(wp), POINTER, DIMENSION(:,:  ) ::  zww 
    64       REAL(wp), POINTER, DIMENSION(:,:,:) ::  ztrdu, ztrdv 
     56      INTEGER  ::   ji, jj, jk   ! dummy loop indices 
     57      REAL(wp) ::   zua, zva     ! local scalars 
     58      REAL(wp), DIMENSION(jpi,jpj)     ::   zww 
     59      REAL(wp), DIMENSION(jpi,jpj,jpk) ::   zwuw, zwvw 
     60      REAL(wp), DIMENSION(:,:,:), ALLOCATABLE ::   ztrdu, ztrdv 
    6561      !!---------------------------------------------------------------------- 
    6662      ! 
    67       IF( nn_timing == 1 )  CALL timing_start('dyn_zad') 
    68       ! 
    69       CALL wrk_alloc( jpi,jpj, zww )  
    70       CALL wrk_alloc( jpi,jpj,jpk, zwuw , zwvw )  
     63      IF( ln_timing )   CALL timing_start('dyn_zad') 
    7164      ! 
    7265      IF( kt == nit000 ) THEN 
    73          IF(lwp)WRITE(numout,*) 
    74          IF(lwp)WRITE(numout,*) 'dyn_zad : arakawa advection scheme' 
     66         IF(lwp) WRITE(numout,*) 
     67         IF(lwp) WRITE(numout,*) 'dyn_zad : 2nd order vertical advection scheme' 
    7568      ENDIF 
    7669 
    7770      IF( l_trddyn )   THEN         ! Save ua and va trends 
    78          CALL wrk_alloc( jpi, jpj, jpk, ztrdu, ztrdv )  
     71         ALLOCATE( ztrdu(jpi,jpj,jpk) , ztrdv(jpi,jpj,jpk) )  
    7972         ztrdu(:,:,:) = ua(:,:,:)  
    8073         ztrdv(:,:,:) = va(:,:,:)  
     
    9689      ! 
    9790      ! Surface and bottom advective fluxes set to zero 
    98       IF ( ln_isfcav ) THEN 
     91      IF( ln_isfcav ) THEN 
    9992         DO jj = 2, jpjm1 
    10093            DO ji = fs_2, fs_jpim1           ! vector opt. 
     
    119112         DO jj = 2, jpjm1 
    120113            DO ji = fs_2, fs_jpim1       ! vector opt. 
    121                !                         ! vertical momentum advective trends 
    122                zua = - ( zwuw(ji,jj,jk) + zwuw(ji,jj,jk+1) ) * r1_e1e2u(ji,jj) / e3u_n(ji,jj,jk) 
    123                zva = - ( zwvw(ji,jj,jk) + zwvw(ji,jj,jk+1) ) * r1_e1e2v(ji,jj) / e3v_n(ji,jj,jk) 
    124                !                         ! add the trends to the general momentum trends 
    125                ua(ji,jj,jk) = ua(ji,jj,jk) + zua 
    126                va(ji,jj,jk) = va(ji,jj,jk) + zva 
     114               ua(ji,jj,jk) = ua(ji,jj,jk) - ( zwuw(ji,jj,jk) + zwuw(ji,jj,jk+1) ) * r1_e1e2u(ji,jj) / e3u_n(ji,jj,jk) 
     115               va(ji,jj,jk) = va(ji,jj,jk) - ( zwvw(ji,jj,jk) + zwvw(ji,jj,jk+1) ) * r1_e1e2v(ji,jj) / e3v_n(ji,jj,jk) 
    127116            END DO   
    128117         END DO   
     
    133122         ztrdv(:,:,:) = va(:,:,:) - ztrdv(:,:,:) 
    134123         CALL trd_dyn( ztrdu, ztrdv, jpdyn_zad, kt ) 
    135          CALL wrk_dealloc( jpi, jpj, jpk, ztrdu, ztrdv )  
     124         DEALLOCATE( ztrdu, ztrdv )  
    136125      ENDIF 
    137126      !                             ! Control print 
     
    139128         &                       tab3d_2=va, clinfo2=       ' Va: ', mask2=vmask, clinfo3='dyn' ) 
    140129      ! 
    141       CALL wrk_dealloc( jpi,jpj, zww )  
    142       CALL wrk_dealloc( jpi,jpj,jpk, zwuw , zwvw )  
    143       ! 
    144       IF( nn_timing == 1 )  CALL timing_stop('dyn_zad') 
     130      IF( ln_timing )   CALL timing_stop('dyn_zad') 
    145131      ! 
    146132   END SUBROUTINE dyn_zad 
    147133 
    148  
    149    SUBROUTINE dyn_zad_zts ( kt ) 
    150       !!---------------------------------------------------------------------- 
    151       !!                  ***  ROUTINE dynzad_zts  *** 
    152       !!  
    153       !! ** Purpose :   Compute the now vertical momentum advection trend and  
    154       !!      add it to the general trend of momentum equation. This version 
    155       !!      uses sub-timesteps for improved numerical stability with small 
    156       !!      vertical grid sizes. This is especially relevant when using  
    157       !!      embedded ice with thin surface boxes. 
    158       !! 
    159       !! ** Method  :   The now vertical advection of momentum is given by: 
    160       !!         w dz(u) = ua + 1/(e1u*e2u*e3u) mk+1[ mi(e1t*e2t*wn) dk(un) ] 
    161       !!         w dz(v) = va + 1/(e1v*e2v*e3v) mk+1[ mj(e1t*e2t*wn) dk(vn) ] 
    162       !!      Add this trend to the general trend (ua,va): 
    163       !!         (ua,va) = (ua,va) + w dz(u,v) 
    164       !! 
    165       !! ** Action  : - Update (ua,va) with the vert. momentum adv. trends 
    166       !!              - Save the trends in (ztrdu,ztrdv) ('key_trddyn') 
    167       !!---------------------------------------------------------------------- 
    168       INTEGER, INTENT(in) ::   kt   ! ocean time-step inedx 
    169       ! 
    170       INTEGER  ::   ji, jj, jk, jl  ! dummy loop indices 
    171       INTEGER  ::   jnzts = 5       ! number of sub-timesteps for vertical advection 
    172       INTEGER  ::   jtb, jtn, jta   ! sub timestep pointers for leap-frog/euler forward steps 
    173       REAL(wp) ::   zua, zva        ! temporary scalars 
    174       REAL(wp) ::   zr_rdt          ! temporary scalar 
    175       REAL(wp) ::   z2dtzts         ! length of Euler forward sub-timestep for vertical advection 
    176       REAL(wp) ::   zts             ! length of sub-timestep for vertical advection 
    177       REAL(wp), POINTER, DIMENSION(:,:,:)   ::  zwuw , zwvw, zww 
    178       REAL(wp), POINTER, DIMENSION(:,:,:)   ::  ztrdu, ztrdv 
    179       REAL(wp), POINTER, DIMENSION(:,:,:,:) ::  zus , zvs 
    180       !!---------------------------------------------------------------------- 
    181       ! 
    182       IF( nn_timing == 1 )  CALL timing_start('dyn_zad_zts') 
    183       ! 
    184       CALL wrk_alloc( jpi,jpj,jpk,     zwuw, zwvw, zww )  
    185       CALL wrk_alloc( jpi,jpj,jpk,3,   zus , zvs )  
    186       ! 
    187       IF( kt == nit000 ) THEN 
    188          IF(lwp)WRITE(numout,*) 
    189          IF(lwp)WRITE(numout,*) 'dyn_zad_zts : arakawa advection scheme with sub-timesteps' 
    190       ENDIF 
    191  
    192       IF( l_trddyn )   THEN         ! Save ua and va trends 
    193          CALL wrk_alloc( jpi, jpj, jpk, ztrdu, ztrdv )  
    194          ztrdu(:,:,:) = ua(:,:,:)  
    195          ztrdv(:,:,:) = va(:,:,:)  
    196       ENDIF 
    197        
    198       IF( neuler == 0 .AND. kt == nit000 ) THEN 
    199           z2dtzts =         rdt / REAL( jnzts, wp )   ! = rdt (restart with Euler time stepping) 
    200       ELSE 
    201           z2dtzts = 2._wp * rdt / REAL( jnzts, wp )   ! = 2 rdt (leapfrog) 
    202       ENDIF 
    203        
    204       DO jk = 2, jpkm1                    ! Calculate and store vertical fluxes 
    205          DO jj = 2, jpj                    
    206             DO ji = fs_2, jpi             ! vector opt. 
    207                zww(ji,jj,jk) = 0.25_wp * e1e2t(ji,jj) * wn(ji,jj,jk) 
    208             END DO 
    209          END DO 
    210       END DO 
    211  
    212       DO jj = 2, jpjm1                    ! Surface and bottom advective fluxes set to zero 
    213          DO ji = fs_2, fs_jpim1           ! vector opt. 
    214  !!gm missing ISF boundary condition 
    215             zwuw(ji,jj, 1 ) = 0._wp 
    216             zwvw(ji,jj, 1 ) = 0._wp 
    217             zwuw(ji,jj,jpk) = 0._wp 
    218             zwvw(ji,jj,jpk) = 0._wp 
    219          END DO   
    220       END DO 
    221  
    222 ! Start with before values and use sub timestepping to reach after values 
    223  
    224       zus(:,:,:,1) = ub(:,:,:) 
    225       zvs(:,:,:,1) = vb(:,:,:) 
    226  
    227       DO jl = 1, jnzts                   ! Start of sub timestepping loop 
    228  
    229          IF( jl == 1 ) THEN              ! Euler forward to kick things off 
    230            jtb = 1   ;   jtn = 1   ;   jta = 2 
    231            zts = z2dtzts 
    232          ELSEIF( jl == 2 ) THEN          ! First leapfrog step 
    233            jtb = 1   ;   jtn = 2   ;   jta = 3 
    234            zts = 2._wp * z2dtzts 
    235          ELSE                            ! Shuffle pointers for subsequent leapfrog steps 
    236            jtb = MOD(jtb,3) + 1 
    237            jtn = MOD(jtn,3) + 1 
    238            jta = MOD(jta,3) + 1 
    239          ENDIF 
    240  
    241          DO jk = 2, jpkm1           ! Vertical momentum advection at level w and u- and v- vertical 
    242             DO jj = 2, jpjm1                 ! vertical momentum advection at w-point 
    243                DO ji = fs_2, fs_jpim1        ! vector opt. 
    244                   zwuw(ji,jj,jk) = ( zww(ji+1,jj  ,jk) + zww(ji,jj,jk) ) * ( zus(ji,jj,jk-1,jtn)-zus(ji,jj,jk,jtn) ) !* wumask(ji,jj,jk) 
    245                   zwvw(ji,jj,jk) = ( zww(ji  ,jj+1,jk) + zww(ji,jj,jk) ) * ( zvs(ji,jj,jk-1,jtn)-zvs(ji,jj,jk,jtn) ) !* wvmask(ji,jj,jk) 
    246                END DO   
    247             END DO    
    248          END DO 
    249          DO jk = 1, jpkm1           ! Vertical momentum advection at u- and v-points 
    250             DO jj = 2, jpjm1 
    251                DO ji = fs_2, fs_jpim1       ! vector opt. 
    252                   !                         ! vertical momentum advective trends 
    253                   zua = - ( zwuw(ji,jj,jk) + zwuw(ji,jj,jk+1) ) * r1_e1e2u(ji,jj) / e3u_n(ji,jj,jk) 
    254                   zva = - ( zwvw(ji,jj,jk) + zwvw(ji,jj,jk+1) ) * r1_e1e2v(ji,jj) / e3v_n(ji,jj,jk) 
    255                   zus(ji,jj,jk,jta) = zus(ji,jj,jk,jtb) + zua * zts 
    256                   zvs(ji,jj,jk,jta) = zvs(ji,jj,jk,jtb) + zva * zts 
    257                END DO   
    258             END DO   
    259          END DO 
    260  
    261       END DO      ! End of sub timestepping loop 
    262  
    263       zr_rdt = 1._wp / ( REAL( jnzts, wp ) * z2dtzts ) 
    264       DO jk = 1, jpkm1              ! Recover trends over the outer timestep 
    265          DO jj = 2, jpjm1 
    266             DO ji = fs_2, fs_jpim1       ! vector opt. 
    267                !                         ! vertical momentum advective trends 
    268                !                         ! add the trends to the general momentum trends 
    269                ua(ji,jj,jk) = ua(ji,jj,jk) + ( zus(ji,jj,jk,jta) - ub(ji,jj,jk)) * zr_rdt 
    270                va(ji,jj,jk) = va(ji,jj,jk) + ( zvs(ji,jj,jk,jta) - vb(ji,jj,jk)) * zr_rdt 
    271             END DO   
    272          END DO   
    273       END DO 
    274  
    275       IF( l_trddyn ) THEN           ! save the vertical advection trends for diagnostic 
    276          ztrdu(:,:,:) = ua(:,:,:) - ztrdu(:,:,:) 
    277          ztrdv(:,:,:) = va(:,:,:) - ztrdv(:,:,:) 
    278          CALL trd_dyn( ztrdu, ztrdv, jpdyn_zad, kt ) 
    279          CALL wrk_dealloc( jpi, jpj, jpk, ztrdu, ztrdv )  
    280       ENDIF 
    281       !                             ! Control print 
    282       IF(ln_ctl)   CALL prt_ctl( tab3d_1=ua, clinfo1=' zad  - Ua: ', mask1=umask,   & 
    283          &                       tab3d_2=va, clinfo2=       ' Va: ', mask2=vmask, clinfo3='dyn' ) 
    284       ! 
    285       CALL wrk_dealloc( jpi,jpj,jpk,     zwuw, zwvw, zww )  
    286       CALL wrk_dealloc( jpi,jpj,jpk,3,   zus , zvs )  
    287       ! 
    288       IF( nn_timing == 1 )  CALL timing_stop('dyn_zad_zts') 
    289       ! 
    290    END SUBROUTINE dyn_zad_zts 
    291  
    292134   !!====================================================================== 
    293135END MODULE dynzad 
Note: See TracChangeset for help on using the changeset viewer.