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.
traldf.F90 in trunk/NEMOGCM/NEMO/OPA_SRC/TRA – NEMO

source: trunk/NEMOGCM/NEMO/OPA_SRC/TRA/traldf.F90 @ 7698

Last change on this file since 7698 was 7698, checked in by mocavero, 7 years ago

update trunk with OpenMP parallelization

  • Property svn:keywords set to Id
File size: 12.0 KB
RevLine 
[458]1MODULE traldf
2   !!======================================================================
3   !!                       ***  MODULE  traldf  ***
4   !! Ocean Active tracers : lateral diffusive trends
5   !!=====================================================================
[5836]6   !! History :  9.0  ! 2005-11  (G. Madec)  Original code
7   !!  NEMO      3.0  ! 2008-01  (C. Ethe, G. Madec)  merge TRC-TRA
8   !!            3.7  ! 2013-12  (G. Madec) remove the optional computation from T & S anomaly profiles and traldf_bilapg
9   !!             -   ! 2013-12  (F. Lemarie, G. Madec)  triad operator (Griffies) + Method of Stabilizing Correction
10   !!             -   ! 2014-01  (G. Madec, S. Masson)  restructuration/simplification of lateral diffusive operators
[458]11   !!----------------------------------------------------------------------
[503]12
13   !!----------------------------------------------------------------------
[6140]14   !!   tra_ldf       : update the tracer trend with the lateral diffusion trend
15   !!   tra_ldf_init  : initialization, namelist read, and parameters control
[458]16   !!----------------------------------------------------------------------
[6140]17   USE oce            ! ocean dynamics and tracers
18   USE dom_oce        ! ocean space and time domain
19   USE phycst         ! physical constants
20   USE ldftra         ! lateral diffusion: eddy diffusivity & EIV coeff.
21   USE ldfslp         ! lateral diffusion: iso-neutral slope
22   USE traldf_lap_blp ! lateral diffusion: laplacian iso-level            operator  (tra_ldf_lap/_blp   routines)
23   USE traldf_iso     ! lateral diffusion: laplacian iso-neutral standard operator  (tra_ldf_iso        routine )
24   USE traldf_triad   ! lateral diffusion: laplacian iso-neutral triad    operator  (tra_ldf_triad      routine )
25   USE trd_oce        ! trends: ocean variables
26   USE trdtra         ! ocean active tracers trends
[4990]27   !
[5836]28   USE prtctl         ! Print control
29   USE in_out_manager ! I/O manager
30   USE lib_mpp        ! distribued memory computing library
31   USE lbclnk         ! ocean lateral boundary conditions (or mpp link)
32   USE wrk_nemo       ! Memory allocation
33   USE timing         ! Timing
[458]34
35   IMPLICIT NONE
36   PRIVATE
37
[4990]38   PUBLIC   tra_ldf        ! called by step.F90
[5836]39   PUBLIC   tra_ldf_init   ! called by nemogcm.F90
[2528]40   !
[5836]41   INTEGER ::   nldf = 0   ! type of lateral diffusion used defined from ln_traldf_... (namlist logicals)
42   
[458]43   !! * Substitutions
44#  include "vectopt_loop_substitute.h90"
[503]45   !!----------------------------------------------------------------------
[5836]46   !! NEMO/OPA 3.7 , NEMO Consortium (2015)
[1152]47   !! $Id$
[2528]48   !! Software governed by the CeCILL licence     (NEMOGCM/NEMO_CeCILL.txt)
[503]49   !!----------------------------------------------------------------------
[458]50CONTAINS
51
52   SUBROUTINE tra_ldf( kt )
53      !!----------------------------------------------------------------------
54      !!                  ***  ROUTINE tra_ldf  ***
55      !!
56      !! ** Purpose :   compute the lateral ocean tracer physics.
57      !!----------------------------------------------------------------------
[503]58      INTEGER, INTENT( in ) ::   kt   ! ocean time-step index
[7698]59      INTEGER ::   jk, jj, ji         ! dummy loop indices
[503]60      !!
[3294]61      REAL(wp), POINTER, DIMENSION(:,:,:) ::  ztrdt, ztrds
[458]62      !!----------------------------------------------------------------------
[3294]63      !
[5836]64      IF( nn_timing == 1 )   CALL timing_start('tra_ldf')
[3294]65      !
[2528]66      IF( l_trdtra )   THEN                    !* Save ta and sa trends
[5836]67         CALL wrk_alloc( jpi,jpj,jpk,   ztrdt, ztrds ) 
[7698]68!$OMP PARALLEL DO schedule(static) private(jk,jj,ji)
69         DO jk = 1, jpk
70            DO jj = 1, jpj
71               DO ji = 1, jpi
72                  ztrdt(ji,jj,jk) = tsa(ji,jj,jk,jp_tem)
73                  ztrds(ji,jj,jk) = tsa(ji,jj,jk,jp_sal)
74               END DO
75            END DO
76         END DO
[458]77      ENDIF
[5836]78      !
79      SELECT CASE ( nldf )                     !* compute lateral mixing trend and add it to the general trend
80      CASE ( np_lap   )                                  ! laplacian: iso-level operator
81         CALL tra_ldf_lap  ( kt, nit000,'TRA', ahtu, ahtv, gtsu, gtsv, gtui, gtvi, tsb,      tsa, jpts,  1   )
82      CASE ( np_lap_i )                                  ! laplacian: standard iso-neutral operator (Madec)
83         CALL tra_ldf_iso  ( kt, nit000,'TRA', ahtu, ahtv, gtsu, gtsv, gtui, gtvi, tsb, tsb, tsa, jpts,  1   )
84      CASE ( np_lap_it )                                 ! laplacian: triad iso-neutral operator (griffies)
85         CALL tra_ldf_triad( kt, nit000,'TRA', ahtu, ahtv, gtsu, gtsv, gtui, gtvi, tsb, tsb, tsa, jpts,  1   )
86      CASE ( np_blp , np_blp_i , np_blp_it )             ! bilaplacian: iso-level & iso-neutral operators
87         CALL tra_ldf_blp  ( kt, nit000,'TRA', ahtu, ahtv, gtsu, gtsv, gtui, gtvi, tsb      , tsa, jpts, nldf )
[458]88      END SELECT
[6140]89      !
[5836]90      IF( l_trdtra )   THEN                    !* save the horizontal diffusive trends for further diagnostics
[7698]91!$OMP PARALLEL DO schedule(static) private(jk,jj,ji)
92         DO jk = 1, jpk
93            DO jj = 1, jpj
94               DO ji = 1, jpi
95                  ztrdt(ji,jj,jk) = tsa(ji,jj,jk,jp_tem) - ztrdt(ji,jj,jk)
96                  ztrds(ji,jj,jk) = tsa(ji,jj,jk,jp_sal) - ztrds(ji,jj,jk)
97               END DO
98            END DO
99         END DO
[4990]100         CALL trd_tra( kt, 'TRA', jp_tem, jptra_ldf, ztrdt )
101         CALL trd_tra( kt, 'TRA', jp_sal, jptra_ldf, ztrds )
[5836]102         CALL wrk_dealloc( jpi,jpj,jpk,   ztrdt, ztrds ) 
[458]103      ENDIF
[5836]104      !                                        !* print mean trends (used for debugging)
[2528]105      IF(ln_ctl)   CALL prt_ctl( tab3d_1=tsa(:,:,:,jp_tem), clinfo1=' ldf  - Ta: ', mask1=tmask,               &
106         &                       tab3d_2=tsa(:,:,:,jp_sal), clinfo2=       ' Sa: ', mask2=tmask, clinfo3='tra' )
[503]107      !
[5836]108      IF( nn_timing == 1 )   CALL timing_stop('tra_ldf')
[3294]109      !
[458]110   END SUBROUTINE tra_ldf
111
112
[2528]113   SUBROUTINE tra_ldf_init
[458]114      !!----------------------------------------------------------------------
[2528]115      !!                  ***  ROUTINE tra_ldf_init  ***
[458]116      !!
117      !! ** Purpose :   Choice of the operator for the lateral tracer diffusion
118      !!
[1601]119      !! ** Method  :   set nldf from the namtra_ldf logicals
[458]120      !!----------------------------------------------------------------------
[5836]121      INTEGER ::   ioptio, ierr   ! temporary integers
[458]122      !!----------------------------------------------------------------------
[5836]123      !
124      IF(lwp) THEN                     ! Namelist print
[458]125         WRITE(numout,*)
[2528]126         WRITE(numout,*) 'tra_ldf_init : lateral tracer diffusive operator'
[7646]127         WRITE(numout,*) '~~~~~~~~~~~~'
[6140]128         WRITE(numout,*) '   Namelist namtra_ldf: already read in ldftra module'
129         WRITE(numout,*) '      see ldf_tra_init report for lateral mixing parameters'
[458]130      ENDIF
[5836]131      !                                   ! use of lateral operator or not
132      nldf   = np_ERROR
[458]133      ioptio = 0
[5836]134      IF( ln_traldf_lap )   ioptio = ioptio + 1
135      IF( ln_traldf_blp )   ioptio = ioptio + 1
136      IF( ioptio >  1   )   CALL ctl_stop( 'tra_ldf_init: use ONE or NONE of the 2 lap/bilap operator type on tracer' )
137      IF( ioptio == 0   )   nldf = np_no_ldf     ! No lateral diffusion
138      !
139      IF( nldf /= np_no_ldf ) THEN        ! direction ==>> type of operator 
140         ioptio = 0
141         IF( ln_traldf_lev )   ioptio = ioptio + 1
142         IF( ln_traldf_hor )   ioptio = ioptio + 1
143         IF( ln_traldf_iso )   ioptio = ioptio + 1
144         IF( ioptio >  1 )   CALL ctl_stop( 'tra_ldf_init: use only ONE direction (level/hor/iso)' )
145         !
146         !                                ! defined the type of lateral diffusion from ln_traldf_... logicals
147         ierr = 0
148         IF( ln_traldf_lap ) THEN         ! laplacian operator
149            IF ( ln_zco ) THEN               ! z-coordinate
150               IF ( ln_traldf_lev   )   nldf = np_lap     ! iso-level = horizontal (no rotation)
151               IF ( ln_traldf_hor   )   nldf = np_lap     ! iso-level = horizontal (no rotation)
152               IF ( ln_traldf_iso   )   nldf = np_lap_i   ! iso-neutral: standard  (   rotation)
153               IF ( ln_traldf_triad )   nldf = np_lap_it  ! iso-neutral: triad     (   rotation)
154            ENDIF
155            IF ( ln_zps ) THEN               ! z-coordinate with partial step
156               IF ( ln_traldf_lev   )   ierr = 1          ! iso-level not allowed
157               IF ( ln_traldf_hor   )   nldf = np_lap     ! horizontal             (no rotation)
158               IF ( ln_traldf_iso   )   nldf = np_lap_i   ! iso-neutral: standard     (rotation)
159               IF ( ln_traldf_triad )   nldf = np_lap_it  ! iso-neutral: triad        (rotation)
160            ENDIF
161            IF ( ln_sco ) THEN               ! s-coordinate
162               IF ( ln_traldf_lev   )   nldf = np_lap     ! iso-level              (no rotation)
163               IF ( ln_traldf_hor   )   nldf = np_lap_i   ! horizontal             (   rotation)
164               IF ( ln_traldf_iso   )   nldf = np_lap_i   ! iso-neutral: standard  (   rotation)
165               IF ( ln_traldf_triad )   nldf = np_lap_it  ! iso-neutral: triad     (   rotation)
166            ENDIF
[458]167         ENDIF
[5836]168         !
169         IF( ln_traldf_blp ) THEN         ! bilaplacian operator
170            IF ( ln_zco ) THEN               ! z-coordinate
171               IF ( ln_traldf_lev   )   nldf = np_blp     ! iso-level = horizontal (no rotation)
172               IF ( ln_traldf_hor   )   nldf = np_blp     ! iso-level = horizontal (no rotation)
173               IF ( ln_traldf_iso   )   nldf = np_blp_i   ! iso-neutral: standard  (   rotation)
174               IF ( ln_traldf_triad )   nldf = np_blp_it  ! iso-neutral: triad     (   rotation)
175            ENDIF
176            IF ( ln_zps ) THEN               ! z-coordinate with partial step
177               IF ( ln_traldf_lev   )   ierr = 1          ! iso-level not allowed
178               IF ( ln_traldf_hor   )   nldf = np_blp     ! horizontal             (no rotation)
179               IF ( ln_traldf_iso   )   nldf = np_blp_i   ! iso-neutral: standard  (   rotation)
180               IF ( ln_traldf_triad )   nldf = np_blp_it  ! iso-neutral: triad     (   rotation)
181            ENDIF
182            IF ( ln_sco ) THEN               ! s-coordinate
183               IF ( ln_traldf_lev   )   nldf = np_blp     ! iso-level              (no rotation)
184               IF ( ln_traldf_hor   )   nldf = np_blp_it  ! horizontal             (   rotation)
185               IF ( ln_traldf_iso   )   nldf = np_blp_i   ! iso-neutral: standard  (   rotation)
186               IF ( ln_traldf_triad )   nldf = np_blp_it  ! iso-neutral: triad     (   rotation)
187            ENDIF
[458]188         ENDIF
189      ENDIF
[5836]190      !
[6140]191      IF( ierr == 1 )   CALL ctl_stop( 'iso-level in z-partial step, not allowed' )
[5836]192      IF( ln_ldfeiv .AND. .NOT.( ln_traldf_iso .OR. ln_traldf_triad ) )                                    &
[6140]193           &            CALL ctl_stop( 'eddy induced velocity on tracers requires iso-neutral laplacian diffusion' )
[6352]194      IF( ln_isfcav .AND. ln_traldf_triad ) &
195           &            CALL ctl_stop( ' ice shelf cavity and traldf_triad not tested' )
[6140]196           !
[5836]197      IF(  nldf == np_lap_i .OR. nldf == np_lap_it .OR. &
198         & nldf == np_blp_i .OR. nldf == np_blp_it  )   l_ldfslp = .TRUE.    ! slope of neutral surfaces required
199      !
[458]200      IF(lwp) THEN
201         WRITE(numout,*)
[6140]202         SELECT CASE( nldf )
[7646]203         CASE( np_no_ldf )   ;   WRITE(numout,*) '      ===>>   NO lateral diffusion'
204         CASE( np_lap    )   ;   WRITE(numout,*) '      ===>>   laplacian iso-level operator'
205         CASE( np_lap_i  )   ;   WRITE(numout,*) '      ===>>   Rotated laplacian operator (standard)'
206         CASE( np_lap_it )   ;   WRITE(numout,*) '      ===>>   Rotated laplacian operator (triad)'
207         CASE( np_blp    )   ;   WRITE(numout,*) '      ===>>   bilaplacian iso-level operator'
208         CASE( np_blp_i  )   ;   WRITE(numout,*) '      ===>>   Rotated bilaplacian operator (standard)'
209         CASE( np_blp_it )   ;   WRITE(numout,*) '      ===>>   Rotated bilaplacian operator (triad)'
[6140]210         END SELECT
[458]211      ENDIF
[503]212      !
[2528]213   END SUBROUTINE tra_ldf_init
[458]214
215   !!======================================================================
[620]216END MODULE traldf
Note: See TracBrowser for help on using the repository browser.