source: LMDZ6/branches/Amaury_dev/libf/dyn3dmem/vlspltqs_loc.f90 @ 5327

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