1 | !! |
---|
2 | !! This module computes surface conditions |
---|
3 | !! - albedo |
---|
4 | !! - roughness |
---|
5 | !! - emissivity |
---|
6 | !! |
---|
7 | !! @author Marie-Alice Foujols and Jan Polcher |
---|
8 | !! @Version : $Revision: 45 $, $Date: 2011-01-01 21:30:44 +0100 (Sat, 01 Jan 2011) $ |
---|
9 | !! |
---|
10 | !< $HeadURL: http://forge.ipsl.jussieu.fr/orchidee/svn/trunk/ORCHIDEE/src_sechiba/condveg.f90 $ |
---|
11 | !< $Date: 2011-01-01 21:30:44 +0100 (Sat, 01 Jan 2011) $ |
---|
12 | !< $Author: mmaipsl $ |
---|
13 | !< $Revision: 45 $ |
---|
14 | !! IPSL (2006) |
---|
15 | !! This software is governed by the CeCILL licence see ORCHIDEE/ORCHIDEE_CeCILL.LIC |
---|
16 | !! |
---|
17 | MODULE condveg |
---|
18 | ! |
---|
19 | USE ioipsl |
---|
20 | ! |
---|
21 | ! modules used : |
---|
22 | USE constantes |
---|
23 | USE pft_parameters |
---|
24 | USE interpol_help |
---|
25 | USE parallel |
---|
26 | |
---|
27 | IMPLICIT NONE |
---|
28 | |
---|
29 | ! public routines : |
---|
30 | ! condveg_main only |
---|
31 | PRIVATE |
---|
32 | PUBLIC :: condveg_main,condveg_clear |
---|
33 | |
---|
34 | ! |
---|
35 | ! variables used inside condveg module : declaration and initialisation |
---|
36 | ! |
---|
37 | LOGICAL, SAVE :: l_first_condveg=.TRUE. !! To keep first call's trace |
---|
38 | ! |
---|
39 | REAL(r_std), ALLOCATABLE, SAVE :: soilalb_dry(:,:) !! albedo for the dry bare soil |
---|
40 | REAL(r_std), ALLOCATABLE, SAVE :: soilalb_wet(:,:) !! albedo for the wet bare soil |
---|
41 | ! Ajout Nathalie pour autre calcul soilalbedo |
---|
42 | REAL(r_std), ALLOCATABLE, SAVE :: soilalb_moy(:,:) !! mean soil albedo. |
---|
43 | ! Ajouts Nathalie - Septembre 2008 |
---|
44 | REAL(r_std), ALLOCATABLE, SAVE :: alb_bare(:,:) !! Soil Albedo, vis(1) and nir(2) |
---|
45 | REAL(r_std), ALLOCATABLE, SAVE :: alb_veget(:,:) !! Vegetation Albedo, vis(1) and nir(2) |
---|
46 | ! |
---|
47 | REAL(r_std), ALLOCATABLE, SAVE, DIMENSION (:) :: albedo_snow !! Snow albedo |
---|
48 | REAL(r_std), ALLOCATABLE, SAVE, DIMENSION (:) :: albedo_glob !! Mean albedo |
---|
49 | ! |
---|
50 | |
---|
51 | CONTAINS |
---|
52 | |
---|
53 | !! |
---|
54 | !! Main routine for *condveg* module |
---|
55 | !! - called only one time for initialisation |
---|
56 | !! - called every time step |
---|
57 | !! - called one more time at last time step for writing _restart_ file |
---|
58 | !! |
---|
59 | !! Algorithm: |
---|
60 | !! - call condveg_init for initialisation |
---|
61 | !! - call condveg_var_init for initialisation done every time step |
---|
62 | !! - call condveg_snow for computing the modification of the albedo induced by snow cover |
---|
63 | !! |
---|
64 | !! @call condveg_init |
---|
65 | !! @call condveg_var_init |
---|
66 | !! @call condveg_snow |
---|
67 | !! |
---|
68 | !! |
---|
69 | SUBROUTINE condveg_main (kjit, kjpindex, dtradia, ldrestart_read, ldrestart_write, index,& |
---|
70 | & lalo, neighbours, resolution, contfrac, veget, veget_max, frac_nobio, totfrac_nobio, & |
---|
71 | & zlev, snow, snow_age, snow_nobio, snow_nobio_age, & |
---|
72 | & drysoil_frac, height, deadleaf_cover, emis, albedo, z0, roughheight, soiltype, rest_id, hist_id, hist2_id) |
---|
73 | |
---|
74 | ! interface description: |
---|
75 | ! input scalar |
---|
76 | INTEGER(i_std), INTENT(in) :: kjit !! Time step number |
---|
77 | INTEGER(i_std), INTENT(in) :: kjpindex !! Domain size |
---|
78 | INTEGER(i_std),INTENT (in) :: rest_id !! _Restart_ file identifier |
---|
79 | INTEGER(i_std),INTENT (in) :: hist_id !! _History_ file identifier |
---|
80 | INTEGER(i_std), OPTIONAL, INTENT (in) :: hist2_id !! _History_ file 2 identifier |
---|
81 | REAL(r_std), INTENT (in) :: dtradia !! Time step in seconds |
---|
82 | LOGICAL, INTENT(in) :: ldrestart_read !! Logical for restart file to read |
---|
83 | LOGICAL, INTENT(in) :: ldrestart_write !! Logical for restart file to write |
---|
84 | ! input fields |
---|
85 | INTEGER(i_std),DIMENSION (kjpindex), INTENT (in) :: index !! Indeces of the points on the map |
---|
86 | REAL(r_std),DIMENSION (kjpindex,2), INTENT (in) :: lalo !! Geographical coordinates |
---|
87 | INTEGER(i_std),DIMENSION (kjpindex,8), INTENT(in):: neighbours !! neighoring grid points if land |
---|
88 | REAL(r_std), DIMENSION (kjpindex,2), INTENT(in) :: resolution !! size in x an y of the grid (m) |
---|
89 | REAL(r_std), DIMENSION (kjpindex), INTENT(in) :: contfrac ! Fraction of land in each grid box. |
---|
90 | REAL(r_std),DIMENSION (kjpindex,nvm), INTENT(in) :: veget !! Fraction of vegetation types |
---|
91 | REAL(r_std),DIMENSION (kjpindex,nvm), INTENT(in) :: veget_max !! Fraction of vegetation type |
---|
92 | REAL(r_std),DIMENSION (kjpindex,nnobio), INTENT(in) :: frac_nobio !! Fraction of continental ice, lakes, ... |
---|
93 | REAL(r_std),DIMENSION (kjpindex), INTENT(in) :: totfrac_nobio !! total fraction of continental ice+lakes+... |
---|
94 | REAL(r_std),DIMENSION (kjpindex), INTENT (in) :: zlev !! Height of first layer |
---|
95 | REAL(r_std),DIMENSION (kjpindex), INTENT(in) :: snow !! Snow mass [Kg/m^2] |
---|
96 | REAL(r_std),DIMENSION (kjpindex), INTENT(in) :: snow_age !! Snow age |
---|
97 | REAL(r_std),DIMENSION (kjpindex,nnobio), INTENT(in) :: snow_nobio !! Snow mass [Kg/m^2] on ice, lakes, ... |
---|
98 | REAL(r_std),DIMENSION (kjpindex), INTENT(in) :: snow_nobio_age !! Snow age on ice, lakes, ... |
---|
99 | REAL(r_std),DIMENSION (kjpindex), INTENT(in) :: drysoil_frac !! Fraction of visibly Dry soil(between 0 and 1) |
---|
100 | REAL(r_std),DIMENSION (kjpindex,nvm), INTENT(in) :: height !! Vegetation Height (m) |
---|
101 | REAL(r_std),DIMENSION (kjpindex), INTENT(in) :: deadleaf_cover !! Fraction of soil covered by dead leaves |
---|
102 | ! output scalar |
---|
103 | ! output fields |
---|
104 | REAL(r_std),DIMENSION (kjpindex), INTENT (out) :: emis !! Emissivity |
---|
105 | REAL(r_std),DIMENSION (kjpindex,2), INTENT (out) :: albedo !! Albedo, vis(1) and nir(2) |
---|
106 | REAL(r_std),DIMENSION (kjpindex), INTENT (out) :: z0 !! Roughness |
---|
107 | REAL(r_std),DIMENSION (kjpindex), INTENT (out) :: roughheight !! Effective height for roughness |
---|
108 | REAL(r_std),DIMENSION (kjpindex,nstm), INTENT (in) :: soiltype !! fraction of soil types |
---|
109 | ! local |
---|
110 | CHARACTER(LEN=80) :: var_name !! To store variables names for I/O |
---|
111 | ! |
---|
112 | IF (l_first_condveg) THEN |
---|
113 | |
---|
114 | IF (long_print) WRITE (numout,*) ' l_first_condveg : call condveg_init ' |
---|
115 | |
---|
116 | CALL condveg_init (kjit, ldrestart_read, kjpindex, index, veget, & |
---|
117 | lalo, neighbours, resolution, contfrac, rest_id) |
---|
118 | CALL condveg_var_init (ldrestart_read, kjpindex, veget, veget_max, frac_nobio, totfrac_nobio, & |
---|
119 | & drysoil_frac, zlev, height, deadleaf_cover, emis, albedo, z0, roughheight) |
---|
120 | ! Nathalie - Fevrier 2007 - c'est veget_max qu'il faut passer |
---|
121 | ! Sauf en cas de DGVM .... pour le moment car la somme des maxvegetfrac depasse 1! |
---|
122 | ! Si DGVM alors on passe veget. |
---|
123 | IF (control%ok_dgvm) THEN |
---|
124 | CALL condveg_snow (ldrestart_read, kjpindex, veget, frac_nobio, totfrac_nobio, & |
---|
125 | snow, snow_age, snow_nobio, snow_nobio_age, albedo, albedo_snow, albedo_glob) |
---|
126 | ELSE |
---|
127 | CALL condveg_snow (ldrestart_read, kjpindex, veget_max, frac_nobio, totfrac_nobio, & |
---|
128 | snow, snow_age, snow_nobio, snow_nobio_age, albedo, albedo_snow, albedo_glob) |
---|
129 | ENDIF |
---|
130 | |
---|
131 | RETURN |
---|
132 | |
---|
133 | ENDIF |
---|
134 | |
---|
135 | CALL condveg_var_update (ldrestart_read, kjpindex, veget, veget_max, frac_nobio, totfrac_nobio, & |
---|
136 | & drysoil_frac, zlev, height, deadleaf_cover, emis, albedo, z0, roughheight) |
---|
137 | ! Nathalie - Fevrier 2007 - c'est veget_max qu'il faut passer |
---|
138 | ! Sauf en cas de DGVM .... pour le moment car la somme des maxvegetfrac depasse 1! |
---|
139 | ! Si DGVM alors on passe veget. |
---|
140 | IF (control%ok_dgvm) THEN |
---|
141 | CALL condveg_snow (ldrestart_read, kjpindex, veget, frac_nobio, totfrac_nobio, & |
---|
142 | snow, snow_age, snow_nobio, snow_nobio_age, albedo, albedo_snow, albedo_glob) |
---|
143 | ELSE |
---|
144 | CALL condveg_snow (ldrestart_read, kjpindex, veget_max, frac_nobio, totfrac_nobio, & |
---|
145 | snow, snow_age, snow_nobio, snow_nobio_age, albedo, albedo_snow, albedo_glob) |
---|
146 | ENDIF |
---|
147 | |
---|
148 | IF (ldrestart_write) THEN |
---|
149 | ! |
---|
150 | var_name = 'soilalbedo_dry' |
---|
151 | CALL restput_p (rest_id, var_name, nbp_glo, 2, 1, kjit, soilalb_dry, 'scatter', nbp_glo, index_g) |
---|
152 | ! |
---|
153 | var_name = 'soilalbedo_wet' |
---|
154 | CALL restput_p (rest_id, var_name, nbp_glo, 2, 1, kjit, soilalb_wet, 'scatter', nbp_glo, index_g) |
---|
155 | ! |
---|
156 | var_name = 'soilalbedo_moy' |
---|
157 | CALL restput_p (rest_id, var_name, nbp_glo, 2, 1, kjit, soilalb_moy, 'scatter', nbp_glo, index_g) |
---|
158 | ! |
---|
159 | RETURN |
---|
160 | ! |
---|
161 | ENDIF |
---|
162 | |
---|
163 | IF ( almaoutput ) THEN |
---|
164 | CALL histwrite(hist_id, 'Albedo', kjit, albedo_glob, kjpindex, index) |
---|
165 | CALL histwrite(hist_id, 'SAlbedo', kjit, albedo_snow, kjpindex, index) |
---|
166 | IF ( hist2_id > 0 ) THEN |
---|
167 | CALL histwrite(hist2_id, 'Albedo', kjit, albedo_glob, kjpindex, index) |
---|
168 | CALL histwrite(hist2_id, 'SAlbedo', kjit, albedo_snow, kjpindex, index) |
---|
169 | ENDIF |
---|
170 | ELSE |
---|
171 | CALL histwrite(hist_id, 'soilalb_vis', kjit, alb_bare(:,1), kjpindex, index) |
---|
172 | CALL histwrite(hist_id, 'soilalb_nir', kjit, alb_bare(:,2), kjpindex, index) |
---|
173 | CALL histwrite(hist_id, 'vegalb_vis', kjit, alb_veget(:,1), kjpindex, index) |
---|
174 | CALL histwrite(hist_id, 'vegalb_nir', kjit, alb_veget(:,2), kjpindex, index) |
---|
175 | IF ( hist2_id > 0 ) THEN |
---|
176 | CALL histwrite(hist2_id, 'soilalb_vis', kjit, alb_bare(:,1), kjpindex, index) |
---|
177 | CALL histwrite(hist2_id, 'soilalb_nir', kjit, alb_bare(:,2), kjpindex, index) |
---|
178 | CALL histwrite(hist2_id, 'vegalb_vis', kjit, alb_veget(:,1), kjpindex, index) |
---|
179 | CALL histwrite(hist2_id, 'vegalb_nir', kjit, alb_veget(:,2), kjpindex, index) |
---|
180 | ENDIF |
---|
181 | ENDIF |
---|
182 | |
---|
183 | IF (long_print) WRITE (numout,*)' condveg_main done ' |
---|
184 | |
---|
185 | END SUBROUTINE condveg_main |
---|
186 | |
---|
187 | !! Algorithm: |
---|
188 | !! - dynamic allocation for local array |
---|
189 | !! |
---|
190 | SUBROUTINE condveg_init (kjit, ldrestart_read, kjpindex, index, veget, & |
---|
191 | lalo, neighbours, resolution, contfrac, rest_id) |
---|
192 | |
---|
193 | ! interface description |
---|
194 | ! input scalar |
---|
195 | INTEGER(i_std), INTENT(in) :: kjit !! Time step number |
---|
196 | LOGICAL, INTENT(in) :: ldrestart_read !! Logical for restart file to read |
---|
197 | INTEGER(i_std), INTENT(in) :: kjpindex !! Domain size |
---|
198 | INTEGER(i_std),DIMENSION (kjpindex), INTENT (in) :: index !! Indeces of the points on the map |
---|
199 | REAL(r_std),DIMENSION (kjpindex,nvm), INTENT (in):: veget !! Vegetation distribution |
---|
200 | REAL(r_std),DIMENSION (kjpindex,2), INTENT (in) :: lalo !! Geographical coordinates |
---|
201 | INTEGER(i_std),DIMENSION (kjpindex,8), INTENT(in):: neighbours !! neighoring grid points if land |
---|
202 | REAL(r_std), DIMENSION (kjpindex,2), INTENT(in) :: resolution !! size in x an y of the grid (m) |
---|
203 | REAL(r_std),DIMENSION (kjpindex), INTENT(in) :: contfrac ! Fraction of land in each grid box. |
---|
204 | INTEGER(i_std), INTENT(in) :: rest_id !! Restart file identifier |
---|
205 | ! input fields |
---|
206 | ! output scalar |
---|
207 | ! output fields |
---|
208 | |
---|
209 | ! local declaration |
---|
210 | INTEGER(i_std) :: ji |
---|
211 | INTEGER(i_std) :: ier |
---|
212 | CHARACTER(LEN=80) :: var_name !! To store variables names for I/O |
---|
213 | ! initialisation |
---|
214 | IF (l_first_condveg) THEN |
---|
215 | ! |
---|
216 | l_first_condveg=.FALSE. |
---|
217 | ! |
---|
218 | ! Allocate variables which have to |
---|
219 | ! |
---|
220 | ALLOCATE (soilalb_dry(kjpindex,2),stat=ier) |
---|
221 | IF (ier.NE.0) THEN |
---|
222 | WRITE (numout,*) ' error in soilalb_dry allocation. We stop.We need kjpindex*2 words = ',kjpindex*2 |
---|
223 | STOP 'condveg_init' |
---|
224 | END IF |
---|
225 | soilalb_dry(:,:) = val_exp |
---|
226 | |
---|
227 | ALLOCATE (soilalb_wet(kjpindex,2),stat=ier) |
---|
228 | IF (ier.NE.0) THEN |
---|
229 | WRITE (numout,*) ' error in soilalb_wet allocation. We stop.We need kjpindex*2 words = ',kjpindex*2 |
---|
230 | STOP 'condveg_init' |
---|
231 | END IF |
---|
232 | soilalb_wet(:,:) = val_exp |
---|
233 | |
---|
234 | ! Ajout Nathalie |
---|
235 | ALLOCATE (soilalb_moy(kjpindex,2),stat=ier) |
---|
236 | IF (ier.NE.0) THEN |
---|
237 | WRITE (numout,*) ' error in soilalb_moy allocation. We stop.We need kjpindex*2 words = ',kjpindex*2 |
---|
238 | STOP 'condveg_init' |
---|
239 | END IF |
---|
240 | soilalb_moy(:,:) = val_exp |
---|
241 | |
---|
242 | ALLOCATE (albedo_snow(kjpindex),stat=ier) |
---|
243 | IF (ier.NE.0) THEN |
---|
244 | WRITE (numout,*) ' error in albedo_snow allocation. We stop.We need kjpindex words = ',kjpindex |
---|
245 | STOP 'condveg_init' |
---|
246 | END IF |
---|
247 | |
---|
248 | ALLOCATE (albedo_glob(kjpindex),stat=ier) |
---|
249 | IF (ier.NE.0) THEN |
---|
250 | WRITE (numout,*) ' error in albedo_glob allocation. We stop.We need kjpindex words = ',kjpindex |
---|
251 | STOP 'condveg_init' |
---|
252 | END IF |
---|
253 | |
---|
254 | ALLOCATE (alb_bare(kjpindex,2),stat=ier) |
---|
255 | IF (ier.NE.0) THEN |
---|
256 | WRITE (numout,*) ' error in alb_bare allocation. We stop.We need kjpindex*2 words = ',kjpindex*2 |
---|
257 | STOP 'condveg_init' |
---|
258 | END IF |
---|
259 | alb_bare(:,:) = val_exp |
---|
260 | |
---|
261 | ALLOCATE (alb_veget(kjpindex,2),stat=ier) |
---|
262 | IF (ier.NE.0) THEN |
---|
263 | WRITE (numout,*) ' error in alb_veget allocation. We stop.We need kjpindex*2 words = ',kjpindex*2 |
---|
264 | STOP 'condveg_init' |
---|
265 | END IF |
---|
266 | alb_veget(:,:) = val_exp |
---|
267 | ! |
---|
268 | ! Get the bare soil albedo |
---|
269 | ! |
---|
270 | ! |
---|
271 | var_name= 'soilalbedo_dry' |
---|
272 | CALL ioconf_setatt('UNITS', '-') |
---|
273 | CALL ioconf_setatt('LONG_NAME','Dry bare soil albedo') |
---|
274 | CALL restget_p (rest_id, var_name, nbp_glo, 2, 1, kjit, .TRUE., soilalb_dry, "gather", nbp_glo, index_g) |
---|
275 | |
---|
276 | var_name= 'soilalbedo_wet' |
---|
277 | CALL ioconf_setatt('UNITS', '-') |
---|
278 | CALL ioconf_setatt('LONG_NAME','Wet bare soil albedo') |
---|
279 | CALL restget_p (rest_id, var_name, nbp_glo, 2, 1, kjit, .TRUE., soilalb_wet, "gather", nbp_glo, index_g) |
---|
280 | |
---|
281 | var_name= 'soilalbedo_moy' |
---|
282 | CALL ioconf_setatt('UNITS', '-') |
---|
283 | CALL ioconf_setatt('LONG_NAME','Mean bare soil albedo') |
---|
284 | CALL restget_p (rest_id, var_name, nbp_glo, 2, 1, kjit, .TRUE., soilalb_moy, "gather", nbp_glo, index_g) |
---|
285 | ! |
---|
286 | IF ( MINVAL(soilalb_wet) .EQ. MAXVAL(soilalb_wet) .AND. MAXVAL(soilalb_wet) .EQ. val_exp .OR.& |
---|
287 | & MINVAL(soilalb_dry) .EQ. MAXVAL(soilalb_dry) .AND. MAXVAL(soilalb_dry) .EQ. val_exp .OR.& |
---|
288 | & MINVAL(soilalb_moy) .EQ. MAXVAL(soilalb_moy) .AND. MAXVAL(soilalb_moy) .EQ. val_exp) THEN |
---|
289 | CALL condveg_soilalb(kjpindex, lalo, neighbours, resolution, contfrac, soilalb_dry,soilalb_wet) |
---|
290 | WRITE(numout,*) '---> val_exp ', val_exp |
---|
291 | WRITE(numout,*) '---> ALBEDO_wet VIS:', MINVAL(soilalb_wet(:,ivis)), MAXVAL(soilalb_wet(:,ivis)) |
---|
292 | WRITE(numout,*) '---> ALBEDO_wet NIR:', MINVAL(soilalb_wet(:,inir)), MAXVAL(soilalb_wet(:,inir)) |
---|
293 | WRITE(numout,*) '---> ALBEDO_dry VIS:', MINVAL(soilalb_dry(:,ivis)), MAXVAL(soilalb_dry(:,ivis)) |
---|
294 | WRITE(numout,*) '---> ALBEDO_dry NIR:', MINVAL(soilalb_dry(:,inir)), MAXVAL(soilalb_dry(:,inir)) |
---|
295 | WRITE(numout,*) '---> ALBEDO_moy VIS:', MINVAL(soilalb_moy(:,ivis)), MAXVAL(soilalb_moy(:,ivis)) |
---|
296 | WRITE(numout,*) '---> ALBEDO_moy NIR:', MINVAL(soilalb_moy(:,inir)), MAXVAL(soilalb_moy(:,inir)) |
---|
297 | ENDIF |
---|
298 | ! |
---|
299 | ELSE |
---|
300 | WRITE (numout,*) ' l_first_condveg false . we stop ' |
---|
301 | STOP 'condveg_init' |
---|
302 | ENDIF |
---|
303 | !! test de commentaires |
---|
304 | |
---|
305 | IF (long_print) WRITE (numout,*) ' condveg_init done ' |
---|
306 | |
---|
307 | END SUBROUTINE condveg_init |
---|
308 | !! |
---|
309 | !! |
---|
310 | SUBROUTINE condveg_clear () |
---|
311 | |
---|
312 | l_first_condveg=.TRUE. |
---|
313 | |
---|
314 | IF (ALLOCATED (soilalb_dry)) DEALLOCATE (soilalb_dry) |
---|
315 | IF (ALLOCATED(soilalb_wet)) DEALLOCATE (soilalb_wet) |
---|
316 | ! Ajout Nathalie |
---|
317 | IF (ALLOCATED(soilalb_moy)) DEALLOCATE (soilalb_moy) |
---|
318 | IF (ALLOCATED(albedo_snow)) DEALLOCATE (albedo_snow) |
---|
319 | IF (ALLOCATED(albedo_glob)) DEALLOCATE (albedo_glob) |
---|
320 | IF (ALLOCATED(alb_bare)) DEALLOCATE (alb_bare) |
---|
321 | IF (ALLOCATED(alb_veget)) DEALLOCATE (alb_veget) |
---|
322 | ! |
---|
323 | END SUBROUTINE condveg_clear |
---|
324 | |
---|
325 | !! Algorithm: |
---|
326 | !! - initialisation of local arry |
---|
327 | !! - reads map for emissivity, albedo or roughness |
---|
328 | !! |
---|
329 | SUBROUTINE condveg_var_init (ldrestart_read, kjpindex, veget, veget_max, frac_nobio, totfrac_nobio,& |
---|
330 | & drysoil_frac, zlev, height, deadleaf_cover, emis, albedo, z0, roughheight) |
---|
331 | |
---|
332 | ! interface description |
---|
333 | ! input scalar |
---|
334 | INTEGER(i_std), INTENT(in) :: kjpindex !! Domain size |
---|
335 | LOGICAL, INTENT(in) :: ldrestart_read !! Logical for _restart_ file to read |
---|
336 | ! input fields |
---|
337 | REAL(r_std),DIMENSION (kjpindex,nvm), INTENT(in) :: veget !! Fraction of vegetation types |
---|
338 | REAL(r_std),DIMENSION (kjpindex,nvm), INTENT(in) :: veget_max !! Fraction of vegetation type |
---|
339 | REAL(r_std),DIMENSION (kjpindex,nnobio), INTENT(in) :: frac_nobio !! Fraction of continental ice, lakes, ... |
---|
340 | REAL(r_std),DIMENSION (kjpindex), INTENT(in) :: totfrac_nobio !! Total fraction of continental ice+lakes+... |
---|
341 | REAL(r_std),DIMENSION (kjpindex), INTENT(in) :: drysoil_frac !! Fraction of visibly Dry soil(between 0 and 1) |
---|
342 | REAL(r_std),DIMENSION (kjpindex), INTENT (in) :: zlev !! Height of first layer |
---|
343 | REAL(r_std),DIMENSION (kjpindex,nvm), INTENT(in) :: height !! Vegetation Height (m) |
---|
344 | REAL(r_std),DIMENSION (kjpindex), INTENT(in) :: deadleaf_cover !! Fraction of soil covered by dead leaves |
---|
345 | ! output scalar |
---|
346 | ! output fields |
---|
347 | REAL(r_std),DIMENSION (kjpindex), INTENT (out) :: emis !! Emissivity |
---|
348 | REAL(r_std),DIMENSION (kjpindex,2), INTENT (out) :: albedo !! Albedo, vis(1) and nir(2) |
---|
349 | REAL(r_std),DIMENSION (kjpindex), INTENT (out) :: z0 !! Roughness |
---|
350 | REAL(r_std),DIMENSION (kjpindex), INTENT (out) :: roughheight !! Effective height for roughness |
---|
351 | ! |
---|
352 | ! local declaration |
---|
353 | INTEGER(i_std) :: ier !! Error code |
---|
354 | INTEGER(i_std) :: jv |
---|
355 | ! initialisation of variables |
---|
356 | |
---|
357 | !! |
---|
358 | !! calculs de emis |
---|
359 | !! |
---|
360 | |
---|
361 | IF ( impaze ) THEN |
---|
362 | ! |
---|
363 | emis(:) = emis_scal |
---|
364 | ! |
---|
365 | ELSE |
---|
366 | ! Some day it will be moisture dependent |
---|
367 | emis_scal = un |
---|
368 | |
---|
369 | emis(:) = emis_scal |
---|
370 | ENDIF |
---|
371 | |
---|
372 | !! |
---|
373 | !! calculs de albedo |
---|
374 | !! |
---|
375 | ! |
---|
376 | IF ( impaze ) THEN |
---|
377 | ! |
---|
378 | albedo(:,ivis) = albedo_scal(ivis) |
---|
379 | albedo(:,inir) = albedo_scal(inir) |
---|
380 | ! |
---|
381 | ELSE |
---|
382 | ! |
---|
383 | CALL condveg_albcalc (kjpindex,deadleaf_cover,veget,drysoil_frac,albedo) |
---|
384 | ! |
---|
385 | ENDIF |
---|
386 | !! |
---|
387 | !! calculs de z0 |
---|
388 | !! |
---|
389 | !! |
---|
390 | IF ( impaze ) THEN |
---|
391 | ! |
---|
392 | z0(:) = z0_scal |
---|
393 | roughheight(:) = roughheight_scal |
---|
394 | ! |
---|
395 | ELSE |
---|
396 | ! |
---|
397 | IF ( z0cdrag_ave ) THEN |
---|
398 | CALL condveg_z0cdrag(kjpindex, veget, veget_max, frac_nobio, totfrac_nobio, zlev, & |
---|
399 | & height, z0, roughheight) |
---|
400 | ELSE |
---|
401 | CALL condveg_z0logz(kjpindex, veget, veget_max, frac_nobio, totfrac_nobio, height, & |
---|
402 | & z0, roughheight) |
---|
403 | ENDIF |
---|
404 | ! |
---|
405 | ENDIF |
---|
406 | !! |
---|
407 | !! |
---|
408 | IF (long_print) WRITE (numout,*) ' condveg_var_init done ' |
---|
409 | |
---|
410 | END SUBROUTINE condveg_var_init |
---|
411 | !! |
---|
412 | !! Algorithm: |
---|
413 | !! - Simply update the emissivity, albedo and roughness fields |
---|
414 | !! |
---|
415 | SUBROUTINE condveg_var_update (ldrestart_read, kjpindex, veget, veget_max, frac_nobio, totfrac_nobio, & |
---|
416 | & drysoil_frac, zlev, height, deadleaf_cover, emis, albedo, z0, roughheight) |
---|
417 | |
---|
418 | ! interface description |
---|
419 | ! input scalar |
---|
420 | INTEGER(i_std), INTENT(in) :: kjpindex !! Domain size |
---|
421 | LOGICAL, INTENT(in) :: ldrestart_read !! Logical for _restart_ file to read |
---|
422 | ! input fields |
---|
423 | REAL(r_std),DIMENSION (kjpindex,nvm), INTENT(in) :: veget !! Fraction of vegetation types |
---|
424 | REAL(r_std),DIMENSION (kjpindex,nvm), INTENT(in) :: veget_max !! Fraction of vegetation type |
---|
425 | REAL(r_std),DIMENSION (kjpindex,nnobio), INTENT(in) :: frac_nobio !! Fraction of continental ice, lakes, ... |
---|
426 | REAL(r_std),DIMENSION (kjpindex), INTENT(in) :: totfrac_nobio !! Total fraction of continental ice+lakes+... |
---|
427 | REAL(r_std),DIMENSION (kjpindex), INTENT(in) :: drysoil_frac !! Fraction of visibly Dry soil(between 0 and 1) |
---|
428 | REAL(r_std),DIMENSION (kjpindex), INTENT (in) :: zlev !! Height of first layer |
---|
429 | REAL(r_std),DIMENSION (kjpindex,nvm), INTENT(in) :: height !! Vegetation Height (m) |
---|
430 | REAL(r_std),DIMENSION (kjpindex), INTENT(in) :: deadleaf_cover !! Fraction of soil covered by dead leaves |
---|
431 | ! output scalar |
---|
432 | ! output fields |
---|
433 | REAL(r_std),DIMENSION (kjpindex), INTENT (out) :: emis !! Emissivity |
---|
434 | REAL(r_std),DIMENSION (kjpindex,2), INTENT (out) :: albedo !! Albedo, vis(1) and nir(2) |
---|
435 | REAL(r_std),DIMENSION (kjpindex), INTENT (out) :: z0 !! Roughness |
---|
436 | REAL(r_std),DIMENSION (kjpindex), INTENT (out) :: roughheight !! Effective height for roughness |
---|
437 | ! |
---|
438 | ! local |
---|
439 | INTEGER(i_std) :: ji, jv |
---|
440 | !! |
---|
441 | !! calculs de emis |
---|
442 | !! |
---|
443 | |
---|
444 | emis(:) = emis_scal |
---|
445 | |
---|
446 | !! |
---|
447 | !! calculs de albedo |
---|
448 | !! |
---|
449 | ! |
---|
450 | IF ( impaze ) THEN |
---|
451 | ! |
---|
452 | albedo(:,ivis) = albedo_scal(ivis) |
---|
453 | albedo(:,inir) = albedo_scal(inir) |
---|
454 | ! |
---|
455 | ELSE |
---|
456 | ! |
---|
457 | CALL condveg_albcalc (kjpindex,deadleaf_cover,veget,drysoil_frac,albedo) |
---|
458 | ! |
---|
459 | ENDIF |
---|
460 | ! |
---|
461 | !! |
---|
462 | !! Calculs de la rugosite |
---|
463 | !! |
---|
464 | |
---|
465 | IF ( impaze ) THEN |
---|
466 | |
---|
467 | DO ji = 1, kjpindex |
---|
468 | z0(ji) = z0_scal |
---|
469 | roughheight(ji) = roughheight_scal |
---|
470 | ENDDO |
---|
471 | |
---|
472 | ELSE |
---|
473 | ! |
---|
474 | IF ( z0cdrag_ave ) THEN |
---|
475 | CALL condveg_z0cdrag (kjpindex, veget, veget_max, frac_nobio, totfrac_nobio, zlev, height, & |
---|
476 | & z0, roughheight) |
---|
477 | ELSE |
---|
478 | CALL condveg_z0logz (kjpindex, veget, veget_max, frac_nobio, totfrac_nobio, height, & |
---|
479 | & z0, roughheight) |
---|
480 | ENDIF |
---|
481 | ! |
---|
482 | ENDIF |
---|
483 | |
---|
484 | IF (long_print) WRITE (numout,*) ' condveg_var_update done ' |
---|
485 | |
---|
486 | END SUBROUTINE condveg_var_update |
---|
487 | |
---|
488 | !! Algorithm: |
---|
489 | !! - The snow albedo is updated by the snow within the mesh |
---|
490 | !! This is done as a function of snow mass, snow age and vegetation type |
---|
491 | !! The model is described in Chalita 1992 |
---|
492 | !! |
---|
493 | SUBROUTINE condveg_snow (ldrestart_read, kjpindex, veget, frac_nobio, totfrac_nobio, & |
---|
494 | snow, snow_age, snow_nobio, snow_nobio_age, albedo, albedo_snow, albedo_glob) |
---|
495 | |
---|
496 | ! interface description |
---|
497 | ! input scalar |
---|
498 | INTEGER(i_std), INTENT(in) :: kjpindex !! Domain size |
---|
499 | LOGICAL, INTENT(in) :: ldrestart_read !! Logical for _restart_ file to read |
---|
500 | ! input fields |
---|
501 | REAL(r_std),DIMENSION (kjpindex,nvm), INTENT (in) :: veget !! Fraction of vegetation types |
---|
502 | REAL(r_std),DIMENSION (kjpindex,nnobio), INTENT(in) :: frac_nobio !! Fraction of continental ice, lakes, ... |
---|
503 | REAL(r_std),DIMENSION (kjpindex), INTENT(in) :: totfrac_nobio !! Total fraction of continental ice+lakes+ ... |
---|
504 | REAL(r_std),DIMENSION (kjpindex), INTENT(in) :: snow !! Snow mass [Kg/m^2] in vegetation |
---|
505 | REAL(r_std),DIMENSION (kjpindex,nnobio), INTENT(in) :: snow_nobio !! Snow mass [Kg/m^2]on ice, lakes, ... |
---|
506 | REAL(r_std),DIMENSION (kjpindex), INTENT(in) :: snow_age !! Snow age |
---|
507 | REAL(r_std),DIMENSION (kjpindex,nnobio), INTENT(in) :: snow_nobio_age !! Snow age on ice, lakes, ... |
---|
508 | ! output scalar |
---|
509 | ! output fields |
---|
510 | REAL(r_std),DIMENSION (kjpindex,2), INTENT (inout) :: albedo !! Albedo |
---|
511 | REAL(r_std),DIMENSION (kjpindex), INTENT (out) :: albedo_snow !! Albedo de la neige |
---|
512 | REAL(r_std),DIMENSION (kjpindex), INTENT (out) :: albedo_glob !! Mean albedo |
---|
513 | ! |
---|
514 | ! local declaration |
---|
515 | INTEGER(i_std) :: ji, jv, jb !! Loop index |
---|
516 | REAL(r_std), DIMENSION(kjpindex) :: frac_snow_veg !! Fraction of snow on vegetation |
---|
517 | REAL(r_std), DIMENSION(kjpindex,nnobio) :: frac_snow_nobio !! Fraction of snow on ice, lakes, ... |
---|
518 | REAL(r_std), DIMENSION(kjpindex) :: snowa_veg !! Total albedo of snow covered area on vegetation |
---|
519 | REAL(r_std), DIMENSION(kjpindex,nnobio) :: snowa_nobio !! albedo of snow covered area on ice, lakes, ... |
---|
520 | REAL(r_std), DIMENSION(kjpindex) :: fraction_veg !! total vegetation fraction |
---|
521 | REAL(r_std), DIMENSION(kjpindex) :: agefunc_veg !! age dependency of snow albedo on vegetation |
---|
522 | REAL(r_std), DIMENSION(kjpindex,nnobio) :: agefunc_nobio !! age dependency of snow albedo on ice, lakes, ..; |
---|
523 | REAL(r_std) :: alb_nobio |
---|
524 | ! |
---|
525 | |
---|
526 | DO ji = 1, kjpindex |
---|
527 | albedo_snow(ji) = zero |
---|
528 | albedo_glob(ji) = zero |
---|
529 | ENDDO |
---|
530 | |
---|
531 | IF (ABS(fixed_snow_albedo - undef_sechiba) .GT. EPSILON(undef_sechiba)) THEN |
---|
532 | snowa_veg(:) = fixed_snow_albedo |
---|
533 | snowa_nobio(:,:) = fixed_snow_albedo |
---|
534 | ELSE |
---|
535 | ! |
---|
536 | ! calculate first age dependence |
---|
537 | ! |
---|
538 | DO ji = 1, kjpindex |
---|
539 | agefunc_veg(ji) = EXP(-snow_age(ji)/tcst_snowa) |
---|
540 | ENDDO |
---|
541 | ! |
---|
542 | ! |
---|
543 | DO jv = 1, nnobio |
---|
544 | DO ji = 1, kjpindex |
---|
545 | agefunc_nobio(ji,jv) = EXP(-snow_nobio_age(ji,jv)/tcst_snowa) |
---|
546 | ENDDO |
---|
547 | ENDDO |
---|
548 | ! |
---|
549 | ! snow albedo on vegetated surfaces |
---|
550 | ! |
---|
551 | fraction_veg(:) = un - totfrac_nobio(:) |
---|
552 | snowa_veg(:) = zero |
---|
553 | DO jv = 1, nvm |
---|
554 | DO ji = 1, kjpindex |
---|
555 | IF ( fraction_veg(ji) .GT. min_sechiba ) THEN |
---|
556 | snowa_veg(ji) = snowa_veg(ji) + & |
---|
557 | veget(ji,jv)/fraction_veg(ji) * ( snowa_ini(jv)+snowa_dec(jv)*agefunc_veg(ji) ) |
---|
558 | ENDIF |
---|
559 | ENDDO |
---|
560 | ENDDO |
---|
561 | ! |
---|
562 | ! snow albedo on other surfaces |
---|
563 | ! |
---|
564 | DO jv = 1, nnobio |
---|
565 | DO ji = 1, kjpindex |
---|
566 | snowa_nobio(ji,jv) = ( snowa_ini(1) + snowa_dec(1) * agefunc_nobio(ji,jv) ) |
---|
567 | ENDDO |
---|
568 | ENDDO |
---|
569 | ENDIF |
---|
570 | |
---|
571 | frac_snow_veg(:) = MIN(MAX(snow(:),zero)/(MAX(snow(:),zero)+snowcri_alb),un) |
---|
572 | DO jv = 1, nnobio |
---|
573 | frac_snow_nobio(:,jv) = MIN(MAX(snow_nobio(:,jv),zero)/(MAX(snow_nobio(:,jv),zero)+snowcri_alb),un) |
---|
574 | ENDDO |
---|
575 | |
---|
576 | |
---|
577 | DO jb = 1, 2 |
---|
578 | ! |
---|
579 | albedo(:,jb) = ( fraction_veg(:) ) * & |
---|
580 | ( (un-frac_snow_veg(:)) * albedo(:,jb) + & |
---|
581 | ( frac_snow_veg(:) ) * snowa_veg(:) ) |
---|
582 | albedo_snow(:) = albedo_snow(:) + (fraction_veg(:)) * (frac_snow_veg(:)) * snowa_veg(:) |
---|
583 | ! |
---|
584 | DO jv = 1, nnobio |
---|
585 | ! |
---|
586 | IF ( jv .EQ. iice ) THEN |
---|
587 | alb_nobio = alb_ice(jb) |
---|
588 | ELSE |
---|
589 | WRITE(numout,*) 'jv=',jv |
---|
590 | STOP 'DO NOT KNOW ALBEDO OF THIS SURFACE TYPE' |
---|
591 | ENDIF |
---|
592 | ! |
---|
593 | albedo(:,jb) = albedo(:,jb) + & |
---|
594 | ( frac_nobio(:,jv) ) * & |
---|
595 | ( (un-frac_snow_nobio(:,jv)) * alb_nobio + & |
---|
596 | ( frac_snow_nobio(:,jv) ) * snowa_nobio(:,jv) ) |
---|
597 | albedo_snow(:) = albedo_snow(:) + & |
---|
598 | ( frac_nobio(:,jv) ) * ( frac_snow_nobio(:,jv) ) * & |
---|
599 | snowa_nobio(:,jv) |
---|
600 | albedo_glob(:) = albedo_glob(:) + albedo(:,jb) |
---|
601 | ! |
---|
602 | ENDDO |
---|
603 | ! |
---|
604 | END DO |
---|
605 | ! |
---|
606 | DO ji = 1, kjpindex |
---|
607 | albedo_snow(ji) = (albedo_snow(ji))/2. |
---|
608 | albedo_glob(ji) = (albedo_glob(ji))/2. |
---|
609 | ENDDO |
---|
610 | |
---|
611 | IF (long_print) WRITE (numout,*) ' condveg_snow done ' |
---|
612 | |
---|
613 | END SUBROUTINE condveg_snow |
---|
614 | ! |
---|
615 | ! |
---|
616 | ! |
---|
617 | SUBROUTINE condveg_soilalb(nbpt, lalo, neighbours, resolution, contfrac, soilalb_dry,soilalb_wet) |
---|
618 | ! |
---|
619 | ! |
---|
620 | ! This subroutine should read the soil color maps from the Henderson-Sellers & Wilson database. This data |
---|
621 | ! is then interpolated to the models resolution and transformed into dry and wet albedos. We have chosen to |
---|
622 | ! do both these operations at the same time as one can average the albedo but not the color types. |
---|
623 | ! |
---|
624 | ! We make the assumption in this code that the grid of the data is regular and that it covers the globe. |
---|
625 | ! For the model grid we base the calculation of the borders of the grid on the resolution. |
---|
626 | ! |
---|
627 | ! |
---|
628 | ! 0.1 INPUT |
---|
629 | ! |
---|
630 | INTEGER(i_std), INTENT(in) :: nbpt ! Number of points for which the data needs to be interpolated |
---|
631 | REAL(r_std), INTENT(in) :: lalo(nbpt,2) ! Vector of latitude and longitudes (beware of the order !) |
---|
632 | INTEGER(i_std), INTENT(in) :: neighbours(nbpt,8) ! Vector of neighbours for each grid point (1=N, 2=E, 3=S, 4=W) |
---|
633 | REAL(r_std), INTENT(in) :: resolution(nbpt,2) ! The size in km of each grid-box in X and Y |
---|
634 | REAL(r_std), INTENT(in) :: contfrac(nbpt) ! Fraction of land in each grid box. |
---|
635 | REAL(r_std), INTENT(inout) :: soilalb_dry(nbpt,2) ! albedo for the dry bare soil |
---|
636 | REAL(r_std), INTENT(inout) :: soilalb_wet(nbpt,2) ! albedo for the wet bare soil |
---|
637 | |
---|
638 | ! |
---|
639 | ! |
---|
640 | ! 0.3 LOCAL |
---|
641 | ! |
---|
642 | INTEGER(i_std) :: nbvmax |
---|
643 | ! |
---|
644 | CHARACTER(LEN=80) :: filename |
---|
645 | INTEGER(i_std) :: iml, jml, lml, tml, fid, ib, ip, jp, fopt, ilf, lastjp, nbexp |
---|
646 | REAL(r_std) :: lev(1), date, dt, coslat, sgn |
---|
647 | INTEGER(i_std) :: itau(1) |
---|
648 | REAL(r_std), ALLOCATABLE, DIMENSION(:,:) :: lat_rel, lon_rel, soilcol |
---|
649 | REAL(r_std), ALLOCATABLE, DIMENSION(:,:) :: sub_area |
---|
650 | INTEGER(i_std), ALLOCATABLE, DIMENSION(:,:,:) :: sub_index |
---|
651 | INTEGER(i_std), ALLOCATABLE, DIMENSION(:,:) :: mask |
---|
652 | CHARACTER(LEN=30) :: callsign |
---|
653 | ! |
---|
654 | LOGICAL :: ok_interpol = .FALSE. ! optionnal return of aggregate_2d |
---|
655 | ! |
---|
656 | INTEGER :: ALLOC_ERR |
---|
657 | ! |
---|
658 | ! |
---|
659 | ! Needs to be a configurable variable |
---|
660 | ! |
---|
661 | ! |
---|
662 | !Config Key = SOILALB_FILE |
---|
663 | !Config Desc = Name of file from which the bare soil albedo |
---|
664 | !Config Def = ../surfmap/soils_param.nc |
---|
665 | !Config If = !IMPOSE_AZE |
---|
666 | !Config Help = The name of the file to be opened to read the soil types from |
---|
667 | !Config which we derive then the bare soil albedos. This file is 1x1 |
---|
668 | !Config deg and based on the soil colors defined by Wilson and Henderson-Seller. |
---|
669 | ! |
---|
670 | filename = '../surfmap/soils_param.nc' |
---|
671 | CALL getin_p('SOILALB_FILE',filename) |
---|
672 | ! |
---|
673 | IF (is_root_prc) CALL flininfo(filename,iml, jml, lml, tml, fid) |
---|
674 | CALL bcast(iml) |
---|
675 | CALL bcast(jml) |
---|
676 | CALL bcast(lml) |
---|
677 | CALL bcast(tml) |
---|
678 | ! |
---|
679 | ! soils_param.nc file is 1° soit texture file. |
---|
680 | ! |
---|
681 | ALLOC_ERR=-1 |
---|
682 | ALLOCATE(lat_rel(iml,jml), STAT=ALLOC_ERR) |
---|
683 | IF (ALLOC_ERR/=0) THEN |
---|
684 | WRITE(numout,*) "ERROR IN ALLOCATION of lat_rel : ",ALLOC_ERR |
---|
685 | STOP |
---|
686 | ENDIF |
---|
687 | ALLOC_ERR=-1 |
---|
688 | ALLOCATE(lon_rel(iml,jml), STAT=ALLOC_ERR) |
---|
689 | IF (ALLOC_ERR/=0) THEN |
---|
690 | WRITE(numout,*) "ERROR IN ALLOCATION of lon_rel : ",ALLOC_ERR |
---|
691 | STOP |
---|
692 | ENDIF |
---|
693 | ALLOC_ERR=-1 |
---|
694 | ALLOCATE(mask(iml,jml), STAT=ALLOC_ERR) |
---|
695 | IF (ALLOC_ERR/=0) THEN |
---|
696 | WRITE(numout,*) "ERROR IN ALLOCATION of mask : ",ALLOC_ERR |
---|
697 | STOP |
---|
698 | ENDIF |
---|
699 | ALLOC_ERR=-1 |
---|
700 | ALLOCATE(soilcol(iml,jml), STAT=ALLOC_ERR) |
---|
701 | IF (ALLOC_ERR/=0) THEN |
---|
702 | WRITE(numout,*) "ERROR IN ALLOCATION of soiltext : ",ALLOC_ERR |
---|
703 | STOP |
---|
704 | ENDIF |
---|
705 | ! |
---|
706 | IF (is_root_prc) CALL flinopen(filename, .FALSE., iml, jml, lml, lon_rel, lat_rel, lev, tml, itau, date, dt, fid) |
---|
707 | CALL bcast(lon_rel) |
---|
708 | CALL bcast(lat_rel) |
---|
709 | CALL bcast(lev) |
---|
710 | CALL bcast(itau) |
---|
711 | CALL bcast(date) |
---|
712 | CALL bcast(dt) |
---|
713 | ! |
---|
714 | IF (is_root_prc) CALL flinget(fid, 'soilcolor', iml, jml, lml, tml, 1, 1, soilcol) |
---|
715 | CALL bcast(soilcol) |
---|
716 | ! |
---|
717 | IF (is_root_prc) CALL flinclo(fid) |
---|
718 | ! |
---|
719 | ! Mask of permitted variables. |
---|
720 | ! |
---|
721 | mask(:,:) = zero |
---|
722 | DO ip=1,iml |
---|
723 | DO jp=1,jml |
---|
724 | IF (soilcol(ip,jp) > min_sechiba) THEN |
---|
725 | mask(ip,jp) = un |
---|
726 | ENDIF |
---|
727 | ENDDO |
---|
728 | ENDDO |
---|
729 | ! |
---|
730 | nbvmax = 200 |
---|
731 | ! |
---|
732 | callsign = 'Soil color map' |
---|
733 | ! |
---|
734 | DO WHILE ( .NOT. ok_interpol ) |
---|
735 | WRITE(numout,*) "Projection arrays for ",callsign," : " |
---|
736 | WRITE(numout,*) "nbvmax = ",nbvmax |
---|
737 | ! |
---|
738 | ALLOC_ERR=-1 |
---|
739 | ALLOCATE(sub_area(nbpt,nbvmax), STAT=ALLOC_ERR) |
---|
740 | IF (ALLOC_ERR/=0) THEN |
---|
741 | WRITE(numout,*) "ERROR IN ALLOCATION of sub_area : ",ALLOC_ERR |
---|
742 | STOP |
---|
743 | ENDIF |
---|
744 | sub_area(:,:)=zero |
---|
745 | ALLOC_ERR=-1 |
---|
746 | ALLOCATE(sub_index(nbpt,nbvmax,2), STAT=ALLOC_ERR) |
---|
747 | IF (ALLOC_ERR/=0) THEN |
---|
748 | WRITE(numout,*) "ERROR IN ALLOCATION of sub_index : ",ALLOC_ERR |
---|
749 | STOP |
---|
750 | ENDIF |
---|
751 | sub_index(:,:,:)=0 |
---|
752 | ! |
---|
753 | CALL aggregate_p(nbpt, lalo, neighbours, resolution, contfrac, & |
---|
754 | & iml, jml, lon_rel, lat_rel, mask, callsign, & |
---|
755 | & nbvmax, sub_index, sub_area, ok_interpol) |
---|
756 | ! |
---|
757 | IF ( .NOT. ok_interpol ) THEN |
---|
758 | DEALLOCATE(sub_area) |
---|
759 | DEALLOCATE(sub_index) |
---|
760 | ENDIF |
---|
761 | ! |
---|
762 | nbvmax = nbvmax * 2 |
---|
763 | ENDDO |
---|
764 | ! |
---|
765 | nbexp = 0 |
---|
766 | ! |
---|
767 | ! Check that we found some points |
---|
768 | ! |
---|
769 | soilalb_dry(:,:) = zero |
---|
770 | soilalb_wet(:,:) = zero |
---|
771 | ! Ajout Nathalie |
---|
772 | soilalb_moy(:,:) = zero |
---|
773 | ! |
---|
774 | DO ib=1,nbpt |
---|
775 | ! |
---|
776 | ! GO through the point we have found |
---|
777 | ! |
---|
778 | ! |
---|
779 | fopt = COUNT(sub_area(ib,:) > zero) |
---|
780 | ! |
---|
781 | IF ( fopt .EQ. 0) THEN |
---|
782 | nbexp = nbexp + 1 |
---|
783 | soilalb_dry(ib,ivis) = (SUM(vis_dry)/classnb + SUM(vis_wet)/classnb)/deux |
---|
784 | soilalb_dry(ib,inir) = (SUM(nir_dry)/classnb + SUM(nir_wet)/classnb)/deux |
---|
785 | soilalb_wet(ib,ivis) = (SUM(vis_dry)/classnb + SUM(vis_wet)/classnb)/deux |
---|
786 | soilalb_wet(ib,inir) = (SUM(nir_dry)/classnb + SUM(nir_wet)/classnb)/deux |
---|
787 | ! Ajout Nathalie |
---|
788 | soilalb_moy(ib,ivis) = SUM(albsoil_vis)/classnb |
---|
789 | soilalb_moy(ib,inir) = SUM(albsoil_nir)/classnb |
---|
790 | ELSE |
---|
791 | sgn = zero |
---|
792 | ! |
---|
793 | ! Compute the average bare soil albedo parameters |
---|
794 | ! |
---|
795 | DO ilf = 1,fopt |
---|
796 | ! |
---|
797 | ip = sub_index(ib,ilf,1) |
---|
798 | jp = sub_index(ib,ilf,2) |
---|
799 | ! |
---|
800 | IF ( NINT(soilcol(ip,jp)) .LE. classnb) THEN |
---|
801 | soilalb_dry(ib,ivis) = soilalb_dry(ib,ivis) + vis_dry(NINT(soilcol(ip,jp))) * sub_area(ib,ilf) |
---|
802 | soilalb_dry(ib,inir) = soilalb_dry(ib,inir) + nir_dry(NINT(soilcol(ip,jp))) * sub_area(ib,ilf) |
---|
803 | soilalb_wet(ib,ivis) = soilalb_wet(ib,ivis) + vis_wet(NINT(soilcol(ip,jp))) * sub_area(ib,ilf) |
---|
804 | soilalb_wet(ib,inir) = soilalb_wet(ib,inir) + nir_wet(NINT(soilcol(ip,jp))) * sub_area(ib,ilf) |
---|
805 | ! Ajout Nathalie |
---|
806 | soilalb_moy(ib,ivis) = soilalb_moy(ib,ivis) + albsoil_vis(NINT(soilcol(ip,jp))) * sub_area(ib,ilf) |
---|
807 | soilalb_moy(ib,inir) = soilalb_moy(ib,inir) + albsoil_nir(NINT(soilcol(ip,jp))) * sub_area(ib,ilf) |
---|
808 | sgn = sgn + sub_area(ib,ilf) |
---|
809 | ELSE |
---|
810 | WRITE(numout,*) 'The file contains a soil color class which is incompatible with this program' |
---|
811 | STOP |
---|
812 | ENDIF |
---|
813 | ! |
---|
814 | ENDDO |
---|
815 | ! |
---|
816 | ! Normalize the surface |
---|
817 | ! |
---|
818 | IF ( sgn .LT. min_sechiba) THEN |
---|
819 | nbexp = nbexp + 1 |
---|
820 | soilalb_dry(ib,ivis) = (SUM(vis_dry)/classnb + SUM(vis_wet)/classnb)/deux |
---|
821 | soilalb_dry(ib,inir) = (SUM(nir_dry)/classnb + SUM(nir_wet)/classnb)/deux |
---|
822 | soilalb_wet(ib,ivis) = (SUM(vis_dry)/classnb + SUM(vis_wet)/classnb)/deux |
---|
823 | soilalb_wet(ib,inir) = (SUM(nir_dry)/classnb + SUM(nir_wet)/classnb)/deux |
---|
824 | ! Ajout Nathalie |
---|
825 | soilalb_moy(ib,ivis) = SUM(albsoil_vis)/classnb |
---|
826 | soilalb_moy(ib,inir) = SUM(albsoil_nir)/classnb |
---|
827 | ELSE |
---|
828 | soilalb_dry(ib,ivis) = soilalb_dry(ib,ivis)/sgn |
---|
829 | soilalb_dry(ib,inir) = soilalb_dry(ib,inir)/sgn |
---|
830 | soilalb_wet(ib,ivis) = soilalb_wet(ib,ivis)/sgn |
---|
831 | soilalb_wet(ib,inir) = soilalb_wet(ib,inir)/sgn |
---|
832 | ! Ajout Nathalie |
---|
833 | soilalb_moy(ib,ivis) = soilalb_moy(ib,ivis)/sgn |
---|
834 | soilalb_moy(ib,inir) = soilalb_moy(ib,inir)/sgn |
---|
835 | ENDIF |
---|
836 | ! |
---|
837 | ENDIF |
---|
838 | ! |
---|
839 | ENDDO |
---|
840 | ! |
---|
841 | IF ( nbexp .GT. 0 ) THEN |
---|
842 | WRITE(numout,*) 'CONDVEG_soilalb : The interpolation of the bare soil albedo had ', nbexp |
---|
843 | WRITE(numout,*) 'CONDVEG_soilalb : points without data. This are either coastal points or' |
---|
844 | WRITE(numout,*) 'CONDVEG_soilalb : ice covered land.' |
---|
845 | WRITE(numout,*) 'CONDVEG_soilalb : The problem was solved by using the average of all soils' |
---|
846 | WRITE(numout,*) 'CONDVEG_soilalb : in dry and wet conditions' |
---|
847 | ENDIF |
---|
848 | ! |
---|
849 | DEALLOCATE (lat_rel) |
---|
850 | DEALLOCATE (lon_rel) |
---|
851 | DEALLOCATE (mask) |
---|
852 | DEALLOCATE (sub_index) |
---|
853 | DEALLOCATE (sub_area) |
---|
854 | DEALLOCATE (soilcol) |
---|
855 | ! |
---|
856 | ! |
---|
857 | RETURN |
---|
858 | ! |
---|
859 | END SUBROUTINE condveg_soilalb |
---|
860 | ! |
---|
861 | ! |
---|
862 | ! |
---|
863 | SUBROUTINE condveg_z0logz (kjpindex, veget, veget_max, frac_nobio, totfrac_nobio, height, & |
---|
864 | & z0, roughheight) |
---|
865 | |
---|
866 | ! |
---|
867 | ! 0. Declarations |
---|
868 | ! |
---|
869 | |
---|
870 | ! 0.1 Input |
---|
871 | INTEGER(i_std), INTENT(in) :: kjpindex |
---|
872 | REAL(r_std), DIMENSION(kjpindex,nvm), INTENT(in) :: veget |
---|
873 | REAL(r_std), DIMENSION(kjpindex,nvm), INTENT(in) :: veget_max |
---|
874 | REAL(r_std), DIMENSION(kjpindex,nnobio), INTENT(in) :: frac_nobio |
---|
875 | REAL(r_std), DIMENSION(kjpindex), INTENT(in) :: totfrac_nobio |
---|
876 | REAL(r_std), DIMENSION(kjpindex,nvm), INTENT(in) :: height |
---|
877 | |
---|
878 | ! 0.2 Output |
---|
879 | REAL(r_std), DIMENSION(kjpindex), INTENT(out) :: z0 |
---|
880 | REAL(r_std), DIMENSION(kjpindex), INTENT(out) :: roughheight |
---|
881 | |
---|
882 | ! 0.3 Local |
---|
883 | INTEGER(i_std) :: jv |
---|
884 | REAL(r_std), DIMENSION(kjpindex) :: sumveg, ave_height |
---|
885 | REAL(r_std), DIMENSION(kjpindex) :: d_veg, zhdispl |
---|
886 | REAL(r_std) :: z0_nobio |
---|
887 | |
---|
888 | z0(:) = veget(:,1) * LOG(z0_bare) |
---|
889 | sumveg(:) = veget(:,1) |
---|
890 | ave_height(:) = zero |
---|
891 | ! |
---|
892 | DO jv = 2, nvm |
---|
893 | ! |
---|
894 | IF ( is_tree(jv) ) THEN |
---|
895 | ! tree trunks influence the atmosphere even when there are no leaves |
---|
896 | d_veg(:) = veget_max(:,jv) |
---|
897 | ELSE |
---|
898 | ! grasses only have an influence if they are really there! |
---|
899 | d_veg(:) = veget(:,jv) |
---|
900 | ENDIF |
---|
901 | ! |
---|
902 | z0(:) = z0(:) + d_veg(:) * & |
---|
903 | LOG( MAX(height(:,jv)*z0_over_height,z0_bare) ) |
---|
904 | sumveg(:) = sumveg(:) + d_veg(:) |
---|
905 | ! |
---|
906 | ave_height(:) = ave_height(:) + veget_max(:,jv)*height(:,jv) |
---|
907 | ! |
---|
908 | ENDDO |
---|
909 | ! |
---|
910 | WHERE ( sumveg(:) > zero ) z0(:) = z0(:) / sumveg(:) |
---|
911 | ! |
---|
912 | z0(:) = (un - totfrac_nobio(:)) * z0(:) |
---|
913 | ! |
---|
914 | DO jv = 1, nnobio |
---|
915 | ! |
---|
916 | IF ( jv .EQ. iice ) THEN |
---|
917 | z0_nobio = z0_ice |
---|
918 | ELSE |
---|
919 | WRITE(numout,*) 'jv=',jv |
---|
920 | STOP 'DO NOT KNOW ROUGHNESS OF THIS SURFACE TYPE' |
---|
921 | ENDIF |
---|
922 | ! |
---|
923 | z0(:) = z0(:) + frac_nobio(:,jv) * LOG(z0_nobio) |
---|
924 | ! |
---|
925 | ENDDO |
---|
926 | ! |
---|
927 | z0(:) = EXP( z0(:) ) |
---|
928 | ! |
---|
929 | ! Temporarily we compute the zero plane displacement height |
---|
930 | ! |
---|
931 | zhdispl(:) = ave_height(:) * height_displacement |
---|
932 | ! |
---|
933 | ! In order to get a variable independent of the height of the |
---|
934 | ! vegetation we compute what we call the effective roughness height. |
---|
935 | ! This is the height over which the roughness acts. It combines the |
---|
936 | ! zero plane displacement height and the vegetation height. |
---|
937 | ! |
---|
938 | roughheight(:) = ave_height(:) - zhdispl(:) |
---|
939 | ! |
---|
940 | END SUBROUTINE condveg_z0logz |
---|
941 | ! |
---|
942 | ! |
---|
943 | ! |
---|
944 | SUBROUTINE condveg_z0cdrag (kjpindex,veget,veget_max,frac_nobio,totfrac_nobio,zlev, height, & |
---|
945 | & z0, roughheight) |
---|
946 | |
---|
947 | ! |
---|
948 | ! 0. Declarations |
---|
949 | ! |
---|
950 | |
---|
951 | ! 0.1 Input |
---|
952 | INTEGER(i_std), INTENT(in) :: kjpindex |
---|
953 | REAL(r_std), DIMENSION(kjpindex,nvm), INTENT(in) :: veget |
---|
954 | REAL(r_std), DIMENSION(kjpindex,nvm), INTENT(in) :: veget_max |
---|
955 | REAL(r_std), DIMENSION(kjpindex,nnobio), INTENT(in) :: frac_nobio |
---|
956 | REAL(r_std), DIMENSION(kjpindex), INTENT(in) :: totfrac_nobio |
---|
957 | REAL(r_std),DIMENSION (kjpindex), INTENT (in) :: zlev !! Height of first layer |
---|
958 | REAL(r_std), DIMENSION(kjpindex,nvm), INTENT(in) :: height |
---|
959 | |
---|
960 | ! 0.2 Output |
---|
961 | REAL(r_std), DIMENSION(kjpindex), INTENT(out) :: z0 |
---|
962 | REAL(r_std), DIMENSION(kjpindex), INTENT(out) :: roughheight |
---|
963 | |
---|
964 | ! 0.3 Local |
---|
965 | INTEGER(i_std) :: jv |
---|
966 | REAL(r_std), DIMENSION(kjpindex) :: sumveg, ztmp, ave_height |
---|
967 | REAL(r_std), DIMENSION(kjpindex) :: d_veg, zhdispl |
---|
968 | REAL(r_std) :: z0_nobio |
---|
969 | ! |
---|
970 | ! The grid average z0 is computed by averaging the neutral drag coefficients. |
---|
971 | ! This is pretty straight forward except for the reference level which needs |
---|
972 | ! to be chosen. |
---|
973 | ! |
---|
974 | ! We need a reference lever high enough above the canopy else we get into |
---|
975 | ! singularities of the LOG. |
---|
976 | ! |
---|
977 | ztmp(:) = MAX(10., zlev(:)) |
---|
978 | ! |
---|
979 | z0(:) = veget(:,1) * (ct_karman/LOG(ztmp(:)/z0_bare))**2 |
---|
980 | sumveg(:) = veget(:,1) |
---|
981 | ave_height(:) = zero |
---|
982 | ! |
---|
983 | DO jv = 2, nvm |
---|
984 | ! |
---|
985 | IF ( is_tree(jv) ) THEN |
---|
986 | ! tree trunks influence the atmosphere even when there are no leaves |
---|
987 | d_veg(:) = veget_max(:,jv) |
---|
988 | ELSE |
---|
989 | ! grasses only have an influence if they are really there! |
---|
990 | d_veg(:) = veget(:,jv) |
---|
991 | ENDIF |
---|
992 | ! |
---|
993 | z0(:) = z0(:) + d_veg(:) * (ct_karman/LOG(ztmp(:)/MAX(height(:,jv)*z0_over_height,z0_bare)))**2 |
---|
994 | sumveg(:) = sumveg(:) + d_veg(:) |
---|
995 | ! |
---|
996 | ave_height(:) = ave_height(:) + veget_max(:,jv)*height(:,jv) |
---|
997 | ! |
---|
998 | ENDDO |
---|
999 | ! |
---|
1000 | WHERE ( sumveg(:) .GT. zero ) z0(:) = z0(:) / sumveg(:) |
---|
1001 | ! |
---|
1002 | z0(:) = (un - totfrac_nobio(:)) * z0(:) |
---|
1003 | ! |
---|
1004 | DO jv = 1, nnobio |
---|
1005 | ! |
---|
1006 | IF ( jv .EQ. iice ) THEN |
---|
1007 | z0_nobio = z0_ice |
---|
1008 | ELSE |
---|
1009 | WRITE(numout,*) 'jv=',jv |
---|
1010 | STOP 'DO NOT KNOW ROUGHNESS OF THIS SURFACE TYPE' |
---|
1011 | ENDIF |
---|
1012 | ! |
---|
1013 | z0(:) = z0(:) + frac_nobio(:,jv) * (ct_karman/LOG(ztmp(:)/z0_nobio))**2 |
---|
1014 | ! |
---|
1015 | ENDDO |
---|
1016 | ! |
---|
1017 | z0(:) = ztmp(:) / EXP(ct_karman/SQRT(z0(:))) |
---|
1018 | ! |
---|
1019 | ! Temporarily we compute the zero plane displacement height |
---|
1020 | ! |
---|
1021 | zhdispl(:) = ave_height(:) * height_displacement |
---|
1022 | ! |
---|
1023 | ! In order to get a variable independent of the height of the |
---|
1024 | ! vegetation we compute what we call the effective roughness height. |
---|
1025 | ! This is the height over which the roughness acts. It combines the |
---|
1026 | ! zero plane displacement height and the vegetation height. |
---|
1027 | ! |
---|
1028 | roughheight(:) = ave_height(:) - zhdispl(:) |
---|
1029 | ! |
---|
1030 | END SUBROUTINE condveg_z0cdrag |
---|
1031 | ! |
---|
1032 | ! |
---|
1033 | ! |
---|
1034 | SUBROUTINE condveg_albcalc (kjpindex,deadleaf_cover,veget,drysoil_frac,albedo) |
---|
1035 | |
---|
1036 | ! |
---|
1037 | ! 0. Declarations |
---|
1038 | ! |
---|
1039 | |
---|
1040 | ! 0.1 Input |
---|
1041 | INTEGER(i_std), INTENT(in) :: kjpindex !! Domain size |
---|
1042 | REAL(r_std), DIMENSION(kjpindex), INTENT(in) :: deadleaf_cover !! Fraction of soil covered by dead leaves |
---|
1043 | REAL(r_std), DIMENSION(kjpindex,nvm), INTENT(in) :: veget !! Fraction of vegetation types |
---|
1044 | REAL(r_std), DIMENSION(kjpindex), INTENT(in) :: drysoil_frac !! Fraction of visibly Dry soil(between 0 and 1) |
---|
1045 | |
---|
1046 | ! 0.2 Output |
---|
1047 | REAL(r_std),DIMENSION (kjpindex,2), INTENT (out) :: albedo !! Albedo, vis(1) and nir(2) |
---|
1048 | ! 0.3 Local |
---|
1049 | ! REAL(r_std),DIMENSION (kjpindex) :: alb_bare |
---|
1050 | REAL(r_std),DIMENSION (nvm,2) :: alb_leaf_tmp |
---|
1051 | INTEGER(i_std) :: ks, jv |
---|
1052 | ! |
---|
1053 | !!$ DS :Correction 11/02/2011 : update 2D parameters |
---|
1054 | alb_leaf(1:nvm) = alb_leaf_vis(:) |
---|
1055 | alb_leaf(nvm+1:2*nvm) = alb_leaf_nir(:) |
---|
1056 | ! |
---|
1057 | alb_leaf_tmp(:,1) = alb_leaf(1:nvm) |
---|
1058 | alb_leaf_tmp(:,2) = alb_leaf(nvm+1:2*nvm) |
---|
1059 | ! |
---|
1060 | ! |
---|
1061 | DO ks = 1, 2 |
---|
1062 | ! |
---|
1063 | IF ( alb_bare_model ) THEN |
---|
1064 | alb_bare(:,ks) = soilalb_wet(:,ks) + drysoil_frac(:) * (soilalb_dry(:,ks) - soilalb_wet(:,ks)) |
---|
1065 | ELSE |
---|
1066 | ! Nouvelle formulation Nathalie, sans dependance en drysoil_frac. |
---|
1067 | alb_bare(:,ks) = soilalb_moy(:,ks) |
---|
1068 | ENDIF |
---|
1069 | ! |
---|
1070 | ! Correction Nathalie le 12 Avril 2006 - suppression de la dependance en deadleaf_cover |
---|
1071 | !albedo(:,ks) = veget(:,1) * ( (un-deadleaf_cover(:))*alb_bare(:) + & |
---|
1072 | ! deadleaf_cover(:)*alb_deadleaf(ks) ) |
---|
1073 | albedo(:,ks) = veget(:,1) * alb_bare(:,ks) |
---|
1074 | |
---|
1075 | ! vegetation |
---|
1076 | alb_veget(:,ks) = zero |
---|
1077 | DO jv = 2, nvm |
---|
1078 | albedo(:,ks) = albedo(:,ks) + veget(:,jv)*alb_leaf_tmp(jv,ks) |
---|
1079 | alb_veget(:,ks) = alb_veget(:,ks) + veget(:,jv)*alb_leaf_tmp(jv,ks) |
---|
1080 | ENDDO |
---|
1081 | ! |
---|
1082 | ENDDO |
---|
1083 | |
---|
1084 | END SUBROUTINE condveg_albcalc |
---|
1085 | |
---|
1086 | END MODULE condveg |
---|