source: LMDZ4/branches/V3_test/libf/phylmd/interface_surf.F90 @ 718

Last change on this file since 718 was 718, checked in by Laurent Fairhead, 18 years ago

Corrections bugs divers YM
LF

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 122.8 KB
Line 
1!
2! $Header$
3!
4
5  MODULE interface_surf
6
7! Ce module regroupe toutes les routines gerant l'interface entre le modele
8! atmospherique et les modeles de surface (sols continentaux, oceans, glaces)
9! Les routines sont les suivantes:
10!
11!   interfsurf_*: routines d'aiguillage vers les interfaces avec les
12!                 differents modeles de surface
13!   interfsol\
14!             > routines d'interface proprement dite
15!   interfoce/
16!
17!   interfstart: routine d'initialisation et de lecture de l'etat initial
18!                "interface"
19!   interffin  : routine d'ecriture de l'etat de redemmarage de l'interface
20!
21!
22! L. Fairhead, LMD, 02/2000
23
24!ym  USE ioipsl
25
26  IMPLICIT none
27
28  PRIVATE
29  PUBLIC :: interfsurf,interfsurf_hq, gath2cpl
30
31  INTERFACE interfsurf
32    module procedure interfsurf_hq, interfsurf_vent
33  END INTERFACE
34
35  INTERFACE interfoce
36    module procedure interfoce_cpl, interfoce_slab, interfoce_lim
37  END INTERFACE
38
39#include "YOMCST.inc"
40#include "indicesol.inc"
41!IM
42#include "clesphys.inc"
43
44! run_off      ruissellement total
45  REAL, ALLOCATABLE, DIMENSION(:),SAVE    :: run_off, run_off_lic
46!$OMP THREADPRIVATE(run_off, run_off_lic)
47  real, allocatable, dimension(:),save    :: coastalflow, riverflow
48!$OMP THREADPRIVATE(coastalflow, riverflow)
49!!$PB
50  REAL, ALLOCATABLE, DIMENSION(:,:), SAVE :: tmp_rriv, tmp_rcoa,tmp_rlic
51!$OMP THREADPRIVATE(tmp_rriv, tmp_rcoa,tmp_rlic)
52!! pour simuler la fonte des glaciers antarctiques
53  REAL, ALLOCATABLE, DIMENSION(:,:), SAVE :: coeff_iceberg
54!$OMP THREADPRIVATE(coeff_iceberg)
55  real, save                              :: surf_maille
56!$OMP THREADPRIVATE(surf_maille)
57  real, save                              :: cte_flux_iceberg = 6.3e7
58!$OMP THREADPRIVATE(cte_flux_iceberg) 
59  integer, save                           :: num_antarctic = 1
60!$OMP THREADPRIVATE(num_antarctic)
61  REAL, save                              :: tau_calv
62!$OMP THREADPRIVATE(tau_calv)
63!!$
64  CONTAINS
65!
66!############################################################################
67!
68  SUBROUTINE interfsurf_hq(itime, dtime, date0, jour, rmu0, &
69      & klon, iim, jjm, nisurf, knon, knindex, pctsrf, &
70      & rlon, rlat, cufi, cvfi,&
71      & debut, lafin, ok_veget, soil_model, nsoilmx, tsoil, qsol,&
72      & zlev,  u1_lay, v1_lay, temp_air, spechum, epot_air, ccanopy, &
73      & tq_cdrag, petAcoef, peqAcoef, petBcoef, peqBcoef, &
74      & precip_rain, precip_snow, sollw, sollwdown, swnet, swdown, &
75      & fder, taux, tauy, &
76! -- LOOP
77      & windsp, &
78! -- LOOP
79      & rugos, rugoro, &
80      & albedo, snow, qsurf, &
81      & tsurf, p1lay, ps, radsol, &
82      & ocean, npas, nexca, zmasq, &
83      & evap, fluxsens, fluxlat, dflux_l, dflux_s, &             
84      & tsol_rad, tsurf_new, alb_new, alblw, emis_new, &
85      & z0_new, pctsrf_new, agesno,fqcalving,fqfonte,ffonte, run_off_lic_0,&
86!IM "slab" ocean
87      & flux_o, flux_g, tslab, seaice)
88
89
90   USE dimphy,only : monocpu,jjphy_nb,omp_rank
91! Cette routine sert d'aiguillage entre l'atmosphere et la surface en general
92! (sols continentaux, oceans, glaces) pour les fluxs de chaleur et d'humidite.
93! En pratique l'interface se fait entre la couche limite du modele
94! atmospherique (clmain.F) et les routines de surface (sechiba, oasis, ...)
95!
96!
97! L.Fairhead 02/2000
98!
99! input:
100!   itime        numero du pas de temps
101!   klon         nombre total de points de grille
102!   iim, jjm     nbres de pts de grille
103!   dtime        pas de temps de la physique (en s)
104!   date0        jour initial
105!   jour         jour dans l'annee en cours,
106!   rmu0         cosinus de l'angle solaire zenithal
107!   nexca        pas de temps couplage
108!   nisurf       index de la surface a traiter (1 = sol continental)
109!   knon         nombre de points de la surface a traiter
110!   knindex      index des points de la surface a traiter
111!   pctsrf       tableau des pourcentages de surface de chaque maille
112!   rlon         longitudes
113!   rlat         latitudes
114!   cufi,cvfi    resolution des mailles en x et y (m)
115!   debut        logical: 1er appel a la physique
116!   lafin        logical: dernier appel a la physique
117!   ok_veget     logical: appel ou non au schema de surface continental
118!                     (si false calcul simplifie des fluxs sur les continents)
119!   zlev         hauteur de la premiere couche
120!   u1_lay       vitesse u 1ere couche
121!   v1_lay       vitesse v 1ere couche
122!   temp_air     temperature de l'air 1ere couche
123!   spechum      humidite specifique 1ere couche
124!   epot_air     temp potentielle de l'air
125!   ccanopy      concentration CO2 canopee
126!   tq_cdrag     cdrag
127!   petAcoef     coeff. A de la resolution de la CL pour t
128!   peqAcoef     coeff. A de la resolution de la CL pour q
129!   petBcoef     coeff. B de la resolution de la CL pour t
130!   peqBcoef     coeff. B de la resolution de la CL pour q
131!   precip_rain  precipitation liquide
132!   precip_snow  precipitation solide
133!   sollw        flux IR net a la surface
134!   sollwdown    flux IR descendant a la surface
135!   swnet        flux solaire net
136!   swdown       flux solaire entrant a la surface
137!   albedo       albedo de la surface
138!   tsurf        temperature de surface
139!   tslab        temperature slab ocean
140!   pctsrf_slab  pourcentages (0-1) des sous-surfaces dans le slab
141!   tmp_pctsrf_slab = pctsrf_slab
142!   p1lay        pression 1er niveau (milieu de couche)
143!   ps           pression au sol
144!   radsol       rayonnement net aus sol (LW + SW)
145!   ocean        type d'ocean utilise (force, slab, couple)
146!   fder         derivee des flux (pour le couplage)
147!   taux, tauy   tension de vents
148! -- LOOP
149!   windsp       module du vent a 10m
150! -- LOOP
151!   rugos        rugosite
152!   zmasq        masque terre/ocean
153!   rugoro       rugosite orographique
154!   run_off_lic_0 runoff glacier du pas de temps precedent
155!
156! output:
157!   evap         evaporation totale
158!   fluxsens     flux de chaleur sensible
159!   fluxlat      flux de chaleur latente
160!   tsol_rad     
161!   tsurf_new    temperature au sol
162!   alb_new      albedo
163!   emis_new     emissivite
164!   z0_new       surface roughness
165!   pctsrf_new   nouvelle repartition des surfaces
166
167#include "iniprint.h"
168
169
170! Parametres d'entree
171  integer, intent(IN) :: itime
172  integer, intent(IN) :: iim, jjm
173  integer, intent(IN) :: klon
174  real, intent(IN) :: dtime
175  real, intent(IN) :: date0
176  integer, intent(IN) :: jour
177  real, intent(IN)    :: rmu0(klon)
178  integer, intent(IN) :: nisurf
179  integer, intent(IN) :: knon
180  integer, dimension(klon), intent(in) :: knindex
181  real, dimension(klon,nbsrf), intent(IN) :: pctsrf
182  logical, intent(IN) :: debut, lafin, ok_veget
183  real, dimension(klon), intent(IN) :: rlon, rlat
184  real, dimension(klon), intent(IN) :: cufi, cvfi
185  real, dimension(klon), intent(INOUT) :: tq_cdrag
186  real, dimension(klon), intent(IN) :: zlev
187  real, dimension(klon), intent(IN) :: u1_lay, v1_lay
188  real, dimension(klon), intent(IN) :: temp_air, spechum
189  real, dimension(klon), intent(IN) :: epot_air, ccanopy
190  real, dimension(klon), intent(IN) :: petAcoef, peqAcoef
191  real, dimension(klon), intent(IN) :: petBcoef, peqBcoef
192  real, dimension(klon), intent(IN) :: precip_rain, precip_snow
193  real, dimension(klon), intent(IN) :: sollw, sollwdown, swnet, swdown
194  real, dimension(klon), intent(IN) :: ps, albedo
195  real, dimension(klon), intent(IN) :: tsurf, p1lay
196!IM: "slab" ocean
197  real :: amn, amx
198  real, dimension(klon), intent(INOUT) :: tslab
199  real, allocatable, dimension(:), save :: tmp_tslab
200!$OMP THREADPRIVATE(tmp_tslab)
201  real, dimension(klon), intent(OUT) :: flux_o, flux_g
202  real, dimension(klon), intent(INOUT)        :: seaice ! glace de mer (kg/m2)
203  real, dimension(klon)                       :: siceh  ! hauteur glace de mer (m)
204  REAL, DIMENSION(klon), INTENT(INOUT) :: radsol,fder
205 
206!  real, dimension(klon), intent(IN) :: zmasq
207  real, dimension(klon), intent(IN) :: zmasq
208  real, dimension(klon), intent(IN) :: taux, tauy, rugos, rugoro
209! -- LOOP
210  real, dimension(klon), intent(IN) :: windsp
211! -- LOOP
212  character (len = 6)  :: ocean
213  integer              :: npas, nexca ! nombre et pas de temps couplage
214  real, dimension(klon), intent(INOUT) :: evap, snow, qsurf
215!! PB ajout pour soil
216  logical          :: soil_model
217  integer          :: nsoilmx
218  REAL, DIMENSION(klon, nsoilmx) :: tsoil
219  REAL, dimension(klon), intent(INOUT) :: qsol
220  REAL, dimension(klon)          :: soilcap
221  REAL, dimension(klon)          :: soilflux
222! Parametres de sortie
223  real, dimension(klon), intent(OUT):: fluxsens, fluxlat
224  real, dimension(klon), intent(OUT):: tsol_rad, tsurf_new, alb_new
225  real, dimension(klon), intent(OUT):: alblw
226  real, dimension(klon), intent(OUT):: emis_new, z0_new
227  real, dimension(klon), intent(OUT):: dflux_l, dflux_s
228  real, dimension(klon,nbsrf), intent(OUT) :: pctsrf_new
229  real, dimension(klon), intent(INOUT):: agesno
230  real, dimension(klon), intent(INOUT):: run_off_lic_0
231
232! Flux thermique utiliser pour fondre la neige
233!jld a rajouter   real, dimension(klon), intent(INOUT):: ffonte
234  real, dimension(klon), intent(INOUT):: ffonte
235! Flux d'eau "perdue" par la surface et n�essaire pour que limiter la
236! hauteur de neige, en kg/m2/s. Et quantite d'eau de fonte de la calotte.
237!jld a rajouter   real, dimension(klon), intent(INOUT):: fqcalving, fqfonte
238  REAL, DIMENSION(klon), INTENT(INOUT):: fqcalving, fqfonte
239!IM: "slab" ocean
240  real, dimension(klon) :: new_dif_grnd
241!IM: "slab" ocean - Local
242  real, parameter :: t_grnd=271.35
243  real, dimension(klon) :: zx_sl
244  integer i
245  real, allocatable, dimension(:), save :: tmp_flux_o, tmp_flux_g
246!$OMP THREADPRIVATE(tmp_flux_o, tmp_flux_g) 
247  real, allocatable, dimension(:), save :: tmp_radsol
248!$OMP THREADPRIVATE(tmp_radsol)
249  real, allocatable, dimension(:,:), save :: tmp_pctsrf_slab
250!$OMP THREADPRIVATE(tmp_pctsrf_slab)
251  real, allocatable, dimension(:), save :: tmp_seaice
252!$OMP THREADPRIVATE(tmp_seaice)
253! Local
254  character (len = 20),save :: modname = 'interfsurf_hq'
255!$OMP THREADPRIVATE(modname)
256  character (len = 80) :: abort_message
257  logical, save        :: first_call = .true.
258!$OMP THREADPRIVATE(first_call) 
259  integer, save        :: error
260!$OMP THREADPRIVATE(error) 
261  integer              :: ii, index
262  logical,save              :: check = .true.
263!$OMP THREADPRIVATE(check) 
264  real, dimension(klon):: cal, beta, dif_grnd, capsol
265!!$PB  real, parameter      :: calice=1.0/(5.1444e+06*0.15), tau_gl=86400.*5.
266  real, parameter      :: calice=1.0/(5.1444e+06*0.15), tau_gl=86400.*5.
267  real, parameter      :: calsno=1./(2.3867e+06*.15)
268  real, dimension(klon):: alb_ice
269  real, dimension(klon):: tsurf_temp
270  real, dimension(klon):: qsurf_new
271!!  real, allocatable, dimension(:), save :: alb_neig_grid
272  real, dimension(klon):: alb_neig, alb_eau
273  real, DIMENSION(klon):: zfra
274  logical              :: cumul = .false.
275  INTEGER,dimension(1) :: iloc
276  INTEGER                 :: isize
277  real, dimension(klon):: fder_prev
278  REAL, dimension(klon) :: bidule
279  real, dimension(klon) :: ps_tmp,p1lay_tmp
280  INTEGER :: j
281!
282!IM ?? quelques variables pour netcdf
283#include "netcdf.inc"
284
285  if (check) write(*,*) 'Entree ', modname
286!
287! On doit commencer par appeler les schemas de surfaces continentales
288! car l'ocean a besoin du ruissellement qui est y calcule
289!
290  if (first_call) then
291    call conf_interface(tau_calv)
292    if (nisurf /= is_ter .and. klon > 1) then
293      write(*,*)' *** Warning ***'
294      write(*,*)' nisurf = ',nisurf,' /= is_ter = ',is_ter
295      write(*,*)'or on doit commencer par les surfaces continentales'
296      abort_message='voir ci-dessus'
297      call abort_gcm(modname,abort_message,1)
298    endif
299    if (ocean /= 'slab  ' .and. ocean /= 'force ' .and. ocean /= 'couple') then
300      write(*,*)' *** Warning ***'
301      write(*,*)'Option couplage pour l''ocean = ', ocean
302      abort_message='option pour l''ocean non valable'
303      call abort_gcm(modname,abort_message,1)
304    endif
305    if ( is_oce > is_sic ) then
306      write(*,*)' *** Warning ***'
307      write(*,*)' Pour des raisons de sequencement dans le code'
308      write(*,*)' l''ocean doit etre traite avant la banquise'
309      write(*,*)' or is_oce = ',is_oce, '> is_sic = ',is_sic
310      abort_message='voir ci-dessus'
311      call abort_gcm(modname,abort_message,1)
312    endif
313!    allocate(alb_neig_grid(klon), stat = error)
314!    if (error /= 0) then
315!      abort_message='Pb allocation alb_neig_grid'
316!      call abort_gcm(modname,abort_message,1)
317!    endif
318  endif
319  first_call = .false.
320 
321! Initialisations diverses
322!
323!!$  cal=0.; beta=1.; dif_grnd=0.; capsol=0.
324!!$  alb_new = 0.; z0_new = 0.; alb_neig = 0.0
325!!$! PB
326!!$  tsurf_new = 0.
327
328!IM cf JLD
329  ffonte(1:knon)=0.
330  fqcalving(1:knon)=0.
331  fqfonte  (1:knon)=0.
332
333
334  cal = 999999. ; beta = 999999. ; dif_grnd = 999999. ; capsol = 999999.
335  alb_new = 999999. ; z0_new = 999999. ; alb_neig = 999999.
336  tsurf_new = 999999.
337  alblw = 999999.
338
339!IM: "slab" ocean; initialisations
340  flux_o = 0.
341  flux_g = 0.
342!
343    if (.not. allocated(tmp_flux_o)) then
344      allocate(tmp_flux_o(klon), stat = error)
345      DO i=1, knon
346       tmp_flux_o(knindex(i))=flux_o(i)
347      ENDDO
348      if (error /= 0) then
349        abort_message='Pb allocation tmp_flux_o'
350        call abort_gcm(modname,abort_message,1)
351      endif
352    endif
353    if (.not. allocated(tmp_flux_g)) then 
354      allocate(tmp_flux_g(klon), stat = error)
355      DO i=1, knon
356       tmp_flux_g(knindex(i))=flux_g(i)
357      ENDDO
358      if (error /= 0) then
359        abort_message='Pb allocation tmp_flux_g'
360        call abort_gcm(modname,abort_message,1)
361      endif
362    endif
363    if (.not. allocated(tmp_radsol)) then 
364      allocate(tmp_radsol(klon), stat = error)
365      if (error /= 0) then
366        abort_message='Pb allocation tmp_radsol'
367        call abort_gcm(modname,abort_message,1)
368      endif
369    endif
370    if (.not. allocated(tmp_pctsrf_slab)) then
371      allocate(tmp_pctsrf_slab(klon,nbsrf), stat = error)
372      if (error /= 0) then
373        abort_message='Pb allocation tmp_pctsrf_slab'
374        call abort_gcm(modname,abort_message,1)
375      endif
376    DO i=1, klon
377     tmp_pctsrf_slab(i,1:nbsrf)=pctsrf(i,1:nbsrf)
378    ENDDO
379    endif
380!
381    if (.not. allocated(tmp_seaice)) then
382      allocate(tmp_seaice(klon), stat = error)
383      if (error /= 0) then
384        abort_message='Pb allocation tmp_seaice'
385        call abort_gcm(modname,abort_message,1)
386      endif
387    IF(check) THEN
388     PRINT*,'allocation tmp_seaice nisurf itime',nisurf, itime
389    ENDIF
390    endif
391!
392    if (.not. allocated(tmp_tslab)) then
393      allocate(tmp_tslab(klon), stat = error)
394      if (error /= 0) then
395        abort_message='Pb allocation tmp_tslab'
396        call abort_gcm(modname,abort_message,1)
397      endif
398    endif
399    DO i=1, klon
400     tmp_tslab(i)=tslab(i)
401    ENDDO
402!
403! Aiguillage vers les differents schemas de surface
404
405  if (nisurf == is_ter) then
406!
407! Surface "terre" appel a l'interface avec les sols continentaux
408!
409! allocation du run-off
410    if (.not. allocated(coastalflow)) then
411      allocate(coastalflow(knon), stat = error)
412      if (error /= 0) then
413        abort_message='Pb allocation coastalflow'
414        call abort_gcm(modname,abort_message,1)
415      endif
416      allocate(riverflow(knon), stat = error)
417      if (error /= 0) then
418        abort_message='Pb allocation riverflow'
419        call abort_gcm(modname,abort_message,1)
420      endif
421      allocate(run_off(knon), stat = error)
422      if (error /= 0) then
423        abort_message='Pb allocation run_off'
424        call abort_gcm(modname,abort_message,1)
425      endif
426!cym     
427      run_off=0.0
428!cym
429
430!!$PB
431      ALLOCATE (tmp_rriv(iim,jjphy_nb), stat=error)
432      if (error /= 0) then
433        abort_message='Pb allocation tmp_rriv'
434        call abort_gcm(modname,abort_message,1)
435      endif
436      tmp_rriv=0.
437      ALLOCATE (tmp_rcoa(iim,jjphy_nb), stat=error)
438      if (error /= 0) then
439        abort_message='Pb allocation tmp_rcoa'
440        call abort_gcm(modname,abort_message,1)
441      endif
442      tmp_rcoa=0.
443!ym      ALLOCATE (tmp_rlic(iim,jjm+1), stat=error)
444      ALLOCATE (tmp_rlic(iim,jjphy_nb), stat=error)
445      if (error /= 0) then
446        abort_message='Pb allocation tmp_rlic'
447        call abort_gcm(modname,abort_message,1)
448      endif
449      tmp_rlic=0.
450!!$
451    else if (size(coastalflow) /= knon) then
452      write(*,*)'Bizarre, le nombre de points continentaux'
453      write(*,*)'a change entre deux appels. J''arrete ...'
454      abort_message='voir ci-dessus'
455      call abort_gcm(modname,abort_message,1)
456    endif
457    coastalflow = 0.
458    riverflow = 0.
459!
460! Calcul age de la neige
461!
462!!$ PB ATTENTION changement ordre des appels
463!!$    CALL albsno(klon,agesno,alb_neig_grid) 
464
465    if (.not. ok_veget) then
466!
467! calcul albedo: lecture albedo fichier CL puis ajout albedo neige
468!
469       call interfsur_lim(itime, dtime, jour, &
470     & klon, nisurf, knon, knindex, debut,  &
471     & alb_new, z0_new)
472
473! calcul snow et qsurf, hydrol adapt�!
474       CALL calbeta(dtime, nisurf, knon, snow, qsol, beta, capsol, dif_grnd)
475
476       IF (soil_model) THEN
477           CALL soil(dtime, nisurf, knon,snow, tsurf, tsoil,soilcap, soilflux)
478           cal(1:knon) = RCPD / soilcap(1:knon)
479           radsol(1:knon) = radsol(1:knon)  + soilflux(1:knon)
480       ELSE
481           cal = RCPD * capsol
482!!$      cal = capsol
483       ENDIF
484       CALL calcul_fluxs( klon, knon, nisurf, dtime, &
485     &   tsurf, p1lay, cal, beta, tq_cdrag, ps, &
486     &   precip_rain, precip_snow, snow, qsurf,  &
487     &   radsol, dif_grnd, temp_air, spechum, u1_lay, v1_lay, &
488     &   petAcoef, peqAcoef, petBcoef, peqBcoef, &
489     &   tsurf_new, evap, fluxlat, fluxsens, dflux_s, dflux_l)
490
491       CALL fonte_neige( klon, knon, nisurf, dtime, &
492     &   tsurf, p1lay, cal, beta, tq_cdrag, ps, &
493     &   precip_rain, precip_snow, snow, qsol,  &
494     &   radsol, dif_grnd, temp_air, spechum, u1_lay, v1_lay, &
495     &   petAcoef, peqAcoef, petBcoef, peqBcoef, &
496     &   tsurf_new, evap, fluxlat, fluxsens, dflux_s, dflux_l, &
497     &   fqcalving,fqfonte,ffonte, run_off_lic_0)
498
499
500     call albsno(klon,knon,dtime,agesno(:),alb_neig(:), precip_snow(:)) 
501     where (snow(1 : knon) .LT. 0.0001) agesno(1 : knon) = 0.
502     zfra(1:knon) = max(0.0,min(1.0,snow(1:knon)/(snow(1:knon)+10.0)))
503     alb_new(1 : knon)  = alb_neig(1 : knon) *zfra(1:knon) + &
504    &                     alb_new(1 : knon)*(1.0-zfra(1:knon))
505     z0_new = sqrt(z0_new**2+rugoro**2)
506     alblw(1 : knon) = alb_new(1 : knon)
507
508    else
509!!      CALL albsno(klon,agesno,alb_neig_grid) 
510!
511!  appel a sechiba
512!
513#ifdef CPP_VEGET
514      p1lay_tmp(1:knon)=p1lay(1:knon)/100.
515      ps_tmp(1:knon)=ps(1:knon)/100.
516 
517       call interfsol(itime, klon, dtime, date0, nisurf, knon, &
518     &  knindex, rlon, rlat, cufi, cvfi, iim, jjm, pctsrf, &
519     &  debut, lafin, ok_veget, &
520     &  zlev,  u1_lay, v1_lay, temp_air, spechum, epot_air, ccanopy, &
521     &  tq_cdrag, petAcoef, peqAcoef, petBcoef, peqBcoef, &
522     &  precip_rain, precip_snow, sollwdown, swnet, swdown, &
523     &  tsurf, p1lay_tmp, ps_tmp, radsol, &
524     &  evap, fluxsens, fluxlat, &             
525     &  tsol_rad, tsurf_new, alb_new, alblw, &
526     &  emis_new, z0_new, dflux_l, dflux_s, qsurf_new)
527
528
529! ajout de la contribution du relief
530
531      z0_new = SQRT(z0_new**2+rugoro**2)
532!
533! mise a jour de l'humidite saturante calculee par ORCHIDEE
534      qsurf(1:knon) = qsurf_new(1:knon)
535#else
536      abort_message='Pb de coherence: ok_veget = .t. mais CPP_VEGET = .f.'
537      call abort_gcm(modname,abort_message,1)
538#endif
539
540    endif   
541!
542! Remplissage des pourcentages de surface
543!
544    pctsrf_new(:,nisurf) = pctsrf(:,nisurf)
545
546  else if (nisurf == is_oce) then
547
548    if (check) write(*,*)'ocean, nisurf = ',nisurf,'knon=',knon
549!
550! Surface "ocean" appel a l'interface avec l'ocean
551!
552    if (ocean == 'couple') then
553      if (nexca == 0) then
554        abort_message='nexca = 0 dans interfoce_cpl'
555        call abort_gcm(modname,abort_message,1)
556      endif
557
558      cumul = .false.
559
560      iloc = maxloc(fder(1:klon))
561      if (check) then
562        if (fder(iloc(1))> 0.) then
563          WRITE(*,*)'**** Debug fder ****'
564          WRITE(*,*)'max fder(',iloc(1),') = ',fder(iloc(1))
565        endif
566      endif
567!!$
568!!$      where(fder.gt.0.)
569!!$        fder = 0.
570!!$      endwhere
571
572      call interfoce(itime, dtime, cumul, &
573      & klon, iim, jjm, nisurf, pctsrf, knon, knindex, rlon, rlat, &
574      & ocean, npas, nexca, debut, lafin, &
575      & swdown, sollw, precip_rain, precip_snow, evap, tsurf, &
576      & fluxlat, fluxsens, fder, albedo, taux, tauy, &
577! -- LOOP
578      & windsp, &
579! -- LOOP
580      & zmasq, &
581      & tsurf_new, alb_new, &
582      & pctsrf_new)
583
584!IM: "slab" ocean
585     else if (ocean == 'slab  ') then
586      DO i=1, knon
587       tsurf_new(i) = tmp_tslab(knindex(i))
588      ENDDO
589      pctsrf_new = tmp_pctsrf_slab
590!
591    else                              ! lecture conditions limites
592      call interfoce(itime, dtime, jour, &
593     &  klon, nisurf, knon, knindex, &
594     &  debut, &
595     &  tsurf_new, pctsrf_new)
596
597    endif
598
599    tsurf_temp = tsurf_new
600    cal = 0.
601    beta = 1.
602    dif_grnd = 0.
603    alb_neig(:) = 0.
604    agesno(:) = 0.
605
606    call calcul_fluxs( klon, knon, nisurf, dtime, &
607     &   tsurf_temp, p1lay, cal, beta, tq_cdrag, ps, &
608     &   precip_rain, precip_snow, snow, qsurf,  &
609     &   radsol, dif_grnd, temp_air, spechum, u1_lay, v1_lay, &
610     &   petAcoef, peqAcoef, petBcoef, peqBcoef, &
611     &   tsurf_new, evap, fluxlat, fluxsens, dflux_s, dflux_l)
612
613    fder_prev = fder   
614    fder = fder_prev + dflux_s + dflux_l
615
616      iloc = maxloc(fder(1:klon))
617        if (check.and.fder(iloc(1))> 0.) then
618          WRITE(*,*)'**** Debug fder****'
619          WRITE(*,*)'max fder(',iloc(1),') = ',fder(iloc(1))
620          WRITE(*,*)'fder_prev, dflux_s, dflux_l',fder_prev(iloc(1)), &
621     &                        dflux_s(iloc(1)), dflux_l(iloc(1))
622        endif
623!!$
624!!$      where(fder.gt.0.)
625!!$        fder = 0.
626!!$      endwhere
627
628!IM: flux ocean-atmosphere utile pour le "slab" ocean
629    DO i=1, knon
630     zx_sl(i) = RLVTT
631     if (tsurf_new(i) .LT. RTT) zx_sl(i) = RLSTT
632!IM     flux_o(i) = fluxsens(i)-evap(i)*zx_sl(i)
633     flux_o(i) = fluxsens(i) + fluxlat(i)
634     tmp_flux_o(knindex(i)) = flux_o(i)
635     tmp_radsol(knindex(i))=radsol(i)
636    ENDDO
637!
638! 2eme appel a interfoce pour le cumul des champs (en particulier
639! fluxsens et fluxlat calcules dans calcul_fluxs)
640!
641    if (ocean == 'couple') then
642
643      cumul = .true.
644
645      call interfoce(itime, dtime, cumul, &
646      & klon, iim, jjm, nisurf, pctsrf, knon, knindex, rlon, rlat, &
647      & ocean, npas, nexca, debut, lafin, &
648      & swdown, sollw, precip_rain, precip_snow, evap, tsurf, &
649      & fluxlat, fluxsens, fder, albedo, taux, tauy, &
650! -- LOOP
651      & windsp, &
652! -- LOOP
653      & zmasq, &
654      & tsurf_new, alb_new, &
655      & pctsrf_new)
656
657    endif
658
659!
660! calcul albedo
661!
662
663    if ( minval(rmu0) == maxval(rmu0) .and. minval(rmu0) == -999.999 ) then
664      CALL alboc(FLOAT(jour),rlat,alb_eau)
665    else  ! cycle diurne
666      CALL alboc_cd(rmu0,alb_eau)
667    endif
668    DO ii =1, knon
669      alb_new(ii) = alb_eau(knindex(ii))
670    enddo
671
672    z0_new = sqrt(rugos**2 + rugoro**2)
673    alblw(1:knon) = alb_new(1:knon)
674
675!
676  else if (nisurf == is_sic) then
677
678    if (check) write(*,*)'sea ice, nisurf = ',nisurf,'knon=',knon
679!
680! Surface "glace de mer" appel a l'interface avec l'ocean
681!
682!
683    if (ocean == 'couple') then
684
685      cumul =.false.
686
687      iloc = maxloc(fder(1:klon))
688      if (check.and.fder(iloc(1))> 0.) then
689        WRITE(*,*)'**** Debug fder ****'
690        WRITE(*,*)'max fder(',iloc(1),') = ',fder(iloc(1))
691      endif
692!!$
693!!$      where(fder.gt.0.)
694!!$        fder = 0.
695!!$      endwhere
696
697      call interfoce(itime, dtime, cumul, &
698      & klon, iim, jjm, nisurf, pctsrf, knon, knindex, rlon, rlat, &
699      & ocean, npas, nexca, debut, lafin, &
700      & swdown, sollw, precip_rain, precip_snow, evap, tsurf, &
701      & fluxlat, fluxsens, fder, albedo, taux, tauy, &
702! -- LOOP
703      & windsp, &
704! -- LOOP
705      & zmasq, &
706      & tsurf_new, alb_new, &
707      & pctsrf_new)
708
709      tsurf_temp = tsurf_new
710      cal = 0.
711      dif_grnd = 0.
712      beta = 1.0
713
714!IM: "slab" ocean
715    else if (ocean == 'slab  ') then
716!IM ajout sicOBSERVE BEG
717   IF ( ok_slab_sicOBS) THEN
718!                              ! lecture conditions limites
719      CALL interfoce(itime, dtime, jour, &
720             &  klon, nisurf, knon, knindex, &
721             &  debut, &
722             &  tsurf_new, pctsrf_new)
723!
724    tmp_pctsrf_slab=pctsrf_new
725    print*,'jour lecture pctsrf_new sic =',jour
726!
727   ELSE !ok_slab_sicOBS
728     pctsrf_new=tmp_pctsrf_slab
729   ENDIF
730!IM ajout sicOBSERVE END
731!
732     DO ii = 1, knon
733      tsurf_new(ii) = tsurf(ii)
734      IF (pctsrf_new(knindex(ii),nisurf) < EPSFRA) then
735       snow(ii) = 0.0
736       tsurf_new(ii) = RTT - 1.8
737       IF (soil_model) tsoil(ii,:) = RTT -1.8
738      ENDIF
739     ENDDO
740
741     CALL calbeta(dtime, nisurf, knon, snow, qsol, beta, capsol, dif_grnd)
742     
743     IF (soil_model) THEN
744      CALL soil(dtime, nisurf, knon,snow, tsurf_new, tsoil,soilcap, soilflux)
745      cal(1:knon) = RCPD / soilcap(1:knon)
746      radsol(1:knon) = radsol(1:knon)  + soilflux(1:knon)
747     ELSE
748      dif_grnd = 1.0 / tau_gl
749      cal = RCPD * calice
750      WHERE (snow > 0.0) cal = RCPD * calsno
751     ENDIF
752     tsurf_temp = tsurf_new
753     beta = 1.0
754!
755    ELSE
756!                              ! lecture conditions limites
757      CALL interfoce(itime, dtime, jour, &
758             &  klon, nisurf, knon, knindex, &
759             &  debut, &
760             &  tsurf_new, pctsrf_new)
761
762!IM cf LF
763      DO ii = 1, knon
764       tsurf_new(ii) = tsurf(ii)
765       IF (pctsrf_new(knindex(ii),nisurf) < EPSFRA) then
766          snow(ii) = 0.0
767!IM cf LF/JLD         tsurf(ii) = RTT - 1.8
768          tsurf_new(ii) = RTT - 1.8
769          IF (soil_model) tsoil(ii,:) = RTT -1.8
770        endif
771      enddo
772
773      CALL calbeta(dtime, nisurf, knon, snow, qsol, beta, capsol, dif_grnd)
774     
775      IF (soil_model) THEN
776!IM cf LF/JLD        CALL soil(dtime, nisurf, knon,snow, tsurf, tsoil,soilcap, soilflux)
777         CALL soil(dtime, nisurf, knon,snow, tsurf_new, tsoil,soilcap, soilflux)
778         cal(1:knon) = RCPD / soilcap(1:knon)
779         radsol(1:knon) = radsol(1:knon)  + soilflux(1:knon)
780         dif_grnd = 1.0 / tau_gl
781      ELSE
782         dif_grnd = 1.0 / tau_gl
783         cal = RCPD * calice
784         WHERE (snow > 0.0) cal = RCPD * calsno
785      ENDIF
786!IMbadtsurf_temp = tsurf
787      tsurf_temp = tsurf_new
788      beta = 1.0
789    ENDIF !ocean ==
790
791    CALL calcul_fluxs( klon, knon, nisurf, dtime, &
792         &   tsurf_temp, p1lay, cal, beta, tq_cdrag, ps, &
793         &   precip_rain, precip_snow, snow, qsurf,  &
794         &   radsol, dif_grnd, temp_air, spechum, u1_lay, v1_lay, &
795         &   petAcoef, peqAcoef, petBcoef, peqBcoef, &
796         &   tsurf_new, evap, fluxlat, fluxsens, dflux_s, dflux_l)
797!
798    IF (ocean /= 'couple') THEN
799      CALL fonte_neige( klon, knon, nisurf, dtime, &
800             &   tsurf_temp, p1lay, cal, beta, tq_cdrag, ps, &
801             &   precip_rain, precip_snow, snow, qsol,  &
802             &   radsol, dif_grnd, temp_air, spechum, u1_lay, v1_lay, &
803             &   petAcoef, peqAcoef, petBcoef, peqBcoef, &
804             &   tsurf_new, evap, fluxlat, fluxsens, dflux_s, dflux_l, &
805             &   fqcalving,fqfonte,ffonte, run_off_lic_0)
806
807!     calcul albedo
808
809      CALL albsno(klon,knon,dtime,agesno(:),alb_neig(:), precip_snow(:)) 
810      WHERE (snow(1 : knon) .LT. 0.0001) agesno(1 : knon) = 0.
811      zfra(1:knon) = MAX(0.0,MIN(1.0,snow(1:knon)/(snow(1:knon)+10.0)))
812      alb_new(1 : knon) = alb_neig(1 : knon) *zfra(1:knon) + &
813     &                    0.6 * (1.0-zfra(1:knon))
814!!      alb_new(1 : knon) = 0.6
815    ENDIF
816!
817!IM: flux entre l'ocean et la glace de mer pour le "slab" ocean
818!
819    DO i = 1, knon
820!
821!IM: faire dependre le coefficient de conduction de la glace de mer
822!    de l'epaisseur de la glace de mer, dans l'hypothese ou le coeff.
823!    actuel correspond a 3m de glace de mer, cf. L.Li
824!
825       IF(1.EQ.0) THEN
826        IF(siceh(i).GT.0.) THEN
827         new_dif_grnd(i) = dif_grnd(i)*3./siceh(i)
828        ELSE
829         new_dif_grnd(i) = 0.
830        ENDIF
831       ENDIF !(1.EQ.0) THEN
832!
833     IF (cal(i).GT.1.0e-15) THEN
834       flux_g(i)=(tsurf_new(i)-t_grnd) &
835    &                          * dif_grnd(i) *RCPD/cal(i)
836!   &                          * new_dif_grnd(i) *RCPD/cal(i)
837     ENDIF
838     tmp_flux_g(knindex(i))=flux_g(i)
839!
840!IM: Attention: ne pas initialiser le tmp_radsol puisque c'est deja fait sur is_oce;
841!IM:            tmp_radsol doit etre le flux solaire qui arrive sur l'ocean
842!IM:            et non pas celui qui arrive sur la glace de mer
843!
844    ENDDO
845
846    fder_prev = fder   
847    fder = fder_prev + dflux_s + dflux_l
848
849      iloc = maxloc(fder(1:klon))
850      if (check.and.fder(iloc(1))> 0.) then
851        WRITE(*,*)'**** Debug fder ****'
852        WRITE(*,*)'max fder(',iloc(1),') = ',fder(iloc(1))
853        WRITE(*,*)'fder_prev, dflux_s, dflux_l',fder_prev(iloc(1)), &
854     &                        dflux_s(iloc(1)), dflux_l(iloc(1))
855      endif
856!!$      where(fder.gt.0.)
857!!$        fder = 0.
858!!$      endwhere
859
860!
861! 2eme appel a interfoce pour le cumul et le passage des flux a l'ocean
862!
863    if (ocean == 'couple') then
864
865      cumul =.true.
866
867      call interfoce(itime, dtime, cumul, &
868      & klon, iim, jjm, nisurf, pctsrf, knon, knindex, rlon, rlat, &
869      & ocean, npas, nexca, debut, lafin, &
870      & swdown, sollw, precip_rain, precip_snow, evap, tsurf, &
871      & fluxlat, fluxsens, fder, albedo, taux, tauy, &
872! -- LOOP
873      & windsp, &
874! -- LOOP
875      & zmasq, &
876      & tsurf_new, alb_new, &
877      & pctsrf_new)
878
879!IM: "slab" ocean
880    else if (ocean == 'slab  ') then
881!
882   IF (check) THEN
883    amn=MIN(tmp_tslab(1),1000.)
884    amx=MAX(tmp_tslab(1),-1000.)
885    DO i=2, klon
886     amn=MIN(tmp_tslab(i),amn)
887     amx=MAX(tmp_tslab(i),amx)
888    ENDDO
889!
890    PRINT*,' debut avant interfoce_slab min max tmp_tslab',amn,amx
891   ENDIF !(check) THEN
892!
893       cumul = .true.
894       tslab = tmp_tslab   
895       call interfoce(klon, debut, itime, dtime, jour, &
896     & tmp_radsol, tmp_flux_o, tmp_flux_g, tmp_pctsrf_slab, &
897     & tslab, seaice, pctsrf_new)
898!
899       tmp_seaice=seaice
900       tmp_pctsrf_slab=pctsrf_new
901       DO i=1, knon
902         tmp_tslab(knindex(i))=tslab(knindex(i))
903       ENDDO !i
904!
905
906    endif
907
908     
909    z0_new = 0.002
910    z0_new = SQRT(z0_new**2+rugoro**2)
911    alblw(1:knon) = alb_new(1:knon)
912
913
914  else if (nisurf == is_lic) then
915
916    if (check) write(*,*)'glacier, nisurf = ',nisurf
917
918    if (.not. allocated(run_off_lic)) then
919      allocate(run_off_lic(klon), stat = error)
920      if (error /= 0) then
921        abort_message='Pb allocation run_off_lic'
922        call abort_gcm(modname,abort_message,1)
923      endif
924      run_off_lic = 0.
925    endif
926!
927! Surface "glacier continentaux" appel a l'interface avec le sol
928!
929!    call interfsol(nisurf)
930    IF (soil_model) THEN
931        CALL soil(dtime, nisurf, knon, snow, tsurf, tsoil,soilcap, soilflux)
932        cal(1:knon) = RCPD / soilcap(1:knon)
933        radsol(1:knon)  = radsol(1:knon) + soilflux(1:knon)
934    ELSE
935        cal = RCPD * calice
936        WHERE (snow > 0.0) cal = RCPD * calsno
937    ENDIF
938    beta = 1.0
939    dif_grnd = 0.0
940
941    call calcul_fluxs( klon, knon, nisurf, dtime, &
942     &   tsurf, p1lay, cal, beta, tq_cdrag, ps, &
943     &   precip_rain, precip_snow, snow, qsurf,  &
944     &   radsol, dif_grnd, temp_air, spechum, u1_lay, v1_lay, &
945     &   petAcoef, peqAcoef, petBcoef, peqBcoef, &
946     &   tsurf_new, evap, fluxlat, fluxsens, dflux_s, dflux_l)
947
948    call fonte_neige( klon, knon, nisurf, dtime, &
949     &   tsurf, p1lay, cal, beta, tq_cdrag, ps, &
950     &   precip_rain, precip_snow, snow, qsol,  &
951     &   radsol, dif_grnd, temp_air, spechum, u1_lay, v1_lay, &
952     &   petAcoef, peqAcoef, petBcoef, peqBcoef, &
953     &   tsurf_new, evap, fluxlat, fluxsens, dflux_s, dflux_l, &
954     &   fqcalving,fqfonte,ffonte, run_off_lic_0)
955
956! passage du run-off des glaciers calcule dans fonte_neige au coupleur
957    bidule=0.
958    bidule(1:knon)= run_off_lic(1:knon)   
959    call gath2cpl(bidule, tmp_rlic, klon, knon,iim,jjm,knindex)
960!
961! calcul albedo
962!
963     CALL albsno(klon,knon,dtime,agesno(:),alb_neig(:), precip_snow(:)) 
964     WHERE (snow(1 : knon) .LT. 0.0001) agesno(1 : knon) = 0.
965     zfra(1:knon) = MAX(0.0,MIN(1.0,snow(1:knon)/(snow(1:knon)+10.0)))
966     alb_new(1 : knon)  = alb_neig(1 : knon)*zfra(1:knon) + &
967    &                     0.6 * (1.0-zfra(1:knon))
968!
969!IM: plusieurs choix/tests sur l'albedo des "glaciers continentaux"
970!       alb_new(1 : knon)  = 0.6 !IM cf FH/GK
971!       alb_new(1 : knon)  = 0.82
972!       alb_new(1 : knon)  = 0.77 !211003 Ksta0.77
973!       alb_new(1 : knon)  = 0.8 !KstaTER0.8 & LMD_ARMIP5
974!IM: KstaTER0.77 & LMD_ARMIP6   
975        alb_new(1 : knon)  = 0.77
976
977!
978! Rugosite
979!
980    z0_new = rugoro
981!
982! Remplissage des pourcentages de surface
983!
984    pctsrf_new(:,nisurf) = pctsrf(:,nisurf)
985
986    alblw(1:knon) = alb_new(1:knon)
987  else
988    write(*,*)'Index surface = ',nisurf
989    abort_message = 'Index surface non valable'
990    call abort_gcm(modname,abort_message,1)
991  endif
992
993  END SUBROUTINE interfsurf_hq
994
995!
996!#########################################################################
997!
998  SUBROUTINE interfsurf_vent(nisurf, knon   &         
999  &                     )
1000!
1001! Cette routine sert d'aiguillage entre l'atmosphere et la surface en general
1002! (sols continentaux, oceans, glaces) pour les tensions de vents.
1003! En pratique l'interface se fait entre la couche limite du modele
1004! atmospherique (clmain.F) et les routines de surface (sechiba, oasis, ...)
1005!
1006!
1007! L.Fairhead 02/2000
1008!
1009! input:
1010!   nisurf       index de la surface a traiter (1 = sol continental)
1011!   knon         nombre de points de la surface a traiter
1012
1013! Parametres d'entree
1014  integer, intent(IN) :: nisurf
1015  integer, intent(IN) :: knon
1016
1017
1018  return
1019  END SUBROUTINE interfsurf_vent
1020!
1021!#########################################################################
1022!
1023#ifdef CPP_VEGET
1024  SUBROUTINE interfsol(itime, klon, dtime, date0, nisurf, knon, &
1025     & knindex, rlon, rlat, cufi, cvfi, iim, jjm, pctsrf, &
1026     & debut, lafin, ok_veget, &
1027     & plev,  u1_lay, v1_lay, temp_air, spechum, epot_air, ccanopy, &
1028     & tq_cdrag, petAcoef, peqAcoef, petBcoef, peqBcoef, &
1029     & precip_rain, precip_snow, lwdown, swnet, swdown, &
1030     & tsurf, p1lay, ps, radsol, &
1031     & evap, fluxsens, fluxlat, &             
1032     & tsol_rad, tsurf_new, alb_new, alblw, &
1033     & emis_new, z0_new, dflux_l, dflux_s, qsurf)
1034
1035  USE intersurf
1036  USE dimphy, klon_x=>klon
1037  IMPLICIT NONE
1038! Cette routine sert d'interface entre le modele atmospherique et le
1039! modele de sol continental. Appel a sechiba
1040!
1041! L. Fairhead 02/2000
1042!
1043! input:
1044!   itime        numero du pas de temps
1045!   klon         nombre total de points de grille
1046!   dtime        pas de temps de la physique (en s)
1047!   nisurf       index de la surface a traiter (1 = sol continental)
1048!   knon         nombre de points de la surface a traiter
1049!   knindex      index des points de la surface a traiter
1050!   rlon         longitudes de la grille entiere
1051!   rlat         latitudes de la grille entiere
1052!   pctsrf       tableau des fractions de surface de chaque maille
1053!   debut        logical: 1er appel a la physique (lire les restart)
1054!   lafin        logical: dernier appel a la physique (ecrire les restart)
1055!   ok_veget     logical: appel ou non au schema de surface continental
1056!                     (si false calcul simplifie des fluxs sur les continents)
1057!   plev         hauteur de la premiere couche (Pa)     
1058!   u1_lay       vitesse u 1ere couche
1059!   v1_lay       vitesse v 1ere couche
1060!   temp_air     temperature de l'air 1ere couche
1061!   spechum      humidite specifique 1ere couche
1062!   epot_air     temp pot de l'air
1063!   ccanopy      concentration CO2 canopee
1064!   tq_cdrag     cdrag
1065!   petAcoef     coeff. A de la resolution de la CL pour t
1066!   peqAcoef     coeff. A de la resolution de la CL pour q
1067!   petBcoef     coeff. B de la resolution de la CL pour t
1068!   peqBcoef     coeff. B de la resolution de la CL pour q
1069!   precip_rain  precipitation liquide
1070!   precip_snow  precipitation solide
1071!   lwdown       flux IR descendant a la surface
1072!   swnet        flux solaire net
1073!   swdown       flux solaire entrant a la surface
1074!   tsurf        temperature de surface
1075!   p1lay        pression 1er niveau (milieu de couche)
1076!   ps           pression au sol
1077!   radsol       rayonnement net aus sol (LW + SW)
1078!   
1079!
1080! input/output
1081!   run_off      ruissellement total
1082!
1083! output:
1084!   evap         evaporation totale
1085!   fluxsens     flux de chaleur sensible
1086!   fluxlat      flux de chaleur latente
1087!   tsol_rad     
1088!   tsurf_new    temperature au sol
1089!   alb_new      albedo
1090!   emis_new     emissivite
1091!   z0_new       surface roughness
1092!   qsurf        air moisture at surface
1093
1094! Parametres d'entree
1095  integer, intent(IN) :: itime
1096  integer, intent(IN) :: klon
1097  real, intent(IN)    :: dtime
1098  real, intent(IN)    :: date0
1099  integer, intent(IN) :: nisurf
1100  integer, intent(IN) :: knon
1101  integer, intent(IN) :: iim, jjm
1102  integer, dimension(klon), intent(IN) :: knindex
1103  logical, intent(IN) :: debut, lafin, ok_veget
1104  real, dimension(klon,nbsrf), intent(IN) :: pctsrf
1105  real, dimension(klon), intent(IN) :: rlon, rlat
1106  real, dimension(klon), intent(IN) :: cufi, cvfi
1107  real, dimension(klon), intent(IN) :: plev
1108  real, dimension(klon), intent(IN) :: u1_lay, v1_lay
1109  real, dimension(klon), intent(IN) :: temp_air, spechum
1110  real, dimension(klon), intent(IN) :: epot_air, ccanopy
1111  real, dimension(klon), intent(INOUT) :: tq_cdrag
1112  real, dimension(klon), intent(IN) :: petAcoef, peqAcoef
1113  real, dimension(klon), intent(IN) :: petBcoef, peqBcoef
1114  real, dimension(klon), intent(IN) :: precip_rain, precip_snow
1115  real, dimension(klon), intent(IN) :: lwdown, swnet, swdown, ps
1116!IM cf. JP +++
1117  real, dimension(klon) :: swdown_vrai
1118!IM cf. JP ---
1119  real, dimension(klon), intent(IN) :: tsurf, p1lay
1120  real, dimension(klon), intent(IN) :: radsol
1121! Parametres de sortie
1122  real, dimension(klon), intent(OUT):: evap, fluxsens, fluxlat, qsurf
1123  real, dimension(klon), intent(OUT):: tsol_rad, tsurf_new, alb_new, alblw
1124  real, dimension(klon), intent(OUT):: emis_new, z0_new
1125  real, dimension(klon), intent(OUT):: dflux_s, dflux_l
1126
1127! Local
1128!
1129  integer              :: ii, ij, jj, igrid, ireal, i, index, iglob
1130  integer              :: error
1131  character (len = 20) :: modname = 'interfsol'
1132  character (len = 80) :: abort_message
1133  logical,save              :: check = .FALSE.
1134  real, dimension(klon) :: cal, beta, dif_grnd, capsol
1135! type de couplage dans sechiba
1136!  character (len=10)   :: coupling = 'implicit'
1137! drapeaux controlant les appels dans SECHIBA
1138!  type(control_type), save   :: control_in
1139! Preserved albedo
1140!IM cf. JP +++
1141  real, allocatable, dimension(:), save :: albedo_keep, zlev
1142!IM cf. JP ---
1143! coordonnees geographiques
1144  real, allocatable, dimension(:,:), save :: lalo
1145! pts voisins
1146  integer,allocatable, dimension(:,:), save :: neighbours
1147! fractions continents
1148  real,allocatable, dimension(:), save :: contfrac
1149! resolution de la grille
1150  real, allocatable, dimension (:,:), save :: resolution
1151! correspondance point n -> indices (i,j)
1152  integer, allocatable, dimension(:,:), save :: correspond
1153! offset pour calculer les point voisins
1154  integer, dimension(8,3), save :: off_ini
1155 ! Identifieurs des fichiers restart et histoire
1156  integer, save          :: rest_id, hist_id
1157  integer, save          :: rest_id_stom, hist_id_stom
1158!
1159  real, allocatable, dimension (:,:), save :: lon_scat, lat_scat 
1160
1161  logical, save          :: lrestart_read = .true. , lrestart_write = .false.
1162
1163  real, dimension(klon):: snow
1164  real, dimension(knon,2) :: albedo_out
1165! Pb de nomenclature
1166  real, dimension(klon) :: petA_orc, peqA_orc
1167  real, dimension(klon) :: petB_orc, peqB_orc
1168! Pb de correspondances de grilles
1169  integer, dimension(:), save, allocatable :: ig, jg
1170  integer :: indi, indj
1171  integer, save, allocatable,dimension(:) :: ktindex
1172  REAL, dimension(klon) :: bidule
1173! Essai cdrag
1174  real, dimension(klon) :: cdrag
1175  integer :: jjb,jje,ijb,ije
1176  INTEGER,SAVE :: offset
1177  REAL, dimension(klon2) :: rlon_g,rlat_g
1178  INTEGER, SAVE          :: orch_comm
1179#include "temps.inc"
1180#include "YOMCST.inc"
1181#include "iniprint.h"
1182
1183  if (check) write(lunout,*)'Entree ', modname
1184  if (check) write(lunout,*)'ok_veget = ',ok_veget
1185
1186
1187 
1188! initialisation
1189 
1190  if (debut) then
1191    ALLOCATE(ktindex(klon))
1192  IF ( .NOT. allocated(albedo_keep)) THEN
1193     ALLOCATE(albedo_keep(klon))
1194     ALLOCATE(zlev(klon))
1195  ENDIF
1196! Pb de correspondances de grilles
1197   allocate(ig(klon))
1198   allocate(jg(klon))
1199   ig(1) = 1
1200   jg(1) = 1
1201   indi = 0
1202   indj = 2
1203   do igrid = 2, klon - 1
1204     indi = indi + 1
1205     if ( indi > iim) then
1206       indi = 1
1207       indj = indj + 1
1208     endif
1209     ig(igrid) = indi
1210     jg(igrid) = indj
1211   enddo
1212   ig(klon) = 1
1213   jg(klon) = jjm + 1
1214
1215    if ((.not. allocated(lalo))) then
1216      allocate(lalo(knon,2), stat = error)
1217      if (error /= 0) then
1218        abort_message='Pb allocation lalo'
1219        call abort_gcm(modname,abort_message,1)
1220      endif     
1221    endif
1222    if ((.not. allocated(lon_scat))) then
1223      allocate(lon_scat(iim,jjm+1), stat = error)
1224      if (error /= 0) then
1225        abort_message='Pb allocation lon_scat'
1226        call abort_gcm(modname,abort_message,1)
1227      endif     
1228    endif
1229    if ((.not. allocated(lat_scat))) then
1230      allocate(lat_scat(iim,jjm+1), stat = error)
1231      if (error /= 0) then
1232        abort_message='Pb allocation lat_scat'
1233        call abort_gcm(modname,abort_message,1)
1234      endif     
1235    endif
1236    lon_scat = 0.
1237    lat_scat = 0.
1238    do igrid = 1, knon
1239      index = knindex(igrid)
1240      lalo(igrid,2) = rlon(index)
1241      lalo(igrid,1) = rlat(index)
1242
1243    enddo
1244   
1245
1246   
1247    Call GatherField(rlon,rlon_g,1)
1248    Call GatherField(rlat,rlat_g,1)
1249
1250    IF (phy_rank==0) THEN
1251      index = 1
1252      do jj = 2, jjm
1253        do ij = 1, iim
1254          index = index + 1
1255          lon_scat(ij,jj) = rlon_g(index)
1256          lat_scat(ij,jj) = rlat_g(index)
1257        enddo
1258      enddo
1259     lon_scat(:,1) = lon_scat(:,2)
1260     lat_scat(:,1) = rlat_g(1)
1261     lon_scat(:,jjm+1) = lon_scat(:,2)
1262     lat_scat(:,jjm+1) = rlat_g(klon2)
1263   ENDIF
1264   
1265
1266!
1267! Allouer et initialiser le tableau des voisins et des fraction de continents
1268!
1269    if ( (.not.allocated(neighbours))) THEN
1270      allocate(neighbours(knon,8), stat = error)
1271      if (error /= 0) then
1272        abort_message='Pb allocation neighbours'
1273        call abort_gcm(modname,abort_message,1)
1274      endif
1275    endif
1276    neighbours = -1.
1277    if (( .not. allocated(contfrac))) then
1278      allocate(contfrac(knon), stat = error)
1279      if (error /= 0) then
1280        abort_message='Pb allocation contfrac'
1281        call abort_gcm(modname,abort_message,1)
1282      endif     
1283    endif
1284
1285    do igrid = 1, knon
1286      ireal = knindex(igrid)
1287      contfrac(igrid) = pctsrf(ireal,is_ter)
1288    enddo
1289
1290
1291   CALL Init_neighbours(iim,jjm,knon,neighbours,knindex,pctsrf(:,is_ter))
1292
1293!
1294!  Allocation et calcul resolutions
1295    IF ( (.NOT.ALLOCATED(resolution))) THEN
1296      ALLOCATE(resolution(knon,2), stat = error)
1297      if (error /= 0) then
1298        abort_message='Pb allocation resolution'
1299        call abort_gcm(modname,abort_message,1)
1300      endif
1301    ENDIF
1302    do igrid = 1, knon
1303      ij = knindex(igrid)
1304      resolution(igrid,1) = cufi(ij)
1305      resolution(igrid,2) = cvfi(ij)
1306    enddo 
1307
1308  endif                          ! (fin debut)
1309
1310!
1311! Appel a la routine sols continentaux
1312!
1313  if (lafin) lrestart_write = .true.
1314  if (check) write(lunout,*)'lafin ',lafin,lrestart_write
1315
1316  petA_orc = petBcoef * dtime
1317  petB_orc = petAcoef
1318  peqA_orc = peqBcoef * dtime
1319  peqB_orc = peqAcoef
1320
1321  cdrag = 0.
1322  cdrag(1:knon) = tq_cdrag(1:knon)
1323
1324!IM cf. JP +++
1325! zlev(1:knon) = (100.*plev(1:knon))/((ps(1:knon)/287.05*temp_air(1:knon))*9.80665)
1326  zlev(1:knon) = (100.*plev(1:knon))/((ps(1:knon)/RD*temp_air(1:knon))*RG)
1327!IM cf. JP ---
1328
1329
1330! PF et PASB
1331!   where(cdrag > 0.01)
1332!     cdrag = 0.01
1333!   endwhere
1334!  write(*,*)'Cdrag = ',minval(cdrag),maxval(cdrag)
1335
1336!
1337! Init Orchidee
1338!
1339!  if (pole_nord) then
1340!    offset=0
1341!    ktindex(:)=ktindex(:)+iim-1
1342!  else
1343!    offset = klon_begin-1+iim-1
1344!    ktindex(:)=ktindex(:)+MOD(offset,iim)
1345!    offset=offset-MOD(offset,iim)
1346!  endif
1347 
1348  PRINT *,'ORCHIDEE ------> KNON : ',knon
1349 
1350   
1351  if (debut) then
1352    CALL Get_orchidee_communicator(knon,orch_comm)
1353    IF (knon /=0) THEN
1354      CALL Init_orchidee_index(iim,knon,orch_comm,knindex,offset,ktindex)
1355   
1356      call intersurf_main (itime+itau_phy-1, iim, jjm+1,offset, knon, ktindex, &
1357       & orch_comm,dtime, lrestart_read, lrestart_write, lalo, &
1358       & contfrac, neighbours, resolution, date0, &
1359       & zlev,  u1_lay, v1_lay, spechum, temp_air, epot_air, ccanopy, &
1360       & cdrag, petA_orc, peqA_orc, petB_orc, peqB_orc, &
1361       & precip_rain, precip_snow, lwdown, swnet, swdown, ps, &
1362       & evap, fluxsens, fluxlat, coastalflow, riverflow, &
1363       & tsol_rad, tsurf_new, qsurf, albedo_out, emis_new, z0_new, &
1364       & lon_scat, lat_scat)
1365
1366     ENDIF
1367!IM cf. JP +++
1368    albedo_keep(1:knon) = (albedo_out(1:knon,1)+albedo_out(1:knon,2))/2.
1369!IM cf. JP ---
1370
1371  endif
1372
1373!IM cf. JP +++
1374!  swdown_vrai(1:knon) = swnet(1:knon)/(1. - albedo_keep(1:knon))
1375  swdown_vrai(1:knon) = swdown(1:knon)
1376
1377!IM cf. JP ---
1378    IF (knon /=0) THEN
1379   
1380      call intersurf_main (itime+itau_phy, iim, jjm+1,offset, knon, ktindex, &
1381       & orch_comm,dtime, lrestart_read, lrestart_write, lalo, &
1382       & contfrac, neighbours, resolution, date0, &
1383       & zlev,  u1_lay, v1_lay, spechum, temp_air, epot_air, ccanopy, &
1384       & cdrag, petA_orc, peqA_orc, petB_orc, peqB_orc, &
1385       & precip_rain, precip_snow, lwdown, swnet, swdown_vrai, ps, &
1386       & evap, fluxsens, fluxlat, coastalflow, riverflow, &
1387       & tsol_rad, tsurf_new, qsurf, albedo_out, emis_new, z0_new, &
1388       & lon_scat, lat_scat)
1389
1390    ENDIF
1391!IM cf. JP +++
1392    albedo_keep(1:knon) = (albedo_out(1:knon,1)+albedo_out(1:knon,2))/2.
1393!IM cf. JP ---
1394
1395    bidule=0.
1396    bidule(1:knon)=riverflow(1:knon)
1397    call gath2cpl(bidule, tmp_rriv, klon, knon,iim,jjphy_nb,knindex)
1398    bidule=0.
1399    bidule(1:knon)=coastalflow(1:knon)
1400    call gath2cpl(bidule, tmp_rcoa, klon, knon,iim,jjphy_nb,knindex)
1401    alb_new(1:knon) = albedo_out(1:knon,1)
1402    alblw(1:knon) = albedo_out(1:knon,2)
1403
1404
1405! Convention orchidee: positif vers le haut
1406  fluxsens(1:knon) = -1. * fluxsens(1:knon)
1407  fluxlat(1:knon)  = -1. * fluxlat(1:knon)
1408
1409!  evap     = -1. * evap
1410
1411  if (debut) lrestart_read = .false.
1412
1413  END SUBROUTINE interfsol
1414 
1415  SUBROUTINE Init_orchidee_index(iim,knon,orch_comm,knindex,offset,ktindex)
1416  USE dimphy
1417  IMPLICIT NONE
1418    INTEGER,INTENT(IN)  :: iim
1419    INTEGER,INTENT(IN)  :: knon
1420    INTEGER,INTENT(IN)  :: orch_comm
1421    INTEGER,INTENT(IN)  :: knindex(knon)
1422    INTEGER,INTENT(OUT) :: offset
1423    INTEGER,INTENT(OUT) :: ktindex(knon)
1424
1425#ifdef CPP_PARA
1426    INCLUDE 'mpif.h'
1427    INTEGER :: status(MPI_STATUS_SIZE)
1428#endif
1429    INTEGER :: MyLastPoint
1430    INTEGER :: LastPoint
1431    INTEGER :: mpi_rank
1432    INTEGER :: mpi_size
1433    INTEGER :: ierr   
1434   
1435    MyLastPoint=klon_begin-1+knindex(knon)+iim-1
1436
1437    IF (.NOT. monocpu) THEN
1438#ifdef CPP_PARA   
1439      call MPI_COMM_SIZE(orch_comm,mpi_size,ierr)
1440      call MPI_COMM_RANK(orch_comm,mpi_rank,ierr)
1441#endif
1442    ELSE
1443      mpi_rank=0
1444      mpi_size=1
1445    ENDIF
1446   
1447    IF (.NOT. monocpu) THEN
1448      IF (mpi_rank /= 0) then
1449#ifdef CPP_PARA
1450        CALL MPI_RECV(LastPoint,1,MPI_INTEGER,mpi_rank-1,1234,orch_comm,status,ierr)
1451#endif
1452      ENDIF
1453       
1454      IF (mpi_rank /= mpi_size-1) THEN
1455#ifdef CPP_PARA
1456        CALL MPI_SEND(MyLastPoint,1,MPI_INTEGER,mpi_rank+1,1234,orch_comm,ierr) 
1457#endif
1458      ENDIF
1459    ENDIF
1460   
1461    IF (mpi_rank==0) THEN
1462      offset=0
1463    ELSE
1464     offset=LastPoint-MOD(LastPoint,iim)
1465    ENDIF
1466     
1467    ktindex(:)=knindex(:)+(klon_begin+iim-1)-offset-1   
1468   
1469
1470   END SUBROUTINE  Init_orchidee_index
1471
1472 
1473  SUBROUTINE Get_orchidee_communicator(knon,orch_comm)
1474  USE dimphy, only : phy_rank
1475#ifdef CPP_PARA
1476  USE parallel, only : COMM_LMDZ
1477#endif
1478  IMPLICIT NONE
1479#ifdef CPP_PARA
1480    include 'mpif.h'
1481#endif   
1482    INTEGER,INTENT(IN)  :: knon
1483    INTEGER,INTENT(OUT) :: orch_comm
1484   
1485    INTEGER :: color
1486    INTEGER :: ierr
1487   
1488    IF (knon==0) THEN
1489      color = 0
1490    ELSE
1491      color = 1
1492    ENDIF
1493
1494#ifdef CPP_PARA   
1495    CALL MPI_COMM_SPLIT(COMM_LMDZ,color,phy_rank,orch_comm,ierr)
1496#endif
1497   
1498  END SUBROUTINE Get_orchidee_communicator
1499   
1500   
1501  SUBROUTINE Init_neighbours(iim,jjm,knon,neighbours,ktindex,pctsrf)
1502#ifdef CPP_PARA
1503  USE parallel,only : COMM_LMDZ
1504#endif 
1505  USE dimphy
1506  IMPLICIT NONE
1507#ifdef CPP_PARA
1508  include 'mpif.h'
1509#endif
1510  INTEGER :: iim,jjm
1511  INTEGER :: knon
1512  INTEGER :: neighbours(knon,8)
1513  INTEGER :: ktindex(knon)
1514  REAL :: pctsrf(klon)
1515 
1516  INTEGER :: knon_nb(0:phy_size-1)
1517  INTEGER,DIMENSION(0:phy_size-1) :: displs,sendcount
1518  INTEGER,ALLOCATABLE :: ktindex_g(:)
1519  REAL*8  :: pctsrf_g(klon2)
1520  INTEGER,ALLOCATABLE ::neighbours_g(:,:)
1521  INTEGER :: knon_g
1522  REAL*8 :: correspond(iim,jjm+1)
1523  INTEGER :: i,igrid,jj,ij,iglob,ierr,ireal,index
1524  integer, dimension(8,3) :: off_ini
1525  integer, dimension(8)   :: offset 
1526  INTEGER :: ktindex_p(knon)
1527
1528  IF (monocpu) THEN
1529    knon_nb(:)=knon
1530  ELSE 
1531
1532#ifdef CPP_PARA 
1533    CALL MPI_GATHER(knon,1,MPI_INTEGER,knon_nb,1,MPI_INTEGER,0,COMM_LMDZ,ierr)
1534#endif
1535 
1536  ENDIF
1537   
1538  IF (phy_rank==0) THEN
1539    knon_g=sum(knon_nb(:))
1540    ALLOCATE(ktindex_g(knon_g))
1541    ALLOCATE(neighbours_g(knon_g,8))
1542    neighbours_g(:,:)=-1
1543    displs(0)=0
1544    DO i=1,phy_size-1
1545      displs(i)=displs(i-1)+knon_nb(i-1)
1546    ENDDO 
1547  ENDIF
1548 
1549  ktindex_p(:)=ktindex(:)+klon_begin-1+iim-1
1550
1551  IF (monocpu) THEN
1552    ktindex_g(:)=ktindex_p(:)
1553  ELSE
1554
1555#ifdef CPP_PARA 
1556    CALL MPI_GATHERV(ktindex_p,knon,MPI_INTEGER,ktindex_g,knon_nb,displs,MPI_INTEGER,0,COMM_LMDZ,ierr)
1557#endif
1558
1559  ENDIF
1560     
1561  CALL GatherField(pctsrf,pctsrf_g,1)
1562 
1563  IF (phy_rank==0) THEN
1564!  Initialisation des offset   
1565!
1566! offset bord ouest
1567   off_ini(1,1) = - iim  ; off_ini(2,1) = - iim + 1; off_ini(3,1) = 1
1568   off_ini(4,1) = iim + 1; off_ini(5,1) = iim      ; off_ini(6,1) = 2 * iim - 1
1569   off_ini(7,1) = iim -1 ; off_ini(8,1) = - 1
1570! offset point normal
1571   off_ini(1,2) = - iim  ; off_ini(2,2) = - iim + 1; off_ini(3,2) = 1
1572   off_ini(4,2) = iim + 1; off_ini(5,2) = iim      ; off_ini(6,2) = iim - 1
1573   off_ini(7,2) = -1     ; off_ini(8,2) = - iim - 1
1574! offset bord   est
1575   off_ini(1,3) = - iim; off_ini(2,3) = - 2 * iim + 1; off_ini(3,3) = - iim + 1
1576   off_ini(4,3) =  1   ; off_ini(5,3) = iim          ; off_ini(6,3) = iim - 1
1577   off_ini(7,3) = -1   ; off_ini(8,3) = - iim - 1
1578!
1579!
1580! Attention aux poles
1581!
1582    do igrid = 1, knon_g
1583      index = ktindex_g(igrid)
1584          jj = int((index - 1)/iim) + 1
1585          ij = index - (jj - 1) * iim
1586      correspond(ij,jj) = igrid
1587    enddo
1588
1589    do igrid = 1, knon_g
1590      iglob = ktindex_g(igrid)
1591      if (mod(iglob, iim) == 1) then
1592        offset = off_ini(:,1)
1593      else if(mod(iglob, iim) == 0) then
1594        offset = off_ini(:,3)
1595      else
1596        offset = off_ini(:,2)
1597      endif
1598      do i = 1, 8
1599        index = iglob + offset(i)
1600        ireal = (min(max(1, index - iim + 1), klon2))
1601        if (pctsrf_g(ireal) > EPSFRA) then
1602          jj = int((index - 1)/iim) + 1
1603          ij = index - (jj - 1) * iim
1604            neighbours_g(igrid, i) = correspond(ij, jj)
1605        endif
1606      enddo
1607    enddo
1608
1609!    DO i=0,phy_size-1
1610!      displs(i)=displs(i)*8
1611!      sendcount(i)=knon_nb(i)*8
1612!    ENDDO
1613 
1614  ENDIF
1615 
1616  DO i=1,8
1617    IF (monocpu) THEN
1618      neighbours(:,i)=neighbours_g(:,i)
1619    ELSE
1620#ifdef CPP_PARA
1621    CALL MPI_SCATTERV(neighbours_g(:,i),knon_nb,displs,MPI_INTEGER,neighbours(:,i),knon,MPI_INTEGER,0,COMM_LMDZ,ierr)
1622#endif
1623    ENDIF
1624  ENDDO
1625 
1626  END SUBROUTINE Init_neighbours
1627#endif
1628!
1629!#########################################################################
1630!
1631  SUBROUTINE interfoce_cpl(itime, dtime, cumul, &
1632      & klon, iim, jjm, nisurf, pctsrf, knon, knindex, rlon, rlat, &
1633      & ocean, npas, nexca, debut, lafin, &
1634      & swdown, lwdown, precip_rain, precip_snow, evap, tsurf, &
1635      & fluxlat, fluxsens, fder, albsol, taux, tauy, &
1636! -- LOOP
1637      & windsp, &
1638! -- LOOP
1639      & zmasq, &
1640      & tsurf_new, alb_new, &
1641      & pctsrf_new)
1642
1643   USE ioipsl
1644   USE dimphy, only : jjphy_nb, iiphy_begin,iiphy_end,phy_rank,phy_size, monocpu
1645   USE iophy
1646#ifdef CPP_PARA
1647   USE parallel, only: pole_nord,pole_sud,COMM_LMDZ
1648#endif
1649#ifdef CPP_PSMILE
1650   USE oasis
1651#endif
1652   USE write_field_phy
1653   implicit none
1654#include "indicesol.inc"
1655#include "YOMCST.inc"
1656! Cette routine sert d'interface entre le modele atmospherique et un
1657! coupleur avec un modele d'ocean 'complet' derriere
1658!
1659! Le modele de glace qu'il est prevu d'utiliser etant couple directement a
1660! l'ocean presentement, on va passer deux fois dans cette routine par pas de
1661! temps physique, une fois avec les points oceans et l'autre avec les points
1662! glace. A chaque pas de temps de couplage, la lecture des champs provenant
1663! du coupleur se fera "dans" l'ocean et l'ecriture des champs a envoyer
1664! au coupleur "dans" la glace. Il faut donc des tableaux de travail "tampons"
1665! dimensionnes sur toute la grille qui remplissent les champs sur les
1666! domaines ocean/glace quand il le faut. Il est aussi necessaire que l'index
1667! ocean soit traiter avant l'index glace (sinon tout intervertir)
1668!
1669!
1670! L. Fairhead 02/2000
1671!
1672! input:
1673!   itime        numero du pas de temps
1674!   iim, jjm     nbres de pts de grille
1675!   dtime        pas de temps de la physique
1676!   klon         nombre total de points de grille
1677!   nisurf       index de la surface a traiter (1 = sol continental)
1678!   pctsrf       tableau des fractions de surface de chaque maille
1679!   knon         nombre de points de la surface a traiter
1680!   knindex      index des points de la surface a traiter
1681!   rlon         longitudes
1682!   rlat         latitudes
1683!   debut        logical: 1er appel a la physique
1684!   lafin        logical: dernier appel a la physique
1685!   ocean        type d'ocean
1686!   nexca        frequence de couplage
1687!   swdown       flux solaire entrant a la surface
1688!   lwdown       flux IR net a la surface
1689!   precip_rain  precipitation liquide
1690!   precip_snow  precipitation solide
1691!   evap         evaporation
1692!   tsurf        temperature de surface
1693!   fder         derivee dF/dT
1694!   albsol       albedo du sol (coherent avec swdown)
1695!   taux         tension de vent en x
1696!   tauy         tension de vent en y
1697! -- LOOP
1698!    windsp       module du vent a 10m
1699! -- LOOP
1700!   nexca        frequence de couplage
1701!   zmasq        masque terre/ocean
1702!
1703!
1704! output:
1705!   tsurf_new    temperature au sol
1706!   alb_new      albedo
1707!   pctsrf_new   nouvelle repartition des surfaces
1708!   alb_ice      albedo de la glace
1709!
1710
1711
1712! Parametres d'entree
1713  integer, intent(IN) :: itime
1714  integer, intent(IN) :: iim, jjm
1715  real, intent(IN) :: dtime
1716  integer, intent(IN) :: klon
1717  integer, intent(IN) :: nisurf
1718  integer, intent(IN) :: knon
1719  real, dimension(klon,nbsrf), intent(IN) :: pctsrf
1720  integer, dimension(klon), intent(in) :: knindex
1721  logical, intent(IN) :: debut, lafin
1722  real, dimension(klon), intent(IN) :: rlon, rlat
1723  character (len = 6)  :: ocean
1724  real, dimension(klon), intent(IN) :: lwdown, swdown
1725  real, dimension(klon), intent(IN) :: precip_rain, precip_snow
1726  real, dimension(klon), intent(IN) :: tsurf, fder, albsol, taux, tauy
1727! -- LOOP
1728   real, dimension(klon), intent(IN) :: windsp
1729! -- LOOP
1730  INTEGER              :: nexca, npas, kstep
1731  real, dimension(klon), intent(IN) :: zmasq
1732  real, dimension(klon), intent(IN) :: fluxlat, fluxsens
1733  logical, intent(IN)               :: cumul
1734  real, dimension(klon), intent(INOUT) :: evap
1735
1736! Parametres de sortie
1737  real, dimension(klon), intent(OUT):: tsurf_new, alb_new
1738  real, dimension(klon,nbsrf), intent(OUT) :: pctsrf_new
1739
1740! Variables locales
1741  integer                    :: j, error, sum_error, ig, cpl_index,i
1742! -- LOOP
1743  INTEGER :: nsrf
1744! -- LOOP
1745  character (len = 20) :: modname = 'interfoce_cpl'
1746  character (len = 80) :: abort_message
1747  logical,save              :: check = .FALSE.
1748! variables pour moyenner les variables de couplage
1749  real, allocatable, dimension(:,:),save :: cpl_sols, cpl_nsol, cpl_rain
1750  real, allocatable, dimension(:,:),save :: cpl_snow, cpl_evap, cpl_tsol
1751  real, allocatable, dimension(:,:),save :: cpl_fder, cpl_albe, cpl_taux
1752! -- LOOP
1753  real, allocatable, dimension(:,:),save :: cpl_windsp
1754! -- LOOP
1755  real, allocatable, dimension(:,:),save :: cpl_tauy
1756  REAL, ALLOCATABLE, DIMENSION(:,:),SAVE :: cpl_rriv, cpl_rcoa, cpl_rlic
1757!!$
1758! variables tampons avant le passage au coupleur
1759  real, allocatable, dimension(:,:,:),save :: tmp_sols, tmp_nsol, tmp_rain
1760  real, allocatable, dimension(:,:,:),save :: tmp_snow, tmp_evap, tmp_tsol
1761  real, allocatable, dimension(:,:,:),save :: tmp_fder, tmp_albe, tmp_taux
1762! -- LOOP
1763  real, allocatable, dimension(:,:,:),save :: tmp_windsp
1764! -- LOOP
1765!!$  real, allocatable, dimension(:,:,:),save :: tmp_tauy, tmp_rriv, tmp_rcoa
1766  REAL, ALLOCATABLE, DIMENSION(:,:,:),SAVE :: tmp_tauy
1767! variables a passer au coupleur
1768!ym  real, dimension(iim, jjm+1) :: wri_sol_ice, wri_sol_sea, wri_nsol_ice
1769!ym  real, dimension(iim, jjm+1) :: wri_nsol_sea, wri_fder_ice, wri_evap_ice
1770!ym  REAL, DIMENSION(iim, jjm+1) :: wri_evap_sea, wri_rcoa, wri_rriv
1771!ym  REAL, DIMENSION(iim, jjm+1) :: wri_rain, wri_snow, wri_taux, wri_tauy
1772!ym  REAL, DIMENSION(iim, jjm+1) :: wri_calv
1773!ym  REAL, DIMENSION(iim, jjm+1) :: wri_tauxx, wri_tauyy, wri_tauzz
1774!ym  REAL, DIMENSION(iim, jjm+1) :: tmp_lon, tmp_lat
1775
1776  real, dimension(iim, jjphy_nb) :: wri_sol_ice, wri_sol_sea, wri_nsol_ice
1777  real, dimension(iim, jjphy_nb) :: wri_nsol_sea, wri_fder_ice, wri_evap_ice
1778  REAL, DIMENSION(iim, jjphy_nb) :: wri_evap_sea, wri_rcoa, wri_rriv
1779  REAL, DIMENSION(iim, jjphy_nb) :: wri_rain, wri_snow, wri_taux, wri_tauy
1780  REAL, DIMENSION(iim, jjphy_nb) :: wri_calv
1781  REAL, DIMENSION(iim, jjphy_nb) :: wri_tauxx, wri_tauyy, wri_tauzz
1782  REAL, DIMENSION(iim, jjphy_nb) :: tmp_lon, tmp_lat
1783  REAL, DIMENSION(iim, jjphy_nb) :: wri_windsp
1784
1785! variables relues par le coupleur
1786! read_sic = fraction de glace
1787! read_sit = temperature de glace
1788  real, allocatable, dimension(:,:),save :: read_sst, read_sic, read_sit
1789  real, allocatable, dimension(:,:),save :: read_alb_sic
1790! variable tampon
1791  real, dimension(klon)       :: tamp_sic
1792! sauvegarde des fractions de surface d'un pas de temps a l'autre apres
1793! l'avoir lu
1794  real, allocatable,dimension(:,:),save :: pctsrf_sav
1795  real, dimension(iim, jjphy_nb, 3) :: tamp_srf
1796  integer, allocatable, dimension(:), save :: tamp_ind
1797  real, allocatable, dimension(:,:),save :: tamp_zmasq
1798  real, dimension(iim, jjphy_nb) :: deno
1799  integer                     :: idtime
1800  integer, allocatable,dimension(:),save :: unity
1801!
1802  logical, save    :: first_appel = .true.
1803  logical,save          :: print
1804!maf
1805! variables pour avoir une sortie IOIPSL des champs echanges
1806  CHARACTER*80,SAVE :: clintocplnam, clfromcplnam
1807  INTEGER, SAVE :: jf,nhoridct,nidct
1808  INTEGER, SAVE :: nhoridcs,nidcs
1809  INTEGER :: ndexct(iim*(jjm+1)),ndexcs(iim*(jjm+1))
1810  REAL :: zx_lon(iim,jjm+1), zx_lat(iim,jjm+1), zjulian
1811  INTEGER,save :: idayref
1812!med  integer :: itau_w
1813  integer,save :: itau_w
1814! -- LOOP
1815  integer :: nb_interf_cpl
1816! -- LOOP
1817
1818  real :: Up,Down
1819  integer :: ierr
1820  integer :: il_time_secs
1821  real :: tmp_field(klon)
1822 
1823#include "param_cou.h"
1824#include "inc_cpl.h"
1825#include "temps.inc"
1826#include "iniprint.h"
1827
1828#ifdef CPP_PARA
1829  include 'mpif.h'
1830  integer :: status(MPI_STATUS_SIZE)
1831#endif
1832
1833!
1834! Initialisation
1835!
1836  if (check) write(*,*)'Entree ',modname,'nisurf = ',nisurf
1837 
1838  if (first_appel) then
1839    error = 0
1840    allocate(unity(klon), stat = error)
1841    if ( error  /=0) then
1842      abort_message='Pb allocation variable unity'
1843      call abort_gcm(modname,abort_message,1)
1844    endif
1845    allocate(pctsrf_sav(klon,nbsrf), stat = error)
1846    if ( error  /=0) then
1847      abort_message='Pb allocation variable pctsrf_sav'
1848      call abort_gcm(modname,abort_message,1)
1849    endif
1850    pctsrf_sav = 0.
1851
1852    do ig = 1, klon
1853      unity(ig) = ig
1854    enddo
1855    sum_error = 0
1856    allocate(cpl_sols(klon,2), stat = error); sum_error = sum_error + error
1857    allocate(cpl_nsol(klon,2), stat = error); sum_error = sum_error + error
1858    allocate(cpl_rain(klon,2), stat = error); sum_error = sum_error + error
1859    allocate(cpl_snow(klon,2), stat = error); sum_error = sum_error + error
1860    allocate(cpl_evap(klon,2), stat = error); sum_error = sum_error + error
1861    allocate(cpl_tsol(klon,2), stat = error); sum_error = sum_error + error
1862    allocate(cpl_fder(klon,2), stat = error); sum_error = sum_error + error
1863    allocate(cpl_albe(klon,2), stat = error); sum_error = sum_error + error
1864    allocate(cpl_taux(klon,2), stat = error); sum_error = sum_error + error
1865! -- LOOP
1866     allocate(cpl_windsp(klon,2), stat = error); sum_error = sum_error + error
1867! -- LOOP
1868    allocate(cpl_tauy(klon,2), stat = error); sum_error = sum_error + error
1869!ym    ALLOCATE(cpl_rriv(iim,jjm+1), stat=error); sum_error = sum_error + error
1870!ym    ALLOCATE(cpl_rcoa(iim,jjm+1), stat=error); sum_error = sum_error + error
1871!ym    ALLOCATE(cpl_rlic(iim,jjm+1), stat=error); sum_error = sum_error + error
1872    ALLOCATE(cpl_rriv(iim,jjphy_nb), stat=error); sum_error = sum_error + error
1873    ALLOCATE(cpl_rcoa(iim,jjphy_nb), stat=error); sum_error = sum_error + error
1874    ALLOCATE(cpl_rlic(iim,jjphy_nb), stat=error); sum_error = sum_error + error
1875
1876
1877!!
1878!ym    allocate(read_sst(iim, jjm+1), stat = error); sum_error = sum_error + error
1879!ym    allocate(read_sic(iim, jjm+1), stat = error); sum_error = sum_error + error
1880!ym    allocate(read_sit(iim, jjm+1), stat = error); sum_error = sum_error + error
1881!ym    allocate(read_alb_sic(iim, jjm+1), stat = error); sum_error = sum_error + error
1882    allocate(read_sst(iim, jjphy_nb), stat = error); sum_error = sum_error + error
1883    allocate(read_sic(iim, jjphy_nb), stat = error); sum_error = sum_error + error
1884    allocate(read_sit(iim, jjphy_nb), stat = error); sum_error = sum_error + error
1885    allocate(read_alb_sic(iim, jjphy_nb), stat = error); sum_error = sum_error + error
1886    read_sst=0.
1887    read_sic=0.
1888    read_sit=0.
1889    read_alb_sic=0.
1890    if (sum_error /= 0) then
1891      abort_message='Pb allocation variables couplees'
1892      call abort_gcm(modname,abort_message,1)
1893    endif
1894    cpl_sols = 0.; cpl_nsol = 0.; cpl_rain = 0.; cpl_snow = 0.
1895    cpl_evap = 0.; cpl_tsol = 0.; cpl_fder = 0.; cpl_albe = 0.
1896    cpl_taux = 0.; cpl_tauy = 0.; cpl_rriv = 0.; cpl_rcoa = 0.; cpl_rlic = 0.
1897! -- LOOP
1898     cpl_windsp = 0.
1899! -- LOOP
1900
1901    sum_error = 0
1902    allocate(tamp_ind(klon), stat = error); sum_error = sum_error + error
1903!ym    allocate(tamp_zmasq(iim, jjm+1), stat = error); sum_error = sum_error + error   
1904    allocate(tamp_zmasq(iim, jjphy_nb), stat = error); sum_error = sum_error + error   
1905    tamp_zmasq=1.
1906   
1907    do ig = 1, klon
1908      tamp_ind(ig) = ig
1909    enddo
1910    call gath2cpl(zmasq, tamp_zmasq, klon, klon, iim, jjphy_nb, tamp_ind)
1911!
1912! initialisation couplage
1913!
1914    idtime = int(dtime)
1915#ifdef CPP_COUPLE
1916#ifdef CPP_PSMILE
1917   CALL inicma(iim, (jjm+1))
1918#else
1919   if (.not. monocpu) then
1920      abort_message='coupleur parallele uniquement avec PSMILE'
1921      call abort_gcm(modname,abort_message,1)
1922   endif
1923   call inicma(npas , nexca, idtime,(jjm+1)*iim)
1924#endif
1925#endif
1926!
1927! initialisation sorties netcdf
1928!
1929 !ym  IO de check deconnect�pour le moment en //
1930    IF (monocpu) THEN
1931    idayref = day_ini
1932    CALL ymds2ju(annee_ref, 1, idayref, 0.0, zjulian)
1933    CALL gr_fi_ecrit(1,klon,iim,jjm+1,rlon,zx_lon)
1934    DO i = 1, iim
1935      zx_lon(i,1) = rlon(i+1)
1936      zx_lon(i,jjm+1) = rlon(i+1)
1937    ENDDO
1938    CALL gr_fi_ecrit(1,klon,iim,jjm+1,rlat,zx_lat)
1939    clintocplnam="cpl_atm_tauflx"
1940    CALL histbeg(clintocplnam, iim,zx_lon(:,1),jjm+1,zx_lat(1,:),1,iim,1,jjm+1, &
1941       & itau_phy,zjulian,dtime,nhoridct,nidct)
1942! no vertical axis
1943    CALL histdef(nidct, 'tauxe','tauxe', &
1944         & "-",iim, jjm+1, nhoridct, 1, 1, 1, -99, 32, "inst", dtime,dtime)
1945    CALL histdef(nidct, 'tauyn','tauyn', &
1946         & "-",iim, jjm+1, nhoridct, 1, 1, 1, -99, 32, "inst", dtime,dtime)
1947    CALL histdef(nidct, 'tmp_lon','tmp_lon', &
1948         & "-",iim, jjm+1, nhoridct, 1, 1, 1, -99, 32, "inst", dtime,dtime)
1949    CALL histdef(nidct, 'tmp_lat','tmp_lat', &
1950         & "-",iim, jjm+1, nhoridct, 1, 1, 1, -99, 32, "inst", dtime,dtime)
1951    DO jf=1,jpflda2o1 + jpflda2o2
1952      CALL histdef(nidct, cl_writ(jf),cl_writ(jf), &
1953         & "-",iim, jjm+1, nhoridct, 1, 1, 1, -99, 32, "inst", dtime,dtime)
1954    END DO
1955    CALL histend(nidct)
1956    CALL histsync(nidct)
1957
1958    clfromcplnam="cpl_atm_sst"
1959    CALL histbeg(clfromcplnam, iim,zx_lon(:,1),jjm+1,zx_lat(1,:),1,iim,1,jjm+1, &
1960       & 0,zjulian,dtime,nhoridcs,nidcs)
1961! no vertical axis
1962    DO jf=1,jpfldo2a
1963      CALL histdef(nidcs, cl_read(jf),cl_read(jf), &
1964         & "-",iim, jjm+1, nhoridcs, 1, 1, 1, -99, 32, "inst", dtime,dtime)
1965    END DO
1966    CALL histend(nidcs)
1967    CALL histsync(nidcs)
1968
1969    ENDIF    ! monocpu
1970   
1971! pour simuler la fonte des glaciers antarctiques
1972!
1973!ym => pour le moment, c'est en commentaire, donc je squizze
1974
1975!ym    surf_maille = (4. * rpi * ra**2) / (iim * (jjm +1))
1976!ym    ALLOCATE(coeff_iceberg(iim,jjm+1), stat=error)
1977!ym    if (error /= 0) then
1978!ym      abort_message='Pb allocation variable coeff_iceberg'
1979!ym      call abort_gcm(modname,abort_message,1)
1980!ym    endif
1981!ym    open (12,file='flux_iceberg',form='formatted',status='old')
1982!ym    read (12,*) coeff_iceberg
1983!ym    close (12)
1984!ym    num_antarctic = max(1, count(coeff_iceberg > 0))
1985   
1986    first_appel = .false.
1987  endif ! fin if (first_appel)
1988
1989! Initialisations
1990
1991! calcul des fluxs a passer
1992! -- LOOP
1993  nb_interf_cpl = nb_interf_cpl + 1 
1994  if (check) write(lunout,*)'passage dans interface_surf.F90 :  ',nb_interf_cpl
1995! -- LOOP
1996  cpl_index = 1
1997  if (nisurf == is_sic) cpl_index = 2
1998  if (cumul) then
1999! -- LOOP
2000      if (check) write(lunout,*)'passage dans cumul '
2001      if (check) write(lunout,*)'valeur de cpl_index ', cpl_index
2002! -- LOOP 
2003    if (check) write(*,*) modname, 'cumul des champs'
2004    do ig = 1, knon
2005      cpl_sols(ig,cpl_index) = cpl_sols(ig,cpl_index) &
2006       &                          + swdown(ig)      / FLOAT(nexca)
2007      cpl_nsol(ig,cpl_index) = cpl_nsol(ig,cpl_index) &
2008       &                          + (lwdown(ig) + fluxlat(ig) +fluxsens(ig))&
2009       &                                / FLOAT(nexca)
2010      cpl_rain(ig,cpl_index) = cpl_rain(ig,cpl_index) &
2011       &                          + precip_rain(ig) / FLOAT(nexca)
2012      cpl_snow(ig,cpl_index) = cpl_snow(ig,cpl_index) &
2013       &                          + precip_snow(ig) / FLOAT(nexca)
2014      cpl_evap(ig,cpl_index) = cpl_evap(ig,cpl_index) &
2015       &                          + evap(ig)        / FLOAT(nexca)
2016      cpl_tsol(ig,cpl_index) = cpl_tsol(ig,cpl_index) &
2017       &                          + tsurf(ig)       / FLOAT(nexca)
2018      cpl_fder(ig,cpl_index) = cpl_fder(ig,cpl_index) &
2019       &                          + fder(ig)        / FLOAT(nexca)
2020      cpl_albe(ig,cpl_index) = cpl_albe(ig,cpl_index) &
2021       &                          + albsol(ig)      / FLOAT(nexca)
2022      cpl_taux(ig,cpl_index) = cpl_taux(ig,cpl_index) &
2023       &                          + taux(ig)        / FLOAT(nexca)
2024      cpl_tauy(ig,cpl_index) = cpl_tauy(ig,cpl_index) &
2025       &                          + tauy(ig)        / FLOAT(nexca)
2026! -- LOOP
2027      IF (cpl_index .EQ. 1) THEN
2028      cpl_windsp(ig,cpl_index) = cpl_windsp(ig,cpl_index) &
2029       &                          + windsp(ig)      / FLOAT(nexca)
2030      ENDIF
2031! -- LOOP
2032    enddo
2033    IF (cpl_index .EQ. 1) THEN
2034        cpl_rriv(:,:) = cpl_rriv(:,:) + tmp_rriv(:,:) / FLOAT(nexca)
2035        cpl_rcoa(:,:) = cpl_rcoa(:,:) + tmp_rcoa(:,:) / FLOAT(nexca)
2036        cpl_rlic(:,:) = cpl_rlic(:,:) + tmp_rlic(:,:) / FLOAT(nexca)
2037    ENDIF
2038  endif
2039
2040  if (mod(itime, nexca) == 1) then
2041!
2042! Demande des champs au coupleur
2043!
2044! Si le domaine considere est l'ocean, on lit les champs venant du coupleur
2045!
2046    if (nisurf == is_oce .and. .not. cumul) then
2047      if (check) write(*,*)'rentree fromcpl, itime-1 = ',itime-1
2048#ifdef CPP_COUPLE
2049#ifdef CPP_PSMILE
2050      il_time_secs=(itime-1)*dtime
2051      CALL fromcpl(il_time_secs, iim, jjphy_nb,                           &
2052     &        read_sst, read_sic, read_sit, read_alb_sic)
2053      print *,read_sst
2054#else
2055     if (.not. monocpu) then
2056        abort_message='coupleur parallele uniquement avec PSMILE'
2057        call abort_gcm(modname,abort_message,1)
2058     endif
2059
2060      call fromcpl(itime-1,(jjm+1)*iim,                                  &
2061     &        read_sst, read_sic, read_sit, read_alb_sic)
2062#endif
2063#endif
2064!
2065! sorties NETCDF des champs recus
2066!
2067!ym       ndexcs(:)=0
2068!ym       itau_w = itau_phy + itime
2069!ym       CALL histwrite(nidcs,cl_read(1),itau_w,read_sst,iim*(jjm+1),ndexcs)
2070!ym       CALL histwrite(nidcs,cl_read(2),itau_w,read_sic,iim*(jjm+1),ndexcs)
2071!ym       CALL histwrite(nidcs,cl_read(3),itau_w,read_alb_sic,iim*(jjm+1),ndexcs)
2072!ym       CALL histwrite(nidcs,cl_read(4),itau_w,read_sit,iim*(jjm+1),ndexcs)
2073!ym       CALL histsync(nidcs)
2074! pas utile      IF (npas-itime.LT.nexca )CALL histclo(nidcs)
2075
2076!ym      do j = 1, jjm + 1
2077       do j = 1, jjphy_nb
2078         do ig = 1, iim
2079          if (abs(1. - read_sic(ig,j)) < 0.00001) then
2080            read_sst(ig,j) = RTT - 1.8
2081            read_sit(ig,j) = read_sit(ig,j) / read_sic(ig,j)
2082            read_alb_sic(ig,j) = read_alb_sic(ig,j) / read_sic(ig,j)
2083          else if (abs(read_sic(ig,j)) < 0.00001) then
2084            read_sst(ig,j) = read_sst(ig,j) / (1. - read_sic(ig,j))
2085            read_sit(ig,j) = read_sst(ig,j)
2086            read_alb_sic(ig,j) =  0.6
2087          else
2088            read_sst(ig,j) = read_sst(ig,j) / (1. - read_sic(ig,j))
2089            read_sit(ig,j) = read_sit(ig,j) / read_sic(ig,j)
2090            read_alb_sic(ig,j) = read_alb_sic(ig,j) / read_sic(ig,j)
2091          endif
2092        enddo
2093      enddo
2094!
2095! transformer read_sic en pctsrf_sav
2096!
2097      call cpl2gath(read_sic, tamp_sic , klon, klon,iim,jjphy_nb, unity)
2098      do ig = 1, klon
2099        IF (pctsrf(ig,is_oce) > epsfra .OR.            &
2100     &             pctsrf(ig,is_sic) > epsfra) THEN
2101          pctsrf_sav(ig,is_sic) = (pctsrf(ig,is_oce) + pctsrf(ig,is_sic)) &
2102     &                               * tamp_sic(ig)
2103          pctsrf_sav(ig,is_oce) = (pctsrf(ig,is_oce) + pctsrf(ig,is_sic)) &
2104     &                        - pctsrf_sav(ig,is_sic)
2105        endif
2106      enddo
2107!
2108! Pour rattraper des erreurs d'arrondis
2109!
2110      where (abs(pctsrf_sav(:,is_sic)) .le. 2.*epsilon(pctsrf_sav(1,is_sic)))
2111        pctsrf_sav(:,is_sic) = 0.
2112        pctsrf_sav(:,is_oce) = pctsrf(:,is_oce) + pctsrf(:,is_sic)
2113      endwhere
2114      where (abs(pctsrf_sav(:,is_oce)) .le. 2.*epsilon(pctsrf_sav(1,is_oce)))
2115        pctsrf_sav(:,is_sic) = pctsrf(:,is_oce) + pctsrf(:,is_sic)
2116        pctsrf_sav(:,is_oce) = 0.
2117      endwhere
2118      if (minval(pctsrf_sav(:,is_oce)) < 0.) then
2119        write(*,*)'Pb fraction ocean inferieure a 0'
2120        write(*,*)'au point ',minloc(pctsrf_sav(:,is_oce))
2121        write(*,*)'valeur = ',minval(pctsrf_sav(:,is_oce))
2122        abort_message = 'voir ci-dessus'
2123        call abort_gcm(modname,abort_message,1)
2124      endif
2125      if (minval(pctsrf_sav(:,is_sic)) < 0.) then
2126        write(*,*)'Pb fraction glace inferieure a 0'
2127        write(*,*)'au point ',minloc(pctsrf_sav(:,is_sic))
2128        write(*,*)'valeur = ',minval(pctsrf_sav(:,is_sic))
2129        abort_message = 'voir ci-dessus'
2130        call abort_gcm(modname,abort_message,1)
2131      endif
2132    endif
2133  endif                         ! fin mod(itime, nexca) == 1
2134
2135  if (mod(itime, nexca) == 0) then
2136!
2137! allocation memoire
2138    if (nisurf == is_oce .and. (.not. cumul) ) then
2139      sum_error = 0
2140      allocate(tmp_sols(iim,jjphy_nb,2), stat=error); sum_error = sum_error + error
2141      allocate(tmp_nsol(iim,jjphy_nb,2), stat=error); sum_error = sum_error + error
2142      allocate(tmp_rain(iim,jjphy_nb,2), stat=error); sum_error = sum_error + error
2143      allocate(tmp_snow(iim,jjphy_nb,2), stat=error); sum_error = sum_error + error
2144      allocate(tmp_evap(iim,jjphy_nb,2), stat=error); sum_error = sum_error + error
2145      allocate(tmp_tsol(iim,jjphy_nb,2), stat=error); sum_error = sum_error + error
2146      allocate(tmp_fder(iim,jjphy_nb,2), stat=error); sum_error = sum_error + error
2147      allocate(tmp_albe(iim,jjphy_nb,2), stat=error); sum_error = sum_error + error
2148      allocate(tmp_taux(iim,jjphy_nb,2), stat=error); sum_error = sum_error + error
2149      allocate(tmp_tauy(iim,jjphy_nb,2), stat=error); sum_error = sum_error + error
2150! -- LOOP
2151       allocate(tmp_windsp(iim,jjphy_nb,2), stat=error); sum_error = sum_error + error
2152! -- LOOP
2153!!$      allocate(tmp_rriv(iim,jjm+1,2), stat=error); sum_error = sum_error + error
2154!!$      allocate(tmp_rcoa(iim,jjm+1,2), stat=error); sum_error = sum_error + error
2155      if (sum_error /= 0) then
2156        abort_message='Pb allocation variables couplees pour l''ecriture'
2157        call abort_gcm(modname,abort_message,1)
2158      endif
2159    endif
2160
2161!
2162! Mise sur la bonne grille des champs a passer au coupleur
2163!
2164    cpl_index = 1
2165    if (nisurf == is_sic) cpl_index = 2
2166    call gath2cpl(cpl_sols(1,cpl_index), tmp_sols(1,1,cpl_index), klon, knon,iim,jjphy_nb,                  knindex)
2167    call gath2cpl(cpl_nsol(1,cpl_index), tmp_nsol(1,1,cpl_index), klon, knon,iim,jjphy_nb,                  knindex)
2168    call gath2cpl(cpl_rain(1,cpl_index), tmp_rain(1,1,cpl_index), klon, knon,iim,jjphy_nb,                  knindex)
2169    call gath2cpl(cpl_snow(1,cpl_index), tmp_snow(1,1,cpl_index), klon, knon,iim,jjphy_nb,                  knindex)
2170    call gath2cpl(cpl_evap(1,cpl_index), tmp_evap(1,1,cpl_index), klon, knon,iim,jjphy_nb,                  knindex)
2171    call gath2cpl(cpl_tsol(1,cpl_index), tmp_tsol(1,1,cpl_index), klon, knon,iim,jjphy_nb,                  knindex)
2172    call gath2cpl(cpl_fder(1,cpl_index), tmp_fder(1,1,cpl_index), klon, knon,iim,jjphy_nb,                  knindex)
2173    call gath2cpl(cpl_albe(1,cpl_index), tmp_albe(1,1,cpl_index), klon, knon,iim,jjphy_nb,                  knindex)
2174    call gath2cpl(cpl_taux(1,cpl_index), tmp_taux(1,1,cpl_index), klon, knon,iim,jjphy_nb,                  knindex)
2175    call gath2cpl(cpl_tauy(1,cpl_index), tmp_tauy(1,1,cpl_index), klon, knon,iim,jjphy_nb,                  knindex)
2176! -- LOOP
2177     call gath2cpl(cpl_windsp(1,cpl_index), tmp_windsp(1,1,cpl_index), klon, knon,iim,jjphy_nb,            knindex)
2178! -- LOOP
2179
2180!
2181! Si le domaine considere est la banquise, on envoie les champs au coupleur
2182!
2183    if (nisurf == is_sic .and. cumul) then
2184      wri_rain = 0.; wri_snow = 0.; wri_rcoa = 0.; wri_rriv = 0.
2185      wri_taux = 0.; wri_tauy = 0.
2186! -- LOOP
2187       wri_windsp = 0.
2188! -- LOOP     
2189      call gath2cpl(pctsrf(1,is_oce), tamp_srf(1,1,1), klon, klon, iim, jjphy_nb, tamp_ind)
2190      call gath2cpl(pctsrf(1,is_sic), tamp_srf(1,1,2), klon, klon, iim, jjphy_nb, tamp_ind)
2191
2192      wri_sol_ice = tmp_sols(:,:,2)
2193      wri_sol_sea = tmp_sols(:,:,1)
2194      wri_nsol_ice = tmp_nsol(:,:,2)
2195      wri_nsol_sea = tmp_nsol(:,:,1)
2196      wri_fder_ice = tmp_fder(:,:,2)
2197      wri_evap_ice = tmp_evap(:,:,2)
2198      wri_evap_sea = tmp_evap(:,:,1)
2199! -- LOOP
2200       wri_windsp = tmp_windsp(:,:,1)
2201! -- LOOP
2202
2203!!$PB
2204      wri_rriv = cpl_rriv(:,:)
2205      wri_rcoa = cpl_rcoa(:,:)
2206
2207!ym  !! ATTENTION ICI
2208     
2209!ym      DO j = 1, jjm + 1
2210!ym        wri_calv(:,j) = sum(cpl_rlic(:,j)) / iim
2211!ym      enddo
2212
2213!Essai OM+JLD : ca marche !!!! (17 mars 2006)
2214      tamp_srf(:,:,3)=0.
2215      CALL gath2cpl( pctsrf(1,is_lic), tamp_srf(1,1,3), klon, klon, iim, jjphy_nb, tamp_ind)
2216
2217!YM pour retrouver resultat avant tamp_srf(:,3)=1.
2218     
2219      DO j = 1, jjphy_nb
2220         wri_calv(:,j) = DOT_PRODUCT (cpl_rlic(1:iim,j), tamp_srf(1:iim,j,3)) / REAL(iim)
2221      ENDDO
2222
2223!ym      wri_calv(:,:)=0.
2224!ym      DO j = 1, jjphy_nb
2225!ym        wri_calv(:,j) = sum(cpl_rlic(:,j))/iim
2226!ym      enddo
2227
2228      IF (.NOT. monocpu) THEN
2229        if (phy_rank /= 0) then
2230#ifdef CPP_PARA
2231          call MPI_RECV(Up,1,MPI_REAL8,phy_rank-1,1234,COMM_LMDZ,status,ierr)
2232          call MPI_SEND(wri_calv(1,1),1,MPI_REAL8,phy_rank-1,1234,COMM_LMDZ,ierr)
2233#endif
2234        endif
2235       
2236        if (phy_rank /= phy_size-1) then
2237#ifdef CPP_PARA
2238          call MPI_SEND(wri_calv(1,jjphy_nb),1,MPI_REAL8,phy_rank+1,1234,COMM_LMDZ,ierr) 
2239          call MPI_RECV(down,1,MPI_REAL8,phy_rank+1,1234,COMM_LMDZ,status,ierr)
2240#endif
2241        endif
2242       
2243        if (phy_rank /=0 .and. iiphy_begin /=1) then
2244          Up=Up+wri_calv(iim,1)
2245          wri_calv(:,1)=Up
2246        endif
2247     
2248        if (phy_rank /=phy_size-1 .and. iiphy_end /= iim) then
2249          Down=Down+wri_calv(1,jjphy_nb)
2250          wri_calv(:,jjphy_nb)=Down     
2251        endif
2252      ENDIF
2253     
2254      where (tamp_zmasq /= 1.)
2255        deno =  tamp_srf(:,:,1) + tamp_srf(:,:,2)
2256        wri_rain = tmp_rain(:,:,1) * tamp_srf(:,:,1) / deno +    &
2257      &            tmp_rain(:,:,2) * tamp_srf(:,:,2) / deno
2258        wri_snow = tmp_snow(:,:,1) * tamp_srf(:,:,1) / deno +    &
2259      &            tmp_snow(:,:,2) * tamp_srf(:,:,2) / deno
2260        wri_taux = tmp_taux(:,:,1) * tamp_srf(:,:,1) / deno +    &
2261      &            tmp_taux(:,:,2) * tamp_srf(:,:,2) / deno
2262        wri_tauy = tmp_tauy(:,:,1) * tamp_srf(:,:,1) / deno +    &
2263      &            tmp_tauy(:,:,2) * tamp_srf(:,:,2) / deno
2264      endwhere
2265!
2266! pour simuler la fonte des glaciers antarctiques
2267!
2268!$$$        wri_rain = wri_rain      &
2269!$$$      &     + coeff_iceberg * cte_flux_iceberg / (num_antarctic * surf_maille)
2270!      wri_calv = coeff_iceberg * cte_flux_iceberg / (num_antarctic * surf_maille)
2271!
2272! on passe les coordonn�s de la grille
2273!
2274
2275!ym      CALL gr_fi_ecrit(1,klon,iim,jjm+1,rlon,tmp_lon)
2276!ym      CALL gr_fi_ecrit(1,klon,iim,jjm+1,rlat,tmp_lat)
2277
2278      CALL phy2dyn(rlon,tmp_lon,1)
2279      CALL phy2dyn(rlat,tmp_lat,1)
2280     
2281!ym      DO i = 1, iim
2282!ym        tmp_lon(i,1) = rlon(i+1)
2283!ym        tmp_lon(i,jjm + 1) = rlon(i+1)
2284!ym      ENDDO
2285
2286!
2287! sortie netcdf des champs pour le changement de repere
2288!
2289      IF (monocpu) THEN
2290        ndexct(:)=0
2291        CALL histwrite(nidct,'tauxe',itau_w,wri_taux,iim*(jjm+1),ndexct)
2292        CALL histwrite(nidct,'tauyn',itau_w,wri_tauy,iim*(jjm+1),ndexct)
2293        CALL histwrite(nidct,'tmp_lon',itau_w,tmp_lon,iim*(jjm+1),ndexct)
2294        CALL histwrite(nidct,'tmp_lat',itau_w,tmp_lat,iim*(jjm+1),ndexct)
2295      ENDIF 
2296!
2297! calcul 3 coordonn�s du vent
2298!
2299      CALL atm2geo (iim , jjphy_nb, wri_taux, wri_tauy, tmp_lon, tmp_lat, &
2300         & wri_tauxx, wri_tauyy, wri_tauzz )
2301!
2302! sortie netcdf des champs apres changement de repere et juste avant
2303! envoi au coupleur
2304!
2305    IF (monocpu) THEN
2306      CALL histwrite(nidct,cl_writ(8),itau_w,wri_sol_ice,iim*(jjm+1),ndexct)
2307      CALL histwrite(nidct,cl_writ(9),itau_w,wri_sol_sea,iim*(jjm+1),ndexct)
2308      CALL histwrite(nidct,cl_writ(10),itau_w,wri_nsol_ice,iim*(jjm+1),ndexct)
2309      CALL histwrite(nidct,cl_writ(11),itau_w,wri_nsol_sea,iim*(jjm+1),ndexct)
2310      CALL histwrite(nidct,cl_writ(12),itau_w,wri_fder_ice,iim*(jjm+1),ndexct)
2311      CALL histwrite(nidct,cl_writ(13),itau_w,wri_evap_ice,iim*(jjm+1),ndexct)
2312      CALL histwrite(nidct,cl_writ(14),itau_w,wri_evap_sea,iim*(jjm+1),ndexct)
2313      CALL histwrite(nidct,cl_writ(15),itau_w,wri_rain,iim*(jjm+1),ndexct)
2314      CALL histwrite(nidct,cl_writ(16),itau_w,wri_snow,iim*(jjm+1),ndexct)
2315      CALL histwrite(nidct,cl_writ(17),itau_w,wri_rcoa,iim*(jjm+1),ndexct)
2316      CALL histwrite(nidct,cl_writ(18),itau_w,wri_rriv,iim*(jjm+1),ndexct)
2317      CALL histwrite(nidct,cl_writ(19),itau_w,wri_calv,iim*(jjm+1),ndexct)
2318      CALL histwrite(nidct,cl_writ(1),itau_w,wri_tauxx,iim*(jjm+1),ndexct)
2319      CALL histwrite(nidct,cl_writ(2),itau_w,wri_tauyy,iim*(jjm+1),ndexct)
2320      CALL histwrite(nidct,cl_writ(3),itau_w,wri_tauzz,iim*(jjm+1),ndexct)
2321      CALL histwrite(nidct,cl_writ(4),itau_w,wri_tauxx,iim*(jjm+1),ndexct)
2322      CALL histwrite(nidct,cl_writ(5),itau_w,wri_tauyy,iim*(jjm+1),ndexct)
2323      CALL histwrite(nidct,cl_writ(6),itau_w,wri_tauzz,iim*(jjm+1),ndexct)
2324! -- LOOP
2325      CALL histwrite(nidct,cl_writ(7),itau_w,wri_windsp,iim*(jjm+1),ndexct)
2326! -- LOOP
2327      CALL histsync(nidct)
2328    ENDIF
2329! pas utile      IF (lafin) CALL histclo(nidct)
2330#ifdef CPP_COUPLE
2331#ifdef CPP_PSMILE
2332      il_time_secs=(itime-1)*dtime
2333     
2334      CALL intocpl(il_time_secs, iim, jjm+1, wri_sol_ice, wri_sol_sea, wri_nsol_ice,&
2335      & wri_nsol_sea, wri_fder_ice, wri_evap_ice, wri_evap_sea, wri_rain, &
2336      & wri_snow, wri_rcoa, wri_rriv, wri_calv, wri_tauxx, wri_tauyy,     &
2337      & wri_tauzz, wri_tauxx, wri_tauyy, wri_tauzz,                       &
2338! -- LOOP
2339      & wri_windsp,lafin)
2340! -- LOOP
2341#else
2342      call intocpl(itime, (jjm+1)*iim, wri_sol_ice, wri_sol_sea, wri_nsol_ice,&
2343      & wri_nsol_sea, wri_fder_ice, wri_evap_ice, wri_evap_sea, wri_rain, &
2344      & wri_snow, wri_rcoa, wri_rriv, wri_calv, wri_tauxx, wri_tauyy,     &
2345      & wri_tauzz, wri_tauxx, wri_tauyy, wri_tauzz,                       &
2346! -- LOOP
2347      & wri_windsp,lafin)
2348! -- LOOP
2349#endif
2350#endif
2351!
2352      cpl_sols = 0.; cpl_nsol = 0.; cpl_rain = 0.; cpl_snow = 0.
2353      cpl_evap = 0.; cpl_tsol = 0.; cpl_fder = 0.; cpl_albe = 0.
2354      cpl_taux = 0.; cpl_tauy = 0.; cpl_rriv = 0.; cpl_rcoa = 0.; cpl_rlic = 0.
2355! -- LOOP
2356      cpl_windsp = 0.
2357! -- LOOP
2358!
2359! deallocation memoire variables temporaires
2360!
2361      sum_error = 0
2362      deallocate(tmp_sols, stat=error); sum_error = sum_error + error
2363      deallocate(tmp_nsol, stat=error); sum_error = sum_error + error
2364      deallocate(tmp_rain, stat=error); sum_error = sum_error + error
2365      deallocate(tmp_snow, stat=error); sum_error = sum_error + error
2366      deallocate(tmp_evap, stat=error); sum_error = sum_error + error
2367      deallocate(tmp_fder, stat=error); sum_error = sum_error + error
2368      deallocate(tmp_tsol, stat=error); sum_error = sum_error + error
2369      deallocate(tmp_albe, stat=error); sum_error = sum_error + error
2370      deallocate(tmp_taux, stat=error); sum_error = sum_error + error
2371      deallocate(tmp_tauy, stat=error); sum_error = sum_error + error
2372! -- LOOP
2373      deallocate(tmp_windsp, stat=error); sum_error = sum_error + error
2374! -- LOOP
2375!!$PB
2376!!$      deallocate(tmp_rriv, stat=error); sum_error = sum_error + error
2377!!$      deallocate(tmp_rcoa, stat=error); sum_error = sum_error + error
2378      if (sum_error /= 0) then
2379        abort_message='Pb deallocation variables couplees'
2380        call abort_gcm(modname,abort_message,1)
2381      endif
2382
2383    endif
2384
2385  endif            ! fin (mod(itime, nexca) == 0)
2386!
2387! on range les variables lues/sauvegardees dans les bonnes variables de sortie
2388!
2389  if (nisurf == is_oce) then
2390    call cpl2gath(read_sst, tsurf_new, klon, knon,iim,jjphy_nb, knindex)
2391  else if (nisurf == is_sic) then
2392    call cpl2gath(read_sit, tsurf_new, klon, knon,iim,jjphy_nb, knindex)
2393    call cpl2gath(read_alb_sic, alb_new, klon, knon,iim,jjphy_nb, knindex)
2394  endif
2395  pctsrf_new(:,nisurf) = pctsrf_sav(:,nisurf)
2396 
2397  if (mod(itime, nexca) == -1) then
2398    tmp_field=0.
2399    do i = 1, knon
2400      ig = knindex(i)
2401      tmp_field(ig) = 1.
2402    enddo   
2403    call WriteField_phy('knindex',tmp_field,1)
2404   
2405    tmp_field=0.
2406    do i = 1, knon
2407      ig = knindex(i)
2408      tmp_field(ig) = tsurf_new(i)
2409    enddo   
2410    call WriteField_phy('tsurf_new',tmp_field,1)
2411   
2412    tmp_field=0.
2413    do i = 1, knon
2414      ig = knindex(i)
2415      tmp_field(ig) = alb_new(i)
2416    enddo   
2417    call WriteField_phy('alb_new',tmp_field,1)
2418   
2419!    tmp_field=0.
2420!   do i = 1, knon
2421!      ig = knindex(i)
2422!      tmp_field(ig) = pctsrf_new(i,nisurf)
2423 !   enddo   
2424    call WriteField_phy('pctsrf_new', pctsrf_new(:,nisurf),1)
2425  endif
2426!ym  do j=1,jjphy_nb
2427!ym    do i=1,iim
2428!ym      print *,phy_rank,'read_sst(',i,',',j,')=',read_sst(i,j)
2429!ym    enddo
2430!ym  enddo
2431 
2432!ym  do i=1,knon
2433!ym    print *,phy_rank,'tsurf_new(',i,')=',tsurf_new(i)
2434!ym  enddo
2435!  if (lafin) call quitcpl
2436
2437  END SUBROUTINE interfoce_cpl
2438!
2439!#########################################################################
2440!
2441   SUBROUTINE interfoce_slab(klon, debut, itap, dtime, ijour, &
2442 & radsol, fluxo, fluxg, pctsrf, &
2443 & tslab, seaice, pctsrf_slab)
2444!
2445! Cette routine calcule la temperature d'un slab ocean, la glace de mer
2446! et les pourcentages de la maille couverte par l'ocean libre et/ou
2447! la glace de mer pour un "slab" ocean de 50m
2448!
2449! Conception: Laurent Li
2450! Re-ecriture + adaptation LMDZ4: I. Musat
2451!
2452! input:
2453!   klon         nombre total de points de grille
2454!   debut        logical: 1er appel a la physique
2455!   itap         numero du pas de temps
2456!   dtime        pas de temps de la physique (en s)
2457!   ijour        jour dans l'annee en cours
2458!   radsol       rayonnement net au sol (LW + SW)
2459!   fluxo        flux turbulent (sensible + latent) sur les mailles oceaniques
2460!   fluxg        flux de conduction entre la surface de la glace de mer et l'ocean
2461!   pctsrf       tableau des pourcentages de surface de chaque maille
2462! output:
2463!   tslab        temperature de l'ocean libre
2464!   seaice       glace de mer (kg/m2)
2465!   pctsrf_slab  "pourcentages" (valeurs entre 0. et 1.) surfaces issus du slab
2466!
2467#include "indicesol.inc"
2468#include "clesphys.inc"
2469! Parametres d'entree
2470  integer, intent(IN) :: klon
2471  logical, intent(IN) :: debut
2472  INTEGER, intent(IN) :: itap
2473  REAL, intent(IN) :: dtime
2474  INTEGER, intent(IN) :: ijour
2475  REAL, dimension(klon), intent(IN) :: radsol
2476  REAL, dimension(klon), intent(IN) :: fluxo
2477  REAL, dimension(klon), intent(IN) :: fluxg
2478  real, dimension(klon, nbsrf), intent(IN) :: pctsrf
2479! Parametres de sortie
2480  real, dimension(klon), intent(INOUT) :: tslab
2481  real, dimension(klon), intent(INOUT)        :: seaice ! glace de mer (kg/m2)
2482  real, dimension(klon, nbsrf), intent(OUT) :: pctsrf_slab
2483!
2484! Variables locales :
2485  REAL :: amn, amx
2486  INTEGER, save :: lmt_pas, julien, idayvrai
2487  REAL, parameter :: unjour=86400.
2488  real, allocatable, dimension(:), save :: tmp_tslab, tmp_seaice
2489  REAL, allocatable, dimension(:), save :: slab_bils
2490  REAL, allocatable, dimension(:), save :: lmt_bils
2491  logical,save              :: check = .false.
2492!
2493  REAL, parameter :: cyang=50.0 * 4.228e+06 ! capacite calorifique volumetrique de l'eau J/(m2 K)
2494  REAL, parameter :: cbing=0.334e+05        ! J/kg
2495  real, dimension(klon)                 :: siceh !hauteur de la glace de mer (m)
2496  INTEGER :: i
2497  integer :: sum_error, error
2498  REAL :: zz, za, zb
2499!
2500  character (len = 80) :: abort_message
2501  character (len = 20) :: modname = 'interfoce_slab'
2502!
2503  julien = MOD(ijour,360)
2504  sum_error = 0
2505  IF (debut) THEN
2506   allocate(slab_bils(klon), stat = error); sum_error = sum_error + error
2507   allocate(lmt_bils(klon), stat = error); sum_error = sum_error + error
2508   allocate(tmp_tslab(klon), stat = error); sum_error = sum_error + error
2509   allocate(tmp_seaice(klon), stat = error); sum_error = sum_error + error
2510   if (sum_error /= 0) then
2511    abort_message='Pb allocation var. slab_bils,lmt_bils,tmp_tslab,tmp_seaice'
2512    call abort_gcm(modname,abort_message,1)
2513   endif
2514   tmp_tslab=tslab
2515   tmp_seaice=seaice
2516   lmt_pas = nint(86400./dtime * 1.0) ! pour une lecture une fois par jour
2517!
2518   IF (check) THEN
2519    PRINT*,'interfoce_slab klon, debut, itap, dtime, ijour, &
2520 &          lmt_pas ', klon, debut, itap, dtime, ijour, &
2521 &          lmt_pas
2522   ENDIF !check
2523!
2524   PRINT*, '************************'
2525   PRINT*, 'SLAB OCEAN est actif, prenez precautions !'
2526   PRINT*, '************************'
2527!
2528! a mettre un slab_bils aussi en force !!!
2529!
2530    DO i = 1, klon
2531     slab_bils(i) = 0.0
2532    ENDDO
2533!
2534   ENDIF !debut
2535!
2536   IF (check ) THEN
2537    amn=MIN(tmp_tslab(1),1000.)
2538    amx=MAX(tmp_tslab(1),-1000.)
2539    DO i=2, klon
2540     amn=MIN(tmp_tslab(i),amn)
2541     amx=MAX(tmp_tslab(i),amx)
2542    ENDDO
2543!
2544    PRINT*,' debut min max tslab',amn,amx
2545!
2546!!
2547    PRINT*,' itap,lmt_pas unjour',itap,lmt_pas,unjour
2548   ENDIF
2549!!
2550!
2551   pctsrf_slab(1:klon,1:nbsrf) = pctsrf(1:klon,1:nbsrf)
2552!
2553! lecture du bilan au sol lmt_bils issu d'une simulation forcee en debut de journee
2554!
2555   IF (MOD(itap,lmt_pas) .EQ. 1) THEN !1er pas de temps de la journee
2556    idayvrai = ijour
2557    CALL condsurf(julien,idayvrai, lmt_bils)
2558   ENDIF !(MOD(itap-1,lmt_pas) .EQ. 0) THEN
2559
2560   DO i = 1, klon
2561     IF((pctsrf_slab(i,is_oce).GT.epsfra).OR. &
2562     &  (pctsrf_slab(i,is_sic).GT.epsfra)) THEN
2563!
2564! fabriquer de la glace si congelation atteinte:
2565!
2566      IF (tmp_tslab(i).LT.(RTT-1.8)) THEN
2567       zz =  (RTT-1.8)-tmp_tslab(i)
2568       tmp_seaice(i) = tmp_seaice(i) + cyang/cbing * zz
2569       seaice(i) = tmp_seaice(i)
2570       tmp_tslab(i) = RTT-1.8
2571      ENDIF
2572!
2573! faire fondre de la glace si temperature est superieure a 0:
2574!
2575      IF ((tmp_tslab(i).GT.RTT) .AND. (tmp_seaice(i).GT.0.0)) THEN
2576       zz = cyang/cbing * (tmp_tslab(i)-RTT)
2577       zz = MIN(zz,tmp_seaice(i))
2578       tmp_seaice(i) = tmp_seaice(i) - zz
2579       seaice(i) = tmp_seaice(i)
2580       tmp_tslab(i) = tmp_tslab(i) - zz*cbing/cyang
2581      ENDIF
2582!
2583! limiter la glace de mer a 10 metres (10000 kg/m2)
2584!
2585      IF(tmp_seaice(i).GT.45.) THEN
2586       tmp_seaice(i) = MIN(tmp_seaice(i),10000.0)
2587      ELSE
2588       tmp_seaice(i) = 0.
2589      ENDIF
2590      seaice(i) = tmp_seaice(i)
2591      siceh(i)=tmp_seaice(i)/1000. !en metres
2592!
2593! determiner la nature du sol (glace de mer ou ocean libre):
2594!
2595! on fait dependre la fraction de seaice "pctsrf(i,is_sic)"
2596! de l'epaisseur de seaice :
2597! pctsrf(i,is_sic)=1. si l'epaisseur de la glace de mer est >= a 20cm
2598! et pctsrf(i,is_sic) croit lineairement avec seaice de 0. a 20cm d'epaisseur
2599!
2600
2601     IF(.NOT.ok_slab_sicOBS) then
2602      pctsrf_slab(i,is_sic)=MIN(siceh(i)/0.20, &
2603     &                      1.-(pctsrf_slab(i,is_ter)+pctsrf_slab(i,is_lic)))
2604      pctsrf_slab(i,is_oce)=1.0 - &
2605     &      (pctsrf_slab(i,is_ter)+pctsrf_slab(i,is_lic)+pctsrf_slab(i,is_sic))
2606     ELSE
2607      IF (i.EQ.1) print*,'cas ok_slab_sicOBS TRUE : passe sur la modif.'
2608     ENDIF !(.NOT.ok_slab_sicOBS) then
2609     ENDIF !pctsrf
2610   ENDDO
2611!
2612! Calculer le bilan du flux de chaleur au sol :
2613!
2614   DO i = 1, klon
2615    za = radsol(i) + fluxo(i)
2616    zb = fluxg(i)
2617    IF((pctsrf_slab(i,is_oce).GT.epsfra).OR. &
2618   &   (pctsrf_slab(i,is_sic).GT.epsfra)) THEN
2619     slab_bils(i)=slab_bils(i)+(za*pctsrf_slab(i,is_oce) &
2620   &             +zb*pctsrf_slab(i,is_sic))/ FLOAT(lmt_pas)
2621    ENDIF
2622   ENDDO !klon
2623!
2624! calcul tslab
2625!
2626   IF (MOD(itap,lmt_pas).EQ.0) THEN !fin de journee
2627!
2628! calcul tslab
2629    amn=MIN(tmp_tslab(1),1000.)
2630    amx=MAX(tmp_tslab(1),-1000.)
2631    DO i = 1, klon
2632      IF ((pctsrf_slab(i,is_oce).GT.epsfra).OR. &
2633     &    (pctsrf_slab(i,is_sic).GT.epsfra)) THEN
2634       tmp_tslab(i) = tmp_tslab(i) + &
2635     & (slab_bils(i)-lmt_bils(i)) &
2636     &                         /cyang*unjour
2637! on remet l'accumulation a 0
2638       slab_bils(i) = 0.
2639      ENDIF !pctsrf
2640!
2641      IF (check) THEN
2642       IF(i.EQ.1) THEN 
2643        PRINT*,'i tmp_tslab MOD(itap,lmt_pas).EQ.0 sicINTER',i,itap, &
2644      & tmp_tslab(i), tmp_seaice(i)
2645       ENDIF
2646!
2647       amn=MIN(tmp_tslab(i),amn)
2648       amx=MAX(tmp_tslab(i),amx)
2649      ENDIF
2650    ENDDO !klon
2651   ENDIF !(MOD(itap,lmt_pas).EQ.0) THEN
2652!
2653   IF ( check ) THEN
2654    PRINT*,'fin min max tslab',amn,amx
2655   ENDIF
2656!
2657   tslab = tmp_tslab
2658   seaice = tmp_seaice
2659  END SUBROUTINE interfoce_slab
2660!
2661!#########################################################################
2662!
2663  SUBROUTINE interfoce_lim(itime, dtime, jour, &
2664     & klon_xx, nisurf, knon, knindex, &
2665     & debut,  &
2666     & lmt_sst_p, pctsrf_new_p)
2667     
2668     USE dimphy,klon=>klon2,klon2=>klon
2669
2670#include "indicesol.inc"
2671
2672! Cette routine sert d'interface entre le modele atmospherique et un fichier
2673! de conditions aux limites
2674!
2675! L. Fairhead 02/2000
2676!
2677! input:
2678!   itime        numero du pas de temps courant
2679!   dtime        pas de temps de la physique (en s)
2680!   jour         jour a lire dans l'annee
2681!   nisurf       index de la surface a traiter (1 = sol continental)
2682!   knon         nombre de points dans le domaine a traiter
2683!   knindex      index des points de la surface a traiter
2684!   klon         taille de la grille
2685!   debut        logical: 1er appel a la physique (initialisation)
2686!
2687! output:
2688!   lmt_sst      SST lues dans le fichier de CL
2689!   pctsrf_new   sous-maille fractionnelle
2690!
2691
2692
2693! Parametres d'entree
2694  integer, intent(IN) :: itime
2695  real   , intent(IN) :: dtime
2696  integer, intent(IN) :: jour
2697  integer, intent(in) :: klon_xx
2698  integer, intent(IN) :: nisurf
2699  integer, intent(IN) :: knon
2700  integer, dimension(klon2), intent(in) :: knindex
2701  logical, intent(IN) :: debut
2702
2703! Parametres de sortie
2704  real, intent(out), dimension(klon2) :: lmt_sst_p
2705  real, intent(out), dimension(klon2,nbsrf) :: pctsrf_new_p
2706
2707!  real, dimension(klon) :: lmt_sst
2708  real, dimension(klon,nbsrf) :: pctsrf_new
2709
2710! Variables locales
2711  integer     :: ii
2712  INTEGER,save :: lmt_pas     ! frequence de lecture des conditions limites
2713                             ! (en pas de physique)
2714!$OMP THREADPRIVATE(lmt_pas)
2715  logical,save :: deja_lu    ! pour indiquer que le jour a lire a deja
2716                             ! lu pour une surface precedente
2717!$OMP THREADPRIVATE(deja_lu)
2718  integer,save :: jour_lu
2719!$OMP THREADPRIVATE(jour_lu)
2720  integer      :: ierr
2721  character (len = 20) :: modname = 'interfoce_lim'
2722  character (len = 80) :: abort_message
2723  character (len = 20),save :: fich ='limit.nc'
2724!$OMP THREADPRIVATE(fich)
2725  logical, save     :: newlmt = .TRUE.
2726!$OMP THREADPRIVATE(newlmt)
2727  logical, save     :: check = .FALSE.
2728!$OMP THREADPRIVATE(check)
2729! Champs lus dans le fichier de CL
2730  real, allocatable , save, dimension(:) :: sst_lu_p
2731!$OMP THREADPRIVATE(sst_lu_p)
2732  real, allocatable , save, dimension(:) :: sst_lu_mpi
2733
2734  real, allocatable , save, dimension(:,:) :: pct_tmp_p
2735!$OMP THREADPRIVATE(pct_tmp_p)
2736  real, allocatable , save, dimension(:,:) :: pct_tmp_mpi
2737  real, dimension(klon,nbsrf) :: pct_tmp
2738  real, dimension(klon) :: sst_lu
2739  real, dimension(klon) :: nat_lu
2740!
2741! quelques variables pour netcdf
2742!
2743#include "netcdf.inc"
2744  integer              :: nid, nvarid
2745  integer, dimension(2) :: start, epais
2746!
2747! Fin d�laration
2748!
2749 
2750  if (debut .and. .not. allocated(sst_lu_p)) then
2751    lmt_pas = nint(86400./dtime * 1.0) ! pour une lecture une fois par jour
2752    jour_lu = jour - 1
2753    allocate(sst_lu_p(klon_omp))
2754    allocate(pct_tmp_p(klon_omp,nbsrf))
2755  endif
2756
2757  if ((jour - jour_lu) /= 0) deja_lu = .false.
2758 
2759  if (check) write(*,*)modname,' :: jour, jour_lu, deja_lu', jour, jour_lu, deja_lu
2760  if (check) write(*,*)modname,' :: itime, lmt_pas ', itime, lmt_pas,dtime
2761
2762! Tester d'abord si c'est le moment de lire le fichier
2763  if (mod(itime-1, lmt_pas) == 0 .and. .not. deja_lu) then
2764!
2765! Ouverture du fichier
2766!
2767!$OMP MASTER
2768    if (.not. allocated(sst_lu_mpi)) allocate(sst_lu_mpi(klon_mpi))
2769    if (.not. allocated(pct_tmp_mpi)) allocate(pct_tmp_mpi(klon_mpi,nbsrf))
2770   
2771    if (phy_rank==0) then
2772   
2773    fich = trim(fich)
2774    ierr = NF_OPEN (fich, NF_NOWRITE,nid)
2775    if (ierr.NE.NF_NOERR) then
2776      abort_message = 'Pb d''ouverture du fichier de conditions aux limites'
2777      call abort_gcm(modname,abort_message,1)
2778    endif
2779!
2780! La tranche de donnees a lire:
2781!
2782    start(1) = 1
2783    start(2) = jour
2784    epais(1) = klon
2785    epais(2) = 1
2786!
2787    if (newlmt) then
2788!
2789! Fraction "ocean"
2790!
2791      ierr = NF_INQ_VARID(nid, 'FOCE', nvarid)
2792      if (ierr /= NF_NOERR) then
2793        abort_message = 'Le champ <FOCE> est absent'
2794        call abort_gcm(modname,abort_message,1)
2795      endif
2796#ifdef NC_DOUBLE
2797      ierr = NF_GET_VARA_DOUBLE(nid,nvarid,start,epais,pct_tmp(1,is_oce))
2798#else
2799      ierr = NF_GET_VARA_REAL(nid,nvarid,start,epais,pct_tmp(1,is_oce))
2800#endif
2801      if (ierr /= NF_NOERR) then
2802        abort_message = 'Lecture echouee pour <FOCE>'
2803        call abort_gcm(modname,abort_message,1)
2804      endif
2805!
2806! Fraction "glace de mer"
2807!
2808      ierr = NF_INQ_VARID(nid, 'FSIC', nvarid)
2809      if (ierr /= NF_NOERR) then
2810        abort_message = 'Le champ <FSIC> est absent'
2811        call abort_gcm(modname,abort_message,1)
2812      endif
2813#ifdef NC_DOUBLE
2814      ierr = NF_GET_VARA_DOUBLE(nid,nvarid,start,epais,pct_tmp(1,is_sic))
2815#else
2816      ierr = NF_GET_VARA_REAL(nid,nvarid,start,epais,pct_tmp(1,is_sic))
2817#endif
2818      if (ierr /= NF_NOERR) then
2819        abort_message = 'Lecture echouee pour <FSIC>'
2820        call abort_gcm(modname,abort_message,1)
2821      endif
2822!
2823! Fraction "terre"
2824!
2825      ierr = NF_INQ_VARID(nid, 'FTER', nvarid)
2826      if (ierr /= NF_NOERR) then
2827        abort_message = 'Le champ <FTER> est absent'
2828        call abort_gcm(modname,abort_message,1)
2829      endif
2830#ifdef NC_DOUBLE
2831      ierr = NF_GET_VARA_DOUBLE(nid,nvarid,start,epais,pct_tmp(1,is_ter))
2832#else
2833      ierr = NF_GET_VARA_REAL(nid,nvarid,start,epais,pct_tmp(1,is_ter))
2834#endif
2835      if (ierr /= NF_NOERR) then
2836        abort_message = 'Lecture echouee pour <FTER>'
2837        call abort_gcm(modname,abort_message,1)
2838      endif
2839!
2840! Fraction "glacier terre"
2841!
2842      ierr = NF_INQ_VARID(nid, 'FLIC', nvarid)
2843      if (ierr /= NF_NOERR) then
2844        abort_message = 'Le champ <FLIC> est absent'
2845        call abort_gcm(modname,abort_message,1)
2846      endif
2847#ifdef NC_DOUBLE
2848      ierr = NF_GET_VARA_DOUBLE(nid,nvarid,start,epais,pct_tmp(1,is_lic))
2849#else
2850      ierr = NF_GET_VARA_REAL(nid,nvarid,start,epais,pct_tmp(1,is_lic))
2851#endif
2852      if (ierr /= NF_NOERR) then
2853        abort_message = 'Lecture echouee pour <FLIC>'
2854        call abort_gcm(modname,abort_message,1)
2855      endif
2856!
2857    else  ! on en est toujours a rnatur
2858!
2859      ierr = NF_INQ_VARID(nid, 'NAT', nvarid)
2860      if (ierr /= NF_NOERR) then
2861        abort_message = 'Le champ <NAT> est absent'
2862        call abort_gcm(modname,abort_message,1)
2863      endif
2864#ifdef NC_DOUBLE
2865      ierr = NF_GET_VARA_DOUBLE(nid,nvarid,start,epais, nat_lu)
2866#else
2867      ierr = NF_GET_VARA_REAL(nid,nvarid,start,epais, nat_lu)
2868#endif
2869      if (ierr /= NF_NOERR) then
2870        abort_message = 'Lecture echouee pour <NAT>'
2871        call abort_gcm(modname,abort_message,1)
2872      endif
2873!
2874! Remplissage des fractions de surface
2875! nat = 0, 1, 2, 3 pour ocean, terre, glacier, seaice
2876!
2877      pct_tmp = 0.0
2878      do ii = 1, klon
2879        pct_tmp(ii,nint(nat_lu(ii)) + 1) = 1.
2880      enddo
2881
2882!
2883!  On se retrouve avec ocean en 1 et terre en 2 alors qu'on veut le contraire
2884!
2885      pctsrf_new = pct_tmp
2886      pctsrf_new (:,2)= pct_tmp (:,1)
2887      pctsrf_new (:,1)= pct_tmp (:,2)
2888      pct_tmp = pctsrf_new
2889    endif ! fin test sur newlmt
2890!
2891! Lecture SST
2892!
2893    ierr = NF_INQ_VARID(nid, 'SST', nvarid)
2894    if (ierr /= NF_NOERR) then
2895      abort_message = 'Le champ <SST> est absent'
2896      call abort_gcm(modname,abort_message,1)
2897    endif
2898#ifdef NC_DOUBLE
2899    ierr = NF_GET_VARA_DOUBLE(nid,nvarid,start,epais, sst_lu)
2900#else
2901    ierr = NF_GET_VARA_REAL(nid,nvarid,start,epais, sst_lu)
2902#endif
2903    if (ierr /= NF_NOERR) then
2904      abort_message = 'Lecture echouee pour <SST>'
2905      call abort_gcm(modname,abort_message,1)
2906    endif   
2907
2908!
2909! Fin de lecture
2910!
2911    ierr = NF_CLOSE(nid)
2912   endif ! phyrank
2913!
2914! Recopie des variables dans les champs de sortie
2915!
2916  call ScatterField(sst_lu,sst_lu_mpi,1)
2917  call ScatterField(pct_tmp(:,is_oce),pct_tmp_mpi(:,is_oce),1)
2918  call ScatterField(pct_tmp(:,is_sic),pct_tmp_mpi(:,is_sic),1)
2919!$OMP END MASTER
2920!$OMP BARRIER
2921  call ScatterField_omp(sst_lu_mpi,sst_lu_p,1)
2922  call ScatterField_omp(pct_tmp_mpi(:,is_oce),pct_tmp_p(:,is_oce),1)
2923  call ScatterField_omp(pct_tmp_mpi(:,is_sic),pct_tmp_p(:,is_sic),1)
2924   deja_lu = .true.
2925   jour_lu = jour
2926  endif   
2927 
2928  lmt_sst_p = 999999999.
2929 
2930  do ii = 1, knon
2931    lmt_sst_p(ii) = sst_lu_p(knindex(ii))
2932  enddo
2933
2934  do ii=1,klon2
2935    pctsrf_new_p(ii,is_oce)=pct_tmp_p(ii,is_oce)
2936    pctsrf_new_p(ii,is_sic)=pct_tmp_p(ii,is_sic)
2937  enddo
2938 
2939
2940  END SUBROUTINE interfoce_lim
2941
2942!
2943!#########################################################################
2944!
2945  SUBROUTINE interfsur_lim(itime, dtime, jour, &
2946     & klon_xx, nisurf, knon, knindex, &
2947     & debut,  &
2948     & lmt_alb_p, lmt_rug_p)
2949
2950     USE dimphy,klon=>klon2,klon2=>klon
2951
2952! Cette routine sert d'interface entre le modele atmospherique et un fichier
2953! de conditions aux limites
2954!
2955! L. Fairhead 02/2000
2956!
2957! input:
2958!   itime        numero du pas de temps courant
2959!   dtime        pas de temps de la physique (en s)
2960!   jour         jour a lire dans l'annee
2961!   nisurf       index de la surface a traiter (1 = sol continental)
2962!   knon         nombre de points dans le domaine a traiter
2963!   knindex      index des points de la surface a traiter
2964!   klon         taille de la grille
2965!   debut        logical: 1er appel a la physique (initialisation)
2966!
2967! output:
2968!   lmt_sst      SST lues dans le fichier de CL
2969!   lmt_alb      Albedo lu
2970!   lmt_rug      longueur de rugosit�lue
2971!   pctsrf_new   sous-maille fractionnelle
2972!
2973
2974
2975! Parametres d'entree
2976  integer, intent(IN) :: itime
2977  real   , intent(IN) :: dtime
2978  integer, intent(IN) :: jour
2979  integer, intent(IN) :: nisurf
2980  integer, intent(IN) :: knon
2981  integer, intent(IN) :: klon_xx
2982  integer, dimension(klon2), intent(in) :: knindex
2983  logical, intent(IN) :: debut
2984
2985! Parametres de sortie
2986  real, intent(out), dimension(klon2) :: lmt_alb_p
2987  real, intent(out), dimension(klon2) :: lmt_rug_p
2988
2989!  real,  dimension(klon) :: lmt_alb
2990!  real,  dimension(klon) :: lmt_rug
2991
2992! Variables locales
2993  integer     :: ii
2994  integer,save :: lmt_pas     ! frequence de lecture des conditions limites
2995                             ! (en pas de physique)
2996!$OMP THREADPRIVATE(lmt_pas)
2997  logical,save :: deja_lu_sur! pour indiquer que le jour a lire a deja
2998                             ! lu pour une surface precedente
2999!$OMP THREADPRIVATE(deja_lu_sur)
3000  integer,save :: jour_lu_sur
3001!$OMP THREADPRIVATE(jour_lu_sur)
3002  integer      :: ierr
3003  character (len = 20) :: modname = 'interfsur_lim'
3004  character (len = 80) :: abort_message
3005  character (len = 20),save :: fich ='limit.nc'
3006!$OMP THREADPRIVATE(fich)
3007  logical,save     :: newlmt = .false.
3008!$OMP THREADPRIVATE(newlmt)
3009  logical,save     :: check = .false.
3010!$OMP THREADPRIVATE(check)
3011! Champs lus dans le fichier de CL
3012  real, allocatable , save, dimension(:) :: alb_lu_p, rug_lu_p
3013!$OMP THREADPRIVATE(alb_lu_p, rug_lu_p)
3014  real, allocatable , save, dimension(:) :: alb_lu_mpi, rug_lu_mpi
3015  real, dimension(klon) :: alb_lu, rug_lu
3016!
3017! quelques variables pour netcdf
3018!
3019#include "netcdf.inc"
3020  integer ,save             :: nid, nvarid
3021!$OMP THREADPRIVATE(nid, nvarid)
3022  integer, dimension(2),save :: start, epais
3023!$OMP THREADPRIVATE(start, epais)
3024!
3025! Fin d�laration
3026!
3027 
3028  if (debut) then
3029    lmt_pas = nint(86400./dtime * 1.0) ! pour une lecture une fois par jour
3030    jour_lu_sur = jour - 1
3031    allocate(alb_lu_p(klon_omp))
3032    allocate(rug_lu_p(klon_omp))
3033  endif
3034
3035  if ((jour - jour_lu_sur) /= 0) deja_lu_sur = .false.
3036 
3037  if (check) write(*,*)modname,':: jour_lu_sur, deja_lu_sur', jour_lu_sur, deja_lu_sur
3038  if (check) write(*,*)modname,':: itime, lmt_pas', itime, lmt_pas
3039  if (check) call flush(6)
3040
3041! Tester d'abord si c'est le moment de lire le fichier
3042  if (mod(itime-1, lmt_pas) == 0 .and. .not. deja_lu_sur) then
3043
3044!$OMP MASTER
3045    if (.not. allocated(alb_lu_mpi)) allocate(alb_lu_mpi(klon_mpi))
3046    if (.not. allocated(rug_lu_mpi)) allocate(rug_lu_mpi(klon_mpi)) 
3047  if (phy_rank==0) then
3048!
3049! Ouverture du fichier
3050!
3051    fich = trim(fich)
3052    IF (check) WRITE(*,*)modname,' ouverture fichier ',fich
3053    if (check) CALL flush(6)
3054    ierr = NF_OPEN (fich, NF_NOWRITE,nid)
3055    if (ierr.NE.NF_NOERR) then
3056      abort_message = 'Pb d''ouverture du fichier de conditions aux limites'
3057      call abort_gcm(modname,abort_message,1)
3058    endif
3059!
3060! La tranche de donnees a lire:
3061 
3062    start(1) = 1
3063    start(2) = jour
3064    epais(1) = klon
3065    epais(2) = 1
3066!
3067! Lecture Albedo
3068!
3069    ierr = NF_INQ_VARID(nid, 'ALB', nvarid)
3070    if (ierr /= NF_NOERR) then
3071      abort_message = 'Le champ <ALB> est absent'
3072      call abort_gcm(modname,abort_message,1)
3073    endif
3074#ifdef NC_DOUBLE
3075    ierr = NF_GET_VARA_DOUBLE(nid,nvarid,start,epais, alb_lu)
3076#else
3077    ierr = NF_GET_VARA_REAL(nid,nvarid,start,epais, alb_lu)
3078#endif
3079    if (ierr /= NF_NOERR) then
3080      abort_message = 'Lecture echouee pour <ALB>'
3081      call abort_gcm(modname,abort_message,1)
3082    endif
3083!
3084! Lecture rugosit�!
3085    ierr = NF_INQ_VARID(nid, 'RUG', nvarid)
3086    if (ierr /= NF_NOERR) then
3087      abort_message = 'Le champ <RUG> est absent'
3088      call abort_gcm(modname,abort_message,1)
3089    endif
3090#ifdef NC_DOUBLE
3091    ierr = NF_GET_VARA_DOUBLE(nid,nvarid,start,epais, rug_lu)
3092#else
3093    ierr = NF_GET_VARA_REAL(nid,nvarid,start,epais, rug_lu)
3094#endif
3095    if (ierr /= NF_NOERR) then
3096      abort_message = 'Lecture echouee pour <RUG>'
3097      call abort_gcm(modname,abort_message,1)
3098    endif
3099
3100!
3101! Fin de lecture
3102!
3103    ierr = NF_CLOSE(nid)
3104
3105
3106  endif  !! phyrank
3107
3108    call ScatterField(alb_lu,alb_lu_mpi,1)
3109    call ScatterField(rug_lu,rug_lu_mpi,1)
3110!$OMP END MASTER
3111!$OMP BARRIER
3112
3113    call ScatterField_omp(alb_lu_mpi,alb_lu_p,1)
3114    call ScatterField_omp(rug_lu_mpi,rug_lu_p,1)
3115   
3116    deja_lu_sur = .true.
3117    jour_lu_sur = jour
3118
3119
3120  endif
3121 
3122!
3123! Recopie des variables dans les champs de sortie
3124!
3125!!$  lmt_alb(:) = 0.0
3126!!$  lmt_rug(:) = 0.0
3127 
3128  lmt_alb_p(:) = 999999.
3129  lmt_rug_p(:) = 999999.
3130  DO ii = 1, knon
3131    lmt_alb_p(ii) = alb_lu_p(knindex(ii))
3132    lmt_rug_p(ii) = rug_lu_p(knindex(ii))
3133  enddo
3134
3135
3136  END SUBROUTINE interfsur_lim
3137
3138!
3139!#########################################################################
3140!
3141
3142  SUBROUTINE calcul_fluxs( klon, knon, nisurf, dtime, &
3143     & tsurf, p1lay, cal, beta, coef1lay, ps, &
3144     & precip_rain, precip_snow, snow, qsurf, &
3145     & radsol, dif_grnd, t1lay, q1lay, u1lay, v1lay, &
3146     & petAcoef, peqAcoef, petBcoef, peqBcoef, &
3147     & tsurf_new, evap, fluxlat, fluxsens, dflux_s, dflux_l)
3148     USE dimphy,only : omp_rank
3149! Cette routine calcule les fluxs en h et q a l'interface et eventuellement
3150! une temperature de surface (au cas ou ok_veget = false)
3151!
3152! L. Fairhead 4/2000
3153!
3154! input:
3155!   knon         nombre de points a traiter
3156!   nisurf       surface a traiter
3157!   tsurf        temperature de surface
3158!   p1lay        pression 1er niveau (milieu de couche)
3159!   cal          capacite calorifique du sol
3160!   beta         evap reelle
3161!   coef1lay     coefficient d'echange
3162!   ps           pression au sol
3163!   precip_rain  precipitations liquides
3164!   precip_snow  precipitations solides
3165!   snow         champs hauteur de neige
3166!   runoff       runoff en cas de trop plein
3167!   petAcoef     coeff. A de la resolution de la CL pour t
3168!   peqAcoef     coeff. A de la resolution de la CL pour q
3169!   petBcoef     coeff. B de la resolution de la CL pour t
3170!   peqBcoef     coeff. B de la resolution de la CL pour q
3171!   radsol       rayonnement net aus sol (LW + SW)
3172!   dif_grnd     coeff. diffusion vers le sol profond
3173!
3174! output:
3175!   tsurf_new    temperature au sol
3176!   qsurf        humidite de l'air au dessus du sol
3177!   fluxsens     flux de chaleur sensible
3178!   fluxlat      flux de chaleur latente
3179!   dflux_s      derivee du flux de chaleur sensible / Ts
3180!   dflux_l      derivee du flux de chaleur latente  / Ts
3181!
3182
3183#include "YOETHF.inc"
3184#include "FCTTRE.inc"
3185#include "indicesol.inc"
3186#include "YOMCST.inc"
3187
3188! Parametres d'entree
3189  integer, intent(IN) :: knon, nisurf, klon
3190  real   , intent(IN) :: dtime
3191  real, dimension(klon), intent(IN) :: petAcoef, peqAcoef
3192  real, dimension(klon), intent(IN) :: petBcoef, peqBcoef
3193  real, dimension(klon), intent(IN) :: ps, q1lay
3194  real, dimension(klon), intent(IN) :: tsurf, p1lay, cal, beta, coef1lay
3195  real, dimension(klon), intent(IN) :: precip_rain, precip_snow
3196  real, dimension(klon), intent(IN) :: radsol, dif_grnd
3197  real, dimension(klon), intent(IN) :: t1lay, u1lay, v1lay
3198  real, dimension(klon), intent(INOUT) :: snow, qsurf
3199
3200! Parametres sorties
3201  real, dimension(klon), intent(OUT):: tsurf_new, evap, fluxsens, fluxlat
3202  real, dimension(klon), intent(OUT):: dflux_s, dflux_l
3203
3204! Variables locales
3205  integer :: i
3206  real, dimension(klon) :: zx_mh, zx_nh, zx_oh
3207  real, dimension(klon) :: zx_mq, zx_nq, zx_oq
3208  real, dimension(klon) :: zx_pkh, zx_dq_s_dt, zx_qsat, zx_coef
3209  real, dimension(klon) :: zx_sl, zx_k1
3210  real, dimension(klon) :: zx_q_0 , d_ts
3211  real                  :: zdelta, zcvm5, zx_qs, zcor, zx_dq_s_dh
3212  real                  :: bilan_f, fq_fonte
3213  REAL                  :: subli, fsno
3214  REAL                  :: qsat_new, q1_new
3215  real, parameter :: t_grnd = 271.35, t_coup = 273.15
3216!! PB temporaire en attendant mieux pour le modele de neige
3217  REAL, parameter :: chasno = 3.334E+05/(2.3867E+06*0.15)
3218!
3219  logical, save         :: check = .false.
3220!$OMP THREADPRIVATE(check)
3221  character (len = 20)  :: modname = 'calcul_fluxs'
3222  logical, save         :: fonte_neige = .false.
3223!$OMP THREADPRIVATE(fonte_neige)
3224  real, save            :: max_eau_sol = 150.0
3225!$OMP THREADPRIVATE(max_eau_sol)
3226  character (len = 80) :: abort_message
3227  logical,save         :: first = .true.,second=.false.
3228!$OMP THREADPRIVATE(first,second)
3229
3230  if (check) write(*,*)'Entree ', modname,' surface = ',nisurf
3231
3232  IF (check) THEN
3233      WRITE(*,*)' radsol (min, max)' &
3234         &     , MINVAL(radsol(1:knon)), MAXVAL(radsol(1:knon))
3235      CALL flush(6)
3236  ENDIF
3237
3238  if (size(coastalflow) /= knon .AND. nisurf == is_ter) then
3239    write(*,*)'Bizarre, le nombre de points continentaux'
3240    write(*,*)'a change entre deux appels. J''arrete ...'
3241    abort_message='Pb run_off'
3242    call abort_gcm(modname,abort_message,1)
3243  endif
3244!
3245! Traitement neige et humidite du sol
3246!
3247!!$  WRITE(*,*)'test calcul_flux, surface ', nisurf
3248!!PB test
3249!!$    if (nisurf == is_oce) then
3250!!$      snow = 0.
3251!!$      qsol = max_eau_sol
3252!!$    else
3253!!$      where (precip_snow > 0.) snow = snow + (precip_snow * dtime)
3254!!$      where (snow > epsilon(snow)) snow = max(0.0, snow - (evap * dtime))
3255!!$!      snow = max(0.0, snow + (precip_snow - evap) * dtime)
3256!!$      where (precip_rain > 0.) qsol = qsol + (precip_rain - evap) * dtime
3257!!$    endif
3258!!$    IF (nisurf /= is_ter) qsol = max_eau_sol
3259
3260
3261!
3262! Initialisation
3263!
3264  evap = 0.
3265  fluxsens=0.
3266  fluxlat=0.
3267  dflux_s = 0.
3268  dflux_l = 0. 
3269!
3270! zx_qs = qsat en kg/kg
3271!
3272  DO i = 1, knon
3273    zx_pkh(i) = (ps(i)/ps(i))**RKAPPA
3274  IF (thermcep) THEN
3275      zdelta=MAX(0.,SIGN(1.,rtt-tsurf(i)))
3276      zcvm5 = R5LES*RLVTT*(1.-zdelta) + R5IES*RLSTT*zdelta
3277      zcvm5 = zcvm5 / RCPD / (1.0+RVTMP2*q1lay(i))
3278      zx_qs= r2es * FOEEW(tsurf(i),zdelta)/ps(i)
3279      zx_qs=MIN(0.5,zx_qs)
3280      zcor=1./(1.-retv*zx_qs)
3281      zx_qs=zx_qs*zcor
3282      zx_dq_s_dh = FOEDE(tsurf(i),zdelta,zcvm5,zx_qs,zcor) &
3283     &                 /RLVTT / zx_pkh(i)
3284    ELSE
3285      IF (tsurf(i).LT.t_coup) THEN
3286        zx_qs = qsats(tsurf(i)) / ps(i)
3287        zx_dq_s_dh = dqsats(tsurf(i),zx_qs)/RLVTT &
3288     &                    / zx_pkh(i)
3289      ELSE
3290        zx_qs = qsatl(tsurf(i)) / ps(i)
3291        zx_dq_s_dh = dqsatl(tsurf(i),zx_qs)/RLVTT &
3292     &               / zx_pkh(i)
3293      ENDIF
3294    ENDIF
3295    zx_dq_s_dt(i) = RCPD * zx_pkh(i) * zx_dq_s_dh
3296    zx_qsat(i) = zx_qs
3297    zx_coef(i) = coef1lay(i) &
3298     & * (1.0+SQRT(u1lay(i)**2+v1lay(i)**2)) &
3299     & * p1lay(i)/(RD*t1lay(i))
3300
3301  ENDDO
3302
3303
3304! === Calcul de la temperature de surface ===
3305!
3306! zx_sl = chaleur latente d'evaporation ou de sublimation
3307!
3308  do i = 1, knon
3309    zx_sl(i) = RLVTT
3310    if (tsurf(i) .LT. RTT) zx_sl(i) = RLSTT
3311    zx_k1(i) = zx_coef(i)
3312  enddo
3313
3314
3315  do i = 1, knon
3316! Q
3317    zx_oq(i) = 1. - (beta(i) * zx_k1(i) * peqBcoef(i) * dtime)
3318    zx_mq(i) = beta(i) * zx_k1(i) * &
3319     &             (peqAcoef(i) - zx_qsat(i) &
3320     &                          + zx_dq_s_dt(i) * tsurf(i)) &
3321     &             / zx_oq(i)
3322    zx_nq(i) = beta(i) * zx_k1(i) * (-1. * zx_dq_s_dt(i)) &
3323     &                              / zx_oq(i)
3324
3325! H
3326    zx_oh(i) = 1. - (zx_k1(i) * petBcoef(i) * dtime)
3327    zx_mh(i) = zx_k1(i) * petAcoef(i) / zx_oh(i)
3328    zx_nh(i) = - (zx_k1(i) * RCPD * zx_pkh(i))/ zx_oh(i)
3329
3330! Tsurface
3331    tsurf_new(i) = (tsurf(i) + cal(i)/(RCPD * zx_pkh(i)) * dtime * &
3332     &             (radsol(i) + zx_mh(i) + zx_sl(i) * zx_mq(i)) &
3333     &                 + dif_grnd(i) * t_grnd * dtime)/ &
3334     &          ( 1. - dtime * cal(i)/(RCPD * zx_pkh(i)) * ( &
3335     &                       zx_nh(i) + zx_sl(i) * zx_nq(i)) & 
3336     &                     + dtime * dif_grnd(i))
3337
3338!
3339! Y'a-t-il fonte de neige?
3340!
3341!    fonte_neige = (nisurf /= is_oce) .AND. &
3342!     & (snow(i) > epsfra .OR. nisurf == is_sic .OR. nisurf == is_lic) &
3343!     & .AND. (tsurf_new(i) >= RTT)
3344!    if (fonte_neige) tsurf_new(i) = RTT 
3345    d_ts(i) = tsurf_new(i) - tsurf(i)
3346!    zx_h_ts(i) = tsurf_new(i) * RCPD * zx_pkh(i)
3347!    zx_q_0(i) = zx_qsat(i) + zx_dq_s_dt(i) * d_ts(i)
3348!== flux_q est le flux de vapeur d'eau: kg/(m**2 s)  positive vers bas
3349!== flux_t est le flux de cpt (energie sensible): j/(m**2 s)
3350    evap(i) = - zx_mq(i) - zx_nq(i) * tsurf_new(i)
3351    fluxlat(i) = - evap(i) * zx_sl(i)
3352    fluxsens(i) = zx_mh(i) + zx_nh(i) * tsurf_new(i)
3353! Derives des flux dF/dTs (W m-2 K-1):
3354    dflux_s(i) = zx_nh(i)
3355    dflux_l(i) = (zx_sl(i) * zx_nq(i))
3356! Nouvelle valeure de l'humidite au dessus du sol
3357    qsat_new=zx_qsat(i) + zx_dq_s_dt(i) * d_ts(i)
3358    q1_new = peqAcoef(i) - peqBcoef(i)*evap(i)*dtime
3359    qsurf(i)=q1_new*(1.-beta(i)) + beta(i)*qsat_new
3360!
3361! en cas de fonte de neige
3362!
3363!    if (fonte_neige) then
3364!      bilan_f = radsol(i) + fluxsens(i) - (zx_sl(i) * evap (i)) - &
3365!     &          dif_grnd(i) * (tsurf_new(i) - t_grnd) - &
3366!     &          RCPD * (zx_pkh(i))/cal(i)/dtime * (tsurf_new(i) - tsurf(i))
3367!      bilan_f = max(0., bilan_f)
3368!      fq_fonte = bilan_f / zx_sl(i)
3369!      snow(i) = max(0., snow(i) - fq_fonte * dtime)
3370!      qsol(i) = qsol(i) + (fq_fonte * dtime)
3371!    endif
3372!!$    if (nisurf == is_ter)  &
3373!!$     &  run_off(i) = run_off(i) + max(qsol(i) - max_eau_sol, 0.0)
3374!!$    qsol(i) = min(qsol(i), max_eau_sol)
3375  ENDDO
3376
3377  END SUBROUTINE calcul_fluxs
3378!
3379!#########################################################################
3380!
3381  SUBROUTINE gath2cpl(champ_in, champ_out, klon, knon, iim, jmp1, knindex)
3382  use dimphy, only: liste_i,liste_j,jjphy_begin,jjphy_nb,phy_rank,phy_size
3383  implicit none
3384 
3385! Cette routine ecrit un champ 'gathered' sur la grille 2D pour le passer
3386! au coupleur.
3387!
3388!
3389! input:         
3390!   champ_in     champ sur la grille gathere       
3391!   knon         nombre de points dans le domaine a traiter
3392!   knindex      index des points de la surface a traiter
3393!   klon         taille de la grille
3394!   iim,jjm      dimension de la grille 2D
3395!
3396! output:
3397!   champ_out    champ sur la grille 2D
3398!
3399! input
3400  integer                   :: klon, knon, iim, jmp1
3401  real, dimension(klon)     :: champ_in
3402  integer, dimension(klon)  :: knindex
3403! output
3404  real, dimension(iim,jmp1)  :: champ_out
3405! local
3406  integer                   :: i, ig, j
3407  real, dimension(klon)     :: tamp
3408
3409  tamp = 0.
3410  do i = 1, knon
3411    ig = knindex(i)
3412    tamp(ig) = champ_in(i)
3413  enddo   
3414
3415!ym  ig = 1
3416!ym  champ_out(:,1) = tamp(ig)
3417!ym  do j = 2, jjm
3418!ym    do i = 1, iim
3419!ym      ig = ig + 1
3420!ym      champ_out(i,j) = tamp(ig)
3421!ym    enddo
3422!ym  enddo
3423!ym  ig = ig + 1
3424!ym  champ_out(:,jjm+1) = tamp(ig)
3425
3426  do ig=1,klon
3427    i=liste_i(ig)
3428    j=liste_j(ig)-jjphy_begin+1
3429    champ_out(i,j)=tamp(ig)
3430  enddo
3431 
3432  if (phy_rank==0) champ_out(:,1)=tamp(1)
3433  if (phy_rank==phy_size-1) champ_out(:,jjphy_nb)=tamp(klon)
3434
3435  END SUBROUTINE gath2cpl
3436!
3437!#########################################################################
3438!
3439  SUBROUTINE cpl2gath(champ_in, champ_out, klon, knon, iim, jmp1, knindex)
3440  use dimphy, only : liste_i, liste_j, jjphy_begin
3441  implicit none
3442! Cette routine ecrit un champ 'gathered' sur la grille 2D pour le passer
3443! au coupleur.
3444!
3445!
3446! input:         
3447!   champ_in     champ sur la grille gathere       
3448!   knon         nombre de points dans le domaine a traiter
3449!   knindex      index des points de la surface a traiter
3450!   klon         taille de la grille
3451!   iim,jjm      dimension de la grille 2D
3452!
3453! output:
3454!   champ_out    champ sur la grille 2D
3455!
3456! input
3457  integer                   :: klon, knon, iim, jmp1
3458  real, dimension(iim,jmp1)     :: champ_in
3459  integer, dimension(klon)  :: knindex
3460! output
3461  real, dimension(klon)  :: champ_out
3462! local
3463  integer                   :: i, ig, j
3464  real, dimension(klon)     :: tamp
3465  logical ,save                  :: check = .false.
3466
3467!ym  ig = 1
3468!ym  tamp(ig) = champ_in(1,1)
3469!ym  do j = 2, jjm
3470!ym    do i = 1, iim
3471!ym      ig = ig + 1
3472!ym      tamp(ig) = champ_in(i,j)
3473!ym    enddo
3474!ym  enddo
3475!ym  ig = ig + 1
3476!ym  tamp(ig) = champ_in(1,jjm+1)
3477
3478  do ig=1,klon
3479   i=liste_i(ig)
3480   j=liste_j(ig)-jjphy_begin+1
3481   tamp(ig)=champ_in(i,j)
3482  enddo
3483 
3484  do i = 1, knon
3485    ig = knindex(i)
3486    champ_out(i) = tamp(ig)
3487  enddo   
3488
3489  END SUBROUTINE cpl2gath
3490!
3491!#########################################################################
3492!
3493  SUBROUTINE albsno(klon, knon,dtime,agesno,alb_neig_grid, precip_snow)
3494  IMPLICIT none
3495 
3496  INTEGER :: klon, knon
3497  INTEGER, PARAMETER :: nvm = 8
3498  REAL   :: dtime
3499  REAL, dimension(klon,nvm) :: veget
3500  REAL, DIMENSION(klon) :: alb_neig_grid, agesno, precip_snow
3501 
3502  INTEGER :: i, nv
3503 
3504  REAL, DIMENSION(nvm),SAVE :: init, decay
3505!$OMP THREADPRIVATE(init, decay)
3506  REAL :: as
3507  DATA init /0.55, 0.14, 0.18, 0.29, 0.15, 0.15, 0.14, 0./
3508  DATA decay/0.30, 0.67, 0.63, 0.45, 0.40, 0.14, 0.06, 1./
3509 
3510  veget = 0.
3511  veget(:,1) = 1.     ! desert partout
3512  DO i = 1, knon
3513    alb_neig_grid(i) = 0.0
3514  ENDDO
3515  DO nv = 1, nvm
3516    DO i = 1, knon
3517      as = init(nv)+decay(nv)*EXP(-agesno(i)/5.)
3518      alb_neig_grid(i) = alb_neig_grid(i) + veget(i,nv)*as
3519    ENDDO
3520  ENDDO
3521!
3522!! modilation en fonction de l'age de la neige
3523!
3524  DO i = 1, knon
3525    agesno(i)  = (agesno(i) + (1.-agesno(i)/50.)*dtime/86400.)&
3526            &             * EXP(-1.*MAX(0.0,precip_snow(i))*dtime/0.3)
3527    agesno(i) =  MAX(agesno(i),0.0)
3528  ENDDO
3529 
3530  END SUBROUTINE albsno
3531!
3532!#########################################################################
3533!
3534
3535  SUBROUTINE fonte_neige( klon, knon, nisurf, dtime, &
3536     & tsurf, p1lay, cal, beta, coef1lay, ps, &
3537     & precip_rain, precip_snow, snow, qsol, &
3538     & radsol, dif_grnd, t1lay, q1lay, u1lay, v1lay, &
3539     & petAcoef, peqAcoef, petBcoef, peqBcoef, &
3540     & tsurf_new, evap, fluxlat, fluxsens, dflux_s, dflux_l, &
3541     & fqcalving,fqfonte,ffonte,run_off_lic_0)
3542
3543! Routine de traitement de la fonte de la neige dans le cas du traitement
3544! de sol simplifi�!
3545! LF 03/2001
3546! input:
3547!   knon         nombre de points a traiter
3548!   nisurf       surface a traiter
3549!   tsurf        temperature de surface
3550!   p1lay        pression 1er niveau (milieu de couche)
3551!   cal          capacite calorifique du sol
3552!   beta         evap reelle
3553!   coef1lay     coefficient d'echange
3554!   ps           pression au sol
3555!   precip_rain  precipitations liquides
3556!   precip_snow  precipitations solides
3557!   snow         champs hauteur de neige
3558!   qsol         hauteur d'eau contenu dans le sol
3559!   runoff       runoff en cas de trop plein
3560!   petAcoef     coeff. A de la resolution de la CL pour t
3561!   peqAcoef     coeff. A de la resolution de la CL pour q
3562!   petBcoef     coeff. B de la resolution de la CL pour t
3563!   peqBcoef     coeff. B de la resolution de la CL pour q
3564!   radsol       rayonnement net aus sol (LW + SW)
3565!   dif_grnd     coeff. diffusion vers le sol profond
3566!
3567! output:
3568!   tsurf_new    temperature au sol
3569!   fluxsens     flux de chaleur sensible
3570!   fluxlat      flux de chaleur latente
3571!   dflux_s      derivee du flux de chaleur sensible / Ts
3572!   dflux_l      derivee du flux de chaleur latente  / Ts
3573! in/out:
3574!   run_off_lic_0 run off glacier du pas de temps pr�edent
3575!
3576
3577#include "YOETHF.inc"
3578!rv#include "FCTTRE.inc"
3579#include "indicesol.inc"
3580!IM cf JLD
3581#include "YOMCST.inc"
3582
3583! Parametres d'entree
3584  integer, intent(IN) :: knon, nisurf, klon
3585  real   , intent(IN) :: dtime
3586  real, dimension(klon), intent(IN) :: petAcoef, peqAcoef
3587  real, dimension(klon), intent(IN) :: petBcoef, peqBcoef
3588  real, dimension(klon), intent(IN) :: ps, q1lay
3589  real, dimension(klon), intent(IN) :: tsurf, p1lay, cal, beta, coef1lay
3590  real, dimension(klon), intent(IN) :: precip_rain, precip_snow
3591  real, dimension(klon), intent(IN) :: radsol, dif_grnd
3592  real, dimension(klon), intent(IN) :: t1lay, u1lay, v1lay
3593  real, dimension(klon), intent(INOUT) :: snow, qsol
3594
3595! Parametres sorties
3596  real, dimension(klon), intent(INOUT):: tsurf_new, evap, fluxsens, fluxlat
3597  real, dimension(klon), intent(INOUT):: dflux_s, dflux_l
3598! Flux thermique utiliser pour fondre la neige
3599  real, dimension(klon), intent(INOUT):: ffonte
3600! Flux d'eau "perdu" par la surface et necessaire pour que limiter la
3601! hauteur de neige, en kg/m2/s. Et flux d'eau de fonte de la calotte.
3602  REAL, DIMENSION(klon), INTENT(INOUT):: fqcalving, fqfonte
3603  real, dimension(klon), intent(INOUT):: run_off_lic_0
3604! Variables locales
3605! Masse maximum de neige (kg/m2). Au dessus de ce seuil, la neige
3606! en exces "s'ecoule" (calving)
3607!  real, parameter :: snow_max=1.
3608!IM cf JLD/GK
3609  real, parameter :: snow_max=3000.
3610  integer :: i
3611  real, dimension(klon) :: zx_mh, zx_nh, zx_oh
3612  real, dimension(klon) :: zx_mq, zx_nq, zx_oq
3613  real, dimension(klon) :: zx_pkh, zx_dq_s_dt, zx_qsat, zx_coef
3614  real, dimension(klon) :: zx_sl, zx_k1
3615  real, dimension(klon) :: zx_q_0 , d_ts
3616  real                  :: zdelta, zcvm5, zx_qs, zcor, zx_dq_s_dh
3617  real                  :: bilan_f, fq_fonte
3618  REAL                  :: subli, fsno
3619  REAL, DIMENSION(klon) :: bil_eau_s, snow_evap
3620  real, parameter :: t_grnd = 271.35, t_coup = 273.15
3621!! PB temporaire en attendant mieux pour le modele de neige
3622! REAL, parameter :: chasno = RLMLT/(2.3867E+06*0.15)
3623  REAL, parameter :: chasno = 3.334E+05/(2.3867E+06*0.15)
3624!IM cf JLD/ GKtest
3625  REAL, parameter :: chaice = 3.334E+05/(2.3867E+06*0.15)
3626! fin GKtest
3627!
3628  logical, save         :: check = .FALSE.
3629!$OMP THREADPRIVATE(check)
3630  character (len = 20)  :: modname = 'fonte_neige'
3631  logical, save         :: neige_fond = .false.
3632!$OMP THREADPRIVATE(neige_fond)
3633  real, save            :: max_eau_sol = 150.0
3634!$OMP THREADPRIVATE(max_eau_sol)
3635  character (len = 80) :: abort_message
3636  logical,save         :: first = .true.,second=.false.
3637!$OMP THREADPRIVATE(first,second)
3638  real                 :: coeff_rel
3639#include "FCTTRE.inc"
3640
3641
3642  if (check) write(*,*)'Entree ', modname,' surface = ',nisurf
3643
3644! Initialisations
3645  coeff_rel = dtime/(tau_calv * rday)
3646  bil_eau_s(:) = 0.
3647  DO i = 1, knon
3648    zx_pkh(i) = (ps(i)/ps(i))**RKAPPA
3649  IF (thermcep) THEN
3650      zdelta=MAX(0.,SIGN(1.,rtt-tsurf(i)))
3651      zcvm5 = R5LES*RLVTT*(1.-zdelta) + R5IES*RLSTT*zdelta
3652      zcvm5 = zcvm5 / RCPD / (1.0+RVTMP2*q1lay(i))
3653      zx_qs= r2es * FOEEW(tsurf(i),zdelta)/ps(i)
3654      zx_qs=MIN(0.5,zx_qs)
3655      zcor=1./(1.-retv*zx_qs)
3656      zx_qs=zx_qs*zcor
3657      zx_dq_s_dh = FOEDE(tsurf(i),zdelta,zcvm5,zx_qs,zcor) &
3658     &                 /RLVTT / zx_pkh(i)
3659    ELSE
3660      IF (tsurf(i).LT.t_coup) THEN
3661        zx_qs = qsats(tsurf(i)) / ps(i)
3662        zx_dq_s_dh = dqsats(tsurf(i),zx_qs)/RLVTT &
3663     &                    / zx_pkh(i)
3664      ELSE
3665        zx_qs = qsatl(tsurf(i)) / ps(i)
3666        zx_dq_s_dh = dqsatl(tsurf(i),zx_qs)/RLVTT &
3667     &               / zx_pkh(i)
3668      ENDIF
3669    ENDIF
3670    zx_dq_s_dt(i) = RCPD * zx_pkh(i) * zx_dq_s_dh
3671    zx_qsat(i) = zx_qs
3672    zx_coef(i) = coef1lay(i) &
3673     & * (1.0+SQRT(u1lay(i)**2+v1lay(i)**2)) &
3674     & * p1lay(i)/(RD*t1lay(i))
3675  ENDDO
3676
3677
3678! === Calcul de la temperature de surface ===
3679!
3680! zx_sl = chaleur latente d'evaporation ou de sublimation
3681!
3682  do i = 1, knon
3683    zx_sl(i) = RLVTT
3684    if (tsurf(i) .LT. RTT) zx_sl(i) = RLSTT
3685    zx_k1(i) = zx_coef(i)
3686  enddo
3687
3688
3689  do i = 1, knon
3690! Q
3691    zx_oq(i) = 1. - (beta(i) * zx_k1(i) * peqBcoef(i) * dtime)
3692    zx_mq(i) = beta(i) * zx_k1(i) * &
3693     &             (peqAcoef(i) - zx_qsat(i) &
3694     &                          + zx_dq_s_dt(i) * tsurf(i)) &
3695     &             / zx_oq(i)
3696    zx_nq(i) = beta(i) * zx_k1(i) * (-1. * zx_dq_s_dt(i)) &
3697     &                              / zx_oq(i)
3698
3699! H
3700    zx_oh(i) = 1. - (zx_k1(i) * petBcoef(i) * dtime)
3701    zx_mh(i) = zx_k1(i) * petAcoef(i) / zx_oh(i)
3702    zx_nh(i) = - (zx_k1(i) * RCPD * zx_pkh(i))/ zx_oh(i)
3703  enddo
3704
3705
3706  WHERE (precip_snow > 0.) snow = snow + (precip_snow * dtime)
3707  snow_evap = 0.
3708  WHERE (evap > 0. )
3709    snow_evap = MIN (snow / dtime, evap)
3710    snow = snow - snow_evap * dtime
3711    snow = MAX(0.0, snow)
3712  end where
3713 
3714!  bil_eau_s = bil_eau_s + (precip_rain * dtime) - (evap - snow_evap) * dtime
3715  bil_eau_s = (precip_rain * dtime) - (evap - snow_evap) * dtime
3716
3717!
3718! Y'a-t-il fonte de neige?
3719!
3720  ffonte=0.
3721  do i = 1, knon
3722    neige_fond = ((snow(i) > epsfra .OR. nisurf == is_sic .OR. nisurf == is_lic) &
3723     & .AND. tsurf_new(i) >= RTT)
3724    if (neige_fond) then
3725      fq_fonte = MIN( MAX((tsurf_new(i)-RTT )/chasno,0.0),snow(i))
3726      ffonte(i) = fq_fonte * RLMLT/dtime
3727      fqfonte(i) = fq_fonte/dtime
3728      snow(i) = max(0., snow(i) - fq_fonte)
3729      bil_eau_s(i) = bil_eau_s(i) + fq_fonte
3730      tsurf_new(i) = tsurf_new(i) - fq_fonte * chasno 
3731!IM cf JLD OK     
3732!IM cf JLD/ GKtest fonte aussi pour la glace
3733      IF (nisurf == is_sic .OR. nisurf == is_lic ) THEN
3734        fq_fonte = MAX((tsurf_new(i)-RTT )/chaice,0.0)
3735        ffonte(i) = ffonte(i) + fq_fonte * RLMLT/dtime
3736        IF ( ok_lic_melt ) THEN
3737           fqfonte(i) = fqfonte(i) + fq_fonte/dtime
3738           bil_eau_s(i) = bil_eau_s(i) + fq_fonte
3739        ENDIF
3740        tsurf_new(i) = RTT
3741      ENDIF
3742      d_ts(i) = tsurf_new(i) - tsurf(i)
3743    endif
3744!
3745!   s'il y a une hauteur trop importante de neige, elle s'coule
3746    fqcalving(i) = max(0., snow(i) - snow_max)/dtime
3747    snow(i)=min(snow(i),snow_max)
3748!
3749    IF (nisurf == is_ter) then
3750      qsol(i) = qsol(i) + bil_eau_s(i)
3751      run_off(i) = run_off(i) + MAX(qsol(i) - max_eau_sol, 0.0)
3752      qsol(i) = MIN(qsol(i), max_eau_sol)
3753    else if (nisurf == is_lic) then
3754      run_off_lic(i) = (coeff_rel *  fqcalving(i)) + &
3755 &                        (1. - coeff_rel) * run_off_lic_0(i)
3756      run_off_lic_0(i) = run_off_lic(i)
3757      run_off_lic(i) = run_off_lic(i) + fqfonte(i)/dtime
3758    endif
3759  enddo
3760
3761  END SUBROUTINE fonte_neige
3762!
3763!#########################################################################
3764!
3765  END MODULE interface_surf
Note: See TracBrowser for help on using the repository browser.