Changeset 2656 for LMDZ5/trunk/libf/phylmd/ocean_slab_mod.F90
- Timestamp:
- Oct 10, 2016, 10:57:24 AM (8 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
LMDZ5/trunk/libf/phylmd/ocean_slab_mod.F90
r2311 r2656 9 9 USE indice_sol_mod 10 10 USE surface_data 11 USE mod_grid_phy_lmdz, ONLY: klon_glo 12 USE mod_phys_lmdz_mpi_data, ONLY: is_mpi_root 11 13 12 14 IMPLICIT NONE … … 14 16 PUBLIC :: ocean_slab_init, ocean_slab_frac, ocean_slab_noice, ocean_slab_ice 15 17 16 !*********************************************************************************** *****18 !*********************************************************************************** 17 19 ! Global saved variables 18 !**************************************************************************************** 19 20 !*********************************************************************************** 21 ! number of slab vertical layers 22 INTEGER, PUBLIC, SAVE :: nslay 23 !$OMP THREADPRIVATE(nslay) 24 ! timestep for coupling (update slab temperature) in timesteps 20 25 INTEGER, PRIVATE, SAVE :: cpl_pas 21 26 !$OMP THREADPRIVATE(cpl_pas) 27 ! cyang = 1/heat capacity of top layer (rho.c.H) 22 28 REAL, PRIVATE, SAVE :: cyang 23 29 !$OMP THREADPRIVATE(cyang) 30 ! depth of slab layers (1 or 2) 24 31 REAL, ALLOCATABLE, DIMENSION(:), PRIVATE, SAVE :: slabh 25 32 !$OMP THREADPRIVATE(slabh) 33 ! slab temperature 26 34 REAL, ALLOCATABLE, DIMENSION(:,:), PUBLIC, SAVE :: tslab 27 35 !$OMP THREADPRIVATE(tslab) 36 ! heat flux convergence due to Ekman 37 REAL, ALLOCATABLE, DIMENSION(:,:), PUBLIC, SAVE :: dt_ekman 38 !$OMP THREADPRIVATE(dt_ekman) 39 ! heat flux convergence due to horiz diffusion 40 REAL, ALLOCATABLE, DIMENSION(:,:), PUBLIC, SAVE :: dt_hdiff 41 !$OMP THREADPRIVATE(dt_hdiff) 42 ! fraction of ocean covered by sea ice (sic / (oce+sic)) 28 43 REAL, ALLOCATABLE, DIMENSION(:), PUBLIC, SAVE :: fsic 29 44 !$OMP THREADPRIVATE(fsic) 45 ! temperature of the sea ice 30 46 REAL, ALLOCATABLE, DIMENSION(:), PUBLIC, SAVE :: tice 31 47 !$OMP THREADPRIVATE(tice) 48 ! sea ice thickness, in kg/m2 32 49 REAL, ALLOCATABLE, DIMENSION(:), PUBLIC, SAVE :: seaice 33 50 !$OMP THREADPRIVATE(seaice) 51 ! net surface heat flux, weighted by open ocean fraction 34 52 REAL, ALLOCATABLE, DIMENSION(:), PUBLIC, SAVE :: slab_bils 35 53 !$OMP THREADPRIVATE(slab_bils) 54 ! slab_bils accumulated over cpl_pas timesteps 36 55 REAL, ALLOCATABLE, DIMENSION(:), PRIVATE, SAVE :: bils_cum 37 56 !$OMP THREADPRIVATE(bils_cum) 57 ! net heat flux into the ocean below the ice : conduction + solar radiation 38 58 REAL, ALLOCATABLE, DIMENSION(:), PUBLIC, SAVE :: slab_bilg 39 59 !$OMP THREADPRIVATE(slab_bilg) 60 ! slab_bilg over cpl_pas timesteps 40 61 REAL, ALLOCATABLE, DIMENSION(:), PRIVATE, SAVE :: bilg_cum 41 62 !$OMP THREADPRIVATE(bilg_cum) 42 43 !**************************************************************************************** 63 ! wind stress saved over cpl_pas timesteps 64 REAL, ALLOCATABLE, DIMENSION(:), PRIVATE, SAVE :: taux_cum 65 !$OMP THREADPRIVATE(taux_cum) 66 REAL, ALLOCATABLE, DIMENSION(:), PRIVATE, SAVE :: tauy_cum 67 !$OMP THREADPRIVATE(tauy_cum) 68 69 !*********************************************************************************** 44 70 ! Parameters (could be read in def file: move to slab_init) 45 !*********************************************************************************** *****71 !*********************************************************************************** 46 72 ! snow and ice physical characteristics: 47 73 REAL, PARAMETER :: t_freeze=271.35 ! freezing sea water temp 48 74 REAL, PARAMETER :: t_melt=273.15 ! melting ice temp 49 75 REAL, PARAMETER :: sno_den=300. !mean snow density, kg/m3 50 REAL, PARAMETER :: ice_den=917. 51 REAL, PARAMETER :: sea_den=1025. 52 REAL, PARAMETER :: ice_cond=2.17*ice_den !conductivity 53 REAL, PARAMETER :: sno_cond=0.31*sno_den 76 REAL, PARAMETER :: ice_den=917. ! ice density 77 REAL, PARAMETER :: sea_den=1025. ! sea water density 78 REAL, PARAMETER :: ice_cond=2.17*ice_den !conductivity of ice 79 REAL, PARAMETER :: sno_cond=0.31*sno_den ! conductivity of snow 54 80 REAL, PARAMETER :: ice_cap=2067. ! specific heat capacity, snow and ice 81 REAL, PARAMETER :: sea_cap=3995. ! specific heat capacity, snow and ice 55 82 REAL, PARAMETER :: ice_lat=334000. ! freeze /melt latent heat snow and ice 56 83 … … 74 101 REAL, PARAMETER :: alb_ice_dry=0.75 !dry thick ice 75 102 REAL, PARAMETER :: alb_ice_wet=0.66 !melting thick ice 76 REAL, PARAMETER :: pen_frac=0.3 !fraction of penetrating shortwave (no snow) 103 REAL, PARAMETER :: pen_frac=0.3 !fraction of shortwave penetrating into the 104 ! ice (no snow) 77 105 REAL, PARAMETER :: pen_ext=1.5 !extinction of penetrating shortwave (m-1) 78 106 79 !**************************************************************************************** 107 ! horizontal transport 108 LOGICAL, PUBLIC, SAVE :: slab_hdiff 109 !$OMP THREADPRIVATE(slab_hdiff) 110 REAL, PRIVATE, SAVE :: coef_hdiff ! coefficient for horizontal diffusion 111 !$OMP THREADPRIVATE(coef_hdiff) 112 INTEGER, PUBLIC, SAVE :: slab_ekman, slab_cadj ! Ekman, conv adjustment 113 !$OMP THREADPRIVATE(slab_ekman) 114 !$OMP THREADPRIVATE(slab_cadj) 115 116 !*********************************************************************************** 80 117 81 118 CONTAINS 82 119 ! 83 !*********************************************************************************** *****120 !*********************************************************************************** 84 121 ! 85 122 SUBROUTINE ocean_slab_init(dtime, pctsrf_rst) 86 123 !, seaice_rst etc 87 124 88 use IOIPSL 89 90 ! For ok_xxx vars (Ekman...) 91 INCLUDE "clesphys.h" 125 USE ioipsl_getin_p_mod, ONLY : getin_p 126 USE mod_phys_lmdz_transfert_para, ONLY : gather 127 USE slab_heat_transp_mod, ONLY : ini_slab_transp 92 128 93 129 ! Input variables 94 !*********************************************************************************** *****130 !*********************************************************************************** 95 131 REAL, INTENT(IN) :: dtime 96 132 ! Variables read from restart file 97 REAL, DIMENSION(klon, nbsrf), INTENT(IN) :: pctsrf_rst 133 REAL, DIMENSION(klon, nbsrf), INTENT(IN) :: pctsrf_rst 134 ! surface fractions from start file 98 135 99 136 ! Local variables 100 !************************************************************************************ ****137 !************************************************************************************ 101 138 INTEGER :: error 139 REAL, DIMENSION(klon_glo) :: zmasq_glo 102 140 CHARACTER (len = 80) :: abort_message 103 141 CHARACTER (len = 20) :: modname = 'ocean_slab_intit' 104 142 105 !**************************************************************************************** 143 !*********************************************************************************** 144 ! Define some parameters 145 !*********************************************************************************** 146 ! Number of slab layers 147 nslay=2 148 CALL getin_p('slab_layers',nslay) 149 print *,'number of slab layers : ',nslay 150 ! Layer thickness 151 ALLOCATE(slabh(nslay), stat = error) 152 IF (error /= 0) THEN 153 abort_message='Pb allocation slabh' 154 CALL abort_physic(modname,abort_message,1) 155 ENDIF 156 slabh(1)=50. 157 IF (nslay.GT.1) THEN 158 slabh(2)=150. 159 END IF 160 161 ! cyang = 1/heat capacity of top layer (rho.c.H) 162 cyang=1/(slabh(1)*sea_den*sea_cap) 163 164 ! cpl_pas coupling period (update of tslab and ice fraction) 165 ! pour un calcul a chaque pas de temps, cpl_pas=1 166 cpl_pas = NINT(86400./dtime * 1.0) ! une fois par jour 167 CALL getin_p('cpl_pas',cpl_pas) 168 print *,'cpl_pas',cpl_pas 169 170 ! Horizontal diffusion 171 slab_hdiff=.FALSE. 172 CALL getin_p('slab_hdiff',slab_hdiff) 173 coef_hdiff=25000. 174 CALL getin_p('coef_hdiff',coef_hdiff) 175 ! Ekman transport 176 slab_ekman=0 177 CALL getin_p('slab_ekman',slab_ekman) 178 ! Convective adjustment 179 IF (nslay.EQ.1) THEN 180 slab_cadj=0 181 ELSE 182 slab_cadj=1 183 END IF 184 CALL getin_p('slab_cadj',slab_cadj) 185 186 !************************************************************************************ 106 187 ! Allocate surface fraction read from restart file 107 !************************************************************************************ ****188 !************************************************************************************ 108 189 ALLOCATE(fsic(klon), stat = error) 109 190 IF (error /= 0) THEN … … 112 193 ENDIF 113 194 fsic(:)=0. 195 !zmasq = continent fraction 114 196 WHERE (1.-zmasq(:)>EPSFRA) 115 197 fsic(:) = pctsrf_rst(:,is_sic)/(1.-zmasq(:)) 116 198 END WHERE 117 199 118 !************************************************************************************ ****119 ! Allocate saved variables120 !************************************************************************************ ****200 !************************************************************************************ 201 ! Allocate saved fields 202 !************************************************************************************ 121 203 ALLOCATE(tslab(klon,nslay), stat=error) 122 204 IF (error /= 0) CALL abort_physic & … … 136 218 bils_cum(:) = 0.0 137 219 138 IF (version_ocean=='sicINT') THEN 220 IF (version_ocean=='sicINT') THEN ! interactive sea ice 139 221 ALLOCATE(slab_bilg(klon), stat = error) 140 222 IF (error /= 0) THEN … … 161 243 END IF 162 244 163 !**************************************************************************************** 164 ! Define some parameters 165 !**************************************************************************************** 166 ! Layer thickness 167 ALLOCATE(slabh(nslay), stat = error) 168 IF (error /= 0) THEN 169 abort_message='Pb allocation slabh' 170 CALL abort_physic(modname,abort_message,1) 245 IF (slab_hdiff) THEN !horizontal diffusion 246 ALLOCATE(dt_hdiff(klon,nslay), stat = error) 247 IF (error /= 0) THEN 248 abort_message='Pb allocation dt_hdiff' 249 CALL abort_physic(modname,abort_message,1) 250 ENDIF 251 dt_hdiff(:,:) = 0.0 171 252 ENDIF 172 slabh(1)=50. 173 ! cyang = 1/heat capacity of top layer (rho.c.H) 174 cyang=1/(slabh(1)*4.228e+06) 175 176 ! cpl_pas periode de couplage avec slab (update tslab, pctsrf) 177 ! pour un calcul à chaque pas de temps, cpl_pas=1 178 cpl_pas = NINT(86400./dtime * 1.0) ! une fois par jour 179 CALL getin('cpl_pas',cpl_pas) 180 print *,'cpl_pas',cpl_pas 253 254 IF (slab_ekman.GT.0) THEN ! ekman transport 255 ALLOCATE(dt_ekman(klon,nslay), stat = error) 256 IF (error /= 0) THEN 257 abort_message='Pb allocation dt_ekman' 258 CALL abort_physic(modname,abort_message,1) 259 ENDIF 260 dt_ekman(:,:) = 0.0 261 ALLOCATE(taux_cum(klon), stat = error) 262 IF (error /= 0) THEN 263 abort_message='Pb allocation taux_cum' 264 CALL abort_physic(modname,abort_message,1) 265 ENDIF 266 taux_cum(:) = 0.0 267 ALLOCATE(tauy_cum(klon), stat = error) 268 IF (error /= 0) THEN 269 abort_message='Pb allocation tauy_cum' 270 CALL abort_physic(modname,abort_message,1) 271 ENDIF 272 tauy_cum(:) = 0.0 273 ENDIF 274 275 ! Initialize transport 276 IF (slab_hdiff.OR.(slab_ekman.GT.0)) THEN 277 CALL gather(zmasq,zmasq_glo) 278 !$OMP MASTER ! Only master thread 279 IF (is_mpi_root) THEN 280 CALL ini_slab_transp(zmasq_glo) 281 END IF 282 !$OMP END MASTER 283 END IF 181 284 182 285 END SUBROUTINE ocean_slab_init 183 286 ! 184 !*********************************************************************************** *****287 !*********************************************************************************** 185 288 ! 186 289 SUBROUTINE ocean_slab_frac(itime, dtime, jour, pctsrf_chg, is_modified) 187 290 188 USE limit_read_mod 189 190 ! INCLUDE "clesphys.h" 291 ! this routine sends back the sea ice and ocean fraction to the main physics 292 ! routine. Called only with interactive sea ice 191 293 192 294 ! Arguments 193 !************************************************************************************ ****194 INTEGER, INTENT(IN) :: itime ! numero du pas de temps courant195 INTEGER, INTENT(IN) :: jour ! jour a lire dans l'annee196 REAL , INTENT(IN) :: dtime ! p as de temps de la physique (ens)295 !************************************************************************************ 296 INTEGER, INTENT(IN) :: itime ! current timestep 297 INTEGER, INTENT(IN) :: jour ! day in year (not 298 REAL , INTENT(IN) :: dtime ! physics timestep (s) 197 299 REAL, DIMENSION(klon,nbsrf), INTENT(INOUT) :: pctsrf_chg ! sub-surface fraction 198 LOGICAL, INTENT(OUT) :: is_modified ! true if pctsrf is modified at this time step 199 200 ! Local variables 201 !**************************************************************************************** 202 203 IF (version_ocean == 'sicOBS'.OR. version_ocean == 'sicNO') THEN 204 CALL limit_read_frac(itime, dtime, jour, pctsrf_chg, is_modified) 205 ELSE 300 LOGICAL, INTENT(OUT) :: is_modified ! true if pctsrf is 301 ! modified at this time step 302 206 303 pctsrf_chg(:,is_oce)=(1.-fsic(:))*(1.-zmasq(:)) 207 304 pctsrf_chg(:,is_sic)=fsic(:)*(1.-zmasq(:)) 208 305 is_modified=.TRUE. 209 END IF210 306 211 307 END SUBROUTINE ocean_slab_frac 212 308 ! 213 !************************************************************************************ ****309 !************************************************************************************ 214 310 ! 215 311 SUBROUTINE ocean_slab_noice( & … … 224 320 225 321 USE calcul_fluxs_mod 322 USE slab_heat_transp_mod, ONLY: divgrad_phy, slab_ekman1, slab_ekman2 323 USE mod_phys_lmdz_para 226 324 227 325 INCLUDE "clesphys.h" 228 326 327 ! This routine 328 ! (1) computes surface turbulent fluxes over points with some open ocean 329 ! (2) reads additional Q-flux (everywhere) 330 ! (3) computes horizontal transport (diffusion & Ekman) 331 ! (4) updates slab temperature every cpl_pas ; creates new ice if needed. 332 333 ! Note : 334 ! klon total number of points 335 ! knon number of points with open ocean (varies with time) 336 ! knindex gives position of the knon points within klon. 337 ! In general, local saved variables have klon values 338 ! variables exchanged with PBL module have knon. 339 229 340 ! Input arguments 230 !**************************************************************************************** 231 INTEGER, INTENT(IN) :: itime 232 INTEGER, INTENT(IN) :: jour 233 INTEGER, INTENT(IN) :: knon 234 INTEGER, DIMENSION(klon), INTENT(IN) :: knindex 235 REAL, INTENT(IN) :: dtime 236 REAL, DIMENSION(klon), INTENT(IN) :: p1lay 237 REAL, DIMENSION(klon), INTENT(IN) :: cdragh, cdragq, cdragm 238 REAL, DIMENSION(klon), INTENT(IN) :: precip_rain, precip_snow 239 REAL, DIMENSION(klon), INTENT(IN) :: temp_air, spechum 240 REAL, DIMENSION(klon), INTENT(IN) :: AcoefH, AcoefQ, BcoefH, BcoefQ 241 REAL, DIMENSION(klon), INTENT(IN) :: AcoefU, AcoefV, BcoefU, BcoefV 242 REAL, DIMENSION(klon), INTENT(IN) :: ps 243 REAL, DIMENSION(klon), INTENT(IN) :: u1, v1, gustiness 244 REAL, DIMENSION(klon), INTENT(IN) :: tsurf_in 245 REAL, DIMENSION(klon), INTENT(INOUT) :: radsol 341 !*********************************************************************************** 342 INTEGER, INTENT(IN) :: itime ! current timestep INTEGER, 343 INTEGER, INTENT(IN) :: jour ! day in year (for Q-Flux) 344 INTEGER, INTENT(IN) :: knon ! number of points 345 INTEGER, DIMENSION(klon), INTENT(IN) :: knindex 346 REAL, INTENT(IN) :: dtime ! timestep (s) 347 REAL, DIMENSION(klon), INTENT(IN) :: p1lay 348 REAL, DIMENSION(klon), INTENT(IN) :: cdragh, cdragq, cdragm 349 ! drag coefficients 350 REAL, DIMENSION(klon), INTENT(IN) :: precip_rain, precip_snow 351 REAL, DIMENSION(klon), INTENT(IN) :: temp_air, spechum ! near surface T, q 352 REAL, DIMENSION(klon), INTENT(IN) :: AcoefH, AcoefQ, BcoefH, BcoefQ 353 REAL, DIMENSION(klon), INTENT(IN) :: AcoefU, AcoefV, BcoefU, BcoefV 354 ! exchange coefficients for boundary layer scheme 355 REAL, DIMENSION(klon), INTENT(IN) :: ps ! surface pressure 356 REAL, DIMENSION(klon), INTENT(IN) :: u1, v1, gustiness ! surface wind 357 REAL, DIMENSION(klon), INTENT(IN) :: tsurf_in ! surface temperature 358 REAL, DIMENSION(klon), INTENT(INOUT) :: radsol ! net surface radiative flux 246 359 247 360 ! In/Output arguments 248 !************************************************************************************ ****249 REAL, DIMENSION(klon), INTENT(INOUT) :: snow 361 !************************************************************************************ 362 REAL, DIMENSION(klon), INTENT(INOUT) :: snow ! in kg/m2 250 363 251 364 ! Output arguments 252 !************************************************************************************ ****365 !************************************************************************************ 253 366 REAL, DIMENSION(klon), INTENT(OUT) :: qsurf 254 367 REAL, DIMENSION(klon), INTENT(OUT) :: evap, fluxsens, fluxlat 255 368 REAL, DIMENSION(klon), INTENT(OUT) :: flux_u1, flux_v1 256 REAL, DIMENSION(klon), INTENT(OUT) :: tsurf_new 369 REAL, DIMENSION(klon), INTENT(OUT) :: tsurf_new ! new surface tempearture 257 370 REAL, DIMENSION(klon), INTENT(OUT) :: dflux_s, dflux_l 258 371 REAL, DIMENSION(klon), INTENT(OUT) :: qflux 259 372 260 373 ! Local variables 261 !**************************************************************************************** 262 INTEGER :: i,ki 263 ! surface fluxes 374 !************************************************************************************ 375 INTEGER :: i,ki,k 376 REAL :: t_cadj 377 ! for surface heat fluxes 264 378 REAL, DIMENSION(klon) :: cal, beta, dif_grnd 265 ! f lux correction379 ! for Q-Flux computation: d/dt SST, d/dt ice volume (kg/m2), surf fluxes 266 380 REAL, DIMENSION(klon) :: diff_sst, diff_siv, lmt_bils 267 ! surface wind stress381 ! for surface wind stress 268 382 REAL, DIMENSION(klon) :: u0, v0 269 383 REAL, DIMENSION(klon) :: u1_lay, v1_lay 270 ! ice creation384 ! for new ice creation 271 385 REAL :: e_freeze, h_new, dfsic 272 273 !**************************************************************************************** 274 ! 1) Flux calculation 275 ! 276 !**************************************************************************************** 277 cal(:) = 0. 278 beta(:) = 1. 279 dif_grnd(:) = 0. 386 ! horizontal diffusion and Ekman local vars 387 ! dimension = global domain (klon_glo) instead of // subdomains 388 REAL, DIMENSION(klon_glo,nslay) :: dt_hdiff_glo, dt_ekman_glo 389 ! dt_ekman_glo saved for diagnostic, dt_ekman_tmp used for time loop 390 REAL, DIMENSION(klon_glo,nslay) :: dt_hdiff_tmp, dt_ekman_tmp 391 REAL, DIMENSION(klon_glo,nslay) :: tslab_glo 392 REAL, DIMENSION(klon_glo) :: taux_glo,tauy_glo 393 394 !**************************************************************************************** 395 ! 1) Surface fluxes calculation 396 ! 397 !**************************************************************************************** 398 cal(:) = 0. ! infinite thermal inertia 399 beta(:) = 1. ! wet surface 400 dif_grnd(:) = 0. ! no diffusion into ground 280 401 281 402 ! Suppose zero surface speed … … 285 406 v1_lay(:) = v1(:) - v0(:) 286 407 408 ! Compute latent & sensible fluxes 287 409 CALL calcul_fluxs(knon, is_oce, dtime, & 288 410 tsurf_in, p1lay, cal, beta, cdragh, cdragq, ps, & … … 292 414 tsurf_new, evap, fluxlat, fluxsens, dflux_s, dflux_l) 293 415 294 ! - Flux calculation at first modele level for U and V 295 CALL calcul_flux_wind(knon, dtime, & 296 u0, v0, u1, v1, gustiness, cdragm, & 297 AcoefU, AcoefV, BcoefU, BcoefV, & 298 p1lay, temp_air, & 299 flux_u1, flux_v1) 300 301 ! Accumulate total fluxes locally 416 ! save total cumulated heat fluxes locally 417 ! radiative + turbulent + melt of falling snow 302 418 slab_bils(:)=0. 303 419 DO i=1,knon … … 306 422 -precip_snow(i)*ice_lat*(1.+snow_wfact*fsic(ki))) 307 423 bils_cum(ki)=bils_cum(ki)+slab_bils(ki) 308 ! Also taux, tauy, saved vars...309 424 END DO 310 425 311 !**************************************************************************************** 312 ! 2) Get global variables lmt_bils and diff_sst from file limit_slab.nc 426 ! Compute surface wind stress 427 CALL calcul_flux_wind(knon, dtime, & 428 u0, v0, u1, v1, gustiness, cdragm, & 429 AcoefU, AcoefV, BcoefU, BcoefV, & 430 p1lay, temp_air, & 431 flux_u1, flux_v1) 432 433 ! save cumulated wind stress 434 IF (slab_ekman.GT.0) THEN 435 DO i=1,knon 436 ki=knindex(i) 437 taux_cum(ki)=taux_cum(ki)+flux_u1(i)*(1.-fsic(ki))/cpl_pas 438 tauy_cum(ki)=tauy_cum(ki)+flux_v1(i)*(1.-fsic(ki))/cpl_pas 439 END DO 440 ENDIF 441 442 !**************************************************************************************** 443 ! 2) Q-Flux : get global variables lmt_bils, diff_sst and diff_siv from file limit_slab.nc 313 444 ! 314 445 !**************************************************************************************** 315 446 lmt_bils(:)=0. 316 CALL limit_slab(itime, dtime, jour, lmt_bils, diff_sst, diff_siv) ! global pour un processus447 CALL limit_slab(itime, dtime, jour, lmt_bils, diff_sst, diff_siv) 317 448 ! lmt_bils and diff_sst,siv saved by limit_slab 318 449 qflux(:)=lmt_bils(:)+diff_sst(:)/cyang/86400.-diff_siv(:)*ice_den*ice_lat/86400. … … 320 451 321 452 !**************************************************************************************** 322 ! 3) Recalculate new temperature 323 ! 453 ! 3) Recalculate new temperature (add Surf fluxes, Q-Flux, Ocean transport) 454 ! Bring to freezing temp and make sea ice if necessary 455 ! 324 456 !***********************************************o***************************************** 325 457 tsurf_new=tsurf_in 326 458 IF (MOD(itime,cpl_pas).EQ.0) THEN ! time to update tslab & fraction 327 ! Compute transport 328 ! Add read QFlux and SST tendency 329 tslab(:,1)=tslab(:,1)+qflux(:)*cyang*dtime*cpl_pas 330 ! Add cumulated surface fluxes 331 tslab(:,1)=tslab(:,1)+bils_cum(:)*cyang*dtime 332 ! Update surface temperature 333 SELECT CASE(version_ocean) 334 CASE('sicNO') 335 DO i=1,knon 336 ki=knindex(i) 337 tsurf_new(i)=tslab(ki,1) 459 ! *********************************** 460 ! Horizontal transport 461 ! *********************************** 462 IF (slab_ekman.GT.0) THEN 463 ! copy wind stress to global var 464 CALL gather(taux_cum,taux_glo) 465 CALL gather(tauy_cum,tauy_glo) 466 END IF 467 468 IF (slab_hdiff.OR.(slab_ekman.GT.0)) THEN 469 CALL gather(tslab,tslab_glo) 470 ! Compute horiz transport on one process only 471 !$OMP MASTER ! Only master thread 472 IF (is_mpi_root) THEN ! Only master processus 473 IF (slab_hdiff) THEN 474 dt_hdiff_glo(:,:)=0. 475 END IF 476 IF (slab_ekman.GT.0) THEN 477 dt_ekman_glo(:,:)=0. 478 END IF 479 DO i=1,cpl_pas ! time splitting for numerical stability 480 IF (slab_ekman.GT.0) THEN 481 SELECT CASE (slab_ekman) 482 CASE (1) 483 CALL slab_ekman1(taux_glo,tauy_glo,tslab_glo,dt_ekman_tmp) 484 CASE (2) 485 CALL slab_ekman2(taux_glo,tauy_glo,tslab_glo,dt_ekman_tmp) 486 CASE DEFAULT 487 dt_ekman_tmp(:,:)=0. 488 END SELECT 489 dt_ekman_glo(:,:)=dt_ekman_glo(:,:)+dt_ekman_tmp(:,:) 490 ! convert dt_ekman from K.s-1.(kg.m-2) to K.s-1 491 DO k=1,nslay 492 dt_ekman_tmp(:,k)=dt_ekman_tmp(:,k)/(slabh(k)*sea_den) 493 ENDDO 494 tslab_glo=tslab_glo+dt_ekman_tmp*dtime 495 ENDIF 496 IF (slab_hdiff) THEN ! horizontal diffusion 497 ! laplacian of slab T 498 CALL divgrad_phy(nslay,tslab_glo,dt_hdiff_tmp) 499 ! multiply by diff coef and normalize to 50m slab equivalent 500 dt_hdiff_tmp=dt_hdiff_tmp*coef_hdiff*50./SUM(slabh) 501 dt_hdiff_glo(:,:)=dt_hdiff_glo(:,:)+ dt_hdiff_tmp(:,:) 502 tslab_glo=tslab_glo+dt_hdiff_tmp*dtime 503 END IF 504 END DO ! time splitting 505 IF (slab_hdiff) THEN 506 !dt_hdiff_glo saved in W/m2 507 DO k=1,nslay 508 dt_hdiff_glo(:,k)=dt_hdiff_glo(:,k)*slabh(k)*sea_den*sea_cap/cpl_pas 338 509 END DO 339 CASE('sicOBS') ! check for sea ice or tslab below freezing 340 DO i=1,knon 341 ki=knindex(i) 342 IF ((tslab(ki,1).LT.t_freeze).OR.(fsic(ki).GT.epsfra)) THEN 343 tslab(ki,1)=t_freeze 344 END IF 345 tsurf_new(i)=tslab(ki,1) 346 END DO 347 CASE('sicINT') 348 DO i=1,knon 349 ki=knindex(i) 350 IF (fsic(ki).LT.epsfra) THEN ! Free of ice 351 IF (tslab(ki,1).LT.t_freeze) THEN ! create new ice 352 ! quantity of new ice formed 353 e_freeze=(t_freeze-tslab(ki,1))/cyang/ice_lat 354 ! new ice 355 tice(ki)=t_freeze 356 fsic(ki)=MIN(ice_frac_max,e_freeze/h_ice_thin) 357 IF (fsic(ki).GT.ice_frac_min) THEN 358 seaice(ki)=MIN(e_freeze/fsic(ki),h_ice_max) 359 tslab(ki,1)=t_freeze 360 ELSE 361 fsic(ki)=0. 362 END IF 363 tsurf_new(i)=t_freeze 364 ELSE 365 tsurf_new(i)=tslab(ki,1) 366 END IF 367 ELSE ! ice present 368 tsurf_new(i)=t_freeze 369 IF (tslab(ki,1).LT.t_freeze) THEN ! create new ice 370 ! quantity of new ice formed over open ocean 371 e_freeze=(t_freeze-tslab(ki,1))/cyang*(1.-fsic(ki)) & 372 /(ice_lat+ice_cap/2.*(t_freeze-tice(ki))) 373 ! new ice height and fraction 374 h_new=MIN(h_ice_new,seaice(ki)) ! max new height ice_new 375 dfsic=MIN(ice_frac_max-fsic(ki),e_freeze/h_new) 376 h_new=MIN(e_freeze/dfsic,h_ice_max) 377 ! update tslab to freezing over open ocean only 378 tslab(ki,1)=tslab(ki,1)*fsic(ki)+t_freeze*(1.-fsic(ki)) 379 ! update sea ice 380 seaice(ki)=(h_new*dfsic+seaice(ki)*fsic(ki)) & 381 /(dfsic+fsic(ki)) 382 fsic(ki)=fsic(ki)+dfsic 383 ! update snow? 384 END IF !freezing 385 END IF ! sea ice present 386 END DO 387 END SELECT 388 bils_cum(:)=0.0! clear cumulated fluxes 510 END IF 511 IF (slab_ekman.GT.0) THEN 512 ! dt_ekman_glo saved in W/m2 513 dt_ekman_glo(:,:)=dt_ekman_glo(:,:)*sea_cap/cpl_pas 514 END IF 515 END IF ! is_mpi_root 516 !$OMP END MASTER 517 !$OMP BARRIER 518 ! Send new fields back to all processes 519 CALL Scatter(tslab_glo,tslab) 520 IF (slab_hdiff) THEN 521 CALL Scatter(dt_hdiff_glo,dt_hdiff) 522 END IF 523 IF (slab_ekman.GT.0) THEN 524 CALL Scatter(dt_ekman_glo,dt_ekman) 525 ! clear wind stress 526 taux_cum(:)=0. 527 tauy_cum(:)=0. 528 END IF 529 ENDIF ! transport 530 531 ! *********************************** 532 ! Other heat fluxes 533 ! *********************************** 534 ! Add read QFlux 535 tslab(:,1)=tslab(:,1)+qflux(:)*cyang*dtime*cpl_pas 536 ! Add cumulated surface fluxes 537 tslab(:,1)=tslab(:,1)+bils_cum(:)*cyang*dtime 538 ! Convective adjustment if 2 layers 539 IF ((nslay.GT.1).AND.(slab_cadj.GT.0)) THEN 540 DO i=1,klon 541 IF (tslab(i,2).GT.tslab(i,1)) THEN 542 ! mean (mass-weighted) temperature 543 t_cadj=SUM(tslab(i,:)*slabh(:))/SUM(slabh(:)) 544 tslab(i,1)=t_cadj 545 tslab(i,2)=t_cadj 546 END IF 547 END DO 548 END IF 549 ! *********************************** 550 ! Update surface temperature and ice 551 ! *********************************** 552 SELECT CASE(version_ocean) 553 CASE('sicNO') ! no sea ice even below freezing ! 554 DO i=1,knon 555 ki=knindex(i) 556 tsurf_new(i)=tslab(ki,1) 557 END DO 558 CASE('sicOBS') ! "realistic" case, for prescribed sea ice 559 ! tslab cannot be below freezing, or above it if there is sea ice 560 DO i=1,knon 561 ki=knindex(i) 562 IF ((tslab(ki,1).LT.t_freeze).OR.(fsic(ki).GT.epsfra)) THEN 563 tslab(ki,1)=t_freeze 564 END IF 565 tsurf_new(i)=tslab(ki,1) 566 END DO 567 CASE('sicINT') ! interactive sea ice 568 DO i=1,knon 569 ki=knindex(i) 570 IF (fsic(ki).LT.epsfra) THEN ! Free of ice 571 IF (tslab(ki,1).LT.t_freeze) THEN ! create new ice 572 ! quantity of new ice formed 573 e_freeze=(t_freeze-tslab(ki,1))/cyang/ice_lat 574 ! new ice 575 tice(ki)=t_freeze 576 fsic(ki)=MIN(ice_frac_max,e_freeze/h_ice_thin) 577 IF (fsic(ki).GT.ice_frac_min) THEN 578 seaice(ki)=MIN(e_freeze/fsic(ki),h_ice_max) 579 tslab(ki,1)=t_freeze 580 ELSE 581 fsic(ki)=0. 582 END IF 583 tsurf_new(i)=t_freeze 584 ELSE 585 tsurf_new(i)=tslab(ki,1) 586 END IF 587 ELSE ! ice present 588 tsurf_new(i)=t_freeze 589 IF (tslab(ki,1).LT.t_freeze) THEN ! create new ice 590 ! quantity of new ice formed over open ocean 591 e_freeze=(t_freeze-tslab(ki,1))/cyang*(1.-fsic(ki)) & 592 /(ice_lat+ice_cap/2.*(t_freeze-tice(ki))) 593 ! new ice height and fraction 594 h_new=MIN(h_ice_new,seaice(ki)) ! max new height ice_new 595 dfsic=MIN(ice_frac_max-fsic(ki),e_freeze/h_new) 596 h_new=MIN(e_freeze/dfsic,h_ice_max) 597 ! update tslab to freezing over open ocean only 598 tslab(ki,1)=tslab(ki,1)*fsic(ki)+t_freeze*(1.-fsic(ki)) 599 ! update sea ice 600 seaice(ki)=(h_new*dfsic+seaice(ki)*fsic(ki)) & 601 /(dfsic+fsic(ki)) 602 fsic(ki)=fsic(ki)+dfsic 603 ! update snow? 604 END IF ! tslab below freezing 605 END IF ! sea ice present 606 END DO 607 END SELECT 608 bils_cum(:)=0.0! clear cumulated fluxes 389 609 END IF ! coupling time 390 610 END SUBROUTINE ocean_slab_noice … … 530 750 seaice(ki) = MAX(0.0,seaice(ki)-(evap(i)-snow_evap)*dtime) 531 751 ENDIF 532 ! Melt / Freeze from above if Tsurf>0752 ! Melt / Freeze snow from above if Tsurf>0 533 753 IF (tsurf_new(i).GT.t_melt) THEN 534 ! energy available for melting snow (in kg /m2 of snow)754 ! energy available for melting snow (in kg of melted snow /m2) 535 755 e_melt = MIN(MAX(snow(i)*(tsurf_new(i)-t_melt)*ice_cap/2. & 536 756 /(ice_lat+ice_cap/2.*(t_melt-tice(ki))),0.0),snow(i)) … … 672 892 END IF ! coupling time 673 893 674 !tests fraction glace894 !tests ice fraction 675 895 WHERE (fsic.LT.ice_frac_min) 676 896 tslab(:,1)=tslab(:,1)-fsic*seaice*ice_lat*cyang … … 691 911 IF (ALLOCATED(tslab)) DEALLOCATE(tslab) 692 912 IF (ALLOCATED(fsic)) DEALLOCATE(fsic) 913 IF (ALLOCATED(tice)) DEALLOCATE(tice) 914 IF (ALLOCATED(seaice)) DEALLOCATE(seaice) 693 915 IF (ALLOCATED(slab_bils)) DEALLOCATE(slab_bils) 694 916 IF (ALLOCATED(slab_bilg)) DEALLOCATE(slab_bilg) 695 917 IF (ALLOCATED(bilg_cum)) DEALLOCATE(bilg_cum) 696 918 IF (ALLOCATED(bils_cum)) DEALLOCATE(bils_cum) 697 IF (ALLOCATED(tslab)) DEALLOCATE(tslab) 919 IF (ALLOCATED(taux_cum)) DEALLOCATE(taux_cum) 920 IF (ALLOCATED(tauy_cum)) DEALLOCATE(tauy_cum) 921 IF (ALLOCATED(dt_ekman)) DEALLOCATE(dt_ekman) 922 IF (ALLOCATED(dt_hdiff)) DEALLOCATE(dt_hdiff) 698 923 699 924 END SUBROUTINE ocean_slab_final
Note: See TracChangeset
for help on using the changeset viewer.