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 @ 503

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

nemo_v1_update_064 : CT : general trends update including the addition of mean windows analysis possibility in the mixed layer

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