/[lmdze]/trunk/phylmd/Interface_surf/interface_surf.f
ViewVC logotype

Diff of /trunk/phylmd/Interface_surf/interface_surf.f

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 12 by guez, Mon Jul 21 16:05:07 2008 UTC revision 43 by guez, Fri Apr 8 12:43:31 2011 UTC
# Line 1  Line 1 
1  MODULE interface_surf  MODULE interface_surf
2    
3    ! From phylmd/interface_surf.F90,v 1.8 2005/05/25 13:10:09    ! From phylmd/interface_surf.F90, version 1.8 2005/05/25 13:10:09
4    
5    ! Ce module regroupe toutes les routines gérant l'interface entre le modèle    ! Ce module regroupe toutes les routines gérant l'interface entre le
6    ! atmosphérique et les modèles de surface (sols continentaux,    ! modèle atmosphérique et les modèles de surface (sols continentaux,
7    ! océans, glaces).    ! océans, glaces). Les routines sont les suivantes. "interfsurf_hq" :
8    ! Les routines sont les suivantes:    ! routine d'aiguillage vers les interfaces avec les différents
9    ! interfsurf_hq : routine d'aiguillage vers les interfaces avec les    ! modèles de surface ; "interfoce_*" : routines d'interface proprement
10    !    différents modèles de surface    ! dites.
   ! interfoce_* : routines d'interface proprement dites  
11    
12    ! L. Fairhead, LMD, 02/2000    ! L. Fairhead, LMD, february 2000
13    
14    IMPLICIT none    IMPLICIT none
15    
16    PRIVATE    PRIVATE
17    PUBLIC :: interfsurf_hq    PUBLIC :: interfsurf_hq
18    
19    ! run_off      ruissellement total    ! run_off ruissellement total
20    REAL, ALLOCATABLE, DIMENSION(:),SAVE    :: run_off, run_off_lic    REAL, ALLOCATABLE, DIMENSION(:), SAVE :: run_off, run_off_lic
21    real, allocatable, dimension(:),save    :: coastalflow, riverflow    real, allocatable, dimension(:), save :: coastalflow, riverflow
22    
23    REAL, ALLOCATABLE, DIMENSION(:,:), SAVE :: tmp_rriv, tmp_rcoa,tmp_rlic    REAL, ALLOCATABLE, DIMENSION(:, :), SAVE :: tmp_rriv, tmp_rcoa, tmp_rlic
24    !! pour simuler la fonte des glaciers antarctiques    ! pour simuler la fonte des glaciers antarctiques
25    REAL, ALLOCATABLE, DIMENSION(:,:), SAVE :: coeff_iceberg    REAL, ALLOCATABLE, DIMENSION(:, :), SAVE :: coeff_iceberg
26    real, save                              :: surf_maille    real, save :: surf_maille
27    real, save                              :: cte_flux_iceberg = 6.3e7    real, save :: cte_flux_iceberg = 6.3e7
28    integer, save                           :: num_antarctic = 1    integer, save :: num_antarctic = 1
29    REAL, save                              :: tau_calv    REAL, save :: tau_calv
30    
31  CONTAINS  CONTAINS
32    
33    SUBROUTINE interfsurf_hq(itime, dtime, date0, jour, rmu0, &    SUBROUTINE interfsurf_hq(itime, dtime, date0, jour, rmu0,  &
34         & klon, iim, jjm, nisurf, knon, knindex, pctsrf, &         klon, iim, jjm, nisurf, knon, knindex, pctsrf,  &
35         & rlon, rlat, cufi, cvfi,&         rlon, rlat, cufi, cvfi,  &
36         & debut, lafin, ok_veget, soil_model, nsoilmx, tsoil, qsol,&         debut, lafin, ok_veget, soil_model, nsoilmx, tsoil, qsol,  &
37         & zlev,  u1_lay, v1_lay, temp_air, spechum, epot_air, ccanopy, &         zlev, u1_lay, v1_lay, temp_air, spechum, epot_air, ccanopy, &
38         & tq_cdrag, petAcoef, peqAcoef, petBcoef, peqBcoef, &         tq_cdrag, petAcoef, peqAcoef, petBcoef, peqBcoef,  &
39         & precip_rain, precip_snow, sollw, sollwdown, swnet, swdown, &         precip_rain, precip_snow, sollw, sollwdown, swnet, swdown,  &
40         & fder, taux, tauy, &         fder, taux, tauy,  &
41         & windsp, &         windsp,  &
42         & rugos, rugoro, &         rugos, rugoro,  &
43         & albedo, snow, qsurf, &         albedo, snow, qsurf,  &
44         & tsurf, p1lay, ps, radsol, &         tsurf, p1lay, ps, radsol,  &
45         & ocean, npas, nexca, zmasq, &         ocean, npas, nexca, zmasq,  &
46         & evap, fluxsens, fluxlat, dflux_l, dflux_s, &                       evap, fluxsens, fluxlat, dflux_l, dflux_s, &
47         & tsol_rad, tsurf_new, alb_new, alblw, emis_new, &         tsol_rad, tsurf_new, alb_new, alblw, emis_new,  &
48         & z0_new, pctsrf_new, agesno,fqcalving,ffonte, run_off_lic_0,&         z0_new, pctsrf_new, agesno, fqcalving, ffonte, run_off_lic_0, &
49         !IM "slab" ocean         flux_o, flux_g, tslab, seaice)
        & flux_o, flux_g, tslab, seaice)  
50    
51      ! Cette routine sert d'aiguillage entre l'atmosphère et la surface      ! Cette routine sert d'aiguillage entre l'atmosphère et la surface
52      ! en général (sols continentaux, océans, glaces) pour les fluxs de      ! en général (sols continentaux, océans, glaces) pour les flux de
53      ! chaleur et d'humidité.      ! chaleur et d'humidité.
54      ! En pratique l'interface se fait entre la couche limite du modèle      ! En pratique l'interface se fait entre la couche limite du modèle
55      ! atmosphérique ("clmain.F") et les routines de surface      ! atmosphérique ("clmain.F") et les routines de surface
# Line 59  CONTAINS Line 57  CONTAINS
57    
58      ! L.Fairhead 02/2000      ! L.Fairhead 02/2000
59    
     ! input:  
     !   klon         nombre total de points de grille  
     !   iim, jjm     nbres de pts de grille  
     !   dtime        pas de temps de la physique (en s)  
     !   date0        jour initial  
     !   jour         jour dans l'annee en cours,  
     !   rmu0         cosinus de l'angle solaire zenithal  
     !   nexca        pas de temps couplage  
     !   nisurf       index de la surface a traiter (1 = sol continental)  
     !   knon         nombre de points de la surface a traiter  
     !   knindex      index des points de la surface a traiter  
     !   pctsrf       tableau des pourcentages de surface de chaque maille  
     !   rlon         longitudes  
     !   rlat         latitudes  
     !   cufi,cvfi    resolution des mailles en x et y (m)  
     !   debut        logical: 1er appel a la physique  
     !   lafin        logical: dernier appel a la physique  
     !   ok_veget     logical: appel ou non au schema de surface continental  
     !                  (si false calcul simplifie des fluxs sur les continents)  
     !   zlev         hauteur de la premiere couche  
     !   u1_lay       vitesse u 1ere couche  
     !   v1_lay       vitesse v 1ere couche  
     !   temp_air     temperature de l'air 1ere couche  
     !   spechum      humidite specifique 1ere couche  
     !   epot_air     temp potentielle de l'air  
     !   ccanopy      concentration CO2 canopee  
     !   tq_cdrag     cdrag  
     !   petAcoef     coeff. A de la resolution de la CL pour t  
     !   peqAcoef     coeff. A de la resolution de la CL pour q  
     !   petBcoef     coeff. B de la resolution de la CL pour t  
     !   peqBcoef     coeff. B de la resolution de la CL pour q  
     !   precip_rain  precipitation liquide  
     !   precip_snow  precipitation solide  
     !   sollw        flux IR net a la surface  
     !   sollwdown    flux IR descendant a la surface  
     !   swnet        flux solaire net  
     !   swdown       flux solaire entrant a la surface  
     !   albedo       albedo de la surface  
     !   tsurf        temperature de surface  
     !   tslab        temperature slab ocean  
     !   pctsrf_slab  pourcentages (0-1) des sous-surfaces dans le slab  
     !   tmp_pctsrf_slab = pctsrf_slab  
     !   p1lay        pression 1er niveau (milieu de couche)  
     !   ps           pression au sol  
     !   radsol       rayonnement net aus sol (LW + SW)  
     !   ocean        type d'ocean utilise ("force" ou "slab" mais pas "couple")  
     !   fder         derivee des flux (pour le couplage)  
     !   taux, tauy   tension de vents  
     !   windsp       module du vent a 10m  
     !   rugos        rugosite  
     !   zmasq        masque terre/ocean  
     !   rugoro       rugosite orographique  
     !   run_off_lic_0 runoff glacier du pas de temps precedent  
   
     ! output:  
     !   evap         evaporation totale  
     !   fluxsens     flux de chaleur sensible  
     !   fluxlat      flux de chaleur latente  
     !   tsol_rad      
     !   tsurf_new    temperature au sol  
     !   alb_new      albedo  
     !   emis_new     emissivite  
     !   z0_new       surface roughness  
     !   pctsrf_new   nouvelle repartition des surfaces  
   
60      use abort_gcm_m, only: abort_gcm      use abort_gcm_m, only: abort_gcm
61      use gath_cpl, only: gath2cpl      use gath_cpl, only: gath2cpl
62      use indicesol      use indicesol
63      use YOMCST      use SUPHEC_M
64      use albsno_m, only: albsno      use albsno_m, only: albsno
65    
66      ! Parametres d'entree      ! Parametres d'entree
67      integer, intent(IN) :: itime     !  numero du pas de temps      ! input:
68        ! klon nombre total de points de grille
69        ! iim, jjm nbres de pts de grille
70        ! dtime pas de temps de la physique (en s)
71        ! date0 jour initial
72        ! jour jour dans l'annee en cours,
73        ! rmu0 cosinus de l'angle solaire zenithal
74        ! nexca pas de temps couplage
75        ! nisurf index de la surface a traiter (1 = sol continental)
76        ! knon nombre de points de la surface a traiter
77        ! knindex index des points de la surface a traiter
78        ! pctsrf tableau des pourcentages de surface de chaque maille
79        ! rlon longitudes
80        ! rlat latitudes
81        ! cufi, cvfi resolution des mailles en x et y (m)
82        ! debut logical: 1er appel a la physique
83        ! lafin logical: dernier appel a la physique
84        ! ok_veget logical: appel ou non au schema de surface continental
85        ! (si false calcul simplifie des fluxs sur les continents)
86        ! zlev hauteur de la premiere couche
87        ! u1_lay vitesse u 1ere couche
88        ! v1_lay vitesse v 1ere couche
89        ! temp_air temperature de l'air 1ere couche
90        ! spechum humidite specifique 1ere couche
91        ! epot_air temp potentielle de l'air
92        ! ccanopy concentration CO2 canopee
93        ! tq_cdrag cdrag
94        ! petAcoef coeff. A de la resolution de la CL pour t
95        ! peqAcoef coeff. A de la resolution de la CL pour q
96        ! petBcoef coeff. B de la resolution de la CL pour t
97        ! peqBcoef coeff. B de la resolution de la CL pour q
98        ! precip_rain precipitation liquide
99        ! precip_snow precipitation solide
100        ! sollw flux IR net a la surface
101        ! sollwdown flux IR descendant a la surface
102        ! swnet flux solaire net
103        ! swdown flux solaire entrant a la surface
104        ! albedo albedo de la surface
105        ! tsurf temperature de surface
106        ! tslab temperature slab ocean
107        ! pctsrf_slab pourcentages (0-1) des sous-surfaces dans le slab
108        ! tmp_pctsrf_slab = pctsrf_slab
109        ! p1lay pression 1er niveau (milieu de couche)
110        ! ps pression au sol
111        ! radsol rayonnement net aus sol (LW + SW)
112        ! ocean type d'ocean utilise ("force" ou "slab" mais pas "couple")
113        ! fder derivee des flux (pour le couplage)
114        ! taux, tauy tension de vents
115        ! windsp module du vent a 10m
116        ! rugos rugosite
117        ! zmasq masque terre/ocean
118        ! rugoro rugosite orographique
119        ! run_off_lic_0 runoff glacier du pas de temps precedent
120        integer, intent(IN) :: itime ! numero du pas de temps
121      integer, intent(IN) :: iim, jjm      integer, intent(IN) :: iim, jjm
122      integer, intent(IN) :: klon      integer, intent(IN) :: klon
123      real, intent(IN) :: dtime      real, intent(IN) :: dtime
124      real, intent(IN) :: date0      real, intent(IN) :: date0
125      integer, intent(IN) :: jour      integer, intent(IN) :: jour
126      real, intent(IN)    :: rmu0(klon)      real, intent(IN) :: rmu0(klon)
127      integer, intent(IN) :: nisurf      integer, intent(IN) :: nisurf
128      integer, intent(IN) :: knon      integer, intent(IN) :: knon
129      integer, dimension(klon), intent(in) :: knindex      integer, dimension(klon), intent(in) :: knindex
130      real, dimension(klon,nbsrf), intent(IN) :: pctsrf      real, dimension(klon, nbsrf), intent(IN) :: pctsrf
131      logical, intent(IN) :: debut, lafin, ok_veget      logical, intent(IN) :: debut, lafin, ok_veget
132      real, dimension(klon), intent(IN) :: rlon, rlat      real, dimension(klon), intent(IN) :: rlon, rlat
133      real, dimension(klon), intent(IN) :: cufi, cvfi      real, dimension(klon), intent(IN) :: cufi, cvfi
# Line 160  CONTAINS Line 146  CONTAINS
146      real, dimension(klon), intent(INOUT) :: tslab      real, dimension(klon), intent(INOUT) :: tslab
147      real, allocatable, dimension(:), save :: tmp_tslab      real, allocatable, dimension(:), save :: tmp_tslab
148      real, dimension(klon), intent(OUT) :: flux_o, flux_g      real, dimension(klon), intent(OUT) :: flux_o, flux_g
149      real, dimension(klon), intent(INOUT)      :: seaice ! glace de mer (kg/m2)      real, dimension(klon), intent(INOUT) :: seaice ! glace de mer (kg/m2)
150      REAL, DIMENSION(klon), INTENT(INOUT) :: radsol,fder      REAL, DIMENSION(klon), INTENT(INOUT) :: radsol, fder
151      real, dimension(klon), intent(IN) :: zmasq      real, dimension(klon), intent(IN) :: zmasq
152      real, dimension(klon), intent(IN) :: taux, tauy, rugos, rugoro      real, dimension(klon), intent(IN) :: taux, tauy, rugos, rugoro
153      real, dimension(klon), intent(IN) :: windsp      real, dimension(klon), intent(IN) :: windsp
154      character(len=*), intent(IN):: ocean      character(len=*), intent(IN):: ocean
155      integer              :: npas, nexca ! nombre et pas de temps couplage      integer :: npas, nexca ! nombre et pas de temps couplage
156      real, dimension(klon), intent(INOUT) :: evap, snow, qsurf      real, dimension(klon), intent(INOUT) :: evap, snow, qsurf
157      !! PB ajout pour soil      !! PB ajout pour soil
158      logical, intent(in):: soil_model      logical, intent(in):: soil_model
159      integer          :: nsoilmx      integer :: nsoilmx
160      REAL, DIMENSION(klon, nsoilmx) :: tsoil      REAL, DIMENSION(klon, nsoilmx) :: tsoil
161      REAL, dimension(klon), intent(INOUT) :: qsol      REAL, dimension(klon), intent(INOUT) :: qsol
162      REAL, dimension(klon)          :: soilcap      REAL, dimension(klon) :: soilcap
163      REAL, dimension(klon)          :: soilflux      REAL, dimension(klon) :: soilflux
164    
165      ! Parametres de sortie      ! Parametres de sortie
166        ! output:
167        ! evap evaporation totale
168        ! fluxsens flux de chaleur sensible
169        ! fluxlat flux de chaleur latente
170        ! tsol_rad
171        ! tsurf_new temperature au sol
172        ! alb_new albedo
173        ! emis_new emissivite
174        ! z0_new surface roughness
175        ! pctsrf_new nouvelle repartition des surfaces
176      real, dimension(klon), intent(OUT):: fluxsens, fluxlat      real, dimension(klon), intent(OUT):: fluxsens, fluxlat
177      real, dimension(klon), intent(OUT):: tsol_rad, tsurf_new, alb_new      real, dimension(klon), intent(OUT):: tsol_rad, tsurf_new, alb_new
178      real, dimension(klon), intent(OUT):: alblw      real, dimension(klon), intent(OUT):: alblw
179      real, dimension(klon), intent(OUT):: emis_new, z0_new      real, dimension(klon), intent(OUT):: emis_new, z0_new
180      real, dimension(klon), intent(OUT):: dflux_l, dflux_s      real, dimension(klon), intent(OUT):: dflux_l, dflux_s
181      real, dimension(klon,nbsrf), intent(OUT) :: pctsrf_new      real, dimension(klon, nbsrf), intent(OUT) :: pctsrf_new
182      real, dimension(klon), intent(INOUT):: agesno      real, dimension(klon), intent(INOUT):: agesno
183      real, dimension(klon), intent(INOUT):: run_off_lic_0      real, dimension(klon), intent(INOUT):: run_off_lic_0
184    
185      ! Flux thermique utiliser pour fondre la neige      ! Flux thermique utiliser pour fondre la neige
186      !jld a rajouter   real, dimension(klon), intent(INOUT):: ffonte      !jld a rajouter real, dimension(klon), intent(INOUT):: ffonte
187      real, dimension(klon), intent(INOUT):: ffonte      real, dimension(klon), intent(INOUT):: ffonte
188      ! Flux d'eau "perdue" par la surface et nécessaire pour que limiter la      ! Flux d'eau "perdue" par la surface et nécessaire pour que limiter la
189      ! hauteur de neige, en kg/m2/s      ! hauteur de neige, en kg/m2/s
190      !jld a rajouter   real, dimension(klon), intent(INOUT):: fqcalving      !jld a rajouter real, dimension(klon), intent(INOUT):: fqcalving
191      real, dimension(klon), intent(INOUT):: fqcalving      real, dimension(klon), intent(INOUT):: fqcalving
192      !IM: "slab" ocean - Local      !IM: "slab" ocean - Local
193      real, parameter :: t_grnd=271.35      real, parameter :: t_grnd=271.35
# Line 198  CONTAINS Line 195  CONTAINS
195      integer i      integer i
196      real, allocatable, dimension(:), save :: tmp_flux_o, tmp_flux_g      real, allocatable, dimension(:), save :: tmp_flux_o, tmp_flux_g
197      real, allocatable, dimension(:), save :: tmp_radsol      real, allocatable, dimension(:), save :: tmp_radsol
198      real, allocatable, dimension(:,:), save :: tmp_pctsrf_slab      real, allocatable, dimension(:, :), save :: tmp_pctsrf_slab
199      real, allocatable, dimension(:), save :: tmp_seaice      real, allocatable, dimension(:), save :: tmp_seaice
200    
201      ! Local      ! Local
202      character (len = 20),save :: modname = 'interfsurf_hq'      character (len = 20), save :: modname = 'interfsurf_hq'
203      character (len = 80) :: abort_message      character (len = 80) :: abort_message
204      logical, save        :: first_call = .true.      logical, save :: first_call = .true.
205      integer, save        :: error      integer, save :: error
206      integer              :: ii      integer :: ii
207      logical,save              :: check = .false.      logical, save :: check = .false.
208      real, dimension(klon):: cal, beta, dif_grnd, capsol      real, dimension(klon):: cal, beta, dif_grnd, capsol
209  !!$PB  real, parameter      :: calice=1.0/(5.1444e+06*0.15), tau_gl=86400.*5.      real, parameter :: calice=1.0/(5.1444e+06*0.15), tau_gl=86400.*5.
210      real, parameter      :: calice=1.0/(5.1444e+06*0.15), tau_gl=86400.*5.      real, parameter :: calsno=1./(2.3867e+06*.15)
     real, parameter      :: calsno=1./(2.3867e+06*.15)  
