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.
#456 (Compute vertical viscosity/diffusion coefficients due to internal tidal mixing: optimisation) – NEMO

Opened 15 years ago

Closed 15 years ago

Last modified 7 years ago

#456 closed Enhancement (duplicate)

Compute vertical viscosity/diffusion coefficients due to internal tidal mixing: optimisation

Reported by: gm Owned by: nemo
Priority: low Milestone:
Component: OCE Version: v3.1
Severity: Keywords: ZDF mixing
Cc:

Description

Minor optimisations in zdftmx.F90 :

abstract :

# move arrays from the header of zdftmx to the header of the routine included into zdftmx (same in-core memory)

# remove the computation of zsum1 and zsum2 which are not used in tmx_itf

# transform tmx_itf to only update av_tide, save CPU-time by avoiding duplication of avmu, avmv computation

# on-line documentation: header of the routines has been updated (see attachment)

in attachment, the modified zdftmx.F90 and zdf_oce.F90 are given as a example only. They have been neither used with NVTK nor even compiled.

pending issue:

# the paper documentation is still missing

# with new IOM, the av_tide should be removed from zdf_oce and put in zdfmix.F90, as the iomput will be done directly in zdfmix.F90 (nomore in diawri)

# in zdf_itf, the 4 local arrays (zempba_3d_1, zempba_3d_2, zempba_3d , zdn2dz) can be defined in memory using ua,va, ta, sa as they are workspace at this stage

# some comments starting with !!gm that should improve both the style and the speed of the computation

details:

# 1 decrease the memory requirement by more than 7 3D arrays:

  • az_tsm and zempba removed from the head of zdftmx module, since never used. So the following declarations can be removed
   REAL(wp), DIMENSION(jpi,jpj,jpk) ::   az_tsm          ! avt(tidal) = avt0 + az_tmx / n2
   REAL(wp), DIMENSION(jpk) ::   zempba                  ! zempba profil vertical d'energie
  • az_tmx_itf removed since only locally used in tmx_itf routine as follows:
          DO jk= 1, jpk
              DO jj = 1, jpj
                 DO ji = 1, jpi
                    az_tmx_itf(ji,jj,jk) = en_tmx(ji,jj) * rn_tfe_itf / rn_tfe / rau0    &
                        &                  * zempba_3d(ji,jj,jk) * z1sum(ji,jj) * tmask(ji,jj,jk) 
                 END DO
              END DO
           END DO           
    
          !                             ! first estimation (with n2 bound by rn_n2min) bounded by 10 cm2/s
    
          av_tide_itf(:,:,:) = MIN(  10.e-4, az_tmx_itf(:,:,:) / MAX( rn_n2min, rn2(:,:,:) )  )
    

Which can be transformed into:

      REAL(wp) ::   zcoef        ! temporary scalar
...
      zcoef = rn_tfe_itf / ( rn_tfe * rau0 )
      DO jk= 1, jpk
         zavt_itf(:,:,jk) = MIN(  10.e-4, zcoef * en_tmx(:,:) * z1sum(:,:) * zempba_3d(:,:,jk)   &
            &                                   / MAX( rn_n2min, rn2(:,:,jk) ) * tmask(:,:,jk)  )
      END DO           
  • from the head of the module, the following declarations are removed:
       REAL(wp), DIMENSION(jpi,jpj) ::  zhdep                ! Ocean depth 
       REAL(wp), DIMENSION(jpi,jpj) ::  zsum1, zsum2, zsum    
       REAL(wp), DIMENSION(jpi,jpj) ::  z1sum1, z1sum2, z1sum  
       REAL(wp), DIMENSION(jpi,jpj,jpk) ::  zempba_3d_1, zempba_3d_2
       REAL(wp), DIMENSION(jpi,jpj,jpk) ::  zempba_3d, drn2dz                              
    

and put into zdf_tmx_init (for zhdep) or in tmx_itf routine (for all the other arrays)
(become temporary workspace)

in addition drn2dz should be renamed as zdn2dz (DOCTOR norm)

  • suppression of av_tide_itf, only av_tide is kept

suppress av_tide_itf from zdf_oce.F90 and add in tmx_itf routine :

      REAL(wp), DIMENSION(jpi,jpj,jpk) ::  zavt_itf                   !  -      -

and change all av_tide_itf into zavt_itf


# 2 speed : idea: compute av_tide (standard + itf) and only then cange avmu, avmv so that only one call to lbc_lnk

