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.
trddyn.F90 in NEMO/branches/UKMO/NEMO_4.0_momentum_trends/src/OCE/TRD – NEMO

source: NEMO/branches/UKMO/NEMO_4.0_momentum_trends/src/OCE/TRD/trddyn.F90 @ 11613

Last change on this file since 11613 was 11613, checked in by davestorkey, 5 years ago

UKMO/NEMO_4.0_momentum_trends branch : first set of code changes.

File size: 16.1 KB
RevLine 
[4619]1MODULE trddyn
2   !!======================================================================
3   !!                       ***  MODULE  trddyn  ***
4   !! Ocean diagnostics:  ocean dynamic trends
5   !!=====================================================================
6   !! History :  3.5  !  2012-02  (G. Madec) creation from trdmod: split DYN and TRA trends
7   !!                                        and manage  3D trends output for U, V, and KE
8   !!----------------------------------------------------------------------
9
10   !!----------------------------------------------------------------------
11   !!   trd_dyn       : manage the type of momentum trend diagnostics (3D I/O, domain averaged, KE)
12   !!   trd_dyn_iom   : output 3D momentum and/or tracer trends using IOM
13   !!   trd_dyn_init  : initialization step
14   !!----------------------------------------------------------------------
15   USE oce            ! ocean dynamics and tracers variables
16   USE dom_oce        ! ocean space and time domain variables
[9019]17   USE phycst         ! physical constants
18   USE sbc_oce        ! surface boundary condition: ocean
19   USE zdf_oce        ! ocean vertical physics: variables
[4619]20   USE trd_oce        ! trends: ocean variables
21   USE trdken         ! trends: Kinetic ENergy
22   USE trdglo         ! trends: global domain averaged
23   USE trdvor         ! trends: vertical averaged vorticity
24   USE trdmxl         ! trends: mixed layer averaged
[9019]25   !
[4619]26   USE in_out_manager ! I/O manager
27   USE lbclnk         ! lateral boundary condition
28   USE iom            ! I/O manager library
29   USE lib_mpp        ! MPP library
30
31   IMPLICIT NONE
32   PRIVATE
33
[9019]34   PUBLIC trd_dyn        ! called by all dynXXX modules
[4619]35
[11613]36   INTERFACE trd_dyn
37      module procedure trd_dyn_3d, trd_dyn_2d
38   END INTERFACE
39
40   REAL(wp), ALLOCATABLE, DIMENSION(:,:,:), SAVE :: zutrd_hpg, zvtrd_hpg
41   REAL(wp), ALLOCATABLE, DIMENSION(:,:,:), SAVE :: zutrd_pvo, zvtrd_pvo
42
[4619]43   !! * Substitutions
44#  include "vectopt_loop_substitute.h90"
45   !!----------------------------------------------------------------------
[9598]46   !! NEMO/OCE 4.0 , NEMO Consortium (2018)
[5215]47   !! $Id$
[10068]48   !! Software governed by the CeCILL license (see ./LICENSE)
[4619]49   !!----------------------------------------------------------------------
50CONTAINS
51
[11613]52   SUBROUTINE trd_dyn_3d( putrd, pvtrd, ktrd, kt )
[4619]53      !!---------------------------------------------------------------------
[11613]54      !!                  ***  ROUTINE trd_dyn_3d  ***
[4619]55      !!
56      !! ** Purpose :   Dispatch momentum trend computation, e.g. 3D output,
57      !!              integral constraints, barotropic vorticity, kinetic enrgy,
58      !!              and/or mixed layer budget.
59      !!----------------------------------------------------------------------
60      REAL(wp), DIMENSION(:,:,:), INTENT(inout) ::   putrd, pvtrd   ! U and V trends
61      INTEGER                   , INTENT(in   ) ::   ktrd           ! trend index
62      INTEGER                   , INTENT(in   ) ::   kt             ! time step
63      !!----------------------------------------------------------------------
64      !
65      putrd(:,:,:) = putrd(:,:,:) * umask(:,:,:)                       ! mask the trends
66      pvtrd(:,:,:) = pvtrd(:,:,:) * vmask(:,:,:)
67      !
68
69!!gm NB : here a lbc_lnk should probably be added
70
[11613]71      SELECT CASE( ktrd )
72      CASE( jpdyn_hpg_save ) 
73         !
74         ! save 3D HPG trends to possibly have barotropic part corrected later before writing out
75         ALLOCATE( zutrd_hpg(jpi,jpj,jpk), zvtrd_hpg(jpi,jpj,jpk) )
76         zutrd_hpg(:,:,:) = putrd(:,:,:)
77         zvtrd_hpg(:,:,:) = pvtrd(:,:,:)
78
79      CASE( jpdyn_pvo_save ) 
80         !
81         ! save 3D coriolis trends to possibly have barotropic part corrected later before writing out
82         ALLOCATE( zutrd_pvo(jpi,jpj,jpk), zvtrd_pvo(jpi,jpj,jpk) )
83         zutrd_pvo(:,:,:) = putrd(:,:,:)
84         zvtrd_pvo(:,:,:) = pvtrd(:,:,:)
85
86      CASE DEFAULT
87
88         IF( ktrd == jpdyn_spg ) THEN
89            ! For explicit scheme SPG trends come here as 3D fields
90            ! Add SPG trend to 3D HPG trend and also output as 2D diagnostic in own right.
91            CALL trd_dyn_iom_2d( putrd(:,:,1), pvtrd(:,:,1), jpdyn_spg, kt ) 
92            putrd(:,:,:) = putrd(:,:,:) + zutrd_hpg(:,:,:) 
93            pvtrd(:,:,:) = pvtrd(:,:,:) + zvtrd_hpg(:,:,:) 
94            DEALLOCATE( zutrd_hpg, zvtrd_hpg )
95         ENDIF
96
97         !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
98         !   3D output of momentum and/or tracers trends using IOM interface
99         !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
100         IF( ln_dyn_trd )   CALL trd_dyn_iom_3d( putrd, pvtrd, ktrd, kt )
101
102         !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
103         !  Integral Constraints Properties for momentum and/or tracers trends
104         !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
105         IF( ln_glo_trd )   CALL trd_glo( putrd, pvtrd, ktrd, 'DYN', kt )
106
107         !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
108         !  Kinetic Energy trends
109         !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
110         IF( ln_KE_trd  )   CALL trd_ken( putrd, pvtrd, ktrd, kt )
111
112         !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
113         !  Vorticity trends
114         !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
115         IF( ln_vor_trd )   CALL trd_vor( putrd, pvtrd, ktrd, kt )
116
117         !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
118         !  Mixed layer trends for active tracers
119         !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
120         !!gm      IF( ln_dyn_mxl )   CALL trd_mxl_dyn   
121         !
122      END SELECT
123      !
124   END SUBROUTINE trd_dyn_3d
125
126
127   SUBROUTINE trd_dyn_2d( putrd, pvtrd, ktrd, kt )
128      !!---------------------------------------------------------------------
129      !!                  ***  ROUTINE trd_mod  ***
130      !!
131      !! ** Purpose :   Dispatch momentum trend computation, e.g. 2D output,
132      !!              integral constraints, barotropic vorticity, kinetic enrgy,
133      !!              and/or mixed layer budget.
134      !!----------------------------------------------------------------------
135      REAL(wp), DIMENSION(:,:), INTENT(inout) ::   putrd, pvtrd   ! U and V trends
136      INTEGER                 , INTENT(in   ) ::   ktrd           ! trend index
137      INTEGER                 , INTENT(in   ) ::   kt             ! time step
138      INTEGER                                 ::   jk
139      !!----------------------------------------------------------------------
140      !
141      putrd(:,:) = putrd(:,:) * umask(:,:,1)                       ! mask the trends
142      pvtrd(:,:) = pvtrd(:,:) * vmask(:,:,1)
143      !
144
145!!gm NB : here a lbc_lnk should probably be added
146
147      SELECT CASE(ktrd)
148
149      CASE ( jpdyn_hpg_corr )
150         !
151         ! Remove "first-guess" SPG trend from 3D HPG trend.
152         DO jk = 1, jpkm1
153            zutrd_hpg(:,:,jk) = zutrd_hpg(:,:,jk) - putrd(:,:)
154            zvtrd_hpg(:,:,jk) = zvtrd_hpg(:,:,jk) - pvtrd(:,:)
155         ENDDO
156         CALL trd_dyn_iom_2d( putrd, pvtrd, jpdyn_hpg_corr, kt ) 
157
158      CASE( jpdyn_pvo_corr )
159         !
160         ! Remove "first-guess" barotropic coriolis trend from 3D PVO trend.
161         DO jk = 1, jpkm1
162            zutrd_pvo(:,:,jk) = zutrd_pvo(:,:,jk) - putrd(:,:)
163            zvtrd_pvo(:,:,jk) = zvtrd_pvo(:,:,jk) - pvtrd(:,:)
164         ENDDO
165         CALL trd_dyn_iom_2d( putrd, pvtrd, jpdyn_pvo_corr, kt ) 
166
167      CASE( jpdyn_spg )
168          !
169          ! For split-explicit scheme SPG trends come here as 2D fields
170          ! Add SPG trend to 3D HPG trend and also output as 2D diagnostic in own right.
171          DO jk = 1, jpkm1
172             zutrd_hpg(:,:,jk) = zutrd_hpg(:,:,jk) + putrd(:,:)
173             zvtrd_hpg(:,:,jk) = zvtrd_hpg(:,:,jk) + pvtrd(:,:)
174          ENDDO
175          CALL trd_dyn_iom_2d( putrd(:,:), pvtrd(:,:), jpdyn_spg, kt ) 
176          CALL trd_dyn_3d( zutrd_hpg, zvtrd_hpg, jpdyn_hpg, kt )
177          DEALLOCATE( zutrd_hpg, zvtrd_hpg )
178
179      CASE( jpdyn_pvo )
180          !
181          ! Add 2D PVO trend to 3D PVO trend and also output as diagnostic in own right.
182          DO jk = 1, jpkm1
183             zutrd_pvo(:,:,jk) = zutrd_pvo(:,:,jk) + putrd(:,:)
184             zvtrd_pvo(:,:,jk) = zvtrd_pvo(:,:,jk) + pvtrd(:,:)
185          ENDDO
186          CALL trd_dyn_iom_2d( putrd, pvtrd, jpdyn_pvo, kt ) 
187          CALL trd_dyn_3d( zutrd_pvo, zvtrd_pvo, jpdyn_pvo, kt )
188          DEALLOCATE( zutrd_pvo, zvtrd_pvo )
189
190      CASE DEFAULT 
191
192         !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
193         !   2D output of momentum and/or tracers trends using IOM interface
194         !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
195         IF( ln_dyn_trd )   CALL trd_dyn_iom_2d( putrd, pvtrd, ktrd, kt )
[4619]196         
[11613]197      END SELECT
[4619]198
[11613]199!!$   CALLS TO THESE ROUTINES FOR 2D DIAGOSTICS NOT CODED YET
200!!$      !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
201!!$      !  Integral Constraints Properties for momentum and/or tracers trends
202!!$      !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
203!!$      IF( ln_glo_trd )   CALL trd_glo( putrd, pvtrd, ktrd, 'DYN', kt )
204!!$
205!!$      !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
206!!$      !  Kinetic Energy trends
207!!$      !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
208!!$      IF( ln_KE_trd  )   CALL trd_ken( putrd, pvtrd, ktrd, kt )
209!!$
210!!$      !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
211!!$      !  Vorticity trends
212!!$      !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
213!!$      IF( ln_vor_trd )   CALL trd_vor( putrd, pvtrd, ktrd, kt )
[4619]214
215      !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
216      !  Mixed layer trends for active tracers
217      !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
[4804]218!!gm      IF( ln_dyn_mxl )   CALL trd_mxl_dyn   
[4619]219      !
[11613]220   END SUBROUTINE trd_dyn_2d
[4619]221
222
[11613]223   SUBROUTINE trd_dyn_iom_3d( putrd, pvtrd, ktrd, kt )
[4619]224      !!---------------------------------------------------------------------
225      !!                  ***  ROUTINE trd_dyn_iom  ***
226      !!
227      !! ** Purpose :   output 3D trends using IOM
228      !!----------------------------------------------------------------------
229      REAL(wp), DIMENSION(:,:,:), INTENT(inout) ::   putrd, pvtrd   ! U and V trends
230      INTEGER                   , INTENT(in   ) ::   ktrd           ! trend index
231      INTEGER                   , INTENT(in   ) ::   kt             ! time step
232      !
233      INTEGER ::   ji, jj, jk   ! dummy loop indices
234      INTEGER ::   ikbu, ikbv   ! local integers
[9019]235      REAL(wp), ALLOCATABLE, DIMENSION(:,:)   ::   z2dx, z2dy   ! 2D workspace
236      REAL(wp), ALLOCATABLE, DIMENSION(:,:,:) ::   z3dx, z3dy   ! 3D workspace
[4619]237      !!----------------------------------------------------------------------
238      !
239      SELECT CASE( ktrd )
240      CASE( jpdyn_hpg )   ;   CALL iom_put( "utrd_hpg", putrd )    ! hydrostatic pressure gradient
241                              CALL iom_put( "vtrd_hpg", pvtrd )
242      CASE( jpdyn_pvo )   ;   CALL iom_put( "utrd_pvo", putrd )    ! planetary vorticity
243                              CALL iom_put( "vtrd_pvo", pvtrd )
244      CASE( jpdyn_rvo )   ;   CALL iom_put( "utrd_rvo", putrd )    ! relative  vorticity     (or metric term)
245                              CALL iom_put( "vtrd_rvo", pvtrd )
246      CASE( jpdyn_keg )   ;   CALL iom_put( "utrd_keg", putrd )    ! Kinetic Energy gradient (or had)
247                              CALL iom_put( "vtrd_keg", pvtrd )
[9019]248                              ALLOCATE( z3dx(jpi,jpj,jpk) , z3dy(jpi,jpj,jpk) )
[4619]249                              z3dx(:,:,:) = 0._wp                  ! U.dxU & V.dyV (approximation)
250                              z3dy(:,:,:) = 0._wp
[9097]251                              DO jk = 1, jpkm1   ! no mask as un,vn are masked
[4619]252                                 DO jj = 2, jpjm1
253                                    DO ji = 2, jpim1
254                                       z3dx(ji,jj,jk) = un(ji,jj,jk) * ( un(ji+1,jj,jk) - un(ji-1,jj,jk) ) / ( 2._wp * e1u(ji,jj) )
255                                       z3dy(ji,jj,jk) = vn(ji,jj,jk) * ( vn(ji,jj+1,jk) - vn(ji,jj-1,jk) ) / ( 2._wp * e2v(ji,jj) )
256                                    END DO
257                                 END DO
258                              END DO
[10425]259                              CALL lbc_lnk_multi( 'trddyn', z3dx, 'U', -1., z3dy, 'V', -1. )
[4619]260                              CALL iom_put( "utrd_udx", z3dx  )
261                              CALL iom_put( "vtrd_vdy", z3dy  )
[9019]262                              DEALLOCATE( z3dx , z3dy )
263      CASE( jpdyn_zad )   ;   CALL iom_put( "utrd_zad", putrd )    ! vertical advection
[4619]264                              CALL iom_put( "vtrd_zad", pvtrd )
[9019]265      CASE( jpdyn_ldf )   ;   CALL iom_put( "utrd_ldf", putrd )    ! lateral  diffusion
[4619]266                              CALL iom_put( "vtrd_ldf", pvtrd )
267      CASE( jpdyn_zdf )   ;   CALL iom_put( "utrd_zdf", putrd )    ! vertical diffusion
268                              CALL iom_put( "vtrd_zdf", pvtrd )
[9019]269                              !
[4619]270                              !                                    ! wind stress trends
[9019]271                              ALLOCATE( z2dx(jpi,jpj) , z2dy(jpi,jpj) )
[6140]272                              z2dx(:,:) = ( utau_b(:,:) + utau(:,:) ) / ( e3u_n(:,:,1) * rau0 )
273                              z2dy(:,:) = ( vtau_b(:,:) + vtau(:,:) ) / ( e3v_n(:,:,1) * rau0 )
[4619]274                              CALL iom_put( "utrd_tau", z2dx )
275                              CALL iom_put( "vtrd_tau", z2dy )
[9019]276                              DEALLOCATE( z2dx , z2dy )
[11613]277      CASE( jpdyn_bfr )   ;   CALL iom_put( "utrd_bfr", putrd )    ! bottom friction (explicit case)
[9019]278                              CALL iom_put( "vtrd_bfr", pvtrd )
[11613]279      CASE( jpdyn_bfri)   ;   CALL iom_put( "utrd_bfri", putrd )    ! bottom friction (implicit case)
280                              CALL iom_put( "vtrd_bfri", pvtrd )
[9019]281      CASE( jpdyn_atf )   ;   CALL iom_put( "utrd_atf", putrd )        ! asselin filter trends
282                              CALL iom_put( "vtrd_atf", pvtrd )
[4619]283      END SELECT
284      !
[11613]285   END SUBROUTINE trd_dyn_iom_3d
[4619]286
[11613]287
288   SUBROUTINE trd_dyn_iom_2d( putrd, pvtrd, ktrd, kt )
289      !!---------------------------------------------------------------------
290      !!                  ***  ROUTINE trd_dyn_iom  ***
291      !!
292      !! ** Purpose :   output 2D trends using IOM
293      !!----------------------------------------------------------------------
294      REAL(wp), DIMENSION(:,:), INTENT(inout) ::   putrd, pvtrd   ! U and V trends
295      INTEGER                 , INTENT(in   ) ::   ktrd           ! trend index
296      INTEGER                 , INTENT(in   ) ::   kt             ! time step
297      !
298      INTEGER ::   ji, jj, jk   ! dummy loop indices
299      INTEGER ::   ikbu, ikbv   ! local integers
300      REAL(wp), ALLOCATABLE, DIMENSION(:,:)   ::   z2dx, z2dy   ! 2D workspace
301      REAL(wp), ALLOCATABLE, DIMENSION(:,:,:) ::   z3dx, z3dy   ! 3D workspace
302      !!----------------------------------------------------------------------
303      !
304      SELECT CASE( ktrd )
305      CASE( jpdyn_spg )      ;   CALL iom_put( "utrd_spg2d", putrd )      ! surface pressure gradient
306                                 CALL iom_put( "vtrd_spg2d", pvtrd )
307      CASE( jpdyn_pvo )      ;   CALL iom_put( "utrd_pvo2d", putrd )      ! planetary vorticity (barotropic part)
308                                 CALL iom_put( "vtrd_pvo2d", pvtrd )
309      CASE( jpdyn_hpg_corr ) ;   CALL iom_put( "utrd_hpg_corr", putrd )   ! horizontal pressure gradient correction
310                                 CALL iom_put( "vtrd_hpg_corr", pvtrd )
311      CASE( jpdyn_pvo_corr ) ;   CALL iom_put( "utrd_pvo_corr", putrd )   ! planetary vorticity correction
312                                 CALL iom_put( "vtrd_pvo_corr", pvtrd )
313      CASE( jpdyn_bfr )      ;   CALL iom_put( "utrd_bfr2d", putrd )      ! bottom friction due to barotropic currents
314                                 CALL iom_put( "vtrd_bfr2d", pvtrd )
315      END SELECT
316      !
317   END SUBROUTINE trd_dyn_iom_2d
318
[4619]319   !!======================================================================
320END MODULE trddyn
Note: See TracBrowser for help on using the repository browser.