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.
zdfbfr.F90 in branches/UKMO/dev_1d_bugfixes_tocommit/NEMOGCM/NEMO/OPA_SRC/ZDF – NEMO

source: branches/UKMO/dev_1d_bugfixes_tocommit/NEMOGCM/NEMO/OPA_SRC/ZDF/zdfbfr.F90 @ 13191

Last change on this file since 13191 was 13191, checked in by jwhile, 4 years ago

Updates for 1d runnig

File size: 25.5 KB
RevLine 
[3]1MODULE zdfbfr
2   !!======================================================================
3   !!                       ***  MODULE  zdfbfr  ***
4   !! Ocean physics: Bottom friction
5   !!======================================================================
[1662]6   !! History :  OPA  ! 1997-06  (G. Madec, A.-M. Treguier)  Original code
[1601]7   !!   NEMO     1.0  ! 2002-06  (G. Madec)  F90: Free form and module
[1708]8   !!            3.2  ! 2009-09  (A.C.Coward)  Correction to include barotropic contribution
[2528]9   !!            3.3  ! 2010-10  (C. Ethe, G. Madec) reorganisation of initialisation phase
[3633]10   !!            3.4  ! 2011-11  (H. Liu) implementation of semi-implicit bottom friction option
11   !!                 ! 2012-06  (H. Liu) implementation of Log Layer bottom friction option
[1601]12   !!----------------------------------------------------------------------
[3]13
14   !!----------------------------------------------------------------------
[4381]15   !!   zdf_bfr      : update bottom friction coefficient (non-linear bottom friction only)
[1601]16   !!   zdf_bfr_init : read in namelist and control the bottom friction parameters.
[3]17   !!----------------------------------------------------------------------
18   USE oce             ! ocean dynamics and tracers variables
[3764]19   USE dom_oce         ! ocean space and time domain variables
[3]20   USE zdf_oce         ! ocean vertical physics variables
21   USE in_out_manager  ! I/O manager
22   USE lbclnk          ! ocean lateral boundary conditions (or mpp link)
[1671]23   USE lib_mpp         ! distributed memory computing
[258]24   USE prtctl          ! Print control
[3294]25   USE timing          ! Timing
[4381]26   USE wrk_nemo        ! Memory Allocation
[3633]27   USE phycst, ONLY: vkarmn
[11442]28   USE stopack
[3633]29
[3]30   IMPLICIT NONE
31   PRIVATE
32
[2528]33   PUBLIC   zdf_bfr         ! called by step.F90
[4381]34   PUBLIC   zdf_bfr_init    ! called by nemogcm.F90
[2715]35
[4147]36   !                                 !!* Namelist nambfr: bottom friction namelist *
37   INTEGER , PUBLIC ::   nn_bfr       ! = 0/1/2/3 type of bottom friction  (PUBLIC for TAM)
38   REAL(wp), PUBLIC ::   rn_bfri1     ! bottom drag coefficient (linear case)  (PUBLIC for TAM)
39   REAL(wp), PUBLIC ::   rn_bfri2     ! bottom drag coefficient (non linear case) (PUBLIC for TAM)
[4381]40   REAL(wp), PUBLIC ::   rn_bfri2_max ! Maximum bottom drag coefficient (non linear case and ln_loglayer=T) (PUBLIC for TAM)
[4147]41   REAL(wp), PUBLIC ::   rn_bfeb2     ! background bottom turbulent kinetic energy  [m2/s2] (PUBLIC for TAM)
42   REAL(wp), PUBLIC ::   rn_bfrien    ! local factor to enhance coefficient bfri (PUBLIC for TAM)
43   LOGICAL , PUBLIC ::   ln_bfr2d     ! logical switch for 2D enhancement (PUBLIC for TAM)
[4990]44   REAL(wp), PUBLIC ::   rn_tfri1     ! top drag coefficient (linear case)  (PUBLIC for TAM)
45   REAL(wp), PUBLIC ::   rn_tfri2     ! top drag coefficient (non linear case) (PUBLIC for TAM)
46   REAL(wp), PUBLIC ::   rn_tfri2_max ! Maximum top drag coefficient (non linear case and ln_loglayer=T) (PUBLIC for TAM)
47   REAL(wp), PUBLIC ::   rn_tfeb2     ! background top turbulent kinetic energy  [m2/s2] (PUBLIC for TAM)
48   REAL(wp), PUBLIC ::   rn_tfrien    ! local factor to enhance coefficient tfri (PUBLIC for TAM)
49   LOGICAL , PUBLIC ::   ln_tfr2d     ! logical switch for 2D enhancement (PUBLIC for TAM)
50
[4147]51   LOGICAL , PUBLIC ::   ln_loglayer  ! switch for log layer bfr coeff. (PUBLIC for TAM)
52   REAL(wp), PUBLIC ::   rn_bfrz0     ! bottom roughness for loglayer bfr coeff (PUBLIC for TAM)
[4990]53   REAL(wp), PUBLIC ::   rn_tfrz0     ! bottom roughness for loglayer bfr coeff (PUBLIC for TAM)
[4381]54   LOGICAL , PUBLIC ::   ln_bfrimp    ! logical switch for implicit bottom friction
[11442]55   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:), PUBLIC ::  bfrcoef2d, tfrcoef2d,bfrcoef2d0   ! 2D bottom/top drag coefficient (PUBLIC for TAM)
[3]56
57   !! * Substitutions
[2528]58#  include "vectopt_loop_substitute.h90"
[3]59#  include "domzgr_substitute.h90"
60   !!----------------------------------------------------------------------
[2715]61   !! NEMO/OPA 4.0 , NEMO Consortium (2011)
[2528]62   !! $Id$
63   !! Software governed by the CeCILL licence     (NEMOGCM/NEMO_CeCILL.txt)
[3]64   !!----------------------------------------------------------------------
65CONTAINS
66
[2715]67   INTEGER FUNCTION zdf_bfr_alloc()
68      !!----------------------------------------------------------------------
69      !!                ***  FUNCTION zdf_bfr_alloc  ***
70      !!----------------------------------------------------------------------
[11442]71      ALLOCATE( bfrcoef2d(jpi,jpj), tfrcoef2d(jpi,jpj), bfrcoef2d0(jpi,jpj),STAT=zdf_bfr_alloc )
[2715]72      !
73      IF( lk_mpp             )   CALL mpp_sum ( zdf_bfr_alloc )
74      IF( zdf_bfr_alloc /= 0 )   CALL ctl_warn('zdf_bfr_alloc: failed to allocate arrays.')
75   END FUNCTION zdf_bfr_alloc
76
77
[3]78   SUBROUTINE zdf_bfr( kt )
79      !!----------------------------------------------------------------------
80      !!                   ***  ROUTINE zdf_bfr  ***
[3764]81      !!
[1708]82      !! ** Purpose :   compute the bottom friction coefficient.
[3]83      !!
[3764]84      !! ** Method  :   Calculate and store part of the momentum trend due
85      !!              to bottom friction following the chosen friction type
[1662]86      !!              (free-slip, linear, or quadratic). The component
87      !!              calculated here is multiplied by the bottom velocity in
88      !!              dyn_bfr to provide the trend term.
[1708]89      !!                The coefficients are updated at each time step only
90      !!              in the quadratic case.
[1662]91      !!
92      !! ** Action  :   bfrua , bfrva   bottom friction coefficients
[3]93      !!----------------------------------------------------------------------
94      INTEGER, INTENT( in ) ::   kt   ! ocean time-step index
[1601]95      !!
[3633]96      INTEGER  ::   ji, jj                       ! dummy loop indices
[4381]97      INTEGER  ::   ikbt, ikbu, ikbv             ! local integers
98      REAL(wp) ::   zvu, zuv, zecu, zecv, ztmp   ! temporary scalars
[4990]99      REAL(wp), POINTER, DIMENSION(:,:) ::  zbfrt, ztfrt
[3]100      !!----------------------------------------------------------------------
[3294]101      !
102      IF( nn_timing == 1 )  CALL timing_start('zdf_bfr')
103      !
[4381]104      IF( kt == nit000 .AND. lwp ) THEN
105         WRITE(numout,*)
106         WRITE(numout,*) 'zdf_bfr : Set bottom friction coefficient (non-linear case)'
107         WRITE(numout,*) '~~~~~~~~'
108      ENDIF
[13191]109      !
110#if defined key_traldf_c2d || key_traldf_c3d
[11442]111      IF( ln_stopack .AND. ( nn_spp_bfr > 0 ) ) THEN
112         bfrcoef2d = bfrcoef2d0
113         CALL spp_gen(kt, bfrcoef2d, nn_spp_bfr, rn_bfr_sd, jk_spp_bfr)
114      ENDIF
[13191]115#else
116      IF ( ln_stopack .AND. ( nn_spp_bfr > 0 ) ) &
117         & CALL ctl_stop( 'zdf_bfr: parameter perturbation will only work with '// &
118                          'key_traldf_c2d or key_traldf_c3d')
119#endif
[4381]120      !
121      IF( nn_bfr == 2 ) THEN                 ! quadratic bottom friction only
[1662]122         !
[4990]123         CALL wrk_alloc( jpi, jpj, zbfrt, ztfrt )
[3633]124
[4381]125         IF ( ln_loglayer.AND.lk_vvl ) THEN ! "log layer" bottom friction coefficient
[3820]126
[4381]127            DO jj = 1, jpj
128               DO ji = 1, jpi
129                  ikbt = mbkt(ji,jj)
[4990]130!! JC: possible WAD implementation should modify line below if layers vanish
[4381]131                  ztmp = tmask(ji,jj,ikbt) * ( vkarmn / LOG( 0.5_wp * fse3t_n(ji,jj,ikbt) / rn_bfrz0 ))**2._wp
132                  zbfrt(ji,jj) = MAX(bfrcoef2d(ji,jj), ztmp)
133                  zbfrt(ji,jj) = MIN(zbfrt(ji,jj), rn_bfri2_max)
[5120]134               END DO
135            END DO
[4990]136! (ISF)
[5120]137            IF ( ln_isfcav ) THEN
138               DO jj = 1, jpj
139                  DO ji = 1, jpi
140                     ikbt = mikt(ji,jj)
[4990]141! JC: possible WAD implementation should modify line below if layers vanish
[5120]142                     ztmp = (1-tmask(ji,jj,1)) * ( vkarmn / LOG( 0.5_wp * fse3t_n(ji,jj,ikbt) / rn_bfrz0 ))**2._wp
143                     ztfrt(ji,jj) = MAX(tfrcoef2d(ji,jj), ztmp)
144                     ztfrt(ji,jj) = MIN(ztfrt(ji,jj), rn_tfri2_max)
145                  END DO
[4381]146               END DO
[5120]147            END IF
[13191]148         !
[4381]149         ELSE
150            zbfrt(:,:) = bfrcoef2d(:,:)
[4990]151            ztfrt(:,:) = tfrcoef2d(:,:)
[3633]152         ENDIF
153
[3]154         DO jj = 2, jpjm1
155            DO ji = 2, jpim1
[3764]156               ikbu = mbku(ji,jj)         ! ocean bottom level at u- and v-points
[2528]157               ikbv = mbkv(ji,jj)         ! (deepest ocean u- and v-points)
[1662]158               !
[2528]159               zvu  = 0.25 * (  vn(ji,jj  ,ikbu) + vn(ji+1,jj  ,ikbu)     &
160                  &           + vn(ji,jj-1,ikbu) + vn(ji+1,jj-1,ikbu)  )
161               zuv  = 0.25 * (  un(ji,jj  ,ikbv) + un(ji-1,jj  ,ikbv)     &
162                  &           + un(ji,jj+1,ikbv) + un(ji-1,jj+1,ikbv)  )
[1662]163               !
[2528]164               zecu = SQRT(  un(ji,jj,ikbu) * un(ji,jj,ikbu) + zvu*zvu + rn_bfeb2  )
165               zecv = SQRT(  vn(ji,jj,ikbv) * vn(ji,jj,ikbv) + zuv*zuv + rn_bfeb2  )
[1662]166               !
[4381]167               bfrua(ji,jj) = - 0.5_wp * ( zbfrt(ji,jj) + zbfrt(ji+1,jj  ) ) * zecu
168               bfrva(ji,jj) = - 0.5_wp * ( zbfrt(ji,jj) + zbfrt(ji  ,jj+1) ) * zecv
[4990]169               !
170               ! in case of 2 cell water column, we assume each cell feels the top and bottom friction
[5120]171               IF ( ln_isfcav ) THEN
172                  IF ( miku(ji,jj) + 1 .GE. mbku(ji,jj) ) THEN
173                     bfrua(ji,jj) = - 0.5_wp * ( ( zbfrt(ji,jj) + zbfrt(ji+1,jj  ) )   &
174                                  &            + ( ztfrt(ji,jj) + ztfrt(ji+1,jj  ) ) ) &
175                                  &          * zecu * (1._wp - umask(ji,jj,1))
176                  END IF
177                  IF ( mikv(ji,jj) + 1 .GE. mbkv(ji,jj) ) THEN
178                     bfrva(ji,jj) = - 0.5_wp * ( ( zbfrt(ji,jj) + zbfrt(ji  ,jj+1) )   &
179                                  &            + ( ztfrt(ji,jj) + ztfrt(ji  ,jj+1) ) ) &
180                                  &          * zecv * (1._wp - vmask(ji,jj,1))
181                  END IF
[4990]182               END IF
[3]183            END DO
184         END DO
[5332]185         CALL lbc_lnk( bfrua, 'U', 1. )   ;   CALL lbc_lnk( bfrva, 'V', 1. )      ! Lateral boundary condition
186
[5120]187         IF ( ln_isfcav ) THEN
188            DO jj = 2, jpjm1
189               DO ji = 2, jpim1
190                  ! (ISF) ========================================================================
[13191]191                  ikbu = miku(ji,jj)         ! ocean top level at u- and v-points
[5332]192                  ikbv = mikv(ji,jj)         ! (1st wet ocean u- and v-points)
[5120]193                  !
194                  zvu  = 0.25 * (  vn(ji,jj  ,ikbu) + vn(ji+1,jj  ,ikbu)     &
195                     &           + vn(ji,jj-1,ikbu) + vn(ji+1,jj-1,ikbu)  )
196                  zuv  = 0.25 * (  un(ji,jj  ,ikbv) + un(ji-1,jj  ,ikbv)     &
197                     &           + un(ji,jj+1,ikbv) + un(ji-1,jj+1,ikbv)  )
198              !
[5332]199                  zecu = SQRT(  un(ji,jj,ikbu) * un(ji,jj,ikbu) + zvu*zvu + rn_tfeb2 )
200                  zecv = SQRT(  vn(ji,jj,ikbv) * vn(ji,jj,ikbv) + zuv*zuv + rn_tfeb2 )
[5120]201              !
202                  tfrua(ji,jj) = - 0.5_wp * ( ztfrt(ji,jj) + ztfrt(ji+1,jj  ) ) * zecu * (1._wp - umask(ji,jj,1))
203                  tfrva(ji,jj) = - 0.5_wp * ( ztfrt(ji,jj) + ztfrt(ji  ,jj+1) ) * zecv * (1._wp - vmask(ji,jj,1))
204              ! (ISF) END ====================================================================
205              ! in case of 2 cell water column, we assume each cell feels the top and bottom friction
206                  IF ( miku(ji,jj) + 1 .GE. mbku(ji,jj) ) THEN
207                     tfrua(ji,jj) = - 0.5_wp * ( ( ztfrt(ji,jj) + ztfrt(ji+1,jj  ) )   &
208                                  &            + ( zbfrt(ji,jj) + zbfrt(ji+1,jj  ) ) ) &
209                                  &          * zecu * (1._wp - umask(ji,jj,1))
210                  END IF
211                  IF ( mikv(ji,jj) + 1 .GE. mbkv(ji,jj) ) THEN
212                     tfrva(ji,jj) = - 0.5_wp * ( ( ztfrt(ji,jj) + ztfrt(ji  ,jj+1) )   &
213                                  &            + ( zbfrt(ji,jj) + zbfrt(ji  ,jj+1) ) ) &
214                                  &          * zecv * (1._wp - vmask(ji,jj,1))
215                  END IF
216               END DO
217            END DO
[5332]218            CALL lbc_lnk( tfrua, 'U', 1. )   ;   CALL lbc_lnk( tfrva, 'V', 1. )      ! Lateral boundary condition
[5120]219         END IF
[1601]220         !
[1708]221         !
222         IF(ln_ctl)   CALL prt_ctl( tab2d_1=bfrua, clinfo1=' bfr  - u: ', mask1=umask,        &
223            &                       tab2d_2=bfrva, clinfo2=       ' v: ', mask2=vmask,ovlap=1 )
[4990]224         CALL wrk_dealloc( jpi,jpj,zbfrt, ztfrt )
[1662]225      ENDIF
226      !
[3294]227      IF( nn_timing == 1 )  CALL timing_stop('zdf_bfr')
228      !
[3]229   END SUBROUTINE zdf_bfr
230
231
232   SUBROUTINE zdf_bfr_init
233      !!----------------------------------------------------------------------
234      !!                  ***  ROUTINE zdf_bfr_init  ***
[3764]235      !!
[3]236      !! ** Purpose :   Initialization of the bottom friction
237      !!
[4381]238      !! ** Method  :   Read the nambfr namelist and check their consistency
239      !!                called at the first timestep (nit000)
[3]240      !!----------------------------------------------------------------------
[1662]241      USE iom   ! I/O module for ehanced bottom friction file
242      !!
[3633]243      INTEGER   ::   inum         ! logical unit for enhanced bottom friction file
244      INTEGER   ::   ji, jj       ! dummy loop indexes
[4381]245      INTEGER   ::   ikbt, ikbu, ikbv   ! temporary integers
246      INTEGER   ::   ictu, ictv         !    -          -
[4147]247      INTEGER   ::   ios
[3633]248      REAL(wp)  ::   zminbfr, zmaxbfr   ! temporary scalars
[4990]249      REAL(wp)  ::   zmintfr, zmaxtfr   ! temporary scalars
[4381]250      REAL(wp)  ::   ztmp, zfru, zfrv   !    -         -
[1708]251      !!
[4381]252      NAMELIST/nambfr/ nn_bfr, rn_bfri1, rn_bfri2, rn_bfri2_max, rn_bfeb2, rn_bfrz0, ln_bfr2d, &
[4990]253                    &          rn_tfri1, rn_tfri2, rn_tfri2_max, rn_tfeb2, rn_tfrz0, ln_tfr2d, &
254                    &  rn_bfrien, rn_tfrien, ln_bfrimp, ln_loglayer
[3]255      !!----------------------------------------------------------------------
[3294]256      !
257      IF( nn_timing == 1 )  CALL timing_start('zdf_bfr_init')
258      !
[4381]259      !                              !* Allocate zdfbfr arrays
260      IF( zdf_bfr_alloc() /= 0 )   CALL ctl_stop( 'STOP', 'zdf_bfr_init : unable to allocate arrays' )
261      !
262      !                              !* Parameter control and print
263      !
[4147]264      REWIND( numnam_ref )              ! Namelist nambfr in reference namelist : Bottom momentum boundary condition
265      READ  ( numnam_ref, nambfr, IOSTAT = ios, ERR = 901)
266901   IF( ios /= 0 ) CALL ctl_nam ( ios , 'nambfr in reference namelist', lwp )
[3]267
[4147]268      REWIND( numnam_cfg )              ! Namelist nambfr in configuration namelist : Bottom momentum boundary condition
269      READ  ( numnam_cfg, nambfr, IOSTAT = ios, ERR = 902 )
270902   IF( ios /= 0 ) CALL ctl_nam ( ios , 'nambfr in configuration namelist', lwp )
[4624]271      IF(lwm) WRITE ( numond, nambfr )
[1662]272      IF(lwp) WRITE(numout,*)
[4381]273      IF(lwp) WRITE(numout,*) 'zdf_bfr_init : momentum bottom friction'
274      IF(lwp) WRITE(numout,*) '~~~~~~~~~~~~~'
[1708]275      IF(lwp) WRITE(numout,*) '   Namelist nam_bfr : set bottom friction parameters'
[4381]276      !
[1662]277      SELECT CASE (nn_bfr)
[2715]278      !
[3]279      CASE( 0 )
[1708]280         IF(lwp) WRITE(numout,*) '      free-slip '
[1662]281         bfrua(:,:) = 0.e0
282         bfrva(:,:) = 0.e0
[4990]283         tfrua(:,:) = 0.e0
284         tfrva(:,:) = 0.e0
[1662]285         !
[3]286      CASE( 1 )
[1708]287         IF(lwp) WRITE(numout,*) '      linear botton friction'
[4990]288         IF(lwp) WRITE(numout,*) '      bottom friction coef.   rn_bfri1  = ', rn_bfri1
[1708]289         IF( ln_bfr2d ) THEN
290            IF(lwp) WRITE(numout,*) '      read coef. enhancement distribution from file   ln_bfr2d  = ', ln_bfr2d
291            IF(lwp) WRITE(numout,*) '      coef rn_bfri2 enhancement factor                rn_bfrien  = ',rn_bfrien
[1662]292         ENDIF
[5332]293         IF ( ln_isfcav ) THEN
294            IF(lwp) WRITE(numout,*) '      top    friction coef.   rn_bfri1  = ', rn_tfri1
295            IF( ln_tfr2d ) THEN
296               IF(lwp) WRITE(numout,*) '      read coef. enhancement distribution from file   ln_tfr2d  = ', ln_tfr2d
297               IF(lwp) WRITE(numout,*) '      coef rn_tfri2 enhancement factor                rn_tfrien  = ',rn_tfrien
298            ENDIF
299         END IF
[1601]300         !
[3764]301         IF(ln_bfr2d) THEN
[1662]302            ! bfr_coef is a coefficient in [0,1] giving the mask where to apply the bfr enhancement
303            CALL iom_open('bfr_coef.nc',inum)
304            CALL iom_get (inum, jpdom_data, 'bfr_coef',bfrcoef2d,1) ! bfrcoef2d is used as tmp array
305            CALL iom_close(inum)
[2715]306            bfrcoef2d(:,:) = rn_bfri1 * ( 1 + rn_bfrien * bfrcoef2d(:,:) )
[4381]307         ELSE
308            bfrcoef2d(:,:) = rn_bfri1  ! initialize bfrcoef2d to the namelist variable
[1662]309         ENDIF
[4381]310         !
[1662]311         bfrua(:,:) = - bfrcoef2d(:,:)
312         bfrva(:,:) = - bfrcoef2d(:,:)
313         !
[5332]314         IF ( ln_isfcav ) THEN
315            IF(ln_tfr2d) THEN
316               ! tfr_coef is a coefficient in [0,1] giving the mask where to apply the bfr enhancement
317               CALL iom_open('tfr_coef.nc',inum)
318               CALL iom_get (inum, jpdom_data, 'tfr_coef',tfrcoef2d,1) ! tfrcoef2d is used as tmp array
319               CALL iom_close(inum)
320               tfrcoef2d(:,:) = rn_tfri1 * ( 1 + rn_tfrien * tfrcoef2d(:,:) )
321            ELSE
322               tfrcoef2d(:,:) = rn_tfri1  ! initialize tfrcoef2d to the namelist variable
323            ENDIF
324            !
325            tfrua(:,:) = - tfrcoef2d(:,:)
326            tfrva(:,:) = - tfrcoef2d(:,:)
327         END IF
328         !
[3]329      CASE( 2 )
[4381]330         IF(lwp) WRITE(numout,*) '      quadratic bottom friction'
[1708]331         IF(lwp) WRITE(numout,*) '      friction coef.   rn_bfri2  = ', rn_bfri2
[4381]332         IF(lwp) WRITE(numout,*) '      Max. coef. (log case)   rn_bfri2_max  = ', rn_bfri2_max
[1708]333         IF(lwp) WRITE(numout,*) '      background tke   rn_bfeb2  = ', rn_bfeb2
[4381]334         IF(lwp) WRITE(numout,*) '      log formulation   ln_bfr2d = ', ln_loglayer
335         IF(lwp) WRITE(numout,*) '      bottom roughness  rn_bfrz0 [m] = ', rn_bfrz0
336         IF( rn_bfrz0<=0.e0 ) THEN
337            WRITE(ctmp1,*) '      bottom roughness must be strictly positive'
338            CALL ctl_stop( ctmp1 )
339         ENDIF
[1708]340         IF( ln_bfr2d ) THEN
341            IF(lwp) WRITE(numout,*) '      read coef. enhancement distribution from file   ln_bfr2d  = ', ln_bfr2d
342            IF(lwp) WRITE(numout,*) '      coef rn_bfri2 enhancement factor                rn_bfrien  = ',rn_bfrien
[1662]343         ENDIF
[5332]344         IF ( ln_isfcav ) THEN
345            IF(lwp) WRITE(numout,*) '      quadratic top    friction'
346            IF(lwp) WRITE(numout,*) '      friction coef.    rn_tfri2     = ', rn_tfri2
347            IF(lwp) WRITE(numout,*) '      Max. coef. (log case)   rn_tfri2_max  = ', rn_tfri2_max
348            IF(lwp) WRITE(numout,*) '      background tke    rn_tfeb2     = ', rn_tfeb2
349            IF(lwp) WRITE(numout,*) '      log formulation   ln_tfr2d     = ', ln_loglayer
350            IF(lwp) WRITE(numout,*) '      top roughness     rn_tfrz0 [m] = ', rn_tfrz0
351            IF( rn_tfrz0<=0.e0 ) THEN
352               WRITE(ctmp1,*) '      top roughness must be strictly positive'
353               CALL ctl_stop( ctmp1 )
354            ENDIF
355            IF( ln_tfr2d ) THEN
356               IF(lwp) WRITE(numout,*) '      read coef. enhancement distribution from file   ln_tfr2d  = ', ln_tfr2d
357               IF(lwp) WRITE(numout,*) '      coef rn_tfri2 enhancement factor                rn_tfrien  = ',rn_tfrien
358            ENDIF
359         END IF
[1708]360         !
[3764]361         IF(ln_bfr2d) THEN
[1662]362            ! bfr_coef is a coefficient in [0,1] giving the mask where to apply the bfr enhancement
363            CALL iom_open('bfr_coef.nc',inum)
364            CALL iom_get (inum, jpdom_data, 'bfr_coef',bfrcoef2d,1) ! bfrcoef2d is used as tmp array
365            CALL iom_close(inum)
[4381]366            !
367            bfrcoef2d(:,:) = rn_bfri2 * ( 1 + rn_bfrien * bfrcoef2d(:,:) )
368         ELSE
369            bfrcoef2d(:,:) = rn_bfri2  ! initialize bfrcoef2d to the namelist variable
[1662]370         ENDIF
[13191]371
[5332]372         IF ( ln_isfcav ) THEN
373            IF(ln_tfr2d) THEN
374               ! tfr_coef is a coefficient in [0,1] giving the mask where to apply the bfr enhancement
375               CALL iom_open('tfr_coef.nc',inum)
376               CALL iom_get (inum, jpdom_data, 'tfr_coef',tfrcoef2d,1) ! tfrcoef2d is used as tmp array
377               CALL iom_close(inum)
378               !
379               tfrcoef2d(:,:) = rn_tfri2 * ( 1 + rn_tfrien * tfrcoef2d(:,:) )
380            ELSE
381               tfrcoef2d(:,:) = rn_tfri2  ! initialize tfrcoef2d to the namelist variable
382            ENDIF
383         END IF
[1601]384         !
[4381]385         IF ( ln_loglayer.AND.(.NOT.lk_vvl) ) THEN ! set "log layer" bottom friction once for all
386            DO jj = 1, jpj
387               DO ji = 1, jpi
388                  ikbt = mbkt(ji,jj)
389                  ztmp = tmask(ji,jj,ikbt) * ( vkarmn / LOG( 0.5_wp * fse3t_n(ji,jj,ikbt) / rn_bfrz0 ))**2._wp
390                  bfrcoef2d(ji,jj) = MAX(bfrcoef2d(ji,jj), ztmp)
391                  bfrcoef2d(ji,jj) = MIN(bfrcoef2d(ji,jj), rn_bfri2_max)
392               END DO
393            END DO
[5332]394            IF ( ln_isfcav ) THEN
395               DO jj = 1, jpj
396                  DO ji = 1, jpi
397                     ikbt = mikt(ji,jj)
398                     ztmp = tmask(ji,jj,ikbt) * ( vkarmn / LOG( 0.5_wp * fse3t_n(ji,jj,ikbt) / rn_tfrz0 ))**2._wp
399                     tfrcoef2d(ji,jj) = MAX(tfrcoef2d(ji,jj), ztmp)
400                     tfrcoef2d(ji,jj) = MIN(tfrcoef2d(ji,jj), rn_tfri2_max)
401                  END DO
402               END DO
403            END IF
[4381]404         ENDIF
405         !
[3]406      CASE DEFAULT
[1708]407         IF(lwp) WRITE(ctmp1,*) '         bad flag value for nn_bfr = ', nn_bfr
[474]408         CALL ctl_stop( ctmp1 )
[1601]409         !
[3]410      END SELECT
[4381]411      !
412      IF(lwp) WRITE(numout,*) '      implicit bottom friction switch                ln_bfrimp  = ', ln_bfrimp
413      !
414      !                              ! Make sure ln_zdfexp=.false. when use implicit bfr
415      IF( ln_bfrimp .AND. ln_zdfexp ) THEN
[3820]416         IF(lwp) THEN
417            WRITE(numout,*)
[4381]418            WRITE(numout,*) 'Implicit bottom friction can only be used when ln_zdfexp=.false.'
419            WRITE(numout,*) '         but you set: ln_bfrimp=.true. and ln_zdfexp=.true.!!!!'
420            WRITE(ctmp1,*)  '         set either ln_zdfexp = .false or ln_bfrimp = .false.'
[3820]421            CALL ctl_stop( ctmp1 )
422         END IF
423      END IF
[1601]424      !
[1662]425      ! Basic stability check on bottom friction coefficient
426      !
427      ictu = 0               ! counter for stability criterion breaches at U-pts
428      ictv = 0               ! counter for stability criterion breaches at V-pts
[1708]429      zminbfr =  1.e10_wp    ! initialise tracker for minimum of bottom friction coefficient
430      zmaxbfr = -1.e10_wp    ! initialise tracker for maximum of bottom friction coefficient
[4990]431      zmintfr =  1.e10_wp    ! initialise tracker for minimum of bottom friction coefficient
432      zmaxtfr = -1.e10_wp    ! initialise tracker for maximum of bottom friction coefficient
[1662]433      !
434      DO jj = 2, jpjm1
435         DO ji = 2, jpim1
[2528]436             ikbu = mbku(ji,jj)       ! deepest ocean level at u- and v-points
437             ikbv = mbkv(ji,jj)
438             zfru = 0.5 * fse3u(ji,jj,ikbu) / rdt
439             zfrv = 0.5 * fse3v(ji,jj,ikbv) / rdt
[1708]440             IF( ABS( bfrcoef2d(ji,jj) ) > zfru ) THEN
441                IF( ln_ctl ) THEN
[2528]442                   WRITE(numout,*) 'BFR ', narea, nimpp+ji, njmpp+jj, ikbu
443                   WRITE(numout,*) 'BFR ', ABS( bfrcoef2d(ji,jj) ), zfru
[1662]444                ENDIF
445                ictu = ictu + 1
446             ENDIF
[1708]447             IF( ABS( bfrcoef2d(ji,jj) ) > zfrv ) THEN
448                 IF( ln_ctl ) THEN
449                     WRITE(numout,*) 'BFR ', narea, nimpp+ji, njmpp+jj, ikbv
450                     WRITE(numout,*) 'BFR ', bfrcoef2d(ji,jj), zfrv
[1662]451                 ENDIF
452                 ictv = ictv + 1
453             ENDIF
[1708]454             zminbfr = MIN(  zminbfr, MIN( zfru, ABS( bfrcoef2d(ji,jj) ) )  )
455             zmaxbfr = MAX(  zmaxbfr, MIN( zfrv, ABS( bfrcoef2d(ji,jj) ) )  )
[5332]456! (ISF)
457             IF ( ln_isfcav ) THEN
458                ikbu = miku(ji,jj)       ! 1st wet ocean level at u- and v-points
459                ikbv = mikv(ji,jj)
460                zfru = 0.5 * fse3u(ji,jj,ikbu) / rdt
461                zfrv = 0.5 * fse3v(ji,jj,ikbv) / rdt
462                IF( ABS( tfrcoef2d(ji,jj) ) > zfru ) THEN
463                   IF( ln_ctl ) THEN
464                      WRITE(numout,*) 'TFR ', narea, nimpp+ji, njmpp+jj, ikbu
465                      WRITE(numout,*) 'TFR ', ABS( tfrcoef2d(ji,jj) ), zfru
466                   ENDIF
467                   ictu = ictu + 1
468                ENDIF
469                IF( ABS( tfrcoef2d(ji,jj) ) > zfrv ) THEN
470                   IF( ln_ctl ) THEN
471                      WRITE(numout,*) 'TFR ', narea, nimpp+ji, njmpp+jj, ikbv
472                      WRITE(numout,*) 'TFR ', tfrcoef2d(ji,jj), zfrv
473                   ENDIF
474                   ictv = ictv + 1
475                ENDIF
476                zmintfr = MIN(  zmintfr, MIN( zfru, ABS( tfrcoef2d(ji,jj) ) )  )
477                zmaxtfr = MAX(  zmaxtfr, MIN( zfrv, ABS( tfrcoef2d(ji,jj) ) )  )
478             END IF
479! END ISF
[1662]480         END DO
481      END DO
[1708]482      IF( lk_mpp ) THEN
[1662]483         CALL mpp_sum( ictu )
484         CALL mpp_sum( ictv )
[1708]485         CALL mpp_min( zminbfr )
486         CALL mpp_max( zmaxbfr )
[5332]487         IF ( ln_isfcav) CALL mpp_min( zmintfr )
488         IF ( ln_isfcav) CALL mpp_max( zmaxtfr )
[1662]489      ENDIF
[3294]490      IF( .NOT.ln_bfrimp) THEN
[2528]491      IF( lwp .AND. ictu + ictv > 0 ) THEN
[5332]492         WRITE(numout,*) ' Bottom/Top friction stability check failed at ', ictu, ' U-points '
493         WRITE(numout,*) ' Bottom/Top friction stability check failed at ', ictv, ' V-points '
[1708]494         WRITE(numout,*) ' Bottom friction coefficient now ranges from: ', zminbfr, ' to ', zmaxbfr
[5332]495         IF ( ln_isfcav ) WRITE(numout,*) ' Top friction coefficient now ranges from: ', zmintfr, ' to ', zmaxtfr
496         WRITE(numout,*) ' Bottom/Top friction coefficient will be reduced where necessary'
[1662]497      ENDIF
[3294]498      ENDIF
[1662]499      !
[11442]500      bfrcoef2d0(:,:) = bfrcoef2d(:,:)
[3294]501      IF( nn_timing == 1 )  CALL timing_stop('zdf_bfr_init')
502      !
[3]503   END SUBROUTINE zdf_bfr_init
504
505   !!======================================================================
506END MODULE zdfbfr
Note: See TracBrowser for help on using the repository browser.