source: LMDZ6/branches/Ocean_skin/libf/phylmd/ocean_cpl_mod.F90 @ 3747

Last change on this file since 3747 was 3744, checked in by lguez, 4 years ago

Store delta_sst instead of sst_nff

Store as a state variable the difference between ocean-air interface
temperature and bulk SST instead of sst_nff, which can be either
interface temperature or bulk SST. This is clearer. Also, it is
analoguous to what we will do with salinity.

So replace the two dummy arguments tsurf_in and sst_nff of
procedure cpl_send_ocean_fields by a single dummy argument
delta_sst. Replace dummy argument sst_nff of procedures
ocean_cpl_noice and surf_ocean by dummy argument
delta_sst. Replace variable sst_nff of module phys_state_var_mod
by variable delta_sst. Rename local variable ysst_nff of procedure
pbl_surface to ydelta_sst. Set variable delta_sst of module
phys_state_var_mod to 0 for an appearing ocean fraction and a
missing startup field. Replace variable o_sst_nff of module
phys_output_ctrlout_mod by variable o_delta_sst.

Rename variables cpl_delta_temp and cpl_delta_temp_2D of module
cpl_mod to cpl_delta_sst and cpl_delta_sst_2D, clearer. Rename
variable ids_delta_temp of module oasis to ids_delta_sst. Change
infosend(ids_delta_temp)%name to "CODELSST".

  • 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: 15.1 KB
