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.
dynzdf_imp.F90 in branches/UKMO/dev_r5518_GO6_starthour_obsoper/NEMOGCM/NEMO/OPA_SRC/DYN – NEMO

source: branches/UKMO/dev_r5518_GO6_starthour_obsoper/NEMOGCM/NEMO/OPA_SRC/DYN/dynzdf_imp.F90 @ 12555

Last change on this file since 12555 was 12555, checked in by charris, 4 years ago

Changes from GO6 package branch (GMED ticket 450):

svn merge -r 11035:11101 svn+ssh://charris@forge.ipsl.jussieu.fr/ipsl/forge/projets/nemo/svn/branches/UKMO/dev_r5518_GO6_package

File size: 17.4 KB
RevLine 
[3]1MODULE dynzdf_imp
[2715]2   !!======================================================================
[3]3   !!                    ***  MODULE  dynzdf_imp  ***
4   !! Ocean dynamics:  vertical component(s) of the momentum mixing trend
[2715]5   !!======================================================================
[2528]6   !! History :  OPA  !  1990-10  (B. Blanke)  Original code
7   !!            8.0  !  1997-05  (G. Madec)  vertical component of isopycnal
[2715]8   !!   NEMO     0.5  !  2002-08  (G. Madec)  F90: Free form and module
[2528]9   !!            3.3  !  2010-04  (M. Leclair, G. Madec)  Forcing averaged over 2 time steps
[3294]10   !!            3.4  !  2012-01  (H. Liu) Semi-implicit bottom friction
[503]11   !!----------------------------------------------------------------------
[3]12
13   !!----------------------------------------------------------------------
[2715]14   !!   dyn_zdf_imp  : update the momentum trend with the vertical diffusion using a implicit time-stepping
[3]15   !!----------------------------------------------------------------------
16   USE oce             ! ocean dynamics and tracers
17   USE dom_oce         ! ocean space and time domain
[4292]18   USE domvvl          ! variable volume
[888]19   USE sbc_oce         ! surface boundary condition: ocean
20   USE zdf_oce         ! ocean vertical physics
[719]21   USE phycst          ! physical constants
[3]22   USE in_out_manager  ! I/O manager
[2715]23   USE lib_mpp         ! MPP library
[3294]24   USE zdfbfr          ! Bottom friction setup
25   USE wrk_nemo        ! Memory Allocation
26   USE timing          ! Timing
[4292]27   USE dynadv          ! dynamics: vector invariant versus flux form
[4354]28   USE dynspg_oce, ONLY: lk_dynspg_ts
[3]29
30   IMPLICIT NONE
31   PRIVATE
32
[2528]33   PUBLIC   dyn_zdf_imp   ! called by step.F90
[3]34
[4292]35   REAL(wp) ::  r_vvl     ! variable volume indicator, =1 if lk_vvl=T, =0 otherwise
36
[3]37   !! * Substitutions
38#  include "domzgr_substitute.h90"
39#  include "vectopt_loop_substitute.h90"
40   !!----------------------------------------------------------------------
[2528]41   !! NEMO/OPA 3.3 , NEMO Consortium (2010)
[888]42   !! $Id$
[2528]43   !! Software governed by the CeCILL licence     (NEMOGCM/NEMO_CeCILL.txt)
[3]44   !!----------------------------------------------------------------------
45CONTAINS
46
[503]47   SUBROUTINE dyn_zdf_imp( kt, p2dt )
[3]48      !!----------------------------------------------------------------------
49      !!                  ***  ROUTINE dyn_zdf_imp  ***
50      !!                   
51      !! ** Purpose :   Compute the trend due to the vert. momentum diffusion
52      !!      and the surface forcing, and add it to the general trend of
53      !!      the momentum equations.
54      !!
55      !! ** Method  :   The vertical momentum mixing trend is given by :
56      !!             dz( avmu dz(u) ) = 1/e3u dk+1( avmu/e3uw dk(ua) )
57      !!      backward time stepping
[2528]58      !!      Surface boundary conditions: wind stress input (averaged over kt-1/2 & kt+1/2)
[3]59      !!      Bottom boundary conditions : bottom stress (cf zdfbfr.F)
60      !!      Add this trend to the general trend ua :
61      !!         ua = ua + dz( avmu dz(u) )
62      !!
[2528]63      !! ** Action : - Update (ua,va) arrays with the after vertical diffusive mixing trend.
[3]64      !!---------------------------------------------------------------------
[3294]65      INTEGER , INTENT(in) ::  kt     ! ocean time-step index
[2715]66      REAL(wp), INTENT(in) ::  p2dt   ! vertical profile of tracer time-step
[2528]67      !!
[2715]68      INTEGER  ::   ji, jj, jk   ! dummy loop indices
[3294]69      INTEGER  ::   ikbu, ikbv   ! local integers
[2715]70      REAL(wp) ::   z1_p2dt, zcoef, zzwi, zzws, zrhs   ! local scalars
[4292]71      REAL(wp) ::   ze3ua, ze3va
[3294]72      REAL(wp), POINTER, DIMENSION(:,:,:) ::  zwi, zwd, zws
73      !!----------------------------------------------------------------------
74      !
75      IF( nn_timing == 1 )  CALL timing_start('dyn_zdf_imp')
76      !
77      CALL wrk_alloc( jpi,jpj,jpk, zwi, zwd, zws ) 
78      !
[3]79      IF( kt == nit000 ) THEN
80         IF(lwp) WRITE(numout,*)
81         IF(lwp) WRITE(numout,*) 'dyn_zdf_imp : vertical momentum diffusion implicit operator'
82         IF(lwp) WRITE(numout,*) '~~~~~~~~~~~ '
[12555]83         IF(lwp .AND. lflush) CALL flush(numout)
[4292]84         !
85         IF( lk_vvl ) THEN   ;    r_vvl = 1._wp       ! Variable volume indicator
86         ELSE                ;    r_vvl = 0._wp       
87         ENDIF
[3]88      ENDIF
89
90      ! 0. Local constant initialization
91      ! --------------------------------
[2528]92      z1_p2dt = 1._wp / p2dt      ! inverse of the timestep
[455]93
[3294]94      ! 1. Apply semi-implicit bottom friction
95      ! --------------------------------------
96      ! Only needed for semi-implicit bottom friction setup. The explicit
97      ! bottom friction has been included in "u(v)a" which act as the R.H.S
98      ! column vector of the tri-diagonal matrix equation
99      !
100
101      IF( ln_bfrimp ) THEN
[4292]102         DO jj = 2, jpjm1
103            DO ji = 2, jpim1
104               ikbu = mbku(ji,jj)       ! ocean bottom level at u- and v-points
105               ikbv = mbkv(ji,jj)       ! (deepest ocean u- and v-points)
106               avmu(ji,jj,ikbu+1) = -bfrua(ji,jj) * fse3uw(ji,jj,ikbu+1)
107               avmv(ji,jj,ikbv+1) = -bfrva(ji,jj) * fse3vw(ji,jj,ikbv+1)
108            END DO
[3294]109         END DO
[5120]110         IF ( ln_isfcav ) THEN
111            DO jj = 2, jpjm1
112               DO ji = 2, jpim1
113                  ikbu = miku(ji,jj)       ! ocean top level at u- and v-points
114                  ikbv = mikv(ji,jj)       ! (first wet ocean u- and v-points)
115                  IF (ikbu .GE. 2) avmu(ji,jj,ikbu) = -tfrua(ji,jj) * fse3uw(ji,jj,ikbu)
116                  IF (ikbv .GE. 2) avmv(ji,jj,ikbv) = -tfrva(ji,jj) * fse3vw(ji,jj,ikbv)
117               END DO
118            END DO
119         END IF
[3294]120      ENDIF
121
[4292]122#if defined key_dynspg_ts
123      IF( ln_dynadv_vec .OR. .NOT. lk_vvl ) THEN      ! applied on velocity
124         DO jk = 1, jpkm1
125            ua(:,:,jk) = ( ub(:,:,jk) + p2dt * ua(:,:,jk) ) * umask(:,:,jk)
126            va(:,:,jk) = ( vb(:,:,jk) + p2dt * va(:,:,jk) ) * vmask(:,:,jk)
127         END DO
128      ELSE                                            ! applied on thickness weighted velocity
129         DO jk = 1, jpkm1
130            ua(:,:,jk) = (          ub(:,:,jk) * fse3u_b(:,:,jk)      &
131               &           + p2dt * ua(:,:,jk) * fse3u_n(:,:,jk)  )   &
132               &                               / fse3u_a(:,:,jk) * umask(:,:,jk)
133            va(:,:,jk) = (          vb(:,:,jk) * fse3v_b(:,:,jk)      &
134               &           + p2dt * va(:,:,jk) * fse3v_n(:,:,jk)  )   &
135               &                               / fse3v_a(:,:,jk) * vmask(:,:,jk)
136         END DO
137      ENDIF
138
139      IF ( ln_bfrimp .AND.lk_dynspg_ts ) THEN
140         ! remove barotropic velocities:
141         DO jk = 1, jpkm1
142            ua(:,:,jk) = (ua(:,:,jk) - ua_b(:,:)) * umask(:,:,jk)
143            va(:,:,jk) = (va(:,:,jk) - va_b(:,:)) * vmask(:,:,jk)
[4990]144         END DO
145         ! Add bottom/top stress due to barotropic component only:
[4292]146         DO jj = 2, jpjm1       
147            DO ji = fs_2, fs_jpim1   ! vector opt.
148               ikbu = mbku(ji,jj)         ! ocean bottom level at u- and v-points
149               ikbv = mbkv(ji,jj)         ! (deepest ocean u- and v-points)
150               ze3ua =  ( 1._wp - r_vvl ) * fse3u_n(ji,jj,ikbu) + r_vvl   * fse3u_a(ji,jj,ikbu)
151               ze3va =  ( 1._wp - r_vvl ) * fse3v_n(ji,jj,ikbv) + r_vvl   * fse3v_a(ji,jj,ikbv)
152               ua(ji,jj,ikbu) = ua(ji,jj,ikbu) + p2dt * bfrua(ji,jj) * ua_b(ji,jj) / ze3ua
153               va(ji,jj,ikbv) = va(ji,jj,ikbv) + p2dt * bfrva(ji,jj) * va_b(ji,jj) / ze3va
154            END DO
155         END DO
[5120]156         IF ( ln_isfcav ) THEN
157            DO jj = 2, jpjm1       
158               DO ji = fs_2, fs_jpim1   ! vector opt.
159                  ikbu = miku(ji,jj)         ! top ocean level at u- and v-points
160                  ikbv = mikv(ji,jj)         ! (first wet ocean u- and v-points)
161                  ze3ua =  ( 1._wp - r_vvl ) * fse3u_n(ji,jj,ikbu) + r_vvl   * fse3u_a(ji,jj,ikbu)
162                  ze3va =  ( 1._wp - r_vvl ) * fse3v_n(ji,jj,ikbv) + r_vvl   * fse3v_a(ji,jj,ikbv)
163                  ua(ji,jj,ikbu) = ua(ji,jj,ikbu) + p2dt * tfrua(ji,jj) * ua_b(ji,jj) / ze3ua
164                  va(ji,jj,ikbv) = va(ji,jj,ikbv) + p2dt * tfrva(ji,jj) * va_b(ji,jj) / ze3va
165               END DO
166            END DO
167         END IF
[4292]168      ENDIF
169#endif
170
[3294]171      ! 2. Vertical diffusion on u
[3]172      ! ---------------------------
173      ! Matrix and second member construction
[1662]174      ! bottom boundary condition: both zwi and zws must be masked as avmu can take
[3294]175      ! non zero value at the ocean bottom depending on the bottom friction used.
[2528]176      !
177      DO jk = 1, jpkm1        ! Matrix
[3]178         DO jj = 2, jpjm1 
179            DO ji = fs_2, fs_jpim1   ! vector opt.
[4292]180               ze3ua =  ( 1._wp - r_vvl ) * fse3u_n(ji,jj,jk) + r_vvl   * fse3u_a(ji,jj,jk)   ! after scale factor at T-point
181               zcoef = - p2dt / ze3ua     
[5120]182               zzwi          = zcoef * avmu  (ji,jj,jk  ) / fse3uw(ji,jj,jk  )
183               zwi(ji,jj,jk) = zzwi  * wumask(ji,jj,jk  )
184               zzws          = zcoef * avmu  (ji,jj,jk+1) / fse3uw(ji,jj,jk+1) 
185               zws(ji,jj,jk) = zzws  * wumask(ji,jj,jk+1)
186               zwd(ji,jj,jk) = 1._wp - zzwi - zzws
[3]187            END DO
188         END DO
189      END DO
[4292]190      DO jj = 2, jpjm1        ! Surface boundary conditions
[3]191         DO ji = fs_2, fs_jpim1   ! vector opt.
[2528]192            zwi(ji,jj,1) = 0._wp
193            zwd(ji,jj,1) = 1._wp - zws(ji,jj,1)
[3]194         END DO
195      END DO
196
197      ! Matrix inversion starting from the first level
198      !-----------------------------------------------------------------------
199      !   solve m.x = y  where m is a tri diagonal matrix ( jpk*jpk )
200      !
201      !        ( zwd1 zws1   0    0    0  )( zwx1 ) ( zwy1 )
202      !        ( zwi2 zwd2 zws2   0    0  )( zwx2 ) ( zwy2 )
203      !        (  0   zwi3 zwd3 zws3   0  )( zwx3 )=( zwy3 )
204      !        (        ...               )( ...  ) ( ...  )
205      !        (  0    0    0   zwik zwdk )( zwxk ) ( zwyk )
206      !
207      !   m is decomposed in the product of an upper and a lower triangular matrix
208      !   The 3 diagonal terms are in 2d arrays: zwd, zws, zwi
209      !   The solution (the after velocity) is in ua
210      !-----------------------------------------------------------------------
[2528]211      !
[4990]212      !==  First recurrence : Dk = Dk - Lk * Uk-1 / Dk-1   (increasing k)  ==
[5120]213      DO jk = 2, jpkm1
214         DO jj = 2, jpjm1   
215            DO ji = fs_2, fs_jpim1   ! vector opt.
[3]216               zwd(ji,jj,jk) = zwd(ji,jj,jk) - zwi(ji,jj,jk) * zws(ji,jj,jk-1) / zwd(ji,jj,jk-1)
217            END DO
218         END DO
219      END DO
[2528]220      !
221      DO jj = 2, jpjm1        !==  second recurrence:    SOLk = RHSk - Lk / Dk-1  Lk-1  ==
[3]222         DO ji = fs_2, fs_jpim1   ! vector opt.
[4292]223#if defined key_dynspg_ts
[5120]224            ze3ua =  ( 1._wp - r_vvl ) * fse3u_n(ji,jj,1) + r_vvl   * fse3u_a(ji,jj,1) 
225            ua(ji,jj,1) = ua(ji,jj,1) + p2dt * 0.5_wp * ( utau_b(ji,jj) + utau(ji,jj) )   &
226               &                                      / ( ze3ua * rau0 ) * umask(ji,jj,1) 
[4292]227#else
[5120]228            ua(ji,jj,1) = ub(ji,jj,1) &
229               &                   + p2dt *(ua(ji,jj,1) +  0.5_wp * ( utau_b(ji,jj) + utau(ji,jj) )   &
230               &                                      / ( fse3u(ji,jj,1) * rau0     ) * umask(ji,jj,1) ) 
[4292]231#endif
[5120]232         END DO
233      END DO
234      DO jk = 2, jpkm1
235         DO jj = 2, jpjm1
236            DO ji = fs_2, fs_jpim1
[4292]237#if defined key_dynspg_ts
238               zrhs = ua(ji,jj,jk)   ! zrhs=right hand side
239#else
240               zrhs = ub(ji,jj,jk) + p2dt * ua(ji,jj,jk)
241#endif
[3]242               ua(ji,jj,jk) = zrhs - zwi(ji,jj,jk) / zwd(ji,jj,jk-1) * ua(ji,jj,jk-1)
243            END DO
244         END DO
245      END DO
[2528]246      !
247      DO jj = 2, jpjm1        !==  thrid recurrence : SOLk = ( Lk - Uk * Ek+1 ) / Dk  ==
[3]248         DO ji = fs_2, fs_jpim1   ! vector opt.
249            ua(ji,jj,jpkm1) = ua(ji,jj,jpkm1) / zwd(ji,jj,jpkm1)
[5120]250         END DO
251      END DO
252      DO jk = jpk-2, 1, -1
253         DO jj = 2, jpjm1
254            DO ji = fs_2, fs_jpim1
[2528]255               ua(ji,jj,jk) = ( ua(ji,jj,jk) - zws(ji,jj,jk) * ua(ji,jj,jk+1) ) / zwd(ji,jj,jk)
[3]256            END DO
257         END DO
258      END DO
259
[4292]260#if ! defined key_dynspg_ts
[3]261      ! Normalization to obtain the general momentum trend ua
262      DO jk = 1, jpkm1
263         DO jj = 2, jpjm1   
264            DO ji = fs_2, fs_jpim1   ! vector opt.
[2528]265               ua(ji,jj,jk) = ( ua(ji,jj,jk) - ub(ji,jj,jk) ) * z1_p2dt
[3]266            END DO
267         END DO
268      END DO
[4292]269#endif
[3]270
[3294]271      ! 3. Vertical diffusion on v
[3]272      ! ---------------------------
273      ! Matrix and second member construction
[1662]274      ! bottom boundary condition: both zwi and zws must be masked as avmv can take
[3294]275      ! non zero value at the ocean bottom depending on the bottom friction used
[2528]276      !
277      DO jk = 1, jpkm1        ! Matrix
[3]278         DO jj = 2, jpjm1   
279            DO ji = fs_2, fs_jpim1   ! vector opt.
[4292]280               ze3va =  ( 1._wp - r_vvl ) * fse3v_n(ji,jj,jk)  + r_vvl * fse3v_a(ji,jj,jk)   ! after scale factor at T-point
281               zcoef = - p2dt / ze3va
[2528]282               zzwi          = zcoef * avmv (ji,jj,jk  ) / fse3vw(ji,jj,jk  )
[5120]283               zwi(ji,jj,jk) =  zzwi * wvmask(ji,jj,jk)
[2528]284               zzws          = zcoef * avmv (ji,jj,jk+1) / fse3vw(ji,jj,jk+1)
[5120]285               zws(ji,jj,jk) =  zzws * wvmask(ji,jj,jk+1)
286               zwd(ji,jj,jk) = 1._wp - zzwi - zzws
[3]287            END DO
288         END DO
289      END DO
[4292]290      DO jj = 2, jpjm1        ! Surface boundary conditions
[3]291         DO ji = fs_2, fs_jpim1   ! vector opt.
[2528]292            zwi(ji,jj,1) = 0._wp
293            zwd(ji,jj,1) = 1._wp - zws(ji,jj,1)
[3]294         END DO
295      END DO
296
297      ! Matrix inversion
298      !-----------------------------------------------------------------------
299      !   solve m.x = y  where m is a tri diagonal matrix ( jpk*jpk )
300      !
301      !        ( zwd1 zws1   0    0    0  )( zwx1 ) ( zwy1 )
302      !        ( zwi2 zwd2 zws2   0    0  )( zwx2 ) ( zwy2 )
303      !        (  0   zwi3 zwd3 zws3   0  )( zwx3 )=( zwy3 )
304      !        (        ...               )( ...  ) ( ...  )
305      !        (  0    0    0   zwik zwdk )( zwxk ) ( zwyk )
306      !
[2528]307      !   m is decomposed in the product of an upper and lower triangular matrix
[3]308      !   The 3 diagonal terms are in 2d arrays: zwd, zws, zwi
309      !   The solution (after velocity) is in 2d array va
310      !-----------------------------------------------------------------------
[2528]311      !
[4990]312      !==  First recurrence : Dk = Dk - Lk * Uk-1 / Dk-1   (increasing k)  ==
[5120]313      DO jk = 2, jpkm1       
314         DO jj = 2, jpjm1   
315            DO ji = fs_2, fs_jpim1   ! vector opt.
[3]316               zwd(ji,jj,jk) = zwd(ji,jj,jk) - zwi(ji,jj,jk) * zws(ji,jj,jk-1) / zwd(ji,jj,jk-1)
317            END DO
318         END DO
319      END DO
[2528]320      !
321      DO jj = 2, jpjm1        !==  second recurrence:    SOLk = RHSk - Lk / Dk-1  Lk-1  ==
[3]322         DO ji = fs_2, fs_jpim1   ! vector opt.
[4292]323#if defined key_dynspg_ts           
[5120]324            ze3va =  ( 1._wp - r_vvl ) * fse3v_n(ji,jj,1) + r_vvl   * fse3v_a(ji,jj,1) 
325            va(ji,jj,1) = va(ji,jj,1) + p2dt * 0.5_wp * ( vtau_b(ji,jj) + vtau(ji,jj) )   &
[6795]326               &                                      / ( ze3va * rau0 ) * vmask(ji,jj,1)
[4292]327#else
[5120]328            va(ji,jj,1) = vb(ji,jj,1) &
329               &                   + p2dt *(va(ji,jj,1) +  0.5_wp * ( vtau_b(ji,jj) + vtau(ji,jj) )   &
[6795]330               &                                      / ( fse3v(ji,jj,1) * rau0     ) * vmask(ji,jj,1) )
[4292]331#endif
[5120]332         END DO
333      END DO
334      DO jk = 2, jpkm1
335         DO jj = 2, jpjm1
336            DO ji = fs_2, fs_jpim1   ! vector opt.
[4292]337#if defined key_dynspg_ts
338               zrhs = va(ji,jj,jk)   ! zrhs=right hand side
339#else
340               zrhs = vb(ji,jj,jk) + p2dt * va(ji,jj,jk)
341#endif
[3]342               va(ji,jj,jk) = zrhs - zwi(ji,jj,jk) / zwd(ji,jj,jk-1) * va(ji,jj,jk-1)
343            END DO
344         END DO
345      END DO
[2528]346      !
[4292]347      DO jj = 2, jpjm1        !==  third recurrence : SOLk = ( Lk - Uk * SOLk+1 ) / Dk  ==
[3]348         DO ji = fs_2, fs_jpim1   ! vector opt.
349            va(ji,jj,jpkm1) = va(ji,jj,jpkm1) / zwd(ji,jj,jpkm1)
[5120]350         END DO
351      END DO
352      DO jk = jpk-2, 1, -1
353         DO jj = 2, jpjm1
354            DO ji = fs_2, fs_jpim1
[2528]355               va(ji,jj,jk) = ( va(ji,jj,jk) - zws(ji,jj,jk) * va(ji,jj,jk+1) ) / zwd(ji,jj,jk)
[3]356            END DO
357         END DO
358      END DO
359
360      ! Normalization to obtain the general momentum trend va
[4292]361#if ! defined key_dynspg_ts
[3]362      DO jk = 1, jpkm1
363         DO jj = 2, jpjm1   
364            DO ji = fs_2, fs_jpim1   ! vector opt.
[2528]365               va(ji,jj,jk) = ( va(ji,jj,jk) - vb(ji,jj,jk) ) * z1_p2dt
[3]366            END DO
367         END DO
368      END DO
[4292]369#endif
[3294]370
[4292]371      ! J. Chanut: Lines below are useless ?
[3294]372      !! restore bottom layer avmu(v)
373      IF( ln_bfrimp ) THEN
[4990]374        DO jj = 2, jpjm1
375           DO ji = 2, jpim1
376              ikbu = mbku(ji,jj)         ! ocean bottom level at u- and v-points
377              ikbv = mbkv(ji,jj)         ! (deepest ocean u- and v-points)
378              avmu(ji,jj,ikbu+1) = 0.e0
379              avmv(ji,jj,ikbv+1) = 0.e0
380           END DO
381        END DO
[5120]382        IF (ln_isfcav) THEN
383           DO jj = 2, jpjm1
384              DO ji = 2, jpim1
385                 ikbu = miku(ji,jj)         ! ocean top level at u- and v-points
386                 ikbv = mikv(ji,jj)         ! (first wet ocean u- and v-points)
387                 IF (ikbu > 1) avmu(ji,jj,ikbu) = 0.e0
388                 IF (ikbv > 1) avmv(ji,jj,ikbv) = 0.e0
389              END DO
390           END DO
391        END IF
[3294]392      ENDIF
[2528]393      !
[3294]394      CALL wrk_dealloc( jpi,jpj,jpk, zwi, zwd, zws) 
[2715]395      !
[3294]396      IF( nn_timing == 1 )  CALL timing_stop('dyn_zdf_imp')
397      !
[3]398   END SUBROUTINE dyn_zdf_imp
399
400   !!==============================================================================
401END MODULE dynzdf_imp
Note: See TracBrowser for help on using the repository browser.