/[MITgcm]/MITgcm_contrib/heimbach/OpenAD/code_shallow_openad3/gad_implicit_r.F
ViewVC logotype

Annotation of /MITgcm_contrib/heimbach/OpenAD/code_shallow_openad3/gad_implicit_r.F

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


Revision 1.2 - (hide annotations) (download)
Thu May 10 05:04:47 2007 UTC (19 years, 6 months ago) by utke
Branch: MAIN
Changes since 1.1: +18 -15 lines
sync

1 utke 1.2 C $Header: /u/gcmpack/MITgcm_contrib/heimbach/OpenAD/code_shallow_openad3/gad_implicit_r.F,v 1.1 2006/08/01 15:44:28 utke Exp $
2 utke 1.1 C $Name: $
3    
4     #include "GAD_OPTIONS.h"
5    
6     CBOP
7     C !ROUTINE: GAD_IMPLICIT_R
8     C !INTERFACE:
9 utke 1.2 SUBROUTINE GAD_IMPLICIT_R(
10 utke 1.1 I implicitAdvection, advectionScheme, tracerIdentity,
11 utke 1.2 I kappaRX, wVel, tracer,
12 utke 1.1 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 utke 1.2 _RL wFld (1-Olx:sNx+Olx,1-Oly:sNy+Oly)
73     _RL rTrans (1-Olx:sNx+Olx,1-Oly:sNy+Oly)
74 utke 1.1 _RL rTransKp1(1-Olx:sNx+Olx,1-Oly:sNy+Oly)
75     _RL localTijk(1-Olx:sNx+Olx,1-Oly:sNy+Oly,Nr)
76     #ifdef ALLOW_DIAGNOSTICS
77     CHARACTER*8 diagName
78     CHARACTER*4 GAD_DIAG_SUFX, diagSufx
79     EXTERNAL GAD_DIAG_SUFX
80     LOGICAL DIAGNOSTICS_IS_ON
81     EXTERNAL DIAGNOSTICS_IS_ON
82     _RL df (1-Olx:sNx+Olx,1-Oly:sNy+Oly)
83     #endif
84     CEOP
85    
86     C-- no need to solve anything with only 1 level:
87     IF (Nr.GT.1) THEN
88    
89     C-- Initialise
90     iMin = 1
91     jMin = 1
92     iMax = sNx
93     jMax = sNy
94     DO k=1,Nr
95     DO j=1-Oly,sNy+Oly
96     DO i=1-Olx,sNx+Olx
97     a5d(i,j,k) = 0. _d 0
98     b5d(i,j,k) = 0. _d 0
99     c5d(i,j,k) = 1. _d 0
100     d5d(i,j,k) = 0. _d 0
101     e5d(i,j,k) = 0. _d 0
102     ENDDO
103     ENDDO
104     ENDDO
105     diagonalNumber = 1
106    
107     C-- Non-Linear Advection scheme: keep a local copy of tracer field
108 utke 1.2 IF ( advectionScheme.EQ.ENUM_FLUX_LIMIT .OR.
109 utke 1.1 & advectionScheme.EQ.ENUM_DST3_FLUX_LIMIT ) THEN
110     IF ( multiDimAdvection ) THEN
111     DO k=1,Nr
112     DO j=1-Oly,sNy+Oly
113     DO i=1-Olx,sNx+Olx
114     localTijk(i,j,k) = gTracer(i,j,k,bi,bj)
115     ENDDO
116     ENDDO
117     ENDDO
118     ELSE
119     DO k=1,Nr
120     DO j=1-Oly,sNy+Oly
121     DO i=1-Olx,sNx+Olx
122     localTijk(i,j,k) = tracer(i,j,k,bi,bj)
123     ENDDO
124     ENDDO
125     ENDDO
126     ENDIF
127     ENDIF
128    
129     IF (implicitDiffusion) THEN
130     C-- set the tri-diagonal matrix to solve the implicit diffusion problem
131     diagonalNumber = 3
132     C- 1rst lower diagonal :
133     DO k=2,Nr
134     DO j=jMin,jMax
135     DO i=iMin,iMax
136     b5d(i,j,k) = -dTtracerLev(k)*maskC(i,j,k-1,bi,bj)
137 utke 1.2 & *_recip_hFacC(i,j,k,bi,bj)*recip_drF(k)
138 utke 1.1 & *kappaRX(i,j, k )*recip_drC( k )
139     ENDDO
140     ENDDO
141     ENDDO
142     C- 1rst upper diagonal :
143     DO k=1,Nr-1
144     DO j=jMin,jMax
145     DO i=iMin,iMax
146     d5d(i,j,k) = -dTtracerLev(k)*maskC(i,j,k+1,bi,bj)
147 utke 1.2 & *_recip_hFacC(i,j,k,bi,bj)*recip_drF(k)
148 utke 1.1 & *KappaRX(i,j,k+1)*recip_drC(k+1)
149     ENDDO
150     ENDDO
151     ENDDO
152     C- Main diagonal :
153     DO k=1,Nr
154     DO j=jMin,jMax
155     DO i=iMin,iMax
156     c5d(i,j,k) = 1. _d 0 - b5d(i,j,k) - d5d(i,j,k)
157     ENDDO
158     ENDDO
159     ENDDO
160    
161     C-- end if implicitDiffusion
162     ENDIF
163    
164     IF (implicitAdvection) THEN
165    
166     DO k=Nr,1,-1
167    
168     C-- Compute transport
169     IF (k.EQ.Nr) THEN
170     DO j=1-Oly,sNy+Oly
171     DO i=1-Olx,sNx+Olx
172     rTransKp1(i,j) = 0.
173     ENDDO
174     ENDDO
175     ELSE
176     DO j=1-Oly,sNy+Oly
177     DO i=1-Olx,sNx+Olx
178     rTransKp1(i,j) = rTrans(i,j)
179     ENDDO
180     ENDDO
181     ENDIF
182    
183     IF (k.EQ.1) THEN
184     DO j=1-Oly,sNy+Oly
185     DO i=1-Olx,sNx+Olx
186 utke 1.2 wFld(i,j) = 0. _d 0
187     rTrans(i,j) = 0. _d 0
188 utke 1.1 ENDDO
189     ENDDO
190     ELSE
191     DO j=1-Oly,sNy+Oly
192     DO i=1-Olx,sNx+Olx
193 utke 1.2 wFld(i,j) = wVel(i,j,k,bi,bj)
194     rTrans(i,j) = wFld(i,j)*rA(i,j,bi,bj)%v*maskC(i,j,k-1,bi,bj)
195 utke 1.1 ENDDO
196     ENDDO
197     #ifdef ALLOW_GMREDI
198     C-- Residual transp = Bolus transp + Eulerian transp
199 utke 1.2 IF (useGMRedi)
200     & CALL GMREDI_CALC_WFLOW(
201     U wFld, rTrans,
202     I k, bi, bj, myThid )
203 utke 1.1 #endif /* ALLOW_GMREDI */
204     ENDIF
205     DO j=jMin,jMax
206     DO i=iMin,iMax
207 utke 1.2 c localTijk(i,j,k) = gTracer(i,j,k,bi,bj)
208 utke 1.1 gTracer(i,j,k,bi,bj) = gTracer(i,j,k,bi,bj)
209     & + dTtracerLev(1)*recip_rA(i,j,bi,bj)
210     & *_recip_hFacC(i,j,k,bi,bj)*recip_drF(k)
211     & *tracer(i,j,k,bi,bj)*(rTransKp1(i,j)-rTrans(i,j))*rkSign
212     ENDDO
213     ENDDO
214    
215     #ifdef ALLOW_AIM
216     C- a hack to prevent Water-Vapor vert.transport into the stratospheric level Nr
217     IF ( K.GE.2 .AND.
218     & (.NOT.useAIM .OR.tracerIdentity.NE.GAD_SALINITY .OR.K.LT.Nr)
219     & ) THEN
220     #else
221     IF ( K.GE.2 ) THEN
222     #endif
223    
224     IF ( advectionScheme.EQ.ENUM_CENTERED_2ND ) THEN
225     diagonalNumber = 3
226     CALL GAD_C2_IMPL_R( bi,bj,k, iMin,iMax,jMin,jMax,
227     I dTtracerLev, rTrans,
228     U b5d, c5d, d5d,
229     I myThid )
230     ELSEIF ( advectionScheme.EQ.ENUM_UPWIND_1RST
231     & .OR. advectionScheme.EQ.ENUM_DST2 ) THEN
232     diagonalNumber = 3
233     CALL GAD_DST2U1_IMPL_R( bi,bj,k, iMin,iMax,jMin,jMax,
234     I advectionScheme, dTtracerLev, rTrans,
235     U b5d, c5d, d5d,
236     I myThid )
237     ELSEIF ( advectionScheme.EQ.ENUM_FLUX_LIMIT ) THEN
238     diagonalNumber = 3
239     CALL GAD_FLUXLIMIT_IMPL_R( bi,bj,k, iMin,iMax,jMin,jMax,
240     I dTtracerLev, rTrans, localTijk,
241     U b5d, c5d, d5d,
242     I myThid )
243     ELSEIF ( advectionScheme.EQ.ENUM_UPWIND_3RD
244     & .OR. advectionScheme.EQ.ENUM_CENTERED_4TH
245     & .OR. advectionScheme.EQ.ENUM_DST3 ) THEN
246     diagonalNumber = 5
247     CALL GAD_U3C4_IMPL_R( bi,bj,k, iMin,iMax,jMin,jMax,
248     I advectionScheme, dTtracerLev, rTrans,
249     U a5d, b5d, c5d, d5d, e5d,
250     I myThid )
251     ELSEIF ( advectionScheme.EQ.ENUM_DST3_FLUX_LIMIT ) THEN
252     diagonalNumber = 5
253     CALL GAD_DST3FL_IMPL_R( bi,bj,k, iMin,iMax,jMin,jMax,
254     I dTtracerLev, rTrans, localTijk,
255     U a5d, b5d, c5d, d5d, e5d,
256     I myThid )
257     ELSE
258     STOP 'GAD_IMPLICIT_R: Adv.Scheme in Impl form not yet coded'
259     ENDIF
260    
261     ENDIF
262    
263     C-- end k loop
264     ENDDO
265    
266     C-- end if implicitAdvection
267     ENDIF
268    
269     IF ( diagonalNumber .EQ. 3 ) THEN
270     C-- Solve tri-diagonal system :
271     CALL SOLVE_TRIDIAGONAL( iMin,iMax, jMin,jMax,
272     I b5d, c5d, d5d,
273     U gTracer,
274     O errCode,
275     I bi, bj, myThid )
276     IF (errCode.GE.1) THEN
277     STOP 'GAD_IMPLICIT_R: error when solving 3-Diag problem'
278     ENDIF
279     ELSEIF ( diagonalNumber .EQ. 5 ) THEN
280     C-- Solve penta-diagonal system :
281     CALL SOLVE_PENTADIAGONAL( iMin,iMax, jMin,jMax,
282     I a5d, b5d, c5d, d5d, e5d,
283     U gTracer,
284     O errCode,
285     I bi, bj, myThid )
286     IF (errCode.GE.1) THEN
287     STOP 'GAD_IMPLICIT_R: error when solving 5-Diag problem'
288     ENDIF
289     ELSEIF ( diagonalNumber .NE. 1 ) THEN
290     STOP 'GAD_IMPLICIT_R: no solver available'
291     ENDIF
292    
293     #ifdef ALLOW_DIAGNOSTICS
294     C-- Set diagnostic suffix for the current tracer
295     IF ( useDiagnostics .AND. implicitDiffusion ) THEN
296     diagSufx = GAD_DIAG_SUFX( tracerIdentity, myThid )
297     diagName = 'DFrI'//diagSufx
298     IF ( DIAGNOSTICS_IS_ON(diagName,myThid) ) THEN
299     DO k= 1,Nr
300     IF ( k.EQ.1 ) THEN
301     C- Note: Needs to call DIAGNOSTICS_FILL at level k=1 even if array == 0
302     C otherwise counter is not incremented !!
303     DO j=1-OLy,sNy+OLy
304     DO i=1-OLx,sNx+OLx
305     df(i,j) = 0. _d 0
306     ENDDO
307     ENDDO
308     ELSE
309     DO j=1,sNy
310     DO i=1,sNx
311 utke 1.2 df(i,j) =
312 utke 1.1 & rA(i,j,bi,bj)%v
313     & * KappaRX(i,j,k)*recip_drC(k)
314     & * (gTracer(i,j,k,bi,bj) - gTracer(i,j,k-1,bi,bj))
315     ENDDO
316     ENDDO
317     ENDIF
318     CALL DIAGNOSTICS_FILL(df,diagName, k,1, 2,bi,bj, myThid)
319     ENDDO
320     ENDIF
321     ENDIF
322     #endif /* ALLOW_DIAGNOSTICS */
323    
324     C-- end if Nr > 1
325     ENDIF
326    
327     RETURN
328     END

  ViewVC Help
Powered by ViewVC 1.1.22