SURFEX  V8_0
Surfex V8_0 release
 All Classes Files Functions Variables
mode_snow3l.F90
Go to the documentation of this file.
1 !SFX_LIC Copyright 1994-2014 CNRS, Meteo-France and Universite Paul Sabatier
2 !SFX_LIC This is part of the SURFEX software governed by the CeCILL-C licence
3 !SFX_LIC version 1. See LICENSE, CeCILL-C_V1-en.txt and CeCILL-C_V1-fr.txt
4 !SFX_LIC for details. version 1.
5 ! ##################
6  MODULE mode_snow3l
7 ! ##################
8 !
9 !!**** *MODE_SNOW * - contains explicit snow (ISBA-ES) characteristics functions
10 !! for total liquid water holding capacity of a snow layer (m)
11 !! and the thermal heat capacity of a layer (J K-1 m-3)
12 !!
13 !! PURPOSE
14 !! -------
15 !
16 !!** METHOD
17 !! ------
18 !! direct calculation
19 !!
20 !! EXTERNAL
21 !! --------
22 !!
23 !! IMPLICIT ARGUMENTS
24 !! ------------------
25 !!
26 !! REFERENCE
27 !! ---------
28 !! Boone and Etchevers, J. HydroMeteor., 2001
29 !!
30 !!
31 !! AUTHOR
32 !! ------
33 !! A. Boone * Meteo France *
34 !!
35 !! MODIFICATIONS
36 !! -------------
37 !! Original 01/08/02
38 !! V. Masson 01/2004 add snow grid computations
39 !! V. Vionnet 06/2008 -Introduction of Crocus formulation to
40 ! calculate maximum liquid water holding capacity
41 !! - New algorithm to compute snow grid :
42 ! 10 layers
43 !! - Routine to aggregate snow grain type
44 ! from 2 layers
45 !! _ Routine to compute average grain
46 ! type when snow depth< 3 cm.
47 ! S. Morin 02/2011 - Add routines for Crocus
48 ! A. Boone 02/2012 - Add optimization of do-loops.
49 ! C. Carmagnola 12/2012 - Add the case CSNOWMETAMO!='B92' in subroutine SNOW3LAVGRAIN and in function SNOW3LDIFTYP
50 ! M. Lafaysse 01/2013 - Remove SNOWCROWLIQMAX routines (not used)
51 ! M. Lafaysse 08/2013 - simplification of routine SNOW3LAVGRAIN (logical GDENDRITIC)
52 ! B. Decharme 07/2013 - SNOW3LGRID cleanning
53 ! New algorithm to compute snow grid for 6-L or 12-L
54 ! A. Boone 10/2014 - Added snow thermal conductivity routines
55 ! B. Decharme 01/2015 - Added optical snow grain size diameter
56 !----------------------------------------------------------------------------
57 !
58 !* 0. DECLARATIONS
59 !
60 !
61 INTERFACE snow3lwliqmax
62  MODULE PROCEDURE snow3lwliqmax_3d
63  MODULE PROCEDURE snow3lwliqmax_2d
64  MODULE PROCEDURE snow3lwliqmax_1d
65 END INTERFACE
66 !
67 INTERFACE snow3lhold
68  MODULE PROCEDURE snow3lhold_3d
69  MODULE PROCEDURE snow3lhold_2d
70  MODULE PROCEDURE snow3lhold_1d
71  MODULE PROCEDURE snow3lhold_0d
72 END INTERFACE
73 INTERFACE snowcrohold
74  MODULE PROCEDURE snowcrohold_3d
75  MODULE PROCEDURE snowcrohold_2d
76  MODULE PROCEDURE snowcrohold_1d
77  MODULE PROCEDURE snowcrohold_0d
78 END INTERFACE
79 !
80 INTERFACE snow3lscap
81  MODULE PROCEDURE snow3lscap_3d
82  MODULE PROCEDURE snow3lscap_2d
83  MODULE PROCEDURE snow3lscap_1d
84  MODULE PROCEDURE snow3lscap_0d
85 END INTERFACE
86 !
87 INTERFACE snow3l_marbouty
88  MODULE PROCEDURE snow3l_marbouty
89 END INTERFACE
90 !
91 INTERFACE snow3lgrid
92  MODULE PROCEDURE snow3lgrid_2d
93  MODULE PROCEDURE snow3lgrid_1d
94 END INTERFACE
95 !
96 INTERFACE snow3lagreg
97  MODULE PROCEDURE snow3lagreg
98 END INTERFACE
99 !
100 INTERFACE snow3lavgrain
101  MODULE PROCEDURE snow3lavgrain
102 END INTERFACE
103 !
104 INTERFACE snow3ldiftyp
105  MODULE PROCEDURE snow3ldiftyp
106 END INTERFACE
107 !
108 INTERFACE get_mass_heat
109  MODULE PROCEDURE get_mass_heat
110 END INTERFACE
111 !
112 INTERFACE get_diam
113  MODULE PROCEDURE get_diam
114 END INTERFACE
115 !
116 INTERFACE snow3lradabs
117  MODULE PROCEDURE snow3lradabs_2d
118  MODULE PROCEDURE snow3lradabs_1d
119  MODULE PROCEDURE snow3lradabs_0d
120 END INTERFACE
121 !
122 INTERFACE snow3lthrm
123  MODULE PROCEDURE snow3lthrm
124 END INTERFACE
125 !
126 INTERFACE snow3ldopt
127  MODULE PROCEDURE snow3ldopt_2d
128  MODULE PROCEDURE snow3ldopt_1d
129  MODULE PROCEDURE snow3ldopt_0d
130 END INTERFACE
131 !
132 INTERFACE snow3lalb
133  MODULE PROCEDURE snow3lalb
134 END INTERFACE
135 !
136 !-------------------------------------------------------------------------------
137  CONTAINS
138 !
139 !####################################################################
140  FUNCTION snow3lwliqmax_3d(PSNOWRHO) RESULT(PWLIQMAX)
141 !
142 !! PURPOSE
143 !! -------
144 ! Calculate the maximum liquid water holding capacity of
145 ! snow layer(s).
146 !
147 USE modd_snow_par, ONLY : xrhosmax_es, xsnowrhohold, &
148  xwsnowholdmax2, xwsnowholdmax1
149 !
150 USE yomhook ,ONLY : lhook, dr_hook
151 USE parkind1 ,ONLY : jprb
152 !
153 IMPLICIT NONE
154 !
155 !* 0.1 declarations of arguments
156 !
157 REAL, DIMENSION(:,:,:), INTENT(IN) :: psnowrho ! (kg/m3)
158 !
159 REAL, DIMENSION(SIZE(PSNOWRHO,1),SIZE(PSNOWRHO,2),SIZE(PSNOWRHO,3)) :: pwliqmax ! (kg/m3)
160 !
161 !* 0.2 declarations of local variables
162 !
163 REAL, DIMENSION(SIZE(PSNOWRHO,1),SIZE(PSNOWRHO,2),SIZE(PSNOWRHO,3)) :: zholdmaxr, zsnowrho
164 REAL(KIND=JPRB) :: zhook_handle
165 !-----------------------------------------------------------------------
166 ! Evaluate capacity using upper density limit:
167 !
168 IF (lhook) CALL dr_hook('MODE_SNOW3L:SNOW3LWLIQMAX_3D',0,zhook_handle)
169 zsnowrho(:,:,:) = min(xrhosmax_es, psnowrho(:,:,:))
170 !
171 ! Maximum ratio of liquid to SWE:
172 !
173 zholdmaxr(:,:,:) = xwsnowholdmax1 + (xwsnowholdmax2-xwsnowholdmax1)* &
174  max(0.,xsnowrhohold-zsnowrho(:,:,:))/xsnowrhohold
175 !
176 ! Maximum liquid water holding capacity of the snow (kg/m3):
177 !
178 pwliqmax(:,:,:) = zholdmaxr(:,:,:)*zsnowrho(:,:,:)
179 IF (lhook) CALL dr_hook('MODE_SNOW3L:SNOW3LWLIQMAX_3D',1,zhook_handle)
180 !
181 END FUNCTION snow3lwliqmax_3d
182 !####################################################################
183  FUNCTION snow3lwliqmax_2d(PSNOWRHO) RESULT(PWLIQMAX)
184 !
185 !! PURPOSE
186 !! -------
187 ! Calculate the maximum liquid water holding capacity of
188 ! snow layer(s).
189 !
190 USE modd_snow_par, ONLY : xrhosmax_es, xsnowrhohold, &
191  xwsnowholdmax2, xwsnowholdmax1
192 !
193 USE yomhook ,ONLY : lhook, dr_hook
194 USE parkind1 ,ONLY : jprb
195 !
196 IMPLICIT NONE
197 !
198 !* 0.1 declarations of arguments
199 !
200 REAL, DIMENSION(:,:), INTENT(IN) :: psnowrho ! (kg/m3)
201 !
202 REAL, DIMENSION(SIZE(PSNOWRHO,1),SIZE(PSNOWRHO,2)) :: pwliqmax ! (kg/m3)
203 !
204 !* 0.2 declarations of local variables
205 !
206 REAL, DIMENSION(SIZE(PSNOWRHO,1),SIZE(PSNOWRHO,2)) :: zholdmaxr, zsnowrho
207 REAL(KIND=JPRB) :: zhook_handle
208 !-----------------------------------------------------------------------
209 ! Evaluate capacity using upper density limit:
210 !
211 IF (lhook) CALL dr_hook('MODE_SNOW3L:SNOW3LWLIQMAX_2D',0,zhook_handle)
212 zsnowrho(:,:) = min(xrhosmax_es, psnowrho(:,:))
213 !
214 ! Maximum ratio of liquid to SWE:
215 !
216 zholdmaxr(:,:) = xwsnowholdmax1 + (xwsnowholdmax2-xwsnowholdmax1)* &
217  max(0.,xsnowrhohold-zsnowrho(:,:))/xsnowrhohold
218 !
219 ! Maximum liquid water holding capacity of the snow (kg/m3):
220 !
221 pwliqmax(:,:) = zholdmaxr(:,:)*zsnowrho(:,:)
222 IF (lhook) CALL dr_hook('MODE_SNOW3L:SNOW3LWLIQMAX_2D',1,zhook_handle)
223 !
224 END FUNCTION snow3lwliqmax_2d
225 !####################################################################
226  FUNCTION snow3lwliqmax_1d(PSNOWRHO) RESULT(PWLIQMAX)
227 !
228 !! PURPOSE
229 !! -------
230 ! Calculate the maximum liquid water holding capacity of
231 ! snow layer(s).
232 !
233 USE modd_snow_par, ONLY : xrhosmax_es, xsnowrhohold, &
234  xwsnowholdmax2, xwsnowholdmax1
235 !
236 USE yomhook ,ONLY : lhook, dr_hook
237 USE parkind1 ,ONLY : jprb
238 !
239 IMPLICIT NONE
240 !
241 !* 0.1 declarations of arguments
242 !
243 REAL, DIMENSION(:), INTENT(IN) :: psnowrho ! (kg/m3)
244 !
245 REAL, DIMENSION(SIZE(PSNOWRHO)) :: pwliqmax ! (kg/m3)
246 !
247 !* 0.2 declarations of local variables
248 !
249 REAL, DIMENSION(SIZE(PSNOWRHO)) :: zholdmaxr, zsnowrho
250 REAL(KIND=JPRB) :: zhook_handle
251 !----------------------------------------------------------------------
252 ! Evaluate capacity using upper density limit:
253 !
254 IF (lhook) CALL dr_hook('MODE_SNOW3L:SNOW3LWLIQMAX_1D',0,zhook_handle)
255 zsnowrho(:) = min(xrhosmax_es, psnowrho(:))
256 !
257 ! Maximum ratio of liquid to SWE:
258 !
259 zholdmaxr(:) = xwsnowholdmax1 + (xwsnowholdmax2-xwsnowholdmax1)* &
260  max(0.,xsnowrhohold-zsnowrho(:))/xsnowrhohold
261 !
262 ! Maximum liquid water holding capacity of the snow (kg/m3):
263 !
264 pwliqmax(:) = zholdmaxr(:)*zsnowrho(:)
265 IF (lhook) CALL dr_hook('MODE_SNOW3L:SNOW3LWLIQMAX_1D',1,zhook_handle)
266 !
267 END FUNCTION snow3lwliqmax_1d
268 
269 !####################################################################
270 !####################################################################
271 !####################################################################
272  FUNCTION snow3lhold_3d(PSNOWRHO,PSNOWDZ) RESULT(PWHOLDMAX)
273 !
274 !! PURPOSE
275 !! -------
276 ! Calculate the maximum liquid water holding capacity of
277 ! snow layer(s).
278 !
279 USE modd_csts, ONLY : xrholw
280 USE modd_snow_par, ONLY : xrhosmax_es, xsnowrhohold, &
281  xwsnowholdmax2, xwsnowholdmax1
282 !
283 USE yomhook ,ONLY : lhook, dr_hook
284 USE parkind1 ,ONLY : jprb
285 !
286 IMPLICIT NONE
287 !
288 !* 0.1 declarations of arguments
289 !
290 REAL, DIMENSION(:,:,:), INTENT(IN) :: psnowdz, psnowrho
291 !
292 REAL, DIMENSION(SIZE(PSNOWRHO,1),SIZE(PSNOWRHO,2),SIZE(PSNOWRHO,3)) :: pwholdmax
293 !
294 !* 0.2 declarations of local variables
295 !
296 REAL, DIMENSION(SIZE(PSNOWRHO,1),SIZE(PSNOWRHO,2),SIZE(PSNOWRHO,3)) :: zholdmaxr, zsnowrho
297 REAL(KIND=JPRB) :: zhook_handle
298 !-------------------------------------------------------------------------
299 ! Evaluate capacity using upper density limit:
300 !
301 IF (lhook) CALL dr_hook('MODE_SNOW3L:SNOW3LHOLD_3D',0,zhook_handle)
302 zsnowrho(:,:,:) = min(xrhosmax_es, psnowrho(:,:,:))
303 !
304 ! Maximum ratio of liquid to SWE:
305 !
306 zholdmaxr(:,:,:) = xwsnowholdmax1 + (xwsnowholdmax2-xwsnowholdmax1)* &
307  max(0.,xsnowrhohold-zsnowrho(:,:,:))/xsnowrhohold
308 !
309 ! Maximum liquid water holding capacity of the snow (m):
310 !
311 pwholdmax(:,:,:) = zholdmaxr(:,:,:)*psnowdz(:,:,:)*zsnowrho(:,:,:)/xrholw
312 IF (lhook) CALL dr_hook('MODE_SNOW3L:SNOW3LHOLD_3D',1,zhook_handle)
313 !
314 END FUNCTION snow3lhold_3d
315 !####################################################################
316  FUNCTION snow3lhold_2d(PSNOWRHO,PSNOWDZ) RESULT(PWHOLDMAX)
317 !
318 !! PURPOSE
319 !! -------
320 ! Calculate the maximum liquid water holding capacity of
321 ! snow layer(s).
322 !
323 USE modd_csts, ONLY : xrholw
324 USE modd_snow_par, ONLY : xrhosmax_es, xsnowrhohold, &
325  xwsnowholdmax2, xwsnowholdmax1
326 !
327 USE yomhook ,ONLY : lhook, dr_hook
328 USE parkind1 ,ONLY : jprb
329 !
330 IMPLICIT NONE
331 !
332 !* 0.1 declarations of arguments
333 !
334 REAL, DIMENSION(:,:), INTENT(IN) :: psnowdz, psnowrho
335 !
336 REAL, DIMENSION(SIZE(PSNOWRHO,1),SIZE(PSNOWRHO,2)) :: pwholdmax
337 !
338 !* 0.2 declarations of local variables
339 !
340 REAL, DIMENSION(SIZE(PSNOWRHO,1),SIZE(PSNOWRHO,2)) :: zholdmaxr, zsnowrho
341 REAL(KIND=JPRB) :: zhook_handle
342 !-----------------------------------------------------------------------
343 ! Evaluate capacity using upper density limit:
344 !
345 IF (lhook) CALL dr_hook('MODE_SNOW3L:SNOW3LHOLD_2D',0,zhook_handle)
346 zsnowrho(:,:) = min(xrhosmax_es, psnowrho(:,:))
347 !
348 ! Maximum ratio of liquid to SWE:
349 !
350 zholdmaxr(:,:) = xwsnowholdmax1 + (xwsnowholdmax2-xwsnowholdmax1)* &
351  max(0.,xsnowrhohold-zsnowrho(:,:))/xsnowrhohold
352 !
353 ! Maximum liquid water holding capacity of the snow (m):
354 !
355 pwholdmax(:,:) = zholdmaxr(:,:)*psnowdz(:,:)*zsnowrho(:,:)/xrholw
356 IF (lhook) CALL dr_hook('MODE_SNOW3L:SNOW3LHOLD_2D',1,zhook_handle)
357 !
358 END FUNCTION snow3lhold_2d
359 !####################################################################
360  FUNCTION snow3lhold_1d(PSNOWRHO,PSNOWDZ) RESULT(PWHOLDMAX)
361 !
362 !! PURPOSE
363 !! -------
364 ! Calculate the maximum liquid water holding capacity of
365 ! snow layer(s).
366 !
367 USE modd_csts, ONLY : xrholw
368 USE modd_snow_par, ONLY : xrhosmax_es, xsnowrhohold, &
369  xwsnowholdmax2, xwsnowholdmax1
370 !
371 USE yomhook ,ONLY : lhook, dr_hook
372 USE parkind1 ,ONLY : jprb
373 !
374 IMPLICIT NONE
375 !
376 !* 0.1 declarations of arguments
377 !
378 REAL, DIMENSION(:), INTENT(IN) :: psnowdz, psnowrho
379 !
380 REAL, DIMENSION(SIZE(PSNOWRHO)) :: pwholdmax
381 !
382 !* 0.2 declarations of local variables
383 !
384 REAL, DIMENSION(SIZE(PSNOWRHO)) :: zholdmaxr, zsnowrho
385 REAL(KIND=JPRB) :: zhook_handle
386 !-----------------------------------------------------------------------
387 ! Evaluate capacity using upper density limit:
388 !
389 IF (lhook) CALL dr_hook('MODE_SNOW3L:SNOW3LHOLD_1D',0,zhook_handle)
390 zsnowrho(:) = min(xrhosmax_es, psnowrho(:))
391 !
392 ! Maximum ratio of liquid to SWE:
393 !
394 zholdmaxr(:) = xwsnowholdmax1 + (xwsnowholdmax2-xwsnowholdmax1)* &
395  max(0.,xsnowrhohold-zsnowrho(:))/xsnowrhohold
396 !
397 ! Maximum liquid water holding capacity of the snow (m):
398 !
399 pwholdmax(:) = zholdmaxr(:)*psnowdz(:)*zsnowrho(:)/xrholw
400 IF (lhook) CALL dr_hook('MODE_SNOW3L:SNOW3LHOLD_1D',1,zhook_handle)
401 !
402 END FUNCTION snow3lhold_1d
403 !####################################################################
404  FUNCTION snow3lhold_0d(PSNOWRHO,PSNOWDZ) RESULT(PWHOLDMAX)
405 !
406 !! PURPOSE
407 !! -------
408 ! Calculate the maximum liquid water holding capacity of
409 ! snow layer(s).
410 !
411 USE modd_csts, ONLY : xrholw
412 USE modd_snow_par, ONLY : xrhosmax_es, xsnowrhohold, &
413  xwsnowholdmax2, xwsnowholdmax1
414 !
415 USE yomhook ,ONLY : lhook, dr_hook
416 USE parkind1 ,ONLY : jprb
417 !
418 IMPLICIT NONE
419 !
420 !* 0.1 declarations of arguments
421 !
422 REAL, INTENT(IN) :: psnowdz, psnowrho
423 !
424 REAL :: pwholdmax
425 !
426 !* 0.2 declarations of local variables
427 !
428 REAL :: zholdmaxr, zsnowrho
429 REAL(KIND=JPRB) :: zhook_handle
430 !-------------------------------------------------------------------------------
431 ! Evaluate capacity using upper density limit:
432 !
433 IF (lhook) CALL dr_hook('MODE_SNOW3L:SNOW3LHOLD_0D',0,zhook_handle)
434 zsnowrho = min(xrhosmax_es, psnowrho)
435 !
436 ! Maximum ratio of liquid to SWE:
437 !
438 zholdmaxr = xwsnowholdmax1 + (xwsnowholdmax2-xwsnowholdmax1) * &
439  max(0.,xsnowrhohold-zsnowrho)/xsnowrhohold
440 !
441 ! Maximum liquid water holding capacity of the snow (m):
442 !
443 pwholdmax = zholdmaxr*psnowdz*zsnowrho/xrholw
444 IF (lhook) CALL dr_hook('MODE_SNOW3L:SNOW3LHOLD_0D',1,zhook_handle)
445 !
446 END FUNCTION snow3lhold_0d
447 !####################################################################
448  FUNCTION snowcrohold_3d(PSNOWRHO,PSNOWLIQ,PSNOWDZ) RESULT(PWHOLDMAX)
449 !
450 !! PURPOSE
451 !! -------
452 ! Calculate the maximum liquid water holding capacity of
453 ! snow layer(s).
454 !
455 USE modd_csts, ONLY : xrholw,xrholi
456 USE modd_snow_par, ONLY : xpercentagepore
457 !
458 USE yomhook ,ONLY : lhook, dr_hook
459 USE parkind1 ,ONLY : jprb
460 !
461 IMPLICIT NONE
462 !
463 !* 0.1 declarations of arguments
464 !
465 REAL, DIMENSION(:,:,:), INTENT(IN) :: psnowdz, psnowliq, psnowrho
466 !
467 REAL, DIMENSION(SIZE(PSNOWRHO,1),SIZE(PSNOWRHO,2),SIZE(PSNOWRHO,3)) :: pwholdmax
468 REAL(KIND=JPRB) :: zhook_handle
469 !-------------------------------------------------------------------------------
470 ! computation of water holding capacity based on Crocus,
471 !taking into account the conversion between wet and dry density -
472 !S. Morin/V. Vionnet 2010 12 09
473 
474 ! PWHOLDMAX is expressed in m water for each layer
475 ! In short, PWHOLDMAX = XPERCENTAGEPORE * porosity * PSNOWDZ .
476 ! The porosity is computed as (rho_ice - (rho_snow - lwc))/(rho_ice)
477 ! where everything has to be in kg m-3 units. In practice, since
478 ! PSNOWLIQ is expressed in m water, expressing the lwc in kg m-3
479 ! is achieved as PSNOWLIQ*XRHOLW/PSNOWDZ. After some rearranging one
480 ! obtains the equation given above.
481 ! Note that equation (19) in Vionnet et al., GMD 2012, is wrong,
482 ! because it does not take into account the fact that liquid water
483 ! content has to be substracted from total density to compute the
484 ! porosity.
485 
486 
487 IF (lhook) CALL dr_hook('MODE_SNOW3L:SNOWCROHOLD_3D',0,zhook_handle)
488 pwholdmax(:,:,:) = xpercentagepore/xrholi * (psnowdz * (xrholi-psnowrho) + psnowliq*xrholw)
489 IF (lhook) CALL dr_hook('MODE_SNOW3L:SNOWCROHOLD_3D',1,zhook_handle)
490 !
491 END FUNCTION snowcrohold_3d
492 !####################################################################
493  FUNCTION snowcrohold_2d(PSNOWRHO,PSNOWLIQ,PSNOWDZ) RESULT(PWHOLDMAX)
494 !
495 !! PURPOSE
496 !! -------
497 ! Calculate the maximum liquid water holding capacity of
498 ! snow layer(s).
499 !
500 USE modd_csts, ONLY : xrholw,xrholi
501 USE modd_snow_par, ONLY : xpercentagepore
502 !
503 USE yomhook ,ONLY : lhook, dr_hook
504 USE parkind1 ,ONLY : jprb
505 !
506 IMPLICIT NONE
507 !
508 !* 0.1 declarations of arguments
509 !
510 REAL, DIMENSION(:,:), INTENT(IN) :: psnowdz, psnowrho, psnowliq
511 !
512 REAL, DIMENSION(SIZE(PSNOWRHO,1),SIZE(PSNOWRHO,2)) :: pwholdmax
513 REAL(KIND=JPRB) :: zhook_handle
514 !-------------------------------------------------------------------------------
515 ! computation of water holding capacity based on Crocus,
516 !taking into account the conversion between wet and dry density -
517 !S. Morin/V. Vionnet 2010 12 09
518 
519 ! PWHOLDMAX is expressed in m water for each layer
520 ! In short, PWHOLDMAX = XPERCENTAGEPORE * porosity * PSNOWDZ .
521 ! The porosity is computed as (rho_ice - (rho_snow - lwc))/(rho_ice)
522 ! where everything has to be in kg m-3 units. In practice, since
523 ! PSNOWLIQ is expressed in m water, expressing the lwc in kg m-3
524 ! is achieved as PSNOWLIQ*XRHOLW/PSNOWDZ. After some rearranging one
525 ! obtains the equation given above.
526 ! Note that equation (19) in Vionnet et al., GMD 2012, is wrong,
527 ! because it does not take into account the fact that liquid water
528 ! content has to be substracted from total density to compute the
529 ! porosity.
530 
531 IF (lhook) CALL dr_hook('MODE_SNOW3L:SNOWCROHOLD_2D',0,zhook_handle)
532 pwholdmax(:,:) = xpercentagepore/xrholi * (psnowdz * (xrholi-psnowrho) + psnowliq*xrholw)
533 IF (lhook) CALL dr_hook('MODE_SNOW3L:SNOWCROHOLD_2D',1,zhook_handle)
534 !
535 END FUNCTION snowcrohold_2d
536 !####################################################################
537 !####################################################################
538 !####################################################################
539  FUNCTION snowcrohold_1d(PSNOWRHO,PSNOWLIQ,PSNOWDZ) RESULT(PWHOLDMAX)
540 !
541 !! PURPOSE
542 !! -------
543 ! Calculate the maximum liquid water holding capacity of
544 ! snow layer(s).
545 !
546 USE modd_csts, ONLY : xrholw,xrholi
547 USE modd_snow_par, ONLY : xpercentagepore
548 !
549 USE yomhook ,ONLY : lhook, dr_hook
550 USE parkind1 ,ONLY : jprb
551 !
552 IMPLICIT NONE
553 !
554 !* 0.1 declarations of arguments
555 !
556 REAL, DIMENSION(:), INTENT(IN) :: psnowdz, psnowrho, psnowliq
557 !
558 REAL, DIMENSION(SIZE(PSNOWRHO)) :: pwholdmax
559 REAL(KIND=JPRB) :: zhook_handle
560 !-------------------------------------------------------------------------------
561 ! computation of water holding capacity based on Crocus,
562 !taking into account the conversion between wet and dry density -
563 !S. Morin/V. Vionnet 2010 12 09
564 
565 ! PWHOLDMAX is expressed in m water for each layer
566 ! In short, PWHOLDMAX = XPERCENTAGEPORE * porosity * PSNOWDZ .
567 ! The porosity is computed as (rho_ice - (rho_snow - lwc))/(rho_ice)
568 ! where everything has to be in kg m-3 units. In practice, since
569 ! PSNOWLIQ is expressed in m water, expressing the lwc in kg m-3
570 ! is achieved as PSNOWLIQ*XRHOLW/PSNOWDZ. After some rearranging one
571 ! obtains the equation given above.
572 ! Note that equation (19) in Vionnet et al., GMD 2012, is wrong,
573 ! because it does not take into account the fact that liquid water
574 ! content has to be substracted from total density to compute the
575 ! porosity.
576 
577 IF (lhook) CALL dr_hook('MODE_SNOW3L:SNOWCROHOLD_1D',0,zhook_handle)
578 pwholdmax(:) = xpercentagepore/xrholi * (psnowdz * (xrholi-psnowrho) + psnowliq*xrholw)
579 IF (lhook) CALL dr_hook('MODE_SNOW3L:SNOWCROHOLD_1D',1,zhook_handle)
580 !
581 END FUNCTION snowcrohold_1d
582 !####################################################################
583  FUNCTION snowcrohold_0d(PSNOWRHO,PSNOWLIQ,PSNOWDZ) RESULT(PWHOLDMAX)
584 !
585 !! PURPOSE
586 !! -------
587 ! Calculate the maximum liquid water holding capacity of
588 ! snow layer(s).
589 !
590 USE modd_csts, ONLY : xrholw,xrholi
591 USE modd_snow_par, ONLY : xpercentagepore
592 !
593 USE yomhook ,ONLY : lhook, dr_hook
594 USE parkind1 ,ONLY : jprb
595 !
596 IMPLICIT NONE
597 !
598 !* 0.1 declarations of arguments
599 !
600 REAL, INTENT(IN) :: psnowdz, psnowrho, psnowliq
601 !
602 REAL :: pwholdmax
603 REAL(KIND=JPRB) :: zhook_handle
604 !-------------------------------------------------------------------------------
605 ! computation of water holding capacity based on Crocus,
606 !taking into account the conversion between wet and dry density -
607 !S. Morin/V. Vionnet 2010 12 09
608 
609 ! PWHOLDMAX is expressed in m water for each layer
610 ! In short, PWHOLDMAX = XPERCENTAGEPORE * porosity * PSNOWDZ .
611 ! The porosity is computed as (rho_ice - (rho_snow - lwc))/(rho_ice)
612 ! where everything has to be in kg m-3 units. In practice, since
613 ! PSNOWLIQ is expressed in m water, expressing the lwc in kg m-3
614 ! is achieved as PSNOWLIQ*XRHOLW/PSNOWDZ. After some rearranging one
615 ! obtains the equation given above.
616 ! Note that equation (19) in Vionnet et al., GMD 2012, is wrong,
617 ! because it does not take into account the fact that liquid water
618 ! content has to be substracted from total density to compute the
619 ! porosity.
620 
621 IF (lhook) CALL dr_hook('MODE_SNOW3L:SNOWCROHOLD_0D',0,zhook_handle)
622 pwholdmax = xpercentagepore/xrholi * (psnowdz * (xrholi-psnowrho) + psnowliq*xrholw)
623 IF (lhook) CALL dr_hook('MODE_SNOW3L:SNOWCROHOLD_0D',1,zhook_handle)
624 !
625 END FUNCTION snowcrohold_0d
626 !####################################################################
627 !####################################################################
628 !####################################################################
629  FUNCTION snow3lscap_3d(PSNOWRHO) RESULT(PSCAP)
630 !
631 !! PURPOSE
632 !! -------
633 ! Calculate the heat capacity of a snow layer.
634 !
635 USE modd_csts,ONLY : xci
636 !
637 USE yomhook ,ONLY : lhook, dr_hook
638 USE parkind1 ,ONLY : jprb
639 !
640 IMPLICIT NONE
641 !
642 !* 0.1 declarations of arguments
643 !
644 REAL, DIMENSION(:,:,:), INTENT(IN) :: psnowrho
645 !
646 REAL, DIMENSION(SIZE(PSNOWRHO,1),SIZE(PSNOWRHO,2),SIZE(PSNOWRHO,3)) :: pscap
647 REAL(KIND=JPRB) :: zhook_handle
648 !-------------------------------------------------------------------------------
649 ! The method of Verseghy (1991), Int. J. Climat., 11, 111-133.
650 !
651 IF (lhook) CALL dr_hook('MODE_SNOW3L:SNOW3LSCAP_3D',0,zhook_handle)
652 pscap(:,:,:) = psnowrho(:,:,:)*xci ! (J K-1 m-3)
653 IF (lhook) CALL dr_hook('MODE_SNOW3L:SNOW3LSCAP_3D',1,zhook_handle)
654 !
655 END FUNCTION snow3lscap_3d
656 !####################################################################
657  FUNCTION snow3lscap_2d(PSNOWRHO) RESULT(PSCAP)
658 !
659 !! PURPOSE
660 !! -------
661 ! Calculate the heat capacity of a snow layer.
662 !
663 USE modd_csts,ONLY : xci
664 !
665 USE yomhook ,ONLY : lhook, dr_hook
666 USE parkind1 ,ONLY : jprb
667 !
668 IMPLICIT NONE
669 !
670 !* 0.1 declarations of arguments
671 !
672 REAL, DIMENSION(:,:), INTENT(IN) :: psnowrho
673 !
674 REAL, DIMENSION(SIZE(PSNOWRHO,1),SIZE(PSNOWRHO,2)) :: pscap
675 REAL(KIND=JPRB) :: zhook_handle
676 !-------------------------------------------------------------------------------
677 ! The method of Verseghy (1991), Int. J. Climat., 11, 111-133.
678 !
679 IF (lhook) CALL dr_hook('MODE_SNOW3L:SNOW3LSCAP_2D',0,zhook_handle)
680 pscap(:,:) = psnowrho(:,:)*xci ! (J K-1 m-3)
681 IF (lhook) CALL dr_hook('MODE_SNOW3L:SNOW3LSCAP_2D',1,zhook_handle)
682 !
683 END FUNCTION snow3lscap_2d
684 !####################################################################
685  FUNCTION snow3lscap_1d(PSNOWRHO) RESULT(PSCAP)
686 !
687 !! PURPOSE
688 !! -------
689 ! Calculate the heat capacity of a snow layer.
690 !
691 USE modd_csts,ONLY : xci
692 !
693 USE yomhook ,ONLY : lhook, dr_hook
694 USE parkind1 ,ONLY : jprb
695 !
696 IMPLICIT NONE
697 !
698 !* 0.1 declarations of arguments
699 !
700 REAL, DIMENSION(:), INTENT(IN) :: psnowrho
701 !
702 REAL, DIMENSION(SIZE(PSNOWRHO)) :: pscap
703 REAL(KIND=JPRB) :: zhook_handle
704 !-------------------------------------------------------------------------------
705 ! The method of Verseghy (1991), Int. J. Climat., 11, 111-133.
706 !
707 IF (lhook) CALL dr_hook('MODE_SNOW3L:SNOW3LSCAP_1D',0,zhook_handle)
708 pscap(:) = psnowrho(:)*xci ! (J K-1 m-3)
709 IF (lhook) CALL dr_hook('MODE_SNOW3L:SNOW3LSCAP_1D',1,zhook_handle)
710 !
711 END FUNCTION snow3lscap_1d
712 !####################################################################
713  FUNCTION snow3lscap_0d(PSNOWRHO) RESULT(PSCAP)
714 !
715 !! PURPOSE
716 !! -------
717 ! Calculate the heat capacity of a snow layer.
718 !
719 USE modd_csts,ONLY : xci
720 !
721 USE yomhook ,ONLY : lhook, dr_hook
722 USE parkind1 ,ONLY : jprb
723 !
724 IMPLICIT NONE
725 !
726 !* 0.1 declarations of arguments
727 !
728 REAL, INTENT(IN) :: psnowrho
729 !
730 REAL :: pscap
731 REAL(KIND=JPRB) :: zhook_handle
732 !-------------------------------------------------------------------------------
733 ! The method of Verseghy (1991), Int. J. Climat., 11, 111-133.
734 !
735 IF (lhook) CALL dr_hook('MODE_SNOW3L:SNOW3LSCAP_0D',0,zhook_handle)
736 pscap = psnowrho*xci ! (J K-1 m-3)
737 IF (lhook) CALL dr_hook('MODE_SNOW3L:SNOW3LSCAP_0D',1,zhook_handle)
738 !
739 END FUNCTION snow3lscap_0d
740 !
741 !####################################################################
742 !####################################################################
743 !####################################################################
744  FUNCTION snow3l_marbouty(PSNOWRHO,PSNOWTEMP,PGRADT) RESULT(PDANGL)
745 !**** *ZDANGL* - CROISSANCE DES GRAINS NON DENDRITIQUES ET ANGULEUX .
746 ! - GROWTH RATES FOR NON DENDRITIC GRAINS WITH SPHERICITY=0
747 
748 
749 ! OBJET.
750 ! ------
751 
752 !** INTERFACE.
753 ! ----------
754 
755 ! *ZDANGL*(PST,PSRO,PGRADT)*
756 
757 ! *PST* - TEMPERATURE DE LA STRATE DE NEIGE.
758 ! *PSRO* - MASSE VOLUMIQUE DE LA STRATE DE NEIGE.
759 ! *PGRADT* - GRADIENT DE TEMPERATURE AFFECTANT LA STRATE DE NEIGE.
760 
761 ! METHODE.
762 ! --------
763 ! THE FUNCTION RETURN A VALUE BETWEEN 0 AND 1 WHICH IS USED IN THE DETERMINATION OF THE
764 ! GROWTH RATE FOR THE CONSIDERED LAYER.
765 ! THIS VALUE (WITHOUT UNIT) IS THE PRODUCT OF 3 FUNCTIONS (WHICH HAVE THEIR SOLUTIONS BETWEEN 0 AND 1) :
766 ! F(TEMPERATURE) * H(DENSITY) * G(TEMPERATURE GRADIENT)
767 
768 ! EXTERNES.
769 ! ---------
770 
771 ! REFERENCES.
772 ! -----------
773 ! MARBOUTY D (1980) AN EXPERIMENTAL STUDY OF TEMPERATURE GRADIENT
774 ! METAMORPHISM J GLACIOLOGY
775 
776 ! AUTEURS.
777 ! --------
778 ! DOMINIQUE MARBOUTY (FMARBO/GMARBO/HMARBO).
779 
780 ! MODIFICATIONS.
781 ! --------------
782 ! 08/95: YANNICK DANIELOU - CODAGE A LA NORME DOCTOR.
783 ! 03/06: JM WILLEMET - F90 AND SI UNITS
784 ! 01/08: JM WILLEMET - ERROR ON THE FORMULATION OF G FUNCTION (WITH GRADIENT) IS CORRECTED
785 
786 USE modd_csts, ONLY : xtt
787 USE modd_snow_metamo
788 !
789 USE yomhook ,ONLY : lhook, dr_hook
790 USE parkind1 ,ONLY : jprb
791 !
792 IMPLICIT NONE
793 !
794 ! DECLARATIONS.
795 ! -------------
796 !
797 REAL ,INTENT(IN) :: psnowtemp, psnowrho, pgradt
798 !
799 REAL :: pdangl
800 REAL(KIND=JPRB) :: zhook_handle
801 !
802 IF (lhook) CALL dr_hook('MODE_SNOW3L:SNOW3L_MARBOUTY',0,zhook_handle)
803 !
804 pdangl = 0.0
805 !
806 ! INFLUENCE DE LA TEMPERATURE /TEMPERATURE INFLUENCE.
807 IF( psnowtemp>=xtt-xvtang1 ) THEN
808  !
809  IF ( psnowtemp>=xtt-xvtang2 ) THEN
810  pdangl = xvtang4 + xvtang5 * (xtt-psnowtemp) / xvtang6
811  ELSEIF( psnowtemp>=xtt-xvtang3 ) THEN
812  pdangl = xvtang7 - xvtang8 * (xtt-xvtang2-psnowtemp) / xvtang9
813  ELSE
814  pdangl = xvtanga - xvtangb * (xtt-xvtang3-psnowtemp) / xvtangc
815  ENDIF
816  !
817  ! INFLUENCE DE LA MASSE VOLUMIQUE / DENSITY INFLUENCE.
818  IF ( psnowrho<=xvrang1 ) THEN
819  !
820  IF ( psnowrho>xvrang2 ) THEN
821  pdangl = pdangl * ( 1. - (psnowrho-xvrang2)/(xvrang1-xvrang2) )
822  ENDIF
823  !
824  ! INFLUENCE DU GRADIENT DE TEMPERATURE / TEMPERATURE GRADIENT INFLUENCE.
825  IF ( pgradt<=xvgang1 ) THEN
826  !
827  IF ( pgradt<=xvgang2 ) THEN
828  pdangl = pdangl * xvgang5 * (pgradt-xvgang6)/(xvgang2-xvgang6)
829  ELSEIF( pgradt<=xvgang3 ) THEN
830  pdangl = pdangl * ( xvgang7 + xvgang8 * (pgradt-xvgang2)/(xvgang3-xvgang2) )
831  ELSEIF( pgradt<=xvgang4 )THEN
832  pdangl = pdangl * ( xvgang9 + xvganga * (pgradt-xvgang3)/(xvgang4-xvgang3) )
833  ELSE
834  pdangl = pdangl * ( xvgangb + xvgangc * (pgradt-xvgang4)/(xvgang1-xvgang4) )
835  ENDIF
836  !
837  ENDIF
838  !
839  ELSE
840  !
841  pdangl = 0.
842  !
843  ENDIF
844  !
845 ELSE
846  !
847  pdangl = 0.
848  !
849 ENDIF
850 !
851 IF (lhook) CALL dr_hook('MODE_SNOW3L:SNOW3L_MARBOUTY',1,zhook_handle)
852 !
853 END FUNCTION snow3l_marbouty
854 !
855 !####################################################################
856 !####################################################################
857 !####################################################################
858 !
859  SUBROUTINE snow3lgrid_2d(PSNOWDZ,PSNOW,PSNOWDZ_OLD)
860 !
861 !! PURPOSE
862 !! -------
863 ! Once during each time step, update grid to maintain
864 ! grid proportions. Similar to approach of Lynch-Steiglitz,
865 ! 1994, J. Clim., 7, 1842-1855. Corresponding mass and
866 ! heat adjustments made directly after the call to this
867 ! routine. 3 grid configurations:
868 ! 1) for very thin snow, constant grid spacing
869 ! 2) for intermediate thicknesses, highest resolution at soil/snow
870 ! interface and at the snow/atmosphere interface
871 ! 3) for deep snow, vertical resoution finest at snow/atmosphere
872 ! interface (set to a constant value) and increases with snow depth.
873 ! Second layer can't be more than an order of magnitude thicker
874 ! than surface layer.
875 !
876 !
877 USE modd_surf_par, ONLY : xundef
878 USE modd_snow_par, ONLY : xsnowcritd
879 !
880 USE yomhook ,ONLY : lhook, dr_hook
881 USE parkind1 ,ONLY : jprb
882 !
883 IMPLICIT NONE
884 !
885 !* 0.1 declarations of arguments
886 !
887 REAL, DIMENSION(: ), INTENT(IN ) :: psnow
888 REAL, DIMENSION(:,:), INTENT(OUT) :: psnowdz
889 REAL, DIMENSION(:,:), INTENT(IN ), OPTIONAL :: psnowdz_old
890 !
891 !* 0.1 declarations of local variables
892 !
893 INTEGER :: jj, ji
894 !
895 INTEGER :: inlvls, ini
896 !
897 REAL, DIMENSION(SIZE(PSNOW)) :: zwork
898 !
899 LOGICAL , DIMENSION(SIZE(PSNOW)) :: gregrid
900 
901 ! ISBA-ES snow grid parameters
902 !
903 REAL, PARAMETER, DIMENSION(3) :: zsgcoef1 = (/0.25, 0.50, 0.25/)
904 REAL, PARAMETER, DIMENSION(2) :: zsgcoef2 = (/0.05, 0.34/)
905 !
906 REAL, PARAMETER, DIMENSION(3) :: zsgcoef = (/0.3, 0.4, 0.3/)
907 !
908 ! Minimum total snow depth at which surface layer thickness is constant:
909 !
910 REAL, PARAMETER :: zsnowtrans = 0.20 ! (m)
911 !
912 ! Minimum snow depth by layer for 6-L or 12-L configuration :
913 !
914 REAL, PARAMETER :: zdz1=0.01
915 REAL, PARAMETER :: zdz2=0.05
916 REAL, PARAMETER :: zdz3=0.15
917 REAL, PARAMETER :: zdz4=0.50
918 REAL, PARAMETER :: zdz5=1.00
919 REAL, PARAMETER :: zdzn0=0.02
920 REAL, PARAMETER :: zdzn1=0.1
921 REAL, PARAMETER :: zdzn2=0.5
922 REAL, PARAMETER :: zdzn3=1.0
923 !
924 REAL, PARAMETER :: zcoef1 = 0.5
925 REAL, PARAMETER :: zcoef2 = 1.5
926 !
927 REAL(KIND=JPRB) :: zhook_handle
928 !
929 !-------------------------------------------------------------------------------
930 !
931 ! 0. Initialization:
932 ! ------------------
933 !
934 IF (lhook) CALL dr_hook('MODE_SNOW3L:SNOW3LGRID_2D',0,zhook_handle)
935 !
936 inlvls = SIZE(psnowdz(:,:),2)
937 ini = SIZE(psnowdz(:,:),1)
938 !
939 zwork(:) = 0.0
940 gregrid(:) = .true.
941 !
942 ! 1. Calculate current grid for 3-layer (default) configuration):
943 ! ---------------------------------------------------------------
944 ! Based on formulation of Lynch-Stieglitz (1994)
945 ! except for 3 modifications:
946 ! i) smooth transition here at ZSNOWTRANS
947 ! ii) constant ratio for very thin snow:
948 ! iii) ratio of layer 2 to surface layer <= 10
949 !
950 IF(inlvls == 1)THEN
951 !
952  DO ji=1,ini
953  psnowdz(ji,1) = psnow(ji)
954  ENDDO
955 !
956 ELSEIF(inlvls == 3)THEN
957 !
958  WHERE(psnow <= xsnowcritd+0.01)
959  psnowdz(:,1) = min(0.01, psnow(:)/inlvls)
960  psnowdz(:,3) = min(0.01, psnow(:)/inlvls)
961  psnowdz(:,2) = psnow(:) - psnowdz(:,1) - psnowdz(:,3)
962  END WHERE
963 !
964  WHERE(psnow <= zsnowtrans .AND. psnow > xsnowcritd+0.01)
965  psnowdz(:,1) = psnow(:)*zsgcoef1(1)
966  psnowdz(:,2) = psnow(:)*zsgcoef1(2)
967  psnowdz(:,3) = psnow(:)*zsgcoef1(3)
968  END WHERE
969 !
970  WHERE(psnow > zsnowtrans)
971  psnowdz(:,1) = zsgcoef2(1)
972  psnowdz(:,2) = (psnow(:)-zsgcoef2(1))*zsgcoef2(2) + zsgcoef2(1)
973 !
974 ! When using simple finite differences, limit the thickness
975 ! factor between the top and 2nd layers to at most 10
976 !
977  psnowdz(:,2) = min(10*zsgcoef2(1), psnowdz(:,2))
978  psnowdz(:,3) = psnow(:) - psnowdz(:,2) - psnowdz(:,1)
979  END WHERE
980 !
981 !
982 ! 2. Calculate current grid for 6-layer :
983 ! ---------------------------------------------------------------
984 !
985 ELSEIF(inlvls == 6)THEN
986 !
987 ! critere a satisfaire pour remaillage
988 !
989  IF(present(psnowdz_old))THEN
990  gregrid(:) = psnowdz_old(:,1) < zcoef1 * min(zdz1 ,psnow(:)/inlvls) .OR. &
991  & psnowdz_old(:,1) > zcoef2 * min(zdz1 ,psnow(:)/inlvls) .OR. &
992  & psnowdz_old(:,2) < zcoef1 * min(zdz2 ,psnow(:)/inlvls) .OR. &
993  & psnowdz_old(:,2) > zcoef2 * min(zdz2 ,psnow(:)/inlvls) .OR. &
994  & psnowdz_old(:,6) < zcoef1 * min(zdzn1,psnow(:)/inlvls) .OR. &
995  & psnowdz_old(:,6) > zcoef2 * min(zdzn1,psnow(:)/inlvls)
996  ENDIF
997 !
998  WHERE(gregrid(:))
999 ! top layers
1000  psnowdz(:,1) = min(zdz1,psnow(:)/inlvls)
1001  psnowdz(:,2) = min(zdz2,psnow(:)/inlvls)
1002 ! last layers
1003  psnowdz(:,6) = min(zdzn1,psnow(:)/inlvls)
1004 ! remaining snow for remaining layers
1005  zwork(:) = psnow(:) - psnowdz(:,1) - psnowdz(:,2) - psnowdz(:,6)
1006  psnowdz(:,3) = zwork(:)*zsgcoef(1)
1007  psnowdz(:,4) = zwork(:)*zsgcoef(2)
1008  psnowdz(:,5) = zwork(:)*zsgcoef(3)
1009 ! layer 3 tickness >= layer 2 tickness
1010  zwork(:)=min(0.0,psnowdz(:,3)-psnowdz(:,2))
1011  psnowdz(:,3)=psnowdz(:,3)-zwork(:)
1012  psnowdz(:,4)=psnowdz(:,4)+zwork(:)
1013 ! layer 5 tickness >= layer 6 tickness
1014  zwork(:)=min(0.0,psnowdz(:,5)-psnowdz(:,6))
1015  psnowdz(:,5)=psnowdz(:,5)-zwork(:)
1016  psnowdz(:,4)=psnowdz(:,4)+zwork(:)
1017  ENDWHERE
1018 !
1019 ! 3. Calculate current grid for 9-layer :
1020 ! ---------------------------------------------------------------
1021 !
1022 ELSEIF(inlvls == 9)THEN
1023 !
1024 ! critere a satisfaire pour remaillage
1025 !
1026  IF(present(psnowdz_old))THEN
1027  gregrid(:) = psnowdz_old(:,1) < zcoef1 * min(zdz1 ,psnow(:)/inlvls) .OR. &
1028  & psnowdz_old(:,1) > zcoef2 * min(zdz1 ,psnow(:)/inlvls) .OR. &
1029  & psnowdz_old(:,2) < zcoef1 * min(zdz2 ,psnow(:)/inlvls) .OR. &
1030  & psnowdz_old(:,2) > zcoef2 * min(zdz2 ,psnow(:)/inlvls) .OR. &
1031  & psnowdz_old(:,9) < zcoef1 * min(zdzn0,psnow(:)/inlvls) .OR. &
1032  & psnowdz_old(:,9) > zcoef2 * min(zdzn0,psnow(:)/inlvls)
1033  ENDIF
1034 !
1035  WHERE(gregrid(:))
1036 ! top layers
1037  psnowdz(:,1) = min(zdz1,psnow(:)/inlvls)
1038  psnowdz(:,2) = min(zdz2,psnow(:)/inlvls)
1039  psnowdz(:,3) = min(zdz3,psnow(:)/inlvls)
1040 ! last layers
1041  psnowdz(:,9)= min(zdzn0,psnow(:)/inlvls)
1042  psnowdz(:,8)= min(zdzn1,psnow(:)/inlvls)
1043  psnowdz(:,7)= min(zdzn2,psnow(:)/inlvls)
1044 ! remaining snow for remaining layers
1045  zwork(:) = psnow(:) - psnowdz(:, 1) - psnowdz(:, 2) - psnowdz(:, 3) &
1046  - psnowdz(:, 7) - psnowdz(:, 8) - psnowdz(:, 9)
1047  psnowdz(:,4) = zwork(:)*zsgcoef(1)
1048  psnowdz(:,5) = zwork(:)*zsgcoef(2)
1049  psnowdz(:,6) = zwork(:)*zsgcoef(3)
1050 ! layer 4 tickness >= layer 3 tickness
1051  zwork(:)=min(0.0,psnowdz(:,4)-psnowdz(:,3))
1052  psnowdz(:,4)=psnowdz(:,4)-zwork(:)
1053  psnowdz(:,5)=psnowdz(:,5)+zwork(:)
1054 ! layer 6 tickness >= layer 7 tickness
1055  zwork(:)=min(0.0,psnowdz(:,6)-psnowdz(:,7))
1056  psnowdz(:,6)=psnowdz(:,6)-zwork(:)
1057  psnowdz(:,5)=psnowdz(:,5)+zwork(:)
1058  ENDWHERE
1059 !
1060 ! 4. Calculate current grid for 12-layer :
1061 ! ---------------------------------------------------------------
1062 !
1063 ELSEIF(inlvls == 12)THEN
1064 !
1065 ! critere a satisfaire pour remaillage
1066 !
1067  IF(present(psnowdz_old))THEN
1068  gregrid(:) = psnowdz_old(:, 1) < zcoef1 * min(zdz1 ,psnow(:)/inlvls) .OR. &
1069  & psnowdz_old(:, 1) > zcoef2 * min(zdz1 ,psnow(:)/inlvls) .OR. &
1070  & psnowdz_old(:, 2) < zcoef1 * min(zdz2 ,psnow(:)/inlvls) .OR. &
1071  & psnowdz_old(:, 2) > zcoef2 * min(zdz2 ,psnow(:)/inlvls) .OR. &
1072  & psnowdz_old(:,12) < zcoef1 * min(zdzn0,psnow(:)/inlvls) .OR. &
1073  & psnowdz_old(:,12) > zcoef2 * min(zdzn0,psnow(:)/inlvls)
1074  ENDIF
1075 !
1076  WHERE(gregrid(:))
1077 ! top layers
1078  psnowdz(:,1) = min(zdz1,psnow(:)/inlvls)
1079  psnowdz(:,2) = min(zdz2,psnow(:)/inlvls)
1080  psnowdz(:,3) = min(zdz3,psnow(:)/inlvls)
1081  psnowdz(:,4) = min(zdz4,psnow(:)/inlvls)
1082  psnowdz(:,5) = min(zdz5,psnow(:)/inlvls)
1083 ! last layers
1084  psnowdz(:,12)= min(zdzn0,psnow(:)/inlvls)
1085  psnowdz(:,11)= min(zdzn1,psnow(:)/inlvls)
1086  psnowdz(:,10)= min(zdzn2,psnow(:)/inlvls)
1087  psnowdz(:, 9)= min(zdzn3,psnow(:)/inlvls)
1088 ! remaining snow for remaining layers
1089  zwork(:) = psnow(:) - psnowdz(:, 1) - psnowdz(:, 2) - psnowdz(:, 3) &
1090  - psnowdz(:, 4) - psnowdz(:, 5) - psnowdz(:, 9) &
1091  - psnowdz(:,10) - psnowdz(:,11) - psnowdz(:,12)
1092  psnowdz(:,6) = zwork(:)*zsgcoef(1)
1093  psnowdz(:,7) = zwork(:)*zsgcoef(2)
1094  psnowdz(:,8) = zwork(:)*zsgcoef(3)
1095 ! layer 6 tickness >= layer 5 tickness
1096  zwork(:)=min(0.0,psnowdz(:,6)-psnowdz(:,5))
1097  psnowdz(:,6)=psnowdz(:,6)-zwork(:)
1098  psnowdz(:,7)=psnowdz(:,7)+zwork(:)
1099 ! layer 8 tickness >= layer 9 tickness
1100  zwork(:)=min(0.0,psnowdz(:,8)-psnowdz(:,9))
1101  psnowdz(:,8)=psnowdz(:,8)-zwork(:)
1102  psnowdz(:,7)=psnowdz(:,7)+zwork(:)
1103  ENDWHERE
1104 !
1105 ! 4. Calculate other non-optimized grid :
1106 ! ---------------------------------------
1107 !
1108 ELSEIF(inlvls<10.AND.inlvls/=3.AND.inlvls/=6.AND.inlvls/=9) THEN
1109 !
1110  DO jj=1,inlvls
1111  DO ji=1,ini
1112  psnowdz(ji,jj) = psnow(ji)/inlvls
1113  ENDDO
1114  ENDDO
1115 !
1116  psnowdz(:,inlvls) = psnowdz(:,inlvls) + (psnowdz(:,1) - min(0.05, psnowdz(:,1)))
1117  psnowdz(:,1) = min(0.05, psnowdz(:,1))
1118 !
1119 ELSE !(inlvls>=10 and /=12)
1120 !
1121 ! critere a satisfaire pour remaillage
1122 !
1123  IF(present(psnowdz_old))THEN
1124  gregrid(:) = psnowdz_old(:, 1) < zcoef1 * min(zdz1 ,psnow(:)/inlvls) .OR. &
1125  & psnowdz_old(:, 1) > zcoef2 * min(zdz1 ,psnow(:)/inlvls) .OR. &
1126  & psnowdz_old(:, 2) < zcoef1 * min(zdz2 ,psnow(:)/inlvls) .OR. &
1127  & psnowdz_old(:, 2) > zcoef2 * min(zdz2 ,psnow(:)/inlvls) .OR. &
1128  & psnowdz_old(:,inlvls) < zcoef1 * min(0.05*psnow(:),psnow(:)/inlvls) .OR. &
1129  & psnowdz_old(:,inlvls) > zcoef2 * min(0.05*psnow(:),psnow(:)/inlvls)
1130  ENDIF
1131 !
1132  WHERE(gregrid(:))
1133  psnowdz(:,1 ) = min(zdz1 ,psnow(:)/inlvls)
1134  psnowdz(:,2 ) = min(zdz2 ,psnow(:)/inlvls)
1135  psnowdz(:,3 ) = min(zdz3 ,psnow(:)/inlvls)
1136  psnowdz(:,4 ) = min(zdz4 ,psnow(:)/inlvls)
1137  psnowdz(:,5 ) = min(zdz5 ,psnow(:)/inlvls)
1138  psnowdz(:,inlvls) = min(0.05*psnow(:),psnow(:)/inlvls)
1139  ENDWHERE
1140 !
1141  DO jj=6,inlvls-1,1
1142  DO ji=1,ini
1143  IF(gregrid(ji))THEN
1144  zwork(ji) = psnowdz(ji,1)+psnowdz(ji,2)+psnowdz(ji,3)+psnowdz(ji,4)+psnowdz(ji,5)
1145  psnowdz(ji,jj) = (psnow(ji)-zwork(ji)-psnowdz(ji,inlvls))/(inlvls-6)
1146  ENDIF
1147  ENDDO
1148  ENDDO
1149 !
1150 ENDIF
1151 !
1152 DO jj=1,inlvls
1153  DO ji=1,ini
1154  IF(psnow(ji)==xundef)THEN
1155  psnowdz(ji,jj) = xundef
1156  ELSEIF(.NOT.gregrid(ji))THEN
1157  psnowdz(ji,jj)=psnowdz_old(ji,jj)
1158  ENDIF
1159  ENDDO
1160 ENDDO
1161 !
1162 IF (lhook) CALL dr_hook('MODE_SNOW3L:SNOW3LGRID_2D',1,zhook_handle)
1163 !
1164 END SUBROUTINE snow3lgrid_2d
1165 !####################################################################
1166 !####################################################################
1167 !####################################################################
1168 !
1169  SUBROUTINE snow3lgrid_1d(PSNOWDZ,PSNOW,PSNOWDZ_OLD)
1170 !
1171 !! PURPOSE
1172 !! -------
1173 ! Once during each time step, update grid to maintain
1174 ! grid proportions. Similar to approach of Lynch-Steiglitz,
1175 ! 1994, J. Clim., 7, 1842-1855. Corresponding mass and
1176 ! heat adjustments made directly after the call to this
1177 ! routine. 3 grid configurations:
1178 ! 1) for very thin snow, constant grid spacing
1179 ! 2) for intermediate thicknesses, highest resolution at soil/snow
1180 ! interface and at the snow/atmosphere interface
1181 ! 3) for deep snow, vertical resoution finest at snow/atmosphere
1182 ! interface (set to a constant value) and increases with snow depth.
1183 ! Second layer can't be more than an order of magnitude thicker
1184 ! than surface layer.
1185 !
1186 !
1187 USE modd_surf_par, ONLY : xundef
1188 USE modd_snow_par, ONLY : xsnowcritd
1189 !
1190 USE yomhook ,ONLY : lhook, dr_hook
1191 USE parkind1 ,ONLY : jprb
1192 !
1193 IMPLICIT NONE
1194 !
1195 !* 0.1 declarations of arguments
1196 !
1197 REAL, INTENT(IN ) :: psnow
1198 REAL, DIMENSION(:), INTENT(OUT) :: psnowdz
1199 REAL, DIMENSION(:), INTENT(IN ), OPTIONAL :: psnowdz_old
1200 !
1201 !* 0.1 declarations of local variables
1202 !
1203 INTEGER jj
1204 !
1205 INTEGER :: inlvls
1206 !
1207 REAL :: zwork
1208 !
1209 ! modif_EB pour maillage
1210 LOGICAL :: gregrid
1211 
1212 ! ISBA-ES snow grid parameters
1213 !
1214 REAL, PARAMETER, DIMENSION(3) :: zsgcoef1 = (/0.25, 0.50, 0.25/)
1215 REAL, PARAMETER, DIMENSION(2) :: zsgcoef2 = (/0.05, 0.34/)
1216 !
1217 REAL, PARAMETER, DIMENSION(3) :: zsgcoef = (/0.3, 0.4, 0.3/)
1218 !
1219 ! Minimum total snow depth at which surface layer thickness is constant:
1220 !
1221 REAL, PARAMETER :: zsnowtrans = 0.20 ! (m)
1222 !
1223 ! Minimum snow depth by layer for 6-L or 12-L configuration :
1224 !
1225 REAL, PARAMETER :: zdz1=0.01
1226 REAL, PARAMETER :: zdz2=0.05
1227 REAL, PARAMETER :: zdz3=0.15
1228 REAL, PARAMETER :: zdz4=0.50
1229 REAL, PARAMETER :: zdz5=1.00
1230 REAL, PARAMETER :: zdzn0=0.02
1231 REAL, PARAMETER :: zdzn1=0.1
1232 REAL, PARAMETER :: zdzn2=0.5
1233 REAL, PARAMETER :: zdzn3=1.0
1234 !
1235 REAL, PARAMETER :: zcoef1 = 0.5
1236 REAL, PARAMETER :: zcoef2 = 1.5
1237 !
1238 REAL(KIND=JPRB) :: zhook_handle
1239 !
1240 !-------------------------------------------------------------------------------
1241 !
1242 ! 0. Initialization:
1243 ! ------------------
1244 !
1245 IF (lhook) CALL dr_hook('MODE_SNOW3L:SNOW3LGRID_1D',0,zhook_handle)
1246 !
1247 inlvls = SIZE(psnowdz(:),1)
1248 !
1249 gregrid = .true.
1250 !
1251 ! 1. Calculate current grid for 3-layer (default) configuration):
1252 ! ---------------------------------------------------------------
1253 ! Based on formulation of Lynch-Stieglitz (1994)
1254 ! except for 3 modifications:
1255 ! i) smooth transition here at ZSNOWTRANS
1256 ! ii) constant ratio for very thin snow:
1257 ! iii) ratio of layer 2 to surface layer <= 10
1258 !
1259 IF(inlvls == 1)THEN
1260 !
1261  psnowdz(1) = psnow
1262 !
1263 ELSEIF(inlvls == 3)THEN
1264 !
1265  IF(psnow <= xsnowcritd+0.01)THEN
1266  psnowdz(1) = min(0.01, psnow/inlvls)
1267  psnowdz(3) = min(0.01, psnow/inlvls)
1268  psnowdz(2) = psnow - psnowdz(1) - psnowdz(3)
1269  ENDIF
1270 !
1271  IF(psnow <= zsnowtrans .AND. psnow > xsnowcritd+0.01)THEN
1272  psnowdz(1) = psnow*zsgcoef1(1)
1273  psnowdz(2) = psnow*zsgcoef1(2)
1274  psnowdz(3) = psnow*zsgcoef1(3)
1275  ENDIF
1276 !
1277  IF(psnow > zsnowtrans)THEN
1278  psnowdz(1) = zsgcoef2(1)
1279  psnowdz(2) = (psnow-zsgcoef2(1))*zsgcoef2(2) + zsgcoef2(1)
1280 !
1281 ! When using simple finite differences, limit the thickness
1282 ! factor between the top and 2nd layers to at most 10
1283 !
1284  psnowdz(2) = min(10*zsgcoef2(1), psnowdz(2))
1285  psnowdz(3) = psnow - psnowdz(2) - psnowdz(1)
1286  END IF
1287 !
1288 !
1289 ! 2. Calculate current grid for 6-layer :
1290 ! ---------------------------------------------------------------
1291 !
1292 ELSEIF(inlvls == 6)THEN
1293 !
1294 ! critere a satisfaire pour remaillage
1295 !
1296  IF(present(psnowdz_old))THEN
1297  gregrid = psnowdz_old(1) < zcoef1 * min(zdz1 ,psnow/inlvls) .OR. &
1298  & psnowdz_old(1) > zcoef2 * min(zdz1 ,psnow/inlvls) .OR. &
1299  & psnowdz_old(2) < zcoef1 * min(zdz2 ,psnow/inlvls) .OR. &
1300  & psnowdz_old(2) > zcoef2 * min(zdz2 ,psnow/inlvls) .OR. &
1301  & psnowdz_old(6) < zcoef1 * min(zdzn1,psnow/inlvls) .OR. &
1302  & psnowdz_old(6) > zcoef2 * min(zdzn1,psnow/inlvls)
1303  ENDIF
1304 !
1305  IF(gregrid)THEN
1306 ! top layers
1307  psnowdz(1) = min(zdz1,psnow/inlvls)
1308  psnowdz(2) = min(zdz2,psnow/inlvls)
1309 ! last layers
1310  psnowdz(6) = min(zdzn1,psnow/inlvls)
1311 ! remaining snow for remaining layers
1312  zwork = psnow - psnowdz(1) - psnowdz(2) - psnowdz(6)
1313  psnowdz(3) = zwork*zsgcoef(1)
1314  psnowdz(4) = zwork*zsgcoef(2)
1315  psnowdz(5) = zwork*zsgcoef(3)
1316 ! layer 3 tickness >= layer 2 tickness
1317  zwork=min(0.0,psnowdz(3)-psnowdz(2))
1318  psnowdz(3)=psnowdz(3)-zwork
1319  psnowdz(4)=psnowdz(4)+zwork
1320 ! layer 5 tickness >= layer 6 tickness
1321  zwork=min(0.0,psnowdz(5)-psnowdz(6))
1322  psnowdz(5)=psnowdz(5)-zwork
1323  psnowdz(4)=psnowdz(4)+zwork
1324  ENDIF
1325 !
1326 ! 3. Calculate current grid for 9-layer :
1327 ! ---------------------------------------------------------------
1328 !
1329 ELSEIF(inlvls == 9)THEN
1330 !
1331 ! critere a satisfaire pour remaillage
1332 !
1333  IF(present(psnowdz_old))THEN
1334  gregrid = psnowdz_old(1) < zcoef1 * min(zdz1 ,psnow/inlvls) .OR. &
1335  & psnowdz_old(1) > zcoef2 * min(zdz1 ,psnow/inlvls) .OR. &
1336  & psnowdz_old(2) < zcoef1 * min(zdz2 ,psnow/inlvls) .OR. &
1337  & psnowdz_old(2) > zcoef2 * min(zdz2 ,psnow/inlvls) .OR. &
1338  & psnowdz_old(9) < zcoef1 * min(zdzn0,psnow/inlvls) .OR. &
1339  & psnowdz_old(9) > zcoef2 * min(zdzn0,psnow/inlvls)
1340  ENDIF
1341 !
1342  IF(gregrid)THEN
1343 ! top layers
1344  psnowdz(1) = min(zdz1,psnow/inlvls)
1345  psnowdz(2) = min(zdz2,psnow/inlvls)
1346  psnowdz(3) = min(zdz3,psnow/inlvls)
1347 ! last layers
1348  psnowdz(9)= min(zdzn0,psnow/inlvls)
1349  psnowdz(8)= min(zdzn1,psnow/inlvls)
1350  psnowdz(7)= min(zdzn2,psnow/inlvls)
1351 ! remaining snow for remaining layers
1352  zwork = psnow - psnowdz( 1) - psnowdz( 2) - psnowdz( 3) &
1353  - psnowdz( 7) - psnowdz( 8) - psnowdz( 9)
1354  psnowdz(4) = zwork*zsgcoef(1)
1355  psnowdz(5) = zwork*zsgcoef(2)
1356  psnowdz(6) = zwork*zsgcoef(3)
1357 ! layer 4 tickness >= layer 3 tickness
1358  zwork=min(0.0,psnowdz(4)-psnowdz(3))
1359  psnowdz(4)=psnowdz(4)-zwork
1360  psnowdz(5)=psnowdz(5)+zwork
1361 ! layer 6 tickness >= layer 7 tickness
1362  zwork=min(0.0,psnowdz(6)-psnowdz(7))
1363  psnowdz(6)=psnowdz(6)-zwork
1364  psnowdz(5)=psnowdz(5)+zwork
1365  ENDIF
1366 !
1367 ! 4. Calculate current grid for 12-layer :
1368 ! ---------------------------------------------------------------
1369 !
1370 ELSEIF(inlvls == 12)THEN
1371 !
1372 ! modif_EB pour maillage
1373 ! critere a satisfaire pour remaillage
1374  IF(present(psnowdz_old))THEN
1375  gregrid = psnowdz_old(1) < zcoef1 * min(zdz1 ,psnow/inlvls) .OR. &
1376  & psnowdz_old(1) > zcoef2 * min(zdz1 ,psnow/inlvls) .OR. &
1377  & psnowdz_old(2) < zcoef1 * min(zdz2 ,psnow/inlvls) .OR. &
1378  & psnowdz_old(2) > zcoef2 * min(zdz2 ,psnow/inlvls) .OR. &
1379  & psnowdz_old(12) < zcoef1 * min(zdzn0,psnow/inlvls) .OR. &
1380  & psnowdz_old(12) > zcoef2 * min(zdzn0,psnow/inlvls)
1381  ENDIF
1382 !
1383  IF (gregrid)THEN
1384 ! top layers
1385  psnowdz(1) = min(zdz1,psnow/inlvls)
1386  psnowdz(2) = min(zdz2,psnow/inlvls)
1387  psnowdz(3) = min(zdz3,psnow/inlvls)
1388  psnowdz(4) = min(zdz4,psnow/inlvls)
1389  psnowdz(5) = min(zdz5,psnow/inlvls)
1390 ! last layers
1391  psnowdz(12)= min(zdzn0,psnow/inlvls)
1392  psnowdz(11)= min(zdzn1,psnow/inlvls)
1393  psnowdz(10)= min(zdzn2,psnow/inlvls)
1394  psnowdz( 9)= min(zdzn3,psnow/inlvls)
1395 ! remaining snow for remaining layers
1396  zwork = psnow - psnowdz( 1) - psnowdz( 2) - psnowdz( 3) &
1397  - psnowdz( 4) - psnowdz( 5) - psnowdz( 9) &
1398  - psnowdz(10) - psnowdz(11) - psnowdz(12)
1399  psnowdz(6) = zwork*zsgcoef(1)
1400  psnowdz(7) = zwork*zsgcoef(2)
1401  psnowdz(8) = zwork*zsgcoef(3)
1402 ! layer 6 tickness >= layer 5 tickness
1403  zwork=min(0.0,psnowdz(6)-psnowdz(5))
1404  psnowdz(6)=psnowdz(6)-zwork
1405  psnowdz(7)=psnowdz(7)+zwork
1406 ! layer 8 tickness >= layer 9 tickness
1407  zwork=min(0.0,psnowdz(8)-psnowdz(9))
1408  psnowdz(8)=psnowdz(8)-zwork
1409  psnowdz(7)=psnowdz(7)+zwork
1410  ENDIF
1411 !
1412 ! 4. Calculate other non-optimized grid to allow CROCUS PREP :
1413 ! ------------------------------------------------------------
1414 !
1415 ELSE IF(inlvls<10.AND.inlvls/=3.AND.inlvls/=6.AND.inlvls/=9) THEN
1416 !
1417  DO jj=1,inlvls
1418  psnowdz(jj) = psnow/inlvls
1419  ENDDO
1420 !
1421  psnowdz(inlvls) = psnowdz(inlvls) + (psnowdz(1) - min(0.05, psnowdz(1)))
1422  psnowdz(1) = min(0.05, psnowdz(1))
1423 !
1424 ELSE
1425 !
1426  IF(present(psnowdz_old))THEN
1427  gregrid = psnowdz_old( 1) < zcoef1 * min(zdz1 ,psnow/inlvls) .OR. &
1428  & psnowdz_old( 1) > zcoef2 * min(zdz1 ,psnow/inlvls) .OR. &
1429  & psnowdz_old( 2) < zcoef1 * min(zdz2 ,psnow/inlvls) .OR. &
1430  & psnowdz_old( 2) > zcoef2 * min(zdz2 ,psnow/inlvls) .OR. &
1431  & psnowdz_old(inlvls) < zcoef1 * min(0.05*psnow,psnow/inlvls) .OR. &
1432  & psnowdz_old(inlvls) > zcoef2 * min(0.05*psnow,psnow/inlvls)
1433  ENDIF
1434 !
1435  IF (gregrid)THEN
1436  psnowdz( 1) = min(zdz1 ,psnow/inlvls)
1437  psnowdz( 2) = min(zdz2 ,psnow/inlvls)
1438  psnowdz( 3) = min(zdz3 ,psnow/inlvls)
1439  psnowdz( 4) = min(zdz4 ,psnow/inlvls)
1440  psnowdz( 5) = min(zdz5 ,psnow/inlvls)
1441  psnowdz(inlvls) = min(0.05*psnow,psnow/inlvls)
1442  zwork = sum(psnowdz(1:5))
1443  DO jj=6,inlvls-1,1
1444  psnowdz(jj) = (psnow - zwork -psnowdz(inlvls))/(inlvls-6)
1445  END DO
1446  ENDIF
1447 !
1448 ENDIF
1449 !
1450 DO jj=1,inlvls
1451  IF(psnow==xundef)THEN
1452  psnowdz(jj) = xundef
1453  ELSEIF(.NOT.gregrid)THEN
1454  psnowdz(jj) = psnowdz_old(jj)
1455  ENDIF
1456 END DO
1457 !
1458 IF (lhook) CALL dr_hook('MODE_SNOW3L:SNOW3LGRID_1D',1,zhook_handle)
1459 !
1460 END SUBROUTINE snow3lgrid_1d
1461 !
1462 !###################################################################################
1463 !###################################################################################
1464 SUBROUTINE snow3lagreg(PSNOWDZN,PSNOWDZ,PSNOWRHO,PSNOWGRAN1, PSNOWGRAN2, &
1465  psnowhist,psnowgran1n,psnowgran2n,psnowhistn, &
1466  kl1,kl2,psnowddz )
1467 !
1468 USE modd_snow_metamo
1469 !
1470 USE yomhook ,ONLY : lhook, dr_hook
1471 USE parkind1 ,ONLY : jprb
1472 !
1473 IMPLICIT NONE
1474 !
1475 ! 0.1 declarations of arguments
1476 !
1477 REAL, DIMENSION(:), INTENT(IN) :: psnowdzn,psnowdz,psnowrho,psnowddz
1478 !
1479 REAL, DIMENSION(:), INTENT(IN) :: psnowgran1,psnowgran2,psnowhist
1480 REAL, DIMENSION(:), INTENT(OUT) :: psnowgran1n,psnowgran2n,psnowhistn
1481 !
1482 INTEGER, INTENT(IN) :: kl1 ! Indice couche de reference (i)
1483 INTEGER, INTENT(IN) :: kl2 ! Indice de la couche (i-1 ou i+1) dont une
1484  ! partie est aggregee à la couche (i)
1485 !
1486 ! 0.2 declaration of local variables
1487 !
1488 REAL, DIMENSION(SIZE(PSNOWRHO,1)) :: zsnowrho
1489 REAL, DIMENSION(SIZE(PSNOWRHO,1)) :: zdiamd,zdiamv,zspherd,zspherv,&
1490  zdiamn,zsphern,zdent
1491 !
1492 REAL :: zdelta, zcomp
1493 !
1494 INTEGER :: ident, ivieu, il
1495 !
1496 REAL(KIND=JPRB) :: zhook_handle
1497 !
1498 IF (lhook) CALL dr_hook('MODE_SNOW3L:SNOW3LAGREG',0,zhook_handle)
1499 !
1500 IF( kl1<kl2 ) THEN
1501  zdelta = 0.0
1502  il = kl1
1503 ELSE
1504  zdelta = 1.0
1505  il = kl2
1506 ENDIF
1507 !
1508 ! Mean Properties
1509 !
1510 ! 1. History
1511 !
1512 IF ( psnowhist(kl1)/=psnowhist(kl2) ) THEN
1513  psnowhistn(kl1) = 0.0
1514 ENDIF
1515 !
1516 ! 2. New grain types
1517 !
1518 ! 2.1 Same grain type
1519 !
1520 IF ( psnowgran1(kl1)*psnowgran1(kl2)>0.0 .OR. &
1521  ( psnowgran1(kl1)==0.0 .AND. psnowgran1(kl2)>=0.0 ) .OR. &
1522  ( psnowgran1(kl2)==0.0 .AND. psnowgran1(kl1)>=0.0 ) ) THEN
1523  !
1524  !code original vincent PSNOWGRAN1N(KL1)=(PSNOWGRAN1(KL1)*PSNOWRHO(KL1)&
1525  !code original vincent *(PSNOWDZN(KL1)-(1.0-ZDELTA)*ABS(PSNOWDDZ(KL1))-ZDELTA*&
1526  !code original vincent ABS(PSNOWDDZ(KL2)))+PSNOWGRAN1(KL2)* &
1527  !code original vincent PSNOWRHO(KL2)*((1.0-ZDELTA)*ABS(PSNOWDDZ(KL1))+ &
1528  !code original vincent ZDELTA*ABS(PSNOWDDZ(KL2))))/((PSNOWDZN(KL1)-(1.0-ZDELTA)&
1529  !code original vincent *ABS(PSNOWDDZ(KL1))-ZDELTA*ABS(PSNOWDDZ(KL2)))* &
1530  !code original vincent PSNOWRHO(KL1)+((1.0-ZDELTA)*ABS(PSNOWDDZ(KL1))+ &
1531  !code original vincent ZDELTA*ABS(PSNOWDDZ(KL2)))*PSNOWRHO(KL2))
1532  !code original vincent !
1533  !code original vincent PSNOWGRAN2N(KL1)=(PSNOWGRAN2(KL1)*PSNOWRHO(KL1) &
1534  !code original vincent *(PSNOWDZN(KL1)-(1.0-ZDELTA)*ABS(PSNOWDDZ(KL1))-ZDELTA* &
1535  !code original vincent ABS(PSNOWDDZ(KL2)))+PSNOWGRAN2(KL2)* &
1536  !code original vincent PSNOWRHO(KL2)*((1.0-ZDELTA)*ABS(PSNOWDDZ(KL1)) &
1537  !code original vincent +ZDELTA*ABS(PSNOWDDZ(KL2))))/((PSNOWDZN(KL1)-(1.0-ZDELTA)&
1538  !code original vincent *ABS(PSNOWDDZ(KL1))-ZDELTA*ABS(PSNOWDDZ(KL2)))* &
1539  !code original vincent PSNOWRHO(KL1)+((1.0-ZDELTA)*ABS(PSNOWDDZ(KL1))+ &
1540  !code original vincent ZDELTA*ABS(PSNOWDDZ(KL2)))*PSNOWRHO(KL2))
1541  !
1542  !plm
1543  CALL get_agreg(kl1,kl2,psnowgran1(kl1),psnowgran1(kl2),psnowgran1n(kl1))
1544  !
1545  CALL get_agreg(kl1,kl2,psnowgran2(kl1),psnowgran2(kl2),psnowgran2n(kl1))
1546  !
1547  !plm
1548  !
1549 ELSE
1550  !
1551  ! 2.2 Different types
1552  !
1553  IF ( psnowgran1(kl1)<0.0 ) THEN
1554  ident = kl1
1555  ivieu = kl2
1556  ELSE
1557  ident = kl2
1558  ivieu = kl1
1559  ENDIF
1560  !
1561  zdiamd(kl1) = - psnowgran1(ident)/xgran * xdiaet + ( 1.0 + psnowgran1(ident)/xgran ) * &
1562  ( psnowgran2(ident)/xgran * xdiagf + ( 1.0 - psnowgran2(ident)/xgran ) * xdiafp )
1563  !
1564  zspherd(kl1) = psnowgran2(ident)/xgran
1565  zdiamv(kl1) = psnowgran2(ivieu)
1566  zspherv(kl1) = psnowgran1(ivieu)/xgran
1567  !IF(KL1==1)THEN
1568  !write(*,*) 'ZDD1',ZDIAMD(1),'ZSD1',ZSPHERD(1)
1569  !write(*,*) 'ZDV1',ZDIAMV(1),'ZSV1',ZSPHERV(1)
1570  !ENDIF
1571  !
1572  IF ( ident==kl1 ) THEN
1573  !code original vincent ZDIAMN(KL1)= (ZDIAMD(KL1)*PSNOWRHO(IDENT)*&
1574  !code original vincent (PSNOWDZN(IDENT)-(1.0-ZDELTA)*ABS(PSNOWDDZ(KL1))-ZDELTA* &
1575  !code original vincent ABS(PSNOWDDZ(KL2)))+ZDIAMV(KL1)*PSNOWRHO(IVIEU)*( &
1576  !code original vincent (1.0-ZDELTA)*ABS(PSNOWDDZ(KL1))-ZDELTA*ABS(PSNOWDDZ(KL2))))/&
1577  !code original vincent ((PSNOWDZN(KL1)-(1.0-ZDELTA)* &
1578  !code original vincent ABS(PSNOWDDZ(KL1))-ZDELTA*ABS(PSNOWDDZ(KL2)))* &
1579  !code original vincent PSNOWRHO(KL1)+((1.0-ZDELTA)*ABS(PSNOWDDZ(KL1))+ &
1580  !code original vincent ZDELTA*ABS(PSNOWDDZ(KL2)))*PSNOWRHO(KL2))
1581  !
1582  !plm
1583  CALL get_agreg(ident,ivieu,zdiamd(kl1),zdiamv(kl1),zdiamn(kl1))
1584  !
1585  !plm
1586  !
1587  !code original vincent ZSPHERN(KL1)= (ZSPHERD(KL1)*PSNOWRHO(IDENT)*&
1588  !code original vincent (PSNOWDZN(IDENT)-(1.0-ZDELTA)*ABS(PSNOWDDZ(KL1))-ZDELTA* &
1589  !code original vincent ABS(PSNOWDDZ(KL2)))+ZSPHERV(KL1)*PSNOWRHO(IVIEU)*( &
1590  !code original vincent (1.0-ZDELTA)*ABS(PSNOWDDZ(KL1))-ZDELTA*ABS(PSNOWDDZ(KL2))))/&
1591  !code original vincent ((PSNOWDZN(KL1)-(1.0-ZDELTA)* &
1592  !code original vincent ABS(PSNOWDDZ(KL1))-ZDELTA*ABS(PSNOWDDZ(KL2)))* &
1593  !code original vincent PSNOWRHO(KL1)+((1.0-ZDELTA)*ABS(PSNOWDDZ(KL1))+ &
1594  !code original vincent ZDELTA*ABS(PSNOWDDZ(KL2)))*PSNOWRHO(KL2))
1595 
1596  !plm
1597  CALL get_agreg(ident,ivieu,zspherd(kl1),zspherv(kl1),zsphern(kl1))
1598  !plm
1599  !
1600  ELSE
1601  !code original vincent ZDIAMN(KL1)= (ZDIAMD(KL1)*PSNOWRHO(IDENT)*&
1602  !code original vincent ((1.0-ZDELTA)*ABS(PSNOWDDZ(KL1))+ZDELTA*ABS(PSNOWDDZ(KL2)))&
1603  !code original vincent +ZDIAMV(KL1)*PSNOWRHO(IVIEU)*(PSNOWDZN(IVIEU)-(1.0-ZDELTA)* &
1604  !code original vincent ABS(PSNOWDDZ(KL1))-ZDELTA*ABS(PSNOWDDZ(KL2))))/&
1605  !code original vincent ((PSNOWDZN(KL1)-(1.0-ZDELTA)* &
1606  !code original vincent ABS(PSNOWDDZ(KL1))-ZDELTA*ABS(PSNOWDDZ(KL2)))* &
1607  !code original vincent PSNOWRHO(KL1)+((1.0-ZDELTA)*ABS(PSNOWDDZ(KL1))+ &
1608  !code original vincent ZDELTA*ABS(PSNOWDDZ(KL2)))*PSNOWRHO(KL2))
1609  !code original vincent!
1610  !code original vincent ZSPHERN(KL1)= (ZSPHERD(KL1)*PSNOWRHO(IDENT)*&
1611  !code original vincent ((1.0-ZDELTA)*ABS(PSNOWDDZ(KL1))+ZDELTA*ABS(PSNOWDDZ(KL2)))&
1612  !code original vincent +ZSPHERV(KL1)*PSNOWRHO(IVIEU)*(PSNOWDZN(IVIEU)-(1.0-ZDELTA)* &
1613  !code original vincent ABS(PSNOWDDZ(KL1))-ZDELTA*ABS(PSNOWDDZ(KL2))))/&
1614  !code original vincent ((PSNOWDZN(KL1)-(1.0-ZDELTA)* &
1615  !code original vincent ABS(PSNOWDDZ(KL1))-ZDELTA*ABS(PSNOWDDZ(KL2)))* &
1616  !code original vincent PSNOWRHO(KL1)+((1.0-ZDELTA)*ABS(PSNOWDDZ(KL1))+ &
1617  !code original vincent ZDELTA*ABS(PSNOWDDZ(KL2)))*PSNOWRHO(KL2))
1618  !plm
1619  !
1620  CALL get_agreg(ivieu,ident,zdiamv(kl1),zdiamd(kl1),zdiamn(kl1))
1621  !
1622  CALL get_agreg(ivieu,ident,zspherv(kl1),zspherd(kl1),zsphern(kl1))
1623  !plm
1624  !
1625  ENDIF
1626  !
1627  zcomp = zsphern(kl1) * xdiagf + ( 1.-zsphern(kl1) ) * xdiafp
1628  IF( zdiamn(kl1) < zcomp ) THEN
1629  !
1630  zdent(kl1) = ( zdiamn(kl1) - zcomp ) / ( xdiaet - zcomp )
1631  !IF(KL1==1) write(*,*) 'ZDENT',ZDENT(1)
1632  psnowgran1n(kl1) = - xgran * zdent(kl1)
1633  psnowgran2n(kl1) = xgran * zsphern(kl1)
1634  !
1635  ELSE
1636  !
1637  psnowgran1n(kl1) = xgran * zsphern(kl1)
1638  psnowgran2n(kl1) = zdiamn(kl1)
1639  !
1640  ENDIF
1641  !
1642 ENDIF
1643 !
1644 IF (lhook) CALL dr_hook('MODE_SNOW3L:SNOW3LAGREG',1,zhook_handle)
1645 !
1646 ! 3. Update snow grains parameters : GRAN1, GRAN2
1647 ! PSNOWGRAN1(KL1)=ZSNOWGRAN1(KL1)
1648 ! PSNOWGRAN2(KL1)=ZSNOWGRAN2(KL1)
1649 !
1650  CONTAINS
1651 !
1652 SUBROUTINE get_agreg(KID1,KID2,PFIELD1,PFIELD2,PFIELD)
1653 !
1654 INTEGER, INTENT(IN) :: kid1, kid2
1655 REAL, INTENT(IN) :: pfield1, pfield2
1656 REAL, INTENT(OUT) :: pfield
1657 !
1658 REAL(KIND=JPRB) :: zhook_handle
1659 !
1660 IF (lhook) CALL dr_hook('MODE_SNOW3L:SNOW3LAGREG:GET_AGREG',0,zhook_handle)
1661 !
1662 pfield = ( pfield1 * psnowrho(kid1) * ( psnowdzn(kid1) - abs(psnowddz(il)) ) &
1663  + pfield2 * psnowrho(kid2) * abs(psnowddz(il)) ) / &
1664  ( psnowrho(kl1) * ( psnowdzn(kl1) - abs(psnowddz(il)) ) + &
1665  psnowrho(kl2) * abs(psnowddz(il)) )
1666 !
1667 IF (lhook) CALL dr_hook('MODE_SNOW3L:SNOW3LAGREG:GET_AGREG',1,zhook_handle)
1668 !
1669 END SUBROUTINE get_agreg
1670 !
1671 END SUBROUTINE snow3lagreg
1672 !###############################################################################
1673 !###############################################################################
1674 !
1675 !
1676 !ajout EB : ajout des arguments "N" pour faire idem variables d'origine
1677 SUBROUTINE snow3lavgrain(PSNOWGRAN1,PSNOWGRAN2,PSNOWHIST, &
1678  psnowgran1n,psnowgran2n,psnowhistn,pndent,pnvieu,&
1679  hsnowmetamo)
1680 !
1681 USE modd_snow_metamo, ONLY : xvdiam6, xuepsi
1682 !
1683 USE yomhook ,ONLY : lhook, dr_hook
1684 USE parkind1 ,ONLY : jprb
1685 !
1686 IMPLICIT NONE
1687 !
1688 ! 0.1 declarations of arguments
1689 !
1690 REAL, DIMENSION(:,:), INTENT(INOUT) :: psnowgran1,psnowgran2,psnowhist
1691 ! ajout EB
1692 REAL, DIMENSION(:,:), INTENT(INOUT) :: psnowgran1n,psnowgran2n,psnowhistn
1693 !
1694 REAL, DIMENSION(:), INTENT(IN) :: pndent, pnvieu
1695 !
1696  CHARACTER(3), INTENT(IN) :: hsnowmetamo
1697 ! 0.2 declaration of local variables
1698 !
1699 REAL, DIMENSION(SIZE(PSNOWGRAN1,1)) :: zgran1, zgran2, zhist
1700 !
1701 LOGICAL, DIMENSION(SIZE(PSNOWGRAN1,1),SIZE(PSNOWGRAN1,2)) :: gdendritic
1702 !
1703 INTEGER :: ji, jl
1704 INTEGER :: inlvls, ini
1705 !
1706 REAL(KIND=JPRB) :: zhook_handle
1707 !
1708 ! 0.3 initialization
1709 !
1710 IF (lhook) CALL dr_hook('MODE_SNOW3L:SNOW3LAVGRAIN',0,zhook_handle)
1711 !
1712 inlvls = SIZE(psnowgran1,2)
1713 ini = SIZE(psnowgran1,1)
1714 !
1715 zgran1(:) = 0.0
1716 zgran2(:) = 0.0
1717 zhist(:) = 0.0
1718 !
1719 DO ji = 1,ini
1720  !
1721  IF ( pndent(ji)==0.0 .AND. pnvieu(ji)==0.0 ) THEN
1722  !
1723  zgran1(ji) = 1.0
1724  zgran2(ji) = 1.0
1725  zhist(ji) = 1.0
1726  !
1727  ELSE
1728  !
1729  DO jl = 1,inlvls
1730  IF ( hsnowmetamo=='B92' ) THEN
1731  gdendritic(ji,jl) = ( psnowgran1(ji,jl) < 0.0 )
1732  ELSE
1733  gdendritic(ji,jl) = ( psnowgran1(ji,jl) < xvdiam6*(4.-psnowgran2(ji,jl)) - xuepsi )
1734  ENDIF
1735  ENDDO
1736  !
1737  IF ( pndent(ji)>=pnvieu(ji) ) THEN ! more dendritic than non dendritic snow layer
1738  !
1739  DO jl = 1,inlvls
1740  IF ( gdendritic(ji,jl) ) THEN
1741  zgran1(ji) = zgran1(ji) + psnowgran1(ji,jl)
1742  zgran2(ji) = zgran2(ji) + psnowgran2(ji,jl)
1743  ENDIF
1744  ENDDO
1745  !
1746  psnowgran1n(ji,:) = zgran1(ji) / pndent(ji)
1747  psnowgran2n(ji,:) = zgran2(ji) / pndent(ji)
1748  psnowhistn(ji,:) = 0.0
1749  !
1750  ELSE ! more non dendritic than dendritic snow layers
1751  !
1752  DO jl = 1,inlvls
1753  IF ( .NOT.gdendritic(ji,jl) ) THEN
1754  zgran1(ji) = zgran1(ji) + psnowgran1(ji,jl)
1755  zgran2(ji) = zgran2(ji) + psnowgran2(ji,jl)
1756  zhist(ji) = zhist(ji) + psnowhist(ji,jl)
1757  ENDIF
1758  ENDDO
1759  !
1760  psnowgran1n(ji,:) = zgran1(ji) / pnvieu(ji)
1761  psnowgran2n(ji,:) = zgran2(ji) / pnvieu(ji)
1762  psnowhistn(ji,:) = zhist(ji) / pnvieu(ji)
1763  !
1764  ENDIF
1765  !
1766  ENDIF
1767  !
1768 ENDDO
1769 
1770 
1771 
1772 !
1773 IF (lhook) CALL dr_hook('MODE_SNOW3L:SNOW3LAVGRAIN',1,zhook_handle)
1774 !
1775 END SUBROUTINE snow3lavgrain
1776 !
1777 !####################################################################
1778 !####################################################################
1779 !####################################################################
1780 FUNCTION snow3ldiftyp(PGRAIN1,PGRAIN2,PGRAIN3,PGRAIN4,HSNOWMETAMO) RESULT(ZDIFTYPE)
1781 !
1782 ! à remplacer sans doute par une routine equivalente du nouveau crocus
1783 !* CALCUL DE LA DIFFERENCE ENTRE DEUX TYPES DE GRAINS
1784 ! VALEUR ENTRE 200 ET 0
1785 !
1786 USE modd_snow_metamo, ONLY : xgran, xvdiam6, xuepsi
1787 !
1788 USE yomhook ,ONLY : lhook, dr_hook
1789 USE parkind1 ,ONLY : jprb
1790 !
1791 IMPLICIT NONE
1792 !* 0.1 declarations of arguments
1793 REAL, INTENT(IN) :: pgrain1, pgrain2, pgrain3, pgrain4
1794  CHARACTER(3), INTENT(IN) :: hsnowmetamo
1795 REAL :: zdiftype, zcoef3, zcoef4
1796 REAL(KIND=JPRB) :: zhook_handle
1797 
1798 !* 0.2 calcul de la difference entre type de grains
1799 IF (lhook) CALL dr_hook('MODE_SNOW3L:SNOW3LDIFTYP',0,zhook_handle)
1800 !
1801 IF ( hsnowmetamo=='B92' ) THEN
1802  !
1803  IF ( ( pgrain1<0. .AND. pgrain2>=0.) .OR. ( pgrain1>=0. .AND. pgrain2<0. ) ) THEN
1804  zdiftype = 200.
1805  ELSEIF ( pgrain1<0. ) THEN
1806  zdiftype = abs( pgrain1-pgrain2 ) * .5 + abs( pgrain3-pgrain4 ) * .5
1807  ELSE
1808  zdiftype = abs( pgrain1-pgrain2 ) + abs( pgrain3-pgrain4 ) * 5. * 10000.
1809  ENDIF
1810  !
1811 ELSE
1812  !
1813  zcoef3 = xvdiam6 * (4.-pgrain3) - xuepsi
1814  zcoef4 = xvdiam6 * (4.-pgrain4) - xuepsi
1815  IF ( ( pgrain1<zcoef3 .AND. pgrain2>=zcoef4 ) .OR. ( pgrain1>=zcoef3 .AND. pgrain2<zcoef4 ) ) THEN
1816  zdiftype = 200.
1817  ELSEIF ( pgrain1<zcoef3 ) THEN
1818  zdiftype = abs( (pgrain3-pgrain4)*xgran ) * .5 + &
1819  abs( ( (pgrain1/xvdiam6 - 4. + pgrain3) / (pgrain3 - 3.) - &
1820  (pgrain2/xvdiam6 - 4. + pgrain4) / (pgrain4 - 3.) ) * xgran ) * .5
1821 
1822  ELSE
1823  zdiftype = abs( (pgrain3-pgrain4)*xgran ) + abs( zcoef3-zcoef4 ) * 5. * 10000.
1824  ENDIF
1825  !
1826 ENDIF
1827 !
1828 IF (lhook) CALL dr_hook('MODE_SNOW3L:SNOW3LDIFTYP',1,zhook_handle)
1829 !
1830 END FUNCTION snow3ldiftyp
1831 
1832 !####################################################################
1833 SUBROUTINE get_mass_heat(KJ,KNLVLS_NEW,KNLVLS_OLD, &
1834  psnowztop_old,psnowztop_new,psnowzbot_old,psnowzbot_new, &
1835  psnowrhoo,psnowdzo,psnowgran1o,psnowgran2o,psnowhisto, &
1836  psnowageo,psnowheato, &
1837  psnowrhon,psnowdzn,psnowgran1n,psnowgran2n,psnowhistn, &
1838  psnowagen, psnowheatn,hsnowmetamo )
1839 !
1840 USE modd_snow_par, ONLY : xsnowcritd, xd1, xd2, xd3, xx, xvalb5, xvalb6
1841 !
1842 USE yomhook ,ONLY : lhook, dr_hook
1843 USE parkind1 ,ONLY : jprb
1844 !
1845 IMPLICIT NONE
1846 !
1847 INTEGER, INTENt(IN) :: kj
1848 INTEGER, INTENT(IN) :: knlvls_new, knlvls_old
1849 REAL, DIMENSION(:), INTENT(IN) :: psnowztop_old, psnowzbot_old
1850 REAL, DIMENSION(:), INTENT(IN) :: psnowztop_new, psnowzbot_new
1851 REAL, DIMENSION(:), INTENT(IN) :: psnowrhoo, psnowdzo, psnowgran1o, psnowgran2o, &
1852  psnowhisto, psnowageo, psnowheato
1853 REAL, DIMENSION(:), INTENT(IN) :: psnowdzn
1854  CHARACTER(3), INTENT(IN) :: hsnowmetamo
1855 REAL, DIMENSION(:), INTENT(OUT) :: psnowrhon, psnowgran1n, psnowgran2n, &
1856  psnowhistn, psnowagen, psnowheatn
1857 !
1858 REAL :: zpropor, zmasdz_old, zdiam, zmastot_t07
1859 REAL :: zsnowhean, zmastotn, zdentmoyn, zsphermoyn, zalbmoyn, zhistmoyn
1860 REAL :: zagemoyn
1861 !
1862 INTEGER :: jst_new, jst_old
1863 !
1864 REAL(KIND=JPRB) :: zhook_handle
1865 !
1866 IF (lhook) CALL dr_hook('GET_MASS_HEAT',0,zhook_handle)
1867 !
1868 psnowrhon(:) = 0.
1869 psnowgran1n(:) = 0.
1870 psnowgran2n(:) = 0.
1871 psnowhistn(:) = 0.
1872 psnowagen(:) = 0.
1873 psnowheatn(:) = 0.
1874 !
1875 DO jst_new = 1,knlvls_new
1876  !
1877  zsnowhean = 0.
1878  zmastotn = 0.
1879  zmastot_t07 = 0.
1880  zdentmoyn = 0.
1881  zsphermoyn = 0.
1882  zalbmoyn = 0.
1883  zdiam = 0.
1884  zhistmoyn = 0.
1885  zagemoyn = 0.
1886  !
1887  ! lopp over the ols snow layers
1888  DO jst_old = 1,knlvls_old
1889  !
1890  IF( psnowztop_old(jst_old)<=psnowzbot_new(jst_new) ) THEN
1891  ! JST_OLD lower than JJ_NEW ==> no contribution
1892  ELSEIF ( psnowzbot_old(jst_old)>=psnowztop_new(jst_new) ) THEN
1893  ! JST_OLD higher than JJ_NEW ==> no contribution
1894  ELSE
1895  ! old layer contributes to the new one
1896  ! computation of its contributing ratio and mass/heat
1897  zpropor = ( min( psnowztop_old(jst_old), psnowztop_new(jst_new) ) &
1898  - max( psnowzbot_old(jst_old), psnowzbot_new(jst_new) ) ) &
1899  / psnowdzo(jst_old)
1900  zmasdz_old = zpropor * psnowrhoo(jst_old) * psnowdzo(jst_old)
1901  !
1902  zmastotn = zmastotn + zmasdz_old
1903  zmastot_t07 = zmastot_t07 + 1.
1904  !
1905  zsnowhean = zsnowhean + zpropor * psnowheato(jst_old)
1906  !
1907  IF ( hsnowmetamo=='B92' ) THEN
1908  !
1909  ! contribution to the grain optical size and then to the albedo
1910  IF ( psnowgran1o(jst_old)<0. ) THEN
1911  zdiam = -psnowgran1o(jst_old)*xd1/xx + (1.+psnowgran1o(jst_old)/xx) * &
1912  ( psnowgran2o(jst_old)*xd2/xx + (1.-psnowgran2o(jst_old)/xx)*xd3 )
1913  zdiam = zdiam/10000.
1914  zdentmoyn = zdentmoyn - zmasdz_old * psnowgran1o(jst_old) / xx
1915  zsphermoyn = zsphermoyn + zmasdz_old * psnowgran2o(jst_old) / xx
1916  ELSE
1917  zdiam = psnowgran2o(jst_old)
1918  zdentmoyn = zdentmoyn + zmasdz_old * 0.
1919  zsphermoyn = zsphermoyn + zmasdz_old * psnowgran1o(jst_old) / xx
1920  ENDIF
1921  !
1922  ELSE
1923  !
1924  zdiam = psnowgran1o(jst_old)
1925  zsphermoyn = zsphermoyn + zmasdz_old * psnowgran2o(jst_old)
1926  !
1927  ENDIF
1928  !
1929  zalbmoyn = zalbmoyn + max( 0., zmasdz_old * (xvalb5-xvalb6*sqrt(zdiam)) )
1930  zhistmoyn = zhistmoyn + zmasdz_old * psnowhisto(jst_old)
1931  zagemoyn = zagemoyn + zmasdz_old * psnowageo(jst_old)
1932  !
1933  ENDIF
1934  !
1935  ENDDO
1936  !
1937  ! the new layer inherits from the weihted average properties of the old ones
1938  ! heat and mass
1939  psnowheatn(jst_new) = zsnowhean
1940  psnowrhon(jst_new) = zmastotn / psnowdzn(jst_new)
1941  ! grain type and size decuced from the average albedo
1942  zalbmoyn = zalbmoyn / zmastotn
1943  zsphermoyn = max( 0., zsphermoyn/zmastotn )
1944  zdentmoyn = max( 0., zdentmoyn /zmastotn )
1945  zdiam = ( (xvalb5-zalbmoyn)/xvalb6 )**2
1946  !
1947  IF ( hsnowmetamo=='B92' ) THEN
1948  !
1949  ! size between D2 and D3 and dendricity < 0
1950  ! sphericity is firts preserved, if possible. If not,
1951  ! denditricity =0
1952  psnowgran1n(jst_new) = -xx * zdentmoyn
1953  !
1954  IF ( zdentmoyn/=1.) THEN
1955  psnowgran2n(jst_new) = xx * ( ( zdiam*10000. + psnowgran1n(jst_new)*xd1/xx ) &
1956  / ( 1. + psnowgran1n(jst_new)/xx ) - xd3 ) &
1957  / ( xd2-xd3 )
1958  ENDIF
1959  !
1960  ! dendricity is preserved if possible and sphericity is adjusted
1961  IF ( zdiam < xd2/10000. - 0.0000001 ) THEN
1962  !
1963  IF ( abs( psnowgran1n(jst_new)+xx ) < 0.01 ) THEN
1964  !
1965  psnowgran2n(jst_new) = xx * zsphermoyn
1966  !
1967  ELSEIF ( abs( psnowgran1n(jst_new) ) < 0.0001 ) THEN ! dendritic snow
1968  !
1969  psnowgran1n(jst_new) = xx * zsphermoyn
1970  psnowgran2n(jst_new) = zdiam
1971  !
1972  ELSEIF ( psnowgran2n(jst_new) < 0. ) THEN ! non dendritic
1973  !
1974  psnowgran2n(jst_new) = 0.
1975  !
1976  ELSEIF ( psnowgran2n(jst_new) > xx + 0.0000001 ) THEN ! non dendritic
1977  !
1978  psnowgran2n(jst_new) = xx
1979  !
1980  ENDIF
1981  !
1982  ELSEIF ( zdiam > xd3/10000. .OR. zdentmoyn <= 0. + 0.0000001 .OR. &
1983  psnowgran2n(jst_new) < 0. .OR. psnowgran2n(jst_new) > xx ) THEN
1984  !
1985  ! dendritic snow
1986  ! inconsistency with ZDIAM ==> dendricity = 0
1987  ! size between D2 and D3 and dendricity == 0
1988  psnowgran1n(jst_new) = xx * zsphermoyn
1989  psnowgran2n(jst_new) = zdiam
1990  !
1991  ENDIF
1992  !
1993  ELSE
1994  !
1995  psnowgran1n(jst_new) = zdiam
1996  psnowgran2n(jst_new) = min( 1., zsphermoyn )
1997  !
1998  ENDIF
1999  !
2000  psnowhistn(jst_new) = nint( zhistmoyn/zmastotn )
2001  psnowagen(jst_new) = zagemoyn / zmastotn
2002  !
2003 ENDDO
2004 !
2005 IF (lhook) CALL dr_hook('GET_MASS_HEAT',1,zhook_handle)
2006 !
2007 END SUBROUTINE get_mass_heat
2008 !####################################################################
2009 SUBROUTINE get_diam(PSNOWGRAN1,PSNOWGRAN2,PDIAM,HSNOWMETAMO)
2010 !
2011 USE modd_snow_par, ONLY : xd1, xd2, xd3, xx
2012 !
2013 USE yomhook ,ONLY : lhook, dr_hook
2014 USE parkind1 ,ONLY : jprb
2015 !
2016 IMPLICIT NONE
2017 !
2018 REAL, INTENT(IN) :: psnowgran1
2019 REAL, INTENT(IN) :: psnowgran2
2020 REAL, INTENT(OUT) :: pdiam
2021 !
2022  CHARACTER(3), INTENT(IN) :: hsnowmetamo
2023 !
2024 REAL(KIND=JPRB) :: zhook_handle
2025 !
2026 IF (lhook) CALL dr_hook('GET_DIAM',0,zhook_handle)
2027 !
2028 IF ( hsnowmetamo=='B92' ) THEN
2029  !
2030  IF( psnowgran1<0. ) THEN
2031  pdiam = -psnowgran1*xd1/xx + (1.+psnowgran1/xx) * &
2032  ( psnowgran2*xd2/xx + (1.-psnowgran2/xx) * xd3 )
2033  pdiam = pdiam/10000.
2034  ELSE
2035  pdiam = psnowgran2*psnowgran1/xx + &
2036  max( 0.0004, 0.5*psnowgran2 ) * ( 1.-psnowgran1/xx )
2037  ENDIF
2038  !
2039 ELSE
2040  !
2041  pdiam = psnowgran1
2042  !
2043 ENDIF
2044 !
2045 IF (lhook) CALL dr_hook('GET_DIAM',1,zhook_handle)
2046 !
2047 END SUBROUTINE get_diam
2048 !####################################################################
2049 !####################################################################
2050 !####################################################################
2051 FUNCTION snow3lradabs_0d(PSNOWRHO,PSNOWDZ,PSPECTRALALBEDO,PZENITH,PPERMSNOWFRAC,PDSGRAIN) RESULT(PCOEF)
2052 !
2053 !! PURPOSE
2054 !! -------
2055 ! Calculate the transmission of shortwave radiation within the snowpack
2056 ! (with depth)
2057 ! A. Boone 02/2011
2058 ! A. Boone 11/2014 Updated to use spectral dependence.
2059 ! NOTE, assumes 3 spectral bands
2060 !
2061 USE modd_surf_par, ONLY : xundef
2062 USE modd_meb_par, ONLY : xsw_wght_vis, xsw_wght_nir
2063 USE modd_snow_par, ONLY : xvspec1,xvspec2,xvspec3,xvbeta1,xvbeta2, &
2064  xvbeta4,xvbeta3,xvbeta5, xmincoszen
2065 !
2066 USE yomhook ,ONLY : lhook, dr_hook
2067 USE parkind1 ,ONLY : jprb
2068 !
2069 IMPLICIT NONE
2070 !
2071 !* 0.1 declarations of arguments
2072 !
2073 REAL, INTENT(IN) :: psnowrho ! snow density (kg m-3)
2074 REAL, INTENT(IN) :: psnowdz ! layer thickness (m)
2075 REAL, INTENT(IN) :: pzenith ! zenith angle (rad)
2076 REAL, INTENT(IN) :: ppermsnowfrac ! permanent snow fraction (-)
2077 REAL, DIMENSION(:), INTENT(IN) :: pspectralalbedo ! spectral albedo (-)
2078 REAL, INTENT(IN) :: pdsgrain ! Snow optical grain diameter (m)
2079 !
2080 REAL :: pcoef ! -
2081 !
2082 !* 0.2 declarations of local variables
2083 !
2084 REAL :: zwork, zprojlat, &
2085  zbeta1, zbeta2, zbeta3, &
2086  zopticalpath1, zopticalpath2, &
2087  zopticalpath3
2088 !
2089 REAL(KIND=JPRB) :: zhook_handle
2090 !
2091 !-------------------------------------------------------------------------------
2092 IF (lhook) CALL dr_hook('MODE_SNOW3L:SNOW3LRADABS_0D',0,zhook_handle)
2093 !
2094 ! Coefficient for taking into account the increase of path length of rays
2095 ! in snow due to zenithal angle
2096 !
2097 zprojlat = (1.0-ppermsnowfrac)+ppermsnowfrac/ &
2098  max(xmincoszen,cos(pzenith))
2099 !
2100 ! Extinction coefficient:
2101 !
2102 zwork = sqrt(pdsgrain)
2103 zbeta1 = max(xvbeta1*psnowrho/zwork,xvbeta2)
2104 zbeta2 = max(xvbeta3*psnowrho/zwork,xvbeta4)
2105 zbeta3 = xvbeta5
2106 !
2107 zopticalpath1 = zbeta1*psnowdz
2108 zopticalpath2 = zbeta2*psnowdz
2109 zopticalpath3 = xundef
2110 !
2111 IF(pspectralalbedo(3)==xundef)THEN
2112  pcoef = xsw_wght_vis*(1.0-pspectralalbedo(1))*exp(-zopticalpath1*zprojlat) &
2113  + xsw_wght_nir*(1.0-pspectralalbedo(2))*exp(-zopticalpath2*zprojlat)
2114 ELSE
2115  zopticalpath3 = zbeta3*psnowdz
2116  pcoef = xvspec1*(1.0-pspectralalbedo(1))*exp(-zopticalpath1*zprojlat) &
2117  + xvspec2*(1.0-pspectralalbedo(2))*exp(-zopticalpath2*zprojlat) &
2118  + xvspec3*(1.0-pspectralalbedo(3))*exp(-zopticalpath3*zprojlat)
2119 ENDIF
2120 !
2121 IF (lhook) CALL dr_hook('MODE_SNOW3L:SNOW3LRADABS_0D',1,zhook_handle)
2122 !-------------------------------------------------------------------------------
2123 !
2124 END FUNCTION snow3lradabs_0d
2125 !####################################################################
2126 !####################################################################
2127 !####################################################################
2128 FUNCTION snow3lradabs_1d(PSNOWRHO,PSNOWDZ,PSPECTRALALBEDO,PZENITH,PPERMSNOWFRAC,PDSGRAIN) RESULT(PCOEF)
2129 !
2130 !! PURPOSE
2131 !! -------
2132 ! Calculate the transmission of shortwave radiation within the snowpack
2133 ! (with depth)
2134 ! A. Boone 02/2011
2135 ! A. Boone 11/2014 Updated to use spectral dependence
2136 ! NOTE, assumes 3 spectral bands
2137 !
2138 USE modd_surf_par, ONLY : xundef
2139 USE modd_meb_par, ONLY : xsw_wght_vis, xsw_wght_nir
2140 USE modd_snow_par, ONLY : xvspec1,xvspec2,xvspec3,xvbeta1,xvbeta2, &
2141  xvbeta4,xvbeta3,xvbeta5, xmincoszen
2142 !
2143 USE yomhook ,ONLY : lhook, dr_hook
2144 USE parkind1 ,ONLY : jprb
2145 !
2146 IMPLICIT NONE
2147 !
2148 !* 0.1 declarations of arguments
2149 !
2150 REAL, DIMENSION(:), INTENT(IN) :: psnowrho ! snow density (kg m-3)
2151 REAL, DIMENSION(:), INTENT(IN) :: psnowdz ! layer thickness (m)
2152 REAL, DIMENSION(:), INTENT(IN) :: pzenith ! zenith angle (rad)
2153 REAL, DIMENSION(:), INTENT(IN) :: ppermsnowfrac ! permanent snow fraction (-)
2154 REAL, DIMENSION(:,:), INTENT(IN) :: pspectralalbedo ! spectral albedo (-)
2155 REAL, DIMENSION(:), INTENT(IN) :: pdsgrain ! Snow optical grain diameter (m)
2156 !
2157 REAL, DIMENSION(SIZE(PSNOWRHO)) :: pcoef ! -
2158 !
2159 !* 0.2 declarations of local variables
2160 !
2161 REAL, DIMENSION(SIZE(PSNOWRHO)) :: zwork, zprojlat, &
2162  zbeta1, zbeta2, zbeta3, &
2163  zopticalpath1, zopticalpath2, &
2164  zopticalpath3
2165 !
2166 REAL(KIND=JPRB) :: zhook_handle
2167 !
2168 !-------------------------------------------------------------------------------
2169 IF (lhook) CALL dr_hook('MODE_SNOW3L:SNOW3LRADABS_1D',0,zhook_handle)
2170 !
2171 ! Coefficient for taking into account the increase of path length of rays
2172 ! in snow due to zenithal angle
2173 !
2174 zprojlat(:) = (1.0-ppermsnowfrac(:))+ppermsnowfrac(:)/ &
2175  max(xmincoszen,cos(pzenith(:)))
2176 !
2177 ! Extinction coefficient:
2178 !
2179 zwork(:) = sqrt(pdsgrain(:))
2180 zbeta1(:) = max(xvbeta1*psnowrho(:)/zwork(:),xvbeta2)
2181 zbeta2(:) = max(xvbeta3*psnowrho(:)/zwork(:),xvbeta4)
2182 zbeta3(:) = xvbeta5
2183 !
2184 zopticalpath1(:) = zbeta1(:)*psnowdz(:)
2185 zopticalpath2(:) = zbeta2(:)*psnowdz(:)
2186 zopticalpath3(:) = xundef
2187 !
2188 WHERE(pspectralalbedo(:,3)==xundef)
2189  pcoef(:) = xsw_wght_vis*(1.0-pspectralalbedo(:,1))*exp(-zopticalpath1(:)*zprojlat(:)) &
2190  + xsw_wght_nir*(1.0-pspectralalbedo(:,2))*exp(-zopticalpath2(:)*zprojlat(:))
2191 ELSEWHERE
2192  zopticalpath3(:) = zbeta3(:)*psnowdz(:)
2193  pcoef(:) = xvspec1*(1.0-pspectralalbedo(:,1))*exp(-zopticalpath1(:)*zprojlat(:)) &
2194  + xvspec2*(1.0-pspectralalbedo(:,2))*exp(-zopticalpath2(:)*zprojlat(:)) &
2195  + xvspec3*(1.0-pspectralalbedo(:,3))*exp(-zopticalpath3(:)*zprojlat(:))
2196 END WHERE
2197 !
2198 IF (lhook) CALL dr_hook('MODE_SNOW3L:SNOW3LRADABS_1D',1,zhook_handle)
2199 !-------------------------------------------------------------------------------
2200 !
2201 END FUNCTION snow3lradabs_1d
2202 !####################################################################
2203 !####################################################################
2204 !####################################################################
2205 FUNCTION snow3lradabs_2d(PSNOWRHO,PSNOWDZ,PSPECTRALALBEDO,PZENITH,PPERMSNOWFRAC,PDSGRAIN) RESULT(PCOEF)
2206 !
2207 !! PURPOSE
2208 !! -------
2209 ! Calculate the transmission of shortwave radiation within the snowpack
2210 ! (with depth)
2211 ! A. Boone 02/2011
2212 ! A. Boone 11/2014 Updated to use spectral dependence
2213 ! NOTE, assumes 3 spectral bands
2214 !
2215 USE modd_surf_par, ONLY : xundef
2216 USE modd_meb_par, ONLY : xsw_wght_vis, xsw_wght_nir
2217 USE modd_snow_par, ONLY : xvspec1,xvspec2,xvspec3,xvbeta1,xvbeta2, &
2218  xvbeta4,xvbeta3,xvbeta5, xmincoszen
2219 !
2220 USE yomhook ,ONLY : lhook, dr_hook
2221 USE parkind1 ,ONLY : jprb
2222 !
2223 IMPLICIT NONE
2224 !
2225 !* 0.1 declarations of arguments
2226 !
2227 REAL, DIMENSION(:,:), INTENT(IN) :: psnowrho ! snow density (kg m-3)
2228 REAL, DIMENSION(:,:), INTENT(IN) :: psnowdz ! layer thickness (m)
2229 REAL, DIMENSION(:,:), INTENT(IN) :: pzenith ! zenith angle (rad)
2230 REAL, DIMENSION(:,:), INTENT(IN) :: ppermsnowfrac ! permanent snow fraction (-)
2231 REAL, DIMENSION(:,:,:), INTENT(IN) :: pspectralalbedo ! spectral albedo (-)
2232 REAL, DIMENSION(:,:), INTENT(IN) :: pdsgrain ! Snow optical grain diameter (m)
2233 !
2234 REAL, DIMENSION(SIZE(PSNOWRHO,1),SIZE(PSNOWRHO,2)) :: pcoef ! -
2235 !
2236 !* 0.2 declarations of local variables
2237 !
2238 REAL, DIMENSION(SIZE(PSNOWRHO,1),SIZE(PSNOWRHO,2)) :: zwork, zprojlat, &
2239  zbeta1, zbeta2, zbeta3, &
2240  zopticalpath1, zopticalpath2, &
2241  zopticalpath3
2242 !
2243 REAL(KIND=JPRB) :: zhook_handle
2244 !
2245 !-------------------------------------------------------------------------------
2246 IF (lhook) CALL dr_hook('MODE_SNOW3L:SNOW3LRADABS_2D',0,zhook_handle)
2247 !
2248 ! Coefficient for taking into account the increase of path length of rays
2249 ! in snow due to zenithal angle
2250 !
2251 zprojlat(:,:) = (1.0-ppermsnowfrac(:,:))+ppermsnowfrac(:,:)/ &
2252  max(xmincoszen,cos(pzenith(:,:)))
2253 !
2254 ! Extinction coefficient:
2255 !
2256 zwork(:,:) = sqrt(pdsgrain(:,:))
2257 zbeta1(:,:) = max(xvbeta1*psnowrho(:,:)/zwork(:,:),xvbeta2)
2258 zbeta2(:,:) = max(xvbeta3*psnowrho(:,:)/zwork(:,:),xvbeta4)
2259 zbeta3(:,:) = xvbeta5
2260 !
2261 zopticalpath1(:,:) = zbeta1(:,:)*psnowdz(:,:)
2262 zopticalpath2(:,:) = zbeta2(:,:)*psnowdz(:,:)
2263 zopticalpath3(:,:) = xundef
2264 !
2265 WHERE(pspectralalbedo(:,:,3)==xundef)
2266  pcoef(:,:) = xsw_wght_vis*(1.0-pspectralalbedo(:,:,1))*exp(-zopticalpath1(:,:)*zprojlat(:,:)) &
2267  + xsw_wght_nir*(1.0-pspectralalbedo(:,:,2))*exp(-zopticalpath2(:,:)*zprojlat(:,:))
2268 ELSEWHERE
2269  zopticalpath3(:,:) = zbeta3(:,:)*psnowdz(:,:)
2270  pcoef(:,:) = xvspec1*(1.0-pspectralalbedo(:,:,1))*exp(-zopticalpath1(:,:)*zprojlat(:,:)) &
2271  + xvspec2*(1.0-pspectralalbedo(:,:,2))*exp(-zopticalpath2(:,:)*zprojlat(:,:)) &
2272  + xvspec3*(1.0-pspectralalbedo(:,:,3))*exp(-zopticalpath3(:,:)*zprojlat(:,:))
2273 END WHERE
2274 !
2275 IF (lhook) CALL dr_hook('MODE_SNOW3L:SNOW3LRADABS_2D',1,zhook_handle)
2276 !-------------------------------------------------------------------------------
2277 !
2278 END FUNCTION snow3lradabs_2d
2279 !####################################################################
2280 !####################################################################
2281 !####################################################################
2282  SUBROUTINE snow3lthrm(PSNOWRHO,PSCOND,PSNOWTEMP,PPS)
2283 !
2284 !! PURPOSE
2285 !! -------
2286 ! Calculate snow thermal conductivity from
2287 ! Sun et al. 1999, J. of Geophys. Res., 104, 19587-19579 (vapor)
2288 ! and Yen, 1981, CRREL Rep 81-10 (snow)
2289 ! or Anderson, 1976, NOAA Tech. Rep. NWS 19 (snow).
2290 !
2291 !
2292 USE modd_csts, ONLY : xp00, xcondi, xrholw
2293 !
2294 USE modd_snow_par, ONLY : xvrkz6, xsnowthrmcond1, &
2295  xsnowthrmcond2, &
2296  xsnowthrmcond_avap, &
2297  xsnowthrmcond_bvap, &
2298  xsnowthrmcond_cvap
2299 !
2300 USE yomhook ,ONLY : lhook, dr_hook
2301 USE parkind1 ,ONLY : jprb
2302 !
2303 IMPLICIT NONE
2304 !
2305 !* 0.1 declarations of arguments
2306 !
2307 REAL, DIMENSION(:), INTENT(IN) :: pps
2308 !
2309 REAL, DIMENSION(:,:), INTENT(IN) :: psnowtemp, psnowrho
2310 !
2311 REAL, DIMENSION(:,:), INTENT(OUT) :: pscond
2312 !
2313 !
2314 !* 0.2 declarations of local variables
2315 !
2316 INTEGER :: jj, ji
2317 !
2318 INTEGER :: ini
2319 INTEGER :: inlvls
2320 !
2321  CHARACTER(LEN=5) :: ysnowcond !should be in namelist
2322 !
2323 REAL(KIND=JPRB) :: zhook_handle
2324 !-------------------------------------------------------------------------------
2325 !
2326 IF (lhook) CALL dr_hook('MODE_SNOW3L:SNOW3LTHRM',0,zhook_handle)
2327 !
2328 ini = SIZE(psnowrho(:,:),1)
2329 inlvls = SIZE(psnowrho(:,:),2)
2330 !
2331 ! 1. Snow thermal conductivity
2332 ! ----------------------------
2333 !
2334 ysnowcond='YEN81' !should be in namelist
2335 !
2336 IF(ysnowcond=='AND76')THEN
2337 ! Thermal conductivity coefficients from Anderson (1976)
2338  pscond(:,:) = (xsnowthrmcond1 + xsnowthrmcond2*psnowrho(:,:)*psnowrho(:,:))
2339 ELSE
2340 ! Thermal conductivity coefficients from Yen (1981)
2341  pscond(:,:) = xcondi * exp(xvrkz6*log(psnowrho(:,:)/xrholw))
2342 ENDIF
2343 !
2344 ! 2. Implicit vapor diffn effects
2345 ! -------------------------------
2346 !
2347 DO jj=1,inlvls
2348  DO ji=1,ini
2349  pscond(ji,jj) = pscond(ji,jj) + max(0.0,(xsnowthrmcond_avap+(xsnowthrmcond_bvap/(psnowtemp(ji,jj) &
2350  + xsnowthrmcond_cvap)))*(xp00/pps(ji)))
2351  ENDDO
2352 ENDDO
2353 !
2354 IF (lhook) CALL dr_hook('MODE_SNOW3L:SNOW3LTHRM',1,zhook_handle)
2355 !
2356 !-------------------------------------------------------------------------------
2357 !
2358 END SUBROUTINE snow3lthrm
2359 !####################################################################
2360 !####################################################################
2361 !####################################################################
2362 FUNCTION snow3ldopt_2d(PSNOWRHO,PSNOWAGE) RESULT(PDOPT)
2363 !
2364 !! PURPOSE
2365 !! -------
2366 ! Calculate the optical grain diameter.
2367 !
2368 USE modd_snow_par, ONLY : xdsgrain_max,xsnow_agrain, &
2369  xsnow_bgrain,xsnow_cgrain
2370 !
2371 USE yomhook ,ONLY : lhook, dr_hook
2372 USE parkind1 ,ONLY : jprb
2373 !
2374 IMPLICIT NONE
2375 !
2376 !* 0.1 declarations of arguments
2377 !
2378 REAL, DIMENSION(:,:), INTENT(IN) :: psnowrho,psnowage
2379 !
2380 REAL, DIMENSION(SIZE(PSNOWRHO,1),SIZE(PSNOWRHO,2)) :: pdopt
2381 REAL, DIMENSION(SIZE(PSNOWRHO,1),SIZE(PSNOWRHO,2)) :: zage
2382 REAL, DIMENSION(SIZE(PSNOWRHO,1),SIZE(PSNOWRHO,2)) :: zsrho4
2383 !
2384 REAL(KIND=JPRB) :: zhook_handle
2385 !-------------------------------------------------------------------------------
2386 !
2387 IF (lhook) CALL dr_hook('MODE_SNOW3L:SNOW3LDOPT_2D',0,zhook_handle)
2388 !
2389 zage(:,:) = min(15.,psnowage(:,:))
2390 !
2391 zsrho4(:,:) = psnowrho(:,:)*psnowrho(:,:)*psnowrho(:,:)*psnowrho(:,:)
2392 !
2393 pdopt(:,:) = min(xdsgrain_max,xsnow_agrain+xsnow_bgrain*zsrho4(:,:)+xsnow_cgrain*zage(:,:))
2394 !
2395 IF (lhook) CALL dr_hook('MODE_SNOW3L:SNOW3LDOPT_2D',1,zhook_handle)
2396 !
2397 END FUNCTION snow3ldopt_2d
2398 !####################################################################
2399 FUNCTION snow3ldopt_1d(PSNOWRHO,PSNOWAGE) RESULT(PDOPT)
2400 !
2401 !! PURPOSE
2402 !! -------
2403 ! Calculate the optical grain diameter.
2404 !
2405 USE modd_snow_par, ONLY : xdsgrain_max,xsnow_agrain, &
2406  xsnow_bgrain,xsnow_cgrain
2407 !
2408 USE yomhook ,ONLY : lhook, dr_hook
2409 USE parkind1 ,ONLY : jprb
2410 !
2411 IMPLICIT NONE
2412 !
2413 !* 0.1 declarations of arguments
2414 !
2415 REAL, DIMENSION(:), INTENT(IN) :: psnowrho,psnowage
2416 !
2417 REAL, DIMENSION(SIZE(PSNOWRHO)) :: pdopt
2418 REAL, DIMENSION(SIZE(PSNOWRHO)) :: zage
2419 REAL, DIMENSION(SIZE(PSNOWRHO)) :: zsrho4
2420 !
2421 REAL(KIND=JPRB) :: zhook_handle
2422 !-------------------------------------------------------------------------------
2423 !
2424 IF (lhook) CALL dr_hook('MODE_SNOW3L:SNOW3LDOPT_1D',0,zhook_handle)
2425 !
2426 zage(:) = min(15.,psnowage(:))
2427 !
2428 zsrho4(:) = psnowrho(:)*psnowrho(:)*psnowrho(:)*psnowrho(:)
2429 !
2430 pdopt(:) = min(xdsgrain_max,xsnow_agrain+xsnow_bgrain*zsrho4(:)+xsnow_cgrain*zage(:))
2431 !
2432 IF (lhook) CALL dr_hook('MODE_SNOW3L:SNOW3LDOPT_1D',1,zhook_handle)
2433 !
2434 END FUNCTION snow3ldopt_1d
2435 !####################################################################
2436 FUNCTION snow3ldopt_0d(PSNOWRHO,PSNOWAGE) RESULT(PDOPT)
2437 !
2438 !! PURPOSE
2439 !! -------
2440 ! Calculate the optical grain diameter.
2441 !
2442 USE modd_snow_par, ONLY : xdsgrain_max,xsnow_agrain, &
2443  xsnow_bgrain,xsnow_cgrain
2444 !
2445 USE yomhook ,ONLY : lhook, dr_hook
2446 USE parkind1 ,ONLY : jprb
2447 !
2448 IMPLICIT NONE
2449 !
2450 !* 0.1 declarations of arguments
2451 !
2452 REAL, INTENT(IN) :: psnowrho,psnowage
2453 !
2454 REAL :: pdopt
2455 REAL :: zage
2456 REAL :: zsrho4
2457 !
2458 REAL(KIND=JPRB) :: zhook_handle
2459 !-------------------------------------------------------------------------------
2460 !
2461 IF (lhook) CALL dr_hook('MODE_SNOW3L:SNOW3LDOPT_0D',0,zhook_handle)
2462 !
2463 zage = min(15.,psnowage)
2464 !
2465 zsrho4 = psnowrho*psnowrho*psnowrho*psnowrho
2466 !
2467 pdopt = min(xdsgrain_max,xsnow_agrain+xsnow_bgrain*zsrho4+xsnow_cgrain*zage)
2468 !
2469 IF (lhook) CALL dr_hook('MODE_SNOW3L:SNOW3LDOPT_0D',1,zhook_handle)
2470 !
2471 END FUNCTION snow3ldopt_0d
2472 !####################################################################
2473 !####################################################################
2474 !####################################################################
2475 SUBROUTINE snow3lalb(PALBEDOSC,PSPECTRALALBEDO,PSNOWRHO,PSNOWAGE, &
2476  ppermsnowfrac,pps)
2477 !
2478 !! PURPOSE
2479 !! -------
2480 ! Calculate the snow surface albedo. Use the method of
2481 ! CROCUS with 3 spectral albedo depending on snow density
2482 ! and age
2483 !
2484 !
2485 USE modd_snow_par, ONLY : xvaging_glacier, xvaging_noglacier, &
2486  xvalb2,xvalb3,xvalb4,xvalb5,xvalb6, &
2487  xvalb7,xvalb8,xvalb9,xvalb10,xvalb11, &
2488  xvdiop1,xvrpre1,xvrpre2,xvpres1, &
2489  xvw1,xvw2,xvspec1,xvspec2,xvspec3
2490 !
2491 USE yomhook ,ONLY : lhook, dr_hook
2492 USE parkind1 ,ONLY : jprb
2493 !
2494 IMPLICIT NONE
2495 !
2496 !* 0.1 declarations of arguments
2497 !
2498 REAL, DIMENSION(:), INTENT(IN) :: psnowrho
2499 REAL, DIMENSION(:), INTENT(IN) :: psnowage
2500 REAL, DIMENSION(:), INTENT(IN) :: ppermsnowfrac
2501 REAL, DIMENSION(:), INTENT(IN) :: pps
2502 !
2503 REAL, DIMENSION(:), INTENT(INOUT) :: palbedosc
2504 REAL, DIMENSION(:,:), INTENT(INOUT) :: pspectralalbedo
2505 !
2506 !* 0.2 declarations of local variables
2507 !
2508 REAL, PARAMETER :: zalbnir1 = 0.3
2509 REAL, PARAMETER :: zalbnir2 = 0.0
2510 !
2511 REAL, DIMENSION(SIZE(PSNOWRHO)) :: zvaging, zdiam, zage, &
2512  zwork, zpres_effect
2513 !
2514 REAL, DIMENSION(SIZE(PSNOWRHO)) :: zalb1, zalb2, zalb3
2515 !
2516 REAL(KIND=JPRB) :: zhook_handle
2517 !
2518 !-------------------------------------------------------------------------------
2519 !
2520 IF (lhook) CALL dr_hook('MODE_SNOW3L:SNOW3LALB',0,zhook_handle)
2521 !
2522 ! 0. Initialize:
2523 ! ------------------
2524 !
2525 !Snow age effect parameter for Visible (small over glacier)
2526 zvaging(:)=xvaging_glacier*ppermsnowfrac(:) + xvaging_noglacier*(1.0-ppermsnowfrac(:))
2527 !
2528 !Atm pression effect parameter on albedo
2529 zpres_effect(:) = xvalb10*min(max(pps(:)/xvpres1,xvrpre1),xvrpre2)
2530 !
2531 ! 1. Snow optical grain diameter :
2532 ! --------------------------------
2533 !
2534 !Snow optical diameter do not depend on snow age over glacier or polar regions
2535 zage(:) = (1.0-ppermsnowfrac(:))*psnowage(:)
2536 !
2537 zdiam(:) = snow3ldopt(psnowrho(:),zage(:))
2538 !
2539 ! 2. spectral albedo over 3 bands :
2540 ! ---------------------------------
2541 !
2542 !Snow age effect limited to 1 year
2543 zage(:) = min(365.,psnowage(:))
2544 !
2545 zwork(:)=sqrt(zdiam(:))
2546 !
2547 ! Visible
2548 zalb1(:)=min(xvalb4,xvalb2-xvalb3*zwork(:))
2549 zalb1(:)=max(xvalb11,zalb1(:)-zpres_effect(:)*zage(:)/zvaging(:))
2550 !
2551 ! near Infra-red 1
2552 zalb2(:)=xvalb5-xvalb6*zwork(:)
2553 zalb2(:)=max(zalbnir1,zalb2(:))
2554 !
2555 ! near Infra-red 2
2556 zdiam(:)=min(xvdiop1,zdiam(:))
2557 zwork(:)=sqrt(zdiam(:))
2558 zalb3(:)=xvalb7*zdiam(:)-xvalb8*zwork(:)+xvalb9
2559 zalb3(:)=max(zalbnir2,zalb3(:))
2560 !
2561 pspectralalbedo(:,1)=zalb1(:)
2562 pspectralalbedo(:,2)=zalb2(:)
2563 pspectralalbedo(:,3)=zalb3(:)
2564 !
2565 ! 3. total albedo :
2566 ! -----------------
2567 !
2568 palbedosc(:)=xvspec1*zalb1(:)+xvspec2*zalb2(:)+xvspec3*zalb3(:)
2569 !
2570 IF (lhook) CALL dr_hook('MODE_SNOW3L:SNOW3LALB',1,zhook_handle)
2571 !
2572 !-------------------------------------------------------------------------------
2573 !
2574 END SUBROUTINE snow3lalb
2575 !####################################################################
2576 !####################################################################
2577 !####################################################################
2578 END MODULE mode_snow3l
2579 
real function, dimension(size(psnowrho)) snow3lscap_1d(PSNOWRHO)
real function snow3lscap_0d(PSNOWRHO)
real function, dimension(size(psnowrho)) snow3lhold_1d(PSNOWRHO, PSNOWDZ)
real function, dimension(size(psnowrho, 1), size(psnowrho, 2), size(psnowrho, 3)) snowcrohold_3d(PSNOWRHO, PSNOWLIQ, PSNOWDZ)
real function, dimension(size(psnowrho)) snow3lradabs_1d(PSNOWRHO, PSNOWDZ, PSPECTRALALBEDO, PZENITH, PPERMSNOWFRAC, PDSGRAIN)
real function snowcrohold_0d(PSNOWRHO, PSNOWLIQ, PSNOWDZ)
subroutine snow3lgrid_2d(PSNOWDZ, PSNOW, PSNOWDZ_OLD)
real function, dimension(size(psnowrho, 1), size(psnowrho, 2), size(psnowrho, 3)) snow3lhold_3d(PSNOWRHO, PSNOWDZ)
real function, dimension(size(psnowrho, 1), size(psnowrho, 2)) snow3lhold_2d(PSNOWRHO, PSNOWDZ)
subroutine get_agreg(KID1, KID2, PFIELD1, PFIELD2, PFIELD)
real function, dimension(size(psnowrho, 1), size(psnowrho, 2), size(psnowrho, 3)) snow3lwliqmax_3d(PSNOWRHO)
subroutine snow3lgrid_1d(PSNOWDZ, PSNOW, PSNOWDZ_OLD)
real function, dimension(size(psnowrho, 1), size(psnowrho, 2), size(psnowrho, 3)) snow3lscap_3d(PSNOWRHO)
real function, dimension(size(psnowrho)) snow3ldopt_1d(PSNOWRHO, PSNOWAGE)
real function snow3ldopt_0d(PSNOWRHO, PSNOWAGE)
real function, dimension(size(psnowrho, 1), size(psnowrho, 2)) snow3lradabs_2d(PSNOWRHO, PSNOWDZ, PSPECTRALALBEDO, PZENITH, PPERMSNOWFRAC, PDSGRAIN)
real function, dimension(size(psnowrho, 1), size(psnowrho, 2)) snow3lscap_2d(PSNOWRHO)
real function snow3lhold_0d(PSNOWRHO, PSNOWDZ)
real function, dimension(size(psnowrho)) snow3lwliqmax_1d(PSNOWRHO)
real function, dimension(size(psnowrho, 1), size(psnowrho, 2)) snow3ldopt_2d(PSNOWRHO, PSNOWAGE)
real function snow3lradabs_0d(PSNOWRHO, PSNOWDZ, PSPECTRALALBEDO, PZENITH, PPERMSNOWFRAC, PDSGRAIN)
real function, dimension(size(psnowrho, 1), size(psnowrho, 2)) snow3lwliqmax_2d(PSNOWRHO)
real function, dimension(size(psnowrho)) snowcrohold_1d(PSNOWRHO, PSNOWLIQ, PSNOWDZ)
real function, dimension(size(psnowrho, 1), size(psnowrho, 2)) snowcrohold_2d(PSNOWRHO, PSNOWLIQ, PSNOWDZ)