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

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

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