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.
tradmp.F90 in branches/dev_001_GM/NEMO/OPA_SRC/TRA – NEMO

source: branches/dev_001_GM/NEMO/OPA_SRC/TRA/tradmp.F90 @ 740

Last change on this file since 740 was 719, checked in by ctlod, 17 years ago

get back to the nemo_v2_3 version for trunk

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 34.6 KB
Line 
1MODULE tradmp
2   !!======================================================================
3   !!                       ***  MODULE  tradmp  ***
4   !! Ocean physics: internal restoring trend on active tracers (T and S)
5   !!======================================================================
6   !! History :  5.0  !  91-03  (O. Marti, G. Madec)  Original code
7   !!                 !  92-06  (M. Imbard)  doctor norme
8   !!                 !  96-01  (G. Madec)  statement function for e3
9   !!                 !  97-05  (G. Madec)  macro-tasked on jk-slab
10   !!                 !  98-07  (M. Imbard, G. Madec) ORCA version
11   !!            7.0  !  01-02  (M. Imbard)  cofdis, Original code
12   !!            8.1  !  01-02  (G. Madec, E. Durand)  cleaning
13   !!            8.5  !  02-08  (G. Madec, E. Durand)  free form + modules
14   !!----------------------------------------------------------------------
15#if   defined key_tradmp   ||   defined key_esopa
16   !!----------------------------------------------------------------------
17   !!   key_tradmp                                         internal damping
18   !!----------------------------------------------------------------------
19   !!----------------------------------------------------------------------
20   !!   tra_dmp      : update the tracer trend with the internal damping
21   !!   tra_dmp_init : initialization, namlist read, parameters control
22   !!   dtacof_zoom  : restoring coefficient for zoom domain
23   !!   dtacof       : restoring coefficient for global domain
24   !!   cofdis       : compute the distance to the coastline
25   !!----------------------------------------------------------------------
26   USE oce             ! ocean dynamics and tracers variables
27   USE dom_oce         ! ocean space and time domain variables
28   USE trdmod          ! ocean active tracers trends
29   USE trdmod_oce      ! ocean variables trends
30   USE zdf_oce         ! ocean vertical physics
31   USE in_out_manager  ! I/O manager
32   USE phycst          ! Define parameters for the routines
33   USE dtatem          ! temperature data
34   USE dtasal          ! salinity data
35   USE zdfmxl          ! mixed layer depth
36   USE lib_mpp         ! distribued memory computing
37   USE prtctl          ! Print control
38
39   IMPLICIT NONE
40   PRIVATE
41
42   PUBLIC tra_dmp      ! routine called by step.F90
43
44#if ! defined key_agrif
45   LOGICAL, PUBLIC, PARAMETER ::   lk_tradmp = .TRUE.     !: internal damping flag
46#else
47   LOGICAL, PUBLIC            ::   lk_tradmp = .TRUE.     !: internal damping flag
48#endif
49   REAL(wp), PUBLIC, DIMENSION(jpi,jpj,jpk) ::   strdmp   !: damping salinity trend (psu/s)
50   REAL(wp), PUBLIC, DIMENSION(jpi,jpj,jpk) ::   resto    !: restoring coeff. on T and S (s-1)
51   
52   !!* newtonian damping namelist (mandmp)
53   INTEGER  ::   ndmp   =   -1    ! = 0/-1/'latitude' for damping over T and S
54   INTEGER  ::   ndmpf  =    2    ! = 1 create a damping.coeff NetCDF file
55   INTEGER  ::   nmldmp =    0    ! = 0/1/2 flag for damping in the mixed layer
56   REAL(wp) ::   sdmp   =   50.   ! surface time scale for internal damping (days)
57   REAL(wp) ::   bdmp   =  360.   ! bottom time scale for internal damping (days)
58   REAL(wp) ::   hdmp   =  800.   ! depth of transition between sdmp and bdmp (meters)
59
60   !! * Substitutions
61#  include "domzgr_substitute.h90"
62#  include "vectopt_loop_substitute.h90"
63   !!----------------------------------------------------------------------
64   !!   OPA 9.0 , LOCEAN-IPSL (2006)
65   !! $Header$
66   !! Software governed by the CeCILL licence (modipsl/doc/NEMO_CeCILL.txt)
67   !!----------------------------------------------------------------------
68
69CONTAINS
70
71   SUBROUTINE tra_dmp( kt )
72      !!----------------------------------------------------------------------
73      !!                   ***  ROUTINE tra_dmp  ***
74      !!                 
75      !! ** Purpose :   Compute the tracer trend due to a newtonian damping
76      !!      of the tracer field towards given data field and add it to the
77      !!      general tracer trends.
78      !!
79      !! ** Method  :   Newtonian damping towards t_dta and s_dta computed
80      !!      and add to the general tracer trends:
81      !!                     ta = ta + resto * (t_dta - tb)
82      !!                     sa = sa + resto * (s_dta - sb)
83      !!         The trend is computed either throughout the water column
84      !!      (nlmdmp=0) or in area of weak vertical mixing (nlmdmp=1) or
85      !!      below the well mixed layer (nlmdmp=2)
86      !!
87      !! ** Action  : - update the tracer trends (ta,sa) with the newtonian
88      !!                damping trends.
89      !!              - save the trends in (ttrd,strd) ('key_trdtra')
90      !!----------------------------------------------------------------------
91      USE oce, ONLY :   ztrdt => ua   ! use ua as 3D workspace   
92      USE oce, ONLY :   ztrds => va   ! use va as 3D workspace   
93      !!
94      INTEGER, INTENT( in ) ::   kt   ! ocean time-step index
95      !!
96      INTEGER  ::   ji, jj, jk            ! dummy loop indices
97      REAL(wp) ::   ztest, zta, zsa       ! temporary scalars
98      !!----------------------------------------------------------------------
99
100      IF( kt == nit000 )   CALL tra_dmp_init      ! Initialization
101
102      IF( l_trdtra )   THEN                       ! Save ta and sa trends
103         ztrdt(:,:,:) = ta(:,:,:) 
104         ztrds(:,:,:) = sa(:,:,:) 
105      ENDIF
106
107      ! 1. Newtonian damping trends on tracer fields
108      ! --------------------------------------------
109      !    compute the newtonian damping trends depending on nmldmp
110
111      SELECT CASE ( nmldmp )
112      !
113      CASE( 0 )                ! newtonian damping throughout the water column
114         DO jk = 1, jpkm1
115            DO jj = 2, jpjm1
116               DO ji = fs_2, fs_jpim1   ! vector opt.
117                  zta = resto(ji,jj,jk) * ( t_dta(ji,jj,jk) - tb(ji,jj,jk) )
118                  zsa = resto(ji,jj,jk) * ( s_dta(ji,jj,jk) - sb(ji,jj,jk) )
119                  ! add the trends to the general tracer trends
120                  ta(ji,jj,jk) = ta(ji,jj,jk) + zta
121                  sa(ji,jj,jk) = sa(ji,jj,jk) + zsa
122                  ! save the salinity trend (used in flx to close the salt budget)
123                  strdmp(ji,jj,jk) = zsa
124               END DO
125            END DO
126         END DO
127         !
128      CASE ( 1 )                ! no damping in the turbocline (avt > 5 cm2/s)
129         DO jk = 1, jpkm1
130            DO jj = 2, jpjm1
131               DO ji = fs_2, fs_jpim1   ! vector opt.
132                  ztest = avt(ji,jj,jk) - 5.e-4
133                  IF( ztest < 0. ) THEN
134                     zta = resto(ji,jj,jk) * ( t_dta(ji,jj,jk) - tb(ji,jj,jk) )
135                     zsa = resto(ji,jj,jk) * ( s_dta(ji,jj,jk) - sb(ji,jj,jk) )
136                  ELSE
137                     zta = 0.e0
138                     zsa = 0.e0
139                  ENDIF
140                  ! add the trends to the general tracer trends
141                  ta(ji,jj,jk) = ta(ji,jj,jk) + zta
142                  sa(ji,jj,jk) = sa(ji,jj,jk) + zsa
143                  ! save the salinity trend (used in flx to close the salt budget)
144                  strdmp(ji,jj,jk) = zsa
145               END DO
146            END DO
147         END DO
148         !
149      CASE ( 2 )                ! no damping in the mixed layer
150         DO jk = 1, jpkm1
151            DO jj = 2, jpjm1
152               DO ji = fs_2, fs_jpim1   ! vector opt.
153                  IF( fsdept(ji,jj,jk) >= hmlp (ji,jj) ) THEN
154                     zta = resto(ji,jj,jk) * ( t_dta(ji,jj,jk) - tb(ji,jj,jk) )
155                     zsa = resto(ji,jj,jk) * ( s_dta(ji,jj,jk) - sb(ji,jj,jk) )
156                  ELSE
157                     zta = 0.e0
158                     zsa = 0.e0
159                  ENDIF
160                  ! add the trends to the general tracer trends
161                  ta(ji,jj,jk) = ta(ji,jj,jk) + zta
162                  sa(ji,jj,jk) = sa(ji,jj,jk) + zsa
163                  ! save the salinity trend (used in flx to close the salt budget)
164                  strdmp(ji,jj,jk) = zsa
165               END DO
166            END DO
167         END DO
168         !
169      END SELECT
170
171      IF( l_trdtra )   THEN          ! save the damping tracer trends for diagnostic
172         ztrdt(:,:,:) = ta(:,:,:) - ztrdt(:,:,:)
173         ztrds(:,:,:) = sa(:,:,:) - ztrds(:,:,:)
174         CALL trd_mod(ztrdt, ztrds, jptra_trd_dmp, 'TRA', kt)
175      ENDIF
176      !                              ! Control print
177      IF(ln_ctl)   CALL prt_ctl( tab3d_1=ta, clinfo1=' dmp  - Ta: ', mask1=tmask,   &
178         &                       tab3d_2=sa, clinfo2=       ' Sa: ', mask2=tmask, clinfo3='tra' )
179      !
180   END SUBROUTINE tra_dmp
181
182
183   SUBROUTINE tra_dmp_init
184      !!----------------------------------------------------------------------
185      !!                  ***  ROUTINE tra_dmp_init  ***
186      !!
187      !! ** Purpose :   Initialization for the newtonian damping
188      !!
189      !! ** Method  :   read the nammbf namelist and check the parameters
190      !!      called by tra_dmp at the first timestep (nit000)
191      !!----------------------------------------------------------------------
192      NAMELIST/namtdp/ ndmp, ndmpf, nmldmp, sdmp, bdmp, hdmp
193      !!----------------------------------------------------------------------
194
195      REWIND ( numnam )                  ! Read Namelist namtdp : temperature and salinity damping term
196      READ   ( numnam, namtdp )
197      IF( lzoom )   nmldmp = 0           ! restoring to climatology at closed north or south boundaries
198
199      IF(lwp) THEN                       ! Namelist print
200         WRITE(numout,*)
201         WRITE(numout,*) 'tra_dmp : T and S newtonian damping'
202         WRITE(numout,*) '~~~~~~~'
203         WRITE(numout,*) '       Namelist namtdp : set damping parameter'
204         WRITE(numout,*) '          T and S damping option         ndmp   = ', ndmp
205         WRITE(numout,*) '          create a damping.coeff file    ndmpf  = ', ndmpf
206         WRITE(numout,*) '          mixed layer damping option     nmldmp = ', nmldmp, '(zoom: forced to 0)'
207         WRITE(numout,*) '          surface time scale (days)      sdmp   = ', sdmp
208         WRITE(numout,*) '          bottom time scale (days)       bdmp   = ', bdmp
209         WRITE(numout,*) '          depth of transition (meters)   hdmp   = ', hdmp
210      ENDIF
211
212      SELECT CASE ( ndmp )
213      CASE (  -1  )   ;   IF(lwp) WRITE(numout,*) '          tracer damping in the Med & Red seas only'
214      CASE ( 1:90 )   ;   IF(lwp) WRITE(numout,*) '          tracer damping poleward of', ndmp, ' degrees'
215      CASE DEFAULT
216         WRITE(ctmp1,*) '          bad flag value for ndmp = ', ndmp
217         CALL ctl_stop(ctmp1)
218      END SELECT
219
220      SELECT CASE ( nmldmp )
221      CASE ( 0 )   ;   IF(lwp) WRITE(numout,*) '          tracer damping throughout the water column'
222      CASE ( 1 )   ;   IF(lwp) WRITE(numout,*) '          no tracer damping in the turbocline (avt > 5 cm2/s)'
223      CASE ( 2 )   ;   IF(lwp) WRITE(numout,*) '          no tracer damping in the mixed layer'
224      CASE DEFAULT
225         WRITE(ctmp1,*) '          bad flag value for nmldmp = ', nmldmp
226         CALL ctl_stop(ctmp1)
227      END SELECT
228
229      IF( .NOT.lk_dtasal .OR. .NOT.lk_dtatem )   &
230         &   CALL ctl_stop( 'no temperature and/or salinity data define key_dtatem and key_dtasal' )
231
232      strdmp(:,:,:) = 0.e0       ! internal damping salinity trend (used in ocesbc)
233
234      !                          ! Damping coefficients initialization
235      IF( lzoom ) THEN   ;   CALL dtacof_zoom
236      ELSE               ;   CALL dtacof
237      ENDIF
238      !
239   END SUBROUTINE tra_dmp_init
240
241
242   SUBROUTINE dtacof_zoom
243      !!----------------------------------------------------------------------
244      !!                  ***  ROUTINE dtacof_zoom  ***
245      !!
246      !! ** Purpose :   Compute the damping coefficient for zoom domain
247      !!
248      !! ** Method  : - set along closed boundary due to zoom a damping over
249      !!      6 points with a max time scale of 5 days.
250      !!              - ORCA arctic/antarctic zoom: set the damping along
251      !!      south/north boundary over a latitude strip.
252      !!
253      !! ** Action  : - resto, the damping coeff. for T and S
254      !!----------------------------------------------------------------------
255      INTEGER  ::   ji, jj, jk, jn              ! dummy loop indices
256      REAL(wp) ::   zlat, zlat0, zlat1, zlat2   ! temporary scalar
257      REAL(wp), DIMENSION(6)  ::   zfact        ! temporary workspace
258      !!----------------------------------------------------------------------
259
260      zfact(1) =  1.
261      zfact(2) =  1. 
262      zfact(3) = 11./12.
263      zfact(4) =  8./12.
264      zfact(5) =  4./12.
265      zfact(6) =  1./12.
266      zfact(:) = zfact(:) / ( 5. * rday )    ! 5 days max restoring time scale
267
268      resto(:,:,:) = 0.e0
269
270      ! damping along the forced closed boundary over 6 grid-points
271      DO jn = 1, 6
272         IF( lzoom_w )   resto( mi0(jn+jpizoom):mi1(jn+jpizoom), : , : )                    = zfact(jn)   ! west  closed
273         IF( lzoom_s )   resto( : , mj0(jn+jpjzoom):mj1(jn+jpjzoom), : )                    = zfact(jn)   ! south closed
274         IF( lzoom_e )   resto( mi0(jpiglo+jpizoom-1-jn):mi1(jpiglo+jpizoom-1-jn) , : , : ) = zfact(jn)   ! east  closed
275         IF( lzoom_n )   resto( : , mj0(jpjglo+jpjzoom-1-jn):mj1(jpjglo+jpjzoom-1-jn) , : ) = zfact(jn)   ! north closed
276      END DO
277
278
279      IF( lzoom_arct .AND. lzoom_anta ) THEN
280         !
281         ! ====================================================
282         !  ORCA configuration : arctic zoom or antarctic zoom
283         ! ====================================================
284
285         IF(lwp) WRITE(numout,*)
286         IF(lwp .AND. lzoom_arct ) WRITE(numout,*) '              dtacof_zoom : ORCA    Arctic zoom'
287         IF(lwp .AND. lzoom_arct ) WRITE(numout,*) '              dtacof_zoom : ORCA Antarctic zoom'
288         IF(lwp) WRITE(numout,*)
289
290         ! ... Initialization :
291         !     zlat0 : latitude strip where resto decreases
292         !     zlat1 : resto = 1 before zlat1
293         !     zlat2 : resto decreases from 1 to 0 between zlat1 and zlat2
294         resto(:,:,:) = 0.e0
295         zlat0 = 10.
296         zlat1 = 30.
297         zlat2 = zlat1 + zlat0
298
299         ! ... Compute arrays resto ; value for internal damping : 5 days
300         DO jk = 2, jpkm1
301            DO jj = 1, jpj
302               DO ji = 1, jpi
303                  zlat = ABS( gphit(ji,jj) )
304                  IF ( zlat1 <= zlat .AND. zlat <= zlat2 ) THEN
305                     resto(ji,jj,jk) = 0.5 * ( 1./(5.*rday) ) *   &
306                        ( 1. - cos(rpi*(zlat2-zlat)/zlat0) ) 
307                  ELSE IF ( zlat < zlat1 ) THEN
308                     resto(ji,jj,jk) = 1./(5.*rday)
309                  ENDIF
310               END DO
311            END DO
312         END DO
313         !
314      ENDIF
315
316      ! ... Mask resto array
317      resto(:,:,:) = resto(:,:,:) * tmask(:,:,:)
318      !
319   END SUBROUTINE dtacof_zoom
320
321
322   SUBROUTINE dtacof
323      !!----------------------------------------------------------------------
324      !!                  ***  ROUTINE dtacof  ***
325      !!
326      !! ** Purpose :   Compute the damping coefficient
327      !!
328      !! ** Method  :   Arrays defining the damping are computed for each grid
329      !!      point for temperature and salinity (resto)
330      !!      Damping depends on distance to coast, depth and latitude
331      !!
332      !! ** Action  : - resto, the damping coeff. for T and S
333      !!----------------------------------------------------------------------
334      USE iom
335      USE ioipsl
336      !!
337      INTEGER ::   ji, jj, jk     ! dummy loop indices
338      INTEGER ::   itime
339      INTEGER ::   ii0, ii1, ij0, ij1  !    "          "
340      INTEGER ::   idmp         ! logical unit for file restoring damping term
341      INTEGER ::   icot         ! logical unit for file distance to the coast
342      CHARACTER (len=32) :: clname3
343      REAL(wp) ::   zdate0, zinfl, zlon         ! temporary scalars
344      REAL(wp) ::   zlat, zlat0, zlat1, zlat2   !    "         "
345      REAL(wp) ::   zsdmp, zbdmp                !    "         "
346      REAL(wp), DIMENSION(jpk)         ::   zhfac
347      REAL(wp), DIMENSION(jpi,jpj)     ::   zmrs
348      REAL(wp), DIMENSION(jpi,jpj,jpk) ::   zdct
349      !!----------------------------------------------------------------------
350
351      ! ====================================
352      !  ORCA configuration : global domain
353      ! ====================================
354
355      IF(lwp) WRITE(numout,*)
356      IF(lwp) WRITE(numout,*) '              dtacof : Global domain of ORCA'
357      IF(lwp) WRITE(numout,*) '              ------------------------------'
358
359      ! ... Initialization :
360      !   zdct()      : distant to the coastline
361      !   resto()     : array of restoring coeff. on T and S
362
363      resto(:,:,:) = 0.e0
364
365      IF ( ndmp > 0 ) THEN
366
367         !    ------------------------------------
368         !     Damping poleward of 'ndmp' degrees
369         !    ------------------------------------
370
371         IF(lwp) WRITE(numout,*)
372         IF(lwp) WRITE(numout,*) '              Damping poleward of ', ndmp,' deg.'
373         IF(lwp) WRITE(numout,*)
374
375         ! ... Distance to coast (zdct)
376
377         IF(lwp) WRITE(numout,*)
378         IF(lwp) WRITE(numout,*) ' dtacof : distance to coast file'
379         CALL iom_open ( 'dist.coast.nc', icot )
380         IF( icot > 0 ) THEN
381            CALL iom_get ( icot, jpdom_data, 'Tcoast', zdct )
382            CALL iom_close (icot)
383         ELSE
384            !   ... Compute and save the distance-to-coast array (output in zdct)
385            CALL cofdis( zdct )
386         ENDIF
387
388         ! ... Compute arrays resto
389         !      zinfl : distance of influence for damping term
390         !      zlat0 : latitude strip where resto decreases
391         !      zlat1 : resto = 0 between -zlat1 and zlat1
392         !      zlat2 : resto increases from 0 to 1 between |zlat1| and |zlat2|
393         !          and resto = 1 between |zlat2| and 90 deg.
394         zinfl = 1000.e3
395         zlat0 = 10
396         zlat1 = ndmp
397         zlat2 = zlat1 + zlat0
398
399         DO jj = 1, jpj
400            DO ji = 1, jpi
401               zlat = ABS( gphit(ji,jj) )
402               IF ( zlat1 <= zlat .AND. zlat <= zlat2 ) THEN
403                  resto(ji,jj,1) = 0.5 * ( 1. - cos(rpi*(zlat-zlat1)/zlat0 ) )
404               ELSEIF ( zlat > zlat2 ) THEN
405                  resto(ji,jj,1) = 1.
406               ENDIF
407            END DO
408         END DO
409
410         !   ... North Indian ocean (20N/30N x 45E/100E) : resto=0
411         IF ( ndmp == 20 ) THEN
412            DO jj = 1, jpj
413               DO ji = 1, jpi
414                  zlat = gphit(ji,jj)
415                  zlon = MOD( glamt(ji,jj), 360. )
416                  IF ( zlat1 < zlat .AND. zlat < zlat2 .AND.   &
417                     45.  < zlon .AND. zlon < 100. ) THEN
418                     resto(ji,jj,1) = 0.
419                  ENDIF
420               END DO
421            END DO
422         ENDIF
423
424         zsdmp = 1./(sdmp * rday)
425         zbdmp = 1./(bdmp * rday)
426         DO jk = 2, jpkm1
427            DO jj = 1, jpj
428               DO ji = 1, jpi
429                  zdct(ji,jj,jk) = MIN( zinfl, zdct(ji,jj,jk) )
430                  !   ... Decrease the value in the vicinity of the coast
431                  resto(ji,jj,jk) = resto(ji,jj,1) * 0.5 * ( 1. - COS( rpi*zdct(ji,jj,jk)/zinfl) )
432                  !   ... Vertical variation from zsdmp (sea surface) to zbdmp (bottom)
433                  resto(ji,jj,jk) = resto(ji,jj,jk)      * ( zbdmp + (zsdmp-zbdmp)*EXP(-fsdept(ji,jj,jk)/hdmp) )
434               END DO
435            END DO
436         END DO
437         !
438      ENDIF
439
440
441      IF( cp_cfg == "orca" .AND. ( ndmp > 0 .OR. ndmp == -1 ) ) THEN
442
443         !                                         ! =========================
444         !                                         !  Med and Red Sea damping
445         !                                         ! =========================
446         IF(lwp)WRITE(numout,*)
447         IF(lwp)WRITE(numout,*) '              ORCA configuration: Damping in Med and Red Seas'
448
449
450         zmrs(:,:) = 0.e0                             ! damping term on the Med or Red Sea
451
452         SELECT CASE ( jp_cfg )
453         !                                           ! =======================
454         CASE ( 4 )                                  !  ORCA_R4 configuration
455            !                                        ! =======================
456            ! Mediterranean Sea
457            ij0 =  50   ;   ij1 =  56
458            ii0 =  81   ;   ii1 =  91   ;   zmrs( mi0(ii0):mi1(ii1) , mj0(ij0):mj1(ij1) ) = 1.e0
459            ij0 =  50   ;   ij1 =  55
460            ii0 =  75   ;   ii1 =  80   ;   zmrs( mi0(ii0):mi1(ii1) , mj0(ij0):mj1(ij1) ) = 1.e0
461            ij0 =  52   ;   ij1 =  53
462            ii0 =  70   ;   ii1 =  74   ;   zmrs( mi0(ii0):mi1(ii1) , mj0(ij0):mj1(ij1) ) = 1.e0
463            ! Smooth transition from 0 at surface to 1./rday at the 18th level in Med and Red Sea
464            DO jk = 1, 17
465               zhfac (jk) = 0.5*( 1.- COS( rpi*(jk-1)/16. ) ) / rday
466            END DO
467            DO jk = 18, jpkm1
468               zhfac (jk) = 1./rday
469            END DO
470            !                                        ! =======================
471         CASE ( 2 )                                  !  ORCA_R2 configuration
472            !                                        ! =======================
473            ! Mediterranean Sea
474            ij0 =  96   ;   ij1 = 110
475            ii0 = 157   ;   ii1 = 181   ;   zmrs( mi0(ii0):mi1(ii1) , mj0(ij0):mj1(ij1) ) = 1.e0
476            ij0 = 100   ;   ij1 = 110
477            ii0 = 144   ;   ii1 = 156   ;   zmrs( mi0(ii0):mi1(ii1) , mj0(ij0):mj1(ij1) ) = 1.e0
478            ij0 = 100   ;   ij1 = 103
479            ii0 = 139   ;   ii1 = 143   ;   zmrs( mi0(ii0):mi1(ii1) , mj0(ij0):mj1(ij1) ) = 1.e0
480            ! Decrease before Gibraltar Strait
481            ij0 = 101   ;   ij1 = 102
482            ii0 = 139   ;   ii1 = 141   ;   zmrs( mi0(ii0):mi1(ii1) , mj0(ij0):mj1(ij1) ) = 0.e0
483            ii0 = 142   ;   ii1 = 142   ;   zmrs( mi0(ii0):mi1(ii1) , mj0(ij0):mj1(ij1) ) = 1.e0 / 90.e0
484            ii0 = 143   ;   ii1 = 143   ;   zmrs( mi0(ii0):mi1(ii1) , mj0(ij0):mj1(ij1) ) = 0.40e0
485            ii0 = 144   ;   ii1 = 144   ;   zmrs( mi0(ii0):mi1(ii1) , mj0(ij0):mj1(ij1) ) = 0.75e0
486            ! Red Sea
487            ij0 =  87   ;   ij1 =  96
488            ii0 = 147   ;   ii1 = 163   ;   zmrs( mi0(ii0):mi1(ii1) , mj0(ij0):mj1(ij1) ) = 1.e0
489            ! Decrease before Bab el Mandeb Strait
490            ij0 =  91   ;   ij1 =  91
491            ii0 = 153   ;   ii1 = 160   ;   zmrs( mi0(ii0):mi1(ii1) , mj0(ij0):mj1(ij1) ) = 0.80e0
492            ij0 =  90   ;   ij1 =  90
493            ii0 = 153   ;   ii1 = 160   ;   zmrs( mi0(ii0):mi1(ii1) , mj0(ij0):mj1(ij1) ) = 0.40e0
494            ij0 =  89   ;   ij1 =  89
495            ii0 = 158   ;   ii1 = 160   ;   zmrs( mi0(ii0):mi1(ii1) , mj0(ij0):mj1(ij1) ) = 1.e0 / 90.e0
496            ij0 =  88   ;   ij1 =  88
497            ii0 = 160   ;   ii1 = 163   ;   zmrs( mi0(ii0):mi1(ii1) , mj0(ij0):mj1(ij1) ) = 0.e0
498            ! Smooth transition from 0 at surface to 1./rday at the 18th level in Med and Red Sea
499            DO jk = 1, 17
500               zhfac (jk) = 0.5*( 1.- COS( rpi*(jk-1)/16. ) ) / rday
501            END DO
502            DO jk = 18, jpkm1
503               zhfac (jk) = 1./rday
504            END DO
505            !                                        ! =======================
506         CASE ( 05 )                                 !  ORCA_R05 configuration
507            !                                        ! =======================
508            ! Mediterranean Sea
509            ii0 = 568   ;   ii1 = 574 
510            ij0 = 324   ;   ij1 = 333   ;   zmrs( mi0(ii0):mi1(ii1) , mj0(ij0):mj1(ij1) ) = 1.e0
511            ii0 = 575   ;   ii1 = 658
512            ij0 = 314   ;   ij1 = 366   ;   zmrs( mi0(ii0):mi1(ii1) , mj0(ij0):mj1(ij1) ) = 1.e0
513            ! Black Sea (remaining part
514            ii0 = 641   ;   ii1 = 651
515            ij0 = 367   ;   ij1 = 372   ;   zmrs( mi0(ii0):mi1(ii1) , mj0(ij0):mj1(ij1) ) = 1.e0
516            ! Decrease before Gibraltar Strait
517            ij0 = 324   ;   ij1 = 333
518            ii0 = 565   ;   ii1 = 565   ;   zmrs( mi0(ii0):mi1(ii1) , mj0(ij0):mj1(ij1) ) = 1.e0 / 90.e0
519            ii0 = 566   ;   ii1 = 566   ;   zmrs( mi0(ii0):mi1(ii1) , mj0(ij0):mj1(ij1) ) = 0.40
520            ii0 = 567   ;   ii1 = 567   ;   zmrs( mi0(ii0):mi1(ii1) , mj0(ij0):mj1(ij1) ) = 0.75
521            ! Red Sea
522            ii0 = 641   ;   ii1 = 665
523            ij0 = 270   ;   ij1 = 310   ;   zmrs( mi0(ii0):mi1(ii1) , mj0(ij0):mj1(ij1) ) = 1.e0
524            ! Decrease before Bab el Mandeb Strait
525            ii0 = 666   ;   ii1 = 675
526            ij0 = 270   ;   ij1 = 290   
527            DO ji = mi0(ii0), mi1(ii1)
528               zmrs( ji , mj0(ij0):mj1(ij1) ) = 0.1 * ABS( FLOAT(ji - mi1(ii1)) )
529            END DO
530            zsdmp = 1./(sdmp * rday)
531            zbdmp = 1./(bdmp * rday)
532            DO jk = 1, jpk
533               zhfac (jk) = ( zbdmp + (zsdmp-zbdmp) * EXP(-fsdept(1,1,jk)/hdmp) )
534            END DO
535            !                                       ! ========================
536         CASE ( 025 )                               !  ORCA_R025 configuration
537            !                                       ! ========================
538            CALL ctl_stop( ' Not yet implemented in ORCA_R025' )
539            !
540         END SELECT
541
542         DO jk = 1, jpkm1
543            resto(:,:,jk) = zmrs(:,:) * zhfac(jk) + ( 1. - zmrs(:,:) ) * resto(:,:,jk)
544         END DO
545
546         ! Mask resto array and set to 0 first and last levels
547         resto(:,:, : ) = resto(:,:,:) * tmask(:,:,:)
548         resto(:,:, 1 ) = 0.e0
549         resto(:,:,jpk) = 0.e0
550
551      ELSE
552         !    ------------
553         !     No damping
554         !    ------------
555         CALL ctl_stop( 'Choose a correct value of ndmp or DO NOT defined key_tradmp' )
556      ENDIF
557
558      !    ----------------------------
559      !     Create Print damping array
560      !    ----------------------------
561
562      ! ndmpf   : = 1 create a damping.coeff NetCDF file
563
564      IF( ndmpf == 1 ) THEN
565         IF(lwp) WRITE(numout,*) '              create damping.coeff.nc file'
566         itime   = 0
567         clname3 = 'damping.coeff'
568         CALL ymds2ju( 0     , 1      , 1      , 0.e0 , zdate0 )
569         CALL restini( 'NONE', jpi    , jpj    , glamt, gphit,    &
570            &          jpk   , gdept_0, clname3, itime, zdate0,   &
571            &          rdt   , idmp, domain_id=nidom )
572         CALL restput( idmp, 'Resto', jpi, jpj, jpk,   &
573            &          0   , resto  )
574         CALL restclo( idmp )
575      ENDIF
576      !
577   END SUBROUTINE dtacof
578
579
580   SUBROUTINE cofdis( pdct )
581      !!----------------------------------------------------------------------
582      !!                 ***  ROUTINE cofdis  ***
583      !!
584      !! ** Purpose :   Compute the distance between ocean T-points and the
585      !!      ocean model coastlines. Save the distance in a NetCDF file.
586      !!
587      !! ** Method  :   For each model level, the distance-to-coast is
588      !!      computed as follows :
589      !!       - The coastline is defined as the serie of U-,V-,F-points
590      !!      that are at the ocean-land bound.
591      !!       - For each ocean T-point, the distance-to-coast is then
592      !!      computed as the smallest distance (on the sphere) between the
593      !!      T-point and all the coastline points.
594      !!       - For land T-points, the distance-to-coast is set to zero.
595      !!      C A U T I O N : Computation not yet implemented in mpp case.
596      !!
597      !! ** Action  : - pdct, distance to the coastline (argument)
598      !!              - NetCDF file 'dist.coast.nc'
599      !!----------------------------------------------------------------------
600      USE ioipsl      ! IOipsl librairy
601      !!
602      REAL(wp), DIMENSION(jpi,jpj,jpk), INTENT( out ) ::   pdct   ! distance to the coastline
603      !!
604      INTEGER ::   ji, jj, jk, jl      ! dummy loop indices
605      INTEGER ::   iju, ijt            ! temporary integers
606      INTEGER ::   icoast, itime
607      INTEGER ::   icot         ! logical unit for file distance to the coast
608      LOGICAL, DIMENSION(jpi,jpj) ::   llcotu, llcotv, llcotf   ! ???
609      CHARACTER (len=32) ::   clname
610      REAL(wp) ::   zdate0
611      REAL(wp), DIMENSION(jpi,jpj)   ::   zxt, zyt, zzt, zmask   ! cartesian coordinates for T-points
612      REAL(wp), DIMENSION(3*jpi*jpj) ::   zxc, zyc, zzc, zdis    ! temporary workspace
613      !!----------------------------------------------------------------------
614
615      ! 0. Initialization
616      ! -----------------
617      IF(lwp) WRITE(numout,*)
618      IF(lwp) WRITE(numout,*) 'cofdis : compute the distance to coastline'
619      IF(lwp) WRITE(numout,*) '~~~~~~'
620      IF(lwp) WRITE(numout,*)
621      IF( lk_mpp ) &
622           & CALL ctl_stop('         Computation not yet implemented with key_mpp_...', &
623           &               '         Rerun the code on another computer or ', &
624           &               '         create the "dist.coast.nc" file using IDL' )
625
626      pdct(:,:,:) = 0.e0
627      zxt(:,:) = cos( rad * gphit(:,:) ) * cos( rad * glamt(:,:) )
628      zyt(:,:) = cos( rad * gphit(:,:) ) * sin( rad * glamt(:,:) )
629      zzt(:,:) = sin( rad * gphit(:,:) )
630
631
632      ! 1. Loop on vertical levels
633      ! --------------------------
634      !                                                ! ===============
635      DO jk = 1, jpkm1                                 ! Horizontal slab
636         !                                             ! ===============
637         ! Define the coastline points (U, V and F)
638         DO jj = 2, jpjm1
639            DO ji = 2, jpim1
640               zmask(ji,jj) =  ( tmask(ji,jj+1,jk) + tmask(ji+1,jj+1,jk) &
641                   &           + tmask(ji,jj  ,jk) + tmask(ji+1,jj  ,jk) )
642               llcotu(ji,jj) = ( tmask(ji,jj,  jk) + tmask(ji+1,jj  ,jk) == 1. ) 
643               llcotv(ji,jj) = ( tmask(ji,jj  ,jk) + tmask(ji  ,jj+1,jk) == 1. ) 
644               llcotf(ji,jj) = ( zmask(ji,jj) > 0. ) .AND. ( zmask(ji,jj) < 4. )
645            END DO
646         END DO
647
648         ! Lateral boundaries conditions
649         llcotu(:, 1 ) = umask(:,  2  ,jk) == 1
650         llcotu(:,jpj) = umask(:,jpjm1,jk) == 1
651         llcotv(:, 1 ) = vmask(:,  2  ,jk) == 1
652         llcotv(:,jpj) = vmask(:,jpjm1,jk) == 1
653         llcotf(:, 1 ) = fmask(:,  2  ,jk) == 1
654         llcotf(:,jpj) = fmask(:,jpjm1,jk) == 1
655
656         IF( nperio == 1 .OR. nperio == 4 .OR. nperio == 6 ) THEN
657            llcotu( 1 ,:) = llcotu(jpim1,:)
658            llcotu(jpi,:) = llcotu(  2  ,:)
659            llcotv( 1 ,:) = llcotv(jpim1,:)
660            llcotv(jpi,:) = llcotv(  2  ,:)
661            llcotf( 1 ,:) = llcotf(jpim1,:)
662            llcotf(jpi,:) = llcotf(  2  ,:)
663         ELSE
664            llcotu( 1 ,:) = umask(  2  ,:,jk) == 1
665            llcotu(jpi,:) = umask(jpim1,:,jk) == 1
666            llcotv( 1 ,:) = vmask(  2  ,:,jk) == 1
667            llcotv(jpi,:) = vmask(jpim1,:,jk) == 1
668            llcotf( 1 ,:) = fmask(  2  ,:,jk) == 1
669            llcotf(jpi,:) = fmask(jpim1,:,jk) == 1
670         ENDIF
671         IF( nperio == 3 .OR. nperio == 4 ) THEN
672            DO ji = 1, jpim1
673               iju = jpi - ji + 1
674               llcotu(ji,jpj  ) = llcotu(iju,jpj-2)
675               llcotf(ji,jpjm1) = llcotf(iju,jpj-2)
676               llcotf(ji,jpj  ) = llcotf(iju,jpj-3)
677            END DO
678            DO ji = jpi/2, jpim1
679               iju = jpi - ji + 1
680               llcotu(ji,jpjm1) = llcotu(iju,jpjm1)
681            END DO
682            DO ji = 2, jpi
683               ijt = jpi - ji + 2
684               llcotv(ji,jpjm1) = llcotv(ijt,jpj-2)
685               llcotv(ji,jpj  ) = llcotv(ijt,jpj-3)
686            END DO
687         ENDIF
688         IF( nperio == 5 .OR. nperio == 6 ) THEN
689            DO ji = 1, jpim1
690               iju = jpi - ji
691               llcotu(ji,jpj  ) = llcotu(iju,jpjm1)
692               llcotf(ji,jpj  ) = llcotf(iju,jpj-2)
693            END DO
694            DO ji = jpi/2, jpim1
695               iju = jpi - ji
696               llcotf(ji,jpjm1) = llcotf(iju,jpjm1)
697            END DO
698            DO ji = 1, jpi
699               ijt = jpi - ji + 1
700               llcotv(ji,jpj  ) = llcotv(ijt,jpjm1)
701            END DO
702            DO ji = jpi/2+1, jpi
703               ijt = jpi - ji + 1
704               llcotv(ji,jpjm1) = llcotv(ijt,jpjm1)
705            END DO
706         ENDIF
707
708         ! Compute cartesian coordinates of coastline points
709         ! and the number of coastline points
710
711         icoast = 0
712         DO jj = 1, jpj
713            DO ji = 1, jpi
714               IF( llcotf(ji,jj) ) THEN
715                  icoast = icoast + 1
716                  zxc(icoast) = COS( rad*gphif(ji,jj) ) * COS( rad*glamf(ji,jj) )
717                  zyc(icoast) = COS( rad*gphif(ji,jj) ) * SIN( rad*glamf(ji,jj) )
718                  zzc(icoast) = SIN( rad*gphif(ji,jj) )
719               ENDIF
720               IF( llcotu(ji,jj) ) THEN
721                  icoast = icoast+1
722                  zxc(icoast) = COS( rad*gphiu(ji,jj) ) * COS( rad*glamu(ji,jj) )
723                  zyc(icoast) = COS( rad*gphiu(ji,jj) ) * SIN( rad*glamu(ji,jj) )
724                  zzc(icoast) = SIN( rad*gphiu(ji,jj) )
725               ENDIF
726               IF( llcotv(ji,jj) ) THEN
727                  icoast = icoast+1
728                  zxc(icoast) = COS( rad*gphiv(ji,jj) ) * COS( rad*glamv(ji,jj) )
729                  zyc(icoast) = COS( rad*gphiv(ji,jj) ) * SIN( rad*glamv(ji,jj) )
730                  zzc(icoast) = SIN( rad*gphiv(ji,jj) )
731               ENDIF
732            END DO
733         END DO
734
735         ! Distance for the T-points
736
737         DO jj = 1, jpj
738            DO ji = 1, jpi
739               IF( tmask(ji,jj,jk) == 0. ) THEN
740                  pdct(ji,jj,jk) = 0.
741               ELSE
742                  DO jl = 1, icoast
743                     zdis(jl) = ( zxt(ji,jj) - zxc(jl) )**2   &
744                        &     + ( zyt(ji,jj) - zyc(jl) )**2   &
745                        &     + ( zzt(ji,jj) - zzc(jl) )**2
746                  END DO
747                  pdct(ji,jj,jk) = ra * SQRT( MINVAL( zdis(1:icoast) ) )
748               ENDIF
749            END DO
750         END DO
751         !                                                ! ===============
752      END DO                                              !   End of slab
753      !                                                   ! ===============
754
755
756      ! 2. Create the  distance to the coast file in NetCDF format
757      ! ----------------------------------------------------------   
758      clname = 'dist.coast'
759      itime = 0
760      CALL ymds2ju( 0     , 1      , 1     , 0.e0 , zdate0 )
761      CALL restini( 'NONE', jpi    , jpj   , glamt, gphit ,   &
762         &          jpk   , gdept_0, clname, itime, zdate0,   &
763         &          rdt   , icot                         )
764      CALL restput( icot, 'Tcoast', jpi, jpj, jpk, 0, pdct )
765      CALL restclo( icot )
766
767   END SUBROUTINE cofdis
768
769#else
770   !!----------------------------------------------------------------------
771   !!   Default key                                     NO internal damping
772   !!----------------------------------------------------------------------
773   LOGICAL , PUBLIC, PARAMETER ::   lk_tradmp = .FALSE.    !: internal damping flag
774CONTAINS
775   SUBROUTINE tra_dmp( kt )        ! Empty routine
776      WRITE(*,*) 'tra_dmp: You should not have seen this print! error?', kt
777   END SUBROUTINE tra_dmp
778#endif
779
780   !!======================================================================
781END MODULE tradmp
Note: See TracBrowser for help on using the repository browser.