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

Contents 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 - (show 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 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 C $Name: $
3
4 #include "KPP_OPTIONS.h"
5 #ifdef ALLOW_SALT_PLUME
6 #include "SALT_PLUME_OPTIONS.h"
7 #endif
8
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