Line 
1!
2! $Id: ocean_cpl_mod.F90 3744 2020-07-01 16:57:48Z lguez $
3!
4MODULE ocean_cpl_mod
5!
6! This module is used both for the sub-surface ocean and sea-ice for the case of a
7! coupled model configuration, ocean=couple.
8!
9
10  IMPLICIT NONE
11  PRIVATE
12
13  PUBLIC :: ocean_cpl_init, ocean_cpl_noice, ocean_cpl_ice
14
15
16!****************************************************************************************
17!
18CONTAINS
19!
20!****************************************************************************************
21!
22  SUBROUTINE ocean_cpl_init(dtime, rlon, rlat)
23!
24! Allocate fields for this module and initailize the module mod_cpl
25!
26    USE dimphy,           ONLY : klon
27    USE cpl_mod
28
29! Input arguments
30!*************************************************************************************
31    REAL, INTENT(IN)                  :: dtime
32    REAL, DIMENSION(klon), INTENT(IN) :: rlon, rlat
33
34! Local variables
35!*************************************************************************************
36    INTEGER              :: error
37    CHARACTER (len = 80) :: abort_message
38    CHARACTER (len = 20) :: modname = 'ocean_cpl_init'
39
40! Initialize module cpl_init
41    CALL cpl_init(dtime, rlon, rlat)
42   
43  END SUBROUTINE ocean_cpl_init
44!
45!****************************************************************************************
46!
47  SUBROUTINE ocean_cpl_noice( &
48       swnet, lwnet, alb1, &
49       windsp, fder_old, &
50       itime, dtime, knon, knindex, &
51       p1lay, cdragh, cdragq, cdragm, precip_rain, precip_snow, temp_air, spechum, &
52       AcoefH, AcoefQ, BcoefH, BcoefQ, &
53       AcoefU, AcoefV, BcoefU, BcoefV, &
54       ps, u1, v1, gustiness, tsurf_in, &
55       radsol, snow, agesno, &
56       qsurf, evap, fluxsens, fluxlat, flux_u1, flux_v1, &
57       tsurf_new, dflux_s, dflux_l, sens_prec_liq, sss, s_int, rhoa, delta_sst)
58
59!
60! This subroutine treats the "open ocean", all grid points that are not entierly covered
61! by ice. The subroutine first receives fields from coupler, then some calculations at
62! surface is done and finally it sends some fields to the coupler.
63!
64    USE dimphy,           ONLY : klon
65    USE calcul_fluxs_mod
66    USE indice_sol_mod
67    USE phys_output_var_mod, ONLY : sens_prec_liq_o, sens_prec_sol_o, lat_prec_liq_o, lat_prec_sol_o
68    USE cpl_mod, ONLY : gath2cpl, cpl_receive_ocean_fields, &
69         cpl_send_ocean_fields
70    use config_ocean_skin_m, only: activate_ocean_skin
71
72    INCLUDE "YOMCST.h"
73    INCLUDE "clesphys.h"
74!   
75! Input arguments 
76!****************************************************************************************
77    INTEGER, INTENT(IN)                      :: itime, knon
78    INTEGER, DIMENSION(klon), INTENT(IN)     :: knindex
79    REAL, INTENT(IN)                         :: dtime
80    REAL, DIMENSION(klon), INTENT(IN)        :: swnet
81    REAL, DIMENSION(klon), INTENT(IN)        :: lwnet
82    REAL, DIMENSION(klon), INTENT(IN)        :: alb1   ! albedo in visible SW interval
83    REAL, DIMENSION(klon), INTENT(IN)        :: windsp
84    REAL, DIMENSION(klon), INTENT(IN)        :: fder_old
85    REAL, DIMENSION(klon), INTENT(IN)        :: p1lay
86    REAL, DIMENSION(klon), INTENT(IN)        :: cdragh, cdragq, cdragm
87    REAL, DIMENSION(klon), INTENT(IN)        :: precip_rain, precip_snow
88    REAL, DIMENSION(klon), INTENT(IN)        :: temp_air, spechum
89    REAL, DIMENSION(klon), INTENT(IN)        :: AcoefH, AcoefQ, BcoefH, BcoefQ
90    REAL, DIMENSION(klon), INTENT(IN)        :: AcoefU, AcoefV, BcoefU, BcoefV
91    REAL, DIMENSION(klon), INTENT(IN)        :: ps
92    REAL, DIMENSION(klon), INTENT(IN)        :: u1, v1, gustiness
93    REAL, INTENT(IN) :: tsurf_in(:) ! (klon)
94    real, intent(in):: s_int(:) ! (knon) ocean-air interface salinity, in ppt
95    real, intent(in):: rhoa(:) ! (knon) density of moist air  (kg / m3)
96
97    REAL, intent(in):: delta_sst(:) ! (knon)
98    ! Ocean-air interface temperature minus bulk SST, in K. Defined
99    ! only if activate_ocean_skin >= 1.
100
101! In/Output arguments
102!****************************************************************************************
103    REAL, DIMENSION(klon), INTENT(INOUT)     :: radsol
104    REAL, DIMENSION(klon), INTENT(INOUT)     :: snow
105    REAL, DIMENSION(klon), INTENT(INOUT)     :: agesno
106 
107! Output arguments
108!****************************************************************************************
109    REAL, DIMENSION(klon), INTENT(OUT)       :: qsurf
110    REAL, DIMENSION(klon), INTENT(OUT)       :: evap, fluxsens, fluxlat
111    REAL, DIMENSION(klon), INTENT(OUT)       :: flux_u1, flux_v1
112    REAL, DIMENSION(klon), INTENT(OUT)       :: tsurf_new
113    REAL, DIMENSION(klon), INTENT(OUT)       :: dflux_s, dflux_l     
114    REAL, intent(out):: sens_prec_liq(:) ! (knon)
115
116    REAL, INTENT(OUT):: sss(:) ! (klon)
117    ! bulk salinity of the surface layer of the ocean, in ppt
118 
119
120! Local variables
121!****************************************************************************************
122    INTEGER               :: i, j
123    INTEGER, DIMENSION(1) :: iloc
124    REAL, DIMENSION(klon) :: cal, beta, dif_grnd
125    REAL, DIMENSION(klon) :: fder_new
126    REAL, DIMENSION(klon) :: tsurf_cpl
127    REAL, DIMENSION(klon) :: u0_cpl, v0_cpl
128    REAL, DIMENSION(klon) :: u1_lay, v1_lay
129    LOGICAL               :: check=.FALSE.
130    REAL sens_prec_sol(knon) 
131    REAL, DIMENSION(klon) :: lat_prec_liq, lat_prec_sol   
132
133! End definitions
134!****************************************************************************************
135
136    IF (check) WRITE(*,*)' Entering ocean_cpl_noice'
137
138!****************************************************************************************
139! Receive sea-surface temperature(tsurf_cpl) from coupler
140!
141!****************************************************************************************
142    CALL cpl_receive_ocean_fields(knon, knindex, tsurf_cpl, u0_cpl, v0_cpl, &
143         sss)
144
145!****************************************************************************************
146! Calculate fluxes at surface
147!
148!****************************************************************************************
149    cal = 0.
150    beta = 1.
151    dif_grnd = 0.
152    agesno(:) = 0.
153    lat_prec_liq = 0.; lat_prec_sol = 0.
154   
155
156    DO i = 1, knon
157       u1_lay(i) = u1(i) - u0_cpl(i)
158       v1_lay(i) = v1(i) - v0_cpl(i)
159    END DO
160
161    CALL calcul_fluxs(knon, is_oce, dtime, &
162         merge(tsurf_in, tsurf_cpl, activate_ocean_skin == 2), p1lay, cal, &
163         beta, cdragh, cdragq, ps, &
164         precip_rain, precip_snow, snow, qsurf,  &
165         radsol, dif_grnd, temp_air, spechum, u1_lay, v1_lay, gustiness, &
166         f_qsat_oce,AcoefH, AcoefQ, BcoefH, BcoefQ, &
167         tsurf_new, evap, fluxlat, fluxsens, dflux_s, dflux_l, &
168         sens_prec_liq, sens_prec_sol, lat_prec_liq, lat_prec_sol, rhoa)
169
170    if (activate_ocean_skin == 2) then
171       ! tsurf_new was set to tsurf_in in calcul_flux, correct it to
172       ! the new bulk SST tsurf_cpl:
173       tsurf_new = tsurf_cpl
174    end if
175
176    ! assertion: tsurf_new == tsurf_cpl
177   
178    do j = 1, knon
179      i = knindex(j)
180      sens_prec_liq_o(i,1) = sens_prec_liq(j)
181      sens_prec_sol_o(i,1) = sens_prec_sol(j)
182      lat_prec_liq_o(i,1) = lat_prec_liq(j)
183      lat_prec_sol_o(i,1) = lat_prec_sol(j)
184    enddo
185
186
187   
188! - Flux calculation at first modele level for U and V
189    CALL calcul_flux_wind(knon, dtime, &
190         u0_cpl, v0_cpl, u1, v1, gustiness, cdragm, &
191         AcoefU, AcoefV, BcoefU, BcoefV, &
192         p1lay, temp_air, &
193         flux_u1, flux_v1) 
194
195!****************************************************************************************
196! Calculate fder : flux derivative (sensible and latente)
197!
198!****************************************************************************************
199    fder_new(:) = fder_old(:) + dflux_s(:) + dflux_l(:)
200   
201    iloc = MAXLOC(fder_new(1:klon))
202    IF (check .AND. fder_new(iloc(1))> 0.) THEN
203       WRITE(*,*)'**** Debug fder****'
204       WRITE(*,*)'max fder(',iloc(1),') = ',fder_new(iloc(1))
205       WRITE(*,*)'fder_old, dflux_s, dflux_l',fder_old(iloc(1)), &
206            dflux_s(iloc(1)), dflux_l(iloc(1))
207    ENDIF
208
209!****************************************************************************************
210! Send and cumulate fields to the coupler
211!
212!****************************************************************************************
213
214    CALL cpl_send_ocean_fields(itime, knon, knindex, swnet, lwnet, fluxlat, &
215         fluxsens, precip_rain, precip_snow, evap, tsurf_new, fder_new, alb1, &
216         flux_u1, flux_v1, windsp, sens_prec_liq, sens_prec_sol, lat_prec_liq, &
217         lat_prec_sol, delta_sst, s_int)
218
219  END SUBROUTINE ocean_cpl_noice
220!
221!****************************************************************************************
222!
223  SUBROUTINE ocean_cpl_ice( &
224       rlon, rlat, swnet, lwnet, alb1, &
225       fder_old, &
226       itime, dtime, knon, knindex, &
227       lafin, &
228       p1lay, cdragh, cdragm, precip_rain, precip_snow, temp_air, spechum, &
229       AcoefH, AcoefQ, BcoefH, BcoefQ, &
230       AcoefU, AcoefV, BcoefU, BcoefV, &
231       ps, u1, v1, gustiness, pctsrf, &
232       radsol, snow, qsurf, &
233       alb1_new, alb2_new, evap, fluxsens, fluxlat, flux_u1, flux_v1, &
234       tsurf_new, dflux_s, dflux_l, rhoa)
235!
236! This subroutine treats the ocean where there is ice. The subroutine first receives
237! fields from coupler, then some calculations at surface is done and finally sends
238! some fields to the coupler.
239!   
240    USE dimphy,           ONLY : klon
241    USE cpl_mod
242    USE calcul_fluxs_mod
243    USE indice_sol_mod
244    USE phys_output_var_mod, ONLY : sens_prec_liq_o, sens_prec_sol_o, lat_prec_liq_o, lat_prec_sol_o
245
246    INCLUDE "YOMCST.h"
247    INCLUDE "clesphys.h"
248
249! Input arguments
250!****************************************************************************************
251    INTEGER, INTENT(IN)                      :: itime, knon
252    INTEGER, DIMENSION(klon), INTENT(IN)     :: knindex
253    LOGICAL, INTENT(IN)                      :: lafin
254    REAL, INTENT(IN)                         :: dtime
255    REAL, DIMENSION(klon), INTENT(IN)        :: rlon, rlat
256    REAL, DIMENSION(klon), INTENT(IN)        :: swnet
257    REAL, DIMENSION(klon), INTENT(IN)        :: lwnet
258    REAL, DIMENSION(klon), INTENT(IN)        :: alb1   ! albedo in visible SW interval
259    REAL, DIMENSION(klon), INTENT(IN)        :: fder_old
260    REAL, DIMENSION(klon), INTENT(IN)        :: p1lay
261    REAL, DIMENSION(klon), INTENT(IN)        :: cdragh, cdragm
262    REAL, DIMENSION(klon), INTENT(IN)        :: precip_rain, precip_snow
263    REAL, DIMENSION(klon), INTENT(IN)        :: temp_air, spechum
264    REAL, DIMENSION(klon), INTENT(IN)        :: AcoefH, AcoefQ, BcoefH, BcoefQ
265    REAL, DIMENSION(klon), INTENT(IN)        :: AcoefU, AcoefV, BcoefU, BcoefV
266    REAL, DIMENSION(klon), INTENT(IN)        :: ps
267    REAL, DIMENSION(klon), INTENT(IN)        :: u1, v1, gustiness
268    REAL, DIMENSION(klon,nbsrf), INTENT(IN)  :: pctsrf
269    real, intent(in):: rhoa(:) ! (knon) density of moist air  (kg / m3)
270
271! In/output arguments
272!****************************************************************************************
273    REAL, DIMENSION(klon), INTENT(INOUT)     :: radsol
274    REAL, DIMENSION(klon), INTENT(INOUT)     :: snow
275
276! Output arguments
277!****************************************************************************************
278    REAL, DIMENSION(klon), INTENT(OUT)       :: qsurf
279    REAL, DIMENSION(klon), INTENT(OUT)       :: alb1_new, alb2_new
280    REAL, DIMENSION(klon), INTENT(OUT)       :: evap, fluxsens, fluxlat
281    REAL, DIMENSION(klon), INTENT(OUT)       :: flux_u1, flux_v1
282    REAL, DIMENSION(klon), INTENT(OUT)       :: tsurf_new
283    REAL, DIMENSION(klon), INTENT(OUT)       :: dflux_s, dflux_l     
284 
285
286! Local variables
287!****************************************************************************************
288    INTEGER                 :: i, j
289    INTEGER, DIMENSION(1)   :: iloc
290    LOGICAL                 :: check=.FALSE.
291    REAL, PARAMETER         :: t_grnd=271.35
292    REAL, DIMENSION(klon)   :: cal, beta, dif_grnd
293    REAL, DIMENSION(klon)   :: tsurf_cpl, fder_new
294    REAL, DIMENSION(klon)   :: alb_cpl
295    REAL, DIMENSION(klon)   :: u0, v0
296    REAL, DIMENSION(klon)   :: u1_lay, v1_lay
297    REAL sens_prec_liq(knon), sens_prec_sol(knon)   
298    REAL, DIMENSION(klon) :: lat_prec_liq, lat_prec_sol   
299
300! End definitions
301!****************************************************************************************
302   
303    IF (check) WRITE(*,*)'Entering surface_seaice, knon=',knon
304
305    lat_prec_liq = 0.; lat_prec_sol = 0.
306
307!****************************************************************************************
308! Receive ocean temperature(tsurf_cpl) and albedo(alb_new) from coupler
309!
310!****************************************************************************************
311
312    CALL cpl_receive_seaice_fields(knon, knindex, &
313         tsurf_cpl, alb_cpl, u0, v0)
314
315    alb1_new(1:knon) = alb_cpl(1:knon)
316    alb2_new(1:knon) = alb_cpl(1:knon)   
317
318   
319!****************************************************************************************
320! Calculate fluxes at surface
321!
322!****************************************************************************************
323    cal = 0.
324    dif_grnd = 0.
325    beta = 1.0
326   
327    DO i = 1, knon
328       u1_lay(i) = u1(i) - u0(i)
329       v1_lay(i) = v1(i) - v0(i)
330    END DO
331
332    CALL calcul_fluxs(knon, is_sic, dtime, &
333         tsurf_cpl, p1lay, cal, beta, cdragh, cdragh, ps, &
334         precip_rain, precip_snow, snow, qsurf,  &
335         radsol, dif_grnd, temp_air, spechum, u1_lay, v1_lay, gustiness, &
336         f_qsat_oce,AcoefH, AcoefQ, BcoefH, BcoefQ, &
337         tsurf_new, evap, fluxlat, fluxsens, dflux_s, dflux_l, &
338         sens_prec_liq, sens_prec_sol, lat_prec_liq, lat_prec_sol, rhoa)
339    do j = 1, knon
340      i = knindex(j)
341      sens_prec_liq_o(i,2) = sens_prec_liq(j)
342      sens_prec_sol_o(i,2) = sens_prec_sol(j)
343      lat_prec_liq_o(i,2) = lat_prec_liq(j)
344      lat_prec_sol_o(i,2) = lat_prec_sol(j)
345    enddo
346
347
348! - Flux calculation at first modele level for U and V
349    CALL calcul_flux_wind(knon, dtime, &
350         u0, v0, u1, v1, gustiness, cdragm, &
351         AcoefU, AcoefV, BcoefU, BcoefV, &
352         p1lay, temp_air, &
353         flux_u1, flux_v1) 
354
355!****************************************************************************************
356! Calculate fder : flux derivative (sensible and latente)
357!
358!****************************************************************************************
359    fder_new(:) = fder_old(:) + dflux_s(:) + dflux_l(:)
360   
361    iloc = MAXLOC(fder_new(1:klon))
362    IF (check .AND. fder_new(iloc(1))> 0.) THEN
363       WRITE(*,*)'**** Debug fder ****'
364       WRITE(*,*)'max fder(',iloc(1),') = ',fder_new(iloc(1))
365       WRITE(*,*)'fder_old, dflux_s, dflux_l',fder_old(iloc(1)), &
366            dflux_s(iloc(1)), dflux_l(iloc(1))
367    ENDIF
368
369!****************************************************************************************
370! Send and cumulate fields to the coupler
371!
372!****************************************************************************************
373
374    CALL cpl_send_seaice_fields(itime, dtime, knon, knindex, &
375       pctsrf, lafin, rlon, rlat, &
376       swnet, lwnet, fluxlat, fluxsens, &
377       precip_rain, precip_snow, evap, tsurf_new, fder_new, alb1, flux_u1, flux_v1,&
378       sens_prec_liq, sens_prec_sol, lat_prec_liq, lat_prec_sol)
379
380 
381
382  END SUBROUTINE ocean_cpl_ice
383
384!****************************************************************************************
385!
386END MODULE ocean_cpl_mod
Note: See TracBrowser for help on using the repository browser.