211      real, dimension(klon):: tsurf_temp      real, dimension(klon):: tsurf_temp
212      real, dimension(klon):: alb_neig, alb_eau      real, dimension(klon):: alb_neig, alb_eau
213      real, DIMENSION(klon):: zfra      real, DIMENSION(klon):: zfra
214      logical              :: cumul = .false.      logical :: cumul = .false.
215      INTEGER,dimension(1) :: iloc      INTEGER, dimension(1) :: iloc
216      real, dimension(klon):: fder_prev      real, dimension(klon):: fder_prev
217      REAL, dimension(klon) :: bidule      REAL, dimension(klon) :: bidule
218    
219      !-------------------------------------------------------------      !-------------------------------------------------------------
220    
221      if (check) write(*,*) 'Entree ', modname      if (check) write(*, *) 'Entree ', modname
222    
223      ! On doit commencer par appeler les schemas de surfaces continentales      ! On doit commencer par appeler les schemas de surfaces continentales
224      ! car l'ocean a besoin du ruissellement qui est y calcule      ! car l'ocean a besoin du ruissellement qui est y calcule
# Line 230  CONTAINS Line 226  CONTAINS
226      if (first_call) then      if (first_call) then
227         call conf_interface(tau_calv)         call conf_interface(tau_calv)
228         if (nisurf /= is_ter .and. klon > 1) then         if (nisurf /= is_ter .and. klon > 1) then
229            write(*,*)' *** Warning ***'            write(*, *)' *** Warning ***'
230            write(*,*)' nisurf = ',nisurf,' /= is_ter = ',is_ter            write(*, *)' nisurf = ', nisurf, ' /= is_ter = ', is_ter
231            write(*,*)'or on doit commencer par les surfaces continentales'            write(*, *)'or on doit commencer par les surfaces continentales'
232            abort_message='voir ci-dessus'            abort_message='voir ci-dessus'
233            call abort_gcm(modname,abort_message,1)            call abort_gcm(modname, abort_message, 1)
234         endif         endif
235         if (ocean /= 'slab' .and. ocean /= 'force') then         if (ocean /= 'slab' .and. ocean /= 'force') then
236            write(*,*)' *** Warning ***'            write(*, *)' *** Warning ***'
237            write(*,*)'Option couplage pour l''ocean = ', ocean            write(*, *)'Option couplage pour l''ocean = ', ocean
238            abort_message='option pour l''ocean non valable'            abort_message='option pour l''ocean non valable'
239            call abort_gcm(modname,abort_message,1)            call abort_gcm(modname, abort_message, 1)
240         endif         endif
241         if ( is_oce > is_sic ) then         if ( is_oce > is_sic ) then
242            write(*,*)' *** Warning ***'            write(*, *)' *** Warning ***'
243            write(*,*)' Pour des raisons de sequencement dans le code'            write(*, *)' Pour des raisons de sequencement dans le code'
244            write(*,*)' l''ocean doit etre traite avant la banquise'            write(*, *)' l''ocean doit etre traite avant la banquise'
245            write(*,*)' or is_oce = ',is_oce, '> is_sic = ',is_sic            write(*, *)' or is_oce = ', is_oce, '> is_sic = ', is_sic
246            abort_message='voir ci-dessus'            abort_message='voir ci-dessus'
247            call abort_gcm(modname,abort_message,1)            call abort_gcm(modname, abort_message, 1)
248         endif         endif
249      endif      endif
250      first_call = .false.      first_call = .false.
251    
252      ! Initialisations diverses      ! Initialisations diverses
253      !  
254      ffonte(1:knon)=0.      ffonte(1:knon)=0.
255      fqcalving(1:knon)=0.      fqcalving(1:knon)=0.
256    
# Line 266  CONTAINS Line 262  CONTAINS
262      !IM: "slab" ocean; initialisations      !IM: "slab" ocean; initialisations
263      flux_o = 0.      flux_o = 0.
264      flux_g = 0.      flux_g = 0.
265      !  
266      if (.not. allocated(tmp_flux_o)) then      if (.not. allocated(tmp_flux_o)) then
267         allocate(tmp_flux_o(klon), stat = error)         allocate(tmp_flux_o(klon), stat = error)
268         DO i=1, knon         DO i=1, knon
# Line 274  CONTAINS Line 270  CONTAINS
270         ENDDO         ENDDO
271         if (error /= 0) then         if (error /= 0) then
272            abort_message='Pb allocation tmp_flux_o'            abort_message='Pb allocation tmp_flux_o'
273            call abort_gcm(modname,abort_message,1)            call abort_gcm(modname, abort_message, 1)
274         endif         endif
275      endif      endif
276      if (.not. allocated(tmp_flux_g)) then        if (.not. allocated(tmp_flux_g)) then
277         allocate(tmp_flux_g(klon), stat = error)         allocate(tmp_flux_g(klon), stat = error)
278         DO i=1, knon         DO i=1, knon
279            tmp_flux_g(knindex(i))=flux_g(i)            tmp_flux_g(knindex(i))=flux_g(i)
280         ENDDO         ENDDO
281         if (error /= 0) then         if (error /= 0) then
282            abort_message='Pb allocation tmp_flux_g'            abort_message='Pb allocation tmp_flux_g'
283            call abort_gcm(modname,abort_message,1)            call abort_gcm(modname, abort_message, 1)
284         endif         endif
285      endif      endif
286      if (.not. allocated(tmp_radsol)) then        if (.not. allocated(tmp_radsol)) then
287         allocate(tmp_radsol(klon), stat = error)         allocate(tmp_radsol(klon), stat = error)
288         if (error /= 0) then         if (error /= 0) then
289            abort_message='Pb allocation tmp_radsol'            abort_message='Pb allocation tmp_radsol'
290            call abort_gcm(modname,abort_message,1)            call abort_gcm(modname, abort_message, 1)
291         endif         endif
292      endif      endif
293      DO i=1, knon      DO i=1, knon
294         tmp_radsol(knindex(i))=radsol(i)         tmp_radsol(knindex(i))=radsol(i)
295      ENDDO      ENDDO
296      if (.not. allocated(tmp_pctsrf_slab)) then      if (.not. allocated(tmp_pctsrf_slab)) then
297         allocate(tmp_pctsrf_slab(klon,nbsrf), stat = error)         allocate(tmp_pctsrf_slab(klon, nbsrf), stat = error)
298         if (error /= 0) then         if (error /= 0) then
299            abort_message='Pb allocation tmp_pctsrf_slab'            abort_message='Pb allocation tmp_pctsrf_slab'
300            call abort_gcm(modname,abort_message,1)            call abort_gcm(modname, abort_message, 1)
301         endif         endif
302         DO i=1, klon         DO i=1, klon
303            tmp_pctsrf_slab(i,1:nbsrf)=pctsrf(i,1:nbsrf)            tmp_pctsrf_slab(i, 1:nbsrf)=pctsrf(i, 1:nbsrf)
304         ENDDO         ENDDO
305      endif      endif
306      !  
307      if (.not. allocated(tmp_seaice)) then      if (.not. allocated(tmp_seaice)) then
308         allocate(tmp_seaice(klon), stat = error)         allocate(tmp_seaice(klon), stat = error)
309         if (error /= 0) then         if (error /= 0) then
310            abort_message='Pb allocation tmp_seaice'            abort_message='Pb allocation tmp_seaice'
311            call abort_gcm(modname,abort_message,1)            call abort_gcm(modname, abort_message, 1)
312         endif         endif
313         DO i=1, klon         DO i=1, klon
314            tmp_seaice(i)=seaice(i)            tmp_seaice(i)=seaice(i)
315         ENDDO         ENDDO
316      endif      endif
317      !  
318      if (.not. allocated(tmp_tslab)) then      if (.not. allocated(tmp_tslab)) then
319         allocate(tmp_tslab(klon), stat = error)         allocate(tmp_tslab(klon), stat = error)
320         if (error /= 0) then         if (error /= 0) then
321            abort_message='Pb allocation tmp_tslab'            abort_message='Pb allocation tmp_tslab'
322            call abort_gcm(modname,abort_message,1)            call abort_gcm(modname, abort_message, 1)
323         endif         endif
324      endif      endif
325      DO i=1, klon      DO i=1, klon
326         tmp_tslab(i)=tslab(i)         tmp_tslab(i)=tslab(i)
327      ENDDO      ENDDO
328      !  
329      ! Aiguillage vers les differents schemas de surface      ! Aiguillage vers les differents schemas de surface
330    
331      if (nisurf == is_ter) then      if (nisurf == is_ter) then
332         !  
333         ! Surface "terre" appel a l'interface avec les sols continentaux         ! Surface "terre" appel a l'interface avec les sols continentaux
334         !  
335         ! allocation du run-off         ! allocation du run-off
336         if (.not. allocated(coastalflow)) then         if (.not. allocated(coastalflow)) then
337            allocate(coastalflow(knon), stat = error)            allocate(coastalflow(knon), stat = error)
338            if (error /= 0) then            if (error /= 0) then
339               abort_message='Pb allocation coastalflow'               abort_message='Pb allocation coastalflow'
340               call abort_gcm(modname,abort_message,1)               call abort_gcm(modname, abort_message, 1)
341            endif            endif
342            allocate(riverflow(knon), stat = error)            allocate(riverflow(knon), stat = error)
343            if (error /= 0) then            if (error /= 0) then
344               abort_message='Pb allocation riverflow'               abort_message='Pb allocation riverflow'
345               call abort_gcm(modname,abort_message,1)               call abort_gcm(modname, abort_message, 1)
346            endif            endif
347            allocate(run_off(knon), stat = error)            allocate(run_off(knon), stat = error)
348            if (error /= 0) then            if (error /= 0) then
349               abort_message='Pb allocation run_off'               abort_message='Pb allocation run_off'
350               call abort_gcm(modname,abort_message,1)               call abort_gcm(modname, abort_message, 1)
351            endif            endif
352            !cym                  !cym
353            run_off=0.0            run_off=0.0
354            !cym            !cym
355    
356  !!$PB  !!$PB
357            ALLOCATE (tmp_rriv(iim,jjm+1), stat=error)            ALLOCATE (tmp_rriv(iim, jjm+1), stat=error)
358            if (error /= 0) then            if (error /= 0) then
359               abort_message='Pb allocation tmp_rriv'               abort_message='Pb allocation tmp_rriv'
360               call abort_gcm(modname,abort_message,1)               call abort_gcm(modname, abort_message, 1)
361            endif            endif
362            ALLOCATE (tmp_rcoa(iim,jjm+1), stat=error)            ALLOCATE (tmp_rcoa(iim, jjm+1), stat=error)
363            if (error /= 0) then            if (error /= 0) then
364               abort_message='Pb allocation tmp_rcoa'               abort_message='Pb allocation tmp_rcoa'
365               call abort_gcm(modname,abort_message,1)               call abort_gcm(modname, abort_message, 1)
366            endif            endif
367            ALLOCATE (tmp_rlic(iim,jjm+1), stat=error)            ALLOCATE (tmp_rlic(iim, jjm+1), stat=error)
368            if (error /= 0) then            if (error /= 0) then
369               abort_message='Pb allocation tmp_rlic'               abort_message='Pb allocation tmp_rlic'
370               call abort_gcm(modname,abort_message,1)               call abort_gcm(modname, abort_message, 1)
371            endif            endif
372            tmp_rriv = 0.0            tmp_rriv = 0.0
373            tmp_rcoa = 0.0            tmp_rcoa = 0.0
# Line 379  CONTAINS Line 375  CONTAINS
375    
376  !!$  !!$
377         else if (size(coastalflow) /= knon) then         else if (size(coastalflow) /= knon) then
378            write(*,*)'Bizarre, le nombre de points continentaux'            write(*, *)'Bizarre, le nombre de points continentaux'
379            write(*,*)'a change entre deux appels. J''arrete ...'            write(*, *)'a change entre deux appels. J''arrete ...'
380            abort_message='voir ci-dessus'            abort_message='voir ci-dessus'
381            call abort_gcm(modname,abort_message,1)            call abort_gcm(modname, abort_message, 1)
382         endif         endif
383         coastalflow = 0.         coastalflow = 0.
384         riverflow = 0.         riverflow = 0.
385         !  
386         ! Calcul age de la neige         ! Calcul age de la neige
387    
388         if (.not. ok_veget) then         if (.not. ok_veget) then
389            !            ! calcul albedo: lecture albedo fichier boundary conditions
390            ! calcul albedo: lecture albedo fichier CL puis ajout albedo neige            ! puis ajout albedo neige
391            !            call interfsur_lim(itime, dtime, jour, klon, nisurf, knon, knindex, &
392            call interfsur_lim(itime, dtime, jour, &                 debut, alb_new, z0_new)
393                 & klon, nisurf, knon, knindex, debut,  &  
                & alb_new, z0_new)  
           !    
394            ! calcul snow et qsurf, hydrol adapté            ! calcul snow et qsurf, hydrol adapté
           !  
395            CALL calbeta(dtime, nisurf, knon, snow, qsol, beta, capsol, dif_grnd)            CALL calbeta(dtime, nisurf, knon, snow, qsol, beta, capsol, dif_grnd)
396    
397            IF (soil_model) THEN            IF (soil_model) THEN
398               CALL soil(dtime, nisurf, knon,snow, tsurf, tsoil,soilcap, soilflux)               CALL soil(dtime, nisurf, knon, snow, tsurf, tsoil, soilcap, &
399                      soilflux)
400               cal(1:knon) = RCPD / soilcap(1:knon)               cal(1:knon) = RCPD / soilcap(1:knon)
401               radsol(1:knon) = radsol(1:knon)  + soilflux(1:knon)               radsol(1:knon) = radsol(1:knon) + soilflux(1:knon)
402            ELSE            ELSE
403               cal = RCPD * capsol               cal = RCPD * capsol
 !!$      cal = capsol  
404            ENDIF            ENDIF
405            CALL calcul_fluxs( klon, knon, nisurf, dtime, &            CALL calcul_fluxs( klon, knon, nisurf, dtime, &
406                 &   tsurf, p1lay, cal, beta, tq_cdrag, ps, &                 tsurf, p1lay, cal, beta, tq_cdrag, ps, &
407                 &   precip_rain, precip_snow, snow, qsurf,  &                 precip_rain, precip_snow, snow, qsurf, &
408                 &   radsol, dif_grnd, temp_air, spechum, u1_lay, v1_lay, &                 radsol, dif_grnd, temp_air, spechum, u1_lay, v1_lay, &
409                 &   petAcoef, peqAcoef, petBcoef, peqBcoef, &                 petAcoef, peqAcoef, petBcoef, peqBcoef, &
410                 &   tsurf_new, evap, fluxlat, fluxsens, dflux_s, dflux_l)                 tsurf_new, evap, fluxlat, fluxsens, dflux_s, dflux_l)
411    
412            CALL fonte_neige( klon, knon, nisurf, dtime, &            CALL fonte_neige( klon, knon, nisurf, dtime, &
413                 &   tsurf, p1lay, cal, beta, tq_cdrag, ps, &                 tsurf, p1lay, cal, beta, tq_cdrag, ps, &
414                 &   precip_rain, precip_snow, snow, qsol,  &                 precip_rain, precip_snow, snow, qsol, &
415                 &   radsol, dif_grnd, temp_air, spechum, u1_lay, v1_lay, &                 radsol, dif_grnd, temp_air, spechum, u1_lay, v1_lay, &
416                 &   petAcoef, peqAcoef, petBcoef, peqBcoef, &                 petAcoef, peqAcoef, petBcoef, peqBcoef, &
417                 &   tsurf_new, evap, fluxlat, fluxsens, dflux_s, dflux_l, &                 tsurf_new, evap, fluxlat, fluxsens, dflux_s, dflux_l, &
418                 &   fqcalving,ffonte, run_off_lic_0)                 fqcalving, ffonte, run_off_lic_0)
419    
420            call albsno(klon,knon,dtime,agesno(:),alb_neig(:), precip_snow(:))              call albsno(klon, knon, dtime, agesno, alb_neig, precip_snow)
421            where (snow(1 : knon) .LT. 0.0001) agesno(1 : knon) = 0.            where (snow(1 : knon) .LT. 0.0001) agesno(1 : knon) = 0.
422            zfra(1:knon) = max(0.0,min(1.0,snow(1:knon)/(snow(1:knon)+10.0)))            zfra(1:knon) = max(0.0, min(1.0, snow(1:knon)/(snow(1:knon)+10.0)))
423            alb_new(1 : knon)  = alb_neig(1 : knon) *zfra(1:knon) + &            alb_new(1 : knon) = alb_neig(1 : knon) *zfra(1:knon) + &
424                 &                     alb_new(1 : knon)*(1.0-zfra(1:knon))                 alb_new(1 : knon)*(1.0-zfra(1:knon))
425            z0_new = sqrt(z0_new**2+rugoro**2)            z0_new = sqrt(z0_new**2+rugoro**2)
426            alblw(1 : knon) = alb_new(1 : knon)            alblw(1 : knon) = alb_new(1 : knon)
   
        else  
