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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 166 - (hide annotations)
Wed Jul 29 14:32:55 2015 UTC (8 years, 11 months ago) by guez
File size: 20166 byte(s)
Split ppm3d.f into files containing a single procedure.

Factorized computations of filtering matrices into a procedure
inifilr_hemisph. Had then to change the matrices from allocatable to
pointer and from customized lower bound to lower bound 1. The change
in lower bounds does not matter because the matrices are only used as
a whole as actual arguments.

Also, in infilr, instead of finding jfilt[ns][uv] from approximately
jjm /2, start at index j1 that corresponds to the equator. This is not
the same if there is a zoom in latitude.

Also, the test (rlamda(modfrst[ns][uv](j)) * cos(rlat[uv](j)) < 1) in
the loops on filtered latitudes is not useful now that we start from
j1: it is necessarily true. See notes.

Just encapsulated lwvn into a module and removed unused argument ktraer.

1 guez 81 SUBROUTINE ppm3d(igd, q, ps1, ps2, u, v, w, ndt, iord, jord, kord, nc, imr, &
2     jnp, j1, nlay, ap, bp, pt, ae, fill, dum, umax)
3    
4     ! implicit none
5    
6     ! rajout de déclarations
7     ! integer Jmax,kmax,ndt0,nstep,k,j,i,ic,l,js,jn,imh,iad,jad,krd
8     ! integer iu,iiu,j2,jmr,js0,jt
9     ! real dtdy,dtdy5,rcap,iml,jn0,imjm,pi,dl,dp
10     ! real dt,cr1,maxdt,ztc,d5,sum1,sum2,ru
11    
12     ! ********************************************************************
13    
14     ! =============
15     ! INPUT:
16     ! =============
17    
18     ! Q(IMR,JNP,NLAY,NC): mixing ratios at current time (t)
19     ! NC: total number of constituents
20     ! IMR: first dimension (E-W); number of Grid intervals in E-W is IMR
21     ! JNP: 2nd dimension (N-S); number of Grid intervals in N-S is JNP-1
22     ! NLAY: 3rd dimension (number of layers); vertical index increases from 1
23     ! at
24     ! the model top to NLAY near the surface (see fig. below).
25     ! It is assumed that 6 <= NLAY <= JNP (for dynamic memory allocation)
26    
27     ! PS1(IMR,JNP): surface pressure at current time (t)
28     ! PS2(IMR,JNP): surface pressure at mid-time-level (t+NDT/2)
29     ! PS2 is replaced by the predicted PS (at t+NDT) on output.
30     ! Note: surface pressure can have any unit or can be multiplied by any
31     ! const.
32    
33     ! The pressure at layer edges are defined as follows:
34    
35     ! p(i,j,k) = AP(k)*PT + BP(k)*PS(i,j) (1)
36    
37     ! Where PT is a constant having the same unit as PS.
38     ! AP and BP are unitless constants given at layer edges
39     ! defining the vertical coordinate.
40     ! BP(1) = 0., BP(NLAY+1) = 1.
41     ! The pressure at the model top is PTOP = AP(1)*PT
42    
43     ! For pure sigma system set AP(k) = 1 for all k, PT = PTOP,
44     ! BP(k) = sige(k) (sigma at edges), PS = Psfc - PTOP.
45    
46     ! Note: the sigma-P coordinate is a subset of Eq. 1, which in turn
47     ! is a subset of the following even more general sigma-P-thelta coord.
48     ! currently under development.
49     ! p(i,j,k) = (AP(k)*PT + BP(k)*PS(i,j))/(D(k)-C(k)*TE**(-1/kapa))
50    
51     ! /////////////////////////////////
52     ! / \ ------------- PTOP -------------- AP(1), BP(1)
53     ! |
54     ! delp(1) | ........... Q(i,j,1) ............
55     ! |
56     ! W(1) \ / --------------------------------- AP(2), BP(2)
57    
58    
59    
60     ! W(k-1) / \ --------------------------------- AP(k), BP(k)
61     ! |
62     ! delp(K) | ........... Q(i,j,k) ............
63     ! |
64     ! W(k) \ / --------------------------------- AP(k+1), BP(k+1)
65    
66    
67    
68     ! / \ --------------------------------- AP(NLAY), BP(NLAY)
69     ! |
70     ! delp(NLAY) | ........... Q(i,j,NLAY) .........
71     ! |
72     ! W(NLAY)=0 \ / ------------- surface ----------- AP(NLAY+1), BP(NLAY+1)
73     ! //////////////////////////////////
74    
75     ! U(IMR,JNP,NLAY) & V(IMR,JNP,NLAY):winds (m/s) at mid-time-level (t+NDT/2)
76     ! U and V may need to be polar filtered in advance in some cases.
77    
78     ! IGD: grid type on which winds are defined.
79     ! IGD = 0: A-Grid [all variables defined at the same point from south
80     ! pole (j=1) to north pole (j=JNP) ]
81    
82     ! IGD = 1 GEOS-GCM C-Grid
83     ! [North]
84    
85     ! V(i,j)
86     ! |
87     ! |
88     ! |
89     ! U(i-1,j)---Q(i,j)---U(i,j) [EAST]
90     ! |
91     ! |
92     ! |
93     ! V(i,j-1)
94    
95     ! U(i, 1) is defined at South Pole.
96     ! V(i, 1) is half grid north of the South Pole.
97     ! V(i,JMR) is half grid south of the North Pole.
98    
99     ! V must be defined at j=1 and j=JMR if IGD=1
100     ! V at JNP need not be given.
101    
102     ! NDT: time step in seconds (need not be constant during the course of
103     ! the integration). Suggested value: 30 min. for 4x5, 15 min. for 2x2.5
104     ! (Lat-Lon) resolution. Smaller values are recommanded if the model
105     ! has a well-resolved stratosphere.
106    
107     ! J1 defines the size of the polar cap:
108     ! South polar cap edge is located at -90 + (j1-1.5)*180/(JNP-1) deg.
109     ! North polar cap edge is located at 90 - (j1-1.5)*180/(JNP-1) deg.
110     ! There are currently only two choices (j1=2 or 3).
111     ! IMR must be an even integer if j1 = 2. Recommended value: J1=3.
112    
113     ! IORD, JORD, and KORD are integers controlling various options in E-W,
114     ! N-S,
115     ! and vertical transport, respectively. Recommended values for positive
116     ! definite scalars: IORD=JORD=3, KORD=5. Use KORD=3 for non-
117     ! positive definite scalars or when linear correlation between constituents
118     ! is to be maintained.
119    
120     ! _ORD=
121     ! 1: 1st order upstream scheme (too diffusive, not a useful option; it
122     ! can be used for debugging purposes; this is THE only known "linear"
123     ! monotonic advection scheme.).
124     ! 2: 2nd order van Leer (full monotonicity constraint;
125     ! see Lin et al 1994, MWR)
126     ! 3: monotonic PPM* (slightly improved PPM of Collela & Woodward 1984)
127     ! 4: semi-monotonic PPM (same as 3, but overshoots are allowed)
128     ! 5: positive-definite PPM (constraint on the subgrid distribution is
129     ! only strong enough to prevent generation of negative values;
130     ! both overshoots & undershoots are possible).
131     ! 6: un-constrained PPM (nearly diffusion free; slightly faster but
132     ! positivity not quaranteed. Use this option only when the fields
133     ! and winds are very smooth).
134    
135     ! *PPM: Piece-wise Parabolic Method
136    
137     ! Note that KORD <=2 options are no longer supported. DO not use option 4
138     ! or 5.
139     ! for non-positive definite scalars (such as Ertel Potential Vorticity).
140    
141     ! The implicit numerical diffusion decreases as _ORD increases.
142     ! The last two options (ORDER=5, 6) should only be used when there is
143     ! significant explicit diffusion (such as a turbulence parameterization).
144     ! You
145     ! might get dispersive results otherwise.
146     ! No filter of any kind is applied to the constituent fields here.
147    
148     ! AE: Radius of the sphere (meters).
149     ! Recommended value for the planet earth: 6.371E6
150    
151     ! fill(logical): flag to do filling for negatives (see note below).
152    
153     ! Umax: Estimate (upper limit) of the maximum U-wind speed (m/s).
154     ! (220 m/s is a good value for troposphere model; 280 m/s otherwise)
155    
156     ! =============
157     ! Output
158     ! =============
159    
160     ! Q: mixing ratios at future time (t+NDT) (original values are
161     ! over-written)
162     ! W(NLAY): large-scale vertical mass flux as diagnosed from the hydrostatic
163     ! relationship. W will have the same unit as PS1 and PS2 (eg, mb).
164     ! W must be divided by NDT to get the correct mass-flux unit.
165     ! The vertical Courant number C = W/delp_UPWIND, where delp_UPWIND
166     ! is the pressure thickness in the "upwind" direction. For example,
167     ! C(k) = W(k)/delp(k) if W(k) > 0;
168     ! C(k) = W(k)/delp(k+1) if W(k) < 0.
169     ! ( W > 0 is downward, ie, toward surface)
170     ! PS2: predicted PS at t+NDT (original values are over-written)
171    
172     ! ********************************************************************
173     ! NOTES:
174     ! This forward-in-time upstream-biased transport scheme reduces to
175     ! the 2nd order center-in-time center-in-space mass continuity eqn.
176     ! if Q = 1 (constant fields will remain constant). This also ensures
177     ! that the computed vertical velocity to be identical to GEOS-1 GCM
178     ! for on-line transport.
179    
180     ! A larger polar cap is used if j1=3 (recommended for C-Grid winds or when
181     ! winds are noisy near poles).
182    
183     ! Flux-Form Semi-Lagrangian transport in the East-West direction is used
184     ! when and where Courant number is greater than one.
185    
186     ! The user needs to change the parameter Jmax or Kmax if the resolution
187     ! is greater than 0.5 deg in N-S or 150 layers in the vertical direction.
188     ! (this TransPort Core is otherwise resolution independent and can be used
189     ! as a library routine).
190    
191     ! PPM is 4th order accurate when grid spacing is uniform (x & y); 3rd
192     ! order accurate for non-uniform grid (vertical sigma coord.).
193    
194     ! Time step is limitted only by transport in the meridional direction.
195     ! (the FFSL scheme is not implemented in the meridional direction).
196    
197     ! Since only 1-D limiters are applied, negative values could
198     ! potentially be generated when large time step is used and when the
199     ! initial fields contain discontinuities.
200     ! This does not necessarily imply the integration is unstable.
201     ! These negatives are typically very small. A filling algorithm is
202     ! activated if the user set "fill" to be true.
203    
204     ! The van Leer scheme used here is nearly as accurate as the original PPM
205     ! due to the use of a 4th order accurate reference slope. The PPM imple-
206     ! mented here is an improvement over the original and is also based on
207     ! the 4th order reference slope.
208    
209     ! ****6***0*********0*********0*********0*********0*********0**********72
210    
211     ! User modifiable parameters
212    
213     PARAMETER (jmax=361, kmax=150)
214    
215     ! ****6***0*********0*********0*********0*********0*********0**********72
216    
217     ! Input-Output arrays
218    
219    
220     REAL q(imr, jnp, nlay, nc), ps1(imr, jnp), ps2(imr, jnp), &
221     u(imr, jnp, nlay), v(imr, jnp, nlay), ap(nlay+1), bp(nlay+1), &
222     w(imr, jnp, nlay), ndt, val(nlay), umax
223     INTEGER igd, iord, jord, kord, nc, imr, jnp, j1, nlay, ae
224     INTEGER imrd2
225     REAL pt
226     LOGICAL cross, fill, dum
227    
228     ! Local dynamic arrays
229    
230     REAL crx(imr, jnp), cry(imr, jnp), xmass(imr, jnp), ymass(imr, jnp), &
231     fx1(imr+1), dpi(imr, jnp, nlay), delp1(imr, jnp, nlay), &
232     wk1(imr, jnp, nlay), pu(imr, jnp), pv(imr, jnp), dc2(imr, jnp), &
233     delp2(imr, jnp, nlay), dq(imr, jnp, nlay, nc), va(imr, jnp), &
234     ua(imr, jnp), qtmp(-imr:2*imr)
235    
236     ! Local static arrays
237    
238     REAL dtdx(jmax), dtdx5(jmax), acosp(jmax), cosp(jmax), cose(jmax), &
239     dap(kmax), dbk(kmax)
240     DATA ndt0, nstep/0, 0/
241     DATA cross/.TRUE./
242     SAVE dtdy, dtdy5, rcap, js0, jn0, iml, dtdx, dtdx5, acosp, cosp, cose, dap, &
243     dbk
244    
245    
246     jmr = jnp - 1
247     imjm = imr*jnp
248     j2 = jnp - j1 + 1
249     nstep = nstep + 1
250    
251     ! *********** Initialization **********************
252     IF (nstep==1) THEN
253    
254     WRITE (6, *) '------------------------------------ '
255     WRITE (6, *) 'NASA/GSFC Transport Core Version 4.5'
256     WRITE (6, *) '------------------------------------ '
257    
258     WRITE (6, *) 'IMR=', imr, ' JNP=', jnp, ' NLAY=', nlay, ' j1=', j1
259     WRITE (6, *) 'NC=', nc, iord, jord, kord, ndt
260    
261     ! controles sur les parametres
262     IF (nlay<6) THEN
263     WRITE (6, *) 'NLAY must be >= 6'
264     STOP
265     END IF
266     IF (jnp<nlay) THEN
267     WRITE (6, *) 'JNP must be >= NLAY'
268     STOP
269     END IF
270     imrd2 = mod(imr, 2)
271     IF (j1==2 .AND. imrd2/=0) THEN
272     WRITE (6, *) 'if j1=2 IMR must be an even integer'
273     STOP
274     END IF
275    
276    
277     IF (jmax<jnp .OR. kmax<nlay) THEN
278     WRITE (6, *) 'Jmax or Kmax is too small'
279     STOP
280     END IF
281    
282     DO k = 1, nlay
283     dap(k) = (ap(k+1)-ap(k))*pt
284     dbk(k) = bp(k+1) - bp(k)
285     END DO
286    
287     pi = 4.*atan(1.)
288     dl = 2.*pi/float(imr)
289     dp = pi/float(jmr)
290    
291     IF (igd==0) THEN
292     ! Compute analytic cosine at cell edges
293     CALL cosa(cosp, cose, jnp, pi, dp)
294     ELSE
295     ! Define cosine consistent with GEOS-GCM (using dycore2.0 or later)
296     CALL cosc(cosp, cose, jnp, pi, dp)
297     END IF
298    
299     DO j = 2, jmr
300     acosp(j) = 1./cosp(j)
301     END DO
302    
303     ! Inverse of the Scaled polar cap area.
304    
305     rcap = dp/(imr*(1.-cos((j1-1.5)*dp)))
306     acosp(1) = rcap
307     acosp(jnp) = rcap
308     END IF
309    
310     IF (ndt0/=ndt) THEN
311     dt = ndt
312     ndt0 = ndt
313    
314     IF (umax<180.) THEN
315     WRITE (6, *) 'Umax may be too small!'
316     END IF
317     cr1 = abs(umax*dt)/(dl*ae)
318     maxdt = dp*ae/abs(umax) + 0.5
319     WRITE (6, *) 'Largest time step for max(V)=', umax, ' is ', maxdt
320     IF (maxdt<abs(ndt)) THEN
321     WRITE (6, *) 'Warning!!! NDT maybe too large!'
322     END IF
323    
324     IF (cr1>=0.95) THEN
325     js0 = 0
326     jn0 = 0
327     iml = imr - 2
328     ztc = 0.
329     ELSE
330     ztc = acos(cr1)*(180./pi)
331    
332     js0 = float(jmr)*(90.-ztc)/180. + 2
333     js0 = max(js0, j1+1)
334     iml = min(6*js0/(j1-1)+2, 4*imr/5)
335     jn0 = jnp - js0 + 1
336     END IF
337    
338    
339     DO j = 2, jmr
340     dtdx(j) = dt/(dl*ae*cosp(j))
341    
342     dtdx5(j) = 0.5*dtdx(j)
343     END DO
344    
345    
346     dtdy = dt/(ae*dp)
347     dtdy5 = 0.5*dtdy
348    
349     END IF
350    
351     ! *********** End Initialization **********************
352    
353     ! delp = pressure thickness: the psudo-density in a hydrostatic system.
354     DO k = 1, nlay
355     DO j = 1, jnp
356     DO i = 1, imr
357     delp1(i, j, k) = dap(k) + dbk(k)*ps1(i, j)
358     delp2(i, j, k) = dap(k) + dbk(k)*ps2(i, j)
359     END DO
360     END DO
361     END DO
362    
363    
364     IF (j1/=2) THEN
365     DO ic = 1, nc
366     DO l = 1, nlay
367     DO i = 1, imr
368     q(i, 2, l, ic) = q(i, 1, l, ic)
369     q(i, jmr, l, ic) = q(i, jnp, l, ic)
370     END DO
371     END DO
372     END DO
373     END IF
374    
375     ! Compute "tracer density"
376     DO ic = 1, nc
377     DO k = 1, nlay
378     DO j = 1, jnp
379     DO i = 1, imr
380     dq(i, j, k, ic) = q(i, j, k, ic)*delp1(i, j, k)
381     END DO
382     END DO
383     END DO
384     END DO
385    
386     DO k = 1, nlay
387    
388     IF (igd==0) THEN
389     ! Convert winds on A-Grid to Courant number on C-Grid.
390     CALL a2c(u(1,1,k), v(1,1,k), imr, jmr, j1, j2, crx, cry, dtdx5, dtdy5)
391     ELSE
392     ! Convert winds on C-grid to Courant number
393     DO j = j1, j2
394     DO i = 2, imr
395     crx(i, j) = dtdx(j)*u(i-1, j, k)
396     END DO
397     END DO
398    
399    
400     DO j = j1, j2
401     crx(1, j) = dtdx(j)*u(imr, j, k)
402     END DO
403    
404     DO i = 1, imr*jmr
405     cry(i, 2) = dtdy*v(i, 1, k)
406     END DO
407     END IF
408    
409     ! Determine JS and JN
410     js = j1
411     jn = j2
412    
413     DO j = js0, j1 + 1, -1
414     DO i = 1, imr
415     IF (abs(crx(i,j))>1.) THEN
416     js = j
417     GO TO 2222
418     END IF
419     END DO
420     END DO
421    
422     2222 CONTINUE
423     DO j = jn0, j2 - 1
424     DO i = 1, imr
425     IF (abs(crx(i,j))>1.) THEN
426     jn = j
427     GO TO 2233
428     END IF
429     END DO
430     END DO
431     2233 CONTINUE
432    
433     IF (j1/=2) THEN ! Enlarged polar cap.
434     DO i = 1, imr
435     dpi(i, 2, k) = 0.
436     dpi(i, jmr, k) = 0.
437     END DO
438     END IF
439    
440     ! ******* Compute horizontal mass fluxes ************
441    
442     ! N-S component
443     DO j = j1, j2 + 1
444     d5 = 0.5*cose(j)
445     DO i = 1, imr
446     ymass(i, j) = cry(i, j)*d5*(delp2(i,j,k)+delp2(i,j-1,k))
447     END DO
448     END DO
449    
450     DO j = j1, j2
451     DO i = 1, imr
452     dpi(i, j, k) = (ymass(i,j)-ymass(i,j+1))*acosp(j)
453     END DO
454     END DO
455    
456     ! Poles
457     sum1 = ymass(imr, j1)
458     sum2 = ymass(imr, j2+1)
459     DO i = 1, imr - 1
460     sum1 = sum1 + ymass(i, j1)
461     sum2 = sum2 + ymass(i, j2+1)
462     END DO
463    
464     sum1 = -sum1*rcap
465     sum2 = sum2*rcap
466     DO i = 1, imr
467     dpi(i, 1, k) = sum1
468     dpi(i, jnp, k) = sum2
469     END DO
470    
471     ! E-W component
472    
473     DO j = j1, j2
474     DO i = 2, imr
475     pu(i, j) = 0.5*(delp2(i,j,k)+delp2(i-1,j,k))
476     END DO
477     END DO
478    
479     DO j = j1, j2
480     pu(1, j) = 0.5*(delp2(1,j,k)+delp2(imr,j,k))
481     END DO
482    
483     DO j = j1, j2
484     DO i = 1, imr
485     xmass(i, j) = pu(i, j)*crx(i, j)
486     END DO
487     END DO
488    
489     DO j = j1, j2
490     DO i = 1, imr - 1
491     dpi(i, j, k) = dpi(i, j, k) + xmass(i, j) - xmass(i+1, j)
492     END DO
493     END DO
494    
495     DO j = j1, j2
496     dpi(imr, j, k) = dpi(imr, j, k) + xmass(imr, j) - xmass(1, j)
497     END DO
498    
499     DO j = j1, j2
500     DO i = 1, imr - 1
501     ua(i, j) = 0.5*(crx(i,j)+crx(i+1,j))
502     END DO
503     END DO
504    
505     DO j = j1, j2
506     ua(imr, j) = 0.5*(crx(imr,j)+crx(1,j))
507     END DO
508     ! cccccccccccccccccccccccccccccccccccccccccccccccccccccc
509     ! Rajouts pour LMDZ.3.3
510     ! cccccccccccccccccccccccccccccccccccccccccccccccccccccc
511     DO i = 1, imr
512     DO j = 1, jnp
513     va(i, j) = 0.
514     END DO
515     END DO
516    
517     DO i = 1, imr*(jmr-1)
518     va(i, 2) = 0.5*(cry(i,2)+cry(i,3))
519     END DO
520    
521     IF (j1==2) THEN
522     imh = imr/2
523     DO i = 1, imh
524     va(i, 1) = 0.5*(cry(i,2)-cry(i+imh,2))
525     va(i+imh, 1) = -va(i, 1)
526     va(i, jnp) = 0.5*(cry(i,jnp)-cry(i+imh,jmr))
527     va(i+imh, jnp) = -va(i, jnp)
528     END DO
529     va(imr, 1) = va(1, 1)
530     va(imr, jnp) = va(1, jnp)
531     END IF
532    
533     ! ****6***0*********0*********0*********0*********0*********0**********72
534     DO ic = 1, nc
535    
536     DO i = 1, imjm
537     wk1(i, 1, 1) = 0.
538     wk1(i, 1, 2) = 0.
539     END DO
540    
541     ! E-W advective cross term
542     DO j = j1, j2
543     IF (j>js .AND. j<jn) GO TO 250
544    
545     DO i = 1, imr
546     qtmp(i) = q(i, j, k, ic)
547     END DO
548    
549     DO i = -iml, 0
550     qtmp(i) = q(imr+i, j, k, ic)
551     qtmp(imr+1-i) = q(1-i, j, k, ic)
552     END DO
553    
554     DO i = 1, imr
555     iu = ua(i, j)
556     ru = ua(i, j) - iu
557     iiu = i - iu
558     IF (ua(i,j)>=0.) THEN
559     wk1(i, j, 1) = qtmp(iiu) + ru*(qtmp(iiu-1)-qtmp(iiu))
560     ELSE
561     wk1(i, j, 1) = qtmp(iiu) + ru*(qtmp(iiu)-qtmp(iiu+1))
562     END IF
563     wk1(i, j, 1) = wk1(i, j, 1) - qtmp(i)
564     END DO
565     250 END DO
566    
567     IF (jn/=0) THEN
568     DO j = js + 1, jn - 1
569    
570     DO i = 1, imr
571     qtmp(i) = q(i, j, k, ic)
572     END DO
573    
574     qtmp(0) = q(imr, j, k, ic)
575     qtmp(imr+1) = q(1, j, k, ic)
576    
577     DO i = 1, imr
578     iu = i - ua(i, j)
579     wk1(i, j, 1) = ua(i, j)*(qtmp(iu)-qtmp(iu+1))
580     END DO
581     END DO
582     END IF
583     ! ****6***0*********0*********0*********0*********0*********0**********72
584     ! Contribution from the N-S advection
585     DO i = 1, imr*(j2-j1+1)
586     jt = float(j1) - va(i, j1)
587     wk1(i, j1, 2) = va(i, j1)*(q(i,jt,k,ic)-q(i,jt+1,k,ic))
588     END DO
589    
590     DO i = 1, imjm
591     wk1(i, 1, 1) = q(i, 1, k, ic) + 0.5*wk1(i, 1, 1)
592     wk1(i, 1, 2) = q(i, 1, k, ic) + 0.5*wk1(i, 1, 2)
593     END DO
594    
595     IF (cross) THEN
596     ! Add cross terms in the vertical direction.
597     IF (iord>=2) THEN
598     iad = 2
599     ELSE
600     iad = 1
601     END IF
602    
603     IF (jord>=2) THEN
604     jad = 2
605     ELSE
606     jad = 1
607     END IF
608     CALL xadv(imr, jnp, j1, j2, wk1(1,1,2), ua, js, jn, iml, dc2, iad)
609     CALL yadv(imr, jnp, j1, j2, wk1(1,1,1), va, pv, w, jad)
610     DO j = 1, jnp
611     DO i = 1, imr
612     q(i, j, k, ic) = q(i, j, k, ic) + dc2(i, j) + pv(i, j)
613     END DO
614     END DO
615     END IF
616    
617     CALL xtp(imr, jnp, iml, j1, j2, jn, js, pu, dq(1,1,k,ic), wk1(1,1,2), &
618     crx, fx1, xmass, iord)
619    
620     CALL ytp(imr, jnp, j1, j2, acosp, rcap, dq(1,1,k,ic), wk1(1,1,1), cry, &
621     dc2, ymass, wk1(1,1,3), wk1(1,1,4), wk1(1,1,5), wk1(1,1,6), jord)
622    
623     END DO
624     END DO
625    
626     ! ******* Compute vertical mass flux (same unit as PS) ***********
627    
628     ! 1st step: compute total column mass CONVERGENCE.
629    
630     DO j = 1, jnp
631     DO i = 1, imr
632     cry(i, j) = dpi(i, j, 1)
633     END DO
634     END DO
635    
636     DO k = 2, nlay
637     DO j = 1, jnp
638     DO i = 1, imr
639     cry(i, j) = cry(i, j) + dpi(i, j, k)
640     END DO
641     END DO
642     END DO
643    
644     DO j = 1, jnp
645     DO i = 1, imr
646    
647     ! 2nd step: compute PS2 (PS at n+1) using the hydrostatic assumption.
648     ! Changes (increases) to surface pressure = total column mass
649     ! convergence
650    
651     ps2(i, j) = ps1(i, j) + cry(i, j)
652    
653     ! 3rd step: compute vertical mass flux from mass conservation
654     ! principle.
655    
656     w(i, j, 1) = dpi(i, j, 1) - dbk(1)*cry(i, j)
657     w(i, j, nlay) = 0.
658     END DO
659     END DO
660    
661     DO k = 2, nlay - 1
662     DO j = 1, jnp
663     DO i = 1, imr
664     w(i, j, k) = w(i, j, k-1) + dpi(i, j, k) - dbk(k)*cry(i, j)
665     END DO
666     END DO
667     END DO
668    
669     DO k = 1, nlay
670     DO j = 1, jnp
671     DO i = 1, imr
672     delp2(i, j, k) = dap(k) + dbk(k)*ps2(i, j)
673     END DO
674     END DO
675     END DO
676    
677     krd = max(3, kord)
678     DO ic = 1, nc
679    
680     ! ****6***0*********0*********0*********0*********0*********0**********72
681    
682     CALL fzppm(imr, jnp, nlay, j1, dq(1,1,1,ic), w, q(1,1,1,ic), wk1, dpi, &
683     dc2, crx, cry, pu, pv, xmass, ymass, delp1, krd)
684    
685    
686     IF (fill) CALL qckxyz(dq(1,1,1,ic), dc2, imr, jnp, nlay, j1, j2, cosp, &
687     acosp, .FALSE., ic, nstep)
688    
689     ! Recover tracer mixing ratio from "density" using predicted
690     ! "air density" (pressure thickness) at time-level n+1
691    
692     DO k = 1, nlay
693     DO j = 1, jnp
694     DO i = 1, imr
695     q(i, j, k, ic) = dq(i, j, k, ic)/delp2(i, j, k)
696     END DO
697     END DO
698     END DO
699    
700     IF (j1/=2) THEN
701     DO k = 1, nlay
702     DO i = 1, imr
703     ! j=1 c'est le pôle Sud, j=JNP c'est le pôle Nord
704     q(i, 2, k, ic) = q(i, 1, k, ic)
705     q(i, jmr, k, ic) = q(i, jmp, k, ic)
706     END DO
707     END DO
708     END IF
709     END DO
710    
711     IF (j1/=2) THEN
712     DO k = 1, nlay
713     DO i = 1, imr
714     w(i, 2, k) = w(i, 1, k)
715     w(i, jmr, k) = w(i, jnp, k)
716     END DO
717     END DO
718     END IF
719    
720     RETURN
721     END SUBROUTINE ppm3d
722    
723     ! ****6***0*********0*********0*********0*********0*********0**********72

  ViewVC Help
Powered by ViewVC 1.1.21