GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: dyn3d/vlsplt.F Lines: 212 295 71.9 %
Date: 2023-06-30 12:56:34 Branches: 146 228 64.0 %

Line Branch Exec Source
1
c
2
c $Id: vlsplt.F 4470 2023-03-10 16:55:53Z fairhead $
3
c
4
5
1152
      SUBROUTINE vlsplt(q,pente_max,masse,w,pbaru,pbarv,pdt,iq)
6
      USE infotrac, ONLY: nqtot,tracers
7
c
8
c     Auteurs:   P.Le Van, F.Hourdin, F.Forget
9
c
10
c    ********************************************************************
11
c     Shema  d'advection " pseudo amont " .
12
c    ********************************************************************
13
c     q,pbaru,pbarv,w sont des arguments d'entree  pour le s-pg ....
14
c
15
c   pente_max facteur de limitation des pentes: 2 en general
16
c                                               0 pour un schema amont
17
c   pbaru,pbarv,w flux de masse en u ,v ,w
18
c   pdt pas de temps
19
c
20
c   --------------------------------------------------------------------
21
      IMPLICIT NONE
22
c
23
      include "dimensions.h"
24
      include "paramet.h"
25
26
c
27
c   Arguments:
28
c   ----------
29
      REAL masse(ip1jmp1,llm),pente_max
30
c      REAL masse(iip1,jjp1,llm),pente_max
31
      REAL pbaru( ip1jmp1,llm ),pbarv( ip1jm,llm)
32
      REAL q(ip1jmp1,llm,nqtot)
33
c      REAL q(iip1,jjp1,llm)
34
      REAL w(ip1jmp1,llm),pdt
35
      INTEGER iq ! CRisi
36
c
37
c      Local
38
c   ---------
39
c
40
      INTEGER ij,l
41
c
42
2304
      REAL zm(ip1jmp1,llm,nqtot)
43
      REAL mu(ip1jmp1,llm)
44
      REAL mv(ip1jm,llm)
45
      REAL mw(ip1jmp1,llm+1)
46
2304
      REAL zq(ip1jmp1,llm,nqtot)
47
      REAL zzpbar, zzw
48
      INTEGER ifils,iq2 ! CRisi
49
50
      REAL qmin,qmax
51
      DATA qmin,qmax/0.,1.e33/
52
53
1152
        zzpbar = 0.5 * pdt
54
        zzw    = pdt
55
46080
      DO l=1,llm
56
46006272
        DO ij = iip2,ip1jm
57
46006272
            mu(ij,l)=pbaru(ij,l) * zzpbar
58
         ENDDO
59
47488896
         DO ij=1,ip1jm
60
47488896
            mv(ij,l)=pbarv(ij,l) * zzpbar
61
         ENDDO
62
48972672
         DO ij=1,ip1jmp1
63
48971520
            mw(ij,l)=w(ij,l) * zzw
64
         ENDDO
65
      ENDDO
66
67
1255680
      DO ij=1,ip1jmp1
68
1255680
         mw(ij,llm+1)=0.
69
      ENDDO
70
71
1152
      CALL SCOPY(ijp1llm,q(1,1,iq),1,zq(1,1,iq),1)
72
1152
      CALL SCOPY(ijp1llm,masse,1,zm(1,1,iq),1)
73
74
1152
      do ifils=1,tracers(iq)%nqDescen
75
        iq2=tracers(iq)%iqDescen(ifils)
76
1152
        CALL SCOPY(ijp1llm,q(1,1,iq2),1,zq(1,1,iq2),1)
77
      enddo
78
79
cprint*,'Entree vlx1'
80
c	call minmaxq(zq,qmin,qmax,'avant vlx     ')
81
1152
      call vlx(zq,pente_max,zm,mu,iq)
82
cprint*,'Sortie vlx1'
83
c	call minmaxq(zq,qmin,qmax,'apres vlx1    ')
84
85
c print*,'Entree vly1'
86
87
1152
      call vly(zq,pente_max,zm,mv,iq)
88
c	call minmaxq(zq,qmin,qmax,'apres vly1     ')
89
cprint*,'Sortie vly1'
90
1152
      call vlz(zq,pente_max,zm,mw,iq)
91
c	call minmaxq(zq,qmin,qmax,'apres vlz     ')
92
93
94
1152
      call vly(zq,pente_max,zm,mv,iq)
95
c	call minmaxq(zq,qmin,qmax,'apres vly     ')
96
97
98
1152
      call vlx(zq,pente_max,zm,mu,iq)
99
c	call minmaxq(zq,qmin,qmax,'apres vlx2    ')
100
101
102
46080
      DO l=1,llm
103
48971520
         DO ij=1,ip1jmp1
104
48971520
           q(ij,l,iq)=zq(ij,l,iq)
105
         ENDDO
106
1152
         DO ij=1,ip1jm+1,iip1
107
1482624
            q(ij+iim,l,iq)=q(ij,l,iq)
108
         ENDDO
109
      ENDDO
110
      ! CRisi: aussi pour les fils
111
1152
      do ifils=1,tracers(iq)%nqDescen
112
        iq2=tracers(iq)%iqDescen(ifils)
113
1152
        DO l=1,llm
114
          DO ij=1,ip1jmp1
115
            q(ij,l,iq2)=zq(ij,l,iq2)
116
          ENDDO
117
          DO ij=1,ip1jm+1,iip1
118
            q(ij+iim,l,iq2)=q(ij,l,iq2)
119
          ENDDO
120
        ENDDO
121
      enddo
122
123
1152
      RETURN
124
      END
125
2304
      RECURSIVE SUBROUTINE vlx(q,pente_max,masse,u_m,iq)
126
      USE infotrac, ONLY : nqtot,tracers, ! CRisi
127
     &                     min_qParent,min_qMass,min_ratio ! MVals et CRisi
128
129
c     Auteurs:   P.Le Van, F.Hourdin, F.Forget
130
c
131
c    ********************************************************************
132
c     Shema  d'advection " pseudo amont " .
133
c    ********************************************************************
134
c     nq,iq,q,pbaru,pbarv,w sont des arguments d'entree  pour le s-pg ....
135
c
136
c
137
c   --------------------------------------------------------------------
138
      IMPLICIT NONE
139
c
140
      include "dimensions.h"
141
      include "paramet.h"
142
      include "iniprint.h"
