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

Last change on this file since 5218 was 5182, checked in by abarral, 3 months ago

(WIP) Replace REPROBUS CPP KEY by logical
properly name modules

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