/[lmdze]/trunk/Sources/phylmd/clmain.f
ViewVC logotype

Diff of /trunk/Sources/phylmd/clmain.f

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

trunk/libf/phylmd/clmain.f90 revision 25 by guez, Fri Mar 5 16:43:45 2010 UTC trunk/phylmd/clmain.f revision 99 by guez, Wed Jul 2 18:39:15 2014 UTC
# Line 1  Line 1 
1  SUBROUTINE clmain(dtime, itap, date0, pctsrf, pctsrf_new, t, q, u, v,&  module clmain_m
      jour, rmu0, co2_ppm, ok_veget, ocean, npas, nexca, ts,&  
      soil_model, cdmmax, cdhmax, ksta, ksta_ter, ok_kzmin, ftsoil,&  
      qsol, paprs, pplay, snow, qsurf, evap, albe, alblw, fluxlat,&  
      rain_f, snow_f, solsw, sollw, sollwdown, fder, rlon, rlat, cufi,&  
      cvfi, rugos, debut, lafin, agesno, rugoro, d_t, d_q, d_u, d_v,&  
      d_ts, flux_t, flux_q, flux_u, flux_v, cdragh, cdragm, q2,&  
      dflux_t, dflux_q, zcoefh, zu1, zv1, t2m, q2m, u10m, v10m, pblh,&  
      capcl, oliqcl, cteicl, pblt, therm, trmb1, trmb2, trmb3, plcl,&  
      fqcalving, ffonte, run_off_lic_0, flux_o, flux_g, tslab, seaice)  
   
   ! From phylmd/clmain.F, v 1.6 2005/11/16 14:47:19  
   
   !AA Tout ce qui a trait au traceurs est dans phytrac maintenant  
   !AA pour l'instant le calcul de la couche limite pour les traceurs  
   !AA se fait avec cltrac et ne tient pas compte de la differentiation  
   !AA des sous-fraction de sol.  
   
   !AA Pour pouvoir extraire les coefficient d'echanges et le vent  
   !AA dans la premiere couche, 3 champs supplementaires ont ete crees  
   !AA zcoefh, zu1 et zv1. Pour l'instant nous avons moyenne les valeurs  
   !AA de ces trois champs sur les 4 subsurfaces du modele. Dans l'avenir  
   !AA si les informations des subsurfaces doivent etre prises en compte  
   !AA il faudra sortir ces memes champs en leur ajoutant une dimension,  
   !AA c'est a dire nbsrf (nbre de subsurface).  
   
   ! Auteur(s) Z.X. Li (LMD/CNRS) date: 19930818  
   ! Objet: interface de "couche limite" (diffusion verticale)  
   
   ! Arguments:  
   ! dtime----input-R- interval du temps (secondes)  
   ! itap-----input-I- numero du pas de temps  
   ! date0----input-R- jour initial  
   ! t--------input-R- temperature (K)  
   ! q--------input-R- vapeur d'eau (kg/kg)  
   ! u--------input-R- vitesse u  
   ! v--------input-R- vitesse v  
   ! ts-------input-R- temperature du sol (en Kelvin)  
   ! paprs----input-R- pression a intercouche (Pa)  
   ! pplay----input-R- pression au milieu de couche (Pa)  
   ! radsol---input-R- flux radiatif net (positif vers le sol) en W/m**2  
   ! rlat-----input-R- latitude en degree  
   ! rugos----input-R- longeur de rugosite (en m)  
   ! cufi-----input-R- resolution des mailles en x (m)  
   ! cvfi-----input-R- resolution des mailles en y (m)  
   
   ! d_t------output-R- le changement pour "t"  
   ! d_q------output-R- le changement pour "q"  
   ! d_u------output-R- le changement pour "u"  
   ! d_v------output-R- le changement pour "v"  
   ! d_ts-----output-R- le changement pour "ts"  
   ! flux_t---output-R- flux de chaleur sensible (CpT) J/m**2/s (W/m**2)  
   !                    (orientation positive vers le bas)  
   ! flux_q---output-R- flux de vapeur d'eau (kg/m**2/s)  
   ! flux_u---output-R- tension du vent X: (kg m/s)/(m**2 s) ou Pascal  
   ! flux_v---output-R- tension du vent Y: (kg m/s)/(m**2 s) ou Pascal  
   ! dflux_t derive du flux sensible  
   ! dflux_q derive du flux latent  
   !IM "slab" ocean  
   ! flux_g---output-R-  flux glace (pour OCEAN='slab  ')  
   ! flux_o---output-R-  flux ocean (pour OCEAN='slab  ')  
   ! tslab-in/output-R temperature du slab ocean (en Kelvin) ! uniqmnt pour slab  
   ! seaice---output-R-  glace de mer (kg/m2) (pour OCEAN='slab  ')  
   !cc  
   ! ffonte----Flux thermique utilise pour fondre la neige  
   ! fqcalving-Flux d'eau "perdue" par la surface et necessaire pour limiter la  
   !           hauteur de neige, en kg/m2/s  
   !AA on rajoute en output yu1 et yv1 qui sont les vents dans  
   !AA la premiere couche  
   !AA ces 4 variables sont maintenant traites dans phytrac  
   ! itr--------input-I- nombre de traceurs  
   ! tr---------input-R- q. de traceurs  
   ! flux_surf--input-R- flux de traceurs a la surface  
   ! d_tr-------output-R tendance de traceurs  
   !IM cf. AM : PBL  
   ! trmb1-------deep_cape  
   ! trmb2--------inhibition  
   ! trmb3-------Point Omega  
   ! Cape(klon)-------Cape du thermique  
   ! EauLiq(klon)-------Eau liqu integr du thermique  
   ! ctei(klon)-------Critere d'instab d'entrainmt des nuages de CL  
   ! lcl------- Niveau de condensation  
   ! pblh------- HCL  
   ! pblT------- T au nveau HCL  
   
   !$$$ PB ajout pour soil  
   
   USE ioipsl, ONLY : histbeg_totreg, histdef, histend, histsync, &  
        histwrite, ymds2ju  
   USE dimens_m, ONLY : iim, jjm  
   USE indicesol, ONLY : epsfra, is_lic, is_oce, is_sic, is_ter, nbsrf  
   USE dimphy, ONLY : klev, klon, zmasq  
   USE dimsoil, ONLY : nsoilmx  
   USE temps, ONLY : annee_ref, itau_phy  
   USE dynetat0_m, ONLY : day_ini  
   USE iniprint, ONLY : prt_level  
   USE yomcst, ONLY : rd, rg, rkappa  
   USE conf_phys_m, ONLY : iflag_pbl  
   USE gath_cpl, ONLY : gath2cpl  