143
c
144
c
145
c   Arguments:
146
c   ----------
147
      REAL masse(ip1jmp1,llm,nqtot),pente_max
148
      REAL u_m( ip1jmp1,llm )
149
      REAL q(ip1jmp1,llm,nqtot)
150
      INTEGER iq ! CRisi
151
c
152
c      Local
153
c   ---------
154
c
155
      INTEGER ij,l,j,i,iju,ijq,indu(ip1jmp1),niju
156
      INTEGER n0,iadvplus(ip1jmp1,llm),nl(llm)
157
c
158
      REAL new_m,zu_m,zdum(ip1jmp1,llm)
159
c      REAL sigu(ip1jmp1)
160
      REAL dxq(ip1jmp1,llm),dxqu(ip1jmp1)
161
      REAL zz(ip1jmp1)
162
      REAL adxqu(ip1jmp1),dxqmax(ip1jmp1,llm)
163
      REAL u_mq(ip1jmp1,llm)
164
165
      ! CRisi
166
4608
      REAL masseq(ip1jmp1,llm,nqtot),Ratio(ip1jmp1,llm,nqtot)
167
      INTEGER ifils,iq2 ! CRisi
168
169
      Logical first
170
      SAVE first
171
      DATA first/.true./
172
173
c   calcul de la pente a droite et a gauche de la maille
174
175
176
2304
      IF (pente_max.gt.-1.e-5) THEN
177
c       IF (pente_max.gt.10) THEN
178
179
c   calcul des pentes avec limitation, Van Leer scheme I:
180
c   -----------------------------------------------------
181
182
c   calcul de la pente aux points u
183
92160
         DO l = 1, llm
184
91922688
            DO ij=iip2,ip1jm-1
185
91922688
               dxqu(ij)=q(ij+1,l,iq)-q(ij,l,iq)
186
            ENDDO
187
2785536
            DO ij=iip1+iip1,ip1jm,iip1
188
2785536
               dxqu(ij)=dxqu(ij-iim)
189
c              sigu(ij)=sigu(ij-iim)
190
            ENDDO
191
192
92012544
            DO ij=iip2,ip1jm
193
92012544
               adxqu(ij)=abs(dxqu(ij))
194
            ENDDO
195
196
c   calcul de la pente maximum dans la maille en valeur absolue
197
198
91922688
            DO ij=iip2+1,ip1jm
199
               dxqmax(ij,l)=pente_max*
200
91922688
     ,      min(adxqu(ij-1),adxqu(ij))
201
c limitation subtile
202
c    ,      min(adxqu(ij-1)/sigu(ij-1),adxqu(ij)/(1.-sigu(ij)))
203
204
205
            ENDDO
206
207
2785536
            DO ij=iip1+iip1,ip1jm,iip1
208
2785536
               dxqmax(ij-iim,l)=dxqmax(ij,l)
209
            ENDDO
210
211
91924992
            DO ij=iip2+1,ip1jm
212
#ifdef CRAY
213
               dxq(ij,l)=
214
     ,         cvmgp(dxqu(ij-1)+dxqu(ij),0.,dxqu(ij-1)*dxqu(ij))
215
#else
216
91832832
               IF(dxqu(ij-1)*dxqu(ij).gt.0) THEN
217
38135963
                  dxq(ij,l)=dxqu(ij-1)+dxqu(ij)
218
               ELSE
219
c   extremum local
220
53696869
                  dxq(ij,l)=0.
221
               ENDIF
222
#endif
223
91832832
               dxq(ij,l)=0.5*dxq(ij,l)
224
               dxq(ij,l)=
225
91922688
     ,         sign(min(abs(dxq(ij,l)),dxqmax(ij,l)),dxq(ij,l))
226
            ENDDO
227
228
         ENDDO ! l=1,llm
229
cprint*,'Ok calcul des pentes'
230
231
      ELSE ! (pente_max.lt.-1.e-5)
232
233
c   Pentes produits:
234
c   ----------------
235
236
         DO l = 1, llm
237
            DO ij=iip2,ip1jm-1
238
               dxqu(ij)=q(ij+1,l,iq)-q(ij,l,iq)
239
            ENDDO
240
            DO ij=iip1+iip1,ip1jm,iip1
241
               dxqu(ij)=dxqu(ij-iim)
242
            ENDDO
243
244
            DO ij=iip2+1,ip1jm
245
               zz(ij)=dxqu(ij-1)*dxqu(ij)
246
               zz(ij)=zz(ij)+zz(ij)
247
               IF(zz(ij).gt.0) THEN
248
                  dxq(ij,l)=zz(ij)/(dxqu(ij-1)+dxqu(ij))
249
               ELSE
250
c   extremum local
251
                  dxq(ij,l)=0.
252
               ENDIF
253
            ENDDO
254
255
         ENDDO
256
257
      ENDIF ! (pente_max.lt.-1.e-5)
258
259
c   bouclage de la pente en iip1:
260
c   -----------------------------
261
262
92160
      DO l=1,llm
263
2785536
         DO ij=iip1+iip1,ip1jm,iip1
264
2785536
            dxq(ij-iim,l)=dxq(ij,l)
265
         ENDDO
266
97945344
         DO ij=1,ip1jmp1
267
97943040
            iadvplus(ij,l)=0
268
         ENDDO
269
270
      ENDDO
271
272
c print*,'Bouclage en iip1'
273
274
c   calcul des flux a gauche et a droite
275
276
#ifdef CRAY
277
278
      DO l=1,llm
279
       DO ij=iip2,ip1jm-1
280
          zdum(ij,l)=cvmgp(1.-u_m(ij,l)/masse(ij,l,iq),
281
     ,                     1.+u_m(ij,l)/masse(ij+1,l,iq),
282
     ,                     u_m(ij,l))
283
          zdum(ij,l)=0.5*zdum(ij,l)
284
          u_mq(ij,l)=cvmgp(
285
     ,                q(ij,l,iq)+zdum(ij,l)*dxq(ij,l),
286
     ,                q(ij+1,l,iq)-zdum(ij,l)*dxq(ij+1,l),
287
     ,                u_m(ij,l))
288
          u_mq(ij,l)=u_m(ij,l)*u_mq(ij,l)
289
       ENDDO
290
      ENDDO
