/[MITgcm]/MITgcm/pkg/ptracers/ptracers_integrate.F
ViewVC logotype

Contents of /MITgcm/pkg/ptracers/ptracers_integrate.F

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


Revision 1.66 - (show annotations) (download)
Sun Oct 9 18:14:44 2016 UTC (7 years, 8 months ago) by jmc
Branch: MAIN
CVS Tags: checkpoint66g, checkpoint66f, checkpoint66e, checkpoint66d, checkpoint66c, checkpoint66b, checkpoint66a, checkpoint66o, checkpoint66n, checkpoint66m, checkpoint66l, checkpoint66k, checkpoint66j, checkpoint66i, checkpoint66h, HEAD
Changes since 1.65: +4 -2 lines
- with INCLUDE_IMPLVERTADV_CODE defined, also call GAD_IMPLICIT_R
  (instead of IMPLDIFF) when just implicitDiffusion is used (even without
  PTRACERS_ImplVertAdv).

1 C $Header: /u/gcmpack/MITgcm/pkg/ptracers/ptracers_integrate.F,v 1.65 2015/06/02 20:09:22 gforget Exp $
2 C $Name: $
3
4 #include "PTRACERS_OPTIONS.h"
5 #ifdef ALLOW_AUTODIFF
6 # include "AUTODIFF_OPTIONS.h"
7 #endif
8
9 CBOP
10 C !ROUTINE: PTRACERS_INTEGRATE
11
12 C !INTERFACE: ==========================================================
13 SUBROUTINE PTRACERS_INTEGRATE(
14 I bi, bj, recip_hFac,
15 I uFld, vFld, wFld,
16 U KappaRk,
17 I myTime, myIter, myThid )
18
19 C !DESCRIPTION:
20 C Calculates tendency for passive tracers and integrates forward in
21 C time. The tracer array is updated here while adjustments (filters,
22 C conv.adjustment) are applied later, in S/R TRACERS_CORRECTION_STEP
23
24 C !USES: ===============================================================
25 #include "PTRACERS_MOD.h"
26 IMPLICIT NONE
27 #include "SIZE.h"
28 #include "EEPARAMS.h"
29 #include "PARAMS.h"
30 #include "GRID.h"
31 #ifdef ALLOW_LONGSTEP
32 #include "LONGSTEP_PARAMS.h"
33 #endif
34 #include "PTRACERS_SIZE.h"
35 #include "PTRACERS_PARAMS.h"
36 #include "PTRACERS_START.h"
37 #include "PTRACERS_FIELDS.h"
38 #include "GAD.h"
39 #ifdef ALLOW_AUTODIFF_TAMC
40 # include "tamc.h"
41 # include "tamc_keys.h"
42 #endif
43
44 C !INPUT PARAMETERS: ===================================================
45 C bi, bj :: tile indices
46 C recip_hFac :: reciprocal of cell open-depth factor (@ next iter)
47 C uFld, vFld, wFld :: Local copy of velocity field (3 components)
48 C KappaRk :: vertical diffusion used for one passive tracer
49 C myTime :: model time
50 C myIter :: time-step number
51 C myThid :: thread number
52 INTEGER bi, bj
53 _RS recip_hFac(1-OLx:sNx+OLx,1-OLy:sNy+OLy,Nr)
54 _RL uFld (1-OLx:sNx+OLx,1-OLy:sNy+OLy,Nr)
55 _RL vFld (1-OLx:sNx+OLx,1-OLy:sNy+OLy,Nr)
56 _RL wFld (1-OLx:sNx+OLx,1-OLy:sNy+OLy,Nr)
57 _RL KappaRk (1-OLx:sNx+OLx,1-OLy:sNy+OLy,Nr)
58 _RL myTime
59 INTEGER myIter
60 INTEGER myThid
61
62 C !OUTPUT PARAMETERS: ==================================================
63 C none
64
65 #ifdef ALLOW_PTRACERS
66 #ifdef ALLOW_DIAGNOSTICS
67 C !FUNCTIONS:
68 LOGICAL DIAGNOSTICS_IS_ON
69 EXTERNAL DIAGNOSTICS_IS_ON
70 CHARACTER*4 GAD_DIAG_SUFX
71 EXTERNAL GAD_DIAG_SUFX
72 #endif /* ALLOW_DIAGNOSTICS */
73
74 C !LOCAL VARIABLES: ====================================================
75 C iTracer :: tracer index
76 C iMin, iMax :: 1rst index loop range
77 C jMin, jMax :: 2nd index loop range
78 C k :: vertical level number
79 C kUp,kDown :: toggle indices for even/odd level fluxes
80 C kM1 :: =min(1,k-1)
81 C GAD_TR :: passive tracer id (GAD_TR1+iTracer-1)
82 C xA :: face area at U points in level k
83 C yA :: face area at V points in level k
84 C maskUp :: mask for vertical transport
85 C uTrans :: zonal transport in level k
86 C vTrans :: meridional transport in level k
87 C rTrans :: vertical volume transport at interface k
88 C rTransKp :: vertical volume transport at interface k+1
89 C fZon :: passive tracer zonal flux
90 C fMer :: passive tracer meridional flux
91 C fVer :: passive tracer vertical flux
92 C gTracer :: passive tracer tendency
93 C gTrForc :: passive tracer forcing tendency
94 C gTr_AB :: Adams-Bashforth tracer tendency increment
95 INTEGER iTracer
96 INTEGER iMin,iMax,jMin,jMax
97 INTEGER i, j, k
98 INTEGER kUp, kDown, kM1
99 INTEGER GAD_TR
100 _RS xA (1-OLx:sNx+OLx,1-OLy:sNy+OLy)
101 _RS yA (1-OLx:sNx+OLx,1-OLy:sNy+OLy)
102 _RS maskUp (1-OLx:sNx+OLx,1-OLy:sNy+OLy)
103 _RL uTrans (1-OLx:sNx+OLx,1-OLy:sNy+OLy)
104 _RL vTrans (1-OLx:sNx+OLx,1-OLy:sNy+OLy)
105 _RL rTrans (1-OLx:sNx+OLx,1-OLy:sNy+OLy)
106 _RL rTransKp(1-OLx:sNx+OLx,1-OLy:sNy+OLy)
107 _RL fZon (1-OLx:sNx+OLx,1-OLy:sNy+OLy)
108 _RL fMer (1-OLx:sNx+OLx,1-OLy:sNy+OLy)
109 _RL fVer (1-OLx:sNx+OLx,1-OLy:sNy+OLy,2)
110 _RL gTracer (1-OLx:sNx+OLx,1-OLy:sNy+OLy,Nr)
111 _RL gTrForc (1-OLx:sNx+OLx,1-OLy:sNy+OLy)
112 _RL gTr_AB (1-OLx:sNx+OLx,1-OLy:sNy+OLy)
113 LOGICAL calcAdvection
114 INTEGER iterNb
115 _RL dummy(Nr)
116 #ifdef ALLOW_DIAGNOSTICS
117 CHARACTER*8 diagName
118 CHARACTER*4 diagSufx
119 LOGICAL diagForcing, diagAB_tend
120 #endif /* ALLOW_DIAGNOSTICS */
121 CEOP
122
123 C---+----1----+----2----+----3----+----4----+----5----+----6----+----7-|--+----|
124
125 C- Compute iter at beginning of ptracer time step
126 #ifdef ALLOW_LONGSTEP
127 iterNb = myIter - LS_nIter + 1
128 IF (LS_whenToSample.GE.2) iterNb = myIter - LS_nIter
129 #else
130 iterNb = myIter
131 IF (staggerTimeStep) iterNb = myIter - 1
132 #endif
133
134 C- Loop ranges for daughter routines
135 c iMin = 1
136 c iMax = sNx
137 c jMin = 1
138 c jMax = sNy
139 C Regarding model dynamics, only needs to get correct tracer tendency
140 C (gTracer) in tile interior (1:sNx,1:sNy);
141 C However, for some diagnostics, we may want to get valid tendency
142 C extended over 1 point in tile halo region (0:sNx+1,0:sNy=1).
143 iMin = 0
144 iMax = sNx+1
145 jMin = 0
146 jMax = sNy+1
147
148 C-- Loop over tracers
149 DO iTracer=1,PTRACERS_numInUse
150 IF ( PTRACERS_StepFwd(iTracer) ) THEN
151 GAD_TR = GAD_TR1 + iTracer - 1
152
153 C- Initialise tracer tendency to zero
154 DO k=1,Nr
155 DO j=1-OLy,sNy+OLy
156 DO i=1-OLx,sNx+OLx
157 gTracer(i,j,k) = 0. _d 0
158 ENDDO
159 ENDDO
160 ENDDO
161
162 #ifdef ALLOW_DIAGNOSTICS
163 diagForcing = .FALSE.
164 diagAB_tend = .FALSE.
165 IF ( useDiagnostics ) THEN
166 diagSufx = GAD_DIAG_SUFX( GAD_TR, myThid )
167 diagName = 'Forc'//diagSufx
168 diagForcing = DIAGNOSTICS_IS_ON( diagName, myThid )
169 diagName = 'AB_g'//diagSufx
170 IF ( PTRACERS_AdamsBashGtr(iTracer) )
171 & diagAB_tend = DIAGNOSTICS_IS_ON( diagName, myThid )
172 ENDIF
173 #endif
174
175 #ifdef ALLOW_AUTODIFF_TAMC
176 act0 = iTracer - 1
177 max0 = PTRACERS_num
178 act1 = bi - myBxLo(myThid)
179 max1 = myBxHi(myThid) - myBxLo(myThid) + 1
180 act2 = bj - myByLo(myThid)
181 max2 = myByHi(myThid) - myByLo(myThid) + 1
182 act3 = myThid - 1
183 max3 = nTx*nTy
184 act4 = ikey_dynamics - 1
185 iptrkey = (act0 + 1)
186 & + act1*max0
187 & + act2*max0*max1
188 & + act3*max0*max1*max2
189 & + act4*max0*max1*max2*max3
190 #endif /* ALLOW_AUTODIFF_TAMC */
191
192 C- Apply AB on Tracer :
193 IF ( PTRACERS_AdamsBash_Tr(iTracer) ) THEN
194 C compute pTr^n+1/2 (stored in gpTrNm1) extrapolating pTr forward in time
195 CALL ADAMS_BASHFORTH2(
196 I bi, bj, 0, Nr,
197 I pTracer(1-OLx,1-OLy,1,bi,bj,iTracer),
198 U gpTrNm1(1-OLx,1-OLy,1,bi,bj,iTracer),
199 O gTr_AB,
200 I PTRACERS_startAB(iTracer), iterNb, myThid )
201 ENDIF
202
203 DO j=1-OLy,sNy+OLy
204 DO i=1-OLx,sNx+OLx
205 fVer(i,j,1) = 0. _d 0
206 fVer(i,j,2) = 0. _d 0
207 ENDDO
208 ENDDO
209 #ifdef ALLOW_AUTODIFF
210 DO k=1,Nr
211 DO j=1-OLy,sNy+OLy
212 DO i=1-OLx,sNx+OLx
213 kappaRk(i,j,k) = 0. _d 0
214 ENDDO
215 ENDDO
216 ENDDO
217 #endif /* ALLOW_AUTODIFF */
218
219 CALL CALC_3D_DIFFUSIVITY(
220 I bi, bj, iMin,iMax,jMin,jMax,
221 I GAD_TR,
222 I PTRACERS_useGMRedi(iTracer), PTRACERS_useKPP(iTracer),
223 O kappaRk,
224 I myThid)
225
226 #ifndef DISABLE_MULTIDIM_ADVECTION
227 #ifdef ALLOW_AUTODIFF_TAMC
228 CADJ STORE pTracer(:,:,:,bi,bj,iTracer)
229 CADJ & = comlev1_bibj_ptracers, key=iptrkey, byte=isbyte
230 #endif /* ALLOW_AUTODIFF_TAMC */
231
232 #ifdef PTRACERS_ALLOW_DYN_STATE
233 IF ( PTRACERS_SOM_Advection(iTracer) ) THEN
234 # ifdef ALLOW_DEBUG
235 IF (debugMode) CALL DEBUG_CALL('GAD_SOM_ADVECT',myThid)
236 # endif
237 CALL GAD_SOM_ADVECT(
238 I PTRACERS_ImplVertAdv(iTracer),
239 I PTRACERS_advScheme(iTracer),
240 I PTRACERS_advScheme(iTracer),
241 I GAD_TR,
242 I PTRACERS_dTLev, uFld, vFld, wFld,
243 I pTracer(1-OLx,1-OLy,1,1,1,iTracer),
244 U _Ptracers_som(:,:,:,:,:,:,iTracer),
245 O gTracer,
246 I bi, bj, myTime, myIter, myThid )
247 ELSEIF ( PTRACERS_MultiDimAdv(iTracer) ) THEN
248 #else /* PTRACERS_ALLOW_DYN_STATE */
249 IF ( PTRACERS_MultiDimAdv(iTracer) ) THEN
250 #endif /* PTRACERS_ALLOW_DYN_STATE */
251 # ifdef ALLOW_DEBUG
252 IF (debugMode) CALL DEBUG_CALL('GAD_ADVECTION',myThid)
253 # endif
254 CALL GAD_ADVECTION(
255 I PTRACERS_ImplVertAdv(iTracer),
256 I PTRACERS_advScheme(iTracer),
257 I PTRACERS_advScheme(iTracer),
258 I GAD_TR,
259 I PTRACERS_dTLev, uFld, vFld, wFld,
260 I pTracer(1-OLx,1-OLy,1,1,1,iTracer),
261 O gTracer,
262 I bi, bj, myTime, myIter, myThid )
263 ENDIF
264 #endif /* DISABLE_MULTIDIM_ADVECTION */
265
266 C- Start vertical index (k) loop (Nr:1)
267 calcAdvection = .NOT.PTRACERS_MultiDimAdv(iTracer)
268 & .AND. (PTRACERS_advScheme(iTracer).NE.0)
269 DO k=Nr,1,-1
270 #ifdef ALLOW_AUTODIFF_TAMC
271 kkey = (iptrkey-1)*Nr + k
272 #endif /* ALLOW_AUTODIFF_TAMC */
273
274 kM1 = MAX(1,k-1)
275 kUp = 1+MOD(k+1,2)
276 kDown= 1+MOD(k,2)
277
278 #ifdef ALLOW_AUTODIFF_TAMC
279 CADJ STORE fVer(:,:,:) = comlev1_bibj_k_ptracers,
280 CADJ & key = kkey, byte = isbyte, kind = isbyte
281 CADJ STORE gTracer(:,:,k) = comlev1_bibj_k_ptracers,
282 CADJ & key = kkey, byte = isbyte, kind = isbyte
283 CADJ STORE gpTrNm1(:,:,k,bi,bj,iTracer) = comlev1_bibj_k_ptracers,
284 CADJ & key = kkey, byte = isbyte, kind = isbyte
285 #endif /* ALLOW_AUTODIFF_TAMC */
286 CALL CALC_ADV_FLOW(
287 I uFld, vFld, wFld,
288 U rTrans,
289 O uTrans, vTrans, rTransKp,
290 O maskUp, xA, yA,
291 I k, bi, bj, myThid )
292
293 C-- Collect forcing term in local array gTrForc:
294 DO j=1-OLy,sNy+OLy
295 DO i=1-OLx,sNx+OLx
296 gTrForc(i,j) = 0. _d 0
297 ENDDO
298 ENDDO
299 CALL PTRACERS_APPLY_FORCING(
300 U gTrForc,
301 I surfaceForcingPTr(1-OLx,1-OLy,bi,bj,iTracer),
302 I iMin,iMax,jMin,jMax, k, bi, bj,
303 I iTracer, myTime, myIter, myThid )
304 #ifdef ALLOW_DIAGNOSTICS
305 IF ( diagForcing ) THEN
306 diagName = 'Forc'//diagSufx
307 CALL DIAGNOSTICS_FILL(gTrForc,diagName,k,1,2,bi,bj,myThid)
308 ENDIF
309 #endif /* ALLOW_DIAGNOSTICS */
310
311 C- Calculate active tracer tendencies (gTracer) due to internal processes
312 C (advection, [explicit] diffusion, parameterizations,...)
313 CALL GAD_CALC_RHS(
314 I bi,bj, iMin,iMax,jMin,jMax, k,kM1, kUp,kDown,
315 I xA, yA, maskUp, uFld(1-OLx,1-OLy,k),
316 I vFld(1-OLx,1-OLy,k), wFld(1-OLx,1-OLy,k),
317 I uTrans, vTrans, rTrans, rTransKp,
318 I PTRACERS_diffKh(iTracer),
319 I PTRACERS_diffK4(iTracer),
320 I KappaRk(1-OLx,1-OLy,k), dummy,
321 I pTracer(1-OLx,1-OLy,1,bi,bj,iTracer),
322 I gpTrNm1(1-OLx,1-OLy,1,bi,bj,iTracer),
323 I PTRACERS_dTLev, GAD_TR,
324 I PTRACERS_advScheme(iTracer),
325 I PTRACERS_advScheme(iTracer),
326 I calcAdvection, PTRACERS_ImplVertAdv(iTracer),
327 I PTRACERS_AdamsBash_Tr(iTracer), .FALSE.,
328 I PTRACERS_useGMRedi(iTracer),
329 I PTRACERS_useKPP(iTracer),
330 O fZon, fMer,
331 U fVer, gTracer,
332 I myTime, myIter, myThid )
333
334 C- External forcing term(s) inside Adams-Bashforth:
335 IF ( tracForcingOutAB.NE.1 ) THEN
336 DO j=1-OLy,sNy+OLy
337 DO i=1-OLx,sNx+OLx
338 gTracer(i,j,k) = gTracer(i,j,k) + gTrForc(i,j)
339 ENDDO
340 ENDDO
341 ENDIF
342
343 C- If using Adams-Bashforth II, then extrapolate tendencies
344 C gTracer is now the tracer tendency for explicit advection/diffusion
345
346 C If matrix is being computed, skip call to S/R ADAMS_BASHFORTH2 to
347 C prevent gTracer from being replaced by the average of gTracer and gpTrNm1.
348 IF ( .NOT.useMATRIX .AND.
349 & PTRACERS_AdamsBashGtr(iTracer) ) THEN
350 CALL ADAMS_BASHFORTH2(
351 I bi, bj, k, Nr,
352 U gTracer,
353 U gpTrNm1(1-OLx,1-OLy,1,bi,bj,iTracer),
354 O gTr_AB,
355 I PTRACERS_startAB(iTracer), iterNb, myThid )
356 #ifdef ALLOW_DIAGNOSTICS
357 IF ( diagAB_tend ) THEN
358 diagName = 'AB_g'//diagSufx
359 CALL DIAGNOSTICS_FILL(gTr_AB,diagName,k,1,2,bi,bj,myThid)
360 ENDIF
361 #endif /* ALLOW_DIAGNOSTICS */
362 ENDIF
363
364 C- External forcing term(s) outside Adams-Bashforth:
365 IF ( tracForcingOutAB.EQ.1 ) THEN
366 DO j=1-OLy,sNy+OLy
367 DO i=1-OLx,sNx+OLx
368 gTracer(i,j,k) = gTracer(i,j,k) + gTrForc(i,j)
369 ENDDO
370 ENDDO
371 ENDIF
372
373 #ifdef NONLIN_FRSURF
374 C- Account for change in level thickness
375 IF (nonlinFreeSurf.GT.0) THEN
376 CALL FREESURF_RESCALE_G(
377 I bi, bj, k,
378 U gTracer,
379 I myThid )
380 IF ( PTRACERS_AdamsBashGtr(iTracer) )
381 & CALL FREESURF_RESCALE_G(
382 I bi, bj, k,
383 U gpTrNm1(1-OLx,1-OLy,1,bi,bj,iTracer),
384 I myThid )
385 ENDIF
386 #endif /* NONLIN_FRSURF */
387
388 C- end of vertical index (k) loop (Nr:1)
389 ENDDO
390
391 #ifdef ALLOW_DOWN_SLOPE
392 IF ( PTRACERS_useDWNSLP(iTracer) ) THEN
393 IF ( usingPCoords ) THEN
394 CALL DWNSLP_APPLY(
395 I GAD_TR, bi, bj, kSurfC,
396 I pTracer(1-OLx,1-OLy,1,bi,bj,iTracer),
397 U gTracer,
398 I recip_hFac, recip_rA, recip_drF,
399 I PTRACERS_dTLev, myTime, myIter, myThid )
400 ELSE
401 CALL DWNSLP_APPLY(
402 I GAD_TR, bi, bj, kLowC,
403 I pTracer(1-OLx,1-OLy,1,bi,bj,iTracer),
404 U gTracer,
405 I recip_hFac, recip_rA, recip_drF,
406 I PTRACERS_dTLev, myTime, myIter, myThid )
407 ENDIF
408 ENDIF
409 #endif /* ALLOW_DOWN_SLOPE */
410
411 C- Integrate forward in time, storing in gTracer: gTr <= pTr + dt*gTr
412 CALL TIMESTEP_TRACER(
413 I bi, bj, PTRACERS_dTLev,
414 I pTracer(1-OLx,1-OLy,1,bi,bj,iTracer),
415 U gTracer,
416 I myTime, myIter, myThid )
417
418 C All explicit advection/diffusion/sources should now be
419 C done. The updated tracer field is in gTracer.
420 #ifdef ALLOW_MATRIX
421 C Accumalate explicit tendency and also reset gTracer to initial
422 C tracer field for implicit matrix calculation
423 IF ( useMATRIX ) THEN
424 CALL MATRIX_STORE_TENDENCY_EXP(
425 I iTracer, bi, bj,
426 U gTracer,
427 I myTime, myIter, myThid )
428 ENDIF
429 #endif /* ALLOW_MATRIX */
430
431 C-- Vertical advection & diffusion (implicit) for passive tracers
432
433 #ifdef ALLOW_AUTODIFF_TAMC
434 CADJ STORE gTracer(:,:,:) = comlev1_bibj_ptracers,
435 CADJ & key=iptrkey, byte=isbyte
436 #endif /* ALLOW_AUTODIFF_TAMC */
437
438 #ifdef INCLUDE_IMPLVERTADV_CODE
439 IF ( PTRACERS_ImplVertAdv(iTracer) .OR. implicitDiffusion ) THEN
440 C to recover older (prior to 2016-10-05) results:
441 c IF ( PTRACERS_ImplVertAdv(iTracer) ) THEN
442 CALL GAD_IMPLICIT_R(
443 I PTRACERS_ImplVertAdv(iTracer),
444 I PTRACERS_advScheme(iTracer), GAD_TR,
445 I PTRACERS_dTLev, kappaRk, recip_hFac, wFld,
446 I pTracer(1-OLx,1-OLy,1,bi,bj,iTracer),
447 U gTracer,
448 I bi, bj, myTime, myIter, myThid )
449
450 ELSEIF ( implicitDiffusion ) THEN
451 #else /* INCLUDE_IMPLVERTADV_CODE */
452 IF ( implicitDiffusion ) THEN
453 #endif /* INCLUDE_IMPLVERTADV_CODE */
454 CALL IMPLDIFF(
455 I bi, bj, iMin, iMax, jMin, jMax,
456 I GAD_TR, kappaRk, recip_hFac,
457 U gTracer,
458 I myThid )
459 ENDIF
460
461 IF ( PTRACERS_AdamsBash_Tr(iTracer) ) THEN
462 C-- Save current tracer field (for AB on tracer) and then update tracer
463 CALL CYCLE_AB_TRACER(
464 I bi, bj, gTracer,
465 U pTracer(1-OLx,1-OLy,1,bi,bj,iTracer),
466 O gpTrNm1(1-OLx,1-OLy,1,bi,bj,iTracer),
467 I myTime, myIter, myThid )
468 ELSE
469 C-- Update tracer fields: pTr(n) = pTr**
470 CALL CYCLE_TRACER(
471 I bi, bj,
472 O pTracer(1-OLx,1-OLy,1,bi,bj,iTracer),
473 I gTracer, myTime, myIter, myThid )
474 ENDIF
475
476 #ifdef ALLOW_OBCS
477 C-- Apply open boundary conditions for each passive tracer
478 IF ( useOBCS ) THEN
479 CALL OBCS_APPLY_PTRACER(
480 I bi, bj, 0, iTracer,
481 U pTracer(1-OLx,1-OLy,1,bi,bj,iTracer),
482 I myThid )
483 ENDIF
484 #endif /* ALLOW_OBCS */
485
486 C-- end of tracer loop
487 ENDIF
488 ENDDO
489
490 #endif /* ALLOW_PTRACERS */
491
492 RETURN
493 END

  ViewVC Help
Powered by ViewVC 1.1.22