source: LMDZ5/trunk/libf/phylmd/surf_ocean_mod.F90 @ 5456

Last change on this file since 5456 was 3002, checked in by Ehouarn Millour, 7 years ago

Improved slab routines.
FC

  • Property copyright set to
    Name of program: LMDZ
    Creation date: 1984
    Version: LMDZ5
    License: CeCILL version 2
    Holder: Laboratoire de m\'et\'eorologie dynamique, CNRS, UMR 8539
    See the license file in the root directory
  • Property svn:eol-style set to native
  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 10.8 KB
RevLine 
[781]1!
[2538]2! $Id: surf_ocean_mod.F90 3002 2017-10-03 06:18:41Z aborella $
3!
[781]4MODULE surf_ocean_mod
5
6  IMPLICIT NONE
7
8CONTAINS
9!
[2254]10!******************************************************************************
[781]11!
[888]12  SUBROUTINE surf_ocean(rlon, rlat, swnet, lwnet, alb1, &
[2243]13       windsp, rmu0, fder, tsurf_in, &
[781]14       itime, dtime, jour, knon, knindex, &
[2254]15       p1lay, z1lay, cdragh, cdragm, precip_rain, precip_snow, temp_air, spechum, &
[1067]16       AcoefH, AcoefQ, BcoefH, BcoefQ, &
17       AcoefU, AcoefV, BcoefU, BcoefV, &
[2240]18       ps, u1, v1, gustiness, rugoro, pctsrf, &
[888]19       snow, qsurf, agesno, &
[2243]20       z0m, z0h, SFRWL, alb_dir_new, alb_dif_new, evap, fluxsens, fluxlat, &
[1067]21       tsurf_new, dflux_s, dflux_l, lmt_bils, &
22       flux_u1, flux_v1)
23
[2322]24  use albedo, only: alboc, alboc_cd
[2391]25  USE dimphy, ONLY: klon, zmasq
[1067]26  USE surface_data, ONLY     : type_ocean
27  USE ocean_forced_mod, ONLY : ocean_forced_noice
28  USE ocean_slab_mod, ONLY   : ocean_slab_noice
29  USE ocean_cpl_mod, ONLY    : ocean_cpl_noice
[2391]30  USE indice_sol_mod, ONLY : nbsrf, is_oce
[3002]31  USE limit_read_mod
[781]32!
33! This subroutine will make a call to ocean_XXX_noice according to the ocean mode (force,
34! slab or couple). The calculations of albedo and rugosity for the ocean surface are
35! done in here because they are identical for the different modes of ocean.
[1785]36
37
[793]38    INCLUDE "YOMCST.h"
[781]39
[2178]40    include "clesphys.h"
[2455]41    ! for cycle_diurne and for iflag_z0_oce==-1 (prescribed z0)
[2178]42
[781]43! Input variables
[2254]44!******************************************************************************
[781]45    INTEGER, INTENT(IN)                      :: itime, jour, knon
46    INTEGER, DIMENSION(klon), INTENT(IN)     :: knindex
47    REAL, INTENT(IN)                         :: dtime
48    REAL, DIMENSION(klon), INTENT(IN)        :: rlon, rlat
[888]49    REAL, DIMENSION(klon), INTENT(IN)        :: swnet  ! net shortwave radiation at surface 
50    REAL, DIMENSION(klon), INTENT(IN)        :: lwnet  ! net longwave radiation at surface 
51    REAL, DIMENSION(klon), INTENT(IN)        :: alb1   ! albedo in visible SW interval
[781]52    REAL, DIMENSION(klon), INTENT(IN)        :: windsp
53    REAL, DIMENSION(klon), INTENT(IN)        :: rmu0 
54    REAL, DIMENSION(klon), INTENT(IN)        :: fder
[996]55    REAL, DIMENSION(klon), INTENT(IN)        :: tsurf_in
[2254]56    REAL, DIMENSION(klon), INTENT(IN)        :: p1lay,z1lay ! pression (Pa) et altitude (m) du premier niveau
[1067]57    REAL, DIMENSION(klon), INTENT(IN)        :: cdragh
58    REAL, DIMENSION(klon), INTENT(IN)        :: cdragm
[781]59    REAL, DIMENSION(klon), INTENT(IN)        :: precip_rain, precip_snow
60    REAL, DIMENSION(klon), INTENT(IN)        :: temp_air, spechum
[1067]61    REAL, DIMENSION(klon), INTENT(IN)        :: AcoefH, AcoefQ, BcoefH, BcoefQ
62    REAL, DIMENSION(klon), INTENT(IN)        :: AcoefU, AcoefV, BcoefU, BcoefV
[781]63    REAL, DIMENSION(klon), INTENT(IN)        :: ps
[2240]64    REAL, DIMENSION(klon), INTENT(IN)        :: u1, v1, gustiness
[781]65    REAL, DIMENSION(klon), INTENT(IN)        :: rugoro
66    REAL, DIMENSION(klon,nbsrf), INTENT(IN)  :: pctsrf
67
68! In/Output variables
[2254]69!******************************************************************************
[888]70    REAL, DIMENSION(klon), INTENT(INOUT)     :: snow
71    REAL, DIMENSION(klon), INTENT(INOUT)     :: qsurf
[781]72    REAL, DIMENSION(klon), INTENT(INOUT)     :: agesno
73
74! Output variables
[2254]75!******************************************************************************
[2243]76    REAL, DIMENSION(klon), INTENT(OUT)       :: z0m, z0h
[2227]77!albedo SB >>>
78!    REAL, DIMENSION(klon), INTENT(OUT)       :: alb1_new  ! new albedo in visible SW interval
79!    REAL, DIMENSION(klon), INTENT(OUT)       :: alb2_new  ! new albedo in near IR interval
80    REAL, DIMENSION(6), INTENT(IN)          :: SFRWL
81    REAL, DIMENSION(klon,nsw), INTENT(OUT)       :: alb_dir_new,alb_dif_new
82!albedo SB <<<     
[781]83    REAL, DIMENSION(klon), INTENT(OUT)       :: evap, fluxsens, fluxlat
[888]84    REAL, DIMENSION(klon), INTENT(OUT)       :: tsurf_new
[781]85    REAL, DIMENSION(klon), INTENT(OUT)       :: dflux_s, dflux_l     
[996]86    REAL, DIMENSION(klon), INTENT(OUT)       :: lmt_bils
[1067]87    REAL, DIMENSION(klon), INTENT(OUT)       :: flux_u1, flux_v1
[781]88
89! Local variables
[2254]90!******************************************************************************
[2227]91    INTEGER               :: i, k
[1146]92    REAL                  :: tmp
93    REAL, PARAMETER       :: cepdu2=(0.1)**2
[3002]94    REAL, DIMENSION(klon) :: alb_eau, z0_lim
[888]95    REAL, DIMENSION(klon) :: radsol
[2254]96    REAL, DIMENSION(klon) :: cdragq ! Cdrag pour l'evaporation
[2391]97    CHARACTER(len=20),PARAMETER :: modname="surf_ocean"
[781]98
99! End definition
[2254]100!******************************************************************************
[888]101
102
[2254]103!******************************************************************************
[888]104! Calculate total net radiance at surface
105!
[2254]106!******************************************************************************
[2719]107    radsol(1:klon) = 0.0 ! initialisation a priori inutile
[888]108    radsol(1:knon) = swnet(1:knon) + lwnet(1:knon)
109
[2254]110!******************************************************************************
111! Cdragq computed from cdrag
112! The difference comes only from a factor (f_z0qh_oce) on z0, so that
113! it can be computed inside surf_ocean
114! More complicated appraches may require the propagation through
115! pbl_surface of an independant cdragq variable.
116!******************************************************************************
117
118    IF ( f_z0qh_oce .ne. 1.) THEN
[2261]119! Si on suit les formulations par exemple de Tessel, on
120! a z0h=0.4*nu/u*, z0q=0.62*nu/u*, d'ou f_z0qh_oce=0.62/0.4=1.55
[2718]121       cdragq(1:knon)=cdragh(1:knon)*                                      &
122       log(z1lay(1:knon)/z0h(1:knon))/log(z1lay(1:knon)/(f_z0qh_oce*z0h(1:knon)))
[2254]123    ELSE
[2718]124       cdragq(1:knon)=cdragh(1:knon)
[2254]125    ENDIF
126
[3002]127
[2254]128!******************************************************************************
[781]129! Switch according to type of ocean (couple, slab or forced)
[2254]130!******************************************************************************
[996]131    SELECT CASE(type_ocean)
[781]132    CASE('couple')
[888]133       CALL ocean_cpl_noice( &
134            swnet, lwnet, alb1, &
[1067]135            windsp, fder, &
[781]136            itime, dtime, knon, knindex, &
[2254]137            p1lay, cdragh, cdragq, cdragm, precip_rain, precip_snow,temp_air,spechum,&
[1067]138            AcoefH, AcoefQ, BcoefH, BcoefQ, &
139            AcoefU, AcoefV, BcoefU, BcoefV, &
[2240]140            ps, u1, v1, gustiness, &
[888]141            radsol, snow, agesno, &
[1067]142            qsurf, evap, fluxsens, fluxlat, flux_u1, flux_v1, &
[996]143            tsurf_new, dflux_s, dflux_l)
[781]144
145    CASE('slab')
[888]146       CALL ocean_slab_noice( &
[996]147            itime, dtime, jour, knon, knindex, &
[2254]148            p1lay, cdragh, cdragq, cdragm, precip_rain, precip_snow, temp_air, spechum,&
[1067]149            AcoefH, AcoefQ, BcoefH, BcoefQ, &
150            AcoefU, AcoefV, BcoefU, BcoefV, &
[2240]151            ps, u1, v1, gustiness, tsurf_in, &
[2209]152            radsol, snow, &
[1067]153            qsurf, evap, fluxsens, fluxlat, flux_u1, flux_v1, &
[996]154            tsurf_new, dflux_s, dflux_l, lmt_bils)
[781]155       
156    CASE('force')
[888]157       CALL ocean_forced_noice( &
158            itime, dtime, jour, knon, knindex, &
[2254]159            p1lay, cdragh, cdragq, cdragm, precip_rain, precip_snow, &
[781]160            temp_air, spechum, &
[1067]161            AcoefH, AcoefQ, BcoefH, BcoefQ, &
162            AcoefU, AcoefV, BcoefU, BcoefV, &
[2240]163            ps, u1, v1, gustiness, &
[888]164            radsol, snow, agesno, &
[1067]165            qsurf, evap, fluxsens, fluxlat, flux_u1, flux_v1, &
[996]166            tsurf_new, dflux_s, dflux_l)
[781]167    END SELECT
168
[2254]169!******************************************************************************
[2057]170! fcodron: compute lmt_bils  forced case (same as wfbils_oce / 1.-contfracatm)
[2254]171!******************************************************************************
[2057]172    IF (type_ocean.NE.'slab') THEN
[2719]173        lmt_bils(1:klon)=0.
[2057]174        DO i=1,knon
175           lmt_bils(knindex(i))=(swnet(i)+lwnet(i)+fluxsens(i)+fluxlat(i)) &
176           *pctsrf(knindex(i),is_oce)/(1.-zmasq(knindex(i)))
177        END DO
178    END IF
179
[2254]180!******************************************************************************
[2413]181! Calculate ocean surface albedo
[2254]182!******************************************************************************
[2227]183!albedo SB >>>
[2413]184IF (iflag_albedo==0) THEN
185!--old parametrizations of ocean surface albedo
186!
[2178]187    IF (cycle_diurne) THEN
[2413]188!
[2178]189       CALL alboc_cd(rmu0,alb_eau)
[2413]190!
191!--ad-hoc correction for model radiative balance tuning
192!--now outside alboc_cd routine
[2718]193       alb_eau(1:klon) = fmagic*alb_eau(1:klon) + pmagic
194       alb_eau(1:klon)=MIN(MAX(alb_eau(1:klon),0.0),1.0)
[2413]195!
[2178]196    ELSE
[2413]197!
[1403]198       CALL alboc(REAL(jour),rlat,alb_eau)
[2413]199!--ad-hoc correction for model radiative balance tuning
200!--now outside alboc routine
[2718]201       alb_eau(1:klon) = fmagic*alb_eau(1:klon) + pmagic
202       alb_eau(1:klon)=MIN(MAX(alb_eau(1:klon),0.04),0.60)
[2413]203!
[781]204    ENDIF
[2413]205!
[781]206    DO i =1, knon
[2413]207      DO  k=1,nsw
[2227]208       alb_dir_new(i,k) = alb_eau(knindex(i))
[2413]209      ENDDO
[781]210    ENDDO
[2413]211!IM 09122015 next line corresponds to the old way of doing in LMDZ5A/IPSLCM5A versions
212!albedo for diffuse radiation is taken the same as for direct radiation
[2718]213     alb_dif_new(1:knon,:)=alb_dir_new(1:knon,:)
[2405]214!IM 09122015 end
[2413]215!
216ELSE IF (iflag_albedo==1) THEN
217!--new parametrization of ocean surface albedo by Sunghye Baek
218!--albedo for direct and diffuse radiation are different
219!
220    CALL ocean_albedo(knon,rmu0,knindex,windsp,SFRWL,alb_dir_new,alb_dif_new)
221!
222!--ad-hoc correction for model radiative balance tuning
[2718]223    alb_dir_new(1:knon,:) = fmagic*alb_dir_new(1:knon,:) + pmagic
[2719]224    alb_dif_new(1:knon,:) = fmagic*alb_dif_new(1:knon,:) + pmagic
[2718]225    alb_dir_new(1:knon,:)=MIN(MAX(alb_dir_new(1:knon,:),0.0),1.0)
226    alb_dif_new(1:knon,:)=MIN(MAX(alb_dif_new(1:knon,:),0.0),1.0)
[2413]227!
[3002]228! F. Codron albedo read from limit.nc
229ELSE IF (iflag_albedo==2) THEN
230    CALL limit_read_rug_alb(itime, dtime, jour,&
231         knon, knindex, z0_lim, alb_eau)
232    DO i =1, knon
233      DO  k=1,nsw
234       alb_dir_new(i,k) = alb_eau(i)
235      ENDDO
236    ENDDO
237    alb_dif_new=alb_dir_new
[2413]238ENDIF
[2227]239!albedo SB <<<
240
[2254]241!******************************************************************************
[781]242! Calculate the rugosity
[2254]243!******************************************************************************
[2243]244IF (iflag_z0_oce==0) THEN
[781]245    DO i = 1, knon
[2278]246       tmp = MAX(cepdu2,gustiness(i)+u1(i)**2+v1(i)**2)
247       z0m(i) = 0.018*cdragm(i) * (gustiness(i)+u1(i)**2+v1(i)**2)/RG  &
[1146]248            +  0.11*14e-6 / SQRT(cdragm(i) * tmp)
[2243]249       z0m(i) = MAX(1.5e-05,z0m(i))
[1146]250    ENDDO   
[2243]251    z0h(1:knon)=z0m(1:knon) ! En attendant mieux
252
[2261]253ELSE IF (iflag_z0_oce==1) THEN
[2264]254    DO i = 1, knon
[2278]255       tmp = MAX(cepdu2,gustiness(i)+u1(i)**2+v1(i)**2)
256       z0m(i) = 0.018*cdragm(i) * (gustiness(i)+u1(i)**2+v1(i)**2)/RG  &
[2264]257            + 0.11*14e-6 / SQRT(cdragm(i) * tmp)
258       z0m(i) = MAX(1.5e-05,z0m(i))
[2278]259       z0h(i)=0.4*14e-6 / SQRT(cdragm(i) * tmp)
[2264]260    ENDDO
[2455]261ELSE IF (iflag_z0_oce==-1) THEN
262    DO i = 1, knon
263       z0m(i) = z0min
264       z0h(i) = z0min
265    ENDDO
[2243]266ELSE
[2391]267       CALL abort_physic(modname,'version non prevue',1)
[2243]268ENDIF
[781]269!
[2254]270!******************************************************************************
[781]271  END SUBROUTINE surf_ocean
[2254]272!******************************************************************************
[781]273!
274END MODULE surf_ocean_mod
Note: See TracBrowser for help on using the repository browser.