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

Annotation 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 - (hide 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 jmc 1.11 C $Header: /u/gcmpack/MITgcm/pkg/generic_advdiff/gad_implicit_r.F,v 1.10 2005/06/22 00:27:47 jmc Exp $
2 jmc 1.1 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 edhill 1.4 C !DESCRIPTION:
15     C Solve implicitly vertical advection and diffusion for one tracer.
16 jmc 1.1
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 edhill 1.4 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 jmc 1.1 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 edhill 1.4 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 jmc 1.1 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 jmc 1.2 _RL rTransKp1(1-Olx:sNx+Olx,1-Oly:sNy+Oly)
74     _RL localTijk(1-Olx:sNx+Olx,1-Oly:sNy+Oly,Nr)
75 jmc 1.8 #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 jmc 1.1 CEOP
84    
85 jmc 1.7 C-- no need to solve anything with only 1 level:
86     IF (Nr.GT.1) THEN
87 jmc 1.1
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 jmc 1.2 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 jmc 1.1 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 jmc 1.7 b5d(i,j,k) = -dTtracerLev(k)*maskC(i,j,k-1,bi,bj)
136 jmc 1.1 & *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 jmc 1.7 d5d(i,j,k) = -dTtracerLev(k)*maskC(i,j,k+1,bi,bj)
146 jmc 1.1 & *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 jmc 1.2 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 jmc 1.1
182 jmc 1.2 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 jmc 1.1 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 jmc 1.2 ENDDO
195 jmc 1.1 #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 jmc 1.2 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 jmc 1.6 & + dTtracerLev(1)*recip_rA(i,j,bi,bj)
207 jmc 1.2 & *_recip_hFacC(i,j,k,bi,bj)*recip_drF(k)
208 jmc 1.10 & *tracer(i,j,k,bi,bj)*(rTransKp1(i,j)-rTrans(i,j))*rkSign
209 jmc 1.2 ENDDO
210     ENDDO
211    
212 jmc 1.5 #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 jmc 1.1
221 jmc 1.2 IF ( advectionScheme.EQ.ENUM_CENTERED_2ND ) THEN
222     diagonalNumber = 3
223     CALL GAD_C2_IMPL_R( bi,bj,k, iMin,iMax,jMin,jMax,
224 jmc 1.7 I dTtracerLev, rTrans,
225 jmc 1.2 U b5d, c5d, d5d,
226 jmc 1.11 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 jmc 1.2 diagonalNumber = 3
236     CALL GAD_FLUXLIMIT_IMPL_R( bi,bj,k, iMin,iMax,jMin,jMax,
237 jmc 1.7 I dTtracerLev, rTrans, localTijk,
238 jmc 1.2 U b5d, c5d, d5d,
239 jmc 1.11 I myThid )
240     ELSEIF ( advectionScheme.EQ.ENUM_UPWIND_3RD
241     & .OR. advectionScheme.EQ.ENUM_CENTERED_4TH
242     & .OR. advectionScheme.EQ.ENUM_DST3 ) THEN
243 jmc 1.2 diagonalNumber = 5
244     CALL GAD_U3C4_IMPL_R( bi,bj,k, iMin,iMax,jMin,jMax,
245 jmc 1.7 I advectionScheme, dTtracerLev, rTrans,
246 jmc 1.2 U a5d, b5d, c5d, d5d, e5d,
247 jmc 1.11 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 jmc 1.2 ELSE
255     STOP 'GAD_IMPLICIT_R: Adv.Scheme in Impl form not yet coded'
256     ENDIF
257    
258     ENDIF
259 jmc 1.1
260 jmc 1.2 C-- end k loop
261     ENDDO
262 jmc 1.1
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 jmc 1.2 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 jmc 1.1 ENDIF
286     ELSEIF ( diagonalNumber .NE. 1 ) THEN
287     STOP 'GAD_IMPLICIT_R: no solver available'
288     ENDIF
289    
290 jmc 1.8 #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 jmc 1.9 CALL DIAGNOSTICS_FILL(df,diagName, k,1, 2,bi,bj, myThid)
316 jmc 1.8 ENDDO
317     ENDIF
318     ENDIF
319     #endif /* ALLOW_DIAGNOSTICS */
320    
321 jmc 1.7 C-- end if Nr > 1
322     ENDIF
323    
324 jmc 1.1 RETURN
325     END

  ViewVC Help
Powered by ViewVC 1.1.22