source: LMDZ6/branches/Amaury_dev/libf/dyn3d/vlsplt.F90 @ 5137

Last change on this file since 5137 was 5136, checked in by abarral, 11 months ago

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