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

Annotation of /trunk/dyn3d/limit.f

Parent Directory Parent Directory | Revision Log Revision Log


Revision 264 - (hide annotations)
Mon Mar 19 10:28:42 2018 UTC (6 years, 2 months 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 guez 3 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 guez 247 ! It uses files with climatological data. Both grids must be
13     ! regular.
14 guez 3
15 guez 57 use conf_dat2d_m, only: conf_dat2d
16 guez 3 use dimens_m, only: iim, jjm
17     use dimphy, only: klon, zmasq
18 guez 139 use dynetat0_m, only: rlonu, rlatv
19 guez 3 use etat0_mod, only: pctsrf
20 guez 57 use grid_change, only: dyn_phy
21 guez 264 use indicesol, only: epsfra, is_ter, is_oce, is_lic, is_sic
22 guez 3 use inter_barxy_m, only: inter_barxy
23 guez 98 use netcdf95, only: NF95_CLOSE, NF95_CREATE, NF95_DEF_DIM, nf95_def_var, &
24 guez 97 nf95_enddef, nf95_get_var, nf95_gw_var, nf95_inq_dimid, &
25 guez 98 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 guez 247 use nr_util, only: assert
30 guez 61 use numer_rec_95, only: spline, splint
31 guez 57 use start_init_orog_m, only: mask
32     use unit_nml_m, only: unit_nml
33 guez 3
34 guez 247 ! Local:
35 guez 3
36     LOGICAL:: extrap = .FALSE.
37 guez 139 ! (extrapolation de donn\'ees, comme pour les SST lorsque le fichier
38     ! ne contient pas uniquement des points oc\'eaniques)
39 guez 3
40     REAL phy_bil(klon, 360)
41     REAL phy_ice(klon)
42    
43 guez 139 ! Pour le champ de d\'epart:
44 guez 3 INTEGER imdep, jmdep, lmdep
45    
46     REAL, ALLOCATABLE:: dlon(:), dlat(:)
47 guez 225 REAL, ALLOCATABLE:: dlon_ini(:), dlat_ini(:), timeyear(:)
48 guez 3 REAL, ALLOCATABLE:: champ(:, :)
49     REAL, ALLOCATABLE:: work(:, :)
50    
51 guez 139 ! Pour le champ interpol\'e 3D :
52 guez 3 REAL, allocatable:: champtime(:, :, :)
53     REAL champan(iim + 1, jjm + 1, 360)
54    
55     ! Pour l'inteprolation verticale :
56     REAL, allocatable:: yder(:)
57    
58 guez 264 INTEGER ndim, ntim
59     INTEGER varid_time
60 guez 3 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 guez 264 INTEGER ncid, ncid_limit, varid, dimid
65 guez 3
66 guez 264 REAL, parameter:: tmidmonth(12) = [(15. + 30. * i, i = 0, 11)]
67 guez 3
68     namelist /limit_nml/extrap
69    
70     !--------------------
71    
72     print *, "Call sequence information: limit"
73    
74     print *, "Enter namelist 'limit_nml'."
75 guez 98 read(unit=*, nml=limit_nml)
76 guez 57 write(unit_nml, nml=limit_nml)
77 guez 3
78 guez 264 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 guez 68 PRINT *, 'Processing rugosity...'
127 guez 3
128     call NF95_OPEN('Rugos.nc', NF90_NOWRITE, ncid)
129    
130 guez 15 ! Read coordinate variables:
131    
132 guez 22 call nf95_inq_varid(ncid, "longitude", varid)
133     call nf95_gw_var(ncid, varid, dlon_ini)
134 guez 3 imdep = size(dlon_ini)
135    
136 guez 22 call nf95_inq_varid(ncid, "latitude", varid)
137     call nf95_gw_var(ncid, varid, dlat_ini)
138 guez 3 jmdep = size(dlat_ini)
139    
140 guez 22 call nf95_inq_varid(ncid, "temps", varid)
141     call nf95_gw_var(ncid, varid, timeyear)
142 guez 3 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 guez 15 ! Read the primary variable day by day and regrid horizontally,
149     ! result in "champtime":
150 guez 3 DO l = 1, lmdep
151 guez 264 call NF95_GET_VAR(ncid, varid, champ, start=[1, 1, l])
152 guez 3 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 guez 15 where (nint(mask(:iim, :)) /= 1) champtime(:, :, l) = 0.001
157 guez 3 end do
158    
159     call NF95_CLOSE(ncid)
160    
161 guez 225 DEALLOCATE(dlon, dlat, champ)
162 guez 3 allocate(yder(lmdep))
163    
164 guez 15 ! Interpolate monthly values to daily values, at each horizontal position:
165 guez 3 DO j = 1, jjm + 1
166     DO i = 1, iim
167 guez 68 yder = SPLINE(timeyear, champtime(i, j, :))
168 guez 3 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 guez 225 deallocate(champtime, yder)
176 guez 3 champan(iim + 1, :, :) = champan(1, :, :)
177    
178 guez 264 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 guez 3
183     PRINT *, 'Processing sea ice...'
184     call NF95_OPEN('amipbc_sic_1x1.nc', NF90_NOWRITE, ncid)
185    
186 guez 22 call nf95_inq_varid(ncid, "longitude", varid)
187     call nf95_gw_var(ncid, varid, dlon_ini)
188 guez 3 imdep = size(dlon_ini)
189    
190 guez 22 call nf95_inq_varid(ncid, "latitude", varid)
191     call nf95_gw_var(ncid, varid, dlat_ini)
192 guez 3 jmdep = size(dlat_ini)
193    
194     call nf95_inq_dimid(ncid, "time", dimid)
195 guez 34 call NF95_INQuire_DIMension(ncid, dimid, nclen=lmdep)
196 guez 3 print *, 'lmdep = ', lmdep
197 guez 139 ! Coordonn\'ee temporelle fichiers AMIP pas en jours. Ici on suppose
198 guez 68 ! 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 guez 3
204     ALLOCATE(champ(imdep, jmdep), champtime(iim, jjm + 1, lmdep))
205 guez 98 ALLOCATE(dlon(imdep), dlat(jmdep))
206 guez 3 call NF95_INQ_VARID(ncid, 'sicbcs', varid)
207     DO l = 1, lmdep
208 guez 264 call NF95_GET_VAR(ncid, varid, champ, start=[1, 1, l])
209 guez 3 CALL conf_dat2d(dlon_ini, dlat_ini, dlon, dlat, champ)
210 guez 98 CALL inter_barxy(dlon, dlat(:jmdep -1), champ, rlonu(:iim), rlatv, &
211 guez 3 champtime(:, :, l))
212     ENDDO
213    
214     call NF95_CLOSE(ncid)
215    
216 guez 225 DEALLOCATE(dlon, dlat, champ)
217 guez 3 PRINT *, 'Interpolation temporelle'
218     allocate(yder(lmdep))
219    
220     DO j = 1, jjm + 1
221     DO i = 1, iim
222 guez 68 yder = SPLINE(tmidmonth, champtime(i, j, :))
223 guez 3 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 guez 68 phy_ice = pack(champan(:, :, k), dyn_phy)
239 guez 3
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 guez 68 WHERE (phy_ice < EPSFRA) phy_ice = 0.
244 guez 3
245 guez 264 pctsrf(:, is_sic) = max(phy_ice - pctsrf(:, is_lic), 0.)
246 guez 139 ! Il y a des cas o\`u il y a de la glace dans landiceref et
247 guez 3 ! pas dans AMIP
248 guez 68 WHERE (1. - zmasq < EPSFRA)
249 guez 264 pctsrf(:, is_sic) = 0.
250     pctsrf(:, is_oce) = 0.
251 guez 3 elsewhere
252 guez 264 where (pctsrf(:, is_sic) >= 1 - zmasq)
253     pctsrf(:, is_sic) = 1. - zmasq
254     pctsrf(:, is_oce) = 0.
255 guez 3 ELSEwhere
256 guez 264 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 guez 3 end where
261     end where
262     end where
263    
264     DO i = 1, klon
265 guez 264 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 guez 3 ENDIF
270 guez 264 IF (abs(sum(pctsrf(i, :)) - 1.) > EPSFRA) THEN
271     print *, "k = ", k
272 guez 139 print *, 'Bad surface fraction:'
273 guez 264 print *, "pctsrf(", i, ", :) = ", pctsrf(i, :)
274 guez 3 print *, "phy_ice(", i, ") = ", phy_ice(i)
275     ENDIF
276     END DO
277    
278 guez 264 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 guez 3 PRINT *, 'Traitement de la sst'
285     call NF95_OPEN('amipbc_sst_1x1.nc', NF90_NOWRITE, ncid)
286    
287 guez 22 call nf95_inq_varid(ncid, "longitude", varid)
288     call nf95_gw_var(ncid, varid, dlon_ini)
289 guez 3 imdep = size(dlon_ini)
290    
291 guez 22 call nf95_inq_varid(ncid, "latitude", varid)
292     call nf95_gw_var(ncid, varid, dlat_ini)
293 guez 3 jmdep = size(dlat_ini)
294    
295     call nf95_inq_dimid(ncid, "time", dimid)
296 guez 34 call NF95_INQuire_DIMension(ncid, dimid, nclen=lmdep)
297 guez 3 print *, 'lmdep = ', lmdep
298 guez 247 ! 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 guez 3
301 guez 68 ALLOCATE(champ(imdep, jmdep), champtime(iim, jjm + 1, lmdep))
302 guez 247 IF (extrap) ALLOCATE(work(imdep, jmdep))
303 guez 68 ALLOCATE(dlon(imdep), dlat(jmdep))
304 guez 3 call NF95_INQ_VARID(ncid, 'tosbcs', varid)
305    
306     DO l = 1, lmdep
307 guez 264 call NF95_GET_VAR(ncid, varid, champ, start=[1, 1, l])
308 guez 3 CALL conf_dat2d(dlon_ini, dlat_ini, dlon, dlat, champ)
309 guez 247 IF (extrap) &
310     CALL extrapol(champ, imdep, jmdep, 999999., .TRUE., .TRUE., 2, work)
311 guez 98 CALL inter_barxy(dlon, dlat(:jmdep -1), champ, rlonu(:iim), rlatv, &
312 guez 68 champtime(:, :, l))
313 guez 3 ENDDO
314    
315     call NF95_CLOSE(ncid)
316 guez 225 DEALLOCATE(dlon, dlat, champ)
317 guez 3 allocate(yder(lmdep))
318    
319     ! interpolation temporelle
320     DO j = 1, jjm + 1
321     DO i = 1, iim
322 guez 68 yder = SPLINE(tmidmonth, champtime(i, j, :))
323 guez 3 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 guez 247 PRINT *, 'limit: SST Amipbc >= 271.38 '
335    
336 guez 3 DO k = 1, 360
337     DO j = 1, jjm + 1
338     DO i = 1, iim
339 guez 247 champan(i, j, k) = max(champan(i, j, k), 271.38)
340 guez 3 ENDDO
341 guez 247
342 guez 3 champan(iim + 1, j, k) = champan(1, j, k)
343     ENDDO
344     ENDDO
345 guez 247
346 guez 264 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 guez 3
351 guez 97 PRINT *, "Traitement de l'albedo..."
352 guez 3 call NF95_OPEN('Albedo.nc', NF90_NOWRITE, ncid)
353    
354 guez 22 call nf95_inq_varid(ncid, "longitude", varid)
355     call nf95_gw_var(ncid, varid, dlon_ini)
356 guez 3 imdep = size(dlon_ini)
357    
358 guez 22 call nf95_inq_varid(ncid, "latitude", varid)
359     call nf95_gw_var(ncid, varid, dlat_ini)
360 guez 3 jmdep = size(dlat_ini)
361    
362 guez 22 call nf95_inq_varid(ncid, "temps", varid)
363     call nf95_gw_var(ncid, varid, timeyear)
364 guez 3 lmdep = size(timeyear)
365    
366 guez 98 ALLOCATE(champ(imdep, jmdep), champtime(iim, jjm + 1, lmdep))
367     ALLOCATE(dlon(imdep), dlat(jmdep))
368 guez 3 call NF95_INQ_VARID(ncid, 'ALBEDO', varid)
369    
370     DO l = 1, lmdep
371 guez 97 PRINT *, "timeyear(", l, ") =", timeyear(l)
372 guez 264 call NF95_GET_VAR(ncid, varid, champ, start=[1, 1, l])
373 guez 3 CALL conf_dat2d(dlon_ini, dlat_ini, dlon, dlat, champ)
374     CALL inter_barxy(dlon, dlat(:jmdep-1), champ, rlonu(:iim), rlatv, &
375 guez 68 champtime(:, :, l))
376 guez 3 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 guez 68 yder = SPLINE(timeyear, champtime(i, j, :))
386 guez 3 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 guez 264 call NF95_PUT_VAR(ncid_limit, id_ALB, pack(champan(:, :, k), dyn_phy), &
397     start=[1, k])
398     end DO
399 guez 3
400 guez 264 phy_bil = 0.
401     call NF95_PUT_VAR(ncid_limit, id_BILS, phy_bil)
402 guez 3
403 guez 264 call NF95_CLOSE(ncid_limit)
404 guez 3
405     END SUBROUTINE limit
406    
407     end module limit_mod

  ViewVC Help
Powered by ViewVC 1.1.21