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

Last change on this file since 5157 was 5153, checked in by abarral, 7 weeks ago

Revert FCTTRE to INCLUDE to assess impact of inlining

  • 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
211    USE lmdz_yomcst
212
213    IMPLICIT NONE
214 INCLUDE "FCTTRE.h"
215
216    !======================================================================
217    ! Auteur(s) F. Hourdin, M. Forichon, Z.X. Li (LMD/CNRS) date: 19930922
218    !           (une version strictement identique a l'ancien modele)
219    ! Objet: calculer le coefficient du frottement du sol (Cdrag) et les
220    !        coefficients d'echange turbulent dans l'atmosphere.
221    ! Arguments:
222    ! nsrf-----input-I- indicateur de la nature du sol
223    ! knon-----input-I- nombre de points a traiter
224    ! paprs----input-R- pregssion a chaque intercouche (en Pa)
225    ! pplay----input-R- pression au milieu de chaque couche (en Pa)
226    ! ts-------input-R- temperature du sol (en Kelvin)
227    ! u--------input-R- vitesse u
228    ! v--------input-R- vitesse v
229    ! t--------input-R- temperature (K)
230    ! q--------input-R- vapeur d'eau (kg/kg)
231
232    ! pcfm-----output-R- coefficients a calculer (vitesse)
233    ! pcfh-----output-R- coefficients a calculer (chaleur et humidite)
234    !======================================================================
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    USE lmdz_yomcst
493
494    !======================================================================
495    ! J'introduit un peu de diffusion sauf dans les endroits
496    ! ou une forte inversion est presente
497    ! On peut dire qu'il represente la convection peu profonde
498
499    ! Arguments:
500    ! nsrf-----input-I- indicateur de la nature du sol
501    ! knon-----input-I- nombre de points a traiter
502    ! paprs----input-R- pression a chaque intercouche (en Pa)
503    ! pplay----input-R- pression au milieu de chaque couche (en Pa)
504    ! t--------input-R- temperature (K)
505
506    ! pcfm-----output-R- coefficients a calculer (vitesse)
507    ! pcfh-----output-R- coefficients a calculer (chaleur et humidite)
508    !======================================================================
509
510    ! Arguments:
511
512    INTEGER, INTENT(IN) :: knon, nsrf
513    REAL, DIMENSION(klon, klev + 1), INTENT(IN) :: paprs
514    REAL, DIMENSION(klon, klev), INTENT(IN) :: pplay
515    REAL, DIMENSION(klon, klev), INTENT(IN) :: t(klon, klev)
516
517    REAL, DIMENSION(klon, klev), INTENT(OUT) :: pcfm, pcfh
518
519    ! Quelques constantes et options:
520
521    REAL, PARAMETER :: prandtl = 0.4
522    REAL, PARAMETER :: kstable = 0.002
523    !   REAL, PARAMETER :: kstable=0.001
524    REAL, PARAMETER :: mixlen = 35.0 ! constante controlant longueur de melange
525    REAL, PARAMETER :: seuil = -0.02 ! au-dela l'inversion est consideree trop faible
526    !    PARAMETER (seuil=-0.04)
527    !    PARAMETER (seuil=-0.06)
528    !    PARAMETER (seuil=-0.09)
529
530    ! Variables locales:
531
532    INTEGER i, k, invb(knon)
533    REAL zl2(knon)
534    REAL zdthmin(knon), zdthdp
535
536    ! Initialiser les sorties
537
538    DO k = 1, klev
539      DO i = 1, knon
540        pcfm(i, k) = 0.0
541        pcfh(i, k) = 0.0
542      ENDDO
543    ENDDO
544
545    ! Chercher la zone d'inversion forte
546
547    DO i = 1, knon
548      invb(i) = klev
549      zdthmin(i) = 0.0
550    ENDDO
551    DO k = 2, klev / 2 - 1
552      DO i = 1, knon
553        zdthdp = (t(i, k) - t(i, k + 1)) / (pplay(i, k) - pplay(i, k + 1)) &
554                - RD * 0.5 * (t(i, k) + t(i, k + 1)) / RCPD / paprs(i, k + 1)
555        zdthdp = zdthdp * 100.0
556        IF (pplay(i, k)>0.8 * paprs(i, 1) .AND. &
557                zdthdp<zdthmin(i)) THEN
558          zdthmin(i) = zdthdp
559          invb(i) = k
560        ENDIF
561      ENDDO
562    ENDDO
563
564    ! Introduire une diffusion:
565
566    IF (nsrf==is_oce) THEN
567      DO k = 2, klev
568        DO i = 1, knon
569          !IM cf FH/GK   IF ( (nsrf.NE.is_oce) .OR.  ! si ce n'est pas sur l'ocean
570          !IM cf FH/GK  .     (invb(i).EQ.klev) .OR. ! s'il n'y a pas d'inversion
571          !IM cf JLD/ GKtest TERkz2
572          ! IF ( (nsrf.EQ.is_ter) .OR.  ! si on est sur la terre
573          ! fin GKtest
574
575
576          ! s'il n'y a pas d'inversion ou si l'inversion est trop faible
577          !          IF ( (nsrf.EQ.is_oce) .AND. &
578          IF ((invb(i)==klev) .OR. (zdthmin(i)>seuil)) THEN
579            zl2(i) = (mixlen * MAX(0.0, (paprs(i, k) - paprs(i, klev + 1)) &
580                    / (paprs(i, 2) - paprs(i, klev + 1))))**2
581            pcfm(i, k) = zl2(i) * kstable
582            pcfh(i, k) = pcfm(i, k) / prandtl ! h et m different
583          ENDIF
584        ENDDO
585      ENDDO
586    ENDIF
587
588  END SUBROUTINE coefkz2
589
590  !****************************************************************************************
591
592END MODULE coef_diff_turb_mod
Note: See TracBrowser for help on using the repository browser.