2    
3    IMPLICIT NONE    IMPLICIT NONE
4    
5    REAL, INTENT (IN) :: dtime  contains
   REAL date0  
   INTEGER, INTENT (IN) :: itap  
   REAL t(klon, klev), q(klon, klev)  
   REAL u(klon, klev), v(klon, klev)  
   REAL, INTENT (IN) :: paprs(klon, klev+1)  
   REAL, INTENT (IN) :: pplay(klon, klev)  
   REAL, INTENT (IN) :: rlon(klon), rlat(klon)  
   REAL cufi(klon), cvfi(klon)  
   REAL d_t(klon, klev), d_q(klon, klev)  
   REAL d_u(klon, klev), d_v(klon, klev)  
   REAL flux_t(klon, klev, nbsrf), flux_q(klon, klev, nbsrf)  
   REAL dflux_t(klon), dflux_q(klon)  
   !IM "slab" ocean  
   REAL flux_o(klon), flux_g(klon)  
   REAL y_flux_o(klon), y_flux_g(klon)  
   REAL tslab(klon), ytslab(klon)  
   REAL seaice(klon), y_seaice(klon)  
   REAL y_fqcalving(klon), y_ffonte(klon)  
   REAL fqcalving(klon, nbsrf), ffonte(klon, nbsrf)  
   REAL run_off_lic_0(klon), y_run_off_lic_0(klon)  
   
   REAL flux_u(klon, klev, nbsrf), flux_v(klon, klev, nbsrf)  
   REAL rugmer(klon), agesno(klon, nbsrf)  
   REAL, INTENT (IN) :: rugoro(klon)  
   REAL cdragh(klon), cdragm(klon)  
   ! jour de l'annee en cours                  
   INTEGER jour  
   REAL rmu0(klon) ! cosinus de l'angle solaire zenithal      
   ! taux CO2 atmosphere                      
   REAL co2_ppm  
   LOGICAL, INTENT (IN) :: debut  
   LOGICAL, INTENT (IN) :: lafin  
   LOGICAL ok_veget  
   CHARACTER (len=*), INTENT (IN) :: ocean  
   INTEGER npas, nexca  
   
   REAL pctsrf(klon, nbsrf)  
   REAL ts(klon, nbsrf)  
   REAL d_ts(klon, nbsrf)  
   REAL snow(klon, nbsrf)  
   REAL qsurf(klon, nbsrf)  
   REAL evap(klon, nbsrf)  
   REAL albe(klon, nbsrf)  
   REAL alblw(klon, nbsrf)  
   
   REAL fluxlat(klon, nbsrf)  
   
   REAL rain_f(klon), snow_f(klon)  
   REAL fder(klon)  
   
   REAL sollw(klon, nbsrf), solsw(klon, nbsrf), sollwdown(klon)  
   REAL rugos(klon, nbsrf)  
   ! la nouvelle repartition des surfaces sortie de l'interface  
   REAL pctsrf_new(klon, nbsrf)  
   
   REAL zcoefh(klon, klev)  
   REAL zu1(klon)  
   REAL zv1(klon)  
   
   !$$$ PB ajout pour soil  
   LOGICAL, INTENT (IN) :: soil_model  
   !IM ajout seuils cdrm, cdrh  
   REAL cdmmax, cdhmax  
   
   REAL ksta, ksta_ter  
   LOGICAL ok_kzmin  
   
   REAL ftsoil(klon, nsoilmx, nbsrf)  
   REAL ytsoil(klon, nsoilmx)  
   REAL qsol(klon)  
   
   EXTERNAL clqh, clvent, coefkz, calbeta, cltrac  
   
   REAL yts(klon), yrugos(klon), ypct(klon), yz0_new(klon)  
   REAL yalb(klon)  
   REAL yalblw(klon)  
   REAL yu1(klon), yv1(klon)  
   REAL ysnow(klon), yqsurf(klon), yagesno(klon), yqsol(klon)  
   REAL yrain_f(klon), ysnow_f(klon)  
   REAL ysollw(klon), ysolsw(klon), ysollwdown(klon)  
   REAL yfder(klon), ytaux(klon), ytauy(klon)  
   REAL yrugm(klon), yrads(klon), yrugoro(klon)  
   
   REAL yfluxlat(klon)  
   
   REAL y_d_ts(klon)  
   REAL y_d_t(klon, klev), y_d_q(klon, klev)  
   REAL y_d_u(klon, klev), y_d_v(klon, klev)  
   REAL y_flux_t(klon, klev), y_flux_q(klon, klev)  
   REAL y_flux_u(klon, klev), y_flux_v(klon, klev)  
   REAL y_dflux_t(klon), y_dflux_q(klon)  
   REAL ycoefh(klon, klev), ycoefm(klon, klev)  
   REAL yu(klon, klev), yv(klon, klev)  
   REAL yt(klon, klev), yq(klon, klev)  
   REAL ypaprs(klon, klev+1), ypplay(klon, klev), ydelp(klon, klev)  
   
   LOGICAL ok_nonloc  
   PARAMETER (ok_nonloc=.FALSE.)  
   REAL ycoefm0(klon, klev), ycoefh0(klon, klev)  
   
   !IM 081204 hcl_Anne ? BEG  
   REAL yzlay(klon, klev), yzlev(klon, klev+1), yteta(klon, klev)  
   REAL ykmm(klon, klev+1), ykmn(klon, klev+1)  
   REAL ykmq(klon, klev+1)  
   REAL yq2(klon, klev+1), q2(klon, klev+1, nbsrf)  
   REAL q2diag(klon, klev+1)  
   !IM 081204 hcl_Anne ? END  
   
   REAL u1lay(klon), v1lay(klon)  
   REAL delp(klon, klev)  
   INTEGER i, k, nsrf  
   
   INTEGER ni(klon), knon, j  
   ! Introduction d'une variable "pourcentage potentiel" pour tenir compte  
   ! des eventuelles apparitions et/ou disparitions de la glace de mer  
   REAL pctsrf_pot(klon, nbsrf)  
   
   REAL zx_alf1, zx_alf2 !valeur ambiante par extrapola.  
   
   ! maf pour sorties IOISPL en cas de debugagage  
   
   CHARACTER (80) cldebug  
   SAVE cldebug  
   CHARACTER (8) cl_surf(nbsrf)  
   SAVE cl_surf  
   INTEGER nhoridbg, nidbg  
   SAVE nhoridbg, nidbg  
   INTEGER ndexbg(iim*(jjm+1))  
   REAL zx_lon(iim, jjm+1), zx_lat(iim, jjm+1), zjulian  
   REAL tabindx(klon)  
   REAL debugtab(iim, jjm+1)  
   LOGICAL first_appel  
   SAVE first_appel  
   DATA first_appel/ .TRUE./  
   LOGICAL :: debugindex = .FALSE.  
   INTEGER idayref  
   REAL t2m(klon, nbsrf), q2m(klon, nbsrf)  
   REAL u10m(klon, nbsrf), v10m(klon, nbsrf)  
   
   REAL yt2m(klon), yq2m(klon), yu10m(klon)  
   REAL yustar(klon)  
   ! -- LOOP  
   REAL yu10mx(klon)  
   REAL yu10my(klon)  
   REAL ywindsp(klon)  
   ! -- LOOP  
   
   REAL yt10m(klon), yq10m(klon)  
   !IM cf. AM : pbl, hbtm2 (Comme les autres diagnostics on cumule ds  
   ! physiq ce qui permet de sortir les grdeurs par sous surface)  
   REAL pblh(klon, nbsrf)  
   REAL plcl(klon, nbsrf)  
   REAL capcl(klon, nbsrf)  
   REAL oliqcl(klon, nbsrf)  
   REAL cteicl(klon, nbsrf)  
   REAL pblt(klon, nbsrf)  
   REAL therm(klon, nbsrf)  
   REAL trmb1(klon, nbsrf)  
   REAL trmb2(klon, nbsrf)  
   REAL trmb3(klon, nbsrf)  
   REAL ypblh(klon)  
   REAL ylcl(klon)  
   REAL ycapcl(klon)  
   REAL yoliqcl(klon)  
   REAL ycteicl(klon)  
   REAL ypblt(klon)  
   REAL ytherm(klon)  
   REAL ytrmb1(klon)  
   REAL ytrmb2(klon)  
   REAL ytrmb3(klon)  
   REAL y_cd_h(klon), y_cd_m(klon)  
   REAL uzon(klon), vmer(klon)  
   REAL tair1(klon), qair1(klon), tairsol(klon)  
   REAL psfce(klon), patm(klon)  
   
   REAL qairsol(klon), zgeo1(klon)  
   REAL rugo1(klon)  
   
   ! utiliser un jeu de fonctions simples                
   LOGICAL zxli  
   PARAMETER (zxli=.FALSE.)  
   
   REAL zt, zqs, zdelta, zcor  
   REAL t_coup  
   PARAMETER (t_coup=273.15)  
   
   CHARACTER (len=20) :: modname = 'clmain'  
   LOGICAL check  
   PARAMETER (check=.FALSE.)  
   
   !------------------------------------------------------------  
   
   ! initialisation Anne  
   ytherm = 0.  
   
   IF (check) THEN  
      PRINT *, modname, '  klon=', klon  
   END IF  
   
   IF (debugindex .AND. first_appel) THEN  
      first_appel = .FALSE.  
   
      ! initialisation sorties netcdf  
   
      idayref = day_ini  
      CALL ymds2ju(annee_ref, 1, idayref, 0.0, zjulian)  
      CALL gr_fi_ecrit(1, klon, iim, jjm+1, rlon, zx_lon)  
      DO i = 1, iim  
         zx_lon(i, 1) = rlon(i+1)  
         zx_lon(i, jjm+1) = rlon(i+1)  
      END DO  
      CALL gr_fi_ecrit(1, klon, iim, jjm+1, rlat, zx_lat)  
      cldebug = 'sous_index'  
      CALL histbeg_totreg(cldebug, zx_lon(:, 1), zx_lat(1, :), 1, &  
           iim, 1, jjm+1, itau_phy, zjulian, dtime, nhoridbg, nidbg)  
      ! no vertical axis  
      cl_surf(1) = 'ter'  
      cl_surf(2) = 'lic'  
      cl_surf(3) = 'oce'  
      cl_surf(4) = 'sic'  
      DO nsrf = 1, nbsrf  
         CALL histdef(nidbg, cl_surf(nsrf), cl_surf(nsrf), '-', iim, jjm+1, &  
              nhoridbg, 1, 1, 1, -99, 'inst', dtime, dtime)  
      END DO  
      CALL histend(nidbg)  
      CALL histsync(nidbg)  
   END IF  
   
   DO k = 1, klev ! epaisseur de couche  
      DO i = 1, klon  
         delp(i, k) = paprs(i, k) - paprs(i, k+1)  
      END DO  
   END DO  
   DO i = 1, klon ! vent de la premiere couche  
      zx_alf1 = 1.0  
      zx_alf2 = 1.0 - zx_alf1  
      u1lay(i) = u(i, 1)*zx_alf1 + u(i, 2)*zx_alf2  
      v1lay(i) = v(i, 1)*zx_alf1 + v(i, 2)*zx_alf2  
   END DO  
   
   ! initialisation:  
   
   DO i = 1, klon  
      rugmer(i) = 0.0  
      cdragh(i) = 0.0  
      cdragm(i) = 0.0  
      dflux_t(i) = 0.0  
      dflux_q(i) = 0.0  
      zu1(i) = 0.0  
      zv1(i) = 0.0  
   END DO  
   ypct = 0.0  
   yts = 0.0  
   ysnow = 0.0  
   yqsurf = 0.0  
   yalb = 0.0  
   yalblw = 0.0  
   yrain_f = 0.0  
   ysnow_f = 0.0  
   yfder = 0.0  
   ytaux = 0.0  
   ytauy = 0.0  
   ysolsw = 0.0  
   ysollw = 0.0  
   ysollwdown = 0.0  
   yrugos = 0.0  
   yu1 = 0.0  
   yv1 = 0.0  
   yrads = 0.0  
   ypaprs = 0.0  
   ypplay = 0.0  
   ydelp = 0.0  
   yu = 0.0  
   yv = 0.0  
   yt = 0.0  
   yq = 0.0  
   pctsrf_new = 0.0  
   y_flux_u = 0.0  
   y_flux_v = 0.0  
   !$$ PB  
   y_dflux_t = 0.0  
   y_dflux_q = 0.0  
   ytsoil = 999999.  
   yrugoro = 0.  
   ! -- LOOP  
   yu10mx = 0.0  
   yu10my = 0.0  
   ywindsp = 0.0  
   ! -- LOOP  
   DO nsrf = 1, nbsrf  
      DO i = 1, klon  
         d_ts(i, nsrf) = 0.0  
      END DO  
   END DO  
   !§§§ PB  
   yfluxlat = 0.  
   flux_t = 0.  
   flux_q = 0.  
   flux_u = 0.  
   flux_v = 0.  
   DO k = 1, klev  
      DO i = 1, klon  
         d_t(i, k) = 0.0  
         d_q(i, k) = 0.0  
         !$$$         flux_t(i, k) = 0.0  
         !$$$         flux_q(i, k) = 0.0  
         d_u(i, k) = 0.0  
         d_v(i, k) = 0.0  
         !$$$         flux_u(i, k) = 0.0  
         !$$$         flux_v(i, k) = 0.0  
         zcoefh(i, k) = 0.0  
      END DO  
   END DO  
   !AA      IF (itr.GE.1) THEN  
   !AA      DO it = 1, itr  
   !AA      DO k = 1, klev  
   !AA      DO i = 1, klon  
   !AA         d_tr(i, k, it) = 0.0  
   !AA      ENDDO  
   !AA      ENDDO  
   !AA      ENDDO  
   !AA      ENDIF  
   
   
   ! Boucler sur toutes les sous-fractions du sol:  
   
   ! Initialisation des "pourcentages potentiels". On considere ici qu'on  
   ! peut avoir potentiellementdela glace sur tout le domaine oceanique  
   ! (a affiner)  
   
   pctsrf_pot = pctsrf  
   pctsrf_pot(:, is_oce) = 1. - zmasq  
   pctsrf_pot(:, is_sic) = 1. - zmasq  
   
   DO nsrf = 1, nbsrf  
      ! chercher les indices:  
      ni = 0  
      knon = 0  
      DO i = 1, klon  
         ! pour determiner le domaine a traiter on utilise les surfaces  
         ! "potentielles"  
         IF (pctsrf_pot(i, nsrf) > epsfra) THEN  
            knon = knon + 1  
            ni(knon) = i  
         END IF  
      END DO  
   
      IF (check) THEN  
         PRINT *, 'CLMAIN, nsrf, knon =', nsrf, knon  
      END IF  
   
      ! variables pour avoir une sortie IOIPSL des INDEX  
      IF (debugindex) THEN  
         tabindx = 0.  
         DO i = 1, knon  
            tabindx(i) = real(i)  
         END DO  
         debugtab = 0.  
         ndexbg = 0  
         CALL gath2cpl(tabindx, debugtab, klon, knon, iim, jjm, ni)  
         CALL histwrite(nidbg, cl_surf(nsrf), itap, debugtab)  
      END IF  
   
      IF (knon==0) CYCLE  
   
      DO j = 1, knon  
         i = ni(j)  
         ypct(j) = pctsrf(i, nsrf)  
         yts(j) = ts(i, nsrf)  
         ytslab(i) = tslab(i)  
         ysnow(j) = snow(i, nsrf)  
         yqsurf(j) = qsurf(i, nsrf)  
         yalb(j) = albe(i, nsrf)  
         yalblw(j) = alblw(i, nsrf)  
         yrain_f(j) = rain_f(i)  
         ysnow_f(j) = snow_f(i)  
         yagesno(j) = agesno(i, nsrf)  
         yfder(j) = fder(i)  
         ytaux(j) = flux_u(i, 1, nsrf)  
         ytauy(j) = flux_v(i, 1, nsrf)  
         ysolsw(j) = solsw(i, nsrf)  
         ysollw(j) = sollw(i, nsrf)  
         ysollwdown(j) = sollwdown(i)  
         yrugos(j) = rugos(i, nsrf)  
         yrugoro(j) = rugoro(i)  
         yu1(j) = u1lay(i)  
         yv1(j) = v1lay(i)  
         yrads(j) = ysolsw(j) + ysollw(j)  
         ypaprs(j, klev+1) = paprs(i, klev+1)  
         y_run_off_lic_0(j) = run_off_lic_0(i)  
         yu10mx(j) = u10m(i, nsrf)  
         yu10my(j) = v10m(i, nsrf)  
         ywindsp(j) = sqrt(yu10mx(j)*yu10mx(j)+yu10my(j)*yu10my(j))  
      END DO  
   
      !     IF bucket model for continent, copy soil water content  
      IF (nsrf==is_ter .AND. .NOT. ok_veget) THEN  
         DO j = 1, knon  
            i = ni(j)  
            yqsol(j) = qsol(i)  
         END DO  
      ELSE  
         yqsol = 0.  
      END IF  
      !$$$ PB ajour pour soil  
      DO k = 1, nsoilmx  
         DO j = 1, knon  
            i = ni(j)  
            ytsoil(j, k) = ftsoil(i, k, nsrf)  
         END DO  
      END DO  
      DO k = 1, klev  
         DO j = 1, knon  
            i = ni(j)  
            ypaprs(j, k) = paprs(i, k)  
            ypplay(j, k) = pplay(i, k)  
            ydelp(j, k) = delp(i, k)  
            yu(j, k) = u(i, k)  
            yv(j, k) = v(i, k)  
            yt(j, k) = t(i, k)  
            yq(j, k) = q(i, k)  
         END DO  
      END DO  
   
      ! calculer Cdrag et les coefficients d'echange  
      CALL coefkz(nsrf, knon, ypaprs, ypplay, ksta, ksta_ter, yts,&  
           yrugos, yu, yv, yt, yq, yqsurf, ycoefm, ycoefh)  
      !IM 081204 BEG  
      !CR test  
      IF (iflag_pbl==1) THEN  
         !IM 081204 END  
         CALL coefkz2(nsrf, knon, ypaprs, ypplay, yt, ycoefm0, ycoefh0)  
         DO k = 1, klev  
            DO i = 1, knon  
               ycoefm(i, k) = max(ycoefm(i, k), ycoefm0(i, k))  
               ycoefh(i, k) = max(ycoefh(i, k), ycoefh0(i, k))  
            END DO  
         END DO  
      END IF  
   
      !IM cf JLD : on seuille ycoefm et ycoefh  
      IF (nsrf==is_oce) THEN  
         DO j = 1, knon  
            !           ycoefm(j, 1)=min(ycoefm(j, 1), 1.1E-3)  
            ycoefm(j, 1) = min(ycoefm(j, 1), cdmmax)  
            !           ycoefh(j, 1)=min(ycoefh(j, 1), 1.1E-3)  
            ycoefh(j, 1) = min(ycoefh(j, 1), cdhmax)  
         END DO  
      END IF  
   
   
      !IM: 261103  
      IF (ok_kzmin) THEN  
         !IM cf FH: 201103 BEG  
         !   Calcul d'une diffusion minimale pour les conditions tres stables.  
         CALL coefkzmin(knon, ypaprs, ypplay, yu, yv, yt, yq, ycoefm, ycoefm0, &  
              ycoefh0)  
         !      call dump2d(iim, jjm-1, ycoefm(2:klon-1, 2), 'KZ         ')  
         !      call dump2d(iim, jjm-1, ycoefm0(2:klon-1, 2), 'KZMIN      ')  
   
         IF (1==1) THEN  
            DO k = 1, klev  
               DO i = 1, knon  
                  ycoefm(i, k) = max(ycoefm(i, k), ycoefm0(i, k))  
                  ycoefh(i, k) = max(ycoefh(i, k), ycoefh0(i, k))  
               END DO  
            END DO  
         END IF  
         !IM cf FH: 201103 END  
         !IM: 261103  
      END IF !ok_kzmin  
   
      IF (iflag_pbl>=3) THEN  
   
         !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc  
         ! MELLOR ET YAMADA adapte a Mars Richard Fournier et Frederic Hourdin  
         !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc  
   
         yzlay(1:knon, 1) = rd*yt(1:knon, 1)/(0.5*(ypaprs(1:knon, &  
              1)+ypplay(1:knon, 1)))*(ypaprs(1:knon, 1)-ypplay(1:knon, 1))/rg  
         DO k = 2, klev  
            yzlay(1:knon, k) = yzlay(1:knon, k-1) &  
                 + rd*0.5*(yt(1:knon, k-1) +yt(1: knon, k)) &  
                 / ypaprs(1:knon, k) *(ypplay(1:knon, k-1)-ypplay(1:knon, k))/ &  
                 rg  
         END DO  
         DO k = 1, klev  
            yteta(1:knon, k) = yt(1:knon, k)*(ypaprs(1:knon, 1) &  
                 / ypplay(1:knon, k))**rkappa * (1.+0.61*yq(1:knon, k))  
         END DO  
         yzlev(1:knon, 1) = 0.  
         yzlev(1:knon, klev+1) = 2.*yzlay(1:knon, klev) - yzlay(1:knon, klev-1)  
         DO k = 2, klev  
            yzlev(1:knon, k) = 0.5*(yzlay(1:knon, k)+yzlay(1:knon, k-1))  
         END DO  
         DO k = 1, klev + 1  
            DO j = 1, knon  
               i = ni(j)  
               yq2(j, k) = q2(i, k, nsrf)  
            END DO  
         END DO  
   
   
         !   Bug introduit volontairement pour converger avec les resultats  
         !  du papier sur les thermiques.  
         IF (1==1) THEN  
            y_cd_m(1:knon) = ycoefm(1:knon, 1)  
            y_cd_h(1:knon) = ycoefh(1:knon, 1)  
         ELSE  
            y_cd_h(1:knon) = ycoefm(1:knon, 1)  
            y_cd_m(1:knon) = ycoefh(1:knon, 1)  
         END IF  
         CALL ustarhb(knon, yu, yv, y_cd_m, yustar)  
   
         IF (prt_level>9) THEN  
            PRINT *, 'USTAR = ', yustar  
         END IF  
   
         !   iflag_pbl peut etre utilise comme longuer de melange  
   
         IF (iflag_pbl>=11) THEN  
            CALL vdif_kcay(knon, dtime, rg, rd, ypaprs, yt, yzlev, yzlay, yu, yv, yteta, &  
                 y_cd_m, yq2, q2diag, ykmm, ykmn, yustar, iflag_pbl)  
         ELSE  
            CALL yamada4(knon, dtime, rg, rd, ypaprs, yt, yzlev, yzlay, yu, yv, yteta, &  
                 y_cd_m, yq2, ykmm, ykmn, ykmq, yustar, iflag_pbl)  
         END IF  
   
         ycoefm(1:knon, 1) = y_cd_m(1:knon)  
         ycoefh(1:knon, 1) = y_cd_h(1:knon)  
         ycoefm(1:knon, 2:klev) = ykmm(1:knon, 2:klev)  
         ycoefh(1:knon, 2:klev) = ykmn(1:knon, 2:klev)  
   
   
      END IF  
   
      !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc  
      ! calculer la diffusion des vitesses "u" et "v"  
      !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc  
   
      CALL clvent(knon, dtime, yu1, yv1, ycoefm, yt, yu, ypaprs, ypplay, &  
           ydelp, y_d_u, y_flux_u)  
      CALL clvent(knon, dtime, yu1, yv1, ycoefm, yt, yv, ypaprs, ypplay, &  
           ydelp, y_d_v, y_flux_v)  
   
      ! pour le couplage  
      ytaux = y_flux_u(:, 1)  
      ytauy = y_flux_v(:, 1)  
   
      ! FH modif sur le cdrag temperature  
      !$$$PB : déplace dans clcdrag  
      !$$$      do i=1, knon  
      !$$$         ycoefh(i, 1)=ycoefm(i, 1)*0.8  
      !$$$      enddo  
   
      ! calculer la diffusion de "q" et de "h"  
      CALL clqh(dtime, itap, date0, jour, debut, lafin, rlon, rlat,&  
           cufi, cvfi, knon, nsrf, ni, pctsrf, soil_model, ytsoil,&  
           yqsol, ok_veget, ocean, npas, nexca, rmu0, co2_ppm, yrugos,&  
           yrugoro, yu1, yv1, ycoefh, yt, yq, yts, ypaprs, ypplay,&  
           ydelp, yrads, yalb, yalblw, ysnow, yqsurf, yrain_f, ysnow_f, &  
           yfder, ytaux, ytauy, ywindsp, ysollw, ysollwdown, ysolsw,&  
           yfluxlat, pctsrf_new, yagesno, y_d_t, y_d_q, y_d_ts,&  
           yz0_new, y_flux_t, y_flux_q, y_dflux_t, y_dflux_q,&  
           y_fqcalving, y_ffonte, y_run_off_lic_0, y_flux_o, y_flux_g,&  
           ytslab, y_seaice)  
   
      ! calculer la longueur de rugosite sur ocean  
      yrugm = 0.  
      IF (nsrf==is_oce) THEN  
         DO j = 1, knon  
            yrugm(j) = 0.018*ycoefm(j, 1)*(yu1(j)**2+yv1(j)**2)/rg + &  
                 0.11*14E-6/sqrt(ycoefm(j, 1)*(yu1(j)**2+yv1(j)**2))  
            yrugm(j) = max(1.5E-05, yrugm(j))  
         END DO  
      END IF  
      DO j = 1, knon  
         y_dflux_t(j) = y_dflux_t(j)*ypct(j)  
         y_dflux_q(j) = y_dflux_q(j)*ypct(j)  
         yu1(j) = yu1(j)*ypct(j)  
         yv1(j) = yv1(j)*ypct(j)  
      END DO  
   
      DO k = 1, klev  
         DO j = 1, knon  
            i = ni(j)  
            ycoefh(j, k) = ycoefh(j, k)*ypct(j)  
            ycoefm(j, k) = ycoefm(j, k)*ypct(j)  
            y_d_t(j, k) = y_d_t(j, k)*ypct(j)  
            y_d_q(j, k) = y_d_q(j, k)*ypct(j)  
            !§§§ PB  
            flux_t(i, k, nsrf) = y_flux_t(j, k)  
            flux_q(i, k, nsrf) = y_flux_q(j, k)  
            flux_u(i, k, nsrf) = y_flux_u(j, k)  
            flux_v(i, k, nsrf) = y_flux_v(j, k)  
            !$$$ PB        y_flux_t(j, k) = y_flux_t(j, k) * ypct(j)  
            !$$$ PB        y_flux_q(j, k) = y_flux_q(j, k) * ypct(j)  
            y_d_u(j, k) = y_d_u(j, k)*ypct(j)  
            y_d_v(j, k) = y_d_v(j, k)*ypct(j)  
            !$$$ PB        y_flux_u(j, k) = y_flux_u(j, k) * ypct(j)  
            !$$$ PB        y_flux_v(j, k) = y_flux_v(j, k) * ypct(j)  
         END DO  
      END DO  
   
   
      evap(:, nsrf) = -flux_q(:, 1, nsrf)  
   
      albe(:, nsrf) = 0.  
      alblw(:, nsrf) = 0.  
      snow(:, nsrf) = 0.  
      qsurf(:, nsrf) = 0.  
      rugos(:, nsrf) = 0.  
      fluxlat(:, nsrf) = 0.  
      DO j = 1, knon  
         i = ni(j)  
         d_ts(i, nsrf) = y_d_ts(j)  
         albe(i, nsrf) = yalb(j)  
         alblw(i, nsrf) = yalblw(j)  
         snow(i, nsrf) = ysnow(j)  
         qsurf(i, nsrf) = yqsurf(j)  
         rugos(i, nsrf) = yz0_new(j)  
         fluxlat(i, nsrf) = yfluxlat(j)  
         !$$$ pb         rugmer(i) = yrugm(j)  
         IF (nsrf==is_oce) THEN  
            rugmer(i) = yrugm(j)  
            rugos(i, nsrf) = yrugm(j)  
         END IF  
         !IM cf JLD ??  
         agesno(i, nsrf) = yagesno(j)  
         fqcalving(i, nsrf) = y_fqcalving(j)  
         ffonte(i, nsrf) = y_ffonte(j)  
         cdragh(i) = cdragh(i) + ycoefh(j, 1)  
         cdragm(i) = cdragm(i) + ycoefm(j, 1)  
         dflux_t(i) = dflux_t(i) + y_dflux_t(j)  
         dflux_q(i) = dflux_q(i) + y_dflux_q(j)  
         zu1(i) = zu1(i) + yu1(j)  
         zv1(i) = zv1(i) + yv1(j)  
      END DO  
      IF (nsrf==is_ter) THEN  
         DO j = 1, knon  
            i = ni(j)  
            qsol(i) = yqsol(j)  
         END DO  
      END IF  
      IF (nsrf==is_lic) THEN  
         DO j = 1, knon  
            i = ni(j)  
            run_off_lic_0(i) = y_run_off_lic_0(j)  
         END DO  
      END IF  
      !$$$ PB ajout pour soil  
      ftsoil(:, :, nsrf) = 0.  
      DO k = 1, nsoilmx  
         DO j = 1, knon  
            i = ni(j)  
            ftsoil(i, k, nsrf) = ytsoil(j, k)  
         END DO  
      END DO  
   
      DO j = 1, knon  
         i = ni(j)  
         DO k = 1, klev  
            d_t(i, k) = d_t(i, k) + y_d_t(j, k)  
            d_q(i, k) = d_q(i, k) + y_d_q(j, k)  
            !$$$ PB        flux_t(i, k) = flux_t(i, k) + y_flux_t(j, k)  
            !$$$         flux_q(i, k) = flux_q(i, k) + y_flux_q(j, k)  
            d_u(i, k) = d_u(i, k) + y_d_u(j, k)  
            d_v(i, k) = d_v(i, k) + y_d_v(j, k)  
            !$$$  PB       flux_u(i, k) = flux_u(i, k) + y_flux_u(j, k)  
            !$$$         flux_v(i, k) = flux_v(i, k) + y_flux_v(j, k)  
            zcoefh(i, k) = zcoefh(i, k) + ycoefh(j, k)  
         END DO  
      END DO  
   
   
      !cc diagnostic t, q a 2m et u, v a 10m  
   
      DO j = 1, knon  
         i = ni(j)  
         uzon(j) = yu(j, 1) + y_d_u(j, 1)  
         vmer(j) = yv(j, 1) + y_d_v(j, 1)  
         tair1(j) = yt(j, 1) + y_d_t(j, 1)  
         qair1(j) = yq(j, 1) + y_d_q(j, 1)  
         zgeo1(j) = rd*tair1(j)/(0.5*(ypaprs(j, 1)+ypplay(j, &  
              1)))*(ypaprs(j, 1)-ypplay(j, 1))  
         tairsol(j) = yts(j) + y_d_ts(j)  
         rugo1(j) = yrugos(j)  
         IF (nsrf==is_oce) THEN  
            rugo1(j) = rugos(i, nsrf)  
         END IF  
         psfce(j) = ypaprs(j, 1)  
         patm(j) = ypplay(j, 1)  
   
         qairsol(j) = yqsurf(j)  
      END DO  
   
      CALL stdlevvar(klon, knon, nsrf, zxli, uzon, vmer, tair1, qair1, zgeo1, &  
           tairsol, qairsol, rugo1, psfce, patm, yt2m, yq2m, yt10m, yq10m, &  
           yu10m, yustar)  
      !IM 081204 END  
   
      DO j = 1, knon  
         i = ni(j)  
         t2m(i, nsrf) = yt2m(j)  
         q2m(i, nsrf) = yq2m(j)  
   
         ! u10m, v10m : composantes du vent a 10m sans spirale de Ekman  
         u10m(i, nsrf) = (yu10m(j)*uzon(j))/sqrt(uzon(j)**2+vmer(j)**2)  
         v10m(i, nsrf) = (yu10m(j)*vmer(j))/sqrt(uzon(j)**2+vmer(j)**2)  
   
      END DO  
   
      !IM cf AM : pbl, HBTM  
      DO i = 1, knon  
         y_cd_h(i) = ycoefh(i, 1)  
         y_cd_m(i) = ycoefm(i, 1)  
      END DO  
      !     print*, 'appel hbtm2'  
      CALL hbtm(knon, ypaprs, ypplay, yt2m, yt10m, yq2m, yq10m, yustar, y_flux_t, &  
           y_flux_q, yu, yv, yt, yq, ypblh, ycapcl, yoliqcl, ycteicl, ypblt, ytherm, &  
           ytrmb1, ytrmb2, ytrmb3, ylcl)  
      !     print*, 'fin hbtm2'  
   
      DO j = 1, knon  
         i = ni(j)  
         pblh(i, nsrf) = ypblh(j)  
         plcl(i, nsrf) = ylcl(j)  
         capcl(i, nsrf) = ycapcl(j)  
         oliqcl(i, nsrf) = yoliqcl(j)  
         cteicl(i, nsrf) = ycteicl(j)  
         pblt(i, nsrf) = ypblt(j)  
         therm(i, nsrf) = ytherm(j)  
         trmb1(i, nsrf) = ytrmb1(j)  
         trmb2(i, nsrf) = ytrmb2(j)  
         trmb3(i, nsrf) = ytrmb3(j)  
      END DO  
   
   
      DO j = 1, knon  
         DO k = 1, klev + 1  
            i = ni(j)  
            q2(i, k, nsrf) = yq2(j, k)  
         END DO  
      END DO  
      !IM "slab" ocean  
      IF (nsrf==is_oce) THEN  
         DO j = 1, knon  
            ! on projette sur la grille globale  
            i = ni(j)  
            IF (pctsrf_new(i, is_oce)>epsfra) THEN  
               flux_o(i) = y_flux_o(j)  
            ELSE  
               flux_o(i) = 0.  
            END IF  
         END DO  
      END IF  
   
      IF (nsrf==is_sic) THEN  
         DO j = 1, knon  
            i = ni(j)  
            !IM 230604 on pondere lorsque l'on fait le bilan au sol :  flux_g(i) = y_flux_g(j)*ypct(j)  
            IF (pctsrf_new(i, is_sic)>epsfra) THEN  
               flux_g(i) = y_flux_g(j)  
            ELSE  
               flux_g(i) = 0.  
            END IF  
         END DO  
   
      END IF  
      !nsrf.EQ.is_sic                                              
      IF (ocean=='slab  ') THEN  
         IF (nsrf==is_oce) THEN  
            tslab(1:klon) = ytslab(1:klon)  
            seaice(1:klon) = y_seaice(1:klon)  
            !nsrf                                                        
         END IF  
         !OCEAN                                                        
      END IF  
   END DO  
