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

Annotation of /MITgcm/pkg/kpp/kpp_routines.F

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


Revision 1.15 - (hide annotations) (download)
Fri Mar 7 23:51:02 2003 UTC (21 years, 3 months ago) by heimbach
Branch: MAIN
CVS Tags: checkpoint50
Changes since 1.14: +23 -4 lines
Added more storing to avoid more recomp. in
kpp_routines.F, gmredi_calc_tensor.F

1 heimbach 1.15 C $Header: /u/gcmpack/MITgcm/pkg/kpp/kpp_routines.F,v 1.9.6.3 2003/03/07 04:20:57 heimbach Exp $
2 heimbach 1.10 C $Name: $
3 adcroft 1.1
4     #include "KPP_OPTIONS.h"
5    
6     C-- File kpp_routines.F: subroutines needed to implement
7     C-- KPP vertical mixing scheme
8     C-- Contents
9     C-- o KPPMIX - Main driver and interface routine.
10     C-- o BLDEPTH - Determine oceanic planetary boundary layer depth.
11     C-- o WSCALE - Compute turbulent velocity scales.
12     C-- o RI_IWMIX - Compute interior viscosity diffusivity coefficients.
13     C-- o Z121 - Apply 121 vertical smoothing.
14 heimbach 1.4 C-- o KPP_SMOOTH_HORIZ - Apply horizontal smoothing to KPP array.
15     C-- o SMOOTH_HORIZ - Apply horizontal smoothing to global array.
16 adcroft 1.1 C-- o BLMIX - Boundary layer mixing coefficients.
17     C-- o ENHANCE - Enhance diffusivity at boundary layer interface.
18     C-- o STATEKPP - Compute buoyancy-related input arrays.
19    
20 heimbach 1.4 c***********************************************************************
21 adcroft 1.1
22     SUBROUTINE KPPMIX (
23 heimbach 1.4 I mytime, mythid
24     I , kmtj, shsq, dvsq, ustar
25     I , bo, bosol, dbloc, Ritop, coriol
26 adcroft 1.1 I , ikey
27     O , diffus
28     U , ghat
29     O , hbl )
30    
31 heimbach 1.4 c-----------------------------------------------------------------------
32 adcroft 1.1 c
33     c Main driver subroutine for kpp vertical mixing scheme and
34     c interface to greater ocean model
35     c
36     c written by: bill large, june 6, 1994
37     c modified by: jan morzel, june 30, 1994
38     c bill large, august 11, 1994
39     c bill large, january 25, 1995 : "dVsq" and 1d code
40     c detlef stammer, august 1997 : for use with MIT GCM Classic
41     c d. menemenlis, june 1998 : for use with MIT GCM UV
42     c
43     c-----------------------------------------------------------------------
44    
45     IMPLICIT NONE
46    
47     #include "SIZE.h"
48     #include "EEPARAMS.h"
49     #include "PARAMS.h"
50     #include "DYNVARS.h"
51     #include "FFIELDS.h"
52     #include "KPP_PARAMS.h"
53    
54     c input
55 heimbach 1.4 c myTime - current time in simulation
56     c myThid - thread number for this instance of the routine
57 adcroft 1.1 c kmtj (imt) - number of vertical layers on this row
58     c shsq (imt,Nr) - (local velocity shear)^2 ((m/s)^2)
59     c dvsq (imt,Nr) - (velocity shear re sfc)^2 ((m/s)^2)
60     c ustar (imt) - surface friction velocity (m/s)
61     c bo (imt) - surface turbulent buoy. forcing (m^2/s^3)
62     c bosol (imt) - radiative buoyancy forcing (m^2/s^3)
63     c dbloc (imt,Nr) - local delta buoyancy across interfaces (m/s^2)
64     c dblocSm(imt,Nr) - horizontally smoothed dbloc (m/s^2)
65     c stored in ghat to save space
66     c Ritop (imt,Nr) - numerator of bulk Richardson Number
67     c (zref-z) * delta buoyancy w.r.t. surface ((m/s)^2)
68     c coriol (imt) - Coriolis parameter (1/s)
69     c note: there is a conversion from 2-D to 1-D for input output variables,
70     c e.g., hbl(sNx,sNy) -> hbl(imt),
71     c where hbl(i,j) -> hbl((j-1)*sNx+i)
72    
73 heimbach 1.4 _RL mytime
74     integer mythid
75 adcroft 1.1 integer kmtj (imt )
76 heimbach 1.4 _KPP_RL shsq (imt,Nr)
77     _KPP_RL dvsq (imt,Nr)
78     _KPP_RL ustar (imt )
79     _KPP_RL bo (imt )
80     _KPP_RL bosol (imt )
81     _KPP_RL dbloc (imt,Nr)
82     _KPP_RL Ritop (imt,Nr)
83     _KPP_RL coriol(imt )
84 adcroft 1.1
85     integer ikey
86    
87     c output
88     c diffus (imt,1) - vertical viscosity coefficient (m^2/s)
89     c diffus (imt,2) - vertical scalar diffusivity (m^2/s)
90     c diffus (imt,3) - vertical temperature diffusivity (m^2/s)
91     c ghat (imt) - nonlocal transport coefficient (s/m^2)
92     c hbl (imt) - mixing layer depth (m)
93    
94 heimbach 1.4 _KPP_RL diffus(imt,0:Nrp1,mdiff)
95     _KPP_RL ghat (imt,Nr)
96     _KPP_RL hbl (imt)
97 adcroft 1.1
98     #ifdef ALLOW_KPP
99    
100     c local
101     c kbl (imt ) - index of first grid level below hbl
102     c bfsfc (imt ) - surface buoyancy forcing (m^2/s^3)
103     c casea (imt ) - 1 in case A; 0 in case B
104     c stable (imt ) - 1 in stable forcing; 0 if unstable
105     c dkm1 (imt, mdiff) - boundary layer diffusivity at kbl-1 level
106     c blmc (imt,Nr,mdiff) - boundary layer mixing coefficients
107     c sigma (imt ) - normalized depth (d / hbl)
108     c Rib (imt,Nr ) - bulk Richardson number
109    
110 heimbach 1.4 integer kbl (imt )
111     _KPP_RL bfsfc (imt )
112     _KPP_RL casea (imt )
113     _KPP_RL stable(imt )
114     _KPP_RL dkm1 (imt, mdiff)
115     _KPP_RL blmc (imt,Nr,mdiff)
116     _KPP_RL sigma (imt )
117     _KPP_RL Rib (imt,Nr )
118 adcroft 1.1
119     integer i, k, md
120    
121     c-----------------------------------------------------------------------
122     c compute interior mixing coefficients everywhere, due to constant
123     c internal wave activity, static instability, and local shear
124     c instability.
125     c (ghat is temporary storage for horizontally smoothed dbloc)
126     c-----------------------------------------------------------------------
127    
128 heimbach 1.15 cph(
129     cph these storings avoid recomp. of Ri_iwmix
130     CADJ STORE ghat = comlev1_kpp, key = ikey
131     CADJ STORE dbloc = comlev1_kpp, key = ikey
132     cph)
133 adcroft 1.1 call Ri_iwmix (
134     I kmtj, shsq, dbloc, ghat
135     I , ikey
136     O , diffus )
137    
138 heimbach 1.15 cph(
139     cph these storings avoid recomp. of Ri_iwmix
140     cph DESPITE TAFs 'not necessary' warning!
141     CADJ STORE dbloc = comlev1_kpp, key = ikey
142     CADJ STORE shsq = comlev1_kpp, key = ikey
143     CADJ STORE ghat = comlev1_kpp, key = ikey
144     CADJ STORE diffus = comlev1_kpp, key = ikey
145     cph)
146    
147 adcroft 1.1 c-----------------------------------------------------------------------
148     c set seafloor values to zero and fill extra "Nrp1" coefficients
149     c for blmix
150     c-----------------------------------------------------------------------
151    
152     do md = 1, mdiff
153     do i = 1,imt
154     do k=kmtj(i),Nrp1
155     diffus(i,k,md) = 0.0
156     end do
157     end do
158     end do
159    
160     c-----------------------------------------------------------------------
161     c compute boundary layer mixing coefficients:
162     c
163     c diagnose the new boundary layer depth
164     c-----------------------------------------------------------------------
165    
166     call bldepth (
167 heimbach 1.4 I mytime, mythid
168     I , kmtj
169 adcroft 1.1 I , dvsq, dbloc, Ritop, ustar, bo, bosol, coriol
170     I , ikey
171     O , hbl, bfsfc, stable, casea, kbl, Rib, sigma
172     & )
173    
174 heimbach 1.2 CADJ STORE hbl,bfsfc,stable,casea,kbl = comlev1_kpp, key = ikey
175 adcroft 1.1
176     c-----------------------------------------------------------------------
177     c compute boundary layer diffusivities
178     c-----------------------------------------------------------------------
179    
180     call blmix (
181     I ustar, bfsfc, hbl, stable, casea, diffus, kbl
182 heimbach 1.4 O , dkm1, blmc, ghat, sigma, ikey
183 adcroft 1.1 & )
184 heimbach 1.15 cph(
185 heimbach 1.2 CADJ STORE dkm1,blmc,ghat = comlev1_kpp, key = ikey
186 heimbach 1.15 CADJ STORE hbl, kbl, diffus, casea = comlev1_kpp, key = ikey
187     cph)
188 adcroft 1.1
189     c-----------------------------------------------------------------------
190     c enhance diffusivity at interface kbl - 1
191     c-----------------------------------------------------------------------
192    
193     call enhance (
194     I dkm1, hbl, kbl, diffus, casea
195     U , ghat
196     O , blmc )
197 heimbach 1.15
198     cph(
199     cph avoids recomp. of enhance
200     CADJ STORE blmc = comlev1_kpp, key = ikey
201     cph)
202 adcroft 1.1
203     c-----------------------------------------------------------------------
204     c combine interior and boundary layer coefficients and nonlocal term
205 dimitri 1.14 c !!!NOTE!!! In shallow (2-level) regions and for shallow mixed layers
206     c (< 1 level), diffusivity blmc can become negative. The max's below
207     c are a hack until this problem is properly diagnosed and fixed.
208 adcroft 1.1 c-----------------------------------------------------------------------
209     do k = 1, Nr
210     do i = 1, imt
211     if (k .lt. kbl(i)) then
212 dimitri 1.14 diffus(i,k,1) = max ( blmc(i,k,1), viscAr )
213     diffus(i,k,2) = max ( blmc(i,k,2), diffKrS )
214     diffus(i,k,3) = max ( blmc(i,k,3), diffKrT )
215 adcroft 1.1 else
216     ghat(i,k) = 0.
217     endif
218     end do
219     end do
220    
221     #endif /* ALLOW_KPP */
222    
223     return
224     end
225    
226     c*************************************************************************
227    
228     subroutine bldepth (
229 heimbach 1.4 I mytime, mythid
230     I , kmtj
231 adcroft 1.1 I , dvsq, dbloc, Ritop, ustar, bo, bosol, coriol
232     I , ikey
233     O , hbl, bfsfc, stable, casea, kbl, Rib, sigma
234     & )
235    
236     c the oceanic planetary boundary layer depth, hbl, is determined as
237     c the shallowest depth where the bulk Richardson number is
238     c equal to the critical value, Ricr.
239     c
240     c bulk Richardson numbers are evaluated by computing velocity and
241     c buoyancy differences between values at zgrid(kl) < 0 and surface
242     c reference values.
243     c in this configuration, the reference values are equal to the
244     c values in the surface layer.
245     c when using a very fine vertical grid, these values should be
246     c computed as the vertical average of velocity and buoyancy from
247     c the surface down to epsilon*zgrid(kl).
248     c
249     c when the bulk Richardson number at k exceeds Ricr, hbl is
250     c linearly interpolated between grid levels zgrid(k) and zgrid(k-1).
251     c
252     c The water column and the surface forcing are diagnosed for
253     c stable/ustable forcing conditions, and where hbl is relative
254     c to grid points (caseA), so that conditional branches can be
255     c avoided in later subroutines.
256     c
257     IMPLICIT NONE
258    
259     #include "SIZE.h"
260     #include "EEPARAMS.h"
261     #include "PARAMS.h"
262     #include "KPP_PARAMS.h"
263     #include "FFIELDS.h"
264    
265     c input
266     c------
267 heimbach 1.4 c myTime : current time in simulation
268     c myThid : thread number for this instance of the routine
269 adcroft 1.1 c kmtj : number of vertical layers
270     c dvsq : (velocity shear re sfc)^2 ((m/s)^2)
271     c dbloc : local delta buoyancy across interfaces (m/s^2)
272     c Ritop : numerator of bulk Richardson Number
273     c =(z-zref)*dbsfc, where dbsfc=delta
274     c buoyancy with respect to surface ((m/s)^2)
275     c ustar : surface friction velocity (m/s)
276     c bo : surface turbulent buoyancy forcing (m^2/s^3)
277     c bosol : radiative buoyancy forcing (m^2/s^3)
278     c coriol : Coriolis parameter (1/s)
279 heimbach 1.4 _RL mytime
280     integer mythid
281 adcroft 1.1 integer kmtj(imt)
282 heimbach 1.4 _KPP_RL dvsq (imt,Nr)
283     _KPP_RL dbloc (imt,Nr)
284     _KPP_RL Ritop (imt,Nr)
285     _KPP_RL ustar (imt)
286     _KPP_RL bo (imt)
287     _KPP_RL bosol (imt)
288     _KPP_RL coriol(imt)
289 adcroft 1.1 integer ikey
290    
291     c output
292     c--------
293     c hbl : boundary layer depth (m)
294     c bfsfc : Bo+radiation absorbed to d=hbf*hbl (m^2/s^3)
295     c stable : =1 in stable forcing; =0 unstable
296     c casea : =1 in case A, =0 in case B
297     c kbl : -1 of first grid level below hbl
298     c Rib : Bulk Richardson number
299     c sigma : normalized depth (d/hbl)
300 heimbach 1.4 _KPP_RL hbl (imt)
301     _KPP_RL bfsfc (imt)
302     _KPP_RL stable(imt)
303     _KPP_RL casea (imt)
304     integer kbl (imt)
305     _KPP_RL Rib (imt,Nr)
306     _KPP_RL sigma (imt)
307 adcroft 1.1
308     #ifdef ALLOW_KPP
309    
310     c local
311     c-------
312     c wm, ws : turbulent velocity scales (m/s)
313 heimbach 1.4 _KPP_RL wm(imt), ws(imt)
314     _RL worka(imt)
315 adcroft 1.1
316 heimbach 1.4 _KPP_RL bvsq, vtsq, hekman, hmonob, hlimit, tempVar1, tempVar2
317 adcroft 1.1 integer i, kl
318    
319 heimbach 1.4 _KPP_RL p5 , eins
320     parameter ( p5=0.5, eins=1.0 )
321     _RL minusone
322     parameter ( minusone=-1.0 )
323 adcroft 1.1
324     c find bulk Richardson number at every grid level until > Ricr
325     c
326     c note: the reference depth is -epsilon/2.*zgrid(k), but the reference
327     c u,v,t,s values are simply the surface layer values,
328     c and not the averaged values from 0 to 2*ref.depth,
329     c which is necessary for very fine grids(top layer < 2m thickness)
330     c note: max values when Ricr never satisfied are
331     c kbl(i)=kmtj(i) and hbl(i)=-zgrid(kmtj(i))
332    
333     c initialize hbl and kbl to bottomed out values
334    
335     do i = 1, imt
336     Rib(i,1) = 0.0
337     kbl(i) = max(kmtj(i),1)
338     hbl(i) = -zgrid(kbl(i))
339     end do
340    
341     do kl = 2, Nr
342    
343     c compute bfsfc = sw fraction at hbf * zgrid
344    
345     do i = 1, imt
346 heimbach 1.4 worka(i) = zgrid(kl)
347 adcroft 1.1 end do
348     call SWFRAC(
349 heimbach 1.4 I imt, hbf,
350     I mytime, mythid,
351     U worka )
352 adcroft 1.1
353     do i = 1, imt
354    
355     c use caseA as temporary array
356    
357     casea(i) = -zgrid(kl)
358    
359     c compute bfsfc= Bo + radiative contribution down to hbf * hbl
360    
361 heimbach 1.4 bfsfc(i) = bo(i) + bosol(i)*(1. - worka(i))
362 adcroft 1.1 stable(i) = p5 + sign(p5,bfsfc(i))
363     sigma(i) = stable(i) + (1. - stable(i)) * epsilon
364    
365     end do
366    
367     c-----------------------------------------------------------------------
368     c compute velocity scales at sigma, for hbl= caseA = -zgrid(kl)
369     c-----------------------------------------------------------------------
370    
371     call wscale (
372     I sigma, casea, ustar, bfsfc,
373     O wm, ws )
374    
375     do i = 1, imt
376    
377     c-----------------------------------------------------------------------
378     c compute the turbulent shear contribution to Rib
379     c-----------------------------------------------------------------------
380    
381     bvsq = p5 *
382     1 ( dbloc(i,kl-1) / (zgrid(kl-1)-zgrid(kl ))+
383     2 dbloc(i,kl ) / (zgrid(kl )-zgrid(kl+1)))
384    
385     if (bvsq .eq. 0.) then
386     vtsq = 0.0
387     else
388     vtsq = -zgrid(kl) * ws(i) * sqrt(abs(bvsq)) * Vtc
389     endif
390    
391     c compute bulk Richardson number at new level
392     c note: Ritop needs to be zero on land and ocean bottom
393     c points so that the following if statement gets triggered
394     c correctly; otherwise, hbl might get set to (big) negative
395     c values, that might exceed the limit for the "exp" function
396     c in "SWFRAC"
397    
398     c
399     c rg: assignment to double precision variable to avoid overflow
400     c ph: test for zero nominator
401     c
402 heimbach 1.4
403     tempVar1 = dvsq(i,kl) + vtsq
404     tempVar2 = max(tempVar1, phepsi)
405     Rib(i,kl) = Ritop(i,kl) / tempVar2
406    
407 adcroft 1.1 end do
408     end do
409 heimbach 1.10
410     cph(
411     cph without this store, there's a recomputation error for
412     cph rib in adbldepth (probably partial recomputation problem)
413     CADJ store Rib = comlev1_kpp
414     CADJ & , key = ikey, shape = (/ (sNx+2*OLx)*(sNy+2*OLy),Nr /)
415     cph)
416    
417 adcroft 1.1 do kl = 2, Nr
418     do i = 1, imt
419     if (kbl(i).eq.kmtj(i) .and. Rib(i,kl).gt.Ricr) kbl(i) = kl
420     end do
421     end do
422    
423 heimbach 1.2 CADJ store kbl = comlev1_kpp
424 adcroft 1.1 CADJ & , key = ikey, shape = (/ (sNx+2*OLx)*(sNy+2*OLy) /)
425    
426     do i = 1, imt
427     kl = kbl(i)
428     c linearly interpolate to find hbl where Rib = Ricr
429     if (kl.gt.1 .and. kl.lt.kmtj(i)) then
430 heimbach 1.4 tempVar1 = (Rib(i,kl)-Rib(i,kl-1))
431 adcroft 1.1 hbl(i) = -zgrid(kl-1) + (zgrid(kl-1)-zgrid(kl)) *
432 heimbach 1.4 1 (Ricr - Rib(i,kl-1)) / tempVar1
433 adcroft 1.1 endif
434     end do
435    
436 heimbach 1.2 CADJ store hbl = comlev1_kpp
437 adcroft 1.1 CADJ & , key = ikey, shape = (/ (sNx+2*OLx)*(sNy+2*OLy) /)
438    
439     c-----------------------------------------------------------------------
440     c find stability and buoyancy forcing for boundary layer
441     c-----------------------------------------------------------------------
442    
443 heimbach 1.4 do i = 1, imt
444     worka(i) = hbl(i)
445     end do
446 adcroft 1.1 call SWFRAC(
447 heimbach 1.4 I imt, minusone,
448     I mytime, mythid,
449     U worka )
450 adcroft 1.1
451 heimbach 1.4 do i = 1, imt
452     bfsfc(i) = bo(i) + bosol(i) * (1. - worka(i))
453     end do
454 heimbach 1.2 CADJ store bfsfc = comlev1_kpp
455     CADJ & , key = ikey, shape = (/ (sNx+2*OLx)*(sNy+2*OLy) /)
456    
457 heimbach 1.4 c-- ensure bfsfc is never 0
458 adcroft 1.1 do i = 1, imt
459     stable(i) = p5 + sign( p5, bfsfc(i) )
460 heimbach 1.4 bfsfc(i) = sign(eins,bfsfc(i))*max(phepsi,abs(bfsfc(i)))
461     end do
462 adcroft 1.1
463 heimbach 1.10 cph(
464     cph added stable to store list to avoid extensive recomp.
465     CADJ store bfsfc, stable = comlev1_kpp
466 heimbach 1.4 CADJ & , key = ikey, shape = (/ (sNx+2*OLx)*(sNy+2*OLy) /)
467 heimbach 1.10 cph)
468 adcroft 1.1
469     c-----------------------------------------------------------------------
470     c check hbl limits for hekman or hmonob
471     c ph: test for zero nominator
472     c-----------------------------------------------------------------------
473    
474     do i = 1, imt
475     if (bfsfc(i) .gt. 0.0) then
476     hekman = cekman * ustar(i) / max(abs(Coriol(i)),phepsi)
477     hmonob = cmonob * ustar(i)*ustar(i)*ustar(i)
478     & / vonk / bfsfc(i)
479     hlimit = stable(i) * min(hekman,hmonob)
480     & + (stable(i)-1.) * zgrid(Nr)
481     hbl(i) = min(hbl(i),hlimit)
482 heimbach 1.4 end if
483     end do
484     CADJ store hbl = comlev1_kpp
485     CADJ & , key = ikey, shape = (/ (sNx+2*OLx)*(sNy+2*OLy) /)
486    
487     do i = 1, imt
488     hbl(i) = max(hbl(i),minKPPhbl)
489 adcroft 1.1 kbl(i) = kmtj(i)
490     end do
491    
492 heimbach 1.2 CADJ store hbl = comlev1_kpp
493 adcroft 1.1 CADJ & , key = ikey, shape = (/ (sNx+2*OLx)*(sNy+2*OLy) /)
494    
495     c-----------------------------------------------------------------------
496     c find new kbl
497     c-----------------------------------------------------------------------
498    
499     do kl = 2, Nr
500     do i = 1, imt
501     if ( kbl(i).eq.kmtj(i) .and. (-zgrid(kl)).gt.hbl(i) ) then
502     kbl(i) = kl
503     endif
504     end do
505     end do
506    
507     c-----------------------------------------------------------------------
508     c find stability and buoyancy forcing for final hbl values
509     c-----------------------------------------------------------------------
510    
511 heimbach 1.4 do i = 1, imt
512     worka(i) = hbl(i)
513     end do
514 adcroft 1.1 call SWFRAC(
515 heimbach 1.4 I imt, minusone,
516     I mytime, mythid,
517     U worka )
518 adcroft 1.1
519 heimbach 1.4 do i = 1, imt
520     bfsfc(i) = bo(i) + bosol(i) * (1. - worka(i))
521     end do
522 heimbach 1.2 CADJ store bfsfc = comlev1_kpp
523     CADJ & , key = ikey, shape = (/ (sNx+2*OLx)*(sNy+2*OLy) /)
524    
525 heimbach 1.4 c-- ensures bfsfc is never 0
526 adcroft 1.1 do i = 1, imt
527     stable(i) = p5 + sign( p5, bfsfc(i) )
528 heimbach 1.4 bfsfc(i) = sign(eins,bfsfc(i))*max(phepsi,abs(bfsfc(i)))
529 adcroft 1.1 end do
530    
531     c-----------------------------------------------------------------------
532     c determine caseA and caseB
533     c-----------------------------------------------------------------------
534    
535     do i = 1, imt
536     casea(i) = p5 +
537     1 sign(p5, -zgrid(kbl(i)) - p5*hwide(kbl(i)) - hbl(i))
538     end do
539    
540     #endif /* ALLOW_KPP */
541    
542     return
543     end
544    
545     c*************************************************************************
546    
547     subroutine wscale (
548     I sigma, hbl, ustar, bfsfc,
549     O wm, ws )
550    
551     c compute turbulent velocity scales.
552     c use a 2D-lookup table for wm and ws as functions of ustar and
553     c zetahat (=vonk*sigma*hbl*bfsfc).
554     c
555     c note: the lookup table is only used for unstable conditions
556     c (zehat.le.0), in the stable domain wm (=ws) gets computed
557     c directly.
558     c
559     IMPLICIT NONE
560    
561     #include "SIZE.h"
562     #include "KPP_PARAMS.h"
563    
564     c input
565     c------
566     c sigma : normalized depth (d/hbl)
567     c hbl : boundary layer depth (m)
568     c ustar : surface friction velocity (m/s)
569     c bfsfc : total surface buoyancy flux (m^2/s^3)
570 heimbach 1.4 _KPP_RL sigma(imt)
571     _KPP_RL hbl (imt)
572     _KPP_RL ustar(imt)
573     _KPP_RL bfsfc(imt)
574 adcroft 1.1
575     c output
576     c--------
577     c wm, ws : turbulent velocity scales at sigma
578 heimbach 1.4 _KPP_RL wm(imt), ws(imt)
579 adcroft 1.1
580     #ifdef ALLOW_KPP
581    
582     c local
583     c------
584     c zehat : = zeta * ustar**3
585 heimbach 1.4 _KPP_RL zehat
586 adcroft 1.1
587     integer iz, izp1, ju, i, jup1
588 heimbach 1.4 _KPP_RL udiff, zdiff, zfrac, ufrac, fzfrac, wam
589     _KPP_RL wbm, was, wbs, u3, tempVar
590 adcroft 1.1
591     c-----------------------------------------------------------------------
592     c use lookup table for zehat < zmax only; otherwise use
593     c stable formulae
594     c-----------------------------------------------------------------------
595    
596     do i = 1, imt
597     zehat = vonk*sigma(i)*hbl(i)*bfsfc(i)
598    
599     if (zehat .le. zmax) then
600    
601     zdiff = zehat - zmin
602     iz = int( zdiff / deltaz )
603     iz = min( iz, nni )
604     iz = max( iz, 0 )
605     izp1 = iz + 1
606 heimbach 1.4
607 adcroft 1.1 udiff = ustar(i) - umin
608     ju = int( udiff / deltau )
609     ju = min( ju, nnj )
610     ju = max( ju, 0 )
611     jup1 = ju + 1
612 heimbach 1.4
613 adcroft 1.1 zfrac = zdiff / deltaz - float(iz)
614     ufrac = udiff / deltau - float(ju)
615 heimbach 1.4
616 adcroft 1.1 fzfrac= 1. - zfrac
617     wam = fzfrac * wmt(iz,jup1) + zfrac * wmt(izp1,jup1)
618     wbm = fzfrac * wmt(iz,ju ) + zfrac * wmt(izp1,ju )
619     wm(i) = (1.-ufrac) * wbm + ufrac * wam
620 heimbach 1.4
621 adcroft 1.1 was = fzfrac * wst(iz,jup1) + zfrac * wst(izp1,jup1)
622     wbs = fzfrac * wst(iz,ju ) + zfrac * wst(izp1,ju )
623     ws(i) = (1.-ufrac) * wbs + ufrac * was
624 heimbach 1.4
625 adcroft 1.1 else
626 heimbach 1.4
627     u3 = ustar(i) * ustar(i) * ustar(i)
628     tempVar = u3 + conc1 * zehat
629     wm(i) = vonk * ustar(i) * u3 / tempVar
630 adcroft 1.1 ws(i) = wm(i)
631 heimbach 1.4
632 adcroft 1.1 endif
633    
634     end do
635    
636     #endif /* ALLOW_KPP */
637    
638     return
639     end
640    
641     c*************************************************************************
642    
643     subroutine Ri_iwmix (
644     I kmtj, shsq, dbloc, dblocSm
645     I , ikey
646     O , diffus )
647    
648     c compute interior viscosity diffusivity coefficients due
649     c to shear instability (dependent on a local Richardson number),
650     c to background internal wave activity, and
651     c to static instability (local Richardson number < 0).
652    
653     IMPLICIT NONE
654    
655     #include "SIZE.h"
656     #include "EEPARAMS.h"
657     #include "PARAMS.h"
658     #include "KPP_PARAMS.h"
659    
660     c input
661     c kmtj (imt) number of vertical layers on this row
662     c shsq (imt,Nr) (local velocity shear)^2 ((m/s)^2)
663     c dbloc (imt,Nr) local delta buoyancy (m/s^2)
664     c dblocSm(imt,Nr) horizontally smoothed dbloc (m/s^2)
665     integer kmtj (imt)
666 heimbach 1.4 _KPP_RL shsq (imt,Nr)
667     _KPP_RL dbloc (imt,Nr)
668     _KPP_RL dblocSm(imt,Nr)
669 adcroft 1.1 integer ikey
670    
671     c output
672     c diffus(imt,0:Nrp1,1) vertical viscosivity coefficient (m^2/s)
673     c diffus(imt,0:Nrp1,2) vertical scalar diffusivity (m^2/s)
674     c diffus(imt,0:Nrp1,3) vertical temperature diffusivity (m^2/s)
675 heimbach 1.4 _KPP_RL diffus(imt,0:Nrp1,3)
676 adcroft 1.1
677     #ifdef ALLOW_KPP
678    
679     c local variables
680     c Rig local Richardson number
681     c fRi, fcon function of Rig
682 heimbach 1.4 _KPP_RL Rig
683     _KPP_RL fRi, fcon
684     _KPP_RL ratio
685 dimitri 1.13 integer i, ki
686 heimbach 1.4 _KPP_RL c1, c0
687 adcroft 1.1
688 heimbach 1.5 #ifdef ALLOW_KPP_VERTICALLY_SMOOTH
689 dimitri 1.13 integer mr
690 heimbach 1.5 CADJ INIT kpp_ri_tape_mr = common, 1
691     #endif
692    
693 adcroft 1.1 c constants
694     c1 = 1.0
695     c0 = 0.0
696    
697     c-----------------------------------------------------------------------
698     c compute interior gradient Ri at all interfaces ki=1,Nr, (not surface)
699     c use diffus(*,*,1) as temporary storage of Ri to be smoothed
700     c use diffus(*,*,2) as temporary storage for Brunt-Vaisala squared
701     c set values at bottom and below to nearest value above bottom
702 heimbach 1.5 #ifdef ALLOW_AUTODIFF_TAMC
703     C break data flow dependence on diffus
704     diffus(1,1,1) = 0.0
705     #endif
706 adcroft 1.1
707     do ki = 1, Nr
708     do i = 1, imt
709 heimbach 1.9 if (kmtj(i) .LE. 1 ) then
710 adcroft 1.1 diffus(i,ki,1) = 0.
711     diffus(i,ki,2) = 0.
712     elseif (ki .GE. kmtj(i)) then
713     diffus(i,ki,1) = diffus(i,ki-1,1)
714     diffus(i,ki,2) = diffus(i,ki-1,2)
715     else
716     diffus(i,ki,1) = dblocSm(i,ki) * (zgrid(ki)-zgrid(ki+1))
717     & / max( Shsq(i,ki), phepsi )
718     diffus(i,ki,2) = dbloc(i,ki) / (zgrid(ki)-zgrid(ki+1))
719     endif
720     end do
721     end do
722    
723     c-----------------------------------------------------------------------
724     c vertically smooth Ri
725 heimbach 1.5 #ifdef ALLOW_KPP_VERTICALLY_SMOOTH
726 adcroft 1.1 do mr = 1, num_v_smooth_Ri
727 heimbach 1.2
728 heimbach 1.5 CADJ store diffus(:,:,1) = kpp_ri_tape_mr
729     CADJ & , key=mr, shape=(/ (sNx+2*OLx)*(sNy+2*OLy),Nr+2 /)
730 heimbach 1.2
731 adcroft 1.1 call z121 (
732     U diffus(1,0,1))
733     end do
734 heimbach 1.5 #endif
735 adcroft 1.1
736     c-----------------------------------------------------------------------
737     c after smoothing loop
738    
739     do ki = 1, Nr
740     do i = 1, imt
741    
742     c evaluate f of Brunt-Vaisala squared for convection, store in fcon
743    
744     Rig = max ( diffus(i,ki,2) , BVSQcon )
745     ratio = min ( (BVSQcon - Rig) / BVSQcon, c1 )
746     fcon = c1 - ratio * ratio
747     fcon = fcon * fcon * fcon
748    
749     c evaluate f of smooth Ri for shear instability, store in fRi
750    
751     Rig = max ( diffus(i,ki,1), c0 )
752     ratio = min ( Rig / Riinfty , c1 )
753     fRi = c1 - ratio * ratio
754     fRi = fRi * fRi * fRi
755    
756     c ----------------------------------------------------------------------
757     c evaluate diffusivities and viscosity
758     c mixing due to internal waves, and shear and static instability
759    
760     diffus(i,ki,1) = viscAr + fcon * difmcon + fRi * difm0
761     diffus(i,ki,2) = diffKrS + fcon * difscon + fRi * difs0
762 heimbach 1.2 diffus(i,ki,3) = diffKrT + fcon * difscon + fRi * difs0
763 adcroft 1.1
764     end do
765     end do
766    
767     c ------------------------------------------------------------------------
768     c set surface values to 0.0
769    
770     do i = 1, imt
771     diffus(i,0,1) = c0
772     diffus(i,0,2) = c0
773     diffus(i,0,3) = c0
774     end do
775    
776     #endif /* ALLOW_KPP */
777    
778     return
779     end
780    
781     c*************************************************************************
782    
783     subroutine z121 (
784     U v )
785    
786     c Apply 121 smoothing in k to 2-d array V(i,k=1,Nr)
787     c top (0) value is used as a dummy
788     c bottom (Nrp1) value is set to input value from above.
789    
790 heimbach 1.2 c Note that it is important to exclude from the smoothing any points
791 adcroft 1.1 c that are outside the range of the K(Ri) scheme, ie. >0.8, or <0.0.
792 heimbach 1.2 c Otherwise, there is interference with other physics, especially
793 adcroft 1.1 c penetrative convection.
794    
795     IMPLICIT NONE
796     #include "SIZE.h"
797     #include "KPP_PARAMS.h"
798    
799     c input/output
800     c-------------
801     c v : 2-D array to be smoothed in Nrp1 direction
802 heimbach 1.4 _KPP_RL v(imt,0:Nrp1)
803 adcroft 1.1
804     #ifdef ALLOW_KPP
805    
806     c local
807 heimbach 1.4 _KPP_RL zwork, zflag
808     _KPP_RL KRi_range(1:Nrp1)
809 adcroft 1.1 integer i, k, km1, kp1
810    
811 heimbach 1.4 _KPP_RL p0 , p25 , p5 , p2
812 heimbach 1.2 parameter ( p0 = 0.0, p25 = 0.25, p5 = 0.5, p2 = 2.0 )
813    
814     KRi_range(Nrp1) = p0
815 adcroft 1.1
816 heimbach 1.2 #ifdef ALLOW_AUTODIFF_TAMC
817     C-- dummy assignment to end declaration part for TAMC
818     i = 0
819    
820     C-- HPF directive to help TAMC
821     CHPF$ INDEPENDENT
822 heimbach 1.4 CADJ INIT z121tape = common, Nr
823 heimbach 1.2 #endif /* ALLOW_AUTODIFF_TAMC */
824 heimbach 1.4
825 adcroft 1.1 do i = 1, imt
826    
827 heimbach 1.4 k = 1
828     CADJ STORE v(i,k) = z121tape
829 adcroft 1.1 v(i,Nrp1) = v(i,Nr)
830    
831     do k = 1, Nr
832     KRi_range(k) = p5 + SIGN(p5,v(i,k))
833     KRi_range(k) = KRi_range(k) *
834     & ( p5 + SIGN(p5,(Riinfty-v(i,k))) )
835     end do
836    
837     zwork = KRi_range(1) * v(i,1)
838     v(i,1) = p2 * v(i,1) +
839     & KRi_range(1) * KRi_range(2) * v(i,2)
840     zflag = p2 + KRi_range(1) * KRi_range(2)
841     v(i,1) = v(i,1) / zflag
842    
843     do k = 2, Nr
844 heimbach 1.2 CADJ STORE v(i,k), zwork = z121tape
845 adcroft 1.1 km1 = k - 1
846     kp1 = k + 1
847     zflag = v(i,k)
848     v(i,k) = p2 * v(i,k) +
849     & KRi_range(k) * KRi_range(kp1) * v(i,kp1) +
850     & KRi_range(k) * zwork
851     zwork = KRi_range(k) * zflag
852     zflag = p2 + KRi_range(k)*(KRi_range(kp1)+KRi_range(km1))
853     v(i,k) = v(i,k) / zflag
854     end do
855    
856     end do
857    
858     #endif /* ALLOW_KPP */
859    
860     return
861     end
862    
863     c*************************************************************************
864    
865 heimbach 1.4 subroutine kpp_smooth_horiz (
866 adcroft 1.1 I k, bi, bj,
867 heimbach 1.4 U fld )
868 adcroft 1.1
869 heimbach 1.4 c Apply horizontal smoothing to KPP array
870 adcroft 1.1
871     IMPLICIT NONE
872     #include "SIZE.h"
873     #include "KPP_PARAMS.h"
874    
875     c input
876 heimbach 1.4 c bi, bj : array indices
877     c k : vertical index used for masking
878 adcroft 1.1 integer k, bi, bj
879    
880 heimbach 1.4 c input/output
881     c fld : 2-D array to be smoothed
882     _KPP_RL fld( ibot:itop, jbot:jtop )
883 adcroft 1.1
884     #ifdef ALLOW_KPP
885    
886     c local
887     integer i, j, im1, ip1, jm1, jp1
888 heimbach 1.4 _KPP_RL tempVar
889     _KPP_RL fld_tmp( ibot:itop, jbot:jtop )
890 adcroft 1.1
891 heimbach 1.4 integer imin , imax , jmin , jmax
892     parameter( imin=ibot+1, imax=itop-1, jmin=jbot+1, jmax=jtop-1 )
893 adcroft 1.1
894 heimbach 1.4 _KPP_RL p0 , p5 , p25 , p125 , p0625
895 adcroft 1.1 parameter( p0=0.0, p5=0.5, p25=0.25, p125=0.125, p0625=0.0625 )
896    
897     DO j = jmin, jmax
898     jm1 = j-1
899     jp1 = j+1
900     DO i = imin, imax
901     im1 = i-1
902     ip1 = i+1
903     tempVar =
904     & p25 * pMask(i ,j ,k,bi,bj) +
905     & p125 * ( pMask(im1,j ,k,bi,bj) +
906     & pMask(ip1,j ,k,bi,bj) +
907     & pMask(i ,jm1,k,bi,bj) +
908     & pMask(i ,jp1,k,bi,bj) ) +
909     & p0625 * ( pMask(im1,jm1,k,bi,bj) +
910     & pMask(im1,jp1,k,bi,bj) +
911     & pMask(ip1,jm1,k,bi,bj) +
912     & pMask(ip1,jp1,k,bi,bj) )
913     IF ( tempVar .GE. p25 ) THEN
914     fld_tmp(i,j) = (
915 heimbach 1.4 & p25 * fld(i ,j )*pMask(i ,j ,k,bi,bj) +
916     & p125 *(fld(im1,j )*pMask(im1,j ,k,bi,bj) +
917     & fld(ip1,j )*pMask(ip1,j ,k,bi,bj) +
918     & fld(i ,jm1)*pMask(i ,jm1,k,bi,bj) +
919     & fld(i ,jp1)*pMask(i ,jp1,k,bi,bj))+
920     & p0625*(fld(im1,jm1)*pMask(im1,jm1,k,bi,bj) +
921     & fld(im1,jp1)*pMask(im1,jp1,k,bi,bj) +
922     & fld(ip1,jm1)*pMask(ip1,jm1,k,bi,bj) +
923     & fld(ip1,jp1)*pMask(ip1,jp1,k,bi,bj)))
924 adcroft 1.1 & / tempVar
925     ELSE
926 heimbach 1.4 fld_tmp(i,j) = fld(i,j)
927 adcroft 1.1 ENDIF
928     ENDDO
929     ENDDO
930    
931     c transfer smoothed field to output array
932     DO j = jmin, jmax
933     DO i = imin, imax
934 heimbach 1.4 fld(i,j) = fld_tmp(i,j)
935 adcroft 1.1 ENDDO
936     ENDDO
937    
938     #endif /* ALLOW_KPP */
939    
940     return
941     end
942    
943     c*************************************************************************
944    
945 heimbach 1.4 subroutine smooth_horiz (
946 adcroft 1.1 I k, bi, bj,
947 heimbach 1.4 U fld )
948 adcroft 1.1
949 heimbach 1.4 c Apply horizontal smoothing to global _RL 2-D array
950 adcroft 1.1
951     IMPLICIT NONE
952     #include "SIZE.h"
953     #include "KPP_PARAMS.h"
954    
955     c input
956 heimbach 1.4 c bi, bj : array indices
957     c k : vertical index used for masking
958 adcroft 1.1 integer k, bi, bj
959    
960 heimbach 1.4 c input/output
961     c fld : 2-D array to be smoothed
962     _RL fld( 1-OLx:sNx+OLx, 1-OLy:sNy+OLy )
963 adcroft 1.1
964     #ifdef ALLOW_KPP
965    
966     c local
967     integer i, j, im1, ip1, jm1, jp1
968     _RL tempVar
969 heimbach 1.4 _RL fld_tmp( 1-OLx:sNx+OLx, 1-OLy:sNy+OLy )
970 adcroft 1.1
971 heimbach 1.4 integer imin , imax , jmin , jmax
972     parameter(imin=2-OLx, imax=sNx+OLx-1, jmin=2-OLy, jmax=sNy+OLy-1)
973 adcroft 1.1
974 heimbach 1.4 _RL p0 , p5 , p25 , p125 , p0625
975 adcroft 1.1 parameter( p0=0.0, p5=0.5, p25=0.25, p125=0.125, p0625=0.0625 )
976    
977     DO j = jmin, jmax
978     jm1 = j-1
979     jp1 = j+1
980     DO i = imin, imax
981     im1 = i-1
982     ip1 = i+1
983     tempVar =
984     & p25 * pMask(i ,j ,k,bi,bj) +
985     & p125 * ( pMask(im1,j ,k,bi,bj) +
986     & pMask(ip1,j ,k,bi,bj) +
987     & pMask(i ,jm1,k,bi,bj) +
988     & pMask(i ,jp1,k,bi,bj) ) +
989     & p0625 * ( pMask(im1,jm1,k,bi,bj) +
990     & pMask(im1,jp1,k,bi,bj) +
991     & pMask(ip1,jm1,k,bi,bj) +
992     & pMask(ip1,jp1,k,bi,bj) )
993     IF ( tempVar .GE. p25 ) THEN
994     fld_tmp(i,j) = (
995 heimbach 1.4 & p25 * fld(i ,j )*pMask(i ,j ,k,bi,bj) +
996     & p125 *(fld(im1,j )*pMask(im1,j ,k,bi,bj) +
997     & fld(ip1,j )*pMask(ip1,j ,k,bi,bj) +
998     & fld(i ,jm1)*pMask(i ,jm1,k,bi,bj) +
999     & fld(i ,jp1)*pMask(i ,jp1,k,bi,bj))+
1000     & p0625*(fld(im1,jm1)*pMask(im1,jm1,k,bi,bj) +
1001     & fld(im1,jp1)*pMask(im1,jp1,k,bi,bj) +
1002     & fld(ip1,jm1)*pMask(ip1,jm1,k,bi,bj) +
1003     & fld(ip1,jp1)*pMask(ip1,jp1,k,bi,bj)))
1004 adcroft 1.1 & / tempVar
1005     ELSE
1006 heimbach 1.4 fld_tmp(i,j) = fld(i,j)
1007 adcroft 1.1 ENDIF
1008     ENDDO
1009     ENDDO
1010    
1011     c transfer smoothed field to output array
1012     DO j = jmin, jmax
1013     DO i = imin, imax
1014 heimbach 1.4 fld(i,j) = fld_tmp(i,j)
1015 adcroft 1.1 ENDDO
1016     ENDDO
1017    
1018     #endif /* ALLOW_KPP */
1019    
1020     return
1021     end
1022    
1023     c*************************************************************************
1024    
1025     subroutine blmix (
1026     I ustar, bfsfc, hbl, stable, casea, diffus, kbl
1027 heimbach 1.4 O , dkm1, blmc, ghat, sigma, ikey
1028 adcroft 1.1 & )
1029    
1030     c mixing coefficients within boundary layer depend on surface
1031     c forcing and the magnitude and gradient of interior mixing below
1032     c the boundary layer ("matching").
1033     c
1034     c caution: if mixing bottoms out at hbl = -zgrid(Nr) then
1035     c fictitious layer at Nrp1 is needed with small but finite width
1036     c hwide(Nrp1) (eg. epsln = 1.e-20).
1037     c
1038     IMPLICIT NONE
1039    
1040     #include "SIZE.h"
1041     #include "KPP_PARAMS.h"
1042    
1043     c input
1044     c ustar (imt) surface friction velocity (m/s)
1045     c bfsfc (imt) surface buoyancy forcing (m^2/s^3)
1046     c hbl (imt) boundary layer depth (m)
1047     c stable(imt) = 1 in stable forcing
1048     c casea (imt) = 1 in case A
1049     c diffus(imt,0:Nrp1,mdiff) vertical diffusivities (m^2/s)
1050     c kbl(imt) -1 of first grid level below hbl
1051 heimbach 1.4 _KPP_RL ustar (imt)
1052     _KPP_RL bfsfc (imt)
1053     _KPP_RL hbl (imt)
1054     _KPP_RL stable(imt)
1055     _KPP_RL casea (imt)
1056     _KPP_RL diffus(imt,0:Nrp1,mdiff)
1057 adcroft 1.1 integer kbl(imt)
1058    
1059     c output
1060     c dkm1 (imt,mdiff) boundary layer difs at kbl-1 level
1061     c blmc (imt,Nr,mdiff) boundary layer mixing coefficients (m^2/s)
1062     c ghat (imt,Nr) nonlocal scalar transport
1063     c sigma(imt) normalized depth (d / hbl)
1064 heimbach 1.4 _KPP_RL dkm1 (imt,mdiff)
1065     _KPP_RL blmc (imt,Nr,mdiff)
1066     _KPP_RL ghat (imt,Nr)
1067     _KPP_RL sigma(imt)
1068     integer ikey
1069 adcroft 1.1
1070     #ifdef ALLOW_KPP
1071    
1072     c local
1073 heimbach 1.2 c gat1*(imt) shape function at sigma = 1
1074     c dat1*(imt) derivative of shape function at sigma = 1
1075 adcroft 1.1 c ws(imt), wm(imt) turbulent velocity scales (m/s)
1076 heimbach 1.4 _KPP_RL gat1m(imt), gat1s(imt), gat1t(imt)
1077     _KPP_RL dat1m(imt), dat1s(imt), dat1t(imt)
1078     _KPP_RL ws(imt), wm(imt)
1079 adcroft 1.1 integer i, kn, ki
1080 heimbach 1.4 _KPP_RL R, dvdzup, dvdzdn, viscp
1081     _KPP_RL difsp, diftp, visch, difsh, difth
1082     _KPP_RL f1, sig, a1, a2, a3, delhat
1083     _KPP_RL Gm, Gs, Gt
1084     _KPP_RL tempVar
1085 adcroft 1.1
1086 heimbach 1.4 _KPP_RL p0 , eins
1087 heimbach 1.2 parameter (p0=0.0, eins=1.0)
1088 adcroft 1.1
1089     c-----------------------------------------------------------------------
1090     c compute velocity scales at hbl
1091     c-----------------------------------------------------------------------
1092    
1093     do i = 1, imt
1094     sigma(i) = stable(i) * 1.0 + (1. - stable(i)) * epsilon
1095     end do
1096    
1097     call wscale (
1098     I sigma, hbl, ustar, bfsfc,
1099     O wm, ws )
1100    
1101     do i = 1, imt
1102 heimbach 1.4 wm(i) = sign(eins,wm(i))*max(phepsi,abs(wm(i)))
1103     ws(i) = sign(eins,ws(i))*max(phepsi,abs(ws(i)))
1104     end do
1105     CADJ STORE wm = comlev1_kpp, key = ikey
1106     CADJ STORE ws = comlev1_kpp, key = ikey
1107    
1108     do i = 1, imt
1109 adcroft 1.1
1110     kn = int(caseA(i)+phepsi) *(kbl(i) -1) +
1111     $ (1 - int(caseA(i)+phepsi)) * kbl(i)
1112    
1113     c-----------------------------------------------------------------------
1114     c find the interior viscosities and derivatives at hbl(i)
1115     c-----------------------------------------------------------------------
1116    
1117     delhat = 0.5*hwide(kn) - zgrid(kn) - hbl(i)
1118     R = 1.0 - delhat / hwide(kn)
1119     dvdzup = (diffus(i,kn-1,1) - diffus(i,kn ,1)) / hwide(kn)
1120     dvdzdn = (diffus(i,kn ,1) - diffus(i,kn+1,1)) / hwide(kn+1)
1121     viscp = 0.5 * ( (1.-R) * (dvdzup + abs(dvdzup)) +
1122     1 R * (dvdzdn + abs(dvdzdn)) )
1123    
1124     dvdzup = (diffus(i,kn-1,2) - diffus(i,kn ,2)) / hwide(kn)
1125     dvdzdn = (diffus(i,kn ,2) - diffus(i,kn+1,2)) / hwide(kn+1)
1126     difsp = 0.5 * ( (1.-R) * (dvdzup + abs(dvdzup)) +
1127     1 R * (dvdzdn + abs(dvdzdn)) )
1128    
1129     dvdzup = (diffus(i,kn-1,3) - diffus(i,kn ,3)) / hwide(kn)
1130     dvdzdn = (diffus(i,kn ,3) - diffus(i,kn+1,3)) / hwide(kn+1)
1131     diftp = 0.5 * ( (1.-R) * (dvdzup + abs(dvdzup)) +
1132     1 R * (dvdzdn + abs(dvdzdn)) )
1133    
1134     visch = diffus(i,kn,1) + viscp * delhat
1135     difsh = diffus(i,kn,2) + difsp * delhat
1136     difth = diffus(i,kn,3) + diftp * delhat
1137    
1138     f1 = stable(i) * conc1 * bfsfc(i) /
1139     & max(ustar(i)**4,phepsi)
1140 heimbach 1.2 gat1m(i) = visch / hbl(i) / wm(i)
1141     dat1m(i) = -viscp / wm(i) + f1 * visch
1142     dat1m(i) = min(dat1m(i),p0)
1143 adcroft 1.1
1144 heimbach 1.2 gat1s(i) = difsh / hbl(i) / ws(i)
1145     dat1s(i) = -difsp / ws(i) + f1 * difsh
1146     dat1s(i) = min(dat1s(i),p0)
1147 adcroft 1.1
1148 heimbach 1.2 gat1t(i) = difth / hbl(i) / ws(i)
1149     dat1t(i) = -diftp / ws(i) + f1 * difth
1150     dat1t(i) = min(dat1t(i),p0)
1151 adcroft 1.1
1152     end do
1153    
1154     do ki = 1, Nr
1155    
1156     c-----------------------------------------------------------------------
1157     c compute turbulent velocity scales on the interfaces
1158     c-----------------------------------------------------------------------
1159    
1160     do i = 1, imt
1161     sig = (-zgrid(ki) + 0.5 * hwide(ki)) / hbl(i)
1162     sigma(i) = stable(i)*sig + (1.-stable(i))*min(sig,epsilon)
1163     end do
1164     call wscale (
1165     I sigma, hbl, ustar, bfsfc,
1166     O wm, ws )
1167    
1168     c-----------------------------------------------------------------------
1169     c compute the dimensionless shape functions at the interfaces
1170     c-----------------------------------------------------------------------
1171    
1172     do i = 1, imt
1173     sig = (-zgrid(ki) + 0.5 * hwide(ki)) / hbl(i)
1174     a1 = sig - 2.
1175     a2 = 3. - 2. * sig
1176     a3 = sig - 1.
1177    
1178 heimbach 1.2 Gm = a1 + a2 * gat1m(i) + a3 * dat1m(i)
1179     Gs = a1 + a2 * gat1s(i) + a3 * dat1s(i)
1180     Gt = a1 + a2 * gat1t(i) + a3 * dat1t(i)
1181 adcroft 1.1
1182     c-----------------------------------------------------------------------
1183     c compute boundary layer diffusivities at the interfaces
1184     c-----------------------------------------------------------------------
1185    
1186 heimbach 1.2 blmc(i,ki,1) = hbl(i) * wm(i) * sig * (1. + sig * Gm)
1187 adcroft 1.1 blmc(i,ki,2) = hbl(i) * ws(i) * sig * (1. + sig * Gs)
1188     blmc(i,ki,3) = hbl(i) * ws(i) * sig * (1. + sig * Gt)
1189    
1190     c-----------------------------------------------------------------------
1191     c nonlocal transport term = ghat * <ws>o
1192     c-----------------------------------------------------------------------
1193 heimbach 1.4
1194     tempVar = ws(i) * hbl(i)
1195     ghat(i,ki) = (1.-stable(i)) * cg / max(phepsi,tempVar)
1196 adcroft 1.1
1197     end do
1198     end do
1199    
1200     c-----------------------------------------------------------------------
1201     c find diffusivities at kbl-1 grid level
1202     c-----------------------------------------------------------------------
1203    
1204     do i = 1, imt
1205     sig = -zgrid(kbl(i)-1) / hbl(i)
1206     sigma(i) = stable(i) * sig
1207     & + (1. - stable(i)) * min(sig,epsilon)
1208     end do
1209    
1210     call wscale (
1211     I sigma, hbl, ustar, bfsfc,
1212     O wm, ws )
1213    
1214     do i = 1, imt
1215     sig = -zgrid(kbl(i)-1) / hbl(i)
1216     a1 = sig - 2.
1217     a2 = 3. - 2. * sig
1218     a3 = sig - 1.
1219 heimbach 1.2 Gm = a1 + a2 * gat1m(i) + a3 * dat1m(i)
1220     Gs = a1 + a2 * gat1s(i) + a3 * dat1s(i)
1221     Gt = a1 + a2 * gat1t(i) + a3 * dat1t(i)
1222     dkm1(i,1) = hbl(i) * wm(i) * sig * (1. + sig * Gm)
1223 adcroft 1.1 dkm1(i,2) = hbl(i) * ws(i) * sig * (1. + sig * Gs)
1224     dkm1(i,3) = hbl(i) * ws(i) * sig * (1. + sig * Gt)
1225     end do
1226    
1227     #endif /* ALLOW_KPP */
1228    
1229     return
1230     end
1231    
1232     c*************************************************************************
1233    
1234     subroutine enhance (
1235     I dkm1, hbl, kbl, diffus, casea
1236     U , ghat
1237     O , blmc
1238     & )
1239    
1240     c enhance the diffusivity at the kbl-.5 interface
1241    
1242     IMPLICIT NONE
1243    
1244     #include "SIZE.h"
1245     #include "KPP_PARAMS.h"
1246    
1247     c input
1248     c dkm1(imt,mdiff) bl diffusivity at kbl-1 grid level
1249     c hbl(imt) boundary layer depth (m)
1250     c kbl(imt) grid above hbl
1251     c diffus(imt,0:Nrp1,mdiff) vertical diffusivities (m^2/s)
1252     c casea(imt) = 1 in caseA, = 0 in case B
1253 heimbach 1.4 _KPP_RL dkm1 (imt,mdiff)
1254     _KPP_RL hbl (imt)
1255 adcroft 1.1 integer kbl (imt)
1256 heimbach 1.4 _KPP_RL diffus(imt,0:Nrp1,mdiff)
1257     _KPP_RL casea (imt)
1258 adcroft 1.1
1259     c input/output
1260     c nonlocal transport, modified ghat at kbl(i)-1 interface (s/m**2)
1261 heimbach 1.4 _KPP_RL ghat (imt,Nr)
1262 adcroft 1.1
1263     c output
1264     c enhanced bound. layer mixing coeff.
1265 heimbach 1.4 _KPP_RL blmc (imt,Nr,mdiff)
1266 adcroft 1.1
1267     #ifdef ALLOW_KPP
1268    
1269     c local
1270     c fraction hbl lies beteen zgrid neighbors
1271 heimbach 1.4 _KPP_RL delta
1272 adcroft 1.1 integer ki, i, md
1273 heimbach 1.4 _KPP_RL dkmp5, dstar
1274 adcroft 1.1
1275     do i = 1, imt
1276     ki = kbl(i)-1
1277     if ((ki .ge. 1) .and. (ki .lt. Nr)) then
1278     delta = (hbl(i) + zgrid(ki)) / (zgrid(ki) - zgrid(ki+1))
1279     do md = 1, mdiff
1280     dkmp5 = casea(i) * diffus(i,ki,md) +
1281     1 (1.- casea(i)) * blmc (i,ki,md)
1282     dstar = (1.- delta)**2 * dkm1(i,md)
1283     & + delta**2 * dkmp5
1284     blmc(i,ki,md) = (1.- delta)*diffus(i,ki,md)
1285     & + delta*dstar
1286     end do
1287     ghat(i,ki) = (1.- casea(i)) * ghat(i,ki)
1288     endif
1289     end do
1290    
1291     #endif /* ALLOW_KPP */
1292    
1293     return
1294     end
1295    
1296     c*************************************************************************
1297    
1298     SUBROUTINE STATEKPP (
1299     I bi, bj, myThid,
1300     O RHO1, DBLOC, DBSFC, TTALPHA, SSBETA)
1301     c
1302     c-----------------------------------------------------------------------
1303     c "statekpp" computes all necessary input arrays
1304     c for the kpp mixing scheme
1305     c
1306     c input:
1307     c bi, bj = array indices on which to apply calculations
1308     c
1309     c output:
1310     c rho1 = potential density of surface layer (kg/m^3)
1311     c dbloc = local buoyancy gradient at Nr interfaces
1312     c g/rho{k+1,k+1} * [ drho{k,k+1}-drho{k+1,k+1} ] (m/s^2)
1313     c dbsfc = buoyancy difference with respect to the surface
1314     c g * [ drho{1,k}/rho{1,k} - drho{k,k}/rho{k,k} ] (m/s^2)
1315     c ttalpha= thermal expansion coefficient without 1/rho factor
1316     c d(rho) / d(potential temperature) (kg/m^3/C)
1317     c ssbeta = salt expansion coefficient without 1/rho factor
1318     c d(rho) / d(salinity) (kg/m^3/PSU)
1319     c
1320     c see also subroutines find_rho.F find_alpha.F find_beta.F
1321     c
1322     c written by: jan morzel, feb. 10, 1995 (converted from "sigma" version)
1323     c modified by: d. menemenlis, june 1998 : for use with MIT GCM UV
1324     c
1325     c-----------------------------------------------------------------------
1326    
1327     IMPLICIT NONE
1328    
1329     #include "SIZE.h"
1330     #include "EEPARAMS.h"
1331     #include "PARAMS.h"
1332     #include "KPP_PARAMS.h"
1333 adcroft 1.6 #include "DYNVARS.h"
1334 adcroft 1.1
1335     c-------------- Routine arguments -----------------------------------------
1336     INTEGER bi, bj, myThid
1337 heimbach 1.4 _KPP_RL RHO1 ( ibot:itop, jbot:jtop )
1338     _KPP_RL DBLOC ( ibot:itop, jbot:jtop, Nr )
1339     _KPP_RL DBSFC ( ibot:itop, jbot:jtop, Nr )
1340     _KPP_RL TTALPHA( ibot:itop, jbot:jtop, Nrp1 )
1341     _KPP_RL SSBETA ( ibot:itop, jbot:jtop, Nrp1 )
1342 adcroft 1.1
1343     #ifdef ALLOW_KPP
1344    
1345     c--------------------------------------------------------------------------
1346     c
1347     c local arrays:
1348     c
1349     c rhok - density of t(k ) & s(k ) at depth k
1350     c rhokm1 - density of t(k-1) & s(k-1) at depth k
1351     c rho1k - density of t(1 ) & s(1 ) at depth k
1352     c work1, work2 - work arrays for holding horizontal slabs
1353    
1354     _RL RHOK (1-OLx:sNx+OLx,1-OLy:sNy+OLy)
1355     _RL RHOKM1(1-OLx:sNx+OLx,1-OLy:sNy+OLy)
1356     _RL RHO1K (1-OLx:sNx+OLx,1-OLy:sNy+OLy)
1357     _RL WORK1 (1-OLx:sNx+OLx,1-OLy:sNy+OLy)
1358     _RL WORK2 (1-OLx:sNx+OLx,1-OLy:sNy+OLy)
1359     _RL WORK3 (1-OLx:sNx+OLx,1-OLy:sNy+OLy)
1360     INTEGER I, J, K
1361    
1362     c calculate density, alpha, beta in surface layer, and set dbsfc to zero
1363    
1364     call FIND_RHO(
1365 mlosch 1.11 I bi, bj, ibot, itop, jbot, jtop, 1, 1,
1366 adcroft 1.6 I theta, salt,
1367 adcroft 1.1 O WORK1,
1368     I myThid )
1369    
1370     call FIND_ALPHA(
1371 mlosch 1.11 I bi, bj, ibot, itop, jbot, jtop, 1, 1,
1372 adcroft 1.1 O WORK2 )
1373    
1374     call FIND_BETA(
1375 mlosch 1.11 I bi, bj, ibot, itop, jbot, jtop, 1, 1,
1376 adcroft 1.1 O WORK3 )
1377    
1378 heimbach 1.4 DO J = jbot, jtop
1379     DO I = ibot, itop
1380 mlosch 1.12 RHO1(I,J) = WORK1(I,J) + rhoConst
1381 adcroft 1.1 TTALPHA(I,J,1) = WORK2(I,J)
1382     SSBETA(I,J,1) = WORK3(I,J)
1383     DBSFC(I,J,1) = 0.
1384     END DO
1385     END DO
1386    
1387     c calculate alpha, beta, and gradients in interior layers
1388    
1389 heimbach 1.2 CHPF$ INDEPENDENT, NEW (RHOK,RHOKM1,RHO1K,WORK1,WORK2)
1390 adcroft 1.1 DO K = 2, Nr
1391    
1392     call FIND_RHO(
1393 mlosch 1.11 I bi, bj, ibot, itop, jbot, jtop, K, K,
1394 adcroft 1.6 I theta, salt,
1395 adcroft 1.1 O RHOK,
1396     I myThid )
1397    
1398     call FIND_RHO(
1399 mlosch 1.11 I bi, bj, ibot, itop, jbot, jtop, K-1, K,
1400 adcroft 1.6 I theta, salt,
1401 adcroft 1.1 O RHOKM1,
1402     I myThid )
1403    
1404     call FIND_RHO(
1405 mlosch 1.11 I bi, bj, ibot, itop, jbot, jtop, 1, K,
1406 adcroft 1.6 I theta, salt,
1407 adcroft 1.1 O RHO1K,
1408     I myThid )
1409    
1410     call FIND_ALPHA(
1411 mlosch 1.11 I bi, bj, ibot, itop, jbot, jtop, K, K,
1412 adcroft 1.1 O WORK1 )
1413    
1414     call FIND_BETA(
1415 mlosch 1.11 I bi, bj, ibot, itop, jbot, jtop, K, K,
1416 adcroft 1.1 O WORK2 )
1417    
1418 heimbach 1.4 DO J = jbot, jtop
1419     DO I = ibot, itop
1420 adcroft 1.1 TTALPHA(I,J,K) = WORK1 (I,J)
1421     SSBETA(I,J,K) = WORK2 (I,J)
1422     DBLOC(I,J,K-1) = gravity * (RHOK(I,J) - RHOKM1(I,J)) /
1423 mlosch 1.12 & (RHOK(I,J) + rhoConst)
1424 adcroft 1.1 DBSFC(I,J,K) = gravity * (RHOK(I,J) - RHO1K (I,J)) /
1425 mlosch 1.12 & (RHOK(I,J) + rhoConst)
1426 adcroft 1.1 END DO
1427     END DO
1428    
1429     END DO
1430    
1431     c compute arrays for K = Nrp1
1432 heimbach 1.4 DO J = jbot, jtop
1433     DO I = ibot, itop
1434 adcroft 1.1 TTALPHA(I,J,Nrp1) = TTALPHA(I,J,Nr)
1435     SSBETA(I,J,Nrp1) = SSBETA(I,J,Nr)
1436     DBLOC(I,J,Nr) = 0.
1437     END DO
1438     END DO
1439    
1440     #endif /* ALLOW_KPP */
1441    
1442     RETURN
1443     END

  ViewVC Help
Powered by ViewVC 1.1.22