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 12590 for NEMO/branches/2020/dev_r12377_KERNEL-06_techene_e3/src/OCE/TRA/traadv_fct.F90 – NEMO

Ignore:
Timestamp:
2020-03-23T22:16:19+01:00 (4 years ago)
Author:
techene
Message:

all: add e3 substitute, OCE/DOM/domzgr_substitute.h90: correct a bug for e3f

File:
1 edited

Legend:

Unmodified
Added
Removed
  • NEMO/branches/2020/dev_r12377_KERNEL-06_techene_e3/src/OCE/TRA/traadv_fct.F90

    r12377 r12590  
    1010   !!  tra_adv_fct    : update the tracer trend with a 3D advective trends using a 2nd or 4th order FCT scheme 
    1111   !!                   with sub-time-stepping in the vertical direction 
    12    !!  nonosc         : compute monotonic tracer fluxes by a non-oscillatory algorithm  
     12   !!  nonosc         : compute monotonic tracer fluxes by a non-oscillatory algorithm 
    1313   !!  interp_4th_cpt : 4th order compact scheme for the vertical component of the advection 
    1414   !!---------------------------------------------------------------------- 
     
    2424   ! 
    2525   USE in_out_manager ! I/O manager 
    26    USE iom            !  
     26   USE iom            ! 
    2727   USE lib_mpp        ! MPP library 
    28    USE lbclnk         ! ocean lateral boundary condition (or mpp link)  
    29    USE lib_fortran    ! Fortran utilities (allows no signed zero when 'key_nosignedzero' defined)   
     28   USE lbclnk         ! ocean lateral boundary condition (or mpp link) 
     29   USE lib_fortran    ! Fortran utilities (allows no signed zero when 'key_nosignedzero' defined) 
    3030 
    3131   IMPLICIT NONE 
     
    4646   !! * Substitutions 
    4747#  include "do_loop_substitute.h90" 
     48#  include "domzgr_substitute.h90" 
    4849   !!---------------------------------------------------------------------- 
    4950   !! NEMO/OCE 4.0 , NEMO Consortium (2018) 
     
    5758      !!---------------------------------------------------------------------- 
    5859      !!                  ***  ROUTINE tra_adv_fct  *** 
    59       !!  
     60      !! 
    6061      !! **  Purpose :   Compute the now trend due to total advection of tracers 
    6162      !!               and add it to the general trend of tracer equations 
     
    6364      !! **  Method  : - 2nd or 4th FCT scheme on the horizontal direction 
    6465      !!               (choice through the value of kn_fct) 
    65       !!               - on the vertical the 4th order is a compact scheme  
    66       !!               - corrected flux (monotonic correction)  
     66      !!               - on the vertical the 4th order is a compact scheme 
     67      !!               - corrected flux (monotonic correction) 
    6768      !! 
    6869      !! ** Action : - update pt(:,:,:,:,Krhs)  with the now advective tracer trends 
     
    8182      REAL(wp), DIMENSION(jpi,jpj,jpk,kjpt,jpt), INTENT(inout) ::   pt              ! tracers and RHS of tracer equation 
    8283      ! 
    83       INTEGER  ::   ji, jj, jk, jn                           ! dummy loop indices   
     84      INTEGER  ::   ji, jj, jk, jn                           ! dummy loop indices 
    8485      REAL(wp) ::   ztra                                     ! local scalar 
    8586      REAL(wp) ::   zfp_ui, zfp_vj, zfp_wk, zC2t_u, zC4t_u   !   -      - 
     
    102103      ll_zAimp = .FALSE. 
    103104      IF( ( cdtype == 'TRA' .AND. l_trdtra  ) .OR. ( cdtype =='TRC' .AND. l_trdtrc ) )      l_trd = .TRUE. 
    104       IF(   cdtype == 'TRA' .AND. ( iom_use( 'sophtadv' ) .OR. iom_use( 'sophtadv' ) ) )    l_ptr = .TRUE.  
     105      IF(   cdtype == 'TRA' .AND. ( iom_use( 'sophtadv' ) .OR. iom_use( 'sophtadv' ) ) )    l_ptr = .TRUE. 
    105106      IF(   cdtype == 'TRA' .AND. ( iom_use("uadv_heattr") .OR. iom_use("vadv_heattr") .OR.  & 
    106107         &                         iom_use("uadv_salttr") .OR. iom_use("vadv_salttr")  ) )  l_hst = .TRUE. 
     
    111112      ENDIF 
    112113      ! 
    113       IF( l_ptr ) THEN   
     114      IF( l_ptr ) THEN 
    114115         ALLOCATE( zptry(jpi,jpj,jpk) ) 
    115116         zptry(:,:,:) = 0._wp 
    116117      ENDIF 
    117118      !                          ! surface & bottom value : flux set to zero one for all 
    118       zwz(:,:, 1 ) = 0._wp             
     119      zwz(:,:, 1 ) = 0._wp 
    119120      zwx(:,:,jpk) = 0._wp   ;   zwy(:,:,jpk) = 0._wp    ;    zwz(:,:,jpk) = 0._wp 
    120121      ! 
    121       zwi(:,:,:) = 0._wp         
     122      zwi(:,:,:) = 0._wp 
    122123      ! 
    123124      ! If adaptive vertical advection, check if it is needed on this PE at this time 
     
    129130         ALLOCATE(zwdia(jpi,jpj,jpk), zwinf(jpi,jpj,jpk),zwsup(jpi,jpj,jpk)) 
    130131         DO_3D_00_00( 1, jpkm1 ) 
    131             zwdia(ji,jj,jk) =  1._wp + p2dt * ( MAX( wi(ji,jj,jk  ) , 0._wp ) - MIN( wi(ji,jj,jk+1) , 0._wp ) ) / e3t(ji,jj,jk,Krhs) 
     132            zwdia(ji,jj,jk) =  1._wp + p2dt * ( MAX( wi(ji,jj,jk) , 0._wp ) - MIN( wi(ji,jj,jk+1) , 0._wp ) )   & 
     133            &                               / e3t(ji,jj,jk,Krhs) 
    132134            zwinf(ji,jj,jk) =  p2dt * MIN( wi(ji,jj,jk  ) , 0._wp ) / e3t(ji,jj,jk,Krhs) 
    133135            zwsup(ji,jj,jk) = -p2dt * MAX( wi(ji,jj,jk+1) , 0._wp ) / e3t(ji,jj,jk,Krhs) 
     
    138140         ! 
    139141         !        !==  upstream advection with initial mass fluxes & intermediate update  ==! 
    140          !                    !* upstream tracer flux in the i and j direction  
     142         !                    !* upstream tracer flux in the i and j direction 
    141143         DO_3D_10_10( 1, jpkm1 ) 
    142144            ! upstream scheme 
     
    157159            IF( ln_isfcav ) THEN             ! top of the ice-shelf cavities and at the ocean surface 
    158160               DO_2D_11_11 
    159                   zwz(ji,jj, mikt(ji,jj) ) = pW(ji,jj,mikt(ji,jj)) * pt(ji,jj,mikt(ji,jj),jn,Kbb)   ! linear free surface  
     161                  zwz(ji,jj, mikt(ji,jj) ) = pW(ji,jj,mikt(ji,jj)) * pt(ji,jj,mikt(ji,jj),jn,Kbb)   ! linear free surface 
    160162               END_2D 
    161163            ELSE                             ! no cavities: only at the ocean surface 
     
    163165            ENDIF 
    164166         ENDIF 
    165          !                
     167         ! 
    166168         DO_3D_00_00( 1, jpkm1 ) 
    167169            !                             ! total intermediate advective trends 
     
    170172               &      + zwz(ji,jj,jk) - zwz(ji  ,jj  ,jk+1) ) * r1_e1e2t(ji,jj) 
    171173            !                             ! update and guess with monotonic sheme 
    172             pt(ji,jj,jk,jn,Krhs) =                     pt(ji,jj,jk,jn,Krhs) +        ztra   / e3t(ji,jj,jk,Kmm) * tmask(ji,jj,jk) 
    173             zwi(ji,jj,jk)    = ( e3t(ji,jj,jk,Kbb) * pt(ji,jj,jk,jn,Kbb) + p2dt * ztra ) / e3t(ji,jj,jk,Krhs) * tmask(ji,jj,jk) 
     174            pt(ji,jj,jk,jn,Krhs) =                   pt(ji,jj,jk,jn,Krhs) +       ztra   & 
     175               &                                  / e3t(ji,jj,jk,Kmm ) * tmask(ji,jj,jk) 
     176            zwi(ji,jj,jk)    = ( e3t(ji,jj,jk,Kbb) * pt(ji,jj,jk,jn,Kbb) + p2dt * ztra ) & 
     177               &                                  / e3t(ji,jj,jk,Krhs) * tmask(ji,jj,jk) 
    174178         END_3D 
    175           
     179 
    176180         IF ( ll_zAimp ) THEN 
    177181            CALL tridia_solver( zwdia, zwsup, zwinf, zwi, zwi , 0 ) 
     
    186190            DO_3D_00_00( 1, jpkm1 ) 
    187191               pt(ji,jj,jk,jn,Krhs) = pt(ji,jj,jk,jn,Krhs) - ( ztw(ji,jj,jk) - ztw(ji  ,jj  ,jk+1) ) & 
    188                   &                                        * r1_e1e2t(ji,jj) / e3t(ji,jj,jk,Kmm) 
     192                  &                                     * r1_e1e2t(ji,jj) / e3t(ji,jj,jk,Kmm) 
    189193            END_3D 
    190194            ! 
    191195         END IF 
    192          !                 
     196         ! 
    193197         IF( l_trd .OR. l_hst )  THEN             ! trend diagnostics (contribution of upstream fluxes) 
    194198            ztrdx(:,:,:) = zwx(:,:,:)   ;   ztrdy(:,:,:) = zwy(:,:,:)   ;   ztrdz(:,:,:) = zwz(:,:,:) 
    195199         END IF 
    196200         !                             ! "Poleward" heat and salt transports (contribution of upstream fluxes) 
    197          IF( l_ptr )   zptry(:,:,:) = zwy(:,:,:)  
     201         IF( l_ptr )   zptry(:,:,:) = zwy(:,:,:) 
    198202         ! 
    199203         !        !==  anti-diffusive flux : high order minus low order  ==! 
     
    225229               zC2t_u = pt(ji,jj,jk,jn,Kmm) + pt(ji+1,jj  ,jk,jn,Kmm)   ! 2 x C2 interpolation of T at u- & v-points 
    226230               zC2t_v = pt(ji,jj,jk,jn,Kmm) + pt(ji  ,jj+1,jk,jn,Kmm) 
    227                !                                                  ! C4 minus upstream advective fluxes  
     231               !                                                  ! C4 minus upstream advective fluxes 
    228232               zwx(ji,jj,jk) =  0.5_wp * pU(ji,jj,jk) * ( zC2t_u + zltu(ji,jj,jk) - zltu(ji+1,jj,jk) ) - zwx(ji,jj,jk) 
    229233               zwy(ji,jj,jk) =  0.5_wp * pV(ji,jj,jk) * ( zC2t_v + zltv(ji,jj,jk) - zltv(ji,jj+1,jk) ) - zwy(ji,jj,jk) 
     
    245249               zC4t_u =  zC2t_u + r1_6 * ( ztu(ji-1,jj  ,jk) - ztu(ji+1,jj  ,jk) ) 
    246250               zC4t_v =  zC2t_v + r1_6 * ( ztv(ji  ,jj-1,jk) - ztv(ji  ,jj+1,jk) ) 
    247                !                                                  ! C4 minus upstream advective fluxes  
     251               !                                                  ! C4 minus upstream advective fluxes 
    248252               zwx(ji,jj,jk) =  0.5_wp * pU(ji,jj,jk) * zC4t_u - zwx(ji,jj,jk) 
    249253               zwy(ji,jj,jk) =  0.5_wp * pV(ji,jj,jk) * zC4t_v - zwy(ji,jj,jk) 
     
    251255            ! 
    252256         END SELECT 
    253          !                       
     257         ! 
    254258         SELECT CASE( kn_fct_v )    !* vertical anti-diffusive fluxes (w-masked interior values) 
    255259         ! 
     
    270274            zwz(:,:,1) = 0._wp   ! only ocean surface as interior zwz values have been w-masked 
    271275         ENDIF 
    272          !          
     276         ! 
    273277         IF ( ll_zAimp ) THEN 
    274278            DO_3D_00_00( 1, jpkm1 ) 
     
    277281                  &      + zwy(ji,jj,jk) - zwy(ji  ,jj-1,jk  )   & 
    278282                  &      + zwz(ji,jj,jk) - zwz(ji  ,jj  ,jk+1) ) * r1_e1e2t(ji,jj) 
    279                ztw(ji,jj,jk)  = zwi(ji,jj,jk) + p2dt * ztra / e3t(ji,jj,jk,Krhs) * tmask(ji,jj,jk) 
     283               ztw(ji,jj,jk) = zwi(ji,jj,jk) + p2dt * ztra / e3t(ji,jj,jk,Krhs)*tmask(ji,jj,jk) 
    280284            END_3D 
    281285            ! 
     
    316320            DO_3D_00_00( 1, jpkm1 ) 
    317321               pt(ji,jj,jk,jn,Krhs) = pt(ji,jj,jk,jn,Krhs) - ( ztw(ji,jj,jk) - ztw(ji  ,jj  ,jk+1) ) & 
    318                   &                                        * r1_e1e2t(ji,jj) / e3t(ji,jj,jk,Kmm) 
    319             END_3D 
    320          END IF          
     322                  &                                     * r1_e1e2t(ji,jj) / e3t(ji,jj,jk,Kmm) 
     323            END_3D 
     324         END IF 
    321325         ! 
    322326         IF( l_trd .OR. l_hst ) THEN   ! trend diagnostics // heat/salt transport 
    323             ztrdx(:,:,:) = ztrdx(:,:,:) + zwx(:,:,:)  ! <<< add anti-diffusive fluxes  
     327            ztrdx(:,:,:) = ztrdx(:,:,:) + zwx(:,:,:)  ! <<< add anti-diffusive fluxes 
    324328            ztrdy(:,:,:) = ztrdy(:,:,:) + zwy(:,:,:)  !     to upstream fluxes 
    325329            ztrdz(:,:,:) = ztrdz(:,:,:) + zwz(:,:,:)  ! 
     
    344348         DEALLOCATE( zwdia, zwinf, zwsup ) 
    345349      ENDIF 
    346       IF( l_trd .OR. l_hst ) THEN  
     350      IF( l_trd .OR. l_hst ) THEN 
    347351         DEALLOCATE( ztrdx, ztrdy, ztrdz ) 
    348352      ENDIF 
    349       IF( l_ptr ) THEN  
     353      IF( l_ptr ) THEN 
    350354         DEALLOCATE( zptry ) 
    351355      ENDIF 
     
    357361      !!--------------------------------------------------------------------- 
    358362      !!                    ***  ROUTINE nonosc  *** 
    359       !!      
    360       !! **  Purpose :   compute monotonic tracer fluxes from the upstream  
    361       !!       scheme and the before field by a nonoscillatory algorithm  
     363      !! 
     364      !! **  Purpose :   compute monotonic tracer fluxes from the upstream 
     365      !!       scheme and the before field by a nonoscillatory algorithm 
    362366      !! 
    363367      !! **  Method  :   ... ??? 
     
    367371      !!       in-space based differencing for fluid 
    368372      !!---------------------------------------------------------------------- 
    369       INTEGER                          , INTENT(in   ) ::   Kmm             ! time level index  
     373      INTEGER                          , INTENT(in   ) ::   Kmm             ! time level index 
    370374      REAL(wp)                         , INTENT(in   ) ::   p2dt            ! tracer time-step 
    371375      REAL(wp), DIMENSION (jpi,jpj,jpk), INTENT(in   ) ::   pbef, paft      ! before & after field 
     
    453457      !!---------------------------------------------------------------------- 
    454458      !!                  ***  ROUTINE interp_4th_cpt_org  *** 
    455       !!  
     459      !! 
    456460      !! **  Purpose :   Compute the interpolation of tracer at w-point 
    457461      !! 
     
    464468      REAL(wp),DIMENSION(jpi,jpj,jpk) :: zwd, zwi, zws, zwrm, zwt 
    465469      !!---------------------------------------------------------------------- 
    466        
     470 
    467471      DO_3D_11_11( 3, jpkm1 ) 
    468472         zwd (ji,jj,jk) = 4._wp 
     
    475479            zwi (ji,jj,jk) = 0._wp 
    476480            zws (ji,jj,jk) = 0._wp 
    477             zwrm(ji,jj,jk) = 0.5 * ( pt_in(ji,jj,jk-1) + pt_in(ji,jj,jk) )     
     481            zwrm(ji,jj,jk) = 0.5 * ( pt_in(ji,jj,jk-1) + pt_in(ji,jj,jk) ) 
    478482         ENDIF 
    479483      END_3D 
     
    499503      END_2D 
    500504      DO_3D_11_11( 3, jpkm1 ) 
    501          pt_out(ji,jj,jk) = zwrm(ji,jj,jk) - zwi(ji,jj,jk) / zwt(ji,jj,jk-1) *pt_out(ji,jj,jk-1)              
     505         pt_out(ji,jj,jk) = zwrm(ji,jj,jk) - zwi(ji,jj,jk) / zwt(ji,jj,jk-1) *pt_out(ji,jj,jk-1) 
    502506      END_3D 
    503507 
     
    508512         pt_out(ji,jj,jk) = ( pt_out(ji,jj,jk) - zws(ji,jj,jk) * pt_out(ji,jj,jk+1) ) / zwt(ji,jj,jk) 
    509513      END_3D 
    510       !     
     514      ! 
    511515   END SUBROUTINE interp_4th_cpt_org 
    512     
     516 
    513517 
    514518   SUBROUTINE interp_4th_cpt( pt_in, pt_out ) 
    515519      !!---------------------------------------------------------------------- 
    516520      !!                  ***  ROUTINE interp_4th_cpt  *** 
    517       !!  
     521      !! 
    518522      !! **  Purpose :   Compute the interpolation of tracer at w-point 
    519523      !! 
     
    543547!      CASE( np_CEN2 )   ! 2nd order centered  at top & bottom 
    544548!      END SELECT 
    545 !!gm   
     549!!gm 
    546550      ! 
    547551      IF ( ln_isfcav ) THEN            ! set level two values which may not be set in ISF case 
     
    561565         zwi (ji,jj,ikb) = 0._wp 
    562566         zws (ji,jj,ikb) = 0._wp 
    563          zwrm(ji,jj,ikb) = 0.5_wp * ( pt_in(ji,jj,ikb-1) + pt_in(ji,jj,ikb) )             
     567         zwrm(ji,jj,ikb) = 0.5_wp * ( pt_in(ji,jj,ikb-1) + pt_in(ji,jj,ikb) ) 
    564568      END_2D 
    565569      ! 
     
    577581      END_2D 
    578582      DO_3D_00_00( 3, jpkm1 ) 
    579          pt_out(ji,jj,jk) = zwrm(ji,jj,jk) - zwi(ji,jj,jk) / zwt(ji,jj,jk-1) *pt_out(ji,jj,jk-1)              
     583         pt_out(ji,jj,jk) = zwrm(ji,jj,jk) - zwi(ji,jj,jk) / zwt(ji,jj,jk-1) *pt_out(ji,jj,jk-1) 
    580584      END_3D 
    581585 
     
    586590         pt_out(ji,jj,jk) = ( pt_out(ji,jj,jk) - zws(ji,jj,jk) * pt_out(ji,jj,jk+1) ) / zwt(ji,jj,jk) 
    587591      END_3D 
    588       !     
     592      ! 
    589593   END SUBROUTINE interp_4th_cpt 
    590594 
     
    593597      !!---------------------------------------------------------------------- 
    594598      !!                  ***  ROUTINE tridia_solver  *** 
    595       !!  
     599      !! 
    596600      !! **  Purpose :   solve a symmetric 3diagonal system 
    597601      !! 
    598602      !! **  Method  :   solve M.t_out = RHS(t)  where M is a tri diagonal matrix ( jpk*jpk ) 
    599       !!      
     603      !! 
    600604      !!             ( D_1 U_1  0   0   0  )( t_1 )   ( RHS_1 ) 
    601605      !!             ( L_2 D_2 U_2  0   0  )( t_2 )   ( RHS_2 ) 
     
    603607      !!             (        ...          )( ... )   ( ...  ) 
    604608      !!             (  0   0   0  L_k D_k )( t_k )   ( RHS_k ) 
    605       !!      
     609      !! 
    606610      !!        M is decomposed in the product of an upper and lower triangular matrix. 
    607       !!        The tri-diagonals matrix is given as input 3D arrays:   pD, pU, pL  
     611      !!        The tri-diagonals matrix is given as input 3D arrays:   pD, pU, pL 
    608612      !!        (i.e. the Diagonal, the Upper diagonal, and the Lower diagonal). 
    609613      !!        The solution is pta. 
     
    613617      REAL(wp),DIMENSION(:,:,:), INTENT(in   ) ::   pRHS          ! Right-Hand-Side 
    614618      REAL(wp),DIMENSION(:,:,:), INTENT(  out) ::   pt_out        !!gm field at level=F(klev) 
    615       INTEGER                  , INTENT(in   ) ::   klev          ! =1 pt_out at w-level  
     619      INTEGER                  , INTENT(in   ) ::   klev          ! =1 pt_out at w-level 
    616620      !                                                           ! =0 pt at t-level 
    617621      INTEGER ::   ji, jj, jk   ! dummy loop integers 
     
    633637      END_2D 
    634638      DO_3D_00_00( kstart+1, jpkm1 ) 
    635          pt_out(ji,jj,jk) = pRHS(ji,jj,jk) - pL(ji,jj,jk) / zwt(ji,jj,jk-1) *pt_out(ji,jj,jk-1)              
     639         pt_out(ji,jj,jk) = pRHS(ji,jj,jk) - pL(ji,jj,jk) / zwt(ji,jj,jk-1) *pt_out(ji,jj,jk-1) 
    636640      END_3D 
    637641 
Note: See TracChangeset for help on using the changeset viewer.