My Project
 All Classes Files Functions Variables Macros
coefcdrag.F90
Go to the documentation of this file.
1 !
2 !
3 !
4  SUBROUTINE coefcdrag (klon, knon, nsrf, zxli, &
5  speed, t, q, zgeop, psol, &
6  ts, qsurf, rugos, okri, ri1, &
7  cdram, cdrah, cdran, zri1, pref)
8  IMPLICIT none
9 !-------------------------------------------------------------------------
10 ! Objet : calcul des cdrags pour le moment (cdram) et les flux de chaleur
11 ! sensible et latente (cdrah), du cdrag neutre (cdran),
12 ! du nombre de Richardson entre la surface et le niveau de reference
13 ! (zri1) et de la pression au niveau de reference (pref).
14 !
15 ! I. Musat, 01.07.2002
16 !-------------------------------------------------------------------------
17 !
18 ! klon----input-I- dimension de la grille physique (= nb_pts_latitude X nb_pts_longitude)
19 ! knon----input-I- nombre de points pour un type de surface
20 ! nsrf----input-I- indice pour le type de surface; voir indicesol.h
21 ! zxli----input-L- TRUE si calcul des cdrags selon Laurent Li
22 ! speed---input-R- module du vent au 1er niveau du modele
23 ! t-------input-R- temperature de l'air au 1er niveau du modele
24 ! q-------input-R- humidite de l'air au 1er niveau du modele
25 ! zgeop---input-R- geopotentiel au 1er niveau du modele
26 ! psol----input-R- pression au sol
27 ! ts------input-R- temperature de l'air a la surface
28 ! qsurf---input-R- humidite de l'air a la surface
29 ! rugos---input-R- rugosite
30 ! okri----input-L- TRUE si on veut tester le nb. Richardson entre la sfce
31 ! et zref par rapport au Ri entre la sfce et la 1ere couche
32 ! ri1-----input-R- nb. Richardson entre la surface et la 1ere couche
33 !
34 ! cdram--output-R- cdrag pour le moment
35 ! cdrah--output-R- cdrag pour les flux de chaleur latente et sensible
36 ! cdran--output-R- cdrag neutre
37 ! zri1---output-R- nb. Richardson entre la surface et la couche zgeop/RG
38 ! pref---output-R- pression au niveau zgeop/RG
39 !
40  INTEGER, intent(in) :: klon, knon, nsrf
41  LOGICAL, intent(in) :: zxli
42  REAL, dimension(klon), intent(in) :: speed, t, q, zgeop, psol
43  REAL, dimension(klon), intent(in) :: ts, qsurf, rugos, ri1
44  LOGICAL, intent(in) :: okri
45 !
46  REAL, dimension(klon), intent(out) :: cdram, cdrah, cdran, zri1, pref
47 !-------------------------------------------------------------------------
48 !
49  include "YOMCST.h"
50  include "YOETHF.h"
51  include "indicesol.h"
52 ! Quelques constantes :
53  REAL, parameter :: rkar=0.40, cb=5.0, cc=5.0, cd=5.0, cepdu2=(0.1)**2
54 !
55 ! Variables locales :
56  INTEGER :: i
57  REAL, dimension(klon) :: zdu2, zdphi, ztsolv, ztvd
58  REAL, dimension(klon) :: zscf, friv, frih, zucf, zcr
59  REAL, dimension(klon) :: zcfm1, zcfh1
60  REAL, dimension(klon) :: zcfm2, zcfh2
61  REAL, dimension(klon) :: trm0, trm1
62 !-------------------------------------------------------------------------
63  REAL :: fsta, fins, x
64  fsta(x) = 1.0 / (1.0+10.0*x*(1+8.0*x))
65  fins(x) = sqrt(1.0-18.0*x)
66 !-------------------------------------------------------------------------
67 !
68  DO i = 1, knon
69 !
70  zdphi(i) = zgeop(i)
71  zdu2(i) = max(cepdu2,speed(i)**2)
72  pref(i) = exp(log(psol(i)) - zdphi(i)/(rd*t(i)* &
73  (1.+ retv * max(q(i),0.0))))
74  ztsolv(i) = ts(i)
75  ztvd(i) = t(i) * (psol(i)/pref(i))**rkappa
76  trm0(i) = 1. + retv * max(qsurf(i),0.0)
77  trm1(i) = 1. + retv * max(q(i),0.0)
78  ztsolv(i) = ztsolv(i) * trm0(i)
79  ztvd(i) = ztvd(i) * trm1(i)
80  zri1(i) = zdphi(i)*(ztvd(i)-ztsolv(i))/(zdu2(i)*ztvd(i))
81 !
82 ! on teste zri1 par rapport au Richardson de la 1ere couche ri1
83 !
84 !IM +++
85  IF(1.EQ.0) THEN
86  IF (okri) THEN
87  IF (ri1(i).GE.0.0.AND.zri1(i).LT.0.0) THEN
88  zri1(i) = ri1(i)
89  ELSE IF(ri1(i).LT.0.0.AND.zri1(i).GE.0.0) THEN
90  zri1(i) = ri1(i)
91  ENDIF
92  ENDIF
93  ENDIF
94 !IM ---
95 !
96  cdran(i) = (rkar/log(1.+zdphi(i)/(rg*rugos(i))))**2
97 
98  IF (zri1(i) .ge. 0.) THEN
99 !
100 ! situation stable : pour eviter les inconsistances dans les cas
101 ! tres stables on limite zri1 a 20. cf Hess et al. (1995)
102 !
103  zri1(i) = min(20.,zri1(i))
104 !
105  IF (.NOT.zxli) THEN
106  zscf(i) = sqrt(1.+cd*abs(zri1(i)))
107  friv(i) = max(1. / (1.+2.*cb*zri1(i)/ zscf(i)), 0.1)
108  zcfm1(i) = cdran(i) * friv(i)
109  frih(i) = max(1./ (1.+3.*cb*zri1(i)*zscf(i)), 0.1 )
110  zcfh1(i) = cdran(i) * frih(i)
111  cdram(i) = zcfm1(i)
112  cdrah(i) = zcfh1(i)
113  ELSE
114  cdram(i) = cdran(i)* fsta(zri1(i))
115  cdrah(i) = cdran(i)* fsta(zri1(i))
116  ENDIF
117 !
118  ELSE
119 !
120 ! situation instable
121 !
122  IF (.NOT.zxli) THEN
123  zucf(i) = 1./(1.+3.0*cb*cc*cdran(i)*sqrt(abs(zri1(i)) &
124  *(1.0+zdphi(i)/(rg*rugos(i)))))
125  zcfm2(i) = cdran(i)*max((1.-2.0*cb*zri1(i)*zucf(i)),0.1)
126  zcfh2(i) = cdran(i)*max((1.-3.0*cb*zri1(i)*zucf(i)),0.1)
127  cdram(i) = zcfm2(i)
128  cdrah(i) = zcfh2(i)
129  ELSE
130  cdram(i) = cdran(i)* fins(zri1(i))
131  cdrah(i) = cdran(i)* fins(zri1(i))
132  ENDIF
133 !
134 ! cdrah sur l'ocean cf. Miller et al. (1992)
135 !
136  zcr(i) = (0.0016/(cdran(i)*sqrt(zdu2(i))))*abs(ztvd(i)-ztsolv(i)) &
137  **(1./3.)
138  IF (nsrf.EQ.is_oce) cdrah(i) = cdran(i)*(1.0+zcr(i)**1.25) &
139  **(1./1.25)
140  ENDIF
141 !
142  END DO
143  RETURN
144  END SUBROUTINE coefcdrag