/[MITgcm]/MITgcm/pkg/gmredi/gmredi_k3d.F
ViewVC logotype

Contents of /MITgcm/pkg/gmredi/gmredi_k3d.F

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.9 - (show annotations) (download)
Sun Sep 15 14:31:11 2013 UTC (10 years, 9 months ago) by m_bates
Branch: MAIN
CVS Tags: checkpoint64o
Changes since 1.8: +13 -3 lines
Changes for the residual model.

1 C $Header: /u/gcmpack/MITgcm/pkg/gmredi/gmredi_k3d.F,v 1.8 2013/08/31 17:33:55 m_bates Exp $
2 C $Name: $
3 #include "CPP_OPTIONS.h"
4 #include "GMREDI_OPTIONS.h"
5
6 C !ROUTINE: GMREDI_K3D
7 C !INTERFACE:
8 SUBROUTINE GMREDI_K3D(
9 I iMin, iMax, jMin, jMax,
10 I sigmaX, sigmaY, sigmaR,
11 I bi, bj, myTime, myThid )
12
13 C !DESCRIPTION: \bv
14 C *==========================================================*
15 C | SUBROUTINE GMREDI_K3D
16 C | o Calculates the 3D diffusivity as per Bates et al. (2013)
17 C *==========================================================*
18 C \ev
19
20 IMPLICIT NONE
21
22 C == Global variables ==
23 #include "SIZE.h"
24 #include "GRID.h"
25 #include "DYNVARS.h"
26 #include "EEPARAMS.h"
27 #include "PARAMS.h"
28 #include "GMREDI.h"
29
30 C !INPUT/OUTPUT PARAMETERS:
31 C == Routine arguments ==
32 C bi, bj :: tile indices
33 C myThid :: My Thread Id. number
34
35 INTEGER iMin,iMax,jMin,jMax
36 _RL sigmaX(1-Olx:sNx+Olx,1-Oly:sNy+Oly,Nr)
37 _RL sigmaY(1-Olx:sNx+Olx,1-Oly:sNy+Oly,Nr)
38 _RL sigmaR(1-Olx:sNx+Olx,1-Oly:sNy+Oly,Nr)
39 INTEGER bi, bj
40 _RL myTime
41 INTEGER myThid
42
43 #ifdef GM_K3D
44
45 C === Functions ====
46 LOGICAL DIFFERENT_MULTIPLE
47 EXTERNAL DIFFERENT_MULTIPLE
48
49 C !LOCAL VARIABLES:
50 C == Local variables ==
51 INTEGER i,j,k,kk,m
52
53 C update_modes :: Whether to update the eigenmodes
54 LOGICAL update_modes
55
56 C surfk :: index of the depth of the surface layer
57 C kLow_C :: Local version of the index of deepest wet grid cell on tracer grid
58 C kLow_U :: Local version of the index of deepest wet grid cell on U grid
59 C kLow_V :: Local version of the index of deepest wet grid cell on V grid
60 INTEGER surfk(1-Olx:sNx+Olx,1-Oly:sNy+Oly)
61 INTEGER kLow_C(1-Olx:sNx+Olx,1-Oly:sNy+Oly)
62 INTEGER kLow_U(1-Olx:sNx+Olx,1-Oly:sNy+Oly)
63 INTEGER kLow_V(1-Olx:sNx+Olx,1-Oly:sNy+Oly)
64
65 C N2loc :: local N**2
66 C slope :: local slope
67 C Req :: local equatorial deformation radius (m)
68 C deltaH :: local thickness of Eady integration (m)
69 C g_reciprho_sq :: (gravity*recip_rhoConst)**2
70 C M4loc :: local M**4
71 C maxDRhoDz :: maximum value of d(rho)/dz (derived from GM_K3D_minN2)
72 C sigx :: local d(rho)/dx
73 C sigy :: local d(rho)/dy
74 C sigz :: local d(rho)/dz
75 C hsurf :: local surface layer depth
76 C small :: a small number (to avoid floating point exceptions)
77 _RL N2loc
78 _RL slope
79 _RL Req
80 _RL deltaH
81 _RL g_reciprho_sq
82 _RL M4loc
83 _RL maxDRhoDz
84 _RL sigx, sigy, sigz
85 _RL hsurf
86 _RL small
87
88 C dfdy :: gradient of the Coriolis paramter, df/dy, 1/(m*s)
89 C dfdx :: gradient of the Coriolis paramter, df/dx, 1/(m*s)
90 C gradf :: gradient of the Coriolis paramter at a cell centre, 1/(m*s)
91 C Rurms :: a local mixing length used in calculation of urms (m)
92 C RRhines :: The Rhines scale (m)
93 C Rmix :: Mixing length
94 C N2 :: Square of the buoyancy frequency (1/s**2)
95 C N2W :: Square of the buoyancy frequency (1/s**2) averaged to west of grid cell
96 C N2S :: Square of the buoyancy frequency (1/s**2) averaged to south of grid cell
97 C N :: Buoyancy frequency, SQRT(N2)
98 C BVint :: The vertical integral of N (m/s)
99 C ubar :: Zonal velocity on a tracer point (m/s)
100 C vbar :: Meridional velocity on a tracer point (m/s)
101 C Ubaro :: Barotropic velocity (m/s)
102 _RL dfdy( 1-Olx:sNx+Olx,1-Oly:sNy+Oly)
103 _RL dfdx( 1-Olx:sNx+Olx,1-Oly:sNy+Oly)
104 _RL gradf( 1-Olx:sNx+Olx,1-Oly:sNy+Oly)
105 _RL dummy( 1-Olx:sNx+Olx,1-Oly:sNy+Oly)
106 _RL Rurms( 1-Olx:sNx+Olx,1-Oly:sNy+Oly)
107 _RL RRhines(1-Olx:sNx+Olx,1-Oly:sNy+Oly)
108 _RL Rmix( 1-Olx:sNx+Olx,1-Oly:sNy+Oly)
109 _RL N2( 1-Olx:sNx+Olx,1-Oly:sNy+Oly,Nr)
110 _RL N2W( 1-Olx:sNx+Olx,1-Oly:sNy+Oly,Nr)
111 _RL N2S( 1-Olx:sNx+Olx,1-Oly:sNy+Oly,Nr)
112 _RL N( 1-Olx:sNx+Olx,1-Oly:sNy+Oly,Nr)
113 _RL BVint( 1-Olx:sNx+Olx,1-Oly:sNy+Oly)
114 _RL Ubaro( 1-Olx:sNx+Olx,1-Oly:sNy+Oly)
115 _RL ubar( 1-Olx:sNx+Olx,1-Oly:sNy+Oly,Nr,nSx,nSy)
116 _RL vbar( 1-Olx:sNx+Olx,1-Oly:sNy+Oly,Nr,nSx,nSy)
117
118 C Rmid :: Rossby radius (m)
119 C KPV :: Diffusivity (m**2/s)
120 C SlopeX :: isopycnal slope in x direction
121 C SlopeY :: isopycnal slope in y direction
122 C dSigmaDx :: sigmaX averaged onto tracer grid
123 C dSigmaDy :: sigmaY averaged onto tracer grid
124 C tfluxX :: thickness flux in x direction
125 C tfluxY :: thickness flux in y direction
126 C fCoriU :: Coriolis parameter averaged to U points
127 C fCoriV :: Coriolis parameter averaged to V points
128 C cori :: Coriolis parameter forced to be finite near the equator
129 C coriU :: As for cori, but, at U point
130 C coriV :: As for cori, but, at V point
131 C surfkz :: Depth of surface layer (in r units)
132 _RL Rmid(1-Olx:sNx+Olx,1-Oly:sNy+Oly)
133 _RL KPV(1-Olx:sNx+Olx,1-Oly:sNy+Oly,Nr)
134 _RL SlopeX(1-Olx:sNx+Olx,1-Oly:sNy+Oly,Nr)
135 _RL SlopeY(1-Olx:sNx+Olx,1-Oly:sNy+Oly,Nr)
136 _RL dSigmaDx(1-Olx:sNx+Olx,1-Oly:sNy+Oly,Nr)
137 _RL dSigmaDy(1-Olx:sNx+Olx,1-Oly:sNy+Oly,Nr)
138 _RL tfluxX(1-Olx:sNx+Olx,1-Oly:sNy+Oly,Nr)
139 _RL tfluxY(1-Olx:sNx+Olx,1-Oly:sNy+Oly,Nr)
140 _RL cori(1-Olx:sNx+Olx,1-Oly:sNy+Oly)
141 _RL coriU(1-Olx:sNx+Olx,1-Oly:sNy+Oly)
142 _RL coriV(1-Olx:sNx+Olx,1-Oly:sNy+Oly)
143 _RL fCoriU(1-Olx:sNx+Olx,1-Oly:sNy+Oly)
144 _RL fCoriV(1-Olx:sNx+Olx,1-Oly:sNy+Oly)
145 _RL surfkz(1-Olx:sNx+Olx,1-Oly:sNy+Oly)
146
147 C gradqx :: Potential vorticity gradient in x direction
148 C gradqy :: Potential vorticity gradient in y direction
149 C XimX :: Vertical integral of phi_m*K*gradqx
150 C XimY :: Vertical integral of phi_m*K*gradqy
151 C cDopp :: Quasi-Doppler shifted long Rossby wave speed (m/s)
152 C umc :: ubar-c (m/s)
153 C eady :: Eady growth rate (1/s)
154 C urms :: the rms eddy velocity (m/s)
155 C supp :: The suppression factor
156 C ustar :: The eddy induced velocity in the x direction
157 C vstar :: The eddy induced velocity in the y direction
158 C Xix :: Xi in the x direction (m/s**2)
159 C Xiy :: Xi in the y direction (m/s**2)
160 _RL gradqx(1-Olx:sNx+Olx,1-Oly:sNy+Oly,Nr)
161 _RL gradqy(1-Olx:sNx+Olx,1-Oly:sNy+Oly,Nr)
162 _RL XimX(GM_K3D_NModes,1-Olx:sNx+Olx,1-Oly:sNy+Oly)
163 _RL XimY(GM_K3D_NModes,1-Olx:sNx+Olx,1-Oly:sNy+Oly)
164 _RL cDopp(1-Olx:sNx+Olx,1-Oly:sNy+Oly)
165 _RL umc( 1-Olx:sNx+Olx,1-Oly:sNy+Oly,1:Nr)
166 _RL eady( 1-Olx:sNx+Olx,1-Oly:sNy+Oly)
167 _RL urms( 1-Olx:sNx+Olx,1-Oly:sNy+Oly,1:Nr)
168 _RL supp( 1-Olx:sNx+Olx,1-Oly:sNy+Oly,1:Nr)
169 _RL ustar(1-Olx:sNx+Olx,1-Oly:sNy+Oly,1:Nr)
170 _RL vstar(1-Olx:sNx+Olx,1-Oly:sNy+Oly,1:Nr)
171 _RL Xix( 1-Olx:sNx+Olx,1-Oly:sNy+Oly,Nr)
172 _RL Xiy( 1-Olx:sNx+Olx,1-Oly:sNy+Oly,Nr)
173 #ifdef GM_K3D_PASSIVE
174 C psistar :: eddy induced streamfunction in the y direction
175 _RL psistar(1-Olx:sNx+Olx,1-Oly:sNy+Oly,1:Nr)
176 #endif
177
178
179 C---+----1----+----2----+----3----+----4----+----5----+----6----+----7-|--+----|
180
181 C ======================================
182 C Initialise some variables
183 C ======================================
184 small = TINY(zeroRL)
185 update_modes=.FALSE.
186 IF ( DIFFERENT_MULTIPLE(GM_K3D_vecFreq,myTime,deltaTClock) )
187 & update_modes=.TRUE.
188
189 DO j=1-Oly,sNy+Oly
190 DO i=1-Olx,sNx+Olx
191 kLow_C(i,j) = kLowC(i,j,bi,bj)
192 ENDDO
193 ENDDO
194 DO j=1-Oly,sNy+Oly
195 DO i=1-Olx+1,sNx+Olx
196 kLow_U(i,j) = MIN( kLow_C(i,j), kLow_C(i-1,j) )
197 ENDDO
198 ENDDO
199 DO j=1-Oly+1,sNy+Oly
200 DO i=1-Olx,sNx+Olx
201 kLow_V(i,j) = MIN( kLow_C(i,j), kLow_C(i,j-1) )
202 ENDDO
203 ENDDO
204
205 C Dummy values for the edges
206 C This avoids weirdness in gmredi_calc_eigs
207 i=1-Olx
208 DO j=1-Oly,sNy+Oly
209 kLow_U(i,j) = kLow_C(i,j)
210 ENDDO
211 j=1-Oly
212 DO i=1-Olx,sNx+Olx
213 kLow_V(i,j) = kLow_C(i,j)
214 ENDDO
215
216 g_reciprho_sq = (gravity*recip_rhoConst)**2
217 C Gradient of Coriolis
218 DO j=1-Oly+1,sNy+Oly
219 DO i=1-Olx+1,sNx+Olx
220 dfdx(i,j) = ( fCori(i,j,bi,bj)-fCori(i-1,j,bi,bj) )
221 & *recip_dxC(i,j,bi,bj)
222 dfdy(i,j) = ( fCori(i,j,bi,bj)-fCori(i,j-1,bi,bj) )
223 & *recip_dyC(i,j,bi,bj)
224 ENDDO
225 ENDDO
226
227 C Coriolis at C points enforcing a minimum value so
228 C that it is defined at the equator
229 DO j=1-Oly,sNy+Oly
230 DO i=1-Olx,sNx+Olx
231 cori(i,j) = SIGN( MAX( ABS(fCori(i,j,bi,bj)),GM_K3D_minCori ),
232 & fCori(i,j,bi,bj) )
233 ENDDO
234 ENDDO
235 C Coriolis at U and V points
236 DO j=1-Oly+1,sNy+Oly
237 DO i=1-Olx+1,sNx+Olx
238 C Limited so that the inverse is defined at the equator
239 coriU(i,j) = op5*( cori(i,j)+cori(i-1,j) )
240 coriU(i,j) = SIGN( MAX( ABS(coriU(i,j)),GM_K3D_minCori ),
241 & coriU(i,j) )
242
243 coriV(i,j) = op5*( cori(i,j)+cori(i,j-1) )
244 coriV(i,j) = SIGN( MAX( ABS(coriV(i,j)),GM_K3D_minCori ),
245 & coriV(i,j) )
246
247 C Not limited
248 fCoriU(i,j) = op5*( fCori(i,j,bi,bj)+fCori(i-1,j,bi,bj) )
249 fCoriV(i,j) = op5*( fCori(i,j,bi,bj)+fCori(i,j-1,bi,bj) )
250 ENDDO
251 ENDDO
252 DO j=1-Oly,sNy+Oly
253 DO i=1-Olx,sNx+Olx
254 gradf(i,j) = recip_rSphere*fCoriCos(i,j,bi,bj)
255 ENDDO
256 ENDDO
257
258 C Zeroing some cumulative fields
259 DO j=1-Oly,sNy+Oly
260 DO i=1-Olx,sNx+Olx
261 eady(i,j) = zeroRL
262 BVint(i,j) = zeroRL
263 Ubaro(i,j) = zeroRL
264 ENDDO
265 ENDDO
266
267 C Find the zonal velocity at the cell centre
268 C The logicals here are, in order: 1/ go from grid to north/east directions
269 C 2/ go from C to A grid and 3/ apply the mask
270 #ifdef ALLOW_EDDYPSI
271 IF (GM_InMomAsStress) THEN
272 CALL rotate_uv2en_rl(uMean, vMean, ubar, vbar, .TRUE., .TRUE.,
273 & .TRUE.,Nr,mythid)
274 ELSE
275 #endif
276 CALL rotate_uv2en_rl(uVel, vVel, ubar, vbar, .TRUE., .TRUE.,
277 & .TRUE.,Nr,mythid)
278 #ifdef ALLOW_EDDYPSI
279 ENDIF
280 #endif
281
282 C Square of the buoyancy frequency at the top of a grid cell
283 DO k=2,Nr
284 DO j=1-Oly,sNy+Oly
285 DO i=1-Olx,sNx+Olx
286 N2(i,j,k) = -gravity*recip_rhoConst*sigmaR(i,j,k)
287 ENDDO
288 ENDDO
289 ENDDO
290 C N2(k=1) is always zero
291 k=1
292 DO j=1-Oly,sNy+Oly
293 DO i=1-Olx,sNx+Olx
294 N2(i,j,k) = 0.0
295 N(i,j,k) = 0.0
296 ENDDO
297 ENDDO
298 C Enforce a minimum N2
299 DO k=2,Nr
300 DO j=1-Oly,sNy+Oly
301 DO i=1-Olx,sNx+Olx
302 IF (N2(i,j,k).LT.GM_K3D_minN2) N2(i,j,k)=GM_K3D_minN2
303 N(i,j,k) = SQRT(N2(i,j,k))
304 ENDDO
305 ENDDO
306 ENDDO
307 C Calculate the minimum drho/dz
308 maxDRhoDz = -rhoConst*GM_K3D_minN2/gravity
309
310 C Calculate the barotropic velocity by vertically integrating
311 C and the dividing by the depth of the water column
312 C Note that Ubaro is on the U grid.
313 DO k=1,Nr
314 DO j=1-Oly,sNy+Oly
315 DO i=1-Olx,sNx+Olx
316 Ubaro(i,j) = Ubaro(i,j) +
317 & maskW(i,j,k,bi,bj)*drF(k)*hfacC(i,j,k,bi,bj)
318 & *ubar(i,j,k,bi,bj)
319 ENDDO
320 ENDDO
321 ENDDO
322 DO j=1-Oly,sNy+Oly
323 DO i=1-Olx,sNx+Olx
324 IF (kLow_C(i,j).GT.0) THEN
325 C The minus sign is because r_Low<0
326 Ubaro(i,j) = -Ubaro(i,j)/r_Low(i,j,bi,bj)
327 ENDIF
328 ENDDO
329 ENDDO
330
331 C Integrate the buoyancy frequency vertically using the trapezoidal method.
332 DO k=1,Nr
333 DO j=1-Oly,sNy+Oly
334 DO i=1-Olx,sNx+Olx
335 IF (k.LT.kLow_C(i,j)) THEN
336 BVint(i,j) = BVint(i,j) + hFacC(i,j,k,bi,bj)*drF(k)
337 & *(N(i,j,k)+N(i,j,k+1))
338 ELSEIF (k.EQ.kLow_C(i,j)) THEN
339 C Assume that N(z=-H)=0
340 BVint(i,j) = BVint(i,j) + hFacC(i,j,k,bi,bj)*drF(k)*N(i,j,k)
341 ENDIF
342 ENDDO
343 ENDDO
344 ENDDO
345 DO j=1-Oly,sNy+Oly
346 DO i=1-Olx,sNx+Olx
347 BVint(i,j) = op5*BVint(i,j)
348 ENDDO
349 ENDDO
350
351 C Calculate the eigenvalues and eigenvectors
352 IF (update_modes) THEN
353 CALL GMREDI_CALC_EIGS(
354 I iMin,iMax,jMin,jMax,bi,bj,N2,myThid,
355 I kLow_C, maskC(:,:,:,bi,bj),
356 I hfacC(:,:,:,bi,bj), recip_hfacC(:,:,:,bi,bj),
357 I R_Low(:,:,bi,bj), 1, .TRUE.,
358 O Rmid, modesC(:,:,:,:,bi,bj))
359
360 C Calculate the Rossby Radius
361 DO j=1-Oly+1,sNy+Oly
362 DO i=1-Olx+1,sNx+Olx
363 Req = SQRT(BVint(i,j)/(2*pi*gradf(i,j)))
364 Rdef(i,j,bi,bj) = MIN(Rmid(i,j),Req)
365 ENDDO
366 ENDDO
367 ENDIF
368
369 C Average dsigma/dx and dsigma/dy onto the centre points
370
371 DO k=1,Nr
372 DO j=1-Oly,sNy+Oly-1
373 DO i=1-Olx,sNx+Olx-1
374 dSigmaDx(i,j,k) = op5*(sigmaX(i,j,k)+sigmaX(i+1,j,k))
375 dSigmaDy(i,j,k) = op5*(sigmaY(i,j,k)+sigmaY(i,j+1,k))
376 ENDDO
377 ENDDO
378 ENDDO
379
380 C ===============================
381 C Calculate the Eady growth rate
382 C ===============================
383 DO k=1,Nr
384
385 C The bottom of the grid cell is shallower than the top
386 C integration level, so, advance the depth.
387 IF (-rF(k+1).LE. GM_K3D_EadyMinDepth) CYCLE
388
389 C Do not bother going any deeper since the top of the
390 C cell is deeper than the bottom integration level
391 IF (-rF(k).GE.GM_K3D_EadyMaxDepth) EXIT
392
393 C We are in the integration depth range
394 DO j=1-Oly,sNy+Oly-1
395 DO i=1-Olx,sNx+Olx-1
396 IF (kLow_C(i,j).GE.k) THEN
397 IF (k.NE.kLow_C(i,j)) THEN
398 N2loc = op5*(N2(i,j,k)+N2(i,j,k+1))
399 ELSE
400 N2loc = op5*N2(i,j,k)
401 ENDIF
402 M4loc = g_reciprho_sq*( dSigmaDx(i,j,k)**2
403 & +dSigmaDy(i,j,k)**2 )
404 slope = SQRT(SQRT(M4loc)/N2loc)
405
406 C Limit the slope. Note, this is not all the Eady calculations.
407 IF (slope.LE.GM_K3D_maxSlope) THEN
408 eady(i,j) = eady(i,j)
409 & + hfacC(i,j,k,bi,bj)*drF(k)*M4loc/(N2loc)
410 ELSE
411 eady(i,j) = eady(i,j)
412 & + hfacC(i,j,k,bi,bj)*drF(k)*SQRT(M4loc)
413 & *GM_K3D_maxSlope*GM_K3D_maxSlope
414 ENDIF
415 ENDIF
416 ENDDO
417 ENDDO
418 ENDDO
419
420 DO j=1-Oly,sNy+Oly
421 DO i=1-Olx,sNx+Olx
422 C If the minimum depth for the integration is deeper than ocean
423 C bottom then give the eady growth rate a dummy, non-zero value
424 C to avoid floating point exceptions. These points are taken care
425 C of by setting K3D=GM_K3D_smallK later.
426 IF (-r_Low(i,j,bi,bj).LE.GM_K3D_EadyMinDepth) THEN
427 eady(i,j) = small
428
429 C Otherwise, multiply eady by the various constants to get the
430 C growth rate.
431 ELSE
432 deltaH = MIN(-r_low(i,j,bi,bj),GM_K3D_EadyMaxDepth)
433 deltaH = deltaH - GM_K3D_EadyMinDepth
434 eady(i,j) = SQRT(eady(i,j)/deltaH)
435
436 ENDIF
437
438 ENDDO
439 ENDDO
440
441 C ======================================
442 C Calculate the diffusivity
443 C ======================================
444 DO j=1-Oly+1,sNy+Oly
445 DO i=1-Olx+1,sNx+Olx-1
446 C Calculate the Visbeck velocity
447 Rurms(i,j) = MIN(Rdef(i,j,bi,bj),GM_K3D_maxLurms)
448 urms(i,j,1) = GM_K3D_Lambda*eady(i,j)*Rurms(i,j)
449 C Set the bottom urms to zero
450 k=kLow_C(i,j)
451 IF (k.GT.0) urms(i,j,k) = 0.0
452
453 C Calculate the Rhines scale
454 RRhines(i,j) = SQRT(urms(i,j,1)/gradf(i,j))
455
456 C Calculate the estimated length scale
457 Rmix(i,j) = MIN(Rdef(i,j,bi,bj), RRhines(i,j))
458
459 C Calculate the Doppler shifted long Rossby wave speed
460 C Ubaro is on the U grid so we must average onto the M grid.
461 cDopp(i,j) = op5*( Ubaro(i,j)+Ubaro(i+1,j) )
462 & - gradf(i,j)*Rdef(i,j,bi,bj)*Rdef(i,j,bi,bj)
463 C Limit the wave speed to the namelist variable GM_K3D_maxC
464 IF (ABS(cDopp(i,j)).GT.GM_K3D_maxC) THEN
465 cDopp(i,j) = MAX(GM_K3D_maxC, cDopp(i,j))
466 ENDIF
467
468 ENDDO
469 ENDDO
470
471 C Project the surface urms to the subsurface using the first baroclinic mode
472 CALL GMREDI_CALC_URMS(
473 I iMin,iMax,jMin,jMax,bi,bj,N2,myThid,
474 U urms)
475
476 C Calculate the diffusivity (on the mass grid)
477 DO k=1,Nr
478 DO j=1-Oly,sNy+Oly
479 DO i=1-Olx,sNx+Olx
480 IF (k.LE.kLow_C(i,j)) THEN
481 IF (-r_Low(i,j,bi,bj).LE.GM_K3D_EadyMinDepth) THEN
482 K3D(i,j,k,bi,bj) = GM_K3D_smallK
483 ELSE
484 IF (urms(i,j,k).EQ.0.0) THEN
485 K3D(i,j,k,bi,bj) = GM_K3D_smallK
486 ELSE
487 umc(i,j,k) = ubar(i,j,k,bi,bj) - cDopp(i,j)
488 supp(i,j,k) = 1/( 1 + 4*umc(i,j,k)**2/urms(i,j,1)**2 )
489 K3D(i,j,k,bi,bj) = GM_K3D_gamma*urms(i,j,k)
490 & *Rmix(i,j)*supp(i,j,k)
491 ENDIF
492
493 C Enforce lower and upper bounds on the diffusivity
494 IF (K3D(i,j,k,bi,bj).LT.GM_K3D_smallK)
495 & K3D(i,j,k,bi,bj) = GM_K3D_smallK
496 IF (K3D(i,j,k,bi,bj).GT.GM_maxK3D)
497 & K3D(i,j,k,bi,bj) = GM_maxK3D
498 ENDIF
499 ENDIF
500 ENDDO
501 ENDDO
502 ENDDO
503
504 C ======================================
505 C Find the PV gradient
506 C ======================================
507 C Calculate the surface layer thickness.
508 C Use hMixLayer (calculated in model/src/calc_oce_mxlayer)
509 C for the mixed layer depth.
510
511 C Enforce a minimum surface layer depth
512 DO j=1-Oly,sNy+Oly
513 DO i=1-Olx,sNx+Olx
514 surfkz(i,j) = MIN(-GM_K3D_surfMinDepth,-hMixLayer(i,j,bi,bj))
515 surfkz(i,j) = MAX(surfkz(i,j),R_low(i,j,bi,bj))
516 IF(maskC(i,j,1,bi,bj).EQ.0.0) surfkz(i,j)=0.0
517 surfk(i,j) = 0
518 ENDDO
519 ENDDO
520 DO k=1,Nr
521 DO j=1-Oly,sNy+Oly
522 DO i=1-Olx,sNx+Olx
523 IF (rF(k).GT.surfkz(i,j) .AND. surfkz(i,j).GE.rF(k+1))
524 & surfk(i,j) = k
525 ENDDO
526 ENDDO
527 ENDDO
528
529 C Calculate the isopycnal slope
530 DO j=1-Oly,sNy+Oly-1
531 DO i=1-Olx,sNx+Olx-1
532 SlopeX(i,j,1) = zeroRL
533 SlopeY(i,j,1) = zeroRL
534 ENDDO
535 ENDDO
536 DO k=2,Nr
537 DO j=1-Oly+1,sNy+Oly
538 DO i=1-Olx+1,sNx+Olx
539 IF(surfk(i,j).GE.kLowC(i,j,bi,bj)) THEN
540 C If the surface layer is thinner than the water column
541 C the set the slope to zero to avoid problems.
542 SlopeX(i,j,k) = zeroRL
543 SlopeY(i,j,k) = zeroRL
544
545 ELSE
546 C Calculate the zonal slope at the western cell face (U grid)
547 sigz = MIN( op5*(sigmaR(i,j,k)+sigmaR(i-1,j,k)), maxDRhoDz )
548 sigx = op5*( sigmaX(i,j,k)+sigmaX(i,j,k-1) )
549 slope = sigx/sigz
550 C IF(ABS(slope).GT.GM_K3D_maxSlope)
551 C & slope = SIGN(GM_K3D_maxSlope,slope)
552 IF(ABS(slope).GT.GM_maxSlope)
553 & slope = SIGN(GM_maxSlope,slope)
554 SlopeX(i,j,k)=-maskW(i,j,k-1,bi,bj)*maskW(i,j,k,bi,bj)*slope
555
556 C Calculate the meridional slope at the southern cell face (V grid)
557 sigz = MIN( op5*(sigmaR(i,j,k)+sigmaR(i,j-1,k)), maxDRhoDz )
558 sigy = op5*( sigmaY(i,j,k) + sigmaY(i,j,k-1) )
559 slope = sigy/sigz
560 C IF(ABS(slope).GT.GM_K3D_maxSlope)
561 C & slope = SIGN(GM_K3D_maxSlope,slope)
562 IF(ABS(slope).GT.GM_maxSlope)
563 & slope = SIGN(GM_maxSlope,slope)
564 SlopeY(i,j,k)=-maskS(i,j,k-1,bi,bj)*maskS(i,j,k,bi,bj)*slope
565 ENDIF
566 ENDDO
567 ENDDO
568 ENDDO
569
570 C Calculate the thickness flux
571 C Enforce a zero slope bottom boundary condition for the bottom most cells (k=Nr)
572 k=Nr
573 DO j=1-Oly,sNy+Oly
574 DO i=1-Olx,sNx+Olx
575 C Zonal thickness flux at the western cell face
576 tfluxX(i,j,k) = -fCoriU(i,j)*SlopeX(i,j,k)
577 & *recip_drF(k)*recip_hFacW(i,j,k,bi,bj)
578 C Meridional thickness flux at the southern cell face
579 tfluxY(i,j,k) = -fCoriV(i,j)*SlopeY(i,j,k)
580 & *recip_drF(k)*recip_hFacS(i,j,k,bi,bj)
581 ENDDO
582 ENDDO
583
584 C Calculate the thickness flux for other cells (k<Nr)
585 C SlopeX and SlopeY are zero in dry cells, so, the bottom boundary
586 C condition that the slope is zero is taken care of.
587 C We still need to give special treatment for the surface layer however.
588 DO k=Nr-1,1,-1
589 DO j=1-Oly,sNy+Oly-1
590 DO i=1-Olx,sNx+Olx-1
591 IF(k.LE.surfk(i,j) .AND. .NOT. GM_K3D_likeGM) THEN
592 C We are in the surface layer, so set the thickness flux
593 C based on the average slope over the surface layer
594 C If we are on the edge of a "cliff" the surface layer at the
595 C centre of the grid point could be deeper than the U or V point.
596 C So, we ensure that we always take a sensible slope.
597 IF(kLow_U(i,j).LT.surfk(i,j)) THEN
598 kk=kLow_U(i,j)
599 hsurf = -rLowW(i,j,bi,bj)
600 ELSE
601 kk=surfk(i,j)
602 hsurf = -surfkz(i,j)
603 ENDIF
604 IF(kk.GT.0) THEN
605 IF(kk.EQ.Nr) THEN
606 tfluxX(i,j,k) = -fCoriU(i,j)*maskW(i,j,k,bi,bj)
607 & *SlopeX(i,j,kk)/hsurf
608 ELSE
609 tfluxX(i,j,k) = -fCoriU(i,j)*maskW(i,j,k,bi,bj)
610 & *( SlopeX(i,j,kk)-SlopeX(i,j,kk+1) )/hsurf
611 ENDIF
612 ELSE
613 tfluxX(i,j,k) = zeroRL
614 ENDIF
615
616 IF(kLow_V(i,j).LT.surfk(i,j)) THEN
617 kk=kLow_V(i,j)
618 hsurf = -rLowS(i,j,bi,bj)
619 ELSE
620 kk=surfk(i,j)
621 hsurf = -surfkz(i,j)
622 ENDIF
623 IF(kk.GT.0) THEN
624 IF(kk.EQ.Nr) THEN
625 tfluxY(i,j,k) = -fCoriV(i,j)*maskS(i,j,k,bi,bj)
626 & *SlopeY(i,j,kk)/hsurf
627 ELSE
628 tfluxY(i,j,k) = -fCoriV(i,j)*maskS(i,j,k,bi,bj)
629 & *( SlopeY(i,j,kk)-SlopeY(i,j,kk+1) )/hsurf
630 ENDIF
631 ELSE
632 tfluxY(i,j,k) = zeroRL
633 ENDIF
634
635 ELSE
636 C We are not in the surface layer, so calculate the thickness
637 C flux based on the local isopyncal slope
638
639 C Zonal thickness flux at the western cell face
640 tfluxX(i,j,k)=-fCoriU(i,j)*(SlopeX(i,j,k)-SlopeX(i,j,k+1))
641 & *recip_drF(k)*recip_hFacW(i,j,k,bi,bj)
642 & *maskW(i,j,k,bi,bj)
643
644 C Meridional thickness flux at the southern cell face
645 tfluxY(i,j,k)=-fCoriV(i,j)*(SlopeY(i,j,k)-SlopeY(i,j,k+1))
646 & *recip_drF(k)*recip_hFacS(i,j,k,bi,bj)
647 & *maskS(i,j,k,bi,bj)
648 ENDIF
649 ENDDO
650 ENDDO
651 ENDDO
652
653 C Calculate gradq
654 IF (GM_K3D_likeGM .OR. GM_K3D_beta_eq_0) THEN
655 C Ignore beta in the calculation of grad(q)
656 DO k=1,Nr
657 DO j=1-Oly+1,sNy+Oly
658 DO i=1-Olx+1,sNx+Olx
659 gradqx(i,j,k) = maskW(i,j,k,bi,bj)*tfluxX(i,j,k)
660 gradqy(i,j,k) = maskS(i,j,k,bi,bj)*tfluxY(i,j,k)
661 ENDDO
662 ENDDO
663 ENDDO
664
665 ELSE
666 C Do not ignore beta
667 DO k=1,Nr
668 DO j=1-Oly+1,sNy+Oly
669 DO i=1-Olx+1,sNx+Olx
670 gradqx(i,j,k) = maskW(i,j,k,bi,bj)*(dfdx(i,j)+tfluxX(i,j,k))
671 gradqy(i,j,k) = maskS(i,j,k,bi,bj)*(dfdy(i,j)+tfluxY(i,j,k))
672 ENDDO
673 ENDDO
674 ENDDO
675 ENDIF
676
677 C ======================================
678 C Find Xi and the eddy induced velocities
679 C ======================================
680 C Find the buoyancy frequency at the west and south faces of a cell
681 C This is necessary to find the eigenvectors at those points
682 DO k=1,Nr
683 DO j=1-Oly+1,sNy+Oly
684 DO i=1-Olx+1,sNx+Olx
685 N2W(i,j,k) = maskW(i,j,k,bi,bj)
686 & *( N2(i,j,k)+N2(i-1,j,k) )
687 N2S(i,j,k) = maskS(i,j,k,bi,bj)
688 & *( N2(i,j,k)+N2(i,j-1,k) )
689 ENDDO
690 ENDDO
691 C This fudge is necessary to avoid division by zero in gmredi_calc_eigs.
692 C It does not affect the end result since it is in the overlap region.
693 j=1-Oly
694 DO i=1-Olx,sNx+Olx
695 N2W(i,j,k) = GM_K3D_minN2
696 N2S(i,j,k) = GM_K3D_minN2
697 ENDDO
698 i=1-Olx
699 DO j=1-Oly,sNy+Oly
700 N2W(i,j,k) = GM_K3D_minN2
701 N2S(i,j,k) = GM_K3D_minN2
702 ENDDO
703 ENDDO
704
705 IF(GM_K3D_likeGM) THEN
706 DO k=1,Nr
707 DO j=1-Oly,sNy+Oly
708 DO i=1-Olx,sNx+Olx
709 KPV(i,j,k) = GM_K3D_constK
710 ENDDO
711 ENDDO
712 ENDDO
713 ELSE
714 DO k=1,Nr
715 DO j=1-Oly,sNy+Oly
716 DO i=1-Olx,sNx+Olx
717 KPV(i,j,k) = K3D(i,j,k,bi,bj)
718 ENDDO
719 ENDDO
720 ENDDO
721 ENDIF
722
723 IF (.NOT. GM_K3D_smooth) THEN
724 C Do not expand K grad(q) => no smoothing
725 C May only be done with a constant K, otherwise the
726 C integral constraint is violated.
727 DO k=1,Nr
728 DO j=1-Oly,sNy+Oly
729 DO i=1-Olx,sNx+Olx
730 Xix(i,j,k) = -maskW(i,j,k,bi,bj)*KPV(i,j,k)*gradqx(i,j,k)
731 Xiy(i,j,k) = -maskS(i,j,k,bi,bj)*KPV(i,j,k)*gradqy(i,j,k)
732 ENDDO
733 ENDDO
734 ENDDO
735
736 ELSE
737 C Expand K grad(q) in terms of baroclinic modes to smooth
738 C and satisfy the integral constraint
739
740 C Start with the X direction
741 C ------------------------------
742 C Calculate the eigenvectors at the West face of a cell
743 IF (update_modes) THEN
744 CALL GMREDI_CALC_EIGS(
745 I iMin,iMax,jMin,jMax,bi,bj,N2W,myThid,
746 I kLow_U,maskW(:,:,:,bi,bj),
747 I hfacW(:,:,:,bi,bj),recip_hfacW(:,:,:,bi,bj),
748 I rLowW(:,:,bi,bj),GM_K3D_NModes,.FALSE.,
749 O dummy,modesW(:,:,:,:,bi,bj))
750 ENDIF
751
752 C Calculate Xi_m at the west face of a cell
753 DO j=1-Oly,sNy+Oly
754 DO i=1-Olx,sNx+Olx
755 DO m=1,GM_K3D_NModes
756 XimX(m,i,j) = zeroRL
757 ENDDO
758 ENDDO
759 ENDDO
760 DO k=1,Nr
761 DO j=1-Oly,sNy+Oly
762 DO i=1-Olx,sNx+Olx
763 DO m=1,GM_K3D_NModes
764 XimX(m,i,j) = XimX(m,i,j)
765 & - maskW(i,j,k,bi,bj)*drF(k)*hfacW(i,j,k,bi,bj)
766 & *KPV(i,j,k)*gradqx(i,j,k)*modesW(m,i,j,k,bi,bj)
767 ENDDO
768 ENDDO
769 ENDDO
770 ENDDO
771
772 C Calculate Xi in the X direction at the west face
773 DO k=1,Nr
774 DO j=1-Oly,sNy+Oly
775 DO i=1-Olx,sNx+Olx
776 Xix(i,j,k) = zeroRL
777 ENDDO
778 ENDDO
779 ENDDO
780 DO k=1,Nr
781 DO j=1-Oly,sNy+Oly
782 DO i=1-Olx,sNx+Olx
783 DO m=1,GM_K3D_NModes
784 Xix(i,j,k) = Xix(i,j,k)
785 & + maskW(i,j,k,bi,bj)*XimX(m,i,j)*modesW(m,i,j,k,bi,bj)
786 ENDDO
787 ENDDO
788 ENDDO
789 ENDDO
790
791 C Now the Y direction
792 C ------------------------------
793 C Calculate the eigenvectors at the West face of a cell
794 IF (update_modes) THEN
795 CALL GMREDI_CALC_EIGS(
796 I iMin,iMax,jMin,jMax,bi,bj,N2S,myThid,
797 I kLow_V,maskS(:,:,:,bi,bj),
798 I hfacS(:,:,:,bi,bj),recip_hfacS(:,:,:,bi,bj),
799 I rLowS(:,:,bi,bj), GM_K3D_NModes, .FALSE.,
800 O dummy,modesS(:,:,:,:,bi,bj))
801 ENDIF
802
803 DO j=1-Oly,sNy+Oly
804 DO i=1-Olx,sNx+Olx
805 DO m=1,GM_K3D_NModes
806 XimY(m,i,j) = zeroRL
807 ENDDO
808 ENDDO
809 ENDDO
810 DO k=1,Nr
811 DO j=1-Oly,sNy+Oly
812 DO i=1-Olx,sNx+Olx
813 DO m=1,GM_K3D_NModes
814 XimY(m,i,j) = XimY(m,i,j)
815 & - drF(k)*hfacS(i,j,k,bi,bj)
816 & *KPV(i,j,k)*gradqy(i,j,k)*modesS(m,i,j,k,bi,bj)
817 ENDDO
818 ENDDO
819 ENDDO
820 ENDDO
821
822 C Calculate Xi for Y direction at the south face
823 DO k=1,Nr
824 DO j=1-Oly,sNy+Oly
825 DO i=1-Olx,sNx+Olx
826 Xiy(i,j,k) = zeroRL
827 ENDDO
828 ENDDO
829 ENDDO
830 DO k=1,Nr
831 DO j=1-Oly,sNy+Oly
832 DO i=1-Olx,sNx+Olx
833 DO m=1,GM_K3D_NModes
834 Xiy(i,j,k) = Xiy(i,j,k)
835 & + maskS(i,j,k,bi,bj)*XimY(m,i,j)*modesS(m,i,j,k,bi,bj)
836 ENDDO
837 ENDDO
838 ENDDO
839 ENDDO
840
841 C ENDIF GM_K3D_likeGM
842 ENDIF
843
844
845 C Calculate the eddy induced velocity in the X direction at the west face
846 DO k=1,Nr
847 DO j=1-Oly+1,sNy+Oly
848 DO i=1-Olx+1,sNx+Olx
849 ustar(i,j,k) = -Xix(i,j,k)/coriU(i,j)
850 ENDDO
851 ENDDO
852 ENDDO
853
854 C Calculate the eddy induced velocity in the Y direction at the south face
855 DO k=1,Nr
856 DO j=1-Oly+1,sNy+Oly
857 DO i=1-Olx+1,sNx+Olx
858 vstar(i,j,k) = -Xiy(i,j,k)/coriV(i,j)
859 ENDDO
860 ENDDO
861 ENDDO
862
863 C ======================================
864 C Calculate the eddy induced overturning streamfunction
865 C ======================================
866 #ifdef GM_K3D_PASSIVE
867 k=Nr
868 DO j=1-Oly,sNy+Oly
869 DO i=1-Olx,sNx+Olx
870 psistar(i,j,Nr) = -hfacS(i,j,k,bi,bj)*drF(k)*vstar(i,j,k)
871 ENDDO
872 ENDDO
873 DO k=Nr-1,1,-1
874 DO j=1-Oly,sNy+Oly
875 DO i=1-Olx,sNx+Olx
876 psistar(i,j,k) = psistar(i,j,k+1)
877 & - hfacS(i,j,k,bi,bj)*drF(k)*vstar(i,j,k)
878 ENDDO
879 ENDDO
880 ENDDO
881
882 #else
883
884 IF (GM_AdvForm) THEN
885 k=Nr
886 DO j=1-Oly+1,sNy+1
887 DO i=1-Olx+1,sNx+1
888 GM_PsiX(i,j,k,bi,bj) = -hfacW(i,j,k,bi,bj)*drF(k)*ustar(i,j,k)
889 GM_PsiY(i,j,k,bi,bj) = -hfacS(i,j,k,bi,bj)*drF(k)*vstar(i,j,k)
890 ENDDO
891 ENDDO
892 DO k=Nr-1,1,-1
893 DO j=1-Oly+1,sNy+1
894 DO i=1-Olx+1,sNx+1
895 GM_PsiX(i,j,k,bi,bj) = GM_PsiX(i,j,k+1,bi,bj)
896 & - hfacW(i,j,k,bi,bj)*drF(k)*ustar(i,j,k)
897 GM_PsiY(i,j,k,bi,bj) = GM_PsiY(i,j,k+1,bi,bj)
898 & - hfacS(i,j,k,bi,bj)*drF(k)*vstar(i,j,k)
899 ENDDO
900 ENDDO
901 ENDDO
902
903 ENDIF
904 #endif
905
906 #ifdef ALLOW_DIAGNOSTICS
907 C Diagnostics
908 IF ( useDiagnostics ) THEN
909 CALL DIAGNOSTICS_FILL(K3D, 'GM_K3D ',0,Nr,0,1,1,myThid)
910 CALL DIAGNOSTICS_FILL(urms, 'GM_URMS ',0,Nr,0,1,1,myThid)
911 CALL DIAGNOSTICS_FILL(Rdef, 'GM_RDEF ',0, 1,0,1,1,myThid)
912 CALL DIAGNOSTICS_FILL(Rurms, 'GM_RURMS',0, 1,0,1,1,myThid)
913 CALL DIAGNOSTICS_FILL(RRhines,'GM_RRHNS',0, 1,0,1,1,myThid)
914 CALL DIAGNOSTICS_FILL(Rmix, 'GM_RMIX ',0, 1,0,1,1,myThid)
915 CALL DIAGNOSTICS_FILL(supp, 'GM_SUPP ',0,Nr,0,1,1,myThid)
916 CALL DIAGNOSTICS_FILL(Xix, 'GM_Xix ',0,Nr,0,1,1,myThid)
917 CALL DIAGNOSTICS_FILL(Xiy, 'GM_Xiy ',0,Nr,0,1,1,myThid)
918 CALL DIAGNOSTICS_FILL(cDopp, 'GM_C ',0, 1,0,1,1,myThid)
919 CALL DIAGNOSTICS_FILL(Ubaro, 'GM_UBARO',0, 1,0,1,1,myThid)
920 CALL DIAGNOSTICS_FILL(eady, 'GM_EADY ',0, 1,0,1,1,myThid)
921 CALL DIAGNOSTICS_FILL(SlopeX, 'GM_Sx ',0,Nr,0,1,1,myThid)
922 CALL DIAGNOSTICS_FILL(SlopeY, 'GM_Sy ',0,Nr,0,1,1,myThid)
923 CALL DIAGNOSTICS_FILL(tfluxX, 'GM_TFLXX',0,Nr,0,1,1,myThid)
924 CALL DIAGNOSTICS_FILL(tfluxY, 'GM_TFLXY',0,Nr,0,1,1,myThid)
925 CALL DIAGNOSTICS_FILL(gradqx, 'GM_dqdx ',0,Nr,0,1,1,myThid)
926 CALL DIAGNOSTICS_FILL(gradqy, 'GM_dqdy ',0,Nr,0,1,1,myThid)
927 CALL DIAGNOSTICS_FILL(surfkz, 'GM_SFLYR',0, 1,0,1,1,myThid)
928 CALL DIAGNOSTICS_FILL(ustar, 'GM_USTAR',0,Nr,0,1,1,myThid)
929 CALL DIAGNOSTICS_FILL(vstar, 'GM_VSTAR',0,Nr,0,1,1,myThid)
930 CALL DIAGNOSTICS_FILL(umc, 'GM_UMC ',0,Nr,0,1,1,myThid)
931 CALL DIAGNOSTICS_FILL(ubar, 'GM_UBAR ',0,Nr,0,1,1,myThid)
932 CALL DIAGNOSTICS_FILL(modesC(1,:,:,:,bi,bj),
933 & 'GM_MODEC',0,Nr,0,1,1,myThid)
934 ENDIF
935 #endif
936
937 #endif /* GM_K3D */
938 RETURN
939 END

  ViewVC Help
Powered by ViewVC 1.1.22