427         endif         endif
        !  
        ! Remplissage des pourcentages de surface  
        !  
        pctsrf_new(:,nisurf) = pctsrf(:,nisurf)  
428    
429           ! Remplissage des pourcentages de surface
430           pctsrf_new(:, nisurf) = pctsrf(:, nisurf)
431      else if (nisurf == is_oce) then      else if (nisurf == is_oce) then
432         ! Surface "ocean" appel a l'interface avec l'ocean         ! Surface "ocean" appel a l'interface avec l'ocean
433         !         if (ocean == 'slab') then
        if (ocean == 'slab  ') then  
434            tsurf_new = tsurf            tsurf_new = tsurf
435            pctsrf_new = tmp_pctsrf_slab            pctsrf_new = tmp_pctsrf_slab
436            !         else
437         else                              ! lecture conditions limites            ! lecture conditions limites
438            call interfoce_lim(itime, dtime, jour, &            call interfoce_lim(itime, dtime, jour, klon, nisurf, knon, knindex, &
439                 &  klon, nisurf, knon, knindex, &                 debut, tsurf_new, pctsrf_new)
                &  debut, &  
                &  tsurf_new, pctsrf_new)  
   
440         endif         endif
441    
442         tsurf_temp = tsurf_new         tsurf_temp = tsurf_new
443         cal = 0.         cal = 0.
444         beta = 1.         beta = 1.
445         dif_grnd = 0.         dif_grnd = 0.
446         alb_neig(:) = 0.         alb_neig = 0.
447         agesno(:) = 0.         agesno = 0.
448    
449         call calcul_fluxs( klon, knon, nisurf, dtime, &         call calcul_fluxs( klon, knon, nisurf, dtime, &
450              &   tsurf_temp, p1lay, cal, beta, tq_cdrag, ps, &              tsurf_temp, p1lay, cal, beta, tq_cdrag, ps, &
451              &   precip_rain, precip_snow, snow, qsurf,  &              precip_rain, precip_snow, snow, qsurf, &
452              &   radsol, dif_grnd, temp_air, spechum, u1_lay, v1_lay, &              radsol, dif_grnd, temp_air, spechum, u1_lay, v1_lay, &
453              &   petAcoef, peqAcoef, petBcoef, peqBcoef, &              petAcoef, peqAcoef, petBcoef, peqBcoef, &
454              &   tsurf_new, evap, fluxlat, fluxsens, dflux_s, dflux_l)              tsurf_new, evap, fluxlat, fluxsens, dflux_s, dflux_l)
455    
456         fder_prev = fder             fder_prev = fder
457         fder = fder_prev + dflux_s + dflux_l         fder = fder_prev + dflux_s + dflux_l
458    
459         iloc = maxloc(fder(1:klon))         iloc = maxloc(fder(1:klon))
460         if (check.and.fder(iloc(1))> 0.) then         if (check.and.fder(iloc(1))> 0.) then
461            WRITE(*,*)'**** Debug fder****'            WRITE(*, *)'**** Debug fder****'
462            WRITE(*,*)'max fder(',iloc(1),') = ',fder(iloc(1))            WRITE(*, *)'max fder(', iloc(1), ') = ', fder(iloc(1))
463            WRITE(*,*)'fder_prev, dflux_s, dflux_l',fder_prev(iloc(1)), &            WRITE(*, *)'fder_prev, dflux_s, dflux_l', fder_prev(iloc(1)), &
464                 &                        dflux_s(iloc(1)), dflux_l(iloc(1))                 dflux_s(iloc(1)), dflux_l(iloc(1))
465         endif         endif
 !!$  
 !!$      where(fder.gt.0.)  
 !!$        fder = 0.  
 !!$      endwhere  
466    
467         !IM: flux ocean-atmosphere utile pour le "slab" ocean         !IM: flux ocean-atmosphere utile pour le "slab" ocean
468         DO i=1, knon         DO i=1, knon
# Line 491  CONTAINS Line 472  CONTAINS
472            tmp_flux_o(knindex(i)) = flux_o(i)            tmp_flux_o(knindex(i)) = flux_o(i)
473            tmp_radsol(knindex(i))=radsol(i)            tmp_radsol(knindex(i))=radsol(i)
474         ENDDO         ENDDO
475         !  
476         ! 2eme appel a interfoce pour le cumul des champs (en particulier         ! 2eme appel a interfoce pour le cumul des champs (en particulier
477         ! fluxsens et fluxlat calcules dans calcul_fluxs)         ! fluxsens et fluxlat calcules dans calcul_fluxs)
478         !  
479         if (ocean == 'slab  ') then         if (ocean == 'slab ') then
           !  
480            seaice=tmp_seaice            seaice=tmp_seaice
481            cumul = .true.            cumul = .true.
482            call interfoce_slab(klon, debut, itime, dtime, jour, &            call interfoce_slab(klon, debut, itime, dtime, jour, &
483                 & tmp_radsol, tmp_flux_o, tmp_flux_g, pctsrf, &                 tmp_radsol, tmp_flux_o, tmp_flux_g, pctsrf, &
484                 & tslab, seaice, pctsrf_new)                 tslab, seaice, pctsrf_new)
485            !  
486            tmp_pctsrf_slab=pctsrf_new            tmp_pctsrf_slab=pctsrf_new
487            DO i=1, knon            DO i=1, knon
488               tsurf_new(i)=tslab(knindex(i))               tsurf_new(i)=tslab(knindex(i))
489            ENDDO !i            ENDDO
           !  
490         endif         endif
491    
        !  
492         ! calcul albedo         ! calcul albedo
        !  
   
493         if ( minval(rmu0) == maxval(rmu0) .and. minval(rmu0) == -999.999 ) then         if ( minval(rmu0) == maxval(rmu0) .and. minval(rmu0) == -999.999 ) then
494            CALL alboc(FLOAT(jour),rlat,alb_eau)            CALL alboc(FLOAT(jour), rlat, alb_eau)
495         else  ! cycle diurne         else ! cycle diurne
496            CALL alboc_cd(rmu0,alb_eau)            CALL alboc_cd(rmu0, alb_eau)
497         endif         endif
498         DO ii =1, knon         DO ii =1, knon
499            alb_new(ii) = alb_eau(knindex(ii))            alb_new(ii) = alb_eau(knindex(ii))
# Line 525  CONTAINS Line 501  CONTAINS
501    
502         z0_new = sqrt(rugos**2 + rugoro**2)         z0_new = sqrt(rugos**2 + rugoro**2)
503         alblw(1:knon) = alb_new(1:knon)         alblw(1:knon) = alb_new(1:knon)
   
        !  
504      else if (nisurf == is_sic) then      else if (nisurf == is_sic) then
505           if (check) write(*, *)'sea ice, nisurf = ', nisurf
506    
        if (check) write(*,*)'sea ice, nisurf = ',nisurf  
   
        !  
507         ! Surface "glace de mer" appel a l'interface avec l'ocean         ! Surface "glace de mer" appel a l'interface avec l'ocean
508         !  
509         !  
510         if (ocean == 'slab  ') then         if (ocean == 'slab ') then
511            pctsrf_new=tmp_pctsrf_slab            pctsrf_new=tmp_pctsrf_slab
512            !  
513            DO ii = 1, knon            DO ii = 1, knon
514               tsurf_new(ii) = tsurf(ii)               tsurf_new(ii) = tsurf(ii)
515               IF (pctsrf_new(knindex(ii),nisurf) < EPSFRA) then               IF (pctsrf_new(knindex(ii), nisurf) < EPSFRA) then
516                  snow(ii) = 0.0                  snow(ii) = 0.0
517                  tsurf_new(ii) = RTT - 1.8                  tsurf_new(ii) = RTT - 1.8
518                  IF (soil_model) tsoil(ii,:) = RTT -1.8                  IF (soil_model) tsoil(ii, :) = RTT -1.8
519               ENDIF               ENDIF
520            ENDDO            ENDDO
521    
522            CALL calbeta(dtime, nisurf, knon, snow, qsol, beta, capsol, dif_grnd)            CALL calbeta(dtime, nisurf, knon, snow, qsol, beta, capsol, dif_grnd)
523    
524            IF (soil_model) THEN            IF (soil_model) THEN
525               CALL soil(dtime, nisurf, knon,snow, tsurf_new, tsoil,soilcap, soilflux)               CALL soil(dtime, nisurf, knon, snow, tsurf_new, tsoil, soilcap, soilflux)
526               cal(1:knon) = RCPD / soilcap(1:knon)               cal(1:knon) = RCPD / soilcap(1:knon)
527               radsol(1:knon) = radsol(1:knon)  + soilflux(1:knon)               radsol(1:knon) = radsol(1:knon) + soilflux(1:knon)
528            ELSE            ELSE
529               dif_grnd = 1.0 / tau_gl               dif_grnd = 1.0 / tau_gl
530               cal = RCPD * calice               cal = RCPD * calice
# Line 560  CONTAINS Line 532  CONTAINS
532            ENDIF            ENDIF
533            tsurf_temp = tsurf_new            tsurf_temp = tsurf_new
534            beta = 1.0            beta = 1.0
535            !  
536         ELSE         ELSE
537            !                              ! lecture conditions limites            ! ! lecture conditions limites
538            CALL interfoce_lim(itime, dtime, jour, &            CALL interfoce_lim(itime, dtime, jour, &
539                 &  klon, nisurf, knon, knindex, &                 klon, nisurf, knon, knindex, &
540                 &  debut, &                 debut, &
541                 &  tsurf_new, pctsrf_new)                 tsurf_new, pctsrf_new)
542    
543            !IM cf LF            !IM cf LF
544            DO ii = 1, knon            DO ii = 1, knon
545               tsurf_new(ii) = tsurf(ii)               tsurf_new(ii) = tsurf(ii)
546               !IMbad IF (pctsrf_new(ii,nisurf) < EPSFRA) then               !IMbad IF (pctsrf_new(ii, nisurf) < EPSFRA) then
547               IF (pctsrf_new(knindex(ii),nisurf) < EPSFRA) then               IF (pctsrf_new(knindex(ii), nisurf) < EPSFRA) then
548                  snow(ii) = 0.0                  snow(ii) = 0.0
549                  !IM cf LF/JLD         tsurf(ii) = RTT - 1.8                  !IM cf LF/JLD tsurf(ii) = RTT - 1.8
550                  tsurf_new(ii) = RTT - 1.8                  tsurf_new(ii) = RTT - 1.8
551                  IF (soil_model) tsoil(ii,:) = RTT -1.8                  IF (soil_model) tsoil(ii, :) = RTT -1.8
552               endif               endif
553            enddo            enddo
554    
555            CALL calbeta(dtime, nisurf, knon, snow, qsol, beta, capsol, dif_grnd)            CALL calbeta(dtime, nisurf, knon, snow, qsol, beta, capsol, dif_grnd)
556    
557            IF (soil_model) THEN            IF (soil_model) THEN
558               !IM cf LF/JLD        CALL soil(dtime, nisurf, knon,snow, tsurf, tsoil,soilcap, soilflux)               !IM cf LF/JLD CALL soil(dtime, nisurf, knon, snow, tsurf, tsoil, soilcap, soilflux)
559               CALL soil(dtime, nisurf, knon,snow, tsurf_new, tsoil,soilcap, soilflux)               CALL soil(dtime, nisurf, knon, snow, tsurf_new, tsoil, soilcap, soilflux)
560               cal(1:knon) = RCPD / soilcap(1:knon)               cal(1:knon) = RCPD / soilcap(1:knon)
561               radsol(1:knon) = radsol(1:knon)  + soilflux(1:knon)               radsol(1:knon) = radsol(1:knon) + soilflux(1:knon)
562               dif_grnd = 0.               dif_grnd = 0.
563            ELSE            ELSE
564               dif_grnd = 1.0 / tau_gl               dif_grnd = 1.0 / tau_gl
# Line 599  CONTAINS Line 571  CONTAINS
571         ENDIF         ENDIF
572    
573         CALL calcul_fluxs( klon, knon, nisurf, dtime, &         CALL calcul_fluxs( klon, knon, nisurf, dtime, &
574              &   tsurf_temp, p1lay, cal, beta, tq_cdrag, ps, &              tsurf_temp, p1lay, cal, beta, tq_cdrag, ps, &
575              &   precip_rain, precip_snow, snow, qsurf,  &              precip_rain, precip_snow, snow, qsurf, &
576              &   radsol, dif_grnd, temp_air, spechum, u1_lay, v1_lay, &              radsol, dif_grnd, temp_air, spechum, u1_lay, v1_lay, &
577              &   petAcoef, peqAcoef, petBcoef, peqBcoef, &              petAcoef, peqAcoef, petBcoef, peqBcoef, &
578              &   tsurf_new, evap, fluxlat, fluxsens, dflux_s, dflux_l)              tsurf_new, evap, fluxlat, fluxsens, dflux_s, dflux_l)
579         !  
580         !IM: flux entre l'ocean et la glace de mer pour le "slab" ocean         !IM: flux entre l'ocean et la glace de mer pour le "slab" ocean
581         DO i = 1, knon         DO i = 1, knon
582            flux_g(i) = 0.0            flux_g(i) = 0.0
583            !  
584            !IM: faire dependre le coefficient de conduction de la glace de mer            !IM: faire dependre le coefficient de conduction de la glace de mer
585            !    de l'epaisseur de la glace de mer, dans l'hypothese ou le coeff.            ! de l'epaisseur de la glace de mer, dans l'hypothese ou le coeff.
586            !    actuel correspond a 3m de glace de mer, cf. L.Li            ! actuel correspond a 3m de glace de mer, cf. L.Li
587            !  
588            !      IF(1.EQ.0) THEN            ! IF(1.EQ.0) THEN
589            !       IF(siceh(i).GT.0.) THEN            ! IF(siceh(i).GT.0.) THEN
590            !        new_dif_grnd(i) = dif_grnd(i)*3./siceh(i)            ! new_dif_grnd(i) = dif_grnd(i)*3./siceh(i)
591            !       ELSE            ! ELSE
592            !        new_dif_grnd(i) = 0.            ! new_dif_grnd(i) = 0.
593            !       ENDIF            ! ENDIF
594            !      ENDIF !(1.EQ.0) THEN            ! ENDIF !(1.EQ.0) THEN
595            !  
596            IF (cal(i).GT.1.0e-15) flux_g(i)=(tsurf_new(i)-t_grnd) &            IF (cal(i).GT.1.0e-15) flux_g(i)=(tsurf_new(i)-t_grnd) &
597                 &                          * dif_grnd(i) *RCPD/cal(i)                 * dif_grnd(i) *RCPD/cal(i)
598            !   &                          * new_dif_grnd(i) *RCPD/cal(i)            ! & * new_dif_grnd(i) *RCPD/cal(i)
599            tmp_flux_g(knindex(i))=flux_g(i)            tmp_flux_g(knindex(i))=flux_g(i)
600            tmp_radsol(knindex(i))=radsol(i)            tmp_radsol(knindex(i))=radsol(i)
601         ENDDO         ENDDO
602    
603         CALL fonte_neige( klon, knon, nisurf, dtime, &         CALL fonte_neige( klon, knon, nisurf, dtime, &
604              &   tsurf_temp, p1lay, cal, beta, tq_cdrag, ps, &              tsurf_temp, p1lay, cal, beta, tq_cdrag, ps, &
605              &   precip_rain, precip_snow, snow, qsol,  &              precip_rain, precip_snow, snow, qsol, &
606              &   radsol, dif_grnd, temp_air, spechum, u1_lay, v1_lay, &              radsol, dif_grnd, temp_air, spechum, u1_lay, v1_lay, &
607              &   petAcoef, peqAcoef, petBcoef, peqBcoef, &              petAcoef, peqAcoef, petBcoef, peqBcoef, &
608              &   tsurf_new, evap, fluxlat, fluxsens, dflux_s, dflux_l, &              tsurf_new, evap, fluxlat, fluxsens, dflux_s, dflux_l, &
609              &   fqcalving,ffonte, run_off_lic_0)              fqcalving, ffonte, run_off_lic_0)
610    
611         !     calcul albedo         ! calcul albedo
612    
613         CALL albsno(klon,knon,dtime,agesno(:),alb_neig(:), precip_snow(:))           CALL albsno(klon, knon, dtime, agesno, alb_neig, precip_snow)
614         WHERE (snow(1 : knon) .LT. 0.0001) agesno(1 : knon) = 0.         WHERE (snow(1 : knon) .LT. 0.0001) agesno(1 : knon) = 0.
615         zfra(1:knon) = MAX(0.0,MIN(1.0,snow(1:knon)/(snow(1:knon)+10.0)))         zfra(1:knon) = MAX(0.0, MIN(1.0, snow(1:knon)/(snow(1:knon)+10.0)))
616         alb_new(1 : knon) = alb_neig(1 : knon) *zfra(1:knon) + &         alb_new(1 : knon) = alb_neig(1 : knon) *zfra(1:knon) + &
617              0.6 * (1.0-zfra(1:knon))              0.6 * (1.0-zfra(1:knon))
618    
619         fder_prev = fder             fder_prev = fder
620         fder = fder_prev + dflux_s + dflux_l         fder = fder_prev + dflux_s + dflux_l
621    
622         iloc = maxloc(fder(1:klon))         iloc = maxloc(fder(1:klon))
623         if (check.and.fder(iloc(1))> 0.) then         if (check.and.fder(iloc(1))> 0.) then
624            WRITE(*,*)'**** Debug fder ****'            WRITE(*, *)'**** Debug fder ****'
625            WRITE(*,*)'max fder(',iloc(1),') = ',fder(iloc(1))            WRITE(*, *)'max fder(', iloc(1), ') = ', fder(iloc(1))
626            WRITE(*,*)'fder_prev, dflux_s, dflux_l',fder_prev(iloc(1)), &            WRITE(*, *)'fder_prev, dflux_s, dflux_l', fder_prev(iloc(1)), &
627                 &                        dflux_s(iloc(1)), dflux_l(iloc(1))                 dflux_s(iloc(1)), dflux_l(iloc(1))
628         endif         endif
629    
630         !  
631         ! 2eme appel a interfoce pour le cumul et le passage des flux a l'ocean         ! 2eme appel a interfoce pour le cumul et le passage des flux a l'ocean
632         !  
633         z0_new = 0.002         z0_new = 0.002
634         z0_new = SQRT(z0_new**2+rugoro**2)         z0_new = SQRT(z0_new**2+rugoro**2)
635         alblw(1:knon) = alb_new(1:knon)         alblw(1:knon) = alb_new(1:knon)
636    
637      else if (nisurf == is_lic) then      else if (nisurf == is_lic) then
638    
639         if (check) write(*,*)'glacier, nisurf = ',nisurf         if (check) write(*, *)'glacier, nisurf = ', nisurf
640    
641         if (.not. allocated(run_off_lic)) then         if (.not. allocated(run_off_lic)) then
642            allocate(run_off_lic(knon), stat = error)            allocate(run_off_lic(knon), stat = error)
643            if (error /= 0) then            if (error /= 0) then
644               abort_message='Pb allocation run_off_lic'               abort_message='Pb allocation run_off_lic'
645               call abort_gcm(modname,abort_message,1)               call abort_gcm(modname, abort_message, 1)
646            endif            endif
647            run_off_lic = 0.            run_off_lic = 0.
648         endif         endif
649         !  
650         ! Surface "glacier continentaux" appel a l'interface avec le sol         ! Surface "glacier continentaux" appel a l'interface avec le sol
651         !  
652         IF (soil_model) THEN         IF (soil_model) THEN
653            CALL soil(dtime, nisurf, knon, snow, tsurf, tsoil,soilcap, soilflux)            CALL soil(dtime, nisurf, knon, snow, tsurf, tsoil, soilcap, soilflux)
654            cal(1:knon) = RCPD / soilcap(1:knon)            cal(1:knon) = RCPD / soilcap(1:knon)
655            radsol(1:knon)  = radsol(1:knon) + soilflux(1:knon)            radsol(1:knon) = radsol(1:knon) + soilflux(1:knon)
656         ELSE         ELSE
657            cal = RCPD * calice            cal = RCPD * calice
658            WHERE (snow > 0.0) cal = RCPD * calsno            WHERE (snow > 0.0) cal = RCPD * calsno
# Line 689  CONTAINS Line 661  CONTAINS
661         dif_grnd = 0.0         dif_grnd = 0.0
662    
663         call calcul_fluxs( klon, knon, nisurf, dtime, &         call calcul_fluxs( klon, knon, nisurf, dtime, &
664              &   tsurf, p1lay, cal, beta, tq_cdrag, ps, &              tsurf, p1lay, cal, beta, tq_cdrag, ps, &
665              &   precip_rain, precip_snow, snow, qsurf,  &              precip_rain, precip_snow, snow, qsurf, &
666              &   radsol, dif_grnd, temp_air, spechum, u1_lay, v1_lay, &              radsol, dif_grnd, temp_air, spechum, u1_lay, v1_lay, &
667              &   petAcoef, peqAcoef, petBcoef, peqBcoef, &              petAcoef, peqAcoef, petBcoef, peqBcoef, &
668              &   tsurf_new, evap, fluxlat, fluxsens, dflux_s, dflux_l)              tsurf_new, evap, fluxlat, fluxsens, dflux_s, dflux_l)
669    
670         call fonte_neige( klon, knon, nisurf, dtime, &         call fonte_neige( klon, knon, nisurf, dtime, &
671              &   tsurf, p1lay, cal, beta, tq_cdrag, ps, &              tsurf, p1lay, cal, beta, tq_cdrag, ps, &
672              &   precip_rain, precip_snow, snow, qsol,  &              precip_rain, precip_snow, snow, qsol, &
673              &   radsol, dif_grnd, temp_air, spechum, u1_lay, v1_lay, &              radsol, dif_grnd, temp_air, spechum, u1_lay, v1_lay, &
674              &   petAcoef, peqAcoef, petBcoef, peqBcoef, &              petAcoef, peqAcoef, petBcoef, peqBcoef, &
675              &   tsurf_new, evap, fluxlat, fluxsens, dflux_s, dflux_l, &              tsurf_new, evap, fluxlat, fluxsens, dflux_s, dflux_l, &
676              &   fqcalving,ffonte, run_off_lic_0)              fqcalving, ffonte, run_off_lic_0)
677    
678         ! passage du run-off des glaciers calcule dans fonte_neige au coupleur         ! passage du run-off des glaciers calcule dans fonte_neige au coupleur
679         bidule=0.         bidule=0.
680         bidule(1:knon)= run_off_lic(1:knon)             bidule(1:knon)= run_off_lic(1:knon)
681         call gath2cpl(bidule, tmp_rlic, klon, knon,iim,jjm,knindex)         call gath2cpl(bidule, tmp_rlic, klon, knon, iim, jjm, knindex)
682         !  
683         ! calcul albedo         ! calcul albedo
684         !  
685         CALL albsno(klon,knon,dtime,agesno(:),alb_neig(:), precip_snow(:))           CALL albsno(klon, knon, dtime, agesno, alb_neig, precip_snow)
686         WHERE (snow(1 : knon) .LT. 0.0001) agesno(1 : knon) = 0.         WHERE (snow(1 : knon) .LT. 0.0001) agesno(1 : knon) = 0.
687         zfra(1:knon) = MAX(0.0,MIN(1.0,snow(1:knon)/(snow(1:knon)+10.0)))         zfra(1:knon) = MAX(0.0, MIN(1.0, snow(1:knon)/(snow(1:knon)+10.0)))
688         alb_new(1 : knon)  = alb_neig(1 : knon)*zfra(1:knon) + &         alb_new(1 : knon) = alb_neig(1 : knon)*zfra(1:knon) + &
689              &                     0.6 * (1.0-zfra(1:knon))              0.6 * (1.0-zfra(1:knon))
690         !  
691         !IM: plusieurs choix/tests sur l'albedo des "glaciers continentaux"         !IM: plusieurs choix/tests sur l'albedo des "glaciers continentaux"
692         !       alb_new(1 : knon)  = 0.6 !IM cf FH/GK         ! alb_new(1 : knon) = 0.6 !IM cf FH/GK
693         !       alb_new(1 : knon)  = 0.82         ! alb_new(1 : knon) = 0.82
694         !       alb_new(1 : knon)  = 0.77 !211003 Ksta0.77         ! alb_new(1 : knon) = 0.77 !211003 Ksta0.77
695         !       alb_new(1 : knon)  = 0.8 !KstaTER0.8 & LMD_ARMIP5         ! alb_new(1 : knon) = 0.8 !KstaTER0.8 & LMD_ARMIP5
696         !IM: KstaTER0.77 & LMD_ARMIP6             !IM: KstaTER0.77 & LMD_ARMIP6
697         alb_new(1 : knon)  = 0.77         alb_new(1 : knon) = 0.77
698    
699    
        !  