291
#else
292
c   on cumule le flux correspondant a toutes les mailles dont la masse
293
c   au travers de la paroi pENDant le pas de temps.
294
cprint*,'Cumule ....'
295
296
92160
      DO l=1,llm
297
91924992
       DO ij=iip2,ip1jm-1
298
c	print*,'masse(',ij,')=',masse(ij,l,iq)
299
91922688
          IF (u_m(ij,l).gt.0.) THEN
300
65492448
             zdum(ij,l)=1.-u_m(ij,l)/masse(ij,l,iq)
301
65492448
             u_mq(ij,l)=u_m(ij,l)*(q(ij,l,iq)+0.5*zdum(ij,l)*dxq(ij,l))
302
          ELSE
303
26340384
             zdum(ij,l)=1.+u_m(ij,l)/masse(ij+1,l,iq)
304
             u_mq(ij,l)=u_m(ij,l)*(q(ij+1,l,iq)
305
26340384
     &           -0.5*zdum(ij,l)*dxq(ij+1,l))
306
          ENDIF
307
       ENDDO
308
      ENDDO
309
#endif
310
311
c	go to 9999
312
c   detection des points ou on advecte plus que la masse de la
313
c   maille
314
92160
      DO l=1,llm
315
91924992
         DO ij=iip2,ip1jm-1
316
91922688
            IF(zdum(ij,l).lt.0) THEN
317
               iadvplus(ij,l)=1
318
               u_mq(ij,l)=0.
319
            ENDIF
320
         ENDDO
321
      ENDDO
322
cprint*,'Ok test 1'
323
92160
      DO l=1,llm
324
2304
       DO ij=iip1+iip1,ip1jm,iip1
325
2785536
          iadvplus(ij,l)=iadvplus(ij-iim,l)
326
       ENDDO
327
      ENDDO
328
c print*,'Ok test 2'
329
330
331
c   traitement special pour le cas ou on advecte en longitude plus que le
332
c   contenu de la maille.
333
c   cette partie est mal vectorisee.
334
335
c  calcul du nombre de maille sur lequel on advecte plus que la maille.
336
337
2304
      n0=0
338
92160
      DO l=1,llm
339
89856
         nl(l)=0
340
92012544
         DO ij=iip2,ip1jm
341
92012544
            nl(l)=nl(l)+iadvplus(ij,l)
342
         ENDDO
343
92160
         n0=n0+nl(l)
344
      ENDDO
345
346
2304
      IF(n0.gt.0) THEN
347
      if (prt_level > 2) PRINT *,
348
     $        'Nombre de points pour lesquels on advect plus que le'
349
     &       ,'contenu de la maille : ',n0
350
351
         DO l=1,llm
352
            IF(nl(l).gt.0) THEN
353
               iju=0
354
c   indicage des mailles concernees par le traitement special
355
               DO ij=iip2,ip1jm
356
                  IF(iadvplus(ij,l).eq.1.and.mod(ij,iip1).ne.0) THEN
357
                     iju=iju+1
358
                     indu(iju)=ij
359
                  ENDIF
360
               ENDDO
361
               niju=iju
362
c              PRINT*,'niju,nl',niju,nl(l)
363
364
c  traitement des mailles
365
               DO iju=1,niju
366
                  ij=indu(iju)
367
                  j=(ij-1)/iip1+1
368
                  zu_m=u_m(ij,l)
369
                  u_mq(ij,l)=0.
370
                  IF(zu_m.gt.0.) THEN
371
                     ijq=ij
372
                     i=ijq-(j-1)*iip1
373
c   accumulation pour les mailles completements advectees
374
                     do while(zu_m.gt.masse(ijq,l,iq))
375
                        u_mq(ij,l)=u_mq(ij,l)+q(ijq,l,iq)
376
     &                          *masse(ijq,l,iq)
377
                        zu_m=zu_m-masse(ijq,l,iq)
378
                        i=mod(i-2+iim,iim)+1
379
                        ijq=(j-1)*iip1+i
380
                     ENDDO
381
c   ajout de la maille non completement advectee
382
                     u_mq(ij,l)=u_mq(ij,l)+zu_m*
383
     &                  (q(ijq,l,iq)+0.5*(1.-zu_m/masse(ijq,l,iq))
384
     &                  *dxq(ijq,l))
385
                  ELSE
386
                     ijq=ij+1
387
                     i=ijq-(j-1)*iip1
388
c   accumulation pour les mailles completements advectees
389
                     do while(-zu_m.gt.masse(ijq,l,iq))
390
                        u_mq(ij,l)=u_mq(ij,l)-q(ijq,l,iq)
391
     &                          *masse(ijq,l,iq)
392
                        zu_m=zu_m+masse(ijq,l,iq)
393
                        i=mod(i,iim)+1
394
                        ijq=(j-1)*iip1+i
395
                     ENDDO
396
c   ajout de la maille non completement advectee
397
                     u_mq(ij,l)=u_mq(ij,l)+zu_m*(q(ijq,l,iq)-
398
     &               0.5*(1.+zu_m/masse(ijq,l,iq))*dxq(ijq,l))
399
                  ENDIF
400
               ENDDO
401
            ENDIF
402
         ENDDO
403
      ENDIF  ! n0.gt.0
404
c9999    continue
405
406
407
c   bouclage en latitude
408
cprint*,'cvant bouclage en latitude'
409
92160
      DO l=1,llm
410
2304
        DO ij=iip1+iip1,ip1jm,iip1
411
2785536
           u_mq(ij,l)=u_mq(ij-iim,l)
412
        ENDDO
413
      ENDDO
414
415
! CRisi: appel récursif de l'advection sur les fils.
416
! Il faut faire ça avant d'avoir mis à jour q et masse
417
      !write(*,*) 'vlsplt 326: iq,nqDesc(iq)=',iq,tracers(iq)%nqDescen
418
419
2304
      do ifils=1,tracers(iq)%nqDescen
420
        iq2=tracers(iq)%iqDescen(ifils)
421
2304
        DO l=1,llm
422
          DO ij=iip2,ip1jm
423
            ! On a besoin de q et masse seulement entre iip2 et ip1jm
424
            !masseq(ij,l,iq2)=masse(ij,l,iq)*q(ij,l,iq)
425
            !Ratio(ij,l,iq2)=q(ij,l,iq2)/q(ij,l,iq)
426
            !Mvals: veiller a ce qu'on n'ait pas de denominateur nul
