1 | !$Id: clcdrag.F90 5144 2024-07-29 21:01:04Z abarral $ |
---|
2 | |
---|
3 | SUBROUTINE clcdrag(knon, nsrf, paprs, pplay, & |
---|
4 | u1, v1, t1, q1, & |
---|
5 | tsurf, qsurf, rugos, & |
---|
6 | pcfm, pcfh) |
---|
7 | |
---|
8 | USE dimphy |
---|
9 | USE indice_sol_mod |
---|
10 | USE lmdz_abort_physic, ONLY: abort_physic |
---|
11 | USE lmdz_clesphys |
---|
12 | USE lmdz_yoethf |
---|
13 | USE lmdz_yomcst |
---|
14 | |
---|
15 | IMPLICIT NONE |
---|
16 | ! ================================================================= c |
---|
17 | |
---|
18 | ! Objet : calcul des cdrags pour le moment (pcfm) et |
---|
19 | ! les flux de chaleur sensible et latente (pcfh). |
---|
20 | |
---|
21 | ! ================================================================= c |
---|
22 | |
---|
23 | ! knon----input-I- nombre de points pour un type de surface |
---|
24 | ! nsrf----input-I- indice pour le type de surface; voir indice_sol_mod.F90 |
---|
25 | ! u1-------input-R- vent zonal au 1er niveau du modele |
---|
26 | ! v1-------input-R- vent meridien au 1er niveau du modele |
---|
27 | ! t1-------input-R- temperature de l'air au 1er niveau du modele |
---|
28 | ! q1-------input-R- humidite de l'air au 1er niveau du modele |
---|
29 | ! tsurf------input-R- temperature de l'air a la surface |
---|
30 | ! qsurf---input-R- humidite de l'air a la surface |
---|
31 | ! rugos---input-R- rugosite |
---|
32 | |
---|
33 | ! pcfm---output-R- cdrag pour le moment |
---|
34 | ! pcfh---output-R- cdrag pour les flux de chaleur latente et sensible |
---|
35 | |
---|
36 | INTEGER, INTENT(IN) :: knon, nsrf |
---|
37 | REAL, DIMENSION(klon, klev + 1), INTENT(IN) :: paprs |
---|
38 | REAL, DIMENSION(klon, klev), INTENT(IN) :: pplay |
---|
39 | REAL, DIMENSION(klon), INTENT(IN) :: u1, v1, t1, q1 |
---|
40 | REAL, DIMENSION(klon), INTENT(IN) :: tsurf, qsurf |
---|
41 | REAL, DIMENSION(klon), INTENT(IN) :: rugos |
---|
42 | REAL, DIMENSION(klon), INTENT(OUT) :: pcfm, pcfh |
---|
43 | |
---|
44 | ! ================================================================= c |
---|
45 | |
---|
46 | ! Quelques constantes et options: |
---|
47 | !!$PB REAL, PARAMETER :: ckap=0.35, cb=5.0, cc=5.0, cd=5.0, cepdu2=(0.1)**2 |
---|
48 | REAL, PARAMETER :: ckap = 0.40, cb = 5.0, cc = 5.0, cd = 5.0, cepdu2 = (0.1)**2 |
---|
49 | |
---|
50 | ! Variables locales : |
---|
51 | INTEGER :: i |
---|
52 | REAL :: zdu2, ztsolv |
---|
53 | REAL :: ztvd, zscf |
---|
54 | REAL :: zucf, zcr |
---|
55 | REAL :: friv, frih |
---|
56 | REAL, DIMENSION(klon) :: zcfm1, zcfm2 |
---|
57 | REAL, DIMENSION(klon) :: zcfh1, zcfh2 |
---|
58 | REAL, DIMENSION(klon) :: zcdn |
---|
59 | REAL, DIMENSION(klon) :: zri |
---|
60 | REAL, DIMENSION(klon) :: zgeop1 ! geopotentiel au 1er niveau du modele |
---|
61 | LOGICAL, PARAMETER :: zxli = .FALSE. ! calcul des cdrags selon Laurent Li |
---|
62 | |
---|
63 | CHARACTER (LEN = 80) :: abort_message |
---|
64 | CHARACTER (LEN = 20) :: modname = 'clcdrag' |
---|
65 | |
---|
66 | ! Fonctions thermodynamiques et fonctions d'instabilite |
---|
67 | REAL :: fsta, fins, x |
---|
68 | fsta(x) = 1.0 / (1.0 + 10.0 * x * (1 + 8.0 * x)) |
---|
69 | fins(x) = SQRT(1.0 - 18.0 * x) |
---|
70 | |
---|
71 | abort_message = 'obsolete, remplace par cdrag, use at you own risk' |
---|
72 | CALL abort_physic(modname, abort_message, 1) |
---|
73 | |
---|
74 | |
---|
75 | |
---|
76 | ! ================================================================= c |
---|
77 | |
---|
78 | ! Calculer le geopotentiel du premier couche de modele |
---|
79 | |
---|
80 | DO i = 1, knon |
---|
81 | zgeop1(i) = RD * t1(i) / (0.5 * (paprs(i, 1) + pplay(i, 1))) & |
---|
82 | * (paprs(i, 1) - pplay(i, 1)) |
---|
83 | END DO |
---|
84 | ! ================================================================= c |
---|
85 | |
---|
86 | ! Calculer le frottement au sol (Cdrag) |
---|
87 | |
---|
88 | DO i = 1, knon |
---|
89 | zdu2 = MAX(cepdu2, u1(i)**2 + v1(i)**2) |
---|
90 | ztsolv = tsurf(i) * (1.0 + RETV * qsurf(i)) |
---|
91 | ztvd = (t1(i) + zgeop1(i) / RCPD / (1. + RVTMP2 * q1(i))) & |
---|
92 | * (1. + RETV * q1(i)) |
---|
93 | zri(i) = zgeop1(i) * (ztvd - ztsolv) / (zdu2 * ztvd) |
---|
94 | zcdn(i) = (ckap / LOG(1. + zgeop1(i) / (RG * rugos(i))))**2 |
---|
95 | |
---|
96 | !!$ IF (zri(i) .ge. 0.) THEN ! situation stable |
---|
97 | IF (zri(i) > 0.) THEN ! situation stable |
---|
98 | zri(i) = MIN(20., zri(i)) |
---|
99 | IF (.NOT.zxli) THEN |
---|
100 | zscf = SQRT(1. + cd * ABS(zri(i))) |
---|
101 | FRIV = AMAX1(1. / (1. + 2. * CB * zri(i) / ZSCF), f_ri_cd_min) |
---|
102 | zcfm1(i) = zcdn(i) * FRIV |
---|
103 | FRIH = AMAX1(1. / (1. + 3. * CB * zri(i) * ZSCF), f_ri_cd_min) |
---|
104 | !!$ PB zcfh1(i) = zcdn(i) * FRIH |
---|
105 | !!$ PB zcfh1(i) = f_cdrag_stable * zcdn(i) * FRIH |
---|
106 | zcfh1(i) = f_cdrag_ter * zcdn(i) * FRIH |
---|
107 | IF(nsrf==is_oce) zcfh1(i) = f_cdrag_oce * zcdn(i) * FRIH |
---|
108 | !!$ PB |
---|
109 | pcfm(i) = zcfm1(i) |
---|
110 | pcfh(i) = zcfh1(i) |
---|
111 | ELSE |
---|
112 | pcfm(i) = zcdn(i) * fsta(zri(i)) |
---|
113 | pcfh(i) = zcdn(i) * fsta(zri(i)) |
---|
114 | ENDIF |
---|
115 | ELSE ! situation instable |
---|
116 | IF (.NOT.zxli) THEN |
---|
117 | zucf = 1. / (1. + 3.0 * cb * cc * zcdn(i) * SQRT(ABS(zri(i)) & |
---|
118 | * (1.0 + zgeop1(i) / (RG * rugos(i))))) |
---|
119 | zcfm2(i) = zcdn(i) * amax1((1. - 2.0 * cb * zri(i) * zucf), f_ri_cd_min) |
---|
120 | !!$PB zcfh2(i) = zcdn(i)*amax1((1.-3.0*cb*zri(i)*zucf),f_ri_cd_min) |
---|
121 | zcfh2(i) = f_cdrag_ter * zcdn(i) * amax1((1. - 3.0 * cb * zri(i) * zucf), f_ri_cd_min) |
---|
122 | pcfm(i) = zcfm2(i) |
---|
123 | pcfh(i) = zcfh2(i) |
---|
124 | ELSE |
---|
125 | pcfm(i) = zcdn(i) * fins(zri(i)) |
---|
126 | pcfh(i) = zcdn(i) * fins(zri(i)) |
---|
127 | ENDIF |
---|
128 | IF(iflag_gusts==0) THEN |
---|
129 | ! cdrah sur l'ocean cf. Miller et al. (1992) - only active when gustiness parameterization is not active |
---|
130 | zcr = (0.0016 / (zcdn(i) * SQRT(zdu2))) * ABS(ztvd - ztsolv)**(1. / 3.) |
---|
131 | IF(nsrf==is_oce) pcfh(i) = f_cdrag_oce * zcdn(i) * (1.0 + zcr**1.25)**(1. / 1.25) |
---|
132 | ENDIF |
---|
133 | ENDIF |
---|
134 | END DO |
---|
135 | |
---|
136 | ! ================================================================= c |
---|
137 | |
---|
138 | ! IM cf JLD : on seuille cdrag_m et cdrag_h |
---|
139 | IF (nsrf == is_oce) THEN |
---|
140 | DO i = 1, knon |
---|
141 | pcfm(i) = MIN(pcfm(i), cdmmax) |
---|
142 | pcfh(i) = MIN(pcfh(i), cdhmax) |
---|
143 | END DO |
---|
144 | END IF |
---|
145 | |
---|
146 | END SUBROUTINE clcdrag |
---|