700         ! Rugosite         ! Rugosite
701         !  
702         z0_new = rugoro         z0_new = rugoro
703         !  
704         ! Remplissage des pourcentages de surface         ! Remplissage des pourcentages de surface
705         !  
706         pctsrf_new(:,nisurf) = pctsrf(:,nisurf)         pctsrf_new(:, nisurf) = pctsrf(:, nisurf)
707    
708         alblw(1:knon) = alb_new(1:knon)         alblw(1:knon) = alb_new(1:knon)
709      else      else
710         write(*,*)'Index surface = ',nisurf         write(*, *)'Index surface = ', nisurf
711         abort_message = 'Index surface non valable'         abort_message = 'Index surface non valable'
712         call abort_gcm(modname,abort_message,1)         call abort_gcm(modname, abort_message, 1)
713      endif      endif
714    
715    END SUBROUTINE interfsurf_hq    END SUBROUTINE interfsurf_hq
716    
717    !************************    !************************
718    
719    SUBROUTINE interfoce_slab(klon, debut, itap, dtime, ijour, &    SUBROUTINE interfoce_slab(klon, debut, itap, dtime, ijour,  &
720         & radsol, fluxo, fluxg, pctsrf, &         radsol, fluxo, fluxg, pctsrf,  &
721         & tslab, seaice, pctsrf_slab)         tslab, seaice, pctsrf_slab)
722      !  
723      ! Cette routine calcule la temperature d'un slab ocean, la glace de mer      ! Cette routine calcule la temperature d'un slab ocean, la glace de mer
724      ! et les pourcentages de la maille couverte par l'ocean libre et/ou      ! et les pourcentages de la maille couverte par l'ocean libre et/ou
725      ! la glace de mer pour un "slab" ocean de 50m      ! la glace de mer pour un "slab" ocean de 50m
726      !  
727      ! I. Musat 04.02.2005      ! I. Musat 04.02.2005
728      !  
729      ! input:      ! input:
730      !   klon         nombre total de points de grille      ! klon nombre total de points de grille
731      !   debut        logical: 1er appel a la physique      ! debut logical: 1er appel a la physique
732      !   itap         numero du pas de temps      ! itap numero du pas de temps
733      !   dtime        pas de temps de la physique (en s)      ! dtime pas de temps de la physique (en s)
734      !   ijour        jour dans l'annee en cours      ! ijour jour dans l'annee en cours
735      !   radsol       rayonnement net au sol (LW + SW)      ! radsol rayonnement net au sol (LW + SW)
736      !   fluxo        flux turbulent (sensible + latent) sur les mailles oceaniques      ! fluxo flux turbulent (sensible + latent) sur les mailles oceaniques
737      !   fluxg        flux de conduction entre la surface de la glace de mer et l'ocean      ! fluxg flux de conduction entre la surface de la glace de mer et l'ocean
738      !   pctsrf       tableau des pourcentages de surface de chaque maille      ! pctsrf tableau des pourcentages de surface de chaque maille
739      ! output:      ! output:
740      !   tslab        temperature de l'ocean libre      ! tslab temperature de l'ocean libre
741      !   seaice       glace de mer (kg/m2)      ! seaice glace de mer (kg/m2)
742      !   pctsrf_slab  "pourcentages" (valeurs entre 0. et 1.) surfaces issus du slab      ! pctsrf_slab "pourcentages" (valeurs entre 0. et 1.) surfaces issus du slab
743      !  
744      use indicesol      use indicesol
745      use clesphys      use clesphys
746      use abort_gcm_m, only: abort_gcm      use abort_gcm_m, only: abort_gcm
747      use YOMCST      use SUPHEC_M
748    
749      ! Parametres d'entree      ! Parametres d'entree
750      integer, intent(IN) :: klon      integer, intent(IN) :: klon
# Line 786  CONTAINS Line 758  CONTAINS
758      real, dimension(klon, nbsrf), intent(IN) :: pctsrf      real, dimension(klon, nbsrf), intent(IN) :: pctsrf
759      ! Parametres de sortie      ! Parametres de sortie
760      real, dimension(klon), intent(INOUT) :: tslab      real, dimension(klon), intent(INOUT) :: tslab
761      real, dimension(klon), intent(INOUT)        :: seaice ! glace de mer (kg/m2)      real, dimension(klon), intent(INOUT) :: seaice ! glace de mer (kg/m2)
762      real, dimension(klon, nbsrf), intent(OUT) :: pctsrf_slab      real, dimension(klon, nbsrf), intent(OUT) :: pctsrf_slab
763      !  
764      ! Variables locales :      ! Variables locales :
765      INTEGER, save :: lmt_pas, julien, idayvrai      INTEGER, save :: lmt_pas, julien, idayvrai
766      REAL, parameter :: unjour=86400.      REAL, parameter :: unjour=86400.
767      real, allocatable, dimension(:), save :: tmp_tslab, tmp_seaice      real, allocatable, dimension(:), save :: tmp_tslab, tmp_seaice
768      REAL, allocatable, dimension(:), save :: slab_bils      REAL, allocatable, dimension(:), save :: slab_bils
769      REAL, allocatable, dimension(:), save :: lmt_bils      REAL, allocatable, dimension(:), save :: lmt_bils
770      logical,save              :: check = .false.      logical, save :: check = .false.
771      !  
772      REAL, parameter :: cyang=50.0 * 4.228e+06 ! capacite calorifique volumetrique de l'eau J/(m2 K)      REAL, parameter :: cyang=50.0 * 4.228e+06 ! capacite calorifique volumetrique de l'eau J/(m2 K)
773      REAL, parameter :: cbing=0.334e+05        ! J/kg      REAL, parameter :: cbing=0.334e+05 ! J/kg
774      real, dimension(klon)                 :: siceh !hauteur de la glace de mer (m)      real, dimension(klon) :: siceh !hauteur de la glace de mer (m)
775      INTEGER :: i      INTEGER :: i
776      integer :: sum_error, error      integer :: sum_error, error
777      REAL :: zz, za, zb      REAL :: zz, za, zb
778      !  
779      character (len = 80) :: abort_message      character (len = 80) :: abort_message
780      character (len = 20) :: modname = 'interfoce_slab'      character (len = 20) :: modname = 'interfoce_slab'
781      !  
782      julien = MOD(ijour,360)      julien = MOD(ijour, 360)
783      sum_error = 0      sum_error = 0
784      IF (debut) THEN      IF (debut) THEN
785         allocate(slab_bils(klon), stat = error); sum_error = sum_error + error         allocate(slab_bils(klon), stat = error); sum_error = sum_error + error
# Line 815  CONTAINS Line 787  CONTAINS
787         allocate(tmp_tslab(klon), stat = error); sum_error = sum_error + error         allocate(tmp_tslab(klon), stat = error); sum_error = sum_error + error
788         allocate(tmp_seaice(klon), stat = error); sum_error = sum_error + error         allocate(tmp_seaice(klon), stat = error); sum_error = sum_error + error
789         if (sum_error /= 0) then         if (sum_error /= 0) then
790            abort_message='Pb allocation var. slab_bils,lmt_bils,tmp_tslab,tmp_seaice'            abort_message='Pb allocation var. slab_bils, lmt_bils, tmp_tslab, tmp_seaice'
791            call abort_gcm(modname,abort_message,1)            call abort_gcm(modname, abort_message, 1)
792         endif         endif
793         tmp_tslab=tslab         tmp_tslab=tslab
794         tmp_seaice=seaice         tmp_seaice=seaice
795         lmt_pas = nint(86400./dtime * 1.0) ! pour une lecture une fois par jour         lmt_pas = nint(86400./dtime * 1.0) ! pour une lecture une fois par jour
796         !  
797         IF (check) THEN         IF (check) THEN
798            PRINT*,'interfoce_slab klon, debut, itap, dtime, ijour, &            PRINT*, 'interfoce_slab klon, debut, itap, dtime, ijour, &
799                 &          lmt_pas ', klon, debut, itap, dtime, ijour, &                 & lmt_pas ', klon, debut, itap, dtime, ijour, &
800                 &          lmt_pas                 lmt_pas
801         ENDIF !check         ENDIF !check
802         !  
803         PRINT*, '************************'         PRINT*, '************************'
804         PRINT*, 'SLAB OCEAN est actif, prenez precautions !'         PRINT*, 'SLAB OCEAN est actif, prenez precautions !'
805         PRINT*, '************************'         PRINT*, '************************'
806         !  
807         ! a mettre un slab_bils aussi en force !!!         ! a mettre un slab_bils aussi en force !!!
808         !  
809         DO i = 1, klon         DO i = 1, klon
810            slab_bils(i) = 0.0            slab_bils(i) = 0.0
811         ENDDO         ENDDO
812         !  
813      ENDIF !debut      ENDIF !debut
814      pctsrf_slab(1:klon,1:nbsrf) = pctsrf(1:klon,1:nbsrf)      pctsrf_slab(1:klon, 1:nbsrf) = pctsrf(1:klon, 1:nbsrf)
815      !  
816      ! lecture du bilan au sol lmt_bils issu d'une simulation forcee en debut de journee      ! lecture du bilan au sol lmt_bils issu d'une simulation forcee en debut de journee
817      !  
818      IF (MOD(itap,lmt_pas) .EQ. 1) THEN !1er pas de temps de la journee      IF (MOD(itap, lmt_pas) .EQ. 1) THEN !1er pas de temps de la journee
819         idayvrai = ijour         idayvrai = ijour
820         CALL condsurf(julien,idayvrai, lmt_bils)         CALL condsurf(julien, idayvrai, lmt_bils)
821      ENDIF !(MOD(itap-1,lmt_pas) .EQ. 0) THEN      ENDIF !(MOD(itap-1, lmt_pas) .EQ. 0) THEN
822    
823      DO i = 1, klon      DO i = 1, klon
824         IF((pctsrf_slab(i,is_oce).GT.epsfra).OR. &         IF((pctsrf_slab(i, is_oce).GT.epsfra).OR. &
825              &  (pctsrf_slab(i,is_sic).GT.epsfra)) THEN              (pctsrf_slab(i, is_sic).GT.epsfra)) THEN
826            !  
827            ! fabriquer de la glace si congelation atteinte:            ! fabriquer de la glace si congelation atteinte:
828            !  
829            IF (tmp_tslab(i).LT.(RTT-1.8)) THEN            IF (tmp_tslab(i).LT.(RTT-1.8)) THEN
830               zz =  (RTT-1.8)-tmp_tslab(i)               zz = (RTT-1.8)-tmp_tslab(i)
831               tmp_seaice(i) = tmp_seaice(i) + cyang/cbing * zz               tmp_seaice(i) = tmp_seaice(i) + cyang/cbing * zz
832               seaice(i) = tmp_seaice(i)               seaice(i) = tmp_seaice(i)
833               tmp_tslab(i) = RTT-1.8               tmp_tslab(i) = RTT-1.8
834            ENDIF            ENDIF
835            !  
836            ! faire fondre de la glace si temperature est superieure a 0:            ! faire fondre de la glace si temperature est superieure a 0:
837            !  
838            IF ((tmp_tslab(i).GT.RTT) .AND. (tmp_seaice(i).GT.0.0)) THEN            IF ((tmp_tslab(i).GT.RTT) .AND. (tmp_seaice(i).GT.0.0)) THEN
839               zz = cyang/cbing * (tmp_tslab(i)-RTT)               zz = cyang/cbing * (tmp_tslab(i)-RTT)
840               zz = MIN(zz,tmp_seaice(i))               zz = MIN(zz, tmp_seaice(i))
841               tmp_seaice(i) = tmp_seaice(i) - zz               tmp_seaice(i) = tmp_seaice(i) - zz
842               seaice(i) = tmp_seaice(i)               seaice(i) = tmp_seaice(i)
843               tmp_tslab(i) = tmp_tslab(i) - zz*cbing/cyang               tmp_tslab(i) = tmp_tslab(i) - zz*cbing/cyang
844            ENDIF            ENDIF
845            !  
846            ! limiter la glace de mer a 10 metres (10000 kg/m2)            ! limiter la glace de mer a 10 metres (10000 kg/m2)
847            !  
848            IF(tmp_seaice(i).GT.45.) THEN            IF(tmp_seaice(i).GT.45.) THEN
849               tmp_seaice(i) = MIN(tmp_seaice(i),10000.0)               tmp_seaice(i) = MIN(tmp_seaice(i), 10000.0)
850            ELSE            ELSE
851               tmp_seaice(i) = 0.               tmp_seaice(i) = 0.
852            ENDIF            ENDIF
853            seaice(i) = tmp_seaice(i)            seaice(i) = tmp_seaice(i)
854            siceh(i)=tmp_seaice(i)/1000. !en metres            siceh(i)=tmp_seaice(i)/1000. !en metres
855            !  
856            ! determiner la nature du sol (glace de mer ou ocean libre):            ! determiner la nature du sol (glace de mer ou ocean libre):
857            !  
858            ! on fait dependre la fraction de seaice "pctsrf(i,is_sic)"            ! on fait dependre la fraction de seaice "pctsrf(i, is_sic)"
859            ! de l'epaisseur de seaice :            ! de l'epaisseur de seaice :
860            ! pctsrf(i,is_sic)=1. si l'epaisseur de la glace de mer est >= a 20cm            ! pctsrf(i, is_sic)=1. si l'epaisseur de la glace de mer est >= a 20cm
861            ! et pctsrf(i,is_sic) croit lineairement avec seaice de 0. a 20cm d'epaisseur            ! et pctsrf(i, is_sic) croit lineairement avec seaice de 0. a 20cm d'epaisseur
862            !  
863            pctsrf_slab(i,is_sic)=MIN(siceh(i)/0.20, &            pctsrf_slab(i, is_sic)=MIN(siceh(i)/0.20, &
864                 &                      1.-(pctsrf_slab(i,is_ter)+pctsrf_slab(i,is_lic)))                 1.-(pctsrf_slab(i, is_ter)+pctsrf_slab(i, is_lic)))
865            pctsrf_slab(i,is_oce)=1.0 - &            pctsrf_slab(i, is_oce)=1.0 - &
866                 &      (pctsrf_slab(i,is_ter)+pctsrf_slab(i,is_lic)+pctsrf_slab(i,is_sic))                 (pctsrf_slab(i, is_ter)+pctsrf_slab(i, is_lic)+pctsrf_slab(i, is_sic))
867         ENDIF !pctsrf         ENDIF !pctsrf
868      ENDDO      ENDDO
869      !  
870      ! Calculer le bilan du flux de chaleur au sol :      ! Calculer le bilan du flux de chaleur au sol :
871      !  
872      DO i = 1, klon      DO i = 1, klon
873         za = radsol(i) + fluxo(i)         za = radsol(i) + fluxo(i)
874         zb = fluxg(i)         zb = fluxg(i)
875         IF((pctsrf_slab(i,is_oce).GT.epsfra).OR. &         IF((pctsrf_slab(i, is_oce).GT.epsfra).OR. &
876              &   (pctsrf_slab(i,is_sic).GT.epsfra)) THEN              (pctsrf_slab(i, is_sic).GT.epsfra)) THEN
877            slab_bils(i)=slab_bils(i)+(za*pctsrf_slab(i,is_oce) &            slab_bils(i)=slab_bils(i)+(za*pctsrf_slab(i, is_oce) &
878                 &             +zb*pctsrf_slab(i,is_sic))/ FLOAT(lmt_pas)                 +zb*pctsrf_slab(i, is_sic))/ FLOAT(lmt_pas)
879         ENDIF         ENDIF
880      ENDDO !klon      ENDDO !klon
881      !  
882      ! calcul tslab      ! calcul tslab
883      !  
884      IF (MOD(itap,lmt_pas).EQ.0) THEN !fin de journee      IF (MOD(itap, lmt_pas).EQ.0) THEN !fin de journee
885         DO i = 1, klon         DO i = 1, klon
886            IF ((pctsrf_slab(i,is_oce).GT.epsfra).OR. &            IF ((pctsrf_slab(i, is_oce).GT.epsfra).OR. &
887                 &    (pctsrf_slab(i,is_sic).GT.epsfra)) THEN                 (pctsrf_slab(i, is_sic).GT.epsfra)) THEN
888               tmp_tslab(i) = tmp_tslab(i) + &               tmp_tslab(i) = tmp_tslab(i) + &
889                    & (slab_bils(i)-lmt_bils(i)) &                    (slab_bils(i)-lmt_bils(i)) &
890                    &                         /cyang*unjour                    /cyang*unjour
891               ! on remet l'accumulation a 0               ! on remet l'accumulation a 0
892               slab_bils(i) = 0.               slab_bils(i) = 0.
893            ENDIF !pctsrf            ENDIF !pctsrf
894         ENDDO !klon         ENDDO !klon
895      ENDIF !(MOD(itap,lmt_pas).EQ.0) THEN      ENDIF !(MOD(itap, lmt_pas).EQ.0) THEN
896      !  
897      tslab = tmp_tslab      tslab = tmp_tslab
898      seaice = tmp_seaice      seaice = tmp_seaice
899    END SUBROUTINE interfoce_slab    END SUBROUTINE interfoce_slab
900    
901    !************************    !************************
902    
903    SUBROUTINE interfoce_lim(itime, dtime, jour, &    SUBROUTINE interfoce_lim(itime, dtime, jour,  &
904         & klon, nisurf, knon, knindex, &         klon, nisurf, knon, knindex,  &
905         & debut,  &         debut,  &
906         & lmt_sst, pctsrf_new)         lmt_sst, pctsrf_new)
907    
908      ! Cette routine sert d'interface entre le modele atmospherique et un fichier      ! Cette routine sert d'interface entre le modele atmospherique et
909      ! de conditions aux limites      ! un fichier de conditions aux limites
910      !  
911      ! L. Fairhead 02/2000      ! L. Fairhead 02/2000
     !  
     ! input:  
     !   itime        numero du pas de temps courant  
     !   dtime        pas de temps de la physique (en s)  
     !   jour         jour a lire dans l'annee  
     !   nisurf       index de la surface a traiter (1 = sol continental)  
     !   knon         nombre de points dans le domaine a traiter  
     !   knindex      index des points de la surface a traiter  
     !   klon         taille de la grille  
     !   debut        logical: 1er appel a la physique (initialisation)  
     !  
     ! output:  
     !   lmt_sst      SST lues dans le fichier de CL  
     !   pctsrf_new   sous-maille fractionnelle  
     !  
