4 |
|
|
5 |
contains |
contains |
6 |
|
|
7 |
SUBROUTINE coefkz(nsrf, knon, paprs, pplay, ksta, ksta_ter, ts, rugos, u, v, & |
SUBROUTINE coefkz(nsrf, paprs, pplay, ksta, ksta_ter, ts, rugos, u, v, t, & |
8 |
t, q, qsurf, coefm, coefh) |
q, qsurf, coefm, coefh) |
9 |
|
|
10 |
! Authors: F. Hourdin, M. Forichon, Z. X. Li (LMD/CNRS) |
! Authors: F. Hourdin, M. Forichon, Z. X. Li (LMD/CNRS) |
11 |
! date: 1993/09/22 |
! Date: September 22nd, 1993 |
12 |
! Objet : calculer le coefficient de frottement du sol ("Cdrag") et les |
! Objet : calculer le coefficient de frottement du sol ("Cdrag") et les |
13 |
! coefficients d'échange turbulent dans l'atmosphère. |
! coefficients d'échange turbulent dans l'atmosphère. |
14 |
|
|
15 |
|
use clcdrag_m, only: clcdrag |
16 |
|
USE conf_phys_m, ONLY: iflag_pbl |
17 |
|
USE dimphy, ONLY: klev, klon |
18 |
|
USE fcttre, ONLY: foede, foeew |
19 |
USE indicesol, ONLY: is_oce |
USE indicesol, ONLY: is_oce |
|
USE dimphy, ONLY: klev, klon, max |
|
|
USE conf_gcm_m, ONLY: prt_level |
|
20 |
USE suphec_m, ONLY: rcpd, rd, retv, rg, rkappa, rlstt, rlvtt, rtt |
USE suphec_m, ONLY: rcpd, rd, retv, rg, rkappa, rlstt, rlvtt, rtt |
21 |
USE yoethf_m, ONLY: r2es, r5ies, r5les, rvtmp2 |
USE yoethf_m, ONLY: r2es, r5ies, r5les, rvtmp2 |
|
USE fcttre, ONLY: dqsatl, dqsats, foede, foeew, qsatl, qsats, thermcep |
|
|
USE conf_phys_m, ONLY: iflag_pbl |
|
|
use clcdrag_m, only: clcdrag |
|
|
|
|
|
! Arguments: |
|
22 |
|
|
23 |
integer, intent(in):: nsrf ! indicateur de la nature du sol |
integer, intent(in):: nsrf ! indicateur de la nature du sol |
|
INTEGER, intent(in):: knon ! nombre de points a traiter |
|
24 |
|
|
25 |
REAL, intent(in):: paprs(klon, klev+1) |
REAL, intent(in):: paprs(:, :) ! (klon, klev+1) |
26 |
! pression a chaque intercouche (en Pa) |
! pression a chaque intercouche (en Pa) |
27 |
|
|
28 |
real, intent(in):: pplay(klon, klev) |
real, intent(in):: pplay(:, :) ! (klon, klev) |
29 |
! pression au milieu de chaque couche (en Pa) |
! pression au milieu de chaque couche (en Pa) |
30 |
|
|
31 |
REAL, intent(in):: ksta, ksta_ter |
REAL, intent(in):: ksta, ksta_ter |
32 |
REAL, intent(in):: ts(klon) ! temperature du sol (en Kelvin) |
REAL, intent(in):: ts(:) ! (knon) temperature du sol (en Kelvin) |
33 |
REAL, intent(in):: rugos(klon) ! longeur de rugosite (en m) |
REAL, intent(in):: rugos(:) ! (klon) longeur de rugosite (en m) |
34 |
REAL, intent(in):: u(klon, klev), v(klon, klev) ! wind |
REAL, intent(in):: u(:, :), v(:, :) ! (klon, klev) wind |
35 |
REAL, intent(in):: t(klon, klev) ! temperature (K) |
REAL, intent(in):: t(:, :) ! (klon, klev) temperature (K) |
36 |
real, intent(in):: q(klon, klev) ! vapeur d'eau (kg/kg) |
real, intent(in):: q(:, :) ! (klon, klev) vapeur d'eau (kg/kg) |
37 |
real, intent(in):: qsurf(klon) |
real, intent(in):: qsurf(:) ! (knon) |
38 |
REAL, intent(out):: coefm(:, :) ! (knon, klev) coefficient, vitesse |
REAL, intent(out):: coefm(:, :) ! (knon, klev) coefficient, vitesse |
39 |
|
|
40 |
real, intent(out):: coefh(:, :) ! (knon, klev) |
real, intent(out):: coefh(:, :) ! (knon, klev) |
42 |
|
|
43 |
! Local: |
! Local: |
44 |
|
|
45 |
INTEGER itop(knon) ! numero de couche du sommet de la couche limite |
INTEGER knon ! nombre de points a traiter |
46 |
|
INTEGER itop(size(coefm, 1)) ! (knon) numero de couche du sommet |
47 |
|
! de la couche limite |
48 |
|
|
49 |
! Quelques constantes et options: |
! Quelques constantes et options: |
50 |
|
|
55 |
REAL, PARAMETER:: cd = 5. |
REAL, PARAMETER:: cd = 5. |
56 |
REAL, PARAMETER:: clam = 160. |
REAL, PARAMETER:: clam = 160. |
57 |
REAL, PARAMETER:: ratqs = 0.05 ! largeur de distribution de vapeur d'eau |
REAL, PARAMETER:: ratqs = 0.05 ! largeur de distribution de vapeur d'eau |
58 |
|
|
59 |
LOGICAL, PARAMETER:: richum = .TRUE. |
LOGICAL, PARAMETER:: richum = .TRUE. |
60 |
! utilise le nombre de Richardson humide |
! utilise le nombre de Richardson humide |
61 |
|
|
72 |
LOGICAL, PARAMETER:: opt_ec = .FALSE. |
LOGICAL, PARAMETER:: opt_ec = .FALSE. |
73 |
! formule du Centre Europeen dans l'atmosphere |
! formule du Centre Europeen dans l'atmosphere |
74 |
|
|
75 |
INTEGER i, k, kk |
INTEGER i, k |
76 |
REAL zgeop(klon, klev) |
REAL zgeop(klon, klev) |
77 |
REAL zmgeom(klon) |
REAL zmgeom(klon) |
78 |
REAL ri(klon) |
REAL ri(klon) |
82 |
|
|
83 |
REAL zdphi, zdu2, ztvd, ztvu, cdn |
REAL zdphi, zdu2, ztvd, ztvu, cdn |
84 |
REAL scf |
REAL scf |
85 |
REAL zt, zq, zdelta, zcvm5, zcor, zqs, zfr, zdqs |
REAL zt, zq, zcvm5, zcor, zqs, zfr, zdqs |
86 |
|
logical zdelta |
87 |
REAL z2geomf, zalh2, alm2, zscfh, scfm |
REAL z2geomf, zalh2, alm2, zscfh, scfm |
|
REAL, PARAMETER:: t_coup = 273.15 |
|
88 |
REAL gamt(2:klev) ! contre-gradient pour la chaleur sensible: Kelvin/metre |
REAL gamt(2:klev) ! contre-gradient pour la chaleur sensible: Kelvin/metre |
89 |
|
|
90 |
!-------------------------------------------------------------------- |
!-------------------------------------------------------------------- |
91 |
|
|
92 |
|
knon = size(coefm, 1) |
93 |
|
|
94 |
! Prescrire la valeur de contre-gradient |
! Prescrire la valeur de contre-gradient |
95 |
if (iflag_pbl.eq.1) then |
if (iflag_pbl.eq.1) then |
96 |
DO k = 3, klev |
DO k = 3, klev |
132 |
z1(i) = zgeop(i, 1) |
z1(i) = zgeop(i, 1) |
133 |
ENDDO |
ENDDO |
134 |
|
|
135 |
CALL clcdrag(klon, knon, nsrf, .false., u1, v1, t1, q1, z1, ts, qsurf, & |
CALL clcdrag(nsrf, u1, v1, t1, q1, z1, ts, qsurf, rugos, coefm(:, 1), & |
136 |
rugos, coefm(:, 1), coefh(:, 1)) |
coefh(:, 1)) |
137 |
|
|
138 |
! Calculer les coefficients turbulents dans l'atmosphere |
! Calculer les coefficients turbulents dans l'atmosphere |
139 |
|
|
150 |
|
|
151 |
! calculer Qs et dQs/dT: |
! calculer Qs et dQs/dT: |
152 |
|
|
153 |
IF (thermcep) THEN |
zdelta = RTT >=zt |
154 |
zdelta = MAX(0., SIGN(1., RTT-zt)) |
zcvm5 = merge(R5IES * RLSTT, R5LES * RLVTT, zdelta) / RCPD & |
155 |
zcvm5 = R5LES*RLVTT/RCPD/(1.0+RVTMP2*zq)*(1.-zdelta) & |
/ (1. + RVTMP2*zq) |
156 |
+ R5IES*RLSTT/RCPD/(1.0+RVTMP2*zq)*zdelta |
zqs = R2ES * FOEEW(zt, zdelta) / pplay(i, k) |
157 |
zqs = R2ES * FOEEW(zt, zdelta) / pplay(i, k) |
zqs = MIN(0.5, zqs) |
158 |
zqs = MIN(0.5, zqs) |
zcor = 1./(1.-RETV*zqs) |
159 |
zcor = 1./(1.-RETV*zqs) |
zqs = zqs*zcor |
160 |
zqs = zqs*zcor |
zdqs = FOEDE(zt, zdelta, zcvm5, zqs, zcor) |
|
zdqs = FOEDE(zt, zdelta, zcvm5, zqs, zcor) |
|
|
ELSE |
|
|
IF (zt < t_coup) THEN |
|
|
zqs = qsats(zt) / pplay(i, k) |
|
|
zdqs = dqsats(zt, zqs) |
|
|
ELSE |
|
|
zqs = qsatl(zt) / pplay(i, k) |
|
|
zdqs = dqsatl(zt, zqs) |
|
|
ENDIF |
|
|
ENDIF |
|
161 |
|
|
162 |
! calculer la fraction nuageuse (processus humide): |
! calculer la fraction nuageuse (processus humide): |
163 |
|
|