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

Contents of /trunk/dyn3d/limit.f

Parent Directory Parent Directory | Revision Log Revision Log


Revision 324 - (show annotations)
Wed Feb 6 15:58:03 2019 UTC (5 years, 3 months ago) by guez
File size: 13407 byte(s)
Rename variable zmasq of module phyetat0_m to masque, which was
already its name in "restartphy.nc". Rename variable fraclic of
procedure etat0 to landice, which was already its name in
"landiceref.nc". Style guide: we try to have the same names for
identical data objects across the program.

In procedure interfsurf_hq, in case is_sic, define tsurf instead of
tsurf_new, avoiding a copy from tsurf_new to tsurf.

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

  ViewVC Help
Powered by ViewVC 1.1.21