912    
913      use abort_gcm_m, only: abort_gcm      use abort_gcm_m, only: abort_gcm
914      use indicesol      use indicesol
915    
916      ! Parametres d'entree      integer, intent(IN) :: itime ! numero du pas de temps courant
917      integer, intent(IN) :: itime      real , intent(IN) :: dtime ! pas de temps de la physique (en s)
918      real   , intent(IN) :: dtime      integer, intent(IN) :: jour ! jour a lire dans l'annee
919      integer, intent(IN) :: jour      integer, intent(IN) :: nisurf ! index de la surface a traiter (1 = sol continental)
920      integer, intent(IN) :: nisurf      integer, intent(IN) :: knon ! nombre de points dans le domaine a traiter
921      integer, intent(IN) :: knon      integer, intent(IN) :: klon ! taille de la grille
922      integer, intent(IN) :: klon      integer, dimension(klon), intent(in) :: knindex ! index des points de la surface a traiter
923      integer, dimension(klon), intent(in) :: knindex      logical, intent(IN) :: debut ! logical: 1er appel a la physique (initialisation)
     logical, intent(IN) :: debut  
924    
925      ! Parametres de sortie      ! Parametres de sortie
926        ! output:
927        ! lmt_sst SST lues dans le fichier de CL
928        ! pctsrf_new sous-maille fractionnelle
929      real, intent(out), dimension(klon) :: lmt_sst      real, intent(out), dimension(klon) :: lmt_sst
930      real, intent(out), dimension(klon,nbsrf) :: pctsrf_new      real, intent(out), dimension(klon, nbsrf) :: pctsrf_new
931    
932      ! Variables locales      ! Variables locales
933      integer     :: ii      integer :: ii
934      INTEGER,save :: lmt_pas     ! frequence de lecture des conditions limites      INTEGER, save :: lmt_pas ! frequence de lecture des conditions limites
935      ! (en pas de physique)      ! (en pas de physique)
936      logical,save :: deja_lu    ! pour indiquer que le jour a lire a deja      logical, save :: deja_lu ! pour indiquer que le jour a lire a deja
937      ! lu pour une surface precedente      ! lu pour une surface precedente
938      integer,save :: jour_lu      integer, save :: jour_lu
939      integer      :: ierr      integer :: ierr
940      character (len = 20) :: modname = 'interfoce_lim'      character (len = 20) :: modname = 'interfoce_lim'
941      character (len = 80) :: abort_message      character (len = 80) :: abort_message
942      logical, save     :: newlmt = .TRUE.      logical, save :: newlmt = .TRUE.
943      logical, save     :: check = .FALSE.      logical, save :: check = .FALSE.
944      ! Champs lus dans le fichier de CL      ! Champs lus dans le fichier de CL
945      real, allocatable , save, dimension(:) :: sst_lu, rug_lu, nat_lu      real, allocatable , save, dimension(:) :: sst_lu, rug_lu, nat_lu
946      real, allocatable , save, dimension(:,:) :: pct_tmp      real, allocatable , save, dimension(:, :) :: pct_tmp
947      !  
948      ! quelques variables pour netcdf      ! quelques variables pour netcdf
949      !  
950      include "netcdf.inc"      include "netcdf.inc"
951      integer              :: nid, nvarid      integer :: nid, nvarid
952      integer, dimension(2) :: start, epais      integer, dimension(2) :: start, epais
953      !  
954      ! Fin déclaration      ! --------------------------------------------------
     !  
