/[MITgcm]/MITgcm_contrib/atnguyen/code_21Dec2012_saltplume/kpp_routines.F
ViewVC logotype

Annotation of /MITgcm_contrib/atnguyen/code_21Dec2012_saltplume/kpp_routines.F

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


Revision 1.2 - (hide annotations) (download)
Tue Apr 29 06:49:40 2014 UTC (11 years, 3 months ago) by atn
Branch: MAIN
Changes since 1.1: +4 -1 lines
in progress:
1. add SALT_PLUME_OPTIONS.h to several files;
2. replace SPalpha (vol) with SPbrineSconst (salinity);
3. move diagnostics outside bi,bj loop.

1 atn 1.2 C $Header: /u/gcmpack/MITgcm_contrib/atnguyen/code_21Dec2012_saltplume/kpp_routines.F,v 1.1 2014/04/20 04:03:07 atn Exp $
2 atn 1.1 C $Name: $
3    
4     #include "KPP_OPTIONS.h"
5 atn 1.2 #ifdef ALLOW_SALT_PLUME
6     #include "SALT_PLUME_OPTIONS.h"
7     #endif
8 atn 1.1
9     C-- File kpp_routines.F: subroutines needed to implement
10     C-- KPP vertical mixing scheme
11     C-- Contents
12     C-- o KPPMIX - Main driver and interface routine.
13     C-- o BLDEPTH - Determine oceanic planetary boundary layer depth.
14     C-- o WSCALE - Compute turbulent velocity scales.
15     C-- o RI_IWMIX - Compute interior viscosity diffusivity coefficients.
16     C-- o Z121 - Apply 121 vertical smoothing.
17     C-- o SMOOTH_HORIZ- Apply horizontal smoothing to global array.
18     C-- o BLMIX - Boundary layer mixing coefficients.
19     C-- o ENHANCE - Enhance diffusivity at boundary layer interface.
20     C-- o STATEKPP - Compute buoyancy-related input arrays.
21     C-- o KPP_DOUBLEDIFF - Compute double diffusive contribution to diffusivities
22    
23     c***********************************************************************
24    
25     SUBROUTINE KPPMIX (
26     I kmtj, shsq, dvsq, ustar, msk
27     I , bo, bosol
28     #ifdef ALLOW_SALT_PLUME
29     #ifndef SALT_PLUME_VOLUME
30     I , boplume,SPDepth
31     #endif /* ndef SALT_PLUME_VOLUME */
32     #endif /* ALLOW_SALT_PLUME */
33     I , dbloc, Ritop, coriol
34     I , diffusKzS, diffusKzT
35     I , ikppkey
36     O , diffus
37     U , ghat
38     O , hbl
39     I , bi, bj, myTime, myIter, myThid )
40    
41     c-----------------------------------------------------------------------
42     c
43     c Main driver subroutine for kpp vertical mixing scheme and
44     c interface to greater ocean model
45     c
46     c written by: bill large, june 6, 1994
47     c modified by: jan morzel, june 30, 1994
48     c bill large, august 11, 1994
49     c bill large, january 25, 1995 : "dVsq" and 1d code
50     c detlef stammer, august 1997 : for use with MIT GCM Classic
51     c d. menemenlis, june 1998 : for use with MIT GCM UV
52     c
53     c-----------------------------------------------------------------------
54    
55     IMPLICIT NONE
56    
57     #include "SIZE.h"
58     #include "EEPARAMS.h"
59     #include "PARAMS.h"
60     #include "KPP_PARAMS.h"
61     #ifdef ALLOW_AUTODIFF
62     # include "tamc.h"
63     #endif
64    
65     c input
66     c bi, bj :: Array indices on which to apply calculations
67     c myTime :: Current time in simulation
68     c myIter :: Current iteration number in simulation
69     c myThid :: My Thread Id. number
70     c kmtj (imt) - number of vertical layers on this row
71     c msk (imt) - surface mask (=1 if water, =0 otherwise)
72     c shsq (imt,Nr) - (local velocity shear)^2 ((m/s)^2)
73     c dvsq (imt,Nr) - (velocity shear re sfc)^2 ((m/s)^2)
74     c ustar (imt) - surface friction velocity (m/s)
75     c bo (imt) - surface turbulent buoy. forcing (m^2/s^3)
76     c bosol (imt) - radiative buoyancy forcing (m^2/s^3)
77     c boplume(imt) - haline buoyancy forcing (m^2/s^3)
78     c dbloc (imt,Nr) - local delta buoyancy across interfaces (m/s^2)
79     c dblocSm(imt,Nr) - horizontally smoothed dbloc (m/s^2)
80     c stored in ghat to save space
81     c Ritop (imt,Nr) - numerator of bulk Richardson Number
82     c (zref-z) * delta buoyancy w.r.t. surface ((m/s)^2)
83     c coriol (imt) - Coriolis parameter (1/s)
84     c diffusKzS(imt,Nr)- background vertical diffusivity for scalars (m^2/s)
85     c diffusKzT(imt,Nr)- background vertical diffusivity for theta (m^2/s)
86     c note: there is a conversion from 2-D to 1-D for input output variables,
87     c e.g., hbl(sNx,sNy) -> hbl(imt),
88     c where hbl(i,j) -> hbl((j-1)*sNx+i)
89     INTEGER bi, bj
90     _RL myTime
91     integer myIter
92     integer myThid
93     integer kmtj (imt )
94     _RL shsq (imt,Nr)
95     _RL dvsq (imt,Nr)
96     _RL ustar (imt )
97     _RL bo (imt )
98     _RL bosol (imt )
99     #ifdef ALLOW_SALT_PLUME
100     #ifndef SALT_PLUME_VOLUME
101     _RL boplume (imt )
102     _RL SPDepth (imt )
103     #endif /* ndef SALT_PLUME_VOLUME */
104     #endif /* ALLOW_SALT_PLUME */
105     _RL dbloc (imt,Nr)
106     _RL Ritop (imt,Nr)
107     _RL coriol (imt )
108     _RS msk (imt )
109     _RL diffusKzS(imt,Nr)
110     _RL diffusKzT(imt,Nr)
111    
112     integer ikppkey
113    
114     c output
115     c diffus (imt,1) - vertical viscosity coefficient (m^2/s)
116     c diffus (imt,2) - vertical scalar diffusivity (m^2/s)
117     c diffus (imt,3) - vertical temperature diffusivity (m^2/s)
118     c ghat (imt) - nonlocal transport coefficient (s/m^2)
119     c hbl (imt) - mixing layer depth (m)
120    
121     _RL diffus(imt,0:Nrp1,mdiff)
122     _RL ghat (imt,Nr)
123     _RL hbl (imt)
124    
125     #ifdef ALLOW_KPP
126    
127     c local
128     c kbl (imt ) - index of first grid level below hbl
129     c bfsfc (imt ) - surface buoyancy forcing (m^2/s^3)
130     c casea (imt ) - 1 in case A; 0 in case B
131     c stable (imt ) - 1 in stable forcing; 0 if unstable
132     c dkm1 (imt, mdiff) - boundary layer diffusivity at kbl-1 level
133     c blmc (imt,Nr,mdiff) - boundary layer mixing coefficients
134     c sigma (imt ) - normalized depth (d / hbl)
135     c Rib (imt,Nr ) - bulk Richardson number
136    
137     integer kbl(imt )
138     _RL bfsfc (imt )
139     _RL casea (imt )
140     _RL stable (imt )
141     _RL dkm1 (imt, mdiff)
142     _RL blmc (imt,Nr,mdiff)
143     _RL sigma (imt )
144     _RL Rib (imt,Nr )
145    
146     integer i, k, md
147    
148     c-----------------------------------------------------------------------
149     c compute interior mixing coefficients everywhere, due to constant
150     c internal wave activity, static instability, and local shear
151     c instability.
152     c (ghat is temporary storage for horizontally smoothed dbloc)
153     c-----------------------------------------------------------------------
154    
155     cph(
156     cph these storings avoid recomp. of Ri_iwmix
157     CADJ STORE ghat = comlev1_kpp, key=ikppkey, kind=isbyte
158     CADJ STORE dbloc = comlev1_kpp, key=ikppkey, kind=isbyte
159     cph)
160     call Ri_iwmix (
161     I kmtj, shsq, dbloc, ghat
162     I , diffusKzS, diffusKzT
163     I , ikppkey
164     O , diffus, myThid )
165    
166     cph(
167     cph these storings avoid recomp. of Ri_iwmix
168     cph DESPITE TAFs 'not necessary' warning!
169     CADJ STORE dbloc = comlev1_kpp, key=ikppkey, kind=isbyte
170     CADJ STORE shsq = comlev1_kpp, key=ikppkey, kind=isbyte
171     CADJ STORE ghat = comlev1_kpp, key=ikppkey, kind=isbyte
172     CADJ STORE diffus = comlev1_kpp, key=ikppkey, kind=isbyte
173     cph)
174    
175     c-----------------------------------------------------------------------
176     c set seafloor values to zero and fill extra "Nrp1" coefficients
177     c for blmix
178     c-----------------------------------------------------------------------
179    
180     do md = 1, mdiff
181     do k=1,Nrp1
182     do i = 1,imt
183     if(k.ge.kmtj(i)) diffus(i,k,md) = 0.0
184     end do
185     end do
186     end do
187    
188     c-----------------------------------------------------------------------
189     c compute boundary layer mixing coefficients:
190     c
191     c diagnose the new boundary layer depth
192     c-----------------------------------------------------------------------
193    
194     call bldepth (
195     I kmtj
196     I , dvsq, dbloc, Ritop, ustar, bo, bosol
197     #ifdef ALLOW_SALT_PLUME
198     #ifndef SALT_PLUME_VOLUME
199     I , boplume,SPDepth
200     #endif /* ndef SALT_PLUME_VOLUME */
201     #endif /* ALLOW_SALT_PLUME */
202     I , coriol
203     I , ikppkey
204     O , hbl, bfsfc, stable, casea, kbl, Rib, sigma
205     I , bi, bj, myTime, myIter, myThid )
206    
207     CADJ STORE hbl,bfsfc,stable,casea,kbl = comlev1_kpp,
208     CADJ & key=ikppkey, kind=isbyte
209    
210     c-----------------------------------------------------------------------
211     c compute boundary layer diffusivities
212     c-----------------------------------------------------------------------
213    
214     call blmix (
215     I ustar, bfsfc, hbl, stable, casea, diffus, kbl
216     O , dkm1, blmc, ghat, sigma, ikppkey
217     I , myThid )
218     cph(
219     CADJ STORE dkm1,blmc,ghat = comlev1_kpp,
220     CADJ & key=ikppkey, kind=isbyte
221     CADJ STORE hbl, kbl, diffus, casea = comlev1_kpp,
222     CADJ & key=ikppkey, kind=isbyte
223     cph)
224    
225     c-----------------------------------------------------------------------
226     c enhance diffusivity at interface kbl - 1
227     c-----------------------------------------------------------------------
228    
229     call enhance (
230     I dkm1, hbl, kbl, diffus, casea
231     U , ghat
232     O , blmc
233     I , myThid )
234    
235     cph(
236     cph avoids recomp. of enhance
237     CADJ STORE blmc = comlev1_kpp, key=ikppkey, kind=isbyte
238     cph)
239    
240     c-----------------------------------------------------------------------
241     c combine interior and boundary layer coefficients and nonlocal term
242     c !!!NOTE!!! In shallow (2-level) regions and for shallow mixed layers
243     c (< 1 level), diffusivity blmc can become negative. The max-s below
244     c are a hack until this problem is properly diagnosed and fixed.
245     c-----------------------------------------------------------------------
246     do k = 1, Nr
247     do i = 1, imt
248     if (k .lt. kbl(i)) then
249     #ifdef ALLOW_SHELFICE
250     C when there is shelfice on top (msk(i)=0), reset the boundary layer
251     C mixing coefficients blmc to pure Ri-number based mixing
252     blmc(i,k,1) = max ( blmc(i,k,1)*msk(i),
253     & diffus(i,k,1) )
254     blmc(i,k,2) = max ( blmc(i,k,2)*msk(i),
255     & diffus(i,k,2) )
256     blmc(i,k,3) = max ( blmc(i,k,3)*msk(i),
257     & diffus(i,k,3) )
258     #endif /* not ALLOW_SHELFICE */
259     diffus(i,k,1) = max ( blmc(i,k,1), viscArNr(1) )
260     diffus(i,k,2) = max ( blmc(i,k,2), diffusKzS(i,Nr) )
261     diffus(i,k,3) = max ( blmc(i,k,3), diffusKzT(i,Nr) )
262     else
263     ghat(i,k) = 0. _d 0
264     endif
265     end do
266     end do
267    
268     #endif /* ALLOW_KPP */
269    
270     return
271     end
272    
273     c*************************************************************************
274    
275     subroutine bldepth (
276     I kmtj
277     I , dvsq, dbloc, Ritop, ustar, bo, bosol
278     #ifdef ALLOW_SALT_PLUME
279     #ifndef SALT_PLUME_VOLUME
280     I , boplume,SPDepth
281     #endif /* ndef SALT_PLUME_VOLUME */
282     #endif /* ALLOW_SALT_PLUME */
283     I , coriol
284     I , ikppkey
285     O , hbl, bfsfc, stable, casea, kbl, Rib, sigma
286     I , bi, bj, myTime, myIter, myThid )
287    
288     c the oceanic planetary boundary layer depth, hbl, is determined as
289     c the shallowest depth where the bulk Richardson number is
290     c equal to the critical value, Ricr.
291     c
292     c bulk Richardson numbers are evaluated by computing velocity and
293     c buoyancy differences between values at zgrid(kl) < 0 and surface
294     c reference values.
295     c in this configuration, the reference values are equal to the
296     c values in the surface layer.
297     c when using a very fine vertical grid, these values should be
298     c computed as the vertical average of velocity and buoyancy from
299     c the surface down to epsilon*zgrid(kl).
300     c
301     c when the bulk Richardson number at k exceeds Ricr, hbl is
302     c linearly interpolated between grid levels zgrid(k) and zgrid(k-1).
303     c
304     c The water column and the surface forcing are diagnosed for
305     c stable/ustable forcing conditions, and where hbl is relative
306     c to grid points (caseA), so that conditional branches can be
307     c avoided in later subroutines.
308     c
309     IMPLICIT NONE
310    
311     #include "SIZE.h"
312     #include "EEPARAMS.h"
313     #include "PARAMS.h"
314     #include "KPP_PARAMS.h"
315     #ifdef ALLOW_AUTODIFF
316     # include "tamc.h"
317     #endif
318    
319     c input
320     c------
321     c bi, bj :: Array indices on which to apply calculations
322     c myTime :: Current time in simulation
323     c myIter :: Current iteration number in simulation
324     c myThid :: My Thread Id. number
325     c kmtj : number of vertical layers
326     c dvsq : (velocity shear re sfc)^2 ((m/s)^2)
327     c dbloc : local delta buoyancy across interfaces (m/s^2)
328     c Ritop : numerator of bulk Richardson Number
329     c =(z-zref)*dbsfc, where dbsfc=delta
330     c buoyancy with respect to surface ((m/s)^2)
331     c ustar : surface friction velocity (m/s)
332     c bo : surface turbulent buoyancy forcing (m^2/s^3)
333     c bosol : radiative buoyancy forcing (m^2/s^3)
334     c boplume : haline buoyancy forcing (m^2/s^3)
335     c coriol : Coriolis parameter (1/s)
336     INTEGER bi, bj
337     _RL myTime
338     integer myIter
339     integer myThid
340     integer kmtj(imt)
341     _RL dvsq (imt,Nr)
342     _RL dbloc (imt,Nr)
343     _RL Ritop (imt,Nr)
344     _RL ustar (imt)
345     _RL bo (imt)
346     _RL bosol (imt)
347     _RL coriol (imt)
348     integer ikppkey
349     #ifdef ALLOW_SALT_PLUME
350     #ifndef SALT_PLUME_VOLUME
351     _RL boplume (imt)
352     _RL SPDepth (imt)
353     #endif /* ndef SALT_PLUME_VOLUME */
354     #endif /* ALLOW_SALT_PLUME */
355    
356     c output
357     c--------
358     c hbl : boundary layer depth (m)
359     c bfsfc : Bo+radiation absorbed to d=hbf*hbl (m^2/s^3)
360     c stable : =1 in stable forcing; =0 unstable
361     c casea : =1 in case A, =0 in case B
362     c kbl : -1 of first grid level below hbl
363     c Rib : Bulk Richardson number
364     c sigma : normalized depth (d/hbl)
365     _RL hbl (imt)
366     _RL bfsfc (imt)
367     _RL stable (imt)
368     _RL casea (imt)
369     integer kbl(imt)
370     _RL Rib (imt,Nr)
371     _RL sigma (imt)
372    
373     #ifdef ALLOW_KPP
374    
375     c local
376     c-------
377     c wm, ws : turbulent velocity scales (m/s)
378     _RL wm(imt), ws(imt)
379     _RL worka(imt)
380     _RL bvsq, vtsq, hekman, hmonob, hlimit, tempVar1, tempVar2
381     integer i, kl
382    
383     _RL p5 , eins
384     parameter ( p5=0.5, eins=1.0 )
385     _RL minusone
386     parameter ( minusone=-1.0 )
387     #ifdef ALLOW_AUTODIFF_TAMC
388     integer kkppkey
389     #endif
390    
391     #ifdef ALLOW_DIAGNOSTICS
392     c KPPBFSFC - Bo+radiation absorbed to d=hbf*hbl + plume (m^2/s^3)
393     _RL KPPBFSFC(imt,Nr)
394     _RL KPPRi(imt,Nr)
395     #endif /* ALLOW_DIAGNOSTICS */
396    
397     c find bulk Richardson number at every grid level until > Ricr
398     c
399     c note: the reference depth is -epsilon/2.*zgrid(k), but the reference
400     c u,v,t,s values are simply the surface layer values,
401     c and not the averaged values from 0 to 2*ref.depth,
402     c which is necessary for very fine grids(top layer < 2m thickness)
403     c note: max values when Ricr never satisfied are
404     c kbl(i)=kmtj(i) and hbl(i)=-zgrid(kmtj(i))
405    
406     c initialize hbl and kbl to bottomed out values
407    
408     do i = 1, imt
409     Rib(i,1) = 0. _d 0
410     kbl(i) = max(kmtj(i),1)
411     hbl(i) = -zgrid(kbl(i))
412     end do
413    
414     #ifdef ALLOW_DIAGNOSTICS
415     do kl = 1, Nr
416     do i = 1, imt
417     KPPBFSFC(i,kl) = 0. _d 0
418     KPPRi(i,kl) = 0. _d 0
419     enddo
420     enddo
421     #endif /* ALLOW_DIAGNOSTICS */
422    
423     do kl = 2, Nr
424    
425     #ifdef ALLOW_AUTODIFF_TAMC
426     kkppkey = (ikppkey-1)*Nr + kl
427     #endif
428    
429     c compute bfsfc = sw fraction at hbf * zgrid
430    
431     do i = 1, imt
432     worka(i) = zgrid(kl)
433     end do
434     CADJ store worka = comlev1_kpp_k, key = kkppkey, kind=isbyte
435     call SWFRAC(
436     I imt, hbf,
437     U worka,
438     I myTime, myIter, myThid )
439     CADJ store worka = comlev1_kpp_k, key = kkppkey, kind=isbyte
440    
441     do i = 1, imt
442    
443     c use caseA as temporary array
444    
445     casea(i) = -zgrid(kl)
446    
447     c compute bfsfc= Bo + radiative contribution down to hbf * hbl
448    
449     bfsfc(i) = bo(i) + bosol(i)*(1. - worka(i))
450    
451     end do
452     #ifdef ALLOW_SALT_PLUME
453     #ifndef SALT_PLUME_VOLUME
454     c compute bfsfc = plume fraction at hbf * zgrid
455     IF ( useSALT_PLUME ) THEN
456     do i = 1, imt
457     worka(i) = zgrid(kl)
458     enddo
459     call SALT_PLUME_FRAC(
460     I imt, hbf,SPDepth,
461     U worka,
462     I myTime, myIter, myThid)
463     do i = 1, imt
464     bfsfc(i) = bfsfc(i) + boplume(i)*(worka(i))
465     enddo
466     ENDIF
467     #endif /* ndef SALT_PLUME_VOLUME */
468     #endif /* ALLOW_SALT_PLUME */
469    
470     #ifdef ALLOW_DIAGNOSTICS
471     do i = 1, imt
472     KPPBFSFC(i,kl) = bfsfc(i)
473     enddo
474     #endif /* ALLOW_DIAGNOSTICS */
475    
476     do i = 1, imt
477     stable(i) = p5 + sign(p5,bfsfc(i))
478     sigma(i) = stable(i) + (1. - stable(i)) * epsilon
479     enddo
480    
481     c-----------------------------------------------------------------------
482     c compute velocity scales at sigma, for hbl= caseA = -zgrid(kl)
483     c-----------------------------------------------------------------------
484    
485     call wscale (
486     I sigma, casea, ustar, bfsfc,
487     O wm, ws, myThid )
488     CADJ store ws = comlev1_kpp_k, key = kkppkey, kind=isbyte
489    
490     do i = 1, imt
491    
492     c-----------------------------------------------------------------------
493     c compute the turbulent shear contribution to Rib
494     c-----------------------------------------------------------------------
495    
496     bvsq = p5 *
497     1 ( dbloc(i,kl-1) / (zgrid(kl-1)-zgrid(kl ))+
498     2 dbloc(i,kl ) / (zgrid(kl )-zgrid(kl+1)))
499    
500     if (bvsq .eq. 0. _d 0) then
501     vtsq = 0. _d 0
502     else
503     vtsq = -zgrid(kl) * ws(i) * sqrt(abs(bvsq)) * Vtc
504     endif
505    
506     c compute bulk Richardson number at new level
507     c note: Ritop needs to be zero on land and ocean bottom
508     c points so that the following if statement gets triggered
509     c correctly; otherwise, hbl might get set to (big) negative
510     c values, that might exceed the limit for the "exp" function
511     c in "SWFRAC"
512    
513     c
514     c rg: assignment to double precision variable to avoid overflow
515     c ph: test for zero nominator
516     c
517    
518     tempVar1 = dvsq(i,kl) + vtsq
519     tempVar2 = max(tempVar1, phepsi)
520     Rib(i,kl) = Ritop(i,kl) / tempVar2
521     #ifdef ALLOW_DIAGNOSTICS
522     KPPRi(i,kl) = Rib(i,kl)
523     #endif
524    
525     end do
526     end do
527    
528     #ifdef ALLOW_DIAGNOSTICS
529     IF ( useDiagnostics ) THEN
530     CALL DIAGNOSTICS_FILL(KPPBFSFC,'KPPbfsfc',0,Nr,2,bi,bj,myThid)
531     CALL DIAGNOSTICS_FILL(KPPRi ,'KPPRi ',0,Nr,2,bi,bj,myThid)
532     ENDIF
533     #endif /* ALLOW_DIAGNOSTICS */
534    
535     cph(
536     cph without this store, there is a recomputation error for
537     cph rib in adbldepth (probably partial recomputation problem)
538     CADJ store Rib = comlev1_kpp
539     CADJ & , key=ikppkey, kind=isbyte,
540     CADJ & shape = (/ (sNx+2*OLx)*(sNy+2*OLy),Nr /)
541     cph)
542    
543     do kl = 2, Nr
544     do i = 1, imt
545     if (kbl(i).eq.kmtj(i) .and. Rib(i,kl).gt.Ricr) kbl(i) = kl
546     end do
547     end do
548    
549     CADJ store kbl = comlev1_kpp
550     CADJ & , key=ikppkey, kind=isbyte,
551     CADJ & shape = (/ (sNx+2*OLx)*(sNy+2*OLy) /)
552    
553     do i = 1, imt
554     kl = kbl(i)
555     c linearly interpolate to find hbl where Rib = Ricr
556     if (kl.gt.1 .and. kl.lt.kmtj(i)) then
557     tempVar1 = (Rib(i,kl)-Rib(i,kl-1))
558     hbl(i) = -zgrid(kl-1) + (zgrid(kl-1)-zgrid(kl)) *
559     1 (Ricr - Rib(i,kl-1)) / tempVar1
560     endif
561     end do
562    
563     CADJ store hbl = comlev1_kpp
564     CADJ & , key=ikppkey, kind=isbyte,
565     CADJ & shape = (/ (sNx+2*OLx)*(sNy+2*OLy) /)
566    
567     c-----------------------------------------------------------------------
568     c find stability and buoyancy forcing for boundary layer
569     c-----------------------------------------------------------------------
570    
571     do i = 1, imt
572     worka(i) = hbl(i)
573     end do
574     CADJ store worka = comlev1_kpp
575     CADJ & , key=ikppkey, kind=isbyte,
576     CADJ & shape = (/ (sNx+2*OLx)*(sNy+2*OLy) /)
577     call SWFRAC(
578     I imt, minusone,
579     U worka,
580     I myTime, myIter, myThid )
581     CADJ store worka = comlev1_kpp
582     CADJ & , key=ikppkey, kind=isbyte,
583     CADJ & shape = (/ (sNx+2*OLx)*(sNy+2*OLy) /)
584    
585     do i = 1, imt
586     bfsfc(i) = bo(i) + bosol(i) * (1. - worka(i))
587     end do
588    
589     #ifdef ALLOW_SALT_PLUME
590     #ifndef SALT_PLUME_VOLUME
591     IF ( useSALT_PLUME ) THEN
592     do i = 1, imt
593     worka(i) = hbl(i)
594     enddo
595     call SALT_PLUME_FRAC(
596     I imt,minusone,SPDepth,
597     U worka,
598     I myTime, myIter, myThid )
599     do i = 1, imt
600     bfsfc(i) = bfsfc(i) + boplume(i) * (worka(i))
601     enddo
602     ENDIF
603     #endif /* ndef SALT_PLUME_VOLUME */
604     #endif /* ALLOW_SALT_PLUME */
605     CADJ store bfsfc = comlev1_kpp
606     CADJ & , key=ikppkey, kind=isbyte,
607     CADJ & shape = (/ (sNx+2*OLx)*(sNy+2*OLy) /)
608    
609     c-- ensure bfsfc is never 0
610     do i = 1, imt
611     stable(i) = p5 + sign( p5, bfsfc(i) )
612     bfsfc(i) = sign(eins,bfsfc(i))*max(phepsi,abs(bfsfc(i)))
613     end do
614    
615     cph(
616     cph added stable to store list to avoid extensive recomp.
617     CADJ store bfsfc, stable = comlev1_kpp
618     CADJ & , key=ikppkey, kind=isbyte,
619     CADJ & shape = (/ (sNx+2*OLx)*(sNy+2*OLy) /)
620     cph)
621    
622     c-----------------------------------------------------------------------
623     c check hbl limits for hekman or hmonob
624     c ph: test for zero nominator
625     c-----------------------------------------------------------------------
626    
627     IF ( LimitHblStable ) THEN
628     do i = 1, imt
629     if (bfsfc(i) .gt. 0.0) then
630     hekman = cekman * ustar(i) / max(abs(Coriol(i)),phepsi)
631     hmonob = cmonob * ustar(i)*ustar(i)*ustar(i)
632     & / vonk / bfsfc(i)
633     hlimit = stable(i) * min(hekman,hmonob)
634     & + (stable(i)-1.) * zgrid(Nr)
635     hbl(i) = min(hbl(i),hlimit)
636     end if
637     end do
638     ENDIF
639    
640     CADJ store hbl = comlev1_kpp
641     CADJ & , key=ikppkey, kind=isbyte,
642     CADJ & shape = (/ (sNx+2*OLx)*(sNy+2*OLy) /)
643    
644     do i = 1, imt
645     hbl(i) = max(hbl(i),minKPPhbl)
646     kbl(i) = kmtj(i)
647     end do
648    
649     CADJ store hbl = comlev1_kpp
650     CADJ & , key=ikppkey, kind=isbyte,
651     CADJ & shape = (/ (sNx+2*OLx)*(sNy+2*OLy) /)
652    
653     c-----------------------------------------------------------------------
654     c find new kbl
655     c-----------------------------------------------------------------------
656    
657     do kl = 2, Nr
658     do i = 1, imt
659     if ( kbl(i).eq.kmtj(i) .and. (-zgrid(kl)).gt.hbl(i) ) then
660     kbl(i) = kl
661     endif
662     end do
663     end do
664    
665     c-----------------------------------------------------------------------
666     c find stability and buoyancy forcing for final hbl values
667     c-----------------------------------------------------------------------
668    
669     do i = 1, imt
670     worka(i) = hbl(i)
671     end do
672     CADJ store worka = comlev1_kpp
673     CADJ & , key=ikppkey, kind=isbyte,
674     CADJ & shape = (/ (sNx+2*OLx)*(sNy+2*OLy) /)
675     call SWFRAC(
676     I imt, minusone,
677     U worka,
678     I myTime, myIter, myThid )
679     CADJ store worka = comlev1_kpp
680     CADJ & , key=ikppkey, kind=isbyte,
681     CADJ & shape = (/ (sNx+2*OLx)*(sNy+2*OLy) /)
682    
683     do i = 1, imt
684     bfsfc(i) = bo(i) + bosol(i) * (1. - worka(i))
685     end do
686    
687     #ifdef ALLOW_SALT_PLUME
688     #ifndef SALT_PLUME_VOLUME
689     IF ( useSALT_PLUME ) THEN
690     do i = 1, imt
691     worka(i) = hbl(i)
692     enddo
693     call SALT_PLUME_FRAC(
694     I imt,minusone,SPDepth,
695     U worka,
696     I myTime, myIter, myThid )
697     do i = 1, imt
698     bfsfc(i) = bfsfc(i) + boplume(i) * (worka(i))
699     enddo
700     ENDIF
701     #endif /* ndef SALT_PLUME_VOLUME */
702     #endif /* ALLOW_SALT_PLUME */
703     CADJ store bfsfc = comlev1_kpp
704     CADJ & , key=ikppkey, kind=isbyte,
705     CADJ & shape = (/ (sNx+2*OLx)*(sNy+2*OLy) /)
706    
707     c-- ensures bfsfc is never 0
708     do i = 1, imt
709     stable(i) = p5 + sign( p5, bfsfc(i) )
710     bfsfc(i) = sign(eins,bfsfc(i))*max(phepsi,abs(bfsfc(i)))
711     end do
712    
713     c-----------------------------------------------------------------------
714     c determine caseA and caseB
715     c-----------------------------------------------------------------------
716    
717     do i = 1, imt
718     casea(i) = p5 +
719     1 sign(p5, -zgrid(kbl(i)) - p5*hwide(kbl(i)) - hbl(i))
720     end do
721    
722     #endif /* ALLOW_KPP */
723    
724     return
725     end
726    
727     c*************************************************************************
728    
729     subroutine wscale (
730     I sigma, hbl, ustar, bfsfc,
731     O wm, ws,
732     I myThid )
733    
734     c compute turbulent velocity scales.
735     c use a 2D-lookup table for wm and ws as functions of ustar and
736     c zetahat (=vonk*sigma*hbl*bfsfc).
737     c
738     c note: the lookup table is only used for unstable conditions
739     c (zehat.le.0), in the stable domain wm (=ws) gets computed
740     c directly.
741     c
742     IMPLICIT NONE
743    
744     #include "SIZE.h"
745     #include "KPP_PARAMS.h"
746    
747     c input
748     c------
749     c sigma : normalized depth (d/hbl)
750     c hbl : boundary layer depth (m)
751     c ustar : surface friction velocity (m/s)
752     c bfsfc : total surface buoyancy flux (m^2/s^3)
753     c myThid : thread number for this instance of the routine
754     integer myThid
755     _RL sigma(imt)
756     _RL hbl (imt)
757     _RL ustar(imt)
758     _RL bfsfc(imt)
759    
760     c output
761     c--------
762     c wm, ws : turbulent velocity scales at sigma
763     _RL wm(imt), ws(imt)
764    
765     #ifdef ALLOW_KPP
766    
767     c local
768     c------
769     c zehat : = zeta * ustar**3
770     _RL zehat
771    
772     integer iz, izp1, ju, i, jup1
773     _RL udiff, zdiff, zfrac, ufrac, fzfrac, wam
774     _RL wbm, was, wbs, u3, tempVar
775    
776     c-----------------------------------------------------------------------
777     c use lookup table for zehat < zmax only; otherwise use
778     c stable formulae
779     c-----------------------------------------------------------------------
780    
781     do i = 1, imt
782     zehat = vonk*sigma(i)*hbl(i)*bfsfc(i)
783    
784     if (zehat .le. zmax) then
785    
786     zdiff = zehat - zmin
787     iz = int( zdiff / deltaz )
788     iz = min( iz, nni )
789     iz = max( iz, 0 )
790     izp1 = iz + 1
791    
792     udiff = ustar(i) - umin
793     ju = int( udiff / deltau )
794     ju = min( ju, nnj )
795     ju = max( ju, 0 )
796     jup1 = ju + 1
797    
798     zfrac = zdiff / deltaz - float(iz)
799     ufrac = udiff / deltau - float(ju)
800    
801     fzfrac= 1. - zfrac
802     wam = fzfrac * wmt(iz,jup1) + zfrac * wmt(izp1,jup1)
803     wbm = fzfrac * wmt(iz,ju ) + zfrac * wmt(izp1,ju )
804     wm(i) = (1.-ufrac) * wbm + ufrac * wam
805    
806     was = fzfrac * wst(iz,jup1) + zfrac * wst(izp1,jup1)
807     wbs = fzfrac * wst(iz,ju ) + zfrac * wst(izp1,ju )
808     ws(i) = (1.-ufrac) * wbs + ufrac * was
809    
810     else
811    
812     u3 = ustar(i) * ustar(i) * ustar(i)
813     tempVar = u3 + conc1 * zehat
814     wm(i) = vonk * ustar(i) * u3 / tempVar
815     ws(i) = wm(i)
816    
817     endif
818    
819     end do
820    
821     #endif /* ALLOW_KPP */
822    
823     return
824     end
825    
826     c*************************************************************************
827    
828     subroutine Ri_iwmix (
829     I kmtj, shsq, dbloc, dblocSm,
830     I diffusKzS, diffusKzT,
831     I ikppkey,
832     O diffus,
833     I myThid )
834    
835     c compute interior viscosity diffusivity coefficients due
836     c to shear instability (dependent on a local Richardson number),
837     c to background internal wave activity, and
838     c to static instability (local Richardson number < 0).
839    
840     IMPLICIT NONE
841    
842     #include "SIZE.h"
843     #include "EEPARAMS.h"
844     #include "PARAMS.h"
845     #include "KPP_PARAMS.h"
846     #ifdef ALLOW_AUTODIFF
847     # include "AUTODIFF_PARAMS.h"
848     # include "tamc.h"
849     #endif
850    
851     c input
852     c kmtj (imt) number of vertical layers on this row
853     c shsq (imt,Nr) (local velocity shear)^2 ((m/s)^2)
854     c dbloc (imt,Nr) local delta buoyancy (m/s^2)
855     c dblocSm(imt,Nr) horizontally smoothed dbloc (m/s^2)
856     c diffusKzS(imt,Nr)- background vertical diffusivity for scalars (m^2/s)
857     c diffusKzT(imt,Nr)- background vertical diffusivity for theta (m^2/s)
858     c myThid :: My Thread Id. number
859     integer kmtj (imt)
860     _RL shsq (imt,Nr)
861     _RL dbloc (imt,Nr)
862     _RL dblocSm (imt,Nr)
863     _RL diffusKzS(imt,Nr)
864     _RL diffusKzT(imt,Nr)
865     integer ikppkey
866     integer myThid
867    
868     c output
869     c diffus(imt,0:Nrp1,1) vertical viscosivity coefficient (m^2/s)
870     c diffus(imt,0:Nrp1,2) vertical scalar diffusivity (m^2/s)
871     c diffus(imt,0:Nrp1,3) vertical temperature diffusivity (m^2/s)
872     _RL diffus(imt,0:Nrp1,3)
873    
874     #ifdef ALLOW_KPP
875    
876     c local variables
877     c Rig local Richardson number
878     c fRi, fcon function of Rig
879     _RL Rig
880     _RL fRi, fcon
881     _RL ratio
882     integer i, ki, kp1
883     _RL c1, c0
884    
885     #ifdef ALLOW_KPP_VERTICALLY_SMOOTH
886     integer mr
887     CADJ INIT kpp_ri_tape_mr = common, 1
888     #endif
889    
890     c constants
891     c1 = 1. _d 0
892     c0 = 0. _d 0
893    
894     c-----------------------------------------------------------------------
895     c compute interior gradient Ri at all interfaces ki=1,Nr, (not surface)
896     c use diffus(*,*,1) as temporary storage of Ri to be smoothed
897     c use diffus(*,*,2) as temporary storage for Brunt-Vaisala squared
898     c set values at bottom and below to nearest value above bottom
899     #ifdef ALLOW_AUTODIFF_TAMC
900     C break data flow dependence on diffus
901     diffus(1,1,1) = 0.0
902    
903     do ki = 1, Nr
904     do i = 1, imt
905     diffus(i,ki,1) = 0.
906     diffus(i,ki,2) = 0.
907     diffus(i,ki,3) = 0.
908     enddo
909     enddo
910     #endif
911    
912     do ki = 1, Nr
913     do i = 1, imt
914     if (kmtj(i) .LE. 1 ) then
915     diffus(i,ki,1) = 0.
916     diffus(i,ki,2) = 0.
917     elseif (ki .GE. kmtj(i)) then
918     diffus(i,ki,1) = diffus(i,ki-1,1)
919     diffus(i,ki,2) = diffus(i,ki-1,2)
920     else
921     diffus(i,ki,1) = dblocSm(i,ki) * (zgrid(ki)-zgrid(ki+1))
922     & / max( Shsq(i,ki), phepsi )
923     diffus(i,ki,2) = dbloc(i,ki) / (zgrid(ki)-zgrid(ki+1))
924     endif
925     end do
926     end do
927     CADJ store diffus = comlev1_kpp, key=ikppkey, kind=isbyte
928    
929     c-----------------------------------------------------------------------
930     c vertically smooth Ri
931     #ifdef ALLOW_KPP_VERTICALLY_SMOOTH
932     do mr = 1, num_v_smooth_Ri
933    
934     CADJ store diffus(:,:,1) = kpp_ri_tape_mr
935     CADJ & , key=mr, shape=(/ (sNx+2*OLx)*(sNy+2*OLy),Nr+2 /)
936    
937     call z121 (
938     U diffus(1,0,1),
939     I myThid )
940     end do
941     #endif
942    
943     c-----------------------------------------------------------------------
944     c after smoothing loop
945    
946     do ki = 1, Nr
947     do i = 1, imt
948    
949     c evaluate f of Brunt-Vaisala squared for convection, store in fcon
950    
951     Rig = max ( diffus(i,ki,2) , BVSQcon )
952     ratio = min ( (BVSQcon - Rig) / BVSQcon, c1 )
953     fcon = c1 - ratio * ratio
954     fcon = fcon * fcon * fcon
955    
956     c evaluate f of smooth Ri for shear instability, store in fRi
957    
958     Rig = max ( diffus(i,ki,1), c0 )
959     ratio = min ( Rig / Riinfty , c1 )
960     fRi = c1 - ratio * ratio
961     fRi = fRi * fRi * fRi
962    
963     c ----------------------------------------------------------------------
964     c evaluate diffusivities and viscosity
965     c mixing due to internal waves, and shear and static instability
966    
967     kp1 = MIN(ki+1,Nr)
968     #ifdef EXCLUDE_KPP_SHEAR_MIX
969     diffus(i,ki,1) = viscArNr(1)
970     diffus(i,ki,2) = diffusKzS(i,kp1)
971     diffus(i,ki,3) = diffusKzT(i,kp1)
972     #else /* EXCLUDE_KPP_SHEAR_MIX */
973     # ifdef ALLOW_AUTODIFF
974     if ( inAdMode ) then
975     diffus(i,ki,1) = viscArNr(1)
976     diffus(i,ki,2) = diffusKzS(i,kp1)
977     diffus(i,ki,3) = diffusKzT(i,kp1)
978     else
979     # else /* ALLOW_AUTODIFF */
980     if ( .TRUE. ) then
981     # endif /* ALLOW_AUTODIFF */
982     diffus(i,ki,1) = viscArNr(1) + fcon*difmcon + fRi*difm0
983     diffus(i,ki,2) = diffusKzS(i,kp1)+fcon*difscon+fRi*difs0
984     diffus(i,ki,3) = diffusKzT(i,kp1)+fcon*diftcon+fRi*dift0
985     endif
986     #endif /* EXCLUDE_KPP_SHEAR_MIX */
987     end do
988     end do
989    
990     c ------------------------------------------------------------------------
991     c set surface values to 0.0
992    
993     do i = 1, imt
994     diffus(i,0,1) = c0
995     diffus(i,0,2) = c0
996     diffus(i,0,3) = c0
997     end do
998    
999     #endif /* ALLOW_KPP */
1000    
1001     return
1002     end
1003    
1004     c*************************************************************************
1005    
1006     subroutine z121 (
1007     U v,
1008     I myThid )
1009    
1010     c Apply 121 smoothing in k to 2-d array V(i,k=1,Nr)
1011     c top (0) value is used as a dummy
1012     c bottom (Nrp1) value is set to input value from above.
1013    
1014     c Note that it is important to exclude from the smoothing any points
1015     c that are outside the range of the K(Ri) scheme, ie. >0.8, or <0.0.
1016     c Otherwise, there is interference with other physics, especially
1017     c penetrative convection.
1018    
1019     IMPLICIT NONE
1020     #include "SIZE.h"
1021     #include "KPP_PARAMS.h"
1022    
1023     c input/output
1024     c-------------
1025     c v : 2-D array to be smoothed in Nrp1 direction
1026     c myThid: thread number for this instance of the routine
1027     integer myThid
1028     _RL v(imt,0:Nrp1)
1029    
1030     #ifdef ALLOW_KPP
1031    
1032     c local
1033     _RL zwork, zflag
1034     _RL KRi_range(1:Nrp1)
1035     integer i, k, km1, kp1
1036    
1037     _RL p0 , p25 , p5 , p2
1038     parameter ( p0 = 0.0, p25 = 0.25, p5 = 0.5, p2 = 2.0 )
1039    
1040     KRi_range(Nrp1) = p0
1041    
1042     #ifdef ALLOW_AUTODIFF_TAMC
1043     C-- dummy assignment to end declaration part for TAMC
1044     i = 0
1045    
1046     C-- HPF directive to help TAMC
1047     CHPF$ INDEPENDENT
1048     CADJ INIT z121tape = common, Nr
1049     #endif /* ALLOW_AUTODIFF_TAMC */
1050    
1051     do i = 1, imt
1052    
1053     k = 1
1054     CADJ STORE v(i,k) = z121tape
1055     v(i,Nrp1) = v(i,Nr)
1056    
1057     do k = 1, Nr
1058     KRi_range(k) = p5 + SIGN(p5,v(i,k))
1059     KRi_range(k) = KRi_range(k) *
1060     & ( p5 + SIGN(p5,(Riinfty-v(i,k))) )
1061     end do
1062    
1063     zwork = KRi_range(1) * v(i,1)
1064     v(i,1) = p2 * v(i,1) +
1065     & KRi_range(1) * KRi_range(2) * v(i,2)
1066     zflag = p2 + KRi_range(1) * KRi_range(2)
1067     v(i,1) = v(i,1) / zflag
1068    
1069     do k = 2, Nr
1070     CADJ STORE v(i,k), zwork = z121tape
1071     km1 = k - 1
1072     kp1 = k + 1
1073     zflag = v(i,k)
1074     v(i,k) = p2 * v(i,k) +
1075     & KRi_range(k) * KRi_range(kp1) * v(i,kp1) +
1076     & KRi_range(k) * zwork
1077     zwork = KRi_range(k) * zflag
1078     zflag = p2 + KRi_range(k)*(KRi_range(kp1)+KRi_range(km1))
1079     v(i,k) = v(i,k) / zflag
1080     end do
1081    
1082     end do
1083    
1084     #endif /* ALLOW_KPP */
1085    
1086     return
1087     end
1088    
1089     c*************************************************************************
1090    
1091     subroutine smooth_horiz (
1092     I k, bi, bj,
1093     U fld,
1094     I myThid )
1095    
1096     c Apply horizontal smoothing to global _RL 2-D array
1097    
1098     IMPLICIT NONE
1099     #include "SIZE.h"
1100     #include "GRID.h"
1101     #include "KPP_PARAMS.h"
1102    
1103     c input
1104     c bi, bj : array indices
1105     c k : vertical index used for masking
1106     c myThid : thread number for this instance of the routine
1107     INTEGER myThid
1108     integer k, bi, bj
1109    
1110     c input/output
1111     c fld : 2-D array to be smoothed
1112     _RL fld( 1-OLx:sNx+OLx, 1-OLy:sNy+OLy )
1113    
1114     #ifdef ALLOW_KPP
1115    
1116     c local
1117     integer i, j, im1, ip1, jm1, jp1
1118     _RL tempVar
1119     _RL fld_tmp( 1-OLx:sNx+OLx, 1-OLy:sNy+OLy )
1120    
1121     integer imin , imax , jmin , jmax
1122     parameter(imin=2-OLx, imax=sNx+OLx-1, jmin=2-OLy, jmax=sNy+OLy-1)
1123    
1124     _RL p0 , p5 , p25 , p125 , p0625
1125     parameter( p0=0.0, p5=0.5, p25=0.25, p125=0.125, p0625=0.0625 )
1126    
1127     DO j = jmin, jmax
1128     jm1 = j-1
1129     jp1 = j+1
1130     DO i = imin, imax
1131     im1 = i-1
1132     ip1 = i+1
1133     tempVar =
1134     & p25 * maskC(i ,j ,k,bi,bj) +
1135     & p125 * ( maskC(im1,j ,k,bi,bj) +
1136     & maskC(ip1,j ,k,bi,bj) +
1137     & maskC(i ,jm1,k,bi,bj) +
1138     & maskC(i ,jp1,k,bi,bj) ) +
1139     & p0625 * ( maskC(im1,jm1,k,bi,bj) +
1140     & maskC(im1,jp1,k,bi,bj) +
1141     & maskC(ip1,jm1,k,bi,bj) +
1142     & maskC(ip1,jp1,k,bi,bj) )
1143     IF ( tempVar .GE. p25 ) THEN
1144     fld_tmp(i,j) = (
1145     & p25 * fld(i ,j )*maskC(i ,j ,k,bi,bj) +
1146     & p125 *(fld(im1,j )*maskC(im1,j ,k,bi,bj) +
1147     & fld(ip1,j )*maskC(ip1,j ,k,bi,bj) +
1148     & fld(i ,jm1)*maskC(i ,jm1,k,bi,bj) +
1149     & fld(i ,jp1)*maskC(i ,jp1,k,bi,bj))+
1150     & p0625*(fld(im1,jm1)*maskC(im1,jm1,k,bi,bj) +
1151     & fld(im1,jp1)*maskC(im1,jp1,k,bi,bj) +
1152     & fld(ip1,jm1)*maskC(ip1,jm1,k,bi,bj) +
1153     & fld(ip1,jp1)*maskC(ip1,jp1,k,bi,bj)))
1154     & / tempVar
1155     ELSE
1156     fld_tmp(i,j) = fld(i,j)
1157     ENDIF
1158     ENDDO
1159     ENDDO
1160    
1161     c transfer smoothed field to output array
1162     DO j = jmin, jmax
1163     DO i = imin, imax
1164     fld(i,j) = fld_tmp(i,j)
1165     ENDDO
1166     ENDDO
1167    
1168     #endif /* ALLOW_KPP */
1169    
1170     return
1171     end
1172    
1173     c*************************************************************************
1174    
1175     subroutine blmix (
1176     I ustar, bfsfc, hbl, stable, casea, diffus, kbl
1177     O , dkm1, blmc, ghat, sigma, ikppkey
1178     I , myThid )
1179    
1180     c mixing coefficients within boundary layer depend on surface
1181     c forcing and the magnitude and gradient of interior mixing below
1182     c the boundary layer ("matching").
1183     c
1184     c caution: if mixing bottoms out at hbl = -zgrid(Nr) then
1185     c fictitious layer at Nrp1 is needed with small but finite width
1186     c hwide(Nrp1) (eg. epsln = 1.e-20).
1187     c
1188     IMPLICIT NONE
1189    
1190     #include "SIZE.h"
1191     #include "KPP_PARAMS.h"
1192     #ifdef ALLOW_AUTODIFF
1193     # include "tamc.h"
1194     #endif
1195    
1196     c input
1197     c ustar (imt) surface friction velocity (m/s)
1198     c bfsfc (imt) surface buoyancy forcing (m^2/s^3)
1199     c hbl (imt) boundary layer depth (m)
1200     c stable(imt) = 1 in stable forcing
1201     c casea (imt) = 1 in case A
1202     c diffus(imt,0:Nrp1,mdiff) vertical diffusivities (m^2/s)
1203     c kbl (imt) -1 of first grid level below hbl
1204     c myThid thread number for this instance of the routine
1205     integer myThid
1206     _RL ustar (imt)
1207     _RL bfsfc (imt)
1208     _RL hbl (imt)
1209     _RL stable(imt)
1210     _RL casea (imt)
1211     _RL diffus(imt,0:Nrp1,mdiff)
1212     integer kbl(imt)
1213    
1214     c output
1215     c dkm1 (imt,mdiff) boundary layer difs at kbl-1 level
1216     c blmc (imt,Nr,mdiff) boundary layer mixing coefficients (m^2/s)
1217     c ghat (imt,Nr) nonlocal scalar transport
1218     c sigma(imt) normalized depth (d / hbl)
1219     _RL dkm1 (imt,mdiff)
1220     _RL blmc (imt,Nr,mdiff)
1221     _RL ghat (imt,Nr)
1222     _RL sigma(imt)
1223     integer ikppkey
1224    
1225     #ifdef ALLOW_KPP
1226    
1227     c local
1228     c gat1*(imt) shape function at sigma = 1
1229     c dat1*(imt) derivative of shape function at sigma = 1
1230     c ws(imt), wm(imt) turbulent velocity scales (m/s)
1231     _RL gat1m(imt), gat1s(imt), gat1t(imt)
1232     _RL dat1m(imt), dat1s(imt), dat1t(imt)
1233     _RL ws(imt), wm(imt)
1234     integer i, kn, ki
1235     _RL R, dvdzup, dvdzdn, viscp
1236     _RL difsp, diftp, visch, difsh, difth
1237     _RL f1, sig, a1, a2, a3, delhat
1238     _RL Gm, Gs, Gt
1239     _RL tempVar
1240    
1241     _RL p0 , eins
1242     parameter (p0=0.0, eins=1.0)
1243     #ifdef ALLOW_AUTODIFF_TAMC
1244     integer kkppkey
1245     #endif
1246    
1247     c-----------------------------------------------------------------------
1248     c compute velocity scales at hbl
1249     c-----------------------------------------------------------------------
1250    
1251     do i = 1, imt
1252     sigma(i) = stable(i) * 1.0 + (1. - stable(i)) * epsilon
1253     end do
1254    
1255     CADJ STORE sigma = comlev1_kpp, key=ikppkey, kind=isbyte
1256     call wscale (
1257     I sigma, hbl, ustar, bfsfc,
1258     O wm, ws, myThid )
1259     CADJ STORE wm = comlev1_kpp, key=ikppkey, kind=isbyte
1260     CADJ STORE ws = comlev1_kpp, key=ikppkey, kind=isbyte
1261    
1262     do i = 1, imt
1263     wm(i) = sign(eins,wm(i))*max(phepsi,abs(wm(i)))
1264     ws(i) = sign(eins,ws(i))*max(phepsi,abs(ws(i)))
1265     end do
1266     CADJ STORE wm = comlev1_kpp, key=ikppkey, kind=isbyte
1267     CADJ STORE ws = comlev1_kpp, key=ikppkey, kind=isbyte
1268    
1269     do i = 1, imt
1270    
1271     kn = int(caseA(i)+phepsi) *(kbl(i) -1) +
1272     $ (1 - int(caseA(i)+phepsi)) * kbl(i)
1273    
1274     c-----------------------------------------------------------------------
1275     c find the interior viscosities and derivatives at hbl(i)
1276     c-----------------------------------------------------------------------
1277    
1278     delhat = 0.5*hwide(kn) - zgrid(kn) - hbl(i)
1279     R = 1.0 - delhat / hwide(kn)
1280     dvdzup = (diffus(i,kn-1,1) - diffus(i,kn ,1)) / hwide(kn)
1281     dvdzdn = (diffus(i,kn ,1) - diffus(i,kn+1,1)) / hwide(kn+1)
1282     viscp = 0.5 * ( (1.-R) * (dvdzup + abs(dvdzup)) +
1283     1 R * (dvdzdn + abs(dvdzdn)) )
1284    
1285     dvdzup = (diffus(i,kn-1,2) - diffus(i,kn ,2)) / hwide(kn)
1286     dvdzdn = (diffus(i,kn ,2) - diffus(i,kn+1,2)) / hwide(kn+1)
1287     difsp = 0.5 * ( (1.-R) * (dvdzup + abs(dvdzup)) +
1288     1 R * (dvdzdn + abs(dvdzdn)) )
1289    
1290     dvdzup = (diffus(i,kn-1,3) - diffus(i,kn ,3)) / hwide(kn)
1291     dvdzdn = (diffus(i,kn ,3) - diffus(i,kn+1,3)) / hwide(kn+1)
1292     diftp = 0.5 * ( (1.-R) * (dvdzup + abs(dvdzup)) +
1293     1 R * (dvdzdn + abs(dvdzdn)) )
1294    
1295     visch = diffus(i,kn,1) + viscp * delhat
1296     difsh = diffus(i,kn,2) + difsp * delhat
1297     difth = diffus(i,kn,3) + diftp * delhat
1298    
1299     f1 = stable(i) * conc1 * bfsfc(i) /
1300     & max(ustar(i)**4,phepsi)
1301     gat1m(i) = visch / hbl(i) / wm(i)
1302     dat1m(i) = -viscp / wm(i) + f1 * visch
1303    
1304     gat1s(i) = difsh / hbl(i) / ws(i)
1305     dat1s(i) = -difsp / ws(i) + f1 * difsh
1306    
1307     gat1t(i) = difth / hbl(i) / ws(i)
1308     dat1t(i) = -diftp / ws(i) + f1 * difth
1309    
1310     end do
1311     #ifdef KPP_AUTODIFF_EXCESSIVE_STORE
1312     CADJ STORE gat1m = comlev1_kpp, key=ikppkey, kind=isbyte
1313     CADJ STORE gat1s = comlev1_kpp, key=ikppkey, kind=isbyte
1314     CADJ STORE gat1t = comlev1_kpp, key=ikppkey, kind=isbyte
1315     CADJ STORE dat1m = comlev1_kpp, key=ikppkey, kind=isbyte
1316     CADJ STORE dat1s = comlev1_kpp, key=ikppkey, kind=isbyte
1317     CADJ STORE dat1t = comlev1_kpp, key=ikppkey, kind=isbyte
1318     #endif
1319     do i = 1, imt
1320     dat1m(i) = min(dat1m(i),p0)
1321     dat1s(i) = min(dat1s(i),p0)
1322     dat1t(i) = min(dat1t(i),p0)
1323     end do
1324     #ifdef KPP_AUTODIFF_EXCESSIVE_STORE
1325     CADJ STORE dat1m = comlev1_kpp, key=ikppkey, kind=isbyte
1326     CADJ STORE dat1s = comlev1_kpp, key=ikppkey, kind=isbyte
1327     CADJ STORE dat1t = comlev1_kpp, key=ikppkey, kind=isbyte
1328     #endif
1329    
1330     do ki = 1, Nr
1331    
1332     #ifdef ALLOW_AUTODIFF_TAMC
1333     kkppkey = (ikppkey-1)*Nr + ki
1334     #endif
1335    
1336     c-----------------------------------------------------------------------
1337     c compute turbulent velocity scales on the interfaces
1338     c-----------------------------------------------------------------------
1339    
1340     do i = 1, imt
1341     sig = (-zgrid(ki) + 0.5 * hwide(ki)) / hbl(i)
1342     sigma(i) = stable(i)*sig + (1.-stable(i))*min(sig,epsilon)
1343     end do
1344     #ifdef KPP_AUTODIFF_EXCESSIVE_STORE
1345     CADJ STORE wm = comlev1_kpp_k, key = kkppkey
1346     CADJ STORE ws = comlev1_kpp_k, key = kkppkey
1347     #endif
1348     CADJ STORE sigma = comlev1_kpp_k, key = kkppkey
1349     call wscale (
1350     I sigma, hbl, ustar, bfsfc,
1351     O wm, ws, myThid )
1352     CADJ STORE wm = comlev1_kpp_k, key = kkppkey
1353     CADJ STORE ws = comlev1_kpp_k, key = kkppkey
1354    
1355     c-----------------------------------------------------------------------
1356     c compute the dimensionless shape functions at the interfaces
1357     c-----------------------------------------------------------------------
1358    
1359     do i = 1, imt
1360     sig = (-zgrid(ki) + 0.5 * hwide(ki)) / hbl(i)
1361     a1 = sig - 2.
1362     a2 = 3. - 2. * sig
1363     a3 = sig - 1.
1364    
1365     Gm = a1 + a2 * gat1m(i) + a3 * dat1m(i)
1366     Gs = a1 + a2 * gat1s(i) + a3 * dat1s(i)
1367     Gt = a1 + a2 * gat1t(i) + a3 * dat1t(i)
1368    
1369     c-----------------------------------------------------------------------
1370     c compute boundary layer diffusivities at the interfaces
1371     c-----------------------------------------------------------------------
1372    
1373     blmc(i,ki,1) = hbl(i) * wm(i) * sig * (1. + sig * Gm)
1374     blmc(i,ki,2) = hbl(i) * ws(i) * sig * (1. + sig * Gs)
1375     blmc(i,ki,3) = hbl(i) * ws(i) * sig * (1. + sig * Gt)
1376    
1377     c-----------------------------------------------------------------------
1378     c nonlocal transport term = ghat * <ws>o
1379     c-----------------------------------------------------------------------
1380    
1381     tempVar = ws(i) * hbl(i)
1382     ghat(i,ki) = (1.-stable(i)) * cg / max(phepsi,tempVar)
1383    
1384     end do
1385     end do
1386    
1387     c-----------------------------------------------------------------------
1388     c find diffusivities at kbl-1 grid level
1389     c-----------------------------------------------------------------------
1390    
1391     do i = 1, imt
1392     sig = -zgrid(kbl(i)-1) / hbl(i)
1393     sigma(i) = stable(i) * sig
1394     & + (1. - stable(i)) * min(sig,epsilon)
1395     end do
1396    
1397     #ifdef KPP_AUTODIFF_EXCESSIVE_STORE
1398     CADJ STORE wm = comlev1_kpp, key=ikppkey, kind=isbyte
1399     CADJ STORE ws = comlev1_kpp, key=ikppkey, kind=isbyte
1400     #endif
1401     CADJ STORE sigma = comlev1_kpp, key=ikppkey, kind=isbyte
1402     call wscale (
1403     I sigma, hbl, ustar, bfsfc,
1404     O wm, ws, myThid )
1405     CADJ STORE wm = comlev1_kpp, key=ikppkey, kind=isbyte
1406     CADJ STORE ws = comlev1_kpp, key=ikppkey, kind=isbyte
1407    
1408     do i = 1, imt
1409     sig = -zgrid(kbl(i)-1) / hbl(i)
1410     a1 = sig - 2.
1411     a2 = 3. - 2. * sig
1412     a3 = sig - 1.
1413     Gm = a1 + a2 * gat1m(i) + a3 * dat1m(i)
1414     Gs = a1 + a2 * gat1s(i) + a3 * dat1s(i)
1415     Gt = a1 + a2 * gat1t(i) + a3 * dat1t(i)
1416     dkm1(i,1) = hbl(i) * wm(i) * sig * (1. + sig * Gm)
1417     dkm1(i,2) = hbl(i) * ws(i) * sig * (1. + sig * Gs)
1418     dkm1(i,3) = hbl(i) * ws(i) * sig * (1. + sig * Gt)
1419     end do
1420    
1421     #endif /* ALLOW_KPP */
1422    
1423     return
1424     end
1425    
1426     c*************************************************************************
1427    
1428     subroutine enhance (
1429     I dkm1, hbl, kbl, diffus, casea
1430     U , ghat
1431     O , blmc
1432     & , myThid )
1433    
1434     c enhance the diffusivity at the kbl-.5 interface
1435    
1436     IMPLICIT NONE
1437    
1438     #include "SIZE.h"
1439     #include "KPP_PARAMS.h"
1440    
1441     c input
1442     c dkm1(imt,mdiff) bl diffusivity at kbl-1 grid level
1443     c hbl(imt) boundary layer depth (m)
1444     c kbl(imt) grid above hbl
1445     c diffus(imt,0:Nrp1,mdiff) vertical diffusivities (m^2/s)
1446     c casea(imt) = 1 in caseA, = 0 in case B
1447     c myThid thread number for this instance of the routine
1448     integer myThid
1449     _RL dkm1 (imt,mdiff)
1450     _RL hbl (imt)
1451     integer kbl (imt)
1452     _RL diffus(imt,0:Nrp1,mdiff)
1453     _RL casea (imt)
1454    
1455     c input/output
1456     c nonlocal transport, modified ghat at kbl(i)-1 interface (s/m**2)
1457     _RL ghat (imt,Nr)
1458    
1459     c output
1460     c enhanced bound. layer mixing coeff.
1461     _RL blmc (imt,Nr,mdiff)
1462    
1463     #ifdef ALLOW_KPP
1464    
1465     c local
1466     c fraction hbl lies beteen zgrid neighbors
1467     _RL delta
1468     integer ki, i, md
1469     _RL dkmp5, dstar
1470    
1471     do i = 1, imt
1472     ki = kbl(i)-1
1473     if ((ki .ge. 1) .and. (ki .lt. Nr)) then
1474     delta = (hbl(i) + zgrid(ki)) / (zgrid(ki) - zgrid(ki+1))
1475     do md = 1, mdiff
1476     dkmp5 = casea(i) * diffus(i,ki,md) +
1477     1 (1.- casea(i)) * blmc (i,ki,md)
1478     dstar = (1.- delta)**2 * dkm1(i,md)
1479     & + delta**2 * dkmp5
1480     blmc(i,ki,md) = (1.- delta)*diffus(i,ki,md)
1481     & + delta*dstar
1482     end do
1483     ghat(i,ki) = (1.- casea(i)) * ghat(i,ki)
1484     endif
1485     end do
1486    
1487     #endif /* ALLOW_KPP */
1488    
1489     return
1490     end
1491    
1492     c*************************************************************************
1493    
1494     SUBROUTINE STATEKPP (
1495     O RHO1, DBLOC, DBSFC, TTALPHA, SSBETA,
1496     I ikppkey, bi, bj, myThid )
1497     c
1498     c-----------------------------------------------------------------------
1499     c "statekpp" computes all necessary input arrays
1500     c for the kpp mixing scheme
1501     c
1502     c input:
1503     c bi, bj = array indices on which to apply calculations
1504     c
1505     c output:
1506     c rho1 = potential density of surface layer (kg/m^3)
1507     c dbloc = local buoyancy gradient at Nr interfaces
1508     c g/rho{k+1,k+1} * [ drho{k,k+1}-drho{k+1,k+1} ] (m/s^2)
1509     c dbsfc = buoyancy difference with respect to the surface
1510     c g * [ drho{1,k}/rho{1,k} - drho{k,k}/rho{k,k} ] (m/s^2)
1511     c ttalpha= thermal expansion coefficient without 1/rho factor
1512     c d(rho) / d(potential temperature) (kg/m^3/C)
1513     c ssbeta = salt expansion coefficient without 1/rho factor
1514     c d(rho) / d(salinity) (kg/m^3/PSU)
1515     c
1516     c see also subroutines find_rho.F find_alpha.F find_beta.F
1517     c
1518     c written by: jan morzel, feb. 10, 1995 (converted from "sigma" version)
1519     c modified by: d. menemenlis, june 1998 : for use with MIT GCM UV
1520     c
1521    
1522     c-----------------------------------------------------------------------
1523    
1524     IMPLICIT NONE
1525    
1526     #include "SIZE.h"
1527     #include "EEPARAMS.h"
1528     #include "PARAMS.h"
1529     #include "KPP_PARAMS.h"
1530     #include "DYNVARS.h"
1531     #include "GRID.h"
1532     #ifdef ALLOW_AUTODIFF
1533     # include "tamc.h"
1534     #endif
1535    
1536     c-------------- Routine arguments -----------------------------------------
1537     INTEGER bi, bj, myThid
1538     _RL RHO1 ( 1-OLx:sNx+OLx, 1-OLy:sNy+OLy )
1539     _RL DBLOC ( 1-OLx:sNx+OLx, 1-OLy:sNy+OLy, Nr )
1540     _RL DBSFC ( 1-OLx:sNx+OLx, 1-OLy:sNy+OLy, Nr )
1541     _RL TTALPHA( 1-OLx:sNx+OLx, 1-OLy:sNy+OLy, Nrp1 )
1542     _RL SSBETA ( 1-OLx:sNx+OLx, 1-OLy:sNy+OLy, Nrp1 )
1543    
1544     #ifdef ALLOW_KPP
1545    
1546     c--------------------------------------------------------------------------
1547     c
1548     c local arrays:
1549     c
1550     c rhok - density of t(k ) & s(k ) at depth k
1551     c rhokm1 - density of t(k-1) & s(k-1) at depth k
1552     c rho1k - density of t(1 ) & s(1 ) at depth k
1553     c work1,2,3 - work arrays for holding horizontal slabs
1554    
1555     _RL RHOK (1-OLx:sNx+OLx,1-OLy:sNy+OLy)
1556     _RL RHOKM1(1-OLx:sNx+OLx,1-OLy:sNy+OLy)
1557     _RL RHO1K (1-OLx:sNx+OLx,1-OLy:sNy+OLy)
1558     _RL WORK1 (1-OLx:sNx+OLx,1-OLy:sNy+OLy)
1559     _RL WORK2 (1-OLx:sNx+OLx,1-OLy:sNy+OLy)
1560     _RL WORK3 (1-OLx:sNx+OLx,1-OLy:sNy+OLy)
1561    
1562     INTEGER I, J, K
1563     INTEGER ikppkey, kkppkey
1564    
1565     c calculate density, alpha, beta in surface layer, and set dbsfc to zero
1566    
1567     kkppkey = (ikppkey-1)*Nr + 1
1568    
1569     #ifdef KPP_AUTODIFF_EXCESSIVE_STORE
1570     CADJ STORE theta(:,:,1,bi,bj) = comlev1_kpp_k,
1571     CADJ & key=kkppkey, kind=isbyte
1572     CADJ STORE salt (:,:,1,bi,bj) = comlev1_kpp_k,
1573     CADJ & key=kkppkey, kind=isbyte
1574     #endif /* KPP_AUTODIFF_EXCESSIVE_STORE */
1575     CALL FIND_RHO_2D(
1576     I 1-OLx, sNx+OLx, 1-OLy, sNy+OLy, 1,
1577     I theta(1-OLx,1-OLy,1,bi,bj), salt(1-OLx,1-OLy,1,bi,bj),
1578     O WORK1,
1579     I 1, bi, bj, myThid )
1580     #ifdef KPP_AUTODIFF_EXCESSIVE_STORE
1581     CADJ STORE theta(:,:,1,bi,bj) = comlev1_kpp_k,
1582     CADJ & key=kkppkey, kind=isbyte
1583     CADJ STORE salt (:,:,1,bi,bj) = comlev1_kpp_k,
1584     CADJ & key=kkppkey, kind=isbyte
1585     #endif /* KPP_AUTODIFF_EXCESSIVE_STORE */
1586    
1587     call FIND_ALPHA(
1588     I bi, bj, 1-OLx, sNx+OLx, 1-OLy, sNy+OLy, 1, 1,
1589     O WORK2, myThid )
1590    
1591     call FIND_BETA(
1592     I bi, bj, 1-OLx, sNx+OLx, 1-OLy, sNy+OLy, 1, 1,
1593     O WORK3, myThid )
1594    
1595     DO J = 1-OLy, sNy+OLy
1596     DO I = 1-OLx, sNx+OLx
1597     RHO1(I,J) = WORK1(I,J) + rhoConst
1598     TTALPHA(I,J,1) = WORK2(I,J)
1599     SSBETA(I,J,1) = WORK3(I,J)
1600     DBSFC(I,J,1) = 0.
1601     END DO
1602     END DO
1603    
1604     c calculate alpha, beta, and gradients in interior layers
1605    
1606     CHPF$ INDEPENDENT, NEW (RHOK,RHOKM1,RHO1K,WORK1,WORK2)
1607     DO K = 2, Nr
1608    
1609     kkppkey = (ikppkey-1)*Nr + k
1610    
1611     #ifdef KPP_AUTODIFF_EXCESSIVE_STORE
1612     CADJ STORE theta(:,:,k,bi,bj) = comlev1_kpp_k,
1613     CADJ & key=kkppkey, kind=isbyte
1614     CADJ STORE salt (:,:,k,bi,bj) = comlev1_kpp_k,
1615     CADJ & key=kkppkey, kind=isbyte
1616     #endif /* KPP_AUTODIFF_EXCESSIVE_STORE */
1617     CALL FIND_RHO_2D(
1618     I 1-OLx, sNx+OLx, 1-OLy, sNy+OLy, k,
1619     I theta(1-OLx,1-OLy,k,bi,bj), salt(1-OLx,1-OLy,k,bi,bj),
1620     O RHOK,
1621     I k, bi, bj, myThid )
1622    
1623     #ifdef KPP_AUTODIFF_EXCESSIVE_STORE
1624     CADJ STORE theta(:,:,k-1,bi,bj) = comlev1_kpp_k,
1625     CADJ & key=kkppkey, kind=isbyte
1626     CADJ STORE salt (:,:,k-1,bi,bj) = comlev1_kpp_k,
1627     CADJ & key=kkppkey, kind=isbyte
1628     #endif /* KPP_AUTODIFF_EXCESSIVE_STORE */
1629     CALL FIND_RHO_2D(
1630     I 1-OLx, sNx+OLx, 1-OLy, sNy+OLy, k,
1631     I theta(1-OLx,1-OLy,k-1,bi,bj),salt(1-OLx,1-OLy,k-1,bi,bj),
1632     O RHOKM1,
1633     I k-1, bi, bj, myThid )
1634    
1635     #ifdef KPP_AUTODIFF_EXCESSIVE_STORE
1636     CADJ STORE theta(:,:,1,bi,bj) = comlev1_kpp_k,
1637     CADJ & key=kkppkey, kind=isbyte
1638     CADJ STORE salt (:,:,1,bi,bj) = comlev1_kpp_k,
1639     CADJ & key=kkppkey, kind=isbyte
1640     #endif /* KPP_AUTODIFF_EXCESSIVE_STORE */
1641     CALL FIND_RHO_2D(
1642     I 1-OLx, sNx+OLx, 1-OLy, sNy+OLy, k,
1643     I theta(1-OLx,1-OLy,1,bi,bj), salt(1-OLx,1-OLy,1,bi,bj),
1644     O RHO1K,
1645     I 1, bi, bj, myThid )
1646    
1647     #ifdef KPP_AUTODIFF_EXCESSIVE_STORE
1648     CADJ STORE rhok (:,:) = comlev1_kpp_k,
1649     CADJ & key=kkppkey, kind=isbyte
1650     CADJ STORE rhokm1(:,:) = comlev1_kpp_k,
1651     CADJ & key=kkppkey, kind=isbyte
1652     CADJ STORE rho1k (:,:) = comlev1_kpp_k,
1653     CADJ & key=kkppkey, kind=isbyte
1654     #endif /* KPP_AUTODIFF_EXCESSIVE_STORE */
1655    
1656     call FIND_ALPHA(
1657     I bi, bj, 1-OLx, sNx+OLx, 1-OLy, sNy+OLy, K, K,
1658     O WORK1, myThid )
1659    
1660     call FIND_BETA(
1661     I bi, bj, 1-OLx, sNx+OLx, 1-OLy, sNy+OLy, K, K,
1662     O WORK2, myThid )
1663    
1664     DO J = 1-OLy, sNy+OLy
1665     DO I = 1-OLx, sNx+OLx
1666     TTALPHA(I,J,K) = WORK1 (I,J)
1667     SSBETA(I,J,K) = WORK2 (I,J)
1668     DBLOC(I,J,K-1) = gravity * (RHOK(I,J) - RHOKM1(I,J)) /
1669     & (RHOK(I,J) + rhoConst)
1670     DBSFC(I,J,K) = gravity * (RHOK(I,J) - RHO1K (I,J)) /
1671     & (RHOK(I,J) + rhoConst)
1672     END DO
1673     END DO
1674    
1675     END DO
1676    
1677     c compute arrays for K = Nrp1
1678     DO J = 1-OLy, sNy+OLy
1679     DO I = 1-OLx, sNx+OLx
1680     TTALPHA(I,J,Nrp1) = TTALPHA(I,J,Nr)
1681     SSBETA(I,J,Nrp1) = SSBETA(I,J,Nr)
1682     DBLOC(I,J,Nr) = 0.
1683     END DO
1684     END DO
1685    
1686     #ifdef ALLOW_DIAGNOSTICS
1687     IF ( useDiagnostics ) THEN
1688     CALL DIAGNOSTICS_FILL(DBSFC ,'KPPdbsfc',0,Nr,2,bi,bj,myThid)
1689     CALL DIAGNOSTICS_FILL(DBLOC ,'KPPdbloc',0,Nr,2,bi,bj,myThid)
1690     ENDIF
1691     #endif /* ALLOW_DIAGNOSTICS */
1692    
1693     #endif /* ALLOW_KPP */
1694    
1695     RETURN
1696     END
1697    
1698     c*************************************************************************
1699    
1700     SUBROUTINE KPP_DOUBLEDIFF (
1701     I TTALPHA, SSBETA,
1702     U kappaRT,
1703     U kappaRS,
1704     I ikppkey, imin, imax, jmin, jmax, bi, bj, myThid )
1705     c
1706     c-----------------------------------------------------------------------
1707     c "KPP_DOUBLEDIFF" adds the double diffusive contributions
1708     C as Rrho-dependent parameterizations to kappaRT and kappaRS
1709     c
1710     c input:
1711     c bi, bj = array indices on which to apply calculations
1712     c imin, imax, jmin, jmax = array boundaries
1713     c ikppkey = key for TAMC/TAF automatic differentiation
1714     c myThid = thread id
1715     c
1716     c ttalpha= thermal expansion coefficient without 1/rho factor
1717     c d(rho) / d(potential temperature) (kg/m^3/C)
1718     c ssbeta = salt expansion coefficient without 1/rho factor
1719     c d(rho) / d(salinity) (kg/m^3/PSU)
1720     c output: updated
1721     c kappaRT/S :: background diffusivities for temperature and salinity
1722     c
1723     c written by: martin losch, sept. 15, 2009
1724     c
1725    
1726     c-----------------------------------------------------------------------
1727    
1728     IMPLICIT NONE
1729    
1730     #include "SIZE.h"
1731     #include "EEPARAMS.h"
1732     #include "PARAMS.h"
1733     #include "KPP_PARAMS.h"
1734     #include "DYNVARS.h"
1735     #include "GRID.h"
1736     #ifdef ALLOW_AUTODIFF
1737     # include "tamc.h"
1738     #endif
1739    
1740     c-------------- Routine arguments -----------------------------------------
1741     INTEGER ikppkey, imin, imax, jmin, jmax, bi, bj, myThid
1742    
1743     _RL TTALPHA( 1-OLx:sNx+OLx, 1-OLy:sNy+OLy, Nrp1 )
1744     _RL SSBETA ( 1-OLx:sNx+OLx, 1-OLy:sNy+OLy, Nrp1 )
1745     _RL KappaRT( 1-OLx:sNx+OLx, 1-OLy:sNy+OLy, Nr )
1746     _RL KappaRS( 1-OLx:sNx+OLx, 1-OLy:sNy+OLy, Nr )
1747    
1748     #ifdef ALLOW_KPP
1749    
1750     C--------------------------------------------------------------------------
1751     C
1752     C local variables
1753     C I,J,K :: loop indices
1754     C kkppkey :: key for TAMC/TAF automatic differentiation
1755     C
1756     INTEGER I, J, K
1757     INTEGER kkppkey
1758     C alphaDT :: d\rho/d\theta * d\theta
1759     C betaDS :: d\rho/dsalt * dsalt
1760     C Rrho :: "density ratio" R_{\rho} = \alpha dT/dz / \beta dS/dz
1761     C nuddt/s :: double diffusive diffusivities
1762     C numol :: molecular diffusivity
1763     C rFac :: abbreviation for 1/(R_{\rho0}-1)
1764    
1765     _RL alphaDT ( 1-OLx:sNx+OLx, 1-OLy:sNy+OLy )
1766     _RL betaDS ( 1-OLx:sNx+OLx, 1-OLy:sNy+OLy )
1767     _RL nuddt ( 1-OLx:sNx+OLx, 1-OLy:sNy+OLy )
1768     _RL nudds ( 1-OLx:sNx+OLx, 1-OLy:sNy+OLy )
1769     _RL Rrho
1770     _RL numol, rFac, nutmp
1771     INTEGER Km1
1772    
1773     C set some constants here
1774     numol = 1.5 _d -06
1775     rFac = 1. _d 0 / (Rrho0 - 1. _d 0 )
1776     C
1777     kkppkey = (ikppkey-1)*Nr + 1
1778    
1779     CML#ifdef KPP_AUTODIFF_EXCESSIVE_STORE
1780     CMLCADJ STORE theta(:,:,1,bi,bj) = comlev1_kpp_k,
1781     CMLCADJ & key=kkppkey, kind=isbyte
1782     CMLCADJ STORE salt (:,:,1,bi,bj) = comlev1_kpp_k,
1783     CMLCADJ & key=kkppkey, kind=isbyte
1784     CML#endif /* KPP_AUTODIFF_EXCESSIVE_STORE */
1785    
1786     DO K = 1, Nr
1787     Km1 = MAX(K-1,1)
1788     DO J = 1-OLy, sNy+OLy
1789     DO I = 1-OLx, sNx+OLx
1790     alphaDT(I,J) = ( theta(I,J,Km1,bi,bj)-theta(I,J,K,bi,bj) )
1791     & * 0.5 _d 0 * ABS( TTALPHA(I,J,Km1) + TTALPHA(I,J,K) )
1792     betaDS(I,J) = ( salt(I,J,Km1,bi,bj)-salt(I,J,K,bi,bj) )
1793     & * 0.5 _d 0 * ( SSBETA(I,J,Km1) + SSBETA(I,J,K) )
1794     nuddt(I,J) = 0. _d 0
1795     nudds(I,J) = 0. _d 0
1796     ENDDO
1797     ENDDO
1798     IF ( K .GT. 1 ) THEN
1799     DO J = jMin, jMax
1800     DO I = iMin, iMax
1801     Rrho = 0. _d 0
1802     C Now we have many different cases
1803     C a. alphaDT > 0 and betaDS > 0 => salt fingering
1804     C (salinity destabilizes)
1805     IF ( alphaDT(I,J) .GT. betaDS(I,J)
1806     & .AND. betaDS(I,J) .GT. 0. _d 0 ) THEN
1807     Rrho = MIN( alphaDT(I,J)/betaDS(I,J), Rrho0 )
1808     C Large et al. 1994, eq. 31a
1809     C nudds(I,J) = dsfmax * ( 1. _d 0 - (Rrho - 1. _d 0) * rFac )**3
1810     nutmp = ( 1. _d 0 - (Rrho - 1. _d 0) * rFac )
1811     nudds(I,J) = dsfmax * nutmp * nutmp * nutmp
1812     C Large et al. 1994, eq. 31c
1813     nuddt(I,J) = 0.7 _d 0 * nudds(I,J)
1814     ELSEIF ( alphaDT(I,J) .LT. 0. _d 0
1815     & .AND. betaDS(I,J) .LT. 0. _d 0
1816     & .AND.alphaDT(I,J) .GT. betaDS(I,J) ) THEN
1817     C b. alphaDT < 0 and betaDS < 0 => semi-convection, diffusive convection
1818     C (temperature destabilizes)
1819     C for Rrho >= 1 the water column is statically unstable and we never
1820     C reach this point
1821     Rrho = alphaDT(I,J)/betaDS(I,J)
1822     C Large et al. 1994, eq. 32
1823     nuddt(I,J) = numol * 0.909 _d 0
1824     & * exp ( 4.6 _d 0 * exp (
1825     & - 5.4 _d 0 * ( 1. _d 0/Rrho - 1. _d 0 ) ) )
1826     CMLC or
1827     CMLC Large et al. 1994, eq. 33
1828     CML nuddt(I,J) = numol * 8.7 _d 0 * Rrho**1.1
1829     C Large et al. 1994, eqs. 34
1830     nudds(I,J) = nuddt(I,J) * MAX( 0.15 _d 0 * Rrho,
1831     & 1.85 _d 0 * Rrho - 0.85 _d 0 )
1832     ELSE
1833     C Do nothing, because in this case the water colume is unstable
1834     C => double diffusive processes are negligible and mixing due
1835     C to shear instability will dominate
1836     ENDIF
1837     ENDDO
1838     ENDDO
1839     C ENDIF ( K .GT. 1 )
1840     ENDIF
1841     C
1842     DO J = 1-OLy, sNy+OLy
1843     DO I = 1-OLx, sNx+OLx
1844     kappaRT(I,J,K) = kappaRT(I,J,K) + nuddt(I,J)
1845     kappaRS(I,J,K) = kappaRS(I,J,K) + nudds(I,J)
1846     ENDDO
1847     ENDDO
1848     #ifdef ALLOW_DIAGNOSTICS
1849     IF ( useDiagnostics ) THEN
1850     CALL DIAGNOSTICS_FILL(nuddt,'KPPnuddt',k,1,2,bi,bj,myThid)
1851     CALL DIAGNOSTICS_FILL(nudds,'KPPnudds',k,1,2,bi,bj,myThid)
1852     ENDIF
1853     #endif /* ALLOW_DIAGNOSTICS */
1854     C end of K-loop
1855     ENDDO
1856     #endif /* ALLOW_KPP */
1857    
1858     RETURN
1859     END

  ViewVC Help
Powered by ViewVC 1.1.22