427
            masseq(ij,l,iq2)=max(masse(ij,l,iq)*q(ij,l,iq),min_qMass)
428
            if (q(ij,l,iq).gt.min_qParent) then
429
              Ratio(ij,l,iq2)=q(ij,l,iq2)/q(ij,l,iq)
430
            else
431
              Ratio(ij,l,iq2)=min_ratio
432
            endif
433
          enddo
434
        enddo
435
      enddo
436
2304
      do ifils=1,tracers(iq)%nqChildren
437
        iq2=tracers(iq)%iqDescen(ifils)
438
2304
        call vlx(Ratio,pente_max,masseq,u_mq,iq2)
439
      enddo
440
! end CRisi
441
442
443
c   calcul des tENDances
444
445
92160
      DO l=1,llm
446
91922688
         DO ij=iip2+1,ip1jm
447
            !MVals: veiller a ce qu'on ait pas de denominateur nul
448
91832832
            new_m=max(masse(ij,l,iq)+u_m(ij-1,l)-u_m(ij,l),min_qMass)
449
            q(ij,l,iq)=(q(ij,l,iq)*masse(ij,l,iq)+
450
     &      u_mq(ij-1,l)-u_mq(ij,l))
451
91832832
     &      /new_m
452
91922688
            masse(ij,l,iq)=new_m
453
         ENDDO
454
c   ModIF Fred 22 03 96 correction d'un bug (les scopy ci-dessous)
455
2304
         DO ij=iip1+iip1,ip1jm,iip1
456
2785536
            q(ij-iim,l,iq)=q(ij,l,iq)
457
2785536
            masse(ij-iim,l,iq)=masse(ij,l,iq)
458
         ENDDO
459
      ENDDO
460
461
      ! retablir les fils en rapport de melange par rapport a l'air:
462
      ! On calcule q entre iip2+1,ip1jm -> on fait pareil pour ratio
463
      ! puis on boucle en longitude
464
2304
      do ifils=1,tracers(iq)%nqDescen
465
        iq2=tracers(iq)%iqDescen(ifils)
466
2304
        DO l=1,llm
467
          DO ij=iip2+1,ip1jm
468
            q(ij,l,iq2)=q(ij,l,iq)*Ratio(ij,l,iq2)
469
          enddo
470
          DO ij=iip1+iip1,ip1jm,iip1
471
             q(ij-iim,l,iq2)=q(ij,l,iq2)
472
          enddo ! DO ij=ijb+iip1-1,ije,iip1
473
        enddo !DO l=1,llm
474
      enddo
475
476
c     CALL SCOPY((jjm-1)*llm,q(iip1+iip1,1),iip1,q(iip2,1),iip1)
477
c     CALL SCOPY((jjm-1)*llm,masse(iip1+iip1,1),iip1,masse(iip2,1),iip1)
478
479
480
2304
      RETURN
481
      END
482
2304
      RECURSIVE SUBROUTINE vly(q,pente_max,masse,masse_adv_v,iq)
483
      USE infotrac, ONLY : nqtot,tracers, ! CRisi
484
     &                     min_qParent,min_qMass,min_ratio ! MVals et CRisi
485
c
486
c     Auteurs:   P.Le Van, F.Hourdin, F.Forget
487
c
488
c    ********************************************************************
489
c     Shema  d'advection " pseudo amont " .
490
c    ********************************************************************
491
c     q,masse_adv_v,w sont des arguments d'entree  pour le s-pg ....
492
c     dq 	       sont des arguments de sortie pour le s-pg ....
493
c
494
c
495
c   --------------------------------------------------------------------
496
      USE comconst_mod, ONLY: pi
497
      IMPLICIT NONE
498
c
499
      include "dimensions.h"
500
      include "paramet.h"
501
      include "comgeom.h"
502
c
503
c
504
c   Arguments:
505
c   ----------
506
      REAL masse(ip1jmp1,llm,nqtot),pente_max
507
      REAL masse_adv_v( ip1jm,llm)
508
      REAL q(ip1jmp1,llm,nqtot)
509
      INTEGER iq ! CRisi
510
c
511
c      Local
512
c   ---------
513
c
514
      INTEGER i,ij,l
515
c
516
      REAL airej2,airejjm,airescb(iim),airesch(iim)
517
      REAL dyq(ip1jmp1,llm),dyqv(ip1jm)
518
      REAL adyqv(ip1jm),dyqmax(ip1jmp1)
519
      REAL qbyv(ip1jm,llm)
520
521
      REAL qpns,qpsn,dyn1,dys1,dyn2,dys2,newmasse,fn,fs
522
c     REAL appn apps
523
c     REAL newq,oldmasse
524
      LOGICAL first
525
      SAVE first
526
527
      REAL convpn,convps,convmpn,convmps
528
      real massepn,masseps,qpn,qps
529
      REAL sinlon(iip1),sinlondlon(iip1)
530
      REAL coslon(iip1),coslondlon(iip1)
531
      SAVE sinlon,coslon,sinlondlon,coslondlon
532
      SAVE airej2,airejjm
533
534
4608
      REAL masseq(ip1jmp1,llm,nqtot),Ratio(ip1jmp1,llm,nqtot) ! CRisi
535
      INTEGER ifils,iq2 ! CRisi
536
537
c
538
c
539
      REAL      SSUM
540
541
      DATA first/.true./
542
543
      !write(*,*) 'vly 578: entree, iq=',iq
544
545
2304
      IF(first) THEN
546
1
         PRINT*,'Shema  Amont nouveau  appele dans  Vanleer   '
547
1
         first=.false.
548
33
         do i=2,iip1
549
32
            coslon(i)=cos(rlonv(i))
550
32
            sinlon(i)=sin(rlonv(i))
551
32
            coslondlon(i)=coslon(i)*(rlonu(i)-rlonu(i-1))/pi
552
33
            sinlondlon(i)=sinlon(i)*(rlonu(i)-rlonu(i-1))/pi
553
         ENDDO
554
1
         coslon(1)=coslon(iip1)
555
1
         coslondlon(1)=coslondlon(iip1)
556
1
         sinlon(1)=sinlon(iip1)
557
1
         sinlondlon(1)=sinlondlon(iip1)
558
1
         airej2 = SSUM( iim, aire(iip2), 1 )
