/[lmdze]/trunk/phylmd/Interface_surf/coefkz.f90
ViewVC logotype

Contents of /trunk/phylmd/Interface_surf/coefkz.f90

Parent Directory Parent Directory | Revision Log Revision Log


Revision 328 - (show annotations)
Thu Jun 13 14:40:06 2019 UTC (4 years, 11 months ago) by guez
File size: 4912 byte(s)
Change all `.f` suffixes to `.f90`. (The opposite was done in revision
82.)  Because of change of philosopy in GNUmakefile: we already had a
rewritten rule for `.f`, so it does not make the makefile longer to
replace it by a rule for `.f90`. And it spares us options of
makedepf90 and of the compiler. Also we prepare the way for a simpler
`CMakeLists.txt`.

1 module coefkz_m
2
3 IMPLICIT none
4
5 contains
6
7 SUBROUTINE coefkz(nsrf, paprs, pplay, ts, u, v, t, q, zgeop, coefm, coefh)
8
9 ! Authors: F. Hourdin, M. Forichon, Z. X. Li (LMD/CNRS)
10 ! Date: September 22nd, 1993
11
12 ! Objet : calculer les coefficients d'échange turbulent dans
13 ! l'atmosphère.
14
15 USE clesphys, ONLY: ksta, ksta_ter
16 USE conf_phys_m, ONLY: iflag_pbl
17 USE dimphy, ONLY: klev
18 USE fcttre, ONLY: foede, foeew
19 USE indicesol, ONLY: is_oce
20 USE suphec_m, ONLY: rcpd, rd, retv, rg, rkappa, rlstt, rlvtt, rtt
21 USE yoethf_m, ONLY: r2es, r5ies, r5les, rvtmp2
22
23 integer, intent(in):: nsrf ! indicateur de la nature du sol
24
25 REAL, intent(in):: paprs(:, :) ! (knon, klev + 1)
26 ! pression a chaque intercouche (en Pa)
27
28 real, intent(in):: pplay(:, :) ! (knon, klev)
29 ! pression au milieu de chaque couche (en Pa)
30
31 REAL, intent(in):: ts(:) ! (knon) temperature du sol (en Kelvin)
32 REAL, intent(in):: u(:, :), v(:, :) ! (knon, klev) wind
33 REAL, intent(in):: t(:, :) ! (knon, klev) temperature (K)
34 real, intent(in):: q(:, :) ! (knon, klev) vapeur d'eau (kg/kg)
35 REAL, intent(in):: zgeop(:, :) ! (knon, klev)
36 REAL, intent(out):: coefm(:, 2:) ! (knon, 2:klev) coefficient, vitesse
37
38 real, intent(out):: coefh(:, 2:) ! (knon, 2:klev)
39 ! coefficient, chaleur et humidité
40
41 ! Local:
42
43 INTEGER knon ! nombre de points a traiter
44
45 INTEGER itop(size(ts)) ! (knon)
46 ! numero de couche du sommet de la couche limite
47
48 ! Quelques constantes et options:
49
50 REAL, PARAMETER:: cepdu2 =0.1**2
51 REAL, PARAMETER:: ratqs = 0.05 ! largeur de distribution de vapeur d'eau
52 REAL, PARAMETER:: ric = 0.4 ! nombre de Richardson critique
53 REAL, PARAMETER:: prandtl = 0.4
54
55 REAL kstable ! diffusion minimale (situation stable)
56 REAL, PARAMETER:: mixlen = 35. ! constante contrôlant longueur de mélange
57 INTEGER, PARAMETER:: isommet = klev ! sommet de la couche limite
58 INTEGER i, k
59 REAL zmgeom(size(ts))
60 REAL ri(size(ts))
61 REAL l2(size(ts))
62 REAL zdphi, zdu2, ztvd, ztvu, cdn
63 REAL zt, zq, zcvm5, zcor, zqs, zfr, zdqs
64 logical zdelta
65 REAL gamt(2:klev) ! contre-gradient pour la chaleur sensible: Kelvin/metre
66
67 !--------------------------------------------------------------------
68
69 knon = size(ts)
70
71 ! Prescrire la valeur de contre-gradient
72 if (iflag_pbl == 1) then
73 DO k = 3, klev
74 gamt(k) = - 1E-3
75 ENDDO
76 gamt(2) = - 2.5E-3
77 else
78 DO k = 2, klev
79 gamt(k) = 0.0
80 ENDDO
81 ENDIF
82
83 kstable = merge(ksta, ksta_ter, nsrf == is_oce)
84
85 ! Calculer les coefficients turbulents dans l'atmosphere
86
87 itop = isommet
88
89 DO k = 2, isommet
90 DO i = 1, knon
91 zdu2 = MAX(cepdu2, (u(i, k) - u(i, k - 1))**2 &
92 + (v(i, k) - v(i, k - 1))**2)
93 zmgeom(i) = zgeop(i, k) - zgeop(i, k - 1)
94 zdphi = zmgeom(i) / 2.0
95 zt = (t(i, k) + t(i, k - 1)) * 0.5
96 zq = (q(i, k) + q(i, k - 1)) * 0.5
97
98 ! calculer Qs et dQs/dT:
99 zdelta = RTT >=zt
100 zcvm5 = merge(R5IES * RLSTT, R5LES * RLVTT, zdelta) / RCPD &
101 / (1. + RVTMP2 * zq)
102 zqs = R2ES * FOEEW(zt, zdelta) / pplay(i, k)
103 zqs = MIN(0.5, zqs)
104 zcor = 1./(1. - RETV * zqs)
105 zqs = zqs * zcor
106 zdqs = FOEDE(zt, zdelta, zcvm5, zqs, zcor)
107
108 ! calculer la fraction nuageuse (processus humide):
109 zfr = (zq + ratqs * zq - zqs) / (2.0 * ratqs * zq)
110 zfr = MAX(0.0, MIN(1.0, zfr))
111
112 ! calculer le nombre de Richardson:
113 ztvd = (t(i, k) &
114 + zdphi/RCPD/(1. + RVTMP2 * zq) &
115 * ((1. - zfr) + zfr * (1. + RLVTT * zqs/RD/zt)/(1. + zdqs)) &
116 ) * (1. + RETV * q(i, k))
117 ztvu = (t(i, k - 1) &
118 - zdphi/RCPD/(1. + RVTMP2 * zq) &
119 * ((1. - zfr) + zfr * (1. + RLVTT * zqs/RD/zt)/(1. + zdqs)) &
120 ) * (1. + RETV * q(i, k - 1))
121 ri(i) = zmgeom(i) * (ztvd - ztvu)/(zdu2 * 0.5 * (ztvd + ztvu))
122 ri(i) = ri(i) &
123 + zmgeom(i) * zmgeom(i)/RG * gamt(k) &
124 * (paprs(i, k)/101325.0)**RKAPPA &
125 /(zdu2 * 0.5 * (ztvd + ztvu))
126
127 ! finalement, les coefficients d'echange sont obtenus:
128
129 cdn = SQRT(zdu2) / zmgeom(i) * RG
130
131 l2(i) = (mixlen * MAX(0.0, (paprs(i, k) - paprs(i, itop(i) + 1)) &
132 /(paprs(i, 2) - paprs(i, itop(i) + 1))))**2
133 coefm(i, k) = sqrt(max(cdn**2 * (ric - ri(i)) / ric, kstable))
134 coefm(i, k) = l2(i) * coefm(i, k)
135 coefh(i, k) = coefm(i, k) / prandtl ! h et m different
136 ENDDO
137 ENDDO
138
139 ! Au-delà du sommet, pas de diffusion turbulente :
140 forall (i = 1: knon)
141 coefh(i, itop(i) + 1:) = 0.
142 coefm(i, itop(i) + 1:) = 0.
143 END forall
144
145 END SUBROUTINE coefkz
146
147 end module coefkz_m

  ViewVC Help
Powered by ViewVC 1.1.21