/[lmdze]/trunk/Sources/dyn3d/etat0.f
ViewVC logotype

Contents of /trunk/Sources/dyn3d/etat0.f

Parent Directory Parent Directory | Revision Log Revision Log


Revision 139 - (show annotations)
Tue May 26 17:46:03 2015 UTC (8 years, 11 months ago) by guez
File size: 11958 byte(s)
dynetat0 read rlonu, rlatu, rlonv, rlatv, cu_2d, cv_2d, aire_2d from
"start.nc" and then these variables were overwritten by
inigeom. Corrected this. Now, inigeom does not compute rlonu, rlatu,
rlonv and rlatv. Moreover, cu_2d, cv_2d, aire_2d are not written to
"restart.nc". Since xprimu, xprimv, xprimm025, xprimp025, rlatu1,
rlatu2, yprimu1, yprimu2 are computed at the same time as rlonu,
rlatu, rlonv, rlatv, and since it would not be convenient to separate
those computations, we decide to write xprimu, xprimv, xprimm025,
xprimp025, rlatu1, rlatu2, yprimu1, yprimu2 into "restart.nc", read
them from "start.nc" and not compute them in inigeom. So, in summary,
"start.nc" contains all the coordinates and their derivatives, and
inigeom only computes the 2D-variables.

Technical details:

Moved variables rlatu, rlonv, rlonu, rlatv, xprimu, xprimv from module
comgeom to module dynetat0_m. Upgraded local variables rlatu1,
yprimu1, rlatu2, yprimu2, xprimm025, xprimp025 of procedure inigeom to
variables of module dynetat0_m.

Removed unused local variable yprimu of procedure inigeom and
corresponding argument yyprimu of fyhyp.

Moved variables clat, clon, grossismx, grossismy, dzoomx, dzoomy,
taux, tauy from module serre to module dynetat0_m (since they are read
from "start.nc"). The default values are now defined in read_serre
instead of in the declarations. Changed name of module serre to
read_serre_m, no more module variable here.

The calls to fxhyp and fyhyp are moved from inigeom to etat0.

Side effects in programs other than gcm: etat0 and read_serre write
variables of module dynetat0; the programs test_fxyp and
test_inter_barxy need more source files.

Removed unused arguments len and nd of cv3_tracer. Removed unused
argument PPSOL of LWU.

Bug fix in test_inter_barxy: forgotten call to read_serre.

