/[lmdze]/trunk/phylmd/Interface_surf/pbl_surface.f
ViewVC logotype

Contents of /trunk/phylmd/Interface_surf/pbl_surface.f

Parent Directory Parent Directory | Revision Log Revision Log


Revision 62 - (show annotations)
Thu Jul 26 14:37:37 2012 UTC (11 years, 9 months ago) by guez
Original Path: trunk/libf/phylmd/clmain.f90
File size: 25856 byte(s)
Changed handling of compiler in compilation system.

Removed the prefix letters "y", "p", "t" or "z" in some names of variables.

Replaced calls to NetCDF by calls to NetCDF95.

Extracted "ioget_calendar" procedures from "calendar.f90" into a
separate file.

Extracted to a separate file, "mathop2.f90", procedures that were not
part of the generic interface "mathop" in "mathop.f90".

Removed computation of "dq" in "bilan_dyn", which was not used.

In "iniadvtrac", removed schemes 20 Slopes and 30 Prather. Was not
compatible with declarations of array sizes.

In "clcdrag", "ustarhb", "vdif_kcay", "yamada4" and "coefkz", changed
the size of some arrays from "klon" to "knon".

Removed possible call to "conema3" in "physiq".

Removed unused argument "cd" in "yamada".

1 module clmain_m
2
3 IMPLICIT NONE
4
5 contains
6
7 SUBROUTINE clmain(dtime, itap, date0, pctsrf, pctsrf_new, t, q, u, v, &
8 jour, rmu0, co2_ppm, ok_veget, ocean, npas, nexca, ts, &
9 soil_model, cdmmax, cdhmax, ksta, ksta_ter, ok_kzmin, ftsoil, &
10 qsol, paprs, pplay, snow, qsurf, evap, albe, alblw, fluxlat, &
11 rain_fall, snow_f, solsw, sollw, sollwdown, fder, rlon, rlat, cufi, &
12 cvfi, rugos, debut, lafin, agesno, rugoro, d_t, d_q, d_u, d_v, &
13 d_ts, flux_t, flux_q, flux_u, flux_v, cdragh, cdragm, q2, &
14 dflux_t, dflux_q, zcoefh, zu1, zv1, t2m, q2m, u10m, v10m, pblh, &
15 capcl, oliqcl, cteicl, pblt, therm, trmb1, trmb2, trmb3, plcl, &
16 fqcalving, ffonte, run_off_lic_0, flux_o, flux_g, tslab, seaice)
17
18 ! From phylmd/clmain.F, version 1.6 2005/11/16 14:47:19
19 ! Author: Z. X. Li (LMD/CNRS), date: 1993/08/18
20 ! Objet : interface de couche limite (diffusion verticale)
21
22 ! Tout ce qui a trait aux traceurs est dans "phytrac". Le calcul
23 ! de la couche limite pour les traceurs se fait avec "cltrac" et
24 ! ne tient pas compte de la différentiation des sous-fractions de
25 ! sol.
26
27 ! Pour pouvoir extraire les coefficients d'échanges et le vent
28 ! dans la première couche, trois champs ont été créés : "zcoefh",
29 ! "zu1" et "zv1". Nous avons moyenné les valeurs de ces trois
30 ! champs sur les quatre sous-surfaces du modèle.
31
32 use calendar, ONLY: ymds2ju
33 use clqh_m, only: clqh
34 use clvent_m, only: clvent
35 use coefkz_m, only: coefkz
36 use coefkzmin_m, only: coefkzmin
37 USE conf_gcm_m, ONLY: prt_level
38 USE conf_phys_m, ONLY: iflag_pbl
39 USE dimens_m, ONLY: iim, jjm
40 USE dimphy, ONLY: klev, klon, zmasq
41 USE dimsoil, ONLY: nsoilmx
42 USE dynetat0_m, ONLY: day_ini
43 USE gath_cpl, ONLY: gath2cpl
44 use hbtm_m, only: hbtm
45 USE histbeg_totreg_m, ONLY: histbeg_totreg
46 USE histdef_m, ONLY: histdef
47 USE histend_m, ONLY: histend
48 USE histsync_m, ONLY: histsync
49 use histwrite_m, only: histwrite
50 USE indicesol, ONLY: epsfra, is_lic, is_oce, is_sic, is_ter, nbsrf
51 USE suphec_m, ONLY: rd, rg, rkappa
52 USE temps, ONLY: annee_ref, itau_phy
53 use ustarhb_m, only: ustarhb
54 use vdif_kcay_m, only: vdif_kcay
55 use yamada4_m, only: yamada4
56
57 ! Arguments:
58
59 REAL, INTENT(IN):: dtime ! interval du temps (secondes)
60 INTEGER, INTENT(IN):: itap ! numero du pas de temps
61 REAL, INTENT(IN):: date0 ! jour initial
62 REAL, INTENT(inout):: pctsrf(klon, nbsrf)
63
64 ! la nouvelle repartition des surfaces sortie de l'interface
65 REAL, INTENT(out):: pctsrf_new(klon, nbsrf)
66
67 REAL, INTENT(IN):: t(klon, klev) ! temperature (K)
68 REAL, INTENT(IN):: q(klon, klev) ! vapeur d'eau (kg/kg)
69 REAL, INTENT(IN):: u(klon, klev), v(klon, klev) ! vitesse
70 INTEGER, INTENT(IN):: jour ! jour de l'annee en cours
71 REAL, intent(in):: rmu0(klon) ! cosinus de l'angle solaire zenithal
72 REAL, INTENT(IN):: paprs(klon, klev+1) ! pression a intercouche (Pa)
73 REAL, INTENT(IN):: pplay(klon, klev) ! pression au milieu de couche (Pa)
74 REAL, INTENT(IN):: rlon(klon)
75 REAL, INTENT(IN):: rlat(klon) ! latitude en degrés
76 REAL cufi(klon), cvfi(klon)
77 ! cufi-----input-R- resolution des mailles en x (m)
78 ! cvfi-----input-R- resolution des mailles en y (m)
79 REAL d_t(klon, klev), d_q(klon, klev)
80 ! d_t------output-R- le changement pour "t"
81 ! d_q------output-R- le changement pour "q"
82
83 REAL, intent(out):: d_u(klon, klev), d_v(klon, klev)
84 ! changement pour "u" et "v"
85
86 REAL flux_t(klon, klev, nbsrf), flux_q(klon, klev, nbsrf)
87 ! flux_t---output-R- flux de chaleur sensible (CpT) J/m**2/s (W/m**2)
88 ! (orientation positive vers le bas)
89 ! flux_q---output-R- flux de vapeur d'eau (kg/m**2/s)
90 REAL dflux_t(klon), dflux_q(klon)
91 ! dflux_t derive du flux sensible
92 ! dflux_q derive du flux latent
93 !IM "slab" ocean
94 REAL flux_o(klon), flux_g(klon)
95 !IM "slab" ocean
96 ! flux_g---output-R- flux glace (pour OCEAN='slab ')
97 ! flux_o---output-R- flux ocean (pour OCEAN='slab ')
98 REAL y_flux_o(klon), y_flux_g(klon)
99 REAL tslab(klon), ytslab(klon)
100 ! tslab-in/output-R temperature du slab ocean (en Kelvin)
101 ! uniqmnt pour slab
102 REAL seaice(klon), y_seaice(klon)
103 ! seaice---output-R- glace de mer (kg/m2) (pour OCEAN='slab ')
104 REAL y_fqcalving(klon), y_ffonte(klon)
105 REAL fqcalving(klon, nbsrf), ffonte(klon, nbsrf)
106 ! ffonte----Flux thermique utilise pour fondre la neige
107 ! fqcalving-Flux d'eau "perdue" par la surface et necessaire pour limiter la
108 ! hauteur de neige, en kg/m2/s
109 REAL run_off_lic_0(klon), y_run_off_lic_0(klon)
110
111 REAL flux_u(klon, klev, nbsrf), flux_v(klon, klev, nbsrf)
112 ! flux_u---output-R- tension du vent X: (kg m/s)/(m**2 s) ou Pascal
113 ! flux_v---output-R- tension du vent Y: (kg m/s)/(m**2 s) ou Pascal
114 REAL rugmer(klon), agesno(klon, nbsrf)
115 REAL, INTENT(IN):: rugoro(klon)
116 REAL, INTENT(out):: cdragh(klon), cdragm(klon)
117 ! taux CO2 atmosphere
118 REAL co2_ppm
119 LOGICAL, INTENT(IN):: debut
120 LOGICAL, INTENT(IN):: lafin
121 LOGICAL ok_veget
122 CHARACTER(len=*), INTENT(IN):: ocean
123 INTEGER npas, nexca
124
125 REAL ts(klon, nbsrf)
126 ! ts-------input-R- temperature du sol (en Kelvin)
127 REAL d_ts(klon, nbsrf)
128 ! d_ts-----output-R- le changement pour "ts"
129 REAL snow(klon, nbsrf)
130 REAL qsurf(klon, nbsrf)
131 REAL evap(klon, nbsrf)
132 REAL albe(klon, nbsrf)
133 REAL alblw(klon, nbsrf)
134
135 REAL fluxlat(klon, nbsrf)
136
137 REAL, intent(in):: rain_fall(klon), snow_f(klon)
138 REAL fder(klon)
139
140 REAL sollw(klon, nbsrf), solsw(klon, nbsrf), sollwdown(klon)
141 REAL rugos(klon, nbsrf)
142 ! rugos----input-R- longeur de rugosite (en m)
143
144 REAL zcoefh(klon, klev)
145 REAL zu1(klon)
146 REAL zv1(klon)
147
148 !$$$ PB ajout pour soil
149 LOGICAL, INTENT(IN):: soil_model
150 !IM ajout seuils cdrm, cdrh
151 REAL cdmmax, cdhmax
152
153 REAL ksta, ksta_ter
154 LOGICAL ok_kzmin
155
156 REAL ftsoil(klon, nsoilmx, nbsrf)
157 REAL ytsoil(klon, nsoilmx)
158 REAL qsol(klon)
159
160 REAL yts(klon), yrugos(klon), ypct(klon), yz0_new(klon)
161 REAL yalb(klon)
162 REAL yalblw(klon)
163 REAL yu1(klon), yv1(klon)
164 ! on rajoute en output yu1 et yv1 qui sont les vents dans
165 ! la premiere couche
166 REAL ysnow(klon), yqsurf(klon), yagesno(klon), yqsol(klon)
167 REAL yrain_f(klon), ysnow_f(klon)
168 REAL ysollw(klon), ysolsw(klon), ysollwdown(klon)
169 REAL yfder(klon), ytaux(klon), ytauy(klon)
170 REAL yrugm(klon), yrads(klon), yrugoro(klon)
171
172 REAL yfluxlat(klon)
173
174 REAL y_d_ts(klon)
175 REAL y_d_t(klon, klev), y_d_q(klon, klev)
176 REAL y_d_u(klon, klev), y_d_v(klon, klev)
177 REAL y_flux_t(klon, klev), y_flux_q(klon, klev)
178 REAL y_flux_u(klon, klev), y_flux_v(klon, klev)
179 REAL y_dflux_t(klon), y_dflux_q(klon)
180 REAL coefh(klon, klev), coefm(klon, klev)
181 REAL yu(klon, klev), yv(klon, klev)
182 REAL yt(klon, klev), yq(klon, klev)
183 REAL ypaprs(klon, klev+1), ypplay(klon, klev), ydelp(klon, klev)
184
185 LOGICAL ok_nonloc
186 PARAMETER (ok_nonloc=.FALSE.)
187 REAL ycoefm0(klon, klev), ycoefh0(klon, klev)
188
189 REAL yzlay(klon, klev), yzlev(klon, klev+1), yteta(klon, klev)
190 REAL ykmm(klon, klev+1), ykmn(klon, klev+1)
191 REAL ykmq(klon, klev+1)
192 REAL yq2(klon, klev+1), q2(klon, klev+1, nbsrf)
193 REAL q2diag(klon, klev+1)
194
195 REAL u1lay(klon), v1lay(klon)
196 REAL delp(klon, klev)
197 INTEGER i, k, nsrf
198
199 INTEGER ni(klon), knon, j
200
201 REAL pctsrf_pot(klon, nbsrf)
202 ! "pourcentage potentiel" pour tenir compte des éventuelles
203 ! apparitions ou disparitions de la glace de mer
204
205 REAL zx_alf1, zx_alf2 !valeur ambiante par extrapola.
206
207 ! maf pour sorties IOISPL en cas de debugagage
208
209 CHARACTER(80) cldebug
210 SAVE cldebug
211 CHARACTER(8) cl_surf(nbsrf)
212 SAVE cl_surf
213 INTEGER nhoridbg, nidbg
214 SAVE nhoridbg, nidbg
215 INTEGER ndexbg(iim*(jjm+1))
216 REAL zx_lon(iim, jjm+1), zx_lat(iim, jjm+1), zjulian
217 REAL tabindx(klon)
218 REAL debugtab(iim, jjm+1)
219 LOGICAL first_appel
220 SAVE first_appel
221 DATA first_appel/ .TRUE./
222 LOGICAL:: debugindex = .FALSE.
223 INTEGER idayref
224 REAL t2m(klon, nbsrf), q2m(klon, nbsrf)
225 REAL u10m(klon, nbsrf), v10m(klon, nbsrf)
226
227 REAL yt2m(klon), yq2m(klon), yu10m(klon)
228 REAL yustar(klon)
229 ! -- LOOP
230 REAL yu10mx(klon)
231 REAL yu10my(klon)
232 REAL ywindsp(klon)
233 ! -- LOOP
234
235 REAL yt10m(klon), yq10m(klon)
236 !IM cf. AM : pbl, hbtm (Comme les autres diagnostics on cumule ds
237 ! physiq ce qui permet de sortir les grdeurs par sous surface)
238 REAL pblh(klon, nbsrf)
239 ! pblh------- HCL
240 REAL plcl(klon, nbsrf)
241 REAL capcl(klon, nbsrf)
242 REAL oliqcl(klon, nbsrf)
243 REAL cteicl(klon, nbsrf)
244 REAL pblt(klon, nbsrf)
245 ! pblT------- T au nveau HCL
246 REAL therm(klon, nbsrf)
247 REAL trmb1(klon, nbsrf)
248 ! trmb1-------deep_cape
249 REAL trmb2(klon, nbsrf)
250 ! trmb2--------inhibition
251 REAL trmb3(klon, nbsrf)
252 ! trmb3-------Point Omega
253 REAL ypblh(klon)
254 REAL ylcl(klon)
255 REAL ycapcl(klon)
256 REAL yoliqcl(klon)
257 REAL ycteicl(klon)
258 REAL ypblt(klon)
259 REAL ytherm(klon)
260 REAL ytrmb1(klon)
261 REAL ytrmb2(klon)
262 REAL ytrmb3(klon)
263 REAL uzon(klon), vmer(klon)
264 REAL tair1(klon), qair1(klon), tairsol(klon)
265 REAL psfce(klon), patm(klon)
266
267 REAL qairsol(klon), zgeo1(klon)
268 REAL rugo1(klon)
269
270 ! utiliser un jeu de fonctions simples
271 LOGICAL zxli
272 PARAMETER (zxli=.FALSE.)
273
274 REAL zt, zqs, zdelta, zcor
275 REAL t_coup
276 PARAMETER (t_coup=273.15)
277
278 CHARACTER(len=20):: modname = 'clmain'
279
280 !------------------------------------------------------------
281
282 ytherm = 0.
283
284 IF (debugindex .AND. first_appel) THEN
285 first_appel = .FALSE.
286
287 ! initialisation sorties netcdf
288
289 idayref = day_ini
290 CALL ymds2ju(annee_ref, 1, idayref, 0., zjulian)
291 CALL gr_fi_ecrit(1, klon, iim, jjm+1, rlon, zx_lon)
292 DO i = 1, iim
293 zx_lon(i, 1) = rlon(i+1)
294 zx_lon(i, jjm+1) = rlon(i+1)
295 END DO
296 CALL gr_fi_ecrit(1, klon, iim, jjm+1, rlat, zx_lat)
297 cldebug = 'sous_index'
298 CALL histbeg_totreg(cldebug, zx_lon(:, 1), zx_lat(1, :), 1, &
299 iim, 1, jjm+1, itau_phy, zjulian, dtime, nhoridbg, nidbg)
300 ! no vertical axis
301 cl_surf(1) = 'ter'
302 cl_surf(2) = 'lic'
303 cl_surf(3) = 'oce'
304 cl_surf(4) = 'sic'
305 DO nsrf = 1, nbsrf
306 CALL histdef(nidbg, cl_surf(nsrf), cl_surf(nsrf), '-', iim, jjm+1, &
307 nhoridbg, 1, 1, 1, -99, 'inst', dtime, dtime)
308 END DO
309 CALL histend(nidbg)
310 CALL histsync(nidbg)
311 END IF
312
313 DO k = 1, klev ! epaisseur de couche
314 DO i = 1, klon
315 delp(i, k) = paprs(i, k) - paprs(i, k+1)
316 END DO
317 END DO
318 DO i = 1, klon ! vent de la premiere couche
319 zx_alf1 = 1.0
320 zx_alf2 = 1.0 - zx_alf1
321 u1lay(i) = u(i, 1)*zx_alf1 + u(i, 2)*zx_alf2
322 v1lay(i) = v(i, 1)*zx_alf1 + v(i, 2)*zx_alf2
323 END DO
324
325 ! Initialization:
326 rugmer = 0.
327 cdragh = 0.
328 cdragm = 0.
329 dflux_t = 0.
330 dflux_q = 0.
331 zu1 = 0.
332 zv1 = 0.
333 ypct = 0.
334 yts = 0.
335 ysnow = 0.
336 yqsurf = 0.
337 yalb = 0.
338 yalblw = 0.
339 yrain_f = 0.
340 ysnow_f = 0.
341 yfder = 0.
342 ytaux = 0.
343 ytauy = 0.
344 ysolsw = 0.
345 ysollw = 0.
346 ysollwdown = 0.
347 yrugos = 0.
348 yu1 = 0.
349 yv1 = 0.
350 yrads = 0.
351 ypaprs = 0.
352 ypplay = 0.
353 ydelp = 0.
354 yu = 0.
355 yv = 0.
356 yt = 0.
357 yq = 0.
358 pctsrf_new = 0.
359 y_flux_u = 0.
360 y_flux_v = 0.
361 !$$ PB
362 y_dflux_t = 0.
363 y_dflux_q = 0.
364 ytsoil = 999999.
365 yrugoro = 0.
366 ! -- LOOP
367 yu10mx = 0.
368 yu10my = 0.
369 ywindsp = 0.
370 ! -- LOOP
371 d_ts = 0.
372 !§§§ PB
373 yfluxlat = 0.
374 flux_t = 0.
375 flux_q = 0.
376 flux_u = 0.
377 flux_v = 0.
378 d_t = 0.
379 d_q = 0.
380 d_u = 0.
381 d_v = 0.
382 zcoefh = 0.
383
384 ! Boucler sur toutes les sous-fractions du sol:
385
386 ! Initialisation des "pourcentages potentiels". On considère ici qu'on
387 ! peut avoir potentiellement de la glace sur tout le domaine océanique
388 ! (à affiner)
389
390 pctsrf_pot = pctsrf
391 pctsrf_pot(:, is_oce) = 1. - zmasq
392 pctsrf_pot(:, is_sic) = 1. - zmasq
393
394 loop_surface: DO nsrf = 1, nbsrf
395 ! Chercher les indices :
396 ni = 0
397 knon = 0
398 DO i = 1, klon
399 ! Pour déterminer le domaine à traiter, on utilise les surfaces
400 ! "potentielles"
401 IF (pctsrf_pot(i, nsrf) > epsfra) THEN
402 knon = knon + 1
403 ni(knon) = i
404 END IF
405 END DO
406
407 ! variables pour avoir une sortie IOIPSL des INDEX
408 IF (debugindex) THEN
409 tabindx = 0.
410 DO i = 1, knon
411 tabindx(i) = real(i)
412 END DO
413 debugtab = 0.
414 ndexbg = 0
415 CALL gath2cpl(tabindx, debugtab, klon, knon, iim, jjm, ni)
416 CALL histwrite(nidbg, cl_surf(nsrf), itap, debugtab)
417 END IF
418
419 if_knon: IF (knon /= 0) then
420 DO j = 1, knon
421 i = ni(j)
422 ypct(j) = pctsrf(i, nsrf)
423 yts(j) = ts(i, nsrf)
424 ytslab(i) = tslab(i)
425 ysnow(j) = snow(i, nsrf)
426 yqsurf(j) = qsurf(i, nsrf)
427 yalb(j) = albe(i, nsrf)
428 yalblw(j) = alblw(i, nsrf)
429 yrain_f(j) = rain_fall(i)
430 ysnow_f(j) = snow_f(i)
431 yagesno(j) = agesno(i, nsrf)
432 yfder(j) = fder(i)
433 ytaux(j) = flux_u(i, 1, nsrf)
434 ytauy(j) = flux_v(i, 1, nsrf)
435 ysolsw(j) = solsw(i, nsrf)
436 ysollw(j) = sollw(i, nsrf)
437 ysollwdown(j) = sollwdown(i)
438 yrugos(j) = rugos(i, nsrf)
439 yrugoro(j) = rugoro(i)
440 yu1(j) = u1lay(i)
441 yv1(j) = v1lay(i)
442 yrads(j) = ysolsw(j) + ysollw(j)
443 ypaprs(j, klev+1) = paprs(i, klev+1)
444 y_run_off_lic_0(j) = run_off_lic_0(i)
445 yu10mx(j) = u10m(i, nsrf)
446 yu10my(j) = v10m(i, nsrf)
447 ywindsp(j) = sqrt(yu10mx(j)*yu10mx(j)+yu10my(j)*yu10my(j))
448 END DO
449
450 ! IF bucket model for continent, copy soil water content
451 IF (nsrf == is_ter .AND. .NOT. ok_veget) THEN
452 DO j = 1, knon
453 i = ni(j)
454 yqsol(j) = qsol(i)
455 END DO
456 ELSE
457 yqsol = 0.
458 END IF
459
460 DO k = 1, nsoilmx
461 DO j = 1, knon
462 i = ni(j)
463 ytsoil(j, k) = ftsoil(i, k, nsrf)
464 END DO
465 END DO
466
467 DO k = 1, klev
468 DO j = 1, knon
469 i = ni(j)
470 ypaprs(j, k) = paprs(i, k)
471 ypplay(j, k) = pplay(i, k)
472 ydelp(j, k) = delp(i, k)
473 yu(j, k) = u(i, k)
474 yv(j, k) = v(i, k)
475 yt(j, k) = t(i, k)
476 yq(j, k) = q(i, k)
477 END DO
478 END DO
479
480 ! calculer Cdrag et les coefficients d'echange
481 CALL coefkz(nsrf, knon, ypaprs, ypplay, ksta, ksta_ter, yts, yrugos, &
482 yu, yv, yt, yq, yqsurf, coefm(:knon, :), coefh(:knon, :))
483 IF (iflag_pbl == 1) THEN
484 CALL coefkz2(nsrf, knon, ypaprs, ypplay, yt, ycoefm0, ycoefh0)
485 coefm(:knon, :) = max(coefm(:knon, :), ycoefm0(:knon, :))
486 coefh(:knon, :) = max(coefh(:knon, :), ycoefh0(:knon, :))
487 END IF
488
489 ! on seuille coefm et coefh
490 IF (nsrf == is_oce) THEN
491 coefm(:knon, 1) = min(coefm(:knon, 1), cdmmax)
492 coefh(:knon, 1) = min(coefh(:knon, 1), cdhmax)
493 END IF
494
495 IF (ok_kzmin) THEN
496 ! Calcul d'une diffusion minimale pour les conditions tres stables
497 CALL coefkzmin(knon, ypaprs, ypplay, yu, yv, yt, yq, &
498 coefm(:, 1), ycoefm0, ycoefh0)
499 coefm(:knon, :) = max(coefm(:knon, :), ycoefm0(:knon, :))
500 coefh(:knon, :) = max(coefh(:knon, :), ycoefh0(:knon, :))
501 END IF
502
503 IF (iflag_pbl >= 3) THEN
504 ! MELLOR ET YAMADA adapté à Mars, Richard Fournier et
505 ! Frédéric Hourdin
506 yzlay(:knon, 1) = rd * yt(:knon, 1) / (0.5 * (ypaprs(:knon, 1) &
507 + ypplay(:knon, 1))) &
508 * (ypaprs(:knon, 1) - ypplay(:knon, 1)) / rg
509 DO k = 2, klev
510 yzlay(1:knon, k) = yzlay(1:knon, k-1) &
511 + rd * 0.5 * (yt(1:knon, k-1) + yt(1:knon, k)) &
512 / ypaprs(1:knon, k) &
513 * (ypplay(1:knon, k-1) - ypplay(1:knon, k)) / rg
514 END DO
515 DO k = 1, klev
516 yteta(1:knon, k) = yt(1:knon, k)*(ypaprs(1:knon, 1) &
517 / ypplay(1:knon, k))**rkappa * (1.+0.61*yq(1:knon, k))
518 END DO
519 yzlev(1:knon, 1) = 0.
520 yzlev(:knon, klev+1) = 2. * yzlay(:knon, klev) &
521 - yzlay(:knon, klev - 1)
522 DO k = 2, klev
523 yzlev(1:knon, k) = 0.5*(yzlay(1:knon, k)+yzlay(1:knon, k-1))
524 END DO
525 DO k = 1, klev + 1
526 DO j = 1, knon
527 i = ni(j)
528 yq2(j, k) = q2(i, k, nsrf)
529 END DO
530 END DO
531
532 CALL ustarhb(knon, yu, yv, coefm(:knon, 1), yustar)
533
534 IF (prt_level > 9) THEN
535 PRINT *, 'USTAR = ', yustar
536 END IF
537
538 ! iflag_pbl peut être utilisé comme longueur de mélange
539
540 IF (iflag_pbl >= 11) THEN
541 CALL vdif_kcay(knon, dtime, rg, rd, ypaprs, yt, yzlev, yzlay, &
542 yu, yv, yteta, coefm(:knon, 1), yq2, q2diag, ykmm, ykmn, &
543 yustar, iflag_pbl)
544 ELSE
545 CALL yamada4(knon, dtime, rg, yzlev, yzlay, yu, yv, yteta, &
546 coefm(:knon, 1), yq2, ykmm, ykmn, ykmq, yustar, iflag_pbl)
547 END IF
548
549 coefm(:knon, 2:) = ykmm(:knon, 2:klev)
550 coefh(:knon, 2:) = ykmn(:knon, 2:klev)
551 END IF
552
553 ! calculer la diffusion des vitesses "u" et "v"
554 CALL clvent(knon, dtime, yu1, yv1, coefm, yt, yu, ypaprs, ypplay, &
555 ydelp, y_d_u, y_flux_u)
556 CALL clvent(knon, dtime, yu1, yv1, coefm, yt, yv, ypaprs, ypplay, &
557 ydelp, y_d_v, y_flux_v)
558
559 ! pour le couplage
560 ytaux = y_flux_u(:, 1)
561 ytauy = y_flux_v(:, 1)
562
563 ! calculer la diffusion de "q" et de "h"
564 CALL clqh(dtime, itap, date0, jour, debut, lafin, rlon, rlat, &
565 cufi, cvfi, knon, nsrf, ni, pctsrf, soil_model, ytsoil, &
566 yqsol, ok_veget, ocean, npas, nexca, rmu0, co2_ppm, yrugos, &
567 yrugoro, yu1, yv1, coefh, yt, yq, yts, ypaprs, ypplay, &
568 ydelp, yrads, yalb, yalblw, ysnow, yqsurf, yrain_f, ysnow_f, &
569 yfder, ytaux, ytauy, ywindsp, ysollw, ysollwdown, ysolsw, &
570 yfluxlat, pctsrf_new, yagesno, y_d_t, y_d_q, y_d_ts, &
571 yz0_new, y_flux_t, y_flux_q, y_dflux_t, y_dflux_q, &
572 y_fqcalving, y_ffonte, y_run_off_lic_0, y_flux_o, y_flux_g, &
573 ytslab, y_seaice)
574
575 ! calculer la longueur de rugosite sur ocean
576 yrugm = 0.
577 IF (nsrf == is_oce) THEN
578 DO j = 1, knon
579 yrugm(j) = 0.018*coefm(j, 1)*(yu1(j)**2+yv1(j)**2)/rg + &
580 0.11*14E-6/sqrt(coefm(j, 1)*(yu1(j)**2+yv1(j)**2))
581 yrugm(j) = max(1.5E-05, yrugm(j))
582 END DO
583 END IF
584 DO j = 1, knon
585 y_dflux_t(j) = y_dflux_t(j)*ypct(j)
586 y_dflux_q(j) = y_dflux_q(j)*ypct(j)
587 yu1(j) = yu1(j)*ypct(j)
588 yv1(j) = yv1(j)*ypct(j)
589 END DO
590
591 DO k = 1, klev
592 DO j = 1, knon
593 i = ni(j)
594 coefh(j, k) = coefh(j, k)*ypct(j)
595 coefm(j, k) = coefm(j, k)*ypct(j)
596 y_d_t(j, k) = y_d_t(j, k)*ypct(j)
597 y_d_q(j, k) = y_d_q(j, k)*ypct(j)
598 flux_t(i, k, nsrf) = y_flux_t(j, k)
599 flux_q(i, k, nsrf) = y_flux_q(j, k)
600 flux_u(i, k, nsrf) = y_flux_u(j, k)
601 flux_v(i, k, nsrf) = y_flux_v(j, k)
602 y_d_u(j, k) = y_d_u(j, k)*ypct(j)
603 y_d_v(j, k) = y_d_v(j, k)*ypct(j)
604 END DO
605 END DO
606
607 evap(:, nsrf) = -flux_q(:, 1, nsrf)
608
609 albe(:, nsrf) = 0.
610 alblw(:, nsrf) = 0.
611 snow(:, nsrf) = 0.
612 qsurf(:, nsrf) = 0.
613 rugos(:, nsrf) = 0.
614 fluxlat(:, nsrf) = 0.
615 DO j = 1, knon
616 i = ni(j)
617 d_ts(i, nsrf) = y_d_ts(j)
618 albe(i, nsrf) = yalb(j)
619 alblw(i, nsrf) = yalblw(j)
620 snow(i, nsrf) = ysnow(j)
621 qsurf(i, nsrf) = yqsurf(j)
622 rugos(i, nsrf) = yz0_new(j)
623 fluxlat(i, nsrf) = yfluxlat(j)
624 IF (nsrf == is_oce) THEN
625 rugmer(i) = yrugm(j)
626 rugos(i, nsrf) = yrugm(j)
627 END IF
628 agesno(i, nsrf) = yagesno(j)
629 fqcalving(i, nsrf) = y_fqcalving(j)
630 ffonte(i, nsrf) = y_ffonte(j)
631 cdragh(i) = cdragh(i) + coefh(j, 1)
632 cdragm(i) = cdragm(i) + coefm(j, 1)
633 dflux_t(i) = dflux_t(i) + y_dflux_t(j)
634 dflux_q(i) = dflux_q(i) + y_dflux_q(j)
635 zu1(i) = zu1(i) + yu1(j)
636 zv1(i) = zv1(i) + yv1(j)
637 END DO
638 IF (nsrf == is_ter) THEN
639 DO j = 1, knon
640 i = ni(j)
641 qsol(i) = yqsol(j)
642 END DO
643 END IF
644 IF (nsrf == is_lic) THEN
645 DO j = 1, knon
646 i = ni(j)
647 run_off_lic_0(i) = y_run_off_lic_0(j)
648 END DO
649 END IF
650 !$$$ PB ajout pour soil
651 ftsoil(:, :, nsrf) = 0.
652 DO k = 1, nsoilmx
653 DO j = 1, knon
654 i = ni(j)
655 ftsoil(i, k, nsrf) = ytsoil(j, k)
656 END DO
657 END DO
658
659 DO j = 1, knon
660 i = ni(j)
661 DO k = 1, klev
662 d_t(i, k) = d_t(i, k) + y_d_t(j, k)
663 d_q(i, k) = d_q(i, k) + y_d_q(j, k)
664 d_u(i, k) = d_u(i, k) + y_d_u(j, k)
665 d_v(i, k) = d_v(i, k) + y_d_v(j, k)
666 zcoefh(i, k) = zcoefh(i, k) + coefh(j, k)
667 END DO
668 END DO
669
670 !cc diagnostic t, q a 2m et u, v a 10m
671
672 DO j = 1, knon
673 i = ni(j)
674 uzon(j) = yu(j, 1) + y_d_u(j, 1)
675 vmer(j) = yv(j, 1) + y_d_v(j, 1)
676 tair1(j) = yt(j, 1) + y_d_t(j, 1)
677 qair1(j) = yq(j, 1) + y_d_q(j, 1)
678 zgeo1(j) = rd*tair1(j)/(0.5*(ypaprs(j, 1)+ypplay(j, &
679 1)))*(ypaprs(j, 1)-ypplay(j, 1))
680 tairsol(j) = yts(j) + y_d_ts(j)
681 rugo1(j) = yrugos(j)
682 IF (nsrf == is_oce) THEN
683 rugo1(j) = rugos(i, nsrf)
684 END IF
685 psfce(j) = ypaprs(j, 1)
686 patm(j) = ypplay(j, 1)
687
688 qairsol(j) = yqsurf(j)
689 END DO
690
691 CALL stdlevvar(klon, knon, nsrf, zxli, uzon, vmer, tair1, qair1, &
692 zgeo1, tairsol, qairsol, rugo1, psfce, patm, yt2m, yq2m, &
693 yt10m, yq10m, yu10m, yustar)
694
695 DO j = 1, knon
696 i = ni(j)
697 t2m(i, nsrf) = yt2m(j)
698 q2m(i, nsrf) = yq2m(j)
699
700 ! u10m, v10m : composantes du vent a 10m sans spirale de Ekman
701 u10m(i, nsrf) = (yu10m(j)*uzon(j))/sqrt(uzon(j)**2+vmer(j)**2)
702 v10m(i, nsrf) = (yu10m(j)*vmer(j))/sqrt(uzon(j)**2+vmer(j)**2)
703
704 END DO
705
706 CALL hbtm(knon, ypaprs, ypplay, yt2m, yt10m, yq2m, yq10m, yustar, &
707 y_flux_t, y_flux_q, yu, yv, yt, yq, ypblh, ycapcl, yoliqcl, &
708 ycteicl, ypblt, ytherm, ytrmb1, ytrmb2, ytrmb3, ylcl)
709
710 DO j = 1, knon
711 i = ni(j)
712 pblh(i, nsrf) = ypblh(j)
713 plcl(i, nsrf) = ylcl(j)
714 capcl(i, nsrf) = ycapcl(j)
715 oliqcl(i, nsrf) = yoliqcl(j)
716 cteicl(i, nsrf) = ycteicl(j)
717 pblt(i, nsrf) = ypblt(j)
718 therm(i, nsrf) = ytherm(j)
719 trmb1(i, nsrf) = ytrmb1(j)
720 trmb2(i, nsrf) = ytrmb2(j)
721 trmb3(i, nsrf) = ytrmb3(j)
722 END DO
723
724 DO j = 1, knon
725 DO k = 1, klev + 1
726 i = ni(j)
727 q2(i, k, nsrf) = yq2(j, k)
728 END DO
729 END DO
730 !IM "slab" ocean
731 IF (nsrf == is_oce) THEN
732 DO j = 1, knon
733 ! on projette sur la grille globale
734 i = ni(j)
735 IF (pctsrf_new(i, is_oce)>epsfra) THEN
736 flux_o(i) = y_flux_o(j)
737 ELSE
738 flux_o(i) = 0.
739 END IF
740 END DO
741 END IF
742
743 IF (nsrf == is_sic) THEN
744 DO j = 1, knon
745 i = ni(j)
746 ! On pondère lorsque l'on fait le bilan au sol :
747 IF (pctsrf_new(i, is_sic)>epsfra) THEN
748 flux_g(i) = y_flux_g(j)
749 ELSE
750 flux_g(i) = 0.
751 END IF
752 END DO
753
754 END IF
755 IF (ocean == 'slab ') THEN
756 IF (nsrf == is_oce) THEN
757 tslab(1:klon) = ytslab(1:klon)
758 seaice(1:klon) = y_seaice(1:klon)
759 END IF
760 END IF
761 end IF if_knon
762 END DO loop_surface
763
764 ! On utilise les nouvelles surfaces
765
766 rugos(:, is_oce) = rugmer
767 pctsrf = pctsrf_new
768
769 END SUBROUTINE clmain
770
771 end module clmain_m

  ViewVC Help
Powered by ViewVC 1.1.21