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 6225 for branches/2014/dev_r4704_NOC5_MPP_BDY_UPDATE/NEMOGCM/NEMO/OPA_SRC/TRA/trazdf_imp.F90 – NEMO

Ignore:
Timestamp:
2016-01-08T10:35:19+01:00 (8 years ago)
Author:
jamesharle
Message:

Update MPP_BDY_UPDATE branch to be consistent with head of trunk

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/2014/dev_r4704_NOC5_MPP_BDY_UPDATE/NEMOGCM/NEMO/OPA_SRC/TRA/trazdf_imp.F90

    r3294 r6225  
    1616   !!            3.3  !  2010-06  (C. Ethe, G. Madec) Merge TRA-TRC 
    1717   !!             -   !  2011-02  (A. Coward, C. Ethe, G. Madec) improvment of surface boundary condition 
     18   !!            3.7  !  2015-11  (G. Madec, A. Coward)  non linear free surface by default  
    1819   !!---------------------------------------------------------------------- 
    1920   
    2021   !!---------------------------------------------------------------------- 
    21    !!   tra_zdf_imp : Update the tracer trend with the diagonal vertical   
    22    !!                 part of the mixing tensor. 
    23    !!---------------------------------------------------------------------- 
    24    USE oce             ! ocean dynamics and tracers variables 
    25    USE dom_oce         ! ocean space and time domain variables  
    26    USE zdf_oce         ! ocean vertical physics variables 
    27    USE trc_oce         ! share passive tracers/ocean variables 
    28    USE domvvl          ! variable volume 
    29    USE ldftra_oce      ! ocean active tracers: lateral physics 
    30    USE ldftra          ! lateral mixing type 
    31    USE ldfslp          ! lateral physics: slope of diffusion 
    32    USE zdfddm          ! ocean vertical physics: double diffusion 
    33    USE traldf_iso_grif ! active tracers: Griffies operator 
    34    USE in_out_manager  ! I/O manager 
    35    USE lbclnk          ! ocean lateral boundary conditions (or mpp link) 
    36    USE lib_mpp         ! MPP library 
    37    USE wrk_nemo        ! Memory Allocation 
    38    USE timing          ! Timing 
     22   !!   tra_zdf_imp   : Update the tracer trend with vertical mixing, nad compute the after tracer field 
     23   !!---------------------------------------------------------------------- 
     24   USE oce            ! ocean dynamics and tracers variables 
     25   USE dom_oce        ! ocean space and time domain variables  
     26   USE zdf_oce        ! ocean vertical physics variables 
     27   USE trc_oce        ! share passive tracers/ocean variables 
     28   USE domvvl         ! variable volume 
     29   USE ldftra         ! lateral mixing type 
     30   USE ldfslp         ! lateral physics: slope of diffusion 
     31   USE zdfddm         ! ocean vertical physics: double diffusion 
     32   USE traldf_triad   ! active tracers: Method of Stabilizing Correction 
     33   ! 
     34   USE in_out_manager ! I/O manager 
     35   USE lbclnk         ! ocean lateral boundary conditions (or mpp link) 
     36   USE lib_mpp        ! MPP library 
     37   USE wrk_nemo       ! Memory Allocation 
     38   USE timing         ! Timing 
    3939 
    4040   IMPLICIT NONE 
     
    4343   PUBLIC   tra_zdf_imp   !  routine called by step.F90 
    4444 
    45    REAL(wp) ::  r_vvl     ! variable volume indicator, =1 if lk_vvl=T, =0 otherwise  
    46  
    4745   !! * Substitutions 
    48 #  include "domzgr_substitute.h90" 
    49 #  include "ldftra_substitute.h90" 
    5046#  include "zdfddm_substitute.h90" 
    5147#  include "vectopt_loop_substitute.h90" 
    5248   !!---------------------------------------------------------------------- 
    53    !! NEMO/OPA 3.3 , NEMO Consortium (2010) 
     49   !! NEMO/OPA 3.7 , NEMO Consortium (2015) 
    5450   !! $Id$ 
    5551   !! Software governed by the CeCILL licence     (NEMOGCM/NEMO_CeCILL.txt) 
     
    6662      !!     it is already computed and add to the general trend in traldf)  
    6763      !! 
    68       !! ** Method  :  The vertical diffusion of the tracer t  is given by: 
    69       !!                  difft = dz( avt dz(t) ) = 1/e3t dk+1( avt/e3w dk(t) ) 
    70       !!      It is computed using a backward time scheme (t=ta). 
     64      !! ** Method  :  The vertical diffusion of a tracer ,t , is given by: 
     65      !!          difft = dz( avt dz(t) ) = 1/e3t dk+1( avt/e3w dk(t) ) 
     66      !!      It is computed using a backward time scheme (t=after field) 
     67      !!      which provide directly the after tracer field. 
    7168      !!      If lk_zdfddm=T, use avs for salinity or for passive tracers 
    7269      !!      Surface and bottom boundary conditions: no diffusive flux on 
     
    7673      !! ** Action  : - pta  becomes the after tracer 
    7774      !!--------------------------------------------------------------------- 
    78       USE oce     , ONLY:   zwd => ua       , zws => va         ! (ua,va) used as 3D workspace 
    79       ! 
    8075      INTEGER                              , INTENT(in   ) ::   kt       ! ocean time-step index 
    81       INTEGER                              , INTENT(in   ) ::   kit000          ! first time step index 
     76      INTEGER                              , INTENT(in   ) ::   kit000   ! first time step index 
    8277      CHARACTER(len=3)                     , INTENT(in   ) ::   cdtype   ! =TRA or TRC (tracer indicator) 
    8378      INTEGER                              , INTENT(in   ) ::   kjpt     ! number of tracers 
    84       REAL(wp), DIMENSION(        jpk     ), INTENT(in   ) ::   p2dt     ! vertical profile of tracer time-step 
     79      REAL(wp)                             , INTENT(in   ) ::   p2dt     ! tracer time-step 
    8580      REAL(wp), DIMENSION(jpi,jpj,jpk,kjpt), INTENT(in   ) ::   ptb      ! before and now tracer fields 
    86       REAL(wp), DIMENSION(jpi,jpj,jpk,kjpt), INTENT(inout) ::   pta      ! tracer trend  
     81      REAL(wp), DIMENSION(jpi,jpj,jpk,kjpt), INTENT(inout) ::   pta      ! in: tracer trend ; out: after tracer field 
    8782      ! 
    8883      INTEGER  ::  ji, jj, jk, jn   ! dummy loop indices 
    89       REAL(wp) ::  zrhs, ze3tb, ze3tn, ze3ta   ! local scalars 
    90       REAL(wp), POINTER, DIMENSION(:,:,:) ::  zwi, zwt 
     84      REAL(wp) ::  zrhs             ! local scalars 
     85      REAL(wp), POINTER, DIMENSION(:,:,:) ::  zwi, zwt, zwd, zws 
    9186      !!--------------------------------------------------------------------- 
    9287      ! 
    9388      IF( nn_timing == 1 )  CALL timing_start('tra_zdf_imp') 
    9489      ! 
    95       CALL wrk_alloc( jpi, jpj, jpk, zwi, zwt )  
     90      CALL wrk_alloc( jpi,jpj,jpk,   zwi, zwt, zwd, zws )  
    9691      ! 
    9792      IF( kt == kit000 )  THEN 
     
    9994         IF(lwp)WRITE(numout,*) 'tra_zdf_imp : implicit vertical mixing on ', cdtype 
    10095         IF(lwp)WRITE(numout,*) '~~~~~~~~~~~ ' 
    101          ! 
    102          IF( lk_vvl ) THEN   ;    r_vvl = 1._wp       ! Variable volume indicator 
    103          ELSE                ;    r_vvl = 0._wp        
    104          ENDIF 
    10596      ENDIF 
    106       ! 
    10797      !                                               ! ============= ! 
    10898      DO jn = 1, kjpt                                 !  tracer loop  ! 
    10999         !                                            ! ============= ! 
    110          ! 
    111100         !  Matrix construction 
    112101         ! -------------------- 
     
    122111            zwt(:,:,1) = 0._wp 
    123112            ! 
    124 #if defined key_ldfslp 
    125             ! isoneutral diffusion: add the contribution  
    126             IF( ln_traldf_grif    ) THEN     ! Griffies isoneutral diff 
    127                DO jk = 2, jpkm1 
    128                   DO jj = 2, jpjm1 
    129                      DO ji = fs_2, fs_jpim1   ! vector opt. 
    130                         zwt(ji,jj,jk) = zwt(ji,jj,jk) + ah_wslp2(ji,jj,jk)        
     113            IF( l_ldfslp ) THEN            ! isoneutral diffusion: add the contribution  
     114               IF( ln_traldf_msc  ) THEN     ! MSC iso-neutral operator  
     115                  DO jk = 2, jpkm1 
     116                     DO jj = 2, jpjm1 
     117                        DO ji = fs_2, fs_jpim1   ! vector opt. 
     118                           zwt(ji,jj,jk) = zwt(ji,jj,jk) + akz(ji,jj,jk)   
     119                        END DO 
    131120                     END DO 
    132121                  END DO 
    133                END DO 
    134             ELSE IF( l_traldf_rot ) THEN     ! standard isoneutral diff 
    135                DO jk = 2, jpkm1 
    136                   DO jj = 2, jpjm1 
    137                      DO ji = fs_2, fs_jpim1   ! vector opt. 
    138                         zwt(ji,jj,jk) = zwt(ji,jj,jk) + fsahtw(ji,jj,jk)                       & 
    139                            &                          * (  wslpi(ji,jj,jk) * wslpi(ji,jj,jk)   & 
    140                            &                             + wslpj(ji,jj,jk) * wslpj(ji,jj,jk)  ) 
     122               ELSE                          ! standard or triad iso-neutral operator 
     123                  DO jk = 2, jpkm1 
     124                     DO jj = 2, jpjm1 
     125                        DO ji = fs_2, fs_jpim1   ! vector opt. 
     126                           zwt(ji,jj,jk) = zwt(ji,jj,jk) + ah_wslp2(ji,jj,jk) 
     127                        END DO 
    141128                     END DO 
    142129                  END DO 
    143                END DO 
     130               ENDIF 
    144131            ENDIF 
    145 #endif 
     132            ! 
    146133            ! Diagonal, lower (i), upper (s)  (including the bottom boundary condition since avt is masked) 
    147134            DO jk = 1, jpkm1 
    148135               DO jj = 2, jpjm1 
    149136                  DO ji = fs_2, fs_jpim1   ! vector opt. 
    150                      ze3ta =  ( 1. - r_vvl ) +        r_vvl   * fse3t_a(ji,jj,jk)   ! after scale factor at T-point 
    151                      ze3tn =         r_vvl   + ( 1. - r_vvl ) * fse3t_n(ji,jj,jk)   ! now   scale factor at T-point 
    152                      zwi(ji,jj,jk) = - p2dt(jk) * zwt(ji,jj,jk  ) / ( ze3tn * fse3w(ji,jj,jk  ) ) 
    153                      zws(ji,jj,jk) = - p2dt(jk) * zwt(ji,jj,jk+1) / ( ze3tn * fse3w(ji,jj,jk+1) ) 
    154                      zwd(ji,jj,jk) = ze3ta - zwi(ji,jj,jk) - zws(ji,jj,jk) 
     137!!gm BUG  I think, use e3w_a instead of e3w_n 
     138                     zwi(ji,jj,jk) = - p2dt * zwt(ji,jj,jk  ) / e3w_n(ji,jj,jk  ) 
     139                     zws(ji,jj,jk) = - p2dt * zwt(ji,jj,jk+1) / e3w_n(ji,jj,jk+1) 
     140                     zwd(ji,jj,jk) = e3t_a(ji,jj,jk) - zwi(ji,jj,jk) - zws(ji,jj,jk) 
    155141                 END DO 
    156142               END DO 
     
    176162            !   used as a work space array: its value is modified. 
    177163            ! 
    178             ! first recurrence:   Tk = Dk - Ik Sk-1 / Tk-1   (increasing k) 
    179             ! done once for all passive tracers (so included in the IF instruction) 
    180             DO jj = 2, jpjm1 
    181                DO ji = fs_2, fs_jpim1 
     164            DO jj = 2, jpjm1        !* 1st recurrence:   Tk = Dk - Ik Sk-1 / Tk-1   (increasing k) 
     165               DO ji = fs_2, fs_jpim1            ! done one for all passive tracers (so included in the IF instruction) 
    182166                  zwt(ji,jj,1) = zwd(ji,jj,1) 
    183167               END DO 
     
    186170               DO jj = 2, jpjm1 
    187171                  DO ji = fs_2, fs_jpim1 
    188                     zwt(ji,jj,jk) = zwd(ji,jj,jk) - zwi(ji,jj,jk) * zws(ji,jj,jk-1) / zwt(ji,jj,jk-1) 
     172                     zwt(ji,jj,jk) = zwd(ji,jj,jk) - zwi(ji,jj,jk) * zws(ji,jj,jk-1) / zwt(ji,jj,jk-1) 
    189173                  END DO 
    190174               END DO 
    191175            END DO 
    192176            ! 
    193          END IF  
     177         ENDIF  
    194178         !          
    195          ! second recurrence:    Zk = Yk - Ik / Tk-1  Zk-1 
    196          DO jj = 2, jpjm1 
     179         DO jj = 2, jpjm1           !* 2nd recurrence:    Zk = Yk - Ik / Tk-1  Zk-1 
    197180            DO ji = fs_2, fs_jpim1 
    198                ze3tb = ( 1. - r_vvl ) + r_vvl * fse3t_b(ji,jj,1) 
    199                ze3tn = ( 1. - r_vvl ) + r_vvl * fse3t(ji,jj,1) 
    200                pta(ji,jj,1,jn) = ze3tb * ptb(ji,jj,1,jn) + p2dt(1) * ze3tn * pta(ji,jj,1,jn) 
     181               pta(ji,jj,1,jn) = e3t_b(ji,jj,1) * ptb(ji,jj,1,jn) + p2dt * e3t_n(ji,jj,1) * pta(ji,jj,1,jn) 
    201182            END DO 
    202183         END DO 
     
    204185            DO jj = 2, jpjm1 
    205186               DO ji = fs_2, fs_jpim1 
    206                   ze3tb = ( 1. - r_vvl ) + r_vvl * fse3t_b(ji,jj,jk) 
    207                   ze3tn = ( 1. - r_vvl ) + r_vvl * fse3t  (ji,jj,jk) 
    208                   zrhs = ze3tb * ptb(ji,jj,jk,jn) + p2dt(jk) * ze3tn * pta(ji,jj,jk,jn)   ! zrhs=right hand side  
     187                  zrhs = e3t_b(ji,jj,jk) * ptb(ji,jj,jk,jn) + p2dt * e3t_n(ji,jj,jk) * pta(ji,jj,jk,jn)   ! zrhs=right hand side 
    209188                  pta(ji,jj,jk,jn) = zrhs - zwi(ji,jj,jk) / zwt(ji,jj,jk-1) * pta(ji,jj,jk-1,jn) 
    210189               END DO 
    211190            END DO 
    212191         END DO 
    213  
    214          ! third recurrence:    Xk = (Zk - Sk Xk+1 ) / Tk   (result is the after tracer) 
    215          DO jj = 2, jpjm1 
     192         ! 
     193         DO jj = 2, jpjm1           !* 3d recurrence:    Xk = (Zk - Sk Xk+1 ) / Tk   (result is the after tracer) 
    216194            DO ji = fs_2, fs_jpim1 
    217195               pta(ji,jj,jpkm1,jn) = pta(ji,jj,jpkm1,jn) / zwt(ji,jj,jpkm1) * tmask(ji,jj,jpkm1) 
     
    230208      !                                               ! ================= ! 
    231209      ! 
    232       CALL wrk_dealloc( jpi, jpj, jpk, zwi, zwt )  
     210      CALL wrk_dealloc( jpi,jpj,jpk,   zwi, zwt, zwd, zws )  
    233211      ! 
    234212      IF( nn_timing == 1 )  CALL timing_stop('tra_zdf_imp') 
Note: See TracChangeset for help on using the changeset viewer.