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/2014/dev_r4650_UKMO3_masked_damping/NEMOGCM/NEMO/OPA_SRC/TRA – NEMO

source: branches/2014/dev_r4650_UKMO3_masked_damping/NEMOGCM/NEMO/OPA_SRC/TRA/tradmp.F90 @ 4738

Last change on this file since 4738 was 4738, checked in by timgraham, 10 years ago

Modified tra_dmp module to read in restoration coefficient from a netcdf file

Added a tool to create the netcdf file - this replaces all of the hard coded resolution dependencies in tra_dmp_init

  • Property svn:keywords set to Id
File size: 11.7 KB
Line 
1MODULE tradmp
2   !!======================================================================
3   !!                       ***  MODULE  tradmp  ***
4   !! Ocean physics: internal restoring trend on active tracers (T and S)
5   !!======================================================================
6   !! History :  OPA  ! 1991-03  (O. Marti, G. Madec)  Original code
7   !!                 ! 1992-06  (M. Imbard)  doctor norme
8   !!                 ! 1996-01  (G. Madec)  statement function for e3
9   !!                 ! 1997-05  (G. Madec)  macro-tasked on jk-slab
10   !!                 ! 1998-07  (M. Imbard, G. Madec) ORCA version
11   !!            7.0  ! 2001-02  (M. Imbard)  cofdis, Original code
12   !!            8.1  ! 2001-02  (G. Madec, E. Durand)  cleaning
13   !!  NEMO      1.0  ! 2002-08  (G. Madec, E. Durand)  free form + modules
14   !!            3.2  ! 2009-08  (G. Madec, C. Talandier)  DOCTOR norm for namelist parameter
15   !!            3.3  ! 2010-06  (C. Ethe, G. Madec) merge TRA-TRC
16   !!            3.4  ! 2011-04  (G. Madec, C. Ethe) Merge of dtatem and dtasal + suppression of CPP keys
17   !!----------------------------------------------------------------------
18
19   !!----------------------------------------------------------------------
20   !!   tra_dmp_alloc : allocate tradmp arrays
21   !!   tra_dmp       : update the tracer trend with the internal damping
22   !!   tra_dmp_init  : initialization, namlist read, parameters control
23   !!----------------------------------------------------------------------
24   USE oce            ! ocean: variables
25   USE dom_oce        ! ocean: domain variables
26   USE c1d            ! 1D vertical configuration
27   USE trdmod_oce     ! ocean: trend variables
28   USE trdtra         ! active tracers: trends
29   USE zdf_oce        ! ocean: vertical physics
30   USE phycst         ! physical constants
31   USE dtatsd         ! data: temperature & salinity
32   USE zdfmxl         ! vertical physics: mixed layer depth
33   USE in_out_manager ! I/O manager
34   USE lib_mpp        ! MPP library
35   USE prtctl         ! Print control
36   USE wrk_nemo       ! Memory allocation
37   USE timing         ! Timing
38
39   IMPLICIT NONE
40   PRIVATE
41
42   PUBLIC   tra_dmp      ! routine called by step.F90
43   PUBLIC   tra_dmp_init ! routine called by opa.F90
44
45   !                               !!* Namelist namtra_dmp : T & S newtonian damping *
46   LOGICAL , PUBLIC ::   ln_tradmp   !: internal damping flag
47   INTEGER , PUBLIC ::   nn_zdmp     ! = 0/1/2 flag for damping in the mixed layer
48   CHARACTER(LEN=200) :: cn_resto      ! name of netcdf file containing restoration coefficient field
49   LOGICAL , PUBLIC ::   ln_miss      ! check for missing data in T/S data file (slow?)
50   REAL(wp), PUBLIC ::   rn_miss      ! Value of missing data
51
52
53   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) ::   strdmp   !: damping salinity trend (psu/s)
54   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) ::   ttrdmp   !: damping temperature trend (Celcius/s)
55   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) ::   resto    !: restoring coeff. on T and S (s-1)
56
57   !! * Substitutions
58#  include "domzgr_substitute.h90"
59#  include "vectopt_loop_substitute.h90"
60   !!----------------------------------------------------------------------
61   !! NEMO/OPA 3.3 , NEMO Consortium (2010)
62   !! $Id$
63   !! Software governed by the CeCILL licence     (NEMOGCM/NEMO_CeCILL.txt)
64   !!----------------------------------------------------------------------
65CONTAINS
66
67   INTEGER FUNCTION tra_dmp_alloc()
68      !!----------------------------------------------------------------------
69      !!                ***  FUNCTION tra_dmp_alloc  ***
70      !!----------------------------------------------------------------------
71      ALLOCATE( strdmp(jpi,jpj,jpk) , ttrdmp(jpi,jpj,jpk), resto(jpi,jpj,jpk), STAT= tra_dmp_alloc )
72      !
73      IF( lk_mpp            )   CALL mpp_sum ( tra_dmp_alloc )
74      IF( tra_dmp_alloc > 0 )   CALL ctl_warn('tra_dmp_alloc: allocation of arrays failed')
75      !
76   END FUNCTION tra_dmp_alloc
77
78
79   SUBROUTINE tra_dmp( kt )
80      !!----------------------------------------------------------------------
81      !!                   ***  ROUTINE tra_dmp  ***
82      !!                 
83      !! ** Purpose :   Compute the tracer trend due to a newtonian damping
84      !!      of the tracer field towards given data field and add it to the
85      !!      general tracer trends.
86      !!
87      !! ** Method  :   Newtonian damping towards t_dta and s_dta computed
88      !!      and add to the general tracer trends:
89      !!                     ta = ta + resto * (t_dta - tb)
90      !!                     sa = sa + resto * (s_dta - sb)
91      !!         The trend is computed either throughout the water column
92      !!      (nlmdmp=0) or in area of weak vertical mixing (nlmdmp=1) or
93      !!      below the well mixed layer (nlmdmp=2)
94      !!
95      !! ** Action  : - (ta,sa)   tracer trends updated with the damping trend
96      !!----------------------------------------------------------------------
97      !
98      INTEGER, INTENT(in) ::   kt   ! ocean time-step index
99      !!
100      INTEGER  ::   ji, jj, jk   ! dummy loop indices
101      REAL(wp) ::   zta, zsa             ! local scalars
102      REAL(wp), POINTER, DIMENSION(:,:,:,:) ::  zts_dta 
103      !!----------------------------------------------------------------------
104      !
105      IF( nn_timing == 1 )  CALL timing_start( 'tra_dmp')
106      !
107      CALL wrk_alloc( jpi, jpj, jpk, jpts,  zts_dta )
108      !                           !==   input T-S data at kt   ==!
109      CALL dta_tsd( kt, zts_dta )            ! read and interpolates T-S data at kt
110      !
111      SELECT CASE ( nn_zdmp )     !==    type of damping   ==!
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) * ( zts_dta(ji,jj,jk,jp_tem) - tsb(ji,jj,jk,jp_tem) )
118                  zsa = resto(ji,jj,jk) * ( zts_dta(ji,jj,jk,jp_sal) - tsb(ji,jj,jk,jp_sal) )
119                  tsa(ji,jj,jk,jp_tem) = tsa(ji,jj,jk,jp_tem) + zta
120                  tsa(ji,jj,jk,jp_sal) = tsa(ji,jj,jk,jp_sal) + zsa
121                  strdmp(ji,jj,jk) = zsa           ! save the trend (used in asmtrj)
122                  ttrdmp(ji,jj,jk) = zta     
123               END DO
124            END DO
125         END DO
126         !
127      CASE ( 1 )                  !==  no damping in the turbocline (avt > 5 cm2/s)  ==!
128         DO jk = 1, jpkm1
129            DO jj = 2, jpjm1
130               DO ji = fs_2, fs_jpim1   ! vector opt.
131                  IF( avt(ji,jj,jk) <= 5.e-4_wp ) THEN
132                     zta = resto(ji,jj,jk) * ( zts_dta(ji,jj,jk,jp_tem) - tsb(ji,jj,jk,jp_tem) )
133                     zsa = resto(ji,jj,jk) * ( zts_dta(ji,jj,jk,jp_sal) - tsb(ji,jj,jk,jp_sal) )
134                  ELSE
135                     zta = 0._wp
136                     zsa = 0._wp 
137                  ENDIF
138                  tsa(ji,jj,jk,jp_tem) = tsa(ji,jj,jk,jp_tem) + zta
139                  tsa(ji,jj,jk,jp_sal) = tsa(ji,jj,jk,jp_sal) + zsa
140                  strdmp(ji,jj,jk) = zsa           ! save the salinity trend (used in asmtrj)
141                  ttrdmp(ji,jj,jk) = zta
142               END DO
143            END DO
144         END DO
145         !
146      CASE ( 2 )                  !==  no damping in the mixed layer   ==!
147         DO jk = 1, jpkm1
148            DO jj = 2, jpjm1
149               DO ji = fs_2, fs_jpim1   ! vector opt.
150                  IF( fsdept(ji,jj,jk) >= hmlp (ji,jj) ) THEN
151                     zta = resto(ji,jj,jk) * ( zts_dta(ji,jj,jk,jp_tem) - tsb(ji,jj,jk,jp_tem) )
152                     zsa = resto(ji,jj,jk) * ( zts_dta(ji,jj,jk,jp_sal) - tsb(ji,jj,jk,jp_sal) )
153                  ELSE
154                     zta = 0._wp
155                     zsa = 0._wp 
156                  ENDIF
157                  tsa(ji,jj,jk,jp_tem) = tsa(ji,jj,jk,jp_tem) + zta
158                  tsa(ji,jj,jk,jp_sal) = tsa(ji,jj,jk,jp_sal) + zsa
159                  strdmp(ji,jj,jk) = zsa           ! save the salinity trend (used in asmtrj)
160                  ttrdmp(ji,jj,jk) = zta
161               END DO
162            END DO
163         END DO
164         !
165      END SELECT
166      !
167      IF( l_trdtra )   THEN       ! trend diagnostic
168         CALL trd_tra( kt, 'TRA', jp_tem, jptra_trd_dmp, ttrdmp )
169         CALL trd_tra( kt, 'TRA', jp_sal, jptra_trd_dmp, strdmp )
170      ENDIF
171      !                           ! Control print
172      IF(ln_ctl)   CALL prt_ctl( tab3d_1=tsa(:,:,:,jp_tem), clinfo1=' dmp  - Ta: ', mask1=tmask,   &
173         &                       tab3d_2=tsa(:,:,:,jp_sal), clinfo2=       ' Sa: ', mask2=tmask, clinfo3='tra' )
174      !
175      CALL wrk_dealloc( jpi, jpj, jpk, jpts,  zts_dta )
176      !
177      IF( nn_timing == 1 )  CALL timing_stop( 'tra_dmp')
178      !
179   END SUBROUTINE tra_dmp
180
181
182   SUBROUTINE tra_dmp_init
183      !!----------------------------------------------------------------------
184      !!                  ***  ROUTINE tra_dmp_init  ***
185      !!
186      !! ** Purpose :   Initialization for the newtonian damping
187      !!
188      !! ** Method  :   read the namtra_dmp namelist and check the parameters
189      !!----------------------------------------------------------------------
190
191      NAMELIST/namtra_dmp/ ln_tradmp, rn_dmp, nn_zdmp, cn_resto
192      INTEGER ::  ios         ! Local integer for output status of namelist read
193      REAL(wp), POINTER, DIMENSION(:,:,:) ::  dmp_mask   ! 3D mask
194      !!----------------------------------------------------------------------
195
196      REWIND( numnam_ref )   ! Namelist namtra_dmp in reference namelist : T & S relaxation
197      READ  ( numnam_ref, namtra_dmp, IOSTAT = ios, ERR = 901)
198901   IF( ios /= 0 ) CALL ctl_nam ( ios , 'namtra_dmp in reference namelist', lwp )
199
200      REWIND( numnam_cfg )   ! Namelist namtra_dmp in configuration namelist : T & S relaxation
201      READ  ( numnam_cfg, namtra_dmp, IOSTAT = ios, ERR = 902 )
202902   IF( ios /= 0 ) CALL ctl_nam ( ios , 'namtra_dmp in configuration namelist', lwp )
203      IF(lwm) WRITE ( numond, namtra_dmp )
204
205      IF(lwp) THEN                 !Namelist print
206         WRITE(numout,*)
207         WRITE(numout,*) 'tra_dmp_init : T and S newtonian relaxation'
208         WRITE(numout,*) '~~~~~~~'
209         WRITE(numout,*) '   Namelist namtra_dmp : set relaxation parameters'
210         WRITE(numout,*) '      Apply relaxation   or not       ln_tradmp = ', ln_tradmp
211         WRITE(numout,*) '      mixed layer damping option      nn_zdmp   = ', nn_zdmp
212         WRITE(numout,*) '      Damping file name               cn_resto  = ', cn_resto
213         WRITE(numout,*)
214      ENDIF
215
216      IF( ln_tradmp) THEN
217         !
218         !Allocate arrays
219         IF( tra_dmp_alloc() /= 0 )   CALL ctl_stop( 'STOP', 'tra_dmp_init: unable to allocate arrays' )
220
221         !Check values of nn_zdmp
222         SELECT CASE (nn_zdmp)
223         CASE ( 0 )  ; IF(lwp) WRITE(numout,*) '   tracer damping as specified by mask'
224         CASE ( 1 )  ; IF(lwp) WRITE(numout,*) '   no tracer damping in the turbocline'
225         CASE ( 2 )  ; IF(lwp) WRITE(numout,*) '   no tracer damping in the mixed layer'
226
227         !Initialisation of dtatsd - Would it be better to have dmpdta routine
228         !so can damp to something other than intitial conditions files?
229         IF( .NOT.ln_tsd_tradmp ) THEN
230            CALL ctl_warn( 'tra_dmp_init: read T-S data not initialized, we force ln_tsd_tradmp=T' )
231            CALL dta_tsd_init( ld_tradmp=ln_tradmp )        ! forces the initialisation of T-S data
232         ENDIF
233
234         !initialise arrays - Are these actually used anywhere else?
235         strdmp(:,:,:) = 0._wp
236         ttrdmp(:,:,:) = 0._wp
237
238         !Read in mask from file
239         CALL iom_open ( cn_resto, imask)
240         CALL iom_get  ( imask, jpdom_autoglo, 'resto', resto)
241         CALL iom_close( imask )
242       ENDIF
243
244   END SUBROUTINE tra_dmp_init
245
246END MODULE tradmp
Note: See TracBrowser for help on using the repository browser.