955    
956      if (debut .and. .not. allocated(sst_lu)) then      if (debut .and. .not. allocated(sst_lu)) then
957         lmt_pas = nint(86400./dtime * 1.0) ! pour une lecture une fois par jour         lmt_pas = nint(86400./dtime * 1.0) ! pour une lecture une fois par jour
958         jour_lu = jour - 1         jour_lu = jour - 1
959         allocate(sst_lu(klon))         allocate(sst_lu(klon))
960         allocate(nat_lu(klon))         allocate(nat_lu(klon))
961         allocate(pct_tmp(klon,nbsrf))         allocate(pct_tmp(klon, nbsrf))
962      endif      endif
963    
964      if ((jour - jour_lu) /= 0) deja_lu = .false.      if ((jour - jour_lu) /= 0) deja_lu = .false.
965    
966      if (check) write(*,*)modname,' :: jour, jour_lu, deja_lu', jour, jour_lu, &      if (check) write(*, *)modname, ' :: jour, jour_lu, deja_lu', jour, jour_lu, &
967           deja_lu           deja_lu
968      if (check) write(*,*)modname,' :: itime, lmt_pas ', itime, lmt_pas,dtime      if (check) write(*, *)modname, ' :: itime, lmt_pas ', itime, lmt_pas, dtime
969    
970      ! Tester d'abord si c'est le moment de lire le fichier      ! Tester d'abord si c'est le moment de lire le fichier
971      if (mod(itime-1, lmt_pas) == 0 .and. .not. deja_lu) then      if (mod(itime-1, lmt_pas) == 0 .and. .not. deja_lu) then
972         !  
973         ! Ouverture du fichier         ! Ouverture du fichier
974         !  
975         ierr = NF_OPEN ('limit.nc', NF_NOWRITE,nid)         ierr = NF_OPEN ('limit.nc', NF_NOWRITE, nid)
976         if (ierr.NE.NF_NOERR) then         if (ierr.NE.NF_NOERR) then
977            abort_message &            abort_message &
978                 = 'Pb d''ouverture du fichier de conditions aux limites'                 = 'Pb d''ouverture du fichier de conditions aux limites'
979            call abort_gcm(modname,abort_message,1)            call abort_gcm(modname, abort_message, 1)
980         endif         endif
981         !  
982         ! La tranche de donnees a lire:         ! La tranche de donnees a lire:
983         !  
984         start(1) = 1         start(1) = 1
985         start(2) = jour         start(2) = jour
986         epais(1) = klon         epais(1) = klon
987         epais(2) = 1         epais(2) = 1
988         !  
989         if (newlmt) then         if (newlmt) then
990            !  
991            ! Fraction "ocean"            ! Fraction "ocean"
992            !  
993            ierr = NF_INQ_VARID(nid, 'FOCE', nvarid)            ierr = NF_INQ_VARID(nid, 'FOCE', nvarid)
994            if (ierr /= NF_NOERR) then            if (ierr /= NF_NOERR) then
995               abort_message = 'Le champ <FOCE> est absent'               abort_message = 'Le champ <FOCE> est absent'
996               call abort_gcm(modname,abort_message,1)               call abort_gcm(modname, abort_message, 1)
997            endif            endif
998            ierr = NF_GET_VARA_REAL(nid,nvarid,start,epais,pct_tmp(1,is_oce))            ierr = NF_GET_VARA_REAL(nid, nvarid, start, epais, pct_tmp(1, is_oce))
999            if (ierr /= NF_NOERR) then            if (ierr /= NF_NOERR) then
1000               abort_message = 'Lecture echouee pour <FOCE>'               abort_message = 'Lecture echouee pour <FOCE>'
1001               call abort_gcm(modname,abort_message,1)               call abort_gcm(modname, abort_message, 1)
1002            endif            endif
1003            !  
1004            ! Fraction "glace de mer"            ! Fraction "glace de mer"
1005            !  
1006            ierr = NF_INQ_VARID(nid, 'FSIC', nvarid)            ierr = NF_INQ_VARID(nid, 'FSIC', nvarid)
1007            if (ierr /= NF_NOERR) then            if (ierr /= NF_NOERR) then
1008               abort_message = 'Le champ <FSIC> est absent'               abort_message = 'Le champ <FSIC> est absent'
1009               call abort_gcm(modname,abort_message,1)               call abort_gcm(modname, abort_message, 1)
1010            endif            endif
1011            ierr = NF_GET_VARA_REAL(nid,nvarid,start,epais,pct_tmp(1,is_sic))            ierr = NF_GET_VARA_REAL(nid, nvarid, start, epais, pct_tmp(1, is_sic))
1012            if (ierr /= NF_NOERR) then            if (ierr /= NF_NOERR) then
1013               abort_message = 'Lecture echouee pour <FSIC>'               abort_message = 'Lecture echouee pour <FSIC>'
1014               call abort_gcm(modname,abort_message,1)               call abort_gcm(modname, abort_message, 1)
1015            endif            endif
1016            !  
1017            ! Fraction "terre"            ! Fraction "terre"
1018            !  
1019            ierr = NF_INQ_VARID(nid, 'FTER', nvarid)            ierr = NF_INQ_VARID(nid, 'FTER', nvarid)
1020            if (ierr /= NF_NOERR) then            if (ierr /= NF_NOERR) then
1021               abort_message = 'Le champ <FTER> est absent'               abort_message = 'Le champ <FTER> est absent'
1022               call abort_gcm(modname,abort_message,1)               call abort_gcm(modname, abort_message, 1)
1023            endif            endif
1024            ierr = NF_GET_VARA_REAL(nid,nvarid,start,epais,pct_tmp(1,is_ter))            ierr = NF_GET_VARA_REAL(nid, nvarid, start, epais, pct_tmp(1, is_ter))
1025            if (ierr /= NF_NOERR) then            if (ierr /= NF_NOERR) then
1026               abort_message = 'Lecture echouee pour <FTER>'               abort_message = 'Lecture echouee pour <FTER>'
1027               call abort_gcm(modname,abort_message,1)               call abort_gcm(modname, abort_message, 1)
1028            endif            endif
1029            !  
1030            ! Fraction "glacier terre"            ! Fraction "glacier terre"
1031            !  
1032            ierr = NF_INQ_VARID(nid, 'FLIC', nvarid)            ierr = NF_INQ_VARID(nid, 'FLIC', nvarid)
1033            if (ierr /= NF_NOERR) then            if (ierr /= NF_NOERR) then
1034               abort_message = 'Le champ <FLIC> est absent'               abort_message = 'Le champ <FLIC> est absent'
1035               call abort_gcm(modname,abort_message,1)               call abort_gcm(modname, abort_message, 1)
1036            endif            endif
1037            ierr = NF_GET_VARA_REAL(nid,nvarid,start,epais,pct_tmp(1,is_lic))            ierr = NF_GET_VARA_REAL(nid, nvarid, start, epais, pct_tmp(1, is_lic))
1038            if (ierr /= NF_NOERR) then            if (ierr /= NF_NOERR) then
1039               abort_message = 'Lecture echouee pour <FLIC>'               abort_message = 'Lecture echouee pour <FLIC>'
1040               call abort_gcm(modname,abort_message,1)               call abort_gcm(modname, abort_message, 1)
1041            endif            endif
1042            !  
1043         else  ! on en est toujours a rnatur         else ! on en est toujours a rnatur
1044            !  
1045            ierr = NF_INQ_VARID(nid, 'NAT', nvarid)            ierr = NF_INQ_VARID(nid, 'NAT', nvarid)
1046            if (ierr /= NF_NOERR) then            if (ierr /= NF_NOERR) then
1047               abort_message = 'Le champ <NAT> est absent'               abort_message = 'Le champ <NAT> est absent'
1048               call abort_gcm(modname,abort_message,1)               call abort_gcm(modname, abort_message, 1)
1049            endif            endif
1050            ierr = NF_GET_VARA_REAL(nid,nvarid,start,epais, nat_lu)            ierr = NF_GET_VARA_REAL(nid, nvarid, start, epais, nat_lu)
1051            if (ierr /= NF_NOERR) then            if (ierr /= NF_NOERR) then
1052               abort_message = 'Lecture echouee pour <NAT>'               abort_message = 'Lecture echouee pour <NAT>'
1053               call abort_gcm(modname,abort_message,1)               call abort_gcm(modname, abort_message, 1)
1054            endif            endif
1055            !  
1056            ! Remplissage des fractions de surface            ! Remplissage des fractions de surface
1057            ! nat = 0, 1, 2, 3 pour ocean, terre, glacier, seaice            ! nat = 0, 1, 2, 3 pour ocean, terre, glacier, seaice
1058            !  
1059            pct_tmp = 0.0            pct_tmp = 0.0
1060            do ii = 1, klon            do ii = 1, klon
1061               pct_tmp(ii,nint(nat_lu(ii)) + 1) = 1.               pct_tmp(ii, nint(nat_lu(ii)) + 1) = 1.
1062            enddo            enddo
1063    
1064            !  
1065            !  On se retrouve avec ocean en 1 et terre en 2 alors qu'on veut le contraire            ! On se retrouve avec ocean en 1 et terre en 2 alors qu'on veut le contraire
1066            !  
1067            pctsrf_new = pct_tmp            pctsrf_new = pct_tmp
1068            pctsrf_new (:,2)= pct_tmp (:,1)            pctsrf_new (:, 2)= pct_tmp (:, 1)
1069            pctsrf_new (:,1)= pct_tmp (:,2)            pctsrf_new (:, 1)= pct_tmp (:, 2)
1070            pct_tmp = pctsrf_new            pct_tmp = pctsrf_new
1071         endif ! fin test sur newlmt         endif ! fin test sur newlmt
1072         !  
1073         ! Lecture SST         ! Lecture SST
1074         !  
1075         ierr = NF_INQ_VARID(nid, 'SST', nvarid)         ierr = NF_INQ_VARID(nid, 'SST', nvarid)
1076         if (ierr /= NF_NOERR) then         if (ierr /= NF_NOERR) then
1077            abort_message = 'Le champ <SST> est absent'            abort_message = 'Le champ <SST> est absent'
1078            call abort_gcm(modname,abort_message,1)            call abort_gcm(modname, abort_message, 1)
1079         endif         endif
1080         ierr = NF_GET_VARA_REAL(nid,nvarid,start,epais, sst_lu)         ierr = NF_GET_VARA_REAL(nid, nvarid, start, epais, sst_lu)
1081         if (ierr /= NF_NOERR) then         if (ierr /= NF_NOERR) then
1082            abort_message = 'Lecture echouee pour <SST>'            abort_message = 'Lecture echouee pour <SST>'
1083            call abort_gcm(modname,abort_message,1)            call abort_gcm(modname, abort_message, 1)
1084         endif         endif
1085    
1086         !  
1087         ! Fin de lecture         ! Fin de lecture
1088         !  
1089         ierr = NF_CLOSE(nid)         ierr = NF_CLOSE(nid)
1090         deja_lu = .true.         deja_lu = .true.
1091         jour_lu = jour         jour_lu = jour
1092      endif      endif
1093      !  
1094      ! Recopie des variables dans les champs de sortie      ! Recopie des variables dans les champs de sortie
1095      !  
1096      lmt_sst = 999999999.      lmt_sst = 999999999.
1097      do ii = 1, knon      do ii = 1, knon
1098         lmt_sst(ii) = sst_lu(knindex(ii))         lmt_sst(ii) = sst_lu(knindex(ii))
1099      enddo      enddo
1100    
1101      pctsrf_new(:,is_oce) = pct_tmp(:,is_oce)      pctsrf_new(:, is_oce) = pct_tmp(:, is_oce)
1102      pctsrf_new(:,is_sic) = pct_tmp(:,is_sic)      pctsrf_new(:, is_sic) = pct_tmp(:, is_sic)
1103    
1104    END SUBROUTINE interfoce_lim    END SUBROUTINE interfoce_lim
1105    
1106    !************************    !************************
1107    
1108    SUBROUTINE interfsur_lim(itime, dtime, jour, &    SUBROUTINE interfsur_lim(itime, dtime, jour,  &
1109         & klon, nisurf, knon, knindex, &         klon, nisurf, knon, knindex,  &
1110         & debut,  &         debut,  &
1111         & lmt_alb, lmt_rug)         lmt_alb, lmt_rug)
1112    
1113      ! Cette routine sert d'interface entre le modèle atmosphérique et      ! Cette routine sert d'interface entre le modèle atmosphérique et
1114      ! un fichier de conditions aux limites.      ! un fichier de conditions aux limites.
1115      !  
1116      ! L. Fairhead 02/2000      ! L. Fairhead 02/2000
     !  
     ! input:  
     !   itime        numero du pas de temps courant  
     !   dtime        pas de temps de la physique (en s)  
     !   jour         jour a lire dans l'annee  
     !   nisurf       index de la surface a traiter (1 = sol continental)  
     !   knon         nombre de points dans le domaine a traiter  
     !   knindex      index des points de la surface a traiter  
     !   klon         taille de la grille  
     !   debut        logical: 1er appel a la physique (initialisation)  
     !  
     ! output:  
     !   lmt_sst      SST lues dans le fichier de CL  
     !   lmt_alb      Albedo lu  
     !   lmt_rug      longueur de rugosité lue  
     !   pctsrf_new   sous-maille fractionnelle  
     !  
1117    
1118      use abort_gcm_m, only: abort_gcm      use abort_gcm_m, only: abort_gcm
1119    
1120      ! Parametres d'entree      ! Parametres d'entree
1121        ! input:
1122        ! itime numero du pas de temps courant
1123        ! dtime pas de temps de la physique (en s)
1124        ! jour jour a lire dans l'annee
1125        ! nisurf index de la surface a traiter (1 = sol continental)
1126        ! knon nombre de points dans le domaine a traiter
1127        ! knindex index des points de la surface a traiter
1128        ! klon taille de la grille
1129        ! debut logical: 1er appel a la physique (initialisation)
1130      integer, intent(IN) :: itime      integer, intent(IN) :: itime
1131      real   , intent(IN) :: dtime      real , intent(IN) :: dtime
1132      integer, intent(IN) :: jour      integer, intent(IN) :: jour
1133      integer, intent(IN) :: nisurf      integer, intent(IN) :: nisurf
1134      integer, intent(IN) :: knon      integer, intent(IN) :: knon
# Line 1187  CONTAINS Line 1137  CONTAINS
1137      logical, intent(IN) :: debut      logical, intent(IN) :: debut
1138    
1139      ! Parametres de sortie      ! Parametres de sortie
1140        ! output:
1141        ! lmt_sst SST lues dans le fichier de CL
1142        ! lmt_alb Albedo lu
1143        ! lmt_rug longueur de rugosité lue
1144        ! pctsrf_new sous-maille fractionnelle
1145      real, intent(out), dimension(klon) :: lmt_alb      real, intent(out), dimension(klon) :: lmt_alb
1146      real, intent(out), dimension(klon) :: lmt_rug      real, intent(out), dimension(klon) :: lmt_rug
1147    
1148      ! Variables locales      ! Variables locales
1149      integer     :: ii      integer :: ii
1150      integer,save :: lmt_pas     ! frequence de lecture des conditions limites      integer, save :: lmt_pas ! frequence de lecture des conditions limites
1151      ! (en pas de physique)      ! (en pas de physique)
1152      logical,save :: deja_lu_sur! pour indiquer que le jour a lire a deja      logical, save :: deja_lu_sur! pour indiquer que le jour a lire a deja
1153      ! lu pour une surface precedente      ! lu pour une surface precedente
1154      integer,save :: jour_lu_sur      integer, save :: jour_lu_sur
1155      integer      :: ierr      integer :: ierr
1156      character (len = 20) :: modname = 'interfsur_lim'      character (len = 20) :: modname = 'interfsur_lim'
1157      character (len = 80) :: abort_message      character (len = 80) :: abort_message
1158      logical,save     :: newlmt = .false.      logical, save :: newlmt = .false.
1159      logical,save     :: check = .false.      logical, save :: check = .false.
1160      ! Champs lus dans le fichier de CL      ! Champs lus dans le fichier de CL
1161      real, allocatable , save, dimension(:) :: alb_lu, rug_lu      real, allocatable , save, dimension(:) :: alb_lu, rug_lu
1162      !  
1163      ! quelques variables pour netcdf      ! quelques variables pour netcdf
1164      !  
1165      include "netcdf.inc"      include "netcdf.inc"
1166      integer ,save             :: nid, nvarid      integer , save :: nid, nvarid
1167      integer, dimension(2),save :: start, epais      integer, dimension(2), save :: start, epais
1168      !  
1169      ! Fin déclaration      !------------------------------------------------------------
     !  