end of zdf_tmx:

      DO jk = 2, jpkm1              ! update momentum & tracer diffusivity with tidal mixing
         av_tide(:,:,jk) = av_tide(:,:,jk) * ( 1. - mask_itf(:,:) )
         avt    (:,:,jk) = avt    (:,:,jk) + av_tide(:,:,jk)
         DO jj = 2, jpjm1
            DO ji = fs_2, fs_jpim1  ! vector opt.
               avmu(ji,jj,jk) = avmu(ji,jj,jk) + 0.5 * ( av_tide(ji,jj,jk) + av_tide(ji+1,jj  ,jk) ) * umask(ji,jj,jk)
               avmv(ji,jj,jk) = avmv(ji,jj,jk) + 0.5 * ( av_tide(ji,jj,jk) + av_tide(ji  ,jj+1,jk) ) * vmask(ji,jj,jk)
            END DO
         END DO
      END DO
      CALL lbc_lnk( avmu, 'U', 1. )   
      CALL lbc_lnk( avmv, 'V', 1. )
       
      CALL tmx_itf( kt )            ! Indonesian throughflow tidal vertical mixing 

changed into

     !                     ! ----------------------- !
     CALL tmx_itf( kt )    !    ITF  tidal mixing    !  (update av_tide)
     !                     ! ----------------------- !

     !                     ! ----------------------- !
     !                     !   Update  mixing coefs  !                          
     !                     ! ----------------------- !
     DO jk = 2, jpkm1              !* update momentum & tracer diffusivity with tidal mixing
        avt    (:,:,jk) = avt    (:,:,jk) + av_tide(:,:,jk)
        DO jj = 2, jpjm1
           DO ji = fs_2, fs_jpim1  ! vector opt.
              avmu(ji,jj,jk) = avmu(ji,jj,jk) + 0.5 * ( av_tide(ji,jj,jk) + av_tide(ji+1,jj  ,jk) ) * umask(ji,jj,jk)
              avmv(ji,jj,jk) = avmv(ji,jj,jk) + 0.5 * ( av_tide(ji,jj,jk) + av_tide(ji  ,jj+1,jk) ) * vmask(ji,jj,jk)
           END DO
        END DO
     END DO
     CALL lbc_lnk( avmu, 'U', 1. )   ;   CALL lbc_lnk( avmv, 'V', 1. )      ! lateral boundary condition

end of tmx_itf, change:

      DO jk = 2, jpkm1
         zavt_itf(:,:,jk) = zavt_itf(:,:,jk) * mask_itf(:,:) 
         avt(:,:,jk) = avt(:,:,jk) + zavt_itf(:,:,jk)
         !
         DO jj = 2, jpjm1
            DO ji = fs_2, fs_jpim1  ! vector opt.
               avmu(ji,jj,jk) = avmu(ji,jj,jk) + 0.5 * ( zavt_itf(ji,jj,jk) + zavt_itf(ji+1,jj  ,jk) ) * umask(ji,jj,jk)
               avmv(ji,jj,jk) = avmv(ji,jj,jk) + 0.5 * ( zavt_itf(ji,jj,jk) + zavt_itf(ji  ,jj+1,jk) ) * vmask(ji,jj,jk)
            END DO
         END DO
      END DO
      CALL lbc_lnk( avmu, 'U', 1. )   
      CALL lbc_lnk( avmv, 'V', 1. )

into the update of av_tide alone

      DO jk = 2, jpkm1
         av_tide(:,:,jk) = av_tide (:,:,jk) * ( 1. - mask_itf(:,:) )
            &            + zavt_itf(:,:,jk) *        mask_itf(:,:) 
      END DO

in other words, now tmx_itf only update the av_tide array in the ITF area

# 3 minor point

  • simplify the control print : avmu, avmv useless, but av_tides required. So :
          IF(ln_ctl) THEN
             CALL prt_ctl_info( clinfo1='tmx  - t: ', ivar1=INT(SUM( avt (:,:,:) ) ) )
             CALL prt_ctl_info( clinfo1='tmx  - u: ', ivar1=INT(SUM( avmu(:,:,:) ) ),   &
                &               clinfo2='     - v: ', ivar2=INT(SUM( avmv(:,:,:) ) ) )
          ENDIF
    

transformed into:

      IF(ln_ctl)   CALL prt_ctl( tab3d_1=av_tide  , clinfo1=' tmx  - av_tide: ', tab3d_2=avt, clinfo2=' avt: ', ovlap=1, kdim=jpk)

Commit History (0)

(No commits)

Change History (6)

comment:1 Changed 15 years ago by gm

  • Resolution set to duplicate
  • Status changed from new to closed

comment:2 Changed 14 years ago by anonymous

  • Milestone 2009 Stream 3: New features deleted

Milestone 2009 Stream 3: New features deleted

comment:3 Changed 8 years ago by nicolasmartin

  • Keywords ZDF added; zdftmx removed

comment:4 Changed 8 years ago by nicolasmartin

  • Keywords tidal-mixing added; tidal removed

comment:5 Changed 8 years ago by nicolasmartin

  • Keywords mixing removed

comment:6 Changed 7 years ago by nemo

  • Keywords mixing added; tidal-mixing removed
Note: See TracTickets for help on using tickets.