559
1
         airejjm= SSUM( iim, aire(ip1jm -iim), 1 )
560
      ENDIF
561
562
c
563
cPRINT*,'CALCUL EN LATITUDE'
564
565
92160
      DO l = 1, llm
566
c
567
c   --------------------------------
568
c      CALCUL EN LATITUDE
569
c   --------------------------------
570
571
c   On commence par calculer la valeur du traceur moyenne sur le premier cercle
572
c   de latitude autour du pole (qpns pour le pole nord et qpsn pour
573
c    le pole nord) qui sera utilisee pour evaluer les pentes au pole.
574
575
2965248
      DO i = 1, iim
576
2875392
      airescb(i) = aire(i+ iip1) * q(i+ iip1,l,iq)
577
2965248
      airesch(i) = aire(i+ ip1jm- iip1) * q(i+ ip1jm- iip1,l,iq)
578
      ENDDO
579
89856
      qpns   = SSUM( iim,  airescb ,1 ) / airej2
580
89856
      qpsn   = SSUM( iim,  airesch ,1 ) / airejjm
581
582
c   calcul des pentes aux points v
583
584
94977792
      DO ij=1,ip1jm
585
94887936
         dyqv(ij)=q(ij,l,iq)-q(ij+iip1,l,iq)
586
94977792
         adyqv(ij)=abs(dyqv(ij))
587
      ENDDO
588
589
c   calcul des pentes aux points scalaires
590
591
92012544
      DO ij=iip2,ip1jm
592
91922688
         dyq(ij,l)=.5*(dyqv(ij-iip1)+dyqv(ij))
593
91922688
         dyqmax(ij)=min(adyqv(ij-iip1),adyqv(ij))
594
92012544
         dyqmax(ij)=pente_max*dyqmax(ij)
595
      ENDDO
596
597
c   calcul des pentes aux poles
598
599
3055104
      DO ij=1,iip1
600
2965248
         dyq(ij,l)=qpns-q(ij+iip1,l,iq)
601
3055104
         dyq(ip1jm+ij,l)=q(ip1jm+ij-iip1,l,iq)-qpsn
602
      ENDDO
603
604
c   filtrage de la derivee
605
      dyn1=0.
606
      dys1=0.
607
      dyn2=0.
608
      dys2=0.
609
2965248
      DO ij=1,iim
610
2875392
         dyn1=dyn1+sinlondlon(ij)*dyq(ij,l)
611
2875392
         dys1=dys1+sinlondlon(ij)*dyq(ip1jm+ij,l)
612
2875392
         dyn2=dyn2+coslondlon(ij)*dyq(ij,l)
613
2965248
         dys2=dys2+coslondlon(ij)*dyq(ip1jm+ij,l)
614
      ENDDO
615
3055104
      DO ij=1,iip1
616
2965248
         dyq(ij,l)=dyn1*sinlon(ij)+dyn2*coslon(ij)
617
3055104
         dyq(ip1jm+ij,l)=dys1*sinlon(ij)+dys2*coslon(ij)
618
      ENDDO
619
620
c   calcul des pentes limites aux poles
621
622
      goto 8888
623
      fn=1.
624
      fs=1.
625
      DO ij=1,iim
626
         IF(pente_max*adyqv(ij).lt.abs(dyq(ij,l))) THEN
627
            fn=min(pente_max*adyqv(ij)/abs(dyq(ij,l)),fn)
628
         ENDIF
629
      IF(pente_max*adyqv(ij+ip1jm-iip1).lt.abs(dyq(ij+ip1jm,l))) THEN
630
         fs=min(pente_max*adyqv(ij+ip1jm-iip1)/abs(dyq(ij+ip1jm,l)),fs)
631
         ENDIF
632
      ENDDO
633
      DO ij=1,iip1
634
         dyq(ij,l)=fn*dyq(ij,l)
635
         dyq(ip1jm+ij,l)=fs*dyq(ip1jm+ij,l)
636
      ENDDO
637
8888    continue
638
3055104
      DO ij=1,iip1
639
2965248
         dyq(ij,l)=0.
640
3055104
         dyq(ip1jm+ij,l)=0.
641
      ENDDO
642
643
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
644
C  En memoire de dIFferents tests sur la
645
C  limitation des pentes aux poles.
646
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
647
C     PRINT*,dyq(1)
648
C     PRINT*,dyqv(iip1+1)
649
C     appn=abs(dyq(1)/dyqv(iip1+1))
650
C     PRINT*,dyq(ip1jm+1)
651
C     PRINT*,dyqv(ip1jm-iip1+1)
652
C     apps=abs(dyq(ip1jm+1)/dyqv(ip1jm-iip1+1))
653
C     DO ij=2,iim
654
C        appn=amax1(abs(dyq(ij)/dyqv(ij)),appn)
655
C        apps=amax1(abs(dyq(ip1jm+ij)/dyqv(ip1jm-iip1+ij)),apps)
656
C     ENDDO
657
C     appn=min(pente_max/appn,1.)
658
C     apps=min(pente_max/apps,1.)
659
C
660
C
661
C   cas ou on a un extremum au pole
662
C
663
C     IF(dyqv(ismin(iim,dyqv,1))*dyqv(ismax(iim,dyqv,1)).le.0.)
664
C    &   appn=0.
665
C     IF(dyqv(ismax(iim,dyqv(ip1jm-iip1+1),1)+ip1jm-iip1+1)*
666
C    &   dyqv(ismin(iim,dyqv(ip1jm-iip1+1),1)+ip1jm-iip1+1).le.0.)
667
C    &   apps=0.
668
C
669
C   limitation des pentes aux poles
670
C     DO ij=1,iip1
671
C        dyq(ij)=appn*dyq(ij)
672
C        dyq(ip1jm+ij)=apps*dyq(ip1jm+ij)
673
C     ENDDO
674
C
675
C   test
676
C      DO ij=1,iip1
677
C         dyq(iip1+ij)=0.
678
C         dyq(ip1jm+ij-iip1)=0.
679
C      ENDDO
680
C      DO ij=1,ip1jmp1
681
C         dyq(ij)=dyq(ij)*cos(rlatu((ij-1)/iip1+1))
682
C      ENDDO
683
C
684
C changement 10 07 96
685
C     IF(dyqv(ismin(iim,dyqv,1))*dyqv(ismax(iim,dyqv,1)).le.0.)
686
C    &   THEN
687
C        DO ij=1,iip1
688
C           dyqmax(ij)=0.
689
C        ENDDO
690
C     ELSE
691
C        DO ij=1,iip1
692
C           dyqmax(ij)=pente_max*abs(dyqv(ij))
693
C        ENDDO
694
C     ENDIF
695
C
696
C     IF(dyqv(ismax(iim,dyqv(ip1jm-iip1+1),1)+ip1jm-iip1+1)*
697
C    & dyqv(ismin(iim,dyqv(ip1jm-iip1+1),1)+ip1jm-iip1+1).le.0.)
698
C    &THEN
699
C        DO ij=ip1jm+1,ip1jmp1
700
C           dyqmax(ij)=0.
701
C        ENDDO
702
C     ELSE
703
C        DO ij=ip1jm+1,ip1jmp1
704
C           dyqmax(ij)=pente_max*abs(dyqv(ij-iip1))
705
C        ENDDO
706
C     ENDIF
707
C   fin changement 10 07 96
708
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
709
710
c   calcul des pentes limitees
711
712
92014848
      DO ij=iip2,ip1jm