1170    
1171      if (debut) then      if (debut) then
1172         lmt_pas = nint(86400./dtime * 1.0) ! pour une lecture une fois par jour         lmt_pas = nint(86400./dtime * 1.0) ! pour une lecture une fois par jour
# Line 1223  CONTAINS Line 1177  CONTAINS
1177    
1178      if ((jour - jour_lu_sur) /= 0) deja_lu_sur = .false.      if ((jour - jour_lu_sur) /= 0) deja_lu_sur = .false.
1179    
1180      if (check) write(*,*)modname,':: jour_lu_sur, deja_lu_sur', jour_lu_sur, &      if (check) write(*, *)modname, ':: jour_lu_sur, deja_lu_sur', jour_lu_sur, &
1181           deja_lu_sur           deja_lu_sur
1182      if (check) write(*,*)modname,':: itime, lmt_pas', itime, lmt_pas      if (check) write(*, *)modname, ':: itime, lmt_pas', itime, lmt_pas
1183    
1184      ! Tester d'abord si c'est le moment de lire le fichier      ! Tester d'abord si c'est le moment de lire le fichier
1185      if (mod(itime-1, lmt_pas) == 0 .and. .not. deja_lu_sur) then      if (mod(itime-1, lmt_pas) == 0 .and. .not. deja_lu_sur) then
1186         !  
1187         ! Ouverture du fichier         ! Ouverture du fichier
1188         !  
1189         ierr = NF_OPEN ('limit.nc', NF_NOWRITE,nid)         ierr = NF_OPEN ('limit.nc', NF_NOWRITE, nid)
1190         if (ierr.NE.NF_NOERR) then         if (ierr.NE.NF_NOERR) then
1191            abort_message &            abort_message &
1192                 = 'Pb d''ouverture du fichier de conditions aux limites'                 = 'Pb d''ouverture du fichier de conditions aux limites'
1193            call abort_gcm(modname,abort_message,1)            call abort_gcm(modname, abort_message, 1)
1194         endif         endif
1195         !  
1196         ! La tranche de donnees a lire:         ! La tranche de donnees a lire:
1197    
1198         start(1) = 1         start(1) = 1
1199         start(2) = jour         start(2) = jour
1200         epais(1) = klon         epais(1) = klon
1201         epais(2) = 1         epais(2) = 1
1202         !  
1203         ! Lecture Albedo         ! Lecture Albedo
1204         !  
1205         ierr = NF_INQ_VARID(nid, 'ALB', nvarid)         ierr = NF_INQ_VARID(nid, 'ALB', nvarid)
1206         if (ierr /= NF_NOERR) then         if (ierr /= NF_NOERR) then
1207            abort_message = 'Le champ <ALB> est absent'            abort_message = 'Le champ <ALB> est absent'
1208            call abort_gcm(modname,abort_message,1)            call abort_gcm(modname, abort_message, 1)
1209         endif         endif
1210         ierr = NF_GET_VARA_REAL(nid,nvarid,start,epais, alb_lu)         ierr = NF_GET_VARA_REAL(nid, nvarid, start, epais, alb_lu)
1211         if (ierr /= NF_NOERR) then         if (ierr /= NF_NOERR) then
1212            abort_message = 'Lecture echouee pour <ALB>'            abort_message = 'Lecture echouee pour <ALB>'
1213            call abort_gcm(modname,abort_message,1)            call abort_gcm(modname, abort_message, 1)
1214         endif         endif
1215         !  
1216         ! Lecture rugosité         ! Lecture rugosité
1217         !  
1218         ierr = NF_INQ_VARID(nid, 'RUG', nvarid)         ierr = NF_INQ_VARID(nid, 'RUG', nvarid)
1219         if (ierr /= NF_NOERR) then         if (ierr /= NF_NOERR) then
1220            abort_message = 'Le champ <RUG> est absent'            abort_message = 'Le champ <RUG> est absent'
1221            call abort_gcm(modname,abort_message,1)            call abort_gcm(modname, abort_message, 1)
1222         endif         endif
1223         ierr = NF_GET_VARA_REAL(nid,nvarid,start,epais, rug_lu)         ierr = NF_GET_VARA_REAL(nid, nvarid, start, epais, rug_lu)
1224         if (ierr /= NF_NOERR) then         if (ierr /= NF_NOERR) then
1225            abort_message = 'Lecture echouee pour <RUG>'            abort_message = 'Lecture echouee pour <RUG>'
1226            call abort_gcm(modname,abort_message,1)            call abort_gcm(modname, abort_message, 1)
1227         endif         endif
1228    
1229         !  
1230         ! Fin de lecture         ! Fin de lecture
1231         !  
1232         ierr = NF_CLOSE(nid)         ierr = NF_CLOSE(nid)
1233         deja_lu_sur = .true.         deja_lu_sur = .true.
1234         jour_lu_sur = jour         jour_lu_sur = jour
1235      endif      endif
1236      !  
1237      ! Recopie des variables dans les champs de sortie      ! Recopie des variables dans les champs de sortie
1238      !  
1239  !!$  lmt_alb(:) = 0.0  !!$ lmt_alb = 0.0
1240  !!$  lmt_rug(:) = 0.0  !!$ lmt_rug = 0.0
1241      lmt_alb(:) = 999999.      lmt_alb = 999999.
1242      lmt_rug(:) = 999999.      lmt_rug = 999999.
1243      DO ii = 1, knon      DO ii = 1, knon
1244         lmt_alb(ii) = alb_lu(knindex(ii))         lmt_alb(ii) = alb_lu(knindex(ii))
1245         lmt_rug(ii) = rug_lu(knindex(ii))         lmt_rug(ii) = rug_lu(knindex(ii))
# Line 1295  CONTAINS Line 1249  CONTAINS
1249    
1250    !************************    !************************
1251    
1252    SUBROUTINE calcul_fluxs( klon, knon, nisurf, dtime, &    SUBROUTINE calcul_fluxs( klon, knon, nisurf, dtime,  &
1253         & tsurf, p1lay, cal, beta, coef1lay, ps, &         tsurf, p1lay, cal, beta, coef1lay, ps,  &
1254         & precip_rain, precip_snow, snow, qsurf, &         precip_rain, precip_snow, snow, qsurf,  &
1255         & radsol, dif_grnd, t1lay, q1lay, u1lay, v1lay, &         radsol, dif_grnd, t1lay, q1lay, u1lay, v1lay,  &
1256         & petAcoef, peqAcoef, petBcoef, peqBcoef, &         petAcoef, peqAcoef, petBcoef, peqBcoef,  &
1257         & tsurf_new, evap, fluxlat, fluxsens, dflux_s, dflux_l)         tsurf_new, evap, fluxlat, fluxsens, dflux_s, dflux_l)
1258    
1259      ! Cette routine calcule les fluxs en h et q a l'interface et eventuellement      ! Cette routine calcule les fluxs en h et q a l'interface et eventuellement
1260      ! une temperature de surface (au cas ou ok_veget = false)      ! une temperature de surface (au cas ou ok_veget = false)
1261      !  
1262      ! L. Fairhead 4/2000      ! L. Fairhead 4/2000
1263      !  
1264      ! input:      ! input:
1265      !   knon         nombre de points a traiter      ! knon nombre de points a traiter
1266      !   nisurf       surface a traiter      ! nisurf surface a traiter
1267      !   tsurf        temperature de surface      ! tsurf temperature de surface
1268      !   p1lay        pression 1er niveau (milieu de couche)      ! p1lay pression 1er niveau (milieu de couche)
1269      !   cal          capacite calorifique du sol      ! cal capacite calorifique du sol
1270      !   beta         evap reelle      ! beta evap reelle
1271      !   coef1lay     coefficient d'echange      ! coef1lay coefficient d'echange
1272      !   ps           pression au sol      ! ps pression au sol
1273      !   precip_rain  precipitations liquides      ! precip_rain precipitations liquides
1274      !   precip_snow  precipitations solides      ! precip_snow precipitations solides
1275      !   snow         champs hauteur de neige      ! snow champs hauteur de neige
1276      !   runoff       runoff en cas de trop plein      ! runoff runoff en cas de trop plein
1277      !   petAcoef     coeff. A de la resolution de la CL pour t      ! petAcoef coeff. A de la resolution de la CL pour t
1278      !   peqAcoef     coeff. A de la resolution de la CL pour q      ! peqAcoef coeff. A de la resolution de la CL pour q
1279      !   petBcoef     coeff. B de la resolution de la CL pour t      ! petBcoef coeff. B de la resolution de la CL pour t
1280      !   peqBcoef     coeff. B de la resolution de la CL pour q      ! peqBcoef coeff. B de la resolution de la CL pour q
1281      !   radsol       rayonnement net aus sol (LW + SW)      ! radsol rayonnement net aus sol (LW + SW)
1282      !   dif_grnd     coeff. diffusion vers le sol profond      ! dif_grnd coeff. diffusion vers le sol profond
1283      !  
1284      ! output:      ! output:
1285      !   tsurf_new    temperature au sol      ! tsurf_new temperature au sol
1286      !   qsurf        humidite de l'air au dessus du sol      ! qsurf humidite de l'air au dessus du sol
1287      !   fluxsens     flux de chaleur sensible      ! fluxsens flux de chaleur sensible
1288      !   fluxlat      flux de chaleur latente      ! fluxlat flux de chaleur latente
1289      !   dflux_s      derivee du flux de chaleur sensible / Ts      ! dflux_s derivee du flux de chaleur sensible / Ts
1290      !   dflux_l      derivee du flux de chaleur latente  / Ts      ! dflux_l derivee du flux de chaleur latente / Ts
1291      !  
1292    
1293      use indicesol      use indicesol
1294      use abort_gcm_m, only: abort_gcm      use abort_gcm_m, only: abort_gcm
1295      use yoethf      use yoethf_m
1296      use fcttre, only: thermcep, foeew, qsats, qsatl, foede, dqsats, dqsatl      use fcttre, only: thermcep, foeew, qsats, qsatl, foede, dqsats, dqsatl
1297      use YOMCST      use SUPHEC_M
1298    
1299      ! Parametres d'entree      ! Parametres d'entree
1300      integer, intent(IN) :: knon, nisurf, klon      integer, intent(IN) :: knon, nisurf, klon
1301      real   , intent(IN) :: dtime      real , intent(IN) :: dtime
1302      real, dimension(klon), intent(IN) :: petAcoef, peqAcoef      real, dimension(klon), intent(IN) :: petAcoef, peqAcoef
1303      real, dimension(klon), intent(IN) :: petBcoef, peqBcoef      real, dimension(klon), intent(IN) :: petBcoef, peqBcoef
1304      real, dimension(klon), intent(IN) :: ps, q1lay      real, dimension(klon), intent(IN) :: ps, q1lay
# Line 1365  CONTAINS Line 1319  CONTAINS
1319      real, dimension(klon) :: zx_pkh, zx_dq_s_dt, zx_qsat, zx_coef      real, dimension(klon) :: zx_pkh, zx_dq_s_dt, zx_qsat, zx_coef
1320      real, dimension(klon) :: zx_sl, zx_k1      real, dimension(klon) :: zx_sl, zx_k1
1321      real, dimension(klon) :: zx_q_0 , d_ts      real, dimension(klon) :: zx_q_0 , d_ts
1322      real                  :: zdelta, zcvm5, zx_qs, zcor, zx_dq_s_dh      real :: zdelta, zcvm5, zx_qs, zcor, zx_dq_s_dh
1323      real                  :: bilan_f, fq_fonte      real :: bilan_f, fq_fonte
1324      REAL                  :: subli, fsno      REAL :: subli, fsno
1325      REAL                  :: qsat_new, q1_new      REAL :: qsat_new, q1_new
1326      real, parameter :: t_grnd = 271.35, t_coup = 273.15      real, parameter :: t_grnd = 271.35, t_coup = 273.15
1327      !! PB temporaire en attendant mieux pour le modele de neige      !! PB temporaire en attendant mieux pour le modele de neige
1328      REAL, parameter :: chasno = 3.334E+05/(2.3867E+06*0.15)      REAL, parameter :: chasno = 3.334E+05/(2.3867E+06*0.15)
1329      !  
1330      logical, save         :: check = .false.      logical, save :: check = .false.
1331      character (len = 20)  :: modname = 'calcul_fluxs'      character (len = 20) :: modname = 'calcul_fluxs'
1332      logical, save         :: fonte_neige = .false.      logical, save :: fonte_neige = .false.
1333      real, save            :: max_eau_sol = 150.0      real, save :: max_eau_sol = 150.0
1334      character (len = 80) :: abort_message      character (len = 80) :: abort_message
1335      logical,save         :: first = .true.,second=.false.      logical, save :: first = .true., second=.false.
1336    
1337      if (check) write(*,*)'Entree ', modname,' surface = ',nisurf      if (check) write(*, *)'Entree ', modname, ' surface = ', nisurf
1338    
1339      IF (check) THEN      IF (check) THEN
1340         WRITE(*,*)' radsol (min, max)' &         WRITE(*, *)' radsol (min, max)' &
1341              &     , MINVAL(radsol(1:knon)), MAXVAL(radsol(1:knon))              , MINVAL(radsol(1:knon)), MAXVAL(radsol(1:knon))
1342         !!CALL flush(6)         !!CALL flush(6)
1343      ENDIF      ENDIF
1344    
1345      if (size(coastalflow) /= knon .AND. nisurf == is_ter) then      if (size(coastalflow) /= knon .AND. nisurf == is_ter) then
1346         write(*,*)'Bizarre, le nombre de points continentaux'         write(*, *)'Bizarre, le nombre de points continentaux'
1347         write(*,*)'a change entre deux appels. J''arrete ...'         write(*, *)'a change entre deux appels. J''arrete ...'
1348         abort_message='Pb run_off'         abort_message='Pb run_off'
1349         call abort_gcm(modname,abort_message,1)         call abort_gcm(modname, abort_message, 1)
1350      endif      endif
1351      !  
1352      ! Traitement neige et humidite du sol      ! Traitement neige et humidite du sol
     !  
 !!$  WRITE(*,*)'test calcul_flux, surface ', nisurf  
     !!PB test  
 !!$    if (nisurf == is_oce) then  
 !!$      snow = 0.  
 !!$      qsol = max_eau_sol  
 !!$    else  
 !!$      where (precip_snow > 0.) snow = snow + (precip_snow * dtime)  
 !!$      where (snow > epsilon(snow)) snow = max(0.0, snow - (evap * dtime))  
 !!$!      snow = max(0.0, snow + (precip_snow - evap) * dtime)  
 !!$      where (precip_rain > 0.) qsol = qsol + (precip_rain - evap) * dtime  
 !!$    endif  
 !!$    IF (nisurf /= is_ter) qsol = max_eau_sol  
1353    
     !  
1354      ! Initialisation      ! Initialisation
1355      !  
1356      evap = 0.      evap = 0.
1357      fluxsens=0.      fluxsens=0.
1358      fluxlat=0.      fluxlat=0.
1359      dflux_s = 0.      dflux_s = 0.
1360      dflux_l = 0.      dflux_l = 0.
1361      !  
1362      ! zx_qs = qsat en kg/kg      ! zx_qs = qsat en kg/kg
1363      !  
1364      DO i = 1, knon      DO i = 1, knon
1365         zx_pkh(i) = (ps(i)/ps(i))**RKAPPA         zx_pkh(i) = (ps(i)/ps(i))**RKAPPA
1366         IF (thermcep) THEN         IF (thermcep) THEN
1367            zdelta=MAX(0.,SIGN(1.,rtt-tsurf(i)))            zdelta=MAX(0., SIGN(1., rtt-tsurf(i)))
1368            zcvm5 = R5LES*RLVTT*(1.-zdelta) + R5IES*RLSTT*zdelta            zcvm5 = R5LES*RLVTT*(1.-zdelta) + R5IES*RLSTT*zdelta
1369            zcvm5 = zcvm5 / RCPD / (1.0+RVTMP2*q1lay(i))            zcvm5 = zcvm5 / RCPD / (1.0+RVTMP2*q1lay(i))
1370            zx_qs= r2es * FOEEW(tsurf(i),zdelta)/ps(i)            zx_qs= r2es * FOEEW(tsurf(i), zdelta)/ps(i)
1371            zx_qs=MIN(0.5,zx_qs)            zx_qs=MIN(0.5, zx_qs)
1372            zcor=1./(1.-retv*zx_qs)            zcor=1./(1.-retv*zx_qs)
1373            zx_qs=zx_qs*zcor            zx_qs=zx_qs*zcor
1374            zx_dq_s_dh = FOEDE(tsurf(i),zdelta,zcvm5,zx_qs,zcor) &            zx_dq_s_dh = FOEDE(tsurf(i), zdelta, zcvm5, zx_qs, zcor) &
1375                 &                 /RLVTT / zx_pkh(i)                 /RLVTT / zx_pkh(i)
1376         ELSE         ELSE
1377            IF (tsurf(i).LT.t_coup) THEN            IF (tsurf(i).LT.t_coup) THEN
1378               zx_qs = qsats(tsurf(i)) / ps(i)               zx_qs = qsats(tsurf(i)) / ps(i)
1379               zx_dq_s_dh = dqsats(tsurf(i),zx_qs)/RLVTT &               zx_dq_s_dh = dqsats(tsurf(i), zx_qs)/RLVTT &
1380                    &                    / zx_pkh(i)                    / zx_pkh(i)
1381            ELSE            ELSE
1382               zx_qs = qsatl(tsurf(i)) / ps(i)               zx_qs = qsatl(tsurf(i)) / ps(i)
1383               zx_dq_s_dh = dqsatl(tsurf(i),zx_qs)/RLVTT &               zx_dq_s_dh = dqsatl(tsurf(i), zx_qs)/RLVTT &
1384                    &               / zx_pkh(i)                    / zx_pkh(i)
1385            ENDIF            ENDIF
1386         ENDIF         ENDIF
1387         zx_dq_s_dt(i) = RCPD * zx_pkh(i) * zx_dq_s_dh         zx_dq_s_dt(i) = RCPD * zx_pkh(i) * zx_dq_s_dh
1388         zx_qsat(i) = zx_qs         zx_qsat(i) = zx_qs
1389         zx_coef(i) = coef1lay(i) &         zx_coef(i) = coef1lay(i) &
1390              & * (1.0+SQRT(u1lay(i)**2+v1lay(i)**2)) &              * (1.0+SQRT(u1lay(i)**2+v1lay(i)**2)) &
1391              & * p1lay(i)/(RD*t1lay(i))              * p1lay(i)/(RD*t1lay(i))
1392    
1393      ENDDO      ENDDO
1394    
1395      ! === Calcul de la temperature de surface ===      ! === Calcul de la temperature de surface ===
1396      !  
1397      ! zx_sl = chaleur latente d'evaporation ou de sublimation      ! zx_sl = chaleur latente d'evaporation ou de sublimation
1398      !  
1399      do i = 1, knon      do i = 1, knon
1400         zx_sl(i) = RLVTT         zx_sl(i) = RLVTT
1401         if (tsurf(i) .LT. RTT) zx_sl(i) = RLSTT         if (tsurf(i) .LT. RTT) zx_sl(i) = RLSTT
# Line 1466  CONTAINS Line 1406  CONTAINS
1406         ! Q         ! Q
1407         zx_oq(i) = 1. - (beta(i) * zx_k1(i) * peqBcoef(i) * dtime)         zx_oq(i) = 1. - (beta(i) * zx_k1(i) * peqBcoef(i) * dtime)
1408         zx_mq(i) = beta(i) * zx_k1(i) * &         zx_mq(i) = beta(i) * zx_k1(i) * &
1409              &             (peqAcoef(i) - zx_qsat(i) &              (peqAcoef(i) - zx_qsat(i) &
1410              &                          + zx_dq_s_dt(i) * tsurf(i)) &              + zx_dq_s_dt(i) * tsurf(i)) &
1411              &             / zx_oq(i)              / zx_oq(i)
1412         zx_nq(i) = beta(i) * zx_k1(i) * (-1. * zx_dq_s_dt(i)) &         zx_nq(i) = beta(i) * zx_k1(i) * (-1. * zx_dq_s_dt(i)) &
1413              &                              / zx_oq(i)              / zx_oq(i)
1414    
1415         ! H         ! H
1416         zx_oh(i) = 1. - (zx_k1(i) * petBcoef(i) * dtime)         zx_oh(i) = 1. - (zx_k1(i) * petBcoef(i) * dtime)
# Line 1479  CONTAINS Line 1419  CONTAINS
1419    
1420         ! Tsurface         ! Tsurface
1421         tsurf_new(i) = (tsurf(i) + cal(i)/(RCPD * zx_pkh(i)) * dtime * &         tsurf_new(i) = (tsurf(i) + cal(i)/(RCPD * zx_pkh(i)) * dtime * &
1422              &             (radsol(i) + zx_mh(i) + zx_sl(i) * zx_mq(i)) &              (radsol(i) + zx_mh(i) + zx_sl(i) * zx_mq(i)) &
1423              &                 + dif_grnd(i) * t_grnd * dtime)/ &              + dif_grnd(i) * t_grnd * dtime)/ &
1424              &          ( 1. - dtime * cal(i)/(RCPD * zx_pkh(i)) * ( &              ( 1. - dtime * cal(i)/(RCPD * zx_pkh(i)) * ( &
1425              &                       zx_nh(i) + zx_sl(i) * zx_nq(i)) &                zx_nh(i) + zx_sl(i) * zx_nq(i)) &
1426              &                     + dtime * dif_grnd(i))              + dtime * dif_grnd(i))
1427    
1428    
        !  
