/[lmdze]/trunk/Sources/dyn3d/ppm3d.f
ViewVC logotype

Annotation of /trunk/Sources/dyn3d/ppm3d.f

Parent Directory Parent Directory | Revision Log Revision Log


Revision 32 - (hide annotations)
Tue Apr 6 17:52:58 2010 UTC (14 years, 1 month ago) by guez
Original Path: trunk/libf/dyn3d/ppm3d.f
File size: 52639 byte(s)
Split "stringop.f90" into single-procedure files. Gathered files in directory
"IOIPSL/Stringop".

Split "flincom.f90" into "flincom.f90" and "flinget.f90". Removed
unused procedures from module "flincom". Removed unused argument
"filename" of procedure "flinopen_nozoom".

Removed unused files.

Split "grid_change.f90" into "grid_change.f90" and
"gr_phy_write_3d.f90".

Removed unused procedures from modules "calendar", "ioipslmpp",
"grid_atob", "gath_cpl" and "getincom". Removed unused procedures in
files "ppm3d.f" and "thermcell.f".

Split "mathelp.f90" into "mathelp.f90" and "mathop.f90".

Removed unused variable "dpres" of module "comvert".

Use argument "itau" instead of local variables "iadvtr" and "first" to
control algorithm in procedure "fluxstokenc".

Removed unused arguments of procedure "integrd".

Removed useless computations at the end of procedure "leapfrog".

Merged common block "matrfil" into module "parafilt".

