Changeset 14072 for NEMO/trunk/src/ICE
- Timestamp:
- 2020-12-04T08:48:38+01:00 (3 years ago)
- Location:
- NEMO/trunk/src/ICE
- Files:
-
- 22 edited
- 2 copied
Legend:
- Unmodified
- Added
- Removed
-
NEMO/trunk/src/ICE/ice.F90
r14006 r14072 64 64 !! sv_i | - | Sea ice salt content | pss.m | 65 65 !! oa_i | - | Sea ice areal age content | s | 66 !! e_i | | Ice enthalpy | J/m2 | 67 !! | e_i_1d | Ice enthalpy per unit vol. | J/m3 | 68 !! e_s | | Snow enthalpy | J/m2 | 69 !! | e_s_1d | Snow enthalpy per unit vol. | J/m3 | 66 !! e_i | | Ice enthalpy | J/m2 | 67 !! | e_i_1d | Ice enthalpy per unit vol. | J/m3 | 68 !! e_s | | Snow enthalpy | J/m2 | 69 !! | e_s_1d | Snow enthalpy per unit vol. | J/m3 | 70 70 !! a_ip | - | Ice pond concentration | | 71 71 !! v_ip | - | Ice pond volume per unit area| m | … … 108 108 !! tm_i | - | Mean sea ice temperature | K | 109 109 !! tm_s | - | Mean snow temperature | K | 110 !! et_i | - | Total ice enthalpy | J/m2 | 111 !! et_s | - | Total snow enthalpy | J/m2 | 112 !! bv_i | - | relative brine volume | ??? | 110 !! et_i | - | Total ice enthalpy | J/m2 | 111 !! et_s | - | Total snow enthalpy | J/m2 | 112 !! bv_i | - | relative brine volume | ??? | 113 113 !! at_ip | - | Total ice pond concentration | | 114 114 !! hm_ip | - | Mean ice pond depth | m | … … 122 122 !!---------------------------------------------------------------------- 123 123 ! !!** ice-generic parameters namelist (nampar) ** 124 INTEGER , PUBLIC :: jpl !: number of ice categories 125 INTEGER , PUBLIC :: nlay_i !: number of ice layers 126 INTEGER , PUBLIC :: nlay_s !: number of snow layers 124 INTEGER , PUBLIC :: jpl !: number of ice categories 125 INTEGER , PUBLIC :: nlay_i !: number of ice layers 126 INTEGER , PUBLIC :: nlay_s !: number of snow layers 127 127 LOGICAL , PUBLIC :: ln_virtual_itd !: virtual ITD mono-category parameterization (T) or not (F) 128 128 LOGICAL , PUBLIC :: ln_icedyn !: flag for ice dynamics (T) or not (F) … … 137 137 ! !!** ice-itd namelist (namitd) ** 138 138 REAL(wp), PUBLIC :: rn_himin !: minimum ice thickness 139 139 140 140 ! !!** ice-dynamics namelist (namdyn) ** 141 141 REAL(wp), PUBLIC :: rn_ishlat !: lateral boundary condition for sea-ice 142 LOGICAL , PUBLIC :: ln_landfast_L16 !: landfast ice parameterizationfrom lemieux2016 142 LOGICAL , PUBLIC :: ln_landfast_L16 !: landfast ice parameterizationfrom lemieux2016 143 143 REAL(wp), PUBLIC :: rn_lf_depfra !: fraction of ocean depth that ice must reach to initiate landfast ice 144 REAL(wp), PUBLIC :: rn_lf_bfr !: maximum bottom stress per unit area of contact (lemieux2016) or per unit volume (home) 144 REAL(wp), PUBLIC :: rn_lf_bfr !: maximum bottom stress per unit area of contact (lemieux2016) or per unit volume (home) 145 145 REAL(wp), PUBLIC :: rn_lf_relax !: relaxation time scale (s-1) to reach static friction 146 146 REAL(wp), PUBLIC :: rn_lf_tensile !: isotropic tensile strength … … 153 153 LOGICAL , PUBLIC :: ln_rhg_EVP ! EVP rheology switch, used for rdgrft and rheology 154 154 LOGICAL , PUBLIC :: ln_rhg_EAP ! EAP rheology switch, used for rdgrft and rheology 155 LOGICAL , PUBLIC :: ln_aEVP !: using adaptive EVP (T or F) 155 LOGICAL , PUBLIC :: ln_aEVP !: using adaptive EVP (T or F) 156 156 REAL(wp), PUBLIC :: rn_creepl !: creep limit (has to be low enough, circa 10-9 m/s, depending on rheology) 157 157 REAL(wp), PUBLIC :: rn_ecc !: eccentricity of the elliptical yield curve 158 158 INTEGER , PUBLIC :: nn_nevp !: number of iterations for subcycling 159 REAL(wp), PUBLIC :: rn_relast !: ratio => telast/rDt_ice (1/3 or 1/9 depending on nb of subcycling nevp) 160 INTEGER , PUBLIC :: nn_rhg_chkcvg !: check ice rheology convergence 159 REAL(wp), PUBLIC :: rn_relast !: ratio => telast/rDt_ice (1/3 or 1/9 depending on nb of subcycling nevp) 160 INTEGER , PUBLIC :: nn_rhg_chkcvg !: check ice rheology convergence 161 161 ! -- vp 162 162 LOGICAL , PUBLIC :: ln_rhg_VP !: VP rheology … … 181 181 INTEGER , PUBLIC :: nn_flxdist !: Redistribute heat flux over ice categories 182 182 ! ! =-1 Do nothing (needs N(cat) fluxes) 183 ! ! = 0 Average N(cat) fluxes then apply the average over the N(cat) ice 183 ! ! = 0 Average N(cat) fluxes then apply the average over the N(cat) ice 184 184 ! ! = 1 Average N(cat) fluxes then redistribute over the N(cat) ice using T-ice and albedo sensitivity 185 185 ! ! = 2 Redistribute a single flux over categories 186 186 ! -- icethd_zdf -- ! 187 LOGICAL , PUBLIC :: ln_cndflx !: use conduction flux as surface boundary condition (instead of qsr and qns) 188 LOGICAL , PUBLIC :: ln_cndemulate !: emulate conduction flux (if not provided) 187 LOGICAL , PUBLIC :: ln_cndflx !: use conduction flux as surface boundary condition (instead of qsr and qns) 188 LOGICAL , PUBLIC :: ln_cndemulate !: emulate conduction flux (if not provided) 189 189 ! ! Conduction flux as surface forcing or not 190 190 INTEGER, PUBLIC, PARAMETER :: np_cnd_OFF = 0 !: no forcing from conduction flux (ice thermodynamics forced via qsr and qns) … … 192 192 INTEGER, PUBLIC, PARAMETER :: np_cnd_EMU = 2 !: emulate conduction flux via icethd_zdf.F90 (BL99) (1st round compute qcn and qsr_tr, 2nd round use it) 193 193 INTEGER, PUBLIC :: nn_qtrice !: Solar flux transmitted thru the surface scattering layer: 194 ! ! = 0 Grenfell and Maykut 1977 (depends on cloudiness and is 0 when there is snow) 194 ! ! = 0 Grenfell and Maykut 1977 (depends on cloudiness and is 0 when there is snow) 195 195 ! ! = 1 Lebrun 2019 (equals 0.3 anytime with different melting/dry snw conductivities) 196 196 ! … … 198 198 LOGICAL , PUBLIC :: ln_cndi_U64 !: thermal conductivity: Untersteiner (1964) 199 199 LOGICAL , PUBLIC :: ln_cndi_P07 !: thermal conductivity: Pringle et al (2007) 200 REAL(wp), PUBLIC :: rn_cnd_s !: thermal conductivity of the snow [W/m/K] 200 REAL(wp), PUBLIC :: rn_cnd_s !: thermal conductivity of the snow [W/m/K] 201 201 REAL(wp), PUBLIC :: rn_kappa_i !: coef. for the extinction of radiation in sea ice, Grenfell et al. (2006) [1/m] 202 202 REAL(wp), PUBLIC :: rn_kappa_s !: coef. for the extinction of radiation in snw (nn_qtrice=0) [1/m] … … 236 236 INTEGER , PUBLIC :: jiceprt !: debug j-point 237 237 238 ! !!** some other parameters 238 ! !!** some other parameters 239 239 INTEGER , PUBLIC :: kt_ice !: iteration number 240 240 REAL(wp), PUBLIC :: rDt_ice !: ice time step 241 241 REAL(wp), PUBLIC :: r1_Dt_ice !: = 1. / rDt_ice 242 242 REAL(wp), PUBLIC :: r1_nlay_i !: 1 / nlay_i 243 REAL(wp), PUBLIC :: r1_nlay_s !: 1 / nlay_s 243 REAL(wp), PUBLIC :: r1_nlay_s !: 1 / nlay_s 244 244 REAL(wp), PUBLIC :: rswitch !: switch for the presence of ice (1) or not (0) 245 245 REAL(wp), PUBLIC :: rdiag_v, rdiag_s, rdiag_t, rdiag_fv, rdiag_fs, rdiag_ft !: conservation diagnostics 246 REAL(wp), PUBLIC, PARAMETER :: epsi06 = 1.e-06_wp !: small number 247 REAL(wp), PUBLIC, PARAMETER :: epsi10 = 1.e-10_wp !: small number 248 REAL(wp), PUBLIC, PARAMETER :: epsi20 = 1.e-20_wp !: small number 246 REAL(wp), PUBLIC, PARAMETER :: epsi06 = 1.e-06_wp !: small number 247 REAL(wp), PUBLIC, PARAMETER :: epsi10 = 1.e-10_wp !: small number 248 REAL(wp), PUBLIC, PARAMETER :: epsi20 = 1.e-20_wp !: small number 249 249 250 250 ! !!** define arrays … … 259 259 REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) :: rdg_conv 260 260 ! 261 REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) :: t_bo !: Sea-Ice bottom temperature [Kelvin] 261 REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) :: t_bo !: Sea-Ice bottom temperature [Kelvin] 262 262 REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) :: qlead !: heat balance of the lead (or of the open ocean) 263 263 REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) :: qsb_ice_bot !: net downward heat flux from the ice to the ocean … … 306 306 REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) :: qt_atm_oi !: heat flux at the interface atm-[oce+ice] [W.m-2] 307 307 REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) :: qt_oce_ai !: heat flux at the interface oce-[atm+ice] [W.m-2] 308 308 309 309 ! heat flux associated with ice-atmosphere mass exchange 310 310 REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) :: hfx_sub !: heat flux for sublimation [W.m-2] … … 389 389 REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) :: u_ice_b, v_ice_b !: ice velocity 390 390 REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) :: at_i_b !: ice concentration (total) 391 391 392 392 !!---------------------------------------------------------------------- 393 393 !! * Ice thickness distribution variables 394 394 !!---------------------------------------------------------------------- 395 395 REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:) :: hi_max !: Boundary of ice thickness categories in thickness space 396 REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:) :: hi_mean !: Mean ice thickness in catgories 396 REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:) :: hi_mean !: Mean ice thickness in catgories 397 397 ! 398 398 !!---------------------------------------------------------------------- … … 405 405 REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) :: diag_trp_sv !: transport of salt content 406 406 ! 407 REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) :: diag_heat !: snw/ice heat content variation [W/m2] 408 REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) :: diag_sice !: ice salt content variation [] 409 REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) :: diag_vice !: ice volume variation [m/s] 410 REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) :: diag_vsnw !: snw volume variation [m/s] 411 REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) :: diag_aice !: ice conc. variation [s-1] 412 REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) :: diag_vpnd !: pond volume variation [m/s] 407 REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) :: diag_heat !: snw/ice heat content variation [W/m2] 408 REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) :: diag_sice !: ice salt content variation [] 409 REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) :: diag_vice !: ice volume variation [m/s] 410 REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) :: diag_vsnw !: snw volume variation [m/s] 411 REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) :: diag_aice !: ice conc. variation [s-1] 412 REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) :: diag_vpnd !: pond volume variation [m/s] 413 413 ! 414 414 REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) :: diag_adv_mass !: advection of mass (kg/m2/s) … … 430 430 !!---------------------------------------------------------------------- 431 431 ! Extra sea ice diagnostics to address the data request 432 REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) :: t_si !: Temperature at Snow-ice interface (K) 433 REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) :: tm_si !: mean temperature at the snow-ice interface (K) 432 REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) :: t_si !: Temperature at Snow-ice interface (K) 433 REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) :: tm_si !: mean temperature at the snow-ice interface (K) 434 434 REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) :: qcn_ice_bot !: Bottom conduction flux (W/m2) 435 435 REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) :: qcn_ice_top !: Surface conduction flux (W/m2) … … 469 469 & sfx_res (jpi,jpj) , sfx_bri (jpi,jpj) , sfx_dyn(jpi,jpj) , sfx_sub(jpi,jpj) , sfx_lam(jpi,jpj) , & 470 470 & sfx_bog (jpi,jpj) , sfx_bom (jpi,jpj) , sfx_sum(jpi,jpj) , sfx_sni(jpi,jpj) , sfx_opw(jpi,jpj) , & 471 & hfx_res (jpi,jpj) , hfx_snw (jpi,jpj) , hfx_sub(jpi,jpj) , & 471 & hfx_res (jpi,jpj) , hfx_snw (jpi,jpj) , hfx_sub(jpi,jpj) , & 472 472 & qt_atm_oi (jpi,jpj) , qt_oce_ai (jpi,jpj) , fhld (jpi,jpj) , & 473 473 & hfx_sum (jpi,jpj) , hfx_bom (jpi,jpj) , hfx_bog(jpi,jpj) , hfx_dif(jpi,jpj) , & … … 513 513 ii = ii + 1 514 514 ALLOCATE( u_ice_b(jpi,jpj) , v_ice_b(jpi,jpj) , at_i_b(jpi,jpj) , STAT=ierr(ii) ) 515 515 516 516 ! * Ice thickness distribution variables 517 517 ii = ii + 1 … … 520 520 ! * Ice diagnostics 521 521 ii = ii + 1 522 ALLOCATE( diag_trp_vi(jpi,jpj) , diag_trp_vs (jpi,jpj) , diag_trp_ei(jpi,jpj), & 522 ALLOCATE( diag_trp_vi(jpi,jpj) , diag_trp_vs (jpi,jpj) , diag_trp_ei(jpi,jpj), & 523 523 & diag_trp_es(jpi,jpj) , diag_trp_sv (jpi,jpj) , diag_heat (jpi,jpj), & 524 524 & diag_sice (jpi,jpj) , diag_vice (jpi,jpj) , diag_vsnw (jpi,jpj), diag_aice(jpi,jpj), diag_vpnd(jpi,jpj), & … … 527 527 ! * Ice conservation 528 528 ii = ii + 1 529 ALLOCATE( diag_v (jpi,jpj) , diag_s (jpi,jpj) , diag_t (jpi,jpj), & 529 ALLOCATE( diag_v (jpi,jpj) , diag_s (jpi,jpj) , diag_t (jpi,jpj), & 530 530 & diag_fv(jpi,jpj) , diag_fs(jpi,jpj) , diag_ft(jpi,jpj), STAT=ierr(ii) ) 531 531 532 532 ! * SIMIP diagnostics 533 533 ii = ii + 1 -
NEMO/trunk/src/ICE/icectl.F90
r14005 r14072 12 12 !! 'key_si3' SI3 sea-ice model 13 13 !!---------------------------------------------------------------------- 14 !! ice_cons_hsm : conservation tests on heat, salt and mass during a time step (global) 14 !! ice_cons_hsm : conservation tests on heat, salt and mass during a time step (global) 15 15 !! ice_cons_final : conservation tests on heat, salt and mass at end of time step (global) 16 16 !! ice_cons2D : conservation tests on heat, salt and mass at each gridcell … … 55 55 CHARACTER(LEN=50) :: clname="icedrift_diagnostics.ascii" ! ascii filename 56 56 INTEGER :: numicedrift ! outfile unit 57 REAL(wp) :: rdiag_icemass, rdiag_icesalt, rdiag_iceheat 58 REAL(wp) :: rdiag_adv_icemass, rdiag_adv_icesalt, rdiag_adv_iceheat 59 57 REAL(wp) :: rdiag_icemass, rdiag_icesalt, rdiag_iceheat 58 REAL(wp) :: rdiag_adv_icemass, rdiag_adv_icesalt, rdiag_adv_iceheat 59 60 60 !! * Substitutions 61 61 # include "do_loop_substitute.h90" … … 77 77 !! It prints in ocean.output if there is a violation of conservation at each time-step 78 78 !! The thresholds (zchk_m, zchk_s, zchk_t) determine violations 79 !! For salt and heat thresholds, ice is considered to have a salinity of 10 80 !! and a heat content of 3e5 J/kg (=latent heat of fusion) 79 !! For salt and heat thresholds, ice is considered to have a salinity of 10 80 !! and a heat content of 3e5 J/kg (=latent heat of fusion) 81 81 !!------------------------------------------------------------------- 82 82 INTEGER , INTENT(in) :: icount ! called at: =0 the begining of the routine, =1 the end … … 148 148 zetrp = glob_sum( 'icectl', diag_adv_heat * e1e2t ) 149 149 150 ! ice area (+epsi10 to set a threshold > 0 when there is no ice) 150 ! ice area (+epsi10 to set a threshold > 0 when there is no ice) 151 151 zarea = glob_sum( 'icectl', SUM( a_i + epsi10, dim=3 ) * e1e2t ) 152 152 … … 191 191 !! It prints in ocean.output if there is a violation of conservation at each time-step 192 192 !! The thresholds (zchk_m, zchk_s, zchk_t) determine the violations 193 !! For salt and heat thresholds, ice is considered to have a salinity of 10 194 !! and a heat content of 3e5 J/kg (=latent heat of fusion) 193 !! For salt and heat thresholds, ice is considered to have a salinity of 10 194 !! and a heat content of 3e5 J/kg (=latent heat of fusion) 195 195 !!------------------------------------------------------------------- 196 196 CHARACTER(len=*), INTENT(in) :: cd_routine ! name of the routine … … 214 214 !! & ) * e1e2t ) 215 215 216 ! ice area (+epsi10 to set a threshold > 0 when there is no ice) 216 ! ice area (+epsi10 to set a threshold > 0 when there is no ice) 217 217 zarea = glob_sum( 'icectl', SUM( a_i + epsi10, dim=3 ) * e1e2t ) 218 218 … … 243 243 !! 244 244 REAL(wp), DIMENSION(jpi,jpj) :: zdiag_mass, zdiag_salt, zdiag_heat, & 245 & zdiag_amin, zdiag_vmin, zdiag_smin, zdiag_emin !!, zdiag_amax 245 & zdiag_amin, zdiag_vmin, zdiag_smin, zdiag_emin !!, zdiag_amax 246 246 INTEGER :: jl, jk 247 247 LOGICAL :: ll_stop_m = .FALSE. … … 261 261 & wfx_snw_sni + wfx_snw_sum + wfx_snw_dyn + wfx_snw_sub + wfx_ice_sub + wfx_spr 262 262 ! salt flux 263 pdiag_fs = sfx_bri + sfx_bog + sfx_bom + sfx_sum + sfx_sni + sfx_opw + sfx_res + sfx_dyn + sfx_sub + sfx_lam 263 pdiag_fs = sfx_bri + sfx_bog + sfx_bom + sfx_sum + sfx_sni + sfx_opw + sfx_res + sfx_dyn + sfx_sub + sfx_lam 264 264 ! heat flux 265 pdiag_ft = hfx_sum + hfx_bom + hfx_bog + hfx_dif + hfx_opw + hfx_snw & 265 pdiag_ft = hfx_sum + hfx_bom + hfx_bog + hfx_dif + hfx_opw + hfx_snw & 266 266 & - hfx_thd - hfx_dyn - hfx_res - hfx_sub - hfx_spr 267 267 … … 283 283 ! -- heat diag -- ! 284 284 zdiag_heat = ( SUM( SUM( e_i, dim=4 ), dim=3 ) + SUM( SUM( e_s, dim=4 ), dim=3 ) - pdiag_t ) * r1_Dt_ice & 285 & + ( hfx_sum + hfx_bom + hfx_bog + hfx_dif + hfx_opw + hfx_snw & 285 & + ( hfx_sum + hfx_bom + hfx_bog + hfx_dif + hfx_opw + hfx_snw & 286 286 & - hfx_thd - hfx_dyn - hfx_res - hfx_sub - hfx_spr ) & 287 287 & - pdiag_ft … … 324 324 IF( ll_stop_s ) CALL ctl_stop( 'STOP', cd_routine//': ice salt conservation issue' ) 325 325 IF( ll_stop_t ) CALL ctl_stop( 'STOP', cd_routine//': ice heat conservation issue' ) 326 326 327 327 ENDIF 328 328 … … 332 332 !!--------------------------------------------------------------------- 333 333 !! *** ROUTINE ice_cons_wri *** 334 !! 335 !! ** Purpose : create a NetCDF file named cdfile_name which contains 334 !! 335 !! ** Purpose : create a NetCDF file named cdfile_name which contains 336 336 !! the instantaneous fields when conservation issue occurs 337 337 !! … … 340 340 CHARACTER(len=*), INTENT( in ) :: cdfile_name ! name of the file created 341 341 REAL(wp), DIMENSION(:,:), INTENT( in ) :: pdiag_mass, pdiag_salt, pdiag_heat, & 342 & pdiag_amin, pdiag_vmin, pdiag_smin, pdiag_emin !!, pdiag_amax 342 & pdiag_amin, pdiag_vmin, pdiag_smin, pdiag_emin !!, pdiag_amax 343 343 !! 344 344 INTEGER :: inum 345 345 !!---------------------------------------------------------------------- 346 ! 346 ! 347 347 IF(lwp) WRITE(numout,*) 348 348 IF(lwp) WRITE(numout,*) 'ice_cons_wri : single instantaneous ice state' 349 349 IF(lwp) WRITE(numout,*) '~~~~~~~~~~~~~ named :', cdfile_name, '...nc' 350 IF(lwp) WRITE(numout,*) 350 IF(lwp) WRITE(numout,*) 351 351 352 352 CALL iom_open( TRIM(cdfile_name), inum, ldwrt = .TRUE., kdlev = jpl, cdcomp = 'ICE' ) 353 353 354 354 CALL iom_rstput( 0, 0, inum, 'cons_mass', pdiag_mass(:,:) , ktype = jp_r8 ) ! ice mass spurious lost/gain 355 355 CALL iom_rstput( 0, 0, inum, 'cons_salt', pdiag_salt(:,:) , ktype = jp_r8 ) ! ice salt spurious lost/gain 356 356 CALL iom_rstput( 0, 0, inum, 'cons_heat', pdiag_heat(:,:) , ktype = jp_r8 ) ! ice heat spurious lost/gain 357 357 ! other diags 358 CALL iom_rstput( 0, 0, inum, 'aneg_count', pdiag_amin(:,:) , ktype = jp_r8 ) ! 359 CALL iom_rstput( 0, 0, inum, 'vneg_count', pdiag_vmin(:,:) , ktype = jp_r8 ) ! 360 CALL iom_rstput( 0, 0, inum, 'sneg_count', pdiag_smin(:,:) , ktype = jp_r8 ) ! 361 CALL iom_rstput( 0, 0, inum, 'eneg_count', pdiag_emin(:,:) , ktype = jp_r8 ) ! 358 CALL iom_rstput( 0, 0, inum, 'aneg_count', pdiag_amin(:,:) , ktype = jp_r8 ) ! 359 CALL iom_rstput( 0, 0, inum, 'vneg_count', pdiag_vmin(:,:) , ktype = jp_r8 ) ! 360 CALL iom_rstput( 0, 0, inum, 'sneg_count', pdiag_smin(:,:) , ktype = jp_r8 ) ! 361 CALL iom_rstput( 0, 0, inum, 'eneg_count', pdiag_emin(:,:) , ktype = jp_r8 ) ! 362 362 ! mean state 363 363 CALL iom_rstput( 0, 0, inum, 'icecon' , SUM(a_i ,dim=3) , ktype = jp_r8 ) ! … … 366 366 CALL iom_rstput( 0, 0, inum, 'pndvol' , SUM(v_ip,dim=3) , ktype = jp_r8 ) ! 367 367 CALL iom_rstput( 0, 0, inum, 'lidvol' , SUM(v_il,dim=3) , ktype = jp_r8 ) ! 368 368 369 369 CALL iom_close( inum ) 370 370 371 371 END SUBROUTINE ice_cons_wri 372 372 373 373 SUBROUTINE ice_ctl( kt ) 374 374 !!------------------------------------------------------------------- 375 !! *** ROUTINE ice_ctl *** 376 !! 375 !! *** ROUTINE ice_ctl *** 376 !! 377 377 !! ** Purpose : control checks 378 378 !!------------------------------------------------------------------- … … 386 386 inb_alp(:) = 0 387 387 ialert_id = 0 388 388 389 389 ! Alert if very high salinity 390 390 ialert_id = ialert_id + 1 ! reference number of this alert … … 430 430 END_3D 431 431 END DO 432 432 433 433 ! Alert if very warm ice 434 434 ialert_id = ialert_id + 1 ! reference number of this alert … … 444 444 END_3D 445 445 END DO 446 446 447 447 ! Alerte if very thick ice 448 448 ialert_id = ialert_id + 1 ! reference number of this alert 449 449 cl_alname(ialert_id) = ' Very thick ice ' ! name of the alert 450 jl = jpl 450 jl = jpl 451 451 DO_2D( 1, 1, 1, 1 ) 452 452 IF( h_i(ji,jj,jl) > 50._wp ) THEN … … 460 460 ialert_id = ialert_id + 1 ! reference number of this alert 461 461 cl_alname(ialert_id) = ' Very thin ice ' ! name of the alert 462 jl = 1 462 jl = 1 463 463 DO_2D( 1, 1, 1, 1 ) 464 464 IF( h_i(ji,jj,jl) < rn_himin ) THEN … … 484 484 cl_alname(ialert_id) = ' Ice on continents ' ! name of the alert 485 485 DO_2D( 1, 1, 1, 1 ) 486 IF( tmask(ji,jj,1) == 0._wp .AND. ( at_i(ji,jj) > 0._wp .OR. vt_i(ji,jj) > 0._wp ) ) THEN 486 IF( tmask(ji,jj,1) == 0._wp .AND. ( at_i(ji,jj) > 0._wp .OR. vt_i(ji,jj) > 0._wp ) ) THEN 487 487 WRITE(numout,*) ' ALERTE : Ice on continents ',at_i(ji,jj),vt_i(ji,jj) 488 488 WRITE(numout,*) ' at i,j = ',ji,jj … … 496 496 DO_2D( 1, 1, 1, 1 ) 497 497 IF( ( vt_i(ji,jj) == 0._wp .AND. at_i(ji,jj) > 0._wp ) .OR. & 498 & ( vt_i(ji,jj) > 0._wp .AND. at_i(ji,jj) == 0._wp ) ) THEN 498 & ( vt_i(ji,jj) > 0._wp .AND. at_i(ji,jj) == 0._wp ) ) THEN 499 499 WRITE(numout,*) ' ALERTE : Incompatible ice conc and vol ',at_i(ji,jj),vt_i(ji,jj) 500 500 WRITE(numout,*) ' at i,j = ',ji,jj … … 520 520 ! 521 521 END SUBROUTINE ice_ctl 522 522 523 523 SUBROUTINE ice_prt( kt, ki, kj, kn, cd1 ) 524 524 !!------------------------------------------------------------------- 525 !! *** ROUTINE ice_prt *** 526 !! 527 !! ** Purpose : Writes global ice state on the (i,j) point 528 !! in ocean.ouput 529 !! 3 possibilities exist 525 !! *** ROUTINE ice_prt *** 526 !! 527 !! ** Purpose : Writes global ice state on the (i,j) point 528 !! in ocean.ouput 529 !! 3 possibilities exist 530 530 !! n = 1/-1 -> simple ice state 531 531 !! n = 2 -> exhaustive state 532 532 !! n = 3 -> ice/ocean salt fluxes 533 533 !! 534 !! ** input : point coordinates (i,j) 534 !! ** input : point coordinates (i,j) 535 535 !! n : number of the option 536 536 !!------------------------------------------------------------------- … … 550 550 ! Simple state 551 551 !---------------- 552 552 553 553 IF ( kn == 1 .OR. kn == -1 ) THEN 554 554 WRITE(numout,*) ' ice_prt - Point : ',ji,jj … … 566 566 WRITE(numout,*) ' - Cell values ' 567 567 WRITE(numout,*) ' ~~~~~~~~~~~ ' 568 WRITE(numout,*) ' at_i : ', at_i(ji,jj) 569 WRITE(numout,*) ' ato_i : ', ato_i(ji,jj) 570 WRITE(numout,*) ' vt_i : ', vt_i(ji,jj) 571 WRITE(numout,*) ' vt_s : ', vt_s(ji,jj) 568 WRITE(numout,*) ' at_i : ', at_i(ji,jj) 569 WRITE(numout,*) ' ato_i : ', ato_i(ji,jj) 570 WRITE(numout,*) ' vt_i : ', vt_i(ji,jj) 571 WRITE(numout,*) ' vt_s : ', vt_s(ji,jj) 572 572 DO jl = 1, jpl 573 573 WRITE(numout,*) ' - Category (', jl,')' … … 592 592 ! Exhaustive state 593 593 !-------------------- 594 594 595 595 IF ( kn .EQ. 2 ) THEN 596 596 WRITE(numout,*) ' ice_prt - Point : ',ji,jj … … 598 598 WRITE(numout,*) ' Exhaustive state ' 599 599 WRITE(numout,*) ' lat - long ', gphit(ji,jj), glamt(ji,jj) 600 WRITE(numout,*) 600 WRITE(numout,*) 601 601 WRITE(numout,*) ' - Cell values ' 602 602 WRITE(numout,*) ' ~~~~~~~~~~~ ' 603 WRITE(numout,*) ' at_i : ', at_i(ji,jj) 604 WRITE(numout,*) ' vt_i : ', vt_i(ji,jj) 605 WRITE(numout,*) ' vt_s : ', vt_s(ji,jj) 603 WRITE(numout,*) ' at_i : ', at_i(ji,jj) 604 WRITE(numout,*) ' vt_i : ', vt_i(ji,jj) 605 WRITE(numout,*) ' vt_s : ', vt_s(ji,jj) 606 606 WRITE(numout,*) ' u_ice(i-1,j) : ', u_ice(ji-1,jj) 607 607 WRITE(numout,*) ' u_ice(i ,j) : ', u_ice(ji,jj) … … 610 610 WRITE(numout,*) ' strength : ', strength(ji,jj) 611 611 WRITE(numout,*) 612 612 613 613 DO jl = 1, jpl 614 614 WRITE(numout,*) ' - Category (',jl,')' 615 WRITE(numout,*) ' ~~~~~~~~ ' 615 WRITE(numout,*) ' ~~~~~~~~ ' 616 616 WRITE(numout,*) ' h_i : ', h_i(ji,jj,jl) , ' h_s : ', h_s(ji,jj,jl) 617 617 WRITE(numout,*) ' t_i : ', t_i(ji,jj,1:nlay_i,jl) 618 618 WRITE(numout,*) ' t_su : ', t_su(ji,jj,jl) , ' t_s : ', t_s(ji,jj,1:nlay_s,jl) 619 619 WRITE(numout,*) ' s_i : ', s_i(ji,jj,jl) , ' o_i : ', o_i(ji,jj,jl) 620 WRITE(numout,*) ' a_i : ', a_i(ji,jj,jl) , ' a_i_b : ', a_i_b(ji,jj,jl) 621 WRITE(numout,*) ' v_i : ', v_i(ji,jj,jl) , ' v_i_b : ', v_i_b(ji,jj,jl) 622 WRITE(numout,*) ' v_s : ', v_s(ji,jj,jl) , ' v_s_b : ', v_s_b(ji,jj,jl) 623 WRITE(numout,*) ' e_i1 : ', e_i(ji,jj,1,jl) , ' ei1 : ', e_i_b(ji,jj,1,jl) 624 WRITE(numout,*) ' e_i2 : ', e_i(ji,jj,2,jl) , ' ei2_b : ', e_i_b(ji,jj,2,jl) 625 WRITE(numout,*) ' e_snow : ', e_s(ji,jj,1,jl) , ' e_snow_b : ', e_s_b(ji,jj,1,jl) 626 WRITE(numout,*) ' sv_i : ', sv_i(ji,jj,jl) , ' sv_i_b : ', sv_i_b(ji,jj,jl) 620 WRITE(numout,*) ' a_i : ', a_i(ji,jj,jl) , ' a_i_b : ', a_i_b(ji,jj,jl) 621 WRITE(numout,*) ' v_i : ', v_i(ji,jj,jl) , ' v_i_b : ', v_i_b(ji,jj,jl) 622 WRITE(numout,*) ' v_s : ', v_s(ji,jj,jl) , ' v_s_b : ', v_s_b(ji,jj,jl) 623 WRITE(numout,*) ' e_i1 : ', e_i(ji,jj,1,jl) , ' ei1 : ', e_i_b(ji,jj,1,jl) 624 WRITE(numout,*) ' e_i2 : ', e_i(ji,jj,2,jl) , ' ei2_b : ', e_i_b(ji,jj,2,jl) 625 WRITE(numout,*) ' e_snow : ', e_s(ji,jj,1,jl) , ' e_snow_b : ', e_s_b(ji,jj,1,jl) 626 WRITE(numout,*) ' sv_i : ', sv_i(ji,jj,jl) , ' sv_i_b : ', sv_i_b(ji,jj,jl) 627 627 END DO !jl 628 628 629 629 WRITE(numout,*) 630 630 WRITE(numout,*) ' - Heat / FW fluxes ' … … 634 634 WRITE(numout,*) ' qns_ini : ', (1._wp-at_i_b(ji,jj)) * qns(ji,jj) + SUM( a_i_b(ji,jj,:) * qns_ice(ji,jj,:) ) 635 635 WRITE(numout,*) 636 WRITE(numout,*) 637 WRITE(numout,*) ' sst : ', sst_m(ji,jj) 638 WRITE(numout,*) ' sss : ', sss_m(ji,jj) 639 WRITE(numout,*) 636 WRITE(numout,*) 637 WRITE(numout,*) ' sst : ', sst_m(ji,jj) 638 WRITE(numout,*) ' sss : ', sss_m(ji,jj) 639 WRITE(numout,*) 640 640 WRITE(numout,*) ' - Stresses ' 641 641 WRITE(numout,*) ' ~~~~~~~~ ' 642 WRITE(numout,*) ' utau_ice : ', utau_ice(ji,jj) 642 WRITE(numout,*) ' utau_ice : ', utau_ice(ji,jj) 643 643 WRITE(numout,*) ' vtau_ice : ', vtau_ice(ji,jj) 644 WRITE(numout,*) ' utau : ', utau (ji,jj) 644 WRITE(numout,*) ' utau : ', utau (ji,jj) 645 645 WRITE(numout,*) ' vtau : ', vtau (ji,jj) 646 646 ENDIF 647 647 648 648 !--------------------- 649 649 ! Salt / heat fluxes 650 650 !--------------------- 651 651 652 652 IF ( kn .EQ. 3 ) THEN 653 653 WRITE(numout,*) ' ice_prt - Point : ',ji,jj … … 664 664 WRITE(numout,*) ' qt_atm_oi : ', qt_atm_oi(ji,jj) 665 665 WRITE(numout,*) ' qt_oce_ai : ', qt_oce_ai(ji,jj) 666 WRITE(numout,*) ' dhc : ', diag_heat(ji,jj) 666 WRITE(numout,*) ' dhc : ', diag_heat(ji,jj) 667 667 WRITE(numout,*) 668 668 WRITE(numout,*) ' hfx_dyn : ', hfx_dyn(ji,jj) 669 669 WRITE(numout,*) ' hfx_thd : ', hfx_thd(ji,jj) 670 670 WRITE(numout,*) ' hfx_res : ', hfx_res(ji,jj) 671 WRITE(numout,*) ' qsb_ice_bot : ', qsb_ice_bot(ji,jj) 671 WRITE(numout,*) ' qsb_ice_bot : ', qsb_ice_bot(ji,jj) 672 672 WRITE(numout,*) ' qlead : ', qlead(ji,jj) * r1_Dt_ice 673 673 WRITE(numout,*) … … 680 680 WRITE(numout,*) 681 681 WRITE(numout,*) ' - Momentum fluxes ' 682 WRITE(numout,*) ' utau : ', utau(ji,jj) 682 WRITE(numout,*) ' utau : ', utau(ji,jj) 683 683 WRITE(numout,*) ' vtau : ', vtau(ji,jj) 684 ENDIF 684 ENDIF 685 685 WRITE(numout,*) ' ' 686 686 ! … … 694 694 !! *** ROUTINE ice_prt3D *** 695 695 !! 696 !! ** Purpose : CTL prints of ice arrays in case sn_cfctl%prtctl is activated 696 !! ** Purpose : CTL prints of ice arrays in case sn_cfctl%prtctl is activated 697 697 !! 698 698 !!------------------------------------------------------------------- 699 699 CHARACTER(len=*), INTENT(in) :: cd_routine ! name of the routine 700 700 INTEGER :: jk, jl ! dummy loop indices 701 701 702 702 CALL prt_ctl_info(' ========== ') 703 703 CALL prt_ctl_info( cd_routine ) … … 718 718 CALL prt_ctl(tab2d_1=delta_i , clinfo1=' delta_i :') 719 719 CALL prt_ctl(tab2d_1=u_ice , clinfo1=' u_ice :', tab2d_2=v_ice , clinfo2=' v_ice :') 720 720 721 721 DO jl = 1, jpl 722 722 CALL prt_ctl_info(' ') … … 735 735 CALL prt_ctl(tab2d_1=sv_i (:,:,jl) , clinfo1= ' sv_i : ') 736 736 CALL prt_ctl(tab2d_1=oa_i (:,:,jl) , clinfo1= ' oa_i : ') 737 737 738 738 DO jk = 1, nlay_i 739 739 CALL prt_ctl_info(' - Layer : ', ivar=jk) … … 742 742 END DO 743 743 END DO 744 744 745 745 CALL prt_ctl_info(' ') 746 746 CALL prt_ctl_info(' - Stresses : ') … … 748 748 CALL prt_ctl(tab2d_1=utau , clinfo1= ' utau : ', tab2d_2=vtau , clinfo2= ' vtau : ') 749 749 CALL prt_ctl(tab2d_1=utau_ice , clinfo1= ' utau_ice : ', tab2d_2=vtau_ice , clinfo2= ' vtau_ice : ') 750 750 751 751 END SUBROUTINE ice_prt3D 752 752 … … 853 853 !!---------------------------------------------------------------------- 854 854 !! *** ROUTINE ice_drift_init *** 855 !! 855 !! 856 856 !! ** Purpose : create output file, initialise arrays 857 857 !!---------------------------------------------------------------------- … … 879 879 ! 880 880 END SUBROUTINE ice_drift_init 881 881 882 882 #else 883 883 !!---------------------------------------------------------------------- -
NEMO/trunk/src/ICE/icedia.F90
r13970 r14072 2 2 !!====================================================================== 3 3 !! *** MODULE icedia *** 4 !! Sea-Ice: global budgets 4 !! Sea-Ice: global budgets 5 5 !!====================================================================== 6 6 !! History : 3.4 ! 2012-10 (C. Rousset) original code … … 37 37 REAL(wp), DIMENSION(:,:), ALLOCATABLE :: vol_loc_ini, sal_loc_ini, tem_loc_ini ! initial volume, salt and heat contents 38 38 REAL(wp) :: frc_sal, frc_voltop, frc_volbot, frc_temtop, frc_tembot ! global forcing trends 39 39 40 40 !!---------------------------------------------------------------------- 41 41 !! NEMO/ICE 4.0 , NEMO Consortium (2018) … … 59 59 !!--------------------------------------------------------------------------- 60 60 !! *** ROUTINE ice_dia *** 61 !! 62 !! ** Purpose: Compute the sea-ice global heat content, salt content 61 !! 62 !! ** Purpose: Compute the sea-ice global heat content, salt content 63 63 !! and volume conservation 64 64 !!--------------------------------------------------------------------------- 65 INTEGER, INTENT(in) :: kt ! ocean time step 65 INTEGER, INTENT(in) :: kt ! ocean time step 66 66 !! 67 67 REAL(wp) :: zbg_ivol, zbg_item, zbg_area, zbg_isal 68 68 REAL(wp) :: zbg_svol, zbg_stem 69 69 REAL(wp) :: z_frc_voltop, z_frc_temtop, z_frc_sal 70 REAL(wp) :: z_frc_volbot, z_frc_tembot 71 REAL(wp) :: zdiff_vol, zdiff_sal, zdiff_tem 70 REAL(wp) :: z_frc_volbot, z_frc_tembot 71 REAL(wp) :: zdiff_vol, zdiff_sal, zdiff_tem 72 72 !!--------------------------------------------------------------------------- 73 73 IF( ln_timing ) CALL timing_start('ice_dia') … … 82 82 z1_e1e2 = 1._wp / glob_sum( 'icedia', e1e2t(:,:) ) 83 83 ENDIF 84 84 85 85 ! ----------------------- ! 86 86 ! 1 - Contents ! … … 96 96 zbg_stem = glob_sum( 'icedia', et_s(:,:) * e1e2t(:,:) ) * 1.e-20 ! heat content (1.e20 J) 97 97 98 CALL iom_put( 'ibgvol_tot' , zbg_ivol ) 99 CALL iom_put( 'sbgvol_tot' , zbg_svol ) 100 CALL iom_put( 'ibgarea_tot' , zbg_area ) 101 CALL iom_put( 'ibgsalt_tot' , zbg_isal ) 102 CALL iom_put( 'ibgheat_tot' , zbg_item ) 103 CALL iom_put( 'sbgheat_tot' , zbg_stem ) 104 98 CALL iom_put( 'ibgvol_tot' , zbg_ivol ) 99 CALL iom_put( 'sbgvol_tot' , zbg_svol ) 100 CALL iom_put( 'ibgarea_tot' , zbg_area ) 101 CALL iom_put( 'ibgsalt_tot' , zbg_isal ) 102 CALL iom_put( 'ibgheat_tot' , zbg_item ) 103 CALL iom_put( 'sbgheat_tot' , zbg_stem ) 104 105 105 ENDIF 106 106 … … 109 109 ! ---------------------------! 110 110 ! they must be kept outside an IF(iom_use) because of the call to dia_rst below 111 z_frc_volbot = r1_rho0 * glob_sum( 'icedia', -( wfx_ice(:,:) + wfx_snw(:,:) + wfx_err_sub(:,:) ) * e1e2t(:,:) ) * 1.e-9 ! freshwater flux ice/snow-ocean 111 z_frc_volbot = r1_rho0 * glob_sum( 'icedia', -( wfx_ice(:,:) + wfx_snw(:,:) + wfx_err_sub(:,:) ) * e1e2t(:,:) ) * 1.e-9 ! freshwater flux ice/snow-ocean 112 112 z_frc_voltop = r1_rho0 * glob_sum( 'icedia', -( wfx_sub(:,:) + wfx_spr(:,:) ) * e1e2t(:,:) ) * 1.e-9 ! freshwater flux ice/snow-atm 113 113 z_frc_sal = r1_rho0 * glob_sum( 'icedia', - sfx(:,:) * e1e2t(:,:) ) * 1.e-9 ! salt fluxes ice/snow-ocean … … 121 121 frc_tembot = frc_tembot + z_frc_tembot * rDt_ice ! 1.e20 J 122 122 123 CALL iom_put( 'ibgfrcvoltop' , frc_voltop ) ! vol forcing ice/snw-atm (km3 equivalent ocean water) 124 CALL iom_put( 'ibgfrcvolbot' , frc_volbot ) ! vol forcing ice/snw-ocean (km3 equivalent ocean water) 125 CALL iom_put( 'ibgfrcsal' , frc_sal ) ! sal - forcing (psu*km3 equivalent ocean water) 126 CALL iom_put( 'ibgfrctemtop' , frc_temtop ) ! heat on top of ice/snw/ocean (1.e20 J) 127 CALL iom_put( 'ibgfrctembot' , frc_tembot ) ! heat on top of ocean(below ice) (1.e20 J) 123 CALL iom_put( 'ibgfrcvoltop' , frc_voltop ) ! vol forcing ice/snw-atm (km3 equivalent ocean water) 124 CALL iom_put( 'ibgfrcvolbot' , frc_volbot ) ! vol forcing ice/snw-ocean (km3 equivalent ocean water) 125 CALL iom_put( 'ibgfrcsal' , frc_sal ) ! sal - forcing (psu*km3 equivalent ocean water) 126 CALL iom_put( 'ibgfrctemtop' , frc_temtop ) ! heat on top of ice/snw/ocean (1.e20 J) 127 CALL iom_put( 'ibgfrctembot' , frc_tembot ) ! heat on top of ocean(below ice) (1.e20 J) 128 128 129 129 IF( iom_use('ibgfrchfxtop') .OR. iom_use('ibgfrchfxbot') ) THEN 130 130 CALL iom_put( 'ibgfrchfxtop' , frc_temtop * z1_e1e2 * 1.e-20 * kt*rn_Dt ) ! heat on top of ice/snw/ocean (W/m2) 131 CALL iom_put( 'ibgfrchfxbot' , frc_tembot * z1_e1e2 * 1.e-20 * kt*rn_Dt ) ! heat on top of ocean(below ice) (W/m2) 132 ENDIF 133 131 CALL iom_put( 'ibgfrchfxbot' , frc_tembot * z1_e1e2 * 1.e-20 * kt*rn_Dt ) ! heat on top of ocean(below ice) (W/m2) 132 ENDIF 133 134 134 ! ---------------------------------- ! 135 135 ! 3 - Content variations and drifts ! 136 136 ! ---------------------------------- ! 137 137 IF( iom_use('ibgvolume') .OR. iom_use('ibgsaltco') .OR. iom_use('ibgheatco') .OR. iom_use('ibgheatfx') ) THEN 138 139 zdiff_vol = r1_rho0 * glob_sum( 'icedia', ( rhoi*vt_i(:,:) + rhos*vt_s(:,:) - vol_loc_ini(:,:) ) * e1e2t(:,:) ) * 1.e-9 ! freshwater trend (km3) 138 139 zdiff_vol = r1_rho0 * glob_sum( 'icedia', ( rhoi*vt_i(:,:) + rhos*vt_s(:,:) - vol_loc_ini(:,:) ) * e1e2t(:,:) ) * 1.e-9 ! freshwater trend (km3) 140 140 zdiff_sal = r1_rho0 * glob_sum( 'icedia', ( rhoi*st_i(:,:) - sal_loc_ini(:,:) ) * e1e2t(:,:) ) * 1.e-9 ! salt content trend (km3*pss) 141 141 zdiff_tem = glob_sum( 'icedia', ( et_i(:,:) + et_s(:,:) - tem_loc_ini(:,:) ) * e1e2t(:,:) ) * 1.e-20 ! heat content trend (1.e20 J) 142 142 ! + SUM( qevap_ice * a_i_b, dim=3 ) !! clem: I think this term should not be there (but needs a check) 143 143 144 144 zdiff_vol = zdiff_vol - ( frc_voltop + frc_volbot ) 145 145 zdiff_sal = zdiff_sal - frc_sal 146 146 zdiff_tem = zdiff_tem - ( frc_tembot - frc_temtop ) 147 148 CALL iom_put( 'ibgvolume' , zdiff_vol ) ! ice/snow volume drift (km3 equivalent ocean water) 147 148 CALL iom_put( 'ibgvolume' , zdiff_vol ) ! ice/snow volume drift (km3 equivalent ocean water) 149 149 CALL iom_put( 'ibgsaltco' , zdiff_sal ) ! ice salt content drift (psu*km3 equivalent ocean water) 150 150 CALL iom_put( 'ibgheatco' , zdiff_tem ) ! ice/snow heat content drift (1.e20 J) 151 151 ! 152 152 ENDIF 153 153 154 154 IF( lrst_ice ) CALL ice_dia_rst( 'WRITE', kt_ice ) 155 155 ! … … 162 162 !!--------------------------------------------------------------------------- 163 163 !! *** ROUTINE ice_dia_init *** 164 !! 164 !! 165 165 !! ** Purpose: Initialization for the heat salt volume budgets 166 !! 166 !! 167 167 !! ** Method : Compute initial heat content, salt content and volume 168 168 !! … … 173 173 INTEGER :: ios, ierror ! local integer 174 174 !! 175 NAMELIST/namdia/ ln_icediachk, rn_icechk_cel, rn_icechk_glo, ln_icediahsb, ln_icectl, iiceprt, jiceprt 175 NAMELIST/namdia/ ln_icediachk, rn_icechk_cel, rn_icechk_glo, ln_icediahsb, ln_icectl, iiceprt, jiceprt 176 176 !!---------------------------------------------------------------------- 177 177 ! … … 194 194 WRITE(numout,*) ' chosen grid point position (iiceprt,jiceprt) = (', iiceprt,',', jiceprt,')' 195 195 ENDIF 196 ! 196 ! 197 197 IF( ln_icediahsb ) THEN 198 198 IF( ice_dia_alloc() /= 0 ) CALL ctl_stop( 'STOP', 'ice_dia_init : unable to allocate arrays' ) ! allocate tke arrays … … 206 206 !!--------------------------------------------------------------------- 207 207 !! *** ROUTINE icedia_rst *** 208 !! 208 !! 209 209 !! ** Purpose : Read or write DIA file in restart file 210 210 !! … … 218 218 !!---------------------------------------------------------------------- 219 219 ! 220 IF( TRIM(cdrw) == 'READ' ) THEN ! Read/initialise 220 IF( TRIM(cdrw) == 'READ' ) THEN ! Read/initialise 221 221 IF( ln_rstart ) THEN !* Read the restart file 222 222 ! … … 238 238 IF(lwp) WRITE(numout,*) '~~~~~~~' 239 239 ! set trends to 0 240 frc_voltop = 0._wp 241 frc_volbot = 0._wp 242 frc_temtop = 0._wp 243 frc_tembot = 0._wp 244 frc_sal = 0._wp 240 frc_voltop = 0._wp 241 frc_volbot = 0._wp 242 frc_temtop = 0._wp 243 frc_tembot = 0._wp 244 frc_sal = 0._wp 245 245 ! record initial ice volume, salt and temp 246 246 vol_loc_ini(:,:) = rhoi * vt_i(:,:) + rhos * vt_s(:,:) ! ice/snow volume (kg/m2) … … 260 260 ! 261 261 ! Write in numriw (if iter == nitrst) 262 ! ------------------ 262 ! ------------------ 263 263 CALL iom_rstput( iter, nitrst, numriw, 'frc_voltop' , frc_voltop ) 264 264 CALL iom_rstput( iter, nitrst, numriw, 'frc_volbot' , frc_volbot ) … … 273 273 ! 274 274 END SUBROUTINE ice_dia_rst 275 275 276 276 #else 277 277 !!---------------------------------------------------------------------- -
NEMO/trunk/src/ICE/icedyn.F90
r14005 r14072 2 2 !!====================================================================== 3 3 !! *** MODULE icedyn *** 4 !! Sea-Ice dynamics : master routine for sea ice dynamics 4 !! Sea-Ice dynamics : master routine for sea ice dynamics 5 5 !!====================================================================== 6 6 !! history : 4.0 ! 2018 (C. Rousset) original code SI3 [aka Sea Ice cube] … … 36 36 PUBLIC ice_dyn ! called by icestp.F90 37 37 PUBLIC ice_dyn_init ! called by icestp.F90 38 38 39 39 INTEGER :: nice_dyn ! choice of the type of dynamics 40 40 ! ! associated indices: 41 41 INTEGER, PARAMETER :: np_dynALL = 1 ! full ice dynamics (rheology + advection + ridging/rafting + correction) 42 INTEGER, PARAMETER :: np_dynRHGADV = 2 ! pure dynamics (rheology + advection) 42 INTEGER, PARAMETER :: np_dynRHGADV = 2 ! pure dynamics (rheology + advection) 43 43 INTEGER, PARAMETER :: np_dynADV1D = 3 ! only advection 1D - test case from Schar & Smolarkiewicz 1996 44 44 INTEGER, PARAMETER :: np_dynADV2D = 4 ! only advection 2D w prescribed vel.(rn_uvice + advection) … … 51 51 REAL(wp) :: rn_uice ! prescribed u-vel (case np_dynADV1D & np_dynADV2D) 52 52 REAL(wp) :: rn_vice ! prescribed v-vel (case np_dynADV1D & np_dynADV2D) 53 53 54 54 TYPE(FLD), ALLOCATABLE, DIMENSION(:) :: sf_icbmsk ! structure of input grounded icebergs mask (file informations, fields read) 55 55 … … 66 66 !!------------------------------------------------------------------- 67 67 !! *** ROUTINE ice_dyn *** 68 !! 68 !! 69 69 !! ** Purpose : this routine manages sea ice dynamics 70 70 !! … … 91 91 WRITE(numout,*)'~~~~~~~' 92 92 ENDIF 93 ! 93 ! 94 94 ! retrieve thickness from volume for landfast param. and UMx advection scheme 95 95 WHERE( a_i(:,:,:) >= epsi20 ) … … 118 118 CASE ( np_dynALL ) !== all dynamical processes ==! 119 119 ! 120 CALL ice_dyn_rhg ( kt, Kmm ) ! -- rheology 120 CALL ice_dyn_rhg ( kt, Kmm ) ! -- rheology 121 121 CALL ice_dyn_adv ( kt ) ! -- advection of ice 122 CALL ice_dyn_rdgrft( kt ) ! -- ridging/rafting 122 CALL ice_dyn_rdgrft( kt ) ! -- ridging/rafting 123 123 CALL ice_cor ( kt , 1 ) ! -- Corrections 124 124 ! 125 125 CASE ( np_dynRHGADV ) !== no ridge/raft & no corrections ==! 126 126 ! 127 CALL ice_dyn_rhg ( kt, Kmm ) ! -- rheology 127 CALL ice_dyn_rhg ( kt, Kmm ) ! -- rheology 128 128 CALL ice_dyn_adv ( kt ) ! -- advection of ice 129 129 CALL Hpiling ! -- simple pile-up (replaces ridging/rafting) … … 134 134 ! --- monotonicity test from Schar & Smolarkiewicz 1996 --- ! 135 135 ! CFL = 0.5 at a distance from the bound of 1/6 of the basin length 136 ! Then for dx = 2m and dt = 1s => rn_uice = u (1/6th) = 1m/s 136 ! Then for dx = 2m and dt = 1s => rn_uice = u (1/6th) = 1m/s 137 137 DO_2D( 1, 1, 1, 1 ) 138 138 zcoefu = ( REAL(jpiglo+1)*0.5_wp - REAL(ji+nimpp-1) ) / ( REAL(jpiglo+1)*0.5_wp - 1._wp ) … … 156 156 ! 157 157 ! 158 ! diagnostics: divergence at T points 158 ! diagnostics: divergence at T points 159 159 IF( iom_use('icediv') ) THEN 160 160 ! … … 259 259 ENDIF 260 260 ! !== set the choice of ice dynamics ==! 261 ioptio = 0 261 ioptio = 0 262 262 ! !--- full dynamics (rheology + advection + ridging/rafting + correction) 263 263 IF( ln_dynALL ) THEN ; ioptio = ioptio + 1 ; nice_dyn = np_dynALL ; ENDIF … … 292 292 ALLOCATE( sf_icbmsk(1)%fnow(jpi,jpj,1) ) 293 293 IF( sf_icbmsk(1)%ln_tint ) ALLOCATE( sf_icbmsk(1)%fdta(jpi,jpj,1,2) ) 294 IF( TRIM(sf_icbmsk(1)%clrootname) == 'NOT USED' ) sf_icbmsk(1)%fnow(:,:,1) = 0._wp ! not used field (set to 0) 294 IF( TRIM(sf_icbmsk(1)%clrootname) == 'NOT USED' ) sf_icbmsk(1)%fnow(:,:,1) = 0._wp ! not used field (set to 0) 295 295 ELSE 296 296 icb_mask(:,:) = 0._wp 297 297 ENDIF 298 ! !--- other init 298 ! !--- other init 299 299 CALL ice_dyn_rdgrft_init ! set ice ridging/rafting parameters 300 300 CALL ice_dyn_rhg_init ! set ice rheology parameters … … 307 307 !! Default option Empty module NO SI3 sea-ice model 308 308 !!---------------------------------------------------------------------- 309 #endif 309 #endif 310 310 311 311 !!====================================================================== -
NEMO/trunk/src/ICE/icedyn_adv_pra.F90
r14005 r14072 1 MODULE icedyn_adv_pra 1 MODULE icedyn_adv_pra 2 2 !!====================================================================== 3 3 !! *** MODULE icedyn_adv_pra *** … … 35 35 36 36 ! Moments for advection 37 REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:,:) :: sxice, syice, sxxice, syyice, sxyice ! ice thickness 37 REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:,:) :: sxice, syice, sxxice, syyice, sxyice ! ice thickness 38 38 REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:,:) :: sxsn , sysn , sxxsn , syysn , sxysn ! snow thickness 39 39 REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:,:) :: sxa , sya , sxxa , syya , sxya ! ice concentration … … 59 59 !!---------------------------------------------------------------------- 60 60 !! ** routine ice_dyn_adv_pra ** 61 !! 61 !! 62 62 !! ** purpose : Computes and adds the advection trend to sea-ice 63 63 !! … … 101 101 REAL(wp), DIMENSION(jpi,jpj,nlay_i,jpl) :: z0ei 102 102 !! diagnostics 103 REAL(wp), DIMENSION(jpi,jpj) :: zdiag_adv_mass, zdiag_adv_salt, zdiag_adv_heat 103 REAL(wp), DIMENSION(jpi,jpj) :: zdiag_adv_mass, zdiag_adv_salt, zdiag_adv_heat 104 104 !!---------------------------------------------------------------------- 105 105 ! … … 127 127 ELSEWHERE ; ze_s(:,:,jk,:) = 0._wp 128 128 END WHERE 129 END DO 129 END DO 130 130 CALL icemax4D( ze_i , zei_max ) 131 131 CALL icemax4D( ze_s , zes_max ) … … 139 139 zcflnow(1) = MAXVAL( ABS( pu_ice(:,:) ) * rDt_ice * r1_e1u(:,:) ) 140 140 zcflnow(1) = MAX( zcflnow(1), MAXVAL( ABS( pv_ice(:,:) ) * rDt_ice * r1_e2v(:,:) ) ) 141 141 142 142 ! non-blocking global communication send zcflnow and receive zcflprv 143 143 CALL mpp_delay_max( 'icedyn_adv_pra', 'cflice', zcflnow(:), zcflprv(:), kt == nitend - nn_fsbc + 1 ) … … 148 148 zdt = rDt_ice / REAL(icycle) 149 149 z1_dt = 1._wp / zdt 150 150 151 151 ! --- transport --- ! 152 152 zudy(:,:) = pu_ice(:,:) * e2u(:,:) … … 164 164 ! record at_i before advection (for open water) 165 165 zati1(:,:) = SUM( pa_i(:,:,:), dim=3 ) 166 167 ! --- transported fields --- ! 166 167 ! --- transported fields --- ! 168 168 DO jl = 1, jpl 169 169 zarea(:,:,jl) = e1e2t(:,:) … … 209 209 END DO 210 210 DO jk = 1, nlay_i !--- ice heat content 211 CALL adv_x( zdt, zudy, 1._wp, zarea, z0ei(:,:,jk,:), sxe(:,:,jk,:), & 211 CALL adv_x( zdt, zudy, 1._wp, zarea, z0ei(:,:,jk,:), sxe(:,:,jk,:), & 212 212 & sxxe(:,:,jk,:), sye(:,:,jk,:), syye(:,:,jk,:), sxye(:,:,jk,:) ) 213 CALL adv_y( zdt, zvdx, 0._wp, zarea, z0ei(:,:,jk,:), sxe(:,:,jk,:), & 213 CALL adv_y( zdt, zvdx, 0._wp, zarea, z0ei(:,:,jk,:), sxe(:,:,jk,:), & 214 214 & sxxe(:,:,jk,:), sye(:,:,jk,:), syye(:,:,jk,:), sxye(:,:,jk,:) ) 215 215 END DO … … 217 217 IF ( ln_pnd_LEV .OR. ln_pnd_TOPO ) THEN 218 218 CALL adv_x( zdt , zudy , 1._wp , zarea , z0ap , sxap , sxxap , syap , syyap , sxyap ) !--- melt pond fraction 219 CALL adv_y( zdt , zvdx , 0._wp , zarea , z0ap , sxap , sxxap , syap , syyap , sxyap ) 219 CALL adv_y( zdt , zvdx , 0._wp , zarea , z0ap , sxap , sxxap , syap , syyap , sxyap ) 220 220 CALL adv_x( zdt , zudy , 1._wp , zarea , z0vp , sxvp , sxxvp , syvp , syyvp , sxyvp ) !--- melt pond volume 221 CALL adv_y( zdt , zvdx , 0._wp , zarea , z0vp , sxvp , sxxvp , syvp , syyvp , sxyvp ) 221 CALL adv_y( zdt , zvdx , 0._wp , zarea , z0vp , sxvp , sxxvp , syvp , syyvp , sxyvp ) 222 222 IF ( ln_pnd_lids ) THEN 223 223 CALL adv_x( zdt , zudy , 1._wp , zarea , z0vl , sxvl , sxxvl , syvl , syyvl , sxyvl ) !--- melt pond lid volume 224 CALL adv_y( zdt , zvdx , 0._wp , zarea , z0vl , sxvl , sxxvl , syvl , syyvl , sxyvl ) 224 CALL adv_y( zdt , zvdx , 0._wp , zarea , z0vl , sxvl , sxxvl , syvl , syyvl , sxyvl ) 225 225 ENDIF 226 226 ENDIF … … 245 245 END DO 246 246 DO jk = 1, nlay_i !--- ice heat content 247 CALL adv_y( zdt, zvdx, 1._wp, zarea, z0ei(:,:,jk,:), sxe(:,:,jk,:), & 247 CALL adv_y( zdt, zvdx, 1._wp, zarea, z0ei(:,:,jk,:), sxe(:,:,jk,:), & 248 248 & sxxe(:,:,jk,:), sye(:,:,jk,:), syye(:,:,jk,:), sxye(:,:,jk,:) ) 249 CALL adv_x( zdt, zudy, 0._wp, zarea, z0ei(:,:,jk,:), sxe(:,:,jk,:), & 249 CALL adv_x( zdt, zudy, 0._wp, zarea, z0ei(:,:,jk,:), sxe(:,:,jk,:), & 250 250 & sxxe(:,:,jk,:), sye(:,:,jk,:), syye(:,:,jk,:), sxye(:,:,jk,:) ) 251 251 END DO … … 257 257 IF ( ln_pnd_lids ) THEN 258 258 CALL adv_y( zdt , zvdx , 1._wp , zarea , z0vl , sxvl , sxxvl , syvl , syyvl , sxyvl ) !--- melt pond lid volume 259 CALL adv_x( zdt , zudy , 0._wp , zarea , z0vl , sxvl , sxxvl , syvl , syyvl , sxyvl ) 259 CALL adv_x( zdt , zudy , 0._wp , zarea , z0vl , sxvl , sxxvl , syvl , syyvl , sxyvl ) 260 260 ENDIF 261 261 ENDIF 262 262 ! 263 263 ENDIF 264 264 265 265 ! --- Lateral boundary conditions --- ! 266 266 ! caution: for gradients (sx and sy) the sign changes … … 276 276 & , sxxage, 'T', 1._wp, syyage, 'T', 1._wp, sxyage, 'T', 1._wp ) 277 277 CALL lbc_lnk_multi( 'icedyn_adv_pra', z0es , 'T', 1._wp, sxc0 , 'T', -1._wp, syc0 , 'T', -1._wp & ! snw enthalpy 278 & , sxxc0 , 'T', 1._wp, syyc0 , 'T', 1._wp, sxyc0 , 'T', 1._wp ) 278 & , sxxc0 , 'T', 1._wp, syyc0 , 'T', 1._wp, sxyc0 , 'T', 1._wp ) 279 279 CALL lbc_lnk_multi( 'icedyn_adv_pra', z0ei , 'T', 1._wp, sxe , 'T', -1._wp, sye , 'T', -1._wp & ! ice enthalpy 280 280 & , sxxe , 'T', 1._wp, syye , 'T', 1._wp, sxye , 'T', 1._wp ) … … 283 283 & , sxxap, 'T', 1._wp, syyap, 'T', 1._wp, sxyap, 'T', 1._wp & 284 284 & , z0vp , 'T', 1._wp, sxvp , 'T', -1._wp, syvp , 'T', -1._wp & ! melt pond volume 285 & , sxxvp, 'T', 1._wp, syyvp, 'T', 1._wp, sxyvp, 'T', 1._wp ) 285 & , sxxvp, 'T', 1._wp, syyvp, 'T', 1._wp, sxyvp, 'T', 1._wp ) 286 286 IF ( ln_pnd_lids ) THEN 287 287 CALL lbc_lnk_multi( 'icedyn_adv_pra', z0vl ,'T', 1._wp, sxvl ,'T', -1._wp, syvl ,'T', -1._wp & ! melt pond lid volume 288 & , sxxvl,'T', 1._wp, syyvl,'T', 1._wp, sxyvl,'T', 1._wp ) 288 & , sxxvl,'T', 1._wp, syyvl,'T', 1._wp, sxyvl,'T', 1._wp ) 289 289 ENDIF 290 290 ENDIF … … 348 348 ! 349 349 END SUBROUTINE ice_dyn_adv_pra 350 351 350 351 352 352 SUBROUTINE adv_x( pdt, put , pcrh, psm , ps0 , & 353 353 & psx, psxx, psy , psyy, psxy ) 354 354 !!---------------------------------------------------------------------- 355 355 !! ** routine adv_x ** 356 !! 356 !! 357 357 !! ** purpose : Computes and adds the advection trend to sea-ice 358 358 !! variable on x axis … … 363 363 REAL(wp), DIMENSION(:,:,:), INTENT(inout) :: psm ! area 364 364 REAL(wp), DIMENSION(:,:,:), INTENT(inout) :: ps0 ! field to be advected 365 REAL(wp), DIMENSION(:,:,:), INTENT(inout) :: psx , psy ! 1st moments 365 REAL(wp), DIMENSION(:,:,:), INTENT(inout) :: psx , psy ! 1st moments 366 366 REAL(wp), DIMENSION(:,:,:), INTENT(inout) :: psxx, psyy, psxy ! 2nd moments 367 !! 367 !! 368 368 INTEGER :: ji, jj, jl, jcat ! dummy loop indices 369 369 INTEGER :: jj0 ! dummy loop indices … … 386 386 DO jl = 1, jcat ! loop on categories 387 387 ! 388 ! Limitation of moments. 388 ! Limitation of moments. 389 389 DO jj = Njs0 - jj0, Nje0 + jj0 390 390 391 391 DO ji = Nis0 - 1, Nie0 + 1 392 392 … … 399 399 zpsxy = psxy(ji,jj,jl) 400 400 401 ! Initialize volumes of boxes (=area if adv_x first called, =psm otherwise) 401 ! Initialize volumes of boxes (=area if adv_x first called, =psm otherwise) 402 402 zpsm = MAX( pcrh * e1e2t(ji,jj) + ( 1.0 - pcrh ) * zpsm , epsi20 ) 403 403 ! … … 408 408 rswitch = ( 1.0 - MAX( 0._wp, SIGN( 1._wp, -zslpmax) ) ) * tmask(ji,jj,1) ! Case of empty boxes & Apply mask 409 409 410 zps0 = zslpmax 410 zps0 = zslpmax 411 411 zpsx = zs1new * rswitch 412 412 zpsxx = zs2new * rswitch … … 415 415 zpsxy = MIN( zslpmax, MAX( -zslpmax, zpsxy ) ) * rswitch 416 416 417 ! Calculate fluxes and moments between boxes i<-->i+1 418 ! ! Flux from i to i+1 WHEN u GT 0 417 ! Calculate fluxes and moments between boxes i<-->i+1 418 ! ! Flux from i to i+1 WHEN u GT 0 419 419 zbet(ji,jj) = MAX( 0._wp, SIGN( 1._wp, put(ji,jj) ) ) 420 420 zalf = MAX( 0._wp, put(ji,jj) ) * pdt / zpsm … … 423 423 zalf1q = zalf1 * zalf1 424 424 ! 425 zfm (ji,jj) = zalf * zpsm 425 zfm (ji,jj) = zalf * zpsm 426 426 zf0 (ji,jj) = zalf * ( zps0 + zalf1 * ( zpsx + (zalf1 - zalf) * zpsxx ) ) 427 427 zfx (ji,jj) = zalfq * ( zpsx + 3.0 * zalf1 * zpsxx ) … … 441 441 ! 442 442 psm (ji,jj,jl) = zpsm ! optimization 443 ps0 (ji,jj,jl) = zps0 444 psx (ji,jj,jl) = zpsx 443 ps0 (ji,jj,jl) = zps0 444 psx (ji,jj,jl) = zpsx 445 445 psxx(ji,jj,jl) = zpsxx 446 psy (ji,jj,jl) = zpsy 446 psy (ji,jj,jl) = zpsy 447 447 psyy(ji,jj,jl) = zpsyy 448 448 psxy(ji,jj,jl) = zpsxy 449 449 ! 450 450 END DO 451 451 452 452 DO ji = Nis0 - 1, Nie0 453 453 ! ! Flux from i+1 to i when u LT 0. 454 zalf = MAX( 0._wp, -put(ji,jj) ) * pdt / psm(ji+1,jj,jl) 454 zalf = MAX( 0._wp, -put(ji,jj) ) * pdt / psm(ji+1,jj,jl) 455 455 zalg (ji,jj) = zalf 456 456 zalfq = zalf * zalf … … 491 491 zpsxy = zalg1q(ji-1,jj) * zpsxy 492 492 493 ! Put the temporary moments into appropriate neighboring boxes. 493 ! Put the temporary moments into appropriate neighboring boxes. 494 494 ! ! Flux from i to i+1 IF u GT 0. 495 495 zbt = zbet(ji-1,jj) … … 508 508 & + 3.0 * (- zalf1*zfy(ji-1,jj) + zalf * zpsy ) ) & 509 509 & + zbt1 * zpsxy 510 zpsy = zbt * ( zpsy + zfy (ji-1,jj) ) + zbt1 * zpsy 510 zpsy = zbt * ( zpsy + zfy (ji-1,jj) ) + zbt1 * zpsy 511 511 zpsyy = zbt * ( zpsyy + zfyy(ji-1,jj) ) + zbt1 * zpsyy 512 512 … … 530 530 ! 531 531 psm (ji,jj,jl) = zpsm ! optimization 532 ps0 (ji,jj,jl) = zps0 533 psx (ji,jj,jl) = zpsx 532 ps0 (ji,jj,jl) = zps0 533 psx (ji,jj,jl) = zpsx 534 534 psxx(ji,jj,jl) = zpsxx 535 psy (ji,jj,jl) = zpsy 535 psy (ji,jj,jl) = zpsy 536 536 psyy(ji,jj,jl) = zpsyy 537 537 psxy(ji,jj,jl) = zpsxy … … 541 541 ! 542 542 END DO 543 ! 543 ! 544 544 END SUBROUTINE adv_x 545 545 … … 549 549 !!--------------------------------------------------------------------- 550 550 !! ** routine adv_y ** 551 !! 552 !! ** purpose : Computes and adds the advection trend to sea-ice 551 !! 552 !! ** purpose : Computes and adds the advection trend to sea-ice 553 553 !! variable on y axis 554 554 !!--------------------------------------------------------------------- … … 558 558 REAL(wp), DIMENSION(:,:,:), INTENT(inout) :: psm ! area 559 559 REAL(wp), DIMENSION(:,:,:), INTENT(inout) :: ps0 ! field to be advected 560 REAL(wp), DIMENSION(:,:,:), INTENT(inout) :: psx , psy ! 1st moments 560 REAL(wp), DIMENSION(:,:,:), INTENT(inout) :: psx , psy ! 1st moments 561 561 REAL(wp), DIMENSION(:,:,:), INTENT(inout) :: psxx, psyy, psxy ! 2nd moments 562 562 !! … … 578 578 ! 579 579 jcat = SIZE( ps0 , 3 ) ! size of input arrays 580 ! 580 ! 581 581 DO jl = 1, jcat ! loop on categories 582 582 ! … … 601 601 rswitch = ( 1.0 - MAX( 0._wp, SIGN( 1._wp, -zslpmax) ) ) * tmask(ji,jj,1) ! Case of empty boxes & Apply mask 602 602 ! 603 zps0 = zslpmax 603 zps0 = zslpmax 604 604 zpsx = zpsx * rswitch 605 605 zpsxx = zpsxx * rswitch … … 608 608 zpsxy = MIN( zslpmax, MAX( -zslpmax, zpsxy ) ) * rswitch 609 609 610 ! Calculate fluxes and moments between boxes j<-->j+1 611 ! ! Flux from j to j+1 WHEN v GT 0 610 ! Calculate fluxes and moments between boxes j<-->j+1 611 ! ! Flux from j to j+1 WHEN v GT 0 612 612 zbet(ji,jj) = MAX( 0._wp, SIGN( 1._wp, pvt(ji,jj) ) ) 613 613 zalf = MAX( 0._wp, pvt(ji,jj) ) * pdt / zpsm … … 617 617 ! 618 618 zfm (ji,jj) = zalf * zpsm 619 zf0 (ji,jj) = zalf * ( zps0 + zalf1 * ( zpsy + (zalf1-zalf) * zpsyy ) ) 619 zf0 (ji,jj) = zalf * ( zps0 + zalf1 * ( zpsy + (zalf1-zalf) * zpsyy ) ) 620 620 zfy (ji,jj) = zalfq *( zpsy + 3.0*zalf1*zpsyy ) 621 621 zfyy(ji,jj) = zalf * zalfq * zpsyy … … 634 634 ! 635 635 psm (ji,jj,jl) = zpsm ! optimization 636 ps0 (ji,jj,jl) = zps0 637 psx (ji,jj,jl) = zpsx 636 ps0 (ji,jj,jl) = zps0 637 psx (ji,jj,jl) = zpsx 638 638 psxx(ji,jj,jl) = zpsxx 639 psy (ji,jj,jl) = zpsy 639 psy (ji,jj,jl) = zpsy 640 640 psyy(ji,jj,jl) = zpsyy 641 641 psxy(ji,jj,jl) = zpsxy … … 644 644 DO_2D( 1, 0, ji0, ji0 ) 645 645 ! ! Flux from j+1 to j when v LT 0. 646 zalf = MAX( 0._wp, -pvt(ji,jj) ) * pdt / psm(ji,jj+1,jl) 646 zalf = MAX( 0._wp, -pvt(ji,jj) ) * pdt / psm(ji,jj+1,jl) 647 647 zalg (ji,jj) = zalf 648 648 zalfq = zalf * zalf … … 683 683 zpsxy = zalg1q(ji,jj-1) * zpsxy 684 684 685 ! Put the temporary moments into appropriate neighboring boxes. 685 ! Put the temporary moments into appropriate neighboring boxes. 686 686 ! ! Flux from j to j+1 IF v GT 0. 687 687 zbt = zbet(ji,jj-1) 688 688 zbt1 = 1.0 - zbet(ji,jj-1) 689 zpsm = zbt * ( zpsm + zfm(ji,jj-1) ) + zbt1 * zpsm 690 zalf = zbt * zfm(ji,jj-1) / zpsm 689 zpsm = zbt * ( zpsm + zfm(ji,jj-1) ) + zbt1 * zpsm 690 zalf = zbt * zfm(ji,jj-1) / zpsm 691 691 zalf1 = 1.0 - zalf 692 692 ztemp = zalf * zps0 - zalf1 * zf0(ji,jj-1) … … 694 694 zps0 = zbt * ( zps0 + zf0(ji,jj-1) ) + zbt1 * zps0 695 695 zpsy = zbt * ( zalf * zfy(ji,jj-1) + zalf1 * zpsy + 3.0 * ztemp ) & 696 & + zbt1 * zpsy 696 & + zbt1 * zpsy 697 697 zpsyy = zbt * ( zalf * zalf * zfyy(ji,jj-1) + zalf1 * zalf1 * zpsyy & 698 & + 5.0 * ( zalf * zalf1 * ( zpsy - zfy(ji,jj-1) ) - ( zalf1 - zalf ) * ztemp ) ) & 698 & + 5.0 * ( zalf * zalf1 * ( zpsy - zfy(ji,jj-1) ) - ( zalf1 - zalf ) * ztemp ) ) & 699 699 & + zbt1 * zpsyy 700 700 zpsxy = zbt * ( zalf * zfxy(ji,jj-1) + zalf1 * zpsxy & 701 701 & + 3.0 * (- zalf1 * zfx(ji,jj-1) + zalf * zpsx ) ) & 702 702 & + zbt1 * zpsxy 703 zpsx = zbt * ( zpsx + zfx (ji,jj-1) ) + zbt1 * zpsx 703 zpsx = zbt * ( zpsx + zfx (ji,jj-1) ) + zbt1 * zpsx 704 704 zpsxx = zbt * ( zpsxx + zfxx(ji,jj-1) ) + zbt1 * zpsxx 705 705 … … 723 723 ! 724 724 psm (ji,jj,jl) = zpsm ! optimization 725 ps0 (ji,jj,jl) = zps0 726 psx (ji,jj,jl) = zpsx 725 ps0 (ji,jj,jl) = zps0 726 psx (ji,jj,jl) = zpsx 727 727 psxx(ji,jj,jl) = zpsxx 728 psy (ji,jj,jl) = zpsy 728 psy (ji,jj,jl) = zpsy 729 729 psyy(ji,jj,jl) = zpsyy 730 730 psxy(ji,jj,jl) = zpsxy … … 796 796 pe_s(ji,jj,1:nlay_s,jl) = pe_s(ji,jj,1:nlay_s,jl) * zfra 797 797 pv_s(ji,jj,jl) = pa_i(ji,jj,jl) * phs_max(ji,jj,jl) 798 ENDIF 799 ! 798 ENDIF 799 ! 800 800 ! ! -- check s_i -- ! 801 801 ! if s_i is larger than the surrounding 9 pts => put salt excess in the ocean … … 809 809 ENDIF 810 810 END_2D 811 END DO 811 END DO 812 812 ! 813 813 ! ! -- check e_i/v_i -- ! … … 899 899 !! *** ROUTINE adv_pra_init *** 900 900 !! 901 !! ** Purpose : allocate and initialize arrays for Prather advection 901 !! ** Purpose : allocate and initialize arrays for Prather advection 902 902 !!------------------------------------------------------------------- 903 903 INTEGER :: ierr … … 932 932 !!--------------------------------------------------------------------- 933 933 !! *** ROUTINE adv_pra_rst *** 934 !! 934 !! 935 935 !! ** Purpose : Read or write file in restart file 936 936 !! … … 991 991 DO jk = 1, nlay_s 992 992 WRITE(zchar1,'(I2.2)') jk 993 znam = 'sxc0'//'_l'//zchar1 993 znam = 'sxc0'//'_l'//zchar1 994 994 CALL iom_get( numrir, jpdom_auto, znam , z3d, psgn = -1._wp ) ; sxc0 (:,:,jk,:) = z3d(:,:,:) 995 znam = 'syc0'//'_l'//zchar1 995 znam = 'syc0'//'_l'//zchar1 996 996 CALL iom_get( numrir, jpdom_auto, znam , z3d, psgn = -1._wp ) ; syc0 (:,:,jk,:) = z3d(:,:,:) 997 znam = 'sxxc0'//'_l'//zchar1 997 znam = 'sxxc0'//'_l'//zchar1 998 998 CALL iom_get( numrir, jpdom_auto, znam , z3d ) ; sxxc0(:,:,jk,:) = z3d(:,:,:) 999 znam = 'syyc0'//'_l'//zchar1 999 znam = 'syyc0'//'_l'//zchar1 1000 1000 CALL iom_get( numrir, jpdom_auto, znam , z3d ) ; syyc0(:,:,jk,:) = z3d(:,:,:) 1001 znam = 'sxyc0'//'_l'//zchar1 1001 znam = 'sxyc0'//'_l'//zchar1 1002 1002 CALL iom_get( numrir, jpdom_auto, znam , z3d ) ; sxyc0(:,:,jk,:) = z3d(:,:,:) 1003 1003 END DO … … 1005 1005 DO jk = 1, nlay_i 1006 1006 WRITE(zchar1,'(I2.2)') jk 1007 znam = 'sxe'//'_l'//zchar1 1007 znam = 'sxe'//'_l'//zchar1 1008 1008 CALL iom_get( numrir, jpdom_auto, znam , z3d, psgn = -1._wp ) ; sxe (:,:,jk,:) = z3d(:,:,:) 1009 znam = 'sye'//'_l'//zchar1 1009 znam = 'sye'//'_l'//zchar1 1010 1010 CALL iom_get( numrir, jpdom_auto, znam , z3d, psgn = -1._wp ) ; sye (:,:,jk,:) = z3d(:,:,:) 1011 znam = 'sxxe'//'_l'//zchar1 1011 znam = 'sxxe'//'_l'//zchar1 1012 1012 CALL iom_get( numrir, jpdom_auto, znam , z3d ) ; sxxe(:,:,jk,:) = z3d(:,:,:) 1013 znam = 'syye'//'_l'//zchar1 1013 znam = 'syye'//'_l'//zchar1 1014 1014 CALL iom_get( numrir, jpdom_auto, znam , z3d ) ; syye(:,:,jk,:) = z3d(:,:,:) 1015 znam = 'sxye'//'_l'//zchar1 1015 znam = 'sxye'//'_l'//zchar1 1016 1016 CALL iom_get( numrir, jpdom_auto, znam , z3d ) ; sxye(:,:,jk,:) = z3d(:,:,:) 1017 1017 END DO … … 1165 1165 SUBROUTINE icemax3D( pice , pmax ) 1166 1166 !!--------------------------------------------------------------------- 1167 !! *** ROUTINE icemax3D *** 1167 !! *** ROUTINE icemax3D *** 1168 1168 !! ** Purpose : compute the max of the 9 points around 1169 1169 !!---------------------------------------------------------------------- … … 1174 1174 !!---------------------------------------------------------------------- 1175 1175 DO jl = 1, jpl 1176 DO jj = Njs0-1, Nje0+1 1176 DO jj = Njs0-1, Nje0+1 1177 1177 DO ji = Nis0, Nie0 1178 1178 zmax(ji,jj) = MAX( epsi20, pice(ji,jj,jl), pice(ji-1,jj,jl), pice(ji+1,jj,jl) ) 1179 1179 END DO 1180 1180 END DO 1181 DO jj = Njs0, Nje0 1181 DO jj = Njs0, Nje0 1182 1182 DO ji = Nis0, Nie0 1183 1183 pmax(ji,jj,jl) = MAX( epsi20, zmax(ji,jj), zmax(ji,jj-1), zmax(ji,jj+1) ) … … 1189 1189 SUBROUTINE icemax4D( pice , pmax ) 1190 1190 !!--------------------------------------------------------------------- 1191 !! *** ROUTINE icemax4D *** 1191 !! *** ROUTINE icemax4D *** 1192 1192 !! ** Purpose : compute the max of the 9 points around 1193 1193 !!---------------------------------------------------------------------- … … 1200 1200 DO jl = 1, jpl 1201 1201 DO jk = 1, jlay 1202 DO jj = Njs0-1, Nje0+1 1202 DO jj = Njs0-1, Nje0+1 1203 1203 DO ji = Nis0, Nie0 1204 1204 zmax(ji,jj) = MAX( epsi20, pice(ji,jj,jk,jl), pice(ji-1,jj,jk,jl), pice(ji+1,jj,jk,jl) ) 1205 1205 END DO 1206 1206 END DO 1207 DO jj = Njs0, Nje0 1207 DO jj = Njs0, Nje0 1208 1208 DO ji = Nis0, Nie0 1209 1209 pmax(ji,jj,jk,jl) = MAX( epsi20, zmax(ji,jj), zmax(ji,jj-1), zmax(ji,jj+1) ) -
NEMO/trunk/src/ICE/icedyn_adv_umx.F90
r14005 r14072 14 14 !! ultimate_x(_y) : compute a tracer value at velocity points using ULTIMATE scheme at various orders 15 15 !! macho : compute the fluxes 16 !! nonosc_ice : limit the fluxes using a non-oscillatory algorithm 16 !! nonosc_ice : limit the fluxes using a non-oscillatory algorithm 17 17 !!---------------------------------------------------------------------- 18 18 USE phycst ! physical constant … … 63 63 !!---------------------------------------------------------------------- 64 64 !! *** ROUTINE ice_dyn_adv_umx *** 65 !! 66 !! ** Purpose : Compute the now trend due to total advection of 65 !! 66 !! ** Purpose : Compute the now trend due to total advection of 67 67 !! tracers and add it to the general trend of tracer equations 68 68 !! using an "Ultimate-Macho" scheme 69 69 !! 70 !! Reference : Leonard, B.P., 1991, Comput. Methods Appl. Mech. Eng., 88, 17-74. 70 !! Reference : Leonard, B.P., 1991, Comput. Methods Appl. Mech. Eng., 88, 17-74. 71 71 !!---------------------------------------------------------------------- 72 72 INTEGER , INTENT(in ) :: kn_umx ! order of the scheme (1-5=UM or 20=CEN2) … … 103 103 REAL(wp), DIMENSION(jpi,jpj,nlay_s,jpl) :: ze_s, zes_max 104 104 ! 105 REAL(wp), ALLOCATABLE, DIMENSION(:,:,:) :: zuv_ho, zvv_ho, zuv_ups, zvv_ups, z1_vi, z1_vs 105 REAL(wp), ALLOCATABLE, DIMENSION(:,:,:) :: zuv_ho, zvv_ho, zuv_ups, zvv_ups, z1_vi, z1_vs 106 106 !! diagnostics 107 REAL(wp), DIMENSION(jpi,jpj) :: zdiag_adv_mass, zdiag_adv_salt, zdiag_adv_heat 107 REAL(wp), DIMENSION(jpi,jpj) :: zdiag_adv_mass, zdiag_adv_salt, zdiag_adv_heat 108 108 !!---------------------------------------------------------------------- 109 109 ! … … 131 131 ELSEWHERE ; ze_s(:,:,jk,:) = 0._wp 132 132 END WHERE 133 END DO 133 END DO 134 134 CALL icemax4D( ze_i , zei_max ) 135 135 CALL icemax4D( ze_s , zes_max ) … … 143 143 zcflnow(1) = MAXVAL( ABS( pu_ice(:,:) ) * rDt_ice * r1_e1u(:,:) ) 144 144 zcflnow(1) = MAX( zcflnow(1), MAXVAL( ABS( pv_ice(:,:) ) * rDt_ice * r1_e2v(:,:) ) ) 145 145 146 146 ! non-blocking global communication send zcflnow and receive zcflprv 147 147 CALL mpp_delay_max( 'icedyn_adv_umx', 'cflice', zcflnow(:), zcflprv(:), kt == nitend - nn_fsbc + 1 ) … … 157 157 zvdx(:,:) = pv_ice(:,:) * e1v(:,:) 158 158 ! 159 ! setup transport for each ice cat 159 ! setup transport for each ice cat 160 160 DO jl = 1, jpl 161 161 zu_cat(:,:,jl) = zudy(:,:) … … 190 190 ! record at_i before advection (for open water) 191 191 zati1(:,:) = SUM( pa_i(:,:,:), dim=3 ) 192 192 193 193 ! inverse of A and Ap 194 194 WHERE( pa_i(:,:,:) >= epsi20 ) ; z1_ai(:,:,:) = 1._wp / pa_i(:,:,:) … … 201 201 ! setup a mask where advection will be upstream 202 202 IF( ll_neg ) THEN 203 IF( .NOT. ALLOCATED(imsk_small) ) ALLOCATE( imsk_small(jpi,jpj,jpl) ) 204 IF( .NOT. ALLOCATED(jmsk_small) ) ALLOCATE( jmsk_small(jpi,jpj,jpl) ) 203 IF( .NOT. ALLOCATED(imsk_small) ) ALLOCATE( imsk_small(jpi,jpj,jpl) ) 204 IF( .NOT. ALLOCATED(jmsk_small) ) ALLOCATE( jmsk_small(jpi,jpj,jpl) ) 205 205 DO jl = 1, jpl 206 206 DO_2D( 1, 0, 1, 0 ) … … 232 232 CALL adv_umx( zamsk, kn_umx, jt, kt, zdt, zudy , zvdx, zua_ho , zva_ho , zcu_box, zcv_box, & 233 233 & zhvar, pv_i, zua_ups, zva_ups ) 234 !== Snw volume ==! 234 !== Snw volume ==! 235 235 zhvar(:,:,:) = pv_s(:,:,:) * z1_ai(:,:,:) 236 236 CALL adv_umx( zamsk, kn_umx, jt, kt, zdt, zudy , zvdx, zua_ho , zva_ho , zcu_box, zcv_box, & … … 260 260 CALL adv_umx( zamsk, kn_umx, jt, kt, zdt, zudy , zvdx, zua_ho , zva_ho , zcu_box, zcv_box, & 261 261 & zhvar, pv_i, zua_ups, zva_ups ) 262 !== Snw volume ==! 262 !== Snw volume ==! 263 263 zhvar(:,:,:) = pv_s(:,:,:) * z1_ai(:,:,:) 264 264 CALL adv_umx( zamsk, kn_umx, jt, kt, zdt, zudy , zvdx, zua_ho , zva_ho , zcu_box, zcv_box, & … … 316 316 & zhvar, pe_i(:,:,jk,:), zuv_ups, zvv_ups ) 317 317 END DO 318 !== Snow volume ==! 318 !== Snow volume ==! 319 319 zuv_ups = zua_ups 320 320 zvv_ups = zva_ups … … 374 374 zati2(:,:) = SUM( pa_i(:,:,:), dim=3 ) 375 375 DO_2D( 0, 0, 0, 0 ) 376 pato_i(ji,jj) = pato_i(ji,jj) - ( zati2(ji,jj) - zati1(ji,jj) ) & 376 pato_i(ji,jj) = pato_i(ji,jj) - ( zati2(ji,jj) - zati1(ji,jj) ) & 377 377 & - ( zudy(ji,jj) - zudy(ji-1,jj) + zvdx(ji,jj) - zvdx(ji,jj-1) ) * r1_e1e2t(ji,jj) * zdt 378 378 END_2D … … 406 406 END SUBROUTINE ice_dyn_adv_umx 407 407 408 408 409 409 SUBROUTINE adv_umx( pamsk, kn_umx, jt, kt, pdt, pu, pv, puc, pvc, pubox, pvbox, & 410 410 & pt, ptc, pua_ups, pva_ups, pua_ho, pva_ho ) 411 411 !!---------------------------------------------------------------------- 412 412 !! *** ROUTINE adv_umx *** 413 !! 414 !! ** Purpose : Compute the now trend due to total advection of 413 !! 414 !! ** Purpose : Compute the now trend due to total advection of 415 415 !! tracers and add it to the general trend of tracer equations 416 416 !! … … 434 434 !! 435 435 !! in eq. c), one can solve the equation for S (ln_advS=T), then dVS/dt = -div(uV * uS / u) 436 !! or for HS (ln_advS=F), then dVS/dt = -div(uA * uHS / u) 436 !! or for HS (ln_advS=F), then dVS/dt = -div(uA * uHS / u) 437 437 !! 438 438 !! ** Note : - this method can lead to tiny negative V (-1.e-20) => set it to 0 while conserving mass etc. … … 462 462 REAL(wp), DIMENSION(jpi,jpj,jpl), INTENT( out), OPTIONAL :: pua_ho, pva_ho ! high order u*a fluxes 463 463 ! 464 INTEGER :: ji, jj, jl ! dummy loop indices 464 INTEGER :: ji, jj, jl ! dummy loop indices 465 465 REAL(wp) :: ztra ! local scalar 466 466 REAL(wp), DIMENSION(jpi,jpj,jpl) :: zfu_ho , zfv_ho , zpt … … 468 468 !!---------------------------------------------------------------------- 469 469 ! 470 ! Upstream (_ups) fluxes 470 ! Upstream (_ups) fluxes 471 471 ! ----------------------- 472 472 CALL upstream( pamsk, jt, kt, pdt, pt, pu, pv, zt_ups, zfu_ups, zfv_ups ) 473 474 ! High order (_ho) fluxes 473 474 ! High order (_ho) fluxes 475 475 ! ----------------------- 476 476 SELECT CASE( kn_umx ) … … 506 506 zfv_ups(ji,jj,jl) = zfv_ups(ji,jj,jl) * pva_ups(ji,jj,jl) / pv(ji,jj) 507 507 ELSE 508 zfv_ho (ji,jj,jl) = 0._wp 509 zfv_ups(ji,jj,jl) = 0._wp 508 zfv_ho (ji,jj,jl) = 0._wp 509 zfv_ups(ji,jj,jl) = 0._wp 510 510 ENDIF 511 511 END_2D … … 551 551 DO jl = 1, jpl 552 552 DO_2D( 0, 0, 0, 0 ) 553 ztra = - ( zfu_ho(ji,jj,jl) - zfu_ho(ji-1,jj,jl) + zfv_ho(ji,jj,jl) - zfv_ho(ji,jj-1,jl) ) 554 ! 555 ptc(ji,jj,jl) = ( ptc(ji,jj,jl) + ztra * r1_e1e2t(ji,jj) * pdt ) * tmask(ji,jj,1) 553 ztra = - ( zfu_ho(ji,jj,jl) - zfu_ho(ji-1,jj,jl) + zfv_ho(ji,jj,jl) - zfv_ho(ji,jj-1,jl) ) 554 ! 555 ptc(ji,jj,jl) = ( ptc(ji,jj,jl) + ztra * r1_e1e2t(ji,jj) * pdt ) * tmask(ji,jj,1) 556 556 END_2D 557 557 END DO … … 563 563 !!--------------------------------------------------------------------- 564 564 !! *** ROUTINE upstream *** 565 !! 565 !! 566 566 !! ** Purpose : compute the upstream fluxes and upstream guess of tracer 567 567 !!---------------------------------------------------------------------- … … 572 572 REAL(wp), DIMENSION(:,:,:) , INTENT(in ) :: pt ! tracer fields 573 573 REAL(wp), DIMENSION(:,: ) , INTENT(in ) :: pu, pv ! 2 ice velocity components 574 REAL(wp), DIMENSION(jpi,jpj,jpl), INTENT( out) :: pt_ups ! upstream guess of tracer 575 REAL(wp), DIMENSION(jpi,jpj,jpl), INTENT( out) :: pfu_ups, pfv_ups ! upstream fluxes 574 REAL(wp), DIMENSION(jpi,jpj,jpl), INTENT( out) :: pt_ups ! upstream guess of tracer 575 REAL(wp), DIMENSION(jpi,jpj,jpl), INTENT( out) :: pfu_ups, pfv_ups ! upstream fluxes 576 576 ! 577 577 INTEGER :: ji, jj, jl ! dummy loop indices … … 638 638 ! 639 639 ENDIF 640 640 641 641 ENDIF 642 642 ! … … 655 655 END SUBROUTINE upstream 656 656 657 657 658 658 SUBROUTINE cen2( pamsk, jt, kt, pdt, pt, pu, pv, pt_ups, pfu_ups, pfv_ups, pfu_ho, pfv_ho ) 659 659 !!--------------------------------------------------------------------- 660 660 !! *** ROUTINE cen2 *** 661 !! 661 !! 662 662 !! ** Purpose : compute the high order fluxes using a centered 663 !! second order scheme 663 !! second order scheme 664 664 !!---------------------------------------------------------------------- 665 665 REAL(wp) , INTENT(in ) :: pamsk ! advection of concentration (1) or other tracers (0) … … 669 669 REAL(wp), DIMENSION(:,:,:) , INTENT(in ) :: pt ! tracer fields 670 670 REAL(wp), DIMENSION(:,: ) , INTENT(in ) :: pu, pv ! 2 ice velocity components 671 REAL(wp), DIMENSION(:,:,:) , INTENT(in ) :: pt_ups ! upstream guess of tracer 672 REAL(wp), DIMENSION(:,:,:) , INTENT(in ) :: pfu_ups, pfv_ups ! upstream fluxes 673 REAL(wp), DIMENSION(jpi,jpj,jpl), INTENT( out) :: pfu_ho, pfv_ho ! high order fluxes 671 REAL(wp), DIMENSION(:,:,:) , INTENT(in ) :: pt_ups ! upstream guess of tracer 672 REAL(wp), DIMENSION(:,:,:) , INTENT(in ) :: pfu_ups, pfv_ups ! upstream fluxes 673 REAL(wp), DIMENSION(jpi,jpj,jpl), INTENT( out) :: pfu_ho, pfv_ho ! high order fluxes 674 674 ! 675 675 INTEGER :: ji, jj, jl ! dummy loop indices … … 750 750 ENDIF 751 751 IF( np_limiter == 1 ) CALL nonosc_ice( pamsk, pdt, pu, pv, pt, pt_ups, pfu_ups, pfv_ups, pfu_ho, pfv_ho ) 752 752 753 753 ENDIF 754 754 755 755 END SUBROUTINE cen2 756 756 757 757 758 758 SUBROUTINE macho( pamsk, kn_umx, jt, kt, pdt, pt, pu, pv, pubox, pvbox, pt_ups, pfu_ups, pfv_ups, pfu_ho, pfv_ho ) 759 759 !!--------------------------------------------------------------------- 760 760 !! *** ROUTINE macho *** 761 !! 762 !! ** Purpose : compute the high order fluxes using Ultimate-Macho scheme 761 !! 762 !! ** Purpose : compute the high order fluxes using Ultimate-Macho scheme 763 763 !! 764 764 !! ** Method : ... 765 765 !! 766 !! Reference : Leonard, B.P., 1991, Comput. Methods Appl. Mech. Eng., 88, 17-74. 766 !! Reference : Leonard, B.P., 1991, Comput. Methods Appl. Mech. Eng., 88, 17-74. 767 767 !!---------------------------------------------------------------------- 768 768 REAL(wp) , INTENT(in ) :: pamsk ! advection of concentration (1) or other tracers (0) … … 774 774 REAL(wp), DIMENSION(:,: ) , INTENT(in ) :: pu, pv ! 2 ice velocity components 775 775 REAL(wp), DIMENSION(:,: ) , INTENT(in ) :: pubox, pvbox ! upstream velocity 776 REAL(wp), DIMENSION(:,:,:) , INTENT(in ) :: pt_ups ! upstream guess of tracer 777 REAL(wp), DIMENSION(:,:,:) , INTENT(in ) :: pfu_ups, pfv_ups ! upstream fluxes 778 REAL(wp), DIMENSION(jpi,jpj,jpl), INTENT( out) :: pfu_ho, pfv_ho ! high order fluxes 776 REAL(wp), DIMENSION(:,:,:) , INTENT(in ) :: pt_ups ! upstream guess of tracer 777 REAL(wp), DIMENSION(:,:,:) , INTENT(in ) :: pfu_ups, pfv_ups ! upstream fluxes 778 REAL(wp), DIMENSION(jpi,jpj,jpl), INTENT( out) :: pfu_ho, pfv_ho ! high order fluxes 779 779 ! 780 780 INTEGER :: ji, jj, jl ! dummy loop indices … … 807 807 ! !-- limiter in y --! 808 808 IF( np_limiter == 2 .OR. np_limiter == 3 ) CALL limiter_y( pdt, pv, pt, pfv_ups, pfv_ho ) 809 ! 809 ! 810 810 ! 811 811 ELSE !== even ice time step: adv_y then adv_x ==! … … 821 821 & + pt (ji,jj,jl) * ( pv (ji,jj ) - pv (ji,jj-1 ) ) * r1_e1e2t(ji,jj) & 822 822 & * pamsk & 823 & ) * pdt ) * tmask(ji,jj,1) 823 & ) * pdt ) * tmask(ji,jj,1) 824 824 END_2D 825 825 END DO … … 845 845 !!--------------------------------------------------------------------- 846 846 !! *** ROUTINE ultimate_x *** 847 !! 848 !! ** Purpose : compute tracer at u-points 847 !! 848 !! ** Purpose : compute tracer at u-points 849 849 !! 850 850 !! ** Method : ... 851 851 !! 852 !! Reference : Leonard, B.P., 1991, Comput. Methods Appl. Mech. Eng., 88, 17-74. 852 !! Reference : Leonard, B.P., 1991, Comput. Methods Appl. Mech. Eng., 88, 17-74. 853 853 !!---------------------------------------------------------------------- 854 854 REAL(wp) , INTENT(in ) :: pamsk ! advection of concentration (1) or other tracers (0) … … 857 857 REAL(wp), DIMENSION(:,: ) , INTENT(in ) :: pu ! ice i-velocity component 858 858 REAL(wp), DIMENSION(:,:,:) , INTENT(in ) :: pt ! tracer fields 859 REAL(wp), DIMENSION(jpi,jpj,jpl), INTENT( out) :: pt_u ! tracer at u-point 860 REAL(wp), DIMENSION(jpi,jpj,jpl), INTENT( out) :: pfu_ho ! high order flux 859 REAL(wp), DIMENSION(jpi,jpj,jpl), INTENT( out) :: pt_u ! tracer at u-point 860 REAL(wp), DIMENSION(jpi,jpj,jpl), INTENT( out) :: pfu_ho ! high order flux 861 861 ! 862 862 INTEGER :: ji, jj, jl ! dummy loop indices … … 897 897 ! 898 898 CASE( 1 ) !== 1st order central TIM ==! (Eq. 21) 899 ! 899 ! 900 900 DO jl = 1, jpl 901 901 DO_2D( 0, 0, 1, 0 ) … … 911 911 zcu = pu(ji,jj) * r1_e2u(ji,jj) * pdt * r1_e1u(ji,jj) 912 912 pt_u(ji,jj,jl) = 0.5_wp * umask(ji,jj,1) * ( pt(ji+1,jj,jl) + pt(ji,jj,jl) & 913 & - zcu * ( pt(ji+1,jj,jl) - pt(ji,jj,jl) ) ) 914 END_2D 915 END DO 916 ! 913 & - zcu * ( pt(ji+1,jj,jl) - pt(ji,jj,jl) ) ) 914 END_2D 915 END DO 916 ! 917 917 CASE( 3 ) !== 3rd order central TIM ==! (Eq. 24) 918 918 ! … … 983 983 ! 984 984 END SUBROUTINE ultimate_x 985 986 985 986 987 987 SUBROUTINE ultimate_y( pamsk, kn_umx, pdt, pt, pv, pt_v, pfv_ho ) 988 988 !!--------------------------------------------------------------------- 989 989 !! *** ROUTINE ultimate_y *** 990 !! 991 !! ** Purpose : compute tracer at v-points 990 !! 991 !! ** Purpose : compute tracer at v-points 992 992 !! 993 993 !! ** Method : ... 994 994 !! 995 !! Reference : Leonard, B.P., 1991, Comput. Methods Appl. Mech. Eng., 88, 17-74. 995 !! Reference : Leonard, B.P., 1991, Comput. Methods Appl. Mech. Eng., 88, 17-74. 996 996 !!---------------------------------------------------------------------- 997 997 REAL(wp) , INTENT(in ) :: pamsk ! advection of concentration (1) or other tracers (0) … … 1000 1000 REAL(wp), DIMENSION(:,: ) , INTENT(in ) :: pv ! ice j-velocity component 1001 1001 REAL(wp), DIMENSION(:,:,:) , INTENT(in ) :: pt ! tracer fields 1002 REAL(wp), DIMENSION(jpi,jpj,jpl), INTENT( out) :: pt_v ! tracer at v-point 1003 REAL(wp), DIMENSION(jpi,jpj,jpl), INTENT( out) :: pfv_ho ! high order flux 1002 REAL(wp), DIMENSION(jpi,jpj,jpl), INTENT( out) :: pt_v ! tracer at v-point 1003 REAL(wp), DIMENSION(jpi,jpj,jpl), INTENT( out) :: pfv_ho ! high order flux 1004 1004 ! 1005 1005 INTEGER :: ji, jj, jl ! dummy loop indices … … 1115 1115 ! 1116 1116 END SUBROUTINE ultimate_y 1117 1117 1118 1118 1119 1119 SUBROUTINE nonosc_ice( pamsk, pdt, pu, pv, pt, pt_ups, pfu_ups, pfv_ups, pfu_ho, pfv_ho ) 1120 1120 !!--------------------------------------------------------------------- 1121 1121 !! *** ROUTINE nonosc_ice *** 1122 !! 1123 !! ** Purpose : compute monotonic tracer fluxes from the upstream 1124 !! scheme and the before field by a non-oscillatory algorithm 1122 !! 1123 !! ** Purpose : compute monotonic tracer fluxes from the upstream 1124 !! scheme and the before field by a non-oscillatory algorithm 1125 1125 !! 1126 1126 !! ** Method : ... … … 1141 1141 !!---------------------------------------------------------------------- 1142 1142 zbig = 1.e+40_wp 1143 1143 1144 1144 ! antidiffusive flux : high order minus low order 1145 1145 ! -------------------------------------------------- … … 1157 1157 ! pfu_ho 1158 1158 ! * ---> 1159 ! | | * | | 1160 ! | | | * | 1159 ! | | * | | 1160 ! | | | * | 1161 1161 ! | | | | * 1162 ! t_ups : i-1 i i+1 i+2 1162 ! t_ups : i-1 i i+1 i+2 1163 1163 IF( ll_prelim ) THEN 1164 1164 1165 1165 DO jl = 1, jpl 1166 1166 DO_2D( 0, 0, 0, 0 ) … … 1200 1200 z1_dt = 1._wp / pdt 1201 1201 DO jl = 1, jpl 1202 1202 1203 1203 DO_2D( 1, 1, 1, 1 ) 1204 1204 IF ( pt(ji,jj,jl) <= 0._wp .AND. pt_ups(ji,jj,jl) <= 0._wp ) THEN … … 1244 1244 ! if all the points are outside ice cover 1245 1245 IF( zup == -zbig ) zbetup(ji,jj,jl) = 0._wp ! zbig 1246 IF( zdo == zbig ) zbetdo(ji,jj,jl) = 0._wp ! zbig 1246 IF( zdo == zbig ) zbetdo(ji,jj,jl) = 0._wp ! zbig 1247 1247 ! 1248 1248 END_2D … … 1250 1250 CALL lbc_lnk_multi( 'icedyn_adv_umx', zbetup, 'T', 1.0_wp, zbetdo, 'T', 1.0_wp ) ! lateral boundary cond. (unchanged sign) 1251 1251 1252 1252 1253 1253 ! monotonic flux in the y direction 1254 1254 ! --------------------------------- … … 1280 1280 END SUBROUTINE nonosc_ice 1281 1281 1282 1282 1283 1283 SUBROUTINE limiter_x( pdt, pu, pt, pfu_ups, pfu_ho ) 1284 1284 !!--------------------------------------------------------------------- 1285 1285 !! *** ROUTINE limiter_x *** 1286 !! 1287 !! ** Purpose : compute flux limiter 1286 !! 1287 !! ** Purpose : compute flux limiter 1288 1288 !!---------------------------------------------------------------------- 1289 1289 REAL(wp) , INTENT(in ) :: pdt ! tracer time-step … … 1295 1295 REAL(wp) :: Cr, Rjm, Rj, Rjp, uCFL, zpsi, zh3, zlimiter, Rr 1296 1296 INTEGER :: ji, jj, jl ! dummy loop indices 1297 REAL(wp), DIMENSION (jpi,jpj,jpl) :: zslpx ! tracer slopes 1297 REAL(wp), DIMENSION (jpi,jpj,jpl) :: zslpx ! tracer slopes 1298 1298 !!---------------------------------------------------------------------- 1299 1299 ! … … 1304 1304 END DO 1305 1305 CALL lbc_lnk( 'icedyn_adv_umx', zslpx, 'U', -1.0_wp) ! lateral boundary cond. 1306 1306 1307 1307 DO jl = 1, jpl 1308 1308 DO_2D( 0, 0, 0, 0 ) 1309 1309 uCFL = pdt * ABS( pu(ji,jj) ) * r1_e1e2t(ji,jj) 1310 1310 1311 1311 Rjm = zslpx(ji-1,jj,jl) 1312 1312 Rj = zslpx(ji ,jj,jl) … … 1319 1319 ENDIF 1320 1320 1321 zh3 = pfu_ho(ji,jj,jl) - pfu_ups(ji,jj,jl) 1321 zh3 = pfu_ho(ji,jj,jl) - pfu_ups(ji,jj,jl) 1322 1322 IF( Rj > 0. ) THEN 1323 1323 zlimiter = MAX( 0., MIN( zh3, MAX(-Rr * 0.5 * ABS(pu(ji,jj)), & … … 1371 1371 END SUBROUTINE limiter_x 1372 1372 1373 1373 1374 1374 SUBROUTINE limiter_y( pdt, pv, pt, pfv_ups, pfv_ho ) 1375 1375 !!--------------------------------------------------------------------- 1376 1376 !! *** ROUTINE limiter_y *** 1377 !! 1378 !! ** Purpose : compute flux limiter 1377 !! 1378 !! ** Purpose : compute flux limiter 1379 1379 !!---------------------------------------------------------------------- 1380 1380 REAL(wp) , INTENT(in ) :: pdt ! tracer time-step … … 1386 1386 REAL(wp) :: Cr, Rjm, Rj, Rjp, vCFL, zpsi, zh3, zlimiter, Rr 1387 1387 INTEGER :: ji, jj, jl ! dummy loop indices 1388 REAL(wp), DIMENSION (jpi,jpj,jpl) :: zslpy ! tracer slopes 1388 REAL(wp), DIMENSION (jpi,jpj,jpl) :: zslpy ! tracer slopes 1389 1389 !!---------------------------------------------------------------------- 1390 1390 ! … … 1410 1410 ENDIF 1411 1411 1412 zh3 = pfv_ho(ji,jj,jl) - pfv_ups(ji,jj,jl) 1412 zh3 = pfv_ho(ji,jj,jl) - pfv_ups(ji,jj,jl) 1413 1413 IF( Rj > 0. ) THEN 1414 1414 zlimiter = MAX( 0., MIN( zh3, MAX(-Rr * 0.5 * ABS(pv(ji,jj)), & … … 1524 1524 pe_s(ji,jj,1:nlay_s,jl) = pe_s(ji,jj,1:nlay_s,jl) * zfra 1525 1525 pv_s(ji,jj,jl) = pa_i(ji,jj,jl) * phs_max(ji,jj,jl) 1526 ENDIF 1527 ! 1526 ENDIF 1527 ! 1528 1528 ! ! -- check s_i -- ! 1529 1529 ! if s_i is larger than the surrounding 9 pts => put salt excess in the ocean … … 1537 1537 ENDIF 1538 1538 END_2D 1539 END DO 1539 END DO 1540 1540 ! 1541 1541 ! ! -- check e_i/v_i -- ! … … 1624 1624 SUBROUTINE icemax3D( pice , pmax ) 1625 1625 !!--------------------------------------------------------------------- 1626 !! *** ROUTINE icemax3D *** 1626 !! *** ROUTINE icemax3D *** 1627 1627 !! ** Purpose : compute the max of the 9 points around 1628 1628 !!---------------------------------------------------------------------- … … 1633 1633 !!---------------------------------------------------------------------- 1634 1634 DO jl = 1, jpl 1635 DO jj = Njs0-1, Nje0+1 1635 DO jj = Njs0-1, Nje0+1 1636 1636 DO ji = Nis0, Nie0 1637 1637 zmax(ji,jj) = MAX( epsi20, pice(ji,jj,jl), pice(ji-1,jj,jl), pice(ji+1,jj,jl) ) 1638 1638 END DO 1639 1639 END DO 1640 DO jj = Njs0, Nje0 1640 DO jj = Njs0, Nje0 1641 1641 DO ji = Nis0, Nie0 1642 1642 pmax(ji,jj,jl) = MAX( epsi20, zmax(ji,jj), zmax(ji,jj-1), zmax(ji,jj+1) ) … … 1648 1648 SUBROUTINE icemax4D( pice , pmax ) 1649 1649 !!--------------------------------------------------------------------- 1650 !! *** ROUTINE icemax4D *** 1650 !! *** ROUTINE icemax4D *** 1651 1651 !! ** Purpose : compute the max of the 9 points around 1652 1652 !!---------------------------------------------------------------------- … … 1659 1659 DO jl = 1, jpl 1660 1660 DO jk = 1, jlay 1661 DO jj = Njs0-1, Nje0+1 1661 DO jj = Njs0-1, Nje0+1 1662 1662 DO ji = Nis0, Nie0 1663 1663 zmax(ji,jj) = MAX( epsi20, pice(ji,jj,jk,jl), pice(ji-1,jj,jk,jl), pice(ji+1,jj,jk,jl) ) 1664 1664 END DO 1665 1665 END DO 1666 DO jj = Njs0, Nje0 1666 DO jj = Njs0, Nje0 1667 1667 DO ji = Nis0, Nie0 1668 1668 pmax(ji,jj,jk,jl) = MAX( epsi20, zmax(ji,jj), zmax(ji,jj-1), zmax(ji,jj+1) ) -
NEMO/trunk/src/ICE/icedyn_rdgrft.F90
r14011 r14072 2 2 !!====================================================================== 3 3 !! *** MODULE icedyn_rdgrft *** 4 !! sea-ice : Mechanical impact on ice thickness distribution 4 !! sea-ice : Mechanical impact on ice thickness distribution 5 5 !!====================================================================== 6 !! History : ! 2006-02 (M. Vancoppenolle) Original code 6 !! History : ! 2006-02 (M. Vancoppenolle) Original code 7 7 !! 4.0 ! 2018 (many people) SI3 [aka Sea Ice cube] 8 8 !!---------------------------------------------------------------------- … … 16 16 !!---------------------------------------------------------------------- 17 17 USE dom_oce ! ocean domain 18 USE phycst ! physical constants (ocean directory) 18 USE phycst ! physical constants (ocean directory) 19 19 USE sbc_oce , ONLY : sss_m, sst_m ! surface boundary condition: ocean fields 20 20 USE ice1D ! sea-ice: thermodynamics … … 59 59 LOGICAL :: ln_str_H79 ! ice strength parameterization (Hibler79) 60 60 REAL(wp) :: rn_pstar ! determines ice strength, Hibler JPO79 61 REAL(wp) :: rn_csrdg ! fraction of shearing energy contributing to ridging 61 REAL(wp) :: rn_csrdg ! fraction of shearing energy contributing to ridging 62 62 LOGICAL :: ln_partf_lin ! participation function linear (Thorndike et al. (1975)) 63 63 REAL(wp) :: rn_gstar ! fractional area of young ice contributing to ridging 64 64 LOGICAL :: ln_partf_exp ! participation function exponential (Lipscomb et al. (2007)) 65 65 REAL(wp) :: rn_astar ! equivalent of G* for an exponential participation function 66 LOGICAL :: ln_ridging ! ridging of ice or not 66 LOGICAL :: ln_ridging ! ridging of ice or not 67 67 REAL(wp) :: rn_hstar ! thickness that determines the maximal thickness of ridged ice 68 68 REAL(wp) :: rn_porordg ! initial porosity of ridges (0.3 regular value) 69 69 REAL(wp) :: rn_fsnwrdg ! fractional snow loss to the ocean during ridging 70 70 REAL(wp) :: rn_fpndrdg ! fractional pond loss to the ocean during ridging 71 LOGICAL :: ln_rafting ! rafting of ice or not 72 REAL(wp) :: rn_hraft ! threshold thickness (m) for rafting / ridging 71 LOGICAL :: ln_rafting ! rafting of ice or not 72 REAL(wp) :: rn_hraft ! threshold thickness (m) for rafting / ridging 73 73 REAL(wp) :: rn_craft ! coefficient for smoothness of the hyperbolic tangent in rafting 74 74 REAL(wp) :: rn_fsnwrft ! fractional snow loss to the ocean during rafting … … 124 124 !! Hibler, W. D. III, 1980, MWR, 108, 1943-1973, 1980. 125 125 !! Rothrock, D. A., 1975: JGR, 80, 4514-4519. 126 !! Thorndike et al., 1975, JGR, 80, 4501-4513. 126 !! Thorndike et al., 1975, JGR, 80, 4501-4513. 127 127 !! Bitz et al., JGR, 2001 128 128 !! Amundrud and Melling, JGR 2005 129 !! Babko et al., JGR 2002 129 !! Babko et al., JGR 2002 130 130 !! 131 131 !! This routine is based on CICE code and authors William H. Lipscomb, … … 135 135 !! 136 136 INTEGER :: ji, jj, jk, jl ! dummy loop index 137 INTEGER :: iter, iterate_ridging ! local integer 137 INTEGER :: iter, iterate_ridging ! local integer 138 138 INTEGER :: ipti ! local integer 139 139 REAL(wp) :: zfac ! local scalar … … 142 142 REAL(wp), DIMENSION(jpij) :: zconv ! 1D rdg_conv (if EAP rheology) 143 143 ! 144 INTEGER, PARAMETER :: jp_itermax = 20 144 INTEGER, PARAMETER :: jp_itermax = 20 145 145 !!------------------------------------------------------------------- 146 146 ! controls … … 153 153 IF(lwp) WRITE(numout,*)'ice_dyn_rdgrft: ice ridging and rafting' 154 154 IF(lwp) WRITE(numout,*)'~~~~~~~~~~~~~~' 155 ENDIF 155 ENDIF 156 156 157 157 !-------------------------------- … … 168 168 ENDIF 169 169 END_2D 170 170 171 171 !-------------------------------------------------------- 172 172 ! 1) Dynamical inputs (closing rate, divergence, opening) 173 173 !-------------------------------------------------------- 174 174 IF( npti > 0 ) THEN 175 175 176 176 ! just needed here 177 177 CALL tab_2d_1d( npti, nptidx(1:npti), zdelt (1:npti) , delta_i ) … … 184 184 185 185 DO ji = 1, npti 186 ! closing_net = rate at which open water area is removed + ice area removed by ridging 186 ! closing_net = rate at which open water area is removed + ice area removed by ridging 187 187 ! - ice area added in new ridges 188 IF( ln_rhg_EVP .OR. ln_rhg_VP ) & 188 IF( ln_rhg_EVP .OR. ln_rhg_VP ) & 189 189 & closing_net(ji) = rn_csrdg * 0.5_wp * ( zdelt(ji) - ABS( zdivu(ji) ) ) - MIN( zdivu(ji), 0._wp ) 190 190 IF( ln_rhg_EAP ) closing_net(ji) = zconv(ji) … … 225 225 !----------------- 226 226 IF( npti > 0 ) THEN 227 227 228 228 CALL ice_dyn_1d2d( 1 ) ! --- Move to 1D arrays --- ! 229 229 230 230 iter = 1 231 iterate_ridging = 1 231 iterate_ridging = 1 232 232 ! !----------------------! 233 233 DO WHILE( iterate_ridging > 0 .AND. iter < jp_itermax ) ! ridging iterations ! … … 268 268 269 269 ENDIF 270 271 CALL ice_var_agg( 1 ) 270 271 CALL ice_var_agg( 1 ) 272 272 273 273 ! controls … … 287 287 !! ** Purpose : preparation for ridging calculations 288 288 !! 289 !! ** Method : Compute the thickness distribution of the ice and open water 289 !! ** Method : Compute the thickness distribution of the ice and open water 290 290 !! participating in ridging and of the resulting ridges. 291 291 !!------------------------------------------------------------------- 292 REAL(wp), DIMENSION(:) , INTENT(in) :: pato_i, pclosing_net 293 REAL(wp), DIMENSION(:,:), INTENT(in) :: pa_i, pv_i 292 REAL(wp), DIMENSION(:) , INTENT(in) :: pato_i, pclosing_net 293 REAL(wp), DIMENSION(:,:), INTENT(in) :: pa_i, pv_i 294 294 !! 295 295 INTEGER :: ji, jl ! dummy loop indices 296 296 REAL(wp) :: z1_gstar, z1_astar, zhmean, zfac ! local scalar 297 REAL(wp), DIMENSION(jpij) :: zasum, z1_asum, zaksum ! sum of a_i+ato_i and reverse 297 REAL(wp), DIMENSION(jpij) :: zasum, z1_asum, zaksum ! sum of a_i+ato_i and reverse 298 298 REAL(wp), DIMENSION(jpij,jpl) :: zhi ! ice thickness 299 299 REAL(wp), DIMENSION(jpij,-1:jpl) :: zGsum ! zGsum(n) = sum of areas in categories 0 to n … … 321 321 ! This is analogous to 322 322 ! a(h) = b(h)g(h) as defined in Thorndike et al. (1975). 323 ! assuming b(h) = (2/Gstar) * (1 - G(h)/Gstar). 323 ! assuming b(h) = (2/Gstar) * (1 - G(h)/Gstar). 324 324 ! 325 325 ! apartf = integrating b(h)g(h) between the category boundaries … … 346 346 ! 347 347 IF( ln_partf_lin ) THEN !--- Linear formulation (Thorndike et al., 1975) 348 DO jl = 0, jpl 348 DO jl = 0, jpl 349 349 DO ji = 1, npti 350 350 IF ( zGsum(ji,jl) < rn_gstar ) THEN … … 361 361 ! 362 362 ELSEIF( ln_partf_exp ) THEN !--- Exponential, more stable formulation (Lipscomb et al, 2007) 363 ! 363 ! 364 364 zfac = 1._wp / ( 1._wp - EXP(-z1_astar) ) 365 365 DO jl = -1, jpl … … 391 391 END DO 392 392 END DO 393 ELSEIF( ln_rafting .AND. .NOT. ln_ridging ) THEN !- rafting alone 393 ELSEIF( ln_rafting .AND. .NOT. ln_ridging ) THEN !- rafting alone 394 394 DO jl = 1, jpl 395 395 DO ji = 1, npti … … 402 402 DO ji = 1, npti 403 403 aridge(ji,jl) = 0._wp 404 araft (ji,jl) = 0._wp 404 araft (ji,jl) = 0._wp 405 405 END DO 406 406 END DO … … 411 411 ! Compute max and min ridged ice thickness for each ridging category. 412 412 ! Assume ridged ice is uniformly distributed between hrmin and hrmax. 413 ! 413 ! 414 414 ! This parameterization is a modified version of Hibler (1980). 415 415 ! The mean ridging thickness, zhmean, is proportional to hi^(0.5) 416 416 ! and for very thick ridging ice must be >= hrdg_hi_min*hi 417 417 ! 418 ! The minimum ridging thickness, hrmin, is equal to 2*hi 418 ! The minimum ridging thickness, hrmin, is equal to 2*hi 419 419 ! (i.e., rafting) and for very thick ridging ice is 420 420 ! constrained by hrmin <= (zhmean + hi)/2. 421 ! 421 ! 422 422 ! The maximum ridging thickness, hrmax, is determined by zhmean and hrmin. 423 423 ! … … 445 445 & + araft (ji,jl) * ( 1._wp - hi_hrft ) 446 446 ELSE 447 hrmin (ji,jl) = 0._wp 448 hrmax (ji,jl) = 0._wp 449 hraft (ji,jl) = 0._wp 447 hrmin (ji,jl) = 0._wp 448 hrmax (ji,jl) = 0._wp 449 hraft (ji,jl) = 0._wp 450 450 hi_hrdg(ji,jl) = 1._wp 451 451 ENDIF … … 455 455 ! 3) closing_gross 456 456 !----------------- 457 ! Based on the ITD of ridging and ridged ice, convert the net closing rate to a gross closing rate. 457 ! Based on the ITD of ridging and ridged ice, convert the net closing rate to a gross closing rate. 458 458 ! NOTE: 0 < aksum <= 1 459 459 WHERE( zaksum(1:npti) > epsi10 ) ; closing_gross(1:npti) = pclosing_net(1:npti) / zaksum(1:npti) 460 460 ELSEWHERE ; closing_gross(1:npti) = 0._wp 461 461 END WHERE 462 462 463 463 ! correction to closing rate if excessive ice removal 464 464 !---------------------------------------------------- … … 472 472 ENDIF 473 473 END DO 474 END DO 474 END DO 475 475 476 476 ! 4) correction to opening if excessive open water removal … … 478 478 ! Reduce the closing rate if more than 100% of the open water would be removed 479 479 ! Reduce the opening rate in proportion 480 DO ji = 1, npti 480 DO ji = 1, npti 481 481 zfac = pato_i(ji) + ( opning(ji) - apartf(ji,0) * closing_gross(ji) ) * rDt_ice 482 482 IF( zfac < 0._wp ) THEN ! would lead to negative ato_i 483 opning(ji) = apartf(ji,0) * closing_gross(ji) - pato_i(ji) * r1_Dt_ice 483 opning(ji) = apartf(ji,0) * closing_gross(ji) - pato_i(ji) * r1_Dt_ice 484 484 ELSEIF( zfac > zasum(ji) ) THEN ! would lead to ato_i > asum 485 opning(ji) = apartf(ji,0) * closing_gross(ji) + ( zasum(ji) - pato_i(ji) ) * r1_Dt_ice 485 opning(ji) = apartf(ji,0) * closing_gross(ji) + ( zasum(ji) - pato_i(ji) ) * r1_Dt_ice 486 486 ENDIF 487 487 END DO … … 503 503 REAL(wp) :: hL, hR, farea ! left and right limits of integration and new area going to jl2 504 504 REAL(wp) :: vsw ! vol of water trapped into ridges 505 REAL(wp) :: afrdg, afrft ! fraction of category area ridged/rafted 505 REAL(wp) :: afrdg, afrft ! fraction of category area ridged/rafted 506 506 REAL(wp) :: airdg1, oirdg1, aprdg1, virdg1, sirdg1 507 507 REAL(wp) :: airft1, oirft1, aprft1 … … 516 516 REAL(wp), DIMENSION(jpij,nlay_s) :: esrft ! snow energy of rafting ice 517 517 REAL(wp), DIMENSION(jpij,nlay_i) :: eirft ! ice energy of rafting ice 518 REAL(wp), DIMENSION(jpij,nlay_s) :: esrdg ! enth*volume of new ridges 518 REAL(wp), DIMENSION(jpij,nlay_s) :: esrdg ! enth*volume of new ridges 519 519 REAL(wp), DIMENSION(jpij,nlay_i) :: eirdg ! enth*volume of new ridges 520 520 ! … … 529 529 ato_i_1d(ji) = MAX( 0._wp, ato_i_1d(ji) + ( opning(ji) - apartf(ji,0) * closing_gross(ji) ) * rDt_ice ) 530 530 END DO 531 532 ! 2) compute categories in which ice is removed (jl1) 531 532 ! 2) compute categories in which ice is removed (jl1) 533 533 !---------------------------------------------------- 534 534 DO jl1 = 1, jpl 535 535 536 IF( nn_icesal /= 2 ) THEN 536 IF( nn_icesal /= 2 ) THEN 537 537 CALL tab_2d_1d( npti, nptidx(1:npti), s_i_1d(1:npti), s_i(:,:,jl1) ) 538 538 ENDIF … … 545 545 ELSE ; z1_ai(ji) = 0._wp 546 546 ENDIF 547 547 548 548 ! area of ridging / rafting ice (airdg1) and of new ridge (airdg2) 549 549 airdg1 = aridge(ji,jl1) * closing_gross(ji) * rDt_ice … … 571 571 sirdg2(ji) = sv_i_2d(ji,jl1) * afrdg + vsw * sss_1d(ji) 572 572 oirdg1 = oa_i_2d(ji,jl1) * afrdg 573 oirdg2(ji) = oa_i_2d(ji,jl1) * afrdg * hi_hrdg(ji,jl1) 573 oirdg2(ji) = oa_i_2d(ji,jl1) * afrdg * hi_hrdg(ji,jl1) 574 574 575 575 virft(ji) = v_i_2d (ji,jl1) * afrft 576 576 vsrft(ji) = v_s_2d (ji,jl1) * afrft 577 sirft(ji) = sv_i_2d(ji,jl1) * afrft 578 oirft1 = oa_i_2d(ji,jl1) * afrft 579 oirft2(ji) = oa_i_2d(ji,jl1) * afrft * hi_hrft 577 sirft(ji) = sv_i_2d(ji,jl1) * afrft 578 oirft1 = oa_i_2d(ji,jl1) * afrft 579 oirft2(ji) = oa_i_2d(ji,jl1) * afrft * hi_hrft 580 580 581 581 IF ( ln_pnd_LEV .OR. ln_pnd_TOPO ) THEN … … 595 595 wfx_dyn_1d(ji) = wfx_dyn_1d(ji) - vsw * rhoi * r1_Dt_ice ! increase in ice volume due to seawater frozen in voids 596 596 sfx_dyn_1d(ji) = sfx_dyn_1d(ji) - vsw * sss_1d(ji) * rhoi * r1_Dt_ice 597 hfx_dyn_1d(ji) = hfx_dyn_1d(ji) + ersw(ji) * r1_Dt_ice ! > 0 [W.m-2] 597 hfx_dyn_1d(ji) = hfx_dyn_1d(ji) + ersw(ji) * r1_Dt_ice ! > 0 [W.m-2] 598 598 599 599 ! Put the snow lost by ridging into the ocean … … 606 606 sirdg2(ji) = sirdg2(ji) - vsw * ( sss_1d(ji) - s_i_1d(ji) ) ! ridge salinity = s_i 607 607 sfx_bri_1d(ji) = sfx_bri_1d(ji) + sss_1d(ji) * vsw * rhoi * r1_Dt_ice & ! put back sss_m into the ocean 608 & - s_i_1d(ji) * vsw * rhoi * r1_Dt_ice ! and get s_i from the ocean 608 & - s_i_1d(ji) * vsw * rhoi * r1_Dt_ice ! and get s_i from the ocean 609 609 ENDIF 610 610 … … 643 643 ! Remove energy of new ridge to each category jl1 644 644 !------------------------------------------------- 645 ze_s_2d(ji,jk,jl1) = ze_s_2d(ji,jk,jl1) * ( 1._wp - afrdg - afrft ) 645 ze_s_2d(ji,jk,jl1) = ze_s_2d(ji,jk,jl1) * ( 1._wp - afrdg - afrft ) 646 646 ENDIF 647 647 END DO 648 648 END DO 649 649 650 650 ! special loop for e_i because of layers jk 651 651 DO jk = 1, nlay_i … … 661 661 ! Remove energy of new ridge to each category jl1 662 662 !------------------------------------------------- 663 ze_i_2d(ji,jk,jl1) = ze_i_2d(ji,jk,jl1) * ( 1._wp - afrdg - afrft ) 663 ze_i_2d(ji,jk,jl1) = ze_i_2d(ji,jk,jl1) * ( 1._wp - afrdg - afrft ) 664 664 ENDIF 665 665 END DO 666 666 END DO 667 668 ! 3) compute categories in which ice is added (jl2) 667 668 ! 3) compute categories in which ice is added (jl2) 669 669 !-------------------------------------------------- 670 670 itest_rdg(1:npti) = 0 671 671 itest_rft(1:npti) = 0 672 DO jl2 = 1, jpl 672 DO jl2 = 1, jpl 673 673 ! 674 674 DO ji = 1, npti … … 685 685 itest_rdg(ji) = 1 ! test for conservation 686 686 ELSE 687 farea = 0._wp 688 fvol(ji) = 0._wp 687 farea = 0._wp 688 fvol(ji) = 0._wp 689 689 ENDIF 690 690 … … 701 701 ! Sometimes thickness is larger than hi_max(jpl) because of advection scheme (for very small areas) 702 702 ! Then ice volume is removed from one category but the ridging/rafting scheme 703 ! does not know where to move it, leading to a conservation issue. 703 ! does not know where to move it, leading to a conservation issue. 704 704 IF( itest_rdg(ji) == 0 .AND. jl2 == jpl ) THEN ; farea = 1._wp ; fvol(ji) = 1._wp ; ENDIF 705 705 IF( itest_rft(ji) == 0 .AND. jl2 == jpl ) zswitch(ji) = 1._wp … … 716 716 v_ip_2d (ji,jl2) = v_ip_2d(ji,jl2) + ( vprdg (ji) * rn_fpndrdg * fvol (ji) & 717 717 & + vprft (ji) * rn_fpndrft * zswitch(ji) ) 718 a_ip_2d (ji,jl2) = a_ip_2d(ji,jl2) + ( aprdg2(ji) * rn_fpndrdg * farea & 718 a_ip_2d (ji,jl2) = a_ip_2d(ji,jl2) + ( aprdg2(ji) * rn_fpndrdg * farea & 719 719 & + aprft2(ji) * rn_fpndrft * zswitch(ji) ) 720 720 IF ( ln_pnd_lids ) THEN … … 723 723 ENDIF 724 724 ENDIF 725 725 726 726 ENDIF 727 727 … … 741 741 DO ji = 1, npti 742 742 IF( apartf(ji,jl1) > 0._wp .AND. closing_gross(ji) > 0._wp ) & 743 & ze_i_2d(ji,jk,jl2) = ze_i_2d(ji,jk,jl2) + eirdg(ji,jk) * fvol(ji) + eirft(ji,jk) * zswitch(ji) 743 & ze_i_2d(ji,jk,jl2) = ze_i_2d(ji,jk,jl2) + eirdg(ji,jk) * fvol(ji) + eirft(ji,jk) * zswitch(ji) 744 744 END DO 745 745 END DO … … 763 763 !! ** Purpose : computes ice strength used in dynamics routines of ice thickness 764 764 !! 765 !! ** Method : Compute the strength of the ice pack, defined as the energy (J m-2) 765 !! ** Method : Compute the strength of the ice pack, defined as the energy (J m-2) 766 766 !! dissipated per unit area removed from the ice pack under compression, 767 767 !! and assumed proportional to the change in potential energy caused … … 793 793 CASE( 1 ) !--- Spatial smoothing 794 794 DO_2D( 0, 0, 0, 0 ) 795 IF ( SUM( a_i(ji,jj,:) ) > 0._wp ) THEN 795 IF ( SUM( a_i(ji,jj,:) ) > 0._wp ) THEN 796 796 zworka(ji,jj) = ( 4.0 * strength(ji,jj) & 797 & + strength(ji-1,jj) * tmask(ji-1,jj,1) + strength(ji+1,jj) * tmask(ji+1,jj,1) & 797 & + strength(ji-1,jj) * tmask(ji-1,jj,1) + strength(ji+1,jj) * tmask(ji+1,jj,1) & 798 798 & + strength(ji,jj-1) * tmask(ji,jj-1,1) + strength(ji,jj+1) * tmask(ji,jj+1,1) & 799 799 & ) / ( 4.0 + tmask(ji-1,jj,1) + tmask(ji+1,jj,1) + tmask(ji,jj-1,1) + tmask(ji,jj+1,1) ) … … 802 802 ENDIF 803 803 END_2D 804 804 805 805 DO_2D( 0, 0, 0, 0 ) 806 806 strength(ji,jj) = zworka(ji,jj) … … 815 815 ! 816 816 DO_2D( 0, 0, 0, 0 ) 817 IF ( SUM( a_i(ji,jj,:) ) > 0._wp ) THEN 817 IF ( SUM( a_i(ji,jj,:) ) > 0._wp ) THEN 818 818 itframe = 1 ! number of time steps for the running mean 819 819 IF ( zstrp1(ji,jj) > 0._wp ) itframe = itframe + 1 … … 831 831 END SUBROUTINE ice_strength 832 832 833 833 834 834 SUBROUTINE ice_dyn_1d2d( kn ) 835 835 !!----------------------------------------------------------------------- 836 !! *** ROUTINE ice_dyn_1d2d *** 837 !! 836 !! *** ROUTINE ice_dyn_1d2d *** 837 !! 838 838 !! ** Purpose : move arrays from 1d to 2d and the reverse 839 839 !!----------------------------------------------------------------------- … … 905 905 ! 906 906 END SUBROUTINE ice_dyn_1d2d 907 907 908 908 909 909 SUBROUTINE ice_dyn_rdgrft_init … … 911 911 !! *** ROUTINE ice_dyn_rdgrft_init *** 912 912 !! 913 !! ** Purpose : Physical constants and parameters linked 913 !! ** Purpose : Physical constants and parameters linked 914 914 !! to the mechanical ice redistribution 915 915 !! 916 !! ** Method : Read the namdyn_rdgrft namelist 917 !! and check the parameters values 916 !! ** Method : Read the namdyn_rdgrft namelist 917 !! and check the parameters values 918 918 !! called at the first timestep (nit000) 919 919 !! … … 925 925 & rn_csrdg , & 926 926 & ln_partf_lin, rn_gstar, & 927 & ln_partf_exp, rn_astar, & 928 & ln_ridging, rn_hstar, rn_porordg, rn_fsnwrdg, rn_fpndrdg, & 927 & ln_partf_exp, rn_astar, & 928 & ln_ridging, rn_hstar, rn_porordg, rn_fsnwrdg, rn_fpndrdg, & 929 929 & ln_rafting, rn_hraft, rn_craft , rn_fsnwrft, rn_fpndrft 930 930 !!------------------------------------------------------------------- … … 941 941 WRITE(numout,*) '~~~~~~~~~~~~~~~~~~' 942 942 WRITE(numout,*) ' Namelist namdyn_rdgrft:' 943 WRITE(numout,*) ' ice strength parameterization Hibler (1979) ln_str_H79 = ', ln_str_H79 943 WRITE(numout,*) ' ice strength parameterization Hibler (1979) ln_str_H79 = ', ln_str_H79 944 944 WRITE(numout,*) ' 1st bulk-rheology parameter rn_pstar = ', rn_pstar 945 945 WRITE(numout,*) ' 2nd bulk-rhelogy parameter rn_crhg = ', rn_crhg 946 WRITE(numout,*) ' Fraction of shear energy contributing to ridging rn_csrdg = ', rn_csrdg 946 WRITE(numout,*) ' Fraction of shear energy contributing to ridging rn_csrdg = ', rn_csrdg 947 947 WRITE(numout,*) ' linear ridging participation function ln_partf_lin = ', ln_partf_lin 948 948 WRITE(numout,*) ' Fraction of ice coverage contributing to ridging rn_gstar = ', rn_gstar … … 952 952 WRITE(numout,*) ' max ridged ice thickness rn_hstar = ', rn_hstar 953 953 WRITE(numout,*) ' Initial porosity of ridges rn_porordg = ', rn_porordg 954 WRITE(numout,*) ' Fraction of snow volume conserved during ridging rn_fsnwrdg = ', rn_fsnwrdg 955 WRITE(numout,*) ' Fraction of pond volume conserved during ridging rn_fpndrdg = ', rn_fpndrdg 954 WRITE(numout,*) ' Fraction of snow volume conserved during ridging rn_fsnwrdg = ', rn_fsnwrdg 955 WRITE(numout,*) ' Fraction of pond volume conserved during ridging rn_fpndrdg = ', rn_fpndrdg 956 956 WRITE(numout,*) ' Rafting of ice sheets or not ln_rafting = ', ln_rafting 957 957 WRITE(numout,*) ' Parmeter thickness (threshold between ridge-raft) rn_hraft = ', rn_hraft 958 WRITE(numout,*) ' Rafting hyperbolic tangent coefficient rn_craft = ', rn_craft 959 WRITE(numout,*) ' Fraction of snow volume conserved during rafting rn_fsnwrft = ', rn_fsnwrft 960 WRITE(numout,*) ' Fraction of pond volume conserved during rafting rn_fpndrft = ', rn_fpndrft 958 WRITE(numout,*) ' Rafting hyperbolic tangent coefficient rn_craft = ', rn_craft 959 WRITE(numout,*) ' Fraction of snow volume conserved during rafting rn_fsnwrft = ', rn_fsnwrft 960 WRITE(numout,*) ' Fraction of pond volume conserved during rafting rn_fpndrft = ', rn_fpndrft 961 961 ENDIF 962 962 ! … … 972 972 WRITE(numout,*) ' ==> only ice dynamics is activated, thus some parameters must be changed' 973 973 WRITE(numout,*) ' rn_porordg = ', rn_porordg 974 WRITE(numout,*) ' rn_fsnwrdg = ', rn_fsnwrdg 975 WRITE(numout,*) ' rn_fpndrdg = ', rn_fpndrdg 976 WRITE(numout,*) ' rn_fsnwrft = ', rn_fsnwrft 977 WRITE(numout,*) ' rn_fpndrft = ', rn_fpndrft 974 WRITE(numout,*) ' rn_fsnwrdg = ', rn_fsnwrdg 975 WRITE(numout,*) ' rn_fpndrdg = ', rn_fpndrdg 976 WRITE(numout,*) ' rn_fsnwrft = ', rn_fsnwrft 977 WRITE(numout,*) ' rn_fpndrft = ', rn_fpndrft 978 978 ENDIF 979 979 ENDIF -
NEMO/trunk/src/ICE/icedyn_rhg.F90
r14006 r14072 2 2 !!====================================================================== 3 3 !! *** MODULE icedyn_rhg *** 4 !! Sea-Ice dynamics : master routine for rheology 4 !! Sea-Ice dynamics : master routine for rheology 5 5 !!====================================================================== 6 6 !! history : 4.0 ! 2018 (C. Rousset) Original code … … 49 49 !!------------------------------------------------------------------- 50 50 !! *** ROUTINE ice_dyn_rhg *** 51 !! 51 !! 52 52 !! ** Purpose : compute ice velocity 53 53 !! … … 72 72 !--------------! 73 73 !== Rheology ==! 74 !--------------! 74 !--------------! 75 75 SELECT CASE( nice_rhg ) 76 76 ! !------------------------! … … 78 78 ! !------------------------! 79 79 CALL ice_dyn_rhg_evp( kt, Kmm, stress1_i, stress2_i, stress12_i, shear_i, divu_i, delta_i ) 80 ! 80 ! 81 81 ! !------------------------! 82 82 CASE( np_rhgVP ) ! Viscous-Plastic ! … … 121 121 !! 122 122 NAMELIST/namdyn_rhg/ ln_rhg_EVP, ln_aEVP, ln_rhg_EAP, rn_creepl, rn_ecc , nn_nevp, rn_relast, nn_rhg_chkcvg, & !-- evp 123 & ln_rhg_VP, nn_vp_nout, nn_vp_ninn, nn_vp_chkcvg !-- vp 123 & ln_rhg_VP, nn_vp_nout, nn_vp_ninn, nn_vp_chkcvg !-- vp 124 124 !!------------------------------------------------------------------- 125 125 ! … … 156 156 ! 157 157 ! !== set the choice of ice advection ==! 158 ioptio = 0 158 ioptio = 0 159 159 IF( ln_rhg_EVP ) THEN ; ioptio = ioptio + 1 ; nice_rhg = np_rhgEVP ; ENDIF 160 160 IF( ln_rhg_EAP ) THEN ; ioptio = ioptio + 1 ; nice_rhg = np_rhgEAP ; ENDIF 161 IF( ln_rhg_VP ) THEN ; ioptio = ioptio + 1 ; nice_rhg = np_rhgVP ; ENDIF 161 IF( ln_rhg_VP ) THEN ; ioptio = ioptio + 1 ; nice_rhg = np_rhgVP ; ENDIF 162 162 IF( ioptio /= 1 ) CALL ctl_stop( 'ice_dyn_rhg_init: choose one and only one ice rheology' ) 163 163 ! … … 172 172 !! Default option Empty module NO SI3 sea-ice model 173 173 !!---------------------------------------------------------------------- 174 #endif 174 #endif 175 175 176 176 !!====================================================================== -
NEMO/trunk/src/ICE/icedyn_rhg_evp.F90
r14005 r14072 6 6 !! History : - ! 2007-03 (M.A. Morales Maqueda, S. Bouillon) Original code 7 7 !! 3.0 ! 2008-03 (M. Vancoppenolle) adaptation to new model 8 !! - ! 2008-11 (M. Vancoppenolle, S. Bouillon, Y. Aksenov) add surface tilt in ice rheolohy 8 !! - ! 2008-11 (M. Vancoppenolle, S. Bouillon, Y. Aksenov) add surface tilt in ice rheolohy 9 9 !! 3.3 ! 2009-05 (G.Garric) addition of the evp case 10 !! 3.4 ! 2011-01 (A. Porter) dynamical allocation 10 !! 3.4 ! 2011-01 (A. Porter) dynamical allocation 11 11 !! 3.5 ! 2012-08 (R. Benshila) AGRIF 12 12 !! 3.6 ! 2016-06 (C. Rousset) Rewriting + landfast ice + mEVP (Bouillon 2013) … … 28 28 USE icevar ! ice_var_sshdyn 29 29 USE icedyn_rdgrft ! sea-ice: ice strength 30 USE bdy_oce , ONLY : ln_bdy 31 USE bdyice 30 USE bdy_oce , ONLY : ln_bdy 31 USE bdyice 32 32 #if defined key_agrif 33 33 USE agrif_ice_interp … … 69 69 !! 70 70 !! ** purpose : determines sea ice drift from wind stress, ice-ocean 71 !! stress and sea-surface slope. Ice-ice interaction is described by 72 !! a non-linear elasto-viscous-plastic (EVP) law including shear 73 !! strength and a bulk rheology (Hunke and Dukowicz, 2002). 71 !! stress and sea-surface slope. Ice-ice interaction is described by 72 !! a non-linear elasto-viscous-plastic (EVP) law including shear 73 !! strength and a bulk rheology (Hunke and Dukowicz, 2002). 74 74 !! 75 75 !! The points in the C-grid look like this, dear reader … … 79 79 !! | 80 80 !! (ji-1,jj) | (ji,jj) 81 !! --------- 81 !! --------- 82 82 !! | | 83 83 !! | (ji,jj) |------(ji,jj) 84 84 !! | | 85 !! --------- 85 !! --------- 86 86 !! (ji-1,jj-1) (ji,jj-1) 87 87 !! … … 90 90 !! snow total volume (vt_s) per unit area 91 91 !! 92 !! ** Action : - compute u_ice, v_ice : the components of the 92 !! ** Action : - compute u_ice, v_ice : the components of the 93 93 !! sea-ice velocity vector 94 94 !! - compute delta_i, shear_i, divu_i, which are inputs … … 96 96 !! 97 97 !! ** Steps : 0) compute mask at F point 98 !! 1) Compute ice snow mass, ice strength 98 !! 1) Compute ice snow mass, ice strength 99 99 !! 2) Compute wind, oceanic stresses, mass terms and 100 100 !! coriolis terms of the momentum equation … … 152 152 REAL(wp), DIMENSION(jpi,jpj) :: zsshdyn ! array used for the calculation of ice surface slope: 153 153 ! ! ocean surface (ssh_m) if ice is not embedded 154 ! ! ice bottom surface if ice is embedded 154 ! ! ice bottom surface if ice is embedded 155 155 REAL(wp), DIMENSION(jpi,jpj) :: zfU , zfV ! internal stresses 156 156 REAL(wp), DIMENSION(jpi,jpj) :: zspgU, zspgV ! surface pressure gradient at U/V points … … 172 172 !! --- diags 173 173 REAL(wp) :: zsig1, zsig2, zsig12, zfac, z1_strength 174 REAL(wp), ALLOCATABLE, DIMENSION(:,:) :: zsig_I, zsig_II, zsig1_p, zsig2_p 174 REAL(wp), ALLOCATABLE, DIMENSION(:,:) :: zsig_I, zsig_II, zsig1_p, zsig2_p 175 175 !! --- SIMIP diags 176 176 REAL(wp), ALLOCATABLE, DIMENSION(:,:) :: zdiag_xmtrp_ice ! X-component of ice mass transport (kg/s) … … 179 179 REAL(wp), ALLOCATABLE, DIMENSION(:,:) :: zdiag_ymtrp_snw ! Y-component of snow mass transport (kg/s) 180 180 REAL(wp), ALLOCATABLE, DIMENSION(:,:) :: zdiag_xatrp ! X-component of area transport (m2/s) 181 REAL(wp), ALLOCATABLE, DIMENSION(:,:) :: zdiag_yatrp ! Y-component of area transport (m2/s) 181 REAL(wp), ALLOCATABLE, DIMENSION(:,:) :: zdiag_yatrp ! Y-component of area transport (m2/s) 182 182 !!------------------------------------------------------------------- 183 183 … … 229 229 ! 1) define some variables and initialize arrays 230 230 !------------------------------------------------------------------------------! 231 zrhoco = rho0 * rn_cio 231 zrhoco = rho0 * rn_cio 232 232 233 233 ! ecc2: square of yield ellipse eccenticrity … … 248 248 ENDIF 249 249 z1_dtevp = 1._wp / zdtevp 250 251 ! Initialise stress tensor 252 zs1 (:,:) = pstress1_i (:,:) 250 251 ! Initialise stress tensor 252 zs1 (:,:) = pstress1_i (:,:) 253 253 zs2 (:,:) = pstress2_i (:,:) 254 254 zs12(:,:) = pstress12_i(:,:) … … 292 292 ! dt/m at T points (for alpha and beta coefficients) 293 293 zdt_m(ji,jj) = zdtevp / MAX( zm1, zmmin ) 294 294 295 295 ! m/dt 296 296 zmU_t(ji,jj) = zmassU * z1_dtevp 297 297 zmV_t(ji,jj) = zmassV * z1_dtevp 298 298 299 299 ! Drag ice-atm. 300 300 ztaux_ai(ji,jj) = zaU(ji,jj) * utau_ice(ji,jj) … … 350 350 ! ! ==================== ! 351 351 DO jter = 1 , nn_nevp ! loop over jter ! 352 ! ! ==================== ! 352 ! ! ==================== ! 353 353 l_full_nf_update = jter == nn_nevp ! false: disable full North fold update (performances) for iter = 1 to nn_nevp-1 354 354 ! … … 377 377 & + zds(ji,jj-1) * zds(ji,jj-1) * e1e2f(ji,jj-1) + zds(ji-1,jj-1) * zds(ji-1,jj-1) * e1e2f(ji-1,jj-1) & 378 378 & ) * 0.25_wp * r1_e1e2t(ji,jj) 379 379 380 380 ! divergence at T points 381 381 zdiv = ( e2u(ji,jj) * u_ice(ji,jj) - e2u(ji-1,jj) * u_ice(ji-1,jj) & … … 383 383 & ) * r1_e1e2t(ji,jj) 384 384 zdiv2 = zdiv * zdiv 385 385 386 386 ! tension at T points 387 387 zdt = ( ( u_ice(ji,jj) * r1_e2u(ji,jj) - u_ice(ji-1,jj) * r1_e2u(ji-1,jj) ) * e2t(ji,jj) * e2t(ji,jj) & … … 389 389 & ) * r1_e1e2t(ji,jj) 390 390 zdt2 = zdt * zdt 391 391 392 392 ! delta at T points 393 zdelta(ji,jj) = SQRT( zdiv2 + ( zdt2 + zds2 ) * z1_ecc2 ) 393 zdelta(ji,jj) = SQRT( zdiv2 + ( zdt2 + zds2 ) * z1_ecc2 ) 394 394 395 395 END_2D … … 407 407 & + e1v(ji,jj) * v_ice(ji,jj) - e1v(ji,jj-1) * v_ice(ji,jj-1) & 408 408 & ) * r1_e1e2t(ji,jj) 409 409 410 410 ! tension at T points (duplication to avoid communications) 411 411 zdt = ( ( u_ice(ji,jj) * r1_e2u(ji,jj) - u_ice(ji-1,jj) * r1_e2u(ji-1,jj) ) * e2t(ji,jj) * e2t(ji,jj) & 412 412 & - ( v_ice(ji,jj) * r1_e1v(ji,jj) - v_ice(ji,jj-1) * r1_e1v(ji,jj-1) ) * e1t(ji,jj) * e1t(ji,jj) & 413 413 & ) * r1_e1e2t(ji,jj) 414 414 415 415 ! alpha for aEVP 416 416 ! gamma = 0.5*P/(delta+creepl) * (c*pi)**2/Area * dt/m … … 427 427 ! zalph2 = zalph1 428 428 ENDIF 429 429 430 430 ! stress at T points (zkt/=0 if landfast) 431 431 zs1(ji,jj) = ( zs1(ji,jj)*zalph1 + zp_delt(ji,jj) * ( zdiv*(1._wp + zkt) - zdelta(ji,jj)*(1._wp - zkt) ) ) * z1_alph1 432 432 zs2(ji,jj) = ( zs2(ji,jj)*zalph2 + zp_delt(ji,jj) * ( zdt * z1_ecc2 * (1._wp + zkt) ) ) * z1_alph2 433 433 434 434 END_2D 435 435 … … 440 440 END_2D 441 441 ENDIF 442 442 443 443 DO_2D( 1, 0, 1, 0 ) 444 444 … … 451 451 ! zalph2 = zalph2 - 1._wp 452 452 ENDIF 453 453 454 454 ! P/delta at F points 455 455 zp_delf = 0.25_wp * ( zp_delt(ji,jj) + zp_delt(ji+1,jj) + zp_delt(ji,jj+1) + zp_delt(ji+1,jj+1) ) 456 456 457 457 ! stress at F points (zkt/=0 if landfast) 458 458 zs12(ji,jj)= ( zs12(ji,jj) * zalph2 + zp_delf * ( zds(ji,jj) * z1_ecc2 * (1._wp + zkt) ) * 0.5_wp ) * z1_alph2 … … 519 519 & + zRHS + zTauO * v_ice(ji,jj) & ! F + tau_ia + Coriolis + spg + tau_io(only ocean part) 520 520 & ) / MAX( zepsi, zmV_t(ji,jj) * ( zbetav + 1._wp ) + zTauO - zTauB ) & ! m/dt + tau_io(only ice part) + landfast 521 & + ( 1._wp - rswitch ) * ( v_ice_b(ji,jj) & 521 & + ( 1._wp - rswitch ) * ( v_ice_b(ji,jj) & 522 522 & + v_ice (ji,jj) * MAX( 0._wp, zbetav - zdtevp * rn_lf_relax ) & ! static friction => slow decrease to v=0 523 523 & ) / ( zbetav + 1._wp ) & … … 574 574 & + u_ice (ji,jj) * MAX( 0._wp, zbetau - zdtevp * rn_lf_relax ) & ! static friction => slow decrease to v=0 575 575 & ) / ( zbetau + 1._wp ) & 576 & ) * zmsk01x(ji,jj) + u_oce(ji,jj) * 0.01_wp * ( 1._wp - zmsk01x(ji,jj) ) & ! v_ice = v_oce/100 if mass < zmmin & conc < zamin 577 & ) * zmsk00x(ji,jj) 578 ELSE !--- ice velocity using EVP implicit formulation (cf Madec doc & Bouillon 2009) 579 u_ice(ji,jj) = ( ( rswitch * ( zmU_t(ji,jj) * u_ice(ji,jj) & ! previous velocity 580 & + zRHS + zTauO * u_ice(ji,jj) & ! F + tau_ia + Coriolis + spg + tau_io(only ocean part) 581 & ) / MAX( zepsi, zmU_t(ji,jj) + zTauO - zTauB ) & ! m/dt + tau_io(only ice part) + landfast 582 & + ( 1._wp - rswitch ) * u_ice(ji,jj) * MAX( 0._wp, 1._wp - zdtevp * rn_lf_relax ) & ! static friction => slow decrease to v=0 583 & ) * zmsk01x(ji,jj) + u_oce(ji,jj) * 0.01_wp * ( 1._wp - zmsk01x(ji,jj) ) & ! v_ice = v_oce/100 if mass < zmmin & conc < zamin 584 & ) * zmsk00x(ji,jj) 585 ENDIF 586 END_2D 587 CALL lbc_lnk( 'icedyn_rhg_evp', u_ice, 'U', -1.0_wp ) 588 ! 589 #if defined key_agrif 590 !! CALL agrif_interp_ice( 'U', jter, nn_nevp ) 591 CALL agrif_interp_ice( 'U' ) 592 #endif 593 IF( ln_bdy ) CALL bdy_ice_dyn( 'U' ) 594 ! 595 ELSE ! odd iterations 596 ! 597 DO_2D( 0, 0, 0, 0 ) 598 ! !--- tau_io/(u_oce - u_ice) 599 zTauO = zaU(ji,jj) * zrhoco * SQRT( ( u_ice (ji,jj) - u_oce (ji,jj) ) * ( u_ice (ji,jj) - u_oce (ji,jj) ) & 600 & + ( v_iceU(ji,jj) - v_oceU(ji,jj) ) * ( v_iceU(ji,jj) - v_oceU(ji,jj) ) ) 601 ! !--- Ocean-to-Ice stress 602 ztaux_oi(ji,jj) = zTauO * ( u_oce(ji,jj) - u_ice(ji,jj) ) 603 ! 604 ! !--- tau_bottom/u_ice 605 zvel = 5.e-05_wp + SQRT( v_iceU(ji,jj) * v_iceU(ji,jj) + u_ice(ji,jj) * u_ice(ji,jj) ) 606 zTauB = ztaux_base(ji,jj) / zvel 607 ! !--- OceanBottom-to-Ice stress 608 ztaux_bi(ji,jj) = zTauB * u_ice(ji,jj) 609 ! 610 ! !--- Coriolis at U-points (energy conserving formulation) 611 zCorU(ji,jj) = 0.25_wp * r1_e1u(ji,jj) * & 612 & ( zmf(ji ,jj) * ( e1v(ji ,jj) * v_ice(ji ,jj) + e1v(ji ,jj-1) * v_ice(ji ,jj-1) ) & 613 & + zmf(ji+1,jj) * ( e1v(ji+1,jj) * v_ice(ji+1,jj) + e1v(ji+1,jj-1) * v_ice(ji+1,jj-1) ) ) 614 ! 615 ! !--- Sum of external forces (explicit solution) = F + tau_ia + Coriolis + spg + tau_io 616 zRHS = zfU(ji,jj) + ztaux_ai(ji,jj) + zCorU(ji,jj) + zspgU(ji,jj) + ztaux_oi(ji,jj) 617 ! 618 ! !--- landfast switch => 0 = static friction : TauB > RHS & sign(TauB) /= sign(RHS) 619 ! 1 = sliding friction : TauB < RHS 620 rswitch = 1._wp - MIN( 1._wp, ABS( SIGN( 1._wp, zRHS + ztaux_base(ji,jj) ) - SIGN( 1._wp, zRHS ) ) ) 621 ! 622 IF( ln_aEVP ) THEN !--- ice velocity using aEVP (Kimmritz et al 2016 & 2017) 623 zbetau = MAX( zbeta(ji,jj), zbeta(ji+1,jj) ) 624 u_ice(ji,jj) = ( ( rswitch * ( zmU_t(ji,jj) * ( zbetau * u_ice(ji,jj) + u_ice_b(ji,jj) ) & ! previous velocity 625 & + zRHS + zTauO * u_ice(ji,jj) & ! F + tau_ia + Coriolis + spg + tau_io(only ocean part) 626 & ) / MAX( zepsi, zmU_t(ji,jj) * ( zbetau + 1._wp ) + zTauO - zTauB ) & ! m/dt + tau_io(only ice part) + landfast 627 & + ( 1._wp - rswitch ) * ( u_ice_b(ji,jj) & 628 & + u_ice (ji,jj) * MAX( 0._wp, zbetau - zdtevp * rn_lf_relax ) & ! static friction => slow decrease to v=0 629 & ) / ( zbetau + 1._wp ) & 630 & ) * zmsk01x(ji,jj) + u_oce(ji,jj) * 0.01_wp * ( 1._wp - zmsk01x(ji,jj) ) & ! v_ice = v_oce/100 if mass < zmmin & conc < zamin 576 & ) * zmsk01x(ji,jj) + u_oce(ji,jj) * 0.01_wp * ( 1._wp - zmsk01x(ji,jj) ) & ! v_ice = v_oce/100 if mass < zmmin & conc < zamin 631 577 & ) * zmsk00x(ji,jj) 632 578 ELSE !--- ice velocity using EVP implicit formulation (cf Madec doc & Bouillon 2009) … … 647 593 IF( ln_bdy ) CALL bdy_ice_dyn( 'U' ) 648 594 ! 595 ELSE ! odd iterations 596 ! 597 DO_2D( 0, 0, 0, 0 ) 598 ! !--- tau_io/(u_oce - u_ice) 599 zTauO = zaU(ji,jj) * zrhoco * SQRT( ( u_ice (ji,jj) - u_oce (ji,jj) ) * ( u_ice (ji,jj) - u_oce (ji,jj) ) & 600 & + ( v_iceU(ji,jj) - v_oceU(ji,jj) ) * ( v_iceU(ji,jj) - v_oceU(ji,jj) ) ) 601 ! !--- Ocean-to-Ice stress 602 ztaux_oi(ji,jj) = zTauO * ( u_oce(ji,jj) - u_ice(ji,jj) ) 603 ! 604 ! !--- tau_bottom/u_ice 605 zvel = 5.e-05_wp + SQRT( v_iceU(ji,jj) * v_iceU(ji,jj) + u_ice(ji,jj) * u_ice(ji,jj) ) 606 zTauB = ztaux_base(ji,jj) / zvel 607 ! !--- OceanBottom-to-Ice stress 608 ztaux_bi(ji,jj) = zTauB * u_ice(ji,jj) 609 ! 610 ! !--- Coriolis at U-points (energy conserving formulation) 611 zCorU(ji,jj) = 0.25_wp * r1_e1u(ji,jj) * & 612 & ( zmf(ji ,jj) * ( e1v(ji ,jj) * v_ice(ji ,jj) + e1v(ji ,jj-1) * v_ice(ji ,jj-1) ) & 613 & + zmf(ji+1,jj) * ( e1v(ji+1,jj) * v_ice(ji+1,jj) + e1v(ji+1,jj-1) * v_ice(ji+1,jj-1) ) ) 614 ! 615 ! !--- Sum of external forces (explicit solution) = F + tau_ia + Coriolis + spg + tau_io 616 zRHS = zfU(ji,jj) + ztaux_ai(ji,jj) + zCorU(ji,jj) + zspgU(ji,jj) + ztaux_oi(ji,jj) 617 ! 618 ! !--- landfast switch => 0 = static friction : TauB > RHS & sign(TauB) /= sign(RHS) 619 ! 1 = sliding friction : TauB < RHS 620 rswitch = 1._wp - MIN( 1._wp, ABS( SIGN( 1._wp, zRHS + ztaux_base(ji,jj) ) - SIGN( 1._wp, zRHS ) ) ) 621 ! 622 IF( ln_aEVP ) THEN !--- ice velocity using aEVP (Kimmritz et al 2016 & 2017) 623 zbetau = MAX( zbeta(ji,jj), zbeta(ji+1,jj) ) 624 u_ice(ji,jj) = ( ( rswitch * ( zmU_t(ji,jj) * ( zbetau * u_ice(ji,jj) + u_ice_b(ji,jj) ) & ! previous velocity 625 & + zRHS + zTauO * u_ice(ji,jj) & ! F + tau_ia + Coriolis + spg + tau_io(only ocean part) 626 & ) / MAX( zepsi, zmU_t(ji,jj) * ( zbetau + 1._wp ) + zTauO - zTauB ) & ! m/dt + tau_io(only ice part) + landfast 627 & + ( 1._wp - rswitch ) * ( u_ice_b(ji,jj) & 628 & + u_ice (ji,jj) * MAX( 0._wp, zbetau - zdtevp * rn_lf_relax ) & ! static friction => slow decrease to v=0 629 & ) / ( zbetau + 1._wp ) & 630 & ) * zmsk01x(ji,jj) + u_oce(ji,jj) * 0.01_wp * ( 1._wp - zmsk01x(ji,jj) ) & ! v_ice = v_oce/100 if mass < zmmin & conc < zamin 631 & ) * zmsk00x(ji,jj) 632 ELSE !--- ice velocity using EVP implicit formulation (cf Madec doc & Bouillon 2009) 633 u_ice(ji,jj) = ( ( rswitch * ( zmU_t(ji,jj) * u_ice(ji,jj) & ! previous velocity 634 & + zRHS + zTauO * u_ice(ji,jj) & ! F + tau_ia + Coriolis + spg + tau_io(only ocean part) 635 & ) / MAX( zepsi, zmU_t(ji,jj) + zTauO - zTauB ) & ! m/dt + tau_io(only ice part) + landfast 636 & + ( 1._wp - rswitch ) * u_ice(ji,jj) * MAX( 0._wp, 1._wp - zdtevp * rn_lf_relax ) & ! static friction => slow decrease to v=0 637 & ) * zmsk01x(ji,jj) + u_oce(ji,jj) * 0.01_wp * ( 1._wp - zmsk01x(ji,jj) ) & ! v_ice = v_oce/100 if mass < zmmin & conc < zamin 638 & ) * zmsk00x(ji,jj) 639 ENDIF 640 END_2D 641 CALL lbc_lnk( 'icedyn_rhg_evp', u_ice, 'U', -1.0_wp ) 642 ! 643 #if defined key_agrif 644 !! CALL agrif_interp_ice( 'U', jter, nn_nevp ) 645 CALL agrif_interp_ice( 'U' ) 646 #endif 647 IF( ln_bdy ) CALL bdy_ice_dyn( 'U' ) 648 ! 649 649 DO_2D( 0, 0, 0, 0 ) 650 650 ! !--- tau_io/(v_oce - v_ice) … … 679 679 & + ( 1._wp - rswitch ) * ( v_ice_b(ji,jj) & 680 680 & + v_ice (ji,jj) * MAX( 0._wp, zbetav - zdtevp * rn_lf_relax ) & ! static friction => slow decrease to v=0 681 & ) / ( zbetav + 1._wp ) & 681 & ) / ( zbetav + 1._wp ) & 682 682 & ) * zmsk01y(ji,jj) + v_oce(ji,jj) * 0.01_wp * ( 1._wp - zmsk01y(ji,jj) ) & ! v_ice = v_oce/100 if mass < zmmin & conc < zamin 683 683 & ) * zmsk00y(ji,jj) … … 710 710 ! 711 711 !------------------------------------------------------------------------------! 712 ! 4) Recompute delta, shear and div (inputs for mechanical redistribution) 712 ! 4) Recompute delta, shear and div (inputs for mechanical redistribution) 713 713 !------------------------------------------------------------------------------! 714 714 DO_2D( 1, 0, 1, 0 ) … … 720 720 721 721 END_2D 722 722 723 723 DO_2D( 0, 0, 0, 0 ) ! no vector loop 724 724 725 725 ! tension**2 at T points 726 726 zdt = ( ( u_ice(ji,jj) * r1_e2u(ji,jj) - u_ice(ji-1,jj) * r1_e2u(ji-1,jj) ) * e2t(ji,jj) * e2t(ji,jj) & … … 730 730 731 731 zten_i(ji,jj) = zdt 732 732 733 733 ! shear**2 at T points (doc eq. A16) 734 734 zds2 = ( zds(ji,jj ) * zds(ji,jj ) * e1e2f(ji,jj ) + zds(ji-1,jj ) * zds(ji-1,jj ) * e1e2f(ji-1,jj ) & 735 735 & + zds(ji,jj-1) * zds(ji,jj-1) * e1e2f(ji,jj-1) + zds(ji-1,jj-1) * zds(ji-1,jj-1) * e1e2f(ji-1,jj-1) & 736 736 & ) * 0.25_wp * r1_e1e2t(ji,jj) 737 737 738 738 ! shear at T points 739 739 pshear_i(ji,jj) = SQRT( zdt2 + zds2 ) … … 743 743 & + e1v(ji,jj) * v_ice(ji,jj) - e1v(ji,jj-1) * v_ice(ji,jj-1) & 744 744 & ) * r1_e1e2t(ji,jj) 745 745 746 746 ! delta at T points 747 zfac = SQRT( pdivu_i(ji,jj) * pdivu_i(ji,jj) + ( zdt2 + zds2 ) * z1_ecc2 ) ! delta 747 zfac = SQRT( pdivu_i(ji,jj) * pdivu_i(ji,jj) + ( zdt2 + zds2 ) * z1_ecc2 ) ! delta 748 748 rswitch = 1._wp - MAX( 0._wp, SIGN( 1._wp, -zfac ) ) ! 0 if delta=0 749 749 pdelta_i(ji,jj) = zfac + rn_creepl * rswitch ! delta+creepl … … 752 752 CALL lbc_lnk_multi( 'icedyn_rhg_evp', pshear_i, 'T', 1._wp, pdivu_i, 'T', 1._wp, pdelta_i, 'T', 1._wp, zten_i, 'T', 1._wp, & 753 753 & zs1 , 'T', 1._wp, zs2 , 'T', 1._wp, zs12 , 'F', 1._wp ) 754 754 755 755 ! --- Store the stress tensor for the next time step --- ! 756 756 pstress1_i (:,:) = zs1 (:,:) … … 776 776 CALL iom_put( 'vtau_bi' , ztauy_bi * zmsk00 ) 777 777 ENDIF 778 778 779 779 ! --- divergence, shear and strength --- ! 780 780 IF( iom_use('icediv') ) CALL iom_put( 'icediv' , pdivu_i * zmsk00 ) ! divergence … … 786 786 ! 787 787 ALLOCATE( zsig_I(jpi,jpj) , zsig_II(jpi,jpj) ) 788 ! 788 ! 789 789 DO_2D( 1, 1, 1, 1 ) 790 790 791 791 ! Ice stresses 792 792 ! sigma1, sigma2, sigma12 are some useful recombination of the stresses (Hunke and Dukowicz MWR 2002, Bouillon et al., OM2013) 793 793 ! These are NOT stress tensor components, neither stress invariants, neither stress principal components 794 794 ! I know, this can be confusing... 795 zfac = strength(ji,jj) / ( pdelta_i(ji,jj) + rn_creepl ) 795 zfac = strength(ji,jj) / ( pdelta_i(ji,jj) + rn_creepl ) 796 796 zsig1 = zfac * ( pdivu_i(ji,jj) - pdelta_i(ji,jj) ) 797 797 zsig2 = zfac * z1_ecc2 * zten_i(ji,jj) 798 798 zsig12 = zfac * z1_ecc2 * pshear_i(ji,jj) 799 799 800 800 ! Stress invariants (sigma_I, sigma_II, Coon 1974, Feltham 2008) 801 801 zsig_I (ji,jj) = zsig1 * 0.5_wp ! 1st stress invariant, aka average normal stress, aka negative pressure 802 802 zsig_II(ji,jj) = SQRT ( MAX( 0._wp, zsig2 * zsig2 * 0.25_wp + zsig12 ) ) ! 2nd '' '', aka maximum shear stress 803 804 END_2D 803 804 END_2D 805 805 ! 806 806 ! Stress tensor invariants (normal and shear stress N/m) - SIMIP diags - definitions following Coon (1974) and Feltham (2008) 807 807 IF( iom_use('normstr') ) CALL iom_put( 'normstr', zsig_I (:,:) * zmsk00(:,:) ) ! Normal stress 808 808 IF( iom_use('sheastr') ) CALL iom_put( 'sheastr', zsig_II(:,:) * zmsk00(:,:) ) ! Maximum shear stress 809 809 810 810 DEALLOCATE ( zsig_I, zsig_II ) 811 811 812 812 ENDIF 813 813 … … 818 818 IF( iom_use('sig1_pnorm') .OR. iom_use('sig2_pnorm') ) THEN 819 819 ! 820 ALLOCATE( zsig1_p(jpi,jpj) , zsig2_p(jpi,jpj) , zsig_I(jpi,jpj) , zsig_II(jpi,jpj) ) 821 ! 820 ALLOCATE( zsig1_p(jpi,jpj) , zsig2_p(jpi,jpj) , zsig_I(jpi,jpj) , zsig_II(jpi,jpj) ) 821 ! 822 822 DO_2D( 1, 1, 1, 1 ) 823 824 ! Ice stresses computed with **viscosities** (delta, p/delta) at **previous** iterates 823 824 ! Ice stresses computed with **viscosities** (delta, p/delta) at **previous** iterates 825 825 ! and **deformations** at current iterates 826 826 ! following Lemieux & Dupont (2020) … … 829 829 zsig2 = zfac * z1_ecc2 * zten_i(ji,jj) 830 830 zsig12 = zfac * z1_ecc2 * pshear_i(ji,jj) 831 831 832 832 ! Stress invariants (sigma_I, sigma_II, Coon 1974, Feltham 2008), T-point 833 833 zsig_I(ji,jj) = zsig1 * 0.5_wp ! 1st stress invariant, aka average normal stress, aka negative pressure 834 834 zsig_II(ji,jj) = SQRT ( MAX( 0._wp, zsig2 * zsig2 * 0.25_wp + zsig12 ) ) ! 2nd '' '', aka maximum shear stress 835 835 836 836 ! Normalized principal stresses (used to display the ellipse) 837 837 z1_strength = 1._wp / MAX( 1._wp, strength(ji,jj) ) 838 838 zsig1_p(ji,jj) = ( zsig_I(ji,jj) + zsig_II(ji,jj) ) * z1_strength 839 839 zsig2_p(ji,jj) = ( zsig_I(ji,jj) - zsig_II(ji,jj) ) * z1_strength 840 END_2D 841 ! 842 CALL iom_put( 'sig1_pnorm' , zsig1_p ) 843 CALL iom_put( 'sig2_pnorm' , zsig2_p ) 840 END_2D 841 ! 842 CALL iom_put( 'sig1_pnorm' , zsig1_p ) 843 CALL iom_put( 'sig2_pnorm' , zsig2_p ) 844 844 845 845 DEALLOCATE( zsig1_p , zsig2_p , zsig_I, zsig_II ) 846 846 847 847 ENDIF 848 848 … … 889 889 890 890 CALL iom_put( 'xmtrpice' , zdiag_xmtrp_ice ) ! X-component of sea-ice mass transport (kg/s) 891 CALL iom_put( 'ymtrpice' , zdiag_ymtrp_ice ) ! Y-component of sea-ice mass transport 891 CALL iom_put( 'ymtrpice' , zdiag_ymtrp_ice ) ! Y-component of sea-ice mass transport 892 892 CALL iom_put( 'xmtrpsnw' , zdiag_xmtrp_snw ) ! X-component of snow mass transport (kg/s) 893 893 CALL iom_put( 'ymtrpsnw' , zdiag_ymtrp_snw ) ! Y-component of snow mass transport … … 911 911 ENDIF 912 912 ENDIF 913 ENDIF 913 ENDIF 914 914 ! 915 915 DEALLOCATE( zmsk00, zmsk15 ) … … 921 921 !!---------------------------------------------------------------------- 922 922 !! *** ROUTINE rhg_cvg *** 923 !! 923 !! 924 924 !! ** Purpose : check convergence of oce rheology 925 925 !! … … 929 929 !! This routine is called every sub-iteration, so it is cpu expensive 930 930 !! 931 !! ** Note : for the first sub-iteration, uice_cvg is set to 0 (too large otherwise) 931 !! ** Note : for the first sub-iteration, uice_cvg is set to 0 (too large otherwise) 932 932 !!---------------------------------------------------------------------- 933 933 INTEGER , INTENT(in) :: kt, kiter, kitermax ! ocean time-step index … … 936 936 INTEGER :: it, idtime, istatus 937 937 INTEGER :: ji, jj ! dummy loop indices 938 REAL(wp) :: zresm ! local real 938 REAL(wp) :: zresm ! local real 939 939 CHARACTER(len=20) :: clname 940 940 REAL(wp), DIMENSION(jpi,jpj) :: zres ! check convergence … … 963 963 ! time 964 964 it = ( kt - 1 ) * kitermax + kiter 965 965 966 966 ! convergence 967 967 IF( kiter == 1 ) THEN ! remove the first iteration for calculations of convergence (always very large) … … 982 982 IF( kt == nitend - nn_fsbc + 1 ) istatus = NF90_CLOSE(ncvgid) 983 983 ENDIF 984 984 985 985 END SUBROUTINE rhg_cvg 986 986 … … 989 989 !!--------------------------------------------------------------------- 990 990 !! *** ROUTINE rhg_evp_rst *** 991 !! 991 !! 992 992 !! ** Purpose : Read or write RHG file in restart file 993 993 !! … … 1041 1041 END SUBROUTINE rhg_evp_rst 1042 1042 1043 1043 1044 1044 #else 1045 1045 !!---------------------------------------------------------------------- -
NEMO/trunk/src/ICE/iceistate.F90
r14053 r14072 18 18 USE oce ! dynamics and tracers variables 19 19 USE dom_oce ! ocean domain 20 USE sbc_oce , ONLY : sst_m, sss_m, ln_ice_embd 20 USE sbc_oce , ONLY : sst_m, sss_m, ln_ice_embd 21 21 USE sbc_ice , ONLY : tn_ice, snwice_mass, snwice_mass_b 22 22 USE eosbn2 ! equation of state … … 40 40 USE agrif_oce 41 41 USE agrif_ice 42 USE agrif_ice_interp 43 # endif 42 USE agrif_ice_interp 43 # endif 44 44 45 45 IMPLICIT NONE … … 91 91 !! 92 92 !! ** Method : This routine will put some ice where ocean 93 !! is at the freezing point, then fill in ice 94 !! state variables using prescribed initial 95 !! values in the namelist 93 !! is at the freezing point, then fill in ice 94 !! state variables using prescribed initial 95 !! values in the namelist 96 96 !! 97 97 !! ** Steps : 1) Set initial surface and basal temperatures … … 103 103 !! where there is no ice 104 104 !!-------------------------------------------------------------------- 105 INTEGER, INTENT(in) :: kt ! time step 105 INTEGER, INTENT(in) :: kt ! time step 106 106 INTEGER, INTENT(in) :: Kbb, Kmm, Kaa ! ocean time level indices 107 107 ! … … 129 129 ! basal temperature (considered at freezing point) [Kelvin] 130 130 CALL eos_fzp( sss_m(:,:), t_bo(:,:) ) 131 t_bo(:,:) = ( t_bo(:,:) + rt0 ) * tmask(:,:,1) 131 t_bo(:,:) = ( t_bo(:,:) + rt0 ) * tmask(:,:,1) 132 132 ! 133 133 ! surface temperature and conductivity … … 154 154 e_i (:,:,:,:) = 0._wp 155 155 e_s (:,:,:,:) = 0._wp 156 156 157 157 ! general fields 158 158 a_i (:,:,:) = 0._wp … … 229 229 IF( TRIM(si(jp_apd)%clrootname) == 'NOT USED' ) & 230 230 & si(jp_apd)%fnow(:,:,1) = ( rn_apd_ini_n * zswitch + rn_apd_ini_s * (1._wp - zswitch) ) * tmask(:,:,1) & ! rn_apd = pond fraction => rn_apnd * a_i = pond conc. 231 & * si(jp_ati)%fnow(:,:,1) 231 & * si(jp_ati)%fnow(:,:,1) 232 232 ! 233 233 ! pond depth … … 248 248 ! 249 249 ! change the switch for the following 250 WHERE( zat_i_ini(:,:) > 0._wp ) ; zswitch(:,:) = tmask(:,:,1) 250 WHERE( zat_i_ini(:,:) > 0._wp ) ; zswitch(:,:) = tmask(:,:,1) 251 251 ELSEWHERE ; zswitch(:,:) = 0._wp 252 252 END WHERE … … 256 256 ! !---------------! 257 257 ! no ice if (sst - Tfreez) >= thresold 258 WHERE( ( sst_m(:,:) - (t_bo(:,:) - rt0) ) * tmask(:,:,1) >= rn_thres_sst ) ; zswitch(:,:) = 0._wp 258 WHERE( ( sst_m(:,:) - (t_bo(:,:) - rt0) ) * tmask(:,:,1) >= rn_thres_sst ) ; zswitch(:,:) = 0._wp 259 259 ELSEWHERE ; zswitch(:,:) = tmask(:,:,1) 260 260 END WHERE … … 269 269 zt_su_ini(:,:) = rn_tsu_ini_n * zswitch(:,:) 270 270 ztm_s_ini(:,:) = rn_tms_ini_n * zswitch(:,:) 271 zapnd_ini(:,:) = rn_apd_ini_n * zswitch(:,:) * zat_i_ini(:,:) ! rn_apd = pond fraction => rn_apd * a_i = pond conc. 271 zapnd_ini(:,:) = rn_apd_ini_n * zswitch(:,:) * zat_i_ini(:,:) ! rn_apd = pond fraction => rn_apd * a_i = pond conc. 272 272 zhpnd_ini(:,:) = rn_hpd_ini_n * zswitch(:,:) 273 273 zhlid_ini(:,:) = rn_hld_ini_n * zswitch(:,:) … … 295 295 zhlid_ini(:,:) = 0._wp 296 296 ENDIF 297 297 298 298 IF ( .NOT.ln_pnd_lids ) THEN 299 299 zhlid_ini(:,:) = 0._wp 300 300 ENDIF 301 301 302 302 !----------------! 303 303 ! 3) fill fields ! … … 323 323 CALL tab_2d_1d( npti, nptidx(1:npti), h_ip_1d(1:npti) , zhpnd_ini ) 324 324 CALL tab_2d_1d( npti, nptidx(1:npti), h_il_1d(1:npti) , zhlid_ini ) 325 325 326 326 ! allocate temporary arrays 327 327 ALLOCATE( zhi_2d (npti,jpl), zhs_2d (npti,jpl), zai_2d (npti,jpl), & … … 377 377 DO jl = 1, jpl 378 378 DO_3D( 1, 1, 1, 1, 1, nlay_i ) 379 t_i (ji,jj,jk,jl) = zti_3d(ji,jj,jl) 379 t_i (ji,jj,jk,jl) = zti_3d(ji,jj,jl) 380 380 ztmelts = - rTmlt * sz_i(ji,jj,jk,jl) + rt0 ! melting temperature in K 381 381 e_i(ji,jj,jk,jl) = zswitch(ji,jj) * v_i(ji,jj,jl) * r1_nlay_i * & … … 385 385 END_3D 386 386 END DO 387 387 388 388 #if defined key_agrif 389 389 ELSE 390 390 391 391 Agrif_SpecialValue = -9999. 392 392 Agrif_UseSpecialValue = .TRUE. … … 399 399 use_sign_north = .FALSE. 400 400 Agrif_UseSpecialValue = .FALSE. 401 ! lbc ???? 401 ! lbc ???? 402 402 ! Here we know : a_i, v_i, v_s, sv_i, oa_i, a_ip, v_ip, v_il, t_su, e_s, e_i 403 403 CALL ice_var_glo2eqv … … 413 413 v_ip(:,:,:) = h_ip(:,:,:) * a_ip(:,:,:) 414 414 v_il(:,:,:) = h_il(:,:,:) * a_ip(:,:,:) 415 415 416 416 ! specific temperatures for coupled runs 417 417 tn_ice(:,:,:) = t_su(:,:,:) … … 456 456 !!------------------------------------------------------------------- 457 457 !! *** ROUTINE ice_istate_init *** 458 !! 459 !! ** Purpose : Definition of initial state of the ice 460 !! 461 !! ** Method : Read the namini namelist and check the parameter 458 !! 459 !! ** Purpose : Definition of initial state of the ice 460 !! 461 !! ** Method : Read the namini namelist and check the parameter 462 462 !! values called at the first timestep (nit000) 463 463 !! … … 500 500 WRITE(numout,*) ' max ocean temp. above Tfreeze with initial ice rn_thres_sst = ', rn_thres_sst 501 501 IF( ln_iceini .AND. nn_iceini_file == 0 ) THEN 502 WRITE(numout,*) ' initial snw thickness in the north-south rn_hts_ini = ', rn_hts_ini_n,rn_hts_ini_s 502 WRITE(numout,*) ' initial snw thickness in the north-south rn_hts_ini = ', rn_hts_ini_n,rn_hts_ini_s 503 503 WRITE(numout,*) ' initial ice thickness in the north-south rn_hti_ini = ', rn_hti_ini_n,rn_hti_ini_s 504 504 WRITE(numout,*) ' initial ice concentr in the north-south rn_ati_ini = ', rn_ati_ini_n,rn_ati_ini_s -
NEMO/trunk/src/ICE/iceitd.F90
r14005 r14072 18 18 !!---------------------------------------------------------------------- 19 19 USE dom_oce ! ocean domain 20 USE phycst ! physical constants 20 USE phycst ! physical constants 21 21 USE ice1D ! sea-ice: thermodynamic variables 22 22 USE ice ! sea-ice: variables … … 66 66 !! after thermodynamic growth of ice thickness 67 67 !! 68 !! ** Method : Linear remapping 68 !! ** Method : Linear remapping 69 69 !! 70 70 !! References : W.H. Lipscomb, JGR 2001 71 71 !!------------------------------------------------------------------ 72 INTEGER , INTENT (in) :: kt ! Ocean time step 72 INTEGER , INTENT (in) :: kt ! Ocean time step 73 73 ! 74 74 INTEGER :: ji, jj, jl, jcat ! dummy loop index … … 76 76 REAL(wp) :: zx1, zwk1, zdh0, zetamin, zdamax ! local scalars 77 77 REAL(wp) :: zx2, zwk2, zda0, zetamax ! - - 78 REAL(wp) :: zx3 78 REAL(wp) :: zx3 79 79 REAL(wp) :: zslope ! used to compute local thermodynamic "speeds" 80 80 ! … … 90 90 IF( ln_timing ) CALL timing_start('iceitd_rem') 91 91 92 IF( kt == nit000 .AND. lwp ) WRITE(numout,*) '-- ice_itd_rem: remapping ice thickness distribution' 92 IF( kt == nit000 .AND. lwp ) WRITE(numout,*) '-- ice_itd_rem: remapping ice thickness distribution' 93 93 94 94 IF( ln_icediachk ) CALL ice_cons_hsm(0, 'iceitd_rem', rdiag_v, rdiag_s, rdiag_t, rdiag_fv, rdiag_fs, rdiag_ft) … … 107 107 ENDIF 108 108 END_2D 109 109 110 110 !----------------------------------------------------------------------------------------------- 111 111 ! 2) Compute new category boundaries … … 143 143 ELSEIF( a_ib_2d(ji,jl) <= epsi10 .AND. a_ib_2d(ji,jl+1) > epsi10 ) THEN ! a(jl)=0 => Hn* = Hn + fn+1*dt 144 144 zhbnew(ji,jl) = hi_max(jl) + zdhice(ji,jl+1) 145 ELSE ! a(jl+1) & a(jl) = 0 145 ELSE ! a(jl+1) & a(jl) = 0 146 146 zhbnew(ji,jl) = hi_max(jl) 147 147 ENDIF 148 148 ! 149 149 ! --- 2 conditions for remapping --- ! 150 ! 1) hn(t+1)+espi < Hn* < hn+1(t+1)-epsi 151 ! Note: hn(t+1) must not be too close to either HR or HL otherwise a division by nearly 0 is possible 150 ! 1) hn(t+1)+espi < Hn* < hn+1(t+1)-epsi 151 ! Note: hn(t+1) must not be too close to either HR or HL otherwise a division by nearly 0 is possible 152 152 ! in itd_glinear in the case (HR-HL) = 3(Hice - HL) or = 3(HR - Hice) 153 153 # if defined key_single … … 159 159 # endif 160 160 ! 161 ! 2) Hn-1 < Hn* < Hn+1 161 ! 2) Hn-1 < Hn* < Hn+1 162 162 IF( zhbnew(ji,jl) < hi_max(jl-1) ) nptidx(ji) = 0 163 163 IF( zhbnew(ji,jl) > hi_max(jl+1) ) nptidx(ji) = 0 … … 171 171 zhbnew(ji,jpl) = MAX( hi_max(jpl-1), 3._wp * h_i_2d(ji,jpl) - 2._wp * zhbnew(ji,jpl-1) ) 172 172 ELSE 173 zhbnew(ji,jpl) = hi_max(jpl) 173 zhbnew(ji,jpl) = hi_max(jpl) 174 174 ENDIF 175 175 ! 176 176 ! --- 1 additional condition for remapping (1st category) --- ! 177 ! H0+epsi < h1(t) < H1-epsi 178 ! h1(t) must not be too close to either HR or HL otherwise a division by nearly 0 is possible 177 ! H0+epsi < h1(t) < H1-epsi 178 ! h1(t) must not be too close to either HR or HL otherwise a division by nearly 0 is possible 179 179 ! in itd_glinear in the case (HR-HL) = 3(Hice - HL) or = 3(HR - Hice) 180 180 # if defined key_single … … 202 202 ! 203 203 ENDIF 204 204 205 205 !----------------------------------------------------------------------------------------------- 206 ! 4) Compute g(h) 206 ! 4) Compute g(h) 207 207 !----------------------------------------------------------------------------------------------- 208 208 IF( npti > 0 ) THEN 209 209 ! 210 210 zhb0(:) = hi_max(0) ; zhb1(:) = hi_max(1) 211 g0(:,:) = 0._wp ; g1(:,:) = 0._wp 212 hL(:,:) = 0._wp ; hR(:,:) = 0._wp 211 g0(:,:) = 0._wp ; g1(:,:) = 0._wp 212 hL(:,:) = 0._wp ; hR(:,:) = 0._wp 213 213 ! 214 214 DO jl = 1, jpl … … 220 220 ! 221 221 IF( jl == 1 ) THEN 222 ! 222 ! 223 223 ! --- g(h) for category 1 --- ! 224 224 CALL itd_glinear( zhb0(1:npti) , zhb1(1:npti) , h_ib_1d(1:npti) , a_i_1d(1:npti) , & ! in … … 230 230 IF( a_i_1d(ji) > epsi10 ) THEN 231 231 ! 232 zdh0 = h_i_1d(ji) - h_ib_1d(ji) 232 zdh0 = h_i_1d(ji) - h_ib_1d(ji) 233 233 IF( zdh0 < 0.0 ) THEN ! remove area from category 1 234 234 zdh0 = MIN( -zdh0, hi_max(1) ) … … 238 238 IF( zetamax > 0.0 ) THEN 239 239 zx1 = zetamax 240 zx2 = 0.5 * zetamax * zetamax 240 zx2 = 0.5 * zetamax * zetamax 241 241 zda0 = g1(ji,1) * zx2 + g0(ji,1) * zx1 ! ice area removed 242 zdamax = a_i_1d(ji) * (1.0 - h_i_1d(ji) / h_ib_1d(ji) ) ! Constrain new thickness <= h_i 242 zdamax = a_i_1d(ji) * (1.0 - h_i_1d(ji) / h_ib_1d(ji) ) ! Constrain new thickness <= h_i 243 243 zda0 = MIN( zda0, zdamax ) ! ice area lost due to melting of thin ice (zdamax > 0) 244 244 ! Remove area, conserving volume … … 250 250 ELSE ! if ice accretion zdh0 > 0 251 251 ! zhbnew was 0, and is shifted to the right to account for thin ice growth in openwater (F0 = f1) 252 zhbnew(ji,0) = MIN( zdh0, hi_max(1) ) 252 zhbnew(ji,0) = MIN( zdh0, hi_max(1) ) 253 253 ENDIF 254 254 ! … … 263 263 ENDIF ! jl=1 264 264 ! 265 ! --- g(h) for each thickness category --- ! 265 ! --- g(h) for each thickness category --- ! 266 266 CALL itd_glinear( zhbnew(1:npti,jl-1), zhbnew(1:npti,jl), h_i_1d(1:npti) , a_i_1d(1:npti) , & ! in 267 267 & g0 (1:npti,jl ), g1 (1:npti,jl), hL (1:npti,jl), hR (1:npti,jl) ) ! out 268 268 ! 269 269 END DO 270 270 271 271 !----------------------------------------------------------------------------------------------- 272 272 ! 5) Compute area and volume to be shifted across each boundary (Eq. 18) … … 278 278 ! left and right integration limits in eta space 279 279 IF (zhbnew(ji,jl) > hi_max(jl)) THEN ! Hn* > Hn => transfer from jl to jl+1 280 zetamin = MAX( hi_max(jl) , hL(ji,jl) ) - hL(ji,jl) ! hi_max(jl) - hL 280 zetamin = MAX( hi_max(jl) , hL(ji,jl) ) - hL(ji,jl) ! hi_max(jl) - hL 281 281 zetamax = MIN( zhbnew(ji,jl), hR(ji,jl) ) - hL(ji,jl) ! hR - hL 282 282 jdonor(ji,jl) = jl … … 301 301 END DO 302 302 END DO 303 303 304 304 !---------------------------------------------------------------------------------------------- 305 305 ! 6) Shift ice between categories 306 306 !---------------------------------------------------------------------------------------------- 307 307 CALL itd_shiftice ( jdonor(1:npti,:), zdaice(1:npti,:), zdvice(1:npti,:) ) 308 308 309 309 !---------------------------------------------------------------------------------------------- 310 310 ! 7) Make sure h_i >= minimum ice thickness hi_min … … 316 316 DO ji = 1, npti 317 317 IF ( a_i_1d(ji) > epsi10 .AND. h_i_1d(ji) < rn_himin ) THEN 318 a_i_1d(ji) = a_i_1d(ji) * h_i_1d(ji) / rn_himin 318 a_i_1d(ji) = a_i_1d(ji) * h_i_1d(ji) / rn_himin 319 319 IF( ln_pnd_LEV .OR. ln_pnd_TOPO ) a_ip_1d(ji) = a_ip_1d(ji) * h_i_1d(ji) / rn_himin 320 320 h_i_1d(ji) = rn_himin … … 384 384 pg1(ji) = 2._wp * zdhr * zwk1 * ( zwk2 - 0.5_wp ) ! Eq. 14 385 385 ! 386 ELSE ! remap_flag = .false. or a_i < epsi10 386 ELSE ! remap_flag = .false. or a_i < epsi10 387 387 phL(ji) = 0._wp 388 388 phR(ji) = 0._wp … … 415 415 REAL(wp), DIMENSION(jpij,nlay_s,jpl) :: ze_s_2d 416 416 !!------------------------------------------------------------------ 417 417 418 418 CALL tab_3d_2d( npti, nptidx(1:npti), h_i_2d (1:npti,1:jpl), h_i ) 419 419 CALL tab_3d_2d( npti, nptidx(1:npti), a_i_2d (1:npti,1:jpl), a_i ) … … 445 445 END DO 446 446 END DO 447 447 448 448 !------------------------------------------------------------------------------- 449 449 ! 2) Transfer volume and energy between categories … … 457 457 ! 458 458 IF ( jl1 == jl ) THEN ; jl2 = jl1+1 459 ELSE ; jl2 = jl 459 ELSE ; jl2 = jl 460 460 ENDIF 461 461 ! … … 475 475 ztrans = v_s_2d(ji,jl1) * zworkv(ji) ! Snow volumes 476 476 v_s_2d(ji,jl1) = v_s_2d(ji,jl1) - ztrans 477 v_s_2d(ji,jl2) = v_s_2d(ji,jl2) + ztrans 477 v_s_2d(ji,jl2) = v_s_2d(ji,jl2) + ztrans 478 478 ! 479 479 ztrans = oa_i_2d(ji,jl1) * zworka(ji) ! Ice age … … 488 488 zaTsfn(ji,jl1) = zaTsfn(ji,jl1) - ztrans 489 489 zaTsfn(ji,jl2) = zaTsfn(ji,jl2) + ztrans 490 ! 490 ! 491 491 IF ( ln_pnd_LEV .OR. ln_pnd_TOPO ) THEN 492 492 ztrans = a_ip_2d(ji,jl1) * zworka(ji) ! Pond fraction 493 493 a_ip_2d(ji,jl1) = a_ip_2d(ji,jl1) - ztrans 494 494 a_ip_2d(ji,jl2) = a_ip_2d(ji,jl2) + ztrans 495 ! 495 ! 496 496 ztrans = v_ip_2d(ji,jl1) * zworkv(ji) ! Pond volume 497 497 v_ip_2d(ji,jl1) = v_ip_2d(ji,jl1) - ztrans … … 555 555 & a_i_2d(1:npti,jl) = a_i_2d(1:npti,jl) * rn_amax_1d(1:npti) / zworka(1:npti) 556 556 END DO 557 557 558 558 !------------------------------------------------------------------------------- 559 559 ! 4) Update ice thickness and temperature … … 564 564 WHERE( a_i_2d(1:npti,:) >= epsi20 ) 565 565 # endif 566 h_i_2d (1:npti,:) = v_i_2d(1:npti,:) / a_i_2d(1:npti,:) 567 t_su_2d(1:npti,:) = zaTsfn(1:npti,:) / a_i_2d(1:npti,:) 566 h_i_2d (1:npti,:) = v_i_2d(1:npti,:) / a_i_2d(1:npti,:) 567 t_su_2d(1:npti,:) = zaTsfn(1:npti,:) / a_i_2d(1:npti,:) 568 568 ELSEWHERE 569 569 h_i_2d (1:npti,:) = 0._wp … … 591 591 ! 592 592 END SUBROUTINE itd_shiftice 593 593 594 594 595 595 SUBROUTINE ice_itd_reb( kt ) … … 603 603 !! to the neighboring category 604 604 !!------------------------------------------------------------------ 605 INTEGER , INTENT (in) :: kt ! Ocean time step 605 INTEGER , INTENT (in) :: kt ! Ocean time step 606 606 INTEGER :: ji, jj, jl ! dummy loop indices 607 607 ! … … 611 611 IF( ln_timing ) CALL timing_start('iceitd_reb') 612 612 ! 613 IF( kt == nit000 .AND. lwp ) WRITE(numout,*) '-- ice_itd_reb: rebining ice thickness distribution' 613 IF( kt == nit000 .AND. lwp ) WRITE(numout,*) '-- ice_itd_reb: rebining ice thickness distribution' 614 614 ! 615 615 IF( ln_icediachk ) CALL ice_cons_hsm(0, 'iceitd_reb', rdiag_v, rdiag_s, rdiag_t, rdiag_fv, rdiag_fs, rdiag_ft) … … 627 627 IF( a_i(ji,jj,jl) > 0._wp .AND. v_i(ji,jj,jl) > (a_i(ji,jj,jl) * hi_max(jl)) ) THEN 628 628 npti = npti + 1 629 nptidx( npti ) = (jj - 1) * jpi + ji 629 nptidx( npti ) = (jj - 1) * jpi + ji 630 630 ENDIF 631 631 END_2D 632 632 ! 633 IF( npti > 0 ) THEN 633 IF( npti > 0 ) THEN 634 634 !!clem CALL tab_2d_1d( npti, nptidx(1:npti), h_i_1d(1:npti), h_i(:,:,jl) ) 635 635 CALL tab_2d_1d( npti, nptidx(1:npti), a_i_1d(1:npti), a_i(:,:,jl) ) … … 637 637 ! 638 638 DO ji = 1, npti 639 jdonor(ji,jl) = jl 639 jdonor(ji,jl) = jl 640 640 ! how much of a_i you send in cat sup is somewhat arbitrary 641 641 ! these are from CICE => transfer everything … … 663 663 IF( a_i(ji,jj,jl+1) > 0._wp .AND. v_i(ji,jj,jl+1) <= (a_i(ji,jj,jl+1) * hi_max(jl)) ) THEN 664 664 npti = npti + 1 665 nptidx( npti ) = (jj - 1) * jpi + ji 665 nptidx( npti ) = (jj - 1) * jpi + ji 666 666 ENDIF 667 667 END_2D … … 672 672 DO ji = 1, npti 673 673 jdonor(ji,jl) = jl + 1 674 zdaice(ji,jl) = a_i_1d(ji) 674 zdaice(ji,jl) = a_i_1d(ji) 675 675 zdvice(ji,jl) = v_i_1d(ji) 676 676 END DO … … 721 721 WRITE(numout,*) ' mean ice thickness in the domain rn_himean = ', rn_himean 722 722 WRITE(numout,*) ' Ice categories are defined by rn_catbnd ln_cat_usr = ', ln_cat_usr 723 WRITE(numout,*) ' minimum ice thickness allowed rn_himin = ', rn_himin 724 WRITE(numout,*) ' maximum ice thickness allowed rn_himax = ', rn_himax 723 WRITE(numout,*) ' minimum ice thickness allowed rn_himin = ', rn_himin 724 WRITE(numout,*) ' maximum ice thickness allowed rn_himax = ', rn_himax 725 725 ENDIF 726 726 ! … … 729 729 !-----------------------------------! 730 730 ! !== set the choice of ice categories ==! 731 ioptio = 0 731 ioptio = 0 732 732 IF( ln_cat_hfn ) THEN ; ioptio = ioptio + 1 ; nice_catbnd = np_cathfn ; ENDIF 733 733 IF( ln_cat_usr ) THEN ; ioptio = ioptio + 1 ; nice_catbnd = np_catusr ; ENDIF -
NEMO/trunk/src/ICE/icerst.F90
r14039 r14072 11 11 !!---------------------------------------------------------------------- 12 12 !! ice_rst_opn : open restart file 13 !! ice_rst_write : write restart file 14 !! ice_rst_read : read restart file 13 !! ice_rst_write : write restart file 14 !! ice_rst_read : read restart file 15 15 !!---------------------------------------------------------------------- 16 16 USE ice ! sea-ice: variables … … 54 54 CHARACTER(len=20) :: clkt ! ocean time-step define as a character 55 55 CHARACTER(len=50) :: clname ! ice output restart file name 56 CHARACTER(len=256) :: clpath ! full path to ice output restart file 56 CHARACTER(len=256) :: clpath ! full path to ice output restart file 57 57 CHARACTER(LEN=52) :: clpname ! ocean output restart file name including prefix for AGRIF 58 58 !!---------------------------------------------------------------------- … … 61 61 62 62 IF( ln_rst_list .OR. nn_stock /= -1 ) THEN 63 ! in order to get better performances with NetCDF format, we open and define the ice restart file 64 ! one ice time step before writing the data (-> at nitrst - 2*nn_fsbc + 1), except if we write ice 63 ! in order to get better performances with NetCDF format, we open and define the ice restart file 64 ! one ice time step before writing the data (-> at nitrst - 2*nn_fsbc + 1), except if we write ice 65 65 ! restart files every ice time step or if an ice restart file was writen at nitend - 2*nn_fsbc + 1 66 66 IF( kt == nitrst - 2*nn_fsbc + 1 .OR. nn_stock == nn_fsbc & … … 73 73 ! create the file 74 74 clname = TRIM(cexper)//"_"//TRIM(ADJUSTL(clkt))//"_"//TRIM(cn_icerst_out) 75 clpath = TRIM(cn_icerst_outdir) 75 clpath = TRIM(cn_icerst_outdir) 76 76 IF( clpath(LEN_TRIM(clpath):) /= '/' ) clpath = TRIM(clpath)//'/' 77 77 IF(lwp) THEN … … 132 132 IF(lwp) WRITE(numout,*) 133 133 IF(lwp) WRITE(numout,*) 'ice_rst_write : write ice restart file kt =', kt 134 IF(lwp) WRITE(numout,*) '~~~~~~~~~~~~~~' 135 ENDIF 136 134 IF(lwp) WRITE(numout,*) '~~~~~~~~~~~~~~' 135 ENDIF 136 137 137 ! Write in numriw (if iter == nitrst) 138 ! ------------------ 138 ! ------------------ 139 139 ! ! calendar control 140 CALL iom_rstput( iter, nitrst, numriw, 'nn_fsbc', REAL( nn_fsbc, wp ) ) ! time-step 140 CALL iom_rstput( iter, nitrst, numriw, 'nn_fsbc', REAL( nn_fsbc, wp ) ) ! time-step 141 141 CALL iom_rstput( iter, nitrst, numriw, 'kt_ice' , REAL( iter , wp ) ) ! date 142 142 143 143 IF(.NOT.lwxios) CALL iom_delay_rst( 'WRITE', 'ICE', numriw ) ! save only ice delayed global communication variables 144 144 … … 156 156 CALL iom_rstput( iter, nitrst, numriw, 'v_il' , v_il ) 157 157 ! Snow enthalpy 158 DO jk = 1, nlay_s 158 DO jk = 1, nlay_s 159 159 WRITE(zchar1,'(I2.2)') jk 160 160 znam = 'e_s'//'_l'//zchar1 … … 163 163 END DO 164 164 ! Ice enthalpy 165 DO jk = 1, nlay_i 165 DO jk = 1, nlay_i 166 166 WRITE(zchar1,'(I2.2)') jk 167 167 znam = 'e_i'//'_l'//zchar1 … … 224 224 ! clpname = cn_icerst_in 225 225 ! ELSE 226 ! clpname = TRIM(Agrif_CFixed())//"_"//cn_icerst_in 226 ! clpname = TRIM(Agrif_CFixed())//"_"//cn_icerst_in 227 227 ! ENDIF 228 228 CALL iom_init( cr_icerst_cxt, kdid = numrir, ld_closedef = .TRUE. ) 229 229 ENDIF 230 230 231 ! test if v_i exists 231 ! test if v_i exists 232 232 id0 = iom_varid( numrir, 'v_i' , ldstop = .FALSE. ) 233 233 … … 237 237 ! Time info 238 238 CALL iom_get( numrir, 'nn_fsbc', zfice ) 239 CALL iom_get( numrir, 'kt_ice' , ziter ) 239 CALL iom_get( numrir, 'kt_ice' , ziter ) 240 240 IF(lwp) WRITE(numout,*) ' read ice restart file at time step : ', ziter 241 241 IF(lwp) WRITE(numout,*) ' in any case we force it to nit000 - 1 : ', nit000 - 1 … … 251 251 & ' control of time parameter nrstdt' ) 252 252 253 ! --- mandatory fields --- ! 253 ! --- mandatory fields --- ! 254 254 CALL iom_get( numrir, jpdom_auto, 'v_i' , v_i ) 255 255 CALL iom_get( numrir, jpdom_auto, 'v_s' , v_s ) -
NEMO/trunk/src/ICE/icesbc.F90
r14005 r14072 59 59 !! 60 60 INTEGER :: ji, jj ! dummy loop index 61 REAL(wp), DIMENSION(jpi,jpj) :: zutau_ice, zvtau_ice 61 REAL(wp), DIMENSION(jpi,jpj) :: zutau_ice, zvtau_ice 62 62 !!------------------------------------------------------------------- 63 63 ! … … 72 72 SELECT CASE( ksbc ) 73 73 CASE( jp_usr ) ; CALL usrdef_sbc_ice_tau( kt ) ! user defined formulation 74 CASE( jp_blk ) ; CALL blk_ice_1( sf(jp_wndi)%fnow(:,:,1), sf(jp_wndj)%fnow(:,:,1), & 75 & sf(jp_tair)%fnow(:,:,1), sf(jp_humi)%fnow(:,:,1), & 74 CASE( jp_blk ) 75 CALL blk_ice_1( sf(jp_wndi)%fnow(:,:,1), sf(jp_wndj)%fnow(:,:,1), & 76 & theta_air_zt(:,:), q_air_zt(:,:), & ! #LB: known from "sbc_oce" module... 76 77 & sf(jp_slp )%fnow(:,:,1), u_ice, v_ice, tm_su , & ! inputs 77 & putaui = utau_ice, pvtaui = vtau_ice ) ! outputs 78 & putaui = utau_ice, pvtaui = vtau_ice ) ! outputs 78 79 ! CASE( jp_abl ) utau_ice & vtau_ice are computed in ablmod 79 80 CASE( jp_purecpl ) ; CALL sbc_cpl_ice_tau( utau_ice , vtau_ice ) ! Coupled formulation … … 93 94 END SUBROUTINE ice_sbc_tau 94 95 95 96 96 97 SUBROUTINE ice_sbc_flx( kt, ksbc ) 97 98 !!------------------------------------------------------------------- … … 108 109 !! dqns_ice = non solar heat sensistivity [W/m2] 109 110 !! qemp_oce, qemp_ice, qprec_ice, qevap_ice = sensible heat (associated with evap & precip) [W/m2] 110 !! + some fields that are not used outside this module: 111 !! + some fields that are not used outside this module: 111 112 !! qla_ice = latent heat flux over ice [W/m2] 112 113 !! dqla_ice = latent heat sensistivity [W/m2] … … 118 119 ! 119 120 INTEGER :: ji, jj, jl ! dummy loop index 120 REAL(wp) :: zmiss_val ! missing value retrieved from xios 121 REAL(wp) :: zmiss_val ! missing value retrieved from xios 121 122 REAL(wp), DIMENSION(:,:), ALLOCATABLE :: zalb, zmsk00 ! 2D workspace 122 123 !!-------------------------------------------------------------------- … … 142 143 CALL usrdef_sbc_ice_flx( kt, h_s, h_i ) 143 144 CASE( jp_blk, jp_abl ) !--- bulk formulation & ABL formulation 144 CALL blk_ice_2 ( t_su, h_s, h_i, alb_ice, sf(jp_tair)%fnow(:,:,1), sf(jp_humi)%fnow(:,:,1), & 145 & sf(jp_slp)%fnow(:,:,1), sf(jp_qlw)%fnow(:,:,1), sf(jp_prec)%fnow(:,:,1), sf(jp_snow)%fnow(:,:,1) ) ! 145 CALL blk_ice_2 ( t_su, h_s, h_i, alb_ice, & 146 & theta_air_zt(:,:), q_air_zt(:,:), & ! #LB: known from "sbc_oce" module... 147 & sf(jp_slp)%fnow(:,:,1), sf(jp_qlw)%fnow(:,:,1), & 148 & sf(jp_prec)%fnow(:,:,1), sf(jp_snow)%fnow(:,:,1) ) 146 149 IF( ln_mixcpl ) CALL sbc_cpl_ice_flx( picefr=at_i_b, palbi=alb_ice, psst=sst_m, pist=t_su, phs=h_s, phi=h_i ) 147 150 IF( nn_flxdist /= -1 ) CALL ice_flx_dist ( t_su, alb_ice, qns_ice, qsr_ice, dqns_ice, evap_ice, devap_ice, nn_flxdist ) … … 163 166 zalb (:,:) = rn_alb_oce 164 167 ELSEWHERE 165 zmsk00(:,:) = 1._wp 168 zmsk00(:,:) = 1._wp 166 169 zalb (:,:) = SUM( alb_ice * a_i_b, dim=3 ) / at_i_b 167 170 END WHERE … … 185 188 !! *** ROUTINE ice_flx_dist *** 186 189 !! 187 !! ** Purpose : update the ice surface boundary condition by averaging 190 !! ** Purpose : update the ice surface boundary condition by averaging 188 191 !! and/or redistributing fluxes on ice categories 189 192 !! … … 192 195 !! ** Action : depends on k_flxdist 193 196 !! = -1 Do nothing (needs N(cat) fluxes) 194 !! = 0 Average N(cat) fluxes then apply the average over the N(cat) ice 197 !! = 0 Average N(cat) fluxes then apply the average over the N(cat) ice 195 198 !! = 1 Average N(cat) fluxes then redistribute over the N(cat) ice 196 199 !! using T-ice and albedo sensitivity … … 222 225 ELSEWHERE ; z1_at_i(:,:) = 0._wp 223 226 END WHERE 224 227 225 228 SELECT CASE( k_flxdist ) !== averaged on all ice categories ==! 226 229 ! 227 230 CASE( 0 , 1 ) 228 231 ! 229 ALLOCATE( z_qns_m(jpi,jpj), z_qsr_m(jpi,jpj), z_dqn_m(jpi,jpj), z_evap_m(jpi,jpj), z_devap_m(jpi,jpj) ) 232 ALLOCATE( z_qns_m(jpi,jpj), z_qsr_m(jpi,jpj), z_dqn_m(jpi,jpj), z_evap_m(jpi,jpj), z_devap_m(jpi,jpj) ) 230 233 ! 231 234 z_qns_m (:,:) = SUM( a_i(:,:,:) * pqns_ice (:,:,:) , dim=3 ) * z1_at_i(:,:) … … 242 245 END DO 243 246 ! 244 DEALLOCATE( z_qns_m, z_qsr_m, z_dqn_m, z_evap_m, z_devap_m ) 247 DEALLOCATE( z_qns_m, z_qsr_m, z_dqn_m, z_evap_m, z_devap_m ) 245 248 ! 246 249 END SELECT … … 250 253 CASE( 1 , 2 ) 251 254 ! 252 ALLOCATE( zalb_m(jpi,jpj), ztem_m(jpi,jpj) ) 255 ALLOCATE( zalb_m(jpi,jpj), ztem_m(jpi,jpj) ) 253 256 ! 254 257 zalb_m(:,:) = SUM( a_i(:,:,:) * palb_ice(:,:,:) , dim=3 ) * z1_at_i(:,:) … … 260 263 END DO 261 264 ! 262 DEALLOCATE( zalb_m, ztem_m ) 265 DEALLOCATE( zalb_m, ztem_m ) 263 266 ! 264 267 END SELECT … … 272 275 !! 273 276 !! ** Purpose : Physical constants and parameters linked to the ice dynamics 274 !! 277 !! 275 278 !! ** Method : Read the namsbc namelist and check the ice-dynamic 276 279 !! parameter values called at the first timestep (nit000) -
NEMO/trunk/src/ICE/icestp.F90
r14005 r14072 8 8 !! aka Sea Ice cube for its nickname 9 9 !! 10 !! is originally based on LIM3, developed in Louvain-la-Neuve by: 10 !! is originally based on LIM3, developed in Louvain-la-Neuve by: 11 11 !! * Martin Vancoppenolle (UCL-ASTR, Belgium) 12 12 !! * Sylvain Bouillon (UCL-ASTR, Belgium) … … 140 140 IF( .NOT. Agrif_Root() ) nbstep_ice = MOD( nbstep_ice, Agrif_irhot() * Agrif_Parent(nn_fsbc) / nn_fsbc ) + 1 141 141 ! ! these calls must remain here for restartability purposes 142 CALL agrif_interp_ice( 'T' ) 142 CALL agrif_interp_ice( 'T' ) 143 143 CALL agrif_interp_ice( 'U' ) 144 144 CALL agrif_interp_ice( 'V' ) … … 152 152 ! utau_ice, vtau_ice = surface ice stress [N/m2] 153 153 !------------------------------------------------! 154 CALL ice_sbc_tau( kt, ksbc, utau_ice, vtau_ice ) 154 CALL ice_sbc_tau( kt, ksbc, utau_ice, vtau_ice ) 155 155 !-------------------------------------! 156 156 ! --- ice dynamics and advection --- ! 157 157 !-------------------------------------! 158 158 CALL diag_set0 ! set diag of mass, heat and salt fluxes to 0 159 CALL ice_rst_opn( kt ) ! Open Ice restart file (if necessary) 159 CALL ice_rst_opn( kt ) ! Open Ice restart file (if necessary) 160 160 ! 161 161 IF( ln_icedyn .AND. .NOT.lk_c1d ) & … … 169 169 ! !== previous lead fraction and ice volume for flux calculations 170 170 CALL ice_var_glo2eqv ! h_i and h_s for ice albedo calculation 171 CALL ice_var_agg(1) ! at_i for coupling 171 CALL ice_var_agg(1) ! at_i for coupling 172 172 CALL store_fields ! Store now ice values 173 173 ! … … 189 189 ! --- ice thermodynamics --- ! 190 190 !----------------------------! 191 IF( ln_icethd ) CALL ice_thd( kt ) ! -- Ice thermodynamics 191 IF( ln_icethd ) CALL ice_thd( kt ) ! -- Ice thermodynamics 192 192 ! 193 193 CALL diag_trends( 2 ) ! record thermo trends … … 197 197 CALL ice_update_flx( kt ) ! -- Update ocean surface mass, heat and salt fluxes 198 198 ! 199 IF( ln_icediahsb ) CALL ice_dia( kt ) ! -- Diagnostics outputs 200 ! 201 IF( ln_icediachk ) CALL ice_drift_wri( kt ) ! -- Diagnostics outputs for conservation 202 ! 203 CALL ice_wri( kt ) ! -- Ice outputs 204 ! 205 IF( lrst_ice ) CALL ice_rst_write( kt ) ! -- Ice restart file 199 IF( ln_icediahsb ) CALL ice_dia( kt ) ! -- Diagnostics outputs 200 ! 201 IF( ln_icediachk ) CALL ice_drift_wri( kt ) ! -- Diagnostics outputs for conservation 202 ! 203 CALL ice_wri( kt ) ! -- Ice outputs 204 ! 205 IF( lrst_ice ) CALL ice_rst_write( kt ) ! -- Ice restart file 206 206 ! 207 207 IF( ln_icectl ) CALL ice_ctl( kt ) ! -- Control checks … … 231 231 !!---------------------------------------------------------------------- 232 232 IF(lwp) WRITE(numout,*) 233 IF(lwp) WRITE(numout,*) 'Sea Ice Model: SI3 (Sea Ice modelling Integrated Initiative)' 233 IF(lwp) WRITE(numout,*) 'Sea Ice Model: SI3 (Sea Ice modelling Integrated Initiative)' 234 234 IF(lwp) WRITE(numout,*) '~~~~~~~~~~~~~' 235 235 IF(lwp) WRITE(numout,*) 236 IF(lwp) WRITE(numout,*) 'ice_init: Arrays allocation & Initialization of all routines & init state' 236 IF(lwp) WRITE(numout,*) 'ice_init: Arrays allocation & Initialization of all routines & init state' 237 237 IF(lwp) WRITE(numout,*) '~~~~~~~~' 238 238 ! … … 250 250 ! ! Allocate the ice arrays (sbc_ice already allocated in sbc_init) 251 251 ierr = ice_alloc () ! ice variables 252 ierr = ierr + sbc_ice_alloc () ! surface boundary conditions 252 ierr = ierr + sbc_ice_alloc () ! surface boundary conditions 253 253 ierr = ierr + ice1D_alloc () ! thermodynamics 254 254 ! … … 333 333 WRITE(numout,*) ' Ice dynamics (T) or not (F) ln_icedyn = ', ln_icedyn 334 334 WRITE(numout,*) ' Ice thermodynamics (T) or not (F) ln_icethd = ', ln_icethd 335 WRITE(numout,*) ' maximum ice concentration for NH = ', rn_amax_n 335 WRITE(numout,*) ' maximum ice concentration for NH = ', rn_amax_n 336 336 WRITE(numout,*) ' maximum ice concentration for SH = ', rn_amax_s 337 337 ENDIF … … 417 417 wfx_bom(ji,jj) = 0._wp ; wfx_sum(ji,jj) = 0._wp 418 418 wfx_res(ji,jj) = 0._wp ; wfx_sub(ji,jj) = 0._wp 419 wfx_spr(ji,jj) = 0._wp ; wfx_lam(ji,jj) = 0._wp 419 wfx_spr(ji,jj) = 0._wp ; wfx_lam(ji,jj) = 0._wp 420 420 wfx_snw_dyn(ji,jj) = 0._wp ; wfx_snw_sum(ji,jj) = 0._wp 421 421 wfx_snw_sub(ji,jj) = 0._wp ; wfx_ice_sub(ji,jj) = 0._wp 422 wfx_snw_sni(ji,jj) = 0._wp 422 wfx_snw_sni(ji,jj) = 0._wp 423 423 wfx_pnd(ji,jj) = 0._wp 424 424 -
NEMO/trunk/src/ICE/icetab.F90
r13715 r14072 17 17 USE par_oce 18 18 USE ice, ONLY : jpl 19 19 20 20 IMPLICIT NONE 21 21 PRIVATE -
NEMO/trunk/src/ICE/icethd.F90
r14005 r14072 69 69 SUBROUTINE ice_thd( kt ) 70 70 !!------------------------------------------------------------------- 71 !! *** ROUTINE ice_thd *** 72 !! 71 !! *** ROUTINE ice_thd *** 72 !! 73 73 !! ** Purpose : This routine manages ice thermodynamics 74 !! 74 !! 75 75 !! ** Action : - computation of oceanic sensible heat flux at the ice base 76 76 !! energy budget in the leads … … 114 114 ztice_cvgerr = 0._wp ; ztice_cvgstp = 0._wp 115 115 ENDIF 116 116 117 117 !---------------------------------------------! 118 118 ! computation of friction velocity at T points … … 157 157 ! --- Sensible ocean-to-ice heat flux (W/m2) --- ! 158 158 ! (mostly>0 but <0 if supercooling) 159 zfric_u = MAX( SQRT( zfric(ji,jj) ), zfric_umin ) 159 zfric_u = MAX( SQRT( zfric(ji,jj) ), zfric_umin ) 160 160 qsb_ice_bot(ji,jj) = rswitch * rho0 * rcp * zch * zfric_u * ( ( sst_m(ji,jj) + rt0 ) - t_bo(ji,jj) ) 161 162 ! upper bound for qsb_ice_bot: the heat retrieved from the ocean must be smaller than the heat necessary to reach 161 162 ! upper bound for qsb_ice_bot: the heat retrieved from the ocean must be smaller than the heat necessary to reach 163 163 ! the freezing point, so that we do not have SST < T_freeze 164 164 ! This implies: qsb_ice_bot(ji,jj) * at_i(ji,jj) * rtdice <= - zqfr_neg … … 210 210 ! 211 211 END_2D 212 212 213 213 ! In case we bypass open-water ice formation 214 214 IF( .NOT. ln_icedO ) qlead(:,:) = 0._wp … … 227 227 npti = 0 ; nptidx(:) = 0 228 228 DO_2D( 1, 1, 1, 1 ) 229 IF ( a_i(ji,jj,jl) > epsi10 ) THEN 229 IF ( a_i(ji,jj,jl) > epsi10 ) THEN 230 230 npti = npti + 1 231 231 nptidx(npti) = (jj - 1) * jpi + ji … … 234 234 235 235 IF( npti > 0 ) THEN ! If there is no ice, do nothing. 236 ! 236 ! 237 237 CALL ice_thd_1d2d( jl, 1 ) ! --- Move to 1D arrays --- ! 238 238 ! ! --- & Change units of e_i, e_s from J/m2 to J/m3 --- ! 239 239 ! 240 s_i_new (1:npti) = 0._wp ; dh_s_tot(1:npti) = 0._wp ! --- some init --- ! (important to have them here) 241 dh_i_sum (1:npti) = 0._wp ; dh_i_bom(1:npti) = 0._wp ; dh_i_itm (1:npti) = 0._wp 240 s_i_new (1:npti) = 0._wp ; dh_s_tot(1:npti) = 0._wp ! --- some init --- ! (important to have them here) 241 dh_i_sum (1:npti) = 0._wp ; dh_i_bom(1:npti) = 0._wp ; dh_i_itm (1:npti) = 0._wp 242 242 dh_i_sub (1:npti) = 0._wp ; dh_i_bog(1:npti) = 0._wp 243 243 dh_snowice(1:npti) = 0._wp ; dh_s_mlt(1:npti) = 0._wp 244 ! 244 ! 245 245 CALL ice_thd_zdf ! --- Ice-Snow temperature --- ! 246 246 ! 247 247 IF( ln_icedH ) THEN ! --- Growing/Melting --- ! 248 CALL ice_thd_dh ! Ice-Snow thickness 248 CALL ice_thd_dh ! Ice-Snow thickness 249 249 CALL ice_thd_ent( e_i_1d(1:npti,:) ) ! Ice enthalpy remapping 250 250 ENDIF 251 CALL ice_thd_sal( ln_icedS ) ! --- Ice salinity --- ! 251 CALL ice_thd_sal( ln_icedS ) ! --- Ice salinity --- ! 252 252 ! 253 253 CALL ice_thd_temp ! --- Temperature update --- ! … … 266 266 IF( ln_icediachk ) CALL ice_cons_hsm(1, 'icethd', rdiag_v, rdiag_s, rdiag_t, rdiag_fv, rdiag_fs, rdiag_ft) 267 267 IF( ln_icediachk ) CALL ice_cons2D (1, 'icethd', diag_v, diag_s, diag_t, diag_fv, diag_fs, diag_ft) 268 ! 268 ! 269 269 IF ( ln_pnd .AND. ln_icedH ) & 270 & CALL ice_thd_pnd ! --- Melt ponds 270 & CALL ice_thd_pnd ! --- Melt ponds 271 271 ! 272 272 IF( jpl > 1 ) CALL ice_itd_rem( kt ) ! --- Transport ice between thickness categories --- ! … … 276 276 CALL ice_cor( kt , 2 ) ! --- Corrections --- ! 277 277 ! 278 oa_i(:,:,:) = oa_i(:,:,:) + a_i(:,:,:) * rDt_ice ! ice natural aging incrementation 278 oa_i(:,:,:) = oa_i(:,:,:) + a_i(:,:,:) * rDt_ice ! ice natural aging incrementation 279 279 ! 280 280 ! convergence tests … … 290 290 IF( ln_timing ) CALL timing_stop('icethd') ! timing 291 291 ! 292 END SUBROUTINE ice_thd 293 294 292 END SUBROUTINE ice_thd 293 294 295 295 SUBROUTINE ice_thd_temp 296 296 !!----------------------------------------------------------------------- 297 !! *** ROUTINE ice_thd_temp *** 298 !! 297 !! *** ROUTINE ice_thd_temp *** 298 !! 299 299 !! ** Purpose : Computes sea ice temperature (Kelvin) from enthalpy 300 300 !! … … 302 302 !!------------------------------------------------------------------- 303 303 INTEGER :: ji, jk ! dummy loop indices 304 REAL(wp) :: ztmelts, zbbb, zccc ! local scalar 304 REAL(wp) :: ztmelts, zbbb, zccc ! local scalar 305 305 !!------------------------------------------------------------------- 306 306 ! Recover ice temperature … … 312 312 zccc = SQRT( MAX( zbbb * zbbb - 4._wp * rcpi * rLfus * ztmelts, 0._wp ) ) 313 313 t_i_1d(ji,jk) = rt0 - ( zbbb + zccc ) * 0.5_wp * r1_rcpi 314 314 315 315 ! mask temperature 316 rswitch = 1._wp - MAX( 0._wp , SIGN( 1._wp , - h_i_1d(ji) ) ) 316 rswitch = 1._wp - MAX( 0._wp , SIGN( 1._wp , - h_i_1d(ji) ) ) 317 317 t_i_1d(ji,jk) = rswitch * t_i_1d(ji,jk) + ( 1._wp - rswitch ) * rt0 318 END DO 319 END DO 318 END DO 319 END DO 320 320 ! 321 321 END SUBROUTINE ice_thd_temp … … 324 324 SUBROUTINE ice_thd_mono 325 325 !!----------------------------------------------------------------------- 326 !! *** ROUTINE ice_thd_mono *** 327 !! 326 !! *** ROUTINE ice_thd_mono *** 327 !! 328 328 !! ** Purpose : Lateral melting in case virtual_itd 329 329 !! ( dA = A/2h dh ) … … 332 332 REAL(wp) :: zhi_bef ! ice thickness before thermo 333 333 REAL(wp) :: zdh_mel, zda_mel ! net melting 334 REAL(wp) :: zvi, zvs ! ice/snow volumes 334 REAL(wp) :: zvi, zvs ! ice/snow volumes 335 335 !!----------------------------------------------------------------------- 336 336 ! … … 344 344 rswitch = MAX( 0._wp , SIGN( 1._wp , zhi_bef - epsi20 ) ) 345 345 zda_mel = rswitch * a_i_1d(ji) * zdh_mel / ( 2._wp * MAX( zhi_bef, epsi20 ) ) 346 a_i_1d(ji) = MAX( epsi20, a_i_1d(ji) + zda_mel ) 346 a_i_1d(ji) = MAX( epsi20, a_i_1d(ji) + zda_mel ) 347 347 ! adjust thickness 348 h_i_1d(ji) = zvi / a_i_1d(ji) 349 h_s_1d(ji) = zvs / a_i_1d(ji) 348 h_i_1d(ji) = zvi / a_i_1d(ji) 349 h_s_1d(ji) = zvs / a_i_1d(ji) 350 350 ! retrieve total concentration 351 351 at_i_1d(ji) = a_i_1d(ji) … … 358 358 SUBROUTINE ice_thd_1d2d( kl, kn ) 359 359 !!----------------------------------------------------------------------- 360 !! *** ROUTINE ice_thd_1d2d *** 361 !! 360 !! *** ROUTINE ice_thd_1d2d *** 361 !! 362 362 !! ** Purpose : move arrays from 1d to 2d and the reverse 363 363 !!----------------------------------------------------------------------- 364 INTEGER, INTENT(in) :: kl ! index of the ice category 364 INTEGER, INTENT(in) :: kl ! index of the ice category 365 365 INTEGER, INTENT(in) :: kn ! 1= from 2D to 1D ; 2= from 1D to 2D 366 366 ! … … 394 394 CALL tab_2d_1d( npti, nptidx(1:npti), dqns_ice_1d (1:npti), dqns_ice(:,:,kl) ) 395 395 CALL tab_2d_1d( npti, nptidx(1:npti), t_bo_1d (1:npti), t_bo ) 396 CALL tab_2d_1d( npti, nptidx(1:npti), sprecip_1d (1:npti), sprecip ) 396 CALL tab_2d_1d( npti, nptidx(1:npti), sprecip_1d (1:npti), sprecip ) 397 397 CALL tab_2d_1d( npti, nptidx(1:npti), qsb_ice_bot_1d(1:npti), qsb_ice_bot ) 398 398 CALL tab_2d_1d( npti, nptidx(1:npti), fhld_1d (1:npti), fhld ) 399 399 400 400 CALL tab_2d_1d( npti, nptidx(1:npti), qml_ice_1d (1:npti), qml_ice (:,:,kl) ) 401 401 CALL tab_2d_1d( npti, nptidx(1:npti), qcn_ice_1d (1:npti), qcn_ice (:,:,kl) ) … … 471 471 sv_i_1d(1:npti) = s_i_1d (1:npti) * v_i_1d (1:npti) 472 472 oa_i_1d(1:npti) = o_i_1d (1:npti) * a_i_1d (1:npti) 473 473 474 474 CALL tab_1d_2d( npti, nptidx(1:npti), at_i_1d(1:npti), at_i ) 475 475 CALL tab_1d_2d( npti, nptidx(1:npti), a_i_1d (1:npti), a_i (:,:,kl) ) … … 532 532 CALL tab_1d_2d( npti, nptidx(1:npti), dh_i_sum (1:npti) , dh_i_sum_2d(:,:,kl) ) 533 533 CALL tab_1d_2d( npti, nptidx(1:npti), dh_s_mlt (1:npti) , dh_s_mlt_2d(:,:,kl) ) 534 ! SIMIP diagnostics 534 ! SIMIP diagnostics 535 535 CALL tab_1d_2d( npti, nptidx(1:npti), t_si_1d (1:npti), t_si (:,:,kl) ) 536 536 CALL tab_1d_2d( npti, nptidx(1:npti), qcn_ice_bot_1d(1:npti), qcn_ice_bot(:,:,kl) ) … … 554 554 SUBROUTINE ice_thd_init 555 555 !!------------------------------------------------------------------- 556 !! *** ROUTINE ice_thd_init *** 557 !! 556 !! *** ROUTINE ice_thd_init *** 557 !! 558 558 !! ** Purpose : Physical constants and parameters associated with 559 559 !! ice thermodynamics -
NEMO/trunk/src/ICE/icethd_dh.F90
r14005 r14072 2 2 !!====================================================================== 3 3 !! *** MODULE icethd_dh *** 4 !! seaice : thermodynamic growth and melt 4 !! seaice : thermodynamic growth and melt 5 5 !!====================================================================== 6 6 !! History : ! 2003-05 (M. Vancoppenolle) Original code in 1D 7 !! ! 2005-06 (M. Vancoppenolle) 3D version 7 !! ! 2005-06 (M. Vancoppenolle) 3D version 8 8 !! 4.0 ! 2018 (many people) SI3 [aka Sea Ice cube] 9 9 !!---------------------------------------------------------------------- … … 24 24 USE lib_mpp ! MPP library 25 25 USE lib_fortran ! fortran utilities (glob_sum + no signed zero) 26 26 27 27 IMPLICIT NONE 28 28 PRIVATE … … 59 59 !! 60 60 !! References : Bitz and Lipscomb, 1999, J. Geophys. Res. 61 !! Fichefet T. and M. Maqueda 1997, J. Geophys. Res., 102(C6), 12609-12646 62 !! Vancoppenolle, Fichefet and Bitz, 2005, Geophys. Res. Let. 61 !! Fichefet T. and M. Maqueda 1997, J. Geophys. Res., 102(C6), 12609-12646 62 !! Vancoppenolle, Fichefet and Bitz, 2005, Geophys. Res. Let. 63 63 !! Vancoppenolle et al.,2009, Ocean Modelling 64 64 !!------------------------------------------------------------------ … … 67 67 68 68 REAL(wp) :: ztmelts ! local scalar 69 REAL(wp) :: zdum 69 REAL(wp) :: zdum 70 70 REAL(wp) :: zfracs ! fractionation coefficient for bottom salt entrapment 71 71 REAL(wp) :: zswi1 ! switch for computation of bottom salinity … … 87 87 REAL(wp), DIMENSION(jpij) :: zf_tt ! Heat budget to determine melting or freezing(W.m-2) 88 88 REAL(wp), DIMENSION(jpij) :: zevap_rema ! remaining mass flux from sublimation (kg.m-2) 89 REAL(wp), DIMENSION(jpij) :: zdeltah 89 REAL(wp), DIMENSION(jpij) :: zdeltah 90 90 REAL(wp), DIMENSION(jpij) :: zsnw ! distribution of snow after wind blowing 91 91 92 INTEGER , DIMENSION(jpij,nlay_i) :: icount ! number of layers vanishing by melting 92 INTEGER , DIMENSION(jpij,nlay_i) :: icount ! number of layers vanishing by melting 93 93 REAL(wp), DIMENSION(jpij,0:nlay_i+1) :: zh_i ! ice layer thickness (m) 94 94 REAL(wp), DIMENSION(jpij,0:nlay_s ) :: zh_s ! snw layer thickness (m) … … 97 97 REAL(wp) :: zswitch_sal 98 98 99 INTEGER :: num_iter_max ! Heat conservation 99 INTEGER :: num_iter_max ! Heat conservation 100 100 !!------------------------------------------------------------------ 101 101 … … 149 149 ! 150 150 DO ji = 1, npti 151 zf_tt(ji) = qcn_ice_bot_1d(ji) + qsb_ice_bot_1d(ji) + fhld_1d(ji) + qtr_ice_bot_1d(ji) * frq_m_1d(ji) 151 zf_tt(ji) = qcn_ice_bot_1d(ji) + qsb_ice_bot_1d(ji) + fhld_1d(ji) + qtr_ice_bot_1d(ji) * frq_m_1d(ji) 152 152 zq_bot(ji) = MAX( 0._wp, zf_tt(ji) * rDt_ice ) 153 153 END DO … … 172 172 END IF 173 173 END DO 174 END DO 174 END DO 175 175 176 176 ! Snow precipitation … … 202 202 zdum = - rswitch * zq_top(ji) / MAX( ze_s(ji,jk), epsi20 ) ! thickness change 203 203 zdum = MAX( zdum , - zh_s(ji,jk) ) ! bound melting 204 204 205 205 hfx_snw_1d (ji) = hfx_snw_1d (ji) - ze_s(ji,jk) * zdum * a_i_1d(ji) * r1_Dt_ice ! heat used to melt snow(W.m-2, >0) 206 206 wfx_snw_sum_1d(ji) = wfx_snw_sum_1d(ji) - rhos * zdum * a_i_1d(ji) * r1_Dt_ice ! snow melting only = water into the ocean 207 207 208 208 ! updates available heat + thickness 209 209 dh_s_mlt(ji) = dh_s_mlt(ji) + zdum … … 217 217 END DO 218 218 219 ! Snow sublimation 219 ! Snow sublimation 220 220 !----------------- 221 221 ! qla_ice is always >=0 (upwards), heat goes to the atmosphere, therefore snow sublimates … … 225 225 DO ji = 1, npti 226 226 IF( evap_ice_1d(ji) > 0._wp ) THEN 227 zdeltah (ji) = MAX( - evap_ice_1d(ji) * r1_rhos * rDt_ice, - h_s_1d(ji) ) ! amount of snw that sublimates, < 0 227 zdeltah (ji) = MAX( - evap_ice_1d(ji) * r1_rhos * rDt_ice, - h_s_1d(ji) ) ! amount of snw that sublimates, < 0 228 228 zevap_rema(ji) = MAX( 0._wp, evap_ice_1d(ji) * rDt_ice + zdeltah(ji) * rhos ) ! remaining evap in kg.m-2 (used for ice sublimation later on) 229 229 ENDIF 230 230 END DO 231 231 232 232 DO jk = 0, nlay_s 233 233 DO ji = 1, npti … … 247 247 END DO 248 248 249 ! 249 ! 250 250 ! ! ============ ! 251 251 ! ! Ice ! 252 252 ! ! ============ ! 253 253 254 ! Surface ice melting 254 ! Surface ice melting 255 255 !-------------------- 256 256 DO jk = 1, nlay_i 257 257 DO ji = 1, npti 258 258 ztmelts = - rTmlt * sz_i_1d(ji,jk) ! Melting point of layer k [C] 259 259 260 260 IF( t_i_1d(ji,jk) >= (ztmelts+rt0) ) THEN !-- Internal melting 261 261 262 zEi = - e_i_1d(ji,jk) * r1_rhoi ! Specific enthalpy of layer k [J/kg, <0] 262 zEi = - e_i_1d(ji,jk) * r1_rhoi ! Specific enthalpy of layer k [J/kg, <0] 263 263 zdE = 0._wp ! Specific enthalpy difference (J/kg, <0) 264 264 ! set up at 0 since no energy is needed to melt water...(it is already melted) 265 zdum = MIN( 0._wp , - zh_i(ji,jk) ) ! internal melting occurs when the internal temperature is above freezing 265 zdum = MIN( 0._wp , - zh_i(ji,jk) ) ! internal melting occurs when the internal temperature is above freezing 266 266 ! this should normally not happen, but sometimes, heat diffusion leads to this 267 267 zfmdt = - zdum * rhoi ! Recompute mass flux [kg/m2, >0] … … 275 275 ! using s_i_1d and not sz_i_1d(jk) is ok 276 276 ELSE !-- Surface melting 277 277 278 278 zEi = - e_i_1d(ji,jk) * r1_rhoi ! Specific enthalpy of layer k [J/kg, <0] 279 279 zEw = rcp * ztmelts ! Specific enthalpy of resulting meltwater [J/kg, <0] 280 280 zdE = zEi - zEw ! Specific enthalpy difference < 0 281 281 282 282 zfmdt = - zq_top(ji) / zdE ! Mass flux to the ocean [kg/m2, >0] 283 283 284 284 zdum = - zfmdt * r1_rhoi ! Melt of layer jk [m, <0] 285 285 286 286 zdum = MIN( 0._wp , MAX( zdum , - zh_i(ji,jk) ) ) ! Melt of layer jk cannot exceed the layer thickness [m, <0] 287 287 288 288 zq_top(ji) = MAX( 0._wp , zq_top(ji) - zdum * rhoi * zdE ) ! update available heat 289 289 290 290 dh_i_sum(ji) = dh_i_sum(ji) + zdum ! Cumulate surface melt 291 291 292 292 zfmdt = - rhoi * zdum ! Recompute mass flux [kg/m2, >0] 293 293 294 294 zQm = zfmdt * zEw ! Energy of the melt water sent to the ocean [J/m2, <0] 295 295 296 296 hfx_thd_1d(ji) = hfx_thd_1d(ji) + zEw * zfmdt * a_i_1d(ji) * r1_Dt_ice ! Heat flux [W.m-2], < 0 297 hfx_sum_1d(ji) = hfx_sum_1d(ji) - zdE * zfmdt * a_i_1d(ji) * r1_Dt_ice ! Heat flux used in this process [W.m-2], > 0 297 hfx_sum_1d(ji) = hfx_sum_1d(ji) - zdE * zfmdt * a_i_1d(ji) * r1_Dt_ice ! Heat flux used in this process [W.m-2], > 0 298 298 wfx_sum_1d(ji) = wfx_sum_1d(ji) - rhoi * zdum * a_i_1d(ji) * r1_Dt_ice ! Mass flux 299 299 sfx_sum_1d(ji) = sfx_sum_1d(ji) - rhoi * zdum * s_i_1d(ji) * a_i_1d(ji) * r1_Dt_ice ! Salt flux >0 300 ! using s_i_1d and not sz_i_1d(jk) is ok) 300 ! using s_i_1d and not sz_i_1d(jk) is ok) 301 301 END IF 302 302 ! update thickness … … 320 320 ! if all ice is melted. => must be corrected 321 321 ! update remaining mass flux and thickness 322 zevap_rema(ji) = zevap_rema(ji) + zdum * rhoi 322 zevap_rema(ji) = zevap_rema(ji) + zdum * rhoi 323 323 zh_i(ji,jk) = MAX( 0._wp, zh_i(ji,jk) + zdum ) 324 324 h_i_1d(ji) = MAX( 0._wp, h_i_1d(ji) + zdum ) … … 329 329 h_i_old (ji,jk) = h_i_old (ji,jk) + zdum 330 330 331 ! record which layers have disappeared (for bottom melting) 331 ! record which layers have disappeared (for bottom melting) 332 332 ! => icount=0 : no layer has vanished 333 333 ! => icount=5 : 5 layers have vanished 334 rswitch = MAX( 0._wp , SIGN( 1._wp , - zh_i(ji,jk) ) ) 334 rswitch = MAX( 0._wp , SIGN( 1._wp , - zh_i(ji,jk) ) ) 335 335 icount(ji,jk) = NINT( rswitch ) 336 337 END DO 338 END DO 339 336 337 END DO 338 END DO 339 340 340 ! remaining "potential" evap is sent to ocean 341 341 DO ji = 1, npti … … 344 344 345 345 346 ! Ice Basal growth 346 ! Ice Basal growth 347 347 !------------------ 348 348 ! Basal growth is driven by heat imbalance at the ice-ocean interface, 349 ! between the inner conductive flux (qcn_ice_bot), from the open water heat flux 350 ! (fhld) and the sensible ice-ocean flux (qsb_ice_bot). 351 ! qcn_ice_bot is positive downwards. qsb_ice_bot and fhld are positive to the ice 349 ! between the inner conductive flux (qcn_ice_bot), from the open water heat flux 350 ! (fhld) and the sensible ice-ocean flux (qsb_ice_bot). 351 ! qcn_ice_bot is positive downwards. qsb_ice_bot and fhld are positive to the ice 352 352 353 353 ! If salinity varies in time, an iterative procedure is required, because … … 359 359 num_iter_max = 1 360 360 IF( nn_icesal == 2 ) num_iter_max = 5 ! salinity varying in time 361 361 362 362 DO ji = 1, npti 363 363 IF( zf_tt(ji) < 0._wp ) THEN … … 366 366 ! New bottom ice salinity (Cox & Weeks, JGR88 ) 367 367 !--- zswi1 if dh/dt < 2.0e-8 368 !--- zswi12 if 2.0e-8 < dh/dt < 3.6e-7 368 !--- zswi12 if 2.0e-8 < dh/dt < 3.6e-7 369 369 !--- zswi2 if dh/dt > 3.6e-7 370 370 zgrr = MIN( 1.0e-3, MAX ( dh_i_bog(ji) * r1_Dt_ice , epsi10 ) ) … … 380 380 381 381 zt_i_new = zswitch_sal * t_bo_1d(ji) + ( 1. - zswitch_sal) * t_i_1d(ji, nlay_i) 382 382 383 383 zEi = rcpi * ( zt_i_new - (ztmelts+rt0) ) & ! Specific enthalpy of forming ice (J/kg, <0) 384 384 & - rLfus * ( 1.0 - ztmelts / ( MIN( zt_i_new - rt0, -epsi10 ) ) ) + rcp * ztmelts … … 389 389 390 390 dh_i_bog(ji) = rDt_ice * MAX( 0._wp , zf_tt(ji) / ( zdE * rhoi ) ) 391 391 392 392 END DO 393 ! Contribution to Energy and Salt Fluxes 393 ! Contribution to Energy and Salt Fluxes 394 394 zfmdt = - rhoi * dh_i_bog(ji) ! Mass flux x time step (kg/m2, < 0) 395 395 396 396 hfx_thd_1d(ji) = hfx_thd_1d(ji) + zEw * zfmdt * a_i_1d(ji) * r1_Dt_ice ! Heat flux to the ocean [W.m-2], >0 397 hfx_bog_1d(ji) = hfx_bog_1d(ji) - zdE * zfmdt * a_i_1d(ji) * r1_Dt_ice ! Heat flux used in this process [W.m-2], <0 397 hfx_bog_1d(ji) = hfx_bog_1d(ji) - zdE * zfmdt * a_i_1d(ji) * r1_Dt_ice ! Heat flux used in this process [W.m-2], <0 398 398 wfx_bog_1d(ji) = wfx_bog_1d(ji) - rhoi * dh_i_bog(ji) * a_i_1d(ji) * r1_Dt_ice ! Mass flux, <0 399 399 sfx_bog_1d(ji) = sfx_bog_1d(ji) - rhoi * dh_i_bog(ji) * s_i_new(ji) * a_i_1d(ji) * r1_Dt_ice ! Salt flux, <0 … … 415 415 DO jk = nlay_i, 1, -1 416 416 DO ji = 1, npti 417 IF( zf_tt(ji) > 0._wp .AND. jk > icount(ji,jk) ) THEN ! do not calculate where layer has already disappeared by surface melting 417 IF( zf_tt(ji) > 0._wp .AND. jk > icount(ji,jk) ) THEN ! do not calculate where layer has already disappeared by surface melting 418 418 419 419 ztmelts = - rTmlt * sz_i_1d(ji,jk) ! Melting point of layer jk (C) … … 424 424 zdE = 0._wp ! Specific enthalpy difference (J/kg, <0) 425 425 ! set up at 0 since no energy is needed to melt water...(it is already melted) 426 zdum = MIN( 0._wp , - zh_i(ji,jk) ) ! internal melting occurs when the internal temperature is above freezing 426 zdum = MIN( 0._wp , - zh_i(ji,jk) ) ! internal melting occurs when the internal temperature is above freezing 427 427 ! this should normally not happen, but sometimes, heat diffusion leads to this 428 428 dh_i_itm (ji) = dh_i_itm(ji) + zdum … … 446 446 447 447 zdum = MIN( 0._wp , MAX( zdum, - zh_i(ji,jk) ) ) ! bound thickness change 448 448 449 449 zq_bot(ji) = MAX( 0._wp , zq_bot(ji) - zdum * rhoi * zdE ) ! update available heat. MAX is necessary for roundup errors 450 450 … … 455 455 zQm = zfmdt * zEw ! Heat exchanged with ocean 456 456 457 hfx_thd_1d(ji) = hfx_thd_1d(ji) + zEw * zfmdt * a_i_1d(ji) * r1_Dt_ice ! Heat flux to the ocean [W.m-2], <0 457 hfx_thd_1d(ji) = hfx_thd_1d(ji) + zEw * zfmdt * a_i_1d(ji) * r1_Dt_ice ! Heat flux to the ocean [W.m-2], <0 458 458 hfx_bom_1d(ji) = hfx_bom_1d(ji) - zdE * zfmdt * a_i_1d(ji) * r1_Dt_ice ! Heat used in this process [W.m-2], >0 459 459 wfx_bom_1d(ji) = wfx_bom_1d(ji) - rhoi * zdum * a_i_1d(ji) * r1_Dt_ice ! Mass flux … … 488 488 END DO 489 489 END DO 490 490 491 491 ! Snow load on ice 492 492 ! ----------------- … … 511 511 END DO 512 512 END DO 513 513 514 514 ! Snow-Ice formation 515 515 ! ------------------ 516 ! When snow load exceeds Archimede's limit, snow-ice interface goes down under sea-level, 516 ! When snow load exceeds Archimede's limit, snow-ice interface goes down under sea-level, 517 517 ! flooding of seawater transforms snow into ice. Thickness that is transformed is dh_snowice (positive for the ice) 518 518 z1_rho = 1._wp / ( rhos+rho0-rhoi ) … … 528 528 zfmdt = ( rhos - rhoi ) * dh_snowice(ji) ! <0 529 529 zEw = rcp * sst_1d(ji) 530 zQm = zfmdt * zEw 531 530 zQm = zfmdt * zEw 531 532 532 hfx_thd_1d(ji) = hfx_thd_1d(ji) + zEw * zfmdt * a_i_1d(ji) * r1_Dt_ice ! Heat flux 533 533 sfx_sni_1d(ji) = sfx_sni_1d(ji) + sss_1d(ji) * zfmdt * a_i_1d(ji) * r1_Dt_ice ! Salt flux … … 536 536 IF( nn_icesal /= 2 ) THEN 537 537 sfx_bri_1d(ji) = sfx_bri_1d(ji) - sss_1d(ji) * zfmdt * a_i_1d(ji) * r1_Dt_ice & ! put back sss_m into the ocean 538 & - s_i_1d(ji) * dh_snowice(ji) * rhoi * a_i_1d(ji) * r1_Dt_ice ! and get rn_icesal from the ocean 538 & - s_i_1d(ji) * dh_snowice(ji) * rhoi * a_i_1d(ji) * r1_Dt_ice ! and get rn_icesal from the ocean 539 539 ENDIF 540 540 … … 574 574 !-------------------------------------------- 575 575 CALL snw_ent( zh_s, ze_s, e_s_1d ) 576 576 577 577 ! recalculate t_s_1d from e_s_1d 578 578 DO jk = 1, nlay_s … … 589 589 590 590 ! --- ensure that a_i = 0 & h_s = 0 where h_i = 0 --- 591 WHERE( h_i_1d(1:npti) == 0._wp ) 591 WHERE( h_i_1d(1:npti) == 0._wp ) 592 592 a_i_1d (1:npti) = 0._wp 593 593 h_s_1d (1:npti) = 0._wp 594 594 t_su_1d(1:npti) = rt0 595 595 END WHERE 596 596 597 597 END SUBROUTINE ice_thd_dh 598 598 … … 602 602 !! 603 603 !! ** Purpose : 604 !! This routine computes new vertical grids in the snow, 605 !! and consistently redistributes temperatures. 604 !! This routine computes new vertical grids in the snow, 605 !! and consistently redistributes temperatures. 606 606 !! Redistribution is made so as to ensure to energy conservation 607 607 !! 608 608 !! 609 609 !! ** Method : linear conservative remapping 610 !! 610 !! 611 611 !! ** Steps : 1) cumulative integrals of old enthalpies/thicknesses 612 612 !! 2) linear remapping on the new layers … … 637 637 ! 1) Cumulative integral of old enthalpy * thickness and layers interfaces 638 638 !-------------------------------------------------------------------------- 639 zeh_cum0(1:npti,0) = 0._wp 639 zeh_cum0(1:npti,0) = 0._wp 640 640 zh_cum0 (1:npti,0) = 0._wp 641 641 DO jk0 = 1, nlay_s+1 … … 651 651 ! new layer thickesses 652 652 DO ji = 1, npti 653 zhnew(ji) = SUM( ph_old(ji,0:nlay_s) ) * r1_nlay_s 653 zhnew(ji) = SUM( ph_old(ji,0:nlay_s) ) * r1_nlay_s 654 654 END DO 655 655 … … 662 662 END DO 663 663 664 zeh_cum1(1:npti,0:nlay_s) = 0._wp 664 zeh_cum1(1:npti,0:nlay_s) = 0._wp 665 665 ! new cumulative q*h => linear interpolation 666 666 DO jk0 = 1, nlay_s+1 … … 676 676 END DO 677 677 ! to ensure that total heat content is strictly conserved, set: 678 zeh_cum1(1:npti,nlay_s) = zeh_cum0(1:npti,nlay_s+1) 678 zeh_cum1(1:npti,nlay_s) = zeh_cum0(1:npti,nlay_s+1) 679 679 680 680 ! new enthalpies 681 681 DO jk1 = 1, nlay_s 682 682 DO ji = 1, npti 683 rswitch = MAX( 0._wp , SIGN( 1._wp , zhnew(ji) - epsi20 ) ) 683 rswitch = MAX( 0._wp , SIGN( 1._wp , zhnew(ji) - epsi20 ) ) 684 684 pe_new(ji,jk1) = rswitch * ( zeh_cum1(ji,jk1) - zeh_cum1(ji,jk1-1) ) / MAX( zhnew(ji), epsi20 ) 685 685 END DO 686 686 END DO 687 687 688 688 END SUBROUTINE snw_ent 689 689 690 690 691 691 #else 692 692 !!---------------------------------------------------------------------- -
NEMO/trunk/src/ICE/icethd_pnd.F90
r14005 r14072 1 MODULE icethd_pnd 1 MODULE icethd_pnd 2 2 !!====================================================================== 3 3 !! *** MODULE icethd_pnd *** … … 41 41 INTEGER, PARAMETER :: np_pndTOPO = 3 ! Level ice pond scheme 42 42 43 !-------------------------------------------------------------------------- 43 !-------------------------------------------------------------------------- 44 44 ! Diagnostics for pond volume per area 45 45 ! … … 56 56 REAL(wp), ALLOCATABLE, DIMENSION(:,:) :: diag_dvpn_drn ! pond volume lost by drainage [-] 57 57 REAL(wp), ALLOCATABLE, DIMENSION(:,:) :: diag_dvpn_lid ! exchange with lid / refreezing [-] 58 REAL(wp), ALLOCATABLE, DIMENSION(:,:) :: diag_dvpn_rnf ! meltwater pond lost to runoff [-] 58 REAL(wp), ALLOCATABLE, DIMENSION(:,:) :: diag_dvpn_rnf ! meltwater pond lost to runoff [-] 59 59 REAL(wp), ALLOCATABLE, DIMENSION(:) :: diag_dvpn_mlt_1d ! meltwater pond volume input [-] 60 60 REAL(wp), ALLOCATABLE, DIMENSION(:) :: diag_dvpn_drn_1d ! pond volume lost by drainage [-] … … 75 75 !!------------------------------------------------------------------- 76 76 !! *** ROUTINE ice_thd_pnd *** 77 !! 77 !! 78 78 !! ** Purpose : change melt pond fraction and thickness 79 79 !! … … 84 84 INTEGER :: ji, jj, jl ! loop indices 85 85 !!------------------------------------------------------------------- 86 86 87 87 ALLOCATE( diag_dvpn_mlt(jpi,jpj), diag_dvpn_lid(jpi,jpj), diag_dvpn_drn(jpi,jpj), diag_dvpn_rnf(jpi,jpj) ) 88 88 ALLOCATE( diag_dvpn_mlt_1d(jpij), diag_dvpn_lid_1d(jpij), diag_dvpn_drn_1d(jpij), diag_dvpn_rnf_1d(jpij) ) … … 111 111 END_2D 112 112 END DO 113 113 114 114 !------------------------------ 115 115 ! Identify grid cells with ice … … 148 148 DEALLOCATE( diag_dvpn_mlt , diag_dvpn_lid , diag_dvpn_drn , diag_dvpn_rnf ) 149 149 DEALLOCATE( diag_dvpn_mlt_1d, diag_dvpn_lid_1d, diag_dvpn_drn_1d, diag_dvpn_rnf_1d ) 150 151 END SUBROUTINE ice_thd_pnd 152 153 154 SUBROUTINE pnd_CST 150 151 END SUBROUTINE ice_thd_pnd 152 153 154 SUBROUTINE pnd_CST 155 155 !!------------------------------------------------------------------- 156 156 !! *** ROUTINE pnd_CST *** … … 158 158 !! ** Purpose : Compute melt pond evolution 159 159 !! 160 !! ** Method : Melt pond fraction and thickness are prescribed 160 !! ** Method : Melt pond fraction and thickness are prescribed 161 161 !! to non-zero values when t_su = 0C 162 162 !! 163 163 !! ** Tunable parameters : pond fraction (rn_apnd), pond depth (rn_hpnd) 164 !! 164 !! 165 165 !! ** Note : Coupling with such melt ponds is only radiative 166 166 !! Advection, ridging, rafting... are bypassed … … 172 172 !!------------------------------------------------------------------- 173 173 DO jl = 1, jpl 174 174 175 175 CALL tab_2d_1d( npti, nptidx(1:npti), a_i_1d (1:npti), a_i (:,:,jl) ) 176 176 CALL tab_2d_1d( npti, nptidx(1:npti), t_su_1d (1:npti), t_su (:,:,jl) ) … … 185 185 ! 186 186 IF( a_i_1d(ji) >= 0.01_wp .AND. t_su_1d(ji) >= rt0 ) THEN 187 h_ip_1d(ji) = rn_hpnd 187 h_ip_1d(ji) = rn_hpnd 188 188 a_ip_1d(ji) = rn_apnd * a_i_1d(ji) 189 189 h_il_1d(ji) = 0._wp ! no pond lids whatsoever 190 190 ELSE 191 h_ip_1d(ji) = 0._wp 191 h_ip_1d(ji) = 0._wp 192 192 a_ip_1d(ji) = 0._wp 193 193 h_il_1d(ji) = 0._wp … … 222 222 !! ** Method : A fraction of meltwater is accumulated in ponds and sent to ocean when surface is freezing 223 223 !! We work with volumes and then redistribute changes into thickness and concentration 224 !! assuming linear relationship between the two. 224 !! assuming linear relationship between the two. 225 225 !! 226 226 !! ** Action : - pond growth: Vp = Vp + dVmelt --- from Holland et al 2012 --- … … 237 237 !! dH = lid thickness change. Retrieved from this eq.: --- from Flocco et al 2010 --- 238 238 !! 239 !! rhoi * Lf * dH/dt = ki * MAX(Tp-Tsu,0) / H 239 !! rhoi * Lf * dH/dt = ki * MAX(Tp-Tsu,0) / H 240 240 !! H = lid thickness 241 241 !! Lf = latent heat of fusion … … 260 260 !! 261 261 !! ** Tunable parameters : rn_apnd_max, rn_apnd_min, rn_pnd_flush 262 !! 263 !! ** Note : Mostly stolen from CICE but not only. These are between level-ice ponds and CESM ponds. 262 !! 263 !! ** Note : Mostly stolen from CICE but not only. These are between level-ice ponds and CESM ponds. 264 264 !! 265 265 !! ** References : Flocco and Feltham (JGR, 2007) … … 267 267 !! Holland et al (J. Clim, 2012) 268 268 !! Hunke et al (OM 2012) 269 !!------------------------------------------------------------------- 269 !!------------------------------------------------------------------- 270 270 REAL(wp), DIMENSION(nlay_i) :: ztmp ! temporary array 271 271 !! … … 287 287 INTEGER :: ji, jk, jl ! loop indices 288 288 !!------------------------------------------------------------------- 289 z1_rhow = 1._wp / rhow 289 z1_rhow = 1._wp / rhow 290 290 z1_aspect = 1._wp / zaspect 291 z1_Tp = 1._wp / zTp 292 291 z1_Tp = 1._wp / zTp 292 293 293 CALL tab_2d_1d( npti, nptidx(1:npti), at_i_1d (1:npti), at_i ) 294 294 CALL tab_2d_1d( npti, nptidx(1:npti), wfx_pnd_1d (1:npti), wfx_pnd ) 295 295 296 296 CALL tab_2d_1d( npti, nptidx(1:npti), diag_dvpn_mlt_1d (1:npti), diag_dvpn_mlt ) 297 297 CALL tab_2d_1d( npti, nptidx(1:npti), diag_dvpn_drn_1d (1:npti), diag_dvpn_drn ) … … 315 315 CALL tab_2d_1d( npti, nptidx(1:npti), t_i_1d (1:npti,jk), t_i (:,:,jk,jl) ) 316 316 END DO 317 317 318 318 !----------------------- 319 319 ! Melt pond calculations … … 342 342 zdv_avail = -( dh_i_sum(ji)*rhoi + dh_s_mlt(ji)*rhos ) * z1_rhow * a_i_1d(ji) ! > 0 343 343 zfr_mlt = rn_apnd_min + ( rn_apnd_max - rn_apnd_min ) * at_i_1d(ji) ! = ( 1 - r ) = fraction of melt water that is not flushed 344 zdv_mlt = MAX( 0._wp, zfr_mlt * zdv_avail ) ! max for roundoff errors? 344 zdv_mlt = MAX( 0._wp, zfr_mlt * zdv_avail ) ! max for roundoff errors? 345 345 ! 346 346 !--- overflow ---! … … 349 349 ! If pond area exceeds zfr_mlt * a_i_1d(ji) then reduce the pond volume 350 350 ! a_ip_max = zfr_mlt * a_i 351 ! => from zaspect = h_ip / (a_ip / a_i), set v_ip_max as: 351 ! => from zaspect = h_ip / (a_ip / a_i), set v_ip_max as: 352 352 zv_ip_max = zfr_mlt**2 * a_i_1d(ji) * zaspect 353 353 zdv_mlt = MAX( 0._wp, MIN( zdv_mlt, zv_ip_max - v_ip_1d(ji) ) ) … … 356 356 ! If pond depth exceeds half the ice thickness then reduce the pond volume 357 357 ! h_ip_max = 0.5 * h_i 358 ! => from zaspect = h_ip / (a_ip / a_i), set v_ip_max as: 358 ! => from zaspect = h_ip / (a_ip / a_i), set v_ip_max as: 359 359 zv_ip_max = z1_aspect * a_i_1d(ji) * 0.25 * h_i_1d(ji) * h_i_1d(ji) 360 360 zdv_mlt = MAX( 0._wp, MIN( zdv_mlt, zv_ip_max - v_ip_1d(ji) ) ) … … 375 375 IF( ln_pnd_lids ) THEN 376 376 ! 377 !--- Lid growing and subsequent pond shrinking ---! 377 !--- Lid growing and subsequent pond shrinking ---! 378 378 zdv_frz = - 0.5_wp * MAX( 0._wp, -v_il_1d(ji) + & ! Flocco 2010 (eq. 5) solved implicitly as aH**2 + bH + c = 0 379 379 & SQRT( v_il_1d(ji)**2 + a_ip_1d(ji)**2 * 4._wp * rcnd_i * zdT * rDt_ice / (rLfus * rhow) ) ) ! max for roundoff errors … … 386 386 387 387 ELSE 388 zdv_frz = v_ip_1d(ji) * ( EXP( 0.01_wp * zdT * z1_Tp ) - 1._wp ) ! Holland 2012 (eq. 6) 388 zdv_frz = v_ip_1d(ji) * ( EXP( 0.01_wp * zdT * z1_Tp ) - 1._wp ) ! Holland 2012 (eq. 6) 389 389 ! Pond shrinking 390 390 v_ip_1d(ji) = MAX( 0._wp, v_ip_1d(ji) + zdv_frz ) … … 398 398 ! 399 399 400 !------------------------------------------------! 400 !------------------------------------------------! 401 401 ! Pond drainage through brine network (flushing) ! 402 402 !------------------------------------------------! … … 420 420 ! Do the drainage using Darcy's law 421 421 zdv_flush = -zperm * rho0 * grav * zhp * rDt_ice / (zvisc * h_i_1d(ji)) * a_ip_1d(ji) * rn_pnd_flush ! zflush comes from Hunke et al. (2012) 422 zdv_flush = MAX( zdv_flush, -v_ip_1d(ji) ) ! < 0 422 zdv_flush = MAX( zdv_flush, -v_ip_1d(ji) ) ! < 0 423 423 v_ip_1d(ji) = v_ip_1d(ji) + zdv_flush 424 424 … … 479 479 480 480 481 SUBROUTINE pnd_TOPO 482 481 SUBROUTINE pnd_TOPO 482 483 483 !!------------------------------------------------------------------- 484 484 !! *** ROUTINE pnd_TOPO *** … … 488 488 !! 489 489 !! ** Method : This code is initially based on Flocco and Feltham 490 !! (2007) and Flocco et al. (2010). 490 !! (2007) and Flocco et al. (2010). 491 491 !! 492 492 !! - Calculate available pond water base on surface meltwater … … 532 532 REAL(wp), DIMENSION(jpi,jpj) :: zvolp, & !! total melt pond water available before redistribution and drainage 533 533 zvolp_res !! remaining melt pond water available after drainage 534 534 535 535 REAL(wp), DIMENSION(jpi,jpj,jpl) :: z1_a_i 536 536 … … 545 545 546 546 CALL ctl_stop( 'STOP', 'icethd_pnd : topographic melt ponds are still an ongoing work' ) 547 547 548 548 !--------------------------------------------------------------- 549 549 ! Initialise … … 553 553 zrhoi_L = rhoi * rLfus ! volumetric latent heat (J/m^3) 554 554 zTp = rt0 - 0.15_wp ! pond freezing point, slightly below 0C (ponds are bid saline) 555 z1_rhow = 1._wp / rhow 555 z1_rhow = 1._wp / rhow 556 556 557 557 ! Set required ice variables (hard-coded here for now) 558 ! zfpond(:,:) = 0._wp ! contributing freshwater flux (?) 559 558 ! zfpond(:,:) = 0._wp ! contributing freshwater flux (?) 559 560 560 at_i (:,:) = SUM( a_i (:,:,:), dim=3 ) ! ice fraction 561 561 vt_i (:,:) = SUM( v_i (:,:,:), dim=3 ) ! volume per grid area 562 562 vt_ip(:,:) = SUM( v_ip(:,:,:), dim=3 ) ! pond volume per grid area 563 563 vt_il(:,:) = SUM( v_il(:,:,:), dim=3 ) ! lid volume per grid area 564 564 565 565 ! thickness 566 566 WHERE( a_i(:,:,:) > epsi20 ) ; z1_a_i(:,:,:) = 1._wp / a_i(:,:,:) … … 568 568 END WHERE 569 569 h_i(:,:,:) = v_i (:,:,:) * z1_a_i(:,:,:) 570 570 571 571 !--------------------------------------------------------------- 572 572 ! Change 2D to 1D 573 573 !--------------------------------------------------------------- 574 ! MV 574 ! MV 575 575 ! a less computing-intensive version would have 2D-1D passage here 576 576 ! use what we have in iceitd.F90 (incremental remapping) … … 582 582 ! Holland et al (2012) suggest that the fraction of runoff decreases with total ice fraction 583 583 ! I cite her words, they are very talkative 584 ! "grid cells with very little ice cover (and hence more open water area) 584 ! "grid cells with very little ice cover (and hence more open water area) 585 585 ! have a higher runoff fraction to rep- resent the greater proximity of ice to open water." 586 586 ! "This results in the same runoff fraction r for each ice category within a grid cell" 587 587 588 588 zvolp(:,:) = 0._wp 589 589 590 590 DO jl = 1, jpl 591 591 DO_2D( 1, 1, 1, 1 ) 592 592 593 593 IF ( a_i(ji,jj,jl) > epsi10 ) THEN 594 594 595 595 !--- Available and contributing meltwater for melt ponding ---! 596 596 zv_mlt = - ( dh_i_sum_2d(ji,jj,jl) * rhoi + dh_s_mlt_2d(ji,jj,jl) * rhos ) & ! available volume of surface melt water per grid area … … 601 601 602 602 diag_dvpn_mlt(ji,jj) = diag_dvpn_mlt(ji,jj) + zv_mlt * r1_Dt_ice ! diags 603 diag_dvpn_rnf(ji,jj) = diag_dvpn_rnf(ji,jj) + ( 1. - zfr_mlt ) * zv_mlt * r1_Dt_ice 603 diag_dvpn_rnf(ji,jj) = diag_dvpn_rnf(ji,jj) + ( 1. - zfr_mlt ) * zv_mlt * r1_Dt_ice 604 604 605 605 !--- Create possible new ponds … … 610 610 a_ip_frac(ji,jj,jl) = 1.0_wp ! pond fraction of sea ice (apnd for CICE) 611 611 ENDIF 612 612 613 613 !--- Deepen existing ponds with no change in pond fraction, before redistribution and drainage 614 614 v_ip(ji,jj,jl) = v_ip(ji,jj,jl) + zv_pnd ! use pond water to increase thickness 615 615 h_ip(ji,jj,jl) = v_ip(ji,jj,jl) / a_ip(ji,jj,jl) 616 616 617 617 !--- Total available pond water volume (pre-existing + newly produced)j 618 zvolp(ji,jj) = zvolp(ji,jj) + v_ip(ji,jj,jl) 618 zvolp(ji,jj) = zvolp(ji,jj) + v_ip(ji,jj,jl) 619 619 ! zfpond(ji,jj) = zfpond(ji,jj) + zpond * a_ip_frac(ji,jj,jl) ! useless for now 620 620 621 621 ENDIF ! a_i 622 622 623 623 END_2D 624 624 END DO ! ji 625 625 626 626 !-------------------------------------------------------------- 627 627 ! Redistribute and drain water from ponds 628 !-------------------------------------------------------------- 628 !-------------------------------------------------------------- 629 629 CALL ice_thd_pnd_area( zvolp, zvolp_res ) 630 630 631 631 !-------------------------------------------------------------- 632 632 ! Melt pond lid growth and melt 633 !-------------------------------------------------------------- 634 633 !-------------------------------------------------------------- 634 635 635 IF( ln_pnd_lids ) THEN 636 636 … … 638 638 639 639 IF ( at_i(ji,jj) > 0.01 .AND. hm_i(ji,jj) > rn_himin .AND. vt_ip(ji,jj) > zvp_min * at_i(ji,jj) ) THEN 640 640 641 641 !-------------------------- 642 642 ! Pond lid growth and melt … … 648 648 END DO 649 649 zTavg = zTavg / a_i(ji,jj,jl) !!! could get a division by zero here 650 650 651 651 DO jl = 1, jpl-1 652 652 653 653 IF ( v_il(ji,jj,jl) > epsi10 ) THEN 654 654 655 655 !---------------------------------------------------------------- 656 656 ! Lid melting: floating upper ice layer melts in whole or part … … 660 660 661 661 zdvice = MIN( dh_i_sum_2d(ji,jj,jl)*a_ip(ji,jj,jl), v_il(ji,jj,jl) ) 662 662 663 663 IF ( zdvice > epsi10 ) THEN 664 664 665 665 v_il (ji,jj,jl) = v_il (ji,jj,jl) - zdvice 666 v_ip(ji,jj,jl) = v_ip(ji,jj,jl) + zdvice ! MV: not sure i understand dh_i_sum seems counted twice - 666 v_ip(ji,jj,jl) = v_ip(ji,jj,jl) + zdvice ! MV: not sure i understand dh_i_sum seems counted twice - 667 667 ! as it is already counted in surface melt 668 668 ! zvolp(ji,jj) = zvolp(ji,jj) + zdvice ! pointless to calculate total volume (done in icevar) 669 669 ! zfpond(ji,jj) = fpond(ji,jj) + zdvice ! pointless to follow fw budget (ponds have no fw) 670 670 671 671 IF ( v_il(ji,jj,jl) < epsi10 .AND. v_ip(ji,jj,jl) > epsi10) THEN 672 672 ! ice lid melted and category is pond covered 673 v_ip(ji,jj,jl) = v_ip(ji,jj,jl) + v_il(ji,jj,jl) 674 ! zfpond(ji,jj) = zfpond (ji,jj) + v_il(ji,jj,jl) 673 v_ip(ji,jj,jl) = v_ip(ji,jj,jl) + v_il(ji,jj,jl) 674 ! zfpond(ji,jj) = zfpond (ji,jj) + v_il(ji,jj,jl) 675 675 v_il(ji,jj,jl) = 0._wp 676 676 ENDIF 677 677 h_ip(ji,jj,jl) = v_ip(ji,jj,jl) / a_ip(ji,jj,jl) !!! could get a division by zero here 678 678 679 679 diag_dvpn_lid(ji,jj) = diag_dvpn_lid(ji,jj) + zdvice ! diag 680 680 681 681 ENDIF 682 682 683 683 !---------------------------------------------------------------- 684 ! Freeze pre-existing lid 684 ! Freeze pre-existing lid 685 685 !---------------------------------------------------------------- 686 686 … … 688 688 689 689 ! differential growth of base of surface floating ice layer 690 zdTice = MAX( - t_su(ji,jj,jl) - zTd , 0._wp ) ! > 0 690 zdTice = MAX( - t_su(ji,jj,jl) - zTd , 0._wp ) ! > 0 691 691 zomega = rcnd_i * zdTice / zrhoi_L 692 692 zdHui = SQRT( 2._wp * zomega * rDt_ice + ( v_il(ji,jj,jl) / a_i(ji,jj,jl) )**2 ) & 693 693 - v_il(ji,jj,jl) / a_i(ji,jj,jl) 694 694 zdvice = min( zdHui*a_ip(ji,jj,jl) , v_ip(ji,jj,jl) ) 695 695 696 696 IF ( zdvice > epsi10 ) THEN 697 697 v_il (ji,jj,jl) = v_il(ji,jj,jl) + zdvice … … 700 700 ! zfpond(ji,jj) = zfpond(ji,jj) - zdvice 701 701 h_ip(ji,jj,jl) = v_ip(ji,jj,jl) / a_ip(ji,jj,jl) 702 702 703 703 diag_dvpn_lid(ji,jj) = diag_dvpn_lid(ji,jj) - zdvice ! diag 704 704 705 705 ENDIF 706 706 707 707 ENDIF ! Tsfcn(i,j,n) 708 708 … … 714 714 715 715 ELSE ! v_il < epsi10 716 716 717 717 ! thickness of newly formed ice 718 718 ! the surface temperature of a meltpond is the same as that 719 ! of the ice underneath (0C), and the thermodynamic surface 719 ! of the ice underneath (0C), and the thermodynamic surface 720 720 ! flux is the same 721 721 722 722 !!! we need net surface energy flux, excluding conduction 723 723 !!! fsurf is summed over categories in CICE 724 724 !!! we have the category-dependent flux, let us use it ? 725 zfsurf = qns_ice(ji,jj,jl) + qsr_ice(ji,jj,jl) 725 zfsurf = qns_ice(ji,jj,jl) + qsr_ice(ji,jj,jl) 726 726 zdHui = MAX ( -zfsurf * rDt_ice/zrhoi_L , 0._wp ) 727 727 zdvice = MIN ( zdHui * a_ip(ji,jj,jl) , v_ip(ji,jj,jl) ) … … 729 729 v_il (ji,jj,jl) = v_il(ji,jj,jl) + zdvice 730 730 v_ip(ji,jj,jl) = v_ip(ji,jj,jl) - zdvice 731 731 732 732 diag_dvpn_lid(ji,jj) = diag_dvpn_lid(ji,jj) - zdvice ! diag 733 733 ! zvolp(ji,jj) = zvolp(ji,jj) - zdvice … … 735 735 h_ip(ji,jj,jl) = v_ip(ji,jj,jl) / a_ip(ji,jj,jl) ! MV - in principle, this is useless as h_ip is computed in icevar 736 736 ENDIF 737 737 738 738 ENDIF ! v_il 739 739 740 740 END DO ! jl 741 741 … … 745 745 v_il(ji,jj,:) = 0._wp 746 746 ! zfpond(ji,jj) = zfpond(ji,jj)- zvolp(ji,jj) 747 ! zvolp(ji,jj) = 0._wp 747 ! zvolp(ji,jj) = 0._wp 748 748 749 749 ENDIF … … 769 769 ! v_il(ji,jj,jl) = 0._wp ! probably uselesss now since we get zap_small 770 770 ! ENDIF 771 771 772 772 ! recalculate equivalent pond variables 773 773 IF ( a_ip(ji,jj,jl) > epsi10) THEN … … 779 779 ! h_il(ji,jj,jl) = 0._wp ! MV in principle, useless as omputed in icevar 780 780 ! ENDIF 781 781 782 782 END_2D 783 783 … … 787 787 END SUBROUTINE pnd_TOPO 788 788 789 789 790 790 SUBROUTINE ice_thd_pnd_area( zvolp , zdvolp ) 791 791 … … 793 793 !! *** ROUTINE ice_thd_pnd_area *** 794 794 !! 795 !! ** Purpose : Given the total volume of available pond water, 795 !! ** Purpose : Given the total volume of available pond water, 796 796 !! redistribute and drain water 797 797 !! … … 823 823 !! 824 824 !!------------------------------------------------------------------ 825 825 826 826 REAL (wp), DIMENSION(jpi,jpj), INTENT(INOUT) :: & 827 827 zvolp, & ! total available pond water … … 865 865 a_ip(:,:,:) = 0._wp 866 866 h_ip(:,:,:) = 0._wp 867 867 868 868 DO_2D( 1, 1, 1, 1 ) 869 869 870 870 IF ( at_i(ji,jj) > 0.01 .AND. hm_i(ji,jj) > rn_himin .AND. zvolp(ji,jj) > zvp_min * at_i(ji,jj) ) THEN 871 871 872 872 !------------------------------------------------------------------- 873 873 ! initialize 874 874 !------------------------------------------------------------------- 875 875 876 876 DO jl = 1, jpl 877 877 878 878 !---------------------------------------- 879 879 ! compute the effective snow fraction 880 880 !---------------------------------------- 881 881 882 882 IF (a_i(ji,jj,jl) < epsi10) THEN 883 883 hicen(jl) = 0._wp … … 889 889 hsnon(jl) = v_s(ji,jj,jl) / a_i(ji,jj,jl) 890 890 reduced_aicen(jl) = 1._wp ! n=jpl 891 891 892 892 !js: initial code in NEMO_DEV 893 893 !IF (n < jpl) reduced_aicen(jl) = aicen(jl) & 894 894 ! * (-0.024_wp*hicen(jl) + 0.832_wp) 895 895 896 896 !js: from CICE 5.1.2: this limit reduced_aicen to 0.2 when hicen is too large 897 IF (jl < jpl) reduced_aicen(jl) = a_i(ji,jj,jl) & 897 IF (jl < jpl) reduced_aicen(jl) = a_i(ji,jj,jl) & 898 898 * max(0.2_wp,(-0.024_wp*hicen(jl) + 0.832_wp)) 899 899 900 900 asnon(jl) = reduced_aicen(jl) ! effective snow fraction (empirical) 901 901 ! MV should check whether this makes sense to have the same effective snow fraction in here 902 902 ! OLI: it probably doesn't 903 903 END IF 904 904 905 905 ! This choice for alfa and beta ignores hydrostatic equilibium of categories. 906 906 ! Hydrostatic equilibium of the entire ITD is accounted for below, assuming … … 911 911 ! alfan = 60% of the ice volume) in each category lies above the reference line, 912 912 ! and 40% below. Note: p6 is an arbitrary choice, but alfa+beta=1 is required. 913 913 914 914 ! MV: 915 915 ! Note that this choice is not in the original FF07 paper and has been adopted in CICE 916 916 ! No reason why is explained in the doc, but I guess there is a reason. I'll try to investigate, maybe 917 917 918 918 ! Where does that choice come from ? => OLI : Coz' Chuck Norris said so... 919 919 920 920 alfan(jl) = 0.6 * hicen(jl) 921 921 betan(jl) = 0.4 * hicen(jl) 922 922 923 923 cum_max_vol(jl) = 0._wp 924 924 cum_max_vol_tmp(jl) = 0._wp 925 925 926 926 END DO ! jpl 927 927 928 928 cum_max_vol_tmp(0) = 0._wp 929 929 drain = 0._wp 930 930 zdvolp(ji,jj) = 0._wp 931 931 932 932 !---------------------------------------------------------- 933 933 ! Drain overflow water, update pond fraction and volume 934 934 !---------------------------------------------------------- 935 935 936 936 !-------------------------------------------------------------------------- 937 937 ! the maximum amount of water that can be contained up to each ice category … … 940 940 ! Then the excess volume cum_max_vol(jl) drains out of the system 941 941 ! It should be added to wfx_pnd_out 942 942 943 943 DO jl = 1, jpl-1 ! last category can not hold any volume 944 944 945 945 IF (alfan(jl+1) >= alfan(jl) .AND. alfan(jl+1) > 0._wp ) THEN 946 946 947 947 ! total volume in level including snow 948 948 cum_max_vol_tmp(jl) = cum_max_vol_tmp(jl-1) + & 949 949 (alfan(jl+1) - alfan(jl)) * sum(reduced_aicen(1:jl)) 950 950 951 951 ! subtract snow solid volumes from lower categories in current level 952 952 DO ns = 1, jl … … 956 956 max(min(hsnon(ns)+alfan(ns)-alfan(jl), alfan(jl+1)-alfan(jl)), 0._wp) 957 957 END DO 958 958 959 959 ELSE ! assume higher categories unoccupied 960 960 cum_max_vol_tmp(jl) = cum_max_vol_tmp(jl-1) … … 966 966 cum_max_vol_tmp(jpl) = cum_max_vol_tmp(jpl-1) ! last category holds no volume 967 967 cum_max_vol (1:jpl) = cum_max_vol_tmp(1:jpl) 968 968 969 969 !---------------------------------------------------------------- 970 970 ! is there more meltwater than can be held in the floe? … … 973 973 drain = zvolp(ji,jj) - cum_max_vol(jpl) + epsi10 974 974 zvolp(ji,jj) = zvolp(ji,jj) - drain ! update meltwater volume available 975 975 976 976 diag_dvpn_rnf(ji,jj) = - drain ! diag - overflow counted in the runoff part (arbitrary choice) 977 977 978 978 zdvolp(ji,jj) = drain ! this is the drained water 979 979 IF (zvolp(ji,jj) < epsi10) THEN … … 982 982 END IF 983 983 END IF 984 984 985 985 ! height and area corresponding to the remaining volume 986 986 ! routine leaves zvolp unchanged 987 987 CALL ice_thd_pnd_depth(reduced_aicen, asnon, hsnon, alfan, zvolp(ji,jj), cum_max_vol, hpond, m_index) 988 988 989 989 DO jl = 1, m_index 990 990 !h_ip(jl) = hpond - alfan(jl) + alfan(1) ! here oui choulde update … … 996 996 END DO 997 997 !zapond = sum(a_ip(1:m_index)) !js: from CICE 5.1.2; not in Icepack1.1.0-6-gac6195d 998 998 999 999 !------------------------------------------------------------------------ 1000 1000 ! Drainage through brine network (permeability) 1001 1001 !------------------------------------------------------------------------ 1002 1002 !!! drainage due to ice permeability - Darcy's law 1003 1003 1004 1004 ! sea water level 1005 msno = 0._wp 1005 msno = 0._wp 1006 1006 DO jl = 1 , jpl 1007 1007 msno = msno + v_s(ji,jj,jl) * rhos … … 1010 1010 hsl_rel = floe_weight / rho0 & 1011 1011 - ( ( sum(betan(:)*a_i(ji,jj,:)) / at_i(ji,jj) ) + alfan(1) ) 1012 1012 1013 1013 deltah = hpond - hsl_rel 1014 1014 pressure_head = grav * rho0 * max(deltah, 0._wp) 1015 1015 1016 1016 ! drain if ice is permeable 1017 1017 permflag = 0 1018 1018 1019 1019 IF (pressure_head > 0._wp) THEN 1020 1020 DO jl = 1, jpl-1 1021 1021 IF ( hicen(jl) /= 0._wp ) THEN 1022 1022 1023 1023 !IF (hicen(jl) > 0._wp) THEN !js: from CICE 5.1.2 1024 1024 1025 1025 perm = 0._wp ! MV ugly dummy patch 1026 CALL ice_thd_pnd_perm(t_i(ji,jj,:,jl), sz_i(ji,jj,:,jl), perm) ! bof 1026 CALL ice_thd_pnd_perm(t_i(ji,jj,:,jl), sz_i(ji,jj,:,jl), perm) ! bof 1027 1027 IF (perm > 0._wp) permflag = 1 1028 1028 1029 1029 drain = perm*a_ip(ji,jj,jl)*pressure_head*rDt_ice / & 1030 1030 (viscosity*hicen(jl)) 1031 1031 zdvolp(ji,jj) = zdvolp(ji,jj) + min(drain, zvolp(ji,jj)) 1032 1032 zvolp(ji,jj) = max(zvolp(ji,jj) - drain, 0._wp) 1033 1033 1034 1034 diag_dvpn_drn(ji,jj) = - drain ! diag (could be better coded) 1035 1035 1036 1036 IF (zvolp(ji,jj) < epsi10) THEN 1037 1037 zdvolp(ji,jj) = zdvolp(ji,jj) + zvolp(ji,jj) … … 1040 1040 END IF 1041 1041 END DO 1042 1042 1043 1043 ! adjust melt pond dimensions 1044 1044 IF (permflag > 0) THEN … … 1052 1052 END IF 1053 1053 END IF ! pressure_head 1054 1054 1055 1055 !------------------------------- 1056 1056 ! remove water from the snow … … 1060 1060 ! snow in melt ponds is not melted 1061 1061 !------------------------------------------------------------------------ 1062 1062 1063 1063 ! MV here, it seems that we remove some meltwater from the ponds, but I can't really tell 1064 1064 ! how much, so I did not diagnose it 1065 1065 ! so if there is a problem here, nobody is going to see it... 1066 1067 1066 1067 1068 1068 ! Calculate pond volume for lower categories 1069 1069 DO jl = 1,m_index-1 … … 1071 1071 - (rhos/rhow) * asnon(jl) * min(hsnon(jl), h_ip(ji,jj,jl)) 1072 1072 END DO 1073 1073 1074 1074 ! Calculate pond volume for highest category = remaining pond volume 1075 1075 1076 1076 ! The following is completely unclear to Martin at least 1077 1077 ! Could we redefine properly and recode in a more readable way ? 1078 1078 1079 1079 ! m_index = last category with melt pond 1080 1080 1081 1081 IF (m_index == 1) v_ip(ji,jj,m_index) = zvolp(ji,jj) ! volume of mw in 1st category is the total volume of melt water 1082 1082 1083 1083 IF (m_index > 1) THEN 1084 1084 IF (zvolp(ji,jj) > sum( v_ip(ji,jj,1:m_index-1))) THEN 1085 1085 v_ip(ji,jj,m_index) = zvolp(ji,jj) - sum(v_ip(ji,jj,1:m_index-1)) 1086 1086 ELSE 1087 v_ip(ji,jj,m_index) = 0._wp 1087 v_ip(ji,jj,m_index) = 0._wp 1088 1088 h_ip(ji,jj,m_index) = 0._wp 1089 1089 a_ip(ji,jj,m_index) = 0._wp … … 1094 1094 END IF 1095 1095 END IF 1096 1096 1097 1097 DO jl = 1,m_index 1098 1098 IF (a_ip(ji,jj,jl) > epsi10) THEN … … 1100 1100 ELSE 1101 1101 zdvolp(ji,jj) = zdvolp(ji,jj) + v_ip(ji,jj,jl) 1102 h_ip(ji,jj,jl) = 0._wp 1102 h_ip(ji,jj,jl) = 0._wp 1103 1103 v_ip(ji,jj,jl) = 0._wp 1104 1104 a_ip(ji,jj,jl) = 0._wp … … 1106 1106 END DO 1107 1107 DO jl = m_index+1, jpl 1108 h_ip(ji,jj,jl) = 0._wp 1109 a_ip(ji,jj,jl) = 0._wp 1110 v_ip(ji,jj,jl) = 0._wp 1108 h_ip(ji,jj,jl) = 0._wp 1109 a_ip(ji,jj,jl) = 0._wp 1110 v_ip(ji,jj,jl) = 0._wp 1111 1111 END DO 1112 1112 1113 1113 ENDIF 1114 1114 … … 1319 1319 1320 1320 DO k = 1, nlay_i 1321 1321 1322 1322 Sbr = - Tin(k) / rTmlt ! Consistent expression with SI3 (linear liquidus) 1323 1323 ! Best expression to date is that one (Vancoppenolle et al JGR 2019) 1324 1324 ! Sbr = - 18.7 * Tin(k) - 0.519 * Tin(k)**2 - 0.00535 * Tin(k) **3 1325 1325 phi(k) = salin(k) / Sbr 1326 1326 1327 1327 END DO 1328 1328 … … 1335 1335 END SUBROUTINE ice_thd_pnd_perm 1336 1336 1337 SUBROUTINE ice_thd_pnd_init 1337 SUBROUTINE ice_thd_pnd_init 1338 1338 !!------------------------------------------------------------------- 1339 1339 !! *** ROUTINE ice_thd_pnd_init *** … … 1342 1342 !! over sea ice 1343 1343 !! 1344 !! ** Method : Read the namthd_pnd namelist and check the melt pond 1344 !! ** Method : Read the namthd_pnd namelist and check the melt pond 1345 1345 !! parameter values called at the first timestep (nit000) 1346 1346 !! 1347 !! ** input : Namelist namthd_pnd 1347 !! ** input : Namelist namthd_pnd 1348 1348 !!------------------------------------------------------------------- 1349 1349 INTEGER :: ios, ioptio ! Local integer … … 1389 1389 ! 1390 1390 SELECT CASE( nice_pnd ) 1391 CASE( np_pndNO ) 1391 CASE( np_pndNO ) 1392 1392 IF( ln_pnd_alb ) THEN ; ln_pnd_alb = .FALSE. ; CALL ctl_warn( 'ln_pnd_alb=false when no ponds' ) ; ENDIF 1393 1393 IF( ln_pnd_lids ) THEN ; ln_pnd_lids = .FALSE. ; CALL ctl_warn( 'ln_pnd_lids=false when no ponds' ) ; ENDIF 1394 CASE( np_pndCST ) 1394 CASE( np_pndCST ) 1395 1395 IF( ln_pnd_lids ) THEN ; ln_pnd_lids = .FALSE. ; CALL ctl_warn( 'ln_pnd_lids=false when constant ponds' ) ; ENDIF 1396 1396 END SELECT 1397 1397 ! 1398 1398 END SUBROUTINE ice_thd_pnd_init 1399 1399 1400 1400 #else 1401 1401 !!---------------------------------------------------------------------- 1402 1402 !! Default option Empty module NO SI3 sea-ice model 1403 1403 !!---------------------------------------------------------------------- 1404 #endif 1404 #endif 1405 1405 1406 1406 !!====================================================================== 1407 END MODULE icethd_pnd 1407 END MODULE icethd_pnd -
NEMO/trunk/src/ICE/icethd_zdf_bl99.F90
r14005 r14072 2 2 !!====================================================================== 3 3 !! *** MODULE icethd_zdf_BL99 *** 4 !! sea-ice: vertical heat diffusion in sea ice (computation of temperatures) 4 !! sea-ice: vertical heat diffusion in sea ice (computation of temperatures) 5 5 !!====================================================================== 6 6 !! History : ! 2003-02 (M. Vancoppenolle) original 1D code … … 15 15 !!---------------------------------------------------------------------- 16 16 USE dom_oce ! ocean space and time domain 17 USE phycst ! physical constants (ocean directory) 17 USE phycst ! physical constants (ocean directory) 18 18 USE ice ! sea-ice: variables 19 19 USE ice1D ! sea-ice: thermodynamics variables … … 44 44 !! 45 45 !! ** Method : solves the heat equation diffusion with a Neumann boundary 46 !! condition at the surface and a Dirichlet one at the bottom. 46 !! condition at the surface and a Dirichlet one at the bottom. 47 47 !! Solar radiation is partially absorbed into the ice. 48 !! The specific heat and thermal conductivities depend on ice 49 !! salinity and temperature to take into account brine pocket 48 !! The specific heat and thermal conductivities depend on ice 49 !! salinity and temperature to take into account brine pocket 50 50 !! melting. The numerical scheme is an iterative Crank-Nicolson 51 51 !! on a non-uniform multilayer grid in the ice and snow system. … … 91 91 REAL(wp) :: zbeta = 0.117_wp ! for thermal conductivity (could be 0.13) 92 92 REAL(wp) :: zkimin = 0.10_wp ! minimum ice thermal conductivity 93 REAL(wp) :: ztsu_err = 1.e-5_wp ! range around which t_su is considered at 0C 94 REAL(wp) :: zdti_bnd = 1.e-4_wp ! maximal authorized error on temperature 95 REAL(wp) :: zhs_ssl = 0.03_wp ! surface scattering layer in the snow 93 REAL(wp) :: ztsu_err = 1.e-5_wp ! range around which t_su is considered at 0C 94 REAL(wp) :: zdti_bnd = 1.e-4_wp ! maximal authorized error on temperature 95 REAL(wp) :: zhs_ssl = 0.03_wp ! surface scattering layer in the snow 96 96 REAL(wp) :: zhi_ssl = 0.10_wp ! surface scattering layer in the ice 97 97 REAL(wp) :: zh_min = 1.e-3_wp ! minimum ice/snow thickness for conduction 98 98 REAL(wp) :: ztmelts ! ice melting temperature 99 REAL(wp) :: zdti_max ! current maximal error on temperature 99 REAL(wp) :: zdti_max ! current maximal error on temperature 100 100 REAL(wp) :: zcpi ! Ice specific heat 101 101 REAL(wp) :: zhfx_err, zdq ! diag errors on heat … … 127 127 REAL(wp), DIMENSION(jpij) :: zq_ini ! diag errors on heat 128 128 REAL(wp), DIMENSION(jpij) :: zghe ! G(he), th. conduct enhancement factor, mono-cat 129 REAL(wp), DIMENSION(jpij) :: za_s_fra ! ice fraction covered by snow 130 REAL(wp), DIMENSION(jpij) :: isnow ! snow presence (1) or not (0) 131 REAL(wp), DIMENSION(jpij) :: isnow_comb ! snow presence for met-office 129 REAL(wp), DIMENSION(jpij) :: za_s_fra ! ice fraction covered by snow 130 REAL(wp), DIMENSION(jpij) :: isnow ! snow presence (1) or not (0) 131 REAL(wp), DIMENSION(jpij) :: isnow_comb ! snow presence for met-office 132 132 REAL(wp), DIMENSION(jpij,nlay_i+nlay_s+1) :: zindterm ! 'Ind'ependent term 133 133 REAL(wp), DIMENSION(jpij,nlay_i+nlay_s+1) :: zindtbis ! Temporary 'ind'ependent term … … 139 139 REAL(wp) :: zhe ! dummy factor 140 140 REAL(wp) :: zcnd_i ! mean sea ice thermal conductivity 141 !!------------------------------------------------------------------ 141 !!------------------------------------------------------------------ 142 142 143 143 ! --- diag error on heat diffusion - PART 1 --- ! 144 144 DO ji = 1, npti 145 145 zq_ini(ji) = ( SUM( e_i_1d(ji,1:nlay_i) ) * h_i_1d(ji) * r1_nlay_i + & 146 & SUM( e_s_1d(ji,1:nlay_s) ) * h_s_1d(ji) * r1_nlay_s ) 146 & SUM( e_s_1d(ji,1:nlay_s) ) * h_s_1d(ji) * r1_nlay_s ) 147 147 END DO 148 148 149 149 ! calculate ice fraction covered by snow for radiation 150 150 CALL ice_var_snwfra( h_s_1d(1:npti), za_s_fra(1:npti) ) 151 151 152 152 !------------------ 153 153 ! 1) Initialization … … 155 155 ! 156 156 ! extinction radiation in the snow 157 IF ( nn_qtrice == 0 ) THEN ! constant 157 IF ( nn_qtrice == 0 ) THEN ! constant 158 158 zraext_s(1:npti) = rn_kappa_s 159 159 ELSEIF( nn_qtrice == 1 ) THEN ! depends on melting/freezing conditions … … 166 166 DO ji = 1, npti 167 167 ! ice thickness 168 IF( h_i_1d(ji) > 0._wp ) THEN 168 IF( h_i_1d(ji) > 0._wp ) THEN 169 169 zh_i (ji) = MAX( zh_min , h_i_1d(ji) ) * r1_nlay_i ! set a minimum thickness for conduction 170 170 z1_h_i(ji) = 1._wp / zh_i(ji) ! it must be very small … … 198 198 ztsuold (1:npti) = t_su_1d(1:npti) ! surface temperature initial value 199 199 t_su_1d (1:npti) = MIN( t_su_1d(1:npti), rt0 - ztsu_err ) ! required to leave the choice between melting or not 200 zdqns_ice_b(1:npti) = dqns_ice_1d(1:npti) ! derivative of incoming nonsolar flux 200 zdqns_ice_b(1:npti) = dqns_ice_1d(1:npti) ! derivative of incoming nonsolar flux 201 201 zqns_ice_b (1:npti) = qns_ice_1d(1:npti) ! store previous qns_ice_1d value 202 202 ! … … 221 221 ! 222 222 zradtr_i(1:npti,0) = zradtr_s(1:npti,nlay_s) * za_s_fra(1:npti) + qtr_ice_top_1d(1:npti) * ( 1._wp - za_s_fra(1:npti) ) 223 DO jk = 1, nlay_i 223 DO jk = 1, nlay_i 224 224 DO ji = 1, npti 225 225 ! ! radiation transmitted below the layer-th ice layer … … 227 227 & * EXP( - rn_kappa_i * MAX( 0._wp, zh_i(ji) * REAL(jk) - zh_min ) ) & 228 228 & + ( 1._wp - za_s_fra(ji) ) * qtr_ice_top_1d(ji) & ! part snow free 229 & * EXP( - rn_kappa_i * MAX( 0._wp, zh_i(ji) * REAL(jk) - zhi_ssl ) ) 229 & * EXP( - rn_kappa_i * MAX( 0._wp, zh_i(ji) * REAL(jk) - zhi_ssl ) ) 230 230 ! ! radiation absorbed by the layer-th ice layer 231 231 zradab_i(ji,jk) = zradtr_i(ji,jk-1) - zradtr_i(ji,jk) … … 288 288 DO ji = 1, npti 289 289 IF ( .NOT. l_T_converged(ji) ) & 290 ztcond_i(ji,:) = MAX( zkimin, ztcond_i_cp(ji,:) ) 290 ztcond_i(ji,:) = MAX( zkimin, ztcond_i_cp(ji,:) ) 291 291 END DO 292 292 ! … … 401 401 zdiagbis(1:npti,:) = 0._wp 402 402 403 DO jm = nlay_s + 2, nlay_s + nlay_i 403 DO jm = nlay_s + 2, nlay_s + nlay_i 404 404 DO ji = 1, npti 405 405 jk = jm - nlay_s - 1 … … 414 414 DO ji = 1, npti 415 415 ! ice bottom term 416 ztrid (ji,jm,1) = - zeta_i(ji,nlay_i) * zkappa_i(ji,nlay_i-1) 416 ztrid (ji,jm,1) = - zeta_i(ji,nlay_i) * zkappa_i(ji,nlay_i-1) 417 417 ztrid (ji,jm,2) = 1._wp + zeta_i(ji,nlay_i) * ( zkappa_i(ji,nlay_i-1) + zkappa_i(ji,nlay_i) * zg1 ) 418 418 ztrid (ji,jm,3) = 0._wp 419 419 zindterm(ji,jm) = ztiold(ji,nlay_i) + zeta_i(ji,nlay_i) * & 420 & ( zradab_i(ji,nlay_i) + zkappa_i(ji,nlay_i) * zg1 * t_bo_1d(ji) ) 420 & ( zradab_i(ji,nlay_i) + zkappa_i(ji,nlay_i) * zg1 * t_bo_1d(ji) ) 421 421 END DO 422 422 … … 433 433 zindterm(ji,jm) = ztsold(ji,jk) + zeta_s(ji,jk) * zradab_s(ji,jk) 434 434 END DO 435 435 436 436 ! case of only one layer in the ice (ice equation is altered) 437 437 IF( nlay_i == 1 ) THEN 438 438 ztrid (ji,nlay_s+2,3) = 0._wp 439 zindterm(ji,nlay_s+2) = zindterm(ji,nlay_s+2) + zeta_i(ji,1) * zkappa_i(ji,1) * t_bo_1d(ji) 440 ENDIF 441 439 zindterm(ji,nlay_s+2) = zindterm(ji,nlay_s+2) + zeta_i(ji,1) * zkappa_i(ji,1) * t_bo_1d(ji) 440 ENDIF 441 442 442 IF( t_su_1d(ji) < rt0 ) THEN !-- case 1 : no surface melting 443 443 444 444 jm_min(ji) = 1 445 445 jm_max(ji) = nlay_i + nlay_s + 1 446 446 447 447 ! surface equation 448 448 ztrid (ji,1,1) = 0._wp … … 450 450 ztrid (ji,1,3) = zg1s * zkappa_s(ji,0) 451 451 zindterm(ji,1) = zdqns_ice_b(ji) * t_su_1d(ji) - zfnet(ji) 452 452 453 453 ! first layer of snow equation 454 454 ztrid (ji,2,1) = - zeta_s(ji,1) * zkappa_s(ji,0) * zg1s … … 456 456 ztrid (ji,2,3) = - zeta_s(ji,1) * zkappa_s(ji,1) 457 457 zindterm(ji,2) = ztsold(ji,1) + zeta_s(ji,1) * zradab_s(ji,1) 458 458 459 459 ELSE !-- case 2 : surface is melting 460 460 ! 461 461 jm_min(ji) = 2 462 462 jm_max(ji) = nlay_i + nlay_s + 1 463 463 464 464 ! first layer of snow equation 465 465 ztrid (ji,2,1) = 0._wp 466 466 ztrid (ji,2,2) = 1._wp + zeta_s(ji,1) * ( zkappa_s(ji,1) + zkappa_s(ji,0) * zg1s ) 467 ztrid (ji,2,3) = - zeta_s(ji,1) * zkappa_s(ji,1) 468 zindterm(ji,2) = ztsold(ji,1) + zeta_s(ji,1) * ( zradab_s(ji,1) + zkappa_s(ji,0) * zg1s * t_su_1d(ji) ) 467 ztrid (ji,2,3) = - zeta_s(ji,1) * zkappa_s(ji,1) 468 zindterm(ji,2) = ztsold(ji,1) + zeta_s(ji,1) * ( zradab_s(ji,1) + zkappa_s(ji,0) * zg1s * t_su_1d(ji) ) 469 469 ENDIF 470 470 ! !---------------------! … … 476 476 jm_min(ji) = nlay_s + 1 477 477 jm_max(ji) = nlay_i + nlay_s + 1 478 479 ! surface equation 478 479 ! surface equation 480 480 ztrid (ji,jm_min(ji),1) = 0._wp 481 ztrid (ji,jm_min(ji),2) = zdqns_ice_b(ji) - zkappa_i(ji,0) * zg1 481 ztrid (ji,jm_min(ji),2) = zdqns_ice_b(ji) - zkappa_i(ji,0) * zg1 482 482 ztrid (ji,jm_min(ji),3) = zkappa_i(ji,0) * zg1 483 483 zindterm(ji,jm_min(ji)) = zdqns_ice_b(ji) * t_su_1d(ji) - zfnet(ji) 484 484 485 485 ! first layer of ice equation 486 486 ztrid (ji,jm_min(ji)+1,1) = - zeta_i(ji,1) * zkappa_i(ji,0) * zg1 487 487 ztrid (ji,jm_min(ji)+1,2) = 1._wp + zeta_i(ji,1) * ( zkappa_i(ji,1) + zkappa_i(ji,0) * zg1 ) 488 ztrid (ji,jm_min(ji)+1,3) = - zeta_i(ji,1) * zkappa_i(ji,1) 489 zindterm(ji,jm_min(ji)+1) = ztiold(ji,1) + zeta_i(ji,1) * zradab_i(ji,1) 490 488 ztrid (ji,jm_min(ji)+1,3) = - zeta_i(ji,1) * zkappa_i(ji,1) 489 zindterm(ji,jm_min(ji)+1) = ztiold(ji,1) + zeta_i(ji,1) * zradab_i(ji,1) 490 491 491 ! case of only one layer in the ice (surface & ice equations are altered) 492 492 IF( nlay_i == 1 ) THEN … … 499 499 zindterm(ji,jm_min(ji)+1) = ztiold(ji,1) + zeta_i(ji,1) * (zradab_i(ji,1) + zkappa_i(ji,1) * t_bo_1d(ji)) 500 500 ENDIF 501 501 502 502 ELSE !-- case 2 : surface is melting 503 503 504 504 jm_min(ji) = nlay_s + 2 505 505 jm_max(ji) = nlay_i + nlay_s + 1 506 506 507 507 ! first layer of ice equation 508 508 ztrid (ji,jm_min(ji),1) = 0._wp 509 ztrid (ji,jm_min(ji),2) = 1._wp + zeta_i(ji,1) * ( zkappa_i(ji,1) + zkappa_i(ji,0) * zg1 ) 509 ztrid (ji,jm_min(ji),2) = 1._wp + zeta_i(ji,1) * ( zkappa_i(ji,1) + zkappa_i(ji,0) * zg1 ) 510 510 ztrid (ji,jm_min(ji),3) = - zeta_i(ji,1) * zkappa_i(ji,1) 511 zindterm(ji,jm_min(ji)) = ztiold(ji,1) + zeta_i(ji,1) * (zradab_i(ji,1) + zkappa_i(ji,0) * zg1 * t_su_1d(ji)) 512 511 zindterm(ji,jm_min(ji)) = ztiold(ji,1) + zeta_i(ji,1) * (zradab_i(ji,1) + zkappa_i(ji,0) * zg1 * t_su_1d(ji)) 512 513 513 ! case of only one layer in the ice (surface & ice equations are altered) 514 514 IF( nlay_i == 1 ) THEN … … 519 519 & + t_su_1d(ji) * zeta_i(ji,1) * zkappa_i(ji,0) * 2._wp 520 520 ENDIF 521 521 522 522 ENDIF 523 523 ENDIF … … 540 540 !!$ END DO 541 541 !!$ !!clem SNWLAY => check why LIM1D does not get this loop. Is nlay_i+5 correct? 542 !!$ 542 !!$ 543 543 !!$ DO jk = jm_mint+1, jm_maxt 544 544 !!$ DO ji = 1, npti … … 574 574 END DO 575 575 576 ! snow temperatures 576 ! snow temperatures 577 577 DO ji = 1, npti 578 578 ! Variables used after iterations … … 589 589 END DO 590 590 END DO 591 591 592 592 ! surface temperature 593 593 DO ji = 1, npti … … 628 628 zdti_max = MAX( zdti_max, ABS( t_i_1d(ji,jk) - ztib(ji,jk) ) ) 629 629 END DO 630 630 631 631 ! convergence test 632 632 IF( ln_zdf_chkcvg ) THEN … … 665 665 zdiagbis(1:npti,:) = 0._wp 666 666 667 DO jm = nlay_s + 2, nlay_s + nlay_i 667 DO jm = nlay_s + 2, nlay_s + nlay_i 668 668 DO ji = 1, npti 669 669 jk = jm - nlay_s - 1 … … 678 678 DO ji = 1, npti 679 679 ! ice bottom term 680 ztrid (ji,jm,1) = - zeta_i(ji,nlay_i) * zkappa_i(ji,nlay_i-1) 680 ztrid (ji,jm,1) = - zeta_i(ji,nlay_i) * zkappa_i(ji,nlay_i-1) 681 681 ztrid (ji,jm,2) = 1._wp + zeta_i(ji,nlay_i) * ( zkappa_i(ji,nlay_i-1) + zkappa_i(ji,nlay_i) * zg1 ) 682 682 ztrid (ji,jm,3) = 0._wp 683 683 zindterm(ji,jm) = ztiold(ji,nlay_i) + zeta_i(ji,nlay_i) * & 684 & ( zradab_i(ji,nlay_i) + zkappa_i(ji,nlay_i) * zg1 * t_bo_1d(ji) ) 684 & ( zradab_i(ji,nlay_i) + zkappa_i(ji,nlay_i) * zg1 * t_bo_1d(ji) ) 685 685 ENDDO 686 686 … … 697 697 zindterm(ji,jm) = ztsold(ji,jk) + zeta_s(ji,jk) * zradab_s(ji,jk) 698 698 END DO 699 699 700 700 ! case of only one layer in the ice (ice equation is altered) 701 701 IF ( nlay_i == 1 ) THEN 702 702 ztrid (ji,nlay_s+2,3) = 0._wp 703 zindterm(ji,nlay_s+2) = zindterm(ji,nlay_s+2) + zeta_i(ji,1) * zkappa_i(ji,1) * t_bo_1d(ji) 704 ENDIF 705 703 zindterm(ji,nlay_s+2) = zindterm(ji,nlay_s+2) + zeta_i(ji,1) * zkappa_i(ji,1) * t_bo_1d(ji) 704 ENDIF 705 706 706 jm_min(ji) = 2 707 707 jm_max(ji) = nlay_i + nlay_s + 1 708 708 709 709 ! first layer of snow equation 710 710 ztrid (ji,2,1) = 0._wp 711 711 ztrid (ji,2,2) = 1._wp + zeta_s(ji,1) * zkappa_s(ji,1) 712 ztrid (ji,2,3) = - zeta_s(ji,1) * zkappa_s(ji,1) 713 zindterm(ji,2) = ztsold(ji,1) + zeta_s(ji,1) * ( zradab_s(ji,1) + qcn_ice_1d(ji) ) 714 712 ztrid (ji,2,3) = - zeta_s(ji,1) * zkappa_s(ji,1) 713 zindterm(ji,2) = ztsold(ji,1) + zeta_s(ji,1) * ( zradab_s(ji,1) + qcn_ice_1d(ji) ) 714 715 715 ! !---------------------! 716 716 ELSE ! cells without snow ! … … 718 718 jm_min(ji) = nlay_s + 2 719 719 jm_max(ji) = nlay_i + nlay_s + 1 720 720 721 721 ! first layer of ice equation 722 722 ztrid (ji,jm_min(ji),1) = 0._wp 723 ztrid (ji,jm_min(ji),2) = 1._wp + zeta_i(ji,1) * zkappa_i(ji,1) 723 ztrid (ji,jm_min(ji),2) = 1._wp + zeta_i(ji,1) * zkappa_i(ji,1) 724 724 ztrid (ji,jm_min(ji),3) = - zeta_i(ji,1) * zkappa_i(ji,1) 725 725 zindterm(ji,jm_min(ji)) = ztiold(ji,1) + zeta_i(ji,1) * ( zradab_i(ji,1) + qcn_ice_1d(ji) ) 726 726 727 727 ! case of only one layer in the ice (surface & ice equations are altered) 728 728 IF( nlay_i == 1 ) THEN … … 733 733 & ( zradab_i(ji,1) + zkappa_i(ji,1) * t_bo_1d(ji) + qcn_ice_1d(ji) ) 734 734 ENDIF 735 735 736 736 ENDIF 737 737 ! … … 752 752 !!$ jm_maxt = MAX(jm_max(ji),jm_maxt) 753 753 !!$ END DO 754 !!$ 754 !!$ 755 755 !!$ DO jk = jm_mint+1, jm_maxt 756 756 !!$ DO ji = 1, npti … … 786 786 END DO 787 787 END DO 788 789 ! snow temperatures 788 789 ! snow temperatures 790 790 DO ji = 1, npti 791 791 ! Variables used after iterations … … 823 823 824 824 DO jk = 1, nlay_i 825 ztmelts = -rTmlt * sz_i_1d(ji,jk) + rt0 825 ztmelts = -rTmlt * sz_i_1d(ji,jk) + rt0 826 826 t_i_1d(ji,jk) = MAX( MIN( t_i_1d(ji,jk), ztmelts ), rt0 - 100._wp ) 827 827 zdti_max = MAX ( zdti_max, ABS( t_i_1d(ji,jk) - ztib(ji,jk) ) ) … … 885 885 ! 886 886 DO ji = 1, npti 887 hfx_err_dif_1d(ji) = hfx_err_dif_1d(ji) - ( qns_ice_1d(ji) - zqns_ice_b(ji) ) * a_i_1d(ji) 887 hfx_err_dif_1d(ji) = hfx_err_dif_1d(ji) - ( qns_ice_1d(ji) - zqns_ice_b(ji) ) * a_i_1d(ji) 888 888 END DO 889 889 ! … … 893 893 ! 894 894 IF( k_cnd == np_cnd_OFF .OR. k_cnd == np_cnd_ON ) THEN 895 896 CALL ice_var_enthalpy 897 895 896 CALL ice_var_enthalpy 897 898 898 ! zhfx_err = correction on the diagnosed heat flux due to non-convergence of the algorithm used to solve heat equation 899 899 DO ji = 1, npti 900 900 zdq = - zq_ini(ji) + ( SUM( e_i_1d(ji,1:nlay_i) ) * h_i_1d(ji) * r1_nlay_i + & 901 901 & SUM( e_s_1d(ji,1:nlay_s) ) * h_s_1d(ji) * r1_nlay_s ) 902 902 903 903 IF( k_cnd == np_cnd_OFF ) THEN 904 904 905 905 IF( t_su_1d(ji) < rt0 ) THEN ! case T_su < 0degC 906 906 zhfx_err = ( qns_ice_1d(ji) + qsr_ice_1d(ji) - zradtr_i(ji,nlay_i) - qcn_ice_bot_1d(ji) & … … 910 910 & + zdq * r1_Dt_ice ) * a_i_1d(ji) 911 911 ENDIF 912 912 913 913 ELSEIF( k_cnd == np_cnd_ON ) THEN 914 914 915 915 zhfx_err = ( qcn_ice_top_1d(ji) + qtr_ice_top_1d(ji) - zradtr_i(ji,nlay_i) - qcn_ice_bot_1d(ji) & 916 916 & + zdq * r1_Dt_ice ) * a_i_1d(ji) 917 917 918 918 ENDIF 919 919 ! … … 921 921 hfx_err_dif_1d(ji) = hfx_err_dif_1d(ji) + zhfx_err 922 922 ! 923 ! hfx_dif = Heat flux diagnostic of sensible heat used to warm/cool ice in W.m-2 923 ! hfx_dif = Heat flux diagnostic of sensible heat used to warm/cool ice in W.m-2 924 924 hfx_dif_1d(ji) = hfx_dif_1d(ji) - zdq * r1_Dt_ice * a_i_1d(ji) 925 925 ! … … 952 952 ! --- SIMIP diagnostics 953 953 ! 954 DO ji = 1, npti 954 DO ji = 1, npti 955 955 !--- Snow-ice interfacial temperature (diagnostic SIMIP) 956 956 IF( h_s_1d(ji) >= zhs_ssl ) THEN -
NEMO/trunk/src/ICE/iceupdate.F90
r14005 r14072 67 67 !!------------------------------------------------------------------- 68 68 !! *** ROUTINE ice_update_flx *** 69 !! 70 !! ** Purpose : Update the surface ocean boundary condition for heat 69 !! 70 !! ** Purpose : Update the surface ocean boundary condition for heat 71 71 !! salt and mass over areas where sea-ice is non-zero 72 !! 72 !! 73 73 !! ** Action : - computes the heat and freshwater/salt fluxes 74 74 !! at the ice-ocean interface. 75 75 !! - Update the ocean sbc 76 !! 77 !! ** Outputs : - qsr : sea heat flux: solar 76 !! 77 !! ** Outputs : - qsr : sea heat flux: solar 78 78 !! - qns : sea heat flux: non solar 79 !! - emp : freshwater budget: volume flux 80 !! - sfx : salt flux 79 !! - emp : freshwater budget: volume flux 80 !! - sfx : salt flux 81 81 !! - fr_i : ice fraction 82 82 !! - tn_ice : sea-ice surface temperature … … 104 104 ! Net heat flux on top of the ice-ocean (W.m-2) 105 105 !---------------------------------------------- 106 qt_atm_oi(:,:) = qns_tot(:,:) + qsr_tot(:,:) 106 qt_atm_oi(:,:) = qns_tot(:,:) + qsr_tot(:,:) 107 107 108 108 ! --- case we bypass ice thermodynamics --- ! … … 114 114 qevap_ice (:,:,:) = 0._wp 115 115 ENDIF 116 116 117 117 DO_2D( 1, 1, 1, 1 ) 118 118 119 ! Solar heat flux reaching the ocean (max) = zqsr (W.m-2) 119 ! Solar heat flux reaching the ocean (max) = zqsr (W.m-2) 120 120 !--------------------------------------------------- 121 121 zqsr = qsr_tot(ji,jj) - SUM( a_i_b(ji,jj,:) * ( qsr_ice(ji,jj,:) - qtr_ice_bot(ji,jj,:) ) ) 122 122 123 ! Total heat flux reaching the ocean = qt_oce_ai (W.m-2) 123 ! Total heat flux reaching the ocean = qt_oce_ai (W.m-2) 124 124 !--------------------------------------------------- 125 125 qt_oce_ai(ji,jj) = qt_atm_oi(ji,jj) - hfx_sum(ji,jj) - hfx_bom(ji,jj) - hfx_bog(ji,jj) & 126 126 & - hfx_dif(ji,jj) - hfx_opw(ji,jj) - hfx_snw(ji,jj) & 127 127 & + hfx_thd(ji,jj) + hfx_dyn(ji,jj) + hfx_res(ji,jj) & 128 & + hfx_sub(ji,jj) - SUM( qevap_ice(ji,jj,:) * a_i_b(ji,jj,:) ) + hfx_spr(ji,jj) 129 128 & + hfx_sub(ji,jj) - SUM( qevap_ice(ji,jj,:) * a_i_b(ji,jj,:) ) + hfx_spr(ji,jj) 129 130 130 ! New qsr and qns used to compute the oceanic heat flux at the next time step 131 131 !---------------------------------------------------------------------------- … … 144 144 ! 145 145 ! the non-solar is simply derived from the solar flux 146 qns(ji,jj) = qt_oce_ai(ji,jj) - zqsr 147 148 ! Mass flux at the atm. surface 146 qns(ji,jj) = qt_oce_ai(ji,jj) - zqsr 147 148 ! Mass flux at the atm. surface 149 149 !----------------------------------- 150 150 wfx_sub(ji,jj) = wfx_snw_sub(ji,jj) + wfx_ice_sub(ji,jj) 151 151 152 ! Mass flux at the ocean surface 152 ! Mass flux at the ocean surface 153 153 !------------------------------------ 154 154 ! ice-ocean mass flux 155 155 wfx_ice(ji,jj) = wfx_bog(ji,jj) + wfx_bom(ji,jj) + wfx_sum(ji,jj) + wfx_sni(ji,jj) & 156 156 & + wfx_opw(ji,jj) + wfx_dyn(ji,jj) + wfx_res(ji,jj) + wfx_lam(ji,jj) 157 157 158 158 ! snw-ocean mass flux 159 159 wfx_snw(ji,jj) = wfx_snw_sni(ji,jj) + wfx_snw_dyn(ji,jj) + wfx_snw_sum(ji,jj) 160 160 161 161 ! total mass flux at the ocean/ice interface 162 162 fmmflx(ji,jj) = - wfx_ice(ji,jj) - wfx_snw(ji,jj) - wfx_pnd(ji,jj) - wfx_err_sub(ji,jj) ! ice-ocean mass flux saved at least for biogeochemical model 163 163 emp (ji,jj) = emp_oce(ji,jj) - wfx_ice(ji,jj) - wfx_snw(ji,jj) - wfx_pnd(ji,jj) - wfx_err_sub(ji,jj) ! atm-ocean + ice-ocean mass flux 164 164 165 ! Salt flux at the ocean surface 165 ! Salt flux at the ocean surface 166 166 !------------------------------------------ 167 167 sfx(ji,jj) = sfx_bog(ji,jj) + sfx_bom(ji,jj) + sfx_sum(ji,jj) + sfx_sni(ji,jj) + sfx_opw(ji,jj) & 168 168 & + sfx_res(ji,jj) + sfx_dyn(ji,jj) + sfx_bri(ji,jj) + sfx_sub(ji,jj) + sfx_lam(ji,jj) 169 170 ! Mass of snow and ice per unit area 169 170 ! Mass of snow and ice per unit area 171 171 !---------------------------------------- 172 172 snwice_mass_b(ji,jj) = snwice_mass(ji,jj) ! save mass from the previous ice time step 173 173 ! ! new mass per unit area 174 snwice_mass (ji,jj) = tmask(ji,jj,1) * ( rhos * vt_s(ji,jj) + rhoi * vt_i(ji,jj) + rhow * (vt_ip(ji,jj) + vt_il(ji,jj)) ) 174 snwice_mass (ji,jj) = tmask(ji,jj,1) * ( rhos * vt_s(ji,jj) + rhoi * vt_i(ji,jj) + rhow * (vt_ip(ji,jj) + vt_il(ji,jj)) ) 175 175 ! ! time evolution of snow+ice mass 176 176 snwice_fmass (ji,jj) = ( snwice_mass(ji,jj) - snwice_mass_b(ji,jj) ) * r1_Dt_ice 177 177 178 178 END_2D 179 179 180 180 ! Storing the transmitted variables 181 181 !---------------------------------- 182 fr_i (:,:) = at_i(:,:) ! Sea-ice fraction 183 tn_ice(:,:,:) = t_su(:,:,:) ! Ice surface temperature 182 fr_i (:,:) = at_i(:,:) ! Sea-ice fraction 183 tn_ice(:,:,:) = t_su(:,:,:) ! Ice surface temperature 184 184 185 185 ! Snow/ice albedo (only if sent to coupler, useless in forced mode) … … 216 216 CALL iom_put( 'vfxice' , wfx_ice ) ! mass flux from total ice growth/melt 217 217 CALL iom_put( 'vfxbog' , wfx_bog ) ! mass flux from bottom growth 218 CALL iom_put( 'vfxbom' , wfx_bom ) ! mass flux from bottom melt 219 CALL iom_put( 'vfxsum' , wfx_sum ) ! mass flux from surface melt 220 CALL iom_put( 'vfxlam' , wfx_lam ) ! mass flux from lateral melt 218 CALL iom_put( 'vfxbom' , wfx_bom ) ! mass flux from bottom melt 219 CALL iom_put( 'vfxsum' , wfx_sum ) ! mass flux from surface melt 220 CALL iom_put( 'vfxlam' , wfx_lam ) ! mass flux from lateral melt 221 221 CALL iom_put( 'vfxsni' , wfx_sni ) ! mass flux from snow-ice formation 222 222 CALL iom_put( 'vfxopw' , wfx_opw ) ! mass flux from growth in open water 223 223 CALL iom_put( 'vfxdyn' , wfx_dyn ) ! mass flux from dynamics (ridging) 224 CALL iom_put( 'vfxres' , wfx_res ) ! mass flux from undiagnosed processes 224 CALL iom_put( 'vfxres' , wfx_res ) ! mass flux from undiagnosed processes 225 225 CALL iom_put( 'vfxpnd' , wfx_pnd ) ! mass flux from melt ponds 226 226 CALL iom_put( 'vfxsub' , wfx_ice_sub ) ! mass flux from ice sublimation (ice-atm.) 227 CALL iom_put( 'vfxsub_err', wfx_err_sub ) ! "excess" of sublimation sent to ocean 228 229 IF ( iom_use( 'vfxthin' ) ) THEN ! mass flux from ice growth in open water + thin ice (<20cm) => comparable to observations 227 CALL iom_put( 'vfxsub_err', wfx_err_sub ) ! "excess" of sublimation sent to ocean 228 229 IF ( iom_use( 'vfxthin' ) ) THEN ! mass flux from ice growth in open water + thin ice (<20cm) => comparable to observations 230 230 WHERE( hm_i(:,:) < 0.2 .AND. hm_i(:,:) > 0. ) ; z2d = wfx_bog 231 231 ELSEWHERE ; z2d = 0._wp … … 237 237 CALL iom_put( 'vfxsnw' , wfx_snw ) ! mass flux from total snow growth/melt 238 238 CALL iom_put( 'vfxsnw_sum' , wfx_snw_sum ) ! mass flux from snow melt at the surface 239 CALL iom_put( 'vfxsnw_sni' , wfx_snw_sni ) ! mass flux from snow melt during snow-ice formation 240 CALL iom_put( 'vfxsnw_dyn' , wfx_snw_dyn ) ! mass flux from dynamics (ridging) 241 CALL iom_put( 'vfxsnw_sub' , wfx_snw_sub ) ! mass flux from snow sublimation (ice-atm.) 239 CALL iom_put( 'vfxsnw_sni' , wfx_snw_sni ) ! mass flux from snow melt during snow-ice formation 240 CALL iom_put( 'vfxsnw_dyn' , wfx_snw_dyn ) ! mass flux from dynamics (ridging) 241 CALL iom_put( 'vfxsnw_sub' , wfx_snw_sub ) ! mass flux from snow sublimation (ice-atm.) 242 242 CALL iom_put( 'vfxsnw_pre' , wfx_spr ) ! snow precip 243 243 … … 252 252 IF( iom_use('qt_oce' ) ) CALL iom_put( 'qt_oce' , ( qsr_oce + qns_oce ) * ( 1._wp - at_i_b ) + qemp_oce ) 253 253 IF( iom_use('qt_ice' ) ) CALL iom_put( 'qt_ice' , SUM( ( qns_ice + qsr_ice ) * a_i_b, dim=3 ) + qemp_ice ) 254 IF( iom_use('qt_oce_ai' ) ) CALL iom_put( 'qt_oce_ai' , qt_oce_ai * tmask(:,:,1) ) ! total heat flux at the ocean surface: interface oce-(ice+atm) 255 IF( iom_use('qt_atm_oi' ) ) CALL iom_put( 'qt_atm_oi' , qt_atm_oi * tmask(:,:,1) ) ! total heat flux at the oce-ice surface: interface atm-(ice+oce) 254 IF( iom_use('qt_oce_ai' ) ) CALL iom_put( 'qt_oce_ai' , qt_oce_ai * tmask(:,:,1) ) ! total heat flux at the ocean surface: interface oce-(ice+atm) 255 IF( iom_use('qt_atm_oi' ) ) CALL iom_put( 'qt_atm_oi' , qt_atm_oi * tmask(:,:,1) ) ! total heat flux at the oce-ice surface: interface atm-(ice+oce) 256 256 IF( iom_use('qemp_oce' ) ) CALL iom_put( 'qemp_oce' , qemp_oce ) ! Downward Heat Flux from E-P over ocean 257 257 IF( iom_use('qemp_ice' ) ) CALL iom_put( 'qemp_ice' , qemp_ice ) ! Downward Heat Flux from E-P over ice … … 259 259 ! heat fluxes from ice transformations 260 260 ! ! hfxdhc = hfxbog + hfxbom + hfxsum + hfxopw + hfxdif + hfxsnw - ( hfxthd + hfxdyn + hfxres + hfxsub + hfxspr ) 261 CALL iom_put ('hfxbog' , hfx_bog ) ! heat flux used for ice bottom growth 261 CALL iom_put ('hfxbog' , hfx_bog ) ! heat flux used for ice bottom growth 262 262 CALL iom_put ('hfxbom' , hfx_bom ) ! heat flux used for ice bottom melt 263 263 CALL iom_put ('hfxsum' , hfx_sum ) ! heat flux used for ice surface melt 264 264 CALL iom_put ('hfxopw' , hfx_opw ) ! heat flux used for ice formation in open water 265 265 CALL iom_put ('hfxdif' , hfx_dif ) ! heat flux used for ice temperature change 266 CALL iom_put ('hfxsnw' , hfx_snw ) ! heat flux used for snow melt 266 CALL iom_put ('hfxsnw' , hfx_snw ) ! heat flux used for snow melt 267 267 CALL iom_put ('hfxerr' , hfx_err_dif ) ! heat flux error after heat diffusion 268 268 269 269 ! heat fluxes associated with mass exchange (freeze/melt/precip...) 270 CALL iom_put ('hfxthd' , hfx_thd ) ! 271 CALL iom_put ('hfxdyn' , hfx_dyn ) ! 272 CALL iom_put ('hfxres' , hfx_res ) ! 273 CALL iom_put ('hfxsub' , hfx_sub ) ! 274 CALL iom_put ('hfxspr' , hfx_spr ) ! Heat flux from snow precip heat content 270 CALL iom_put ('hfxthd' , hfx_thd ) ! 271 CALL iom_put ('hfxdyn' , hfx_dyn ) ! 272 CALL iom_put ('hfxres' , hfx_res ) ! 273 CALL iom_put ('hfxsub' , hfx_sub ) ! 274 CALL iom_put ('hfxspr' , hfx_spr ) ! Heat flux from snow precip heat content 275 275 276 276 ! other heat fluxes … … 294 294 !!------------------------------------------------------------------- 295 295 !! *** ROUTINE ice_update_tau *** 296 !! 296 !! 297 297 !! ** Purpose : Update the ocean surface stresses due to the ice 298 !! 298 !! 299 299 !! ** Action : * at each ice time step (every nn_fsbc time step): 300 !! - compute the modulus of ice-ocean relative velocity 300 !! - compute the modulus of ice-ocean relative velocity 301 301 !! (*rho*Cd) at T-point (C-grid) or I-point (B-grid) 302 302 !! tmod_io = rhoco * | U_ice-U_oce | 303 303 !! - update the modulus of stress at ocean surface 304 304 !! taum = (1-a) * taum + a * tmod_io * | U_ice-U_oce | 305 !! * at each ocean time step (every kt): 305 !! * at each ocean time step (every kt): 306 306 !! compute linearized ice-ocean stresses as 307 307 !! Utau = tmod_io * | U_ice - pU_oce | … … 310 310 !! NB: - ice-ocean rotation angle no more allowed 311 311 !! - here we make an approximation: taum is only computed every ice time step 312 !! This avoids mutiple average to pass from T -> U,V grids and next from U,V grids 312 !! This avoids mutiple average to pass from T -> U,V grids and next from U,V grids 313 313 !! to T grid. taum is used in TKE and GLS, which should not be too sensitive to this approximaton... 314 314 !! … … 337 337 DO_2D( 0, 0, 0, 0 ) !* update the modulus of stress at ocean surface (T-point) 338 338 ! ! 2*(U_ice-U_oce) at T-point 339 zu_t = u_ice(ji,jj) + u_ice(ji-1,jj) - u_oce(ji,jj) - u_oce(ji-1,jj) 340 zv_t = v_ice(ji,jj) + v_ice(ji,jj-1) - v_oce(ji,jj) - v_oce(ji,jj-1) 339 zu_t = u_ice(ji,jj) + u_ice(ji-1,jj) - u_oce(ji,jj) - u_oce(ji-1,jj) 340 zv_t = v_ice(ji,jj) + v_ice(ji,jj-1) - v_oce(ji,jj) - v_oce(ji,jj-1) 341 341 ! ! |U_ice-U_oce|^2 342 342 zmodt = 0.25_wp * ( zu_t * zu_t + zv_t * zv_t ) … … 354 354 ! !== every ocean time-step ==! 355 355 IF ( ln_drgice_imp ) THEN 356 ! Save drag with right sign to update top drag in the ocean implicit friction 357 rCdU_ice(:,:) = -r1_rho0 * tmod_io(:,:) * at_i(:,:) * tmask(:,:,1) 356 ! Save drag with right sign to update top drag in the ocean implicit friction 357 rCdU_ice(:,:) = -r1_rho0 * tmod_io(:,:) * at_i(:,:) * tmask(:,:,1) 358 358 zflagi = 0._wp 359 359 ELSE … … 362 362 ! 363 363 DO_2D( 0, 0, 0, 0 ) !* update the stress WITHOUT an ice-ocean rotation angle 364 ! ice area at u and v-points 364 ! ice area at u and v-points 365 365 zat_u = ( at_i(ji,jj) * tmask(ji,jj,1) + at_i (ji+1,jj ) * tmask(ji+1,jj ,1) ) & 366 366 & / MAX( 1.0_wp , tmask(ji,jj,1) + tmask(ji+1,jj ,1) ) … … 377 377 ! 378 378 IF( ln_timing ) CALL timing_stop('ice_update') 379 ! 379 ! 380 380 END SUBROUTINE ice_update_tau 381 381 … … 384 384 !!------------------------------------------------------------------- 385 385 !! *** ROUTINE ice_update_init *** 386 !! 386 !! 387 387 !! ** Purpose : allocate ice-ocean stress fields and read restarts 388 388 !! containing the snow & ice mass … … 408 408 !!--------------------------------------------------------------------- 409 409 !! *** ROUTINE rhg_evp_rst *** 410 !! 410 !! 411 411 !! ** Purpose : Read or write RHG file in restart file 412 412 !! … … 456 456 !! Default option Dummy module NO SI3 sea-ice model 457 457 !!---------------------------------------------------------------------- 458 #endif 458 #endif 459 459 460 460 !!====================================================================== -
NEMO/trunk/src/ICE/icevar.F90
r14005 r14072 34 34 !! - st_i(jpi,jpj) 35 35 !! - et_s(jpi,jpj) total snow heat content 36 !! - et_i(jpi,jpj) total ice thermal content 36 !! - et_i(jpi,jpj) total ice thermal content 37 37 !! - sm_i(jpi,jpj) mean ice salinity 38 38 !! - tm_i(jpi,jpj) mean ice temperature … … 55 55 !!---------------------------------------------------------------------- 56 56 USE dom_oce ! ocean space and time domain 57 USE phycst ! physical constants (ocean directory) 57 USE phycst ! physical constants (ocean directory) 58 58 USE sbc_oce , ONLY : sss_m, ln_ice_embd, nn_fsbc 59 59 USE ice ! sea-ice: variables … … 67 67 PRIVATE 68 68 69 PUBLIC ice_var_agg 70 PUBLIC ice_var_glo2eqv 71 PUBLIC ice_var_eqv2glo 72 PUBLIC ice_var_salprof 73 PUBLIC ice_var_salprof1d 69 PUBLIC ice_var_agg 70 PUBLIC ice_var_glo2eqv 71 PUBLIC ice_var_eqv2glo 72 PUBLIC ice_var_salprof 73 PUBLIC ice_var_salprof1d 74 74 PUBLIC ice_var_zapsmall 75 75 PUBLIC ice_var_zapneg 76 76 PUBLIC ice_var_roundoff 77 PUBLIC ice_var_bv 78 PUBLIC ice_var_enthalpy 77 PUBLIC ice_var_bv 78 PUBLIC ice_var_enthalpy 79 79 PUBLIC ice_var_sshdyn 80 80 PUBLIC ice_var_itd … … 108 108 !! *** ROUTINE ice_var_agg *** 109 109 !! 110 !! ** Purpose : aggregates ice-thickness-category variables to 110 !! ** Purpose : aggregates ice-thickness-category variables to 111 111 !! all-ice variables, i.e. it turns VGLO into VAGG 112 112 !!------------------------------------------------------------------- … … 130 130 vt_il(:,:) = SUM( v_il(:,:,:), dim=3 ) 131 131 ! 132 ato_i(:,:) = 1._wp - at_i(:,:) ! open water fraction 132 ato_i(:,:) = 1._wp - at_i(:,:) ! open water fraction 133 133 ! 134 134 !!GS: tm_su always needed by ABL over sea-ice … … 155 155 hm_i(:,:) = vt_i(:,:) * z1_at_i(:,:) 156 156 hm_s(:,:) = vt_s(:,:) * z1_at_i(:,:) 157 ! 157 ! 158 158 ! ! mean temperature (K), salinity and age 159 159 tm_si(:,:) = SUM( t_si(:,:,:) * a_i(:,:,:) , dim=3 ) * z1_at_i(:,:) … … 182 182 WHERE( at_ip(:,:) > epsi20 ) ; hm_ip(:,:) = vt_ip(:,:) / at_ip(:,:) ; hm_il(:,:) = vt_il(:,:) / at_ip(:,:) 183 183 ELSEWHERE ; hm_ip(:,:) = 0._wp ; hm_il(:,:) = 0._wp 184 END WHERE 184 END WHERE 185 185 ! 186 186 DEALLOCATE( z1_vt_i , z1_vt_s ) … … 197 197 !! *** ROUTINE ice_var_glo2eqv *** 198 198 !! 199 !! ** Purpose : computes equivalent variables as function of 199 !! ** Purpose : computes equivalent variables as function of 200 200 !! global variables, i.e. it turns VGLO into VEQV 201 201 !!------------------------------------------------------------------- … … 210 210 !!------------------------------------------------------------------- 211 211 212 !!gm Question 2: It is possible to define existence of sea-ice in a common way between 212 !!gm Question 2: It is possible to define existence of sea-ice in a common way between 213 213 !! ice area and ice volume ? 214 214 !! the idea is to be able to define one for all at the begining of this routine … … 234 234 235 235 zhmax = hi_max(jpl) 236 z1_zhmax = 1._wp / hi_max(jpl) 236 z1_zhmax = 1._wp / hi_max(jpl) 237 237 WHERE( h_i(:,:,jpl) > zhmax ) ! bound h_i by hi_max (i.e. 99 m) with associated update of ice area 238 238 h_i (:,:,jpl) = zhmax 239 a_i (:,:,jpl) = v_i(:,:,jpl) * z1_zhmax 239 a_i (:,:,jpl) = v_i(:,:,jpl) * z1_zhmax 240 240 z1_a_i(:,:,jpl) = zhmax * z1_v_i(:,:,jpl) 241 241 END WHERE 242 242 ! !--- snow thickness 243 243 h_s(:,:,:) = v_s (:,:,:) * z1_a_i(:,:,:) 244 ! !--- ice age 244 ! !--- ice age 245 245 o_i(:,:,:) = oa_i(:,:,:) * z1_a_i(:,:,:) 246 ! !--- pond and lid thickness 246 ! !--- pond and lid thickness 247 247 h_ip(:,:,:) = v_ip(:,:,:) * z1_a_ip(:,:,:) 248 248 h_il(:,:,:) = v_il(:,:,:) * z1_a_ip(:,:,:) … … 258 258 a_ip_eff = MIN( a_ip_eff, 1._wp - za_s_fra ) ! make sure (a_ip_eff + a_s_fra) <= 1 259 259 ! 260 ! !--- salinity (with a minimum value imposed everywhere) 260 ! !--- salinity (with a minimum value imposed everywhere) 261 261 IF( nn_icesal == 2 ) THEN 262 262 WHERE( v_i(:,:,:) > epsi20 ) ; s_i(:,:,:) = MAX( rn_simin , MIN( rn_simax, sv_i(:,:,:) * z1_v_i(:,:,:) ) ) … … 272 272 DO jl = 1, jpl 273 273 DO_3D( 1, 1, 1, 1, 1, nlay_i ) 274 IF ( v_i(ji,jj,jl) > epsi20 ) THEN !--- icy area 274 IF ( v_i(ji,jj,jl) > epsi20 ) THEN !--- icy area 275 275 ! 276 276 ze_i = e_i (ji,jj,jk,jl) * z1_v_i(ji,jj,jl) * zlay_i ! Energy of melting e(S,T) [J.m-3] … … 300 300 END DO 301 301 ! 302 ! integrated values 302 ! integrated values 303 303 vt_i (:,:) = SUM( v_i , dim=3 ) 304 304 vt_s (:,:) = SUM( v_s , dim=3 ) … … 312 312 !! *** ROUTINE ice_var_eqv2glo *** 313 313 !! 314 !! ** Purpose : computes global variables as function of 314 !! ** Purpose : computes global variables as function of 315 315 !! equivalent variables, i.e. it turns VEQV into VGLO 316 316 !!------------------------------------------------------------------- … … 329 329 !! *** ROUTINE ice_var_salprof *** 330 330 !! 331 !! ** Purpose : computes salinity profile in function of bulk salinity 332 !! 333 !! ** Method : If bulk salinity greater than zsi1, 331 !! ** Purpose : computes salinity profile in function of bulk salinity 332 !! 333 !! ** Method : If bulk salinity greater than zsi1, 334 334 !! the profile is assumed to be constant (S_inf) 335 335 !! If bulk salinity lower than zsi0, … … 348 348 !!------------------------------------------------------------------- 349 349 350 !!gm Question: Remove the option 3 ? How many years since it last use ? 350 !!gm Question: Remove the option 3 ? How many years since it last use ? 351 351 352 352 SELECT CASE ( nn_icesal ) … … 369 369 END DO 370 370 END DO 371 ! ! Slope of the linear profile 371 ! ! Slope of the linear profile 372 372 WHERE( h_i(:,:,:) > epsi20 ) ; z_slope_s(:,:,:) = 2._wp * s_i(:,:,:) / h_i(:,:,:) 373 373 ELSEWHERE ; z_slope_s(:,:,:) = 0._wp … … 379 379 zalpha(ji,jj,jl) = MAX( 0._wp , MIN( ( zsi1 - s_i(ji,jj,jl) ) * z1_dS , 1._wp ) ) 380 380 ! ! force a constant profile when SSS too low (Baltic Sea) 381 IF( 2._wp * s_i(ji,jj,jl) >= sss_m(ji,jj) ) zalpha(ji,jj,jl) = 0._wp 381 IF( 2._wp * s_i(ji,jj,jl) >= sss_m(ji,jj) ) zalpha(ji,jj,jl) = 0._wp 382 382 END_2D 383 383 END DO … … 448 448 ALLOCATE( z_slope_s(jpij), zalpha(jpij) ) 449 449 ! 450 ! ! Slope of the linear profile 450 ! ! Slope of the linear profile 451 451 WHERE( h_i_1d(1:npti) > epsi20 ) ; z_slope_s(1:npti) = 2._wp * s_i_1d(1:npti) / h_i_1d(1:npti) 452 452 ELSEWHERE ; z_slope_s(1:npti) = 0._wp 453 453 END WHERE 454 454 455 455 z1_dS = 1._wp / ( zsi1 - zsi0 ) 456 456 DO ji = 1, npti … … 557 557 END_2D 558 558 ! 559 END DO 559 END DO 560 560 561 561 ! to be sure that at_i is the sum of a_i(jl) … … 648 648 END_2D 649 649 ! 650 END DO 650 END DO 651 651 ! 652 652 WHERE( pato_i(:,:) < 0._wp ) pato_i(:,:) = 0._wp … … 693 693 ! 694 694 END SUBROUTINE ice_var_roundoff 695 695 696 696 697 697 SUBROUTINE ice_var_bv … … 713 713 DO jl = 1, jpl 714 714 DO jk = 1, nlay_i 715 WHERE( t_i(:,:,jk,jl) < rt0 - epsi10 ) 715 WHERE( t_i(:,:,jk,jl) < rt0 - epsi10 ) 716 716 bv_i(:,:,jl) = bv_i(:,:,jl) - rTmlt * sz_i(:,:,jk,jl) * r1_nlay_i / ( t_i(:,:,jk,jl) - rt0 ) 717 717 END WHERE … … 727 727 SUBROUTINE ice_var_enthalpy 728 728 !!------------------------------------------------------------------- 729 !! *** ROUTINE ice_var_enthalpy *** 730 !! 729 !! *** ROUTINE ice_var_enthalpy *** 730 !! 731 731 !! ** Purpose : Computes sea ice energy of melting q_i (J.m-3) from temperature 732 732 !! … … 734 734 !!------------------------------------------------------------------- 735 735 INTEGER :: ji, jk ! dummy loop indices 736 REAL(wp) :: ztmelts ! local scalar 736 REAL(wp) :: ztmelts ! local scalar 737 737 !!------------------------------------------------------------------- 738 738 ! … … 741 741 ztmelts = - rTmlt * sz_i_1d(ji,jk) 742 742 t_i_1d(ji,jk) = MIN( t_i_1d(ji,jk), ztmelts + rt0 ) ! Force t_i_1d to be lower than melting point => likely conservation issue 743 ! (sometimes zdf scheme produces abnormally high temperatures) 743 ! (sometimes zdf scheme produces abnormally high temperatures) 744 744 e_i_1d(ji,jk) = rhoi * ( rcpi * ( ztmelts - ( t_i_1d(ji,jk) - rt0 ) ) & 745 745 & + rLfus * ( 1._wp - ztmelts / ( t_i_1d(ji,jk) - rt0 ) ) & … … 755 755 END SUBROUTINE ice_var_enthalpy 756 756 757 757 758 758 FUNCTION ice_var_sshdyn(pssh, psnwice_mass, psnwice_mass_b) 759 759 !!--------------------------------------------------------------------- 760 760 !! *** ROUTINE ice_var_sshdyn *** 761 !! 761 !! 762 762 !! ** Purpose : compute the equivalent ssh in lead when sea ice is embedded 763 763 !! … … 765 765 !! 766 766 !! ** Reference : Jean-Michel Campin, John Marshall, David Ferreira, 767 !! Sea ice-ocean coupling using a rescaled vertical coordinate z*, 767 !! Sea ice-ocean coupling using a rescaled vertical coordinate z*, 768 768 !! Ocean Modelling, Volume 24, Issues 1-2, 2008 769 769 !!---------------------------------------------------------------------- … … 783 783 ! compute ice load used to define the equivalent ssh in lead 784 784 IF( ln_ice_embd ) THEN 785 ! 785 ! 786 786 ! average interpolation coeff as used in dynspg = (1/nn_fsbc) * {SUM[n/nn_fsbc], n=0,nn_fsbc-1} 787 787 ! = (1/nn_fsbc)^2 * {SUM[n] , n=0,nn_fsbc-1} … … 802 802 END FUNCTION ice_var_sshdyn 803 803 804 804 805 805 !!------------------------------------------------------------------- 806 806 !! *** INTERFACE ice_var_itd *** … … 831 831 ph_ip(:) = phtip(:) 832 832 ph_il(:) = phtil(:) 833 833 834 834 END SUBROUTINE ice_var_itd_1c1c 835 835 … … 846 846 REAL(wp), ALLOCATABLE, DIMENSION(:) :: z1_ai, z1_vi, z1_vs 847 847 ! 848 INTEGER :: idim 848 INTEGER :: idim 849 849 !!------------------------------------------------------------------- 850 850 ! … … 888 888 ! 889 889 END SUBROUTINE ice_var_itd_Nc1c 890 890 891 891 SUBROUTINE ice_var_itd_1cMc( phti, phts, pati , ph_i, ph_s, pa_i, & 892 892 & ptmi, ptms, ptmsu, psmi, patip, phtip, phtil, pt_i, pt_s, pt_su, ps_i, pa_ip, ph_ip, ph_il ) … … 898 898 !! ** Method: ice thickness distribution follows a gamma function from Abraham et al. (2015) 899 899 !! it has the property of conserving total concentration and volume 900 !! 900 !! 901 901 !! 902 902 !! ** Arguments : phti: 1-cat ice thickness … … 904 904 !! pati: 1-cat ice concentration 905 905 !! 906 !! ** Output : jpl-cat 906 !! ** Output : jpl-cat 907 907 !! 908 908 !! Abraham, C., Steiner, N., Monahan, A. and Michel, C., 2015. 909 909 !! Effects of subgrid‐scale snow thickness variability on radiative transfer in sea ice. 910 !! Journal of Geophysical Research: Oceans, 120(8), pp.5597-5614 910 !! Journal of Geophysical Research: Oceans, 120(8), pp.5597-5614 911 911 !!------------------------------------------------------------------- 912 912 REAL(wp), DIMENSION(:), INTENT(in) :: phti, phts, pati ! input ice/snow variables … … 987 987 ! In case snow load is in excess that would lead to transformation from snow to ice 988 988 ! Then, transfer the snow excess into the ice (different from icethd_dh) 989 zdh = MAX( 0._wp, ( rhos * ph_s(ji,jl) + ( rhoi - rho0 ) * ph_i(ji,jl) ) * r1_rho0 ) 989 zdh = MAX( 0._wp, ( rhos * ph_s(ji,jl) + ( rhoi - rho0 ) * ph_i(ji,jl) ) * r1_rho0 ) 990 990 ! recompute h_i, h_s avoiding out of bounds values 991 991 ph_i(ji,jl) = MIN( hi_max(jl), ph_i(ji,jl) + zdh ) … … 1047 1047 !! 1048 1048 !! ** Method: Iterative procedure 1049 !! 1049 !! 1050 1050 !! 1) Fill ice cat that correspond to input thicknesses 1051 1051 !! Find the lowest(jlmin) and highest(jlmax) cat that are filled 1052 1052 !! 1053 1053 !! 2) Expand the filling to the cat jlmin-1 and jlmax+1 1054 !! by removing 25% ice area from jlmin and jlmax (resp.) 1055 !! 1056 !! 3) Expand the filling to the empty cat between jlmin and jlmax 1054 !! by removing 25% ice area from jlmin and jlmax (resp.) 1055 !! 1056 !! 3) Expand the filling to the empty cat between jlmin and jlmax 1057 1057 !! by a) removing 25% ice area from the lower cat (ascendant loop jlmin=>jlmax) 1058 1058 !! b) removing 25% ice area from the higher cat (descendant loop jlmax=>jlmin) … … 1062 1062 !! pati: N-cat ice concentration 1063 1063 !! 1064 !! ** Output : jpl-cat 1065 !! 1066 !! (Example of application: BDY forcings when inputs have N-cat /= jpl) 1064 !! ** Output : jpl-cat 1065 !! 1066 !! (Example of application: BDY forcings when inputs have N-cat /= jpl) 1067 1067 !!------------------------------------------------------------------- 1068 1068 REAL(wp), DIMENSION(:,:), INTENT(in) :: phti, phts, pati ! input ice/snow variables … … 1077 1077 REAL(wp), PARAMETER :: ztrans = 0.25_wp 1078 1078 INTEGER :: ji, jl, jl1, jl2 1079 INTEGER :: idim, icat 1079 INTEGER :: idim, icat 1080 1080 !!------------------------------------------------------------------- 1081 1081 ! … … 1116 1116 ELSE ! input cat /= output cat ! 1117 1117 ! ! ----------------------- ! 1118 1118 1119 1119 ALLOCATE( jlfil(idim,jpl), jlfil2(idim,jpl) ) ! allocate arrays 1120 1120 ALLOCATE( jlmin(idim), jlmax(idim) ) … … 1126 1126 ! 1127 1127 ! --- fill the categories --- ! 1128 ! find where cat-input = cat-output and fill cat-output fields 1128 ! find where cat-input = cat-output and fill cat-output fields 1129 1129 jlmax(:) = 0 1130 1130 jlmin(:) = 999 … … 1147 1147 END DO 1148 1148 ! 1149 ! --- fill the gaps between categories --- ! 1149 ! --- fill the gaps between categories --- ! 1150 1150 ! transfer from categories filled at the previous step to the empty ones in between 1151 1151 DO ji = 1, idim … … 1168 1168 END DO 1169 1169 ! 1170 jlfil2(:,:) = jlfil(:,:) 1170 jlfil2(:,:) = jlfil(:,:) 1171 1171 ! fill categories from low to high 1172 1172 DO jl = 2, jpl-1 … … 1189 1189 ! fill low 1190 1190 pa_i(ji,jl) = pa_i(ji,jl) + ztrans * pa_i(ji,jl+1) 1191 ph_i(ji,jl) = hi_mean(jl) 1191 ph_i(ji,jl) = hi_mean(jl) 1192 1192 jlfil2(ji,jl) = jl 1193 1193 ! remove high … … 1279 1279 !! we argue that snow does not cover the whole ice because 1280 1280 !! of wind blowing... 1281 !! 1281 !! 1282 1282 !! ** Arguments : ph_s: snow thickness 1283 !! 1283 !! 1284 1284 !! ** Output : pa_s_fra: fraction of ice covered by snow 1285 1285 !! … … 1326 1326 ENDIF 1327 1327 END SUBROUTINE ice_var_snwfra_1d 1328 1328 1329 1329 !!-------------------------------------------------------------------------- 1330 1330 !! INTERFACE ice_var_snwblow … … 1336 1336 !! If snow fall was uniform, a fraction (1-at_i) would fall into leads 1337 1337 !! but because of the winds, more snow falls on leads than on sea ice 1338 !! and a greater fraction (1-at_i)^beta of the total mass of snow 1338 !! and a greater fraction (1-at_i)^beta of the total mass of snow 1339 1339 !! (beta < 1) falls in leads. 1340 !! In reality, beta depends on wind speed, 1341 !! and should decrease with increasing wind speed but here, it is 1340 !! In reality, beta depends on wind speed, 1341 !! and should decrease with increasing wind speed but here, it is 1342 1342 !! considered as a constant. an average value is 0.66 1343 1343 !!-------------------------------------------------------------------------- -
NEMO/trunk/src/ICE/icewri.F90
r14005 r14072 10 10 !! 'key_si3' SI3 sea-ice model 11 11 !!---------------------------------------------------------------------- 12 !! ice_wri : write of the diagnostics variables in ouput file 12 !! ice_wri : write of the diagnostics variables in ouput file 13 13 !! ice_wri_state : write for initial state or/and abandon 14 14 !!---------------------------------------------------------------------- … … 33 33 34 34 PUBLIC ice_wri ! called by ice_stp 35 PUBLIC ice_wri_state ! called by dia_wri_state 35 PUBLIC ice_wri_state ! called by dia_wri_state 36 36 37 37 !! * Substitutions … … 52 52 INTEGER :: ji, jj, jk, jl ! dummy loop indices 53 53 REAL(wp) :: z2da, z2db, zrho1, zrho2 54 REAL(wp) :: zmiss_val ! missing value retrieved from xios 54 REAL(wp) :: zmiss_val ! missing value retrieved from xios 55 55 REAL(wp), DIMENSION(jpi,jpj) :: z2d, zfast ! 2D workspace 56 56 REAL(wp), DIMENSION(jpi,jpj) :: zmsk00, zmsk05, zmsk15, zmsksn ! O%, 5% and 15% concentration mask and snow mask … … 59 59 ! Global ice diagnostics (SIMIP) 60 60 REAL(wp) :: zdiag_area_nh, zdiag_extt_nh, zdiag_volu_nh ! area, extent, volume 61 REAL(wp) :: zdiag_area_sh, zdiag_extt_sh, zdiag_volu_sh 61 REAL(wp) :: zdiag_area_sh, zdiag_extt_sh, zdiag_volu_sh 62 62 !!------------------------------------------------------------------- 63 63 ! … … 92 92 CALL iom_put( 'icemask05', zmsk05 ) ! ice mask 5% 93 93 CALL iom_put( 'icemask15', zmsk15 ) ! ice mask 15% 94 CALL iom_put( 'icepres' , zmsk00 ) ! Ice presence (1 or 0) 94 CALL iom_put( 'icepres' , zmsk00 ) ! Ice presence (1 or 0) 95 95 ! 96 96 ! general fields 97 IF( iom_use('icemass' ) ) CALL iom_put( 'icemass', vt_i * rhoi * zmsk00 ) ! Ice mass per cell area 97 IF( iom_use('icemass' ) ) CALL iom_put( 'icemass', vt_i * rhoi * zmsk00 ) ! Ice mass per cell area 98 98 IF( iom_use('snwmass' ) ) CALL iom_put( 'snwmass', vt_s * rhos * zmsksn ) ! Snow mass per cell area 99 99 IF( iom_use('iceconc' ) ) CALL iom_put( 'iceconc', at_i * zmsk00 ) ! ice concentration … … 106 106 IF( iom_use('snwvolu' ) ) CALL iom_put( 'snwvolu', vt_s * zmsksn ) ! snow volume 107 107 IF( iom_use('icefrb' ) ) THEN ! Ice freeboard 108 z2d(:,:) = ( zrho1 * hm_i(:,:) - zrho2 * hm_s(:,:) ) 108 z2d(:,:) = ( zrho1 * hm_i(:,:) - zrho2 * hm_s(:,:) ) 109 109 WHERE( z2d < 0._wp ) z2d = 0._wp 110 110 CALL iom_put( 'icefrb' , z2d * zmsk00 ) … … 186 186 IF( iom_use('dmsmel') ) CALL iom_put( 'dmsmel', - wfx_snw_sum ) ! Snow mass change through melt 187 187 IF( iom_use('dmsdyn') ) CALL iom_put( 'dmsdyn', - wfx_snw_dyn + rhos * diag_trp_vs ) ! Snow mass change through dynamics(kg/m2/s) 188 188 189 189 ! Global ice diagnostics 190 190 IF( iom_use('NH_icearea') .OR. iom_use('NH_icevolu') .OR. iom_use('NH_iceextt') .OR. & … … 221 221 END SUBROUTINE ice_wri 222 222 223 223 224 224 SUBROUTINE ice_wri_state( kid ) 225 225 !!--------------------------------------------------------------------- 226 226 !! *** ROUTINE ice_wri_state *** 227 !! 228 !! ** Purpose : create a NetCDF file named cdfile_name which contains 227 !! 228 !! ** Purpose : create a NetCDF file named cdfile_name which contains 229 229 !! the instantaneous ice state and forcing fields for ice model 230 230 !! Used to find errors in the initial state or save the last … … 233 233 !! History : 4.0 ! 2013-06 (C. Rousset) 234 234 !!---------------------------------------------------------------------- 235 INTEGER, INTENT( in ) :: kid 235 INTEGER, INTENT( in ) :: kid 236 236 !!---------------------------------------------------------------------- 237 237 !
Note: See TracChangeset
for help on using the changeset viewer.