source: LMDZ6/branches/Amaury_dev/libf/phylmd/coef_diff_turb_mod.F90 @ 5151

Last change on this file since 5151 was 5144, checked in by abarral, 7 weeks ago

Put YOMCST.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: 20.1 KB
Line 
1MODULE coef_diff_turb_mod
2
3  ! This module contains some procedures for calculation of the coefficients of the
4  ! turbulent diffusion in the atmosphere and coefficients for turbulent diffusion
5  ! at surface(cdrag)
6
7  IMPLICIT NONE
8
9CONTAINS
10
11  !****************************************************************************************
12
13  SUBROUTINE coef_diff_turb(dtime, nsrf, knon, ni, &
14          ypaprs, ypplay, yu, yv, yq, yt, yts, yqsurf, ycdragm, &
15          ycoefm, ycoefh, yq2, yeps, ydrgpro)
16
17    USE dimphy
18    USE indice_sol_mod
19    USE lmdz_print_control, ONLY: prt_level, lunout
20    USE lmdz_clesphys
21    USE lmdz_compbl, ONLY: iflag_pbl, iflag_pbl_split, iflag_order2_sollw, ifl_pbltree
22    USE lmdz_yoethf
23    USE lmdz_yomcst
24
25    ! Calculate coefficients(ycoefm, ycoefh) for turbulent diffusion in the
26    ! atmosphere
27    ! NB! No values are calculated between surface and the first model layer.
28    !     ycoefm(:,1) and ycoefh(:,1) are not valid !!!
29
30
31    ! Input arguments
32    !****************************************************************************************
33    REAL, INTENT(IN) :: dtime
34    INTEGER, INTENT(IN) :: nsrf, knon
35    INTEGER, DIMENSION(klon), INTENT(IN) :: ni
36    REAL, DIMENSION(klon, klev + 1), INTENT(IN) :: ypaprs
37    REAL, DIMENSION(klon, klev), INTENT(IN) :: ypplay
38    REAL, DIMENSION(klon, klev), INTENT(IN) :: yu, yv
39    REAL, DIMENSION(klon, klev), INTENT(IN) :: yq, yt
40    REAL, DIMENSION(klon), INTENT(IN) :: yts, yqsurf
41    REAL, DIMENSION(klon), INTENT(IN) :: ycdragm
42    !FC
43    REAL, DIMENSION(klon, klev), INTENT(IN) :: ydrgpro
44
45
46    ! InOutput arguments
47    !****************************************************************************************
48    REAL, DIMENSION(klon, klev + 1), INTENT(INOUT) :: yq2
49
50    ! Output arguments
51    !****************************************************************************************
52    REAL, DIMENSION(klon, klev + 1), INTENT(OUT) :: yeps
53    REAL, DIMENSION(klon, klev), INTENT(OUT) :: ycoefh
54    REAL, DIMENSION(klon, klev), INTENT(OUT) :: ycoefm
55
56    ! Other local variables
57    !****************************************************************************************
58    INTEGER :: k, i, j
59    REAL, DIMENSION(klon, klev) :: ycoefm0, ycoefh0, yzlay, yteta
60    REAL, DIMENSION(klon, klev + 1) :: yzlev, q2diag, ykmm, ykmn, ykmq
61    REAL, DIMENSION(klon) :: yustar
62
63    ykmm = 0 !ym missing init
64    ykmn = 0 !ym missing init
65    ykmq = 0 !ym missing init
66
67    yeps(:, :) = 0.
68
69    !****************************************************************************************
70    ! Calcul de coefficients de diffusion turbulent de l'atmosphere :
71    ! ycoefm(:,2:klev), ycoefh(:,2:klev)
72
73    !****************************************************************************************
74
75    CALL coefkz(nsrf, knon, ypaprs, ypplay, &
76            ksta, ksta_ter, &
77            yts, yu, yv, yt, yq, &
78            yqsurf, &
79            ycoefm, ycoefh)
80
81    !****************************************************************************************
82    ! Eventuelle recalcule des coeffeicients de diffusion turbulent de l'atmosphere :
83    ! ycoefm(:,2:klev), ycoefh(:,2:klev)
84
85    !****************************************************************************************
86
87    IF (iflag_pbl==1) THEN
88      CALL coefkz2(nsrf, knon, ypaprs, ypplay, yt, &
89              ycoefm0, ycoefh0)
90
91      DO k = 2, klev
92        DO i = 1, knon
93          ycoefm(i, k) = MAX(ycoefm(i, k), ycoefm0(i, k))
94          ycoefh(i, k) = MAX(ycoefh(i, k), ycoefh0(i, k))
95        ENDDO
96      ENDDO
97    ENDIF
98
99
100    !****************************************************************************************
101    ! Calcul d'une diffusion minimale pour les conditions tres stables
102
103    !****************************************************************************************
104    IF (ok_kzmin) THEN
105      CALL coefkzmin(knon, ypaprs, ypplay, yu, yv, yt, yq, ycdragm, &
106              ycoefm0, ycoefh0)
107
108      DO k = 2, klev
109        DO i = 1, knon
110          ycoefm(i, k) = MAX(ycoefm(i, k), ycoefm0(i, k))
111          ycoefh(i, k) = MAX(ycoefh(i, k), ycoefh0(i, k))
112        ENDDO
113      ENDDO
114
115    ENDIF
116
117
118    !****************************************************************************************
119    ! MELLOR ET YAMADA adapte a Mars Richard Fournier et Frederic Hourdin
120
121    !****************************************************************************************
122
123    IF (iflag_pbl>=3) THEN
124
125      yzlay(1:knon, 1) = &
126              RD * yt(1:knon, 1) / (0.5 * (ypaprs(1:knon, 1) + ypplay(1:knon, 1))) &
127                      * (ypaprs(1:knon, 1) - ypplay(1:knon, 1)) / RG
128      DO k = 2, klev
129        DO i = 1, knon
130          yzlay(i, k) = &
131                  yzlay(i, k - 1) + RD * 0.5 * (yt(i, k - 1) + yt(i, k)) &
132                          / ypaprs(i, k) * (ypplay(i, k - 1) - ypplay(i, k)) / RG
133        END DO
134      END DO
135
136      DO k = 1, klev
137        DO i = 1, knon
138          yteta(i, k) = &
139                  yt(i, k) * (ypaprs(i, 1) / ypplay(i, k))**RKAPPA &
140                          * (1. + 0.61 * yq(i, k))
141        END DO
142      END DO
143
144      yzlev(1:knon, 1) = 0.
145      yzlev(1:knon, klev + 1) = 2. * yzlay(1:knon, klev) - yzlay(1:knon, klev - 1)
146      DO k = 2, klev
147        DO i = 1, knon
148          yzlev(i, k) = 0.5 * (yzlay(i, k) + yzlay(i, k - 1))
149        END DO
150      END DO
151
152      !!$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
153      !!$! Pour memoire, le papier Hourdin et al. 2002 a ete obtenur avec un
154      !!$! bug sur les coefficients de surface :
155      !!$!          ycdragh(1:knon) = ycoefm(1:knon,1)
156      !!$!          ycdragm(1:knon) = ycoefh(1:knon,1)
157      !!$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
158
159      ! Normalement, on peut passer dans les codes avec knon=0
160      ! Mais ca fait planter le replay.
161      ! En attendant une réécriture, on a joute des if (Fredho)
162      IF (klon>1 .OR. (klon==1 .AND. knon==1)) THEN
163        CALL ustarhb(knon, klev, knon, yu, yv, ycdragm, yustar)
164      endif
165
166      IF (prt_level > 9) THEN
167        WRITE(lunout, *) 'USTAR = ', (yustar(i), i = 1, knon)
168      ENDIF
169
170      !   iflag_pbl peut etre utilise comme longuer de melange
171      IF (iflag_pbl>=31) THEN
172        IF (klon>1 .OR. (klon==1 .AND. knon==1)) THEN
173          CALL vdif_kcay(knon, klev, knon, dtime, RG, RD, ypaprs, yt, &
174                  yzlev, yzlay, yu, yv, yteta, &
175                  ycdragm, yq2, q2diag, ykmm, ykmn, yustar, &
176                  iflag_pbl)
177        endif
178      ELSE IF (iflag_pbl<20) THEN
179        CALL yamada4(ni, nsrf, knon, dtime, RG, RD, ypaprs, yt, &
180                yzlev, yzlay, yu, yv, yteta, &
181                ycdragm, yq2, yeps, ykmm, ykmn, ykmq, yustar, &
182                iflag_pbl, ydrgpro)
183        !FC
184      ENDIF
185
186      ycoefm(1:knon, 2:klev) = ykmm(1:knon, 2:klev)
187      ycoefh(1:knon, 2:klev) = ykmn(1:knon, 2:klev)
188
189    ELSE
190      ! No TKE for Standard Physics
191      yq2 = 0.
192    ENDIF !(iflag_pbl.ge.3)
193
194  END SUBROUTINE coef_diff_turb
195
196  !****************************************************************************************
197
198  SUBROUTINE coefkz(nsrf, knon, paprs, pplay, &
199          ksta, ksta_ter, &
200          ts, &
201          u, v, t, q, &
202          qsurf, &
203          pcfm, pcfh)
204
205    USE dimphy
206    USE indice_sol_mod
207    USE lmdz_print_control, ONLY: prt_level, lunout
208    USE lmdz_compbl, ONLY: iflag_pbl, iflag_pbl_split, iflag_order2_sollw, ifl_pbltree
209    USE lmdz_yoethf
210    USE lmdz_fcttre, ONLY: foeew, foede, qsats, qsatl, dqsats, dqsatl, thermcep
211    USE lmdz_yomcst
212
213    !======================================================================
214    ! Auteur(s) F. Hourdin, M. Forichon, Z.X. Li (LMD/CNRS) date: 19930922
215    !           (une version strictement identique a l'ancien modele)
216    ! Objet: calculer le coefficient du frottement du sol (Cdrag) et les
217    !        coefficients d'echange turbulent dans l'atmosphere.
218    ! Arguments:
219    ! nsrf-----input-I- indicateur de la nature du sol
220    ! knon-----input-I- nombre de points a traiter
221    ! paprs----input-R- pregssion a chaque intercouche (en Pa)
222    ! pplay----input-R- pression au milieu de chaque couche (en Pa)
223    ! ts-------input-R- temperature du sol (en Kelvin)
224    ! u--------input-R- vitesse u
225    ! v--------input-R- vitesse v
226    ! t--------input-R- temperature (K)
227    ! q--------input-R- vapeur d'eau (kg/kg)
228
229    ! pcfm-----output-R- coefficients a calculer (vitesse)
230    ! pcfh-----output-R- coefficients a calculer (chaleur et humidite)
231    !======================================================================
232
233    ! Arguments:
234
235    INTEGER, INTENT(IN) :: knon, nsrf
236    REAL, INTENT(IN) :: ksta, ksta_ter
237    REAL, DIMENSION(klon), INTENT(IN) :: ts
238    REAL, DIMENSION(klon, klev + 1), INTENT(IN) :: paprs
239    REAL, DIMENSION(klon, klev), INTENT(IN) :: pplay
240    REAL, DIMENSION(klon, klev), INTENT(IN) :: u, v, t, q
241    REAL, DIMENSION(klon), INTENT(IN) :: qsurf
242
243    REAL, DIMENSION(klon, klev), INTENT(OUT) :: pcfm, pcfh
244
245    ! Local variables:
246
247    INTEGER, DIMENSION(klon) :: itop ! numero de couche du sommet de la couche limite
248
249    ! Quelques constantes et options:
250
251    REAL, PARAMETER :: cepdu2 = 0.1**2
252    REAL, PARAMETER :: CKAP = 0.4
253    REAL, PARAMETER :: cb = 5.0
254    REAL, PARAMETER :: cc = 5.0
255    REAL, PARAMETER :: cd = 5.0
256    REAL, PARAMETER :: clam = 160.0
257    REAL, PARAMETER :: ratqs = 0.05 ! largeur de distribution de vapeur d'eau
258    LOGICAL, PARAMETER :: richum = .TRUE. ! utilise le nombre de Richardson humide
259    REAL, PARAMETER :: ric = 0.4 ! nombre de Richardson critique
260    REAL, PARAMETER :: prandtl = 0.4
261    REAL kstable ! diffusion minimale (situation stable)
262    ! GKtest
263    ! PARAMETER (kstable=1.0e-10)
264    !IM: 261103     REAL kstable_ter, kstable_sinon
265    !IM: 211003 cf GK   PARAMETER (kstable_ter = 1.0e-6)
266    !IM: 261103     PARAMETER (kstable_ter = 1.0e-8)
267    !IM: 261103   PARAMETER (kstable_ter = 1.0e-10)
268    !IM: 261103   PARAMETER (kstable_sinon = 1.0e-10)
269    ! fin GKtest
270    REAL, PARAMETER :: mixlen = 35.0 ! constante controlant longueur de melange
271    INTEGER isommet ! le sommet de la couche limite
272    LOGICAL, PARAMETER :: tvirtu = .TRUE. ! calculer Ri d'une maniere plus performante
273    LOGICAL, PARAMETER :: opt_ec = .FALSE.! formule du Centre Europeen dans l'atmosphere
274
275    ! Variables locales:
276    INTEGER i, k !IM 120704
277    REAL zgeop(klon, klev)
278    REAL zmgeom(klon)
279    REAL zri(klon)
280    REAL zl2(klon)
281    REAL zdphi, zdu2, ztvd, ztvu, zcdn
282    REAL zscf
283    REAL zt, zq, zdelta, zcvm5, zcor, zqs, zfr, zdqs
284    REAL z2geomf, zalh2, zalm2, zscfh, zscfm
285    REAL, PARAMETER :: t_coup = 273.15
286    LOGICAL, PARAMETER :: check = .FALSE.
287
288    ! contre-gradient pour la chaleur sensible: Kelvin/metre
289    REAL gamt(2:klev)
290
291    LOGICAL, SAVE :: appel1er = .TRUE.
292    !$OMP THREADPRIVATE(appel1er)
293
294    ! Fonctions thermodynamiques et fonctions d'instabilite
295    REAL fsta, fins, x
296
297    fsta(x) = 1.0 / (1.0 + 10.0 * x * (1 + 8.0 * x))
298    fins(x) = SQRT(1.0 - 18.0 * x)
299
300    isommet = klev
301
302    IF (appel1er) THEN
303      IF (prt_level > 9) THEN
304        WRITE(lunout, *)'coefkz, opt_ec:', opt_ec
305        WRITE(lunout, *)'coefkz, richum:', richum
306        IF (richum) WRITE(lunout, *)'coefkz, ratqs:', ratqs
307        WRITE(lunout, *)'coefkz, isommet:', isommet
308        WRITE(lunout, *)'coefkz, tvirtu:', tvirtu
309        appel1er = .FALSE.
310      ENDIF
311    ENDIF
312
313    ! Initialiser les sorties
314
315    DO k = 1, klev
316      DO i = 1, knon
317        pcfm(i, k) = 0.0
318        pcfh(i, k) = 0.0
319      ENDDO
320    ENDDO
321    DO i = 1, knon
322      itop(i) = 0
323    ENDDO
324
325    ! Prescrire la valeur de contre-gradient
326
327    IF (iflag_pbl==1) THEN
328      DO k = 3, klev
329        gamt(k) = -1.0E-03
330      ENDDO
331      gamt(2) = -2.5E-03
332    ELSE
333      DO k = 2, klev
334        gamt(k) = 0.0
335      ENDDO
336    ENDIF
337    !IM cf JLD/ GKtest
338    IF (nsrf /= is_oce) THEN
339      !IM 261103     kstable = kstable_ter
340      kstable = ksta_ter
341    ELSE
342      !IM 261103     kstable = kstable_sinon
343      kstable = ksta
344    ENDIF
345    !IM cf JLD/ GKtest fin
346
347    ! Calculer les geopotentiels de chaque couche
348
349    DO i = 1, knon
350      zgeop(i, 1) = RD * t(i, 1) / (0.5 * (paprs(i, 1) + pplay(i, 1))) &
351              * (paprs(i, 1) - pplay(i, 1))
352    ENDDO
353    DO k = 2, klev
354      DO i = 1, knon
355        zgeop(i, k) = zgeop(i, k - 1) &
356                + RD * 0.5 * (t(i, k - 1) + t(i, k)) / paprs(i, k) &
357                        * (pplay(i, k - 1) - pplay(i, k))
358      ENDDO
359    ENDDO
360
361    ! Calculer les coefficients turbulents dans l'atmosphere
362
363    DO i = 1, knon
364      itop(i) = isommet
365    ENDDO
366
367    DO k = 2, isommet
368      DO i = 1, knon
369        zdu2 = MAX(cepdu2, (u(i, k) - u(i, k - 1))**2 &
370                + (v(i, k) - v(i, k - 1))**2)
371        zmgeom(i) = zgeop(i, k) - zgeop(i, k - 1)
372        zdphi = zmgeom(i) / 2.0
373        zt = (t(i, k) + t(i, k - 1)) * 0.5
374        zq = (q(i, k) + q(i, k - 1)) * 0.5
375
376        ! Calculer Qs et dQs/dT:
377
378        IF (thermcep) THEN
379          zdelta = MAX(0., SIGN(1., RTT - zt))
380          zcvm5 = R5LES * RLVTT / RCPD / (1.0 + RVTMP2 * zq) * (1. - zdelta) &
381                  + R5IES * RLSTT / RCPD / (1.0 + RVTMP2 * zq) * zdelta
382          zqs = R2ES * FOEEW(zt, zdelta) / pplay(i, k)
383          zqs = MIN(0.5, zqs)
384          zcor = 1. / (1. - RETV * zqs)
385          zqs = zqs * zcor
386          zdqs = FOEDE(zt, zdelta, zcvm5, zqs, zcor)
387        ELSE
388          IF (zt < t_coup) THEN
389            zqs = qsats(zt) / pplay(i, k)
390            zdqs = dqsats(zt, zqs)
391          ELSE
392            zqs = qsatl(zt) / pplay(i, k)
393            zdqs = dqsatl(zt, zqs)
394          ENDIF
395        ENDIF
396
397        !           calculer la fraction nuageuse (processus humide):
398
399        IF (zq /= 0.) THEN
400          zfr = (zq + ratqs * zq - zqs) / (2.0 * ratqs * zq)
401        else
402          zfr = 0.
403        end if
404        zfr = MAX(0.0, MIN(1.0, zfr))
405        IF (.NOT.richum) zfr = 0.0
406
407        !           calculer le nombre de Richardson:
408
409        IF (tvirtu) THEN
410          ztvd = (t(i, k) &
411                  + zdphi / RCPD / (1. + RVTMP2 * zq) &
412                          * ((1. - zfr) + zfr * (1. + RLVTT * zqs / RD / zt) / (1. + zdqs)) &
413                  ) * (1. + RETV * q(i, k))
414          ztvu = (t(i, k - 1) &
415                  - zdphi / RCPD / (1. + RVTMP2 * zq) &
416                          * ((1. - zfr) + zfr * (1. + RLVTT * zqs / RD / zt) / (1. + zdqs)) &
417                  ) * (1. + RETV * q(i, k - 1))
418          zri(i) = zmgeom(i) * (ztvd - ztvu) / (zdu2 * 0.5 * (ztvd + ztvu))
419          zri(i) = zri(i) &
420                  + zmgeom(i) * zmgeom(i) / RG * gamt(k) &
421                          * (paprs(i, k) / 101325.0)**RKAPPA &
422                          / (zdu2 * 0.5 * (ztvd + ztvu))
423
424        ELSE ! calcul de Ridchardson compatible LMD5
425
426          zri(i) = (RCPD * (t(i, k) - t(i, k - 1)) &
427                  - RD * 0.5 * (t(i, k) + t(i, k - 1)) / paprs(i, k) &
428                          * (pplay(i, k) - pplay(i, k - 1)) &
429                  ) * zmgeom(i) / (zdu2 * 0.5 * RCPD * (t(i, k - 1) + t(i, k)))
430          zri(i) = zri(i) + &
431                  zmgeom(i) * zmgeom(i) * gamt(k) / RG &
432                          * (paprs(i, k) / 101325.0)**RKAPPA &
433                          / (zdu2 * 0.5 * (t(i, k - 1) + t(i, k)))
434        ENDIF
435
436        !           finalement, les coefficients d'echange sont obtenus:
437
438        zcdn = SQRT(zdu2) / zmgeom(i) * RG
439
440        IF (opt_ec) THEN
441          z2geomf = zgeop(i, k - 1) + zgeop(i, k)
442          zalm2 = (0.5 * ckap / RG * z2geomf &
443                  / (1. + 0.5 * ckap / rg / clam * z2geomf))**2
444          zalh2 = (0.5 * ckap / rg * z2geomf &
445                  / (1. + 0.5 * ckap / RG / (clam * SQRT(1.5 * cd)) * z2geomf))**2
446          IF (zri(i)<0.0) THEN  ! situation instable
447            zscf = ((zgeop(i, k) / zgeop(i, k - 1))**(1. / 3.) - 1.)**3 &
448                    / (zmgeom(i) / RG)**3 / (zgeop(i, k - 1) / RG)
449            zscf = SQRT(-zri(i) * zscf)
450            zscfm = 1.0 / (1.0 + 3.0 * cb * cc * zalm2 * zscf)
451            zscfh = 1.0 / (1.0 + 3.0 * cb * cc * zalh2 * zscf)
452            pcfm(i, k) = zcdn * zalm2 * (1. - 2.0 * cb * zri(i) * zscfm)
453            pcfh(i, k) = zcdn * zalh2 * (1. - 3.0 * cb * zri(i) * zscfh)
454          ELSE ! situation stable
455            zscf = SQRT(1. + cd * zri(i))
456            pcfm(i, k) = zcdn * zalm2 / (1. + 2.0 * cb * zri(i) / zscf)
457            pcfh(i, k) = zcdn * zalh2 / (1. + 3.0 * cb * zri(i) * zscf)
458          ENDIF
459        ELSE
460          zl2(i) = (mixlen * MAX(0.0, (paprs(i, k) - paprs(i, itop(i) + 1)) &
461                  / (paprs(i, 2) - paprs(i, itop(i) + 1))))**2
462          pcfm(i, k) = SQRT(MAX(zcdn * zcdn * (ric - zri(i)) / ric, kstable))
463          pcfm(i, k) = zl2(i) * pcfm(i, k)
464          pcfh(i, k) = pcfm(i, k) / prandtl ! h et m different
465        ENDIF
466      ENDDO
467    ENDDO
468
469    ! Au-dela du sommet, pas de diffusion turbulente:
470
471    DO i = 1, knon
472      IF (itop(i) + 1 <= klev) THEN
473        DO k = itop(i) + 1, klev
474          pcfh(i, k) = 0.0
475          pcfm(i, k) = 0.0
476        ENDDO
477      ENDIF
478    ENDDO
479
480  END SUBROUTINE coefkz
481
482  !****************************************************************************************
483
484  SUBROUTINE coefkz2(nsrf, knon, paprs, pplay, t, &
485          pcfm, pcfh)
486
487    USE dimphy
488    USE indice_sol_mod
489    USE lmdz_yomcst
490
491    !======================================================================
492    ! J'introduit un peu de diffusion sauf dans les endroits
493    ! ou une forte inversion est presente
494    ! On peut dire qu'il represente la convection peu profonde
495
496    ! Arguments:
497    ! nsrf-----input-I- indicateur de la nature du sol
498    ! knon-----input-I- nombre de points a traiter
499    ! paprs----input-R- pression a chaque intercouche (en Pa)
500    ! pplay----input-R- pression au milieu de chaque couche (en Pa)
501    ! t--------input-R- temperature (K)
502
503    ! pcfm-----output-R- coefficients a calculer (vitesse)
504    ! pcfh-----output-R- coefficients a calculer (chaleur et humidite)
505    !======================================================================
506
507    ! Arguments:
508
509    INTEGER, INTENT(IN) :: knon, nsrf
510    REAL, DIMENSION(klon, klev + 1), INTENT(IN) :: paprs
511    REAL, DIMENSION(klon, klev), INTENT(IN) :: pplay
512    REAL, DIMENSION(klon, klev), INTENT(IN) :: t(klon, klev)
513
514    REAL, DIMENSION(klon, klev), INTENT(OUT) :: pcfm, pcfh
515
516    ! Quelques constantes et options:
517
518    REAL, PARAMETER :: prandtl = 0.4
519    REAL, PARAMETER :: kstable = 0.002
520    !   REAL, PARAMETER :: kstable=0.001
521    REAL, PARAMETER :: mixlen = 35.0 ! constante controlant longueur de melange
522    REAL, PARAMETER :: seuil = -0.02 ! au-dela l'inversion est consideree trop faible
523    !    PARAMETER (seuil=-0.04)
524    !    PARAMETER (seuil=-0.06)
525    !    PARAMETER (seuil=-0.09)
526
527    ! Variables locales:
528
529    INTEGER i, k, invb(knon)
530    REAL zl2(knon)
531    REAL zdthmin(knon), zdthdp
532
533    ! Initialiser les sorties
534
535    DO k = 1, klev
536      DO i = 1, knon
537        pcfm(i, k) = 0.0
538        pcfh(i, k) = 0.0
539      ENDDO
540    ENDDO
541
542    ! Chercher la zone d'inversion forte
543
544    DO i = 1, knon
545      invb(i) = klev
546      zdthmin(i) = 0.0
547    ENDDO
548    DO k = 2, klev / 2 - 1
549      DO i = 1, knon
550        zdthdp = (t(i, k) - t(i, k + 1)) / (pplay(i, k) - pplay(i, k + 1)) &
551                - RD * 0.5 * (t(i, k) + t(i, k + 1)) / RCPD / paprs(i, k + 1)
552        zdthdp = zdthdp * 100.0
553        IF (pplay(i, k)>0.8 * paprs(i, 1) .AND. &
554                zdthdp<zdthmin(i)) THEN
555          zdthmin(i) = zdthdp
556          invb(i) = k
557        ENDIF
558      ENDDO
559    ENDDO
560
561    ! Introduire une diffusion:
562
563    IF (nsrf==is_oce) THEN
564      DO k = 2, klev
565        DO i = 1, knon
566          !IM cf FH/GK   IF ( (nsrf.NE.is_oce) .OR.  ! si ce n'est pas sur l'ocean
567          !IM cf FH/GK  .     (invb(i).EQ.klev) .OR. ! s'il n'y a pas d'inversion
568          !IM cf JLD/ GKtest TERkz2
569          ! IF ( (nsrf.EQ.is_ter) .OR.  ! si on est sur la terre
570          ! fin GKtest
571
572
573          ! s'il n'y a pas d'inversion ou si l'inversion est trop faible
574          !          IF ( (nsrf.EQ.is_oce) .AND. &
575          IF ((invb(i)==klev) .OR. (zdthmin(i)>seuil)) THEN
576            zl2(i) = (mixlen * MAX(0.0, (paprs(i, k) - paprs(i, klev + 1)) &
577                    / (paprs(i, 2) - paprs(i, klev + 1))))**2
578            pcfm(i, k) = zl2(i) * kstable
579            pcfh(i, k) = pcfm(i, k) / prandtl ! h et m different
580          ENDIF
581        ENDDO
582      ENDDO
583    ENDIF
584
585  END SUBROUTINE coefkz2
586
587  !****************************************************************************************
588
589END MODULE coef_diff_turb_mod
Note: See TracBrowser for help on using the repository browser.