1 module etat0_mod
2
3 use indicesol, only: nbsrf
4 use dimphy, only: klon
5
6 IMPLICIT NONE
7
8 REAL pctsrf(klon, nbsrf)
9 ! ("pctsrf(i, :)" is the composition of the surface at horizontal
10 ! position "i")
11
12 private nbsrf, klon
13
14 contains
15
16 SUBROUTINE etat0(phis)
17
18 ! From "etat0_netcdf.F", version 1.3, 2005/05/25 13:10:09
19
20 use caldyn0_m, only: caldyn0
21 use comconst, only: cpp, kappa, iniconst
22 use comgeom, only: aire_2d, apoln, apols, cu_2d, cv_2d, inigeom
23 use dimens_m, only: iim, jjm, llm, nqmx
24 use dimphy, only: zmasq
25 use dimsoil, only: nsoilmx
26 use disvert_m, only: ap, bp, preff, pa, disvert
27 use dynetat0_m, only: day_ref, annee_ref, xprimp025, xprimm025, rlatu1, &
28 rlatu2, rlatu, rlatv, yprimu1, yprimu2, rlonu, rlonv, xprimu, xprimv
29 use dynredem0_m, only: dynredem0
30 use dynredem1_m, only: dynredem1
31 use exner_hyb_m, only: exner_hyb
32 use fxhyp_m, only: fxhyp
33 use fyhyp_m, only: fyhyp
34 use geopot_m, only: geopot
35 use grid_atob, only: grille_m
36 use grid_change, only: init_dyn_phy, dyn_phy
37 use indicesol, only: is_oce, is_sic, is_ter, is_lic, epsfra
38 use iniadvtrac_m, only: iniadvtrac
39 use inifilr_m, only: inifilr
40 use massdair_m, only: massdair
41 use netcdf, only: nf90_nowrite
42 use netcdf95, only: nf95_close, nf95_get_var, nf95_gw_var, &
43 nf95_inq_varid, nf95_open
44 use nr_util, only: pi, assert
45 use paramet_m, only: ip1jm, ip1jmp1
46 use phyetat0_m, only: rlat, rlon
47 use phyredem_m, only: phyredem
48 use q_sat_m, only: q_sat
49 use regr_lat_time_coefoz_m, only: regr_lat_time_coefoz
50 use regr_pr_o3_m, only: regr_pr_o3
51 use startdyn, only: start_init_dyn
52 USE start_init_orog_m, only: start_init_orog, mask
53 use start_init_phys_m, only: start_init_phys
54 use start_inter_3d_m, only: start_inter_3d
55 use temps, only: itau_phy
56 use test_disvert_m, only: test_disvert
57 use unit_nml_m, only: unit_nml
58
59 REAL, intent(out):: phis(:, :) ! (iim + 1, jjm + 1)
60 ! surface geopotential, in m2 s-2
61
62 ! Local:
63
64 REAL, dimension(iim + 1, jjm + 1, llm):: ucov, t3d, teta
65 REAL vcov(iim + 1, jjm, llm)
66
67 REAL q(iim + 1, jjm + 1, llm, nqmx)
68 ! (mass fractions of trace species
69 ! "q(i, j, l)" is at longitude "rlonv(i)", latitude "rlatu(j)"
70 ! and pressure level "pls(i, j, l)".)
71
72 real qsat(iim + 1, jjm + 1, llm) ! mass fraction of saturating water vapor
73 REAL sn(klon)
74 REAL qsolsrf(klon, nbsrf), snsrf(klon, nbsrf)
75 REAL albe(klon, nbsrf), evap(klon, nbsrf)
76 REAL alblw(klon, nbsrf)
77 REAL tsoil(klon, nsoilmx, nbsrf)
78 REAL radsol(klon), rain_fall(klon), snow_fall(klon)
79 REAL solsw(klon), sollw(klon), fder(klon)
80 !IM "slab" ocean
81 real seaice(klon) ! kg m-2
82 REAL frugs(klon, nbsrf), agesno(klon, nbsrf)
83 REAL rugmer(klon)
84 real, dimension(iim + 1, jjm + 1):: zmea_2d, zstd_2d, zsig_2d, zgam_2d
85 real, dimension(iim + 1, jjm + 1):: zthe_2d, zpic_2d, zval_2d
86 real, dimension(iim + 1, jjm + 1):: tsol_2d, qsol_2d, ps
87 REAL zmea(klon), zstd(klon)
88 REAL zsig(klon), zgam(klon)
89 REAL zthe(klon)
90 REAL zpic(klon), zval(klon)
91 REAL t_ancien(klon, llm), q_ancien(klon, llm)
92 REAL run_off_lic_0(klon)
93 real clwcon(klon, llm), rnebcon(klon, llm), ratqs(klon, llm)
94
95 ! D\'eclarations pour lecture glace de mer :
96 INTEGER iml_lic, jml_lic
97 INTEGER ncid, varid
98 REAL, pointer:: dlon_lic(:), dlat_lic(:)
99 REAL, ALLOCATABLE:: fraclic(:, :) ! fraction land ice
100 REAL flic_tmp(iim + 1, jjm + 1) ! fraction land ice temporary
101
102 INTEGER l, ji
103
104 REAL pk(iim + 1, jjm + 1, llm) ! fonction d'Exner aux milieux des couches
105 real pks(iim + 1, jjm + 1)
106
107 REAL masse(iim + 1, jjm + 1, llm)
108 REAL phi(iim + 1, jjm + 1, llm)
109 REAL pbaru(ip1jmp1, llm), pbarv(ip1jm, llm)
110 REAL w(iim + 1, jjm + 1, llm)
111
112 real sig1(klon, llm) ! section adiabatic updraft
113 real w01(klon, llm) ! vertical velocity within adiabatic updraft
114
115 real pls(iim + 1, jjm + 1, llm)
116 ! (pressure at mid-layer of LMDZ grid, in Pa)
117 ! "pls(i, j, l)" is at longitude "rlonv(i)", latitude "rlatu(j)",
118 ! for layer "l")
119
120 REAL p3d(iim + 1, jjm + 1, llm+1) ! pressure at layer interfaces, in Pa
121 ! ("p3d(i, j, l)" is at longitude "rlonv(i)", latitude "rlatu(j)",
122 ! for interface "l")
123
124 namelist /etat0_nml/ day_ref, annee_ref
125
126 !---------------------------------
127
128 print *, "Call sequence information: etat0"
129
130 print *, "Enter namelist 'etat0_nml'."
131 read(unit=*, nml=etat0_nml)
132 write(unit_nml, nml=etat0_nml)
133
134 CALL iniconst
135
136 ! Construct a grid:
137
138 pa = 5e4
139 CALL disvert
140 call test_disvert
141
142 CALL fyhyp(rlatu, rlatv, rlatu2, yprimu2, rlatu1, yprimu1)
143 CALL fxhyp(xprimm025, rlonv, xprimv, rlonu, xprimu, xprimp025)
144
145 rlatu(1) = pi / 2.
146 rlatu(jjm + 1) = -rlatu(1)
147
148 CALL inigeom
149 CALL inifilr
150
151 rlat(1) = 90.
152 rlat(2:klon-1) = pack(spread(rlatu(2:jjm), 1, iim), .true.) * 180. / pi
153 ! (with conversion to degrees)
154 rlat(klon) = - 90.
155
156 rlon(1) = 0.
157 rlon(2:klon-1) = pack(spread(rlonv(:iim), 2, jjm - 1), .true.) * 180. / pi
158 ! (with conversion to degrees)
159 rlon(klon) = 0.
160
161 call start_init_orog(phis, zmea_2d, zstd_2d, zsig_2d, zgam_2d, zthe_2d, &
162 zpic_2d, zval_2d) ! also compute "mask"
163 call init_dyn_phy ! define the mask "dyn_phy" for distinct grid points
164 zmasq = pack(mask, dyn_phy)
165 PRINT *, 'Masque construit'
166
167 call start_init_phys(tsol_2d, qsol_2d)
168 CALL start_init_dyn(tsol_2d, phis, ps)
169
170 ! Compute pressure on intermediate levels:
171 forall(l = 1: llm + 1) p3d(:, :, l) = ap(l) + bp(l) * ps
172 CALL exner_hyb(ps, p3d, pks, pk)
173 call assert(MINVAL(pk) /= MAXVAL(pk), '"pk" should not be constant')
174
175 pls = preff * (pk / cpp)**(1. / kappa)
176 PRINT *, "minval(pls) = ", minval(pls)
177 print *, "maxval(pls) = ", maxval(pls)
178
179 call start_inter_3d('U', rlonv, rlatv, pls, ucov)
180 forall (l = 1: llm) ucov(:iim, :, l) = ucov(:iim, :, l) * cu_2d(:iim, :)
181 ucov(iim+1, :, :) = ucov(1, :, :)
182
183 call start_inter_3d('V', rlonu, rlatu(:jjm), pls(:, :jjm, :), vcov)
184 forall (l = 1: llm) vcov(:iim, :, l) = vcov(:iim, :, l) * cv_2d(:iim, :)
185 vcov(iim + 1, :, :) = vcov(1, :, :)
186
187 call start_inter_3d('TEMP', rlonu, rlatv, pls, t3d)
188 PRINT *, 'minval(t3d) = ', minval(t3d)
189 print *, "maxval(t3d) = ", maxval(t3d)
190
191 teta(:iim, :, :) = t3d(:iim, :, :) * cpp / pk(:iim, :, :)
192 teta(iim + 1, :, :) = teta(1, :, :)
193 DO l = 1, llm
194 teta(:, 1, l) = SUM(aire_2d(:, 1) * teta(:, 1, l)) / apoln
195 teta(:, jjm + 1, l) = SUM(aire_2d(:, jjm + 1) * teta(:, jjm + 1, l)) &
196 / apols
197 ENDDO
198
199 ! Calcul de l'humidit\'e \`a saturation :
200 qsat = q_sat(t3d, pls)
201 PRINT *, "minval(qsat) = ", minval(qsat)
202 print *, "maxval(qsat) = ", maxval(qsat)
203 IF (MINVAL(qsat) == MAXVAL(qsat)) stop '"qsat" should not be constant'
204
205 ! Water vapor:
206 call start_inter_3d('R', rlonu, rlatv, pls, q(:, :, :, 1))
207 q(:, :, :, 1) = 0.01 * q(:, :, :, 1) * qsat
208 WHERE (q(:, :, :, 1) < 0.) q(:, :, :, 1) = 1E-10
209 DO l = 1, llm
210 q(:, 1, l, 1) = SUM(aire_2d(:, 1) * q(:, 1, l, 1)) / apoln
211 q(:, jjm + 1, l, 1) &
212 = SUM(aire_2d(:, jjm + 1) * q(:, jjm + 1, l, 1)) / apols
213 ENDDO
214
215 q(:, :, :, 2:4) = 0. ! liquid water, radon and lead
216
217 if (nqmx >= 5) then
218 ! Ozone:
219 call regr_lat_time_coefoz
220 call regr_pr_o3(p3d, q(:, :, :, 5))
221 ! Convert from mole fraction to mass fraction:
222 q(:, :, :, 5) = q(:, :, :, 5) * 48. / 29.
223 end if
224
225 sn = 0. ! snow
226 radsol = 0.
227 seaice = 0.
228 rugmer = 0.001
229 zmea = pack(zmea_2d, dyn_phy)
230 zstd = pack(zstd_2d, dyn_phy)
231 zsig = pack(zsig_2d, dyn_phy)
232 zgam = pack(zgam_2d, dyn_phy)
233 zthe = pack(zthe_2d, dyn_phy)
234 zpic = pack(zpic_2d, dyn_phy)
235 zval = pack(zval_2d, dyn_phy)
236
237 ! On initialise les sous-surfaces.
238 ! Lecture du fichier glace de terre pour fixer la fraction de terre
239 ! et de glace de terre :
240
241 call nf95_open("landiceref.nc", nf90_nowrite, ncid)
242
243 call nf95_inq_varid(ncid, 'longitude', varid)
244 call nf95_gw_var(ncid, varid, dlon_lic)
245 iml_lic = size(dlon_lic)
246
247 call nf95_inq_varid(ncid, 'latitude', varid)
248 call nf95_gw_var(ncid, varid, dlat_lic)
249 jml_lic = size(dlat_lic)
250
251 call nf95_inq_varid(ncid, 'landice', varid)
252 ALLOCATE(fraclic(iml_lic, jml_lic))
253 call nf95_get_var(ncid, varid, fraclic)
254
255 call nf95_close(ncid)
256
257 ! Interpolation sur la grille T du mod\`ele :
258 PRINT *, 'Dimensions de "landiceref.nc"'
259 print *, "iml_lic = ", iml_lic
260 print *, "jml_lic = ", jml_lic
261
262 ! Si les coordonn\'ees sont en degr\'es, on les transforme :
263 IF (MAXVAL(dlon_lic) > pi) THEN
264 dlon_lic = dlon_lic * pi / 180.
265 ENDIF
266 IF (maxval(dlat_lic) > pi) THEN
267 dlat_lic = dlat_lic * pi/ 180.
268 ENDIF
269
270 flic_tmp(:iim, :) = grille_m(dlon_lic, dlat_lic, fraclic, rlonv(:iim), &
271 rlatu)
272 flic_tmp(iim + 1, :) = flic_tmp(1, :)
273
274 deallocate(dlon_lic, dlat_lic) ! pointers
275
276 ! Passage sur la grille physique
277 pctsrf = 0.
278 pctsrf(:, is_lic) = pack(flic_tmp, dyn_phy)
279 ! Ad\'equation avec le maque terre/mer
280 WHERE (pctsrf(:, is_lic) < EPSFRA) pctsrf(:, is_lic) = 0.
281 WHERE (zmasq < EPSFRA) pctsrf(:, is_lic) = 0.
282 pctsrf(:, is_ter) = zmasq
283 where (zmasq > EPSFRA)
284 where (pctsrf(:, is_lic) >= zmasq)
285 pctsrf(:, is_lic) = zmasq
286 pctsrf(:, is_ter) = 0.
287 elsewhere
288 pctsrf(:, is_ter) = zmasq - pctsrf(:, is_lic)
289 where (pctsrf(:, is_ter) < EPSFRA)
290 pctsrf(:, is_ter) = 0.
291 pctsrf(:, is_lic) = zmasq
292 end where
293 end where
294 end where
295
296 ! Sous-surface oc\'ean et glace de mer (pour d\'emarrer on met glace
297 ! de mer \`a 0) :
298 pctsrf(:, is_oce) = 1. - zmasq
299 WHERE (pctsrf(:, is_oce) < EPSFRA) pctsrf(:, is_oce) = 0.
300
301 ! V\'erification que somme des sous-surfaces vaut 1 :
302 ji = count(abs(sum(pctsrf, dim = 2) - 1.) > EPSFRA)
303 IF (ji /= 0) then
304 PRINT *, 'Bad surface percentages for ', ji, 'points'
305 end IF
306
307 ! Calcul interm\'ediaire :
308 CALL massdair(p3d, masse)
309
310 forall (l = 1:llm)
311 masse(:, 1, l) = SUM(aire_2d(:iim, 1) * masse(:iim, 1, l)) / apoln
312 masse(:, jjm + 1, l) = &
313 SUM(aire_2d(:iim, jjm + 1) * masse(:iim, jjm + 1, l)) / apols
314 END forall
315
316 ! Initialisation pour traceurs:
317 call iniadvtrac
318 itau_phy = 0
319
320 CALL geopot(teta, pk , pks, phis, phi)
321 CALL caldyn0(ucov, vcov, teta, ps, masse, pk, phis, phi, w, pbaru, &
322 pbarv)
323 CALL dynredem0("start.nc", day_ref, phis)
324 CALL dynredem1("start.nc", vcov, ucov, teta, q, masse, ps, itau=0)
325
326 ! Initialisations :
327 snsrf(:, is_ter) = sn
328 snsrf(:, is_lic) = sn
329 snsrf(:, is_oce) = sn
330 snsrf(:, is_sic) = sn
331 albe(:, is_ter) = 0.08
332 albe(:, is_lic) = 0.6
333 albe(:, is_oce) = 0.5
334 albe(:, is_sic) = 0.6
335 alblw = albe
336 evap = 0.
337 qsolsrf = 150.
338 tsoil = spread(spread(pack(tsol_2d, dyn_phy), 2, nsoilmx), 3, nbsrf)
339 rain_fall = 0.
340 snow_fall = 0.
341 solsw = 165.
342 sollw = -53.
343 t_ancien = 273.15
344 q_ancien = 0.
345 agesno = 0.
346 seaice = 0.
347
348 frugs(:, is_oce) = rugmer
349 frugs(:, is_ter) = MAX(1e-5, zstd * zsig / 2)
350 frugs(:, is_lic) = MAX(1e-5, zstd * zsig / 2)
351 frugs(:, is_sic) = 0.001
352 fder = 0.
353 clwcon = 0.
354 rnebcon = 0.
355 ratqs = 0.
356 run_off_lic_0 = 0.
357 sig1 = 0.
358 w01 = 0.
359
360 call phyredem("startphy.nc", pctsrf, tsoil(:, 1, :), tsoil, &
361 tsoil(:, 1, is_oce), seaice, qsolsrf, pack(qsol_2d, dyn_phy), snsrf, &
362 albe, alblw, evap, rain_fall, snow_fall, solsw, sollw, fder, radsol, &
363 frugs, agesno, zmea, zstd, zsig, zgam, zthe, zpic, zval, t_ancien, &
364 q_ancien, rnebcon, ratqs, clwcon, run_off_lic_0, sig1, w01)
365
366 END SUBROUTINE etat0
367
368 end module etat0_mod

  ViewVC Help
Powered by ViewVC 1.1.21