713
92012544
         IF(dyqv(ij)*dyqv(ij-iip1).gt.0.) THEN
714
39107408
            dyq(ij,l)=sign(min(abs(dyq(ij,l)),dyqmax(ij)),dyq(ij,l))
715
         ELSE
716
52815280
            dyq(ij,l)=0.
717
         ENDIF
718
      ENDDO
719
720
      ENDDO
721
722
      !write(*,*) 'vly 756'
723
92160
      DO l=1,llm
724
94980096
       DO ij=1,ip1jm
725
94887936
          IF(masse_adv_v(ij,l).gt.0) THEN
726
              qbyv(ij,l)=q(ij+iip1,l,iq)+dyq(ij+iip1,l)*
727
     ,                   0.5*(1.-masse_adv_v(ij,l)
728
47777704
     ,                   /masse(ij+iip1,l,iq))
729
          ELSE
730
              qbyv(ij,l)=q(ij,l,iq)-dyq(ij,l)*
731
     ,                   0.5*(1.+masse_adv_v(ij,l)
732
47110232
     ,                   /masse(ij,l,iq))
733
          ENDIF
734
94977792
          qbyv(ij,l)=masse_adv_v(ij,l)*qbyv(ij,l)
735
       ENDDO
736
      ENDDO
737
738
! CRisi: appel récursif de l'advection sur les fils.
739
! Il faut faire ça avant d'avoir mis à jour q et masse
740
      !write(*,*) 'vly 689: iq,nqDesc(iq)=',iq,tracers(iq)%nqDescen
741
742
2304
      do ifils=1,tracers(iq)%nqDescen
743
        iq2=tracers(iq)%iqDescen(ifils)
744
2304
        DO l=1,llm
745
          DO ij=1,ip1jmp1
746
            ! attention, chaque fils doit avoir son masseq, sinon, le 1er
747
            ! fils ecrase le masseq de ses freres.
748
            !masseq(ij,l,iq2)=masse(ij,l,iq)*q(ij,l,iq)
749
            !Ratio(ij,l,iq2)=q(ij,l,iq2)/q(ij,l,iq)
750
            !MVals: veiller a ce qu'on n'ait pas de denominateur nul
751
            masseq(ij,l,iq2)=max(masse(ij,l,iq)*q(ij,l,iq),min_qMass)
752
            if (q(ij,l,iq).gt.min_qParent) then
753
              Ratio(ij,l,iq2)=q(ij,l,iq2)/q(ij,l,iq)
754
            else
755
              Ratio(ij,l,iq2)=min_ratio
756
            endif
757
          enddo
758
        enddo
759
      enddo
760
761
2304
      do ifils=1,tracers(iq)%nqDescen
762
        iq2=tracers(iq)%iqDescen(ifils)
763
2304
        call vly(Ratio,pente_max,masseq,qbyv,iq2)
764
      enddo
765
766
92160
      DO l=1,llm
767
92012544
         DO ij=iip2,ip1jm
768
            newmasse=masse(ij,l,iq)
769
91922688
     &      +masse_adv_v(ij,l)-masse_adv_v(ij-iip1,l)
770
            q(ij,l,iq)=(q(ij,l,iq)*masse(ij,l,iq)+qbyv(ij,l)
771
91922688
     &         -qbyv(ij-iip1,l))/newmasse
772
92012544
            masse(ij,l,iq)=newmasse
773
         ENDDO
774
c.-. ancienne version
775
c        convpn=SSUM(iim,qbyv(1,l),1)/apoln
776
c        convmpn=ssum(iim,masse_adv_v(1,l),1)/apoln
777
778
89856
         convpn=SSUM(iim,qbyv(1,l),1)
779
89856
         convmpn=ssum(iim,masse_adv_v(1,l),1)
780
89856
         massepn=ssum(iim,masse(1,l,iq),1)
781
         qpn=0.
782
2965248
         do ij=1,iim
783
2965248
            qpn=qpn+masse(ij,l,iq)*q(ij,l,iq)
784
         enddo
785
89856
         qpn=(qpn+convpn)/(massepn+convmpn)
786
3055104
         do ij=1,iip1
787
3055104
            q(ij,l,iq)=qpn
788
         enddo
789
790
c        convps=-SSUM(iim,qbyv(ip1jm-iim,l),1)/apols
791
c        convmps=-ssum(iim,masse_adv_v(ip1jm-iim,l),1)/apols
792
793
89856
         convps=-SSUM(iim,qbyv(ip1jm-iim,l),1)
794
89856
         convmps=-ssum(iim,masse_adv_v(ip1jm-iim,l),1)
795
89856
         masseps=ssum(iim, masse(ip1jm+1,l,iq),1)
796
         qps=0.
797
2965248
         do ij = ip1jm+1,ip1jmp1-1
798
2965248
            qps=qps+masse(ij,l,iq)*q(ij,l,iq)
799
         enddo
800
89856
         qps=(qps+convps)/(masseps+convmps)
801
3057408
         do ij=ip1jm+1,ip1jmp1
802
3055104
            q(ij,l,iq)=qps
803
         enddo
