source: LMDZ5/trunk/libf/dyn3d_common/advn.F @ 2602

Last change on this file since 2602 was 2600, checked in by Ehouarn Millour, 9 years ago

Cleanup in the dynamics: turn comvert.h into module comvert_mod.F90
EM

  • Property copyright set to
    Name of program: LMDZ
    Creation date: 1984
    Version: LMDZ5
    License: CeCILL version 2
    Holder: Laboratoire de m\'et\'eorologie dynamique, CNRS, UMR 8539
    See the license file in the root directory
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 25.8 KB
Line 
1!
2! $Header$
3!
4      SUBROUTINE advn(q,masse,w,pbaru,pbarv,pdt,mode)
5c
6c     Auteur : F. Hourdin
7c
8c    ********************************************************************
9c     Shema  d'advection " pseudo amont " .
10c    ********************************************************************
11c     q,pbaru,pbarv,w sont des arguments d'entree  pour le s-pg ....
12c
13c   pbaru,pbarv,w flux de masse en u ,v ,w
14c   pdt pas de temps
15c
16c   --------------------------------------------------------------------
17      IMPLICIT NONE
18c
19      include "dimensions.h"
20      include "paramet.h"
21      include "logic.h"
22      include "comgeom.h"
23      include "iniprint.h"
24
25c
26c   Arguments:
27c   ----------
28      integer mode
29      real masse(ip1jmp1,llm)
30      REAL pbaru( ip1jmp1,llm ),pbarv( ip1jm,llm)
31      REAL q(ip1jmp1,llm)
32      REAL w(ip1jmp1,llm),pdt
33c
34c      Local
35c   ---------
36c
37      INTEGER i,ij,l,j,ii
38      integer ijlqmin,iqmin,jqmin,lqmin
39      integer ismin
40c
41      real zm(ip1jmp1,llm),newmasse
42      real mu(ip1jmp1,llm)
43      real mv(ip1jm,llm)
44      real mw(ip1jmp1,llm+1)
45      real zq(ip1jmp1,llm),zz,qpn,qps
46      real zqg(ip1jmp1,llm),zqd(ip1jmp1,llm)
47      real zqs(ip1jmp1,llm),zqn(ip1jmp1,llm)
48      real zqh(ip1jmp1,llm),zqb(ip1jmp1,llm)
49      real temps0,temps1,temps2,temps3
50      real ztemps1,ztemps2,ztemps3,ssum
51      logical testcpu
52      save testcpu
53      save temps1,temps2,temps3
54      real zzpbar,zzw
55
56#ifdef CRAY
57      real second
58#endif
59
60      real qmin,qmax
61      data qmin,qmax/0.,1./
62      data testcpu/.false./
63      data temps1,temps2,temps3/0.,0.,0./
64
65      zzpbar = 0.5 * pdt
66      zzw    = pdt
67
68      DO l=1,llm
69        DO ij = iip2,ip1jm
70            mu(ij,l)=pbaru(ij,l) * zzpbar
71         ENDDO
72         DO ij=1,ip1jm
73            mv(ij,l)=pbarv(ij,l) * zzpbar
74         ENDDO
75         DO ij=1,ip1jmp1
76            mw(ij,l)=w(ij,l) * zzw
77         ENDDO
78      ENDDO
79
80      DO ij=1,ip1jmp1
81         mw(ij,llm+1)=0.
82      ENDDO
83
84      do l=1,llm
85         qpn=0.
86         qps=0.
87         do ij=1,iim
88            qpn=qpn+q(ij,l)*masse(ij,l)
89            qps=qps+q(ip1jm+ij,l)*masse(ip1jm+ij,l)
90         enddo
91         qpn=qpn/ssum(iim,masse(1,l),1)
92         qps=qps/ssum(iim,masse(ip1jm+1,l),1)
93         do ij=1,iip1
94            q(ij,l)=qpn
95            q(ip1jm+ij,l)=qps
96         enddo
97      enddo
98
99      do ij=1,ip1jmp1
100         mw(ij,llm+1)=0.
101      enddo
102      do l=1,llm
103         do ij=1,ip1jmp1
104            zq(ij,l)=q(ij,l)
105            zm(ij,l)=masse(ij,l)
106         enddo
107      enddo
108
109c     call minmaxq(zq,qmin,qmax,'avant vlx     ')
110      call advnqx(zq,zqg,zqd)
111      call advnx(zq,zqg,zqd,zm,mu,mode)
112      call advnqy(zq,zqs,zqn)
113      call advny(zq,zqs,zqn,zm,mv)
114      call advnqz(zq,zqh,zqb)
115      call advnz(zq,zqh,zqb,zm,mw)
116c     call vlz(zq,0.,zm,mw)
117      call advnqy(zq,zqs,zqn)
118      call advny(zq,zqs,zqn,zm,mv)
119      call advnqx(zq,zqg,zqd)
120      call advnx(zq,zqg,zqd,zm,mu,mode)
121c     call minmaxq(zq,qmin,qmax,'apres vlx     ')
122
123#ifdef CRAY
124      if(testcpu) then
125         ztemps1=second(0.)
126         temps1=temps1+ztemps1-ztemps2
127            print*,'VLSPLT X:',temps1,'   Y:',temps2,'   Z:',temps3
128      endif
129#endif
130      do l=1,llm
131         do ij=1,ip1jmp1
132           q(ij,l)=zq(ij,l)
133         enddo
134         do ij=1,ip1jm+1,iip1
135            q(ij+iim,l)=q(ij,l)
136         enddo
137      enddo
138
139      RETURN
140      END
141
142      SUBROUTINE advnqx(q,qg,qd)
143c
144c     Auteurs:   Calcul des valeurs de q aux point u.
145c
146c   --------------------------------------------------------------------
147      IMPLICIT NONE
148c
149#include "dimensions.h"
150#include "paramet.h"
151#include "iniprint.h"
152c
153c
154c   Arguments:
155c   ----------
156      real q(ip1jmp1,llm),qg(ip1jmp1,llm),qd(ip1jmp1,llm)
157c
158c      Local
159c   ---------
160c
161      INTEGER ij,l
162c
163      real dxqu(ip1jmp1),zqu(ip1jmp1)
164      real zqmax(ip1jmp1),zqmin(ip1jmp1)
165      logical extremum(ip1jmp1)
166
167      integer mode
168      save mode
169      data mode/1/
170
171c   calcul des pentes en u:
172c   -----------------------
173      if (mode.eq.0) then
174         do l=1,llm
175            do ij=1,ip1jm
176               qd(ij,l)=q(ij,l)
177               qg(ij,l)=q(ij,l)
178            enddo
179         enddo
180      else
181      do l = 1, llm
182         do ij=iip2,ip1jm-1
183            dxqu(ij)=q(ij+1,l)-q(ij,l)
184            zqu(ij)=0.5*(q(ij+1,l)+q(ij,l))
185         enddo
186         do ij=iip1+iip1,ip1jm,iip1
187            dxqu(ij)=dxqu(ij-iim)
188            zqu(ij)=zqu(ij-iim)
189         enddo
190         do ij=iip2,ip1jm-1
191            zqu(ij)=zqu(ij)-dxqu(ij+1)/12.
192         enddo
193         do ij=iip1+iip1,ip1jm,iip1
194            zqu(ij)=zqu(ij-iim)
195         enddo
196         do ij=iip2+1,ip1jm
197            zqu(ij)=zqu(ij)+dxqu(ij-1)/12.
198         enddo
199         do ij=iip1+iip1,ip1jm,iip1
200            zqu(ij-iim)=zqu(ij)
201         enddo
202
203c   calcul des valeurs max et min acceptees aux interfaces
204
205         do ij=iip2,ip1jm-1
206            zqmax(ij)=max(q(ij+1,l),q(ij,l))
207            zqmin(ij)=min(q(ij+1,l),q(ij,l))
208         enddo
209         do ij=iip1+iip1,ip1jm,iip1
210            zqmax(ij)=zqmax(ij-iim)
211            zqmin(ij)=zqmin(ij-iim)
212         enddo
213         do ij=iip2+1,ip1jm
214            extremum(ij)=dxqu(ij)*dxqu(ij-1).le.0.
215         enddo
216         do ij=iip1+iip1,ip1jm,iip1
217            extremum(ij-iim)=extremum(ij)
218         enddo
219         do ij=iip2,ip1jm
220            zqu(ij)=min(max(zqmin(ij),zqu(ij)),zqmax(ij))
221         enddo
222         do ij=iip2+1,ip1jm
223            if(extremum(ij)) then
224               qg(ij,l)=q(ij,l)
225               qd(ij,l)=q(ij,l)
226            else
227               qd(ij,l)=zqu(ij)
228               qg(ij,l)=zqu(ij-1)
229            endif
230         enddo
231         do ij=iip1+iip1,ip1jm,iip1
232            qd(ij-iim,l)=qd(ij,l)
233            qg(ij-iim,l)=qg(ij,l)
234         enddo
235
236         goto 8888
237
238         do ij=iip2+1,ip1jm
239            if(extremum(ij).and..not.extremum(ij-1))
240     s         qd(ij-1,l)=q(ij,l)
241         enddo
242
243         do ij=iip1+iip1,ip1jm,iip1
244            qd(ij-iim,l)=qd(ij,l)
245         enddo
246         do ij=iip2,ip1jm-1
247            if (extremum(ij).and..not.extremum(ij+1))
248     s         qg(ij+1,l)=q(ij,l)
249         enddo
250
251         do ij=iip1+iip1,ip1jm,iip1
252            qg(ij,l)=qg(ij-iim,l)
253         enddo
2548888     continue
255      enddo
256      endif
257      RETURN
258      END
259      SUBROUTINE advnqy(q,qs,qn)
260c
261c     Auteurs:   Calcul des valeurs de q aux point v.
262c
263c   --------------------------------------------------------------------
264      IMPLICIT NONE
265c
266#include "dimensions.h"
267#include "paramet.h"
268#include "iniprint.h"
269c
270c
271c   Arguments:
272c   ----------
273      real q(ip1jmp1,llm),qs(ip1jmp1,llm),qn(ip1jmp1,llm)
274c
275c      Local
276c   ---------
277c
278      INTEGER ij,l
279c
280      real dyqv(ip1jm),zqv(ip1jm,llm)
281      real zqmax(ip1jm),zqmin(ip1jm)
282      logical extremum(ip1jmp1)
283
284      integer mode
285      save mode
286      data mode/1/
287
288      if (mode.eq.0) then
289         do l=1,llm
290            do ij=1,ip1jmp1
291               qn(ij,l)=q(ij,l)
292               qs(ij,l)=q(ij,l)
293            enddo
294         enddo
295      else
296
297c   calcul des pentes en u:
298c   -----------------------
299      do l = 1, llm
300         do ij=1,ip1jm
301            dyqv(ij)=q(ij,l)-q(ij+iip1,l)
302         enddo
303
304         do ij=iip2,ip1jm-iip1
305            zqv(ij,l)=0.5*(q(ij+iip1,l)+q(ij,l))
306            zqv(ij,l)=zqv(ij,l)+(dyqv(ij+iip1)-dyqv(ij-iip1))/12.
307         enddo
308
309         do ij=iip2,ip1jm
310            extremum(ij)=dyqv(ij)*dyqv(ij-iip1).le.0.
311         enddo
312
313c Pas de pentes aux poles
314         do ij=1,iip1
315            zqv(ij,l)=q(ij,l)
316            zqv(ip1jm-iip1+ij,l)=q(ip1jm+ij,l)
317            extremum(ij)=.true.
318            extremum(ip1jmp1-iip1+ij)=.true.
319         enddo
320
321c   calcul des valeurs max et min acceptees aux interfaces
322         do ij=1,ip1jm
323            zqmax(ij)=max(q(ij+iip1,l),q(ij,l))
324            zqmin(ij)=min(q(ij+iip1,l),q(ij,l))
325         enddo
326
327         do ij=1,ip1jm
328            zqv(ij,l)=min(max(zqmin(ij),zqv(ij,l)),zqmax(ij))
329         enddo
330
331         do ij=iip2,ip1jm
332            if(extremum(ij)) then
333               qs(ij,l)=q(ij,l)
334               qn(ij,l)=q(ij,l)
335c              if (.not.extremum(ij-iip1)) qs(ij-iip1,l)=q(ij,l)
336c              if (.not.extremum(ij+iip1)) qn(ij+iip1,l)=q(ij,l)
337            else
338               qs(ij,l)=zqv(ij,l)
339               qn(ij,l)=zqv(ij-iip1,l)
340            endif
341         enddo
342
343         do ij=1,iip1
344            qs(ij,l)=q(ij,l)
345            qn(ij,l)=q(ij,l)
346            qs(ip1jm+ij,l)=q(ip1jm+ij,l)
347            qn(ip1jm+ij,l)=q(ip1jm+ij,l)
348         enddo
349
350      enddo
351      endif
352      RETURN
353      END
354
355      SUBROUTINE advnqz(q,qh,qb)
356c
357c     Auteurs:   Calcul des valeurs de q aux point v.
358c
359c   --------------------------------------------------------------------
360      IMPLICIT NONE
361c
362#include "dimensions.h"
363#include "paramet.h"
364#include "iniprint.h"
365c
366c
367c   Arguments:
368c   ----------
369      real q(ip1jmp1,llm),qh(ip1jmp1,llm),qb(ip1jmp1,llm)
370c
371c      Local
372c   ---------
373c
374      INTEGER ij,l
375c
376      real dzqw(ip1jmp1,llm+1),zqw(ip1jmp1,llm+1)
377      real zqmax(ip1jmp1,llm),zqmin(ip1jmp1,llm)
378      logical extremum(ip1jmp1,llm)
379
380      integer mode
381      save mode
382
383      data mode/1/
384
385c   calcul des pentes en u:
386c   -----------------------
387
388      if (mode.eq.0) then
389         do l=1,llm
390            do ij=1,ip1jmp1
391               qb(ij,l)=q(ij,l)
392               qh(ij,l)=q(ij,l)
393            enddo
394         enddo
395      else
396      do l = 2, llm
397         do ij=1,ip1jmp1
398            dzqw(ij,l)=q(ij,l-1)-q(ij,l)
399            zqw(ij,l)=0.5*(q(ij,l-1)+q(ij,l))
400         enddo
401      enddo
402      do ij=1,ip1jmp1
403         dzqw(ij,1)=0.
404         dzqw(ij,llm+1)=0.
405      enddo
406      do l=2,llm
407         do ij=1,ip1jmp1
408            zqw(ij,l)=zqw(ij,l)+(dzqw(ij,l+1)-dzqw(ij,l-1))/12.
409         enddo
410      enddo
411      do l=2,llm-1
412         do ij=1,ip1jmp1
413            extremum(ij,l)=dzqw(ij,l)*dzqw(ij,l+1).le.0.
414         enddo
415      enddo
416
417c Pas de pentes en bas et en haut
418         do ij=1,ip1jmp1
419            zqw(ij,2)=q(ij,1)
420            zqw(ij,llm)=q(ij,llm)
421            extremum(ij,1)=.true.
422            extremum(ij,llm)=.true.
423         enddo
424
425c   calcul des valeurs max et min acceptees aux interfaces
426      do l=2,llm
427         do ij=1,ip1jmp1
428            zqmax(ij,l)=max(q(ij,l-1),q(ij,l))
429            zqmin(ij,l)=min(q(ij,l-1),q(ij,l))
430         enddo
431      enddo
432
433      do l=2,llm
434         do ij=1,ip1jmp1
435            zqw(ij,l)=min(max(zqmin(ij,l),zqw(ij,l)),zqmax(ij,l))
436         enddo
437      enddo
438
439      do l=2,llm-1
440         do ij=1,ip1jmp1
441            if(extremum(ij,l)) then
442               qh(ij,l)=q(ij,l)
443               qb(ij,l)=q(ij,l)
444            else
445               qh(ij,l)=zqw(ij,l+1)
446               qb(ij,l)=zqw(ij,l)
447            endif
448         enddo
449      enddo
450c     do l=2,llm-1
451c        do ij=1,ip1jmp1
452c           if(extremum(ij,l)) then
453c              if (.not.extremum(ij,l-1)) qh(ij,l-1)=q(ij,l)
454c              if (.not.extremum(ij,l+1)) qb(ij,l+1)=q(ij,l)
455c           endif
456c        enddo
457c     enddo
458
459      do ij=1,ip1jmp1
460         qb(ij,1)=q(ij,1)
461         qh(ij,1)=q(ij,1)
462         qb(ij,llm)=q(ij,llm)
463         qh(ij,llm)=q(ij,llm)
464      enddo
465
466      endif
467
468      RETURN
469      END
470
471      SUBROUTINE advnx(q,qg,qd,masse,u_m,mode)
472c
473c     Auteur : F. Hourdin
474c
475c    ********************************************************************
476c     Shema  d'advection " pseudo amont " .
477c    ********************************************************************
478c     nq,iq,q,pbaru,pbarv,w sont des arguments d'entree  pour le s-pg ....
479c
480c
481c   --------------------------------------------------------------------
482      IMPLICIT NONE
483c
484      include "dimensions.h"
485      include "paramet.h"
486      include "logic.h"
487      include "iniprint.h"
488c
489c
490c   Arguments:
491c   ----------
492      integer mode
493      real masse(ip1jmp1,llm)
494      real u_m( ip1jmp1,llm )
495      real q(ip1jmp1,llm),qd(ip1jmp1,llm),qg(ip1jmp1,llm)
496c
497c      Local
498c   ---------
499c
500      INTEGER i,j,ij,l,indu(ip1jmp1),niju,iju,ijq
501      integer n0,nl(llm)
502c
503      real new_m,zu_m,zdq,zz
504      real zsigg(ip1jmp1,llm),zsigd(ip1jmp1,llm),zsig
505      real u_mq(ip1jmp1,llm)
506
507      real zm,zq,zsigm,zsigp,zqm,zqp,zu
508
509      logical ladvplus(ip1jmp1,llm)
510
511      real prec
512      save prec
513
514#ifdef CRAY
515      data prec/1.e-24/
516#else
517      data prec/1.e-15/
518#endif
519
520      do l=1,llm
521            do ij=iip2,ip1jm
522               zdq=qd(ij,l)-qg(ij,l)
523c              if((qd(ij,l)-q(ij,l))*(q(ij,l)-qg(ij,l)).lt.0.) then
524c                 print*,'probleme au point ij=',ij,'  l=',l
525c                 print*,qd(ij,l),q(ij,l),qg(ij,l)
526c                 qd(ij,l)=q(ij,l)
527c                 qg(ij,l)=q(ij,l)
528c              endif
529               if(abs(zdq).gt.prec) then
530                  zsigd(ij,l)=(q(ij,l)-qg(ij,l))/zdq
531                  zsigg(ij,l)=1.-zsigd(ij,l)
532c                 if(.not.(zsigd(ij,l).ge.0..and.zsigd(ij,l).le.1. .and.
533c    s               zsigg(ij,l).ge.0..or.zsigg(ij,l).le.1.) ) then
534c                    print*,'probleme au point ij=',ij,'  l=',l
535c                    print*,'sigg=',zsigg(ij,l),'  sigd=',zsigd(ij,l)
536c                    print*,'q d,c,g ',qd(ij,l),q(ij,l),qg(ij,l),zdq
537c                    stop
538c                 endif
539               else
540                  zsigd(ij,l)=0.5
541                  zsigg(ij,l)=0.5
542                  qd(ij,l)=q(ij,l)
543                  qg(ij,l)=q(ij,l)
544               endif
545            enddo
546       enddo
547
548c   calcul de la pente maximum dans la maille en valeur absolue
549
550       do l=1,llm
551       do ij=iip2,ip1jm-1
552          if (u_m(ij,l).ge.0.) then
553             zsigp=zsigd(ij,l)
554             zsigm=zsigg(ij,l)
555             zqp=qd(ij,l)
556             zqm=qg(ij,l)
557             zm=masse(ij,l)
558             zq=q(ij,l)
559          else
560             zsigm=zsigd(ij+1,l)
561             zsigp=zsigg(ij+1,l)
562             zqm=qd(ij+1,l)
563             zqp=qg(ij+1,l)
564             zm=masse(ij+1,l)
565             zq=q(ij+1,l)
566          endif
567          zu=abs(u_m(ij,l))
568          ladvplus(ij,l)=zu.gt.zm
569          zsig=zu/zm
570          if(zsig.eq.0.) zsigp=0.1
571          if (mode.eq.1) then
572             if (zsig.le.zsigp) then
573                 u_mq(ij,l)=u_m(ij,l)*zqp
574             else if (mode.eq.1) then
575                 u_mq(ij,l)=
576     s           sign(zm,u_m(ij,l))*(zsigp*zqp+(zsig-zsigp)*zqm)
577             endif
578          else
579             if (zsig.le.zsigp) then
580                 u_mq(ij,l)=u_m(ij,l)*(zqp-0.5*zsig/zsigp*(zqp-zq))
581             else
582                zz=0.5*(zsig-zsigp)/zsigm
583                u_mq(ij,l)=sign(zm,u_m(ij,l))*( 0.5*(zq+zqp)*zsigp
584     s          +(zsig-zsigp)*(zq+zz*(zqm-zq)) )
585             endif
586          endif
587c         if(zsig.lt.0.) then
588c            print*,'au point ij=',ij,'  l=',l,'  sig=',zsig
589c            stop
590c         endif
591      enddo
592      enddo
593
594      do l=1,llm
595       do ij=iip1+iip1,ip1jm,iip1
596          u_mq(ij,l)=u_mq(ij-iim,l)
597          ladvplus(ij,l)=ladvplus(ij-iim,l)
598       enddo
599      enddo
600
601c=================================================================
602C   SCHEMA SEMI-LAGRAGIEN EN X DANS LES REGIONS POLAIRES
603c=================================================================
604c   tris des regions a traiter
605      n0=0
606      do l=1,llm
607         nl(l)=0
608         do ij=iip2,ip1jm
609            if(ladvplus(ij,l)) then
610               nl(l)=nl(l)+1
611               u_mq(ij,l)=0.
612            endif
613         enddo
614         n0=n0+nl(l)
615      enddo
616
617      if(n0.gt.1) then
618      IF (prt_level > 9) WRITE(lunout,*)
619     & 'Nombre de points pour lesquels on advect plus que le'
620     &       ,'contenu de la maille : ',n0
621
622         do l=1,llm
623            if(nl(l).gt.0) then
624               iju=0
625c   indicage des mailles concernees par le traitement special
626               do ij=iip2,ip1jm
627                  if(ladvplus(ij,l).and.mod(ij,iip1).ne.0) then
628                     iju=iju+1
629                     indu(iju)=ij
630                  endif
631               enddo
632               niju=iju
633c              print*,'niju,nl',niju,nl(l)
634
635c  traitement des mailles
636               do iju=1,niju
637                  ij=indu(iju)
638                  j=(ij-1)/iip1+1
639                  zu_m=u_m(ij,l)
640                  u_mq(ij,l)=0.
641                  if(zu_m.gt.0.) then
642                     ijq=ij
643                     i=ijq-(j-1)*iip1
644c   accumulation pour les mailles completements advectees
645                     do while(zu_m.gt.masse(ijq,l))
646                        u_mq(ij,l)=u_mq(ij,l)+q(ijq,l)*masse(ijq,l)
647                        zu_m=zu_m-masse(ijq,l)
648                        i=mod(i-2+iim,iim)+1
649                        ijq=(j-1)*iip1+i
650                     enddo
651c   MODIFS SPECIFIQUES DU SCHEMA
652c   ajout de la maille non completement advectee
653             zsig=zu_m/masse(ijq,l)
654             if(zsig.le.zsigd(ijq,l)) then
655                u_mq(ij,l)=u_mq(ij,l)+zu_m*(qd(ijq,l)
656     s          -0.5*zsig/zsigd(ijq,l)*(qd(ijq,l)-q(ijq,l)))
657             else
658c               u_mq(ij,l)=u_mq(ij,l)+zu_m*q(ijq,l)
659c         goto 8888
660                zz=0.5*(zsig-zsigd(ijq,l))/zsigg(ijq,l)
661                if(.not.(zz.gt.0..and.zz.le.0.5)) then
662                     WRITE(lunout,*)'probleme2 au point ij=',ij,
663     s               '  l=',l
664                     WRITE(lunout,*)'zz=',zz
665                     stop
666                endif
667                u_mq(ij,l)=u_mq(ij,l)+masse(ijq,l)*(
668     s          0.5*(q(ijq,l)+qd(ijq,l))*zsigd(ijq,l)
669     s        +(zsig-zsigd(ijq,l))*(q(ijq,l)+zz*(qg(ijq,l)-q(ijq,l))) )
670             endif
671                  else
672                     ijq=ij+1
673                     i=ijq-(j-1)*iip1
674c   accumulation pour les mailles completements advectees
675                     do while(-zu_m.gt.masse(ijq,l))
676                        u_mq(ij,l)=u_mq(ij,l)-q(ijq,l)*masse(ijq,l)
677                        zu_m=zu_m+masse(ijq,l)
678                        i=mod(i,iim)+1
679                        ijq=(j-1)*iip1+i
680                     enddo
681c   ajout de la maille non completement advectee
682c 2eme MODIF SPECIFIQUE
683             zsig=-zu_m/masse(ij+1,l)
684             if(zsig.le.zsigg(ijq,l)) then
685                u_mq(ij,l)=u_mq(ij,l)+zu_m*(qg(ijq,l)
686     s          -0.5*zsig/zsigg(ijq,l)*(qg(ijq,l)-q(ijq,l)))
687             else
688c               u_mq(ij,l)=u_mq(ij,l)+zu_m*q(ijq,l)
689c           goto 9999
690                zz=0.5*(zsig-zsigg(ijq,l))/zsigd(ijq,l)
691                if(.not.(zz.gt.0..and.zz.le.0.5)) then
692                     WRITE(lunout,*)'probleme22 au point ij=',ij
693     s               ,'  l=',l
694                     WRITE(lunout,*)'zz=',zz
695                     stop
696                endif
697                u_mq(ij,l)=u_mq(ij,l)-masse(ijq,l)*(
698     s          0.5*(q(ijq,l)+qg(ijq,l))*zsigg(ijq,l)
699     s          +(zsig-zsigg(ijq,l))*
700     s           (q(ijq,l)+zz*(qd(ijq,l)-q(ijq,l))) )
701             endif
702c   fin de la modif
703                  endif
704               enddo
705            endif
706         enddo
707      endif  ! n0.gt.0
708
709c   bouclage en latitude
710      do l=1,llm
711        do ij=iip1+iip1,ip1jm,iip1
712           u_mq(ij,l)=u_mq(ij-iim,l)
713        enddo
714      enddo
715
716c=================================================================
717c   CALCUL DE LA CONVERGENCE DES FLUX
718c=================================================================
719
720      do l=1,llm
721         do ij=iip2+1,ip1jm
722            new_m=masse(ij,l)+u_m(ij-1,l)-u_m(ij,l)
723            q(ij,l)=(q(ij,l)*masse(ij,l)+
724     &      u_mq(ij-1,l)-u_mq(ij,l))
725     &      /new_m
726            masse(ij,l)=new_m
727         enddo
728c   Modif Fred 22 03 96 correction d'un bug (les scopy ci-dessous)
729         do ij=iip1+iip1,ip1jm,iip1
730            q(ij-iim,l)=q(ij,l)
731            masse(ij-iim,l)=masse(ij,l)
732         enddo
733      enddo
734
735      RETURN
736      END
737      SUBROUTINE advny(q,qs,qn,masse,v_m)
738c
739c     Auteur : F. Hourdin
740c
741c    ********************************************************************
742c     Shema  d'advection " pseudo amont " .
743c    ********************************************************************
744c     nq,iq,q,pbaru,pbarv,w sont des arguments d'entree  pour le s-pg ....
745c
746c
747c   --------------------------------------------------------------------
748      IMPLICIT NONE
749c
750#include "dimensions.h"
751#include "paramet.h"
752#include "comgeom.h"
753#include "iniprint.h"
754c
755c
756c   Arguments:
757c   ----------
758      real masse(ip1jmp1,llm)
759      real v_m( ip1jm,llm )
760      real q(ip1jmp1,llm),qn(ip1jmp1,llm),qs(ip1jmp1,llm)
761c
762c      Local
763c   ---------
764c
765      INTEGER ij,l
766c
767      real new_m,zdq,zz
768      real zsigs(ip1jmp1),zsign(ip1jmp1),zsig
769      real v_mq(ip1jm,llm)
770      real convpn,convps,convmpn,convmps,massen,masses
771      real zm,zq,zsigm,zsigp,zqm,zqp
772      real ssum
773      real prec
774      save prec
775
776#ifdef CRAY
777      data prec/1.e-24/
778#else
779      data prec/1.e-15/
780#endif
781      do l=1,llm
782            do ij=1,ip1jmp1
783               zdq=qn(ij,l)-qs(ij,l)
784c              if((qn(ij,l)-q(ij,l))*(q(ij,l)-qs(ij,l)).lt.0.) then
785c                 print*,'probleme au point ij=',ij,'  l=',l,'  advnqx'
786c                 print*,qn(ij,l),q(ij,l),qs(ij,l)
787c                 qn(ij,l)=q(ij,l)
788c                 qs(ij,l)=q(ij,l)
789c              endif
790               if(abs(zdq).gt.prec) then
791                  zsign(ij)=(q(ij,l)-qs(ij,l))/zdq
792                  zsigs(ij)=1.-zsign(ij)
793c                 if(.not.(zsign(ij).ge.0..and.zsign(ij).le.1. .and.
794c    s               zsigs(ij).ge.0..or.zsigs(ij).le.1.) ) then
795c                    print*,'probleme au point ij=',ij,'  l=',l
796c                    print*,'sigs=',zsigs(ij),'  sign=',zsign(ij)
797c                    stop
798c                 endif
799               else
800                  zsign(ij)=0.5
801                  zsigs(ij)=0.5
802               endif
803            enddo
804
805c   calcul de la pente maximum dans la maille en valeur absolue
806
807       do ij=1,ip1jm
808          if (v_m(ij,l).ge.0.) then
809             zsigp=zsign(ij+iip1)
810             zsigm=zsigs(ij+iip1)
811             zqp=qn(ij+iip1,l)
812             zqm=qs(ij+iip1,l)
813             zm=masse(ij+iip1,l)
814             zq=q(ij+iip1,l)
815          else
816             zsigm=zsign(ij)
817             zsigp=zsigs(ij)
818             zqm=qn(ij,l)
819             zqp=qs(ij,l)
820             zm=masse(ij,l)
821             zq=q(ij,l)
822          endif
823          zsig=abs(v_m(ij,l))/zm
824          if(zsig.eq.0.) zsigp=0.1
825          if (zsig.le.zsigp) then
826              v_mq(ij,l)=v_m(ij,l)*(zqp-0.5*zsig/zsigp*(zqp-zq))
827          else
828              zz=0.5*(zsig-zsigp)/zsigm
829              v_mq(ij,l)=sign(zm,v_m(ij,l))*( 0.5*(zq+zqp)*zsigp
830     s        +(zsig-zsigp)*(zq+zz*(zqm-zq)) )
831          endif
832       enddo
833      enddo
834
835      do l=1,llm
836         do ij=iip2,ip1jm
837            new_m=masse(ij,l)
838     &      +v_m(ij,l)-v_m(ij-iip1,l)
839            q(ij,l)=(q(ij,l)*masse(ij,l)+v_mq(ij,l)-v_mq(ij-iip1,l))
840     &         /new_m
841            masse(ij,l)=new_m
842         enddo
843c.-. ancienne version
844         convpn=SSUM(iim,v_mq(1,l),1)
845         convmpn=ssum(iim,v_m(1,l),1)
846         massen=ssum(iim,masse(1,l),1)
847         new_m=massen+convmpn
848         q(1,l)=(q(1,l)*massen+convpn)/new_m
849         do ij = 1,iip1
850            q(ij,l)=q(1,l)
851            masse(ij,l)=new_m*aire(ij)/apoln
852         enddo
853
854         convps=-SSUM(iim,v_mq(ip1jm-iim,l),1)
855         convmps=-ssum(iim,v_m(ip1jm-iim,l),1)
856         masses=ssum(iim,masse(ip1jm+1,l),1)
857         new_m=masses+convmps
858         q(ip1jm+1,l)=(q(ip1jm+1,l)*masses+convps)/new_m
859         do ij = ip1jm+1,ip1jmp1
860            q(ij,l)=q(ip1jm+1,l)
861            masse(ij,l)=new_m*aire(ij)/apols
862         enddo
863      enddo
864
865      RETURN
866      END
867      SUBROUTINE advnz(q,qh,qb,masse,w_m)
868c
869c     Auteurs:   F.Hourdin
870c
871c    ********************************************************************
872c     Shema  d'advection " pseudo amont " .
873c     b designe le bas et h le haut
874c     il y a une correspondance entre le b en z et le d en x
875c    ********************************************************************
876c
877c
878c   --------------------------------------------------------------------
879      IMPLICIT NONE
880c
881#include "dimensions.h"
882#include "paramet.h"
883#include "comgeom.h"
884#include "iniprint.h"
885c
886c
887c   Arguments:
888c   ----------
889      real masse(ip1jmp1,llm)
890      real w_m( ip1jmp1,llm+1)
891      real q(ip1jmp1,llm),qb(ip1jmp1,llm),qh(ip1jmp1,llm)
892
893c
894c      Local
895c   ---------
896c
897      INTEGER ij,l
898c
899      real new_m,zdq,zz
900      real zsigh(ip1jmp1,llm),zsigb(ip1jmp1,llm),zsig
901      real w_mq(ip1jmp1,llm+1)
902      real zm,zq,zsigm,zsigp,zqm,zqp
903      real prec
904      save prec
905
906#ifdef CRAY
907      data prec/1.e-24/
908#else
909      data prec/1.e-13/
910#endif
911
912      do l=1,llm
913            do ij=1,ip1jmp1
914               zdq=qb(ij,l)-qh(ij,l)
915c              if((qh(ij,l)-q(ij,l))*(q(ij,l)-qb(ij,l)).lt.0.) then
916c                 print*,'probleme au point ij=',ij,'  l=',l
917c                 print*,qh(ij,l),q(ij,l),qb(ij,l)
918c                 qh(ij,l)=q(ij,l)
919c                 qb(ij,l)=q(ij,l)
920c              endif
921
922               if(abs(zdq).gt.prec) then
923                  zsigb(ij,l)=(q(ij,l)-qh(ij,l))/zdq
924                  zsigh(ij,l)=1.-zsigb(ij,l)
925                  zsigb(ij,l)=min(max(zsigb(ij,l),0.),1.)
926               else
927                  zsigb(ij,l)=0.5
928                  zsigh(ij,l)=0.5
929               endif
930            enddo
931       enddo
932
933c      print*,'ok1'
934c   calcul de la pente maximum dans la maille en valeur absolue
935       do l=2,llm
936       do ij=1,ip1jmp1
937          if (w_m(ij,l).ge.0.) then
938             zsigp=zsigb(ij,l)
939             zsigm=zsigh(ij,l)
940             zqp=qb(ij,l)
941             zqm=qh(ij,l)
942             zm=masse(ij,l)
943             zq=q(ij,l)
944          else
945             zsigm=zsigb(ij,l-1)
946             zsigp=zsigh(ij,l-1)
947             zqm=qb(ij,l-1)
948             zqp=qh(ij,l-1)
949             zm=masse(ij,l-1)
950             zq=q(ij,l-1)
951          endif
952          zsig=abs(w_m(ij,l))/zm
953          if(zsig.eq.0.) zsigp=0.1
954          if (zsig.le.zsigp) then
955              w_mq(ij,l)=w_m(ij,l)*(zqp-0.5*zsig/zsigp*(zqp-zq))
956          else
957              zz=0.5*(zsig-zsigp)/zsigm
958              w_mq(ij,l)=sign(zm,w_m(ij,l))*( 0.5*(zq+zqp)*zsigp
959     s        +(zsig-zsigp)*(zq+zz*(zqm-zq)) )
960          endif
961      enddo
962      enddo
963
964       do ij=1,ip1jmp1
965          w_mq(ij,llm+1)=0.
966          w_mq(ij,1)=0.
967       enddo
968
969      do l=1,llm
970         do ij=1,ip1jmp1
971            new_m=masse(ij,l)+w_m(ij,l+1)-w_m(ij,l)
972            q(ij,l)=(q(ij,l)*masse(ij,l)+w_mq(ij,l+1)-w_mq(ij,l))
973     &         /new_m
974            masse(ij,l)=new_m
975         enddo
976      enddo
977c     print*,'ok3'
978      RETURN
979      END
Note: See TracBrowser for help on using the repository browser.