/[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 167 - (hide annotations)
Mon Aug 24 16:30:33 2015 UTC (8 years, 10 months ago) by guez
File size: 22236 byte(s)
Added program test_inifilr.

Encapsulated ppm3d into a module and added implicit none. Removed
unused argument dum.

Encountered a problem in procedure invert_zoom_x. With grossismx=2.9,
DZOOMX=0.3, taux=5, for xuv = -0.25, for i = 1, rtsafe fails because
fval is about 1e-16 instead of 0 at xval = pi. So distinguished the
cases abs_y = 0 or pi. Needed then to add argument beta to
invert_zoom_x.

Moved the output of eignvalues of differentiation matrix from inifilr
to inifgn, where they are computed.

Simpler definition of j1 in inifilr.

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

  ViewVC Help
Powered by ViewVC 1.1.21