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

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