/[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.40 - (show annotations) (download)
Tue May 1 04:09:25 2007 UTC (17 years, 1 month ago) by mlosch
Branch: MAIN
CVS Tags: checkpoint59a
Changes since 1.39: +26 -17 lines
 add more code to have only Ri-number based mixing in shelf ice caverns
 add myThid to all kpp routines (long overdue)

1 C $Header: /u/gcmpack/MITgcm/pkg/kpp/kpp_calc.F,v 1.39 2007/04/30 13:49:40 jmc 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 _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 integer work1 ( 1-OLx:sNx+OLx, 1-OLy:sNy+OLy )
169 _RL worka ( 1-OLx:sNx+OLx, 1-OLy:sNy+OLy )
170 _RL work2 ( 1-OLx:sNx+OLx, 1-OLy:sNy+OLy )
171 _RL work3 ( 1-OLx:sNx+OLx, 1-OLy:sNy+OLy )
172 _RL ustar ( 1-OLx:sNx+OLx, 1-OLy:sNy+OLy )
173 _RL bo ( 1-OLx:sNx+OLx, 1-OLy:sNy+OLy )
174 _RL bosol ( 1-OLx:sNx+OLx, 1-OLy:sNy+OLy )
175 _RL shsq ( 1-OLx:sNx+OLx, 1-OLy:sNy+OLy, Nr )
176 _RL dVsq ( 1-OLx:sNx+OLx, 1-OLy:sNy+OLy, Nr )
177 _RL dbloc ( 1-OLx:sNx+OLx, 1-OLy:sNy+OLy, Nr )
178 _RL Ritop ( 1-OLx:sNx+OLx, 1-OLy:sNy+OLy, Nr )
179 _RL vddiff( 1-OLx:sNx+OLx, 1-OLy:sNy+OLy, 0:Nrp1, mdiff )
180 _RL ghat ( 1-OLx:sNx+OLx, 1-OLy:sNy+OLy, Nr )
181 _RL hbl ( 1-OLx:sNx+OLx, 1-OLy:sNy+OLy )
182 cph(
183 _RL TTALPHA( 1-OLx:sNx+OLx, 1-OLy:sNy+OLy, Nrp1 )
184 _RL SSBETA ( 1-OLx:sNx+OLx, 1-OLy:sNy+OLy, Nrp1 )
185 cph)
186 #ifdef KPP_ESTIMATE_UREF
187 _RL z0 ( 1-OLx:sNx+OLx, 1-OLy:sNy+OLy )
188 _RL zRef ( 1-OLx:sNx+OLx, 1-OLy:sNy+OLy )
189 _RL uRef ( 1-OLx:sNx+OLx, 1-OLy:sNy+OLy )
190 _RL vRef ( 1-OLx:sNx+OLx, 1-OLy:sNy+OLy )
191 #endif /* KPP_ESTIMATE_UREF */
192
193 _RL tempvar2
194 integer i, j, k, kp1, km1, im1, ip1, jm1, jp1
195
196 #ifdef KPP_ESTIMATE_UREF
197 _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 O work2, dbloc, Ritop,
255 O TTALPHA, SSBETA,
256 I ikppkey, bi, bj, myThid )
257 CALL TIMER_STOP ('STATEKPP [KPP_CALC]', myThid)
258
259 DO k = 1, Nr
260 DO j = 1-OLy, sNy+OLy
261 DO i = 1-OLx, sNx+OLx
262 ghat(i,j,k) = dbloc(i,j,k)
263 ENDDO
264 ENDDO
265 ENDDO
266
267 #ifdef KPP_SMOOTH_DBLOC
268 c horizontally smooth dbloc with a 121 filter
269 c smooth dbloc stored in ghat to save space
270 c dbloc(k) is buoyancy gradientnote between k and k+1
271 c levels therefore k+1 mask must be used
272
273 DO k = 1, Nr-1
274 CALL SMOOTH_HORIZ (
275 I k+1, bi, bj,
276 U ghat (1-OLx,1-OLy,k),
277 I myThid )
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 SMOOTH_HORIZ (
285 I 1, bi, bj,
286 U work2,
287 I myThid )
288 DO k = 1, Nr
289 CALL SMOOTH_HORIZ (
290 I k+1, bi, bj,
291 U dbloc (1-OLx,1-OLy,k),
292 I myThid )
293 CALL SMOOTH_HORIZ (
294 I k, bi, bj,
295 U Ritop (1-OLx,1-OLy,k),
296 I myThid )
297 CALL SMOOTH_HORIZ (
298 I k, bi, bj,
299 U TTALPHA(1-OLx,1-OLy,k),
300 I myThid )
301 CALL SMOOTH_HORIZ (
302 I k, bi, bj,
303 U SSBETA(1-OLx,1-OLy,k),
304 I myThid )
305 ENDDO
306 #endif /* KPP_SMOOTH_DENS */
307
308 DO k = 1, Nr
309 km1 = max(1,k-1)
310 DO j = 1-OLy, sNy+OLy
311 DO i = 1-OLx, sNx+OLx
312
313 c zero out dbloc over land points (so that the convective
314 c part of the interior mixing can be diagnosed)
315 dbloc(i,j,k) = dbloc(i,j,k) * maskC(i,j,k,bi,bj)
316 & * maskC(i,j,km1,bi,bj)
317 ghat(i,j,k) = ghat(i,j,k) * maskC(i,j,k,bi,bj)
318 & * maskC(i,j,km1,bi,bj)
319 Ritop(i,j,k) = Ritop(i,j,k) * maskC(i,j,k,bi,bj)
320 & * maskC(i,j,km1,bi,bj)
321 if(k.eq.nzmax(i,j,bi,bj)) then
322 dbloc(i,j,k) = p0
323 ghat(i,j,k) = p0
324 Ritop(i,j,k) = p0
325 endif
326
327 c numerator of bulk richardson number on grid levels
328 c note: land and ocean bottom values need to be set to zero
329 c so that the subroutine "bldepth" works correctly
330 Ritop(i,j,k) = (zgrid(1)-zgrid(k)) * Ritop(i,j,k)
331
332 END DO
333 END DO
334 END DO
335
336 cph(
337 cph this avoids a single or double recomp./call of statekpp
338 CADJ store work2 = comlev1_kpp, key = ikppkey
339 #ifdef KPP_AUTODIFF_EXCESSIVE_STORE
340 CADJ store dbloc, Ritop, ghat = comlev1_kpp, key = ikppkey
341 CADJ store vddiff = comlev1_kpp, key = ikppkey
342 CADJ store TTALPHA, SSBETA = comlev1_kpp, key = ikppkey
343 #endif
344 cph)
345
346 c------------------------------------------------------------------------
347 c friction velocity, turbulent and radiative surface buoyancy forcing
348 c -------------------------------------------------------------------
349 c taux / rho = surfaceForcingU (N/m^2)
350 c tauy / rho = surfaceForcingV (N/m^2)
351 c ustar = sqrt( sqrt( taux^2 + tauy^2 ) / rho ) (m/s)
352 c bo = - g * ( alpha*surfaceForcingT +
353 c beta *surfaceForcingS ) / rho (m^2/s^3)
354 c bosol = - g * alpha * Qsw * drF(1) / rho (m^2/s^3)
355 c------------------------------------------------------------------------
356
357 c initialize arrays to zero
358 DO j = 1-OLy, sNy+OLy
359 DO i = 1-OLx, sNx+OLx
360 ustar(i,j) = p0
361 bo (I,J) = p0
362 bosol(I,J) = p0
363 END DO
364 END DO
365
366 DO j = jmin, jmax
367 jp1 = j + 1
368 DO i = imin, imax
369 ip1 = i+1
370 work3(i,j) =
371 & (surfaceForcingU(i,j,bi,bj) + surfaceForcingU(ip1,j,bi,bj)) *
372 & (surfaceForcingU(i,j,bi,bj) + surfaceForcingU(ip1,j,bi,bj)) +
373 & (surfaceForcingV(i,j,bi,bj) + surfaceForcingV(i,jp1,bi,bj)) *
374 & (surfaceForcingV(i,j,bi,bj) + surfaceForcingV(i,jp1,bi,bj))
375 END DO
376 END DO
377 cph(
378 CADJ store work3 = comlev1_kpp, key = ikppkey
379 cph)
380 DO j = jmin, jmax
381 jp1 = j + 1
382 DO i = imin, imax
383 ip1 = i+1
384
385 if ( work3(i,j) .lt. (phepsi*phepsi*drF(1)*drF(1)) ) then
386 ustar(i,j) = SQRT( phepsi * p5 * drF(1) )
387 else
388 tempVar2 = SQRT( work3(i,j) ) * p5
389 ustar(i,j) = SQRT( tempVar2 )
390 endif
391
392 END DO
393 END DO
394
395 CML#ifdef ALLOW_SHELFICE
396 CMLC For the pbl parameterisation to work underneath the ice shelves
397 CMLC it needs to know the surface (ice-ocean) fluxes. However, masking
398 CMLC and indexing problems make this part of the code not work
399 CMLC underneath the ice shelves and the following lines are only here
400 CMLC to remind me that this still needs to be sorted out.
401 CML IF ( useShelfIce ) THEN
402 CML DO j = jmin, jmax
403 CML jp1 = j + 1
404 CML DO i = imin, imax
405 CML ip1 = i+1
406 CML k = kTopC(I,J,bi,bj)
407 CML bo(I,J) = - gravity *
408 CML & ( TTALPHA(I,J,K) * ( maskC(I,J,1,bi,bj)
409 CML & * ( surfaceForcingT(i,j,bi,bj)
410 CML & + surfaceForcingTice(i,j,bi,bj) )
411 CML & + shelficeForcingT(i,j,bi,bj) )
412 CML & + SSBETA(I,J,K) * ( maskC(I,J,1,bi,bj)
413 CML & * surfaceForcingS(i,j,bi,bj)
414 CML & + shelficeForcingS(i,j,bi,bj) ) )
415 CML & / work2(I,J)
416 CML
417 CML bosol(I,J) = gravity * TTALPHA(I,J,1) * Qsw(i,j,bi,bj)
418 CML & * maskC(I,J,1,bi,bj) * recip_Cp*recip_rhoConst
419 CML & / work2(I,J)
420 CML
421 CML END DO
422 CML END DO
423 CML ELSE
424 CML#endif /* ALLOW_SHELFICE */
425 DO j = jmin, jmax
426 jp1 = j + 1
427 DO i = imin, imax
428 ip1 = i+1
429
430 bo(I,J) = - gravity *
431 & ( TTALPHA(I,J,1) * (surfaceForcingT(i,j,bi,bj)+
432 & surfaceForcingTice(i,j,bi,bj)) +
433 & SSBETA(I,J,1) * surfaceForcingS(i,j,bi,bj) )
434 & / work2(I,J)
435
436 bosol(I,J) = gravity * TTALPHA(I,J,1) * Qsw(i,j,bi,bj) *
437 & recip_Cp*recip_rhoConst
438 & / work2(I,J)
439
440 END DO
441 END DO
442 CML#ifdef ALLOW_SHELFICE
443 CML ENDIF
444 CML#endif /* ALLOW_SHELFICE */
445
446 cph(
447 CADJ store ustar = comlev1_kpp, key = ikppkey
448 cph)
449
450 c------------------------------------------------------------------------
451 c velocity shear
452 c --------------
453 c Get velocity shear squared, averaged from "u,v-grid"
454 c onto "t-grid" (in (m/s)**2):
455 c dVsq(k)=(Uref-U(k))**2+(Vref-V(k))**2 at grid levels
456 c shsq(k)=(U(k)-U(k+1))**2+(V(k)-V(k+1))**2 at interfaces
457 c------------------------------------------------------------------------
458
459 c initialize arrays to zero
460 DO k = 1, Nr
461 DO j = 1-OLy, sNy+OLy
462 DO i = 1-OLx, sNx+OLx
463 shsq(i,j,k) = p0
464 dVsq(i,j,k) = p0
465 END DO
466 END DO
467 END DO
468
469 c dVsq computation
470
471 #ifdef KPP_ESTIMATE_UREF
472
473 c Get rid of vertical resolution dependence of dVsq term by
474 c estimating a surface velocity that is independent of first level
475 c thickness in the model. First determine mixed layer depth hMix.
476 c Second zRef = espilon * hMix. Third determine roughness length
477 c scale z0. Third estimate reference velocity.
478
479 DO j = jmin, jmax
480 jp1 = j + 1
481 DO i = imin, imax
482 ip1 = i + 1
483
484 c Determine mixed layer depth hMix as the shallowest depth at which
485 c dB/dz exceeds 5.2e-5 s^-2.
486 work1(i,j) = nzmax(i,j,bi,bj)
487 DO k = 1, Nr
488 IF ( k .LT. nzmax(i,j,bi,bj) .AND.
489 & maskC(I,J,k,bi,bj) .GT. 0. .AND.
490 & dbloc(i,j,k) / drC(k+1) .GT. dB_dz )
491 & work1(i,j) = k
492 END DO
493
494 c Linearly interpolate to find hMix.
495 k = work1(i,j)
496 IF ( k .EQ. 0 .OR. nzmax(i,j,bi,bj) .EQ. 1 ) THEN
497 zRef(i,j) = p0
498 ELSEIF ( k .EQ. 1) THEN
499 dBdz2 = dbloc(i,j,1) / drC(2)
500 zRef(i,j) = drF(1) * dB_dz / dBdz2
501 ELSEIF ( k .LT. nzmax(i,j,bi,bj) ) THEN
502 dBdz1 = dbloc(i,j,k-1) / drC(k )
503 dBdz2 = dbloc(i,j,k ) / drC(k+1)
504 zRef(i,j) = rF(k) + drF(k) * (dB_dz - dBdz1) /
505 & MAX ( phepsi, dBdz2 - dBdz1 )
506 ELSE
507 zRef(i,j) = rF(k+1)
508 ENDIF
509
510 c Compute roughness length scale z0 subject to 0 < z0
511 tempVar1 = p5 * (
512 & (uVel(i, j, 1,bi,bj)-uVel(i, j, 2,bi,bj)) *
513 & (uVel(i, j, 1,bi,bj)-uVel(i, j, 2,bi,bj)) +
514 & (uVel(ip1,j, 1,bi,bj)-uVel(ip1,j, 2,bi,bj)) *
515 & (uVel(ip1,j, 1,bi,bj)-uVel(ip1,j, 2,bi,bj)) +
516 & (vVel(i, j, 1,bi,bj)-vVel(i, j, 2,bi,bj)) *
517 & (vVel(i, j, 1,bi,bj)-vVel(i, j, 2,bi,bj)) +
518 & (vVel(i, jp1,1,bi,bj)-vVel(i, jp1,2,bi,bj)) *
519 & (vVel(i, jp1,1,bi,bj)-vVel(i, jp1,2,bi,bj)) )
520 if ( tempVar1 .lt. (epsln*epsln) ) then
521 tempVar2 = epsln
522 else
523 tempVar2 = SQRT ( tempVar1 )
524 endif
525 z0(i,j) = rF(2) *
526 & ( rF(3) * LOG ( rF(3) / rF(2) ) /
527 & ( rF(3) - rF(2) ) -
528 & tempVar2 * vonK /
529 & MAX ( ustar(i,j), phepsi ) )
530 z0(i,j) = MAX ( z0(i,j), phepsi )
531
532 c zRef is set to 0.1 * hMix subject to z0 <= zRef <= drF(1)
533 zRef(i,j) = MAX ( epsilon * zRef(i,j), z0(i,j) )
534 zRef(i,j) = MIN ( zRef(i,j), drF(1) )
535
536 c Estimate reference velocity uRef and vRef.
537 uRef(i,j) = p5 *
538 & ( uVel(i,j,1,bi,bj) + uVel(ip1,j,1,bi,bj) )
539 vRef(i,j) = p5 *
540 & ( vVel(i,j,1,bi,bj) + vVel(i,jp1,1,bi,bj) )
541 IF ( zRef(i,j) .LT. drF(1) ) THEN
542 ustarX = ( surfaceForcingU(i, j,bi,bj) +
543 & surfaceForcingU(ip1,j,bi,bj) ) * p5
544 & *recip_drF(1)
545 ustarY = ( surfaceForcingV(i,j, bi,bj) +
546 & surfaceForcingV(i,jp1,bi,bj) ) * p5
547 & *recip_drF(1)
548 tempVar1 = ustarX * ustarX + ustarY * ustarY
549 if ( tempVar1 .lt. (epsln*epsln) ) then
550 tempVar2 = epsln
551 else
552 tempVar2 = SQRT ( tempVar1 )
553 endif
554 tempVar2 = ustar(i,j) *
555 & ( LOG ( zRef(i,j) / rF(2) ) +
556 & z0(i,j) / zRef(i,j) - z0(i,j) / rF(2) ) /
557 & vonK / tempVar2
558 uRef(i,j) = uRef(i,j) + ustarX * tempVar2
559 vRef(i,j) = vRef(i,j) + ustarY * tempVar2
560 ENDIF
561
562 END DO
563 END DO
564
565 DO k = 1, Nr
566 DO j = jmin, jmax
567 jm1 = j - 1
568 jp1 = j + 1
569 DO i = imin, imax
570 im1 = i - 1
571 ip1 = i + 1
572 dVsq(i,j,k) = p5 * (
573 $ (uRef(i,j) - uVel(i, j, k,bi,bj)) *
574 $ (uRef(i,j) - uVel(i, j, k,bi,bj)) +
575 $ (uRef(i,j) - uVel(ip1,j, k,bi,bj)) *
576 $ (uRef(i,j) - uVel(ip1,j, k,bi,bj)) +
577 $ (vRef(i,j) - vVel(i, j, k,bi,bj)) *
578 $ (vRef(i,j) - vVel(i, j, k,bi,bj)) +
579 $ (vRef(i,j) - vVel(i, jp1,k,bi,bj)) *
580 $ (vRef(i,j) - vVel(i, jp1,k,bi,bj)) )
581 #ifdef KPP_SMOOTH_DVSQ
582 dVsq(i,j,k) = p5 * dVsq(i,j,k) + p125 * (
583 $ (uRef(i,j) - uVel(i, jm1,k,bi,bj)) *
584 $ (uRef(i,j) - uVel(i, jm1,k,bi,bj)) +
585 $ (uRef(i,j) - uVel(ip1,jm1,k,bi,bj)) *
586 $ (uRef(i,j) - uVel(ip1,jm1,k,bi,bj)) +
587 $ (uRef(i,j) - uVel(i, jp1,k,bi,bj)) *
588 $ (uRef(i,j) - uVel(i, jp1,k,bi,bj)) +
589 $ (uRef(i,j) - uVel(ip1,jp1,k,bi,bj)) *
590 $ (uRef(i,j) - uVel(ip1,jp1,k,bi,bj)) +
591 $ (vRef(i,j) - vVel(im1,j, k,bi,bj)) *
592 $ (vRef(i,j) - vVel(im1,j, k,bi,bj)) +
593 $ (vRef(i,j) - vVel(im1,jp1,k,bi,bj)) *
594 $ (vRef(i,j) - vVel(im1,jp1,k,bi,bj)) +
595 $ (vRef(i,j) - vVel(ip1,j, k,bi,bj)) *
596 $ (vRef(i,j) - vVel(ip1,j, k,bi,bj)) +
597 $ (vRef(i,j) - vVel(ip1,jp1,k,bi,bj)) *
598 $ (vRef(i,j) - vVel(ip1,jp1,k,bi,bj)) )
599 #endif /* KPP_SMOOTH_DVSQ */
600 END DO
601 END DO
602 END DO
603
604 #else /* KPP_ESTIMATE_UREF */
605
606 DO k = 1, Nr
607 DO j = jmin, jmax
608 jm1 = j - 1
609 jp1 = j + 1
610 DO i = imin, imax
611 im1 = i - 1
612 ip1 = i + 1
613 dVsq(i,j,k) = p5 * (
614 $ (uVel(i, j, 1,bi,bj)-uVel(i, j, k,bi,bj)) *
615 $ (uVel(i, j, 1,bi,bj)-uVel(i, j, k,bi,bj)) +
616 $ (uVel(ip1,j, 1,bi,bj)-uVel(ip1,j, k,bi,bj)) *
617 $ (uVel(ip1,j, 1,bi,bj)-uVel(ip1,j, k,bi,bj)) +
618 $ (vVel(i, j, 1,bi,bj)-vVel(i, j, k,bi,bj)) *
619 $ (vVel(i, j, 1,bi,bj)-vVel(i, j, k,bi,bj)) +
620 $ (vVel(i, jp1,1,bi,bj)-vVel(i, jp1,k,bi,bj)) *
621 $ (vVel(i, jp1,1,bi,bj)-vVel(i, jp1,k,bi,bj)) )
622 #ifdef KPP_SMOOTH_DVSQ
623 dVsq(i,j,k) = p5 * dVsq(i,j,k) + p125 * (
624 $ (uVel(i, jm1,1,bi,bj)-uVel(i, jm1,k,bi,bj)) *
625 $ (uVel(i, jm1,1,bi,bj)-uVel(i, jm1,k,bi,bj)) +
626 $ (uVel(ip1,jm1,1,bi,bj)-uVel(ip1,jm1,k,bi,bj)) *
627 $ (uVel(ip1,jm1,1,bi,bj)-uVel(ip1,jm1,k,bi,bj)) +
628 $ (uVel(i, jp1,1,bi,bj)-uVel(i, jp1,k,bi,bj)) *
629 $ (uVel(i, jp1,1,bi,bj)-uVel(i, jp1,k,bi,bj)) +
630 $ (uVel(ip1,jp1,1,bi,bj)-uVel(ip1,jp1,k,bi,bj)) *
631 $ (uVel(ip1,jp1,1,bi,bj)-uVel(ip1,jp1,k,bi,bj)) +
632 $ (vVel(im1,j, 1,bi,bj)-vVel(im1,j, k,bi,bj)) *
633 $ (vVel(im1,j, 1,bi,bj)-vVel(im1,j, k,bi,bj)) +
634 $ (vVel(im1,jp1,1,bi,bj)-vVel(im1,jp1,k,bi,bj)) *
635 $ (vVel(im1,jp1,1,bi,bj)-vVel(im1,jp1,k,bi,bj)) +
636 $ (vVel(ip1,j, 1,bi,bj)-vVel(ip1,j, k,bi,bj)) *
637 $ (vVel(ip1,j, 1,bi,bj)-vVel(ip1,j, k,bi,bj)) +
638 $ (vVel(ip1,jp1,1,bi,bj)-vVel(ip1,jp1,k,bi,bj)) *
639 $ (vVel(ip1,jp1,1,bi,bj)-vVel(ip1,jp1,k,bi,bj)) )
640 #endif /* KPP_SMOOTH_DVSQ */
641 END DO
642 END DO
643 END DO
644
645 #endif /* KPP_ESTIMATE_UREF */
646
647 c shsq computation
648 DO k = 1, Nrm1
649 kp1 = k + 1
650 DO j = jmin, jmax
651 jm1 = j - 1
652 jp1 = j + 1
653 DO i = imin, imax
654 im1 = i - 1
655 ip1 = i + 1
656 shsq(i,j,k) = p5 * (
657 $ (uVel(i, j, k,bi,bj)-uVel(i, j, kp1,bi,bj)) *
658 $ (uVel(i, j, k,bi,bj)-uVel(i, j, kp1,bi,bj)) +
659 $ (uVel(ip1,j, k,bi,bj)-uVel(ip1,j, kp1,bi,bj)) *
660 $ (uVel(ip1,j, k,bi,bj)-uVel(ip1,j, kp1,bi,bj)) +
661 $ (vVel(i, j, k,bi,bj)-vVel(i, j, kp1,bi,bj)) *
662 $ (vVel(i, j, k,bi,bj)-vVel(i, j, kp1,bi,bj)) +
663 $ (vVel(i, jp1,k,bi,bj)-vVel(i, jp1,kp1,bi,bj)) *
664 $ (vVel(i, jp1,k,bi,bj)-vVel(i, jp1,kp1,bi,bj)) )
665 #ifdef KPP_SMOOTH_SHSQ
666 shsq(i,j,k) = p5 * shsq(i,j,k) + p125 * (
667 $ (uVel(i, jm1,k,bi,bj)-uVel(i, jm1,kp1,bi,bj)) *
668 $ (uVel(i, jm1,k,bi,bj)-uVel(i, jm1,kp1,bi,bj)) +
669 $ (uVel(ip1,jm1,k,bi,bj)-uVel(ip1,jm1,kp1,bi,bj)) *
670 $ (uVel(ip1,jm1,k,bi,bj)-uVel(ip1,jm1,kp1,bi,bj)) +
671 $ (uVel(i, jp1,k,bi,bj)-uVel(i, jp1,kp1,bi,bj)) *
672 $ (uVel(i, jp1,k,bi,bj)-uVel(i, jp1,kp1,bi,bj)) +
673 $ (uVel(ip1,jp1,k,bi,bj)-uVel(ip1,jp1,kp1,bi,bj)) *
674 $ (uVel(ip1,jp1,k,bi,bj)-uVel(ip1,jp1,kp1,bi,bj)) +
675 $ (vVel(im1,j, k,bi,bj)-vVel(im1,j, kp1,bi,bj)) *
676 $ (vVel(im1,j, k,bi,bj)-vVel(im1,j, kp1,bi,bj)) +
677 $ (vVel(im1,jp1,k,bi,bj)-vVel(im1,jp1,kp1,bi,bj)) *
678 $ (vVel(im1,jp1,k,bi,bj)-vVel(im1,jp1,kp1,bi,bj)) +
679 $ (vVel(ip1,j, k,bi,bj)-vVel(ip1,j, kp1,bi,bj)) *
680 $ (vVel(ip1,j, k,bi,bj)-vVel(ip1,j, kp1,bi,bj)) +
681 $ (vVel(ip1,jp1,k,bi,bj)-vVel(ip1,jp1,kp1,bi,bj)) *
682 $ (vVel(ip1,jp1,k,bi,bj)-vVel(ip1,jp1,kp1,bi,bj)) )
683 #endif
684 END DO
685 END DO
686 END DO
687
688 cph(
689 #ifdef KPP_AUTODIFF_EXCESSIVE_STORE
690 CADJ store dvsq, shsq = comlev1_kpp, key = ikppkey
691 #endif
692 cph)
693
694 c-----------------------------------------------------------------------
695 c solve for viscosity, diffusivity, ghat, and hbl on "t-grid"
696 c-----------------------------------------------------------------------
697
698 c precompute background vertical diffusivities, which are needed for
699 c matching diffusivities at bottom of KPP PBL
700 CALL CALC_3D_DIFFUSIVITY(
701 I bi,bj,1-Olx,sNx+OLx,1-Oly,sNy+OLy,
702 I GAD_SALINITY, .FALSE., .FALSE.,
703 O KPPdiffKzS(1-Olx,1-Oly,1,bi,bj),
704 I myThid)
705 CALL CALC_3D_DIFFUSIVITY(
706 I bi,bj,1-Olx,sNx+OLx,1-Oly,sNy+OLy,
707 I GAD_TEMPERATURE, .FALSE., .FALSE.,
708 O KPPdiffKzT(1-Olx,1-Oly,1,bi,bj),
709 I myThid)
710
711 DO j = 1-OLy, sNy+OLy
712 DO i = 1-OLx, sNx+OLx
713 work1(i,j) = nzmax(i,j,bi,bj)
714 work2(i,j) = Fcori(i,j,bi,bj)
715 END DO
716 END DO
717 CALL TIMER_START('KPPMIX [KPP_CALC]', myThid)
718 CALL KPPMIX (
719 I work1, shsq, dVsq, ustar
720 I , maskC(1-Olx,1-Oly,1,bi,bj)
721 I , bo, bosol, dbloc, Ritop, work2
722 I , KPPdiffKzS(1-Olx,1-Oly,1,bi,bj)
723 I , KPPdiffKzT(1-Olx,1-Oly,1,bi,bj)
724 I , ikppkey
725 O , vddiff
726 U , ghat
727 O , hbl
728 I , mytime, mythid )
729 CALL TIMER_STOP ('KPPMIX [KPP_CALC]', myThid)
730
731 c-----------------------------------------------------------------------
732 c zero out land values and transfer to global variables
733 c-----------------------------------------------------------------------
734
735 DO j = jmin, jmax
736 DO i = imin, imax
737 DO k = 1, Nr
738 km1 = max(1,k-1)
739 KPPviscAz(i,j,k,bi,bj) = vddiff(i,j,k-1,1) * maskC(i,j,k,bi,bj)
740 & * maskC(i,j,km1,bi,bj)
741 KPPdiffKzS(i,j,k,bi,bj)= vddiff(i,j,k-1,2) * maskC(i,j,k,bi,bj)
742 & * maskC(i,j,km1,bi,bj)
743 KPPdiffKzT(i,j,k,bi,bj)= vddiff(i,j,k-1,3) * maskC(i,j,k,bi,bj)
744 & * maskC(i,j,km1,bi,bj)
745 KPPghat(i,j,k,bi,bj) = ghat(i,j,k) * maskC(i,j,k,bi,bj)
746 & * maskC(i,j,km1,bi,bj)
747 END DO
748 k = 1
749 #ifdef ALLOW_SHELFICE
750 if ( useShelfIce ) k = kTopC(i,j,bi,bj)
751 #endif /* ALLOW_SHELFICE */
752 KPPhbl(i,j,bi,bj) = hbl(i,j) * maskC(i,j,k,bi,bj)
753
754 END DO
755 END DO
756
757 #ifdef KPP_SMOOTH_VISC
758 c horizontal smoothing of vertical viscosity
759 DO k = 1, Nr
760 CALL SMOOTH_HORIZ (
761 I k, bi, bj,
762 U KPPviscAz(1-OLx,1-OLy,k,bi,bj),
763 I myThid )
764 END DO
765 _EXCH_XYZ_R8(KPPviscAz , myThid )
766 #endif /* KPP_SMOOTH_VISC */
767
768 #ifdef KPP_SMOOTH_DIFF
769 c horizontal smoothing of vertical diffusivity
770 DO k = 1, Nr
771 CALL SMOOTH_HORIZ (
772 I k, bi, bj,
773 U KPPdiffKzS(1-OLx,1-OLy,k,bi,bj),
774 I myThid )
775 CALL SMOOTH_HORIZ (
776 I k, bi, bj,
777 U KPPdiffKzT(1-OLx,1-OLy,k,bi,bj),
778 I myThid )
779 END DO
780 _EXCH_XYZ_R8(KPPdiffKzS , myThid )
781 _EXCH_XYZ_R8(KPPdiffKzT , myThid )
782 #endif /* KPP_SMOOTH_DIFF */
783
784 cph(
785 cph crucial: this avoids full recomp./call of kppmix
786 CADJ store KPPhbl = comlev1_kpp, key = ikppkey
787 cph)
788
789 C Compute fraction of solar short-wave flux penetrating to
790 C the bottom of the mixing layer.
791 DO j=1-OLy,sNy+OLy
792 DO i=1-OLx,sNx+OLx
793 worka(i,j) = KPPhbl(i,j,bi,bj)
794 ENDDO
795 ENDDO
796 CALL SWFRAC(
797 I (sNx+2*OLx)*(sNy+2*OLy), minusone,
798 I mytime, mythid,
799 U worka )
800 DO j=1-OLy,sNy+OLy
801 DO i=1-OLx,sNx+OLx
802 KPPfrac(i,j,bi,bj) = worka(i,j)
803 ENDDO
804 ENDDO
805
806 ENDIF
807
808 #endif /* ALLOW_KPP */
809
810 RETURN
811 END
812
813 subroutine KPP_CALC_DUMMY(
814 I bi, bj, myTime, myThid )
815 C /==========================================================\
816 C | SUBROUTINE KPP_CALC_DUMMY |
817 C | o Compute all KPP fields defined in KPP.h |
818 C | o Dummy routine for TAMC
819 C |==========================================================|
820 C | This subroutine serves as an interface between MITGCMUV |
821 C | code and NCOM 1-D routines in kpp_routines.F |
822 C \==========================================================/
823 IMPLICIT NONE
824
825 #include "SIZE.h"
826 #include "EEPARAMS.h"
827 #include "PARAMS.h"
828 #include "KPP.h"
829 #include "KPP_PARAMS.h"
830 #include "GRID.h"
831 #include "GAD.h"
832
833 c Routine arguments
834 c bi, bj - array indices on which to apply calculations
835 c myTime - Current time in simulation
836
837 INTEGER bi, bj
838 INTEGER myThid
839 _RL myTime
840
841 #ifdef ALLOW_KPP
842
843 c Local constants
844 integer i, j, k
845
846 DO j=1-OLy,sNy+OLy
847 DO i=1-OLx,sNx+OLx
848 KPPhbl (i,j,bi,bj) = 1.0
849 KPPfrac(i,j,bi,bj) = 0.0
850 DO k = 1,Nr
851 KPPghat (i,j,k,bi,bj) = 0.0
852 KPPviscAz (i,j,k,bi,bj) = viscAr
853 ENDDO
854 ENDDO
855 ENDDO
856
857 CALL CALC_3D_DIFFUSIVITY(
858 I bi,bj,1-Olx,sNx+OLx,1-Oly,sNy+OLy,
859 I GAD_SALINITY, .FALSE., .FALSE.,
860 O KPPdiffKzS(1-Olx,1-Oly,1,bi,bj),
861 I myThid)
862 CALL CALC_3D_DIFFUSIVITY(
863 I bi,bj,1-Olx,sNx+OLx,1-Oly,sNy+OLy,
864 I GAD_TEMPERATURE, .FALSE., .FALSE.,
865 O KPPdiffKzT(1-Olx,1-Oly,1,bi,bj),
866 I myThid)
867
868 #endif
869 RETURN
870 END

  ViewVC Help
Powered by ViewVC 1.1.22