/[MITgcm]/MITgcm/pkg/generic_advdiff/gad_calc_rhs.F
ViewVC logotype

Contents of /MITgcm/pkg/generic_advdiff/gad_calc_rhs.F

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


Revision 1.53 - (show annotations) (download)
Fri Jun 26 23:10:09 2009 UTC (14 years, 11 months ago) by jahn
Branch: MAIN
CVS Tags: checkpoint62c, checkpoint62a, checkpoint62d, checkpoint62, checkpoint62b, checkpoint61v, checkpoint61w, checkpoint61t, checkpoint61u, checkpoint61s, checkpoint61z, checkpoint61x, checkpoint61y
Changes since 1.52: +25 -23 lines
add package longstep

1 C $Header: /u/gcmpack/MITgcm/pkg/generic_advdiff/gad_calc_rhs.F,v 1.52 2008/04/23 18:32:20 jahn Exp $
2 C $Name: $
3
4 #include "GAD_OPTIONS.h"
5
6 CBOP
7 C !ROUTINE: GAD_CALC_RHS
8
9 C !INTERFACE: ==========================================================
10 SUBROUTINE GAD_CALC_RHS(
11 I bi,bj,iMin,iMax,jMin,jMax,k,kM1,kUp,kDown,
12 I xA, yA, maskUp, uFld, vFld, wFld,
13 I uTrans, vTrans, rTrans, rTransKp1,
14 I diffKh, diffK4, KappaR, TracerN, TracAB,
15 I deltaTLev, tracerIdentity,
16 I advectionScheme, vertAdvecScheme,
17 I calcAdvection, implicitAdvection, applyAB_onTracer,
18 I trUseGMRedi, trUseKPP,
19 U fVerT, gTracer,
20 I myTime, myIter, myThid )
21
22 C !DESCRIPTION:
23 C Calculates the tendency of a tracer due to advection and diffusion.
24 C It calculates the fluxes in each direction indepentently and then
25 C sets the tendency to the divergence of these fluxes. The advective
26 C fluxes are only calculated here when using the linear advection schemes
27 C otherwise only the diffusive and parameterized fluxes are calculated.
28 C
29 C Contributions to the flux are calculated and added:
30 C \begin{equation*}
31 C {\bf F} = {\bf F}_{adv} + {\bf F}_{diff} +{\bf F}_{GM} + {\bf F}_{KPP}
32 C \end{equation*}
33 C
34 C The tendency is the divergence of the fluxes:
35 C \begin{equation*}
36 C G_\theta = G_\theta + \nabla \cdot {\bf F}
37 C \end{equation*}
38 C
39 C The tendency is assumed to contain data on entry.
40
41 C !USES: ===============================================================
42 IMPLICIT NONE
43 #include "SIZE.h"
44 #include "EEPARAMS.h"
45 #include "PARAMS.h"
46 #include "GRID.h"
47 #include "SURFACE.h"
48 #include "GAD.h"
49
50 #ifdef ALLOW_AUTODIFF_TAMC
51 #include "tamc.h"
52 #include "tamc_keys.h"
53 #endif /* ALLOW_AUTODIFF_TAMC */
54
55 C !INPUT PARAMETERS: ===================================================
56 C bi,bj :: tile indices
57 C iMin,iMax :: loop range for called routines
58 C jMin,jMax :: loop range for called routines
59 C k :: vertical index
60 C kM1 :: =k-1 for k>1, =1 for k=1
61 C kUp :: index into 2 1/2D array, toggles between 1|2
62 C kDown :: index into 2 1/2D array, toggles between 2|1
63 C xA,yA :: areas of X and Y face of tracer cells
64 C maskUp :: 2-D array for mask at W points
65 C uFld,vFld,wFld :: Local copy of velocity field (3 components)
66 C uTrans,vTrans :: 2-D arrays of volume transports at U,V points
67 C rTrans :: 2-D arrays of volume transports at W points
68 C rTransKp1 :: 2-D array of volume trans at W pts, interf k+1
69 C diffKh :: horizontal diffusion coefficient
70 C diffK4 :: bi-harmonic diffusion coefficient
71 C KappaR :: 2-D array for vertical diffusion coefficient, interf k
72 C TracerN :: tracer field @ time-step n (Note: only used
73 C if applying AB on tracer field rather than on tendency gTr)
74 C TracAB :: current tracer field (@ time-step n if applying AB on gTr
75 C or extrapolated fwd in time to n+1/2 if applying AB on Tr)
76 C tracerIdentity :: tracer identifier (required for KPP,GM)
77 C advectionScheme :: advection scheme to use (Horizontal plane)
78 C vertAdvecScheme :: advection scheme to use (Vertical direction)
79 C calcAdvection :: =False if Advec computed with multiDim scheme
80 C implicitAdvection:: =True if vertical Advec computed implicitly
81 C applyAB_onTracer :: apply Adams-Bashforth on Tracer (rather than on gTr)
82 C trUseGMRedi :: true if this tracer uses GM-Redi
83 C trUseKPP :: true if this tracer uses KPP
84 C myTime :: current time
85 C myIter :: iteration number
86 C myThid :: thread number
87 INTEGER bi,bj,iMin,iMax,jMin,jMax
88 INTEGER k,kUp,kDown,kM1
89 _RS xA (1-OLx:sNx+OLx,1-OLy:sNy+OLy)
90 _RS yA (1-OLx:sNx+OLx,1-OLy:sNy+OLy)
91 _RS maskUp(1-OLx:sNx+OLx,1-OLy:sNy+OLy)
92 _RL uFld (1-OLx:sNx+OLx,1-OLy:sNy+OLy)
93 _RL vFld (1-OLx:sNx+OLx,1-OLy:sNy+OLy)
94 _RL wFld (1-OLx:sNx+OLx,1-OLy:sNy+OLy)
95 _RL uTrans(1-OLx:sNx+OLx,1-OLy:sNy+OLy)
96 _RL vTrans(1-OLx:sNx+OLx,1-OLy:sNy+OLy)
97 _RL rTrans(1-OLx:sNx+OLx,1-OLy:sNy+OLy)
98 _RL rTransKp1(1-OLx:sNx+OLx,1-OLy:sNy+OLy)
99 _RL diffKh, diffK4
100 _RL KappaR(1-OLx:sNx+OLx,1-OLy:sNy+OLy)
101 _RL TracerN(1-OLx:sNx+OLx,1-OLy:sNy+OLy,Nr,nSx,nSy)
102 _RL TracAB (1-OLx:sNx+OLx,1-OLy:sNy+OLy,Nr,nSx,nSy)
103 _RL deltaTLev(Nr)
104 INTEGER tracerIdentity
105 INTEGER advectionScheme, vertAdvecScheme
106 LOGICAL calcAdvection
107 LOGICAL implicitAdvection, applyAB_onTracer
108 LOGICAL trUseGMRedi, trUseKPP
109 _RL myTime
110 INTEGER myIter, myThid
111
112 C !OUTPUT PARAMETERS: ==================================================
113 C gTracer :: tendency array
114 C fVerT :: 2 1/2D arrays for vertical advective flux
115 _RL gTracer(1-OLx:sNx+OLx,1-OLy:sNy+OLy,Nr,nSx,nSy)
116 _RL fVerT (1-OLx:sNx+OLx,1-OLy:sNy+OLy,2)
117
118 C !LOCAL VARIABLES: ====================================================
119 C i,j :: loop indices
120 C df4 :: used for storing del^2 T for bi-harmonic term
121 C fZon :: zonal flux
122 C fMer :: meridional flux
123 C af :: advective flux
124 C df :: diffusive flux
125 C localT :: local copy of tracer field
126 C locABT :: local copy of (AB-extrapolated) tracer field
127 #ifdef ALLOW_DIAGNOSTICS
128 CHARACTER*8 diagName
129 CHARACTER*4 GAD_DIAG_SUFX, diagSufx
130 EXTERNAL GAD_DIAG_SUFX
131 #endif
132 INTEGER i,j
133 _RL df4 (1-OLx:sNx+OLx,1-OLy:sNy+OLy)
134 _RL fZon (1-OLx:sNx+OLx,1-OLy:sNy+OLy)
135 _RL fMer (1-OLx:sNx+OLx,1-OLy:sNy+OLy)
136 _RL af (1-OLx:sNx+OLx,1-OLy:sNy+OLy)
137 _RL df (1-OLx:sNx+OLx,1-OLy:sNy+OLy)
138 _RL localT(1-OLx:sNx+OLx,1-OLy:sNy+OLy)
139 _RL locABT(1-OLx:sNx+OLx,1-OLy:sNy+OLy)
140 _RL advFac, rAdvFac
141 #ifdef GAD_SMOLARKIEWICZ_HACK
142 _RL outFlux, trac, fac, gTrFac
143 #endif
144 CEOP
145
146 #ifdef ALLOW_AUTODIFF_TAMC
147 C-- only the kUp part of fverT is set in this subroutine
148 C-- the kDown is still required
149 fVerT(1,1,kDown) = fVerT(1,1,kDown)
150 #endif
151
152 #ifdef ALLOW_DIAGNOSTICS
153 C-- Set diagnostic suffix for the current tracer
154 IF ( useDiagnostics ) THEN
155 diagSufx = GAD_DIAG_SUFX( tracerIdentity, myThid )
156 ENDIF
157 #endif
158
159 advFac = 0. _d 0
160 IF (calcAdvection) advFac = 1. _d 0
161 rAdvFac = rkSign*advFac
162 IF (implicitAdvection) rAdvFac = 0. _d 0
163
164 DO j=1-OLy,sNy+OLy
165 DO i=1-OLx,sNx+OLx
166 fZon(i,j) = 0. _d 0
167 fMer(i,j) = 0. _d 0
168 fVerT(i,j,kUp) = 0. _d 0
169 df(i,j) = 0. _d 0
170 df4(i,j) = 0. _d 0
171 ENDDO
172 ENDDO
173
174 C-- Make local copy of tracer array
175 IF ( applyAB_onTracer ) THEN
176 DO j=1-OLy,sNy+OLy
177 DO i=1-OLx,sNx+OLx
178 localT(i,j)=TracerN(i,j,k,bi,bj)
179 locABT(i,j)= TracAB(i,j,k,bi,bj)
180 ENDDO
181 ENDDO
182 ELSE
183 DO j=1-OLy,sNy+OLy
184 DO i=1-OLx,sNx+OLx
185 localT(i,j)= TracAB(i,j,k,bi,bj)
186 locABT(i,j)= TracAB(i,j,k,bi,bj)
187 ENDDO
188 ENDDO
189 ENDIF
190
191 C-- Unless we have already calculated the advection terms we initialize
192 C the tendency to zero.
193 C <== now done earlier at the beginning of thermodynamics.
194 c IF (calcAdvection) THEN
195 c DO j=1-Oly,sNy+Oly
196 c DO i=1-Olx,sNx+Olx
197 c gTracer(i,j,k,bi,bj)=0. _d 0
198 c ENDDO
199 c ENDDO
200 c ENDIF
201
202 C-- Pre-calculate del^2 T if bi-harmonic coefficient is non-zero
203 IF (diffK4 .NE. 0.) THEN
204 CALL GAD_GRAD_X(bi,bj,k,xA,localT,fZon,myThid)
205 CALL GAD_GRAD_Y(bi,bj,k,yA,localT,fMer,myThid)
206 CALL GAD_DEL2(bi,bj,k,fZon,fMer,df4,myThid)
207 ENDIF
208
209 C-- Initialize net flux in X direction
210 DO j=1-Oly,sNy+Oly
211 DO i=1-Olx,sNx+Olx
212 fZon(i,j) = 0. _d 0
213 ENDDO
214 ENDDO
215
216 C- Advective flux in X
217 IF (calcAdvection) THEN
218 IF (advectionScheme.EQ.ENUM_CENTERED_2ND) THEN
219 CALL GAD_C2_ADV_X(bi,bj,k,uTrans,locABT,af,myThid)
220 ELSEIF ( advectionScheme.EQ.ENUM_UPWIND_1RST
221 & .OR. advectionScheme.EQ.ENUM_DST2 ) THEN
222 CALL GAD_DST2U1_ADV_X( bi,bj,k, advectionScheme, .TRUE.,
223 I deltaTLev(k), uTrans, uFld, locABT,
224 O af, myThid )
225 ELSEIF (advectionScheme.EQ.ENUM_FLUX_LIMIT) THEN
226 CALL GAD_FLUXLIMIT_ADV_X( bi,bj,k, .TRUE., deltaTLev(k),
227 I uTrans, uFld, maskW(1-Olx,1-Oly,k,bi,bj), locABT,
228 O af, myThid )
229 ELSEIF (advectionScheme.EQ.ENUM_UPWIND_3RD ) THEN
230 CALL GAD_U3_ADV_X(bi,bj,k,uTrans,locABT,af,myThid)
231 ELSEIF (advectionScheme.EQ.ENUM_CENTERED_4TH) THEN
232 CALL GAD_C4_ADV_X(bi,bj,k,uTrans,locABT,af,myThid)
233 ELSEIF (advectionScheme.EQ.ENUM_DST3 ) THEN
234 CALL GAD_DST3_ADV_X( bi,bj,k, .TRUE., deltaTLev(k),
235 I uTrans, uFld, maskW(1-Olx,1-Oly,k,bi,bj), locABT,
236 O af, myThid )
237 ELSEIF (advectionScheme.EQ.ENUM_DST3_FLUX_LIMIT ) THEN
238 IF ( inAdMode ) THEN
239 cph This block is to trick the adjoint:
240 cph IF inAdExact=.FALSE., we want to use DST3
241 cph with limiters in forward, but without limiters in reverse.
242 CALL GAD_DST3_ADV_X( bi,bj,k, .TRUE., deltaTLev(k),
243 I uTrans, uFld, maskW(1-Olx,1-Oly,k,bi,bj), locABT,
244 O af, myThid )
245 ELSE
246 CALL GAD_DST3FL_ADV_X( bi,bj,k, .TRUE., deltaTLev(k),
247 I uTrans, uFld, maskW(1-Olx,1-Oly,k,bi,bj), locABT,
248 O af, myThid )
249 ENDIF
250 ELSEIF (advectionScheme.EQ.ENUM_OS7MP ) THEN
251 CALL GAD_OS7MP_ADV_X( bi,bj,k, .TRUE., deltaTLev(k),
252 I uTrans, uFld, maskW(1-Olx,1-Oly,k,bi,bj), locABT,
253 O af, myThid )
254 ELSE
255 STOP 'GAD_CALC_RHS: Bad advectionScheme (X)'
256 ENDIF
257 DO j=1-Oly,sNy+Oly
258 DO i=1-Olx,sNx+Olx
259 fZon(i,j) = fZon(i,j) + af(i,j)
260 ENDDO
261 ENDDO
262 #ifdef ALLOW_DIAGNOSTICS
263 IF ( useDiagnostics ) THEN
264 diagName = 'ADVx'//diagSufx
265 CALL DIAGNOSTICS_FILL(af,diagName, k,1, 2,bi,bj, myThid)
266 ENDIF
267 #endif
268 ENDIF
269
270 C- Diffusive flux in X
271 IF (diffKh.NE.0.) THEN
272 CALL GAD_DIFF_X(bi,bj,k,xA,diffKh,localT,df,myThid)
273 ELSE
274 DO j=1-Oly,sNy+Oly
275 DO i=1-Olx,sNx+Olx
276 df(i,j) = 0. _d 0
277 ENDDO
278 ENDDO
279 ENDIF
280
281 C- Add bi-harmonic diffusive flux in X
282 IF (diffK4 .NE. 0.) THEN
283 CALL GAD_BIHARM_X(bi,bj,k,xA,df4,diffK4,df,myThid)
284 ENDIF
285
286 #ifdef ALLOW_GMREDI
287 C- GM/Redi flux in X
288 IF ( trUseGMRedi ) THEN
289 C *note* should update GMREDI_XTRANSPORT to set df *aja*
290 IF ( applyAB_onTracer ) THEN
291 CALL GMREDI_XTRANSPORT(
292 I iMin,iMax,jMin,jMax,bi,bj,k,
293 I xA,TracerN,tracerIdentity,
294 U df,
295 I myThid)
296 ELSE
297 CALL GMREDI_XTRANSPORT(
298 I iMin,iMax,jMin,jMax,bi,bj,k,
299 I xA,TracAB, tracerIdentity,
300 U df,
301 I myThid)
302 ENDIF
303 ENDIF
304 #endif
305 C anelastic: advect.fluxes are scaled by rhoFac but hor.diff. flx are not
306 DO j=1-Oly,sNy+Oly
307 DO i=1-Olx,sNx+Olx
308 fZon(i,j) = fZon(i,j) + df(i,j)*rhoFacC(k)
309 ENDDO
310 ENDDO
311
312 #ifdef ALLOW_DIAGNOSTICS
313 C- Diagnostics of Tracer flux in X dir (mainly Diffusive term),
314 C excluding advective terms:
315 IF ( useDiagnostics .AND.
316 & (diffKh.NE.0. .OR. diffK4 .NE.0. .OR. trUseGMRedi) ) THEN
317 diagName = 'DFxE'//diagSufx
318 CALL DIAGNOSTICS_FILL(df,diagName, k,1, 2,bi,bj, myThid)
319 ENDIF
320 #endif
321
322 C-- Initialize net flux in Y direction
323 DO j=1-Oly,sNy+Oly
324 DO i=1-Olx,sNx+Olx
325 fMer(i,j) = 0. _d 0
326 ENDDO
327 ENDDO
328
329 C- Advective flux in Y
330 IF (calcAdvection) THEN
331 IF (advectionScheme.EQ.ENUM_CENTERED_2ND) THEN
332 CALL GAD_C2_ADV_Y(bi,bj,k,vTrans,locABT,af,myThid)
333 ELSEIF ( advectionScheme.EQ.ENUM_UPWIND_1RST
334 & .OR. advectionScheme.EQ.ENUM_DST2 ) THEN
335 CALL GAD_DST2U1_ADV_Y( bi,bj,k, advectionScheme, .TRUE.,
336 I deltaTLev(k), vTrans, vFld, locABT,
337 O af, myThid )
338 ELSEIF (advectionScheme.EQ.ENUM_FLUX_LIMIT) THEN
339 CALL GAD_FLUXLIMIT_ADV_Y( bi,bj,k, .TRUE., deltaTLev(k),
340 I vTrans, vFld, maskS(1-Olx,1-Oly,k,bi,bj), locABT,
341 O af, myThid )
342 ELSEIF (advectionScheme.EQ.ENUM_UPWIND_3RD ) THEN
343 CALL GAD_U3_ADV_Y(bi,bj,k,vTrans,locABT,af,myThid)
344 ELSEIF (advectionScheme.EQ.ENUM_CENTERED_4TH) THEN
345 CALL GAD_C4_ADV_Y(bi,bj,k,vTrans,locABT,af,myThid)
346 ELSEIF (advectionScheme.EQ.ENUM_DST3 ) THEN
347 CALL GAD_DST3_ADV_Y( bi,bj,k, .TRUE., deltaTLev(k),
348 I vTrans, vFld, maskS(1-Olx,1-Oly,k,bi,bj), locABT,
349 O af, myThid )
350 ELSEIF (advectionScheme.EQ.ENUM_DST3_FLUX_LIMIT ) THEN
351 IF ( inAdMode ) THEN
352 cph This block is to trick the adjoint:
353 cph IF inAdExact=.FALSE., we want to use DST3
354 cph with limiters in forward, but without limiters in reverse.
355 CALL GAD_DST3_ADV_Y( bi,bj,k, .TRUE., deltaTLev(k),
356 I vTrans, vFld, maskS(1-Olx,1-Oly,k,bi,bj), locABT,
357 O af, myThid )
358 ELSE
359 CALL GAD_DST3FL_ADV_Y( bi,bj,k, .TRUE., deltaTLev(k),
360 I vTrans, vFld, maskS(1-Olx,1-Oly,k,bi,bj), locABT,
361 O af, myThid )
362 ENDIF
363 ELSEIF (advectionScheme.EQ.ENUM_OS7MP ) THEN
364 CALL GAD_OS7MP_ADV_Y( bi,bj,k, .TRUE., deltaTLev(k),
365 I vTrans, vFld, maskS(1-Olx,1-Oly,k,bi,bj), locABT,
366 O af, myThid )
367 ELSE
368 STOP 'GAD_CALC_RHS: Bad advectionScheme (Y)'
369 ENDIF
370 DO j=1-Oly,sNy+Oly
371 DO i=1-Olx,sNx+Olx
372 fMer(i,j) = fMer(i,j) + af(i,j)
373 ENDDO
374 ENDDO
375 #ifdef ALLOW_DIAGNOSTICS
376 IF ( useDiagnostics ) THEN
377 diagName = 'ADVy'//diagSufx
378 CALL DIAGNOSTICS_FILL(af,diagName, k,1, 2,bi,bj, myThid)
379 ENDIF
380 #endif
381 ENDIF
382
383 C- Diffusive flux in Y
384 IF (diffKh.NE.0.) THEN
385 CALL GAD_DIFF_Y(bi,bj,k,yA,diffKh,localT,df,myThid)
386 ELSE
387 DO j=1-Oly,sNy+Oly
388 DO i=1-Olx,sNx+Olx
389 df(i,j) = 0. _d 0
390 ENDDO
391 ENDDO
392 ENDIF
393
394 C- Add bi-harmonic flux in Y
395 IF (diffK4 .NE. 0.) THEN
396 CALL GAD_BIHARM_Y(bi,bj,k,yA,df4,diffK4,df,myThid)
397 ENDIF
398
399 #ifdef ALLOW_GMREDI
400 C- GM/Redi flux in Y
401 IF ( trUseGMRedi ) THEN
402 C *note* should update GMREDI_YTRANSPORT to set df *aja*
403 IF ( applyAB_onTracer ) THEN
404 CALL GMREDI_YTRANSPORT(
405 I iMin,iMax,jMin,jMax,bi,bj,k,
406 I yA,TracerN,tracerIdentity,
407 U df,
408 I myThid)
409 ELSE
410 CALL GMREDI_YTRANSPORT(
411 I iMin,iMax,jMin,jMax,bi,bj,k,
412 I yA,TracAB, tracerIdentity,
413 U df,
414 I myThid)
415 ENDIF
416 ENDIF
417 #endif
418 C anelastic: advect.fluxes are scaled by rhoFac but hor.diff. flx are not
419 DO j=1-Oly,sNy+Oly
420 DO i=1-Olx,sNx+Olx
421 fMer(i,j) = fMer(i,j) + df(i,j)*rhoFacC(k)
422 ENDDO
423 ENDDO
424
425 #ifdef ALLOW_DIAGNOSTICS
426 C- Diagnostics of Tracer flux in Y dir (mainly Diffusive terms),
427 C excluding advective terms:
428 IF ( useDiagnostics .AND.
429 & (diffKh.NE.0. .OR. diffK4 .NE.0. .OR. trUseGMRedi) ) THEN
430 diagName = 'DFyE'//diagSufx
431 CALL DIAGNOSTICS_FILL(df,diagName, k,1, 2,bi,bj, myThid)
432 ENDIF
433 #endif
434
435 C-- Compute vertical flux fVerT(kUp) at interface k (between k-1 & k):
436 C- Advective flux in R
437 #ifdef ALLOW_AIM
438 C- a hack to prevent Water-Vapor vert.transport into the stratospheric level Nr
439 IF (calcAdvection .AND. .NOT.implicitAdvection .AND. k.GE.2 .AND.
440 & (.NOT.useAIM .OR.tracerIdentity.NE.GAD_SALINITY .OR.k.LT.Nr)
441 & ) THEN
442 #else
443 IF (calcAdvection .AND. .NOT.implicitAdvection .AND. k.GE.2) THEN
444 #endif
445 C- Compute vertical advective flux in the interior:
446 IF (vertAdvecScheme.EQ.ENUM_CENTERED_2ND) THEN
447 CALL GAD_C2_ADV_R(bi,bj,k,rTrans,TracAB,af,myThid)
448 ELSEIF ( vertAdvecScheme.EQ.ENUM_UPWIND_1RST
449 & .OR. vertAdvecScheme.EQ.ENUM_DST2 ) THEN
450 CALL GAD_DST2U1_ADV_R( bi,bj,k, vertAdvecScheme,
451 I deltaTLev(k),rTrans,wFld,TracAB(1-Olx,1-Oly,1,bi,bj),
452 O af, myThid )
453 ELSEIF (vertAdvecScheme.EQ.ENUM_FLUX_LIMIT) THEN
454 CALL GAD_FLUXLIMIT_ADV_R( bi,bj,k,
455 I deltaTLev(k),rTrans,wFld,TracAB(1-Olx,1-Oly,1,bi,bj),
456 O af, myThid )
457 ELSEIF (vertAdvecScheme.EQ.ENUM_UPWIND_3RD ) THEN
458 CALL GAD_U3_ADV_R(bi,bj,k,rTrans,TracAB,af,myThid)
459 ELSEIF (vertAdvecScheme.EQ.ENUM_CENTERED_4TH) THEN
460 CALL GAD_C4_ADV_R(bi,bj,k,rTrans,TracAB,af,myThid)
461 ELSEIF (vertAdvecScheme.EQ.ENUM_DST3 ) THEN
462 CALL GAD_DST3_ADV_R( bi,bj,k,
463 I deltaTLev(k),rTrans,wFld,TracAB(1-Olx,1-Oly,1,bi,bj),
464 O af, myThid )
465 ELSEIF (vertAdvecScheme.EQ.ENUM_DST3_FLUX_LIMIT ) THEN
466 cph This block is to trick the adjoint:
467 cph IF inAdExact=.FALSE., we want to use DST3
468 cph with limiters in forward, but without limiters in reverse.
469 IF ( inAdMode ) THEN
470 CALL GAD_DST3_ADV_R( bi,bj,k,
471 I deltaTLev(k),rTrans,wFld,TracAB(1-Olx,1-Oly,1,bi,bj),
472 O af, myThid )
473 ELSE
474 CALL GAD_DST3FL_ADV_R( bi,bj,k,
475 I deltaTLev(k),rTrans,wFld,TracAB(1-Olx,1-Oly,1,bi,bj),
476 O af, myThid )
477 ENDIF
478 ELSEIF (vertAdvecScheme.EQ.ENUM_OS7MP ) THEN
479 CALL GAD_OS7MP_ADV_R( bi,bj,k,
480 I deltaTLev(k),rTrans,wFld,TracAB(1-Olx,1-Oly,1,bi,bj),
481 O af, myThid )
482 ELSE
483 STOP 'GAD_CALC_RHS: Bad vertAdvecScheme (R)'
484 ENDIF
485 C- add the advective flux to fVerT
486 DO j=1-Oly,sNy+Oly
487 DO i=1-Olx,sNx+Olx
488 fVerT(i,j,kUp) = fVerT(i,j,kUp) + af(i,j)
489 ENDDO
490 ENDDO
491 #ifdef ALLOW_DIAGNOSTICS
492 IF ( useDiagnostics ) THEN
493 diagName = 'ADVr'//diagSufx
494 CALL DIAGNOSTICS_FILL(af,diagName, k,1, 2,bi,bj, myThid)
495 C- note: needs to explicitly increment the counter since DIAGNOSTICS_FILL
496 C does it only if k=1 (never the case here)
497 IF ( k.EQ.2 ) CALL DIAGNOSTICS_COUNT(diagName,bi,bj,myThid)
498 ENDIF
499 #endif
500 ENDIF
501
502 C- Diffusive flux in R
503 C Note: For K=1 then KM1=1 and this gives a dT/dr = 0 upper
504 C boundary condition.
505 IF (implicitDiffusion) THEN
506 DO j=1-Oly,sNy+Oly
507 DO i=1-Olx,sNx+Olx
508 df(i,j) = 0. _d 0
509 ENDDO
510 ENDDO
511 ELSE
512 IF ( applyAB_onTracer ) THEN
513 CALL GAD_DIFF_R(bi,bj,k,KappaR,TracerN,df,myThid)
514 ELSE
515 CALL GAD_DIFF_R(bi,bj,k,KappaR,TracAB, df,myThid)
516 ENDIF
517 ENDIF
518
519 #ifdef ALLOW_GMREDI
520 C- GM/Redi flux in R
521 IF ( trUseGMRedi ) THEN
522 C *note* should update GMREDI_RTRANSPORT to set df *aja*
523 IF ( applyAB_onTracer ) THEN
524 CALL GMREDI_RTRANSPORT(
525 I iMin,iMax,jMin,jMax,bi,bj,k,
526 I TracerN,tracerIdentity,
527 U df,
528 I myThid)
529 ELSE
530 CALL GMREDI_RTRANSPORT(
531 I iMin,iMax,jMin,jMax,bi,bj,k,
532 I TracAB, tracerIdentity,
533 U df,
534 I myThid)
535 ENDIF
536 ENDIF
537 #endif
538
539 DO j=1-Oly,sNy+Oly
540 DO i=1-Olx,sNx+Olx
541 fVerT(i,j,kUp) = fVerT(i,j,kUp) + df(i,j)*maskUp(i,j)
542 ENDDO
543 ENDDO
544
545 #ifdef ALLOW_DIAGNOSTICS
546 C- Diagnostics of Tracer flux in R dir (mainly Diffusive terms),
547 C Explicit terms only & excluding advective terms:
548 IF ( useDiagnostics .AND.
549 & (.NOT.implicitDiffusion .OR. trUseGMRedi) ) THEN
550 diagName = 'DFrE'//diagSufx
551 CALL DIAGNOSTICS_FILL(df,diagName, k,1, 2,bi,bj, myThid)
552 ENDIF
553 #endif
554
555 #ifdef ALLOW_KPP
556 C- Set non local KPP transport term (ghat):
557 IF ( trUseKPP .AND. k.GE.2 ) THEN
558 DO j=1-Oly,sNy+Oly
559 DO i=1-Olx,sNx+Olx
560 df(i,j) = 0. _d 0
561 ENDDO
562 ENDDO
563 IF (tracerIdentity.EQ.GAD_TEMPERATURE) THEN
564 CALL KPP_TRANSPORT_T(
565 I iMin,iMax,jMin,jMax,bi,bj,k,km1,
566 O df,
567 I myTime, myIter, myThid )
568 ELSEIF (tracerIdentity.EQ.GAD_SALINITY) THEN
569 CALL KPP_TRANSPORT_S(
570 I iMin,iMax,jMin,jMax,bi,bj,k,km1,
571 O df,
572 I myTime, myIter, myThid )
573 #ifdef ALLOW_PTRACERS
574 ELSEIF (tracerIdentity .GE. GAD_TR1) THEN
575 CALL KPP_TRANSPORT_PTR(
576 I iMin,iMax,jMin,jMax,bi,bj,k,km1,
577 I tracerIdentity-GAD_TR1+1,
578 O df,
579 I myTime, myIter, myThid )
580 #endif
581 ELSE
582 PRINT*,'invalid tracer indentity: ', tracerIdentity
583 STOP 'GAD_CALC_RHS: Ooops'
584 ENDIF
585 DO j=1-Oly,sNy+Oly
586 DO i=1-Olx,sNx+Olx
587 fVerT(i,j,kUp) = fVerT(i,j,kUp)
588 & + df(i,j)*maskUp(i,j)*rhoFacF(k)
589 ENDDO
590 ENDDO
591 ENDIF
592 #endif
593
594 #ifdef GAD_SMOLARKIEWICZ_HACK
595 coj Hack to make redi (and everything else in this s/r) positive
596 coj (see Smolarkiewicz MWR 1989 and Bott MWR 1989).
597 coj Only works if 'down' is k+1 and k loop in thermodynamics is k=Nr,1,-1
598 coj
599 coj Apply to all tracers except temperature
600 IF (tracerIdentity.NE.GAD_TEMPERATURE .AND.
601 & tracerIdentity.NE.GAD_SALINITY) THEN
602 DO j=1-Oly,sNy+Oly-1
603 DO i=1-Olx,sNx+Olx-1
604 coj Add outgoing fluxes
605 outFlux=deltaTLev(k)*
606 & _recip_hFacC(i,j,k,bi,bj)*recip_drF(k)
607 & *recip_rA(i,j,bi,bj)*recip_deepFac2C(k)*recip_rhoFacC(k)
608 & *( MAX(0. _d 0,fZon(i+1,j)) + MAX(0. _d 0,-fZon(i,j))
609 & +MAX(0. _d 0,fMer(i,j+1)) + MAX(0. _d 0,-fMer(i,j))
610 & +MAX(0. _d 0,fVerT(i,j,kDown)*rkSign)
611 & +MAX(0. _d 0,-fVerT(i,j,kUp)*rkSign)
612 & )
613 IF ( applyAB_onTracer ) THEN
614 trac=TracerN(i,j,k,bi,bj)
615 ELSE
616 trac=TracAB(i,j,k,bi,bj)
617 ENDIF
618 coj If they would reduce tracer by a fraction of more than
619 coj SmolarkiewiczMaxFrac, scale them down
620 IF (outFlux.GT.0. _d 0 .AND.
621 & outFlux.GT.SmolarkiewiczMaxFrac*trac) THEN
622 coj If tracer is already negative, scale flux to zero
623 fac = MAX(0. _d 0,SmolarkiewiczMaxFrac*trac/outFlux)
624
625 IF (fZon(i+1,j).GT.0. _d 0) fZon(i+1,j)=fac*fZon(i+1,j)
626 IF (-fZon(i,j) .GT.0. _d 0) fZon(i,j) =fac*fZon(i,j)
627 IF (fMer(i,j+1).GT.0. _d 0) fMer(i,j+1)=fac*fMer(i,j+1)
628 IF (-fMer(i,j) .GT.0. _d 0) fMer(i,j) =fac*fMer(i,j)
629 IF (-fVerT(i,j,kUp)*rkSign .GT.0. _d 0)
630 & fVerT(i,j,kUp)=fac*fVerT(i,j,kUp)
631
632 IF (k.LT.Nr .AND. fVerT(i,j,kDown)*rkSign.GT.0. _d 0) THEN
633 coj Down flux is special: it has already been applied in lower layer,
634 coj so we have to readjust this.
635 coj Note: for k+1, gTracer is now the updated tracer, not the tendency!
636 coj thus it has an extra factor deltaTLev(k+1)
637 gTrFac=deltaTLev(k+1)
638 coj Other factors that have been applied to gTracer since the last call:
639 #ifdef NONLIN_FRSURF
640 IF (nonlinFreeSurf.GT.0) THEN
641 IF (select_rStar.GT.0) THEN
642 #ifndef DISABLE_RSTAR_CODE
643 gTrFac = gTrFac/rStarExpC(i,j,bi,bj)
644 #endif /* DISABLE_RSTAR_CODE */
645 ENDIF
646 ENDIF
647 #endif /* NONLIN_FRSURF */
648 coj Now: undo down flux, ...
649 gTracer(i,j,k+1,bi,bj)=gTracer(i,j,k+1,bi,bj)
650 & +gTrFac
651 & *_recip_hFacC(i,j,k+1,bi,bj)*recip_drF(k+1)
652 & *recip_rA(i,j,bi,bj)*recip_deepFac2C(k+1)
653 & *recip_rhoFacC(k+1)
654 & *( -fVerT(i,j,kDown)*rkSign )
655 coj ... scale ...
656 fVerT(i,j,kDown)=fac*fVerT(i,j,kDown)
657 coj ... and reapply
658 gTracer(i,j,k+1,bi,bj)=gTracer(i,j,k+1,bi,bj)
659 & +gTrFac
660 & *_recip_hFacC(i,j,k+1,bi,bj)*recip_drF(k+1)
661 & *recip_rA(i,j,bi,bj)*recip_deepFac2C(k+1)
662 & *recip_rhoFacC(k+1)
663 & *( fVerT(i,j,kDown)*rkSign )
664 ENDIF
665
666 ENDIF
667 ENDDO
668 ENDDO
669 ENDIF
670 #endif
671
672 C-- Divergence of fluxes
673 C Anelastic: scale vertical fluxes by rhoFac and leave Horizontal fluxes unchanged
674 DO j=1-Oly,sNy+Oly-1
675 DO i=1-Olx,sNx+Olx-1
676 gTracer(i,j,k,bi,bj)=gTracer(i,j,k,bi,bj)
677 & -_recip_hFacC(i,j,k,bi,bj)*recip_drF(k)
678 & *recip_rA(i,j,bi,bj)*recip_deepFac2C(k)*recip_rhoFacC(k)
679 & *( (fZon(i+1,j)-fZon(i,j))
680 & +(fMer(i,j+1)-fMer(i,j))
681 & +(fVerT(i,j,kDown)-fVerT(i,j,kUp))*rkSign
682 & -localT(i,j)*( (uTrans(i+1,j)-uTrans(i,j))
683 & +(vTrans(i,j+1)-vTrans(i,j))
684 & +(rTransKp1(i,j)-rTrans(i,j))*rAdvFac
685 & )*advFac
686 & )
687 ENDDO
688 ENDDO
689
690 #ifdef ALLOW_DEBUG
691 IF ( debugLevel .GE. debLevB
692 & .AND. tracerIdentity.EQ.GAD_TEMPERATURE
693 & .AND. k.EQ.2 .AND. myIter.EQ.1+nIter0
694 & .AND. nPx.EQ.1 .AND. nPy.EQ.1
695 & .AND. useCubedSphereExchange ) THEN
696 CALL DEBUG_CS_CORNER_UV( ' fZon,fMer from GAD_CALC_RHS',
697 & fZon,fMer, k, standardMessageUnit,bi,bj,myThid )
698 ENDIF
699 #endif /* ALLOW_DEBUG */
700
701 RETURN
702 END

  ViewVC Help
Powered by ViewVC 1.1.22