804
805
c.-. fin ancienne version
806
807
c._. nouvelle version
808
c        convpn=SSUM(iim,qbyv(1,l),1)
809
c        convmpn=ssum(iim,masse_adv_v(1,l),1)
810
c        oldmasse=ssum(iim,masse(1,l),1)
811
c        newmasse=oldmasse+convmpn
812
c        newq=(q(1,l)*oldmasse+convpn)/newmasse
813
c        newmasse=newmasse/apoln
814
c        DO ij = 1,iip1
815
c           q(ij,l)=newq
816
c           masse(ij,l,iq)=newmasse*aire(ij)
817
c        ENDDO
818
c        convps=-SSUM(iim,qbyv(ip1jm-iim,l),1)
819
c        convmps=-ssum(iim,masse_adv_v(ip1jm-iim,l),1)
820
c        oldmasse=ssum(iim,masse(ip1jm-iim,l),1)
821
c        newmasse=oldmasse+convmps
822
c        newq=(q(ip1jmp1,l)*oldmasse+convps)/newmasse
823
c        newmasse=newmasse/apols
824
c        DO ij = ip1jm+1,ip1jmp1
825
c           q(ij,l)=newq
826
c           masse(ij,l,iq)=newmasse*aire(ij)
827
c        ENDDO
828
c._. fin nouvelle version
829
      ENDDO
830
831
! retablir les fils en rapport de melange par rapport a l'air:
832
2304
      do ifils=1,tracers(iq)%nqDescen
833
        iq2=tracers(iq)%iqDescen(ifils)
834
2304
        DO l=1,llm
835
          DO ij=1,ip1jmp1
836
            q(ij,l,iq2)=q(ij,l,iq)*Ratio(ij,l,iq2)
837
          enddo
838
        enddo
839
      enddo
840
841
      !write(*,*) 'vly 853: sortie'
842
843
2304
      RETURN
844
      END
845
1440
      RECURSIVE SUBROUTINE vlz(q,pente_max,masse,w,iq)
846
      USE infotrac, ONLY : nqtot,tracers, ! CRisi
847
     &                     min_qParent,min_qMass,min_ratio ! MVals et CRisi
848
c
849
c     Auteurs:   P.Le Van, F.Hourdin, F.Forget
850
c
851
c    ********************************************************************
852
c     Shema  d'advection " pseudo amont " .
853
c    ********************************************************************
854
c    q,pbaru,pbarv,w sont des arguments d'entree  pour le s-pg ....
855
c     dq 	       sont des arguments de sortie pour le s-pg ....
856
c
857
c
858
c   --------------------------------------------------------------------
859
      IMPLICIT NONE
860
c
861
      include "dimensions.h"
862
      include "paramet.h"
863
c
864
c
865
c   Arguments:
866
c   ----------
867
      REAL masse(ip1jmp1,llm,nqtot),pente_max
868
      REAL q(ip1jmp1,llm,nqtot)
869
      REAL w(ip1jmp1,llm+1)
870
      INTEGER iq
871
c
872
c      Local
873
c   ---------
874
c
875
      INTEGER ij,l
876
c
877
      REAL wq(ip1jmp1,llm+1),newmasse
878
879
      REAL dzq(ip1jmp1,llm),dzqw(ip1jmp1,llm),adzqw(ip1jmp1,llm),dzqmax
880
      REAL sigw
881
882
1440
      REAL masseq(ip1jmp1,llm,nqtot),Ratio(ip1jmp1,llm,nqtot) ! CRisi
883
      INTEGER ifils,iq2 ! CRisi
884
885
      LOGICAL testcpu
886
      SAVE testcpu
887
888
#ifdef BIDON
889
      REAL temps0,temps1,second
890
      SAVE temps0,temps1
891
892
      DATA testcpu/.false./
893
      DATA temps0,temps1/0.,0./
894
#endif
895
896
c    On oriente tout dans le sens de la pression c'est a dire dans le
897
c    sens de W
898
899
      !write(*,*) 'vlz 923: entree'
900
901
#ifdef BIDON
902
      IF(testcpu) THEN
903
         temps0=second(0.)
904
      ENDIF
905
#endif
906
56160
      DO l=2,llm
907
59646240
         DO ij=1,ip1jmp1
908
59590080
            dzqw(ij,l)=q(ij,l-1,iq)-q(ij,l,iq)
909
59644800
            adzqw(ij,l)=abs(dzqw(ij,l))
910
         ENDDO
911
      ENDDO
912
913
54720
      DO l=2,llm-1
914
58076640
         DO ij=1,ip1jmp1
915
#ifdef CRAY
916
            dzq(ij,l)=0.5*
917
     ,      cvmgp(dzqw(ij,l)+dzqw(ij,l+1),0.,dzqw(ij,l)*dzqw(ij,l+1))
918
#else
919
58021920
            IF(dzqw(ij,l)*dzqw(ij,l+1).gt.0.) THEN
920
32327398
                dzq(ij,l)=0.5*(dzqw(ij,l)+dzqw(ij,l+1))
921
            ELSE
922
25694522
                dzq(ij,l)=0.
923
            ENDIF
924
#endif
925
58021920
            dzqmax=pente_max*min(adzqw(ij,l),adzqw(ij,l+1))
926
58075200
            dzq(ij,l)=sign(min(abs(dzq(ij,l)),dzqmax),dzq(ij,l))
927
         ENDDO
928
      ENDDO
929
930
      !write(*,*) 'vlz 954'
931
1569600
      DO ij=1,ip1jmp1
932
1568160
         dzq(ij,1)=0.
933
1569600
         dzq(ij,llm)=0.
934
      ENDDO
935
936
#ifdef BIDON
937
      IF(testcpu) THEN
938
         temps1=temps1+second(0.)-temps0
939
      ENDIF
940
#endif
941
c ---------------------------------------------------------------
942
c   .... calcul des termes d'advection verticale  .......
943
c ---------------------------------------------------------------
944
945
c calcul de  - d( q   * w )/ d(sigma)    qu'on ajoute a  dq pour calculer dq
946
947
       !write(*,*) 'vlz 969'
948
56160
       DO l = 1,llm-1
949
59646240
         do  ij = 1,ip1jmp1
950
59644800
          IF(w(ij,l+1).gt.0.) THEN
951
30093945
             sigw=w(ij,l+1)/masse(ij,l+1,iq)
