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

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

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


Revision 1.11 - (show annotations) (download)
Sat Oct 22 20:17:44 2005 UTC (18 years, 6 months ago) by jmc
Branch: MAIN
CVS Tags: checkpoint58e_post, checkpoint57y_post, checkpoint57y_pre, checkpoint58, checkpoint58f_post, checkpoint57x_post, checkpoint58d_post, checkpoint58c_post, checkpoint57w_post, checkpoint58a_post, checkpoint58g_post, checkpoint57z_post, checkpoint58b_post
Changes since 1.10: +21 -7 lines
add code to solve implicitly vertical advection using
 DST2, 1rst.O.Upwind, DST3 or DST3_Flux-Limit advection schemes

1 C $Header: /u/gcmpack/MITgcm/pkg/generic_advdiff/gad_implicit_r.F,v 1.10 2005/06/22 00:27:47 jmc Exp $
2 C $Name: $
3
4 #include "GAD_OPTIONS.h"
5
6 CBOP
7 C !ROUTINE: GAD_IMPLICIT_R
8 C !INTERFACE:
9 SUBROUTINE GAD_IMPLICIT_R(
10 I implicitAdvection, advectionScheme, tracerIdentity,
11 I kappaRX, wVel, tracer,
12 U gTracer,
13 I bi, bj, myTime, myIter, myThid )
14 C !DESCRIPTION:
15 C Solve implicitly vertical advection and diffusion for one tracer.
16
17 C !USES:
18 IMPLICIT NONE
19 C == Global data ==
20 #include "SIZE.h"
21 #include "EEPARAMS.h"
22 #include "PARAMS.h"
23 #include "GRID.h"
24 #include "GAD.h"
25
26 C !INPUT/OUTPUT PARAMETERS:
27 C == Routine Arguments ==
28 C implicitAdvection :: if True, treat vertical advection implicitly
29 C advectionScheme :: advection scheme to use
30 C tracerIdentity :: Identifier for the tracer
31 C kappaRX :: 3-D array for vertical diffusion coefficient
32 C wVel :: vertical component of the velcity field
33 C tracer :: tracer field at current time step
34 C gTracer :: future tracer field
35 C bi,bj :: tile indices
36 C myTime :: current time
37 C myIter :: current iteration number
38 C myThid :: thread number
39 LOGICAL implicitAdvection
40 INTEGER advectionScheme
41 INTEGER tracerIdentity
42 _RL kappaRX(1-Olx:sNx+Olx,1-Oly:sNy+Oly,Nr)
43 _RL wVel (1-Olx:sNx+Olx,1-Oly:sNy+Oly,Nr,nSx,nSy)
44 _RL tracer (1-Olx:sNx+Olx,1-Oly:sNy+Oly,Nr,nSx,nSy)
45 _RL gTracer(1-Olx:sNx+Olx,1-Oly:sNy+Oly,Nr,nSx,nSy)
46 INTEGER bi, bj
47 _RL myTime
48 INTEGER myIter, myThid
49
50 C !LOCAL VARIABLES:
51 C == Local variables ==
52 C iMin,iMax,jMin,jMax :: computational domain
53 C i,j,k :: loop indices
54 C a5d :: 2nd lower diagonal of the pentadiagonal matrix
55 C b5d :: 1rst lower diagonal of the pentadiagonal matrix
56 C c5d :: main diagonal of the pentadiagonal matrix
57 C d5d :: 1rst upper diagonal of the pentadiagonal matrix
58 C e5d :: 2nd upper diagonal of the pentadiagonal matrix
59 C rTrans :: vertical volume transport at inteface k
60 C rTransKp1 :: vertical volume transport at inteface k+1
61 C localTijk :: local copy of tracer (for Non-Lin Adv.Scheme)
62 C diagonalNumber :: number of non-zero diagonals in the matrix
63 C errCode :: > 0 if singular matrix
64 INTEGER iMin,iMax,jMin,jMax
65 INTEGER i,j,k
66 INTEGER diagonalNumber, errCode
67 _RL a5d(1-Olx:sNx+Olx,1-Oly:sNy+Oly,Nr)
68 _RL b5d(1-Olx:sNx+Olx,1-Oly:sNy+Oly,Nr)
69 _RL c5d(1-Olx:sNx+Olx,1-Oly:sNy+Oly,Nr)
70 _RL d5d(1-Olx:sNx+Olx,1-Oly:sNy+Oly,Nr)
71 _RL e5d(1-Olx:sNx+Olx,1-Oly:sNy+Oly,Nr)
72 _RL rTrans(1-Olx:sNx+Olx,1-Oly:sNy+Oly)
73 _RL rTransKp1(1-Olx:sNx+Olx,1-Oly:sNy+Oly)
74 _RL localTijk(1-Olx:sNx+Olx,1-Oly:sNy+Oly,Nr)
75 #ifdef ALLOW_DIAGNOSTICS
76 CHARACTER*8 diagName
77 CHARACTER*4 GAD_DIAG_SUFX, diagSufx
78 EXTERNAL GAD_DIAG_SUFX
79 LOGICAL DIAGNOSTICS_IS_ON
80 EXTERNAL DIAGNOSTICS_IS_ON
81 _RL df (1-Olx:sNx+Olx,1-Oly:sNy+Oly)
82 #endif
83 CEOP
84
85 C-- no need to solve anything with only 1 level:
86 IF (Nr.GT.1) THEN
87
88 C-- Initialise
89 iMin = 1
90 jMin = 1
91 iMax = sNx
92 jMax = sNy
93 DO k=1,Nr
94 DO j=1-Oly,sNy+Oly
95 DO i=1-Olx,sNx+Olx
96 a5d(i,j,k) = 0. _d 0
97 b5d(i,j,k) = 0. _d 0
98 c5d(i,j,k) = 1. _d 0
99 d5d(i,j,k) = 0. _d 0
100 e5d(i,j,k) = 0. _d 0
101 ENDDO
102 ENDDO
103 ENDDO
104 diagonalNumber = 1
105
106 C-- Non-Linear Advection scheme: keep a local copy of tracer field
107 IF ( advectionScheme.EQ.ENUM_FLUX_LIMIT .OR.
108 & advectionScheme.EQ.ENUM_DST3_FLUX_LIMIT ) THEN
109 IF ( multiDimAdvection ) THEN
110 DO k=1,Nr
111 DO j=1-Oly,sNy+Oly
112 DO i=1-Olx,sNx+Olx
113 localTijk(i,j,k) = gTracer(i,j,k,bi,bj)
114 ENDDO
115 ENDDO
116 ENDDO
117 ELSE
118 DO k=1,Nr
119 DO j=1-Oly,sNy+Oly
120 DO i=1-Olx,sNx+Olx
121 localTijk(i,j,k) = tracer(i,j,k,bi,bj)
122 ENDDO
123 ENDDO
124 ENDDO
125 ENDIF
126 ENDIF
127
128 IF (implicitDiffusion) THEN
129 C-- set the tri-diagonal matrix to solve the implicit diffusion problem
130 diagonalNumber = 3
131 C- 1rst lower diagonal :
132 DO k=2,Nr
133 DO j=jMin,jMax
134 DO i=iMin,iMax
135 b5d(i,j,k) = -dTtracerLev(k)*maskC(i,j,k-1,bi,bj)
136 & *recip_hFacC(i,j,k,bi,bj)*recip_drF(k)
137 & *kappaRX(i,j, k )*recip_drC( k )
138 ENDDO
139 ENDDO
140 ENDDO
141 C- 1rst upper diagonal :
142 DO k=1,Nr-1
143 DO j=jMin,jMax
144 DO i=iMin,iMax
145 d5d(i,j,k) = -dTtracerLev(k)*maskC(i,j,k+1,bi,bj)
146 & *recip_hFacC(i,j,k,bi,bj)*recip_drF(k)
147 & *KappaRX(i,j,k+1)*recip_drC(k+1)
148 ENDDO
149 ENDDO
150 ENDDO
151 C- Main diagonal :
152 DO k=1,Nr
153 DO j=jMin,jMax
154 DO i=iMin,iMax
155 c5d(i,j,k) = 1. _d 0 - b5d(i,j,k) - d5d(i,j,k)
156 ENDDO
157 ENDDO
158 ENDDO
159
160 C-- end if implicitDiffusion
161 ENDIF
162
163 IF (implicitAdvection) THEN
164
165 DO k=Nr,1,-1
166
167 C-- Compute transport
168 IF (k.EQ.Nr) THEN
169 DO j=1-Oly,sNy+Oly
170 DO i=1-Olx,sNx+Olx
171 rTransKp1(i,j) = 0.
172 ENDDO
173 ENDDO
174 ELSE
175 DO j=1-Oly,sNy+Oly
176 DO i=1-Olx,sNx+Olx
177 rTransKp1(i,j) = rTrans(i,j)
178 ENDDO
179 ENDDO
180 ENDIF
181
182 IF (k.EQ.1) THEN
183 DO j=1-Oly,sNy+Oly
184 DO i=1-Olx,sNx+Olx
185 rTrans(i,j) = 0.
186 ENDDO
187 ENDDO
188 ELSE
189 DO j=1-Oly,sNy+Oly
190 DO i=1-Olx,sNx+Olx
191 rTrans(i,j) = wVel(i,j,k,bi,bj)*rA(i,j,bi,bj)
192 & *maskC(i,j,k-1,bi,bj)
193 ENDDO
194 ENDDO
195 #ifdef ALLOW_GMREDI
196 C-- Residual transp = Bolus transp + Eulerian transp
197 IF (useGMRedi)
198 & CALL GMREDI_CALC_WFLOW(
199 & rTrans, bi, bj, k, myThid)
200 #endif /* ALLOW_GMREDI */
201 ENDIF
202 DO j=jMin,jMax
203 DO i=iMin,iMax
204 c localTijk(i,j,k) = gTracer(i,j,k,bi,bj)
205 gTracer(i,j,k,bi,bj) = gTracer(i,j,k,bi,bj)
206 & + dTtracerLev(1)*recip_rA(i,j,bi,bj)
207 & *_recip_hFacC(i,j,k,bi,bj)*recip_drF(k)
208 & *tracer(i,j,k,bi,bj)*(rTransKp1(i,j)-rTrans(i,j))*rkSign
209 ENDDO
210 ENDDO
211
212 #ifdef ALLOW_AIM
213 C- a hack to prevent Water-Vapor vert.transport into the stratospheric level Nr
214 IF ( K.GE.2 .AND.
215 & (.NOT.useAIM .OR.tracerIdentity.NE.GAD_SALINITY .OR.K.LT.Nr)
216 & ) THEN
217 #else
218 IF ( K.GE.2 ) THEN
219 #endif
220
221 IF ( advectionScheme.EQ.ENUM_CENTERED_2ND ) THEN
222 diagonalNumber = 3
223 CALL GAD_C2_IMPL_R( bi,bj,k, iMin,iMax,jMin,jMax,
224 I dTtracerLev, rTrans,
225 U b5d, c5d, d5d,
226 I myThid )
227 ELSEIF ( advectionScheme.EQ.ENUM_UPWIND_1RST
228 & .OR. advectionScheme.EQ.ENUM_DST2 ) THEN
229 diagonalNumber = 3
230 CALL GAD_DST2U1_IMPL_R( bi,bj,k, iMin,iMax,jMin,jMax,
231 I advectionScheme, dTtracerLev, rTrans,
232 U b5d, c5d, d5d,
233 I myThid )
234 ELSEIF ( advectionScheme.EQ.ENUM_FLUX_LIMIT ) THEN
235 diagonalNumber = 3
236 CALL GAD_FLUXLIMIT_IMPL_R( bi,bj,k, iMin,iMax,jMin,jMax,
237 I dTtracerLev, rTrans, localTijk,
238 U b5d, c5d, d5d,
239 I myThid )
240 ELSEIF ( advectionScheme.EQ.ENUM_UPWIND_3RD
241 & .OR. advectionScheme.EQ.ENUM_CENTERED_4TH
242 & .OR. advectionScheme.EQ.ENUM_DST3 ) THEN
243 diagonalNumber = 5
244 CALL GAD_U3C4_IMPL_R( bi,bj,k, iMin,iMax,jMin,jMax,
245 I advectionScheme, dTtracerLev, rTrans,
246 U a5d, b5d, c5d, d5d, e5d,
247 I myThid )
248 ELSEIF ( advectionScheme.EQ.ENUM_DST3_FLUX_LIMIT ) THEN
249 diagonalNumber = 5
250 CALL GAD_DST3FL_IMPL_R( bi,bj,k, iMin,iMax,jMin,jMax,
251 I dTtracerLev, rTrans, localTijk,
252 U a5d, b5d, c5d, d5d, e5d,
253 I myThid )
254 ELSE
255 STOP 'GAD_IMPLICIT_R: Adv.Scheme in Impl form not yet coded'
256 ENDIF
257
258 ENDIF
259
260 C-- end k loop
261 ENDDO
262
263 C-- end if implicitAdvection
264 ENDIF
265
266 IF ( diagonalNumber .EQ. 3 ) THEN
267 C-- Solve tri-diagonal system :
268 CALL SOLVE_TRIDIAGONAL( iMin,iMax, jMin,jMax,
269 I b5d, c5d, d5d,
270 U gTracer,
271 O errCode,
272 I bi, bj, myThid )
273 IF (errCode.GE.1) THEN
274 STOP 'GAD_IMPLICIT_R: error when solving 3-Diag problem'
275 ENDIF
276 ELSEIF ( diagonalNumber .EQ. 5 ) THEN
277 C-- Solve penta-diagonal system :
278 CALL SOLVE_PENTADIAGONAL( iMin,iMax, jMin,jMax,
279 I a5d, b5d, c5d, d5d, e5d,
280 U gTracer,
281 O errCode,
282 I bi, bj, myThid )
283 IF (errCode.GE.1) THEN
284 STOP 'GAD_IMPLICIT_R: error when solving 5-Diag problem'
285 ENDIF
286 ELSEIF ( diagonalNumber .NE. 1 ) THEN
287 STOP 'GAD_IMPLICIT_R: no solver available'
288 ENDIF
289
290 #ifdef ALLOW_DIAGNOSTICS
291 C-- Set diagnostic suffix for the current tracer
292 IF ( useDiagnostics .AND. implicitDiffusion ) THEN
293 diagSufx = GAD_DIAG_SUFX( tracerIdentity, myThid )
294 diagName = 'DFrI'//diagSufx
295 IF ( DIAGNOSTICS_IS_ON(diagName,myThid) ) THEN
296 DO k= 1,Nr
297 IF ( k.EQ.1 ) THEN
298 C- Note: Needs to call DIAGNOSTICS_FILL at level k=1 even if array == 0
299 C otherwise counter is not incremented !!
300 DO j=1-OLy,sNy+OLy
301 DO i=1-OLx,sNx+OLx
302 df(i,j) = 0. _d 0
303 ENDDO
304 ENDDO
305 ELSE
306 DO j=1,sNy
307 DO i=1,sNx
308 df(i,j) =
309 & rA(i,j,bi,bj)
310 & * KappaRX(i,j,k)*recip_drC(k)
311 & * (gTracer(i,j,k,bi,bj) - gTracer(i,j,k-1,bi,bj))
312 ENDDO
313 ENDDO
314 ENDIF
315 CALL DIAGNOSTICS_FILL(df,diagName, k,1, 2,bi,bj, myThid)
316 ENDDO
317 ENDIF
318 ENDIF
319 #endif /* ALLOW_DIAGNOSTICS */
320
321 C-- end if Nr > 1
322 ENDIF
323
324 RETURN
325 END

  ViewVC Help
Powered by ViewVC 1.1.22