source: LMDZ6/branches/Ocean_skin/libf/phylmd/ocean_forced_mod.F90 @ 3463

Last change on this file since 3463 was 3463, checked in by lguez, 6 years ago

Compute surface sensible heat flux and latent heat flux using
ocean-atmosphere interface temperature instead of bulk SST, if
activate_ocean_skin == 2. So we add argument tsurf_in to
ocean_cpl_noice and ocean_forced_noice, and call calcul_fluxs with
tsurf_in. tsurf_in was already an argument of ocean_slab_noice, and
calcul_fluxs was already called with tsurf_in in ocean_slab_noice.

In procedure surf_ocean, when activate_ocean_skin == 2, rf should be
computed from the ocean-atmosphere interface temperature, tsurf_in,
not the SST bulk temperature, tsurf_new. So, for consistency, we also
use tsurf_in when activate_ocean_skin == 1. So this revision also
changes the results when activate_ocean_skin == 1.

  • 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:keywords set to Id
File size: 12.9 KB
Line 
1!
2! $Id: ocean_forced_mod.F90 3463 2019-02-08 13:28:03Z lguez $
3!
4MODULE ocean_forced_mod
5!
6! This module is used for both the sub-surfaces ocean and sea-ice for the case of a
7! forced ocean,  "ocean=force".
8!
9  IMPLICIT NONE
10
11CONTAINS
12!
13!****************************************************************************************
14!
15  SUBROUTINE ocean_forced_noice( &
16       itime, dtime, jour, knon, knindex, &
17       p1lay, cdragh, cdragq, cdragm, precip_rain, precip_snow, &
18       temp_air, spechum, &
19       AcoefH, AcoefQ, BcoefH, BcoefQ, &
20       AcoefU, AcoefV, BcoefU, BcoefV, &
21       ps, u1, v1, gustiness, tsurf_in, &
22       radsol, snow, agesno, &
23       qsurf, evap, fluxsens, fluxlat, flux_u1, flux_v1, &
24       tsurf_new, dflux_s, dflux_l)
25!
26! This subroutine treats the "open ocean", all grid points that are not entierly covered
27! by ice.
28! The routine receives data from climatologie file limit.nc and does some calculations at the
29! surface.
30!
31    USE dimphy
32    USE calcul_fluxs_mod
33    USE limit_read_mod
34    USE mod_grid_phy_lmdz
35    USE indice_sol_mod
36    USE phys_output_var_mod, ONLY : sens_prec_liq_o, sens_prec_sol_o, lat_prec_liq_o, lat_prec_sol_o
37    use config_ocean_skin_m, only: activate_ocean_skin
38
39    INCLUDE "YOMCST.h"
40    INCLUDE "clesphys.h"
41
42
43! Input arguments
44!****************************************************************************************
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)        :: p1lay
49    REAL, DIMENSION(klon), INTENT(IN)        :: cdragh, cdragq, cdragm
50    REAL, DIMENSION(klon), INTENT(IN)        :: precip_rain, precip_snow
51    REAL, DIMENSION(klon), INTENT(IN)        :: temp_air, spechum
52    REAL, DIMENSION(klon), INTENT(IN)        :: AcoefH, AcoefQ, BcoefH, BcoefQ
53    REAL, DIMENSION(klon), INTENT(IN)        :: AcoefU, AcoefV, BcoefU, BcoefV
54    REAL, DIMENSION(klon), INTENT(IN)        :: ps
55    REAL, DIMENSION(klon), INTENT(IN)        :: u1, v1, gustiness
56    REAL, DIMENSION(klon), INTENT(IN)        :: tsurf_in
57
58! In/Output arguments
59!****************************************************************************************
60    REAL, DIMENSION(klon), INTENT(INOUT)     :: radsol
61    REAL, DIMENSION(klon), INTENT(INOUT)     :: snow
62    REAL, DIMENSION(klon), INTENT(INOUT)     :: agesno !? put to 0 in ocean
63 
64! Output arguments
65!****************************************************************************************
66    REAL, DIMENSION(klon), INTENT(OUT)       :: qsurf
67    REAL, DIMENSION(klon), INTENT(OUT)       :: evap, fluxsens, fluxlat
68    REAL, DIMENSION(klon), INTENT(OUT)       :: flux_u1, flux_v1
69    REAL, DIMENSION(klon), INTENT(OUT)       :: tsurf_new
70    REAL, DIMENSION(klon), INTENT(OUT)       :: dflux_s, dflux_l
71
72! Local variables
73!****************************************************************************************
74    INTEGER                     :: i, j
75    REAL, DIMENSION(klon)       :: cal, beta, dif_grnd
76    REAL, DIMENSION(klon)       :: alb_neig, tsurf_lim, zx_sl
77    REAL, DIMENSION(klon)       :: u0, v0
78    REAL, DIMENSION(klon)       :: u1_lay, v1_lay
79    LOGICAL                     :: check=.FALSE.
80    REAL, DIMENSION(klon) :: sens_prec_liq, sens_prec_sol   
81    REAL, DIMENSION(klon) :: lat_prec_liq, lat_prec_sol   
82
83!****************************************************************************************
84! Start calculation
85!****************************************************************************************
86    IF (check) WRITE(*,*)' Entering ocean_forced_noice'
87   
88!****************************************************************************************
89! 1)   
90! Read sea-surface temperature from file limit.nc
91!
92!****************************************************************************************
93!--sb:
94!!jyg    if (knon.eq.1) then ! single-column model
95    if (klon_glo.eq.1) then ! single-column model
96      CALL read_tsurf1d(knon,tsurf_lim) ! new
97    else ! GCM
98      CALL limit_read_sst(knon,knindex,tsurf_lim)
99    endif ! knon
100!sb--
101
102!****************************************************************************************
103! 2)
104! Flux calculation
105!
106!****************************************************************************************
107! Set some variables for calcul_fluxs
108    cal = 0.
109    beta = 1.
110    dif_grnd = 0.
111    alb_neig(:) = 0.
112    agesno(:) = 0.
113    sens_prec_liq = 0.; sens_prec_sol = 0.; lat_prec_liq = 0.; lat_prec_sol = 0.
114
115! Suppose zero surface speed
116    u0(:)=0.0
117    v0(:)=0.0
118    u1_lay(:) = u1(:) - u0(:)
119    v1_lay(:) = v1(:) - v0(:)
120
121! Calcul de tsurf_new, evap, fluxlat, fluxsens, dflux_s, dflux_l and qsurf
122    CALL calcul_fluxs(knon, is_oce, dtime, &
123         merge(tsurf_in, tsurf_lim, activate_ocean_skin == 2), p1lay, cal, &
124         beta, cdragh, cdragq, ps, &
125         precip_rain, precip_snow, snow, qsurf,  &
126         radsol, dif_grnd, temp_air, spechum, u1_lay, v1_lay, gustiness, &
127         f_qsat_oce,AcoefH, AcoefQ, BcoefH, BcoefQ, &
128         tsurf_new, evap, fluxlat, fluxsens, dflux_s, dflux_l, &
129         sens_prec_liq, sens_prec_sol, lat_prec_liq, lat_prec_sol)
130    if (activate_ocean_skin == 2) tsurf_new = tsurf_lim
131
132    do j = 1, knon
133      i = knindex(j)
134      sens_prec_liq_o(i,1) = sens_prec_liq(j)
135      sens_prec_sol_o(i,1) = sens_prec_sol(j)
136      lat_prec_liq_o(i,1) = lat_prec_liq(j)
137      lat_prec_sol_o(i,1) = lat_prec_sol(j)
138    enddo
139
140
141! - Flux calculation at first modele level for U and V
142    CALL calcul_flux_wind(knon, dtime, &
143         u0, v0, u1, v1, gustiness, cdragm, &
144         AcoefU, AcoefV, BcoefU, BcoefV, &
145         p1lay, temp_air, &
146         flux_u1, flux_v1) 
147
148  END SUBROUTINE ocean_forced_noice
149!
150!***************************************************************************************
151!
152  SUBROUTINE ocean_forced_ice( &
153       itime, dtime, jour, knon, knindex, &
154       tsurf_in, p1lay, cdragh, cdragm, precip_rain, precip_snow, temp_air, spechum, &
155       AcoefH, AcoefQ, BcoefH, BcoefQ, &
156       AcoefU, AcoefV, BcoefU, BcoefV, &
157       ps, u1, v1, gustiness, &
158       radsol, snow, qsol, agesno, tsoil, &
159       qsurf, alb1_new, alb2_new, evap, fluxsens, fluxlat, flux_u1, flux_v1, &
160       tsurf_new, dflux_s, dflux_l)
161!
162! This subroutine treats the ocean where there is ice.
163! The routine reads data from climatologie file and does flux calculations at the
164! surface.
165!
166    USE dimphy
167    USE calcul_fluxs_mod
168    USE surface_data,     ONLY : calice, calsno
169    USE limit_read_mod
170    USE fonte_neige_mod,  ONLY : fonte_neige
171    USE indice_sol_mod
172    USE phys_output_var_mod, ONLY : sens_prec_liq_o, sens_prec_sol_o, lat_prec_liq_o, lat_prec_sol_o
173
174!    INCLUDE "indicesol.h"
175    INCLUDE "dimsoil.h"
176    INCLUDE "YOMCST.h"
177    INCLUDE "clesphys.h"
178
179! Input arguments
180!****************************************************************************************
181    INTEGER, INTENT(IN)                  :: itime, jour, knon
182    INTEGER, DIMENSION(klon), INTENT(IN) :: knindex
183    REAL, INTENT(IN)                     :: dtime
184    REAL, DIMENSION(klon), INTENT(IN)    :: tsurf_in
185    REAL, DIMENSION(klon), INTENT(IN)    :: p1lay
186    REAL, DIMENSION(klon), INTENT(IN)    :: cdragh, cdragm
187    REAL, DIMENSION(klon), INTENT(IN)    :: precip_rain, precip_snow
188    REAL, DIMENSION(klon), INTENT(IN)    :: temp_air, spechum
189    REAL, DIMENSION(klon), INTENT(IN)    :: AcoefH, AcoefQ, BcoefH, BcoefQ
190    REAL, DIMENSION(klon), INTENT(IN)    :: AcoefU, AcoefV, BcoefU, BcoefV
191    REAL, DIMENSION(klon), INTENT(IN)    :: ps
192    REAL, DIMENSION(klon), INTENT(IN)    :: u1, v1, gustiness
193
194! In/Output arguments
195!****************************************************************************************
196    REAL, DIMENSION(klon), INTENT(INOUT)          :: radsol
197    REAL, DIMENSION(klon), INTENT(INOUT)          :: snow, qsol
198    REAL, DIMENSION(klon), INTENT(INOUT)          :: agesno
199    REAL, DIMENSION(klon, nsoilmx), INTENT(INOUT) :: tsoil
200
201! Output arguments
202!****************************************************************************************
203    REAL, DIMENSION(klon), INTENT(OUT)            :: qsurf
204    REAL, DIMENSION(klon), INTENT(OUT)            :: alb1_new  ! new albedo in visible SW interval
205    REAL, DIMENSION(klon), INTENT(OUT)            :: alb2_new  ! new albedo in near IR interval
206    REAL, DIMENSION(klon), INTENT(OUT)            :: evap, fluxsens, fluxlat
207    REAL, DIMENSION(klon), INTENT(OUT)            :: flux_u1, flux_v1
208    REAL, DIMENSION(klon), INTENT(OUT)            :: tsurf_new
209    REAL, DIMENSION(klon), INTENT(OUT)            :: dflux_s, dflux_l     
210
211! Local variables
212!****************************************************************************************
213    LOGICAL                     :: check=.FALSE.
214    INTEGER                     :: i, j
215    REAL                        :: zfra
216    REAL, PARAMETER             :: t_grnd=271.35
217    REAL, DIMENSION(klon)       :: cal, beta, dif_grnd, capsol
218    REAL, DIMENSION(klon)       :: alb_neig, tsurf_tmp
219    REAL, DIMENSION(klon)       :: soilcap, soilflux
220    REAL, DIMENSION(klon)       :: u0, v0
221    REAL, DIMENSION(klon)       :: u1_lay, v1_lay
222    REAL, DIMENSION(klon)       :: sens_prec_liq, sens_prec_sol   
223    REAL, DIMENSION(klon)       :: lat_prec_liq, lat_prec_sol   
224
225
226!****************************************************************************************
227! Start calculation
228!****************************************************************************************
229    IF (check) WRITE(*,*)'Entering surface_seaice, knon=',knon
230
231!****************************************************************************************
232! 1)
233! Flux calculation : tsurf_new, evap, fluxlat, fluxsens, flux_u1, flux_v1
234!                    dflux_s, dflux_l and qsurf
235!****************************************************************************************
236
237    tsurf_tmp(:) = tsurf_in(:)
238
239! calculate the parameters cal, beta, capsol and dif_grnd
240    CALL calbeta(dtime, is_sic, knon, snow, qsol, beta, capsol, dif_grnd)
241
242   
243    IF (soil_model) THEN
244! update tsoil and calculate soilcap and soilflux
245       CALL soil(dtime, is_sic, knon, snow, tsurf_tmp, tsoil,soilcap, soilflux)
246       cal(1:knon) = RCPD / soilcap(1:knon)
247       radsol(1:knon) = radsol(1:knon)  + soilflux(1:knon)
248       dif_grnd = 1.0 / tau_gl
249    ELSE
250       dif_grnd = 1.0 / tau_gl
251       cal = RCPD * calice
252       WHERE (snow > 0.0) cal = RCPD * calsno
253    ENDIF
254
255    beta = 1.0
256    sens_prec_liq = 0.; sens_prec_sol = 0.; lat_prec_liq = 0.; lat_prec_sol = 0.
257
258! Suppose zero surface speed
259    u0(:)=0.0
260    v0(:)=0.0
261    u1_lay(:) = u1(:) - u0(:)
262    v1_lay(:) = v1(:) - v0(:)
263    CALL calcul_fluxs(knon, is_sic, dtime, &
264         tsurf_tmp, p1lay, cal, beta, cdragh, cdragh, ps, &
265         precip_rain, precip_snow, snow, qsurf,  &
266         radsol, dif_grnd, temp_air, spechum, u1_lay, v1_lay, gustiness, &
267         f_qsat_oce,AcoefH, AcoefQ, BcoefH, BcoefQ, &
268         tsurf_new, evap, fluxlat, fluxsens, dflux_s, dflux_l, &
269         sens_prec_liq, sens_prec_sol, lat_prec_liq, lat_prec_sol)
270    do j = 1, knon
271      i = knindex(j)
272      sens_prec_liq_o(i,2) = sens_prec_liq(j)
273      sens_prec_sol_o(i,2) = sens_prec_sol(j)
274      lat_prec_liq_o(i,2) = lat_prec_liq(j)
275      lat_prec_sol_o(i,2) = lat_prec_sol(j)
276    enddo
277
278! - Flux calculation at first modele level for U and V
279    CALL calcul_flux_wind(knon, dtime, &
280         u0, v0, u1, v1, gustiness, cdragm, &
281         AcoefU, AcoefV, BcoefU, BcoefV, &
282         p1lay, temp_air, &
283         flux_u1, flux_v1) 
284
285!****************************************************************************************
286! 2)
287! Calculations due to snow and runoff
288!
289!****************************************************************************************
290    CALL fonte_neige( knon, is_sic, knindex, dtime, &
291         tsurf_tmp, precip_rain, precip_snow, &
292         snow, qsol, tsurf_new, evap)
293   
294! Calculation of albedo at snow (alb_neig) and update the age of snow (agesno)
295!
296    CALL albsno(klon, knon, dtime, agesno(:), alb_neig(:), precip_snow(:)) 
297
298    WHERE (snow(1:knon) .LT. 0.0001) agesno(1:knon) = 0.
299
300    alb1_new(:) = 0.0
301    DO i=1, knon
302       zfra = MAX(0.0,MIN(1.0,snow(i)/(snow(i)+10.0)))
303       alb1_new(i) = alb_neig(i) * zfra +  0.6 * (1.0-zfra)
304    ENDDO
305
306    alb2_new(:) = alb1_new(:)
307
308  END SUBROUTINE ocean_forced_ice
309
310!************************************************************************
311! 1D case
312!************************************************************************
313  SUBROUTINE read_tsurf1d(knon,sst_out)
314
315! This subroutine specifies the surface temperature to be used in 1D simulations
316
317      USE dimphy, ONLY : klon
318
319      INTEGER, INTENT(IN)                  :: knon     ! nomber of points on compressed grid
320      REAL, DIMENSION(klon), INTENT(OUT)   :: sst_out  ! tsurf used to force the single-column model
321
322       INTEGER :: i
323! COMMON defined in lmdz1d.F:
324       real ts_cur
325       common /sst_forcing/ts_cur
326
327       DO i = 1, knon
328        sst_out(i) = ts_cur
329       ENDDO
330
331      END SUBROUTINE read_tsurf1d
332
333!
334!************************************************************************
335!
336END MODULE ocean_forced_mod
337
338
339
340
341
342
Note: See TracBrowser for help on using the repository browser.