1 |
C $Header: /u/gcmpack/MITgcm/pkg/kl10/kl10_calc.F,v 1.4 2014/11/17 14:13:57 jmc Exp $ |
2 |
C $Name: $ |
3 |
|
4 |
#include "KL10_OPTIONS.h" |
5 |
|
6 |
CBOP |
7 |
C !ROUTINE: KL10_CALC |
8 |
|
9 |
C !INTERFACE: ======================================================= |
10 |
SUBROUTINE KL10_CALC( |
11 |
I bi, bj, sigmaR, myTime, myIter, myThid ) |
12 |
|
13 |
C !DESCRIPTION: \bv |
14 |
C *==========================================================* |
15 |
C | SUBROUTINE KL10_CALC | |
16 |
C | o Compute all KL10 fields defined in KL10.h | |
17 |
C *==========================================================* |
18 |
C | This subroutine is based on SPEM code | |
19 |
C *==========================================================* |
20 |
C \ev |
21 |
|
22 |
C-------------------------------------------------------------------- |
23 |
|
24 |
C JMK |
25 |
C global parameters updated by kl_calc |
26 |
C KLviscAz :: KL eddy viscosity coefficient (m^2/s) |
27 |
C KLdiffKzT :: KL diffusion coefficient for temperature (m^2/s) |
28 |
|
29 |
C !USES: ============================================================ |
30 |
IMPLICIT NONE |
31 |
#include "SIZE.h" |
32 |
#include "EEPARAMS.h" |
33 |
#include "PARAMS.h" |
34 |
#include "EOS.h" |
35 |
#include "GRID.h" |
36 |
#include "DYNVARS.h" |
37 |
#include "FFIELDS.h" |
38 |
#include "KL10.h" |
39 |
c#ifdef ALLOW_AUTODIFF_TAMC |
40 |
c# include "tamc.h" |
41 |
c# include "tamc_keys.h" |
42 |
c#endif /* ALLOW_AUTODIFF_TAMC */ |
43 |
|
44 |
C !INPUT PARAMETERS: =================================================== |
45 |
c Routine arguments |
46 |
C bi, bj :: Current tile indices |
47 |
C sigmaR :: Vertical gradient of iso-neutral density |
48 |
C myTime :: Current time in simulation |
49 |
C myIter :: Current time-step number |
50 |
C myThid :: My Thread Id number |
51 |
INTEGER bi, bj |
52 |
_RL sigmaR(1-OLx:sNx+OLx,1-OLy:sNy+OLy,Nr) |
53 |
_RL myTime |
54 |
INTEGER myIter |
55 |
INTEGER myThid |
56 |
|
57 |
#ifdef ALLOW_KL10 |
58 |
C !LOCAL VARIABLES: ==================================================== |
59 |
c Local constants |
60 |
C iMin, iMax, jMin, jMax :: array computation indices |
61 |
INTEGER I, J, K, Km1, JJ |
62 |
INTEGER iMin ,iMax ,jMin ,jMax,di |
63 |
_RL KLviscTmp, rhot, tempu |
64 |
_RL b0, buoyFreqf, buoyFreqc, KLviscold,zsum,zsums |
65 |
_RL rhoS(1:Nr),RS(1:Nr) |
66 |
_RL dzp,ec,ep,es,epss(-1:0),epsw(-1:0),dz,KTemp |
67 |
c _RL bF(1:Nr) |
68 |
c _RL theta_mcb(1:Nr),theta_mcb3(1:Nr) |
69 |
C === Local variables === |
70 |
C msgBuf :: Informational/error message buffer |
71 |
c CHARACTER*(MAX_LEN_MBUF) msgBuf |
72 |
CEOP |
73 |
|
74 |
iMin = 2-OLx |
75 |
iMax = sNx+OLx-1 |
76 |
jMin = 2-OLy |
77 |
jMax = sNy+OLy-1 |
78 |
|
79 |
DO J=jMin,jMax |
80 |
DO I=iMin,iMax |
81 |
K=1 |
82 |
CALL FIND_RHO_SCALAR(theta(I,J,K,bi,bj), salt(I,J,K,bi,bj), |
83 |
& totPhiHyd(I,J,K,bi,bj),rhot,myThid ) |
84 |
rhoS(1)=rhot |
85 |
RS(1)=rC(1) |
86 |
|
87 |
KLeps(I-1,J-1,1,bi,bj)=0.0 |
88 |
c eps(k-1) = (dz(k-1)*eps0(k-1) +dz(k)*eps0(k))/(dz(k-1)+dz(k)) |
89 |
ep = 0.0 |
90 |
dzp = 0.0 |
91 |
|
92 |
KLviscAr(I,J,1,bi,bj) = viscArNr(1) |
93 |
KLviscold = KLviscAr(I,J,1,bi,bj) ! at previous cell center |
94 |
C get sorted densities rhoS, and the array with the depths from which |
95 |
C the density came from, RS. |
96 |
DO K=2,Nr |
97 |
CALL FIND_RHO_SCALAR(theta(I,J,K,bi,bj), salt(I,J,K,bi |
98 |
& ,bj),totPhiHyd(I,J,K,bi,bj),rhot,myThid ) |
99 |
rhoS(K)=rhot |
100 |
RS(K)=rC(K) |
101 |
c$$$ WRITE(msgBuf, '(A,I10.10,A,E10.4,A,E10.4)') 'Hellok ', K |
102 |
c$$$ & -1,' ',theta(I,J,K,bi,bj),' ',rhot |
103 |
c$$$ CALL PRINT_MESSAGE( msgBuf, standardMessageUnit, |
104 |
c$$$ & SQUEEZE_RIGHT, myThid ) |
105 |
IF ( (rhoS(K).LT.rhoS(K-1)).AND.(maskC(I,J,K,bi |
106 |
& ,bj).GT.0)) THEN |
107 |
JJ=K-1 |
108 |
DO WHILE ( (JJ.GT.0).AND.(rhoS(K).LT.rhoS(JJ)) ) |
109 |
c write(*,*) K,JJ,rhoS(K),rhoS(JJ) |
110 |
JJ=JJ-1 |
111 |
ENDDO |
112 |
rhoS(JJ+1:K)=cshift(rhoS(JJ+1:K),-1) |
113 |
RS(JJ+1:K)=cshift(RS(JJ+1:K),-1) |
114 |
ENDIF |
115 |
ENDDO |
116 |
|
117 |
C RS-R is dz.... |
118 |
C recip_drC=inverse distanance between centers, |
119 |
C first is between surface and first center |
120 |
C diffKrNrS(K) = viscArNr(K) = background value |
121 |
|
122 |
KLdiffKr(I,J,1,bi,bj) = MAX(KLviscAr(I,J,1,bi,bj), |
123 |
#ifdef ALLOW_3D_DIFFKR |
124 |
& diffKr(I,J,1,bi,bj) ) |
125 |
#else |
126 |
& diffKrNrS(1) ) |
127 |
#endif |
128 |
C N at surface = zero or uses gradient |
129 |
b0 = MAX(-gravity*mass2rUnit* |
130 |
& (rhoS(1) - rhoS(2))*recip_drC(2),0. _d 0) |
131 |
c b0 = 0. |
132 |
DO di=-1,0 |
133 |
epss(di)=0.0 |
134 |
epsw(di)=0.0 |
135 |
ENDDO |
136 |
|
137 |
DO K=1,Nr |
138 |
IF (K.LT.Nr) THEN |
139 |
buoyFreqf = -gravity*mass2rUnit* |
140 |
& (rhoS(K) - rhoS(K+1))*recip_drC(K+1) |
141 |
ELSE |
142 |
C N zero OR not zero near bottom (at the end of array) |
143 |
buoyFreqf = -gravity*mass2rUnit* |
144 |
& (rhoS(K-1) - rhoS(K))*recip_drC(K) |
145 |
C buoyFreqf = 0. |
146 |
ENDIF |
147 |
buoyFreqf = MAX(buoyFreqf,0. _d 0) ! not < 0 |
148 |
buoyFreqc = (buoyFreqf + b0)*0.5 ! mean at cell center |
149 |
|
150 |
C viscosity at cell center at K |
151 |
C = 0.2*dz^2*N. 0.2 is mixing efficiency. |
152 |
C to derive, note K = 0.2\epsilon/N^2. Then note that |
153 |
C \epsilon = dz^2N^3 (Ozmidov scale) |
154 |
KLviscTmp = MAX( viscArNr(K), 0.2*(RS(K)-rC(K))* |
155 |
& (RS(K)-rC(K))*sqrt(buoyFreqc)) |
156 |
|
157 |
IF (K.GT.1) THEN |
158 |
Km1=K-1 |
159 |
|
160 |
C viscosity at cell face above center at K |
161 |
KTemp = 0.5*(KLviscTmp+KLviscold) |
162 |
C Put an upper limit on viscosity to prevent instability when |
163 |
C explicit viscosity is C used (e.g. for nonhydrostatic case) SAL |
164 |
KTemp = MIN(KLviscMax,KTemp) |
165 |
KLviscAr(I,J,K,bi,bj) = MAX(KTemp,viscArNr(K)) |
166 |
KLdiffKr(I,J,K,bi,bj) = MAX(KTemp, |
167 |
#ifdef ALLOW_3D_DIFFKR |
168 |
& diffKr(I,J,K,bi,bj) ) |
169 |
#else |
170 |
& diffKrNrS(K) ) |
171 |
#endif |
172 |
|
173 |
C Compute Epsilon for diagnostics: |
174 |
C |
175 |
C need to caclulate Im1 and Jm1 epsilon unfortunately... Here at |
176 |
C i-1,j-1 we average the west nu(du/dz)^2 at i-1 and i, and the south |
177 |
C nu(dv/dv)^2 at j-1 and j, and then add them |
178 |
C |
179 |
C dz is calculated from the face distances, with the cells assumed to be |
180 |
C half way. Note the use of hfacW and hfacS to make these correct near |
181 |
C bathy. |
182 |
zsum=0. |
183 |
ec=0.0 |
184 |
zsums=0. |
185 |
es=0. |
186 |
DO di=-1,0 |
187 |
IF (hfacW(I+di,J-1,K,bi,bj).GT.0.000001) THEN |
188 |
dz = 0.5*(drF(K)*hfacW(I+di,J-1,K,bi,bj) |
189 |
& +drF(Km1)*hfacW(I+di,J-1,Km1,bi,bj)) |
190 |
IF (dz.GT.0.00001) THEN |
191 |
tempu = (uVel(I+di,J-1,Km1,bi,bj)-uVel(I+di,J |
192 |
& -1,K,bi,bj))/dz |
193 |
epsw(di)=tempu*tempu*KLviscAr(I+di,J-1,K,bi |
194 |
& ,bj) |
195 |
ec=ec+epsw(di)*dz |
196 |
zsum = zsum+dz |
197 |
ENDIF |
198 |
ELSE |
199 |
C This face is on the seafloor. set epsilon=the |
200 |
C previous and dz = half the face. |
201 |
dz=0.5*(drF(Km1)*hfacW(I+di,J-1,Km1,bi ,bj)) |
202 |
ec=ec+epsw(di)*dz |
203 |
zsum = zsum+dz |
204 |
ENDIF |
205 |
C Now do the v-component |
206 |
IF (hfacS(I-1,J+di,K,bi,bj).GT.0.000001) THEN |
207 |
dz = 0.5*(drF(K)*hfacS(I-1,J+di,K,bi,bj) |
208 |
& +drF(Km1)*hfacS(I-1,J+di,Km1,bi,bj)) |
209 |
IF (dz.GT.0.00001) THEN |
210 |
tempu = (vVel(I-1,J+di,Km1,bi,bj)-vVel(I-1,J |
211 |
& +di,K,bi,bj))/dz |
212 |
epss(di)=tempu*tempu*KLviscAr(I-1,J+di,K,bi |
213 |
& ,bj) |
214 |
es = es+epss(di)*dz |
215 |
zsums = zsums+dz |
216 |
ENDIF |
217 |
ELSE |
218 |
C This face is on the seafloor. set epsilon=the |
219 |
C previous and dz = half the face. |
220 |
dz=+0.5*(drF(Km1)*hfacS(I-1,J+di,Km1 ,bi,bj)) |
221 |
es = es+epss(di)*dz |
222 |
zsums = zsums+dz |
223 |
ENDIF |
224 |
ENDDO |
225 |
C take the average of the du/dz terms |
226 |
IF (zsum.GT.0.00001) THEN |
227 |
ec=ec/zsum |
228 |
ENDIF |
229 |
C take the average of the dv/dz terms |
230 |
IF (zsums.GT.0.00001) THEN |
231 |
es=es/zsums |
232 |
ENDIF |
233 |
C add the u and v dissipations: |
234 |
ec=es+ec |
235 |
|
236 |
C Note this ec is defined on cell faces K=2..NR at the center of the |
237 |
C cells (i.e. at XC), so its above the density variables. |
238 |
C |
239 |
C So to get at the center of the cells, just average this one and the previous one. |
240 |
C And its a true average because the |
241 |
|
242 |
KLeps(I-1,J-1,Km1,bi,bj) = 0.5*(ep+ec) |
243 |
IF (Km1.EQ.1) THEN |
244 |
KLeps(I-1,J-1,Km1,bi,bj) = ec |
245 |
ENDIF |
246 |
ep=ec |
247 |
ENDIF |
248 |
c$$$ WRITE(msgBuf, '(A,I10.10,A,E10.4,A,E10.4)') 'Hellok ', K |
249 |
c$$$ & -1,' ',theta(I,J,K,bi,bj),' ',KLeps(I-1,J-1,Km1,bi |
250 |
c$$$ & ,bj) |
251 |
c$$$ CALL PRINT_MESSAGE( msgBuf, standardMessageUnit, |
252 |
c$$$ & SQUEEZE_RIGHT, myThid ) |
253 |
|
254 |
b0 = buoyFreqf ! at previous cell face |
255 |
KLviscold = KLviscTmp ! at previous cell center |
256 |
ENDDO |
257 |
C ENDDO K |
258 |
C set on K=Nr |
259 |
KLeps(I-1,J-1,Nr,bi,bj) =ep |
260 |
|
261 |
ENDDO |
262 |
C ENDDO J |
263 |
ENDDO |
264 |
C ENDDO I |
265 |
|
266 |
#endif /* ALLOW_KL10 */ |
267 |
|
268 |
RETURN |
269 |
END |