source: LMDZ6/trunk/libf/phylmdiso/surf_landice_mod.F90 @ 3932

Last change on this file since 3932 was 3927, checked in by Laurent Fairhead, 3 years ago

Initial import of the physics wih isotopes from Camille Risi
CR

File size: 18.2 KB
Line 
1!
2MODULE surf_landice_mod
3 
4  IMPLICIT NONE
5
6CONTAINS
7!
8!****************************************************************************************
9!
10  SUBROUTINE surf_landice(itime, dtime, knon, knindex, &
11       rlon, rlat, debut, lafin, &
12       rmu0, lwdownm, albedo, pphi1, &
13       swnet, lwnet, tsurf, p1lay, &
14       cdragh, cdragm, precip_rain, precip_snow, temp_air, spechum, &
15       AcoefH, AcoefQ, BcoefH, BcoefQ, &
16       AcoefU, AcoefV, BcoefU, BcoefV, &
17       ps, u1, v1, gustiness, rugoro, pctsrf, &
18       snow, qsurf, qsol, agesno, &
19       tsoil, z0m, z0h, SFRWL, alb_dir, alb_dif, evap, fluxsens, fluxlat, &
20       tsurf_new, dflux_s, dflux_l, &
21       slope, cloudf, &
22       snowhgt, qsnow, to_ice, sissnow, &
23       alb3, runoff, &
24       flux_u1, flux_v1 &
25#ifdef ISO
26         &      ,xtprecip_rain, xtprecip_snow,xtspechum,Rland_ice &
27         &      ,xtsnow,xtsol,xtevap &
28#endif               
29           &    )
30
31    USE dimphy
32    USE surface_data,     ONLY : type_ocean, calice, calsno, ok_snow
33    USE fonte_neige_mod,  ONLY : fonte_neige, run_off_lic
34    USE cpl_mod,          ONLY : cpl_send_landice_fields
35    USE calcul_fluxs_mod
36    USE phys_output_var_mod
37#ifdef ISO   
38    USE fonte_neige_mod,  ONLY : xtrun_off_lic
39    USE infotrac_phy, ONLY : ntraciso,niso
40    USE isotopes_routines_mod, ONLY: calcul_iso_surf_lic_vectall
41#ifdef ISOVERIF
42    use isotopes_mod, ONLY: iso_eau,ridicule
43    use isotopes_verif_mod
44#endif
45#endif
46!FC
47    USE ioipsl_getin_p_mod, ONLY : getin_p
48
49#ifdef CPP_SISVAT
50    USE surf_sisvat_mod,  ONLY : surf_sisvat
51#endif
52    USE indice_sol_mod
53
54!    INCLUDE "indicesol.h"
55    INCLUDE "dimsoil.h"
56    INCLUDE "YOMCST.h"
57    INCLUDE "clesphys.h"
58
59! Input variables
60!****************************************************************************************
61    INTEGER, INTENT(IN)                           :: itime, knon
62    INTEGER, DIMENSION(klon), INTENT(in)          :: knindex
63    REAL, INTENT(in)                              :: dtime
64    REAL, DIMENSION(klon), INTENT(IN)             :: swnet ! net shortwave radiance
65    REAL, DIMENSION(klon), INTENT(IN)             :: lwnet ! net longwave radiance
66    REAL, DIMENSION(klon), INTENT(IN)             :: tsurf
67    REAL, DIMENSION(klon), INTENT(IN)             :: p1lay
68    REAL, DIMENSION(klon), INTENT(IN)             :: cdragh, cdragm
69    REAL, DIMENSION(klon), INTENT(IN)             :: precip_rain, precip_snow
70    REAL, DIMENSION(klon), INTENT(IN)             :: temp_air, spechum
71    REAL, DIMENSION(klon), INTENT(IN)             :: AcoefH, AcoefQ
72    REAL, DIMENSION(klon), INTENT(IN)             :: BcoefH, BcoefQ
73    REAL, DIMENSION(klon), INTENT(IN)             :: AcoefU, AcoefV, BcoefU, BcoefV
74    REAL, DIMENSION(klon), INTENT(IN)             :: ps
75    REAL, DIMENSION(klon), INTENT(IN)             :: u1, v1, gustiness
76    REAL, DIMENSION(klon), INTENT(IN)             :: rugoro
77    REAL, DIMENSION(klon,nbsrf), INTENT(IN)       :: pctsrf
78#ifdef ISO
79    REAL, DIMENSION(ntraciso,klon), INTENT(IN)        :: xtprecip_rain, xtprecip_snow
80    REAL, DIMENSION(ntraciso,klon), INTENT(IN)        :: xtspechum
81#endif
82
83    LOGICAL,  INTENT(IN)                          :: debut   !true if first step
84    LOGICAL,  INTENT(IN)                          :: lafin   !true if last step
85    REAL, DIMENSION(klon), INTENT(IN)             :: rlon, rlat
86    REAL, DIMENSION(klon), INTENT(IN)             :: rmu0
87    REAL, DIMENSION(klon), INTENT(IN)             :: lwdownm !ylwdown
88    REAL, DIMENSION(klon), INTENT(IN)             :: albedo  !mean albedo
89    REAL, DIMENSION(klon), INTENT(IN)             :: pphi1   
90    REAL, DIMENSION(klon), INTENT(IN)             :: slope   !mean slope in grid box 
91    REAL, DIMENSION(klon), INTENT(IN)             :: cloudf  !total cloud fraction
92
93! In/Output variables
94!****************************************************************************************
95    REAL, DIMENSION(klon), INTENT(INOUT)          :: snow, qsol
96    REAL, DIMENSION(klon), INTENT(INOUT)          :: agesno
97    REAL, DIMENSION(klon, nsoilmx), INTENT(INOUT) :: tsoil
98#ifdef ISO
99    REAL, DIMENSION(niso,klon), INTENT(INOUT)          :: xtsnow, xtsol
100    REAL, DIMENSION(niso,klon), INTENT(INOUT)        :: Rland_ice
101#endif
102
103! Output variables
104!****************************************************************************************
105    REAL, DIMENSION(klon), INTENT(OUT)            :: qsurf
106    REAL, DIMENSION(klon), INTENT(OUT)            :: z0m, z0h
107!albedo SB >>>
108!    REAL, DIMENSION(klon), INTENT(OUT)            :: alb1  ! new albedo in visible SW interval
109!    REAL, DIMENSION(klon), INTENT(OUT)            :: alb2  ! new albedo in near IR interval
110    REAL, DIMENSION(6), INTENT(IN)              ::SFRWL
111    REAL, DIMENSION(klon,nsw), INTENT(OUT)        ::alb_dir,alb_dif
112!albedo SB <<<
113    REAL, DIMENSION(klon), INTENT(OUT)            :: evap, fluxsens, fluxlat
114    REAL, DIMENSION(klon), INTENT(OUT)            :: tsurf_new
115    REAL, DIMENSION(klon), INTENT(OUT)            :: dflux_s, dflux_l     
116    REAL, DIMENSION(klon), INTENT(OUT)            :: flux_u1, flux_v1
117
118    REAL, DIMENSION(klon), INTENT(OUT)           :: alb3
119    REAL, DIMENSION(klon), INTENT(OUT)           :: qsnow   !column water in snow [kg/m2]
120    REAL, DIMENSION(klon), INTENT(OUT)           :: snowhgt !Snow height (m)
121    REAL, DIMENSION(klon), INTENT(OUT)           :: to_ice
122    REAL, DIMENSION(klon), INTENT(OUT)           :: sissnow
123    REAL, DIMENSION(klon), INTENT(OUT)           :: runoff  !Land ice runoff
124#ifdef ISO
125    REAL, DIMENSION(ntraciso,klon), INTENT(OUT)        :: xtevap     
126!    real, DIMENSION(niso,klon) :: xtrun_off_lic_0_diag ! est une variable globale de
127!    fonte_neige
128#endif
129 
130
131! Local variables
132!****************************************************************************************
133    REAL, DIMENSION(klon)    :: soilcap, soilflux
134    REAL, DIMENSION(klon)    :: cal, beta, dif_grnd
135    REAL, DIMENSION(klon)    :: zfra, alb_neig
136    REAL, DIMENSION(klon)    :: radsol
137    REAL, DIMENSION(klon)    :: u0, v0, u1_lay, v1_lay
138    INTEGER                  :: i,j
139#ifdef ISO       
140      real, parameter :: t_coup = 273.15
141      real, dimension(klon) :: fqfonte_diag
142      real, dimension(klon) :: fq_fonte_diag
143      real, dimension(klon) ::  snow_evap_diag
144      real, dimension(klon) ::  fqcalving_diag
145      real max_eau_sol_diag 
146      real, dimension(klon) ::  runoff_diag
147      real, dimension(klon) ::    run_off_lic_diag
148      real ::  coeff_rel_diag
149      integer ixt
150      REAL, DIMENSION(niso,klon) :: xtsnow_prec,xtsol_prec
151      REAL, DIMENSION(klon) :: snow_prec,qsol_prec
152!      real, DIMENSION(klon) :: run_off_lic_0_diag
153#endif
154
155    REAL, DIMENSION(klon)    :: emis_new                  !Emissivity
156    REAL, DIMENSION(klon)    :: swdown,lwdown
157    REAL, DIMENSION(klon)    :: precip_snow_adv, snow_adv !Snow Drift precip./advection
158    REAL, DIMENSION(klon)    :: bl_height, wind_velo      !height boundary layer, wind spd
159    REAL, DIMENSION(klon)    :: dens_air,  snow_cont_air  !air density; snow content air
160    REAL, DIMENSION(klon)    :: alb_soil                  !albedo of underlying ice
161    REAL, DIMENSION(klon)    :: pexner                    !Exner potential
162    REAL                     :: pref
163    REAL, DIMENSION(klon,nsoilmx) :: tsoil0 !modfi
164
165    CHARACTER (len = 20)                      :: modname = 'surf_landice'
166    CHARACTER (len = 80)                      :: abort_message
167
168
169!albedo SB >>>
170    real,dimension(klon) :: alb1,alb2
171!albedo SB <<<
172
173! End definition
174!****************************************************************************************
175!FC
176!FC
177   REAL,SAVE :: alb_vis_sno_lic
178  !$OMP THREADPRIVATE(alb_vis_sno_lic)
179   REAL,SAVE :: alb_nir_sno_lic
180  !$OMP THREADPRIVATE(alb_nir_sno_lic)
181  LOGICAL, SAVE :: firstcall = .TRUE.
182  !$OMP THREADPRIVATE(firstcall)
183!FC
184
185
186#ifdef ISO
187#ifdef ISOVERIF
188!     write(*,*) 'surf_land_ice 1499'   
189     do i=1,knon
190        if (iso_eau.gt.0) then
191             call iso_verif_egalite_choix(xtsnow(iso_eau,i),snow(i), &
192    &            'surf_land_ice 126',errmax,errmaxrel)
193        endif !if (iso_eau.gt.0) then     
194      enddo !do i=1,knon 
195#endif
196#endif
197
198  IF (firstcall) THEN
199  alb_vis_sno_lic=0.77
200  CALL getin_p('alb_vis_sno_lic',alb_vis_sno_lic)
201           PRINT*, 'alb_vis_sno_lic',alb_vis_sno_lic
202  alb_nir_sno_lic=0.77
203  CALL getin_p('alb_nir_sno_lic',alb_nir_sno_lic)
204           PRINT*, 'alb_nir_sno_lic',alb_nir_sno_lic
205  firstcall=.false.
206  ENDIF
207!
208! Initialize output variables
209    alb3(:) = 999999.
210    alb2(:) = 999999.
211    alb1(:) = 999999.
212   
213    runoff(:) = 0.
214!****************************************************************************************
215! Calculate total absorbed radiance at surface
216!
217!****************************************************************************************
218    radsol(:) = 0.0
219    radsol(1:knon) = swnet(1:knon) + lwnet(1:knon)
220
221!****************************************************************************************
222!   ok_snow = TRUE  : prepare and call SISVAT snow model
223!   ok_snow = FALSE : soil_model, calcul_flux, fonte_neige, ...
224!
225!****************************************************************************************
226    IF (ok_snow) THEN
227#ifdef CPP_SISVAT
228       ! Prepare for calling SISVAT
229       
230       ! Calculate incoming flux for SW and LW interval: swdown, lwdown
231       swdown(:)        = 0.0
232       lwdown(:)        = 0.0
233       DO i = 1, knon
234          swdown(i)        = swnet(i)/(1-albedo(i))
235          lwdown(i)        = lwdownm(i)
236       END DO
237       
238       ! Set constants and compute some input for SISVAT
239       snow_adv(:)      = 0.                          ! no snow blown in for now
240       snow_cont_air(:) = 0.       
241       alb_soil(:)      = albedo(:)
242       pref             = 100000.                     ! = 1000 hPa
243       DO i = 1, knon
244          wind_velo(i)     = u1(i)**2 + v1(i)**2
245          wind_velo(i)     = wind_velo(i)**0.5
246          pexner(i)        = (p1lay(i)/pref)**(RD/RCPD)
247          dens_air(i)      = p1lay(i)/RD/temp_air(i)  ! dry air density
248          bl_height(i)     = pphi1(i)/RG             
249       END DO
250
251!****************************************************************************************
252! CALL to SISVAT interface
253!
254!****************************************************************************************
255       ! config: compute everything with SV but temperatures afterwards with soil/calculfluxs
256       DO i = 1, knon
257          tsoil0(i,:)=tsoil(i,:)
258       END DO
259           ! Martin
260           PRINT*, 'on appelle surf_sisvat'
261           ! Martin
262       CALL surf_sisvat(knon, rlon, rlat, knindex, itime, dtime, debut, lafin, &
263            rmu0, swdown, lwdown, pexner, ps, p1lay, &
264            precip_rain, precip_snow, precip_snow_adv, snow_adv, &
265            bl_height, wind_velo, temp_air, dens_air, spechum, tsurf, &
266            rugoro, snow_cont_air, alb_soil, slope, cloudf, &
267            radsol, qsol, tsoil0, snow, snowhgt, qsnow, to_ice,sissnow, agesno, &
268            AcoefH, AcoefQ, BcoefH, BcoefQ, cdragh, &
269            run_off_lic, evap, fluxsens, fluxlat, dflux_s, dflux_l, &       
270            tsurf_new, alb1, alb2, alb3, &
271            emis_new, z0m, qsurf)
272       z0h(1:knon)=z0m(1:knon) ! en attendant mieux
273       
274       ! Suppose zero surface speed
275       u0(:)            = 0.0
276       v0(:)            = 0.0
277       ! The calculation of heat/water fluxes, otherwise done by "CALL calcul_fluxs" is
278       ! integrated in SISVAT, using the same method. It can be found in "sisvat.f", in the
279       ! subroutine "SISVAT_TS2".
280       ! u0, v0=0., dif_grnd=0. and beta=1 are assumed there!
281       
282       CALL calcul_flux_wind(knon, dtime, &
283            u0, v0, u1, v1, gustiness, cdragm, &
284            AcoefU, AcoefV, BcoefU, BcoefV, &
285            p1lay, temp_air, &
286            flux_u1, flux_v1)
287#else
288       abort_message='Pb de coherence: ok_snow = .true. mais CPP_SISVAT = .false.'
289       CALL abort_physic(modname,abort_message,1)
290#endif
291#ifdef ISO
292       abort_message='surf_landice 267: isotopes pas prevus ici'
293       CALL abort_physic(modname,abort_message,1)
294#endif
295    ELSE ! ok_snow=FALSE
296
297!****************************************************************************************
298! Soil calculations
299!
300!****************************************************************************************
301    IF (soil_model) THEN
302       CALL soil(dtime, is_lic, knon, snow, tsurf, tsoil, soilcap, soilflux)
303       cal(1:knon) = RCPD / soilcap(1:knon)
304       radsol(1:knon)  = radsol(1:knon) + soilflux(1:knon)
305    ELSE
306       cal = RCPD * calice
307       WHERE (snow > 0.0) cal = RCPD * calsno
308    ENDIF
309
310
311!****************************************************************************************
312! Calulate fluxes
313!
314!****************************************************************************************
315    beta(:) = 1.0
316    dif_grnd(:) = 0.0
317
318! Suppose zero surface speed
319    u0(:)=0.0
320    v0(:)=0.0
321    u1_lay(:) = u1(:) - u0(:)
322    v1_lay(:) = v1(:) - v0(:)
323
324    CALL calcul_fluxs(knon, is_lic, dtime, &
325         tsurf, p1lay, cal, beta, cdragh, cdragh, ps, &
326         precip_rain, precip_snow, snow, qsurf,  &
327         radsol, dif_grnd, temp_air, spechum, u1_lay, v1_lay, gustiness, &
328         1.,AcoefH, AcoefQ, BcoefH, BcoefQ, &
329         tsurf_new, evap, fluxlat, fluxsens, dflux_s, dflux_l)
330
331
332#ifdef ISO
333   ! verif
334#ifdef ISOVERIF
335     write(*,*) 'surf_land_ice 1499'   
336     do i=1,knon
337       if (iso_eau.gt.0) then
338           if (snow(i).gt.ridicule) then
339             call iso_verif_egalite_choix(xtsnow(iso_eau,i),snow(i), &
340    &            'surf_land_ice 1151',errmax,errmaxrel)
341            endif !if ((snow(i).gt.ridicule)) then
342        endif !if (iso_eau.gt.0) then     
343      enddo !do i=1,knon 
344#endif
345!#ifdef ISOVERIF
346
347    do i=1,knon
348      snow_prec(i)=snow(i)
349      do ixt=1,niso
350      xtsnow_prec(ixt,i)=xtsnow(ixt,i)
351      enddo !do ixt=1,niso
352      ! initialisation:
353      fq_fonte_diag(i)=0.0
354      fqfonte_diag(i)=0.0
355      snow_evap_diag(i)=0.0
356    enddo !do i=1,knon
357#endif         
358!#ifdef ISO
359    CALL calcul_flux_wind(knon, dtime, &
360         u0, v0, u1, v1, gustiness, cdragm, &
361         AcoefU, AcoefV, BcoefU, BcoefV, &
362         p1lay, temp_air, &
363         flux_u1, flux_v1)
364
365!****************************************************************************************
366! Calculate snow height, age, run-off,..
367!   
368!****************************************************************************************
369    CALL fonte_neige( knon, is_lic, knindex, dtime, &
370         tsurf, precip_rain, precip_snow, &
371         snow, qsol, tsurf_new, evap &
372#ifdef ISO   
373     & ,fq_fonte_diag,fqfonte_diag,snow_evap_diag,fqcalving_diag   &
374     & ,max_eau_sol_diag,runoff_diag,run_off_lic_diag,coeff_rel_diag   &
375#endif
376     &   )
377
378
379#ifdef ISO
380#ifdef ISOVERIF
381      do i=1,knon 
382       if (iso_eau.gt.0) then 
383          call iso_verif_egalite_choix(Rland_ice(iso_eau,i),1.0, &
384     &         'surf_landice_mod 217',errmax,errmaxrel)
385       endif !if (iso_eau.gt.0) then   
386      enddo !do i=1,knon 
387#endif
388!#ifdef ISOVERIF
389
390       call calcul_iso_surf_lic_vectall(klon,knon, &
391     &           evap,snow_evap_diag,Tsurf_new,snow, &
392     &           fq_fonte_diag,fqfonte_diag,dtime,t_coup, &
393     &           precip_snow,xtprecip_snow,precip_rain,xtprecip_rain, snow_prec,xtsnow_prec, &
394     &           xtspechum,spechum,ps,Rland_ice, &
395     &           xtevap,xtsnow,fqcalving_diag, &
396     &           knindex,is_lic,run_off_lic_diag,coeff_rel_diag &
397     &  )
398
399!        call fonte_neige_export_xtrun_off_lic_0(knon,xtrun_off_lic_0_diag)
400
401#endif
402!#ifdef ISO
403
404
405!****************************************************************************************
406! Calculate albedo
407!
408!****************************************************************************************
409    CALL albsno(klon,knon,dtime,agesno(:),alb_neig(:), precip_snow(:)) 
410    WHERE (snow(1 : knon) .LT. 0.0001) agesno(1 : knon) = 0.
411    zfra(1:knon) = MAX(0.0,MIN(1.0,snow(1:knon)/(snow(1:knon)+10.0)))
412    alb1(1:knon) = alb_neig(1:knon)*zfra(1:knon) + &
413         0.6 * (1.0-zfra(1:knon))
414!
415!IM: plusieurs choix/tests sur l'albedo des "glaciers continentaux"
416!       alb1(1 : knon)  = 0.6 !IM cf FH/GK
417!       alb1(1 : knon)  = 0.82
418!       alb1(1 : knon)  = 0.77 !211003 Ksta0.77
419!       alb1(1 : knon)  = 0.8 !KstaTER0.8 & LMD_ARMIP5
420!IM: KstaTER0.77 & LMD_ARMIP6   
421
422! Attantion: alb1 and alb2 are the same!
423    alb1(1:knon)  = alb_vis_sno_lic
424    alb2(1:knon)  = alb_nir_sno_lic
425
426
427!****************************************************************************************
428! Rugosity
429!
430!****************************************************************************************
431    z0m=1.e-3
432    z0h = z0m
433    z0m = SQRT(z0m**2+rugoro**2)
434
435    END IF ! ok_snow
436
437
438!****************************************************************************************
439! Send run-off on land-ice to coupler if coupled ocean.
440! run_off_lic has been calculated in fonte_neige or surf_sisvat
441!
442!****************************************************************************************
443    IF (type_ocean=='couple') THEN
444       CALL cpl_send_landice_fields(itime, knon, knindex, run_off_lic)
445    ENDIF
446
447 ! transfer runoff rate [kg/m2/s](!) to physiq for output
448    runoff(1:knon)=run_off_lic(1:knon)/dtime
449
450 
451!****************************************************************************************
452       snow_o=0.
453       zfra_o = 0.
454       DO j = 1, knon
455           i = knindex(j)
456           snow_o(i) = snow(j)
457           zfra_o(i) = zfra(j)
458       ENDDO
459
460!****************************************************************************************
461       snow_o=0.
462       zfra_o = 0.
463       DO j = 1, knon
464           i = knindex(j)
465           snow_o(i) = snow(j)
466           zfra_o(i) = zfra(j)
467       ENDDO
468
469
470!albedo SB >>>
471     select case(NSW)
472     case(2)
473       alb_dir(1:knon,1)=alb1(1:knon)
474       alb_dir(1:knon,2)=alb2(1:knon)
475     case(4)
476       alb_dir(1:knon,1)=alb1(1:knon)
477       alb_dir(1:knon,2)=alb2(1:knon)
478       alb_dir(1:knon,3)=alb2(1:knon)
479       alb_dir(1:knon,4)=alb2(1:knon)
480     case(6)
481       alb_dir(1:knon,1)=alb1(1:knon)
482       alb_dir(1:knon,2)=alb1(1:knon)
483       alb_dir(1:knon,3)=alb1(1:knon)
484       alb_dir(1:knon,4)=alb2(1:knon)
485       alb_dir(1:knon,5)=alb2(1:knon)
486       alb_dir(1:knon,6)=alb2(1:knon)
487     end select
488alb_dif=alb_dir
489!albedo SB <<<
490
491
492
493
494  END SUBROUTINE surf_landice
495!
496!****************************************************************************************
497!
498END MODULE surf_landice_mod
499
500
501
Note: See TracBrowser for help on using the repository browser.