/[MITgcm]/MITgcm/model/src/solve_for_pressure.F
ViewVC logotype

Contents of /MITgcm/model/src/solve_for_pressure.F

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


Revision 1.34 - (show annotations) (download)
Mon Sep 23 16:13:31 2002 UTC (21 years, 8 months ago) by adcroft
Branch: MAIN
CVS Tags: checkpoint46h_pre
Changes since 1.33: +4 -1 lines
Added code to convert surface volume flux (fresh water) into
a mass flux when using P coordinates in the ocean (OCEANICP).
Note: It assumes you have set rho0=rhoConst=density of fresh water.

1 C $Header: /u/gcmpack/models/MITgcmUV/model/src/solve_for_pressure.F,v 1.33 2002/06/21 18:36:06 adcroft Exp $
2 C $Name: $
3
4 #include "CPP_OPTIONS.h"
5
6 CBOP
7 C !ROUTINE: SOLVE_FOR_PRESSURE
8 C !INTERFACE:
9 SUBROUTINE SOLVE_FOR_PRESSURE(myTime, myIter, myThid)
10
11 C !DESCRIPTION: \bv
12 C *==========================================================*
13 C | SUBROUTINE SOLVE_FOR_PRESSURE
14 C | o Controls inversion of two and/or three-dimensional
15 C | elliptic problems for the pressure field.
16 C *==========================================================*
17 C \ev
18
19 C !USES:
20 IMPLICIT NONE
21 C == Global variables
22 #include "SIZE.h"
23 #include "EEPARAMS.h"
24 #include "PARAMS.h"
25 #include "DYNVARS.h"
26 #include "GRID.h"
27 #include "SURFACE.h"
28 #include "FFIELDS.h"
29 #ifdef ALLOW_NONHYDROSTATIC
30 #include "SOLVE_FOR_PRESSURE3D.h"
31 #include "GW.h"
32 #endif
33 #ifdef ALLOW_OBCS
34 #include "OBCS.h"
35 #endif
36 #include "SOLVE_FOR_PRESSURE.h"
37
38 C === Functions ====
39 LOGICAL DIFFERENT_MULTIPLE
40 EXTERNAL DIFFERENT_MULTIPLE
41
42 C !INPUT/OUTPUT PARAMETERS:
43 C == Routine arguments ==
44 C myTime - Current time in simulation
45 C myIter - Current iteration number in simulation
46 C myThid - Thread number for this instance of SOLVE_FOR_PRESSURE
47 _RL myTime
48 INTEGER myIter
49 INTEGER myThid
50
51 C !LOCAL VARIABLES:
52 C == Local variables ==
53 INTEGER i,j,k,bi,bj
54 _RS uf(1-Olx:sNx+Olx,1-Oly:sNy+Oly)
55 _RS vf(1-Olx:sNx+Olx,1-Oly:sNy+Oly)
56 _RL firstResidual,lastResidual
57 _RL tmpFac
58 INTEGER numIters
59 CHARACTER*(MAX_LEN_MBUF) msgBuf
60 CEOP
61
62 C-- Save previous solution & Initialise Vector solution and source term :
63 DO bj=myByLo(myThid),myByHi(myThid)
64 DO bi=myBxLo(myThid),myBxHi(myThid)
65 DO j=1-OLy,sNy+OLy
66 DO i=1-OLx,sNx+OLx
67 #ifdef INCLUDE_CD_CODE
68 etaNm1(i,j,bi,bj) = etaN(i,j,bi,bj)
69 #endif
70 cg2d_x(i,j,bi,bj) = Bo_surf(i,j,bi,bj)*etaN(i,j,bi,bj)
71 cg2d_b(i,j,bi,bj) = 0.
72 ENDDO
73 ENDDO
74 IF (useRealFreshWaterFlux) THEN
75 tmpFac = freeSurfFac
76 IF (exactConserv) tmpFac = freeSurfFac*implicDiv2DFlow
77 IF ( buoyancyRelation .eq. 'OCEANICP' ) THEN
78 tmpFac = tmpFac*horiVertRatio
79 ENDIF
80 DO j=1,sNy
81 DO i=1,sNx
82 cg2d_b(i,j,bi,bj) =
83 & tmpFac*_rA(i,j,bi,bj)*EmPmR(i,j,bi,bj)/deltaTMom
84 ENDDO
85 ENDDO
86 ENDIF
87 ENDDO
88 ENDDO
89
90 DO bj=myByLo(myThid),myByHi(myThid)
91 DO bi=myBxLo(myThid),myBxHi(myThid)
92 DO K=Nr,1,-1
93 DO j=1,sNy+1
94 DO i=1,sNx+1
95 uf(i,j) = _dyG(i,j,bi,bj)
96 & *drF(k)*_hFacW(i,j,k,bi,bj)
97 vf(i,j) = _dxG(i,j,bi,bj)
98 & *drF(k)*_hFacS(i,j,k,bi,bj)
99 ENDDO
100 ENDDO
101 CALL CALC_DIV_GHAT(
102 I bi,bj,1,sNx,1,sNy,K,
103 I uf,vf,
104 U cg2d_b,
105 I myThid)
106 ENDDO
107 ENDDO
108 ENDDO
109
110 C-- Add source term arising from w=d/dt (p_s + p_nh)
111 DO bj=myByLo(myThid),myByHi(myThid)
112 DO bi=myBxLo(myThid),myBxHi(myThid)
113 #ifdef ALLOW_NONHYDROSTATIC
114 IF ( nonHydrostatic ) THEN
115 DO j=1,sNy
116 DO i=1,sNx
117 cg2d_b(i,j,bi,bj) = cg2d_b(i,j,bi,bj)
118 & -freeSurfFac*_rA(i,j,bi,bj)/deltaTMom/deltaTfreesurf
119 & *( etaN(i,j,bi,bj)
120 & +phi_nh(i,j,1,bi,bj)*horiVertRatio/gravity )
121 cg3d_b(i,j,1,bi,bj) = cg3d_b(i,j,1,bi,bj)
122 & -freeSurfFac*_rA(i,j,bi,bj)/deltaTMom/deltaTfreesurf
123 & *( etaN(i,j,bi,bj)
124 & +phi_nh(i,j,1,bi,bj)*horiVertRatio/gravity )
125 ENDDO
126 ENDDO
127 ELSEIF ( exactConserv ) THEN
128 #else
129 IF ( exactConserv ) THEN
130 #endif
131 DO j=1,sNy
132 DO i=1,sNx
133 cg2d_b(i,j,bi,bj) = cg2d_b(i,j,bi,bj)
134 & -freeSurfFac*_rA(i,j,bi,bj)/deltaTMom/deltaTfreesurf
135 & * etaH(i,j,bi,bj)
136 ENDDO
137 ENDDO
138 ELSE
139 DO j=1,sNy
140 DO i=1,sNx
141 cg2d_b(i,j,bi,bj) = cg2d_b(i,j,bi,bj)
142 & -freeSurfFac*_rA(i,j,bi,bj)/deltaTMom/deltaTfreesurf
143 & * etaN(i,j,bi,bj)
144 ENDDO
145 ENDDO
146 ENDIF
147
148 #ifdef ALLOW_OBCS
149 IF (useOBCS) THEN
150 DO i=1,sNx
151 C Northern boundary
152 IF (OB_Jn(I,bi,bj).NE.0) THEN
153 cg2d_b(I,OB_Jn(I,bi,bj),bi,bj)=0.
154 cg2d_x(I,OB_Jn(I,bi,bj),bi,bj)=0.
155 ENDIF
156 C Southern boundary
157 IF (OB_Js(I,bi,bj).NE.0) THEN
158 cg2d_b(I,OB_Js(I,bi,bj),bi,bj)=0.
159 cg2d_x(I,OB_Js(I,bi,bj),bi,bj)=0.
160 ENDIF
161 ENDDO
162 DO j=1,sNy
163 C Eastern boundary
164 IF (OB_Ie(J,bi,bj).NE.0) THEN
165 cg2d_b(OB_Ie(J,bi,bj),J,bi,bj)=0.
166 cg2d_x(OB_Ie(J,bi,bj),J,bi,bj)=0.
167 ENDIF
168 C Western boundary
169 IF (OB_Iw(J,bi,bj).NE.0) THEN
170 cg2d_b(OB_Iw(J,bi,bj),J,bi,bj)=0.
171 cg2d_x(OB_Iw(J,bi,bj),J,bi,bj)=0.
172 ENDIF
173 ENDDO
174 ENDIF
175 #endif
176 ENDDO
177 ENDDO
178
179 #ifndef DISABLE_DEBUGMODE
180 IF (debugMode) THEN
181 CALL DEBUG_STATS_RL(1,cg2d_b,'cg2d_b (SOLVE_FOR_PRESSURE)',
182 & myThid)
183 ENDIF
184 #endif
185
186 C-- Find the surface pressure using a two-dimensional conjugate
187 C-- gradient solver.
188 C see CG2D.h for the interface to this routine.
189 firstResidual=0.
190 lastResidual=0.
191 numIters=cg2dMaxIters
192 CALL CG2D(
193 U cg2d_b,
194 U cg2d_x,
195 O firstResidual,
196 O lastResidual,
197 U numIters,
198 I myThid )
199 _EXCH_XY_R8(cg2d_x, myThid )
200
201 #ifndef DISABLE_DEBUGMODE
202 IF (debugMode) THEN
203 CALL DEBUG_STATS_RL(1,cg2d_x,'cg2d_x (SOLVE_FOR_PRESSURE)',
204 & myThid)
205 ENDIF
206 #endif
207
208 C- dump CG2D output at monitorFreq (to reduce size of STD-OUTPUT files) :
209 IF ( DIFFERENT_MULTIPLE(monitorFreq,myTime,
210 & myTime-deltaTClock) ) THEN
211 _BEGIN_MASTER( myThid )
212 WRITE(msgBuf,'(A34,1PE24.14)') 'cg2d_init_res =',firstResidual
213 CALL PRINT_MESSAGE(msgBuf,standardMessageUnit,SQUEEZE_RIGHT,1)
214 WRITE(msgBuf,'(A34,I6)') 'cg2d_iters =',numIters
215 CALL PRINT_MESSAGE(msgBuf,standardMessageUnit,SQUEEZE_RIGHT,1)
216 WRITE(msgBuf,'(A34,1PE24.14)') 'cg2d_res =',lastResidual
217 CALL PRINT_MESSAGE(msgBuf,standardMessageUnit,SQUEEZE_RIGHT,1)
218 _END_MASTER( )
219 ENDIF
220
221 C-- Transfert the 2D-solution to "etaN" :
222 DO bj=myByLo(myThid),myByHi(myThid)
223 DO bi=myBxLo(myThid),myBxHi(myThid)
224 DO j=1-OLy,sNy+OLy
225 DO i=1-OLx,sNx+OLx
226 etaN(i,j,bi,bj) = recip_Bo(i,j,bi,bj)*cg2d_x(i,j,bi,bj)
227 ENDDO
228 ENDDO
229 ENDDO
230 ENDDO
231
232 #ifdef ALLOW_NONHYDROSTATIC
233 IF ( nonHydrostatic ) THEN
234
235 C-- Solve for a three-dimensional pressure term (NH or IGW or both ).
236 C see CG3D.h for the interface to this routine.
237 DO bj=myByLo(myThid),myByHi(myThid)
238 DO bi=myBxLo(myThid),myBxHi(myThid)
239 DO j=1,sNy+1
240 DO i=1,sNx+1
241 uf(i,j)=-_recip_dxC(i,j,bi,bj)*
242 & (cg2d_x(i,j,bi,bj)-cg2d_x(i-1,j,bi,bj))
243 vf(i,j)=-_recip_dyC(i,j,bi,bj)*
244 & (cg2d_x(i,j,bi,bj)-cg2d_x(i,j-1,bi,bj))
245 ENDDO
246 ENDDO
247
248 #ifdef ALLOW_OBCS
249 IF (useOBCS) THEN
250 DO i=1,sNx+1
251 C Northern boundary
252 IF (OB_Jn(I,bi,bj).NE.0) THEN
253 vf(I,OB_Jn(I,bi,bj))=0.
254 ENDIF
255 C Southern boundary
256 IF (OB_Js(I,bi,bj).NE.0) THEN
257 vf(I,OB_Js(I,bi,bj)+1)=0.
258 ENDIF
259 ENDDO
260 DO j=1,sNy+1
261 C Eastern boundary
262 IF (OB_Ie(J,bi,bj).NE.0) THEN
263 uf(OB_Ie(J,bi,bj),J)=0.
264 ENDIF
265 C Western boundary
266 IF (OB_Iw(J,bi,bj).NE.0) THEN
267 uf(OB_Iw(J,bi,bj)+1,J)=0.
268 ENDIF
269 ENDDO
270 ENDIF
271 #endif
272
273 K=1
274 DO j=1,sNy
275 DO i=1,sNx
276 cg3d_b(i,j,k,bi,bj) = cg3d_b(i,j,k,bi,bj)
277 & +dRF(K)*dYG(i+1,j,bi,bj)*hFacW(i+1,j,k,bi,bj)*uf(i+1,j)
278 & -dRF(K)*dYG( i ,j,bi,bj)*hFacW( i ,j,k,bi,bj)*uf( i ,j)
279 & +dRF(K)*dXG(i,j+1,bi,bj)*hFacS(i,j+1,k,bi,bj)*vf(i,j+1)
280 & -dRF(K)*dXG(i, j ,bi,bj)*hFacS(i, j ,k,bi,bj)*vf(i, j )
281 & +( freeSurfFac*etaN(i,j,bi,bj)/deltaTMom
282 & -wVel(i,j,k+1,bi,bj)
283 & )*_rA(i,j,bi,bj)/deltaTmom
284 ENDDO
285 ENDDO
286 DO K=2,Nr-1
287 DO j=1,sNy
288 DO i=1,sNx
289 cg3d_b(i,j,k,bi,bj) = cg3d_b(i,j,k,bi,bj)
290 & +dRF(K)*dYG(i+1,j,bi,bj)*hFacW(i+1,j,k,bi,bj)*uf(i+1,j)
291 & -dRF(K)*dYG( i ,j,bi,bj)*hFacW( i ,j,k,bi,bj)*uf( i ,j)
292 & +dRF(K)*dXG(i,j+1,bi,bj)*hFacS(i,j+1,k,bi,bj)*vf(i,j+1)
293 & -dRF(K)*dXG(i, j ,bi,bj)*hFacS(i, j ,k,bi,bj)*vf(i, j )
294 & +( wVel(i,j,k ,bi,bj)
295 & -wVel(i,j,k+1,bi,bj)
296 & )*_rA(i,j,bi,bj)/deltaTmom
297
298 ENDDO
299 ENDDO
300 ENDDO
301 K=Nr
302 DO j=1,sNy
303 DO i=1,sNx
304 cg3d_b(i,j,k,bi,bj) = cg3d_b(i,j,k,bi,bj)
305 & +dRF(K)*dYG(i+1,j,bi,bj)*hFacW(i+1,j,k,bi,bj)*uf(i+1,j)
306 & -dRF(K)*dYG( i ,j,bi,bj)*hFacW( i ,j,k,bi,bj)*uf( i ,j)
307 & +dRF(K)*dXG(i,j+1,bi,bj)*hFacS(i,j+1,k,bi,bj)*vf(i,j+1)
308 & -dRF(K)*dXG(i, j ,bi,bj)*hFacS(i, j ,k,bi,bj)*vf(i, j )
309 & +( wVel(i,j,k ,bi,bj)
310 & )*_rA(i,j,bi,bj)/deltaTmom
311
312 ENDDO
313 ENDDO
314
315 #ifdef ALLOW_OBCS
316 IF (useOBCS) THEN
317 DO K=1,Nr
318 DO i=1,sNx
319 C Northern boundary
320 IF (OB_Jn(I,bi,bj).NE.0) THEN
321 cg3d_b(I,OB_Jn(I,bi,bj),K,bi,bj)=0.
322 ENDIF
323 C Southern boundary
324 IF (OB_Js(I,bi,bj).NE.0) THEN
325 cg3d_b(I,OB_Js(I,bi,bj),K,bi,bj)=0.
326 ENDIF
327 ENDDO
328 DO j=1,sNy
329 C Eastern boundary
330 IF (OB_Ie(J,bi,bj).NE.0) THEN
331 cg3d_b(OB_Ie(J,bi,bj),J,K,bi,bj)=0.
332 ENDIF
333 C Western boundary
334 IF (OB_Iw(J,bi,bj).NE.0) THEN
335 cg3d_b(OB_Iw(J,bi,bj),J,K,bi,bj)=0.
336 ENDIF
337 ENDDO
338 ENDDO
339 ENDIF
340 #endif
341
342 ENDDO ! bi
343 ENDDO ! bj
344
345 firstResidual=0.
346 lastResidual=0.
347 numIters=cg2dMaxIters
348 CALL CG3D(
349 U cg3d_b,
350 U phi_nh,
351 O firstResidual,
352 O lastResidual,
353 U numIters,
354 I myThid )
355 _EXCH_XYZ_R8(phi_nh, myThid )
356
357 _BEGIN_MASTER( myThid )
358 WRITE(msgBuf,'(A34,1PE24.14)') 'cg3d_init_res =',firstResidual
359 CALL PRINT_MESSAGE(msgBuf,standardMessageUnit,SQUEEZE_RIGHT,1)
360 WRITE(msgBuf,'(A34,I6)') 'cg3d_iters =',numIters
361 CALL PRINT_MESSAGE(msgBuf,standardMessageUnit,SQUEEZE_RIGHT,1)
362 WRITE(msgBuf,'(A34,1PE24.14)') 'cg3d_res =',lastResidual
363 CALL PRINT_MESSAGE(msgBuf,standardMessageUnit,SQUEEZE_RIGHT,1)
364 _END_MASTER( )
365
366 ENDIF
367 #endif
368
369 RETURN
370 END

  ViewVC Help
Powered by ViewVC 1.1.22