6    
7    ! On utilise les nouvelles surfaces    SUBROUTINE clmain(dtime, itap, pctsrf, pctsrf_new, t, q, u, v, jour, rmu0, &
8    ! A rajouter: conservation de l'albedo         co2_ppm, ts, soil_model, cdmmax, cdhmax, ksta, ksta_ter, &
9           ok_kzmin, ftsoil, qsol, paprs, pplay, snow, qsurf, evap, albe, alblw, &
10           fluxlat, rain_fall, snow_f, solsw, sollw, fder, rlat, rugos, debut, &
11           agesno, rugoro, d_t, d_q, d_u, d_v, d_ts, flux_t, flux_q, flux_u, &
12           flux_v, cdragh, cdragm, q2, dflux_t, dflux_q, ycoefh, zu1, zv1, t2m, &
13           q2m, u10m, v10m, pblh, capcl, oliqcl, cteicl, pblt, therm, trmb1, &
14           trmb2, trmb3, plcl, fqcalving, ffonte, run_off_lic_0, flux_o, flux_g, &
15           tslab, seaice)
16    
17        ! From phylmd/clmain.F, version 1.6, 2005/11/16 14:47:19
18        ! Author: Z. X. Li (LMD/CNRS), date: 1993/08/18
19        ! Objet : interface de couche limite (diffusion verticale)
20    
21        ! Tout ce qui a trait aux traceurs est dans "phytrac". Le calcul
22        ! de la couche limite pour les traceurs se fait avec "cltrac" et
23        ! ne tient pas compte de la différentiation des sous-fractions de
24        ! sol.
25    
26        ! Pour pouvoir extraire les coefficients d'échanges et le vent
27        ! dans la première couche, trois champs ont été créés : "ycoefh",
28        ! "zu1" et "zv1". Nous avons moyenné les valeurs de ces trois
29        ! champs sur les quatre sous-surfaces du modèle.
30    
31        use clqh_m, only: clqh
32        use clvent_m, only: clvent
33        use coefkz_m, only: coefkz
34        use coefkzmin_m, only: coefkzmin
35        USE conf_gcm_m, ONLY: prt_level
36        USE conf_phys_m, ONLY: iflag_pbl
37        USE dimens_m, ONLY: iim, jjm
38        USE dimphy, ONLY: klev, klon, zmasq
39        USE dimsoil, ONLY: nsoilmx
40        use hbtm_m, only: hbtm
41        USE indicesol, ONLY: epsfra, is_lic, is_oce, is_sic, is_ter, nbsrf
42        USE suphec_m, ONLY: rd, rg, rkappa
43        use ustarhb_m, only: ustarhb
44        use vdif_kcay_m, only: vdif_kcay
45        use yamada4_m, only: yamada4
46    
47        REAL, INTENT(IN):: dtime ! interval du temps (secondes)
48        INTEGER, INTENT(IN):: itap ! numero du pas de temps
49        REAL, INTENT(inout):: pctsrf(klon, nbsrf)
50    
51        ! la nouvelle repartition des surfaces sortie de l'interface
52        REAL, INTENT(out):: pctsrf_new(klon, nbsrf)
53    
54        REAL, INTENT(IN):: t(klon, klev) ! temperature (K)
55        REAL, INTENT(IN):: q(klon, klev) ! vapeur d'eau (kg/kg)
56        REAL, INTENT(IN):: u(klon, klev), v(klon, klev) ! vitesse
57        INTEGER, INTENT(IN):: jour ! jour de l'annee en cours
58        REAL, intent(in):: rmu0(klon) ! cosinus de l'angle solaire zenithal    
59        REAL, intent(in):: co2_ppm ! taux CO2 atmosphere
60        REAL, INTENT(IN):: ts(klon, nbsrf) ! input-R- temperature du sol (en Kelvin)
61        LOGICAL, INTENT(IN):: soil_model
62        REAL, INTENT(IN):: cdmmax, cdhmax ! seuils cdrm, cdrh
63        REAL, INTENT(IN):: ksta, ksta_ter
64        LOGICAL, INTENT(IN):: ok_kzmin
65        REAL ftsoil(klon, nsoilmx, nbsrf)
66        REAL, INTENT(inout):: qsol(klon)
67        REAL, INTENT(IN):: paprs(klon, klev+1) ! pression a intercouche (Pa)
68        REAL, INTENT(IN):: pplay(klon, klev) ! pression au milieu de couche (Pa)
69        REAL snow(klon, nbsrf)
70        REAL qsurf(klon, nbsrf)
71        REAL evap(klon, nbsrf)
72        REAL albe(klon, nbsrf)
73        REAL alblw(klon, nbsrf)
74    
75        REAL fluxlat(klon, nbsrf)
76    
77        REAL, intent(in):: rain_fall(klon), snow_f(klon)
78        REAL, INTENT(IN):: solsw(klon, nbsrf), sollw(klon, nbsrf)
79        REAL fder(klon)
80        REAL, INTENT(IN):: rlat(klon) ! latitude en degrés
81    
82        REAL rugos(klon, nbsrf)
83        ! rugos----input-R- longeur de rugosite (en m)
84    
85        LOGICAL, INTENT(IN):: debut
86        real agesno(klon, nbsrf)
87        REAL, INTENT(IN):: rugoro(klon)
88    
89        REAL d_t(klon, klev), d_q(klon, klev)
90        ! d_t------output-R- le changement pour "t"
91        ! d_q------output-R- le changement pour "q"
92    
93        REAL, intent(out):: d_u(klon, klev), d_v(klon, klev)
94        ! changement pour "u" et "v"
95    
96        REAL d_ts(klon, nbsrf)
97        ! d_ts-----output-R- le changement pour "ts"
98    
99        REAL flux_t(klon, klev, nbsrf), flux_q(klon, klev, nbsrf)
100        ! flux_t---output-R- flux de chaleur sensible (CpT) J/m**2/s (W/m**2)
101        !                    (orientation positive vers le bas)
102        ! flux_q---output-R- flux de vapeur d'eau (kg/m**2/s)
103    
104        REAL flux_u(klon, klev, nbsrf), flux_v(klon, klev, nbsrf)
105        ! flux_u---output-R- tension du vent X: (kg m/s)/(m**2 s) ou Pascal
106        ! flux_v---output-R- tension du vent Y: (kg m/s)/(m**2 s) ou Pascal
107    
108        REAL, INTENT(out):: cdragh(klon), cdragm(klon)
109        real q2(klon, klev+1, nbsrf)
110    
111        REAL, INTENT(out):: dflux_t(klon), dflux_q(klon)
112        ! dflux_t derive du flux sensible
113        ! dflux_q derive du flux latent
114        !IM "slab" ocean
115    
116        REAL, intent(out):: ycoefh(klon, klev)
117        REAL, intent(out):: zu1(klon)
118        REAL zv1(klon)
119        REAL t2m(klon, nbsrf), q2m(klon, nbsrf)
120        REAL u10m(klon, nbsrf), v10m(klon, nbsrf)
121    
122        !IM cf. AM : pbl, hbtm (Comme les autres diagnostics on cumule ds
123        ! physiq ce qui permet de sortir les grdeurs par sous surface)
124        REAL pblh(klon, nbsrf)
125        ! pblh------- HCL
126        REAL capcl(klon, nbsrf)
127        REAL oliqcl(klon, nbsrf)
128        REAL cteicl(klon, nbsrf)
129        REAL pblt(klon, nbsrf)
130        ! pblT------- T au nveau HCL
131        REAL therm(klon, nbsrf)
132        REAL trmb1(klon, nbsrf)
133        ! trmb1-------deep_cape
134        REAL trmb2(klon, nbsrf)
135        ! trmb2--------inhibition
136        REAL trmb3(klon, nbsrf)
137        ! trmb3-------Point Omega
138        REAL plcl(klon, nbsrf)
139        REAL fqcalving(klon, nbsrf), ffonte(klon, nbsrf)
140        ! ffonte----Flux thermique utilise pour fondre la neige
141        ! fqcalving-Flux d'eau "perdue" par la surface et necessaire pour limiter la
142        !           hauteur de neige, en kg/m2/s
143        REAL run_off_lic_0(klon)
144    
145        REAL flux_o(klon), flux_g(klon)
146        !IM "slab" ocean
147        ! flux_g---output-R-  flux glace (pour OCEAN='slab  ')
148        ! flux_o---output-R-  flux ocean (pour OCEAN='slab  ')
149    
150        REAL tslab(klon)
151        ! tslab-in/output-R temperature du slab ocean (en Kelvin)
152        ! uniqmnt pour slab
153    
154        REAL seaice(klon)
155        ! seaice---output-R-  glace de mer (kg/m2) (pour OCEAN='slab  ')
156    
157        ! Local:
158    
159        REAL y_flux_o(klon), y_flux_g(klon)
160        real ytslab(klon)
161        real y_seaice(klon)
162        REAL y_fqcalving(klon), y_ffonte(klon)
163        real y_run_off_lic_0(klon)
164    
165        REAL rugmer(klon)
166    
167        REAL ytsoil(klon, nsoilmx)
168    
169        REAL yts(klon), yrugos(klon), ypct(klon), yz0_new(klon)
170        REAL yalb(klon)
171        REAL yalblw(klon)
172        REAL yu1(klon), yv1(klon)
173        ! on rajoute en output yu1 et yv1 qui sont les vents dans
174        ! la premiere couche
175        REAL ysnow(klon), yqsurf(klon), yagesno(klon), yqsol(klon)
176        REAL yrain_f(klon), ysnow_f(klon)
177        REAL ysollw(klon), ysolsw(klon)
178        REAL yfder(klon)
179        REAL yrugm(klon), yrads(klon), yrugoro(klon)
180    
181        REAL yfluxlat(klon)
182    
183        REAL y_d_ts(klon)
184        REAL y_d_t(klon, klev), y_d_q(klon, klev)
185        REAL y_d_u(klon, klev), y_d_v(klon, klev)
186        REAL y_flux_t(klon, klev), y_flux_q(klon, klev)
187        REAL y_flux_u(klon, klev), y_flux_v(klon, klev)
188        REAL y_dflux_t(klon), y_dflux_q(klon)
189        REAL coefh(klon, klev), coefm(klon, klev)
190        REAL yu(klon, klev), yv(klon, klev)
191        REAL yt(klon, klev), yq(klon, klev)
192        REAL ypaprs(klon, klev+1), ypplay(klon, klev), ydelp(klon, klev)
193    
194        REAL ycoefm0(klon, klev), ycoefh0(klon, klev)
195    
196        REAL yzlay(klon, klev), yzlev(klon, klev+1), yteta(klon, klev)
197        REAL ykmm(klon, klev+1), ykmn(klon, klev+1)
198        REAL ykmq(klon, klev+1)
199        REAL yq2(klon, klev+1)
200        REAL q2diag(klon, klev+1)
201    
202        REAL u1lay(klon), v1lay(klon)
203        REAL delp(klon, klev)
204        INTEGER i, k, nsrf
205    
206        INTEGER ni(klon), knon, j
207    
208        REAL pctsrf_pot(klon, nbsrf)
209        ! "pourcentage potentiel" pour tenir compte des éventuelles
210        ! apparitions ou disparitions de la glace de mer
211    
212        REAL zx_alf1, zx_alf2 !valeur ambiante par extrapola.
213    
214        REAL yt2m(klon), yq2m(klon), yu10m(klon)
215        REAL yustar(klon)
216        ! -- LOOP
217        REAL yu10mx(klon)
218        REAL yu10my(klon)
219        REAL ywindsp(klon)
220        ! -- LOOP
221    
222        REAL yt10m(klon), yq10m(klon)
223        REAL ypblh(klon)
224        REAL ylcl(klon)
225        REAL ycapcl(klon)
226        REAL yoliqcl(klon)
227        REAL ycteicl(klon)
228        REAL ypblt(klon)
229        REAL ytherm(klon)
230        REAL ytrmb1(klon)
231        REAL ytrmb2(klon)
232        REAL ytrmb3(klon)
233        REAL uzon(klon), vmer(klon)
234        REAL tair1(klon), qair1(klon), tairsol(klon)
235        REAL psfce(klon), patm(klon)
236    
237        REAL qairsol(klon), zgeo1(klon)
238        REAL rugo1(klon)
239    
240        ! utiliser un jeu de fonctions simples              
241        LOGICAL zxli
242        PARAMETER (zxli=.FALSE.)
243    
244        !------------------------------------------------------------
245    
246        ytherm = 0.
247    
248        DO k = 1, klev ! epaisseur de couche
249           DO i = 1, klon
250              delp(i, k) = paprs(i, k) - paprs(i, k+1)
251           END DO
252        END DO
253        DO i = 1, klon ! vent de la premiere couche
254           zx_alf1 = 1.0
255           zx_alf2 = 1.0 - zx_alf1
256           u1lay(i) = u(i, 1)*zx_alf1 + u(i, 2)*zx_alf2
257           v1lay(i) = v(i, 1)*zx_alf1 + v(i, 2)*zx_alf2
258        END DO
259    
260        ! Initialization:
261        rugmer = 0.
262        cdragh = 0.
263        cdragm = 0.
264        dflux_t = 0.
265        dflux_q = 0.
266        zu1 = 0.
267        zv1 = 0.
268        ypct = 0.
269        yts = 0.
270        ysnow = 0.
271        yqsurf = 0.
272        yalb = 0.
273        yalblw = 0.
274        yrain_f = 0.
275        ysnow_f = 0.
276        yfder = 0.
277        ysolsw = 0.
278        ysollw = 0.
279        yrugos = 0.
280        yu1 = 0.
281        yv1 = 0.
282        yrads = 0.
283        ypaprs = 0.
284        ypplay = 0.
285        ydelp = 0.
286        yu = 0.
287        yv = 0.
288        yt = 0.
289        yq = 0.
290        pctsrf_new = 0.
291        y_flux_u = 0.
292        y_flux_v = 0.
293        y_dflux_t = 0.
294        y_dflux_q = 0.
295        ytsoil = 999999.
296        yrugoro = 0.
297        ! -- LOOP
298        yu10mx = 0.
299        yu10my = 0.
300        ywindsp = 0.
301        ! -- LOOP
302        d_ts = 0.
303        yfluxlat = 0.
304        flux_t = 0.
305        flux_q = 0.
306        flux_u = 0.
307        flux_v = 0.
308        d_t = 0.
309        d_q = 0.
310        d_u = 0.
311        d_v = 0.
312        ycoefh = 0.
313    
314        ! Initialisation des "pourcentages potentiels". On considère ici qu'on
315        ! peut avoir potentiellement de la glace sur tout le domaine océanique
316        ! (à affiner)
317    
318        pctsrf_pot = pctsrf
319        pctsrf_pot(:, is_oce) = 1. - zmasq
320        pctsrf_pot(:, is_sic) = 1. - zmasq
321    
322        ! Boucler sur toutes les sous-fractions du sol:
323    
324        loop_surface: DO nsrf = 1, nbsrf
325           ! Chercher les indices :
326           ni = 0
327           knon = 0
328           DO i = 1, klon
329              ! Pour déterminer le domaine à traiter, on utilise les surfaces
330              ! "potentielles"
331              IF (pctsrf_pot(i, nsrf) > epsfra) THEN
332                 knon = knon + 1
333                 ni(knon) = i
334              END IF
335           END DO
336    
337           if_knon: IF (knon /= 0) then
338              DO j = 1, knon
339                 i = ni(j)
340                 ypct(j) = pctsrf(i, nsrf)
341                 yts(j) = ts(i, nsrf)
342                 ytslab(i) = tslab(i)
343                 ysnow(j) = snow(i, nsrf)
344                 yqsurf(j) = qsurf(i, nsrf)
345                 yalb(j) = albe(i, nsrf)
346                 yalblw(j) = alblw(i, nsrf)
347                 yrain_f(j) = rain_fall(i)
348                 ysnow_f(j) = snow_f(i)
349                 yagesno(j) = agesno(i, nsrf)
350                 yfder(j) = fder(i)
351                 ysolsw(j) = solsw(i, nsrf)
352                 ysollw(j) = sollw(i, nsrf)
353                 yrugos(j) = rugos(i, nsrf)
354                 yrugoro(j) = rugoro(i)
355                 yu1(j) = u1lay(i)
356                 yv1(j) = v1lay(i)
357                 yrads(j) = ysolsw(j) + ysollw(j)
358                 ypaprs(j, klev+1) = paprs(i, klev+1)
359                 y_run_off_lic_0(j) = run_off_lic_0(i)
360                 yu10mx(j) = u10m(i, nsrf)
361                 yu10my(j) = v10m(i, nsrf)
362                 ywindsp(j) = sqrt(yu10mx(j)*yu10mx(j)+yu10my(j)*yu10my(j))
363              END DO
364    
365              ! For continent, copy soil water content
366              IF (nsrf == is_ter) THEN
367                 yqsol(:knon) = qsol(ni(:knon))
368              ELSE
369                 yqsol = 0.
370              END IF
371    
372              DO k = 1, nsoilmx
373                 DO j = 1, knon
374                    i = ni(j)
375                    ytsoil(j, k) = ftsoil(i, k, nsrf)
376                 END DO
377              END DO
378    
379              DO k = 1, klev
380                 DO j = 1, knon
381                    i = ni(j)
382                    ypaprs(j, k) = paprs(i, k)
383                    ypplay(j, k) = pplay(i, k)
384                    ydelp(j, k) = delp(i, k)
385                    yu(j, k) = u(i, k)
386                    yv(j, k) = v(i, k)
387                    yt(j, k) = t(i, k)
388                    yq(j, k) = q(i, k)
389                 END DO
390              END DO
391    
392              ! calculer Cdrag et les coefficients d'echange
393              CALL coefkz(nsrf, knon, ypaprs, ypplay, ksta, ksta_ter, yts, yrugos, &
394                   yu, yv, yt, yq, yqsurf, coefm(:knon, :), coefh(:knon, :))
395              IF (iflag_pbl == 1) THEN
396                 CALL coefkz2(nsrf, knon, ypaprs, ypplay, yt, ycoefm0, ycoefh0)
397                 coefm(:knon, :) = max(coefm(:knon, :), ycoefm0(:knon, :))
398                 coefh(:knon, :) = max(coefh(:knon, :), ycoefh0(:knon, :))
399              END IF
400    
401              ! on met un seuil pour coefm et coefh
402              IF (nsrf == is_oce) THEN
403                 coefm(:knon, 1) = min(coefm(:knon, 1), cdmmax)
404                 coefh(:knon, 1) = min(coefh(:knon, 1), cdhmax)
405              END IF
406    
407              IF (ok_kzmin) THEN
408                 ! Calcul d'une diffusion minimale pour les conditions tres stables
409                 CALL coefkzmin(knon, ypaprs, ypplay, yu, yv, yt, yq, &
410                      coefm(:knon, 1), ycoefm0, ycoefh0)
411                 coefm(:knon, :) = max(coefm(:knon, :), ycoefm0(:knon, :))
412                 coefh(:knon, :) = max(coefh(:knon, :), ycoefh0(:knon, :))
413              END IF
414    
415              IF (iflag_pbl >= 3) THEN
416                 ! Mellor et Yamada adapté à Mars, Richard Fournier et
417                 ! Frédéric Hourdin
418                 yzlay(:knon, 1) = rd * yt(:knon, 1) / (0.5 * (ypaprs(:knon, 1) &
419                      + ypplay(:knon, 1))) &
420                      * (ypaprs(:knon, 1) - ypplay(:knon, 1)) / rg
421                 DO k = 2, klev
422                    yzlay(1:knon, k) = yzlay(1:knon, k-1) &
423                         + rd * 0.5 * (yt(1:knon, k-1) + yt(1:knon, k)) &
424                         / ypaprs(1:knon, k) &
425                         * (ypplay(1:knon, k-1) - ypplay(1:knon, k)) / rg
426                 END DO
427                 DO k = 1, klev
428                    yteta(1:knon, k) = yt(1:knon, k)*(ypaprs(1:knon, 1) &
429                         / ypplay(1:knon, k))**rkappa * (1.+0.61*yq(1:knon, k))
430                 END DO
431                 yzlev(1:knon, 1) = 0.
432                 yzlev(:knon, klev+1) = 2. * yzlay(:knon, klev) &
433                      - yzlay(:knon, klev - 1)
434                 DO k = 2, klev
435                    yzlev(1:knon, k) = 0.5*(yzlay(1:knon, k)+yzlay(1:knon, k-1))
436                 END DO
437                 DO k = 1, klev + 1
438                    DO j = 1, knon
439                       i = ni(j)
440                       yq2(j, k) = q2(i, k, nsrf)
441                    END DO
442                 END DO
443    
444                 CALL ustarhb(knon, yu, yv, coefm(:knon, 1), yustar)
445                 IF (prt_level > 9) PRINT *, 'USTAR = ', yustar
446    
447                 ! iflag_pbl peut être utilisé comme longueur de mélange
448    
449                 IF (iflag_pbl >= 11) THEN
450                    CALL vdif_kcay(knon, dtime, rg, rd, ypaprs, yt, yzlev, yzlay, &
451                         yu, yv, yteta, coefm(:knon, 1), yq2, q2diag, ykmm, ykmn, &
452                         yustar, iflag_pbl)
453                 ELSE
454                    CALL yamada4(knon, dtime, rg, yzlev, yzlay, yu, yv, yteta, &
455                         coefm(:knon, 1), yq2, ykmm, ykmn, ykmq, yustar, iflag_pbl)
456                 END IF
457    
458                 coefm(:knon, 2:) = ykmm(:knon, 2:klev)
459                 coefh(:knon, 2:) = ykmn(:knon, 2:klev)
460              END IF
461    
462              ! calculer la diffusion des vitesses "u" et "v"
463              CALL clvent(knon, dtime, yu1, yv1, coefm(:knon, :), yt, yu, ypaprs, &
464                   ypplay, ydelp, y_d_u, y_flux_u)
465              CALL clvent(knon, dtime, yu1, yv1, coefm(:knon, :), yt, yv, ypaprs, &
466                   ypplay, ydelp, y_d_v, y_flux_v)
467    
468              ! calculer la diffusion de "q" et de "h"
469              CALL clqh(dtime, itap, jour, debut, rlat, knon, nsrf, ni, pctsrf, &
470                   soil_model, ytsoil, yqsol, rmu0, co2_ppm, yrugos, yrugoro, &
471                   yu1, yv1, coefh(:knon, :), yt, yq, yts, ypaprs, ypplay, ydelp, &
472                   yrads, yalb, yalblw, ysnow, yqsurf, yrain_f, ysnow_f, yfder, &
473                   ysolsw, yfluxlat, pctsrf_new, yagesno, y_d_t, y_d_q, y_d_ts, &
474                   yz0_new, y_flux_t, y_flux_q, y_dflux_t, y_dflux_q, &
475                   y_fqcalving, y_ffonte, y_run_off_lic_0, y_flux_o, y_flux_g, &
476                   ytslab, y_seaice)
477    
478              ! calculer la longueur de rugosite sur ocean
479              yrugm = 0.
480              IF (nsrf == is_oce) THEN
481                 DO j = 1, knon
482                    yrugm(j) = 0.018*coefm(j, 1)*(yu1(j)**2+yv1(j)**2)/rg + &
483                         0.11*14E-6/sqrt(coefm(j, 1)*(yu1(j)**2+yv1(j)**2))
484                    yrugm(j) = max(1.5E-05, yrugm(j))
485                 END DO
486              END IF
487              DO j = 1, knon
488                 y_dflux_t(j) = y_dflux_t(j)*ypct(j)
489                 y_dflux_q(j) = y_dflux_q(j)*ypct(j)
490                 yu1(j) = yu1(j)*ypct(j)
491                 yv1(j) = yv1(j)*ypct(j)
492              END DO
493    
494              DO k = 1, klev
495                 DO j = 1, knon
496                    i = ni(j)
497                    coefh(j, k) = coefh(j, k)*ypct(j)
498                    coefm(j, k) = coefm(j, k)*ypct(j)
499                    y_d_t(j, k) = y_d_t(j, k)*ypct(j)
500                    y_d_q(j, k) = y_d_q(j, k)*ypct(j)
501                    flux_t(i, k, nsrf) = y_flux_t(j, k)
502                    flux_q(i, k, nsrf) = y_flux_q(j, k)
503                    flux_u(i, k, nsrf) = y_flux_u(j, k)
504                    flux_v(i, k, nsrf) = y_flux_v(j, k)
505                    y_d_u(j, k) = y_d_u(j, k)*ypct(j)
506                    y_d_v(j, k) = y_d_v(j, k)*ypct(j)
507                 END DO
508              END DO
509    
510              evap(:, nsrf) = -flux_q(:, 1, nsrf)
511    
512              albe(:, nsrf) = 0.
513              alblw(:, nsrf) = 0.
514              snow(:, nsrf) = 0.
515              qsurf(:, nsrf) = 0.
516              rugos(:, nsrf) = 0.
517              fluxlat(:, nsrf) = 0.
518              DO j = 1, knon
519                 i = ni(j)
520                 d_ts(i, nsrf) = y_d_ts(j)
521                 albe(i, nsrf) = yalb(j)
522                 alblw(i, nsrf) = yalblw(j)
523                 snow(i, nsrf) = ysnow(j)
524                 qsurf(i, nsrf) = yqsurf(j)
525                 rugos(i, nsrf) = yz0_new(j)
526                 fluxlat(i, nsrf) = yfluxlat(j)
527                 IF (nsrf == is_oce) THEN
528                    rugmer(i) = yrugm(j)
529                    rugos(i, nsrf) = yrugm(j)
530                 END IF
531                 agesno(i, nsrf) = yagesno(j)
532                 fqcalving(i, nsrf) = y_fqcalving(j)
533                 ffonte(i, nsrf) = y_ffonte(j)
534                 cdragh(i) = cdragh(i) + coefh(j, 1)
535                 cdragm(i) = cdragm(i) + coefm(j, 1)
536                 dflux_t(i) = dflux_t(i) + y_dflux_t(j)
537                 dflux_q(i) = dflux_q(i) + y_dflux_q(j)
538                 zu1(i) = zu1(i) + yu1(j)
539                 zv1(i) = zv1(i) + yv1(j)
540              END DO
541              IF (nsrf == is_ter) THEN
542                 qsol(ni(:knon)) = yqsol(:knon)
543              else IF (nsrf == is_lic) THEN
544                 DO j = 1, knon
545                    i = ni(j)
546                    run_off_lic_0(i) = y_run_off_lic_0(j)
547                 END DO
548              END IF
549              !$$$ PB ajout pour soil
550              ftsoil(:, :, nsrf) = 0.
551              DO k = 1, nsoilmx
552                 DO j = 1, knon
553                    i = ni(j)
554                    ftsoil(i, k, nsrf) = ytsoil(j, k)
555                 END DO
556              END DO
557    
558              DO j = 1, knon
559                 i = ni(j)
560                 DO k = 1, klev
561                    d_t(i, k) = d_t(i, k) + y_d_t(j, k)
562                    d_q(i, k) = d_q(i, k) + y_d_q(j, k)
563                    d_u(i, k) = d_u(i, k) + y_d_u(j, k)
564                    d_v(i, k) = d_v(i, k) + y_d_v(j, k)
565                    ycoefh(i, k) = ycoefh(i, k) + coefh(j, k)
566                 END DO
567              END DO
568    
569              ! diagnostic t, q a 2m et u, v a 10m
570    
571              DO j = 1, knon
572                 i = ni(j)
573                 uzon(j) = yu(j, 1) + y_d_u(j, 1)
574                 vmer(j) = yv(j, 1) + y_d_v(j, 1)
575                 tair1(j) = yt(j, 1) + y_d_t(j, 1)
576                 qair1(j) = yq(j, 1) + y_d_q(j, 1)
577                 zgeo1(j) = rd*tair1(j)/(0.5*(ypaprs(j, 1)+ypplay(j, &
578                      1)))*(ypaprs(j, 1)-ypplay(j, 1))
579                 tairsol(j) = yts(j) + y_d_ts(j)
580                 rugo1(j) = yrugos(j)
581                 IF (nsrf == is_oce) THEN
582                    rugo1(j) = rugos(i, nsrf)
583                 END IF
584                 psfce(j) = ypaprs(j, 1)
585                 patm(j) = ypplay(j, 1)
586    
587                 qairsol(j) = yqsurf(j)
588              END DO
589    
590              CALL stdlevvar(klon, knon, nsrf, zxli, uzon, vmer, tair1, qair1, &
591                   zgeo1, tairsol, qairsol, rugo1, psfce, patm, yt2m, yq2m, &
592                   yt10m, yq10m, yu10m, yustar)
593    
594              DO j = 1, knon
595                 i = ni(j)
596                 t2m(i, nsrf) = yt2m(j)
597                 q2m(i, nsrf) = yq2m(j)
598    
599                 ! u10m, v10m : composantes du vent a 10m sans spirale de Ekman
600                 u10m(i, nsrf) = (yu10m(j)*uzon(j))/sqrt(uzon(j)**2+vmer(j)**2)
601                 v10m(i, nsrf) = (yu10m(j)*vmer(j))/sqrt(uzon(j)**2+vmer(j)**2)
602    
603              END DO
604    
605              CALL hbtm(knon, ypaprs, ypplay, yt2m, yt10m, yq2m, yq10m, yustar, &
606                   y_flux_t, y_flux_q, yu, yv, yt, yq, ypblh, ycapcl, yoliqcl, &
607                   ycteicl, ypblt, ytherm, ytrmb1, ytrmb2, ytrmb3, ylcl)
608    
609              DO j = 1, knon
610                 i = ni(j)
611                 pblh(i, nsrf) = ypblh(j)
612                 plcl(i, nsrf) = ylcl(j)
613                 capcl(i, nsrf) = ycapcl(j)
614                 oliqcl(i, nsrf) = yoliqcl(j)
615                 cteicl(i, nsrf) = ycteicl(j)
616                 pblt(i, nsrf) = ypblt(j)
617                 therm(i, nsrf) = ytherm(j)
618                 trmb1(i, nsrf) = ytrmb1(j)
619                 trmb2(i, nsrf) = ytrmb2(j)
620                 trmb3(i, nsrf) = ytrmb3(j)
621              END DO
622    
623              DO j = 1, knon
624                 DO k = 1, klev + 1
625                    i = ni(j)
626                    q2(i, k, nsrf) = yq2(j, k)
627                 END DO
628              END DO
629              !IM "slab" ocean
630              IF (nsrf == is_oce) THEN
631                 DO j = 1, knon
632                    ! on projette sur la grille globale
633                    i = ni(j)
634                    IF (pctsrf_new(i, is_oce)>epsfra) THEN
635                       flux_o(i) = y_flux_o(j)
636                    ELSE
637                       flux_o(i) = 0.
638                    END IF
639                 END DO
640              END IF
641    
642              IF (nsrf == is_sic) THEN
643                 DO j = 1, knon
644                    i = ni(j)
645                    ! On pondère lorsque l'on fait le bilan au sol :
646                    IF (pctsrf_new(i, is_sic)>epsfra) THEN
647                       flux_g(i) = y_flux_g(j)
648                    ELSE
649                       flux_g(i) = 0.
650                    END IF
651                 END DO
652    
653              END IF
654           end IF if_knon
655        END DO loop_surface
656    
657    rugos(:, is_oce) = rugmer      ! On utilise les nouvelles surfaces
   pctsrf = pctsrf_new  
658    
659  END SUBROUTINE clmain      rugos(:, is_oce) = rugmer
660        pctsrf = pctsrf_new
661    
662      END SUBROUTINE clmain
663    
664    end module clmain_m

Legend:
Removed from v.25  
changed lines
  Added in v.99

  ViewVC Help
Powered by ViewVC 1.1.21