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

Annotation of /trunk/dyn3d/limit.f

Parent Directory Parent Directory | Revision Log Revision Log


Revision 276 - (hide annotations)
Thu Jul 12 14:49:20 2018 UTC (5 years, 11 months ago) by guez
File size: 13401 byte(s)
Move procedure read_serre from module read_serre_m to module
dynetat0_m, to avoid side effet on variables of module dynetat0_m.

Create procedure set_unit_nml to avoid side effect on variable of
module unit_nml_m.

Downgrade pctsrf from variable of module etat0_m to argument of etat0
and limit to avoid side effect on pctsrf.

Move variable zmasq from module dimphy to module phyetat0_m to avoid
side effect on zmasq.

1 guez 3 module limit_mod
2    
3     IMPLICIT none
4    
5     contains
6    
7 guez 276 SUBROUTINE limit(pctsrf)
8 guez 3
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 265 use dimensions, only: iim, jjm
17 guez 276 use dimphy, only: klon
18 guez 139 use dynetat0_m, only: rlonu, rlatv
19 guez 57 use grid_change, only: dyn_phy
20 guez 264 use indicesol, only: epsfra, is_ter, is_oce, is_lic, is_sic
21 guez 3 use inter_barxy_m, only: inter_barxy
22 guez 98 use netcdf95, only: NF95_CLOSE, NF95_CREATE, NF95_DEF_DIM, nf95_def_var, &
23 guez 97 nf95_enddef, nf95_get_var, nf95_gw_var, nf95_inq_dimid, &
24 guez 98 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 guez 247 use nr_util, only: assert
29 guez 61 use numer_rec_95, only: spline, splint
30 guez 276 use phyetat0_m, only: zmasq
31 guez 57 use start_init_orog_m, only: mask
32     use unit_nml_m, only: unit_nml
33 guez 3
34 guez 276 REAL, intent(inout):: pctsrf(:, :) ! (klon, nbsrf)
35     ! "pctsrf(i, :)" is the composition of the surface at horizontal
36     ! position "i".
37    
38 guez 247 ! Local:
39 guez 3
40     LOGICAL:: extrap = .FALSE.
41 guez 139 ! (extrapolation de donn\'ees, comme pour les SST lorsque le fichier
42     ! ne contient pas uniquement des points oc\'eaniques)
43 guez 3
44     REAL phy_bil(klon, 360)
45     REAL phy_ice(klon)
46    
47 guez 139 ! Pour le champ de d\'epart:
48 guez 3 INTEGER imdep, jmdep, lmdep
49    
50     REAL, ALLOCATABLE:: dlon(:), dlat(:)
51 guez 225 REAL, ALLOCATABLE:: dlon_ini(:), dlat_ini(:), timeyear(:)
52 guez 3 REAL, ALLOCATABLE:: champ(:, :)
53     REAL, ALLOCATABLE:: work(:, :)
54    
55 guez 139 ! Pour le champ interpol\'e 3D :
56 guez 3 REAL, allocatable:: champtime(:, :, :)
57     REAL champan(iim + 1, jjm + 1, 360)
58    
59     ! Pour l'inteprolation verticale :
60     REAL, allocatable:: yder(:)
61    
62 guez 264 INTEGER ndim, ntim
63     INTEGER varid_time
64 guez 3 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 guez 264 INTEGER ncid, ncid_limit, varid, dimid
69 guez 3
70 guez 264 REAL, parameter:: tmidmonth(12) = [(15. + 30. * i, i = 0, 11)]
71 guez 3
72     namelist /limit_nml/extrap
73    
74     !--------------------
75    
76     print *, "Call sequence information: limit"
77    
78     print *, "Enter namelist 'limit_nml'."
79 guez 98 read(unit=*, nml=limit_nml)
80 guez 57 write(unit_nml, nml=limit_nml)
81 guez 3
82 guez 264 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 guez 68 PRINT *, 'Processing rugosity...'
131 guez 3
132     call NF95_OPEN('Rugos.nc', NF90_NOWRITE, ncid)
133    
134 guez 15 ! Read coordinate variables:
135    
136 guez 22 call nf95_inq_varid(ncid, "longitude", varid)
137     call nf95_gw_var(ncid, varid, dlon_ini)
138 guez 3 imdep = size(dlon_ini)
139    
140 guez 22 call nf95_inq_varid(ncid, "latitude", varid)
141     call nf95_gw_var(ncid, varid, dlat_ini)
142 guez 3 jmdep = size(dlat_ini)
143    
144 guez 22 call nf95_inq_varid(ncid, "temps", varid)
145     call nf95_gw_var(ncid, varid, timeyear)
146 guez 3 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 guez 15 ! Read the primary variable day by day and regrid horizontally,
153     ! result in "champtime":
154 guez 3 DO l = 1, lmdep
155 guez 264 call NF95_GET_VAR(ncid, varid, champ, start=[1, 1, l])
156 guez 3 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 guez 15 where (nint(mask(:iim, :)) /= 1) champtime(:, :, l) = 0.001
161 guez 3 end do
162    
163     call NF95_CLOSE(ncid)
164    
165 guez 225 DEALLOCATE(dlon, dlat, champ)
166 guez 3 allocate(yder(lmdep))
167    
168 guez 15 ! Interpolate monthly values to daily values, at each horizontal position:
169 guez 3 DO j = 1, jjm + 1
170     DO i = 1, iim
171 guez 68 yder = SPLINE(timeyear, champtime(i, j, :))
172 guez 3 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 guez 225 deallocate(champtime, yder)
180 guez 3 champan(iim + 1, :, :) = champan(1, :, :)
181    
182 guez 264 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 guez 3
187     PRINT *, 'Processing sea ice...'
188     call NF95_OPEN('amipbc_sic_1x1.nc', NF90_NOWRITE, ncid)
189    
190 guez 22 call nf95_inq_varid(ncid, "longitude", varid)
191     call nf95_gw_var(ncid, varid, dlon_ini)
192 guez 3 imdep = size(dlon_ini)
193    
194 guez 22 call nf95_inq_varid(ncid, "latitude", varid)
195     call nf95_gw_var(ncid, varid, dlat_ini)
196 guez 3 jmdep = size(dlat_ini)
197    
198     call nf95_inq_dimid(ncid, "time", dimid)
199 guez 34 call NF95_INQuire_DIMension(ncid, dimid, nclen=lmdep)
200 guez 3 print *, 'lmdep = ', lmdep
201 guez 139 ! Coordonn\'ee temporelle fichiers AMIP pas en jours. Ici on suppose
202 guez 68 ! 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 guez 3
208     ALLOCATE(champ(imdep, jmdep), champtime(iim, jjm + 1, lmdep))
209 guez 98 ALLOCATE(dlon(imdep), dlat(jmdep))
210 guez 3 call NF95_INQ_VARID(ncid, 'sicbcs', varid)
211     DO l = 1, lmdep
212 guez 264 call NF95_GET_VAR(ncid, varid, champ, start=[1, 1, l])
213 guez 3 CALL conf_dat2d(dlon_ini, dlat_ini, dlon, dlat, champ)
214 guez 98 CALL inter_barxy(dlon, dlat(:jmdep -1), champ, rlonu(:iim), rlatv, &
215 guez 3 champtime(:, :, l))
216     ENDDO
217    
218     call NF95_CLOSE(ncid)
219    
220 guez 225 DEALLOCATE(dlon, dlat, champ)
221 guez 3 PRINT *, 'Interpolation temporelle'
222     allocate(yder(lmdep))
223    
224     DO j = 1, jjm + 1
225     DO i = 1, iim
226 guez 68 yder = SPLINE(tmidmonth, champtime(i, j, :))
227 guez 3 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 guez 68 phy_ice = pack(champan(:, :, k), dyn_phy)
243 guez 3
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 guez 68 WHERE (phy_ice < EPSFRA) phy_ice = 0.
248 guez 3
249 guez 264 pctsrf(:, is_sic) = max(phy_ice - pctsrf(:, is_lic), 0.)
250 guez 139 ! Il y a des cas o\`u il y a de la glace dans landiceref et
251 guez 3 ! pas dans AMIP
252 guez 68 WHERE (1. - zmasq < EPSFRA)
253 guez 264 pctsrf(:, is_sic) = 0.
254     pctsrf(:, is_oce) = 0.
255 guez 3 elsewhere
256 guez 264 where (pctsrf(:, is_sic) >= 1 - zmasq)
257     pctsrf(:, is_sic) = 1. - zmasq
258     pctsrf(:, is_oce) = 0.
259 guez 3 ELSEwhere
260 guez 264 pctsrf(:, is_oce) = 1. - zmasq - pctsrf(:, is_sic)
261     where (pctsrf(:, is_oce) < EPSFRA)
262     pctsrf(:, is_oce) = 0.
263     pctsrf(:, is_sic) = 1 - zmasq
264 guez 3 end where
265     end where
266     end where
267    
268     DO i = 1, klon
269 guez 264 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 guez 3 ENDIF
274 guez 264 IF (abs(sum(pctsrf(i, :)) - 1.) > EPSFRA) THEN
275     print *, "k = ", k
276 guez 139 print *, 'Bad surface fraction:'
277 guez 264 print *, "pctsrf(", i, ", :) = ", pctsrf(i, :)
278 guez 3 print *, "phy_ice(", i, ") = ", phy_ice(i)
279     ENDIF
280     END DO
281    
282 guez 264 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 guez 3 PRINT *, 'Traitement de la sst'
289     call NF95_OPEN('amipbc_sst_1x1.nc', NF90_NOWRITE, ncid)
290    
291 guez 22 call nf95_inq_varid(ncid, "longitude", varid)
292     call nf95_gw_var(ncid, varid, dlon_ini)
293 guez 3 imdep = size(dlon_ini)
294    
295 guez 22 call nf95_inq_varid(ncid, "latitude", varid)
296     call nf95_gw_var(ncid, varid, dlat_ini)
297 guez 3 jmdep = size(dlat_ini)
298    
299     call nf95_inq_dimid(ncid, "time", dimid)
300 guez 34 call NF95_INQuire_DIMension(ncid, dimid, nclen=lmdep)
301 guez 3 print *, 'lmdep = ', lmdep
302 guez 247 ! 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 guez 3
305 guez 68 ALLOCATE(champ(imdep, jmdep), champtime(iim, jjm + 1, lmdep))
306 guez 247 IF (extrap) ALLOCATE(work(imdep, jmdep))
307 guez 68 ALLOCATE(dlon(imdep), dlat(jmdep))
308 guez 3 call NF95_INQ_VARID(ncid, 'tosbcs', varid)
309    
310     DO l = 1, lmdep
311 guez 264 call NF95_GET_VAR(ncid, varid, champ, start=[1, 1, l])
312 guez 3 CALL conf_dat2d(dlon_ini, dlat_ini, dlon, dlat, champ)
313 guez 247 IF (extrap) &
314     CALL extrapol(champ, imdep, jmdep, 999999., .TRUE., .TRUE., 2, work)
315 guez 98 CALL inter_barxy(dlon, dlat(:jmdep -1), champ, rlonu(:iim), rlatv, &
316 guez 68 champtime(:, :, l))
317 guez 3 ENDDO
318    
319     call NF95_CLOSE(ncid)
320 guez 225 DEALLOCATE(dlon, dlat, champ)
321 guez 3 allocate(yder(lmdep))
322    
323     ! interpolation temporelle
324     DO j = 1, jjm + 1
325     DO i = 1, iim
326 guez 68 yder = SPLINE(tmidmonth, champtime(i, j, :))
327 guez 3 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 guez 247 PRINT *, 'limit: SST Amipbc >= 271.38 '
339    
340 guez 3 DO k = 1, 360
341     DO j = 1, jjm + 1
342     DO i = 1, iim
343 guez 247 champan(i, j, k) = max(champan(i, j, k), 271.38)
344 guez 3 ENDDO
345 guez 247
346 guez 3 champan(iim + 1, j, k) = champan(1, j, k)
347     ENDDO
348     ENDDO
349 guez 247
350 guez 264 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 guez 3
355 guez 97 PRINT *, "Traitement de l'albedo..."
356 guez 3 call NF95_OPEN('Albedo.nc', NF90_NOWRITE, ncid)
357    
358 guez 22 call nf95_inq_varid(ncid, "longitude", varid)
359     call nf95_gw_var(ncid, varid, dlon_ini)
360 guez 3 imdep = size(dlon_ini)
361    
362 guez 22 call nf95_inq_varid(ncid, "latitude", varid)
363     call nf95_gw_var(ncid, varid, dlat_ini)
364 guez 3 jmdep = size(dlat_ini)
365    
366 guez 22 call nf95_inq_varid(ncid, "temps", varid)
367     call nf95_gw_var(ncid, varid, timeyear)
368 guez 3 lmdep = size(timeyear)
369    
370 guez 98 ALLOCATE(champ(imdep, jmdep), champtime(iim, jjm + 1, lmdep))
371     ALLOCATE(dlon(imdep), dlat(jmdep))
372 guez 3 call NF95_INQ_VARID(ncid, 'ALBEDO', varid)
373    
374     DO l = 1, lmdep
375 guez 97 PRINT *, "timeyear(", l, ") =", timeyear(l)
376 guez 264 call NF95_GET_VAR(ncid, varid, champ, start=[1, 1, l])
377 guez 3 CALL conf_dat2d(dlon_ini, dlat_ini, dlon, dlat, champ)
378     CALL inter_barxy(dlon, dlat(:jmdep-1), champ, rlonu(:iim), rlatv, &
379 guez 68 champtime(:, :, l))
380 guez 3 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 guez 68 yder = SPLINE(timeyear, champtime(i, j, :))
390 guez 3 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 guez 264 call NF95_PUT_VAR(ncid_limit, id_ALB, pack(champan(:, :, k), dyn_phy), &
401     start=[1, k])
402     end DO
403 guez 3
404 guez 264 phy_bil = 0.
405     call NF95_PUT_VAR(ncid_limit, id_BILS, phy_bil)
406 guez 3
407 guez 264 call NF95_CLOSE(ncid_limit)
408 guez 3
409     END SUBROUTINE limit
410    
411     end module limit_mod

  ViewVC Help
Powered by ViewVC 1.1.21