1429         ! Y'a-t-il fonte de neige?         ! Y'a-t-il fonte de neige?
1430         !  
1431         !    fonte_neige = (nisurf /= is_oce) .AND. &         ! fonte_neige = (nisurf /= is_oce) .AND. &
1432         !     & (snow(i) > epsfra .OR. nisurf == is_sic .OR. nisurf == is_lic) &         ! & (snow(i) > epsfra .OR. nisurf == is_sic .OR. nisurf == is_lic) &
1433         !     & .AND. (tsurf_new(i) >= RTT)         ! & .AND. (tsurf_new(i) >= RTT)
1434         !    if (fonte_neige) tsurf_new(i) = RTT           ! if (fonte_neige) tsurf_new(i) = RTT
1435         d_ts(i) = tsurf_new(i) - tsurf(i)         d_ts(i) = tsurf_new(i) - tsurf(i)
1436         !    zx_h_ts(i) = tsurf_new(i) * RCPD * zx_pkh(i)         ! zx_h_ts(i) = tsurf_new(i) * RCPD * zx_pkh(i)
1437         !    zx_q_0(i) = zx_qsat(i) + zx_dq_s_dt(i) * d_ts(i)         ! zx_q_0(i) = zx_qsat(i) + zx_dq_s_dt(i) * d_ts(i)
1438         !== flux_q est le flux de vapeur d'eau: kg/(m**2 s)  positive vers bas         !== flux_q est le flux de vapeur d'eau: kg/(m**2 s) positive vers bas
1439         !== flux_t est le flux de cpt (energie sensible): j/(m**2 s)         !== flux_t est le flux de cpt (energie sensible): j/(m**2 s)
1440         evap(i) = - zx_mq(i) - zx_nq(i) * tsurf_new(i)         evap(i) = - zx_mq(i) - zx_nq(i) * tsurf_new(i)
1441         fluxlat(i) = - evap(i) * zx_sl(i)         fluxlat(i) = - evap(i) * zx_sl(i)
# Line 1513  CONTAINS Line 1453  CONTAINS
1453    
1454    !************************    !************************
1455    
1456    SUBROUTINE fonte_neige( klon, knon, nisurf, dtime, &    SUBROUTINE fonte_neige( klon, knon, nisurf, dtime,  &
1457         & tsurf, p1lay, cal, beta, coef1lay, ps, &         tsurf, p1lay, cal, beta, coef1lay, ps,  &
1458         & precip_rain, precip_snow, snow, qsol, &         precip_rain, precip_snow, snow, qsol,  &
1459         & radsol, dif_grnd, t1lay, q1lay, u1lay, v1lay, &         radsol, dif_grnd, t1lay, q1lay, u1lay, v1lay,  &
1460         & petAcoef, peqAcoef, petBcoef, peqBcoef, &         petAcoef, peqAcoef, petBcoef, peqBcoef,  &
1461         & tsurf_new, evap, fluxlat, fluxsens, dflux_s, dflux_l, &         tsurf_new, evap, fluxlat, fluxsens, dflux_s, dflux_l,  &
1462         & fqcalving,ffonte,run_off_lic_0)         fqcalving, ffonte, run_off_lic_0)
1463    
1464      ! Routine de traitement de la fonte de la neige dans le cas du traitement      ! Routine de traitement de la fonte de la neige dans le cas du traitement
1465      ! de sol simplifié      ! de sol simplifié
1466      !  
1467      ! LF 03/2001      ! LF 03/2001
1468      ! input:      ! input:
1469      !   knon         nombre de points a traiter      ! knon nombre de points a traiter
1470      !   nisurf       surface a traiter      ! nisurf surface a traiter
1471      !   tsurf        temperature de surface      ! tsurf temperature de surface
1472      !   p1lay        pression 1er niveau (milieu de couche)      ! p1lay pression 1er niveau (milieu de couche)
1473      !   cal          capacite calorifique du sol      ! cal capacite calorifique du sol
1474      !   beta         evap reelle      ! beta evap reelle
1475      !   coef1lay     coefficient d'echange      ! coef1lay coefficient d'echange
1476      !   ps           pression au sol      ! ps pression au sol
1477      !   precip_rain  precipitations liquides      ! precip_rain precipitations liquides
1478      !   precip_snow  precipitations solides      ! precip_snow precipitations solides
1479      !   snow         champs hauteur de neige      ! snow champs hauteur de neige
1480      !   qsol         hauteur d'eau contenu dans le sol      ! qsol hauteur d'eau contenu dans le sol
1481      !   runoff       runoff en cas de trop plein      ! runoff runoff en cas de trop plein
1482      !   petAcoef     coeff. A de la resolution de la CL pour t      ! petAcoef coeff. A de la resolution de la CL pour t
1483      !   peqAcoef     coeff. A de la resolution de la CL pour q      ! peqAcoef coeff. A de la resolution de la CL pour q
1484      !   petBcoef     coeff. B de la resolution de la CL pour t      ! petBcoef coeff. B de la resolution de la CL pour t
1485      !   peqBcoef     coeff. B de la resolution de la CL pour q      ! peqBcoef coeff. B de la resolution de la CL pour q
1486      !   radsol       rayonnement net aus sol (LW + SW)      ! radsol rayonnement net aus sol (LW + SW)
1487      !   dif_grnd     coeff. diffusion vers le sol profond      ! dif_grnd coeff. diffusion vers le sol profond
1488      !  
1489      ! output:      ! output:
1490      !   tsurf_new    temperature au sol      ! tsurf_new temperature au sol
1491      !   fluxsens     flux de chaleur sensible      ! fluxsens flux de chaleur sensible
1492      !   fluxlat      flux de chaleur latente      ! fluxlat flux de chaleur latente
1493      !   dflux_s      derivee du flux de chaleur sensible / Ts      ! dflux_s derivee du flux de chaleur sensible / Ts
1494      !   dflux_l      derivee du flux de chaleur latente  / Ts      ! dflux_l derivee du flux de chaleur latente / Ts
1495      ! in/out:      ! in/out:
1496      !   run_off_lic_0 run off glacier du pas de temps précedent      ! run_off_lic_0 run off glacier du pas de temps précedent
1497      !  
1498    
1499      use indicesol      use indicesol
1500      use YOMCST      use SUPHEC_M
1501      use yoethf      use yoethf_m
1502      use fcttre      use fcttre
1503      !IM cf JLD      !IM cf JLD
1504    
1505      ! Parametres d'entree      ! Parametres d'entree
1506      integer, intent(IN) :: knon, nisurf, klon      integer, intent(IN) :: knon, nisurf, klon
1507      real   , intent(IN) :: dtime      real , intent(IN) :: dtime
1508      real, dimension(klon), intent(IN) :: petAcoef, peqAcoef      real, dimension(klon), intent(IN) :: petAcoef, peqAcoef
1509      real, dimension(klon), intent(IN) :: petBcoef, peqBcoef      real, dimension(klon), intent(IN) :: petBcoef, peqBcoef
1510      real, dimension(klon), intent(IN) :: ps, q1lay      real, dimension(klon), intent(IN) :: ps, q1lay
# Line 1586  CONTAINS Line 1526  CONTAINS
1526      ! Variables locales      ! Variables locales
1527      ! Masse maximum de neige (kg/m2). Au dessus de ce seuil, la neige      ! Masse maximum de neige (kg/m2). Au dessus de ce seuil, la neige
1528      ! en exces "s'ecoule" (calving)      ! en exces "s'ecoule" (calving)
1529      !  real, parameter :: snow_max=1.      ! real, parameter :: snow_max=1.
1530      !IM cf JLD/GK      !IM cf JLD/GK
1531      real, parameter :: snow_max=3000.      real, parameter :: snow_max=3000.
1532      integer :: i      integer :: i
# Line 1595  CONTAINS Line 1535  CONTAINS
1535      real, dimension(klon) :: zx_pkh, zx_dq_s_dt, zx_qsat, zx_coef      real, dimension(klon) :: zx_pkh, zx_dq_s_dt, zx_qsat, zx_coef
1536      real, dimension(klon) :: zx_sl, zx_k1      real, dimension(klon) :: zx_sl, zx_k1
1537      real, dimension(klon) :: zx_q_0 , d_ts      real, dimension(klon) :: zx_q_0 , d_ts
1538      real                  :: zdelta, zcvm5, zx_qs, zcor, zx_dq_s_dh      real :: zdelta, zcvm5, zx_qs, zcor, zx_dq_s_dh
1539      real                  :: bilan_f, fq_fonte      real :: bilan_f, fq_fonte
1540      REAL                  :: subli, fsno      REAL :: subli, fsno
1541      REAL, DIMENSION(klon) :: bil_eau_s, snow_evap      REAL, DIMENSION(klon) :: bil_eau_s, snow_evap
1542      real, parameter :: t_grnd = 271.35, t_coup = 273.15      real, parameter :: t_grnd = 271.35, t_coup = 273.15
1543      !! PB temporaire en attendant mieux pour le modele de neige      !! PB temporaire en attendant mieux pour le modele de neige
# Line 1606  CONTAINS Line 1546  CONTAINS
1546      !IM cf JLD/ GKtest      !IM cf JLD/ GKtest
1547      REAL, parameter :: chaice = 3.334E+05/(2.3867E+06*0.15)      REAL, parameter :: chaice = 3.334E+05/(2.3867E+06*0.15)
1548      ! fin GKtest      ! fin GKtest
1549      !  
1550      logical, save         :: check = .FALSE.      logical, save :: check = .FALSE.
1551      character (len = 20)  :: modname = 'fonte_neige'      character (len = 20) :: modname = 'fonte_neige'
1552      logical, save         :: neige_fond = .false.      logical, save :: neige_fond = .false.
1553      real, save            :: max_eau_sol = 150.0      real, save :: max_eau_sol = 150.0
1554      character (len = 80) :: abort_message      character (len = 80) :: abort_message
1555      logical,save         :: first = .true.,second=.false.      logical, save :: first = .true., second=.false.
1556      real                 :: coeff_rel      real :: coeff_rel
1557    
1558      if (check) write(*,*)'Entree ', modname,' surface = ',nisurf      if (check) write(*, *)'Entree ', modname, ' surface = ', nisurf
1559    
1560      ! Initialisations      ! Initialisations
1561      coeff_rel = dtime/(tau_calv * rday)      coeff_rel = dtime/(tau_calv * rday)
1562      bil_eau_s(:) = 0.      bil_eau_s = 0.
1563      DO i = 1, knon      DO i = 1, knon
1564         zx_pkh(i) = (ps(i)/ps(i))**RKAPPA         zx_pkh(i) = (ps(i)/ps(i))**RKAPPA
1565         IF (thermcep) THEN         IF (thermcep) THEN
1566            zdelta=MAX(0.,SIGN(1.,rtt-tsurf(i)))            zdelta=MAX(0., SIGN(1., rtt-tsurf(i)))
1567            zcvm5 = R5LES*RLVTT*(1.-zdelta) + R5IES*RLSTT*zdelta            zcvm5 = R5LES*RLVTT*(1.-zdelta) + R5IES*RLSTT*zdelta
1568            zcvm5 = zcvm5 / RCPD / (1.0+RVTMP2*q1lay(i))            zcvm5 = zcvm5 / RCPD / (1.0+RVTMP2*q1lay(i))
1569            zx_qs= r2es * FOEEW(tsurf(i),zdelta)/ps(i)            zx_qs= r2es * FOEEW(tsurf(i), zdelta)/ps(i)
1570            zx_qs=MIN(0.5,zx_qs)            zx_qs=MIN(0.5, zx_qs)
1571            zcor=1./(1.-retv*zx_qs)            zcor=1./(1.-retv*zx_qs)
1572            zx_qs=zx_qs*zcor            zx_qs=zx_qs*zcor
1573            zx_dq_s_dh = FOEDE(tsurf(i),zdelta,zcvm5,zx_qs,zcor) &            zx_dq_s_dh = FOEDE(tsurf(i), zdelta, zcvm5, zx_qs, zcor) &
1574                 &                 /RLVTT / zx_pkh(i)                 /RLVTT / zx_pkh(i)
1575         ELSE         ELSE
1576            IF (tsurf(i).LT.t_coup) THEN            IF (tsurf(i).LT.t_coup) THEN
1577               zx_qs = qsats(tsurf(i)) / ps(i)               zx_qs = qsats(tsurf(i)) / ps(i)
1578               zx_dq_s_dh = dqsats(tsurf(i),zx_qs)/RLVTT &               zx_dq_s_dh = dqsats(tsurf(i), zx_qs)/RLVTT &
1579                    &                    / zx_pkh(i)                    / zx_pkh(i)
1580            ELSE            ELSE
1581               zx_qs = qsatl(tsurf(i)) / ps(i)               zx_qs = qsatl(tsurf(i)) / ps(i)
1582               zx_dq_s_dh = dqsatl(tsurf(i),zx_qs)/RLVTT &               zx_dq_s_dh = dqsatl(tsurf(i), zx_qs)/RLVTT &
1583                    &               / zx_pkh(i)                    / zx_pkh(i)
1584            ENDIF            ENDIF
1585         ENDIF         ENDIF
1586         zx_dq_s_dt(i) = RCPD * zx_pkh(i) * zx_dq_s_dh         zx_dq_s_dt(i) = RCPD * zx_pkh(i) * zx_dq_s_dh
1587         zx_qsat(i) = zx_qs         zx_qsat(i) = zx_qs
1588         zx_coef(i) = coef1lay(i) &         zx_coef(i) = coef1lay(i) &
1589              & * (1.0+SQRT(u1lay(i)**2+v1lay(i)**2)) &              * (1.0+SQRT(u1lay(i)**2+v1lay(i)**2)) &
1590              & * p1lay(i)/(RD*t1lay(i))              * p1lay(i)/(RD*t1lay(i))
1591      ENDDO      ENDDO
1592    
1593      ! === Calcul de la temperature de surface ===      ! === Calcul de la temperature de surface ===
1594      !  
1595      ! zx_sl = chaleur latente d'evaporation ou de sublimation      ! zx_sl = chaleur latente d'evaporation ou de sublimation
1596      !  
1597      do i = 1, knon      do i = 1, knon
1598         zx_sl(i) = RLVTT         zx_sl(i) = RLVTT
1599         if (tsurf(i) .LT. RTT) zx_sl(i) = RLSTT         if (tsurf(i) .LT. RTT) zx_sl(i) = RLSTT
# Line 1664  CONTAINS Line 1604  CONTAINS
1604         ! Q         ! Q
1605         zx_oq(i) = 1. - (beta(i) * zx_k1(i) * peqBcoef(i) * dtime)         zx_oq(i) = 1. - (beta(i) * zx_k1(i) * peqBcoef(i) * dtime)
1606         zx_mq(i) = beta(i) * zx_k1(i) * &         zx_mq(i) = beta(i) * zx_k1(i) * &
1607              &             (peqAcoef(i) - zx_qsat(i) &              (peqAcoef(i) - zx_qsat(i) &
1608              &                          + zx_dq_s_dt(i) * tsurf(i)) &              + zx_dq_s_dt(i) * tsurf(i)) &
1609              &             / zx_oq(i)              / zx_oq(i)
1610         zx_nq(i) = beta(i) * zx_k1(i) * (-1. * zx_dq_s_dt(i)) &         zx_nq(i) = beta(i) * zx_k1(i) * (-1. * zx_dq_s_dt(i)) &
1611              &                              / zx_oq(i)              / zx_oq(i)
1612    
1613         ! H         ! H
1614         zx_oh(i) = 1. - (zx_k1(i) * petBcoef(i) * dtime)         zx_oh(i) = 1. - (zx_k1(i) * petBcoef(i) * dtime)
# Line 1684  CONTAINS Line 1624  CONTAINS
1624         snow = MAX(0.0, snow)         snow = MAX(0.0, snow)
1625      end where      end where
1626    
1627      !  bil_eau_s = bil_eau_s + (precip_rain * dtime) - (evap - snow_evap) * dtime      ! bil_eau_s = bil_eau_s + (precip_rain * dtime) - (evap - snow_evap) * dtime
1628      bil_eau_s = (precip_rain * dtime) - (evap - snow_evap) * dtime      bil_eau_s = (precip_rain * dtime) - (evap - snow_evap) * dtime
1629    
1630      !  
1631      ! Y'a-t-il fonte de neige?      ! Y'a-t-il fonte de neige?
1632      !  
1633      ffonte=0.      ffonte=0.
1634      do i = 1, knon      do i = 1, knon
1635         neige_fond = ((snow(i) > epsfra .OR. nisurf == is_sic .OR. nisurf == is_lic) &         neige_fond = ((snow(i) > epsfra .OR. nisurf == is_sic .OR. nisurf == is_lic) &
1636              & .AND. tsurf_new(i) >= RTT)              .AND. tsurf_new(i) >= RTT)
1637         if (neige_fond) then         if (neige_fond) then
1638            fq_fonte = MIN( MAX((tsurf_new(i)-RTT )/chasno,0.0),snow(i))            fq_fonte = MIN( MAX((tsurf_new(i)-RTT )/chasno, 0.0), snow(i))
1639            ffonte(i) = fq_fonte * RLMLT/dtime            ffonte(i) = fq_fonte * RLMLT/dtime
1640            snow(i) = max(0., snow(i) - fq_fonte)            snow(i) = max(0., snow(i) - fq_fonte)
1641            bil_eau_s(i) = bil_eau_s(i) + fq_fonte            bil_eau_s(i) = bil_eau_s(i) + fq_fonte
1642            tsurf_new(i) = tsurf_new(i) - fq_fonte * chasno              tsurf_new(i) = tsurf_new(i) - fq_fonte * chasno
1643            !IM cf JLD OK                !IM cf JLD OK
1644            !IM cf JLD/ GKtest fonte aussi pour la glace            !IM cf JLD/ GKtest fonte aussi pour la glace
1645            IF (nisurf == is_sic .OR. nisurf == is_lic ) THEN            IF (nisurf == is_sic .OR. nisurf == is_lic ) THEN
1646               fq_fonte = MAX((tsurf_new(i)-RTT )/chaice,0.0)               fq_fonte = MAX((tsurf_new(i)-RTT )/chaice, 0.0)
1647               ffonte(i) = ffonte(i) + fq_fonte * RLMLT/dtime               ffonte(i) = ffonte(i) + fq_fonte * RLMLT/dtime
1648               bil_eau_s(i) = bil_eau_s(i) + fq_fonte               bil_eau_s(i) = bil_eau_s(i) + fq_fonte
1649               tsurf_new(i) = RTT               tsurf_new(i) = RTT
1650            ENDIF            ENDIF
1651            d_ts(i) = tsurf_new(i) - tsurf(i)            d_ts(i) = tsurf_new(i) - tsurf(i)
1652         endif         endif
1653         !  
1654         !   s'il y a une hauteur trop importante de neige, elle s'coule         ! s'il y a une hauteur trop importante de neige, elle s'coule
1655         fqcalving(i) = max(0., snow(i) - snow_max)/dtime         fqcalving(i) = max(0., snow(i) - snow_max)/dtime
1656         snow(i)=min(snow(i),snow_max)         snow(i)=min(snow(i), snow_max)
1657         !  
1658         IF (nisurf == is_ter) then         IF (nisurf == is_ter) then
1659            qsol(i) = qsol(i) + bil_eau_s(i)            qsol(i) = qsol(i) + bil_eau_s(i)
1660            run_off(i) = run_off(i) + MAX(qsol(i) - max_eau_sol, 0.0)            run_off(i) = run_off(i) + MAX(qsol(i) - max_eau_sol, 0.0)
1661            qsol(i) = MIN(qsol(i), max_eau_sol)            qsol(i) = MIN(qsol(i), max_eau_sol)
1662         else if (nisurf == is_lic) then         else if (nisurf == is_lic) then
1663            run_off_lic(i) = (coeff_rel *  fqcalving(i)) + &            run_off_lic(i) = (coeff_rel * fqcalving(i)) + &
1664                 &                        (1. - coeff_rel) * run_off_lic_0(i)                 (1. - coeff_rel) * run_off_lic_0(i)
1665            run_off_lic_0(i) = run_off_lic(i)            run_off_lic_0(i) = run_off_lic(i)
1666            run_off_lic(i) = run_off_lic(i) + bil_eau_s(i)/dtime            run_off_lic(i) = run_off_lic(i) + bil_eau_s(i)/dtime
1667         endif         endif

Legend:
Removed from v.12  
changed lines
  Added in v.43

  ViewVC Help
Powered by ViewVC 1.1.21