source: LMDZ6/branches/Amaury_dev/libf/dyn3d/vlspltqs.F90 @ 5134

Last change on this file since 5134 was 5134, checked in by abarral, 4 months ago

Replace academic.h, alpale.h, comdissip.h, comdissipn.h, comdissnew.h by modules
Remove unused clesph0.h

  • 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: 23.3 KB
Line 
1!
2! $Id: vlspltqs.F90 5134 2024-07-26 15:56:37Z abarral $
3!
4SUBROUTINE vlspltqs(q, pente_max, masse, w, pbaru, pbarv, pdt, &
5        p, pk, teta, iq)
6  USE infotrac, ONLY: nqtot, tracers
7  !
8  ! Auteurs:   P.Le Van, F.Hourdin, F.Forget, F.Codron
9  !
10  !    ********************************************************************
11  !      Shema  d'advection " pseudo amont " .
12  !  + test sur humidite specifique: Q advecte< Qsat aval
13  !               (F. Codron, 10/99)
14  !    ********************************************************************
15  ! q,pbaru,pbarv,w sont des arguments d'entree  pour le s-pg ....
16  !
17  ! pente_max facteur de limitation des pentes: 2 en general
18  !0 pour un schema amont
19  ! pbaru,pbarv,w flux de masse en u ,v ,w
20  ! pdt pas de temps
21  !
22  ! teta temperature potentielle, p pression aux interfaces,
23  ! pk exner au milieu des couches necessaire pour calculer Qsat
24  !   --------------------------------------------------------------------
25
26  USE comconst_mod, ONLY: cpp
27  USE logic_mod, ONLY: adv_qsat_liq
28  USE lmdz_ssum_scopy, ONLY: scopy
29  IMPLICIT NONE
30  !
31  INCLUDE "dimensions.h"
32  INCLUDE "paramet.h"
33
34  !
35  !   Arguments:
36  !   ----------
37  REAL :: masse(ip1jmp1, llm), pente_max
38  REAL :: pbaru(ip1jmp1, llm), pbarv(ip1jm, llm)
39  REAL :: q(ip1jmp1, llm, nqtot)
40  REAL :: w(ip1jmp1, llm), pdt
41  REAL :: p(ip1jmp1, llmp1), teta(ip1jmp1, llm), pk(ip1jmp1, llm)
42  INTEGER :: iq ! CRisi
43  !
44  !  Local
45  !   ---------
46  !
47  INTEGER :: i, ij, l, j, ii
48  INTEGER :: ifils, iq2 ! CRisi
49  !
50  REAL :: qsat(ip1jmp1, llm)
51  REAL :: zm(ip1jmp1, llm, nqtot)
52  REAL :: mu(ip1jmp1, llm)
53  REAL :: mv(ip1jm, llm)
54  REAL :: mw(ip1jmp1, llm + 1)
55  REAL :: zq(ip1jmp1, llm, nqtot)
56  REAL :: temps1, temps2, temps3
57  REAL :: zzpbar, zzw
58  SAVE temps1, temps2, temps3
59
60  REAL :: qmin, qmax
61  DATA qmin, qmax/0., 1.e33/
62  DATA temps1, temps2, temps3/0., 0., 0./
63
64  !--pour rapport de melange saturant--
65
66  REAL :: rtt, retv, r2es, r3les, r3ies, r4les, r4ies, play
67  REAL :: ptarg, pdelarg, foeew, zdelta
68  REAL :: tempe(ip1jmp1)
69
70  !    fonction psat(T)
71
72  FOEEW (PTARG, PDELARG) = EXP (&
73          (R3LES * (1. - PDELARG) + R3IES * PDELARG) * (PTARG - RTT) &
74                  / (PTARG - (R4LES * (1. - PDELARG) + R4IES * PDELARG)))
75
76  r2es = 380.11733
77  r3les = 17.269
78  r3ies = 21.875
79  r4les = 35.86
80  r4ies = 7.66
81  retv = 0.6077667
82  rtt = 273.16
83
84  !-- Calcul de Qsat en chaque point
85  !-- approximation: au milieu des couches play(l)=(p(l)+p(l+1))/2
86  !   pour eviter une exponentielle.
87  DO l = 1, llm
88    DO ij = 1, ip1jmp1
89      tempe(ij) = teta(ij, l) * pk(ij, l) / cpp
90    ENDDO
91    DO ij = 1, ip1jmp1
92      IF (adv_qsat_liq) THEN
93        zdelta = 0.
94      ELSE
95        zdelta = MAX(0., SIGN(1., rtt - tempe(ij)))
96      ENDIF
97      play = 0.5 * (p(ij, l) + p(ij, l + 1))
98      qsat(ij, l) = MIN(0.5, r2es * FOEEW(tempe(ij), zdelta) / play)
99      qsat(ij, l) = qsat(ij, l) / (1. - retv * qsat(ij, l))
100    ENDDO
101  ENDDO
102
103  ! PRINT*,'Debut vlsplt version debug sans vlyqs'
104
105  zzpbar = 0.5 * pdt
106  zzw = pdt
107  DO l = 1, llm
108    DO ij = iip2, ip1jm
109      mu(ij, l) = pbaru(ij, l) * zzpbar
110    ENDDO
111    DO ij = 1, ip1jm
112      mv(ij, l) = pbarv(ij, l) * zzpbar
113    ENDDO
114    DO ij = 1, ip1jmp1
115      mw(ij, l) = w(ij, l) * zzw
116    ENDDO
117  ENDDO
118
119  DO ij = 1, ip1jmp1
120    mw(ij, llm + 1) = 0.
121  ENDDO
122
123  CALL SCOPY(ijp1llm, q(1, 1, iq), 1, zq(1, 1, iq), 1)
124  CALL SCOPY(ijp1llm, masse, 1, zm(1, 1, iq), 1)
125  do ifils = 1, tracers(iq)%nqDescen
126    iq2 = tracers(iq)%iqDescen(ifils)
127    CALL SCOPY(ijp1llm, q(1, 1, iq2), 1, zq(1, 1, iq2), 1)
128  enddo
129
130  ! CALL minmaxq(zq,qmin,qmax,'avant vlxqs     ')
131  CALL vlxqs(zq, pente_max, zm, mu, qsat, iq)
132
133  ! CALL minmaxq(zq,qmin,qmax,'avant vlyqs     ')
134
135  CALL vlyqs(zq, pente_max, zm, mv, qsat, iq)
136
137  ! CALL minmaxq(zq,qmin,qmax,'avant vlz     ')
138
139  CALL vlz(zq, pente_max, zm, mw, iq)
140
141  ! CALL minmaxq(zq,qmin,qmax,'avant vlyqs     ')
142  ! CALL minmaxq(zm,qmin,qmax,'M avant vlyqs     ')
143
144  CALL vlyqs(zq, pente_max, zm, mv, qsat, iq)
145
146  ! CALL minmaxq(zq,qmin,qmax,'avant vlxqs     ')
147  ! CALL minmaxq(zm,qmin,qmax,'M avant vlxqs     ')
148
149  CALL vlxqs(zq, pente_max, zm, mu, qsat, iq)
150
151  ! CALL minmaxq(zq,qmin,qmax,'apres vlxqs     ')
152  ! CALL minmaxq(zm,qmin,qmax,'M apres vlxqs     ')
153
154  DO l = 1, llm
155    DO ij = 1, ip1jmp1
156      q(ij, l, iq) = zq(ij, l, iq)
157    ENDDO
158    DO ij = 1, ip1jm + 1, iip1
159      q(ij + iim, l, iq) = q(ij, l, iq)
160    ENDDO
161  ENDDO
162  ! CRisi: aussi pour les fils
163  do ifils = 1, tracers(iq)%nqDescen
164    iq2 = tracers(iq)%iqDescen(ifils)
165    DO l = 1, llm
166      DO ij = 1, ip1jmp1
167        q(ij, l, iq2) = zq(ij, l, iq2)
168      ENDDO
169      DO ij = 1, ip1jm + 1, iip1
170        q(ij + iim, l, iq2) = q(ij, l, iq2)
171      ENDDO
172    ENDDO
173  enddo
174  !WRITE(*,*) 'vlspltqs 183: fin de la routine'
175
176END SUBROUTINE vlspltqs
177SUBROUTINE vlxqs(q, pente_max, masse, u_m, qsat, iq)
178  USE infotrac, ONLY: nqtot, tracers ! CRisi
179
180  !
181  ! Auteurs:   P.Le Van, F.Hourdin, F.Forget
182  !
183  !    ********************************************************************
184  ! Shema  d'advection " pseudo amont " .
185  !    ********************************************************************
186  !
187  !   --------------------------------------------------------------------
188  IMPLICIT NONE
189  !
190  INCLUDE "dimensions.h"
191  INCLUDE "paramet.h"
192  !
193  !
194  !   Arguments:
195  !   ----------
196  REAL :: masse(ip1jmp1, llm, nqtot), pente_max
197  REAL :: u_m(ip1jmp1, llm)
198  REAL :: q(ip1jmp1, llm, nqtot)
199  REAL :: qsat(ip1jmp1, llm)
200  INTEGER :: iq ! CRisi
201  !
202  !  Local
203  !   ---------
204  !
205  INTEGER :: ij, l, j, i, iju, ijq, indu(ip1jmp1), niju
206  INTEGER :: n0, iadvplus(ip1jmp1, llm), nl(llm)
207  !
208  REAL :: new_m, zu_m, zdum(ip1jmp1, llm)
209  REAL :: dxq(ip1jmp1, llm), dxqu(ip1jmp1)
210  REAL :: zz(ip1jmp1)
211  REAL :: adxqu(ip1jmp1), dxqmax(ip1jmp1, llm)
212  REAL :: u_mq(ip1jmp1, llm)
213
214  ! CRisi
215  REAL :: masseq(ip1jmp1, llm, nqtot), Ratio(ip1jmp1, llm, nqtot)
216  INTEGER :: ifils, iq2 ! CRisi
217
218  Logical :: first
219  SAVE first
220
221  REAL :: temps0, temps1, temps2, temps3, temps4, temps5
222  SAVE temps0, temps1, temps2, temps3, temps4, temps5
223
224  DATA first/.TRUE./
225
226  IF(first) THEN
227    temps1 = 0.
228    temps2 = 0.
229    temps3 = 0.
230    temps4 = 0.
231    temps5 = 0.
232    first = .FALSE.
233  ENDIF
234
235  !   calcul de la pente a droite et a gauche de la maille
236
237  IF (pente_max>-1.e-5) THEN
238    ! IF (pente_max.gt.10) THEN
239
240    !   calcul des pentes avec limitation, Van Leer scheme I:
241    !   -----------------------------------------------------
242
243    !   calcul de la pente aux points u
244    DO l = 1, llm
245      DO ij = iip2, ip1jm - 1
246        dxqu(ij) = q(ij + 1, l, iq) - q(ij, l, iq)
247      ENDDO
248      DO ij = iip1 + iip1, ip1jm, iip1
249        dxqu(ij) = dxqu(ij - iim)
250        ! sigu(ij)=sigu(ij-iim)
251      ENDDO
252
253      DO ij = iip2, ip1jm
254        adxqu(ij) = abs(dxqu(ij))
255      ENDDO
256
257      !   calcul de la pente maximum dans la maille en valeur absolue
258
259      DO ij = iip2 + 1, ip1jm
260        dxqmax(ij, l) = pente_max * &
261                min(adxqu(ij - 1), adxqu(ij))
262        ! limitation subtile
263        !    ,      min(adxqu(ij-1)/sigu(ij-1),adxqu(ij)/(1.-sigu(ij)))
264
265      ENDDO
266
267      DO ij = iip1 + iip1, ip1jm, iip1
268        dxqmax(ij - iim, l) = dxqmax(ij, l)
269      ENDDO
270
271      DO ij = iip2 + 1, ip1jm
272        IF(dxqu(ij - 1) * dxqu(ij)>0) THEN
273          dxq(ij, l) = dxqu(ij - 1) + dxqu(ij)
274        ELSE
275          !   extremum local
276          dxq(ij, l) = 0.
277        ENDIF
278        dxq(ij, l) = 0.5 * dxq(ij, l)
279        dxq(ij, l) = &
280                sign(min(abs(dxq(ij, l)), dxqmax(ij, l)), dxq(ij, l))
281      ENDDO
282
283    ENDDO ! l=1,llm
284
285  ELSE ! (pente_max.lt.-1.e-5)
286
287    !   Pentes produits:
288    !   ----------------
289
290    DO l = 1, llm
291      DO ij = iip2, ip1jm - 1
292        dxqu(ij) = q(ij + 1, l, iq) - q(ij, l, iq)
293      ENDDO
294      DO ij = iip1 + iip1, ip1jm, iip1
295        dxqu(ij) = dxqu(ij - iim)
296      ENDDO
297
298      DO ij = iip2 + 1, ip1jm
299        zz(ij) = dxqu(ij - 1) * dxqu(ij)
300        zz(ij) = zz(ij) + zz(ij)
301        IF(zz(ij)>0) THEN
302          dxq(ij, l) = zz(ij) / (dxqu(ij - 1) + dxqu(ij))
303        ELSE
304          !   extremum local
305          dxq(ij, l) = 0.
306        ENDIF
307      ENDDO
308
309    ENDDO
310
311  ENDIF ! (pente_max.lt.-1.e-5)
312
313  !   bouclage de la pente en iip1:
314  !   -----------------------------
315
316  DO l = 1, llm
317    DO ij = iip1 + iip1, ip1jm, iip1
318      dxq(ij - iim, l) = dxq(ij, l)
319    ENDDO
320
321    DO ij = 1, ip1jmp1
322      iadvplus(ij, l) = 0
323    ENDDO
324
325  ENDDO
326
327
328  !   calcul des flux a gauche et a droite
329
330  !   on cumule le flux correspondant a toutes les mailles dont la masse
331  !   au travers de la paroi pENDant le pas de temps.
332  !   le rapport de melange de l'air advecte est min(q_vanleer, Qsat_downwind)
333  DO l = 1, llm
334    DO ij = iip2, ip1jm - 1
335      IF (u_m(ij, l)>0.) THEN
336        zdum(ij, l) = 1. - u_m(ij, l) / masse(ij, l, iq)
337        u_mq(ij, l) = u_m(ij, l) * &
338                min(q(ij, l, iq) + 0.5 * zdum(ij, l) * dxq(ij, l), qsat(ij + 1, l))
339      ELSE
340        zdum(ij, l) = 1. + u_m(ij, l) / masse(ij + 1, l, iq)
341        u_mq(ij, l) = u_m(ij, l) * &
342                min(q(ij + 1, l, iq) - 0.5 * zdum(ij, l) * dxq(ij + 1, l), qsat(ij, l))
343      ENDIF
344    ENDDO
345  ENDDO
346
347
348  !   detection des points ou on advecte plus que la masse de la
349  !   maille
350  DO l = 1, llm
351    DO ij = iip2, ip1jm - 1
352      IF(zdum(ij, l)<0) THEN
353        iadvplus(ij, l) = 1
354        u_mq(ij, l) = 0.
355      ENDIF
356    ENDDO
357  ENDDO
358  DO l = 1, llm
359    DO ij = iip1 + iip1, ip1jm, iip1
360      iadvplus(ij, l) = iadvplus(ij - iim, l)
361    ENDDO
362  ENDDO
363
364
365
366  !   traitement special pour le cas ou on advecte en longitude plus que le
367  !   contenu de la maille.
368  !   cette partie est mal vectorisee.
369
370  !   pas d'influence de la pression saturante (pour l'instant)
371
372  !  calcul du nombre de maille sur lequel on advecte plus que la maille.
373
374  n0 = 0
375  DO l = 1, llm
376    nl(l) = 0
377    DO ij = iip2, ip1jm
378      nl(l) = nl(l) + iadvplus(ij, l)
379    ENDDO
380    n0 = n0 + nl(l)
381  ENDDO
382
383  IF(n0>0) THEN
384    !cc      PRINT*,'Nombre de points pour lesquels on advect plus que le'
385    !cc     &       ,'contenu de la maille : ',n0
386
387    DO l = 1, llm
388      IF(nl(l)>0) THEN
389        iju = 0
390        !   indicage des mailles concernees par le traitement special
391        DO ij = iip2, ip1jm
392          IF(iadvplus(ij, l)==1.AND.mod(ij, iip1)/=0) THEN
393            iju = iju + 1
394            indu(iju) = ij
395          ENDIF
396        ENDDO
397        niju = iju
398        ! PRINT*,'niju,nl',niju,nl(l)
399
400        !  traitement des mailles
401        DO iju = 1, niju
402          ij = indu(iju)
403          j = (ij - 1) / iip1 + 1
404          zu_m = u_m(ij, l)
405          u_mq(ij, l) = 0.
406          IF(zu_m>0.) THEN
407            ijq = ij
408            i = ijq - (j - 1) * iip1
409            !   accumulation pour les mailles completements advectees
410            do while(zu_m>masse(ijq, l, iq))
411              u_mq(ij, l) = u_mq(ij, l) + q(ijq, l, iq) &
412                      * masse(ijq, l, iq)
413              zu_m = zu_m - masse(ijq, l, iq)
414              i = mod(i - 2 + iim, iim) + 1
415              ijq = (j - 1) * iip1 + i
416            ENDDO
417            !   ajout de la maille non completement advectee
418            u_mq(ij, l) = u_mq(ij, l) + zu_m * &
419                    (q(ijq, l, iq) + 0.5 * (1. - zu_m / masse(ijq, l, iq)) &
420                            * dxq(ijq, l))
421          ELSE
422            ijq = ij + 1
423            i = ijq - (j - 1) * iip1
424            !   accumulation pour les mailles completements advectees
425            do while(-zu_m>masse(ijq, l, iq))
426              u_mq(ij, l) = u_mq(ij, l) - q(ijq, l, iq) &
427                      * masse(ijq, l, iq)
428              zu_m = zu_m + masse(ijq, l, iq)
429              i = mod(i, iim) + 1
430              ijq = (j - 1) * iip1 + i
431            ENDDO
432            !   ajout de la maille non completement advectee
433            u_mq(ij, l) = u_mq(ij, l) + zu_m * (q(ijq, l, iq) - &
434                    0.5 * (1. + zu_m / masse(ijq, l, iq)) * dxq(ijq, l))
435          ENDIF
436        ENDDO
437      ENDIF
438    ENDDO
439  ENDIF  ! n0.gt.0
440
441
442
443  !   bouclage en latitude
444
445  DO l = 1, llm
446    DO ij = iip1 + iip1, ip1jm, iip1
447      u_mq(ij, l) = u_mq(ij - iim, l)
448    ENDDO
449  ENDDO
450
451  ! CRisi: appel récursif de l'advection sur les fils.
452  ! Il faut faire ça avant d'avoir mis à jour q et masse
453  !WRITE(*,*) 'vlspltqs 326: iq,nqChildren(iq)=',iq,
454  ! &                 tracers(iq)%nqChildren
455
456  do ifils = 1, tracers(iq)%nqDescen
457    iq2 = tracers(iq)%iqDescen(ifils)
458    DO l = 1, llm
459      DO ij = iip2, ip1jm
460        ! On a besoin de q et masse seulement entre iip2 et ip1jm
461        masseq(ij, l, iq2) = masse(ij, l, iq) * q(ij, l, iq)
462        Ratio(ij, l, iq2) = q(ij, l, iq2) / q(ij, l, iq)
463      enddo
464    enddo
465  enddo
466  do ifils = 1, tracers(iq)%nqChildren
467    iq2 = tracers(iq)%iqDescen(ifils)
468    CALL vlx(Ratio, pente_max, masseq, u_mq, iq2)
469  enddo
470  ! end CRisi
471
472  !   calcul des tendances
473
474  DO l = 1, llm
475    DO ij = iip2 + 1, ip1jm
476      new_m = masse(ij, l, iq) + u_m(ij - 1, l) - u_m(ij, l)
477      q(ij, l, iq) = (q(ij, l, iq) * masse(ij, l, iq) + &
478              u_mq(ij - 1, l) - u_mq(ij, l)) &
479              / new_m
480      masse(ij, l, iq) = new_m
481    ENDDO
482    !   Modif Fred 22 03 96 correction d'un bug (les scopy ci-dessous)
483    DO ij = iip1 + iip1, ip1jm, iip1
484      q(ij - iim, l, iq) = q(ij, l, iq)
485      masse(ij - iim, l, iq) = masse(ij, l, iq)
486    ENDDO
487  ENDDO
488
489  ! retablir les fils en rapport de melange par rapport a l'air:
490  ! On calcule q entre iip2+1,ip1jm -> on fait pareil pour ratio
491  ! puis on boucle en longitude
492  do ifils = 1, tracers(iq)%nqDescen
493    iq2 = tracers(iq)%iqDescen(ifils)
494    DO l = 1, llm
495      DO ij = iip2 + 1, ip1jm
496        q(ij, l, iq2) = q(ij, l, iq) * Ratio(ij, l, iq2)
497      enddo
498      DO ij = iip1 + iip1, ip1jm, iip1
499        q(ij - iim, l, iq2) = q(ij, l, iq2)
500      enddo
501    enddo
502  enddo
503
504  ! CALL SCOPY((jjm-1)*llm,q(iip1+iip1,1),iip1,q(iip2,1),iip1)
505  ! CALL SCOPY((jjm-1)*llm,masse(iip1+iip1,1),iip1,masse(iip2,1),iip1)
506
507END SUBROUTINE vlxqs
508SUBROUTINE vlyqs(q, pente_max, masse, masse_adv_v, qsat, iq)
509  USE infotrac, ONLY: nqtot, tracers ! CRisi
510  !
511  ! Auteurs:   P.Le Van, F.Hourdin, F.Forget
512  !
513  !    ********************************************************************
514  ! Shema  d'advection " pseudo amont " .
515  !    ********************************************************************
516  ! q,masse_adv_v,w sont des arguments d'entree  pour le s-pg ....
517  !     qsat           est   un argument de sortie pour le s-pg ....
518  !
519  !
520  !   --------------------------------------------------------------------
521
522  USE comconst_mod, ONLY: pi
523  USE lmdz_ssum_scopy, ONLY: ssum
524
525  IMPLICIT NONE
526  !
527  INCLUDE "dimensions.h"
528  INCLUDE "paramet.h"
529  INCLUDE "comgeom.h"
530  !
531  !
532  !   Arguments:
533  !   ----------
534  REAL :: masse(ip1jmp1, llm, nqtot), pente_max
535  REAL :: masse_adv_v(ip1jm, llm)
536  REAL :: q(ip1jmp1, llm, nqtot)
537  REAL :: qsat(ip1jmp1, llm)
538  INTEGER :: iq ! CRisi
539  !
540  !  Local
541  !   ---------
542  !
543  INTEGER :: i, ij, l
544  !
545  REAL :: airej2, airejjm, airescb(iim), airesch(iim)
546  REAL :: dyq(ip1jmp1, llm), dyqv(ip1jm)
547  REAL :: adyqv(ip1jm), dyqmax(ip1jmp1)
548  REAL :: qbyv(ip1jm, llm)
549
550  REAL :: qpns, qpsn, dyn1, dys1, dyn2, dys2, newmasse, fn, fs
551  ! REAL newq,oldmasse
552  Logical :: first
553  REAL :: temps0, temps1, temps2, temps3, temps4, temps5
554  SAVE temps0, temps1, temps2, temps3, temps4, temps5
555  SAVE first
556
557  REAL :: convpn, convps, convmpn, convmps
558  REAL :: sinlon(iip1), sinlondlon(iip1)
559  REAL :: coslon(iip1), coslondlon(iip1)
560  SAVE sinlon, coslon, sinlondlon, coslondlon
561  SAVE airej2, airejjm
562
563  REAL :: masseq(ip1jmp1, llm, nqtot), Ratio(ip1jmp1, llm, nqtot) ! CRisi
564  INTEGER :: ifils, iq2 ! CRisi
565
566  DATA first/.TRUE./
567  DATA temps0, temps1, temps2, temps3, temps4, temps5/0., 0., 0., 0., 0., 0./
568
569  IF(first) THEN
570    PRINT*, 'Shema  Amont nouveau  appele dans  Vanleer   '
571    first = .FALSE.
572    do i = 2, iip1
573      coslon(i) = cos(rlonv(i))
574      sinlon(i) = sin(rlonv(i))
575      coslondlon(i) = coslon(i) * (rlonu(i) - rlonu(i - 1)) / pi
576      sinlondlon(i) = sinlon(i) * (rlonu(i) - rlonu(i - 1)) / pi
577    ENDDO
578    coslon(1) = coslon(iip1)
579    coslondlon(1) = coslondlon(iip1)
580    sinlon(1) = sinlon(iip1)
581    sinlondlon(1) = sinlondlon(iip1)
582    airej2 = SSUM(iim, aire(iip2), 1)
583    airejjm = SSUM(iim, aire(ip1jm - iim), 1)
584  ENDIF
585
586  !
587
588  DO l = 1, llm
589    !
590    !   --------------------------------
591    !  CALCUL EN LATITUDE
592    !   --------------------------------
593
594    !   On commence par calculer la valeur du traceur moyenne sur le premier cercle
595    !   de latitude autour du pole (qpns pour le pole nord et qpsn pour
596    !    le pole nord) qui sera utilisee pour evaluer les pentes au pole.
597
598    DO i = 1, iim
599      airescb(i) = aire(i + iip1) * q(i + iip1, l, iq)
600      airesch(i) = aire(i + ip1jm - iip1) * q(i + ip1jm - iip1, l, iq)
601    ENDDO
602    qpns = SSUM(iim, airescb, 1) / airej2
603    qpsn = SSUM(iim, airesch, 1) / airejjm
604
605    !   calcul des pentes aux points v
606
607    DO ij = 1, ip1jm
608      dyqv(ij) = q(ij, l, iq) - q(ij + iip1, l, iq)
609      adyqv(ij) = abs(dyqv(ij))
610    ENDDO
611
612    !   calcul des pentes aux points scalaires
613
614    DO ij = iip2, ip1jm
615      dyq(ij, l) = .5 * (dyqv(ij - iip1) + dyqv(ij))
616      dyqmax(ij) = min(adyqv(ij - iip1), adyqv(ij))
617      dyqmax(ij) = pente_max * dyqmax(ij)
618    ENDDO
619
620    !   calcul des pentes aux poles
621
622    DO ij = 1, iip1
623      dyq(ij, l) = qpns - q(ij + iip1, l, iq)
624      dyq(ip1jm + ij, l) = q(ip1jm + ij - iip1, l, iq) - qpsn
625    ENDDO
626
627    !   filtrage de la derivee
628    dyn1 = 0.
629    dys1 = 0.
630    dyn2 = 0.
631    dys2 = 0.
632    DO ij = 1, iim
633      dyn1 = dyn1 + sinlondlon(ij) * dyq(ij, l)
634      dys1 = dys1 + sinlondlon(ij) * dyq(ip1jm + ij, l)
635      dyn2 = dyn2 + coslondlon(ij) * dyq(ij, l)
636      dys2 = dys2 + coslondlon(ij) * dyq(ip1jm + ij, l)
637    ENDDO
638    DO ij = 1, iip1
639      dyq(ij, l) = dyn1 * sinlon(ij) + dyn2 * coslon(ij)
640      dyq(ip1jm + ij, l) = dys1 * sinlon(ij) + dys2 * coslon(ij)
641    ENDDO
642
643    !   calcul des pentes limites aux poles
644
645    fn = 1.
646    fs = 1.
647    DO ij = 1, iim
648      IF(pente_max * adyqv(ij)<abs(dyq(ij, l))) THEN
649        fn = min(pente_max * adyqv(ij) / abs(dyq(ij, l)), fn)
650      ENDIF
651      IF(pente_max * adyqv(ij + ip1jm - iip1)<abs(dyq(ij + ip1jm, l))) THEN
652        fs = min(pente_max * adyqv(ij + ip1jm - iip1) / abs(dyq(ij + ip1jm, l)), fs)
653      ENDIF
654    ENDDO
655    DO ij = 1, iip1
656      dyq(ij, l) = fn * dyq(ij, l)
657      dyq(ip1jm + ij, l) = fs * dyq(ip1jm + ij, l)
658    ENDDO
659
660    !CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
661    !  En memoire de dIFferents tests sur la
662    !  limitation des pentes aux poles.
663    !CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
664    ! PRINT*,dyq(1)
665    ! PRINT*,dyqv(iip1+1)
666    ! appn=abs(dyq(1)/dyqv(iip1+1))
667    ! PRINT*,dyq(ip1jm+1)
668    ! PRINT*,dyqv(ip1jm-iip1+1)
669    ! apps=abs(dyq(ip1jm+1)/dyqv(ip1jm-iip1+1))
670    ! DO ij=2,iim
671    !    appn=amax1(abs(dyq(ij)/dyqv(ij)),appn)
672    !    apps=amax1(abs(dyq(ip1jm+ij)/dyqv(ip1jm-iip1+ij)),apps)
673    ! ENDDO
674    ! appn=min(pente_max/appn,1.)
675    ! apps=min(pente_max/apps,1.)
676    !
677    !
678    !   cas ou on a un extremum au pole
679    !
680    ! IF(dyqv(ismin(iim,dyqv,1))*dyqv(ismax(iim,dyqv,1)).le.0.)
681    !    &   appn=0.
682    ! IF(dyqv(ismax(iim,dyqv(ip1jm-iip1+1),1)+ip1jm-iip1+1)*
683    !    &   dyqv(ismin(iim,dyqv(ip1jm-iip1+1),1)+ip1jm-iip1+1).le.0.)
684    !    &   apps=0.
685    !
686    !   limitation des pentes aux poles
687    ! DO ij=1,iip1
688    !    dyq(ij)=appn*dyq(ij)
689    !    dyq(ip1jm+ij)=apps*dyq(ip1jm+ij)
690    ! ENDDO
691    !
692    !   test
693    !  DO ij=1,iip1
694    !     dyq(iip1+ij)=0.
695    !     dyq(ip1jm+ij-iip1)=0.
696    !  ENDDO
697    !  DO ij=1,ip1jmp1
698    !     dyq(ij)=dyq(ij)*cos(rlatu((ij-1)/iip1+1))
699    !  ENDDO
700    !
701    ! changement 10 07 96
702    ! IF(dyqv(ismin(iim,dyqv,1))*dyqv(ismax(iim,dyqv,1)).le.0.)
703    !    &   THEN
704    !    DO ij=1,iip1
705    !       dyqmax(ij)=0.
706    !    ENDDO
707    ! ELSE
708    !    DO ij=1,iip1
709    !       dyqmax(ij)=pente_max*abs(dyqv(ij))
710    !    ENDDO
711    ! ENDIF
712    !
713    ! IF(dyqv(ismax(iim,dyqv(ip1jm-iip1+1),1)+ip1jm-iip1+1)*
714    !    & dyqv(ismin(iim,dyqv(ip1jm-iip1+1),1)+ip1jm-iip1+1).le.0.)
715    !    &THEN
716    !    DO ij=ip1jm+1,ip1jmp1
717    !       dyqmax(ij)=0.
718    !    ENDDO
719    ! ELSE
720    !    DO ij=ip1jm+1,ip1jmp1
721    !       dyqmax(ij)=pente_max*abs(dyqv(ij-iip1))
722    !    ENDDO
723    ! ENDIF
724    !   fin changement 10 07 96
725    !CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
726
727    !   calcul des pentes limitees
728
729    DO ij = iip2, ip1jm
730      IF(dyqv(ij) * dyqv(ij - iip1)>0.) THEN
731        dyq(ij, l) = sign(min(abs(dyq(ij, l)), dyqmax(ij)), dyq(ij, l))
732      ELSE
733        dyq(ij, l) = 0.
734      ENDIF
735    ENDDO
736
737  ENDDO
738
739  DO l = 1, llm
740    DO ij = 1, ip1jm
741      IF(masse_adv_v(ij, l)>0.) THEN
742        qbyv(ij, l) = MIN(qsat(ij + iip1, l), q(ij + iip1, l, iq) + &
743                dyq(ij + iip1, l) * 0.5 * (1. - masse_adv_v(ij, l) &
744                        / masse(ij + iip1, l, iq)))
745      ELSE
746        qbyv(ij, l) = MIN(qsat(ij, l), q(ij, l, iq) - dyq(ij, l) * &
747                0.5 * (1. + masse_adv_v(ij, l) / masse(ij, l, iq)))
748      ENDIF
749      qbyv(ij, l) = masse_adv_v(ij, l) * qbyv(ij, l)
750    ENDDO
751  ENDDO
752
753
754  ! CRisi: appel récursif de l'advection sur les fils.
755  ! Il faut faire ça avant d'avoir mis à jour q et masse
756  !WRITE(*,*) 'vlyqs 689: iq,nqChildren(iq)=',iq,
757  ! &              tracers(iq)%nqChildren
758
759  do ifils = 1, tracers(iq)%nqDescen
760    iq2 = tracers(iq)%iqDescen(ifils)
761    DO l = 1, llm
762      DO ij = 1, ip1jmp1
763        masseq(ij, l, iq2) = masse(ij, l, iq) * q(ij, l, iq)
764        Ratio(ij, l, iq2) = q(ij, l, iq2) / q(ij, l, iq)
765      enddo
766    enddo
767  enddo
768  do ifils = 1, tracers(iq)%nqChildren
769    iq2 = tracers(iq)%iqDescen(ifils)
770    ! !WRITE(*,*) 'vlyqs 783: appel rec de vly, iq2=',iq2
771    CALL vly(Ratio, pente_max, masseq, qbyv, iq2)
772  enddo
773
774  DO l = 1, llm
775    DO ij = iip2, ip1jm
776      newmasse = masse(ij, l, iq) &
777              + masse_adv_v(ij, l) - masse_adv_v(ij - iip1, l)
778      q(ij, l, iq) = (q(ij, l, iq) * masse(ij, l, iq) + qbyv(ij, l) &
779              - qbyv(ij - iip1, l)) / newmasse
780      masse(ij, l, iq) = newmasse
781    ENDDO
782    !.-. ancienne version
783    convpn = SSUM(iim, qbyv(1, l), 1) / apoln
784    convmpn = ssum(iim, masse_adv_v(1, l), 1) / apoln
785    DO ij = 1, iip1
786      newmasse = masse(ij, l, iq) + convmpn * aire(ij)
787      q(ij, l, iq) = (q(ij, l, iq) * masse(ij, l, iq) + convpn * aire(ij)) / &
788              newmasse
789      masse(ij, l, iq) = newmasse
790    ENDDO
791    convps = -SSUM(iim, qbyv(ip1jm - iim, l), 1) / apols
792    convmps = -SSUM(iim, masse_adv_v(ip1jm - iim, l), 1) / apols
793    DO ij = ip1jm + 1, ip1jmp1
794      newmasse = masse(ij, l, iq) + convmps * aire(ij)
795      q(ij, l, iq) = (q(ij, l, iq) * masse(ij, l, iq) + convps * aire(ij)) / &
796              newmasse
797      masse(ij, l, iq) = newmasse
798    ENDDO
799    !.-. fin ancienne version
800
801    !._. nouvelle version
802    ! convpn=SSUM(iim,qbyv(1,l),1)
803    ! convmpn=ssum(iim,masse_adv_v(1,l),1)
804    ! oldmasse=ssum(iim,masse(1,l),1)
805    ! newmasse=oldmasse+convmpn
806    ! newq=(q(1,l)*oldmasse+convpn)/newmasse
807    ! newmasse=newmasse/apoln
808    ! DO ij = 1,iip1
809    !    q(ij,l)=newq
810    !    masse(ij,l,iq)=newmasse*aire(ij)
811    ! ENDDO
812    ! convps=-SSUM(iim,qbyv(ip1jm-iim,l),1)
813    ! convmps=-ssum(iim,masse_adv_v(ip1jm-iim,l),1)
814    ! oldmasse=ssum(iim,masse(ip1jm-iim,l),1)
815    ! newmasse=oldmasse+convmps
816    ! newq=(q(ip1jmp1,l)*oldmasse+convps)/newmasse
817    ! newmasse=newmasse/apols
818    ! DO ij = ip1jm+1,ip1jmp1
819    !    q(ij,l)=newq
820    !    masse(ij,l,iq)=newmasse*aire(ij)
821    ! ENDDO
822    !._. fin nouvelle version
823  ENDDO
824
825  ! !WRITE(*,*) 'vly 866'
826
827  ! retablir les fils en rapport de melange par rapport a l'air:
828  do ifils = 1, tracers(iq)%nqDescen
829    iq2 = tracers(iq)%iqDescen(ifils)
830    DO l = 1, llm
831      DO ij = 1, ip1jmp1
832        q(ij, l, iq2) = q(ij, l, iq) * Ratio(ij, l, iq2)
833      enddo
834    enddo
835  enddo
836  ! !WRITE(*,*) 'vly 879'
837
838END SUBROUTINE vlyqs
Note: See TracBrowser for help on using the repository browser.