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 trunk/NEMO/OPA_SRC/TRA – NEMO

source: trunk/NEMO/OPA_SRC/TRA/tradmp.F90 @ 467

Last change on this file since 467 was 457, checked in by opalod, 18 years ago

nemo_v1_update_049:RB: reorganization of tracers part, remove traadv_cen2_atsk.h90 traldf_iso_zps.F90 trazdf_iso.F90 trazdf_iso_vopt.F90, change atsk routines to jki

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