1 guez 3 !
2     ! $Header: /home/cvsroot/LMDZ4/libf/dyn3d/ppm3d.F,v 1.1.1.1 2004/05/19 12:53:07 lmdzadmin Exp $
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     c 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 guez 10 C NC: total number of constituents
84     C IMR: first dimension (E-W); number of Grid intervals in E-W is IMR
85     C JNP: 2nd dimension (N-S); number of Grid intervals in N-S is JNP-1
86     C NLAY: 3rd dimension (number of layers); vertical index increases from 1 at
87 guez 3 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 guez 10 C when and where Courant number is greater than one.
244 guez 3 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     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     SAVE DTDY, DTDY5, RCAP, JS0, JN0, IML,
302     & DTDX, DTDX5, ACOSP, COSP, COSE, DAP,DBK
303     C
304    
305     JMR = JNP -1
306     IMJM = IMR*JNP
307     j2 = JNP - j1 + 1
308     NSTEP = NSTEP + 1
309     C
310     C *********** Initialization **********************
311     if(NSTEP.eq.1) then
312     c
313     write(6,*) '------------------------------------ '
314     write(6,*) 'NASA/GSFC Transport Core Version 4.5'
315     write(6,*) '------------------------------------ '
316     c
317     WRITE(6,*) 'IMR=',IMR,' JNP=',JNP,' NLAY=',NLAY,' j1=',j1
318     WRITE(6,*) 'NC=',NC,IORD,JORD,KORD,NDT
319     C
320     C controles sur les parametres
321     if(NLAY.LT.6) then
322     write(6,*) 'NLAY must be >= 6'
323     stop
324     endif
325     if (JNP.LT.NLAY) then
326     write(6,*) 'JNP must be >= NLAY'
327     stop
328     endif
329     IMRD2=mod(IMR,2)
330     if (j1.eq.2.and.IMRD2.NE.0) then
331     write(6,*) 'if j1=2 IMR must be an even integer'
332     stop
333     endif
334    
335     C
336     if(Jmax.lt.JNP .or. Kmax.lt.NLAY) then
337     write(6,*) 'Jmax or Kmax is too small'
338     stop
339     endif
340     C
341     DO k=1,NLAY
342     DAP(k) = (AP(k+1) - AP(k))*PT
343     DBK(k) = BP(k+1) - BP(k)
344     ENDDO
345     C
346     PI = 4. * ATAN(1.)
347     DL = 2.*PI / float(IMR)
348     DP = PI / float(JMR)
349     C
350     if(IGD.eq.0) then
351     C Compute analytic cosine at cell edges
352     call cosa(cosp,cose,JNP,PI,DP)
353     else
354     C Define cosine consistent with GEOS-GCM (using dycore2.0 or later)
355     call cosc(cosp,cose,JNP,PI,DP)
356     endif
357     C
358     do 15 J=2,JMR
359     15 acosp(j) = 1. / cosp(j)
360     C
361     C Inverse of the Scaled polar cap area.
362     C
363     RCAP = DP / (IMR*(1.-COS((j1-1.5)*DP)))
364     acosp(1) = RCAP
365     acosp(JNP) = RCAP
366     endif
367     C
368     if(NDT0 .ne. NDT) then
369     DT = NDT
370     NDT0 = NDT
371    
372     if(Umax .lt. 180.) then
373     write(6,*) 'Umax may be too small!'
374     endif
375     CR1 = abs(Umax*DT)/(DL*AE)
376     MaxDT = DP*AE / abs(Umax) + 0.5
377     write(6,*)'Largest time step for max(V)=',Umax,' is ',MaxDT
378     if(MaxDT .lt. abs(NDT)) then
379     write(6,*) 'Warning!!! NDT maybe too large!'
380     endif
381     C
382     if(CR1.ge.0.95) then
383     JS0 = 0
384     JN0 = 0
385     IML = IMR-2
386     ZTC = 0.
387     else
388     ZTC = acos(CR1) * (180./PI)
389     C
390     JS0 = float(JMR)*(90.-ZTC)/180. + 2
391     JS0 = max(JS0, J1+1)
392     IML = min(6*JS0/(J1-1)+2, 4*IMR/5)
393     JN0 = JNP-JS0+1
394     endif
395     C
396     C
397     do J=2,JMR
398     DTDX(j) = DT / ( DL*AE*COSP(J) )
399    
400     DTDX5(j) = 0.5*DTDX(j)
401     enddo
402     C
403    
404     DTDY = DT /(AE*DP)
405     DTDY5 = 0.5*DTDY
406     C
407     endif
408     C
409     C *********** End Initialization **********************
410     C
411     C delp = pressure thickness: the psudo-density in a hydrostatic system.
412     do k=1,NLAY
413     do j=1,JNP
414     do i=1,IMR
415     delp1(i,j,k)=DAP(k)+DBK(k)*PS1(i,j)
416     delp2(i,j,k)=DAP(k)+DBK(k)*PS2(i,j)
417     enddo
418     enddo
419     enddo
420    
421     C
422     if(j1.ne.2) then
423     DO 40 IC=1,NC
424     DO 40 L=1,NLAY
425     DO 40 I=1,IMR
426     Q(I, 2,L,IC) = Q(I, 1,L,IC)
427     40 Q(I,JMR,L,IC) = Q(I,JNP,L,IC)
428     endif
429     C
430     C Compute "tracer density"
431     DO 550 IC=1,NC
432     DO 44 k=1,NLAY
433     DO 44 j=1,JNP
434     DO 44 i=1,IMR
435     44 DQ(i,j,k,IC) = Q(i,j,k,IC)*delp1(i,j,k)
436     550 continue
437     C
438     do 1500 k=1,NLAY
439     C
440     if(IGD.eq.0) then
441 guez 10 C Convert winds on A-Grid to Courant number on C-Grid.
442 guez 3 call A2C(U(1,1,k),V(1,1,k),IMR,JMR,j1,j2,CRX,CRY,dtdx5,DTDY5)
443     else
444 guez 10 C Convert winds on C-grid to Courant number
445 guez 3 do 45 j=j1,j2
446     do 45 i=2,IMR
447     45 CRX(i,J) = dtdx(j)*U(i-1,j,k)
448    
449     C
450     do 50 j=j1,j2
451     50 CRX(1,J) = dtdx(j)*U(IMR,j,k)
452     C
453     do 55 i=1,IMR*JMR
454     55 CRY(i,2) = DTDY*V(i,1,k)
455     endif
456     C
457     C Determine JS and JN
458     JS = j1
459     JN = j2
460     C
461     do j=JS0,j1+1,-1
462     do i=1,IMR
463     if(abs(CRX(i,j)).GT.1.) then
464     JS = j
465     go to 2222
466     endif
467     enddo
468     enddo
469     C
470     2222 continue
471     do j=JN0,j2-1
472     do i=1,IMR
473     if(abs(CRX(i,j)).GT.1.) then
474     JN = j
475     go to 2233
476     endif
477     enddo
478     enddo
479     2233 continue
480     C
481     if(j1.ne.2) then ! Enlarged polar cap.
482     do i=1,IMR
483     DPI(i, 2,k) = 0.
484     DPI(i,JMR,k) = 0.
485     enddo
486     endif
487     C
488     C ******* Compute horizontal mass fluxes ************
489     C
490     C N-S component
491     do j=j1,j2+1
492     D5 = 0.5 * COSE(j)
493     do i=1,IMR
494     ymass(i,j) = CRY(i,j)*D5*(delp2(i,j,k) + delp2(i,j-1,k))
495     enddo
496     enddo
497     C
498     do 95 j=j1,j2
499     DO 95 i=1,IMR
500     95 DPI(i,j,k) = (ymass(i,j) - ymass(i,j+1)) * acosp(j)
501     C
502     C Poles
503     sum1 = ymass(IMR,j1 )
504     sum2 = ymass(IMR,J2+1)
505     do i=1,IMR-1
506     sum1 = sum1 + ymass(i,j1 )
507     sum2 = sum2 + ymass(i,J2+1)
508     enddo
509     C
510     sum1 = - sum1 * RCAP
511     sum2 = sum2 * RCAP
512     do i=1,IMR
513     DPI(i, 1,k) = sum1
514     DPI(i,JNP,k) = sum2
515     enddo
516     C
517     C E-W component
518     C
519     do j=j1,j2
520     do i=2,IMR
521     PU(i,j) = 0.5 * (delp2(i,j,k) + delp2(i-1,j,k))
522     enddo
523     enddo
524     C
525     do j=j1,j2
526     PU(1,j) = 0.5 * (delp2(1,j,k) + delp2(IMR,j,k))
527     enddo
528     C
529     do 110 j=j1,j2
530     DO 110 i=1,IMR
531     110 xmass(i,j) = PU(i,j)*CRX(i,j)
532     C
533     DO 120 j=j1,j2
534     DO 120 i=1,IMR-1
535     120 DPI(i,j,k) = DPI(i,j,k) + xmass(i,j) - xmass(i+1,j)
536     C
537     DO 130 j=j1,j2
538     130 DPI(IMR,j,k) = DPI(IMR,j,k) + xmass(IMR,j) - xmass(1,j)
539     C
540     DO j=j1,j2
541     do i=1,IMR-1
542     UA(i,j) = 0.5 * (CRX(i,j)+CRX(i+1,j))
543     enddo
544     enddo
545     C
546     DO j=j1,j2
547     UA(imr,j) = 0.5 * (CRX(imr,j)+CRX(1,j))
548     enddo
549     ccccccccccccccccccccccccccccccccccccccccccccccccccccccc
550     c Rajouts pour LMDZ.3.3
551     ccccccccccccccccccccccccccccccccccccccccccccccccccccccc
552     do i=1,IMR
553     do j=1,JNP
554     VA(i,j)=0.
555     enddo
556     enddo
557    
558     do i=1,imr*(JMR-1)
559     VA(i,2) = 0.5*(CRY(i,2)+CRY(i,3))
560     enddo
561     C
562     if(j1.eq.2) then
563     IMH = IMR/2
564     do i=1,IMH
565     VA(i, 1) = 0.5*(CRY(i,2)-CRY(i+IMH,2))
566     VA(i+IMH, 1) = -VA(i,1)
567     VA(i, JNP) = 0.5*(CRY(i,JNP)-CRY(i+IMH,JMR))
568     VA(i+IMH,JNP) = -VA(i,JNP)
569     enddo
570     VA(IMR,1)=VA(1,1)
571     VA(IMR,JNP)=VA(1,JNP)
572     endif
573     C
574     C ****6***0*********0*********0*********0*********0*********0**********72
575     do 1000 IC=1,NC
576     C
577     do i=1,IMJM
578     wk1(i,1,1) = 0.
579     wk1(i,1,2) = 0.
580     enddo
581     C
582     C E-W advective cross term
583     do 250 j=J1,J2
584     if(J.GT.JS .and. J.LT.JN) GO TO 250
585     C
586     do i=1,IMR
587     qtmp(i) = q(i,j,k,IC)
588     enddo
589     C
590     do i=-IML,0
591     qtmp(i) = q(IMR+i,j,k,IC)
592     qtmp(IMR+1-i) = q(1-i,j,k,IC)
593     enddo
594     C
595     DO 230 i=1,IMR
596     iu = UA(i,j)
597     ru = UA(i,j) - iu
598     iiu = i-iu
599     if(UA(i,j).GE.0.) then
600     wk1(i,j,1) = qtmp(iiu)+ru*(qtmp(iiu-1)-qtmp(iiu))
601     else
602     wk1(i,j,1) = qtmp(iiu)+ru*(qtmp(iiu)-qtmp(iiu+1))
603     endif
604     wk1(i,j,1) = wk1(i,j,1) - qtmp(i)
605     230 continue
606     250 continue
607     C
608     if(JN.ne.0) then
609     do j=JS+1,JN-1
610     C
611     do i=1,IMR
612     qtmp(i) = q(i,j,k,IC)
613     enddo
614     C
615     qtmp(0) = q(IMR,J,k,IC)
616     qtmp(IMR+1) = q( 1,J,k,IC)
617     C
618     do i=1,imr
619     iu = i - UA(i,j)
620     wk1(i,j,1) = UA(i,j)*(qtmp(iu) - qtmp(iu+1))
621     enddo
622     enddo
623     endif
624     C ****6***0*********0*********0*********0*********0*********0**********72
625     C Contribution from the N-S advection
626     do i=1,imr*(j2-j1+1)
627     JT = float(J1) - VA(i,j1)
628     wk1(i,j1,2) = VA(i,j1) * (q(i,jt,k,IC) - q(i,jt+1,k,IC))
629     enddo
630     C
631     do i=1,IMJM
632     wk1(i,1,1) = q(i,1,k,IC) + 0.5*wk1(i,1,1)
633     wk1(i,1,2) = q(i,1,k,IC) + 0.5*wk1(i,1,2)
634     enddo
635     C
636     if(cross) then
637     C Add cross terms in the vertical direction.
638     if(IORD .GE. 2) then
639     iad = 2
640     else
641     iad = 1
642     endif
643     C
644     if(JORD .GE. 2) then
645     jad = 2
646     else
647     jad = 1
648     endif
649     call xadv(IMR,JNP,j1,j2,wk1(1,1,2),UA,JS,JN,IML,DC2,iad)
650     call yadv(IMR,JNP,j1,j2,wk1(1,1,1),VA,PV,W,jad)
651     do j=1,JNP
652     do i=1,IMR
653     q(i,j,k,IC) = q(i,j,k,IC) + DC2(i,j) + PV(i,j)
654     enddo
655     enddo
656     endif
657     C
658     call xtp(IMR,JNP,IML,j1,j2,JN,JS,PU,DQ(1,1,k,IC),wk1(1,1,2)
659     & ,CRX,fx1,xmass,IORD)
660    
661     call ytp(IMR,JNP,j1,j2,acosp,RCAP,DQ(1,1,k,IC),wk1(1,1,1),CRY,
662     & DC2,ymass,WK1(1,1,3),wk1(1,1,4),WK1(1,1,5),WK1(1,1,6),JORD)
663     C
664     1000 continue
665     1500 continue
666     C
667     C ******* Compute vertical mass flux (same unit as PS) ***********
668     C
669     C 1st step: compute total column mass CONVERGENCE.
670     C
671     do 320 j=1,JNP
672     do 320 i=1,IMR
673     320 CRY(i,j) = DPI(i,j,1)
674     C
675     do 330 k=2,NLAY
676     do 330 j=1,JNP
677     do 330 i=1,IMR
678     CRY(i,j) = CRY(i,j) + DPI(i,j,k)
679     330 continue
680     C
681     do 360 j=1,JNP
682     do 360 i=1,IMR
683     C
684     C 2nd step: compute PS2 (PS at n+1) using the hydrostatic assumption.
685     C Changes (increases) to surface pressure = total column mass convergence
686     C
687     PS2(i,j) = PS1(i,j) + CRY(i,j)
688     C
689     C 3rd step: compute vertical mass flux from mass conservation principle.
690     C
691     W(i,j,1) = DPI(i,j,1) - DBK(1)*CRY(i,j)
692     W(i,j,NLAY) = 0.
693     360 continue
694     C
695     do 370 k=2,NLAY-1
696     do 370 j=1,JNP
697     do 370 i=1,IMR
698     W(i,j,k) = W(i,j,k-1) + DPI(i,j,k) - DBK(k)*CRY(i,j)
699     370 continue
700     C
701     DO 380 k=1,NLAY
702     DO 380 j=1,JNP
703     DO 380 i=1,IMR
704     delp2(i,j,k) = DAP(k) + DBK(k)*PS2(i,j)
705     380 continue
706     C
707     KRD = max(3, KORD)
708     do 4000 IC=1,NC
709     C
710     C****6***0*********0*********0*********0*********0*********0**********72
711    
712     call FZPPM(IMR,JNP,NLAY,j1,DQ(1,1,1,IC),W,Q(1,1,1,IC),WK1,DPI,
713     & DC2,CRX,CRY,PU,PV,xmass,ymass,delp1,KRD)
714     C
715    
716     if(fill) call qckxyz(DQ(1,1,1,IC),DC2,IMR,JNP,NLAY,j1,j2,
717     & cosp,acosp,.false.,IC,NSTEP)
718     C
719     C Recover tracer mixing ratio from "density" using predicted
720     C "air density" (pressure thickness) at time-level n+1
721     C
722     DO k=1,NLAY
723     DO j=1,JNP
724     DO i=1,IMR
725     Q(i,j,k,IC) = DQ(i,j,k,IC) / delp2(i,j,k)
726     enddo
727     enddo
728     enddo
729     C
730     if(j1.ne.2) then
731     DO 400 k=1,NLAY
732     DO 400 I=1,IMR
733     c j=1 c'est le pôle Sud, j=JNP c'est le pôle Nord
734     Q(I, 2,k,IC) = Q(I, 1,k,IC)
735     Q(I,JMR,k,IC) = Q(I,JMP,k,IC)
736     400 CONTINUE
737     endif
738     4000 continue
739     C
740     if(j1.ne.2) then
741     DO 5000 k=1,NLAY
742     DO 5000 i=1,IMR
743     W(i, 2,k) = W(i, 1,k)
744     W(i,JMR,k) = W(i,JNP,k)
745     5000 continue
746     endif
747     C
748     RETURN
749     END
750     C
751     C****6***0*********0*********0*********0*********0*********0**********72
752     subroutine FZPPM(IMR,JNP,NLAY,j1,DQ,WZ,P,DC,DQDT,AR,AL,A6,
753     & flux,wk1,wk2,wz2,delp,KORD)
754     parameter ( kmax = 150 )
755     parameter ( R23 = 2./3., R3 = 1./3.)
756     real WZ(IMR,JNP,NLAY),P(IMR,JNP,NLAY),DC(IMR,JNP,NLAY),
757     & wk1(IMR,*),delp(IMR,JNP,NLAY),DQ(IMR,JNP,NLAY),
758     & DQDT(IMR,JNP,NLAY)
759     C Assuming JNP >= NLAY
760     real AR(IMR,*),AL(IMR,*),A6(IMR,*),flux(IMR,*),wk2(IMR,*),
761     & wz2(IMR,*)
762     C
763     JMR = JNP - 1
764     IMJM = IMR*JNP
765     NLAYM1 = NLAY - 1
766     C
767     LMT = KORD - 3
768     C
769     C ****6***0*********0*********0*********0*********0*********0**********72
770     C Compute DC for PPM
771     C ****6***0*********0*********0*********0*********0*********0**********72
772     C
773     do 1000 k=1,NLAYM1
774     do 1000 i=1,IMJM
775     DQDT(i,1,k) = P(i,1,k+1) - P(i,1,k)
776     1000 continue
777     C
778     DO 1220 k=2,NLAYM1
779     DO 1220 I=1,IMJM
780     c0 = delp(i,1,k) / (delp(i,1,k-1)+delp(i,1,k)+delp(i,1,k+1))
781     c1 = (delp(i,1,k-1)+0.5*delp(i,1,k))/(delp(i,1,k+1)+delp(i,1,k))
782     c2 = (delp(i,1,k+1)+0.5*delp(i,1,k))/(delp(i,1,k-1)+delp(i,1,k))
783     tmp = c0*(c1*DQDT(i,1,k) + c2*DQDT(i,1,k-1))
784     Qmax = max(P(i,1,k-1),P(i,1,k),P(i,1,k+1)) - P(i,1,k)
785     Qmin = P(i,1,k) - min(P(i,1,k-1),P(i,1,k),P(i,1,k+1))
786     DC(i,1,k) = sign(min(abs(tmp),Qmax,Qmin), tmp)
787     1220 CONTINUE
788    
789     C
790     C ****6***0*********0*********0*********0*********0*********0**********72
791     C Loop over latitudes (to save memory)
792     C ****6***0*********0*********0*********0*********0*********0**********72
793     C
794     DO 2000 j=1,JNP
795     if((j.eq.2 .or. j.eq.JMR) .and. j1.ne.2) goto 2000
796     C
797     DO k=1,NLAY
798     DO i=1,IMR
799     wz2(i,k) = WZ(i,j,k)
800     wk1(i,k) = P(i,j,k)
801     wk2(i,k) = delp(i,j,k)
802     flux(i,k) = DC(i,j,k) !this flux is actually the monotone slope
803     enddo
804     enddo
805     C
806     C****6***0*********0*********0*********0*********0*********0**********72
807     C Compute first guesses at cell interfaces
808     C First guesses are required to be continuous.
809     C ****6***0*********0*********0*********0*********0*********0**********72
810     C
811     C three-cell parabolic subgrid distribution at model top
812     C two-cell parabolic with zero gradient subgrid distribution
813     C at the surface.
814     C
815     C First guess top edge value
816     DO 10 i=1,IMR
817     C three-cell PPM
818     C Compute a,b, and c of q = aP**2 + bP + c using cell averages and delp
819     a = 3.*( DQDT(i,j,2) - DQDT(i,j,1)*(wk2(i,2)+wk2(i,3))/
820     & (wk2(i,1)+wk2(i,2)) ) /
821     & ( (wk2(i,2)+wk2(i,3))*(wk2(i,1)+wk2(i,2)+wk2(i,3)) )
822     b = 2.*DQDT(i,j,1)/(wk2(i,1)+wk2(i,2)) -
823     & R23*a*(2.*wk2(i,1)+wk2(i,2))
824     AL(i,1) = wk1(i,1) - wk2(i,1)*(R3*a*wk2(i,1) + 0.5*b)
825     AL(i,2) = wk2(i,1)*(a*wk2(i,1) + b) + AL(i,1)
826     C
827     C Check if change sign
828     if(wk1(i,1)*AL(i,1).le.0.) then
829     AL(i,1) = 0.
830     flux(i,1) = 0.
831     else
832     flux(i,1) = wk1(i,1) - AL(i,1)
833     endif
834     10 continue
835     C
836     C Bottom
837     DO 15 i=1,IMR
838     C 2-cell PPM with zero gradient right at the surface
839     C
840     fct = DQDT(i,j,NLAYM1)*wk2(i,NLAY)**2 /
841     & ( (wk2(i,NLAY)+wk2(i,NLAYM1))*(2.*wk2(i,NLAY)+wk2(i,NLAYM1)))
842     AR(i,NLAY) = wk1(i,NLAY) + fct
843     AL(i,NLAY) = wk1(i,NLAY) - (fct+fct)
844     if(wk1(i,NLAY)*AR(i,NLAY).le.0.) AR(i,NLAY) = 0.
845     flux(i,NLAY) = AR(i,NLAY) - wk1(i,NLAY)
846     15 continue
847    
848     C
849     C****6***0*********0*********0*********0*********0*********0**********72
850     C 4th order interpolation in the interior.
851     C****6***0*********0*********0*********0*********0*********0**********72
852     C
853     DO 14 k=3,NLAYM1
854     DO 12 i=1,IMR
855     c1 = DQDT(i,j,k-1)*wk2(i,k-1) / (wk2(i,k-1)+wk2(i,k))
856     c2 = 2. / (wk2(i,k-2)+wk2(i,k-1)+wk2(i,k)+wk2(i,k+1))
857     A1 = (wk2(i,k-2)+wk2(i,k-1)) / (2.*wk2(i,k-1)+wk2(i,k))
858     A2 = (wk2(i,k )+wk2(i,k+1)) / (2.*wk2(i,k)+wk2(i,k-1))
859     AL(i,k) = wk1(i,k-1) + c1 + c2 *
860     & ( wk2(i,k )*(c1*(A1 - A2)+A2*flux(i,k-1)) -
861     & wk2(i,k-1)*A1*flux(i,k) )
862     12 CONTINUE
863     14 continue
864     C
865     do 20 i=1,IMR*NLAYM1
866     AR(i,1) = AL(i,2)
867     20 continue
868     C
869     do 30 i=1,IMR*NLAY
870     A6(i,1) = 3.*(wk1(i,1)+wk1(i,1) - (AL(i,1)+AR(i,1)))
871     30 continue
872     C
873     C****6***0*********0*********0*********0*********0*********0**********72
874     C Top & Bot always monotonic
875     call lmtppm(flux(1,1),A6(1,1),AR(1,1),AL(1,1),wk1(1,1),IMR,0)
876     call lmtppm(flux(1,NLAY),A6(1,NLAY),AR(1,NLAY),AL(1,NLAY),
877     & wk1(1,NLAY),IMR,0)
878     C
879     C Interior depending on KORD
880     if(LMT.LE.2)
881     & call lmtppm(flux(1,2),A6(1,2),AR(1,2),AL(1,2),wk1(1,2),
882     & IMR*(NLAY-2),LMT)
883     C
884     C****6***0*********0*********0*********0*********0*********0**********72
885     C
886     DO 140 i=1,IMR*NLAYM1
887     IF(wz2(i,1).GT.0.) then
888     CM = wz2(i,1) / wk2(i,1)
889     flux(i,2) = AR(i,1)+0.5*CM*(AL(i,1)-AR(i,1)+A6(i,1)*(1.-R23*CM))
890     else
891     CP= wz2(i,1) / wk2(i,2)
892     flux(i,2) = AL(i,2)+0.5*CP*(AL(i,2)-AR(i,2)-A6(i,2)*(1.+R23*CP))
893     endif
894     140 continue
895     C
896     DO 250 i=1,IMR*NLAYM1
897     flux(i,2) = wz2(i,1) * flux(i,2)
898     250 continue
899     C
900     do 350 i=1,IMR
901     DQ(i,j, 1) = DQ(i,j, 1) - flux(i, 2)
902     DQ(i,j,NLAY) = DQ(i,j,NLAY) + flux(i,NLAY)
903     350 continue
904     C
905     do 360 k=2,NLAYM1
906     do 360 i=1,IMR
907     360 DQ(i,j,k) = DQ(i,j,k) + flux(i,k) - flux(i,k+1)
908     2000 continue
909     return
910     end
911     C
912     subroutine xtp(IMR,JNP,IML,j1,j2,JN,JS,PU,DQ,Q,UC,
913     & fx1,xmass,IORD)
914     dimension UC(IMR,*),DC(-IML:IMR+IML+1),xmass(IMR,JNP)
915     & ,fx1(IMR+1),DQ(IMR,JNP),qtmp(-IML:IMR+1+IML)
916     dimension PU(IMR,JNP),Q(IMR,JNP),ISAVE(IMR)
917     C
918     IMP = IMR + 1
919     C
920     C van Leer at high latitudes
921     jvan = max(1,JNP/18)
922     j1vl = j1+jvan
923     j2vl = j2-jvan
924     C
925     do 1310 j=j1,j2
926     C
927     do i=1,IMR
928     qtmp(i) = q(i,j)
929     enddo
930     C
931     if(j.ge.JN .or. j.le.JS) goto 2222
932     C ************* Eulerian **********
933     C
934     qtmp(0) = q(IMR,J)
935     qtmp(-1) = q(IMR-1,J)
936     qtmp(IMP) = q(1,J)
937     qtmp(IMP+1) = q(2,J)
938     C
939     IF(IORD.eq.1 .or. j.eq.j1. or. j.eq.j2) THEN
940     DO 1406 i=1,IMR
941     iu = float(i) - uc(i,j)
942     1406 fx1(i) = qtmp(iu)
943     ELSE
944     call xmist(IMR,IML,Qtmp,DC)
945     DC(0) = DC(IMR)
946     C
947     if(IORD.eq.2 .or. j.le.j1vl .or. j.ge.j2vl) then
948     DO 1408 i=1,IMR
949     iu = float(i) - uc(i,j)
950     1408 fx1(i) = qtmp(iu) + DC(iu)*(sign(1.,uc(i,j))-uc(i,j))
951     else
952     call fxppm(IMR,IML,UC(1,j),Qtmp,DC,fx1,IORD)
953     endif
954     C
955     ENDIF
956     C
957     DO 1506 i=1,IMR
958     1506 fx1(i) = fx1(i)*xmass(i,j)
959     C
960     goto 1309
961     C
962     C ***** Conservative (flux-form) Semi-Lagrangian transport *****
963     C
964     2222 continue
965     C
966     do i=-IML,0
967     qtmp(i) = q(IMR+i,j)
968     qtmp(IMP-i) = q(1-i,j)
969     enddo
970     C
971     IF(IORD.eq.1 .or. j.eq.j1. or. j.eq.j2) THEN
972     DO 1306 i=1,IMR
973     itmp = INT(uc(i,j))
974     ISAVE(i) = i - itmp
975     iu = i - uc(i,j)
976     1306 fx1(i) = (uc(i,j) - itmp)*qtmp(iu)
977     ELSE
978     call xmist(IMR,IML,Qtmp,DC)
979     C
980     do i=-IML,0
981     DC(i) = DC(IMR+i)
982     DC(IMP-i) = DC(1-i)
983     enddo
984     C
985     DO 1307 i=1,IMR
986     itmp = INT(uc(i,j))
987     rut = uc(i,j) - itmp
988     ISAVE(i) = i - itmp
989     iu = i - uc(i,j)
990     1307 fx1(i) = rut*(qtmp(iu) + DC(iu)*(sign(1.,rut) - rut))
991     ENDIF
992     C
993     do 1308 i=1,IMR
994     IF(uc(i,j).GT.1.) then
995     CDIR$ NOVECTOR
996     do ist = ISAVE(i),i-1
997     fx1(i) = fx1(i) + qtmp(ist)
998     enddo
999     elseIF(uc(i,j).LT.-1.) then
1000     do ist = i,ISAVE(i)-1
1001     fx1(i) = fx1(i) - qtmp(ist)
1002     enddo
1003     CDIR$ VECTOR
1004     endif
1005     1308 continue
1006     do i=1,IMR
1007     fx1(i) = PU(i,j)*fx1(i)
1008     enddo
1009     C
1010     C ***************************************
1011     C
1012     1309 fx1(IMP) = fx1(1)
1013     DO 1215 i=1,IMR
1014     1215 DQ(i,j) = DQ(i,j) + fx1(i)-fx1(i+1)
1015     C
1016     C ***************************************
1017     C
1018     1310 continue
1019     return
1020     end
1021     C
1022     subroutine fxppm(IMR,IML,UT,P,DC,flux,IORD)
1023     parameter ( R3 = 1./3., R23 = 2./3. )
1024     DIMENSION UT(*),flux(*),P(-IML:IMR+IML+1),DC(-IML:IMR+IML+1)
1025     DIMENSION AR(0:IMR),AL(0:IMR),A6(0:IMR)
1026     integer LMT
1027     c logical first
1028     c data first /.true./
1029     c SAVE LMT
1030     c if(first) then
1031     C
1032     C correction calcul de LMT a chaque passage pour pouvoir choisir
1033     c plusieurs schemas PPM pour differents traceurs
1034     c IF (IORD.LE.0) then
1035     c if(IMR.GE.144) then
1036     c LMT = 0
1037     c elseif(IMR.GE.72) then
1038     c LMT = 1
1039     c else
1040     c LMT = 2
1041     c endif
1042     c else
1043     c LMT = IORD - 3
1044     c endif
1045     C
1046     LMT = IORD - 3
1047 guez 32
1048 guez 3 DO 10 i=1,IMR
1049     10 AL(i) = 0.5*(p(i-1)+p(i)) + (DC(i-1) - DC(i))*R3
1050     C
1051     do 20 i=1,IMR-1
1052     20 AR(i) = AL(i+1)
1053     AR(IMR) = AL(1)
1054     C
1055     do 30 i=1,IMR
1056     30 A6(i) = 3.*(p(i)+p(i) - (AL(i)+AR(i)))
1057     C
1058     if(LMT.LE.2) call lmtppm(DC(1),A6(1),AR(1),AL(1),P(1),IMR,LMT)
1059     C
1060     AL(0) = AL(IMR)
1061     AR(0) = AR(IMR)
1062     A6(0) = A6(IMR)
1063     C
1064     DO i=1,IMR
1065     IF(UT(i).GT.0.) then
1066     flux(i) = AR(i-1) + 0.5*UT(i)*(AL(i-1) - AR(i-1) +
1067     & A6(i-1)*(1.-R23*UT(i)) )
1068     else
1069     flux(i) = AL(i) - 0.5*UT(i)*(AR(i) - AL(i) +
1070     & A6(i)*(1.+R23*UT(i)))
1071     endif
1072     enddo
1073     return
1074     end
1075     C
1076     subroutine xmist(IMR,IML,P,DC)
1077     parameter( R24 = 1./24.)
1078     dimension P(-IML:IMR+1+IML),DC(-IML:IMR+1+IML)
1079     C
1080     do 10 i=1,IMR
1081     tmp = R24*(8.*(p(i+1) - p(i-1)) + p(i-2) - p(i+2))
1082     Pmax = max(P(i-1), p(i), p(i+1)) - p(i)
1083     Pmin = p(i) - min(P(i-1), p(i), p(i+1))
1084     10 DC(i) = sign(min(abs(tmp),Pmax,Pmin), tmp)
1085     return
1086     end
1087     C
1088     subroutine ytp(IMR,JNP,j1,j2,acosp,RCAP,DQ,P,VC,DC2
1089     & ,ymass,fx,A6,AR,AL,JORD)
1090     dimension P(IMR,JNP),VC(IMR,JNP),ymass(IMR,JNP)
1091     & ,DC2(IMR,JNP),DQ(IMR,JNP),acosp(JNP)
1092     C Work array
1093     DIMENSION fx(IMR,JNP),AR(IMR,JNP),AL(IMR,JNP),A6(IMR,JNP)
1094     C
1095     JMR = JNP - 1
1096     len = IMR*(J2-J1+2)
1097     C
1098     if(JORD.eq.1) then
1099     DO 1000 i=1,len
1100     JT = float(J1) - VC(i,J1)
1101     1000 fx(i,j1) = p(i,JT)
1102     else
1103    
1104     call ymist(IMR,JNP,j1,P,DC2,4)
1105     C
1106     if(JORD.LE.0 .or. JORD.GE.3) then
1107    
1108     call fyppm(VC,P,DC2,fx,IMR,JNP,j1,j2,A6,AR,AL,JORD)
1109    
1110     else
1111     DO 1200 i=1,len
1112     JT = float(J1) - VC(i,J1)
1113     1200 fx(i,j1) = p(i,JT) + (sign(1.,VC(i,j1))-VC(i,j1))*DC2(i,JT)
1114     endif
1115     endif
1116     C
1117     DO 1300 i=1,len
1118     1300 fx(i,j1) = fx(i,j1)*ymass(i,j1)
1119     C
1120     DO 1400 j=j1,j2
1121     DO 1400 i=1,IMR
1122     1400 DQ(i,j) = DQ(i,j) + (fx(i,j) - fx(i,j+1)) * acosp(j)
1123     C
1124     C Poles
1125     sum1 = fx(IMR,j1 )
1126     sum2 = fx(IMR,J2+1)
1127     do i=1,IMR-1
1128     sum1 = sum1 + fx(i,j1 )
1129     sum2 = sum2 + fx(i,J2+1)
1130     enddo
1131     C
1132     sum1 = DQ(1, 1) - sum1 * RCAP
1133     sum2 = DQ(1,JNP) + sum2 * RCAP
1134     do i=1,IMR
1135     DQ(i, 1) = sum1
1136     DQ(i,JNP) = sum2
1137     enddo
1138     C
1139     if(j1.ne.2) then
1140     do i=1,IMR
1141     DQ(i, 2) = sum1
1142     DQ(i,JMR) = sum2
1143     enddo
1144     endif
1145     C
1146     return
1147     end
1148     C
1149     subroutine ymist(IMR,JNP,j1,P,DC,ID)
1150     parameter ( R24 = 1./24. )
1151     dimension P(IMR,JNP),DC(IMR,JNP)
1152     C
1153     IMH = IMR / 2
1154     JMR = JNP - 1
1155     IJM3 = IMR*(JMR-3)
1156     C
1157     IF(ID.EQ.2) THEN
1158     do 10 i=1,IMR*(JMR-1)
1159     tmp = 0.25*(p(i,3) - p(i,1))
1160     Pmax = max(p(i,1),p(i,2),p(i,3)) - p(i,2)
1161     Pmin = p(i,2) - min(p(i,1),p(i,2),p(i,3))
1162     DC(i,2) = sign(min(abs(tmp),Pmin,Pmax),tmp)
1163     10 CONTINUE
1164     ELSE
1165     do 12 i=1,IMH
1166     C J=2
1167     tmp = (8.*(p(i,3) - p(i,1)) + p(i+IMH,2) - p(i,4))*R24
1168     Pmax = max(p(i,1),p(i,2),p(i,3)) - p(i,2)
1169     Pmin = p(i,2) - min(p(i,1),p(i,2),p(i,3))
1170     DC(i,2) = sign(min(abs(tmp),Pmin,Pmax),tmp)
1171     C J=JMR
1172     tmp=(8.*(p(i,JNP)-p(i,JMR-1))+p(i,JMR-2)-p(i+IMH,JMR))*R24
1173     Pmax = max(p(i,JMR-1),p(i,JMR),p(i,JNP)) - p(i,JMR)
1174     Pmin = p(i,JMR) - min(p(i,JMR-1),p(i,JMR),p(i,JNP))
1175     DC(i,JMR) = sign(min(abs(tmp),Pmin,Pmax),tmp)
1176     12 CONTINUE
1177     do 14 i=IMH+1,IMR
1178     C J=2
1179     tmp = (8.*(p(i,3) - p(i,1)) + p(i-IMH,2) - p(i,4))*R24
1180     Pmax = max(p(i,1),p(i,2),p(i,3)) - p(i,2)
1181     Pmin = p(i,2) - min(p(i,1),p(i,2),p(i,3))
1182     DC(i,2) = sign(min(abs(tmp),Pmin,Pmax),tmp)
1183     C J=JMR
1184     tmp=(8.*(p(i,JNP)-p(i,JMR-1))+p(i,JMR-2)-p(i-IMH,JMR))*R24
1185     Pmax = max(p(i,JMR-1),p(i,JMR),p(i,JNP)) - p(i,JMR)
1186     Pmin = p(i,JMR) - min(p(i,JMR-1),p(i,JMR),p(i,JNP))
1187     DC(i,JMR) = sign(min(abs(tmp),Pmin,Pmax),tmp)
1188     14 CONTINUE
1189     C
1190     do 15 i=1,IJM3
1191     tmp = (8.*(p(i,4) - p(i,2)) + p(i,1) - p(i,5))*R24
1192     Pmax = max(p(i,2),p(i,3),p(i,4)) - p(i,3)
1193     Pmin = p(i,3) - min(p(i,2),p(i,3),p(i,4))
1194     DC(i,3) = sign(min(abs(tmp),Pmin,Pmax),tmp)
1195     15 CONTINUE
1196     ENDIF
1197     C
1198     if(j1.ne.2) then
1199     do i=1,IMR
1200     DC(i,1) = 0.
1201     DC(i,JNP) = 0.
1202     enddo
1203     else
1204     C Determine slopes in polar caps for scalars!
1205     C
1206     do 13 i=1,IMH
1207     C South
1208     tmp = 0.25*(p(i,2) - p(i+imh,2))
1209     Pmax = max(p(i,2),p(i,1), p(i+imh,2)) - p(i,1)
1210     Pmin = p(i,1) - min(p(i,2),p(i,1), p(i+imh,2))
1211     DC(i,1)=sign(min(abs(tmp),Pmax,Pmin),tmp)
1212     C North.
1213     tmp = 0.25*(p(i+imh,JMR) - p(i,JMR))
1214     Pmax = max(p(i+imh,JMR),p(i,jnp), p(i,JMR)) - p(i,JNP)
1215     Pmin = p(i,JNP) - min(p(i+imh,JMR),p(i,jnp), p(i,JMR))
1216     DC(i,JNP) = sign(min(abs(tmp),Pmax,pmin),tmp)
1217     13 continue
1218     C
1219     do 25 i=imh+1,IMR
1220     DC(i, 1) = - DC(i-imh, 1)
1221     DC(i,JNP) = - DC(i-imh,JNP)
1222     25 continue
1223     endif
1224     return
1225     end
1226     C
1227     subroutine fyppm(VC,P,DC,flux,IMR,JNP,j1,j2,A6,AR,AL,JORD)
1228     parameter ( R3 = 1./3., R23 = 2./3. )
1229     real VC(IMR,*),flux(IMR,*),P(IMR,*),DC(IMR,*)
1230     C Local work arrays.
1231     real AR(IMR,JNP),AL(IMR,JNP),A6(IMR,JNP)
1232     integer LMT
1233     c logical first
1234     C data first /.true./
1235     C SAVE LMT
1236     C
1237     IMH = IMR / 2
1238     JMR = JNP - 1
1239     j11 = j1-1
1240     IMJM1 = IMR*(J2-J1+2)
1241     len = IMR*(J2-J1+3)
1242     C if(first) then
1243     C IF(JORD.LE.0) then
1244     C if(JMR.GE.90) then
1245     C LMT = 0
1246     C elseif(JMR.GE.45) then
1247     C LMT = 1
1248     C else
1249     C LMT = 2
1250     C endif
1251     C else
1252     C LMT = JORD - 3
1253     C endif
1254     C
1255     C first = .false.
1256     C endif
1257     C
1258     c modifs pour pouvoir choisir plusieurs schemas PPM
1259     LMT = JORD - 3
1260     C
1261     DO 10 i=1,IMR*JMR
1262     AL(i,2) = 0.5*(p(i,1)+p(i,2)) + (DC(i,1) - DC(i,2))*R3
1263     AR(i,1) = AL(i,2)
1264     10 CONTINUE
1265     C
1266     CPoles:
1267     C
1268     DO i=1,IMH
1269     AL(i,1) = AL(i+IMH,2)
1270     AL(i+IMH,1) = AL(i,2)
1271     C
1272     AR(i,JNP) = AR(i+IMH,JMR)
1273     AR(i+IMH,JNP) = AR(i,JMR)
1274     ENDDO
1275    
1276     ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
1277     c Rajout pour LMDZ.3.3
1278     cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
1279     AR(IMR,1)=AL(1,1)
1280     AR(IMR,JNP)=AL(1,JNP)
1281     ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
1282    
1283    
1284     do 30 i=1,len
1285     30 A6(i,j11) = 3.*(p(i,j11)+p(i,j11) - (AL(i,j11)+AR(i,j11)))
1286     C
1287     if(LMT.le.2) call lmtppm(DC(1,j11),A6(1,j11),AR(1,j11)
1288     & ,AL(1,j11),P(1,j11),len,LMT)
1289     C
1290    
1291     DO 140 i=1,IMJM1
1292     IF(VC(i,j1).GT.0.) then
1293     flux(i,j1) = AR(i,j11) + 0.5*VC(i,j1)*(AL(i,j11) - AR(i,j11) +
1294     & A6(i,j11)*(1.-R23*VC(i,j1)) )
1295     else
1296     flux(i,j1) = AL(i,j1) - 0.5*VC(i,j1)*(AR(i,j1) - AL(i,j1) +
1297     & A6(i,j1)*(1.+R23*VC(i,j1)))
1298     endif
1299     140 continue
1300     return
1301     end
1302     C
1303     subroutine yadv(IMR,JNP,j1,j2,p,VA,ady,wk,IAD)
1304     REAL p(IMR,JNP),ady(IMR,JNP),VA(IMR,JNP)
1305     REAL WK(IMR,-1:JNP+2)
1306     C
1307     JMR = JNP-1
1308     IMH = IMR/2
1309     do j=1,JNP
1310     do i=1,IMR
1311     wk(i,j) = p(i,j)
1312     enddo
1313     enddo
1314     C Poles:
1315     do i=1,IMH
1316     wk(i, -1) = p(i+IMH,3)
1317     wk(i+IMH,-1) = p(i,3)
1318     wk(i, 0) = p(i+IMH,2)
1319     wk(i+IMH,0) = p(i,2)
1320     wk(i,JNP+1) = p(i+IMH,JMR)
1321     wk(i+IMH,JNP+1) = p(i,JMR)
1322     wk(i,JNP+2) = p(i+IMH,JNP-2)
1323     wk(i+IMH,JNP+2) = p(i,JNP-2)
1324     enddo
1325 guez 32
1326 guez 3 IF(IAD.eq.2) then
1327     do j=j1-1,j2+1
1328     do i=1,IMR
1329     JP = NINT(VA(i,j))
1330     rv = JP - VA(i,j)
1331     JP = j - JP
1332     a1 = 0.5*(wk(i,jp+1)+wk(i,jp-1)) - wk(i,jp)
1333     b1 = 0.5*(wk(i,jp+1)-wk(i,jp-1))
1334     ady(i,j) = wk(i,jp) + rv*(a1*rv + b1) - wk(i,j)
1335     enddo
1336     enddo
1337 guez 32
1338 guez 3 ELSEIF(IAD.eq.1) then
1339     do j=j1-1,j2+1
1340     do i=1,imr
1341     JP = float(j)-VA(i,j)
1342     ady(i,j) = VA(i,j)*(wk(i,jp)-wk(i,jp+1))
1343     enddo
1344     enddo
1345     ENDIF
1346     C
1347     if(j1.ne.2) then
1348     sum1 = 0.
1349     sum2 = 0.
1350     do i=1,imr
1351     sum1 = sum1 + ady(i,2)
1352     sum2 = sum2 + ady(i,JMR)
1353     enddo
1354     sum1 = sum1 / IMR
1355     sum2 = sum2 / IMR
1356     C
1357     do i=1,imr
1358     ady(i, 2) = sum1
1359     ady(i,JMR) = sum2
1360     ady(i, 1) = sum1
1361     ady(i,JNP) = sum2
1362     enddo
1363     else
1364     C Poles:
1365     sum1 = 0.
1366     sum2 = 0.
1367     do i=1,imr
1368     sum1 = sum1 + ady(i,1)
1369     sum2 = sum2 + ady(i,JNP)
1370     enddo
1371     sum1 = sum1 / IMR
1372     sum2 = sum2 / IMR
1373     C
1374     do i=1,imr
1375     ady(i, 1) = sum1
1376     ady(i,JNP) = sum2
1377     enddo
1378     endif
1379     C
1380     return
1381     end
1382     C
1383     subroutine xadv(IMR,JNP,j1,j2,p,UA,JS,JN,IML,adx,IAD)
1384     REAL p(IMR,JNP),adx(IMR,JNP),qtmp(-IMR:IMR+IMR),UA(IMR,JNP)
1385     C
1386     JMR = JNP-1
1387     do 1309 j=j1,j2
1388     if(J.GT.JS .and. J.LT.JN) GO TO 1309
1389     C
1390     do i=1,IMR
1391     qtmp(i) = p(i,j)
1392     enddo
1393     C
1394     do i=-IML,0
1395     qtmp(i) = p(IMR+i,j)
1396     qtmp(IMR+1-i) = p(1-i,j)
1397     enddo
1398     C
1399     IF(IAD.eq.2) THEN
1400     DO i=1,IMR
1401     IP = NINT(UA(i,j))
1402     ru = IP - UA(i,j)
1403     IP = i - IP
1404     a1 = 0.5*(qtmp(ip+1)+qtmp(ip-1)) - qtmp(ip)
1405     b1 = 0.5*(qtmp(ip+1)-qtmp(ip-1))
1406     adx(i,j) = qtmp(ip) + ru*(a1*ru + b1)
1407     enddo
1408     ELSEIF(IAD.eq.1) then
1409     DO i=1,IMR
1410     iu = UA(i,j)
1411     ru = UA(i,j) - iu
1412     iiu = i-iu
1413     if(UA(i,j).GE.0.) then
1414     adx(i,j) = qtmp(iiu)+ru*(qtmp(iiu-1)-qtmp(iiu))
1415     else
1416     adx(i,j) = qtmp(iiu)+ru*(qtmp(iiu)-qtmp(iiu+1))
1417     endif
1418     enddo
1419     ENDIF
1420     C
1421     do i=1,IMR
1422     adx(i,j) = adx(i,j) - p(i,j)
1423     enddo
1424     1309 continue
1425     C
1426     C Eulerian upwind
1427     C
1428     do j=JS+1,JN-1
1429     C
1430     do i=1,IMR
1431     qtmp(i) = p(i,j)
1432     enddo
1433     C
1434     qtmp(0) = p(IMR,J)
1435     qtmp(IMR+1) = p(1,J)
1436     C
1437     IF(IAD.eq.2) THEN
1438     qtmp(-1) = p(IMR-1,J)
1439     qtmp(IMR+2) = p(2,J)
1440     do i=1,imr
1441     IP = NINT(UA(i,j))
1442     ru = IP - UA(i,j)
1443     IP = i - IP
1444     a1 = 0.5*(qtmp(ip+1)+qtmp(ip-1)) - qtmp(ip)
1445     b1 = 0.5*(qtmp(ip+1)-qtmp(ip-1))
1446     adx(i,j) = qtmp(ip)- p(i,j) + ru*(a1*ru + b1)
1447     enddo
1448     ELSEIF(IAD.eq.1) then
1449     C 1st order
1450     DO i=1,IMR
1451     IP = i - UA(i,j)
1452     adx(i,j) = UA(i,j)*(qtmp(ip)-qtmp(ip+1))
1453     enddo
1454     ENDIF
1455     enddo
1456     C
1457     if(j1.ne.2) then
1458     do i=1,IMR
1459     adx(i, 2) = 0.
1460     adx(i,JMR) = 0.
1461     enddo
1462     endif
1463     C set cross term due to x-adv at the poles to zero.
1464     do i=1,IMR
1465     adx(i, 1) = 0.
1466     adx(i,JNP) = 0.
1467     enddo
1468     return
1469     end
1470     C
1471     subroutine lmtppm(DC,A6,AR,AL,P,IM,LMT)
1472     C
1473     C A6 = CURVATURE OF THE TEST PARABOLA
1474     C AR = RIGHT EDGE VALUE OF THE TEST PARABOLA
1475     C AL = LEFT EDGE VALUE OF THE TEST PARABOLA
1476     C DC = 0.5 * MISMATCH
1477     C P = CELL-AVERAGED VALUE
1478     C IM = VECTOR LENGTH
1479     C
1480     C OPTIONS:
1481     C
1482     C LMT = 0: FULL MONOTONICITY
1483     C LMT = 1: SEMI-MONOTONIC CONSTRAINT (NO UNDERSHOOTS)
1484     C LMT = 2: POSITIVE-DEFINITE CONSTRAINT
1485     C
1486     parameter ( R12 = 1./12. )
1487     dimension A6(IM),AR(IM),AL(IM),P(IM),DC(IM)
1488     C
1489     if(LMT.eq.0) then
1490     C Full constraint
1491     do 100 i=1,IM
1492     if(DC(i).eq.0.) then
1493     AR(i) = p(i)
1494     AL(i) = p(i)
1495     A6(i) = 0.
1496     else
1497     da1 = AR(i) - AL(i)
1498     da2 = da1**2
1499     A6DA = A6(i)*da1
1500     if(A6DA .lt. -da2) then
1501     A6(i) = 3.*(AL(i)-p(i))
1502     AR(i) = AL(i) - A6(i)
1503     elseif(A6DA .gt. da2) then
1504     A6(i) = 3.*(AR(i)-p(i))
1505     AL(i) = AR(i) - A6(i)
1506     endif
1507     endif
1508     100 continue
1509     elseif(LMT.eq.1) then
1510     C Semi-monotonic constraint
1511     do 150 i=1,IM
1512     if(abs(AR(i)-AL(i)) .GE. -A6(i)) go to 150
1513     if(p(i).lt.AR(i) .and. p(i).lt.AL(i)) then
1514     AR(i) = p(i)
1515     AL(i) = p(i)
1516     A6(i) = 0.
1517     elseif(AR(i) .gt. AL(i)) then
1518     A6(i) = 3.*(AL(i)-p(i))
1519     AR(i) = AL(i) - A6(i)
1520     else
1521     A6(i) = 3.*(AR(i)-p(i))
1522     AL(i) = AR(i) - A6(i)
1523     endif
1524     150 continue
1525     elseif(LMT.eq.2) then
1526     do 250 i=1,IM
1527     if(abs(AR(i)-AL(i)) .GE. -A6(i)) go to 250
1528     fmin = p(i) + 0.25*(AR(i)-AL(i))**2/A6(i) + A6(i)*R12
1529     if(fmin.ge.0.) go to 250
1530     if(p(i).lt.AR(i) .and. p(i).lt.AL(i)) then
1531     AR(i) = p(i)
1532     AL(i) = p(i)
1533     A6(i) = 0.
1534     elseif(AR(i) .gt. AL(i)) then
1535     A6(i) = 3.*(AL(i)-p(i))
1536     AR(i) = AL(i) - A6(i)
1537     else
1538     A6(i) = 3.*(AR(i)-p(i))
1539     AL(i) = AR(i) - A6(i)
1540     endif
1541     250 continue
1542     endif
1543     return
1544     end
1545     C
1546     subroutine A2C(U,V,IMR,JMR,j1,j2,CRX,CRY,dtdx5,DTDY5)
1547     dimension U(IMR,*),V(IMR,*),CRX(IMR,*),CRY(IMR,*),DTDX5(*)
1548     C
1549     do 35 j=j1,j2
1550     do 35 i=2,IMR
1551     35 CRX(i,J) = dtdx5(j)*(U(i,j)+U(i-1,j))
1552     C
1553     do 45 j=j1,j2
1554     45 CRX(1,J) = dtdx5(j)*(U(1,j)+U(IMR,j))
1555     C
1556     do 55 i=1,IMR*JMR
1557     55 CRY(i,2) = DTDY5*(V(i,2)+V(i,1))
1558     return
1559     end
1560     C
1561     subroutine cosa(cosp,cose,JNP,PI,DP)
1562     dimension cosp(*),cose(*)
1563     JMR = JNP-1
1564     do 55 j=2,JNP
1565     ph5 = -0.5*PI + (FLOAT(J-1)-0.5)*DP
1566     55 cose(j) = cos(ph5)
1567     C
1568     JEQ = (JNP+1) / 2
1569     if(JMR .eq. 2*(JMR/2) ) then
1570     do j=JNP, JEQ+1, -1
1571     cose(j) = cose(JNP+2-j)
1572     enddo
1573     else
1574     C cell edge at equator.
1575     cose(JEQ+1) = 1.
1576     do j=JNP, JEQ+2, -1
1577     cose(j) = cose(JNP+2-j)
1578     enddo
1579     endif
1580     C
1581     do 66 j=2,JMR
1582     66 cosp(j) = 0.5*(cose(j)+cose(j+1))
1583     cosp(1) = 0.
1584     cosp(JNP) = 0.
1585     return
1586     end
1587     C
1588     subroutine cosc(cosp,cose,JNP,PI,DP)
1589     dimension cosp(*),cose(*)
1590     C
1591     phi = -0.5*PI
1592     do 55 j=2,JNP-1
1593     phi = phi + DP
1594     55 cosp(j) = cos(phi)
1595     cosp( 1) = 0.
1596     cosp(JNP) = 0.
1597     C
1598     do 66 j=2,JNP
1599     cose(j) = 0.5*(cosp(j)+cosp(j-1))
1600     66 CONTINUE
1601     C
1602     do 77 j=2,JNP-1
1603     cosp(j) = 0.5*(cose(j)+cose(j+1))
1604     77 CONTINUE
1605     return
1606     end
1607     C
1608     SUBROUTINE qckxyz (Q,qtmp,IMR,JNP,NLAY,j1,j2,cosp,acosp,
1609     & cross,IC,NSTEP)
1610     C
1611     parameter( tiny = 1.E-60 )
1612     DIMENSION Q(IMR,JNP,NLAY),qtmp(IMR,JNP),cosp(*),acosp(*)
1613     logical cross
1614     C
1615     NLAYM1 = NLAY-1
1616     len = IMR*(j2-j1+1)
1617     ip = 0
1618     C
1619     C Top layer
1620     L = 1
1621     icr = 1
1622     call filns(q(1,1,L),IMR,JNP,j1,j2,cosp,acosp,ipy,tiny)
1623     if(ipy.eq.0) goto 50
1624     call filew(q(1,1,L),qtmp,IMR,JNP,j1,j2,ipx,tiny)
1625     if(ipx.eq.0) goto 50
1626     C
1627     if(cross) then
1628     call filcr(q(1,1,L),IMR,JNP,j1,j2,cosp,acosp,icr,tiny)
1629     endif
1630     if(icr.eq.0) goto 50
1631     C
1632     C Vertical filling...
1633     do i=1,len
1634     IF( Q(i,j1,1).LT.0.) THEN
1635     ip = ip + 1
1636     Q(i,j1,2) = Q(i,j1,2) + Q(i,j1,1)
1637     Q(i,j1,1) = 0.
1638     endif
1639     enddo
1640     C
1641     50 continue
1642     DO 225 L = 2,NLAYM1
1643     icr = 1
1644     C
1645     call filns(q(1,1,L),IMR,JNP,j1,j2,cosp,acosp,ipy,tiny)
1646     if(ipy.eq.0) goto 225
1647     call filew(q(1,1,L),qtmp,IMR,JNP,j1,j2,ipx,tiny)
1648     if(ipx.eq.0) go to 225
1649     if(cross) then
1650     call filcr(q(1,1,L),IMR,JNP,j1,j2,cosp,acosp,icr,tiny)
1651     endif
1652     if(icr.eq.0) goto 225
1653     C
1654     do i=1,len
1655     IF( Q(I,j1,L).LT.0.) THEN
1656     C
1657     ip = ip + 1
1658     C From above
1659     qup = Q(I,j1,L-1)
1660     qly = -Q(I,j1,L)
1661     dup = min(qly,qup)
1662     Q(I,j1,L-1) = qup - dup
1663     Q(I,j1,L ) = dup-qly
1664     C Below
1665     Q(I,j1,L+1) = Q(I,j1,L+1) + Q(I,j1,L)
1666     Q(I,j1,L) = 0.
1667     ENDIF
1668     ENDDO
1669     225 CONTINUE
1670     C
1671     C BOTTOM LAYER
1672     sum = 0.
1673     L = NLAY
1674     C
1675     call filns(q(1,1,L),IMR,JNP,j1,j2,cosp,acosp,ipy,tiny)
1676     if(ipy.eq.0) goto 911
1677     call filew(q(1,1,L),qtmp,IMR,JNP,j1,j2,ipx,tiny)
1678     if(ipx.eq.0) goto 911
1679     C
1680     call filcr(q(1,1,L),IMR,JNP,j1,j2,cosp,acosp,icr,tiny)
1681     if(icr.eq.0) goto 911
1682     C
1683     DO I=1,len
1684     IF( Q(I,j1,L).LT.0.) THEN
1685     ip = ip + 1
1686     c
1687     C From above
1688     C
1689     qup = Q(I,j1,NLAYM1)
1690     qly = -Q(I,j1,L)
1691     dup = min(qly,qup)
1692     Q(I,j1,NLAYM1) = qup - dup
1693     C From "below" the surface.
1694     sum = sum + qly-dup
1695     Q(I,j1,L) = 0.
1696     ENDIF
1697     ENDDO
1698     C
1699     911 continue
1700     C
1701     if(ip.gt.IMR) then
1702     write(6,*) 'IC=',IC,' STEP=',NSTEP,
1703     & ' Vertical filling pts=',ip
1704     endif
1705     C
1706     if(sum.gt.1.e-25) then
1707     write(6,*) IC,NSTEP,' Mass source from the ground=',sum
1708     endif
1709     RETURN
1710     END
1711     C
1712     subroutine filcr(q,IMR,JNP,j1,j2,cosp,acosp,icr,tiny)
1713     dimension q(IMR,*),cosp(*),acosp(*)
1714     icr = 0
1715     do 65 j=j1+1,j2-1
1716     DO 50 i=1,IMR-1
1717     IF(q(i,j).LT.0.) THEN
1718     icr = 1
1719     dq = - q(i,j)*cosp(j)
1720     C N-E
1721     dn = q(i+1,j+1)*cosp(j+1)
1722     d0 = max(0.,dn)
1723     d1 = min(dq,d0)
1724     q(i+1,j+1) = (dn - d1)*acosp(j+1)
1725     dq = dq - d1
1726     C S-E
1727     ds = q(i+1,j-1)*cosp(j-1)
1728     d0 = max(0.,ds)
1729     d2 = min(dq,d0)
1730     q(i+1,j-1) = (ds - d2)*acosp(j-1)
1731     q(i,j) = (d2 - dq)*acosp(j) + tiny
1732     endif
1733     50 continue
1734     if(icr.eq.0 .and. q(IMR,j).ge.0.) goto 65
1735     DO 55 i=2,IMR
1736     IF(q(i,j).LT.0.) THEN
1737     icr = 1
1738     dq = - q(i,j)*cosp(j)
1739     C N-W
1740     dn = q(i-1,j+1)*cosp(j+1)
1741     d0 = max(0.,dn)
1742     d1 = min(dq,d0)
1743     q(i-1,j+1) = (dn - d1)*acosp(j+1)
1744     dq = dq - d1
1745     C S-W
1746     ds = q(i-1,j-1)*cosp(j-1)
1747     d0 = max(0.,ds)
1748     d2 = min(dq,d0)
1749     q(i-1,j-1) = (ds - d2)*acosp(j-1)
1750     q(i,j) = (d2 - dq)*acosp(j) + tiny
1751     endif
1752     55 continue
1753     C *****************************************
1754     C i=1
1755     i=1
1756     IF(q(i,j).LT.0.) THEN
1757     icr = 1
1758     dq = - q(i,j)*cosp(j)
1759     C N-W
1760     dn = q(IMR,j+1)*cosp(j+1)
1761     d0 = max(0.,dn)
1762     d1 = min(dq,d0)
1763     q(IMR,j+1) = (dn - d1)*acosp(j+1)
1764     dq = dq - d1
1765     C S-W
1766     ds = q(IMR,j-1)*cosp(j-1)
1767     d0 = max(0.,ds)
1768     d2 = min(dq,d0)
1769     q(IMR,j-1) = (ds - d2)*acosp(j-1)
1770     q(i,j) = (d2 - dq)*acosp(j) + tiny
1771     endif
1772     C *****************************************
1773     C i=IMR
1774     i=IMR
1775     IF(q(i,j).LT.0.) THEN
1776     icr = 1
1777     dq = - q(i,j)*cosp(j)
1778     C N-E
1779     dn = q(1,j+1)*cosp(j+1)
1780     d0 = max(0.,dn)
1781     d1 = min(dq,d0)
1782     q(1,j+1) = (dn - d1)*acosp(j+1)
1783     dq = dq - d1
1784     C S-E
1785     ds = q(1,j-1)*cosp(j-1)
1786     d0 = max(0.,ds)
1787     d2 = min(dq,d0)
1788     q(1,j-1) = (ds - d2)*acosp(j-1)
1789     q(i,j) = (d2 - dq)*acosp(j) + tiny
1790     endif
1791     C *****************************************
1792     65 continue
1793     C
1794     do i=1,IMR
1795     if(q(i,j1).lt.0. .or. q(i,j2).lt.0.) then
1796     icr = 1
1797     goto 80
1798     endif
1799     enddo
1800     C
1801     80 continue
1802     C
1803     if(q(1,1).lt.0. .or. q(1,jnp).lt.0.) then
1804     icr = 1
1805     endif
1806     C
1807     return
1808     end
1809     C
1810     subroutine filns(q,IMR,JNP,j1,j2,cosp,acosp,ipy,tiny)
1811     dimension q(IMR,*),cosp(*),acosp(*)
1812     c logical first
1813     c data first /.true./
1814     c save cap1
1815     C
1816     c if(first) then
1817     DP = 4.*ATAN(1.)/float(JNP-1)
1818     CAP1 = IMR*(1.-COS((j1-1.5)*DP))/DP
1819     c first = .false.
1820     c endif
1821     C
1822     ipy = 0
1823     do 55 j=j1+1,j2-1
1824     DO 55 i=1,IMR
1825     IF(q(i,j).LT.0.) THEN
1826     ipy = 1
1827     dq = - q(i,j)*cosp(j)
1828     C North
1829     dn = q(i,j+1)*cosp(j+1)
1830     d0 = max(0.,dn)
1831     d1 = min(dq,d0)
1832     q(i,j+1) = (dn - d1)*acosp(j+1)
1833     dq = dq - d1
1834     C South
1835     ds = q(i,j-1)*cosp(j-1)
1836     d0 = max(0.,ds)
1837     d2 = min(dq,d0)
1838     q(i,j-1) = (ds - d2)*acosp(j-1)
1839     q(i,j) = (d2 - dq)*acosp(j) + tiny
1840     endif
1841     55 continue
1842     C
1843     do i=1,imr
1844     IF(q(i,j1).LT.0.) THEN
1845     ipy = 1
1846     dq = - q(i,j1)*cosp(j1)
1847     C North
1848     dn = q(i,j1+1)*cosp(j1+1)
1849     d0 = max(0.,dn)
1850     d1 = min(dq,d0)
1851     q(i,j1+1) = (dn - d1)*acosp(j1+1)
1852     q(i,j1) = (d1 - dq)*acosp(j1) + tiny
1853     endif
1854     enddo
1855     C
1856     j = j2
1857     do i=1,imr
1858     IF(q(i,j).LT.0.) THEN
1859     ipy = 1
1860     dq = - q(i,j)*cosp(j)
1861     C South
1862     ds = q(i,j-1)*cosp(j-1)
1863     d0 = max(0.,ds)
1864     d2 = min(dq,d0)
1865     q(i,j-1) = (ds - d2)*acosp(j-1)
1866     q(i,j) = (d2 - dq)*acosp(j) + tiny
1867     endif
1868     enddo
1869     C
1870     C Check Poles.
1871     if(q(1,1).lt.0.) then
1872     dq = q(1,1)*cap1/float(IMR)*acosp(j1)
1873     do i=1,imr
1874     q(i,1) = 0.
1875     q(i,j1) = q(i,j1) + dq
1876     if(q(i,j1).lt.0.) ipy = 1
1877     enddo
1878     endif
1879     C
1880     if(q(1,JNP).lt.0.) then
1881     dq = q(1,JNP)*cap1/float(IMR)*acosp(j2)
1882     do i=1,imr
1883     q(i,JNP) = 0.
1884     q(i,j2) = q(i,j2) + dq
1885     if(q(i,j2).lt.0.) ipy = 1
1886     enddo
1887     endif
1888     C
1889     return
1890     end
1891     C
1892     subroutine filew(q,qtmp,IMR,JNP,j1,j2,ipx,tiny)
1893     dimension q(IMR,*),qtmp(JNP,IMR)
1894     C
1895     ipx = 0
1896     C Copy & swap direction for vectorization.
1897     do 25 i=1,imr
1898     do 25 j=j1,j2
1899     25 qtmp(j,i) = q(i,j)
1900     C
1901     do 55 i=2,imr-1
1902     do 55 j=j1,j2
1903     if(qtmp(j,i).lt.0.) then
1904     ipx = 1
1905     c west
1906     d0 = max(0.,qtmp(j,i-1))
1907     d1 = min(-qtmp(j,i),d0)
1908     qtmp(j,i-1) = qtmp(j,i-1) - d1
1909     qtmp(j,i) = qtmp(j,i) + d1
1910     c east
1911     d0 = max(0.,qtmp(j,i+1))
1912     d2 = min(-qtmp(j,i),d0)
1913     qtmp(j,i+1) = qtmp(j,i+1) - d2
1914     qtmp(j,i) = qtmp(j,i) + d2 + tiny
1915     endif
1916     55 continue
1917     c
1918     i=1
1919     do 65 j=j1,j2
1920     if(qtmp(j,i).lt.0.) then
1921     ipx = 1
1922     c west
1923     d0 = max(0.,qtmp(j,imr))
1924     d1 = min(-qtmp(j,i),d0)
1925     qtmp(j,imr) = qtmp(j,imr) - d1
1926     qtmp(j,i) = qtmp(j,i) + d1
1927     c east
1928     d0 = max(0.,qtmp(j,i+1))
1929     d2 = min(-qtmp(j,i),d0)
1930     qtmp(j,i+1) = qtmp(j,i+1) - d2
1931     c
1932     qtmp(j,i) = qtmp(j,i) + d2 + tiny
1933     endif
1934     65 continue
1935     i=IMR
1936     do 75 j=j1,j2
1937     if(qtmp(j,i).lt.0.) then
1938     ipx = 1
1939     c west
1940     d0 = max(0.,qtmp(j,i-1))
1941     d1 = min(-qtmp(j,i),d0)
1942     qtmp(j,i-1) = qtmp(j,i-1) - d1
1943     qtmp(j,i) = qtmp(j,i) + d1
1944     c east
1945     d0 = max(0.,qtmp(j,1))
1946     d2 = min(-qtmp(j,i),d0)
1947     qtmp(j,1) = qtmp(j,1) - d2
1948     c
1949     qtmp(j,i) = qtmp(j,i) + d2 + tiny
1950     endif
1951     75 continue
1952     C
1953     if(ipx.ne.0) then
1954     do 85 j=j1,j2
1955     do 85 i=1,imr
1956     85 q(i,j) = qtmp(j,i)
1957     else
1958     C
1959     C Poles.
1960     if(q(1,1).lt.0. or. q(1,JNP).lt.0.) ipx = 1
1961     endif
1962     return
1963     end

  ViewVC Help
Powered by ViewVC 1.1.21