/[MITgcm]/MITgcm/pkg/kpp/kpp_calc.F
ViewVC logotype

Contents of /MITgcm/pkg/kpp/kpp_calc.F

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


Revision 1.36 - (show annotations) (download)
Mon Apr 23 20:46:49 2007 UTC (17 years, 1 month ago) by dimitri
Branch: MAIN
Changes since 1.35: +30 -5 lines
o bug fixes for vertical diffusivity computations when both KPP and
    3D diffusivity arrays are used.

1 C $Header: /u/gcmpack/MITgcm/pkg/kpp/kpp_calc.F,v 1.35 2007/04/19 15:49:11 mlosch Exp $
2 C $Name: $
3
4 #include "KPP_OPTIONS.h"
5
6 CBOP
7 C !ROUTINE: KPP_CALC
8
9 C !INTERFACE: ==========================================================
10 subroutine KPP_CALC(
11 I bi, bj, myTime, myThid )
12
13 C !DESCRIPTION: \bv
14 C /==========================================================\
15 C | SUBROUTINE KPP_CALC |
16 C | o Compute all KPP fields defined in KPP.h |
17 C |==========================================================|
18 C | This subroutine serves as an interface between MITGCMUV |
19 C | code and NCOM 1-D routines in kpp_routines.F |
20 C \==========================================================/
21 IMPLICIT NONE
22
23 c=======================================================================
24 c
25 c written by : jan morzel, august 11, 1994
26 c modified by : jan morzel, january 25, 1995 : "dVsq" and 1d code
27 c detlef stammer, august, 1997 : for MIT GCM Classic
28 c d. menemenlis, july, 1998 : for MIT GCM UV
29 c
30 c compute vertical mixing coefficients based on the k-profile
31 c and oceanic planetary boundary layer scheme by large & mcwilliams.
32 c
33 c summary:
34 c - compute interior mixing everywhere:
35 c interior mixing gets computed at all interfaces due to constant
36 c internal wave background activity ("fkpm" and "fkph"), which
37 c is enhanced in places of static instability (local richardson
38 c number < 0).
39 c Additionally, mixing can be enhanced by adding contribution due
40 c to shear instability which is a function of the local richardson
41 c number
42 c - double diffusivity:
43 c interior mixing can be enhanced by double diffusion due to salt
44 c fingering and diffusive convection (ifdef "kmixdd").
45 c - kpp scheme in the boundary layer:
46 c
47 c a.boundary layer depth:
48 c at every gridpoint the depth of the oceanic boundary layer
49 c ("hbl") gets computed by evaluating bulk richardson numbers.
50 c b.boundary layer mixing:
51 c within the boundary layer, above hbl, vertical mixing is
52 c determined by turbulent surface fluxes, and interior mixing at
53 c the lower boundary, i.e. at hbl.
54 c
55 c this subroutine provides the interface between the MIT GCM UV and the
56 c subroutine "kppmix", where boundary layer depth, vertical
57 c viscosity, vertical diffusivity, and counter gradient term (ghat)
58 c are computed slabwise.
59 c note: subroutine "kppmix" uses m-k-s units.
60 c
61 c time level:
62 c input tracer and velocity profiles are evaluated at time level
63 c tau, surface fluxes come from tau or tau-1.
64 c
65 c grid option:
66 c in this "1-grid" implementation, diffusivity and viscosity
67 c profiles are computed on the "t-grid" (by using velocity shear
68 c profiles averaged from the "u,v-grid" onto the "t-grid"; note, that
69 c the averaging includes zero values on coastal and seafloor grid
70 c points). viscosity on the "u,v-grid" is computed by averaging the
71 c "t-grid" viscosity values onto the "u,v-grid".
72 c
73 c vertical grid:
74 c mixing coefficients get evaluated at the bottom of the lowest
75 c layer, i.e., at depth zw(Nr). these values are only useful when
76 c the model ocean domain does not include the entire ocean down to
77 c the seafloor ("upperocean" setup) and allows flux through the
78 c bottom of the domain. for full-depth runs, these mixing
79 c coefficients are being zeroed out before leaving this subroutine.
80 c
81 c-------------------------------------------------------------------------
82
83 c global parameters updated by kpp_calc
84 c KPPviscAz - KPP eddy viscosity coefficient (m^2/s)
85 c KPPdiffKzT - KPP diffusion coefficient for temperature (m^2/s)
86 c KPPdiffKzS - KPP diffusion coefficient for salt and tracers (m^2/s)
87 c KPPghat - Nonlocal transport coefficient (s/m^2)
88 c KPPhbl - Boundary layer depth on "t-grid" (m)
89 c KPPfrac - Fraction of short-wave flux penetrating mixing layer
90
91 c-- KPP_CALC computes vertical viscosity and diffusivity for region
92 c (-2:sNx+3,-2:sNy+3) as required by CALC_DIFFUSIVITY and requires
93 c values of uVel, vVel, surfaceForcingU, surfaceForcingV in the
94 c region (-2:sNx+4,-2:sNy+4).
95 c Hence overlap region needs to be set OLx=4, OLy=4.
96 c \ev
97
98 C !USES: ===============================================================
99 #include "SIZE.h"
100 #include "EEPARAMS.h"
101 #include "PARAMS.h"
102 #include "DYNVARS.h"
103 #include "KPP.h"
104 #include "KPP_PARAMS.h"
105 #include "FFIELDS.h"
106 #include "GRID.h"
107 #include "GAD.h"
108 #ifdef ALLOW_SHELFICE
109 # include "SHELFICE.h"
110 #endif /* ALLOW_SHELFICE */
111 #ifdef ALLOW_AUTODIFF_TAMC
112 #include "tamc.h"
113 #include "tamc_keys.h"
114 #else /* ALLOW_AUTODIFF_TAMC */
115 integer ikppkey
116 #endif /* ALLOW_AUTODIFF_TAMC */
117
118 EXTERNAL DIFFERENT_MULTIPLE
119 LOGICAL DIFFERENT_MULTIPLE
120
121 C !INPUT PARAMETERS: ===================================================
122 c Routine arguments
123 c bi, bj - array indices on which to apply calculations
124 c myTime - Current time in simulation
125
126 INTEGER bi, bj
127 INTEGER myThid
128 _RL myTime
129
130 #ifdef ALLOW_KPP
131
132 C !LOCAL VARIABLES: ====================================================
133 c Local constants
134 c minusone, p0, p5, p25, p125, p0625
135 c imin, imax, jmin, jmax - array computation indices
136
137 _RL minusone
138 parameter( minusone=-1.0)
139 _KPP_RL p0 , p5 , p25 , p125 , p0625
140 parameter( p0=0.0, p5=0.5, p25=0.25, p125=0.125, p0625=0.0625 )
141 integer imin ,imax ,jmin ,jmax
142 parameter(imin=2-OLx,imax=sNx+OLx-1,jmin=2-OLy,jmax=sNy+OLy-1)
143
144 c Local arrays and variables
145 c work? (nx,ny) - horizontal working arrays
146 c ustar (nx,ny) - surface friction velocity (m/s)
147 c bo (nx,ny) - surface turbulent buoyancy forcing (m^2/s^3)
148 c bosol (nx,ny) - surface radiative buoyancy forcing (m^2/s^3)
149 c shsq (nx,ny,Nr) - local velocity shear squared
150 c at interfaces for ri_iwmix (m^2/s^2)
151 c dVsq (nx,ny,Nr) - velocity shear re surface squared
152 c at grid levels for bldepth (m^2/s^2)
153 c dbloc (nx,ny,Nr) - local delta buoyancy at interfaces
154 c for ri_iwmix and bldepth (m/s^2)
155 c Ritop (nx,ny,Nr) - numerator of bulk richardson number
156 c at grid levels for bldepth
157 c vddiff (nx,ny,Nrp2,1)- vertical viscosity on "t-grid" (m^2/s)
158 c vddiff (nx,ny,Nrp2,2)- vert. diff. on next row for salt&tracers (m^2/s)
159 c vddiff (nx,ny,Nrp2,3)- vert. diff. on next row for temperature (m^2/s)
160 c ghat (nx,ny,Nr) - nonlocal transport coefficient (s/m^2)
161 c hbl (nx,ny) - mixing layer depth (m)
162 c kmtj (nx,ny) - maximum number of wet levels in each column
163 c z0 (nx,ny) - Roughness length (m)
164 c zRef (nx,ny) - Reference depth: Hmix * epsilon (m)
165 c uRef (nx,ny) - Reference zonal velocity (m/s)
166 c vRef (nx,ny) - Reference meridional velocity (m/s)
167
168 _RL worka ( 1-OLx:sNx+OLx, 1-OLy:sNy+OLy )
169 integer work1 ( 1-OLx:sNx+OLx, 1-OLy:sNy+OLy )
170 _KPP_RL work2 ( 1-OLx:sNx+OLx, 1-OLy:sNy+OLy )
171 _KPP_RL work3 ( 1-OLx:sNx+OLx, 1-OLy:sNy+OLy )
172 _KPP_RL ustar ( 1-OLx:sNx+OLx, 1-OLy:sNy+OLy )
173 _KPP_RL bo ( 1-OLx:sNx+OLx, 1-OLy:sNy+OLy )
174 _KPP_RL bosol ( 1-OLx:sNx+OLx, 1-OLy:sNy+OLy )
175 _KPP_RL shsq ( 1-OLx:sNx+OLx, 1-OLy:sNy+OLy, Nr )
176 _KPP_RL dVsq ( 1-OLx:sNx+OLx, 1-OLy:sNy+OLy, Nr )
177 _KPP_RL dbloc ( 1-OLx:sNx+OLx, 1-OLy:sNy+OLy, Nr )
178 _KPP_RL Ritop ( 1-OLx:sNx+OLx, 1-OLy:sNy+OLy, Nr )
179 _KPP_RL vddiff( 1-OLx:sNx+OLx, 1-OLy:sNy+OLy, 0:Nrp1, mdiff )
180 _KPP_RL ghat ( 1-OLx:sNx+OLx, 1-OLy:sNy+OLy, Nr )
181 _KPP_RL hbl ( 1-OLx:sNx+OLx, 1-OLy:sNy+OLy )
182 cph(
183 _KPP_RL TTALPHA( 1-OLx:sNx+OLx, 1-OLy:sNy+OLy, Nrp1 )
184 _KPP_RL SSBETA ( 1-OLx:sNx+OLx, 1-OLy:sNy+OLy, Nrp1 )
185 cph)
186 #ifdef KPP_ESTIMATE_UREF
187 _KPP_RL z0 ( 1-OLx:sNx+OLx, 1-OLy:sNy+OLy )
188 _KPP_RL zRef ( 1-OLx:sNx+OLx, 1-OLy:sNy+OLy )
189 _KPP_RL uRef ( 1-OLx:sNx+OLx, 1-OLy:sNy+OLy )
190 _KPP_RL vRef ( 1-OLx:sNx+OLx, 1-OLy:sNy+OLy )
191 #endif /* KPP_ESTIMATE_UREF */
192
193 _KPP_RL tempvar2
194 integer i, j, k, kp1, km1, im1, ip1, jm1, jp1
195
196 #ifdef KPP_ESTIMATE_UREF
197 _KPP_RL tempvar1, dBdz1, dBdz2, ustarX, ustarY
198 #endif
199
200 #ifdef ALLOW_AUTODIFF_TAMC
201 act1 = bi - myBxLo(myThid)
202 max1 = myBxHi(myThid) - myBxLo(myThid) + 1
203 act2 = bj - myByLo(myThid)
204 max2 = myByHi(myThid) - myByLo(myThid) + 1
205 act3 = myThid - 1
206 max3 = nTx*nTy
207 act4 = ikey_dynamics - 1
208 ikppkey = (act1 + 1) + act2*max1
209 & + act3*max1*max2
210 & + act4*max1*max2*max3
211 #endif /* ALLOW_AUTODIFF_TAMC */
212 CEOP
213
214 c Check to see if new vertical mixing coefficient should be computed now?
215 IF ( DIFFERENT_MULTIPLE(kpp_freq,myTime,deltaTClock)
216 1 .OR. myTime .EQ. startTime ) THEN
217
218 c-----------------------------------------------------------------------
219 c prepare input arrays for subroutine "kppmix" to compute
220 c viscosity and diffusivity and ghat.
221 c All input arrays need to be in m-k-s units.
222 c
223 c note: for the computation of the bulk richardson number in the
224 c "bldepth" subroutine, gradients of velocity and buoyancy are
225 c required at every depth. in the case of very fine vertical grids
226 c (thickness of top layer < 2m), the surface reference depth must
227 c be set to zref=epsilon/2*zgrid(k), and the reference value
228 c of velocity and buoyancy must be computed as vertical average
229 c between the surface and 2*zref. in the case of coarse vertical
230 c grids zref is zgrid(1)/2., and the surface reference value is
231 c simply the surface value at zgrid(1).
232 c-----------------------------------------------------------------------
233
234 c------------------------------------------------------------------------
235 c density related quantities
236 c --------------------------
237 c
238 c work2 - density of surface layer (kg/m^3)
239 c dbloc - local buoyancy gradient at Nr interfaces
240 c g/rho{k+1,k+1} * [ drho{k,k+1}-drho{k+1,k+1} ] (m/s^2)
241 c dbsfc (stored in Ritop to conserve stack memory)
242 c - buoyancy difference with respect to the surface
243 c g * [ drho{1,k}/rho{1,k} - drho{k,k}/rho{k,k} ] (m/s^2)
244 c ttalpha (stored in vddiff(:,:,:,1) to conserve stack memory)
245 c - thermal expansion coefficient without 1/rho factor
246 c d(rho{k,k})/d(T(k)) (kg/m^3/C)
247 c ssbeta (stored in vddiff(:,:,:,2) to conserve stack memory)
248 c - salt expansion coefficient without 1/rho factor
249 c d(rho{k,k})/d(S(k)) (kg/m^3/PSU)
250 c------------------------------------------------------------------------
251
252 CALL TIMER_START('STATEKPP [KPP_CALC]', myThid)
253 CALL STATEKPP(
254 I ikppkey, bi, bj, myThid
255 O , work2, dbloc, Ritop
256 O , TTALPHA, SSBETA
257 & )
258 CALL TIMER_STOP ('STATEKPP [KPP_CALC]', myThid)
259
260 DO k = 1, Nr
261 DO j = 1-OLy, sNy+OLy
262 DO i = 1-OLx, sNx+OLx
263 ghat(i,j,k) = dbloc(i,j,k)
264 ENDDO
265 ENDDO
266 ENDDO
267
268 #ifdef KPP_SMOOTH_DBLOC
269 c horizontally smooth dbloc with a 121 filter
270 c smooth dbloc stored in ghat to save space
271 c dbloc(k) is buoyancy gradientnote between k and k+1
272 c levels therefore k+1 mask must be used
273
274 DO k = 1, Nr-1
275 CALL KPP_SMOOTH_HORIZ (
276 I k+1, bi, bj,
277 U ghat (1-OLx,1-OLy,k) )
278 ENDDO
279
280 #endif /* KPP_SMOOTH_DBLOC */
281
282 #ifdef KPP_SMOOTH_DENS
283 c horizontally smooth density related quantities with 121 filters
284 CALL KPP_SMOOTH_HORIZ (
285 I 1, bi, bj,
286 U work2 )
287 DO k = 1, Nr
288 CALL KPP_SMOOTH_HORIZ (
289 I k+1, bi, bj,
290 U dbloc (1-OLx,1-OLy,k) )
291 CALL KPP_SMOOTH_HORIZ (
292 I k, bi, bj,
293 U Ritop (1-OLx,1-OLy,k) )
294 CALL KPP_SMOOTH_HORIZ (
295 I k, bi, bj,
296 U TTALPHA(1-OLx,1-OLy,k) )
297 CALL KPP_SMOOTH_HORIZ (
298 I k, bi, bj,
299 U SSBETA(1-OLx,1-OLy,k) )
300 ENDDO
301 #endif /* KPP_SMOOTH_DENS */
302
303 DO k = 1, Nr
304 km1 = max(1,k-1)
305 DO j = 1-OLy, sNy+OLy
306 DO i = 1-OLx, sNx+OLx
307
308 c zero out dbloc over land points (so that the convective
309 c part of the interior mixing can be diagnosed)
310 dbloc(i,j,k) = dbloc(i,j,k) * maskC(i,j,k,bi,bj)
311 & * maskC(i,j,km1,bi,bj)
312 ghat(i,j,k) = ghat(i,j,k) * maskC(i,j,k,bi,bj)
313 & * maskC(i,j,km1,bi,bj)
314 Ritop(i,j,k) = Ritop(i,j,k) * maskC(i,j,k,bi,bj)
315 & * maskC(i,j,km1,bi,bj)
316 if(k.eq.nzmax(i,j,bi,bj)) then
317 dbloc(i,j,k) = p0
318 ghat(i,j,k) = p0
319 Ritop(i,j,k) = p0
320 endif
321
322 c numerator of bulk richardson number on grid levels
323 c note: land and ocean bottom values need to be set to zero
324 c so that the subroutine "bldepth" works correctly
325 Ritop(i,j,k) = (zgrid(1)-zgrid(k)) * Ritop(i,j,k)
326
327 END DO
328 END DO
329 END DO
330
331 cph(
332 cph this avoids a single or double recomp./call of statekpp
333 CADJ store work2 = comlev1_kpp, key = ikppkey
334 #ifdef KPP_AUTODIFF_EXCESSIVE_STORE
335 CADJ store dbloc, Ritop, ghat = comlev1_kpp, key = ikppkey
336 CADJ store vddiff = comlev1_kpp, key = ikppkey
337 CADJ store TTALPHA, SSBETA = comlev1_kpp, key = ikppkey
338 #endif
339 cph)
340
341 c------------------------------------------------------------------------
342 c friction velocity, turbulent and radiative surface buoyancy forcing
343 c -------------------------------------------------------------------
344 c taux / rho = surfaceForcingU (N/m^2)
345 c tauy / rho = surfaceForcingV (N/m^2)
346 c ustar = sqrt( sqrt( taux^2 + tauy^2 ) / rho ) (m/s)
347 c bo = - g * ( alpha*surfaceForcingT +
348 c beta *surfaceForcingS ) / rho (m^2/s^3)
349 c bosol = - g * alpha * Qsw * drF(1) / rho (m^2/s^3)
350 c------------------------------------------------------------------------
351
352 c initialize arrays to zero
353 DO j = 1-OLy, sNy+OLy
354 DO i = 1-OLx, sNx+OLx
355 ustar(i,j) = p0
356 bo (I,J) = p0
357 bosol(I,J) = p0
358 END DO
359 END DO
360
361 DO j = jmin, jmax
362 jp1 = j + 1
363 DO i = imin, imax
364 ip1 = i+1
365 work3(i,j) =
366 & (surfaceForcingU(i,j,bi,bj) + surfaceForcingU(ip1,j,bi,bj)) *
367 & (surfaceForcingU(i,j,bi,bj) + surfaceForcingU(ip1,j,bi,bj)) +
368 & (surfaceForcingV(i,j,bi,bj) + surfaceForcingV(i,jp1,bi,bj)) *
369 & (surfaceForcingV(i,j,bi,bj) + surfaceForcingV(i,jp1,bi,bj))
370 END DO
371 END DO
372 cph(
373 CADJ store work3 = comlev1_kpp, key = ikppkey
374 cph)
375 DO j = jmin, jmax
376 jp1 = j + 1
377 DO i = imin, imax
378 ip1 = i+1
379
380 if ( work3(i,j) .lt. (phepsi*phepsi*drF(1)*drF(1)) ) then
381 ustar(i,j) = SQRT( phepsi * p5 * drF(1) )
382 else
383 tempVar2 = SQRT( work3(i,j) ) * p5
384 ustar(i,j) = SQRT( tempVar2 )
385 endif
386
387 END DO
388 END DO
389
390 CML#ifdef ALLOW_SHELFICE
391 CMLC For the pbl parameterisation to work underneath the ice shelves
392 CMLC it needs to know the surface (ice-ocean) fluxes. However, masking
393 CMLC and indexing problems make this part of the code not work
394 CMLC underneath the ice shelves and the following lines are only here
395 CMLC to remind me that this still needs to be sorted out.
396 CML IF ( useShelfIce ) THEN
397 CML DO j = jmin, jmax
398 CML jp1 = j + 1
399 CML DO i = imin, imax
400 CML ip1 = i+1
401 CML k = kTopC(I,J,bi,bj)
402 CML bo(I,J) = - gravity *
403 CML & ( TTALPHA(I,J,K) * ( maskC(I,J,1,bi,bj)
404 CML & * ( surfaceForcingT(i,j,bi,bj)
405 CML & + surfaceForcingTice(i,j,bi,bj) )
406 CML & + shelficeForcingT(i,j,bi,bj) )
407 CML & + SSBETA(I,J,K) * ( maskC(I,J,1,bi,bj)
408 CML & * surfaceForcingS(i,j,bi,bj)
409 CML & + shelficeForcingS(i,j,bi,bj) ) )
410 CML & / work2(I,J)
411 CML
412 CML bosol(I,J) = gravity * TTALPHA(I,J,1) * Qsw(i,j,bi,bj)
413 CML & * maskC(I,J,1,bi,bj) * recip_Cp*recip_rhoConst
414 CML & / work2(I,J)
415 CML
416 CML END DO
417 CML END DO
418 CML ELSE
419 CML#endif /* ALLOW_SHELFICE */
420 DO j = jmin, jmax
421 jp1 = j + 1
422 DO i = imin, imax
423 ip1 = i+1
424
425 bo(I,J) = - gravity *
426 & ( TTALPHA(I,J,1) * (surfaceForcingT(i,j,bi,bj)+
427 & surfaceForcingTice(i,j,bi,bj)) +
428 & SSBETA(I,J,1) * surfaceForcingS(i,j,bi,bj) )
429 & / work2(I,J)
430
431 bosol(I,J) = gravity * TTALPHA(I,J,1) * Qsw(i,j,bi,bj) *
432 & recip_Cp*recip_rhoConst
433 & / work2(I,J)
434
435 END DO
436 END DO
437 CML#ifdef ALLOW_SHELFICE
438 CML ENDIF
439 CML#endif /* ALLOW_SHELFICE */
440
441 cph(
442 CADJ store ustar = comlev1_kpp, key = ikppkey
443 cph)
444
445 c------------------------------------------------------------------------
446 c velocity shear
447 c --------------
448 c Get velocity shear squared, averaged from "u,v-grid"
449 c onto "t-grid" (in (m/s)**2):
450 c dVsq(k)=(Uref-U(k))**2+(Vref-V(k))**2 at grid levels
451 c shsq(k)=(U(k)-U(k+1))**2+(V(k)-V(k+1))**2 at interfaces
452 c------------------------------------------------------------------------
453
454 c initialize arrays to zero
455 DO k = 1, Nr
456 DO j = 1-OLy, sNy+OLy
457 DO i = 1-OLx, sNx+OLx
458 shsq(i,j,k) = p0
459 dVsq(i,j,k) = p0
460 END DO
461 END DO
462 END DO
463
464 c dVsq computation
465
466 #ifdef KPP_ESTIMATE_UREF
467
468 c Get rid of vertical resolution dependence of dVsq term by
469 c estimating a surface velocity that is independent of first level
470 c thickness in the model. First determine mixed layer depth hMix.
471 c Second zRef = espilon * hMix. Third determine roughness length
472 c scale z0. Third estimate reference velocity.
473
474 DO j = jmin, jmax
475 jp1 = j + 1
476 DO i = imin, imax
477 ip1 = i + 1
478
479 c Determine mixed layer depth hMix as the shallowest depth at which
480 c dB/dz exceeds 5.2e-5 s^-2.
481 work1(i,j) = nzmax(i,j,bi,bj)
482 DO k = 1, Nr
483 IF ( k .LT. nzmax(i,j,bi,bj) .AND.
484 & maskC(I,J,k,bi,bj) .GT. 0. .AND.
485 & dbloc(i,j,k) / drC(k+1) .GT. dB_dz )
486 & work1(i,j) = k
487 END DO
488
489 c Linearly interpolate to find hMix.
490 k = work1(i,j)
491 IF ( k .EQ. 0 .OR. nzmax(i,j,bi,bj) .EQ. 1 ) THEN
492 zRef(i,j) = p0
493 ELSEIF ( k .EQ. 1) THEN
494 dBdz2 = dbloc(i,j,1) / drC(2)
495 zRef(i,j) = drF(1) * dB_dz / dBdz2
496 ELSEIF ( k .LT. nzmax(i,j,bi,bj) ) THEN
497 dBdz1 = dbloc(i,j,k-1) / drC(k )
498 dBdz2 = dbloc(i,j,k ) / drC(k+1)
499 zRef(i,j) = rF(k) + drF(k) * (dB_dz - dBdz1) /
500 & MAX ( phepsi, dBdz2 - dBdz1 )
501 ELSE
502 zRef(i,j) = rF(k+1)
503 ENDIF
504
505 c Compute roughness length scale z0 subject to 0 < z0
506 tempVar1 = p5 * (
507 & (uVel(i, j, 1,bi,bj)-uVel(i, j, 2,bi,bj)) *
508 & (uVel(i, j, 1,bi,bj)-uVel(i, j, 2,bi,bj)) +
509 & (uVel(ip1,j, 1,bi,bj)-uVel(ip1,j, 2,bi,bj)) *
510 & (uVel(ip1,j, 1,bi,bj)-uVel(ip1,j, 2,bi,bj)) +
511 & (vVel(i, j, 1,bi,bj)-vVel(i, j, 2,bi,bj)) *
512 & (vVel(i, j, 1,bi,bj)-vVel(i, j, 2,bi,bj)) +
513 & (vVel(i, jp1,1,bi,bj)-vVel(i, jp1,2,bi,bj)) *
514 & (vVel(i, jp1,1,bi,bj)-vVel(i, jp1,2,bi,bj)) )
515 if ( tempVar1 .lt. (epsln*epsln) ) then
516 tempVar2 = epsln
517 else
518 tempVar2 = SQRT ( tempVar1 )
519 endif
520 z0(i,j) = rF(2) *
521 & ( rF(3) * LOG ( rF(3) / rF(2) ) /
522 & ( rF(3) - rF(2) ) -
523 & tempVar2 * vonK /
524 & MAX ( ustar(i,j), phepsi ) )
525 z0(i,j) = MAX ( z0(i,j), phepsi )
526
527 c zRef is set to 0.1 * hMix subject to z0 <= zRef <= drF(1)
528 zRef(i,j) = MAX ( epsilon * zRef(i,j), z0(i,j) )
529 zRef(i,j) = MIN ( zRef(i,j), drF(1) )
530
531 c Estimate reference velocity uRef and vRef.
532 uRef(i,j) = p5 *
533 & ( uVel(i,j,1,bi,bj) + uVel(ip1,j,1,bi,bj) )
534 vRef(i,j) = p5 *
535 & ( vVel(i,j,1,bi,bj) + vVel(i,jp1,1,bi,bj) )
536 IF ( zRef(i,j) .LT. drF(1) ) THEN
537 ustarX = ( surfaceForcingU(i, j,bi,bj) +
538 & surfaceForcingU(ip1,j,bi,bj) ) * p5
539 & *recip_drF(1)
540 ustarY = ( surfaceForcingV(i,j, bi,bj) +
541 & surfaceForcingV(i,jp1,bi,bj) ) * p5
542 & *recip_drF(1)
543 tempVar1 = ustarX * ustarX + ustarY * ustarY
544 if ( tempVar1 .lt. (epsln*epsln) ) then
545 tempVar2 = epsln
546 else
547 tempVar2 = SQRT ( tempVar1 )
548 endif
549 tempVar2 = ustar(i,j) *
550 & ( LOG ( zRef(i,j) / rF(2) ) +
551 & z0(i,j) / zRef(i,j) - z0(i,j) / rF(2) ) /
552 & vonK / tempVar2
553 uRef(i,j) = uRef(i,j) + ustarX * tempVar2
554 vRef(i,j) = vRef(i,j) + ustarY * tempVar2
555 ENDIF
556
557 END DO
558 END DO
559
560 DO k = 1, Nr
561 DO j = jmin, jmax
562 jm1 = j - 1
563 jp1 = j + 1
564 DO i = imin, imax
565 im1 = i - 1
566 ip1 = i + 1
567 dVsq(i,j,k) = p5 * (
568 $ (uRef(i,j) - uVel(i, j, k,bi,bj)) *
569 $ (uRef(i,j) - uVel(i, j, k,bi,bj)) +
570 $ (uRef(i,j) - uVel(ip1,j, k,bi,bj)) *
571 $ (uRef(i,j) - uVel(ip1,j, k,bi,bj)) +
572 $ (vRef(i,j) - vVel(i, j, k,bi,bj)) *
573 $ (vRef(i,j) - vVel(i, j, k,bi,bj)) +
574 $ (vRef(i,j) - vVel(i, jp1,k,bi,bj)) *
575 $ (vRef(i,j) - vVel(i, jp1,k,bi,bj)) )
576 #ifdef KPP_SMOOTH_DVSQ
577 dVsq(i,j,k) = p5 * dVsq(i,j,k) + p125 * (
578 $ (uRef(i,j) - uVel(i, jm1,k,bi,bj)) *
579 $ (uRef(i,j) - uVel(i, jm1,k,bi,bj)) +
580 $ (uRef(i,j) - uVel(ip1,jm1,k,bi,bj)) *
581 $ (uRef(i,j) - uVel(ip1,jm1,k,bi,bj)) +
582 $ (uRef(i,j) - uVel(i, jp1,k,bi,bj)) *
583 $ (uRef(i,j) - uVel(i, jp1,k,bi,bj)) +
584 $ (uRef(i,j) - uVel(ip1,jp1,k,bi,bj)) *
585 $ (uRef(i,j) - uVel(ip1,jp1,k,bi,bj)) +
586 $ (vRef(i,j) - vVel(im1,j, k,bi,bj)) *
587 $ (vRef(i,j) - vVel(im1,j, k,bi,bj)) +
588 $ (vRef(i,j) - vVel(im1,jp1,k,bi,bj)) *
589 $ (vRef(i,j) - vVel(im1,jp1,k,bi,bj)) +
590 $ (vRef(i,j) - vVel(ip1,j, k,bi,bj)) *
591 $ (vRef(i,j) - vVel(ip1,j, k,bi,bj)) +
592 $ (vRef(i,j) - vVel(ip1,jp1,k,bi,bj)) *
593 $ (vRef(i,j) - vVel(ip1,jp1,k,bi,bj)) )
594 #endif /* KPP_SMOOTH_DVSQ */
595 END DO
596 END DO
597 END DO
598
599 #else /* KPP_ESTIMATE_UREF */
600
601 DO k = 1, Nr
602 DO j = jmin, jmax
603 jm1 = j - 1
604 jp1 = j + 1
605 DO i = imin, imax
606 im1 = i - 1
607 ip1 = i + 1
608 dVsq(i,j,k) = p5 * (
609 $ (uVel(i, j, 1,bi,bj)-uVel(i, j, k,bi,bj)) *
610 $ (uVel(i, j, 1,bi,bj)-uVel(i, j, k,bi,bj)) +
611 $ (uVel(ip1,j, 1,bi,bj)-uVel(ip1,j, k,bi,bj)) *
612 $ (uVel(ip1,j, 1,bi,bj)-uVel(ip1,j, k,bi,bj)) +
613 $ (vVel(i, j, 1,bi,bj)-vVel(i, j, k,bi,bj)) *
614 $ (vVel(i, j, 1,bi,bj)-vVel(i, j, k,bi,bj)) +
615 $ (vVel(i, jp1,1,bi,bj)-vVel(i, jp1,k,bi,bj)) *
616 $ (vVel(i, jp1,1,bi,bj)-vVel(i, jp1,k,bi,bj)) )
617 #ifdef KPP_SMOOTH_DVSQ
618 dVsq(i,j,k) = p5 * dVsq(i,j,k) + p125 * (
619 $ (uVel(i, jm1,1,bi,bj)-uVel(i, jm1,k,bi,bj)) *
620 $ (uVel(i, jm1,1,bi,bj)-uVel(i, jm1,k,bi,bj)) +
621 $ (uVel(ip1,jm1,1,bi,bj)-uVel(ip1,jm1,k,bi,bj)) *
622 $ (uVel(ip1,jm1,1,bi,bj)-uVel(ip1,jm1,k,bi,bj)) +
623 $ (uVel(i, jp1,1,bi,bj)-uVel(i, jp1,k,bi,bj)) *
624 $ (uVel(i, jp1,1,bi,bj)-uVel(i, jp1,k,bi,bj)) +
625 $ (uVel(ip1,jp1,1,bi,bj)-uVel(ip1,jp1,k,bi,bj)) *
626 $ (uVel(ip1,jp1,1,bi,bj)-uVel(ip1,jp1,k,bi,bj)) +
627 $ (vVel(im1,j, 1,bi,bj)-vVel(im1,j, k,bi,bj)) *
628 $ (vVel(im1,j, 1,bi,bj)-vVel(im1,j, k,bi,bj)) +
629 $ (vVel(im1,jp1,1,bi,bj)-vVel(im1,jp1,k,bi,bj)) *
630 $ (vVel(im1,jp1,1,bi,bj)-vVel(im1,jp1,k,bi,bj)) +
631 $ (vVel(ip1,j, 1,bi,bj)-vVel(ip1,j, k,bi,bj)) *
632 $ (vVel(ip1,j, 1,bi,bj)-vVel(ip1,j, k,bi,bj)) +
633 $ (vVel(ip1,jp1,1,bi,bj)-vVel(ip1,jp1,k,bi,bj)) *
634 $ (vVel(ip1,jp1,1,bi,bj)-vVel(ip1,jp1,k,bi,bj)) )
635 #endif /* KPP_SMOOTH_DVSQ */
636 END DO
637 END DO
638 END DO
639
640 #endif /* KPP_ESTIMATE_UREF */
641
642 c shsq computation
643 DO k = 1, Nrm1
644 kp1 = k + 1
645 DO j = jmin, jmax
646 jm1 = j - 1
647 jp1 = j + 1
648 DO i = imin, imax
649 im1 = i - 1
650 ip1 = i + 1
651 shsq(i,j,k) = p5 * (
652 $ (uVel(i, j, k,bi,bj)-uVel(i, j, kp1,bi,bj)) *
653 $ (uVel(i, j, k,bi,bj)-uVel(i, j, kp1,bi,bj)) +
654 $ (uVel(ip1,j, k,bi,bj)-uVel(ip1,j, kp1,bi,bj)) *
655 $ (uVel(ip1,j, k,bi,bj)-uVel(ip1,j, kp1,bi,bj)) +
656 $ (vVel(i, j, k,bi,bj)-vVel(i, j, kp1,bi,bj)) *
657 $ (vVel(i, j, k,bi,bj)-vVel(i, j, kp1,bi,bj)) +
658 $ (vVel(i, jp1,k,bi,bj)-vVel(i, jp1,kp1,bi,bj)) *
659 $ (vVel(i, jp1,k,bi,bj)-vVel(i, jp1,kp1,bi,bj)) )
660 #ifdef KPP_SMOOTH_SHSQ
661 shsq(i,j,k) = p5 * shsq(i,j,k) + p125 * (
662 $ (uVel(i, jm1,k,bi,bj)-uVel(i, jm1,kp1,bi,bj)) *
663 $ (uVel(i, jm1,k,bi,bj)-uVel(i, jm1,kp1,bi,bj)) +
664 $ (uVel(ip1,jm1,k,bi,bj)-uVel(ip1,jm1,kp1,bi,bj)) *
665 $ (uVel(ip1,jm1,k,bi,bj)-uVel(ip1,jm1,kp1,bi,bj)) +
666 $ (uVel(i, jp1,k,bi,bj)-uVel(i, jp1,kp1,bi,bj)) *
667 $ (uVel(i, jp1,k,bi,bj)-uVel(i, jp1,kp1,bi,bj)) +
668 $ (uVel(ip1,jp1,k,bi,bj)-uVel(ip1,jp1,kp1,bi,bj)) *
669 $ (uVel(ip1,jp1,k,bi,bj)-uVel(ip1,jp1,kp1,bi,bj)) +
670 $ (vVel(im1,j, k,bi,bj)-vVel(im1,j, kp1,bi,bj)) *
671 $ (vVel(im1,j, k,bi,bj)-vVel(im1,j, kp1,bi,bj)) +
672 $ (vVel(im1,jp1,k,bi,bj)-vVel(im1,jp1,kp1,bi,bj)) *
673 $ (vVel(im1,jp1,k,bi,bj)-vVel(im1,jp1,kp1,bi,bj)) +
674 $ (vVel(ip1,j, k,bi,bj)-vVel(ip1,j, kp1,bi,bj)) *
675 $ (vVel(ip1,j, k,bi,bj)-vVel(ip1,j, kp1,bi,bj)) +
676 $ (vVel(ip1,jp1,k,bi,bj)-vVel(ip1,jp1,kp1,bi,bj)) *
677 $ (vVel(ip1,jp1,k,bi,bj)-vVel(ip1,jp1,kp1,bi,bj)) )
678 #endif
679 END DO
680 END DO
681 END DO
682
683 cph(
684 #ifdef KPP_AUTODIFF_EXCESSIVE_STORE
685 CADJ store dvsq, shsq = comlev1_kpp, key = ikppkey
686 #endif
687 cph)
688
689 c-----------------------------------------------------------------------
690 c solve for viscosity, diffusivity, ghat, and hbl on "t-grid"
691 c-----------------------------------------------------------------------
692
693 c precompute background vertical diffusivities, which are needed for
694 c matching diffusivities at bottom of KPP PBL
695 CALL CALC_3D_DIFFUSIVITY(
696 I bi,bj,1-Olx,sNx+OLx,1-Oly,sNy+OLy,
697 I GAD_SALINITY, .FALSE., .FALSE.,
698 O KPPdiffKzS(1-Olx,1-Oly,1,bi,bj),
699 I myThid)
700 CALL CALC_3D_DIFFUSIVITY(
701 I bi,bj,1-Olx,sNx+OLx,1-Oly,sNy+OLy,
702 I GAD_TEMPERATURE, .FALSE., .FALSE.,
703 O KPPdiffKzT(1-Olx,1-Oly,1,bi,bj),
704 I myThid)
705
706 DO j = 1-OLy, sNy+OLy
707 DO i = 1-OLx, sNx+OLx
708 work1(i,j) = nzmax(i,j,bi,bj)
709 work2(i,j) = Fcori(i,j,bi,bj)
710 END DO
711 END DO
712 CALL TIMER_START('KPPMIX [KPP_CALC]', myThid)
713 CALL KPPMIX (
714 I mytime, mythid
715 I , work1, shsq, dVsq, ustar
716 I , bo, bosol, dbloc, Ritop, work2
717 I , KPPdiffKzS(1-Olx,1-Oly,1,bi,bj)
718 I , KPPdiffKzT(1-Olx,1-Oly,1,bi,bj)
719 I , ikppkey
720 O , vddiff
721 U , ghat
722 O , hbl )
723 CALL TIMER_STOP ('KPPMIX [KPP_CALC]', myThid)
724
725 c-----------------------------------------------------------------------
726 c zero out land values and transfer to global variables
727 c-----------------------------------------------------------------------
728
729 DO j = jmin, jmax
730 DO i = imin, imax
731 DO k = 1, Nr
732 km1 = max(1,k-1)
733 KPPviscAz(i,j,k,bi,bj) = vddiff(i,j,k-1,1) * maskC(i,j,k,bi,bj)
734 & * maskC(i,j,km1,bi,bj)
735 KPPdiffKzS(i,j,k,bi,bj)= vddiff(i,j,k-1,2) * maskC(i,j,k,bi,bj)
736 & * maskC(i,j,km1,bi,bj)
737 KPPdiffKzT(i,j,k,bi,bj)= vddiff(i,j,k-1,3) * maskC(i,j,k,bi,bj)
738 & * maskC(i,j,km1,bi,bj)
739 KPPghat(i,j,k,bi,bj) = ghat(i,j,k) * maskC(i,j,k,bi,bj)
740 & * maskC(i,j,km1,bi,bj)
741 END DO
742 k = 1
743 #ifdef ALLOW_SHELFICE
744 if ( useShelfIce ) k = kTopC(i,j,bi,bj)
745 #endif /* ALLOW_SHELFICE */
746 KPPhbl(i,j,bi,bj) = hbl(i,j) * maskC(i,j,k,bi,bj)
747
748 END DO
749 END DO
750
751 #ifdef KPP_SMOOTH_VISC
752 c horizontal smoothing of vertical viscosity
753 DO k = 1, Nr
754 CALL SMOOTH_HORIZ (
755 I k, bi, bj,
756 U KPPviscAz(1-OLx,1-OLy,k,bi,bj) )
757 END DO
758 _EXCH_XYZ_R8(KPPviscAz , myThid )
759 #endif /* KPP_SMOOTH_VISC */
760
761 #ifdef KPP_SMOOTH_DIFF
762 c horizontal smoothing of vertical diffusivity
763 DO k = 1, Nr
764 CALL SMOOTH_HORIZ (
765 I k, bi, bj,
766 U KPPdiffKzS(1-OLx,1-OLy,k,bi,bj) )
767 CALL SMOOTH_HORIZ (
768 I k, bi, bj,
769 U KPPdiffKzT(1-OLx,1-OLy,k,bi,bj) )
770 END DO
771 _EXCH_XYZ_R8(KPPdiffKzS , myThid )
772 _EXCH_XYZ_R8(KPPdiffKzT , myThid )
773 #endif /* KPP_SMOOTH_DIFF */
774
775 cph(
776 cph crucial: this avoids full recomp./call of kppmix
777 CADJ store KPPhbl = comlev1_kpp, key = ikppkey
778 cph)
779
780 C Compute fraction of solar short-wave flux penetrating to
781 C the bottom of the mixing layer.
782 DO j=1-OLy,sNy+OLy
783 DO i=1-OLx,sNx+OLx
784 worka(i,j) = KPPhbl(i,j,bi,bj)
785 ENDDO
786 ENDDO
787 CALL SWFRAC(
788 I (sNx+2*OLx)*(sNy+2*OLy), minusone,
789 I mytime, mythid,
790 U worka )
791 DO j=1-OLy,sNy+OLy
792 DO i=1-OLx,sNx+OLx
793 KPPfrac(i,j,bi,bj) = worka(i,j)
794 ENDDO
795 ENDDO
796
797 ENDIF
798
799 #endif /* ALLOW_KPP */
800
801 RETURN
802 END
803
804 subroutine KPP_CALC_DUMMY(
805 I bi, bj, myTime, myThid )
806 C /==========================================================\
807 C | SUBROUTINE KPP_CALC_DUMMY |
808 C | o Compute all KPP fields defined in KPP.h |
809 C | o Dummy routine for TAMC
810 C |==========================================================|
811 C | This subroutine serves as an interface between MITGCMUV |
812 C | code and NCOM 1-D routines in kpp_routines.F |
813 C \==========================================================/
814 IMPLICIT NONE
815
816 #include "SIZE.h"
817 #include "EEPARAMS.h"
818 #include "PARAMS.h"
819 #include "KPP.h"
820 #include "KPP_PARAMS.h"
821 #include "GRID.h"
822 #include "GAD.h"
823
824 c Routine arguments
825 c bi, bj - array indices on which to apply calculations
826 c myTime - Current time in simulation
827
828 INTEGER bi, bj
829 INTEGER myThid
830 _RL myTime
831
832 #ifdef ALLOW_KPP
833
834 c Local constants
835 integer i, j, k
836
837 DO j=1-OLy,sNy+OLy
838 DO i=1-OLx,sNx+OLx
839 KPPhbl (i,j,bi,bj) = 1.0
840 KPPfrac(i,j,bi,bj) = 0.0
841 DO k = 1,Nr
842 KPPghat (i,j,k,bi,bj) = 0.0
843 KPPviscAz (i,j,k,bi,bj) = viscAr
844 ENDDO
845 ENDDO
846 ENDDO
847
848 CALL CALC_3D_DIFFUSIVITY(
849 I bi,bj,1-Olx,sNx+OLx,1-Oly,sNy+OLy,
850 I GAD_SALINITY, .FALSE., .FALSE.,
851 O KPPdiffKzS(1-Olx,1-Oly,1,bi,bj),
852 I myThid)
853 CALL CALC_3D_DIFFUSIVITY(
854 I bi,bj,1-Olx,sNx+OLx,1-Oly,sNy+OLy,
855 I GAD_TEMPERATURE, .FALSE., .FALSE.,
856 O KPPdiffKzT(1-Olx,1-Oly,1,bi,bj),
857 I myThid)
858
859 #endif
860 RETURN
861 END

  ViewVC Help
Powered by ViewVC 1.1.22