952
             wq(ij,l+1)=w(ij,l+1)*(q(ij,l+1,iq)
953
30093945
     &           +0.5*(1.-sigw)*dzq(ij,l+1))
954
          ELSE
955
29496135
             sigw=w(ij,l+1)/masse(ij,l,iq)
956
29496135
             wq(ij,l+1)=w(ij,l+1)*(q(ij,l,iq)-0.5*(1.+sigw)*dzq(ij,l))
957
          ENDIF
958
         ENDDO
959
       ENDDO
960
961
1569600
       DO ij=1,ip1jmp1
962
1568160
          wq(ij,llm+1)=0.
963
1569600
          wq(ij,1)=0.
964
       ENDDO
965
966
! CRisi: appel récursif de l'advection sur les fils.
967
! Il faut faire ça avant d'avoir mis à jour q et masse
968
      !write(*,*) 'vlsplt 942: iq,nqChildren(iq)=',iq,nqChildren(iq)
969
1440
      do ifils=1,tracers(iq)%nqDescen
970
        iq2=tracers(iq)%iqDescen(ifils)
971
1440
        DO l=1,llm
972
          DO ij=1,ip1jmp1
973
            !masseq(ij,l,iq2)=masse(ij,l,iq)*q(ij,l,iq)
974
            !Ratio(ij,l,iq2)=q(ij,l,iq2)/q(ij,l,iq)
975
            !MVals: veiller a ce qu'on n'ait pas de denominateur nul
976
            masseq(ij,l,iq2)=max(masse(ij,l,iq)*q(ij,l,iq),min_qMass)
977
            if (q(ij,l,iq).gt.min_qParent) then
978
              Ratio(ij,l,iq2)=q(ij,l,iq2)/q(ij,l,iq)
979
            else
980
              Ratio(ij,l,iq2)=min_ratio
981
            endif
982
          enddo
983
        enddo
984
      enddo
985
986
1440
      do ifils=1,tracers(iq)%nqChildren
987
        iq2=tracers(iq)%iqDescen(ifils)
988
1440
        call vlz(Ratio,pente_max,masseq,wq,iq2)
989
      enddo
990
! end CRisi
991
992
57600
      DO l=1,llm
993
61215840
         DO ij=1,ip1jmp1
994
61158240
            newmasse=masse(ij,l,iq)+w(ij,l+1)-w(ij,l)
995
            q(ij,l,iq)=(q(ij,l,iq)*masse(ij,l,iq)+wq(ij,l+1)-wq(ij,l))
996
61158240
     &         /newmasse
997
61214400
            masse(ij,l,iq)=newmasse
998
         ENDDO
999
      ENDDO
1000
1001
! retablir les fils en rapport de melange par rapport a l'air:
1002
1440
      do ifils=1,tracers(iq)%nqDescen
1003
        iq2=tracers(iq)%iqDescen(ifils)
1004
1440
        DO l=1,llm
1005
          DO ij=1,ip1jmp1
1006
            q(ij,l,iq2)=q(ij,l,iq)*Ratio(ij,l,iq2)
1007
          enddo
1008
        enddo
1009
      enddo
1010
      !write(*,*) 'vlsplt 1032'
1011
1012
1440
      RETURN
1013
      END
1014
c      SUBROUTINE minmaxq(zq,qmin,qmax,comment)
1015
c
1016
c#include "dimensions.h"
1017
c#include "paramet.h"
1018
1019
c      CHARACTER*(*) comment
1020
c      real qmin,qmax
1021
c      real zq(ip1jmp1,llm)
1022
1023
c      INTEGER jadrs(ip1jmp1), jbad, k, i
1024
1025
1026
c      DO k = 1, llm
1027
c         jbad = 0
1028
c         DO i = 1, ip1jmp1
1029
c         IF (zq(i,k).GT.qmax .OR. zq(i,k).LT.qmin) THEN
1030
c            jbad = jbad + 1
1031
c            jadrs(jbad) = i
1032
c         ENDIF
1033
c         ENDDO
1034
c         IF (jbad.GT.0) THEN
1035
c         PRINT*, comment
1036
c         DO i = 1, jbad
1037
cc            PRINT*, "i,k,zq=", jadrs(i),k,zq(jadrs(i),k)
1038
c         ENDDO
1039
c         ENDIF
1040
c      ENDDO
1041
1042
c      return
1043
c      end
1044
      subroutine minmaxq(zq,qmin,qmax,comment)
1045
1046
#include "dimensions.h"
1047
#include "paramet.h"
1048
1049
      character*20 comment
1050
      real qmin,qmax
1051
      real zq(ip1jmp1,llm)
1052
      real zzq(iip1,jjp1,llm)
1053
1054
#ifdef isminmax
1055
      integer imin,jmin,lmin,ijlmin
1056
      integer imax,jmax,lmax,ijlmax
1057
1058
      integer ismin,ismax
1059
1060
      call scopy (ip1jmp1*llm,zq,1,zzq,1)
1061
1062
      ijlmin=ismin(ijp1llm,zq,1)
1063
      lmin=(ijlmin-1)/ip1jmp1+1
1064
      ijlmin=ijlmin-(lmin-1.)*ip1jmp1
1065
      jmin=(ijlmin-1)/iip1+1
1066
      imin=ijlmin-(jmin-1.)*iip1
1067
      zqmin=zq(ijlmin,lmin)
1068
1069
      ijlmax=ismax(ijp1llm,zq,1)
1070
      lmax=(ijlmax-1)/ip1jmp1+1
1071
      ijlmax=ijlmax-(lmax-1.)*ip1jmp1
1072
      jmax=(ijlmax-1)/iip1+1
1073
      imax=ijlmax-(jmax-1.)*iip1
1074
      zqmax=zq(ijlmax,lmax)
1075
1076
       if(zqmin.lt.qmin)
1077
c     s     write(*,9999) comment,
1078
     s     write(*,*) comment,
1079
     s     imin,jmin,lmin,zqmin,zzq(imin,jmin,lmin)
1080
       if(zqmax.gt.qmax)
1081
c     s     write(*,9999) comment,
1082
     s     write(*,*) comment,
1083
     s     imax,jmax,lmax,zqmax,zzq(imax,jmax,lmax)
1084
1085
#endif
1086
      return
1087
c9999  format(a20,'  q(',i3,',',i2,',',i2,')=',e12.5,e12.5)
1088
      end
1089
1090
1091