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

Contents of /trunk/dyn3d/limit.f

Parent Directory Parent Directory | Revision Log Revision Log


Revision 264 - (show annotations)
Mon Mar 19 10:28:42 2018 UTC (6 years, 1 month ago) by guez
File size: 13253 byte(s)
In procedure limit, write fields as soon as they are computed. Thus
avoid creating local arrays phy_alb, phy_sst, phy_rug, pctsrf_t and
avoid copying to these arrays. In particular, we use the module
variable pctsrf instead of local pctsrf_t.

1 module limit_mod
2
3 IMPLICIT none
4
5 contains
6
7 SUBROUTINE limit
8
9 ! Authors: L. Fairhead, Z. X. Li, P. Le Van
10
11 ! This subroutine creates files containing boundary conditions.
12 ! It uses files with climatological data. Both grids must be
13 ! regular.
14
15 use conf_dat2d_m, only: conf_dat2d
16 use dimens_m, only: iim, jjm
17 use dimphy, only: klon, zmasq
18 use dynetat0_m, only: rlonu, rlatv
19 use etat0_mod, only: pctsrf
20 use grid_change, only: dyn_phy
21 use indicesol, only: epsfra, is_ter, is_oce, is_lic, is_sic
22 use inter_barxy_m, only: inter_barxy
23 use netcdf95, only: NF95_CLOSE, NF95_CREATE, NF95_DEF_DIM, nf95_def_var, &
24 nf95_enddef, nf95_get_var, nf95_gw_var, nf95_inq_dimid, &
25 nf95_inq_varid, nf95_inquire_dimension, NF95_OPEN, NF95_PUT_ATT, &
26 NF95_PUT_VAR
27 use netcdf, only: NF90_CLOBBER, NF90_FLOAT, NF90_GLOBAL, NF90_NOWRITE, &
28 NF90_UNLIMITED
29 use nr_util, only: assert
30 use numer_rec_95, only: spline, splint
31 use start_init_orog_m, only: mask
32 use unit_nml_m, only: unit_nml
33
34 ! Local:
35
36 LOGICAL:: extrap = .FALSE.
37 ! (extrapolation de donn\'ees, comme pour les SST lorsque le fichier
38 ! ne contient pas uniquement des points oc\'eaniques)
39
40 REAL phy_bil(klon, 360)
41 REAL phy_ice(klon)
42
43 ! Pour le champ de d\'epart:
44 INTEGER imdep, jmdep, lmdep
45
46 REAL, ALLOCATABLE:: dlon(:), dlat(:)
47 REAL, ALLOCATABLE:: dlon_ini(:), dlat_ini(:), timeyear(:)
48 REAL, ALLOCATABLE:: champ(:, :)
49 REAL, ALLOCATABLE:: work(:, :)
50
51 ! Pour le champ interpol\'e 3D :
52 REAL, allocatable:: champtime(:, :, :)
53 REAL champan(iim + 1, jjm + 1, 360)
54
55 ! Pour l'inteprolation verticale :
56 REAL, allocatable:: yder(:)
57
58 INTEGER ndim, ntim
59 INTEGER varid_time
60 INTEGER id_SST, id_BILS, id_RUG, id_ALB
61 INTEGER id_FOCE, id_FSIC, id_FTER, id_FLIC
62
63 INTEGER i, j, k, l
64 INTEGER ncid, ncid_limit, varid, dimid
65
66 REAL, parameter:: tmidmonth(12) = [(15. + 30. * i, i = 0, 11)]
67
68 namelist /limit_nml/extrap
69
70 !--------------------
71
72 print *, "Call sequence information: limit"
73
74 print *, "Enter namelist 'limit_nml'."
75 read(unit=*, nml=limit_nml)
76 write(unit_nml, nml=limit_nml)
77
78 call NF95_CREATE("limit.nc", NF90_CLOBBER, ncid_limit)
79
80 call NF95_PUT_ATT(ncid_limit, NF90_GLOBAL, "title", &
81 "Fichier conditions aux limites")
82 call NF95_DEF_DIM(ncid_limit, "points_physiques", klon, ndim)
83 call NF95_DEF_DIM(ncid_limit, "time", NF90_UNLIMITED, ntim)
84
85 call NF95_DEF_VAR(ncid_limit, "TEMPS", NF90_FLOAT, ntim, varid_time)
86 call NF95_PUT_ATT(ncid_limit, varid_time, "title", "Jour dans l annee")
87
88 call NF95_DEF_VAR(ncid_limit, "FOCE", NF90_FLOAT, dimids=[ndim, ntim], &
89 varid=id_foce)
90 call NF95_PUT_ATT(ncid_limit, id_FOCE, "title", "Fraction ocean")
91
92 call NF95_DEF_VAR(ncid_limit, "FSIC", NF90_FLOAT, dimids=[ndim, ntim], &
93 varid=id_FSIC)
94 call NF95_PUT_ATT(ncid_limit, id_FSIC, "title", "Fraction glace de mer")
95
96 call NF95_DEF_VAR(ncid_limit, "FTER", NF90_FLOAT, dimids=[ndim, ntim], &
97 varid=id_FTER)
98 call NF95_PUT_ATT(ncid_limit, id_FTER, "title", "Fraction terre")
99
100 call NF95_DEF_VAR(ncid_limit, "FLIC", NF90_FLOAT, dimids=[ndim, ntim], &
101 varid=id_FLIC)
102 call NF95_PUT_ATT(ncid_limit, id_FLIC, "title", "Fraction land ice")
103
104 call NF95_DEF_VAR(ncid_limit, "SST", NF90_FLOAT, dimids=[ndim, ntim], &
105 varid=id_SST)
106 call NF95_PUT_ATT(ncid_limit, id_SST, "title", &
107 "Temperature superficielle de la mer")
108
109 call NF95_DEF_VAR(ncid_limit, "BILS", NF90_FLOAT, dimids=[ndim, ntim], &
110 varid=id_BILS)
111 call NF95_PUT_ATT(ncid_limit, id_BILS, "title", &
112 "Reference flux de chaleur au sol")
113
114 call NF95_DEF_VAR(ncid_limit, "ALB", NF90_FLOAT, dimids=[ndim, ntim], &
115 varid=id_ALB)
116 call NF95_PUT_ATT(ncid_limit, id_ALB, "title", "Albedo a la surface")
117
118 call NF95_DEF_VAR(ncid_limit, "RUG", NF90_FLOAT, dimids=[ndim, ntim], &
119 varid=id_RUG)
120 call NF95_PUT_ATT(ncid_limit, id_RUG, "title", "Rugosite")
121
122 call NF95_ENDDEF(ncid_limit)
123
124 call NF95_PUT_VAR(ncid_limit, varid_time, [(k, k = 1, 360)])
125
126 PRINT *, 'Processing rugosity...'
127
128 call NF95_OPEN('Rugos.nc', NF90_NOWRITE, ncid)
129
130 ! Read coordinate variables:
131
132 call nf95_inq_varid(ncid, "longitude", varid)
133 call nf95_gw_var(ncid, varid, dlon_ini)
134 imdep = size(dlon_ini)
135
136 call nf95_inq_varid(ncid, "latitude", varid)
137 call nf95_gw_var(ncid, varid, dlat_ini)
138 jmdep = size(dlat_ini)
139
140 call nf95_inq_varid(ncid, "temps", varid)
141 call nf95_gw_var(ncid, varid, timeyear)
142 lmdep = size(timeyear)
143
144 ALLOCATE(champ(imdep, jmdep), champtime(iim, jjm + 1, lmdep))
145 allocate(dlon(imdep), dlat(jmdep))
146 call NF95_INQ_VARID(ncid, 'RUGOS', varid)
147
148 ! Read the primary variable day by day and regrid horizontally,
149 ! result in "champtime":
150 DO l = 1, lmdep
151 call NF95_GET_VAR(ncid, varid, champ, start=[1, 1, l])
152 CALL conf_dat2d(dlon_ini, dlat_ini, dlon, dlat, champ)
153 CALL inter_barxy(dlon, dlat(:jmdep -1), LOG(champ), rlonu(:iim), &
154 rlatv, champtime(:, :, l))
155 champtime(:, :, l) = EXP(champtime(:, :, l))
156 where (nint(mask(:iim, :)) /= 1) champtime(:, :, l) = 0.001
157 end do
158
159 call NF95_CLOSE(ncid)
160
161 DEALLOCATE(dlon, dlat, champ)
162 allocate(yder(lmdep))
163
164 ! Interpolate monthly values to daily values, at each horizontal position:
165 DO j = 1, jjm + 1
166 DO i = 1, iim
167 yder = SPLINE(timeyear, champtime(i, j, :))
168 DO k = 1, 360
169 champan(i, j, k) = SPLINT(timeyear, champtime(i, j, :), yder, &
170 real(k-1))
171 ENDDO
172 ENDDO
173 ENDDO
174
175 deallocate(champtime, yder)
176 champan(iim + 1, :, :) = champan(1, :, :)
177
178 DO k = 1, 360
179 call NF95_PUT_VAR(ncid_limit, id_RUG, pack(champan(:, :, k), dyn_phy), &
180 start=[1, k])
181 ENDDO
182
183 PRINT *, 'Processing sea ice...'
184 call NF95_OPEN('amipbc_sic_1x1.nc', NF90_NOWRITE, ncid)
185
186 call nf95_inq_varid(ncid, "longitude", varid)
187 call nf95_gw_var(ncid, varid, dlon_ini)
188 imdep = size(dlon_ini)
189
190 call nf95_inq_varid(ncid, "latitude", varid)
191 call nf95_gw_var(ncid, varid, dlat_ini)
192 jmdep = size(dlat_ini)
193
194 call nf95_inq_dimid(ncid, "time", dimid)
195 call NF95_INQuire_DIMension(ncid, dimid, nclen=lmdep)
196 print *, 'lmdep = ', lmdep
197 ! Coordonn\'ee temporelle fichiers AMIP pas en jours. Ici on suppose
198 ! qu'on a 12 mois (de 30 jours).
199 IF (lmdep /= 12) then
200 print *, 'Unknown AMIP file: not 12 months?'
201 STOP 1
202 end IF
203
204 ALLOCATE(champ(imdep, jmdep), champtime(iim, jjm + 1, lmdep))
205 ALLOCATE(dlon(imdep), dlat(jmdep))
206 call NF95_INQ_VARID(ncid, 'sicbcs', varid)
207 DO l = 1, lmdep
208 call NF95_GET_VAR(ncid, varid, champ, start=[1, 1, l])
209 CALL conf_dat2d(dlon_ini, dlat_ini, dlon, dlat, champ)
210 CALL inter_barxy(dlon, dlat(:jmdep -1), champ, rlonu(:iim), rlatv, &
211 champtime(:, :, l))
212 ENDDO
213
214 call NF95_CLOSE(ncid)
215
216 DEALLOCATE(dlon, dlat, champ)
217 PRINT *, 'Interpolation temporelle'
218 allocate(yder(lmdep))
219
220 DO j = 1, jjm + 1
221 DO i = 1, iim
222 yder = SPLINE(tmidmonth, champtime(i, j, :))
223 DO k = 1, 360
224 champan(i, j, k) = SPLINT(tmidmonth, champtime(i, j, :), yder, &
225 real(k-1))
226 ENDDO
227 ENDDO
228 ENDDO
229
230 deallocate(champtime, yder)
231
232 ! Convert from percentage to normal fraction and keep sea ice
233 ! between 0 and 1:
234 champan(:iim, :, :) = max(0., (min(1., (champan(:iim, :, :) / 100.))))
235 champan(iim + 1, :, :) = champan(1, :, :)
236
237 DO k = 1, 360
238 phy_ice = pack(champan(:, :, k), dyn_phy)
239
240 ! (utilisation de la sous-maille fractionnelle tandis que l'ancien
241 ! codage utilisait l'indicateur du sol (0, 1, 2, 3))
242 ! PB en attendant de mettre fraction de terre
243 WHERE (phy_ice < EPSFRA) phy_ice = 0.
244
245 pctsrf(:, is_sic) = max(phy_ice - pctsrf(:, is_lic), 0.)
246 ! Il y a des cas o\`u il y a de la glace dans landiceref et
247 ! pas dans AMIP
248 WHERE (1. - zmasq < EPSFRA)
249 pctsrf(:, is_sic) = 0.
250 pctsrf(:, is_oce) = 0.
251 elsewhere
252 where (pctsrf(:, is_sic) >= 1 - zmasq)
253 pctsrf(:, is_sic) = 1. - zmasq
254 pctsrf(:, is_oce) = 0.
255 ELSEwhere
256 pctsrf(:, is_oce) = 1. - zmasq - pctsrf(:, is_sic)
257 where (pctsrf(:, is_oce) < EPSFRA)
258 pctsrf(:, is_oce) = 0.
259 pctsrf(:, is_sic) = 1 - zmasq
260 end where
261 end where
262 end where
263
264 DO i = 1, klon
265 if (pctsrf(i, is_oce) < 0.) then
266 print *, "k = ", k
267 print *, 'Bad surface fraction: pctsrf(', i, ', is_oce) = ', &
268 pctsrf(i, is_oce)
269 ENDIF
270 IF (abs(sum(pctsrf(i, :)) - 1.) > EPSFRA) THEN
271 print *, "k = ", k
272 print *, 'Bad surface fraction:'
273 print *, "pctsrf(", i, ", :) = ", pctsrf(i, :)
274 print *, "phy_ice(", i, ") = ", phy_ice(i)
275 ENDIF
276 END DO
277
278 call NF95_PUT_VAR(ncid_limit, id_FOCE, pctsrf(:, is_oce), start=[1, k])
279 call NF95_PUT_VAR(ncid_limit, id_FSIC, pctsrf(:, is_sic), start=[1, k])
280 call NF95_PUT_VAR(ncid_limit, id_FTER, pctsrf(:, is_ter), start=[1, k])
281 call NF95_PUT_VAR(ncid_limit, id_FLIC, pctsrf(:, is_lic), start=[1, k])
282 end DO
283
284 PRINT *, 'Traitement de la sst'
285 call NF95_OPEN('amipbc_sst_1x1.nc', NF90_NOWRITE, ncid)
286
287 call nf95_inq_varid(ncid, "longitude", varid)
288 call nf95_gw_var(ncid, varid, dlon_ini)
289 imdep = size(dlon_ini)
290
291 call nf95_inq_varid(ncid, "latitude", varid)
292 call nf95_gw_var(ncid, varid, dlat_ini)
293 jmdep = size(dlat_ini)
294
295 call nf95_inq_dimid(ncid, "time", dimid)
296 call NF95_INQuire_DIMension(ncid, dimid, nclen=lmdep)
297 print *, 'lmdep = ', lmdep
298 ! Ici on suppose qu'on a 12 mois (de 30 jours).
299 call assert(lmdep == 12, 'limit: AMIP file does not contain 12 months')
300
301 ALLOCATE(champ(imdep, jmdep), champtime(iim, jjm + 1, lmdep))
302 IF (extrap) ALLOCATE(work(imdep, jmdep))
303 ALLOCATE(dlon(imdep), dlat(jmdep))
304 call NF95_INQ_VARID(ncid, 'tosbcs', varid)
305
306 DO l = 1, lmdep
307 call NF95_GET_VAR(ncid, varid, champ, start=[1, 1, l])
308 CALL conf_dat2d(dlon_ini, dlat_ini, dlon, dlat, champ)
309 IF (extrap) &
310 CALL extrapol(champ, imdep, jmdep, 999999., .TRUE., .TRUE., 2, work)
311 CALL inter_barxy(dlon, dlat(:jmdep -1), champ, rlonu(:iim), rlatv, &
312 champtime(:, :, l))
313 ENDDO
314
315 call NF95_CLOSE(ncid)
316 DEALLOCATE(dlon, dlat, champ)
317 allocate(yder(lmdep))
318
319 ! interpolation temporelle
320 DO j = 1, jjm + 1
321 DO i = 1, iim
322 yder = SPLINE(tmidmonth, champtime(i, j, :))
323 DO k = 1, 360
324 champan(i, j, k) = SPLINT(tmidmonth, champtime(i, j, :), yder, &
325 real(k-1))
326 ENDDO
327 ENDDO
328 ENDDO
329
330 deallocate(champtime, yder)
331 champan(iim + 1, :, :) = champan(1, :, :)
332
333 !IM14/03/2002 : SST amipbc greater then 271.38
334 PRINT *, 'limit: SST Amipbc >= 271.38 '
335
336 DO k = 1, 360
337 DO j = 1, jjm + 1
338 DO i = 1, iim
339 champan(i, j, k) = max(champan(i, j, k), 271.38)
340 ENDDO
341
342 champan(iim + 1, j, k) = champan(1, j, k)
343 ENDDO
344 ENDDO
345
346 DO k = 1, 360
347 call NF95_PUT_VAR(ncid_limit, id_SST, pack(champan(:, :, k), dyn_phy), &
348 start=[1, k])
349 end DO
350
351 PRINT *, "Traitement de l'albedo..."
352 call NF95_OPEN('Albedo.nc', NF90_NOWRITE, ncid)
353
354 call nf95_inq_varid(ncid, "longitude", varid)
355 call nf95_gw_var(ncid, varid, dlon_ini)
356 imdep = size(dlon_ini)
357
358 call nf95_inq_varid(ncid, "latitude", varid)
359 call nf95_gw_var(ncid, varid, dlat_ini)
360 jmdep = size(dlat_ini)
361
362 call nf95_inq_varid(ncid, "temps", varid)
363 call nf95_gw_var(ncid, varid, timeyear)
364 lmdep = size(timeyear)
365
366 ALLOCATE(champ(imdep, jmdep), champtime(iim, jjm + 1, lmdep))
367 ALLOCATE(dlon(imdep), dlat(jmdep))
368 call NF95_INQ_VARID(ncid, 'ALBEDO', varid)
369
370 DO l = 1, lmdep
371 PRINT *, "timeyear(", l, ") =", timeyear(l)
372 call NF95_GET_VAR(ncid, varid, champ, start=[1, 1, l])
373 CALL conf_dat2d(dlon_ini, dlat_ini, dlon, dlat, champ)
374 CALL inter_barxy(dlon, dlat(:jmdep-1), champ, rlonu(:iim), rlatv, &
375 champtime(:, :, l))
376 ENDDO
377
378 call NF95_CLOSE(ncid)
379
380 allocate(yder(lmdep))
381
382 ! interpolation temporelle
383 DO j = 1, jjm + 1
384 DO i = 1, iim
385 yder = SPLINE(timeyear, champtime(i, j, :))
386 DO k = 1, 360
387 champan(i, j, k) = SPLINT(timeyear, champtime(i, j, :), yder, &
388 real(k-1))
389 ENDDO
390 ENDDO
391 ENDDO
392
393 champan(iim + 1, :, :) = champan(1, :, :)
394
395 DO k = 1, 360
396 call NF95_PUT_VAR(ncid_limit, id_ALB, pack(champan(:, :, k), dyn_phy), &
397 start=[1, k])
398 end DO
399
400 phy_bil = 0.
401 call NF95_PUT_VAR(ncid_limit, id_BILS, phy_bil)
402
403 call NF95_CLOSE(ncid_limit)
404
405 END SUBROUTINE limit
406
407 end module limit_mod

  ViewVC Help
Powered by ViewVC 1.1.21