source: LMDZ6/trunk/libf/dyn3d_common/pentes_ini.f90 @ 5272

Last change on this file since 5272 was 5272, checked in by abarral, 23 hours ago

Turn paramet.h into a module

  • 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: 12.4 KB
Line 
1!
2! $Header$
3!
4SUBROUTINE pentes_ini (q,w,masse,pbaru,pbarv,mode)
5  USE comconst_mod, ONLY: pi, dtvr
6  USE dimensions_mod, ONLY: iim, jjm, llm, ndm
7  USE paramet_mod_h, ONLY: iip1, iip2, iip3, jjp1, llmp1, llmp2, llmm1, kftd, ip1jm, ip1jmp1, &
8          ip1jmi1, ijp1llm, ijmllm, mvar, jcfil, jcfllm
9IMPLICIT NONE
10
11  !=======================================================================
12  !   Adaptation LMDZ:  A.Armengaud (LGGE)
13  !   ----------------
14  !
15  !   ********************************************************************
16  !   Transport des traceurs par la methode des pentes
17  !   ********************************************************************
18  !   Reference possible : Russel. G.L., Lerner J.A.:
19  !     A new Finite-Differencing Scheme for Traceur Transport
20  !     Equation , Journal of Applied Meteorology, pp 1483-1498,dec. 81
21  !   ********************************************************************
22  !   q,w,masse,pbaru et pbarv
23  !                  sont des arguments d'entree  pour le s-pg ....
24  !
25  !=======================================================================
26  include "comgeom2.h"
27
28  !   Arguments:
29  !   ----------
30  integer :: mode
31  REAL :: pbaru( ip1jmp1,llm ),pbarv( ip1jm,llm )
32  REAL :: q( iip1,jjp1,llm,0:3)
33  REAL :: w( ip1jmp1,llm )
34  REAL :: masse( iip1,jjp1,llm)
35  !   Local:
36  !   ------
37  LOGICAL :: limit
38  REAL :: sm ( iip1,jjp1, llm )
39  REAL :: s0( iip1,jjp1,llm ),  sx( iip1,jjp1,llm )
40  REAL :: sy( iip1,jjp1,llm ),  sz( iip1,jjp1,llm )
41  real :: masn,mass,zz
42  INTEGER :: i,j,l,iq
43
44  !  modif Fred 24 03 96
45
46  real :: sinlon(iip1),sinlondlon(iip1)
47  real :: coslon(iip1),coslondlon(iip1)
48  save sinlon,coslon,sinlondlon,coslondlon
49  real :: dyn1,dyn2,dys1,dys2
50  real :: qpn,qps,dqzpn,dqzps
51  real :: smn,sms,s0n,s0s,sxn(iip1),sxs(iip1)
52  real :: qmin,zq,pente_max
53  !
54  REAL :: SSUM
55  integer :: ismax,ismin,lati,latf
56  EXTERNAL  SSUM, ismin,ismax
57  logical :: first
58  save first
59  !   fin modif
60
61   ! EXTERNAL masskg
62  EXTERNAL advx
63  EXTERNAL advy
64  EXTERNAL advz
65
66  !  modif Fred 24 03 96
67  data first/.true./
68
69  limit = .TRUE.
70  pente_max=2
71  ! if (mode.eq.1.or.mode.eq.3) then
72  ! if (mode.eq.1) then
73  if (mode.ge.1) then
74    lati=2
75    latf=jjm
76  else
77    lati=1
78    latf=jjp1
79  endif
80
81  qmin=0.4995
82  qmin=0.
83  if(first) then
84     print*,'SCHEMA AMONT NOUVEAU'
85     first=.false.
86     do i=2,iip1
87        coslon(i)=cos(rlonv(i))
88        sinlon(i)=sin(rlonv(i))
89        coslondlon(i)=coslon(i)*(rlonu(i)-rlonu(i-1))/pi
90        sinlondlon(i)=sinlon(i)*(rlonu(i)-rlonu(i-1))/pi
91        print*,coslondlon(i),sinlondlon(i)
92     enddo
93     coslon(1)=coslon(iip1)
94     coslondlon(1)=coslondlon(iip1)
95     sinlon(1)=sinlon(iip1)
96     sinlondlon(1)=sinlondlon(iip1)
97     print*,'sum sinlondlon ',ssum(iim,sinlondlon,1)/sinlondlon(1)
98     print*,'sum coslondlon ',ssum(iim,coslondlon,1)/coslondlon(1)
99    DO l = 1,llm
100    DO j = 1,jjp1
101     DO i = 1,iip1
102     q ( i,j,l,1 )=0.
103     q ( i,j,l,2 )=0.
104     q ( i,j,l,3 )=0.
105     ENDDO
106     ENDDO
107    ENDDO
108
109  endif
110  !   Fin modif Fred
111
112  ! *** q contient les qqtes de traceur avant l'advection
113
114  ! *** Affectation des tableaux S a partir de Q
115  ! *** Rem : utilisation de SCOPY ulterieurement
116
117   DO l = 1,llm
118    DO j = 1,jjp1
119     DO i = 1,iip1
120         s0( i,j,llm+1-l ) = q ( i,j,l,0 )
121         sx( i,j,llm+1-l ) = q ( i,j,l,1 )
122         sy( i,j,llm+1-l ) = q ( i,j,l,2 )
123         sz( i,j,llm+1-l ) = q ( i,j,l,3 )
124     ENDDO
125    ENDDO
126   ENDDO
127
128   ! PRINT*,'----- S0 just before conversion -------'
129   ! PRINT*,'S0(16,12,1)=',s0(16,12,1)
130   ! PRINT*,'Q(16,12,1,4)=',q(16,12,1,4)
131
132  ! *** On calcule la masse d'air en kg
133
134   DO  l = 1,llm
135     DO  j = 1,jjp1
136       DO  i = 1,iip1
137        sm ( i,j,llm+1-l)=masse( i,j,l )
138      ENDDO
139     ENDDO
140   ENDDO
141
142  ! *** On converti les champs S en atome (resp. kg)
143  ! *** Les routines d'advection traitent les champs
144  ! *** a advecter si ces derniers sont en atome (resp. kg)
145  ! *** A optimiser !!!
146
147   DO  l = 1,llm
148     DO  j = 1,jjp1
149       DO  i = 1,iip1
150           s0(i,j,l) = s0(i,j,l) * sm ( i,j,l )
151           sx(i,j,l) = sx(i,j,l) * sm ( i,j,l )
152           sy(i,j,l) = sy(i,j,l) * sm ( i,j,l )
153           sz(i,j,l) = sz(i,j,l) * sm ( i,j,l )
154       ENDDO
155     ENDDO
156   ENDDO
157
158    ! ss0 = 0.
159    ! DO l = 1,llm
160    !  DO j = 1,jjp1
161    !   DO i = 1,iim
162    !      ss0 = ss0 + s0 ( i,j,l )
163    !   ENDDO
164    !  ENDDO
165    ! ENDDO
166    ! PRINT*, 'valeur tot s0 avant advection=',ss0
167
168  ! *** Appel des subroutines d'advection en X, en Y et en Z
169  ! *** Advection avec "time-splitting"
170
171  !-----------------------------------------------------------
172   ! PRINT*,'----- S0 just before ADVX -------'
173   ! PRINT*,'S0(16,12,1)=',s0(16,12,1)
174
175  !-----------------------------------------------------------
176   ! do l=1,llm
177   !    do j=1,jjp1
178   !     do i=1,iip1
179   !        zq=s0(i,j,l)/sm(i,j,l)
180   !       if(zq.lt.qmin)
181  !    ,       print*,'avant advx1, s0(',i,',',j,',',l,')=',zq
182   !     enddo
183   !    enddo
184   ! enddo
185  !CC
186   if(mode.eq.2) then
187      do l=1,llm
188        s0s=0.
189        s0n=0.
190        dyn1=0.
191        dys1=0.
192        dyn2=0.
193        dys2=0.
194        smn=0.
195        sms=0.
196        do i=1,iim
197           smn=smn+sm(i,1,l)
198           sms=sms+sm(i,jjp1,l)
199           s0n=s0n+s0(i,1,l)
200           s0s=s0s+s0(i,jjp1,l)
201           zz=sy(i,1,l)/sm(i,1,l)
202           dyn1=dyn1+sinlondlon(i)*zz
203           dyn2=dyn2+coslondlon(i)*zz
204           zz=sy(i,jjp1,l)/sm(i,jjp1,l)
205           dys1=dys1+sinlondlon(i)*zz
206           dys2=dys2+coslondlon(i)*zz
207        enddo
208        do i=1,iim
209           sy(i,1,l)=dyn1*sinlon(i)+dyn2*coslon(i)
210           sy(i,jjp1,l)=dys1*sinlon(i)+dys2*coslon(i)
211        enddo
212        do i=1,iim
213           s0(i,1,l)=s0n/smn+sy(i,1,l)
214           s0(i,jjp1,l)=s0s/sms-sy(i,jjp1,l)
215        enddo
216
217        s0(iip1,1,l)=s0(1,1,l)
218        s0(iip1,jjp1,l)=s0(1,jjp1,l)
219
220        do i=1,iim
221           sxn(i)=s0(i+1,1,l)-s0(i,1,l)
222           sxs(i)=s0(i+1,jjp1,l)-s0(i,jjp1,l)
223  !   on rerentre les masses
224        enddo
225        do i=1,iim
226           sy(i,1,l)=sy(i,1,l)*sm(i,1,l)
227           sy(i,jjp1,l)=sy(i,jjp1,l)*sm(i,jjp1,l)
228           s0(i,1,l)=s0(i,1,l)*sm(i,1,l)
229           s0(i,jjp1,l)=s0(i,jjp1,l)*sm(i,jjp1,l)
230        enddo
231        sxn(iip1)=sxn(1)
232        sxs(iip1)=sxs(1)
233        do i=1,iim
234           sx(i+1,1,l)=0.25*(sxn(i)+sxn(i+1))*sm(i+1,1,l)
235           sx(i+1,jjp1,l)=0.25*(sxs(i)+sxs(i+1))*sm(i+1,jjp1,l)
236        enddo
237        s0(iip1,1,l)=s0(1,1,l)
238        s0(iip1,jjp1,l)=s0(1,jjp1,l)
239        sy(iip1,1,l)=sy(1,1,l)
240        sy(iip1,jjp1,l)=sy(1,jjp1,l)
241        sx(1,1,l)=sx(iip1,1,l)
242        sx(1,jjp1,l)=sx(iip1,jjp1,l)
243      enddo
244  endif
245
246  if (mode.eq.4) then
247     do l=1,llm
248        do i=1,iip1
249           sx(i,1,l)=0.
250           sx(i,jjp1,l)=0.
251           sy(i,1,l)=0.
252           sy(i,jjp1,l)=0.
253        enddo
254     enddo
255  endif
256  call limx(s0,sx,sm,pente_max)
257  ! call minmaxq(zq,1.e33,-1.e33,'avant advx     ')
258   call advx( limit,.5*dtvr,pbaru,sm,s0,sx,sy,sz,lati,latf)
259  ! call minmaxq(zq,1.e33,-1.e33,'avant advy     ')
260  if (mode.eq.4) then
261     do l=1,llm
262        do i=1,iip1
263           sx(i,1,l)=0.
264           sx(i,jjp1,l)=0.
265           sy(i,1,l)=0.
266           sy(i,jjp1,l)=0.
267        enddo
268     enddo
269  endif
270   call   limy(s0,sy,sm,pente_max)
271   call advy( limit,.5*dtvr,pbarv,sm,s0,sx,sy,sz )
272  ! call minmaxq(zq,1.e33,-1.e33,'avant advz     ')
273   do j=1,jjp1
274      do i=1,iip1
275         sz(i,j,1)=0.
276         sz(i,j,llm)=0.
277      enddo
278   enddo
279   call limz(s0,sz,sm,pente_max)
280   call advz( limit,dtvr,w,sm,s0,sx,sy,sz )
281  if (mode.eq.4) then
282     do l=1,llm
283        do i=1,iip1
284           sx(i,1,l)=0.
285           sx(i,jjp1,l)=0.
286           sy(i,1,l)=0.
287           sy(i,jjp1,l)=0.
288        enddo
289     enddo
290  endif
291    call limy(s0,sy,sm,pente_max)
292   call advy( limit,.5*dtvr,pbarv,sm,s0,sx,sy,sz )
293   do l=1,llm
294      do j=1,jjp1
295         sm(iip1,j,l)=sm(1,j,l)
296         s0(iip1,j,l)=s0(1,j,l)
297         sx(iip1,j,l)=sx(1,j,l)
298         sy(iip1,j,l)=sy(1,j,l)
299         sz(iip1,j,l)=sz(1,j,l)
300      enddo
301   enddo
302
303
304  ! call minmaxq(zq,1.e33,-1.e33,'avant advx     ')
305  if (mode.eq.4) then
306     do l=1,llm
307        do i=1,iip1
308           sx(i,1,l)=0.
309           sx(i,jjp1,l)=0.
310           sy(i,1,l)=0.
311           sy(i,jjp1,l)=0.
312        enddo
313     enddo
314  endif
315   call limx(s0,sx,sm,pente_max)
316   call advx( limit,.5*dtvr,pbaru,sm,s0,sx,sy,sz,lati,latf)
317  ! call minmaxq(zq,1.e33,-1.e33,'apres advx     ')
318  !  do l=1,llm
319  !     do j=1,jjp1
320  !      do i=1,iip1
321  !         zq=s0(i,j,l)/sm(i,j,l)
322  !        if(zq.lt.qmin)
323  !    ,       print*,'apres advx2, s0(',i,',',j,',',l,')=',zq
324  !      enddo
325  !     enddo
326  !  enddo
327  ! ***   On repasse les S dans la variable q directement 14/10/94
328  !   On revient a des rapports de melange en divisant par la masse
329
330  ! En dehors des poles:
331
332   DO  l = 1,llm
333    DO  j = 1,jjp1
334     DO  i = 1,iim
335         q(i,j,llm+1-l,0)=s0(i,j,l)/sm(i,j,l)
336         q(i,j,llm+1-l,1)=sx(i,j,l)/sm(i,j,l)
337         q(i,j,llm+1-l,2)=sy(i,j,l)/sm(i,j,l)
338         q(i,j,llm+1-l,3)=sz(i,j,l)/sm(i,j,l)
339     ENDDO
340    ENDDO
341  ENDDO
342
343  ! Traitements specifiques au pole
344
345  if(mode.ge.1) then
346  DO l=1,llm
347  !   filtrages aux poles
348     masn=ssum(iim,sm(1,1,l),1)
349     mass=ssum(iim,sm(1,jjp1,l),1)
350     qpn=ssum(iim,s0(1,1,l),1)/masn
351     qps=ssum(iim,s0(1,jjp1,l),1)/mass
352     dqzpn=ssum(iim,sz(1,1,l),1)/masn
353     dqzps=ssum(iim,sz(1,jjp1,l),1)/mass
354     do i=1,iip1
355        q( i,1,llm+1-l,3)=dqzpn
356        q( i,jjp1,llm+1-l,3)=dqzps
357        q( i,1,llm+1-l,0)=qpn
358        q( i,jjp1,llm+1-l,0)=qps
359     enddo
360     if(mode.eq.3) then
361        dyn1=0.
362        dys1=0.
363        dyn2=0.
364        dys2=0.
365        do i=1,iim
366           dyn1=dyn1+sinlondlon(i)*sy(i,1,l)/sm(i,1,l)
367           dyn2=dyn2+coslondlon(i)*sy(i,1,l)/sm(i,1,l)
368           dys1=dys1+sinlondlon(i)*sy(i,jjp1,l)/sm(i,jjp1,l)
369           dys2=dys2+coslondlon(i)*sy(i,jjp1,l)/sm(i,jjp1,l)
370        enddo
371        do i=1,iim
372           q(i,1,llm+1-l,2)= &
373                 (sinlon(i)*dyn1+coslon(i)*dyn2)
374           q(i,1,llm+1-l,0)=q(i,1,llm+1-l,0)+q(i,1,llm+1-l,2)
375           q(i,jjp1,llm+1-l,2)= &
376                 (sinlon(i)*dys1+coslon(i)*dys2)
377           q(i,jjp1,llm+1-l,0)=q(i,jjp1,llm+1-l,0) &
378                 -q(i,jjp1,llm+1-l,2)
379        enddo
380     endif
381     if(mode.eq.1) then
382  !   on filtre les valeurs au bord de la "grande maille pole"
383        dyn1=0.
384        dys1=0.
385        dyn2=0.
386        dys2=0.
387        do i=1,iim
388           zz=s0(i,2,l)/sm(i,2,l)-q(i,1,llm+1-l,0)
389           dyn1=dyn1+sinlondlon(i)*zz
390           dyn2=dyn2+coslondlon(i)*zz
391           zz=q(i,jjp1,llm+1-l,0)-s0(i,jjm,l)/sm(i,jjm,l)
392           dys1=dys1+sinlondlon(i)*zz
393           dys2=dys2+coslondlon(i)*zz
394        enddo
395        do i=1,iim
396           q(i,1,llm+1-l,2)= &
397                 (sinlon(i)*dyn1+coslon(i)*dyn2)/2.
398           q(i,1,llm+1-l,0)=q(i,1,llm+1-l,0)+q(i,1,llm+1-l,2)
399           q(i,jjp1,llm+1-l,2)= &
400                 (sinlon(i)*dys1+coslon(i)*dys2)/2.
401           q(i,jjp1,llm+1-l,0)=q(i,jjp1,llm+1-l,0) &
402                 -q(i,jjp1,llm+1-l,2)
403        enddo
404        q(iip1,1,llm+1-l,0)=q(1,1,llm+1-l,0)
405        q(iip1,jjp1,llm+1-l,0)=q(1,jjp1,llm+1-l,0)
406
407        do i=1,iim
408           sxn(i)=q(i+1,1,llm+1-l,0)-q(i,1,llm+1-l,0)
409           sxs(i)=q(i+1,jjp1,llm+1-l,0)-q(i,jjp1,llm+1-l,0)
410        enddo
411        sxn(iip1)=sxn(1)
412        sxs(iip1)=sxs(1)
413        do i=1,iim
414           q(i+1,1,llm+1-l,1)=0.25*(sxn(i)+sxn(i+1))
415           q(i+1,jjp1,llm+1-l,1)=0.25*(sxs(i)+sxs(i+1))
416        enddo
417        q(1,1,llm+1-l,1)=q(iip1,1,llm+1-l,1)
418        q(1,jjp1,llm+1-l,1)=q(iip1,jjp1,llm+1-l,1)
419
420     endif
421
422   ENDDO
423   endif
424
425  ! bouclage en longitude
426  do iq=0,3
427     do l=1,llm
428        do j=1,jjp1
429           q(iip1,j,l,iq)=q(1,j,l,iq)
430        enddo
431     enddo
432  enddo
433
434    ! PRINT*, ' SORTIE DE PENTES ---  ca peut glisser ....'
435
436    DO l = 1,llm
437         DO j = 1,jjp1
438          DO i = 1,iip1
439            IF (q(i,j,l,0).lt.0.)  THEN
440                 ! PRINT*,'------------ BIP-----------'
441                 ! PRINT*,'Q0(',i,j,l,')=',q(i,j,l,0)
442                 ! PRINT*,'QX(',i,j,l,')=',q(i,j,l,1)
443                 ! PRINT*,'QY(',i,j,l,')=',q(i,j,l,2)
444                 ! PRINT*,'QZ(',i,j,l,')=',q(i,j,l,3)
445                 !         PRINT*,' PBL EN SORTIE DE PENTES'
446                 q(i,j,l,0)=0.
447                 ! STOP
448             ENDIF
449      ENDDO
450     ENDDO
451    ENDDO
452
453    ! PRINT*, '-------------------------------------------'
454
455   do l=1,llm
456      do j=1,jjp1
457       do i=1,iip1
458         if(q(i,j,l,0).lt.qmin) &
459               print*,'apres pentes, s0(',i,',',j,',',l,')=',q(i,j,l,0)
460       enddo
461      enddo
462   enddo
463  RETURN
464END SUBROUTINE pentes_ini
465
466
467
468
469
470
471
472
473
474
475
476
Note: See TracBrowser for help on using the repository browser.