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.
zdfphy.F90 in branches/2017/wrk_OMP_test_for_Silvia/NEMOGCM/NEMO/OPA_SRC/ZDF – NEMO

source: branches/2017/wrk_OMP_test_for_Silvia/NEMOGCM/NEMO/OPA_SRC/ZDF/zdfphy.F90 @ 8055

Last change on this file since 8055 was 8055, checked in by gm, 7 years ago

wrk_OMP: 2nd step: add OMP processor distribution in ZDF package

  • Property svn:keywords set to Id
File size: 16.7 KB
Line 
1MODULE zdfphy
2   !!======================================================================
3   !!                      ***  MODULE  zdfphy  ***
4   !! Vertical ocean physics :   manager of all vertical physics packages
5   !!======================================================================
6   !! History :  4.0  !  2017-04  (G. Madec)  original code
7   !!----------------------------------------------------------------------
8
9   !!----------------------------------------------------------------------
10   !!   zdf_phy_init  : initialization of all vertical physics packages
11   !!   zdf_phy       : upadate at each time-step the vertical mixing coeff.
12   !!----------------------------------------------------------------------
13   USE oce            ! ocean dynamics and tracers variables
14   USE zdf_oce        ! vertical physics: shared variables         
15   USE zdfbfr         ! vertical physics: bottom friction
16   USE zdfsh2         ! vertical physics: shear production term of TKE
17   USE zdfric         ! vertical physics: RIChardson dependent vertical mixing   
18   USE zdftke         ! vertical physics: TKE vertical mixing
19   USE zdfgls         ! vertical physics: GLS vertical mixing
20   USE zdfddm         ! vertical physics: double diffusion mixing     
21   USE zdfevd         ! vertical physics: convection via enhanced vertical diffusion 
22   USE zdfiwm         ! vertical physics: internal wave-induced mixing 
23   USE zdfswm         ! vertical physics: surface  wave-induced mixing
24   USE zdfmxl         ! vertical physics: mixed layer
25   USE tranpc         ! convection: non penetrative adjustment
26   USE trc_oce        ! variables shared between passive tracer & ocean           
27   USE sbc_oce        ! surface module (only for nn_isf in the option compatibility test)
28   USE sbcrnf         ! surface boundary condition: runoff variables
29   !
30   USE in_out_manager ! I/O manager
31   USE iom            ! IOM library
32   USE lbclnk         ! lateral boundary conditions
33   USE lib_mpp        ! distribued memory computing
34
35   IMPLICIT NONE
36   PRIVATE
37
38   PUBLIC   zdf_phy_init  ! called by nemogcm.F90
39   PUBLIC   zdf_phy       ! called by step.F90
40
41   INTEGER ::   nzdf_phy   ! type of vertical closure used
42   !                       ! associated indicators
43   INTEGER, PARAMETER ::   np_CST = 1   ! Constant Kz
44   INTEGER, PARAMETER ::   np_RIC = 2   ! Richardson number dependent Kz
45   INTEGER, PARAMETER ::   np_TKE = 3   ! Turbulente Kinetic Eenergy closure scheme for Kz
46   INTEGER, PARAMETER ::   np_GLS = 4   ! Generic Length Scale closure scheme for Kz
47
48   LOGICAL ::   l_zdfsh2   ! shear production term flag (=F for CST, =T otherwise (i.e. TKE, GLS, RIC))
49
50   !! * Substitutions
51#  include "domain_substitute.h90"   
52   !!----------------------------------------------------------------------
53   !! NEMO/OPA 4.0 , NEMO Consortium (2017)
54   !! $Id$
55   !! Software governed by the CeCILL licence     (NEMOGCM/NEMO_CeCILL.txt)
56   !!----------------------------------------------------------------------
57CONTAINS
58
59   SUBROUTINE zdf_phy_init
60      !!----------------------------------------------------------------------
61      !!                  ***  ROUTINE zdf_phy_init  ***
62      !!
63      !! ** Purpose :   initializations of the vertical ocean physics
64      !!
65      !! ** Method  :   Read namelist namzdf, control logicals
66      !!                set horizontal shape and vertical profile of background mixing coef.
67      !!----------------------------------------------------------------------
68      INTEGER ::   jk            ! dummy loop indices
69      INTEGER ::   ioptio, ios   ! local integers
70      !!
71      NAMELIST/namzdf/ ln_zdfcst, ln_zdfric, ln_zdftke, ln_zdfgls,   &     ! type of closure scheme
72         &             ln_zdfevd, nn_evdm, rn_evd ,                  &     ! convection : evd
73         &             ln_zdfnpc, nn_npc , nn_npcp,                  &     ! convection : npc
74         &             ln_zdfddm, rn_avts, rn_hsbfr,                 &     ! double diffusion
75         &             ln_zdfswm,                                    &     ! surface  wave-induced mixing
76         &             ln_zdfiwm,                                    &     ! internal  -      -      -
77         &             ln_zdfexp, nn_zdfexp,                         &     ! time-stepping
78         &             rn_avm0, rn_avt0, nn_avb, nn_havtb                  ! coefficients
79      !!----------------------------------------------------------------------
80      !
81      !                           !==  Namelist  ==!
82      REWIND( numnam_ref )              ! Namelist namzdf in reference namelist : Vertical mixing parameters
83      READ  ( numnam_ref, namzdf, IOSTAT = ios, ERR = 901)
84901   IF( ios /= 0 )   CALL ctl_nam ( ios , 'namzdf in reference namelist', lwp )
85      !
86      REWIND( numnam_cfg )              ! Namelist namzdf in reference namelist : Vertical mixing parameters
87      READ  ( numnam_cfg, namzdf, IOSTAT = ios, ERR = 902 )
88902   IF( ios /= 0 )   CALL ctl_nam ( ios , 'namzdf in configuration namelist', lwp )
89      IF(lwm)   WRITE ( numond, namzdf )
90      !
91      IF(lwp) THEN                      ! Parameter print
92         WRITE(numout,*)
93         WRITE(numout,*) 'zdf_phy_init: vertical physics'
94         WRITE(numout,*) '~~~~~~~~~~~~'
95         WRITE(numout,*) '   Namelist namzdf : set vertical mixing mixing parameters'
96         WRITE(numout,*) '      vertical closure scheme'
97         WRITE(numout,*) '         constant vertical mixing coefficient    ln_zdfcst = ', ln_zdfcst
98         WRITE(numout,*) '         Richardson number dependent closure     ln_zdfric = ', ln_zdfric
99         WRITE(numout,*) '         Turbulent Kinetic Energy closure (TKE)  ln_zdftke = ', ln_zdftke
100         WRITE(numout,*) '         Generic Length Scale closure (GLS)      ln_zdfgls = ', ln_zdfgls
101         WRITE(numout,*) '      convection: '
102         WRITE(numout,*) '         enhanced vertical diffusion             ln_zdfevd = ', ln_zdfevd
103         WRITE(numout,*) '            applied on momentum (=1/0)             nn_evdm = ', nn_evdm
104         WRITE(numout,*) '            vertical coefficient for evd           rn_evd  = ', rn_evd
105         WRITE(numout,*) '         non-penetrative convection (npc)        ln_zdfnpc = ', ln_zdfnpc
106         WRITE(numout,*) '            npc call  frequency                    nn_npc  = ', nn_npc
107         WRITE(numout,*) '            npc print frequency                    nn_npcp = ', nn_npcp
108         WRITE(numout,*) '      double diffusive mixing                    ln_zdfddm = ', ln_zdfddm
109         WRITE(numout,*) '         maximum avs for dd mixing                 rn_avts = ', rn_avts
110         WRITE(numout,*) '         heat/salt buoyancy flux ratio             rn_hsbfr= ', rn_hsbfr
111         WRITE(numout,*) '      gravity wave-induced mixing'
112         WRITE(numout,*) '         surface  wave (Qiao et al 2010)         ln_zdfswm = ', ln_zdfswm                                          ! surface wave induced mixing
113         WRITE(numout,*) '         internal wave (de Lavergne et al 2017)  ln_zdfiwm = ', ln_zdfiwm
114         WRITE(numout,*) '      time-steping scheme'
115         WRITE(numout,*) '         time splitting (T) / implicit (F)       ln_zdfexp = ', ln_zdfexp
116         WRITE(numout,*) '         number of sub-time step (ln_zdfexp=T)   nn_zdfexp = ', nn_zdfexp
117         WRITE(numout,*) '      coefficients : '
118         WRITE(numout,*) '         vertical eddy viscosity                 rn_avm0   = ', rn_avm0
119         WRITE(numout,*) '         vertical eddy diffusivity               rn_avt0   = ', rn_avt0
120         WRITE(numout,*) '         constant background or profile          nn_avb    = ', nn_avb
121         WRITE(numout,*) '         horizontal variation for avtb           nn_havtb  = ', nn_havtb
122      ENDIF
123
124      !                          !==  Background eddy viscosity and diffusivity  ==!
125      IF( nn_avb == 0 ) THEN             ! Define avmb, avtb from namelist parameter
126         avmb(:) = rn_avm0
127         avtb(:) = rn_avt0                     
128      ELSE                               ! Background profile of avt (fit a theoretical/observational profile (Krauss 1990)
129         avmb(:) = rn_avm0
130         avtb(:) = rn_avt0 + ( 3.e-4_wp - 2._wp * rn_avt0 ) * 1.e-4_wp * gdepw_1d(:)   ! m2/s
131         IF(ln_sco .AND. lwp)   CALL ctl_warn( 'avtb profile not valid in sco' )
132      ENDIF
133      !                                  ! 2D shape of the avtb
134      avtb_2d(:,:) = 1._wp                   ! uniform
135      !
136      IF( nn_havtb == 1 ) THEN               ! decrease avtb by a factor of ten in the equatorial band
137           !                                 !   -15S -5S : linear decrease from avt0 to avt0/10.
138           !                                 !   -5S  +5N : cst value avt0/10.
139           !                                 !    5N  15N : linear increase from avt0/10, to avt0
140           WHERE(-15. <= gphit .AND. gphit < -5 )   avtb_2d = (1.  - 0.09 * (gphit + 15.))
141           WHERE( -5. <= gphit .AND. gphit <  5 )   avtb_2d =  0.1
142           WHERE(  5. <= gphit .AND. gphit < 15 )   avtb_2d = (0.1 + 0.09 * (gphit -  5.))
143      ENDIF
144      !
145      DO jk = 1, jpk                      ! set turbulent closure Kz to the background value (avt_k, avm_k)
146         avt_k(:,:,jk) = avtb_2d(:,:) * avtb(jk) * wmask (:,:,jk)
147         avm_k(:,:,jk) =                avmb(jk) * wmask (:,:,jk)
148      END DO
149!!gm  to be tested only the 1st & last levels
150!      avt  (:,:, 1 ) = 0._wp   ;   avs(:,:, 1 ) = 0._wp   ;   avm  (:,:, 1 ) = 0._wp
151!      avt  (:,:,jpk) = 0._wp   ;   avs(:,:,jpk) = 0._wp   ;   avm  (:,:,jpk) = 0._wp
152!!gm
153      avt  (:,:,:) = 0._wp   ;   avs(:,:,:) = 0._wp   ;   avm  (:,:,:) = 0._wp
154
155      !                          !==  Convection  ==!
156      !
157      IF( ln_zdfnpc .AND. ln_zdfevd )   CALL ctl_stop( 'zdf_phy_init: chose between ln_zdfnpc and ln_zdfevd' )
158      IF( lk_top    .AND. ln_zdfnpc )   CALL ctl_stop( 'zdf_phy_init: npc scheme is not working with key_top' )
159      IF(lwp) THEN
160         WRITE(numout,*)
161         IF    ( ln_zdfnpc ) THEN  ;   WRITE(numout,*) '      convection: use non penetrative convective scheme'
162         ELSEIF( ln_zdfevd ) THEN  ;   WRITE(numout,*) '      convection: use enhanced vertical diffusion scheme'
163         ELSE                      ;   WRITE(numout,*) '      convection: no specific scheme used'
164         ENDIF
165      ENDIF
166
167      IF(lwp) THEN               !==  Double Diffusion Mixing parameterization  ==!   (ddm)
168         WRITE(numout,*)
169         IF( ln_zdfddm ) THEN   ;   WRITE(numout,*) '      use double diffusive mixing: avs /= avt'
170         ELSE                   ;   WRITE(numout,*) '      No  double diffusive mixing: avs = avt'
171         ENDIF
172      ENDIF
173
174      !                          !==  type of vertical turbulent closure  ==!    (set nzdf_phy)
175      ioptio = 0 
176      IF( ln_zdfcst ) THEN   ;   ioptio = ioptio + 1   ;    nzdf_phy = np_CST   ;   ENDIF
177      IF( ln_zdfric ) THEN   ;   ioptio = ioptio + 1   ;    nzdf_phy = np_RIC   ;   CALL zdf_ric_init   ;   ENDIF
178      IF( ln_zdftke ) THEN   ;   ioptio = ioptio + 1   ;    nzdf_phy = np_TKE   ;   CALL zdf_tke_init   ;   ENDIF
179      IF( ln_zdfgls ) THEN   ;   ioptio = ioptio + 1   ;    nzdf_phy = np_GLS   ;   CALL zdf_gls_init   ;   ENDIF
180      !
181      IF( ioptio /= 1 )    CALL ctl_stop( 'zdf_phy_init: one and only one vertical diffusion option has to be defined ' )
182      IF( ln_isfcav ) THEN
183      IF( ln_zdfric .OR. ln_zdfgls )    CALL ctl_stop( 'zdf_phy_init: zdfric and zdfgls never tested with ice shelves cavities ' )
184      ENDIF
185      !                                ! shear production term flag
186      IF( ln_zdfcst ) THEN   ;   l_zdfsh2 = .FALSE.
187      ELSE                   ;   l_zdfsh2 = .TRUE.
188      ENDIF
189
190      !                          !== gravity wave-driven mixing  ==!
191      IF( ln_zdfiwm )   CALL zdf_iwm_init       ! internal wave-driven mixing
192      IF( ln_zdfswm )   CALL zdf_swm_init       ! surface  wave-driven mixing
193
194      !                          !== bottom friction  ==!
195      CALL zdf_bfr_init
196      !
197      !                          !== time-stepping  ==!
198      ! Check/update of time stepping done in dynzdf_init/trazdf_init
199      !!gm move it here ?
200      !
201   END SUBROUTINE zdf_phy_init
202
203
204   SUBROUTINE zdf_phy( kt )
205      !!----------------------------------------------------------------------
206      !!                     ***  ROUTINE zdf_phy  ***
207      !!
208      !! ** Purpose :  Update ocean physics at each time-step
209      !!
210      !! ** Method  :
211      !!
212      !! ** Action  :   avm, avt vertical eddy viscosity and diffusivity at w-points
213      !!                nmld ??? mixed layer depth in level and meters   <<<<====verifier !
214      !!                bottom stress.....                               <<<<====verifier !
215      !!----------------------------------------------------------------------
216      INTEGER, INTENT(in) ::   kt   ! ocean time-step index
217      !
218      INTEGER ::   ji, jj, jk   ! dummy loop indice
219!!OMP      REAL(wp), DIMENSION(WRK_3D) ::   zsh2   ! shear production
220      REAL(wp), ALLOCATABLE, DIMENSION(:,:,:) ::   zsh2   ! shear production
221      !! ---------------------------------------------------------------------
222      !     
223!!OMP ===>>>>   Open-MP   to be defined elsewhere   
224      !
225      INTEGER ::   ARG_2D
226      !
227#if defined key_vectopt_loop
228      k_Istr = 1   ;   k_Iend = jpi
229#else
230      k_Istr = 2   ;   k_Iend = jpim1
231#endif
232      k_Jstr = 2   ;   k_Jend = jpjm1
233      !
234!!OMP <<<<===   end
235     
236      ALLOCATE( zsh2(WRK_3D) )
237     
238     
239      !
240      CALL zdf_bfr( kt )                        !* bottom friction (if quadratic)
241      !
242
243      !                          !==  Kz from chosen turbulent closure  ==!   (avm_k, avt_k)
244     
245      IF( l_zdfsh2 )   &                        !* shear production at w-points (energy conserving form)
246         CALL zdf_sh2( ARG_2D, ub, vb, un, vn, avm_k,   &   ! <<== in  fields
247            &                                   zsh2    )   ! ==>> out field  : shear production
248
249      !
250      SELECT CASE ( nzdf_phy )                  !* Vertical eddy viscosity and diffusivity coefficients at w-points
251      CASE( np_RIC )   ;   CALL zdf_ric( ARG_2D, kt, gdept_n, zsh2, avm_k, avt_k )         ! Richardson number dependent Kz
252      CASE( np_TKE )   ;   CALL zdf_tke( ARG_2D, kt         , zsh2, avm_k, avt_k )         ! TKE closure scheme for Kz
253      CASE( np_GLS )   ;   CALL zdf_gls( ARG_2D, kt         , zsh2, avm_k, avt_k )         ! GLS closure scheme for Kz
254      CASE( np_CST )                                  ! Constant Kz (reset avt, avm to the background value)
255         ! avt_k and avm_k set one for all at initialisation phase
256!!gm         avt_k(WRK_3D) = rn_avt0 * wmask(WRK_3D)
257!!gm         avm_k(WRK_3D) = rn_avm0 * wmask(WRK_3D)
258      END SELECT
259     
260      !                          !==  ocean Kz  ==!   (avt, avs, avm)
261      !
262      !                                         !* start from turbulent closure values
263      avt(WRK_2D,2:jpkm1) = avt_k(WRK_2D,2:jpkm1)
264      avm(WRK_2D,2:jpkm1) = avm_k(WRK_2D,2:jpkm1)
265      !
266      IF( ln_rnf_mouth ) THEN                   !* increase diffusivity at rivers mouths
267         DO jk = 2, nkrnf
268            avt(WRK_2D,jk) = avt(WRK_2D,jk) + 2._wp * rn_avt_rnf * rnfmsk(WRK_2D) * wmask(WRK_2D,jk)
269         END DO
270      ENDIF
271      !
272      IF( ln_zdfevd )   CALL zdf_evd( ARG_2D, kt, avm, avt )      !* convection: enhanced vertical eddy diffusivity
273      !
274      !                                         !* double diffusive mixing
275      IF( ln_zdfddm ) THEN                            ! update avt and compute avs
276                        CALL zdf_ddm( ARG_2D, kt, avm, avt, avs )
277      ELSE                                            ! same mixing on all tracers
278         avs(WRK_3D) = avt(WRK_3D)
279      ENDIF
280      !
281      !                                         !* wave-induced mixing
282      IF( ln_zdfswm )   CALL zdf_swm( ARG_2D, kt, avm, avt, avs )   ! surface  wave (Qiao et al. 2004)
283      IF( ln_zdfiwm )   CALL zdf_iwm( ARG_2D, kt, avm, avt, avs )   ! internal wave (de Lavergne et al 2017)
284
285
286      !                                         !* Lateral boundary conditions (sign unchanged)
287      CALL lbc_lnk( avm_k, 'W', 1. )
288      CALL lbc_lnk( avt_k, 'W', 1. )
289      CALL lbc_lnk( avm  , 'W', 1. )
290      CALL lbc_lnk( avt  , 'W', 1. )                  !!gm  a priori only avm_k and avm are required
291      CALL lbc_lnk( avs  , 'W', 1. )                  !!gm  To be tested
292      !
293
294      CALL zdf_mxl( kt )                        !* mixed layer depth, and level
295
296
297      IF( lrst_oce ) THEN                       !* write TKE, GLS or RIC fields in the restart file
298         IF( ln_zdftke )   CALL tke_rst( kt, 'WRITE' )
299         IF( ln_zdfgls )   CALL gls_rst( kt, 'WRITE' )
300         IF( ln_zdfric )   CALL ric_rst( kt, 'WRITE' ) 
301      ENDIF
302      !
303      DEALLOCATE( zsh2 )
304      !
305   END SUBROUTINE zdf_phy
306
307   !!======================================================================
308END MODULE zdfphy
Note: See TracBrowser for help on using the repository browser.