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

Annotation of /trunk/dyn3d/limit.f

Parent Directory Parent Directory | Revision Log Revision Log


Revision 247 - (hide annotations)
Fri Jan 5 14:45:45 2018 UTC (6 years, 4 months ago) by guez
Original Path: trunk/Sources/dyn3d/limit.f
File size: 13692 byte(s)
In clvent, clearer to use ven rather than local_ven if possible.

In physiq, igwd was useless.

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

  ViewVC Help
Powered by ViewVC 1.1.21