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 1438 for trunk/NEMO/OPA_SRC/TRA/tranxt.F90 – NEMO

Ignore:
Timestamp:
2009-05-11T16:34:47+02:00 (15 years ago)
Author:
rblod
Message:

Merge VVL branch with the trunk (act II), see ticket #429

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/NEMO/OPA_SRC/TRA/tranxt.F90

    r1146 r1438  
    1414   !!            2.0  !  2006-02  (L. Debreu, C. Mazauric) Agrif implementation 
    1515   !!            3.0  !  2008-06  (G. Madec)  time stepping always done in trazdf 
     16   !!            3.1  !  2009-02  (G. Madec, R. Benshila)  re-introduce the vvl option 
    1617   !!---------------------------------------------------------------------- 
    1718 
    1819   !!---------------------------------------------------------------------- 
    1920   !!   tra_nxt       : time stepping on temperature and salinity 
     21   !!   tra_nxt_fix   : time stepping on temperature and salinity : fixed    volume case 
     22   !!   tra_nxt_vvl   : time stepping on temperature and salinity : variable volume case 
    2023   !!---------------------------------------------------------------------- 
    2124   USE oce             ! ocean dynamics and tracers variables 
    2225   USE dom_oce         ! ocean space and time domain variables  
    2326   USE zdf_oce         ! ??? 
     27   USE domvvl          ! variable volume 
    2428   USE dynspg_oce      ! surface pressure gradient variables 
    2529   USE trdmod_oce      ! ocean variables trends 
     
    3943   PUBLIC   tra_nxt    ! routine called by step.F90 
    4044 
     45   REAL(wp), DIMENSION(jpk) ::   r2dt_t   ! vertical profile time step, =2*rdttra (leapfrog) or =rdttra (Euler) 
     46 
    4147   !! * Substitutions 
    4248#  include "domzgr_substitute.h90" 
     
    6773      !!             at the AGRIF zoom     boundaries (lk_agrif=T) 
    6874      !! 
    69       !!              - Apply the Asselin time filter on now fields, 
    70       !!             save in (ta,sa) an average over the three time levels  
    71       !!             which will be used to compute rdn and thus the semi-implicit 
    72       !!             hydrostatic pressure gradient (ln_dynhpg_imp = T), and 
    73       !!             swap tracer fields to prepare the next time_step. 
    74       !!                This can be summurized for tempearture as: 
    75       !!                    zt = (ta+2tn+tb)/4       ln_dynhpg_imp = T 
    76       !!                    zt = 0                   otherwise 
    77       !!                    tb = tn + atfp*[ tb - 2 tn + ta ] 
    78       !!                    tn = ta  
    79       !!                    ta = zt        (NB: reset to 0 after eos_bn2 call) 
     75      !!              - Update lateral boundary conditions on AGRIF children 
     76      !!             domains (lk_agrif=T) 
    8077      !! 
    8178      !! ** Action  : - (tb,sb) and (tn,sn) ready for the next time step 
     
    8784      INTEGER, INTENT(in) ::   kt    ! ocean time-step index 
    8885      !! 
    89       INTEGER  ::   ji, jj, jk    ! dummy loop indices 
    90       REAL(wp) ::   zt, zs, zfact ! temporary scalars 
     86      INTEGER  ::   jk    ! dummy loop indices 
     87      REAL(wp) ::   zfact ! temporary scalars 
    9188      !!---------------------------------------------------------------------- 
    9289 
     
    111108      CALL Agrif_tra                   ! AGRIF zoom boundaries 
    112109#endif 
     110  
     111      ! set time step size (Euler/Leapfrog) 
     112      IF( neuler == 0 .AND. kt == nit000 ) THEN   ;   r2dt_t(:) =     rdttra(:)      ! at nit000             (Euler) 
     113      ELSEIF( kt <= nit000 + 1 )           THEN   ;   r2dt_t(:) = 2.* rdttra(:)      ! at nit000 or nit000+1 (Leapfrog) 
     114      ENDIF 
    113115 
    114116      ! trends computation initialisation 
     
    118120      ENDIF 
    119121 
    120       ! Asselin time filter and swap of arrays 
    121       !                                              
    122       IF( neuler == 0 .AND. kt == nit000 ) THEN      ! Euler 1st time step : swap only 
    123          DO jk = 1, jpkm1 
    124             tb(:,:,jk) = tn(:,:,jk)                       ! ta, sa remain at their values which 
    125             sb(:,:,jk) = sn(:,:,jk)                       ! correspond to tn, sn after the sawp 
    126             tn(:,:,jk) = ta(:,:,jk)                      
    127             sn(:,:,jk) = sa(:,:,jk) 
    128          END DO 
    129          !                                            
    130       ELSE                                           ! Leap-Frog : filter + swap 
    131          !                                             
    132          IF( ln_dynhpg_imp ) THEN                         ! semi-implicite hpg case 
    133             DO jk = 1, jpkm1                              ! (save the averaged of the 3 time steps  
    134                DO jj = 1, jpj                             !                   in the after fields) 
    135                   DO ji = 1, jpi 
    136                      zt = ( ta(ji,jj,jk) + 2. * tn(ji,jj,jk) + tb(ji,jj,jk) ) * 0.25 
    137                      zs = ( sa(ji,jj,jk) + 2. * sn(ji,jj,jk) + sb(ji,jj,jk) ) * 0.25 
    138                      tb(ji,jj,jk) = atfp * ( tb(ji,jj,jk) + ta(ji,jj,jk) ) + atfp1 * tn(ji,jj,jk) 
    139                      sb(ji,jj,jk) = atfp * ( sb(ji,jj,jk) + sa(ji,jj,jk) ) + atfp1 * sn(ji,jj,jk) 
    140                      tn(ji,jj,jk) = ta(ji,jj,jk) 
    141                      sn(ji,jj,jk) = sa(ji,jj,jk) 
    142                      ta(ji,jj,jk) = zt 
    143                      sa(ji,jj,jk) = zs 
    144                   END DO 
    145                END DO 
    146             END DO 
    147          ELSE                                            ! explicit hpg case 
    148             DO jk = 1, jpkm1 
    149                DO jj = 1, jpj 
    150                   DO ji = 1, jpi 
    151                      tb(ji,jj,jk) = atfp * ( tb(ji,jj,jk) + ta(ji,jj,jk) ) + atfp1 * tn(ji,jj,jk) 
    152                      sb(ji,jj,jk) = atfp * ( sb(ji,jj,jk) + sa(ji,jj,jk) ) + atfp1 * sn(ji,jj,jk) 
    153                      tn(ji,jj,jk) = ta(ji,jj,jk) 
    154                      sn(ji,jj,jk) = sa(ji,jj,jk) 
    155                   END DO 
    156                END DO 
    157             END DO 
    158          ENDIF 
    159          ! 
     122      ! Leap-Frog + Asselin filter time stepping 
     123      IF( lk_vvl )   THEN   ;   CALL tra_nxt_vvl( kt )      ! variable volume level (vvl) 
     124      ELSE                  ;   CALL tra_nxt_fix( kt )      ! fixed    volume level 
    160125      ENDIF 
    161126 
     
    165130#endif       
    166131 
    167       ! trends diagnostics :  Asselin filter trend : (tb filtered - tb)/2dt 
    168       IF( l_trdtra ) THEN      
     132      ! trends computation 
     133      IF( l_trdtra ) THEN              ! trend of the Asselin filter (tb filtered - tb)/dt      
    169134         DO jk = 1, jpkm1 
    170             zfact = 1.e0 / ( 2.*rdttra(jk) )             ! NB: euler case, (tb filtered - tb)=0 so 2dt always OK 
     135            zfact = 1.e0 / r2dt_t(jk)              
    171136            ztrdt(:,:,jk) = ( tb(:,:,jk) - ztrdt(:,:,jk) ) * zfact 
    172137            ztrds(:,:,jk) = ( sb(:,:,jk) - ztrds(:,:,jk) ) * zfact 
     
    174139         CALL trd_mod( ztrdt, ztrds, jptra_trd_atf, 'TRA', kt ) 
    175140      END IF 
     141 
    176142      !                        ! control print 
    177143      IF(ln_ctl)   CALL prt_ctl( tab3d_1=tn, clinfo1=' nxt  - Tn: ', mask1=tmask,   & 
     
    180146   END SUBROUTINE tra_nxt 
    181147 
     148 
     149   SUBROUTINE tra_nxt_fix( kt ) 
     150      !!---------------------------------------------------------------------- 
     151      !!                   ***  ROUTINE tra_nxt_fix  *** 
     152      !! 
     153      !! ** Purpose :   fixed volume: apply the Asselin time filter and  
     154      !!                swap the tracer fields. 
     155      !!  
     156      !! ** Method  : - Apply a Asselin time filter on now fields. 
     157      !!              - save in (ta,sa) an average over the three time levels  
     158      !!             which will be used to compute rdn and thus the semi-implicit 
     159      !!             hydrostatic pressure gradient (ln_dynhpg_imp = T) 
     160      !!              - swap tracer fields to prepare the next time_step. 
     161      !!                This can be summurized for tempearture as: 
     162      !!             ztm = (ta+2tn+tb)/4       ln_dynhpg_imp = T 
     163      !!             ztm = 0                   otherwise 
     164      !!             tb  = tn + atfp*[ tb - 2 tn + ta ] 
     165      !!             tn  = ta  
     166      !!             ta  = ztm       (NB: reset to 0 after eos_bn2 call) 
     167      !! 
     168      !! ** Action  : - (tb,sb) and (tn,sn) ready for the next time step 
     169      !!              - (ta,sa) time averaged (t,s)   (ln_dynhpg_imp = T) 
     170      !!---------------------------------------------------------------------- 
     171      INTEGER, INTENT(in) ::   kt    ! ocean time-step index 
     172      !! 
     173      INTEGER  ::   ji, jj, jk   ! dummy loop indices 
     174      REAL(wp) ::   ztm, ztf     ! temporary scalars 
     175      REAL(wp) ::   zsm, zsf     !    -         - 
     176      !!---------------------------------------------------------------------- 
     177 
     178      IF( kt == nit000 ) THEN 
     179         IF(lwp) WRITE(numout,*) 
     180         IF(lwp) WRITE(numout,*) 'tra_nxt_fix : time stepping' 
     181         IF(lwp) WRITE(numout,*) '~~~~~~~~~~~' 
     182      ENDIF 
     183      ! 
     184      !                                              ! ----------------------- ! 
     185      IF( ln_dynhpg_imp ) THEN                       ! semi-implicite hpg case ! 
     186         !                                           ! ----------------------- ! 
     187         ! 
     188         IF( neuler == 0 .AND. kt == nit000 ) THEN        ! Euler time-stepping at first time-step 
     189            DO jk = 1, jpkm1                              ! (only swap) 
     190               DO jj = 1, jpj 
     191                  DO ji = 1, jpi 
     192                     tn(ji,jj,jk) = ta(ji,jj,jk)                                           ! tb <-- tn 
     193                     sn(ji,jj,jk) = sa(ji,jj,jk) 
     194                  END DO 
     195               END DO 
     196            END DO 
     197         ELSE                                             ! general case (Leapfrog + Asselin filter 
     198            DO jk = 1, jpkm1 
     199               DO jj = 1, jpj 
     200                  DO ji = 1, jpi 
     201                     ztm = 0.25 * ( ta(ji,jj,jk) + 2.* tn(ji,jj,jk) + tb(ji,jj,jk) )       ! mean t 
     202                     zsm = 0.25 * ( sa(ji,jj,jk) + 2.* sn(ji,jj,jk) + sb(ji,jj,jk) ) 
     203                     ztf = atfp * ( ta(ji,jj,jk) - 2.* tn(ji,jj,jk) + tb(ji,jj,jk) )       ! Asselin filter on t  
     204                     zsf = atfp * ( sa(ji,jj,jk) - 2.* sn(ji,jj,jk) + sb(ji,jj,jk) ) 
     205                     tb(ji,jj,jk) = tn(ji,jj,jk) + ztf                                     ! tb <-- filtered tn  
     206                     sb(ji,jj,jk) = sn(ji,jj,jk) + zsf 
     207                     tn(ji,jj,jk) = ta(ji,jj,jk)                                           ! tn <-- ta 
     208                     sn(ji,jj,jk) = sa(ji,jj,jk) 
     209                     ta(ji,jj,jk) = ztm                                                    ! ta <-- mean t 
     210                     sa(ji,jj,jk) = zsm 
     211                  END DO 
     212               END DO 
     213            END DO 
     214         ENDIF 
     215         !                                           ! ----------------------- ! 
     216      ELSE                                           !    explicit hpg case    ! 
     217         !                                           ! ----------------------- ! 
     218         ! 
     219         IF( neuler == 0 .AND. kt == nit000 ) THEN        ! Euler time-stepping at first time-step 
     220            DO jk = 1, jpkm1 
     221               DO jj = 1, jpj 
     222                  DO ji = 1, jpi 
     223                     tn(ji,jj,jk) = ta(ji,jj,jk)                                           ! tn <-- ta 
     224                     sn(ji,jj,jk) = sa(ji,jj,jk) 
     225                  END DO 
     226               END DO 
     227            END DO 
     228         ELSE                                             ! general case (Leapfrog + Asselin filter 
     229            DO jk = 1, jpkm1 
     230               DO jj = 1, jpj 
     231                  DO ji = 1, jpi 
     232                     ztf = atfp * ( ta(ji,jj,jk) - 2.* tn(ji,jj,jk) + tb(ji,jj,jk) )       ! Asselin filter on t  
     233                     zsf = atfp * ( sa(ji,jj,jk) - 2.* sn(ji,jj,jk) + sb(ji,jj,jk) ) 
     234                     tb(ji,jj,jk) = tn(ji,jj,jk) + ztf                                     ! tb <-- filtered tn  
     235                     sb(ji,jj,jk) = sn(ji,jj,jk) + zsf 
     236                     tn(ji,jj,jk) = ta(ji,jj,jk)                                           ! tn <-- ta 
     237                     sn(ji,jj,jk) = sa(ji,jj,jk) 
     238                  END DO 
     239               END DO 
     240            END DO 
     241         ENDIF 
     242      ENDIF 
     243      ! 
     244   END SUBROUTINE tra_nxt_fix 
     245 
     246 
     247   SUBROUTINE tra_nxt_vvl( kt ) 
     248      !!---------------------------------------------------------------------- 
     249      !!                   ***  ROUTINE tra_nxt_vvl  *** 
     250      !! 
     251      !! ** Purpose :   Time varying volume: apply the Asselin time filter   
     252      !!                and swap the tracer fields. 
     253      !!  
     254      !! ** Method  : - Apply a thickness weighted Asselin time filter on now fields. 
     255      !!              - save in (ta,sa) a thickness weighted average over the three  
     256      !!             time levels which will be used to compute rdn and thus the semi- 
     257      !!             implicit hydrostatic pressure gradient (ln_dynhpg_imp = T) 
     258      !!              - swap tracer fields to prepare the next time_step. 
     259      !!                This can be summurized for tempearture as: 
     260      !!             ztm = (e3t_a*ta+2*e3t_n*tn+e3t_b*tb)   ln_dynhpg_imp = T 
     261      !!                  /(e3t_a   +2*e3t_n   +e3t_b   )     
     262      !!             ztm = 0                                otherwise 
     263      !!             tb  = ( e3t_n*tn + atfp*[ e3t_b*tb - 2 e3t_n*tn + e3t_a*ta ] ) 
     264      !!                  /( e3t_n    + atfp*[ e3t_b    - 2 e3t_n    + e3t_a    ] ) 
     265      !!             tn  = ta  
     266      !!             ta  = zt        (NB: reset to 0 after eos_bn2 call) 
     267      !! 
     268      !! ** Action  : - (tb,sb) and (tn,sn) ready for the next time step 
     269      !!              - (ta,sa) time averaged (t,s)   (ln_dynhpg_imp = T) 
     270      !!---------------------------------------------------------------------- 
     271      INTEGER, INTENT(in) ::   kt    ! ocean time-step index 
     272      !!      
     273      INTEGER  ::   ji, jj, jk             ! dummy loop indices 
     274      REAL(wp) ::   ztm , ztc_f , ztf , ztca, ztcn, ztcb   ! temporary scalar 
     275      REAL(wp) ::   zsm , zsc_f , zsf , zsca, zscn, zscb   !    -         - 
     276      REAL(wp) ::   ze3mr, ze3fr                           !    -         - 
     277      REAL(wp) ::   ze3t_b, ze3t_n, ze3t_a, ze3t_f         !    -         - 
     278      !!---------------------------------------------------------------------- 
     279 
     280      IF( kt == nit000 ) THEN 
     281         IF(lwp) WRITE(numout,*) 
     282         IF(lwp) WRITE(numout,*) 'tra_nxt_vvl : time stepping' 
     283         IF(lwp) WRITE(numout,*) '~~~~~~~~~~~' 
     284      ENDIF 
     285 
     286      !                                              ! ----------------------- ! 
     287      IF( ln_dynhpg_imp ) THEN                       ! semi-implicite hpg case ! 
     288         !                                           ! ----------------------- ! 
     289         ! 
     290         IF( neuler == 0 .AND. kt == nit000 ) THEN        ! Euler time-stepping at first time-step 
     291            DO jk = 1, jpkm1                              ! (only swap) 
     292               DO jj = 1, jpj 
     293                  DO ji = 1, jpi 
     294                     tn(ji,jj,jk) = ta(ji,jj,jk)                    ! tn <-- ta 
     295                     sn(ji,jj,jk) = sa(ji,jj,jk) 
     296                  END DO 
     297               END DO 
     298            END DO 
     299         ELSE 
     300            DO jk = 1, jpkm1 
     301               DO jj = 1, jpj 
     302                  DO ji = 1, jpi 
     303                     ze3t_b = fse3t_b(ji,jj,jk) 
     304                     ze3t_n = fse3t_n(ji,jj,jk) 
     305                     ze3t_a = fse3t_a(ji,jj,jk) 
     306                     !                                         ! tracer content at Before, now and after 
     307                     ztcb = tb(ji,jj,jk) *  ze3t_b   ;   zscb = sb(ji,jj,jk) * ze3t_b 
     308                     ztcn = tn(ji,jj,jk) *  ze3t_n   ;   zscn = sn(ji,jj,jk) * ze3t_n 
     309                     ztca = ta(ji,jj,jk) *  ze3t_a   ;   zsca = sa(ji,jj,jk) * ze3t_a 
     310                     ! 
     311                     !                                         ! Asselin filter on thickness and tracer content 
     312                     ze3t_f = atfp * ( ze3t_a - 2.* ze3t_n + ze3t_b ) 
     313                     ztc_f  = atfp * ( ztca   - 2.* ztcn   + ztcb   )  
     314                     zsc_f  = atfp * ( zsca   - 2.* zscn   + zscb   )  
     315                     ! 
     316                     !                                         ! filtered tracer including the correction  
     317                     ze3fr = 1.e0  / ( ze3t_n + ze3t_f ) 
     318                     ztf   = ze3fr * ( ztcn   + ztc_f  ) 
     319                     zsf   = ze3fr * ( zscn   + zsc_f  ) 
     320                     !                                         ! mean thickness and tracer 
     321                     ze3mr = 1.e0  / ( ze3t_a + 2.* ze3t_n + ze3t_b ) 
     322                     ztm   = ze3mr * ( ztca   + 2.* ztcn   + ztcb   ) 
     323                     zsm   = ze3mr * ( zsca   + 2.* zscn   + zscb   ) 
     324!!gm mean e3t have to be saved and used in dynhpg  or it can be recomputed in dynhpg !! 
     325!!gm                 e3t_m(ji,jj,jk) = 0.25 / ze3mr 
     326                     !                                         ! swap of arrays 
     327                     tb(ji,jj,jk) = ztf                             ! tb <-- tn + filter 
     328                     sb(ji,jj,jk) = zsf 
     329                     tn(ji,jj,jk) = ta(ji,jj,jk)                    ! tn <-- ta 
     330                     sn(ji,jj,jk) = sa(ji,jj,jk) 
     331                     ta(ji,jj,jk) = ztm                             ! ta <-- mean t 
     332                     sa(ji,jj,jk) = zsm 
     333                  END DO 
     334               END DO 
     335            END DO 
     336         ENDIF 
     337         !                                           ! ----------------------- ! 
     338      ELSE                                           !    explicit hpg case    ! 
     339         !                                           ! ----------------------- ! 
     340         ! 
     341         IF( neuler == 0 .AND. kt == nit000 ) THEN        ! case of Euler time-stepping at first time-step 
     342            DO jk = 1, jpkm1                              ! No filter nor thickness weighting computation required 
     343               DO jj = 1, jpj                             ! ONLY swap 
     344                  DO ji = 1, jpi 
     345                     tn(ji,jj,jk) = ta(ji,jj,jk)                                 ! tn <-- ta 
     346                     sn(ji,jj,jk) = sa(ji,jj,jk) 
     347                  END DO 
     348               END DO 
     349            END DO 
     350            !                                             ! general case (Leapfrog + Asselin filter) 
     351         ELSE                                             ! apply filter on thickness weighted tracer and swap 
     352            DO jk = 1, jpkm1 
     353               DO jj = 1, jpj 
     354                  DO ji = 1, jpi 
     355                     ze3t_b = fse3t_b(ji,jj,jk) 
     356                     ze3t_n = fse3t_n(ji,jj,jk) 
     357                     ze3t_a = fse3t_a(ji,jj,jk) 
     358                     !                                         ! tracer content at Before, now and after 
     359                     ztcb = tb(ji,jj,jk) *  ze3t_b   ;   zscb = sb(ji,jj,jk) * ze3t_b 
     360                     ztcn = tn(ji,jj,jk) *  ze3t_n   ;   zscn = sn(ji,jj,jk) * ze3t_n 
     361                     ztca = ta(ji,jj,jk) *  ze3t_a   ;   zsca = sa(ji,jj,jk) * ze3t_a 
     362                     ! 
     363                     !                                         ! Asselin filter on thickness and tracer content 
     364                     ze3t_f = atfp * ( ze3t_a - 2.* ze3t_n + ze3t_b ) 
     365                     ztc_f  = atfp * ( ztca   - 2.* ztcn   + ztcb   )  
     366                     zsc_f  = atfp * ( zsca   - 2.* zscn   + zscb   )  
     367                     ! 
     368                     !                                         ! filtered tracer including the correction  
     369                     ze3fr = 1.e0 / ( ze3t_n + ze3t_f ) 
     370                     ztf   =  ( ztcn  + ztc_f ) * ze3fr 
     371                     zsf   =  ( zscn  + zsc_f ) * ze3fr 
     372                     !                                         ! swap of arrays 
     373                     tb(ji,jj,jk) = ztf                             ! tb <-- tn filtered 
     374                     sb(ji,jj,jk) = zsf 
     375                     tn(ji,jj,jk) = ta(ji,jj,jk)                    ! tn <-- ta 
     376                     sn(ji,jj,jk) = sa(ji,jj,jk) 
     377                  END DO 
     378               END DO 
     379            END DO 
     380         ENDIF 
     381      ENDIF 
     382      ! 
     383   END SUBROUTINE tra_nxt_vvl 
     384 
    182385   !!====================================================================== 
    183386END MODULE tranxt 
Note: See TracChangeset for help on using the changeset viewer.