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

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

Add missing klon on strataer_emiss_mod.F90
Correct various missing explicit declarations
Replace tabs by spaces (tabs are not part of the fortran charset)
Continue cleaning modules
Removed unused arguments and variables

  • 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 5158 2024-08-02 12:12:03Z 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  USE lmdz_comgeom
525
526  IMPLICIT NONE
527  !
528  INCLUDE "dimensions.h"
529  INCLUDE "paramet.h"
530  !
531  !   Arguments:
532  !   ----------
533  REAL :: masse(ip1jmp1, llm, nqtot), pente_max
534  REAL :: masse_adv_v(ip1jm, llm)
535  REAL :: q(ip1jmp1, llm, nqtot)
536  REAL :: qsat(ip1jmp1, llm)
537  INTEGER :: iq ! CRisi
538  !
539  !  Local
540  !   ---------
541  !
542  INTEGER :: i, ij, l
543  !
544  REAL :: airej2, airejjm, airescb(iim), airesch(iim)
545  REAL :: dyq(ip1jmp1, llm), dyqv(ip1jm)
546  REAL :: adyqv(ip1jm), dyqmax(ip1jmp1)
547  REAL :: qbyv(ip1jm, llm)
548
549  REAL :: qpns, qpsn, dyn1, dys1, dyn2, dys2, newmasse, fn, fs
550  ! REAL newq,oldmasse
551  Logical :: first
552  REAL :: temps0, temps1, temps2, temps3, temps4, temps5
553  SAVE temps0, temps1, temps2, temps3, temps4, temps5
554  SAVE first
555
556  REAL :: convpn, convps, convmpn, convmps
557  REAL :: sinlon(iip1), sinlondlon(iip1)
558  REAL :: coslon(iip1), coslondlon(iip1)
559  SAVE sinlon, coslon, sinlondlon, coslondlon
560  SAVE airej2, airejjm
561
562  REAL :: masseq(ip1jmp1, llm, nqtot), Ratio(ip1jmp1, llm, nqtot) ! CRisi
563  INTEGER :: ifils, iq2 ! CRisi
564
565  DATA first/.TRUE./
566  DATA temps0, temps1, temps2, temps3, temps4, temps5/0., 0., 0., 0., 0., 0./
567
568  IF(first) THEN
569    PRINT*, 'Shema  Amont nouveau  appele dans  Vanleer   '
570    first = .FALSE.
571    DO i = 2, iip1
572      coslon(i) = cos(rlonv(i))
573      sinlon(i) = sin(rlonv(i))
574      coslondlon(i) = coslon(i) * (rlonu(i) - rlonu(i - 1)) / pi
575      sinlondlon(i) = sinlon(i) * (rlonu(i) - rlonu(i - 1)) / pi
576    ENDDO
577    coslon(1) = coslon(iip1)
578    coslondlon(1) = coslondlon(iip1)
579    sinlon(1) = sinlon(iip1)
580    sinlondlon(1) = sinlondlon(iip1)
581    airej2 = SSUM(iim, aire(iip2), 1)
582    airejjm = SSUM(iim, aire(ip1jm - iim), 1)
583  ENDIF
584
585  !
586
587  DO l = 1, llm
588    !
589    !   --------------------------------
590    !  CALCUL EN LATITUDE
591    !   --------------------------------
592
593    !   On commence par calculer la valeur du traceur moyenne sur le premier cercle
594    !   de latitude autour du pole (qpns pour le pole nord et qpsn pour
595    !    le pole nord) qui sera utilisee pour evaluer les pentes au pole.
596
597    DO i = 1, iim
598      airescb(i) = aire(i + iip1) * q(i + iip1, l, iq)
599      airesch(i) = aire(i + ip1jm - iip1) * q(i + ip1jm - iip1, l, iq)
600    ENDDO
601    qpns = SSUM(iim, airescb, 1) / airej2
602    qpsn = SSUM(iim, airesch, 1) / airejjm
603
604    !   calcul des pentes aux points v
605
606    DO ij = 1, ip1jm
607      dyqv(ij) = q(ij, l, iq) - q(ij + iip1, l, iq)
608      adyqv(ij) = abs(dyqv(ij))
609    ENDDO
610
611    !   calcul des pentes aux points scalaires
612
613    DO ij = iip2, ip1jm
614      dyq(ij, l) = .5 * (dyqv(ij - iip1) + dyqv(ij))
615      dyqmax(ij) = min(adyqv(ij - iip1), adyqv(ij))
616      dyqmax(ij) = pente_max * dyqmax(ij)
617    ENDDO
618
619    !   calcul des pentes aux poles
620
621    DO ij = 1, iip1
622      dyq(ij, l) = qpns - q(ij + iip1, l, iq)
623      dyq(ip1jm + ij, l) = q(ip1jm + ij - iip1, l, iq) - qpsn
624    ENDDO
625
626    !   filtrage de la derivee
627    dyn1 = 0.
628    dys1 = 0.
629    dyn2 = 0.
630    dys2 = 0.
631    DO ij = 1, iim
632      dyn1 = dyn1 + sinlondlon(ij) * dyq(ij, l)
633      dys1 = dys1 + sinlondlon(ij) * dyq(ip1jm + ij, l)
634      dyn2 = dyn2 + coslondlon(ij) * dyq(ij, l)
635      dys2 = dys2 + coslondlon(ij) * dyq(ip1jm + ij, l)
636    ENDDO
637    DO ij = 1, iip1
638      dyq(ij, l) = dyn1 * sinlon(ij) + dyn2 * coslon(ij)
639      dyq(ip1jm + ij, l) = dys1 * sinlon(ij) + dys2 * coslon(ij)
640    ENDDO
641
642    !   calcul des pentes limites aux poles
643
644    fn = 1.
645    fs = 1.
646    DO ij = 1, iim
647      IF(pente_max * adyqv(ij)<abs(dyq(ij, l))) THEN
648        fn = min(pente_max * adyqv(ij) / abs(dyq(ij, l)), fn)
649      ENDIF
650      IF(pente_max * adyqv(ij + ip1jm - iip1)<abs(dyq(ij + ip1jm, l))) THEN
651        fs = min(pente_max * adyqv(ij + ip1jm - iip1) / abs(dyq(ij + ip1jm, l)), fs)
652      ENDIF
653    ENDDO
654    DO ij = 1, iip1
655      dyq(ij, l) = fn * dyq(ij, l)
656      dyq(ip1jm + ij, l) = fs * dyq(ip1jm + ij, l)
657    ENDDO
658
659    !CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
660    !  En memoire de dIFferents tests sur la
661    !  limitation des pentes aux poles.
662    !CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
663    ! PRINT*,dyq(1)
664    ! PRINT*,dyqv(iip1+1)
665    ! appn=abs(dyq(1)/dyqv(iip1+1))
666    ! PRINT*,dyq(ip1jm+1)
667    ! PRINT*,dyqv(ip1jm-iip1+1)
668    ! apps=abs(dyq(ip1jm+1)/dyqv(ip1jm-iip1+1))
669    ! DO ij=2,iim
670    !    appn=amax1(abs(dyq(ij)/dyqv(ij)),appn)
671    !    apps=amax1(abs(dyq(ip1jm+ij)/dyqv(ip1jm-iip1+ij)),apps)
672    ! ENDDO
673    ! appn=min(pente_max/appn,1.)
674    ! apps=min(pente_max/apps,1.)
675    !
676    !
677    !   cas ou on a un extremum au pole
678    !
679    ! IF(dyqv(ismin(iim,dyqv,1))*dyqv(ismax(iim,dyqv,1)).le.0.)
680    !    &   appn=0.
681    ! IF(dyqv(ismax(iim,dyqv(ip1jm-iip1+1),1)+ip1jm-iip1+1)*
682    !    &   dyqv(ismin(iim,dyqv(ip1jm-iip1+1),1)+ip1jm-iip1+1).le.0.)
683    !    &   apps=0.
684    !
685    !   limitation des pentes aux poles
686    ! DO ij=1,iip1
687    !    dyq(ij)=appn*dyq(ij)
688    !    dyq(ip1jm+ij)=apps*dyq(ip1jm+ij)
689    ! ENDDO
690    !
691    !   test
692    !  DO ij=1,iip1
693    !     dyq(iip1+ij)=0.
694    !     dyq(ip1jm+ij-iip1)=0.
695    !  ENDDO
696    !  DO ij=1,ip1jmp1
697    !     dyq(ij)=dyq(ij)*cos(rlatu((ij-1)/iip1+1))
698    !  ENDDO
699    !
700    ! changement 10 07 96
701    ! IF(dyqv(ismin(iim,dyqv,1))*dyqv(ismax(iim,dyqv,1)).le.0.)
702    !    &   THEN
703    !    DO ij=1,iip1
704    !       dyqmax(ij)=0.
705    !    ENDDO
706    ! ELSE
707    !    DO ij=1,iip1
708    !       dyqmax(ij)=pente_max*abs(dyqv(ij))
709    !    ENDDO
710    ! ENDIF
711    !
712    ! IF(dyqv(ismax(iim,dyqv(ip1jm-iip1+1),1)+ip1jm-iip1+1)*
713    !    & dyqv(ismin(iim,dyqv(ip1jm-iip1+1),1)+ip1jm-iip1+1).le.0.)
714    !    &THEN
715    !    DO ij=ip1jm+1,ip1jmp1
716    !       dyqmax(ij)=0.
717    !    ENDDO
718    ! ELSE
719    !    DO ij=ip1jm+1,ip1jmp1
720    !       dyqmax(ij)=pente_max*abs(dyqv(ij-iip1))
721    !    ENDDO
722    ! ENDIF
723    !   fin changement 10 07 96
724    !CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
725
726    !   calcul des pentes limitees
727
728    DO ij = iip2, ip1jm
729      IF(dyqv(ij) * dyqv(ij - iip1)>0.) THEN
730        dyq(ij, l) = sign(min(abs(dyq(ij, l)), dyqmax(ij)), dyq(ij, l))
731      ELSE
732        dyq(ij, l) = 0.
733      ENDIF
734    ENDDO
735
736  ENDDO
737
738  DO l = 1, llm
739    DO ij = 1, ip1jm
740      IF(masse_adv_v(ij, l)>0.) THEN
741        qbyv(ij, l) = MIN(qsat(ij + iip1, l), q(ij + iip1, l, iq) + &
742                dyq(ij + iip1, l) * 0.5 * (1. - masse_adv_v(ij, l) &
743                        / masse(ij + iip1, l, iq)))
744      ELSE
745        qbyv(ij, l) = MIN(qsat(ij, l), q(ij, l, iq) - dyq(ij, l) * &
746                0.5 * (1. + masse_adv_v(ij, l) / masse(ij, l, iq)))
747      ENDIF
748      qbyv(ij, l) = masse_adv_v(ij, l) * qbyv(ij, l)
749    ENDDO
750  ENDDO
751
752
753  ! CRisi: appel récursif de l'advection sur les fils.
754  ! Il faut faire ça avant d'avoir mis à jour q et masse
755  !WRITE(*,*) 'vlyqs 689: iq,nqChildren(iq)=',iq,
756  ! &              tracers(iq)%nqChildren
757
758  DO ifils = 1, tracers(iq)%nqDescen
759    iq2 = tracers(iq)%iqDescen(ifils)
760    DO l = 1, llm
761      DO ij = 1, ip1jmp1
762        masseq(ij, l, iq2) = masse(ij, l, iq) * q(ij, l, iq)
763        Ratio(ij, l, iq2) = q(ij, l, iq2) / q(ij, l, iq)
764      enddo
765    enddo
766  enddo
767  DO ifils = 1, tracers(iq)%nqChildren
768    iq2 = tracers(iq)%iqDescen(ifils)
769    ! !WRITE(*,*) 'vlyqs 783: appel rec de vly, iq2=',iq2
770    CALL vly(Ratio, pente_max, masseq, qbyv, iq2)
771  enddo
772
773  DO l = 1, llm
774    DO ij = iip2, ip1jm
775      newmasse = masse(ij, l, iq) &
776              + masse_adv_v(ij, l) - masse_adv_v(ij - iip1, l)
777      q(ij, l, iq) = (q(ij, l, iq) * masse(ij, l, iq) + qbyv(ij, l) &
778              - qbyv(ij - iip1, l)) / newmasse
779      masse(ij, l, iq) = newmasse
780    ENDDO
781    !.-. ancienne version
782    convpn = SSUM(iim, qbyv(1, l), 1) / apoln
783    convmpn = ssum(iim, masse_adv_v(1, l), 1) / apoln
784    DO ij = 1, iip1
785      newmasse = masse(ij, l, iq) + convmpn * aire(ij)
786      q(ij, l, iq) = (q(ij, l, iq) * masse(ij, l, iq) + convpn * aire(ij)) / &
787              newmasse
788      masse(ij, l, iq) = newmasse
789    ENDDO
790    convps = -SSUM(iim, qbyv(ip1jm - iim, l), 1) / apols
791    convmps = -SSUM(iim, masse_adv_v(ip1jm - iim, l), 1) / apols
792    DO ij = ip1jm + 1, ip1jmp1
793      newmasse = masse(ij, l, iq) + convmps * aire(ij)
794      q(ij, l, iq) = (q(ij, l, iq) * masse(ij, l, iq) + convps * aire(ij)) / &
795              newmasse
796      masse(ij, l, iq) = newmasse
797    ENDDO
798    !.-. fin ancienne version
799
800    !._. nouvelle version
801    ! convpn=SSUM(iim,qbyv(1,l),1)
802    ! convmpn=ssum(iim,masse_adv_v(1,l),1)
803    ! oldmasse=ssum(iim,masse(1,l),1)
804    ! newmasse=oldmasse+convmpn
805    ! newq=(q(1,l)*oldmasse+convpn)/newmasse
806    ! newmasse=newmasse/apoln
807    ! DO ij = 1,iip1
808    !    q(ij,l)=newq
809    !    masse(ij,l,iq)=newmasse*aire(ij)
810    ! ENDDO
811    ! convps=-SSUM(iim,qbyv(ip1jm-iim,l),1)
812    ! convmps=-ssum(iim,masse_adv_v(ip1jm-iim,l),1)
813    ! oldmasse=ssum(iim,masse(ip1jm-iim,l),1)
814    ! newmasse=oldmasse+convmps
815    ! newq=(q(ip1jmp1,l)*oldmasse+convps)/newmasse
816    ! newmasse=newmasse/apols
817    ! DO ij = ip1jm+1,ip1jmp1
818    !    q(ij,l)=newq
819    !    masse(ij,l,iq)=newmasse*aire(ij)
820    ! ENDDO
821    !._. fin nouvelle version
822  ENDDO
823
824  ! !WRITE(*,*) 'vly 866'
825
826  ! retablir les fils en rapport de melange par rapport a l'air:
827  DO ifils = 1, tracers(iq)%nqDescen
828    iq2 = tracers(iq)%iqDescen(ifils)
829    DO l = 1, llm
830      DO ij = 1, ip1jmp1
831        q(ij, l, iq2) = q(ij, l, iq) * Ratio(ij, l, iq2)
832      enddo
833    enddo
834  enddo
835  ! !WRITE(*,*) 'vly 879'
836
837END SUBROUTINE vlyqs
Note: See TracBrowser for help on using the repository browser.