GCC Code Coverage Report


Directory: ./
File: dyn3d_common/ppm3d.f
Date: 2022-01-11 19:19:34
Exec Total Coverage
Lines: 0 975 0.0%
Branches: 0 634 0.0%

Line Branch Exec Source
1 !
2 ! $Id: ppm3d.F 2197 2015-02-09 07:13:05Z emillour $
3 !
4
5 cFrom lin@explorer.gsfc.nasa.gov Wed Apr 15 17:44:44 1998
6 cDate: Wed, 15 Apr 1998 11:37:03 -0400
7 cFrom: lin@explorer.gsfc.nasa.gov
8 cTo: Frederic.Hourdin@lmd.jussieu.fr
9 cSubject: 3D transport module of the GSFC CTM and GEOS GCM
10
11
12 cThis code is sent to you by S-J Lin, DAO, NASA-GSFC
13
14 cNote: this version is intended for machines like CRAY
15 C-90. No multitasking directives implemented.
16
17
18 C ********************************************************************
19 C
20 C TransPort Core for Goddard Chemistry Transport Model (G-CTM), Goddard
21 C Earth Observing System General Circulation Model (GEOS-GCM), and Data
22 C Assimilation System (GEOS-DAS).
23 C
24 C ********************************************************************
25 C
26 C Purpose: given horizontal winds on a hybrid sigma-p surfaces,
27 C one call to tpcore updates the 3-D mixing ratio
28 C fields one time step (NDT). [vertical mass flux is computed
29 C internally consistent with the discretized hydrostatic mass
30 C continuity equation of the C-Grid GEOS-GCM (for IGD=1)].
31 C
32 C Schemes: Multi-dimensional Flux Form Semi-Lagrangian (FFSL) scheme based
33 C on the van Leer or PPM.
34 C (see Lin and Rood 1996).
35 C Version 4.5
36 C Last modified: Dec. 5, 1996
37 C Major changes from version 4.0: a more general vertical hybrid sigma-
38 C pressure coordinate.
39 C Subroutines modified: xtp, ytp, fzppm, qckxyz
40 C Subroutines deleted: vanz
41 C
42 C Author: Shian-Jiann Lin
43 C mail address:
44 C Shian-Jiann Lin*
45 C Code 910.3, NASA/GSFC, Greenbelt, MD 20771
46 C Phone: 301-286-9540
47 C E-mail: lin@dao.gsfc.nasa.gov
48 C
49 C *affiliation:
50 C Joint Center for Earth Systems Technology
51 C The University of Maryland Baltimore County
52 C NASA - Goddard Space Flight Center
53 C References:
54 C
55 C 1. Lin, S.-J., and R. B. Rood, 1996: Multidimensional flux form semi-
56 C Lagrangian transport schemes. Mon. Wea. Rev., 124, 2046-2070.
57 C
58 C 2. Lin, S.-J., W. C. Chao, Y. C. Sud, and G. K. Walker, 1994: A class of
59 C the van Leer-type transport schemes and its applications to the moist-
60 C ure transport in a General Circulation Model. Mon. Wea. Rev., 122,
61 C 1575-1593.
62 C
63 C ****6***0*********0*********0*********0*********0*********0**********72
64 C
65 subroutine ppm3d(IGD,Q,PS1,PS2,U,V,W,NDT,IORD,JORD,KORD,NC,IMR,
66 & JNP,j1,NLAY,AP,BP,PT,AE,fill,dum,Umax)
67
68 implicit none
69
70 c rajout de d�clarations
71 c integer Jmax,kmax,ndt0,nstep,k,j,i,ic,l,js,jn,imh,iad,jad,krd
72 c integer iu,iiu,j2,jmr,js0,jt
73 c real dtdy,dtdy5,rcap,iml,jn0,imjm,pi,dl,dp
74 c real dt,cr1,maxdt,ztc,d5,sum1,sum2,ru
75 C
76 C ********************************************************************
77 C
78 C =============
79 C INPUT:
80 C =============
81 C
82 C Q(IMR,JNP,NLAY,NC): mixing ratios at current time (t)
83 C NC: total # of constituents
84 C IMR: first dimension (E-W); # of Grid intervals in E-W is IMR
85 C JNP: 2nd dimension (N-S); # of Grid intervals in N-S is JNP-1
86 C NLAY: 3rd dimension (# of layers); vertical index increases from 1 at
87 C the model top to NLAY near the surface (see fig. below).
88 C It is assumed that 6 <= NLAY <= JNP (for dynamic memory allocation)
89 C
90 C PS1(IMR,JNP): surface pressure at current time (t)
91 C PS2(IMR,JNP): surface pressure at mid-time-level (t+NDT/2)
92 C PS2 is replaced by the predicted PS (at t+NDT) on output.
93 C Note: surface pressure can have any unit or can be multiplied by any
94 C const.
95 C
96 C The pressure at layer edges are defined as follows:
97 C
98 C p(i,j,k) = AP(k)*PT + BP(k)*PS(i,j) (1)
99 C
100 C Where PT is a constant having the same unit as PS.
101 C AP and BP are unitless constants given at layer edges
102 C defining the vertical coordinate.
103 C BP(1) = 0., BP(NLAY+1) = 1.
104 C The pressure at the model top is PTOP = AP(1)*PT
105 C
106 C For pure sigma system set AP(k) = 1 for all k, PT = PTOP,
107 C BP(k) = sige(k) (sigma at edges), PS = Psfc - PTOP.
108 C
109 C Note: the sigma-P coordinate is a subset of Eq. 1, which in turn
110 C is a subset of the following even more general sigma-P-thelta coord.
111 C currently under development.
112 C p(i,j,k) = (AP(k)*PT + BP(k)*PS(i,j))/(D(k)-C(k)*TE**(-1/kapa))
113 C
114 C /////////////////////////////////
115 C / \ ------------- PTOP -------------- AP(1), BP(1)
116 C |
117 C delp(1) | ........... Q(i,j,1) ............
118 C |
119 C W(1) \ / --------------------------------- AP(2), BP(2)
120 C
121 C
122 C
123 C W(k-1) / \ --------------------------------- AP(k), BP(k)
124 C |
125 C delp(K) | ........... Q(i,j,k) ............
126 C |
127 C W(k) \ / --------------------------------- AP(k+1), BP(k+1)
128 C
129 C
130 C
131 C / \ --------------------------------- AP(NLAY), BP(NLAY)
132 C |
133 C delp(NLAY) | ........... Q(i,j,NLAY) .........
134 C |
135 C W(NLAY)=0 \ / ------------- surface ----------- AP(NLAY+1), BP(NLAY+1)
136 C //////////////////////////////////
137 C
138 C U(IMR,JNP,NLAY) & V(IMR,JNP,NLAY):winds (m/s) at mid-time-level (t+NDT/2)
139 C U and V may need to be polar filtered in advance in some cases.
140 C
141 C IGD: grid type on which winds are defined.
142 C IGD = 0: A-Grid [all variables defined at the same point from south
143 C pole (j=1) to north pole (j=JNP) ]
144 C
145 C IGD = 1 GEOS-GCM C-Grid
146 C [North]
147 C
148 C V(i,j)
149 C |
150 C |
151 C |
152 C U(i-1,j)---Q(i,j)---U(i,j) [EAST]
153 C |
154 C |
155 C |
156 C V(i,j-1)
157 C
158 C U(i, 1) is defined at South Pole.
159 C V(i, 1) is half grid north of the South Pole.
160 C V(i,JMR) is half grid south of the North Pole.
161 C
162 C V must be defined at j=1 and j=JMR if IGD=1
163 C V at JNP need not be given.
164 C
165 C NDT: time step in seconds (need not be constant during the course of
166 C the integration). Suggested value: 30 min. for 4x5, 15 min. for 2x2.5
167 C (Lat-Lon) resolution. Smaller values are recommanded if the model
168 C has a well-resolved stratosphere.
169 C
170 C J1 defines the size of the polar cap:
171 C South polar cap edge is located at -90 + (j1-1.5)*180/(JNP-1) deg.
172 C North polar cap edge is located at 90 - (j1-1.5)*180/(JNP-1) deg.
173 C There are currently only two choices (j1=2 or 3).
174 C IMR must be an even integer if j1 = 2. Recommended value: J1=3.
175 C
176 C IORD, JORD, and KORD are integers controlling various options in E-W, N-S,
177 C and vertical transport, respectively. Recommended values for positive
178 C definite scalars: IORD=JORD=3, KORD=5. Use KORD=3 for non-
179 C positive definite scalars or when linear correlation between constituents
180 C is to be maintained.
181 C
182 C _ORD=
183 C 1: 1st order upstream scheme (too diffusive, not a useful option; it
184 C can be used for debugging purposes; this is THE only known "linear"
185 C monotonic advection scheme.).
186 C 2: 2nd order van Leer (full monotonicity constraint;
187 C see Lin et al 1994, MWR)
188 C 3: monotonic PPM* (slightly improved PPM of Collela & Woodward 1984)
189 C 4: semi-monotonic PPM (same as 3, but overshoots are allowed)
190 C 5: positive-definite PPM (constraint on the subgrid distribution is
191 C only strong enough to prevent generation of negative values;
192 C both overshoots & undershoots are possible).
193 C 6: un-constrained PPM (nearly diffusion free; slightly faster but
194 C positivity not quaranteed. Use this option only when the fields
195 C and winds are very smooth).
196 C
197 C *PPM: Piece-wise Parabolic Method
198 C
199 C Note that KORD <=2 options are no longer supported. DO not use option 4 or 5.
200 C for non-positive definite scalars (such as Ertel Potential Vorticity).
201 C
202 C The implicit numerical diffusion decreases as _ORD increases.
203 C The last two options (ORDER=5, 6) should only be used when there is
204 C significant explicit diffusion (such as a turbulence parameterization). You
205 C might get dispersive results otherwise.
206 C No filter of any kind is applied to the constituent fields here.
207 C
208 C AE: Radius of the sphere (meters).
209 C Recommended value for the planet earth: 6.371E6
210 C
211 C fill(logical): flag to do filling for negatives (see note below).
212 C
213 C Umax: Estimate (upper limit) of the maximum U-wind speed (m/s).
214 C (220 m/s is a good value for troposphere model; 280 m/s otherwise)
215 C
216 C =============
217 C Output
218 C =============
219 C
220 C Q: mixing ratios at future time (t+NDT) (original values are over-written)
221 C W(NLAY): large-scale vertical mass flux as diagnosed from the hydrostatic
222 C relationship. W will have the same unit as PS1 and PS2 (eg, mb).
223 C W must be divided by NDT to get the correct mass-flux unit.
224 C The vertical Courant number C = W/delp_UPWIND, where delp_UPWIND
225 C is the pressure thickness in the "upwind" direction. For example,
226 C C(k) = W(k)/delp(k) if W(k) > 0;
227 C C(k) = W(k)/delp(k+1) if W(k) < 0.
228 C ( W > 0 is downward, ie, toward surface)
229 C PS2: predicted PS at t+NDT (original values are over-written)
230 C
231 C ********************************************************************
232 C NOTES:
233 C This forward-in-time upstream-biased transport scheme reduces to
234 C the 2nd order center-in-time center-in-space mass continuity eqn.
235 C if Q = 1 (constant fields will remain constant). This also ensures
236 C that the computed vertical velocity to be identical to GEOS-1 GCM
237 C for on-line transport.
238 C
239 C A larger polar cap is used if j1=3 (recommended for C-Grid winds or when
240 C winds are noisy near poles).
241 C
242 C Flux-Form Semi-Lagrangian transport in the East-West direction is used
243 C when and where Courant # is greater than one.
244 C
245 C The user needs to change the parameter Jmax or Kmax if the resolution
246 C is greater than 0.5 deg in N-S or 150 layers in the vertical direction.
247 C (this TransPort Core is otherwise resolution independent and can be used
248 C as a library routine).
249 C
250 C PPM is 4th order accurate when grid spacing is uniform (x & y); 3rd
251 C order accurate for non-uniform grid (vertical sigma coord.).
252 C
253 C Time step is limitted only by transport in the meridional direction.
254 C (the FFSL scheme is not implemented in the meridional direction).
255 C
256 C Since only 1-D limiters are applied, negative values could
257 C potentially be generated when large time step is used and when the
258 C initial fields contain discontinuities.
259 C This does not necessarily imply the integration is unstable.
260 C These negatives are typically very small. A filling algorithm is
261 C activated if the user set "fill" to be true.
262 C
263 C The van Leer scheme used here is nearly as accurate as the original PPM
264 C due to the use of a 4th order accurate reference slope. The PPM imple-
265 C mented here is an improvement over the original and is also based on
266 C the 4th order reference slope.
267 C
268 C ****6***0*********0*********0*********0*********0*********0**********72
269 C
270 C User modifiable parameters
271 C
272 integer,parameter :: Jmax = 361, kmax = 150
273 C
274 C ****6***0*********0*********0*********0*********0*********0**********72
275 C
276 C Input-Output arrays
277 C
278
279 real Q(IMR,JNP,NLAY,NC),PS1(IMR,JNP),PS2(IMR,JNP),
280 & U(IMR,JNP,NLAY),V(IMR,JNP,NLAY),AP(NLAY+1),
281 & BP(NLAY+1),W(IMR,JNP,NLAY),NDT,val(NLAY),Umax
282 integer IGD,IORD,JORD,KORD,NC,IMR,JNP,j1,NLAY,AE
283 integer IMRD2
284 real PT
285 logical cross, fill, dum
286 C
287 C Local dynamic arrays
288 C
289 real CRX(IMR,JNP),CRY(IMR,JNP),xmass(IMR,JNP),ymass(IMR,JNP),
290 & fx1(IMR+1),DPI(IMR,JNP,NLAY),delp1(IMR,JNP,NLAY),
291 & WK1(IMR,JNP,NLAY),PU(IMR,JNP),PV(IMR,JNP),DC2(IMR,JNP),
292 & delp2(IMR,JNP,NLAY),DQ(IMR,JNP,NLAY,NC),VA(IMR,JNP),
293 & UA(IMR,JNP),qtmp(-IMR:2*IMR)
294 C
295 C Local static arrays
296 C
297 real DTDX(Jmax), DTDX5(Jmax), acosp(Jmax),
298 & cosp(Jmax), cose(Jmax), DAP(kmax),DBK(Kmax)
299 data NDT0, NSTEP /0, 0/
300 data cross /.true./
301 REAL DTDY, DTDY5, RCAP
302 INTEGER JS0, JN0, IML, JMR, IMJM
303 SAVE DTDY, DTDY5, RCAP, JS0, JN0, IML,
304 & DTDX, DTDX5, ACOSP, COSP, COSE, DAP,DBK
305 C
306 INTEGER NDT0, NSTEP, j2, k,j,i,ic,l,JS,JN,IMH
307 INTEGER IU,IIU,JT,iad,jad,krd
308 REAL r23,r3,PI,DL,DP,DT,CR1,MAXDT,ZTC,D5
309 REAL sum1,sum2,ru
310
311 JMR = JNP -1
312 IMJM = IMR*JNP
313 j2 = JNP - j1 + 1
314 NSTEP = NSTEP + 1
315 C
316 C *********** Initialization **********************
317 if(NSTEP.eq.1) then
318 c
319 write(6,*) '------------------------------------ '
320 write(6,*) 'NASA/GSFC Transport Core Version 4.5'
321 write(6,*) '------------------------------------ '
322 c
323 WRITE(6,*) 'IMR=',IMR,' JNP=',JNP,' NLAY=',NLAY,' j1=',j1
324 WRITE(6,*) 'NC=',NC,IORD,JORD,KORD,NDT
325 C
326 C controles sur les parametres
327 if(NLAY.LT.6) then
328 write(6,*) 'NLAY must be >= 6'
329 stop
330 endif
331 if (JNP.LT.NLAY) then
332 write(6,*) 'JNP must be >= NLAY'
333 stop
334 endif
335 IMRD2=mod(IMR,2)
336 if (j1.eq.2.and.IMRD2.NE.0) then
337 write(6,*) 'if j1=2 IMR must be an even integer'
338 stop
339 endif
340
341 C
342 if(Jmax.lt.JNP .or. Kmax.lt.NLAY) then
343 write(6,*) 'Jmax or Kmax is too small'
344 stop
345 endif
346 C
347 DO k=1,NLAY
348 DAP(k) = (AP(k+1) - AP(k))*PT
349 DBK(k) = BP(k+1) - BP(k)
350 ENDDO
351 C
352 PI = 4. * ATAN(1.)
353 DL = 2.*PI / REAL(IMR)
354 DP = PI / REAL(JMR)
355 C
356 if(IGD.eq.0) then
357 C Compute analytic cosine at cell edges
358 call cosa(cosp,cose,JNP,PI,DP)
359 else
360 C Define cosine consistent with GEOS-GCM (using dycore2.0 or later)
361 call cosc(cosp,cose,JNP,PI,DP)
362 endif
363 C
364 do 15 J=2,JMR
365 15 acosp(j) = 1. / cosp(j)
366 C
367 C Inverse of the Scaled polar cap area.
368 C
369 RCAP = DP / (IMR*(1.-COS((j1-1.5)*DP)))
370 acosp(1) = RCAP
371 acosp(JNP) = RCAP
372 endif
373 C
374 if(NDT0 .ne. NDT) then
375 DT = NDT
376 NDT0 = NDT
377
378 if(Umax .lt. 180.) then
379 write(6,*) 'Umax may be too small!'
380 endif
381 CR1 = abs(Umax*DT)/(DL*AE)
382 MaxDT = DP*AE / abs(Umax) + 0.5
383 write(6,*)'Largest time step for max(V)=',Umax,' is ',MaxDT
384 if(MaxDT .lt. abs(NDT)) then
385 write(6,*) 'Warning!!! NDT maybe too large!'
386 endif
387 C
388 if(CR1.ge.0.95) then
389 JS0 = 0
390 JN0 = 0
391 IML = IMR-2
392 ZTC = 0.
393 else
394 ZTC = acos(CR1) * (180./PI)
395 C
396 JS0 = REAL(JMR)*(90.-ZTC)/180. + 2
397 JS0 = max(JS0, J1+1)
398 IML = min(6*JS0/(J1-1)+2, 4*IMR/5)
399 JN0 = JNP-JS0+1
400 endif
401 C
402 C
403 do J=2,JMR
404 DTDX(j) = DT / ( DL*AE*COSP(J) )
405
406 c print*,'dtdx=',dtdx(j)
407 DTDX5(j) = 0.5*DTDX(j)
408 enddo
409 C
410
411 DTDY = DT /(AE*DP)
412 c print*,'dtdy=',dtdy
413 DTDY5 = 0.5*DTDY
414 C
415 c write(6,*) 'J1=',J1,' J2=', J2
416 endif
417 C
418 C *********** End Initialization **********************
419 C
420 C delp = pressure thickness: the psudo-density in a hydrostatic system.
421 do k=1,NLAY
422 do j=1,JNP
423 do i=1,IMR
424 delp1(i,j,k)=DAP(k)+DBK(k)*PS1(i,j)
425 delp2(i,j,k)=DAP(k)+DBK(k)*PS2(i,j)
426 enddo
427 enddo
428 enddo
429
430 C
431 if(j1.ne.2) then
432 DO 40 IC=1,NC
433 DO 40 L=1,NLAY
434 DO 40 I=1,IMR
435 Q(I, 2,L,IC) = Q(I, 1,L,IC)
436 40 Q(I,JMR,L,IC) = Q(I,JNP,L,IC)
437 endif
438 C
439 C Compute "tracer density"
440 DO 550 IC=1,NC
441 DO 44 k=1,NLAY
442 DO 44 j=1,JNP
443 DO 44 i=1,IMR
444 44 DQ(i,j,k,IC) = Q(i,j,k,IC)*delp1(i,j,k)
445 550 continue
446 C
447 do 1500 k=1,NLAY
448 C
449 if(IGD.eq.0) then
450 C Convert winds on A-Grid to Courant # on C-Grid.
451 call A2C(U(1,1,k),V(1,1,k),IMR,JMR,j1,j2,CRX,CRY,dtdx5,DTDY5)
452 else
453 C Convert winds on C-grid to Courant #
454 do 45 j=j1,j2
455 do 45 i=2,IMR
456 45 CRX(i,J) = dtdx(j)*U(i-1,j,k)
457
458 C
459 do 50 j=j1,j2
460 50 CRX(1,J) = dtdx(j)*U(IMR,j,k)
461 C
462 do 55 i=1,IMR*JMR
463 55 CRY(i,2) = DTDY*V(i,1,k)
464 endif
465 C
466 C Determine JS and JN
467 JS = j1
468 JN = j2
469 C
470 do j=JS0,j1+1,-1
471 do i=1,IMR
472 if(abs(CRX(i,j)).GT.1.) then
473 JS = j
474 go to 2222
475 endif
476 enddo
477 enddo
478 C
479 2222 continue
480 do j=JN0,j2-1
481 do i=1,IMR
482 if(abs(CRX(i,j)).GT.1.) then
483 JN = j
484 go to 2233
485 endif
486 enddo
487 enddo
488 2233 continue
489 C
490 if(j1.ne.2) then ! Enlarged polar cap.
491 do i=1,IMR
492 DPI(i, 2,k) = 0.
493 DPI(i,JMR,k) = 0.
494 enddo
495 endif
496 C
497 C ******* Compute horizontal mass fluxes ************
498 C
499 C N-S component
500 do j=j1,j2+1
501 D5 = 0.5 * COSE(j)
502 do i=1,IMR
503 ymass(i,j) = CRY(i,j)*D5*(delp2(i,j,k) + delp2(i,j-1,k))
504 enddo
505 enddo
506 C
507 do 95 j=j1,j2
508 DO 95 i=1,IMR
509 95 DPI(i,j,k) = (ymass(i,j) - ymass(i,j+1)) * acosp(j)
510 C
511 C Poles
512 sum1 = ymass(IMR,j1 )
513 sum2 = ymass(IMR,J2+1)
514 do i=1,IMR-1
515 sum1 = sum1 + ymass(i,j1 )
516 sum2 = sum2 + ymass(i,J2+1)
517 enddo
518 C
519 sum1 = - sum1 * RCAP
520 sum2 = sum2 * RCAP
521 do i=1,IMR
522 DPI(i, 1,k) = sum1
523 DPI(i,JNP,k) = sum2
524 enddo
525 C
526 C E-W component
527 C
528 do j=j1,j2
529 do i=2,IMR
530 PU(i,j) = 0.5 * (delp2(i,j,k) + delp2(i-1,j,k))
531 enddo
532 enddo
533 C
534 do j=j1,j2
535 PU(1,j) = 0.5 * (delp2(1,j,k) + delp2(IMR,j,k))
536 enddo
537 C
538 do 110 j=j1,j2
539 DO 110 i=1,IMR
540 110 xmass(i,j) = PU(i,j)*CRX(i,j)
541 C
542 DO 120 j=j1,j2
543 DO 120 i=1,IMR-1
544 120 DPI(i,j,k) = DPI(i,j,k) + xmass(i,j) - xmass(i+1,j)
545 C
546 DO 130 j=j1,j2
547 130 DPI(IMR,j,k) = DPI(IMR,j,k) + xmass(IMR,j) - xmass(1,j)
548 C
549 DO j=j1,j2
550 do i=1,IMR-1
551 UA(i,j) = 0.5 * (CRX(i,j)+CRX(i+1,j))
552 enddo
553 enddo
554 C
555 DO j=j1,j2
556 UA(imr,j) = 0.5 * (CRX(imr,j)+CRX(1,j))
557 enddo
558 ccccccccccccccccccccccccccccccccccccccccccccccccccccccc
559 c Rajouts pour LMDZ.3.3
560 ccccccccccccccccccccccccccccccccccccccccccccccccccccccc
561 do i=1,IMR
562 do j=1,JNP
563 VA(i,j)=0.
564 enddo
565 enddo
566
567 do i=1,imr*(JMR-1)
568 VA(i,2) = 0.5*(CRY(i,2)+CRY(i,3))
569 enddo
570 C
571 if(j1.eq.2) then
572 IMH = IMR/2
573 do i=1,IMH
574 VA(i, 1) = 0.5*(CRY(i,2)-CRY(i+IMH,2))
575 VA(i+IMH, 1) = -VA(i,1)
576 VA(i, JNP) = 0.5*(CRY(i,JNP)-CRY(i+IMH,JMR))
577 VA(i+IMH,JNP) = -VA(i,JNP)
578 enddo
579 VA(IMR,1)=VA(1,1)
580 VA(IMR,JNP)=VA(1,JNP)
581 endif
582 C
583 C ****6***0*********0*********0*********0*********0*********0**********72
584 do 1000 IC=1,NC
585 C
586 do i=1,IMJM
587 wk1(i,1,1) = 0.
588 wk1(i,1,2) = 0.
589 enddo
590 C
591 C E-W advective cross term
592 do 250 j=J1,J2
593 if(J.GT.JS .and. J.LT.JN) GO TO 250
594 C
595 do i=1,IMR
596 qtmp(i) = q(i,j,k,IC)
597 enddo
598 C
599 do i=-IML,0
600 qtmp(i) = q(IMR+i,j,k,IC)
601 qtmp(IMR+1-i) = q(1-i,j,k,IC)
602 enddo
603 C
604 DO 230 i=1,IMR
605 iu = UA(i,j)
606 ru = UA(i,j) - iu
607 iiu = i-iu
608 if(UA(i,j).GE.0.) then
609 wk1(i,j,1) = qtmp(iiu)+ru*(qtmp(iiu-1)-qtmp(iiu))
610 else
611 wk1(i,j,1) = qtmp(iiu)+ru*(qtmp(iiu)-qtmp(iiu+1))
612 endif
613 wk1(i,j,1) = wk1(i,j,1) - qtmp(i)
614 230 continue
615 250 continue
616 C
617 if(JN.ne.0) then
618 do j=JS+1,JN-1
619 C
620 do i=1,IMR
621 qtmp(i) = q(i,j,k,IC)
622 enddo
623 C
624 qtmp(0) = q(IMR,J,k,IC)
625 qtmp(IMR+1) = q( 1,J,k,IC)
626 C
627 do i=1,imr
628 iu = i - UA(i,j)
629 wk1(i,j,1) = UA(i,j)*(qtmp(iu) - qtmp(iu+1))
630 enddo
631 enddo
632 endif
633 C ****6***0*********0*********0*********0*********0*********0**********72
634 C Contribution from the N-S advection
635 do i=1,imr*(j2-j1+1)
636 JT = REAL(J1) - VA(i,j1)
637 wk1(i,j1,2) = VA(i,j1) * (q(i,jt,k,IC) - q(i,jt+1,k,IC))
638 enddo
639 C
640 do i=1,IMJM
641 wk1(i,1,1) = q(i,1,k,IC) + 0.5*wk1(i,1,1)
642 wk1(i,1,2) = q(i,1,k,IC) + 0.5*wk1(i,1,2)
643 enddo
644 C
645 if(cross) then
646 C Add cross terms in the vertical direction.
647 if(IORD .GE. 2) then
648 iad = 2
649 else
650 iad = 1
651 endif
652 C
653 if(JORD .GE. 2) then
654 jad = 2
655 else
656 jad = 1
657 endif
658 call xadv(IMR,JNP,j1,j2,wk1(1,1,2),UA,JS,JN,IML,DC2,iad)
659 call yadv(IMR,JNP,j1,j2,wk1(1,1,1),VA,PV,W,jad)
660 do j=1,JNP
661 do i=1,IMR
662 q(i,j,k,IC) = q(i,j,k,IC) + DC2(i,j) + PV(i,j)
663 enddo
664 enddo
665 endif
666 C
667 call xtp(IMR,JNP,IML,j1,j2,JN,JS,PU,DQ(1,1,k,IC),wk1(1,1,2)
668 & ,CRX,fx1,xmass,IORD)
669
670 call ytp(IMR,JNP,j1,j2,acosp,RCAP,DQ(1,1,k,IC),wk1(1,1,1),CRY,
671 & DC2,ymass,WK1(1,1,3),wk1(1,1,4),WK1(1,1,5),WK1(1,1,6),JORD)
672 C
673 1000 continue
674 1500 continue
675 C
676 C ******* Compute vertical mass flux (same unit as PS) ***********
677 C
678 C 1st step: compute total column mass CONVERGENCE.
679 C
680 do 320 j=1,JNP
681 do 320 i=1,IMR
682 320 CRY(i,j) = DPI(i,j,1)
683 C
684 do 330 k=2,NLAY
685 do 330 j=1,JNP
686 do 330 i=1,IMR
687 CRY(i,j) = CRY(i,j) + DPI(i,j,k)
688 330 continue
689 C
690 do 360 j=1,JNP
691 do 360 i=1,IMR
692 C
693 C 2nd step: compute PS2 (PS at n+1) using the hydrostatic assumption.
694 C Changes (increases) to surface pressure = total column mass convergence
695 C
696 PS2(i,j) = PS1(i,j) + CRY(i,j)
697 C
698 C 3rd step: compute vertical mass flux from mass conservation principle.
699 C
700 W(i,j,1) = DPI(i,j,1) - DBK(1)*CRY(i,j)
701 W(i,j,NLAY) = 0.
702 360 continue
703 C
704 do 370 k=2,NLAY-1
705 do 370 j=1,JNP
706 do 370 i=1,IMR
707 W(i,j,k) = W(i,j,k-1) + DPI(i,j,k) - DBK(k)*CRY(i,j)
708 370 continue
709 C
710 DO 380 k=1,NLAY
711 DO 380 j=1,JNP
712 DO 380 i=1,IMR
713 delp2(i,j,k) = DAP(k) + DBK(k)*PS2(i,j)
714 380 continue
715 C
716 KRD = max(3, KORD)
717 do 4000 IC=1,NC
718 C
719 C****6***0*********0*********0*********0*********0*********0**********72
720
721 call FZPPM(IMR,JNP,NLAY,j1,DQ(1,1,1,IC),W,Q(1,1,1,IC),WK1,DPI,
722 & DC2,CRX,CRY,PU,PV,xmass,ymass,delp1,KRD)
723 C
724
725 if(fill) call qckxyz(DQ(1,1,1,IC),DC2,IMR,JNP,NLAY,j1,j2,
726 & cosp,acosp,.false.,IC,NSTEP)
727 C
728 C Recover tracer mixing ratio from "density" using predicted
729 C "air density" (pressure thickness) at time-level n+1
730 C
731 DO k=1,NLAY
732 DO j=1,JNP
733 DO i=1,IMR
734 Q(i,j,k,IC) = DQ(i,j,k,IC) / delp2(i,j,k)
735 c print*,'i=',i,'j=',j,'k=',k,'Q(i,j,k,IC)=',Q(i,j,k,IC)
736 enddo
737 enddo
738 enddo
739 C
740 if(j1.ne.2) then
741 DO 400 k=1,NLAY
742 DO 400 I=1,IMR
743 c j=1 c'est le p�le Sud, j=JNP c'est le p�le Nord
744 Q(I, 2,k,IC) = Q(I, 1,k,IC)
745 Q(I,JMR,k,IC) = Q(I,JNP,k,IC)
746 400 CONTINUE
747 endif
748 4000 continue
749 C
750 if(j1.ne.2) then
751 DO 5000 k=1,NLAY
752 DO 5000 i=1,IMR
753 W(i, 2,k) = W(i, 1,k)
754 W(i,JMR,k) = W(i,JNP,k)
755 5000 continue
756 endif
757 C
758 RETURN
759 END
760 C
761 C****6***0*********0*********0*********0*********0*********0**********72
762 subroutine FZPPM(IMR,JNP,NLAY,j1,DQ,WZ,P,DC,DQDT,AR,AL,A6,
763 & flux,wk1,wk2,wz2,delp,KORD)
764 implicit none
765 integer,parameter :: kmax = 150
766 real,parameter :: R23 = 2./3., R3 = 1./3.
767 integer IMR,JNP,NLAY,J1,KORD
768 real WZ(IMR,JNP,NLAY),P(IMR,JNP,NLAY),DC(IMR,JNP,NLAY),
769 & wk1(IMR,*),delp(IMR,JNP,NLAY),DQ(IMR,JNP,NLAY),
770 & DQDT(IMR,JNP,NLAY)
771 C Assuming JNP >= NLAY
772 real AR(IMR,*),AL(IMR,*),A6(IMR,*),flux(IMR,*),wk2(IMR,*),
773 & wz2(IMR,*)
774 integer JMR,IMJM,NLAYM1,LMT,K,I,J
775 real c0,c1,c2,tmp,qmax,qmin,a,b,fct,a1,a2,cm,cp
776 C
777 JMR = JNP - 1
778 IMJM = IMR*JNP
779 NLAYM1 = NLAY - 1
780 C
781 LMT = KORD - 3
782 C
783 C ****6***0*********0*********0*********0*********0*********0**********72
784 C Compute DC for PPM
785 C ****6***0*********0*********0*********0*********0*********0**********72
786 C
787 do 1000 k=1,NLAYM1
788 do 1000 i=1,IMJM
789 DQDT(i,1,k) = P(i,1,k+1) - P(i,1,k)
790 1000 continue
791 C
792 DO 1220 k=2,NLAYM1
793 DO 1220 I=1,IMJM
794 c0 = delp(i,1,k) / (delp(i,1,k-1)+delp(i,1,k)+delp(i,1,k+1))
795 c1 = (delp(i,1,k-1)+0.5*delp(i,1,k))/(delp(i,1,k+1)+delp(i,1,k))
796 c2 = (delp(i,1,k+1)+0.5*delp(i,1,k))/(delp(i,1,k-1)+delp(i,1,k))
797 tmp = c0*(c1*DQDT(i,1,k) + c2*DQDT(i,1,k-1))
798 Qmax = max(P(i,1,k-1),P(i,1,k),P(i,1,k+1)) - P(i,1,k)
799 Qmin = P(i,1,k) - min(P(i,1,k-1),P(i,1,k),P(i,1,k+1))
800 DC(i,1,k) = sign(min(abs(tmp),Qmax,Qmin), tmp)
801 1220 CONTINUE
802
803 C
804 C ****6***0*********0*********0*********0*********0*********0**********72
805 C Loop over latitudes (to save memory)
806 C ****6***0*********0*********0*********0*********0*********0**********72
807 C
808 DO 2000 j=1,JNP
809 if((j.eq.2 .or. j.eq.JMR) .and. j1.ne.2) goto 2000
810 C
811 DO k=1,NLAY
812 DO i=1,IMR
813 wz2(i,k) = WZ(i,j,k)
814 wk1(i,k) = P(i,j,k)
815 wk2(i,k) = delp(i,j,k)
816 flux(i,k) = DC(i,j,k) !this flux is actually the monotone slope
817 enddo
818 enddo
819 C
820 C****6***0*********0*********0*********0*********0*********0**********72
821 C Compute first guesses at cell interfaces
822 C First guesses are required to be continuous.
823 C ****6***0*********0*********0*********0*********0*********0**********72
824 C
825 C three-cell parabolic subgrid distribution at model top
826 C two-cell parabolic with zero gradient subgrid distribution
827 C at the surface.
828 C
829 C First guess top edge value
830 DO 10 i=1,IMR
831 C three-cell PPM
832 C Compute a,b, and c of q = aP**2 + bP + c using cell averages and delp
833 a = 3.*( DQDT(i,j,2) - DQDT(i,j,1)*(wk2(i,2)+wk2(i,3))/
834 & (wk2(i,1)+wk2(i,2)) ) /
835 & ( (wk2(i,2)+wk2(i,3))*(wk2(i,1)+wk2(i,2)+wk2(i,3)) )
836 b = 2.*DQDT(i,j,1)/(wk2(i,1)+wk2(i,2)) -
837 & R23*a*(2.*wk2(i,1)+wk2(i,2))
838 AL(i,1) = wk1(i,1) - wk2(i,1)*(R3*a*wk2(i,1) + 0.5*b)
839 AL(i,2) = wk2(i,1)*(a*wk2(i,1) + b) + AL(i,1)
840 C
841 C Check if change sign
842 if(wk1(i,1)*AL(i,1).le.0.) then
843 AL(i,1) = 0.
844 flux(i,1) = 0.
845 else
846 flux(i,1) = wk1(i,1) - AL(i,1)
847 endif
848 10 continue
849 C
850 C Bottom
851 DO 15 i=1,IMR
852 C 2-cell PPM with zero gradient right at the surface
853 C
854 fct = DQDT(i,j,NLAYM1)*wk2(i,NLAY)**2 /
855 & ( (wk2(i,NLAY)+wk2(i,NLAYM1))*(2.*wk2(i,NLAY)+wk2(i,NLAYM1)))
856 AR(i,NLAY) = wk1(i,NLAY) + fct
857 AL(i,NLAY) = wk1(i,NLAY) - (fct+fct)
858 if(wk1(i,NLAY)*AR(i,NLAY).le.0.) AR(i,NLAY) = 0.
859 flux(i,NLAY) = AR(i,NLAY) - wk1(i,NLAY)
860 15 continue
861
862 C
863 C****6***0*********0*********0*********0*********0*********0**********72
864 C 4th order interpolation in the interior.
865 C****6***0*********0*********0*********0*********0*********0**********72
866 C
867 DO 14 k=3,NLAYM1
868 DO 12 i=1,IMR
869 c1 = DQDT(i,j,k-1)*wk2(i,k-1) / (wk2(i,k-1)+wk2(i,k))
870 c2 = 2. / (wk2(i,k-2)+wk2(i,k-1)+wk2(i,k)+wk2(i,k+1))
871 A1 = (wk2(i,k-2)+wk2(i,k-1)) / (2.*wk2(i,k-1)+wk2(i,k))
872 A2 = (wk2(i,k )+wk2(i,k+1)) / (2.*wk2(i,k)+wk2(i,k-1))
873 AL(i,k) = wk1(i,k-1) + c1 + c2 *
874 & ( wk2(i,k )*(c1*(A1 - A2)+A2*flux(i,k-1)) -
875 & wk2(i,k-1)*A1*flux(i,k) )
876 C print *,'AL1',i,k, AL(i,k)
877 12 CONTINUE
878 14 continue
879 C
880 do 20 i=1,IMR*NLAYM1
881 AR(i,1) = AL(i,2)
882 C print *,'AR1',i,AR(i,1)
883 20 continue
884 C
885 do 30 i=1,IMR*NLAY
886 A6(i,1) = 3.*(wk1(i,1)+wk1(i,1) - (AL(i,1)+AR(i,1)))
887 C print *,'A61',i,A6(i,1)
888 30 continue
889 C
890 C****6***0*********0*********0*********0*********0*********0**********72
891 C Top & Bot always monotonic
892 call lmtppm(flux(1,1),A6(1,1),AR(1,1),AL(1,1),wk1(1,1),IMR,0)
893 call lmtppm(flux(1,NLAY),A6(1,NLAY),AR(1,NLAY),AL(1,NLAY),
894 & wk1(1,NLAY),IMR,0)
895 C
896 C Interior depending on KORD
897 if(LMT.LE.2)
898 & call lmtppm(flux(1,2),A6(1,2),AR(1,2),AL(1,2),wk1(1,2),
899 & IMR*(NLAY-2),LMT)
900 C
901 C****6***0*********0*********0*********0*********0*********0**********72
902 C
903 DO 140 i=1,IMR*NLAYM1
904 IF(wz2(i,1).GT.0.) then
905 CM = wz2(i,1) / wk2(i,1)
906 flux(i,2) = AR(i,1)+0.5*CM*(AL(i,1)-AR(i,1)+A6(i,1)*(1.-R23*CM))
907 else
908 C print *,'test2-0',i,j,wz2(i,1),wk2(i,2)
909 CP= wz2(i,1) / wk2(i,2)
910 C print *,'testCP',CP
911 flux(i,2) = AL(i,2)+0.5*CP*(AL(i,2)-AR(i,2)-A6(i,2)*(1.+R23*CP))
912 C print *,'test2',i, AL(i,2),AR(i,2),A6(i,2),R23
913 endif
914 140 continue
915 C
916 DO 250 i=1,IMR*NLAYM1
917 flux(i,2) = wz2(i,1) * flux(i,2)
918 250 continue
919 C
920 do 350 i=1,IMR
921 DQ(i,j, 1) = DQ(i,j, 1) - flux(i, 2)
922 DQ(i,j,NLAY) = DQ(i,j,NLAY) + flux(i,NLAY)
923 350 continue
924 C
925 do 360 k=2,NLAYM1
926 do 360 i=1,IMR
927 360 DQ(i,j,k) = DQ(i,j,k) + flux(i,k) - flux(i,k+1)
928 2000 continue
929 return
930 end
931 C
932 subroutine xtp(IMR,JNP,IML,j1,j2,JN,JS,PU,DQ,Q,UC,
933 & fx1,xmass,IORD)
934 implicit none
935 integer IMR,JNP,IML,j1,j2,JN,JS,IORD
936 real PU,DQ,Q,UC,fx1,xmass
937 real dc,qtmp
938 integer ISAVE(IMR)
939 dimension UC(IMR,*),DC(-IML:IMR+IML+1),xmass(IMR,JNP)
940 & ,fx1(IMR+1),DQ(IMR,JNP),qtmp(-IML:IMR+1+IML)
941 dimension PU(IMR,JNP),Q(IMR,JNP)
942 integer jvan,j1vl,j2vl,j,i,iu,itmp,ist,imp
943 real rut
944 C
945 IMP = IMR + 1
946 C
947 C van Leer at high latitudes
948 jvan = max(1,JNP/18)
949 j1vl = j1+jvan
950 j2vl = j2-jvan
951 C
952 do 1310 j=j1,j2
953 C
954 do i=1,IMR
955 qtmp(i) = q(i,j)
956 enddo
957 C
958 if(j.ge.JN .or. j.le.JS) goto 2222
959 C ************* Eulerian **********
960 C
961 qtmp(0) = q(IMR,J)
962 qtmp(-1) = q(IMR-1,J)
963 qtmp(IMP) = q(1,J)
964 qtmp(IMP+1) = q(2,J)
965 C
966 IF(IORD.eq.1 .or. j.eq.j1. or. j.eq.j2) THEN
967 DO 1406 i=1,IMR
968 iu = REAL(i) - uc(i,j)
969 1406 fx1(i) = qtmp(iu)
970 ELSE
971 call xmist(IMR,IML,Qtmp,DC)
972 DC(0) = DC(IMR)
973 C
974 if(IORD.eq.2 .or. j.le.j1vl .or. j.ge.j2vl) then
975 DO 1408 i=1,IMR
976 iu = REAL(i) - uc(i,j)
977 1408 fx1(i) = qtmp(iu) + DC(iu)*(sign(1.,uc(i,j))-uc(i,j))
978 else
979 call fxppm(IMR,IML,UC(1,j),Qtmp,DC,fx1,IORD)
980 endif
981 C
982 ENDIF
983 C
984 DO 1506 i=1,IMR
985 1506 fx1(i) = fx1(i)*xmass(i,j)
986 C
987 goto 1309
988 C
989 C ***** Conservative (flux-form) Semi-Lagrangian transport *****
990 C
991 2222 continue
992 C
993 do i=-IML,0
994 qtmp(i) = q(IMR+i,j)
995 qtmp(IMP-i) = q(1-i,j)
996 enddo
997 C
998 IF(IORD.eq.1 .or. j.eq.j1. or. j.eq.j2) THEN
999 DO 1306 i=1,IMR
1000 itmp = INT(uc(i,j))
1001 ISAVE(i) = i - itmp
1002 iu = i - uc(i,j)
1003 1306 fx1(i) = (uc(i,j) - itmp)*qtmp(iu)
1004 ELSE
1005 call xmist(IMR,IML,Qtmp,DC)
1006 C
1007 do i=-IML,0
1008 DC(i) = DC(IMR+i)
1009 DC(IMP-i) = DC(1-i)
1010 enddo
1011 C
1012 DO 1307 i=1,IMR
1013 itmp = INT(uc(i,j))
1014 rut = uc(i,j) - itmp
1015 ISAVE(i) = i - itmp
1016 iu = i - uc(i,j)
1017 1307 fx1(i) = rut*(qtmp(iu) + DC(iu)*(sign(1.,rut) - rut))
1018 ENDIF
1019 C
1020 do 1308 i=1,IMR
1021 IF(uc(i,j).GT.1.) then
1022 CDIR$ NOVECTOR
1023 do ist = ISAVE(i),i-1
1024 fx1(i) = fx1(i) + qtmp(ist)
1025 enddo
1026 elseIF(uc(i,j).LT.-1.) then
1027 do ist = i,ISAVE(i)-1
1028 fx1(i) = fx1(i) - qtmp(ist)
1029 enddo
1030 CDIR$ VECTOR
1031 endif
1032 1308 continue
1033 do i=1,IMR
1034 fx1(i) = PU(i,j)*fx1(i)
1035 enddo
1036 C
1037 C ***************************************
1038 C
1039 1309 fx1(IMP) = fx1(1)
1040 DO 1215 i=1,IMR
1041 1215 DQ(i,j) = DQ(i,j) + fx1(i)-fx1(i+1)
1042 C
1043 C ***************************************
1044 C
1045 1310 continue
1046 return
1047 end
1048 C
1049 subroutine fxppm(IMR,IML,UT,P,DC,flux,IORD)
1050 implicit none
1051 integer IMR,IML,IORD
1052 real UT,P,DC,flux
1053 real,parameter :: R3 = 1./3., R23 = 2./3.
1054 DIMENSION UT(*),flux(*),P(-IML:IMR+IML+1),DC(-IML:IMR+IML+1)
1055 REAL :: AR(0:IMR),AL(0:IMR),A6(0:IMR)
1056 integer LMT,IMP,JLVL,i
1057 c logical first
1058 c data first /.true./
1059 c SAVE LMT
1060 c if(first) then
1061 C
1062 C correction calcul de LMT a chaque passage pour pouvoir choisir
1063 c plusieurs schemas PPM pour differents traceurs
1064 c IF (IORD.LE.0) then
1065 c if(IMR.GE.144) then
1066 c LMT = 0
1067 c elseif(IMR.GE.72) then
1068 c LMT = 1
1069 c else
1070 c LMT = 2
1071 c endif
1072 c else
1073 c LMT = IORD - 3
1074 c endif
1075 C
1076 LMT = IORD - 3
1077 c write(6,*) 'PPM option in E-W direction = ', LMT
1078 c first = .false.
1079 C endif
1080 C
1081 DO 10 i=1,IMR
1082 10 AL(i) = 0.5*(p(i-1)+p(i)) + (DC(i-1) - DC(i))*R3
1083 C
1084 do 20 i=1,IMR-1
1085 20 AR(i) = AL(i+1)
1086 AR(IMR) = AL(1)
1087 C
1088 do 30 i=1,IMR
1089 30 A6(i) = 3.*(p(i)+p(i) - (AL(i)+AR(i)))
1090 C
1091 if(LMT.LE.2) call lmtppm(DC(1),A6(1),AR(1),AL(1),P(1),IMR,LMT)
1092 C
1093 AL(0) = AL(IMR)
1094 AR(0) = AR(IMR)
1095 A6(0) = A6(IMR)
1096 C
1097 DO i=1,IMR
1098 IF(UT(i).GT.0.) then
1099 flux(i) = AR(i-1) + 0.5*UT(i)*(AL(i-1) - AR(i-1) +
1100 & A6(i-1)*(1.-R23*UT(i)) )
1101 else
1102 flux(i) = AL(i) - 0.5*UT(i)*(AR(i) - AL(i) +
1103 & A6(i)*(1.+R23*UT(i)))
1104 endif
1105 enddo
1106 return
1107 end
1108 C
1109 subroutine xmist(IMR,IML,P,DC)
1110 implicit none
1111 integer IMR,IML
1112 real,parameter :: R24 = 1./24.
1113 real :: P(-IML:IMR+1+IML),DC(-IML:IMR+1+IML)
1114 integer :: i
1115 real :: tmp,pmax,pmin
1116 C
1117 do 10 i=1,IMR
1118 tmp = R24*(8.*(p(i+1) - p(i-1)) + p(i-2) - p(i+2))
1119 Pmax = max(P(i-1), p(i), p(i+1)) - p(i)
1120 Pmin = p(i) - min(P(i-1), p(i), p(i+1))
1121 10 DC(i) = sign(min(abs(tmp),Pmax,Pmin), tmp)
1122 return
1123 end
1124 C
1125 subroutine ytp(IMR,JNP,j1,j2,acosp,RCAP,DQ,P,VC,DC2
1126 & ,ymass,fx,A6,AR,AL,JORD)
1127 implicit none
1128 integer :: IMR,JNP,j1,j2,JORD
1129 real :: acosp,RCAP,DQ,P,VC,DC2,ymass,fx,A6,AR,AL
1130 dimension P(IMR,JNP),VC(IMR,JNP),ymass(IMR,JNP)
1131 & ,DC2(IMR,JNP),DQ(IMR,JNP),acosp(JNP)
1132 C Work array
1133 DIMENSION fx(IMR,JNP),AR(IMR,JNP),AL(IMR,JNP),A6(IMR,JNP)
1134 integer :: JMR,len,i,jt,j
1135 real :: sum1,sum2
1136 C
1137 JMR = JNP - 1
1138 len = IMR*(J2-J1+2)
1139 C
1140 if(JORD.eq.1) then
1141 DO 1000 i=1,len
1142 JT = REAL(J1) - VC(i,J1)
1143 1000 fx(i,j1) = p(i,JT)
1144 else
1145
1146 call ymist(IMR,JNP,j1,P,DC2,4)
1147 C
1148 if(JORD.LE.0 .or. JORD.GE.3) then
1149
1150 call fyppm(VC,P,DC2,fx,IMR,JNP,j1,j2,A6,AR,AL,JORD)
1151
1152 else
1153 DO 1200 i=1,len
1154 JT = REAL(J1) - VC(i,J1)
1155 1200 fx(i,j1) = p(i,JT) + (sign(1.,VC(i,j1))-VC(i,j1))*DC2(i,JT)
1156 endif
1157 endif
1158 C
1159 DO 1300 i=1,len
1160 1300 fx(i,j1) = fx(i,j1)*ymass(i,j1)
1161 C
1162 DO 1400 j=j1,j2
1163 DO 1400 i=1,IMR
1164 1400 DQ(i,j) = DQ(i,j) + (fx(i,j) - fx(i,j+1)) * acosp(j)
1165 C
1166 C Poles
1167 sum1 = fx(IMR,j1 )
1168 sum2 = fx(IMR,J2+1)
1169 do i=1,IMR-1
1170 sum1 = sum1 + fx(i,j1 )
1171 sum2 = sum2 + fx(i,J2+1)
1172 enddo
1173 C
1174 sum1 = DQ(1, 1) - sum1 * RCAP
1175 sum2 = DQ(1,JNP) + sum2 * RCAP
1176 do i=1,IMR
1177 DQ(i, 1) = sum1
1178 DQ(i,JNP) = sum2
1179 enddo
1180 C
1181 if(j1.ne.2) then
1182 do i=1,IMR
1183 DQ(i, 2) = sum1
1184 DQ(i,JMR) = sum2
1185 enddo
1186 endif
1187 C
1188 return
1189 end
1190 C
1191 subroutine ymist(IMR,JNP,j1,P,DC,ID)
1192 implicit none
1193 integer :: IMR,JNP,j1,ID
1194 real,parameter :: R24 = 1./24.
1195 real :: P(IMR,JNP),DC(IMR,JNP)
1196 integer :: iimh,jmr,ijm3,imh,i
1197 real :: pmax,pmin,tmp
1198 C
1199 IMH = IMR / 2
1200 JMR = JNP - 1
1201 IJM3 = IMR*(JMR-3)
1202 C
1203 IF(ID.EQ.2) THEN
1204 do 10 i=1,IMR*(JMR-1)
1205 tmp = 0.25*(p(i,3) - p(i,1))
1206 Pmax = max(p(i,1),p(i,2),p(i,3)) - p(i,2)
1207 Pmin = p(i,2) - min(p(i,1),p(i,2),p(i,3))
1208 DC(i,2) = sign(min(abs(tmp),Pmin,Pmax),tmp)
1209 10 CONTINUE
1210 ELSE
1211 do 12 i=1,IMH
1212 C J=2
1213 tmp = (8.*(p(i,3) - p(i,1)) + p(i+IMH,2) - p(i,4))*R24
1214 Pmax = max(p(i,1),p(i,2),p(i,3)) - p(i,2)
1215 Pmin = p(i,2) - min(p(i,1),p(i,2),p(i,3))
1216 DC(i,2) = sign(min(abs(tmp),Pmin,Pmax),tmp)
1217 C J=JMR
1218 tmp=(8.*(p(i,JNP)-p(i,JMR-1))+p(i,JMR-2)-p(i+IMH,JMR))*R24
1219 Pmax = max(p(i,JMR-1),p(i,JMR),p(i,JNP)) - p(i,JMR)
1220 Pmin = p(i,JMR) - min(p(i,JMR-1),p(i,JMR),p(i,JNP))
1221 DC(i,JMR) = sign(min(abs(tmp),Pmin,Pmax),tmp)
1222 12 CONTINUE
1223 do 14 i=IMH+1,IMR
1224 C J=2
1225 tmp = (8.*(p(i,3) - p(i,1)) + p(i-IMH,2) - p(i,4))*R24
1226 Pmax = max(p(i,1),p(i,2),p(i,3)) - p(i,2)
1227 Pmin = p(i,2) - min(p(i,1),p(i,2),p(i,3))
1228 DC(i,2) = sign(min(abs(tmp),Pmin,Pmax),tmp)
1229 C J=JMR
1230 tmp=(8.*(p(i,JNP)-p(i,JMR-1))+p(i,JMR-2)-p(i-IMH,JMR))*R24
1231 Pmax = max(p(i,JMR-1),p(i,JMR),p(i,JNP)) - p(i,JMR)
1232 Pmin = p(i,JMR) - min(p(i,JMR-1),p(i,JMR),p(i,JNP))
1233 DC(i,JMR) = sign(min(abs(tmp),Pmin,Pmax),tmp)
1234 14 CONTINUE
1235 C
1236 do 15 i=1,IJM3
1237 tmp = (8.*(p(i,4) - p(i,2)) + p(i,1) - p(i,5))*R24
1238 Pmax = max(p(i,2),p(i,3),p(i,4)) - p(i,3)
1239 Pmin = p(i,3) - min(p(i,2),p(i,3),p(i,4))
1240 DC(i,3) = sign(min(abs(tmp),Pmin,Pmax),tmp)
1241 15 CONTINUE
1242 ENDIF
1243 C
1244 if(j1.ne.2) then
1245 do i=1,IMR
1246 DC(i,1) = 0.
1247 DC(i,JNP) = 0.
1248 enddo
1249 else
1250 C Determine slopes in polar caps for scalars!
1251 C
1252 do 13 i=1,IMH
1253 C South
1254 tmp = 0.25*(p(i,2) - p(i+imh,2))
1255 Pmax = max(p(i,2),p(i,1), p(i+imh,2)) - p(i,1)
1256 Pmin = p(i,1) - min(p(i,2),p(i,1), p(i+imh,2))
1257 DC(i,1)=sign(min(abs(tmp),Pmax,Pmin),tmp)
1258 C North.
1259 tmp = 0.25*(p(i+imh,JMR) - p(i,JMR))
1260 Pmax = max(p(i+imh,JMR),p(i,jnp), p(i,JMR)) - p(i,JNP)
1261 Pmin = p(i,JNP) - min(p(i+imh,JMR),p(i,jnp), p(i,JMR))
1262 DC(i,JNP) = sign(min(abs(tmp),Pmax,pmin),tmp)
1263 13 continue
1264 C
1265 do 25 i=imh+1,IMR
1266 DC(i, 1) = - DC(i-imh, 1)
1267 DC(i,JNP) = - DC(i-imh,JNP)
1268 25 continue
1269 endif
1270 return
1271 end
1272 C
1273 subroutine fyppm(VC,P,DC,flux,IMR,JNP,j1,j2,A6,AR,AL,JORD)
1274 implicit none
1275 integer IMR,JNP,j1,j2,JORD
1276 real,parameter :: R3 = 1./3., R23 = 2./3.
1277 real VC(IMR,*),flux(IMR,*),P(IMR,*),DC(IMR,*)
1278 C Local work arrays.
1279 real AR(IMR,JNP),AL(IMR,JNP),A6(IMR,JNP)
1280 integer LMT,i
1281 integer IMH,JMR,j11,IMJM1,len
1282 c logical first
1283 C data first /.true./
1284 C SAVE LMT
1285 C
1286 IMH = IMR / 2
1287 JMR = JNP - 1
1288 j11 = j1-1
1289 IMJM1 = IMR*(J2-J1+2)
1290 len = IMR*(J2-J1+3)
1291 C if(first) then
1292 C IF(JORD.LE.0) then
1293 C if(JMR.GE.90) then
1294 C LMT = 0
1295 C elseif(JMR.GE.45) then
1296 C LMT = 1
1297 C else
1298 C LMT = 2
1299 C endif
1300 C else
1301 C LMT = JORD - 3
1302 C endif
1303 C
1304 C first = .false.
1305 C endif
1306 C
1307 c modifs pour pouvoir choisir plusieurs schemas PPM
1308 LMT = JORD - 3
1309 C
1310 DO 10 i=1,IMR*JMR
1311 AL(i,2) = 0.5*(p(i,1)+p(i,2)) + (DC(i,1) - DC(i,2))*R3
1312 AR(i,1) = AL(i,2)
1313 10 CONTINUE
1314 C
1315 CPoles:
1316 C
1317 DO i=1,IMH
1318 AL(i,1) = AL(i+IMH,2)
1319 AL(i+IMH,1) = AL(i,2)
1320 C
1321 AR(i,JNP) = AR(i+IMH,JMR)
1322 AR(i+IMH,JNP) = AR(i,JMR)
1323 ENDDO
1324
1325 ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
1326 c Rajout pour LMDZ.3.3
1327 cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
1328 AR(IMR,1)=AL(1,1)
1329 AR(IMR,JNP)=AL(1,JNP)
1330 ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
1331
1332
1333 do 30 i=1,len
1334 30 A6(i,j11) = 3.*(p(i,j11)+p(i,j11) - (AL(i,j11)+AR(i,j11)))
1335 C
1336 if(LMT.le.2) call lmtppm(DC(1,j11),A6(1,j11),AR(1,j11)
1337 & ,AL(1,j11),P(1,j11),len,LMT)
1338 C
1339
1340 DO 140 i=1,IMJM1
1341 IF(VC(i,j1).GT.0.) then
1342 flux(i,j1) = AR(i,j11) + 0.5*VC(i,j1)*(AL(i,j11) - AR(i,j11) +
1343 & A6(i,j11)*(1.-R23*VC(i,j1)) )
1344 else
1345 flux(i,j1) = AL(i,j1) - 0.5*VC(i,j1)*(AR(i,j1) - AL(i,j1) +
1346 & A6(i,j1)*(1.+R23*VC(i,j1)))
1347 endif
1348 140 continue
1349 return
1350 end
1351 C
1352 subroutine yadv(IMR,JNP,j1,j2,p,VA,ady,wk,IAD)
1353 implicit none
1354 integer IMR,JNP,j1,j2,IAD
1355 REAL p(IMR,JNP),ady(IMR,JNP),VA(IMR,JNP)
1356 REAL WK(IMR,-1:JNP+2)
1357 INTEGER JMR,IMH,i,j,jp
1358 REAL rv,a1,b1,sum1,sum2
1359 C
1360 JMR = JNP-1
1361 IMH = IMR/2
1362 do j=1,JNP
1363 do i=1,IMR
1364 wk(i,j) = p(i,j)
1365 enddo
1366 enddo
1367 C Poles:
1368 do i=1,IMH
1369 wk(i, -1) = p(i+IMH,3)
1370 wk(i+IMH,-1) = p(i,3)
1371 wk(i, 0) = p(i+IMH,2)
1372 wk(i+IMH,0) = p(i,2)
1373 wk(i,JNP+1) = p(i+IMH,JMR)
1374 wk(i+IMH,JNP+1) = p(i,JMR)
1375 wk(i,JNP+2) = p(i+IMH,JNP-2)
1376 wk(i+IMH,JNP+2) = p(i,JNP-2)
1377 enddo
1378 c write(*,*) 'toto 1'
1379 C --------------------------------
1380 IF(IAD.eq.2) then
1381 do j=j1-1,j2+1
1382 do i=1,IMR
1383 c write(*,*) 'avt NINT','i=',i,'j=',j
1384 JP = NINT(VA(i,j))
1385 rv = JP - VA(i,j)
1386 c write(*,*) 'VA=',VA(i,j), 'JP1=',JP,'rv=',rv
1387 JP = j - JP
1388 c write(*,*) 'JP2=',JP
1389 a1 = 0.5*(wk(i,jp+1)+wk(i,jp-1)) - wk(i,jp)
1390 b1 = 0.5*(wk(i,jp+1)-wk(i,jp-1))
1391 c write(*,*) 'a1=',a1,'b1=',b1
1392 ady(i,j) = wk(i,jp) + rv*(a1*rv + b1) - wk(i,j)
1393 enddo
1394 enddo
1395 c write(*,*) 'toto 2'
1396 C
1397 ELSEIF(IAD.eq.1) then
1398 do j=j1-1,j2+1
1399 do i=1,imr
1400 JP = REAL(j)-VA(i,j)
1401 ady(i,j) = VA(i,j)*(wk(i,jp)-wk(i,jp+1))
1402 enddo
1403 enddo
1404 ENDIF
1405 C
1406 if(j1.ne.2) then
1407 sum1 = 0.
1408 sum2 = 0.
1409 do i=1,imr
1410 sum1 = sum1 + ady(i,2)
1411 sum2 = sum2 + ady(i,JMR)
1412 enddo
1413 sum1 = sum1 / IMR
1414 sum2 = sum2 / IMR
1415 C
1416 do i=1,imr
1417 ady(i, 2) = sum1
1418 ady(i,JMR) = sum2
1419 ady(i, 1) = sum1
1420 ady(i,JNP) = sum2
1421 enddo
1422 else
1423 C Poles:
1424 sum1 = 0.
1425 sum2 = 0.
1426 do i=1,imr
1427 sum1 = sum1 + ady(i,1)
1428 sum2 = sum2 + ady(i,JNP)
1429 enddo
1430 sum1 = sum1 / IMR
1431 sum2 = sum2 / IMR
1432 C
1433 do i=1,imr
1434 ady(i, 1) = sum1
1435 ady(i,JNP) = sum2
1436 enddo
1437 endif
1438 C
1439 return
1440 end
1441 C
1442 subroutine xadv(IMR,JNP,j1,j2,p,UA,JS,JN,IML,adx,IAD)
1443 implicit none
1444 INTEGER IMR,JNP,j1,j2,JS,JN,IML,IAD
1445 REAL p(IMR,JNP),adx(IMR,JNP),qtmp(-IMR:IMR+IMR),UA(IMR,JNP)
1446 INTEGER JMR,j,i,ip,iu,iiu
1447 REAL ru,a1,b1
1448 C
1449 JMR = JNP-1
1450 do 1309 j=j1,j2
1451 if(J.GT.JS .and. J.LT.JN) GO TO 1309
1452 C
1453 do i=1,IMR
1454 qtmp(i) = p(i,j)
1455 enddo
1456 C
1457 do i=-IML,0
1458 qtmp(i) = p(IMR+i,j)
1459 qtmp(IMR+1-i) = p(1-i,j)
1460 enddo
1461 C
1462 IF(IAD.eq.2) THEN
1463 DO i=1,IMR
1464 IP = NINT(UA(i,j))
1465 ru = IP - UA(i,j)
1466 IP = i - IP
1467 a1 = 0.5*(qtmp(ip+1)+qtmp(ip-1)) - qtmp(ip)
1468 b1 = 0.5*(qtmp(ip+1)-qtmp(ip-1))
1469 adx(i,j) = qtmp(ip) + ru*(a1*ru + b1)
1470 enddo
1471 ELSEIF(IAD.eq.1) then
1472 DO i=1,IMR
1473 iu = UA(i,j)
1474 ru = UA(i,j) - iu
1475 iiu = i-iu
1476 if(UA(i,j).GE.0.) then
1477 adx(i,j) = qtmp(iiu)+ru*(qtmp(iiu-1)-qtmp(iiu))
1478 else
1479 adx(i,j) = qtmp(iiu)+ru*(qtmp(iiu)-qtmp(iiu+1))
1480 endif
1481 enddo
1482 ENDIF
1483 C
1484 do i=1,IMR
1485 adx(i,j) = adx(i,j) - p(i,j)
1486 enddo
1487 1309 continue
1488 C
1489 C Eulerian upwind
1490 C
1491 do j=JS+1,JN-1
1492 C
1493 do i=1,IMR
1494 qtmp(i) = p(i,j)
1495 enddo
1496 C
1497 qtmp(0) = p(IMR,J)
1498 qtmp(IMR+1) = p(1,J)
1499 C
1500 IF(IAD.eq.2) THEN
1501 qtmp(-1) = p(IMR-1,J)
1502 qtmp(IMR+2) = p(2,J)
1503 do i=1,imr
1504 IP = NINT(UA(i,j))
1505 ru = IP - UA(i,j)
1506 IP = i - IP
1507 a1 = 0.5*(qtmp(ip+1)+qtmp(ip-1)) - qtmp(ip)
1508 b1 = 0.5*(qtmp(ip+1)-qtmp(ip-1))
1509 adx(i,j) = qtmp(ip)- p(i,j) + ru*(a1*ru + b1)
1510 enddo
1511 ELSEIF(IAD.eq.1) then
1512 C 1st order
1513 DO i=1,IMR
1514 IP = i - UA(i,j)
1515 adx(i,j) = UA(i,j)*(qtmp(ip)-qtmp(ip+1))
1516 enddo
1517 ENDIF
1518 enddo
1519 C
1520 if(j1.ne.2) then
1521 do i=1,IMR
1522 adx(i, 2) = 0.
1523 adx(i,JMR) = 0.
1524 enddo
1525 endif
1526 C set cross term due to x-adv at the poles to zero.
1527 do i=1,IMR
1528 adx(i, 1) = 0.
1529 adx(i,JNP) = 0.
1530 enddo
1531 return
1532 end
1533 C
1534 subroutine lmtppm(DC,A6,AR,AL,P,IM,LMT)
1535 implicit none
1536 C
1537 C A6 = CURVATURE OF THE TEST PARABOLA
1538 C AR = RIGHT EDGE VALUE OF THE TEST PARABOLA
1539 C AL = LEFT EDGE VALUE OF THE TEST PARABOLA
1540 C DC = 0.5 * MISMATCH
1541 C P = CELL-AVERAGED VALUE
1542 C IM = VECTOR LENGTH
1543 C
1544 C OPTIONS:
1545 C
1546 C LMT = 0: FULL MONOTONICITY
1547 C LMT = 1: SEMI-MONOTONIC CONSTRAINT (NO UNDERSHOOTS)
1548 C LMT = 2: POSITIVE-DEFINITE CONSTRAINT
1549 C
1550 real,parameter :: R12 = 1./12.
1551 real :: A6(IM),AR(IM),AL(IM),P(IM),DC(IM)
1552 integer :: IM,LMT
1553 INTEGER i
1554 REAL da1,da2,a6da,fmin
1555 C
1556 if(LMT.eq.0) then
1557 C Full constraint
1558 do 100 i=1,IM
1559 if(DC(i).eq.0.) then
1560 AR(i) = p(i)
1561 AL(i) = p(i)
1562 A6(i) = 0.
1563 else
1564 da1 = AR(i) - AL(i)
1565 da2 = da1**2
1566 A6DA = A6(i)*da1
1567 if(A6DA .lt. -da2) then
1568 A6(i) = 3.*(AL(i)-p(i))
1569 AR(i) = AL(i) - A6(i)
1570 elseif(A6DA .gt. da2) then
1571 A6(i) = 3.*(AR(i)-p(i))
1572 AL(i) = AR(i) - A6(i)
1573 endif
1574 endif
1575 100 continue
1576 elseif(LMT.eq.1) then
1577 C Semi-monotonic constraint
1578 do 150 i=1,IM
1579 if(abs(AR(i)-AL(i)) .GE. -A6(i)) go to 150
1580 if(p(i).lt.AR(i) .and. p(i).lt.AL(i)) then
1581 AR(i) = p(i)
1582 AL(i) = p(i)
1583 A6(i) = 0.
1584 elseif(AR(i) .gt. AL(i)) then
1585 A6(i) = 3.*(AL(i)-p(i))
1586 AR(i) = AL(i) - A6(i)
1587 else
1588 A6(i) = 3.*(AR(i)-p(i))
1589 AL(i) = AR(i) - A6(i)
1590 endif
1591 150 continue
1592 elseif(LMT.eq.2) then
1593 do 250 i=1,IM
1594 if(abs(AR(i)-AL(i)) .GE. -A6(i)) go to 250
1595 fmin = p(i) + 0.25*(AR(i)-AL(i))**2/A6(i) + A6(i)*R12
1596 if(fmin.ge.0.) go to 250
1597 if(p(i).lt.AR(i) .and. p(i).lt.AL(i)) then
1598 AR(i) = p(i)
1599 AL(i) = p(i)
1600 A6(i) = 0.
1601 elseif(AR(i) .gt. AL(i)) then
1602 A6(i) = 3.*(AL(i)-p(i))
1603 AR(i) = AL(i) - A6(i)
1604 else
1605 A6(i) = 3.*(AR(i)-p(i))
1606 AL(i) = AR(i) - A6(i)
1607 endif
1608 250 continue
1609 endif
1610 return
1611 end
1612 C
1613 subroutine A2C(U,V,IMR,JMR,j1,j2,CRX,CRY,dtdx5,DTDY5)
1614 implicit none
1615 integer IMR,JMR,j1,j2
1616 real :: U(IMR,*),V(IMR,*),CRX(IMR,*),CRY(IMR,*),DTDX5(*),DTDY5
1617 integer i,j
1618 C
1619 do 35 j=j1,j2
1620 do 35 i=2,IMR
1621 35 CRX(i,J) = dtdx5(j)*(U(i,j)+U(i-1,j))
1622 C
1623 do 45 j=j1,j2
1624 45 CRX(1,J) = dtdx5(j)*(U(1,j)+U(IMR,j))
1625 C
1626 do 55 i=1,IMR*JMR
1627 55 CRY(i,2) = DTDY5*(V(i,2)+V(i,1))
1628 return
1629 end
1630 C
1631 subroutine cosa(cosp,cose,JNP,PI,DP)
1632 implicit none
1633 integer JNP
1634 real :: cosp(*),cose(*),PI,DP
1635 integer JMR,j,jeq
1636 real ph5
1637 JMR = JNP-1
1638 do 55 j=2,JNP
1639 ph5 = -0.5*PI + (REAL(J-1)-0.5)*DP
1640 55 cose(j) = cos(ph5)
1641 C
1642 JEQ = (JNP+1) / 2
1643 if(JMR .eq. 2*(JMR/2) ) then
1644 do j=JNP, JEQ+1, -1
1645 cose(j) = cose(JNP+2-j)
1646 enddo
1647 else
1648 C cell edge at equator.
1649 cose(JEQ+1) = 1.
1650 do j=JNP, JEQ+2, -1
1651 cose(j) = cose(JNP+2-j)
1652 enddo
1653 endif
1654 C
1655 do 66 j=2,JMR
1656 66 cosp(j) = 0.5*(cose(j)+cose(j+1))
1657 cosp(1) = 0.
1658 cosp(JNP) = 0.
1659 return
1660 end
1661 C
1662 subroutine cosc(cosp,cose,JNP,PI,DP)
1663 implicit none
1664 integer JNP
1665 real :: cosp(*),cose(*),PI,DP
1666 real phi
1667 integer j
1668 C
1669 phi = -0.5*PI
1670 do 55 j=2,JNP-1
1671 phi = phi + DP
1672 55 cosp(j) = cos(phi)
1673 cosp( 1) = 0.
1674 cosp(JNP) = 0.
1675 C
1676 do 66 j=2,JNP
1677 cose(j) = 0.5*(cosp(j)+cosp(j-1))
1678 66 CONTINUE
1679 C
1680 do 77 j=2,JNP-1
1681 cosp(j) = 0.5*(cose(j)+cose(j+1))
1682 77 CONTINUE
1683 return
1684 end
1685 C
1686 SUBROUTINE qckxyz (Q,qtmp,IMR,JNP,NLAY,j1,j2,cosp,acosp,
1687 & cross,IC,NSTEP)
1688 C
1689 real,parameter :: tiny = 1.E-60
1690 INTEGER :: IMR,JNP,NLAY,j1,j2,IC,NSTEP
1691 REAL :: Q(IMR,JNP,NLAY),qtmp(IMR,JNP),cosp(*),acosp(*)
1692 logical cross
1693 INTEGER :: NLAYM1,len,ip,L,icr,ipy,ipx,i
1694 real :: qup,qly,dup,sum
1695 C
1696 NLAYM1 = NLAY-1
1697 len = IMR*(j2-j1+1)
1698 ip = 0
1699 C
1700 C Top layer
1701 L = 1
1702 icr = 1
1703 call filns(q(1,1,L),IMR,JNP,j1,j2,cosp,acosp,ipy,tiny)
1704 if(ipy.eq.0) goto 50
1705 call filew(q(1,1,L),qtmp,IMR,JNP,j1,j2,ipx,tiny)
1706 if(ipx.eq.0) goto 50
1707 C
1708 if(cross) then
1709 call filcr(q(1,1,L),IMR,JNP,j1,j2,cosp,acosp,icr,tiny)
1710 endif
1711 if(icr.eq.0) goto 50
1712 C
1713 C Vertical filling...
1714 do i=1,len
1715 IF( Q(i,j1,1).LT.0.) THEN
1716 ip = ip + 1
1717 Q(i,j1,2) = Q(i,j1,2) + Q(i,j1,1)
1718 Q(i,j1,1) = 0.
1719 endif
1720 enddo
1721 C
1722 50 continue
1723 DO 225 L = 2,NLAYM1
1724 icr = 1
1725 C
1726 call filns(q(1,1,L),IMR,JNP,j1,j2,cosp,acosp,ipy,tiny)
1727 if(ipy.eq.0) goto 225
1728 call filew(q(1,1,L),qtmp,IMR,JNP,j1,j2,ipx,tiny)
1729 if(ipx.eq.0) go to 225
1730 if(cross) then
1731 call filcr(q(1,1,L),IMR,JNP,j1,j2,cosp,acosp,icr,tiny)
1732 endif
1733 if(icr.eq.0) goto 225
1734 C
1735 do i=1,len
1736 IF( Q(I,j1,L).LT.0.) THEN
1737 C
1738 ip = ip + 1
1739 C From above
1740 qup = Q(I,j1,L-1)
1741 qly = -Q(I,j1,L)
1742 dup = min(qly,qup)
1743 Q(I,j1,L-1) = qup - dup
1744 Q(I,j1,L ) = dup-qly
1745 C Below
1746 Q(I,j1,L+1) = Q(I,j1,L+1) + Q(I,j1,L)
1747 Q(I,j1,L) = 0.
1748 ENDIF
1749 ENDDO
1750 225 CONTINUE
1751 C
1752 C BOTTOM LAYER
1753 sum = 0.
1754 L = NLAY
1755 C
1756 call filns(q(1,1,L),IMR,JNP,j1,j2,cosp,acosp,ipy,tiny)
1757 if(ipy.eq.0) goto 911
1758 call filew(q(1,1,L),qtmp,IMR,JNP,j1,j2,ipx,tiny)
1759 if(ipx.eq.0) goto 911
1760 C
1761 call filcr(q(1,1,L),IMR,JNP,j1,j2,cosp,acosp,icr,tiny)
1762 if(icr.eq.0) goto 911
1763 C
1764 DO I=1,len
1765 IF( Q(I,j1,L).LT.0.) THEN
1766 ip = ip + 1
1767 c
1768 C From above
1769 C
1770 qup = Q(I,j1,NLAYM1)
1771 qly = -Q(I,j1,L)
1772 dup = min(qly,qup)
1773 Q(I,j1,NLAYM1) = qup - dup
1774 C From "below" the surface.
1775 sum = sum + qly-dup
1776 Q(I,j1,L) = 0.
1777 ENDIF
1778 ENDDO
1779 C
1780 911 continue
1781 C
1782 if(ip.gt.IMR) then
1783 write(6,*) 'IC=',IC,' STEP=',NSTEP,
1784 & ' Vertical filling pts=',ip
1785 endif
1786 C
1787 if(sum.gt.1.e-25) then
1788 write(6,*) IC,NSTEP,' Mass source from the ground=',sum
1789 endif
1790 RETURN
1791 END
1792 C
1793 subroutine filcr(q,IMR,JNP,j1,j2,cosp,acosp,icr,tiny)
1794 implicit none
1795 integer :: IMR,JNP,j1,j2,icr
1796 real :: q(IMR,*),cosp(*),acosp(*),tiny
1797 integer :: i,j
1798 real :: dq,dn,d0,d1,ds,d2
1799 icr = 0
1800 do 65 j=j1+1,j2-1
1801 DO 50 i=1,IMR-1
1802 IF(q(i,j).LT.0.) THEN
1803 icr = 1
1804 dq = - q(i,j)*cosp(j)
1805 C N-E
1806 dn = q(i+1,j+1)*cosp(j+1)
1807 d0 = max(0.,dn)
1808 d1 = min(dq,d0)
1809 q(i+1,j+1) = (dn - d1)*acosp(j+1)
1810 dq = dq - d1
1811 C S-E
1812 ds = q(i+1,j-1)*cosp(j-1)
1813 d0 = max(0.,ds)
1814 d2 = min(dq,d0)
1815 q(i+1,j-1) = (ds - d2)*acosp(j-1)
1816 q(i,j) = (d2 - dq)*acosp(j) + tiny
1817 endif
1818 50 continue
1819 if(icr.eq.0 .and. q(IMR,j).ge.0.) goto 65
1820 DO 55 i=2,IMR
1821 IF(q(i,j).LT.0.) THEN
1822 icr = 1
1823 dq = - q(i,j)*cosp(j)
1824 C N-W
1825 dn = q(i-1,j+1)*cosp(j+1)
1826 d0 = max(0.,dn)
1827 d1 = min(dq,d0)
1828 q(i-1,j+1) = (dn - d1)*acosp(j+1)
1829 dq = dq - d1
1830 C S-W
1831 ds = q(i-1,j-1)*cosp(j-1)
1832 d0 = max(0.,ds)
1833 d2 = min(dq,d0)
1834 q(i-1,j-1) = (ds - d2)*acosp(j-1)
1835 q(i,j) = (d2 - dq)*acosp(j) + tiny
1836 endif
1837 55 continue
1838 C *****************************************
1839 C i=1
1840 i=1
1841 IF(q(i,j).LT.0.) THEN
1842 icr = 1
1843 dq = - q(i,j)*cosp(j)
1844 C N-W
1845 dn = q(IMR,j+1)*cosp(j+1)
1846 d0 = max(0.,dn)
1847 d1 = min(dq,d0)
1848 q(IMR,j+1) = (dn - d1)*acosp(j+1)
1849 dq = dq - d1
1850 C S-W
1851 ds = q(IMR,j-1)*cosp(j-1)
1852 d0 = max(0.,ds)
1853 d2 = min(dq,d0)
1854 q(IMR,j-1) = (ds - d2)*acosp(j-1)
1855 q(i,j) = (d2 - dq)*acosp(j) + tiny
1856 endif
1857 C *****************************************
1858 C i=IMR
1859 i=IMR
1860 IF(q(i,j).LT.0.) THEN
1861 icr = 1
1862 dq = - q(i,j)*cosp(j)
1863 C N-E
1864 dn = q(1,j+1)*cosp(j+1)
1865 d0 = max(0.,dn)
1866 d1 = min(dq,d0)
1867 q(1,j+1) = (dn - d1)*acosp(j+1)
1868 dq = dq - d1
1869 C S-E
1870 ds = q(1,j-1)*cosp(j-1)
1871 d0 = max(0.,ds)
1872 d2 = min(dq,d0)
1873 q(1,j-1) = (ds - d2)*acosp(j-1)
1874 q(i,j) = (d2 - dq)*acosp(j) + tiny
1875 endif
1876 C *****************************************
1877 65 continue
1878 C
1879 do i=1,IMR
1880 if(q(i,j1).lt.0. .or. q(i,j2).lt.0.) then
1881 icr = 1
1882 goto 80
1883 endif
1884 enddo
1885 C
1886 80 continue
1887 C
1888 if(q(1,1).lt.0. .or. q(1,jnp).lt.0.) then
1889 icr = 1
1890 endif
1891 C
1892 return
1893 end
1894 C
1895 subroutine filns(q,IMR,JNP,j1,j2,cosp,acosp,ipy,tiny)
1896 implicit none
1897 integer :: IMR,JNP,j1,j2,ipy
1898 real :: q(IMR,*),cosp(*),acosp(*),tiny
1899 real :: DP,CAP1,dq,dn,d0,d1,ds,d2
1900 INTEGER :: i,j
1901 c logical first
1902 c data first /.true./
1903 c save cap1
1904 C
1905 c if(first) then
1906 DP = 4.*ATAN(1.)/REAL(JNP-1)
1907 CAP1 = IMR*(1.-COS((j1-1.5)*DP))/DP
1908 c first = .false.
1909 c endif
1910 C
1911 ipy = 0
1912 do 55 j=j1+1,j2-1
1913 DO 55 i=1,IMR
1914 IF(q(i,j).LT.0.) THEN
1915 ipy = 1
1916 dq = - q(i,j)*cosp(j)
1917 C North
1918 dn = q(i,j+1)*cosp(j+1)
1919 d0 = max(0.,dn)
1920 d1 = min(dq,d0)
1921 q(i,j+1) = (dn - d1)*acosp(j+1)
1922 dq = dq - d1
1923 C South
1924 ds = q(i,j-1)*cosp(j-1)
1925 d0 = max(0.,ds)
1926 d2 = min(dq,d0)
1927 q(i,j-1) = (ds - d2)*acosp(j-1)
1928 q(i,j) = (d2 - dq)*acosp(j) + tiny
1929 endif
1930 55 continue
1931 C
1932 do i=1,imr
1933 IF(q(i,j1).LT.0.) THEN
1934 ipy = 1
1935 dq = - q(i,j1)*cosp(j1)
1936 C North
1937 dn = q(i,j1+1)*cosp(j1+1)
1938 d0 = max(0.,dn)
1939 d1 = min(dq,d0)
1940 q(i,j1+1) = (dn - d1)*acosp(j1+1)
1941 q(i,j1) = (d1 - dq)*acosp(j1) + tiny
1942 endif
1943 enddo
1944 C
1945 j = j2
1946 do i=1,imr
1947 IF(q(i,j).LT.0.) THEN
1948 ipy = 1
1949 dq = - q(i,j)*cosp(j)
1950 C South
1951 ds = q(i,j-1)*cosp(j-1)
1952 d0 = max(0.,ds)
1953 d2 = min(dq,d0)
1954 q(i,j-1) = (ds - d2)*acosp(j-1)
1955 q(i,j) = (d2 - dq)*acosp(j) + tiny
1956 endif
1957 enddo
1958 C
1959 C Check Poles.
1960 if(q(1,1).lt.0.) then
1961 dq = q(1,1)*cap1/REAL(IMR)*acosp(j1)
1962 do i=1,imr
1963 q(i,1) = 0.
1964 q(i,j1) = q(i,j1) + dq
1965 if(q(i,j1).lt.0.) ipy = 1
1966 enddo
1967 endif
1968 C
1969 if(q(1,JNP).lt.0.) then
1970 dq = q(1,JNP)*cap1/REAL(IMR)*acosp(j2)
1971 do i=1,imr
1972 q(i,JNP) = 0.
1973 q(i,j2) = q(i,j2) + dq
1974 if(q(i,j2).lt.0.) ipy = 1
1975 enddo
1976 endif
1977 C
1978 return
1979 end
1980 C
1981 subroutine filew(q,qtmp,IMR,JNP,j1,j2,ipx,tiny)
1982 implicit none
1983 integer :: IMR,JNP,j1,j2,ipx
1984 real :: q(IMR,*),qtmp(JNP,IMR),tiny
1985 integer :: i,j
1986 real :: d0,d1,d2
1987 C
1988 ipx = 0
1989 C Copy & swap direction for vectorization.
1990 do 25 i=1,imr
1991 do 25 j=j1,j2
1992 25 qtmp(j,i) = q(i,j)
1993 C
1994 do 55 i=2,imr-1
1995 do 55 j=j1,j2
1996 if(qtmp(j,i).lt.0.) then
1997 ipx = 1
1998 c west
1999 d0 = max(0.,qtmp(j,i-1))
2000 d1 = min(-qtmp(j,i),d0)
2001 qtmp(j,i-1) = qtmp(j,i-1) - d1
2002 qtmp(j,i) = qtmp(j,i) + d1
2003 c east
2004 d0 = max(0.,qtmp(j,i+1))
2005 d2 = min(-qtmp(j,i),d0)
2006 qtmp(j,i+1) = qtmp(j,i+1) - d2
2007 qtmp(j,i) = qtmp(j,i) + d2 + tiny
2008 endif
2009 55 continue
2010 c
2011 i=1
2012 do 65 j=j1,j2
2013 if(qtmp(j,i).lt.0.) then
2014 ipx = 1
2015 c west
2016 d0 = max(0.,qtmp(j,imr))
2017 d1 = min(-qtmp(j,i),d0)
2018 qtmp(j,imr) = qtmp(j,imr) - d1
2019 qtmp(j,i) = qtmp(j,i) + d1
2020 c east
2021 d0 = max(0.,qtmp(j,i+1))
2022 d2 = min(-qtmp(j,i),d0)
2023 qtmp(j,i+1) = qtmp(j,i+1) - d2
2024 c
2025 qtmp(j,i) = qtmp(j,i) + d2 + tiny
2026 endif
2027 65 continue
2028 i=IMR
2029 do 75 j=j1,j2
2030 if(qtmp(j,i).lt.0.) then
2031 ipx = 1
2032 c west
2033 d0 = max(0.,qtmp(j,i-1))
2034 d1 = min(-qtmp(j,i),d0)
2035 qtmp(j,i-1) = qtmp(j,i-1) - d1
2036 qtmp(j,i) = qtmp(j,i) + d1
2037 c east
2038 d0 = max(0.,qtmp(j,1))
2039 d2 = min(-qtmp(j,i),d0)
2040 qtmp(j,1) = qtmp(j,1) - d2
2041 c
2042 qtmp(j,i) = qtmp(j,i) + d2 + tiny
2043 endif
2044 75 continue
2045 C
2046 if(ipx.ne.0) then
2047 do 85 j=j1,j2
2048 do 85 i=1,imr
2049 85 q(i,j) = qtmp(j,i)
2050 else
2051 C
2052 C Poles.
2053 if(q(1,1).lt.0. or. q(1,JNP).lt.0.) ipx = 1
2054 endif
2055 return
2056 end
2057 C
2058 subroutine zflip(q,im,km,nc)
2059 implicit none
2060 C This routine flip the array q (in the vertical).
2061 integer :: im,km,nc
2062 real q(im,km,nc)
2063 C local dynamic array
2064 real qtmp(im,km)
2065 integer IC,k,i
2066 C
2067 do 4000 IC = 1, nc
2068 C
2069 do 1000 k=1,km
2070 do 1000 i=1,im
2071 qtmp(i,k) = q(i,km+1-k,IC)
2072 1000 continue
2073 C
2074 do 2000 i=1,im*km
2075 2000 q(i,1,IC) = qtmp(i,1)
2076 4000 continue
2077 return
2078 end
2079