/[lmdze]/trunk/dyn3d/bilan_dyn.f
ViewVC logotype

Contents of /trunk/dyn3d/bilan_dyn.f

Parent Directory Parent Directory | Revision Log Revision Log


Revision 55 - (show annotations)
Mon Dec 12 13:25:01 2011 UTC (12 years, 5 months ago) by guez
Original Path: trunk/libf/dyn3d/bilan_dyn.f90
File size: 12461 byte(s)
-- In procedure "bilan_dyn", replaced average of "zvq" by integral of
"zvq", following a comment of Francis Codron :

Le calcul actuel donne des unités peu pratiques : transports de
chaleur en K m / s par exemple. C'est bien pour les sorties à 2
dimensions, latitude et pression, car alors le transport ne dépend pas
de l'espacement des niveaux, mieux pour comparer ou tracer en latitude
et pression. Par contre, quand on somme sur la verticale, on
préfèrerait avoir des transports d'énergie en watts, ou au moins an K
kg / s (à multiplier par "Cp" ou "L"). On doit pouvoir recalculer le
transport intégré à partir des fichiers de sortie, mais c'est embêtant
(calcul de "cv").

-- Gathered files in directory Dissipation.

1 module bilan_dyn_m
2
3 IMPLICIT NONE
4
5 contains
6
7 SUBROUTINE bilan_dyn(ps, masse, pk, flux_u, flux_v, teta, phi, ucov, vcov, &
8 trac, dt_app, dt_cum)
9
10 ! From LMDZ4/libf/dyn3d/bilan_dyn.F, version 1.5 2005/03/16
11 ! 10:12:17 fairhead
12
13 ! Sous-programme consacré à des diagnostics dynamiques de base.
14 ! De façon générale, les moyennes des scalaires Q sont pondérées
15 ! par la masse. Les flux de masse sont, eux, simplement moyennés.
16
17 USE histcom, ONLY: histbeg_totreg, histdef, histend, histvert
18 USE calendar, ONLY: ymds2ju
19 USE histwrite_m, ONLY: histwrite
20 USE dimens_m, ONLY: iim, jjm, llm
21 USE paramet_m, ONLY: iip1, jjp1
22 USE comconst, ONLY: cpp
23 USE comvert, ONLY: presnivs
24 USE comgeom, ONLY: constang_2d, cu_2d, cv_2d, rlatv
25 USE temps, ONLY: annee_ref, day_ref, itau_dyn
26 USE inigrads_m, ONLY: inigrads
27 USE nr_util, ONLY: pi
28
29 ! Arguments:
30
31 real, intent(in):: dt_app, dt_cum
32 real ps(iip1, jjp1)
33 real masse(iip1, jjp1, llm), pk(iip1, jjp1, llm)
34 real flux_u(iip1, jjp1, llm)
35 real flux_v(iip1, jjm, llm)
36 real, intent(in):: teta(iip1, jjp1, llm)
37 real phi(iip1, jjp1, llm)
38 real ucov(iip1, jjp1, llm)
39 real vcov(iip1, jjm, llm)
40 real, intent(in):: trac(:, :, :) ! (iim + 1, jjm + 1, llm)
41
42 ! Local:
43
44 integer:: icum = 0
45 integer, save:: ncum
46 logical:: first = .true.
47 real zz, zqy, zfactv(jjm, llm)
48
49 integer, parameter:: nQ = 7
50 character(len=4), parameter:: nom(nQ) = (/'T ', 'gz ', 'K ', 'ang ', &
51 'u ', 'ovap', 'un '/)
52 character(len=5), parameter:: unites(nQ) = (/'K ', 'm2/s2', 'm2/s2', &
53 'ang ', 'm/s ', 'kg/kg', 'un '/)
54
55 real:: time = 0.
56 integer:: itau = 0
57 real ww
58
59 ! Variables dynamiques intermédiaires
60 REAL vcont(iip1, jjm, llm), ucont(iip1, jjp1, llm)
61 REAL ang(iip1, jjp1, llm), unat(iip1, jjp1, llm)
62 REAL massebx(iip1, jjp1, llm), masseby(iip1, jjm, llm)
63 REAL w(iip1, jjp1, llm), ecin(iip1, jjp1, llm), convm(iip1, jjp1, llm)
64
65 ! Champ contenant les scalaires advectés
66 real Q(iip1, jjp1, llm, nQ)
67
68 ! Champs cumulés
69 real, save:: ps_cum(iip1, jjp1)
70 real, save:: masse_cum(iip1, jjp1, llm)
71 real, save:: flux_u_cum(iip1, jjp1, llm)
72 real, save:: flux_v_cum(iip1, jjm, llm)
73 real, save:: Q_cum(iip1, jjp1, llm, nQ)
74 real, save:: flux_uQ_cum(iip1, jjp1, llm, nQ)
75 real, save:: flux_vQ_cum(iip1, jjm, llm, nQ)
76 real dQ(iip1, jjp1, llm, nQ)
77
78 ! champs de tansport en moyenne zonale
79 integer itr
80 integer, parameter:: ntr = 5
81
82 character(len=10), save:: znom(ntr, nQ)
83 character(len=26), save:: znoml(ntr, nQ)
84 character(len=12), save:: zunites(ntr, nQ)
85
86 integer, parameter:: iave = 1, itot = 2, immc = 3, itrs = 4, istn = 5
87 character(len=3), parameter:: ctrs(ntr) = (/' ', 'TOT', 'MMC', 'TRS', &
88 'STN'/)
89
90 real zvQ(jjm, llm, ntr, nQ), zvQtmp(jjm, llm)
91 real zavQ(jjm, 2: ntr, nQ), psiQ(jjm, llm + 1, nQ)
92 real zmasse(jjm, llm)
93
94 real zv(jjm, llm), psi(jjm, llm + 1)
95
96 integer i, j, l, iQ
97
98 ! Initialisation du fichier contenant les moyennes zonales.
99
100 integer, save:: fileid
101 integer thoriid, zvertiid
102
103 real zjulian
104 integer zan, dayref
105
106 real rlong(jjm), rlatg(jjm)
107
108 !-----------------------------------------------------------------
109
110 !!print *, "Call sequence information: bilan_dyn"
111
112 ! Initialisation
113
114 time = time + dt_app
115 itau = itau + 1
116
117 first_call: if (first) then
118 ! initialisation des fichiers
119 first = .false.
120 ! ncum est la frequence de stokage en pas de temps
121 ncum = dt_cum / dt_app
122 if (abs(ncum * dt_app - dt_cum) > 1e-5 * dt_app) then
123 print *, 'Problème : le pas de cumul doit être multiple du pas'
124 print *, 'dt_app = ', dt_app
125 print *, 'dt_cum = ', dt_cum
126 stop 1
127 endif
128
129 call inigrads(i_f=4, x=(/0./), fx=180./pi, xmin=0., xmax=0., y=rlatv, &
130 ymin=-90., ymax=90., fy=180./pi, z=presnivs, fz=1., dt=dt_cum, &
131 file='dynzon', titlel='dyn_zon ')
132
133 ! Initialisation du fichier contenant les moyennes zonales
134
135 zan = annee_ref
136 dayref = day_ref
137 CALL ymds2ju(zan, 1, dayref, 0.0, zjulian)
138
139 rlong = 0.
140 rlatg = rlatv*180./pi
141
142 call histbeg_totreg('dynzon', rlong(:1), rlatg, 1, 1, 1, jjm, itau_dyn, &
143 zjulian, dt_cum, thoriid, fileid)
144
145 ! Appel à histvert pour la grille verticale
146
147 call histvert(fileid, 'presnivs', 'Niveaux sigma', 'mb', llm, presnivs, &
148 zvertiid)
149
150 ! Appels à histdef pour la définition des variables à sauvegarder
151 do iQ = 1, nQ
152 do itr = 1, ntr
153 if (itr == 1) then
154 znom(itr, iQ) = nom(iQ)
155 znoml(itr, iQ) = nom(iQ)
156 zunites(itr, iQ) = unites(iQ)
157 else
158 znom(itr, iQ) = ctrs(itr)//'v'//nom(iQ)
159 znoml(itr, iQ) = 'transport : v * '//nom(iQ)//' '//ctrs(itr)
160 zunites(itr, iQ) = 'm/s * '//unites(iQ)
161 endif
162 enddo
163 enddo
164
165 ! Déclarations des champs avec dimension verticale
166 do iQ = 1, nQ
167 do itr = 1, ntr
168 call histdef(fileid, znom(itr, iQ), znoml(itr, iQ), &
169 zunites(itr, iQ), 1, jjm, thoriid, llm, 1, llm, zvertiid, &
170 'ave(X)', dt_cum, dt_cum)
171 enddo
172 ! Declarations pour les fonctions de courant
173 call histdef(fileid, 'psi'//nom(iQ), 'stream fn. '//znoml(itot, iQ), &
174 zunites(itot, iQ), 1, jjm, thoriid, llm, 1, llm, zvertiid, &
175 'ave(X)', dt_cum, dt_cum)
176 enddo
177
178 ! Declarations pour les champs de transport d'air
179 call histdef(fileid, 'masse', 'masse', &
180 'kg', 1, jjm, thoriid, llm, 1, llm, zvertiid, &
181 'ave(X)', dt_cum, dt_cum)
182 call histdef(fileid, 'v', 'v', &
183 'm/s', 1, jjm, thoriid, llm, 1, llm, zvertiid, &
184 'ave(X)', dt_cum, dt_cum)
185 ! Declarations pour les fonctions de courant
186 call histdef(fileid, 'psi', 'stream fn. MMC ', 'mega t/s', &
187 1, jjm, thoriid, llm, 1, llm, zvertiid, &
188 'ave(X)', dt_cum, dt_cum)
189
190 ! Declaration des champs 1D de transport en latitude
191 do iQ = 1, nQ
192 do itr = 2, ntr
193 call histdef(fileid, 'a'//znom(itr, iQ), znoml(itr, iQ), &
194 zunites(itr, iQ), 1, jjm, thoriid, 1, 1, 1, -99, &
195 'ave(X)', dt_cum, dt_cum)
196 enddo
197 enddo
198
199 CALL histend(fileid)
200 endif first_call
201
202 ! Calcul des champs dynamiques
203
204 ! Énergie cinétique
205 ucont = 0
206 CALL covcont(llm, ucov, vcov, ucont, vcont)
207 CALL enercin(vcov, ucov, vcont, ucont, ecin)
208
209 ! moment cinétique
210 do l = 1, llm
211 ang(:, :, l) = ucov(:, :, l) + constang_2d
212 unat(:, :, l) = ucont(:, :, l)*cu_2d
213 enddo
214
215 Q(:, :, :, 1) = teta * pk / cpp
216 Q(:, :, :, 2) = phi
217 Q(:, :, :, 3) = ecin
218 Q(:, :, :, 4) = ang
219 Q(:, :, :, 5) = unat
220 Q(:, :, :, 6) = trac
221 Q(:, :, :, 7) = 1.
222
223 ! Cumul
224
225 if (icum == 0) then
226 ps_cum = 0.
227 masse_cum = 0.
228 flux_u_cum = 0.
229 flux_v_cum = 0.
230 Q_cum = 0.
231 flux_vQ_cum = 0.
232 flux_uQ_cum = 0.
233 endif
234
235 icum = icum + 1
236
237 ! Accumulation des flux de masse horizontaux
238 ps_cum = ps_cum + ps
239 masse_cum = masse_cum + masse
240 flux_u_cum = flux_u_cum + flux_u
241 flux_v_cum = flux_v_cum + flux_v
242 do iQ = 1, nQ
243 Q_cum(:, :, :, iQ) = Q_cum(:, :, :, iQ) + Q(:, :, :, iQ)*masse
244 enddo
245
246 ! FLUX ET TENDANCES
247
248 ! Flux longitudinal
249 forall (iQ = 1: nQ, i = 1: iim) flux_uQ_cum(i, :, :, iQ) &
250 = flux_uQ_cum(i, :, :, iQ) &
251 + flux_u(i, :, :) * 0.5 * (Q(i, :, :, iQ) + Q(i + 1, :, :, iQ))
252 flux_uQ_cum(iip1, :, :, :) = flux_uQ_cum(1, :, :, :)
253
254 ! Flux méridien
255 forall (iQ = 1: nQ, j = 1: jjm) flux_vQ_cum(:, j, :, iQ) &
256 = flux_vQ_cum(:, j, :, iQ) &
257 + flux_v(:, j, :) * 0.5 * (Q(:, j, :, iQ) + Q(:, j + 1, :, iQ))
258
259 ! tendances
260
261 ! convergence horizontale
262 call convflu(flux_uQ_cum, flux_vQ_cum, llm*nQ, dQ)
263
264 ! calcul de la vitesse verticale
265 call convmas(flux_u_cum, flux_v_cum, convm)
266 CALL vitvert(convm, w)
267
268 do iQ = 1, nQ
269 do l = 1, llm-1
270 do j = 1, jjp1
271 do i = 1, iip1
272 ww = -0.5*w(i, j, l + 1)*(Q(i, j, l, iQ) + Q(i, j, l + 1, iQ))
273 dQ(i, j, l, iQ) = dQ(i, j, l, iQ)-ww
274 dQ(i, j, l + 1, iQ) = dQ(i, j, l + 1, iQ) + ww
275 enddo
276 enddo
277 enddo
278 enddo
279
280 ! PAS DE TEMPS D'ECRITURE
281
282 writing_step: if (icum == ncum) then
283 ! Normalisation
284 do iQ = 1, nQ
285 Q_cum(:, :, :, iQ) = Q_cum(:, :, :, iQ)/masse_cum
286 enddo
287 zz = 1. / real(ncum)
288 ps_cum = ps_cum*zz
289 masse_cum = masse_cum*zz
290 flux_u_cum = flux_u_cum*zz
291 flux_v_cum = flux_v_cum*zz
292 flux_uQ_cum = flux_uQ_cum*zz
293 flux_vQ_cum = flux_vQ_cum*zz
294 dQ = dQ*zz
295
296 ! A retravailler eventuellement
297 ! division de dQ par la masse pour revenir aux bonnes grandeurs
298 do iQ = 1, nQ
299 dQ(:, :, :, iQ) = dQ(:, :, :, iQ)/masse_cum
300 enddo
301
302 ! Transport méridien
303
304 ! cumul zonal des masses des mailles
305
306 zv = 0.
307 zmasse = 0.
308 call massbar(masse_cum, massebx, masseby)
309 do l = 1, llm
310 do j = 1, jjm
311 do i = 1, iim
312 zmasse(j, l) = zmasse(j, l) + masseby(i, j, l)
313 zv(j, l) = zv(j, l) + flux_v_cum(i, j, l)
314 enddo
315 zfactv(j, l) = cv_2d(1, j)/zmasse(j, l)
316 enddo
317 enddo
318
319 ! Transport dans le plan latitude-altitude
320
321 zvQ = 0.
322 psiQ = 0.
323 do iQ = 1, nQ
324 zvQtmp = 0.
325 do l = 1, llm
326 do j = 1, jjm
327 ! Calcul des moyennes zonales du transort total et de zvQtmp
328 do i = 1, iim
329 zvQ(j, l, itot, iQ) = zvQ(j, l, itot, iQ) &
330 + flux_vQ_cum(i, j, l, iQ)
331 zqy = 0.5 * (Q_cum(i, j, l, iQ) * masse_cum(i, j, l) &
332 + Q_cum(i, j + 1, l, iQ) * masse_cum(i, j + 1, l))
333 zvQtmp(j, l) = zvQtmp(j, l) + flux_v_cum(i, j, l) * zqy &
334 / (0.5 * (masse_cum(i, j, l) + masse_cum(i, j + 1, l)))
335 zvQ(j, l, iave, iQ) = zvQ(j, l, iave, iQ) + zqy
336 enddo
337 ! Decomposition
338 zvQ(j, l, iave, iQ) = zvQ(j, l, iave, iQ)/zmasse(j, l)
339 zvQ(j, l, itot, iQ) = zvQ(j, l, itot, iQ)*zfactv(j, l)
340 zvQtmp(j, l) = zvQtmp(j, l)*zfactv(j, l)
341 zvQ(j, l, immc, iQ) = zv(j, l)*zvQ(j, l, iave, iQ)*zfactv(j, l)
342 zvQ(j, l, itrs, iQ) = zvQ(j, l, itot, iQ)-zvQtmp(j, l)
343 zvQ(j, l, istn, iQ) = zvQtmp(j, l)-zvQ(j, l, immc, iQ)
344 enddo
345 enddo
346 ! fonction de courant meridienne pour la quantite Q
347 do l = llm, 1, -1
348 do j = 1, jjm
349 psiQ(j, l, iQ) = psiQ(j, l + 1, iQ) + zvQ(j, l, itot, iQ)
350 enddo
351 enddo
352 enddo
353
354 ! fonction de courant pour la circulation meridienne moyenne
355 psi = 0.
356 do l = llm, 1, -1
357 do j = 1, jjm
358 psi(j, l) = psi(j, l + 1) + zv(j, l)
359 zv(j, l) = zv(j, l)*zfactv(j, l)
360 enddo
361 enddo
362
363 ! sorties proprement dites
364 do iQ = 1, nQ
365 do itr = 1, ntr
366 call histwrite(fileid, znom(itr, iQ), itau, zvQ(:, :, itr, iQ))
367 enddo
368 call histwrite(fileid, 'psi'//nom(iQ), itau, psiQ(:, :llm, iQ))
369 enddo
370
371 call histwrite(fileid, 'masse', itau, zmasse)
372 call histwrite(fileid, 'v', itau, zv)
373 psi = psi*1.e-9
374 call histwrite(fileid, 'psi', itau, psi(:, :llm))
375
376 ! Intégrale verticale
377
378 forall (iQ = 1: nQ, itr = 2: ntr) zavQ(:, itr, iQ) &
379 = sum(zvQ(:, :, itr, iQ) * zmasse, dim=2) / cv_2d(1, :)
380
381 do iQ = 1, nQ
382 do itr = 2, ntr
383 call histwrite(fileid, 'a'//znom(itr, iQ), itau, zavQ(:, itr, iQ))
384 enddo
385 enddo
386
387 ! On doit pouvoir tracer systematiquement la fonction de courant.
388 icum = 0
389 endif writing_step
390
391 end SUBROUTINE bilan_dyn
392
393 end module bilan_dyn_m

  ViewVC Help
Powered by ViewVC 1.1.21