- Timestamp:
- 2021-11-28T18:59:49+01:00 (3 years ago)
- Location:
- NEMO/branches/2021/ticket2632_r14588_theta_sbcblk
- Files:
-
- 26 edited
Legend:
- Unmodified
- Added
- Removed
-
NEMO/branches/2021/ticket2632_r14588_theta_sbcblk
- Property svn:externals
-
old new 9 9 10 10 # SETTE 11 ^/utils/CI/sette@14244 sette 11 ^/utils/CI/sette@HEAD sette 12
-
- Property svn:externals
-
NEMO/branches/2021/ticket2632_r14588_theta_sbcblk/src/ICE/ice.F90
r14103 r15548 147 147 ! 148 148 ! !!** ice-ridging/rafting namelist (namdyn_rdgrft) ** 149 LOGICAL, PUBLIC :: ln_str_H79 !: ice strength parameterization (Hibler79) (may be used in rheology) 149 150 REAL(wp), PUBLIC :: rn_crhg !: determines changes in ice strength (also used for landfast param) 151 REAL(wp), PUBLIC :: rn_pstar !: determines ice strength, Hibler JPO79 (may be used in rheology) 150 152 ! 151 153 ! !!** ice-rheology namelist (namdyn_rhg) ** … … 194 196 ! ! = 0 Grenfell and Maykut 1977 (depends on cloudiness and is 0 when there is snow) 195 197 ! ! = 1 Lebrun 2019 (equals 0.3 anytime with different melting/dry snw conductivities) 198 199 ! !!** namelist (namthd) ** 200 LOGICAL , PUBLIC :: ln_icedH ! activate ice thickness change from growing/melting (T) or not (F) 201 LOGICAL , PUBLIC :: ln_icedA ! activate lateral melting param. (T) or not (F) 202 LOGICAL , PUBLIC :: ln_icedO ! activate ice growth in open-water (T) or not (F) 203 LOGICAL , PUBLIC :: ln_icedS ! activate gravity drainage and flushing (T) or not (F) 204 LOGICAL , PUBLIC :: ln_leadhfx ! heat in the leads is used to melt sea-ice before warming the ocean 205 ! 206 ! !!** namelist (namthd_do) ** 207 REAL(wp), PUBLIC :: rn_hinew ! thickness for new ice formation (m) 208 LOGICAL , PUBLIC :: ln_frazil ! use of frazil ice collection as function of wind (T) or not (F) 209 REAL(wp), PUBLIC :: rn_maxfraz ! maximum portion of frazil ice collecting at the ice bottom 210 REAL(wp), PUBLIC :: rn_vfraz ! threshold drift speed for collection of bottom frazil ice 211 REAL(wp), PUBLIC :: rn_Cfraz ! squeezing coefficient for collection of bottom frazil ice 196 212 ! 197 213 ! !!** ice-vertical diffusion namelist (namthd_zdf) ** … … 251 267 REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) :: u_oce,v_oce !: surface ocean velocity used in ice dynamics 252 268 REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) :: ht_i_new !: ice collection thickness accreted in leads 269 REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) :: fraz_frac !: fraction of frazil ice accreted at the ice bottom 253 270 REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) :: strength !: ice strength 254 271 REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) :: stress1_i, stress2_i, stress12_i !: 1st, 2nd & diagonal stress tensor element … … 453 470 454 471 ii = 1 455 ALLOCATE( u_oce (jpi,jpj) , v_oce (jpi,jpj) , ht_i_new (jpi,jpj) , strength(jpi,jpj) , &456 & stre ss1_i(jpi,jpj) , stress2_i(jpi,jpj) , stress12_i(jpi,jpj) ,&457 & delta_i (jpi,jpj) , divu_i (jpi,jpj) , shear_i (jpi,jpj) ,&458 & aniso_11 (jpi,jpj) , aniso_12 (jpi,jpj) , rdg_conv 472 ALLOCATE( u_oce (jpi,jpj) , v_oce (jpi,jpj) , ht_i_new (jpi,jpj) , fraz_frac (jpi,jpj) , & 473 & strength (jpi,jpj) , stress1_i(jpi,jpj) , stress2_i(jpi,jpj) , stress12_i(jpi,jpj) , & 474 & delta_i (jpi,jpj) , divu_i (jpi,jpj) , shear_i (jpi,jpj) , & 475 & aniso_11 (jpi,jpj) , aniso_12 (jpi,jpj) , rdg_conv (jpi,jpj) , STAT=ierr(ii) ) 459 476 460 477 ii = ii + 1 -
NEMO/branches/2021/ticket2632_r14588_theta_sbcblk/src/ICE/icealb.F90
r13472 r15548 30 30 PUBLIC ice_alb ! called in icesbc.F90 and iceupdate.F90 31 31 32 REAL(wp), PUBLIC, PARAMETER :: rn_alb_oce = 0.066 !: ocean or lead albedo (Pegau and Paulson, Ann. Glac. 2001)32 REAL(wp), PUBLIC, PARAMETER :: rn_alb_oce = 0.066_wp !: ocean or lead albedo (Pegau and Paulson, Ann. Glac. 2001) 33 33 ! 34 34 ! !!* albedo namelist (namalb) … … 111 111 REAL(wp) :: zalb_snw, zafrac_snw ! snow-covered sea ice albedo & relative snow fraction 112 112 REAL(wp) :: zalb_cs, zalb_os ! albedo of ice under clear/overcast sky 113 !! clem 114 REAL(wp), PARAMETER :: zhi_albcst = 1.5_wp ! pivotal thickness (should be in the namelist) 113 115 !!--------------------------------------------------------------------- 114 116 ! 115 117 IF( ln_timing ) CALL timing_start('icealb') 116 118 ! 117 z1_href_pnd = 1. / 0.05118 z1_c1 = 1. / ( LOG(1.5) - LOG(0.05) )119 z1_c2 = 1. / 0.05120 z1_c3 = 1. / 0.02121 z1_c4 = 1. / 0.03119 z1_href_pnd = 1._wp / 0.05_wp 120 z1_c1 = 1._wp / ( LOG(zhi_albcst) - LOG(0.05_wp) ) 121 z1_c2 = 1._wp / 0.05_wp 122 z1_c3 = 1._wp / 0.02_wp 123 z1_c4 = 1._wp / 0.03_wp 122 124 ! 123 125 CALL ice_var_snwfra( ph_snw, za_s_fra ) ! calculate ice fraction covered by snow 124 126 ! 125 127 DO jl = 1, jpl 126 DO_2D( 1, 1, 1, 1 )128 DO_2D( nn_hls, nn_hls, nn_hls, nn_hls ) ! palb_ice used over the full domain in icesbc 127 129 ! 128 130 !---------------------------------------------! … … 148 150 ENDIF 149 151 ! !--- Bare ice albedo (for hi < 150cm) 150 IF( 0.05 < ph_ice(ji,jj,jl) .AND. ph_ice(ji,jj,jl) <= 1.5) THEN ! 5cm < hi < 150cm151 zalb_ice = zalb_ice + ( 0.18 - zalb_ice ) * z1_c1 * ( LOG(1.5) - LOG(ph_ice(ji,jj,jl)) )152 ELSEIF( ph_ice(ji,jj,jl) <= 0.05 ) THEN ! 0cm < hi < 5cm153 zalb_ice = rn_alb_oce + ( 0.18 - rn_alb_oce ) * z1_c2 * ph_ice(ji,jj,jl)152 IF( 0.05 < ph_ice(ji,jj,jl) .AND. ph_ice(ji,jj,jl) <= zhi_albcst ) THEN ! 5cm < hi < 150cm 153 zalb_ice = zalb_ice + ( 0.18_wp - zalb_ice ) * z1_c1 * ( LOG(zhi_albcst) - LOG(ph_ice(ji,jj,jl)) ) 154 ELSEIF( ph_ice(ji,jj,jl) <= 0.05_wp ) THEN ! 0cm < hi < 5cm 155 zalb_ice = rn_alb_oce + ( 0.18_wp - rn_alb_oce ) * z1_c2 * ph_ice(ji,jj,jl) 154 156 ENDIF 155 157 ! … … 166 168 zalb_os = ( zafrac_snw * zalb_snw + zafrac_pnd * zalb_pnd + zafrac_ice * zalb_ice ) * tmask(ji,jj,1) 167 169 ! 168 zalb_cs = zalb_os - ( - 0.1010 * zalb_os * zalb_os &169 & + 0.1933 * zalb_os - 0.0148) * tmask(ji,jj,1)170 zalb_cs = zalb_os - ( - 0.1010_wp * zalb_os * zalb_os & 171 & + 0.1933_wp * zalb_os - 0.0148_wp ) * tmask(ji,jj,1) 170 172 ! 171 173 ! albedo depends on cloud fraction because of non-linear spectral effects -
NEMO/branches/2021/ticket2632_r14588_theta_sbcblk/src/ICE/icecor.F90
r14433 r15548 53 53 INTEGER, INTENT(in) :: kn ! 1 = after dyn ; 2 = after thermo 54 54 ! 55 INTEGER :: ji, jj, j k, jl! dummy loop indices55 INTEGER :: ji, jj, jl ! dummy loop indices 56 56 REAL(wp) :: zsal, zzc 57 57 !!---------------------------------------------------------------------- … … 91 91 zzc = rhoi * r1_Dt_ice 92 92 DO jl = 1, jpl 93 DO_2D( 1, 1, 1, 1)93 DO_2D( nn_hls, nn_hls, nn_hls, nn_hls ) 94 94 zsal = sv_i(ji,jj,jl) 95 95 sv_i(ji,jj,jl) = MIN( MAX( rn_simin*v_i(ji,jj,jl) , sv_i(ji,jj,jl) ) , rn_simax*v_i(ji,jj,jl) ) … … 99 99 END DO 100 100 ENDIF 101 101 ! 102 102 IF( kn /= 0 ) THEN ! no zapsmall if kn=0 (for bdy for instance) because we do not want ice-ocean exchanges (wfx,sfx,hfx) 103 103 ! otherwise conservation diags will fail … … 105 105 CALL ice_var_zapsmall ! Zap small values ! 106 106 ! !----------------------------------------------------- 107 ENDIF108 ! !-----------------------------------------------------109 IF( kn == 2 ) THEN ! Ice drift case: Corrections to avoid wrong values !110 DO_2D( 0, 0, 0, 0 ) !-----------------------------------------------------111 IF ( at_i(ji,jj) == 0._wp ) THEN ! what to do if there is no ice112 IF ( at_i(ji+1,jj) == 0._wp ) u_ice(ji ,jj) = 0._wp ! right side113 IF ( at_i(ji-1,jj) == 0._wp ) u_ice(ji-1,jj) = 0._wp ! left side114 IF ( at_i(ji,jj+1) == 0._wp ) v_ice(ji,jj ) = 0._wp ! upper side115 IF ( at_i(ji,jj-1) == 0._wp ) v_ice(ji,jj-1) = 0._wp ! bottom side116 ENDIF117 END_2D118 CALL lbc_lnk( 'icecor', u_ice, 'U', -1.0_wp, v_ice, 'V', -1.0_wp )119 107 ENDIF 120 108 ! -
NEMO/branches/2021/ticket2632_r14588_theta_sbcblk/src/ICE/icectl.F90
r14072 r15548 84 84 REAL(wp) , INTENT(inout) :: pdiag_v, pdiag_s, pdiag_t, pdiag_fv, pdiag_fs, pdiag_ft 85 85 !! 86 REAL(wp) :: zdiag_mass, zdiag_salt, zdiag_heat, & 87 & zdiag_vimin, zdiag_vsmin, zdiag_vpmin, zdiag_vlmin, zdiag_aimin, zdiag_aimax, & 88 & zdiag_eimin, zdiag_esmin, zdiag_simin 89 REAL(wp) :: zvtrp, zetrp 90 REAL(wp) :: zarea 91 !!------------------------------------------------------------------- 92 ! 86 REAL(wp) :: zdiag_mass, zdiag_salt, zdiag_heat 87 REAL(wp), DIMENSION(jpi,jpj,10) :: ztmp3 88 REAL(wp), DIMENSION(jpi,jpj,jpl,8) :: ztmp4 89 REAL(wp), DIMENSION(10) :: zchk3 90 REAL(wp), DIMENSION(8) :: zchk4 91 !!------------------------------------------------------------------- 92 ! 93 ! -- quantities -- ! 94 ztmp3(:,:,1) = SUM( v_i * rhoi + v_s * rhos + ( v_ip + v_il ) * rhow, dim=3 ) * e1e2t ! volume 95 ztmp3(:,:,2) = SUM( sv_i * rhoi, dim=3 ) * e1e2t ! salt 96 ztmp3(:,:,3) = ( SUM( SUM( e_i, dim=4 ), dim=3 ) + SUM( SUM( e_s, dim=4 ), dim=3 ) ) * e1e2t ! heat 97 ! 98 ! -- fluxes -- ! 99 ztmp3(:,:,4) = ( wfx_bog + wfx_bom + wfx_sum + wfx_sni + wfx_opw + wfx_res + wfx_dyn + wfx_lam + wfx_pnd & ! mass 100 & + wfx_snw_sni + wfx_snw_sum + wfx_snw_dyn + wfx_snw_sub + wfx_ice_sub + wfx_spr ) * e1e2t 101 ztmp3(:,:,5) = ( sfx_bri + sfx_bog + sfx_bom + sfx_sum + sfx_sni + sfx_opw & ! salt 102 & + sfx_res + sfx_dyn + sfx_sub + sfx_lam ) * e1e2t 103 ztmp3(:,:,6) = ( hfx_sum + hfx_bom + hfx_bog + hfx_dif + hfx_opw + hfx_snw & ! heat 104 & - hfx_thd - hfx_dyn - hfx_res - hfx_sub - hfx_spr ) * e1e2t 105 ! 106 ! -- global sum -- ! 107 zchk3(1:6) = glob_sum_vec( 'icectl', ztmp3(:,:,1:6) ) 108 93 109 IF( icount == 0 ) THEN 94 95 pdiag_v = glob_sum( 'icectl', SUM( v_i * rhoi + v_s * rhos + ( v_ip + v_il ) * rhow, dim=3 ) * e1e2t ) 96 pdiag_s = glob_sum( 'icectl', SUM( sv_i * rhoi , dim=3 ) * e1e2t ) 97 pdiag_t = glob_sum( 'icectl', ( SUM( SUM( e_i, dim=4 ), dim=3 ) + SUM( SUM( e_s, dim=4 ), dim=3 ) ) * e1e2t ) 98 99 ! mass flux 100 pdiag_fv = glob_sum( 'icectl', & 101 & ( wfx_bog + wfx_bom + wfx_sum + wfx_sni + wfx_opw + wfx_res + wfx_dyn + wfx_lam + wfx_pnd + & 102 & wfx_snw_sni + wfx_snw_sum + wfx_snw_dyn + wfx_snw_sub + wfx_ice_sub + wfx_spr ) * e1e2t ) 103 ! salt flux 104 pdiag_fs = glob_sum( 'icectl', & 105 & ( sfx_bri + sfx_bog + sfx_bom + sfx_sum + sfx_sni + & 106 & sfx_opw + sfx_res + sfx_dyn + sfx_sub + sfx_lam ) * e1e2t ) 107 ! heat flux 108 pdiag_ft = glob_sum( 'icectl', & 109 & ( hfx_sum + hfx_bom + hfx_bog + hfx_dif + hfx_opw + hfx_snw & 110 & - hfx_thd - hfx_dyn - hfx_res - hfx_sub - hfx_spr ) * e1e2t ) 111 110 ! 111 pdiag_v = zchk3(1) 112 pdiag_s = zchk3(2) 113 pdiag_t = zchk3(3) 114 pdiag_fv = zchk3(4) 115 pdiag_fs = zchk3(5) 116 pdiag_ft = zchk3(6) 117 ! 112 118 ELSEIF( icount == 1 ) THEN 113 114 ! -- mass diag -- !115 zdiag_mass = ( glob_sum( 'icectl', SUM( v_i * rhoi + v_s * rhos + ( v_ip + v_il ) * rhow, dim=3 ) * e1e2t ) &116 & - pdiag_v ) * r1_Dt_ice &117 & + glob_sum( 'icectl', ( wfx_bog + wfx_bom + wfx_sum + wfx_sni + wfx_opw + wfx_res + wfx_dyn + &118 & wfx_lam + wfx_pnd + wfx_snw_sni + wfx_snw_sum + wfx_snw_dyn + wfx_snw_sub + &119 & wfx_ice_sub + wfx_spr ) * e1e2t ) &120 & - pdiag_fv121 119 ! 122 ! -- salt diag -- ! 123 zdiag_salt = ( glob_sum( 'icectl', SUM( sv_i * rhoi , dim=3 ) * e1e2t ) - pdiag_s ) * r1_Dt_ice & 124 & + glob_sum( 'icectl', ( sfx_bri + sfx_bog + sfx_bom + sfx_sum + sfx_sni + & 125 & sfx_opw + sfx_res + sfx_dyn + sfx_sub + sfx_lam ) * e1e2t ) & 126 & - pdiag_fs 127 ! 128 ! -- heat diag -- ! 129 zdiag_heat = ( glob_sum( 'icectl', ( SUM(SUM(e_i, dim=4), dim=3) + SUM(SUM(e_s, dim=4), dim=3) ) * e1e2t ) - pdiag_t & 130 & ) * r1_Dt_ice & 131 & + glob_sum( 'icectl', ( hfx_sum + hfx_bom + hfx_bog + hfx_dif + hfx_opw + hfx_snw & 132 & - hfx_thd - hfx_dyn - hfx_res - hfx_sub - hfx_spr ) * e1e2t ) & 133 & - pdiag_ft 134 135 ! -- min/max diag -- ! 136 zdiag_aimax = glob_max( 'icectl', SUM( a_i, dim=3 ) ) 137 zdiag_vimin = glob_min( 'icectl', v_i ) 138 zdiag_vsmin = glob_min( 'icectl', v_s ) 139 zdiag_vpmin = glob_min( 'icectl', v_ip ) 140 zdiag_vlmin = glob_min( 'icectl', v_il ) 141 zdiag_aimin = glob_min( 'icectl', a_i ) 142 zdiag_simin = glob_min( 'icectl', sv_i ) 143 zdiag_eimin = glob_min( 'icectl', SUM( e_i, dim=3 ) ) 144 zdiag_esmin = glob_min( 'icectl', SUM( e_s, dim=3 ) ) 120 ! -- mass, salt and heat diags -- ! 121 zdiag_mass = ( zchk3(1) - pdiag_v ) * r1_Dt_ice + ( zchk3(4) - pdiag_fv ) 122 zdiag_salt = ( zchk3(2) - pdiag_s ) * r1_Dt_ice + ( zchk3(5) - pdiag_fs ) 123 zdiag_heat = ( zchk3(3) - pdiag_t ) * r1_Dt_ice + ( zchk3(6) - pdiag_ft ) 124 125 ! -- max concentration diag -- ! 126 ztmp3(:,:,7) = SUM( a_i, dim=3 ) 127 zchk3(7) = glob_max( 'icectl', ztmp3(:,:,7) ) 145 128 146 129 ! -- advection scheme is conservative? -- ! 147 zvtrp = glob_sum( 'icectl', diag_adv_mass * e1e2t ) 148 zetrp = glob_sum( 'icectl', diag_adv_heat * e1e2t ) 149 150 ! ice area (+epsi10 to set a threshold > 0 when there is no ice) 151 zarea = glob_sum( 'icectl', SUM( a_i + epsi10, dim=3 ) * e1e2t ) 130 ztmp3(:,:,8 ) = diag_adv_mass * e1e2t 131 ztmp3(:,:,9 ) = diag_adv_heat * e1e2t 132 ztmp3(:,:,10) = SUM( a_i + epsi10, dim=3 ) * e1e2t ! ice area (+epsi10 to set a threshold > 0 when there is no ice) 133 zchk3(8:10) = glob_sum_vec( 'icectl', ztmp3(:,:,8:10) ) 134 135 ! -- min diags -- ! 136 ztmp4(:,:,:,1) = v_i 137 ztmp4(:,:,:,2) = v_s 138 ztmp4(:,:,:,3) = v_ip 139 ztmp4(:,:,:,4) = v_il 140 ztmp4(:,:,:,5) = a_i 141 ztmp4(:,:,:,6) = sv_i 142 ztmp4(:,:,:,7) = SUM( e_i, dim=3 ) 143 ztmp4(:,:,:,8) = SUM( e_s, dim=3 ) 144 zchk4(1:8) = glob_min_vec( 'icectl', ztmp4(:,:,:,1:8) ) 152 145 153 146 IF( lwp ) THEN 154 147 ! check conservation issues 155 IF( ABS(zdiag_mass) > zchk_m * rn_icechk_glo * z area) &148 IF( ABS(zdiag_mass) > zchk_m * rn_icechk_glo * zchk3(10) ) & 156 149 & WRITE(numout,*) cd_routine,' : violation mass cons. [kg] = ',zdiag_mass * rDt_ice 157 IF( ABS(zdiag_salt) > zchk_s * rn_icechk_glo * z area) &150 IF( ABS(zdiag_salt) > zchk_s * rn_icechk_glo * zchk3(10) ) & 158 151 & WRITE(numout,*) cd_routine,' : violation salt cons. [g] = ',zdiag_salt * rDt_ice 159 IF( ABS(zdiag_heat) > zchk_t * rn_icechk_glo * z area) &152 IF( ABS(zdiag_heat) > zchk_t * rn_icechk_glo * zchk3(10) ) & 160 153 & WRITE(numout,*) cd_routine,' : violation heat cons. [J] = ',zdiag_heat * rDt_ice 161 154 ! check negative values 162 IF( z diag_vimin < 0. ) WRITE(numout,*) cd_routine,' : violation v_i < 0 = ',zdiag_vimin163 IF( z diag_vsmin < 0. ) WRITE(numout,*) cd_routine,' : violation v_s < 0 = ',zdiag_vsmin164 IF( z diag_vpmin < 0. ) WRITE(numout,*) cd_routine,' : violation v_ip < 0 = ',zdiag_vpmin165 IF( z diag_vlmin < 0. ) WRITE(numout,*) cd_routine,' : violation v_il < 0 = ',zdiag_vlmin166 IF( z diag_aimin < 0. ) WRITE(numout,*) cd_routine,' : violation a_i < 0 = ',zdiag_aimin167 IF( z diag_simin < 0. ) WRITE(numout,*) cd_routine,' : violation s_i < 0 = ',zdiag_simin168 IF( z diag_eimin < 0. ) WRITE(numout,*) cd_routine,' : violation e_i < 0 = ',zdiag_eimin169 IF( z diag_esmin < 0. ) WRITE(numout,*) cd_routine,' : violation e_s < 0 = ',zdiag_esmin155 IF( zchk4(1) < 0. ) WRITE(numout,*) cd_routine,' : violation v_i < 0 = ',zchk4(1) 156 IF( zchk4(2) < 0. ) WRITE(numout,*) cd_routine,' : violation v_s < 0 = ',zchk4(2) 157 IF( zchk4(3) < 0. ) WRITE(numout,*) cd_routine,' : violation v_ip < 0 = ',zchk4(3) 158 IF( zchk4(4) < 0. ) WRITE(numout,*) cd_routine,' : violation v_il < 0 = ',zchk4(4) 159 IF( zchk4(5) < 0. ) WRITE(numout,*) cd_routine,' : violation a_i < 0 = ',zchk4(5) 160 IF( zchk4(6) < 0. ) WRITE(numout,*) cd_routine,' : violation s_i < 0 = ',zchk4(6) 161 IF( zchk4(7) < 0. ) WRITE(numout,*) cd_routine,' : violation e_i < 0 = ',zchk4(7) 162 IF( zchk4(8) < 0. ) WRITE(numout,*) cd_routine,' : violation e_s < 0 = ',zchk4(8) 170 163 ! check maximum ice concentration 171 IF( z diag_aimax>MAX(rn_amax_n,rn_amax_s)+epsi10 .AND. cd_routine /= 'icedyn_adv' .AND. cd_routine /= 'icedyn_rdgrft' ) &172 & WRITE(numout,*) cd_routine,' : violation a_i > amax = ',zdiag_aimax164 IF( zchk3(7)>MAX(rn_amax_n,rn_amax_s)+epsi10 .AND. cd_routine /= 'icedyn_adv' .AND. cd_routine /= 'icedyn_rdgrft' ) & 165 & WRITE(numout,*) cd_routine,' : violation a_i > amax = ',zchk3(7) 173 166 ! check if advection scheme is conservative 174 IF( ABS(z vtrp) > zchk_m * rn_icechk_glo * zarea.AND. cd_routine == 'icedyn_adv' ) &175 & WRITE(numout,*) cd_routine,' : violation adv scheme [kg] = ',zvtrp* rDt_ice176 IF( ABS(z etrp) > zchk_t * rn_icechk_glo * zarea.AND. cd_routine == 'icedyn_adv' ) &177 & WRITE(numout,*) cd_routine,' : violation adv scheme [J] = ',zetrp* rDt_ice167 IF( ABS(zchk3(8)) > zchk_m * rn_icechk_glo * zchk3(10) .AND. cd_routine == 'icedyn_adv' ) & 168 & WRITE(numout,*) cd_routine,' : violation adv scheme [kg] = ',zchk3(8) * rDt_ice 169 IF( ABS(zchk3(9)) > zchk_t * rn_icechk_glo * zchk3(10) .AND. cd_routine == 'icedyn_adv' ) & 170 & WRITE(numout,*) cd_routine,' : violation adv scheme [J] = ',zchk3(9) * rDt_ice 178 171 ENDIF 179 172 ! … … 195 188 !!------------------------------------------------------------------- 196 189 CHARACTER(len=*), INTENT(in) :: cd_routine ! name of the routine 197 REAL(wp) :: zdiag_mass, zdiag_salt, zdiag_heat 198 REAL(wp) :: zarea 199 !!------------------------------------------------------------------- 200 201 ! water flux 202 ! -- mass diag -- ! 203 zdiag_mass = glob_sum( 'icectl', ( wfx_ice + wfx_snw + wfx_spr + wfx_sub + wfx_pnd & 204 & + diag_vice + diag_vsnw + diag_vpnd - diag_adv_mass ) * e1e2t ) 205 206 ! -- salt diag -- ! 207 zdiag_salt = glob_sum( 'icectl', ( sfx + diag_sice - diag_adv_salt ) * e1e2t ) 208 209 ! -- heat diag -- ! 210 zdiag_heat = glob_sum( 'icectl', ( qt_oce_ai - qt_atm_oi + diag_heat - diag_adv_heat ) * e1e2t ) 190 !! 191 REAL(wp), DIMENSION(jpi,jpj,4) :: ztmp 192 REAL(wp), DIMENSION(4) :: zchk 193 !!------------------------------------------------------------------- 194 195 ztmp(:,:,1) = ( wfx_ice + wfx_snw + wfx_spr + wfx_sub + wfx_pnd + diag_vice + diag_vsnw + diag_vpnd - diag_adv_mass ) * e1e2t ! mass diag 196 ztmp(:,:,2) = ( sfx + diag_sice - diag_adv_salt ) * e1e2t ! salt 197 ztmp(:,:,3) = ( qt_oce_ai - qt_atm_oi + diag_heat - diag_adv_heat ) * e1e2t ! heat 211 198 ! equivalent to this: 212 !! zdiag_heat = glob_sum( 'icectl',( -diag_heat + hfx_sum + hfx_bom + hfx_bog + hfx_dif + hfx_opw + hfx_snw &213 !! & - hfx_thd - hfx_dyn - hfx_res - hfx_sub - hfx_spr &214 !! & ) * e1e2t)215 216 ! ice area (+epsi10 to set a threshold > 0 when there is no ice)217 z area = glob_sum( 'icectl', SUM( a_i + epsi10, dim=3 ) * e1e2t)218 199 !! ( -diag_heat + hfx_sum + hfx_bom + hfx_bog + hfx_dif + hfx_opw + hfx_snw & 200 !! & - hfx_thd - hfx_dyn - hfx_res - hfx_sub - hfx_spr ) * e1e2t ) 201 ztmp(:,:,4) = SUM( a_i + epsi10, dim=3 ) * e1e2t ! ice area (+epsi10 to set a threshold > 0 when there is no ice) 202 203 ! global sums 204 zchk(1:4) = glob_sum_vec( 'icectl', ztmp(:,:,1:4) ) 205 219 206 IF( lwp ) THEN 220 IF( ABS(z diag_mass) > zchk_m * rn_icechk_glo * zarea) &221 & WRITE(numout,*) cd_routine,' : violation mass cons. [kg] = ',z diag_mass* rDt_ice222 IF( ABS(z diag_salt) > zchk_s * rn_icechk_glo * zarea) &223 & WRITE(numout,*) cd_routine,' : violation salt cons. [g] = ',z diag_salt* rDt_ice224 IF( ABS(z diag_heat) > zchk_t * rn_icechk_glo * zarea) &225 & WRITE(numout,*) cd_routine,' : violation heat cons. [J] = ',z diag_heat* rDt_ice207 IF( ABS(zchk(1)) > zchk_m * rn_icechk_glo * zchk(4) ) & 208 & WRITE(numout,*) cd_routine,' : violation mass cons. [kg] = ',zchk(1) * rDt_ice 209 IF( ABS(zchk(2)) > zchk_s * rn_icechk_glo * zchk(4) ) & 210 & WRITE(numout,*) cd_routine,' : violation salt cons. [g] = ',zchk(2) * rDt_ice 211 IF( ABS(zchk(3)) > zchk_t * rn_icechk_glo * zchk(4) ) & 212 & WRITE(numout,*) cd_routine,' : violation heat cons. [J] = ',zchk(3) * rDt_ice 226 213 ENDIF 227 214 ! … … 391 378 cl_alname(ialert_id) = ' Very high salinity ' ! name of the alert 392 379 DO jl = 1, jpl 393 DO_2D( 1, 1, 1, 1)380 DO_2D( 0, 0, 0, 0 ) 394 381 IF( v_i(ji,jj,jl) > epsi10 ) THEN 395 382 IF( sv_i(ji,jj,jl) / v_i(ji,jj,jl) > rn_simax ) THEN … … 406 393 cl_alname(ialert_id) = ' Very low salinity ' ! name of the alert 407 394 DO jl = 1, jpl 408 DO_2D( 1, 1, 1, 1)395 DO_2D( 0, 0, 0, 0 ) 409 396 IF( v_i(ji,jj,jl) > epsi10 ) THEN 410 397 IF( sv_i(ji,jj,jl) / v_i(ji,jj,jl) < rn_simin ) THEN … … 421 408 cl_alname(ialert_id) = ' Very cold ice ' ! name of the alert 422 409 DO jl = 1, jpl 423 DO_3D( 1, 1, 1, 1, 1, nlay_i )410 DO_3D( 0, 0, 0, 0, 1, nlay_i ) 424 411 ztmelts = -rTmlt * sz_i(ji,jj,jk,jl) + rt0 425 412 IF( t_i(ji,jj,jk,jl) < -50.+rt0 .AND. v_i(ji,jj,jl) > epsi10 ) THEN … … 435 422 cl_alname(ialert_id) = ' Very warm ice ' ! name of the alert 436 423 DO jl = 1, jpl 437 DO_3D( 1, 1, 1, 1, 1, nlay_i )424 DO_3D( 0, 0, 0, 0, 1, nlay_i ) 438 425 ztmelts = -rTmlt * sz_i(ji,jj,jk,jl) + rt0 439 426 IF( t_i(ji,jj,jk,jl) > ztmelts .AND. v_i(ji,jj,jl) > epsi10 ) THEN … … 449 436 cl_alname(ialert_id) = ' Very thick ice ' ! name of the alert 450 437 jl = jpl 451 DO_2D( 1, 1, 1, 1)438 DO_2D( 0, 0, 0, 0 ) 452 439 IF( h_i(ji,jj,jl) > 50._wp ) THEN 453 440 WRITE(numout,*) ' ALERTE : Very thick ice ',h_i(ji,jj,jl) … … 461 448 cl_alname(ialert_id) = ' Very thin ice ' ! name of the alert 462 449 jl = 1 463 DO_2D( 1, 1, 1, 1)450 DO_2D( 0, 0, 0, 0 ) 464 451 IF( h_i(ji,jj,jl) < rn_himin ) THEN 465 452 WRITE(numout,*) ' ALERTE : Very thin ice ',h_i(ji,jj,jl) … … 472 459 ialert_id = ialert_id + 1 ! reference number of this alert 473 460 cl_alname(ialert_id) = ' Very fast ice ' ! name of the alert 474 DO_2D( 1, 1, 1, 1)461 DO_2D( 0, 0, 0, 0 ) 475 462 IF( MAX( ABS( u_ice(ji,jj) ), ABS( v_ice(ji,jj) ) ) > 2. ) THEN 476 463 WRITE(numout,*) ' ALERTE : Very fast ice ',MAX( ABS( u_ice(ji,jj) ), ABS( v_ice(ji,jj) ) ) … … 483 470 ialert_id = ialert_id + 1 ! reference number of this alert 484 471 cl_alname(ialert_id) = ' Ice on continents ' ! name of the alert 485 DO_2D( 1, 1, 1, 1)472 DO_2D( 0, 0, 0, 0 ) 486 473 IF( tmask(ji,jj,1) == 0._wp .AND. ( at_i(ji,jj) > 0._wp .OR. vt_i(ji,jj) > 0._wp ) ) THEN 487 474 WRITE(numout,*) ' ALERTE : Ice on continents ',at_i(ji,jj),vt_i(ji,jj) … … 494 481 ialert_id = ialert_id + 1 ! reference number of this alert 495 482 cl_alname(ialert_id) = ' Incompatible ice conc and vol ' ! name of the alert 496 DO_2D( 1, 1, 1, 1)483 DO_2D( 0, 0, 0, 0 ) 497 484 IF( ( vt_i(ji,jj) == 0._wp .AND. at_i(ji,jj) > 0._wp ) .OR. & 498 485 & ( vt_i(ji,jj) > 0._wp .AND. at_i(ji,jj) == 0._wp ) ) THEN … … 762 749 INTEGER, INTENT(in) :: kt ! ice time-step index 763 750 ! 764 INTEGER :: ji, jj 765 REAL(wp) :: zdiag_mass, zdiag_salt, zdiag_heat, zdiag_adv_mass, zdiag_adv_salt, zdiag_adv_heat 766 REAL(wp), DIMENSION(jpi,jpj) :: zdiag_mass2D, zdiag_salt2D, zdiag_heat2D 751 REAL(wp), DIMENSION(jpi,jpj,6) :: ztmp 752 REAL(wp), DIMENSION(6) :: zchk 767 753 !!------------------------------------------------------------------- 768 754 ! … … 773 759 ENDIF 774 760 ! 775 ! 2D budgets (must be close to 0) 776 IF( iom_use('icedrift_mass') .OR. iom_use('icedrift_salt') .OR. iom_use('icedrift_heat') ) THEN 777 DO_2D( 1, 1, 1, 1 ) 778 zdiag_mass2D(ji,jj) = wfx_ice(ji,jj) + wfx_snw(ji,jj) + wfx_spr(ji,jj) + wfx_sub(ji,jj) & 779 & + diag_vice(ji,jj) + diag_vsnw(ji,jj) - diag_adv_mass(ji,jj) 780 zdiag_salt2D(ji,jj) = sfx(ji,jj) + diag_sice(ji,jj) - diag_adv_salt(ji,jj) 781 zdiag_heat2D(ji,jj) = qt_oce_ai(ji,jj) - qt_atm_oi(ji,jj) + diag_heat(ji,jj) - diag_adv_heat(ji,jj) 782 END_2D 783 ! 784 ! write outputs 785 CALL iom_put( 'icedrift_mass', zdiag_mass2D ) 786 CALL iom_put( 'icedrift_salt', zdiag_salt2D ) 787 CALL iom_put( 'icedrift_heat', zdiag_heat2D ) 788 ENDIF 789 790 ! -- mass diag -- ! 791 zdiag_mass = glob_sum( 'icectl', ( wfx_ice + wfx_snw + wfx_spr + wfx_sub & 792 & + diag_vice + diag_vsnw - diag_adv_mass ) * e1e2t ) * rDt_ice 793 zdiag_adv_mass = glob_sum( 'icectl', diag_adv_mass * e1e2t ) * rDt_ice 794 795 ! -- salt diag -- ! 796 zdiag_salt = glob_sum( 'icectl', ( sfx + diag_sice - diag_adv_salt ) * e1e2t ) * rDt_ice * 1.e-3 797 zdiag_adv_salt = glob_sum( 'icectl', diag_adv_salt * e1e2t ) * rDt_ice * 1.e-3 798 799 ! -- heat diag -- ! 800 zdiag_heat = glob_sum( 'icectl', ( qt_oce_ai - qt_atm_oi + diag_heat - diag_adv_heat ) * e1e2t ) 801 zdiag_adv_heat = glob_sum( 'icectl', diag_adv_heat * e1e2t ) 802 761 ! -- 2D budgets (must be close to 0) -- ! 762 ztmp(:,:,1) = wfx_ice (:,:) + wfx_snw (:,:) + wfx_spr (:,:) + wfx_sub(:,:) + wfx_pnd(:,:) & 763 & + diag_vice(:,:) + diag_vsnw(:,:) + diag_vpnd(:,:) - diag_adv_mass(:,:) 764 ztmp(:,:,2) = sfx(:,:) + diag_sice(:,:) - diag_adv_salt(:,:) 765 ztmp(:,:,3) = qt_oce_ai(:,:) - qt_atm_oi(:,:) + diag_heat(:,:) - diag_adv_heat(:,:) 766 767 ! write outputs 768 CALL iom_put( 'icedrift_mass', ztmp(:,:,1) ) 769 CALL iom_put( 'icedrift_salt', ztmp(:,:,2) ) 770 CALL iom_put( 'icedrift_heat', ztmp(:,:,3) ) 771 772 ! -- 1D budgets -- ! 773 ztmp(:,:,1) = ztmp(:,:,1) * e1e2t * rDt_ice ! mass 774 ztmp(:,:,2) = ztmp(:,:,2) * e1e2t * rDt_ice * 1.e-3 ! salt 775 ztmp(:,:,3) = ztmp(:,:,3) * e1e2t ! heat 776 777 ztmp(:,:,4) = diag_adv_mass * e1e2t * rDt_ice 778 ztmp(:,:,5) = diag_adv_salt * e1e2t * rDt_ice * 1.e-3 779 ztmp(:,:,6) = diag_adv_heat * e1e2t 780 781 ! global sums 782 zchk(1:6) = glob_sum_vec( 'icectl', ztmp(:,:,1:6) ) 783 803 784 ! ! write out to file 804 785 IF( lwp ) THEN 805 786 ! check global drift (must be close to 0) 806 WRITE(numicedrift,FMT='(2x,i6,3x,a19,4x,f25.5)') kt, 'mass drift [kg]', z diag_mass807 WRITE(numicedrift,FMT='(11x, a19,4x,f25.5)') 'salt drift [kg]', z diag_salt808 WRITE(numicedrift,FMT='(11x, a19,4x,f25.5)') 'heat drift [W] ', z diag_heat787 WRITE(numicedrift,FMT='(2x,i6,3x,a19,4x,f25.5)') kt, 'mass drift [kg]', zchk(1) 788 WRITE(numicedrift,FMT='(11x, a19,4x,f25.5)') 'salt drift [kg]', zchk(2) 789 WRITE(numicedrift,FMT='(11x, a19,4x,f25.5)') 'heat drift [W] ', zchk(3) 809 790 ! check drift from advection scheme (can be /=0 with bdy but not sure why) 810 WRITE(numicedrift,FMT='(11x, a19,4x,f25.5)') 'mass drift adv [kg]', z diag_adv_mass811 WRITE(numicedrift,FMT='(11x, a19,4x,f25.5)') 'salt drift adv [kg]', z diag_adv_salt812 WRITE(numicedrift,FMT='(11x, a19,4x,f25.5)') 'heat drift adv [W] ', z diag_adv_heat791 WRITE(numicedrift,FMT='(11x, a19,4x,f25.5)') 'mass drift adv [kg]', zchk(4) 792 WRITE(numicedrift,FMT='(11x, a19,4x,f25.5)') 'salt drift adv [kg]', zchk(5) 793 WRITE(numicedrift,FMT='(11x, a19,4x,f25.5)') 'heat drift adv [W] ', zchk(6) 813 794 ENDIF 814 795 ! ! drifts 815 rdiag_icemass = rdiag_icemass + z diag_mass816 rdiag_icesalt = rdiag_icesalt + z diag_salt817 rdiag_iceheat = rdiag_iceheat + z diag_heat818 rdiag_adv_icemass = rdiag_adv_icemass + z diag_adv_mass819 rdiag_adv_icesalt = rdiag_adv_icesalt + z diag_adv_salt820 rdiag_adv_iceheat = rdiag_adv_iceheat + z diag_adv_heat796 rdiag_icemass = rdiag_icemass + zchk(1) 797 rdiag_icesalt = rdiag_icesalt + zchk(2) 798 rdiag_iceheat = rdiag_iceheat + zchk(3) 799 rdiag_adv_icemass = rdiag_adv_icemass + zchk(4) 800 rdiag_adv_icesalt = rdiag_adv_icesalt + zchk(5) 801 rdiag_adv_iceheat = rdiag_adv_iceheat + zchk(6) 821 802 ! 822 803 ! ! output drifts and close ascii file -
NEMO/branches/2021/ticket2632_r14588_theta_sbcblk/src/ICE/icedia.F90
r14072 r15548 65 65 INTEGER, INTENT(in) :: kt ! ocean time step 66 66 !! 67 REAL(wp) :: zbg_ivol, zbg_item, zbg_area, zbg_isal 68 REAL(wp) :: zbg_svol, zbg_stem 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 67 REAL(wp), DIMENSION(jpi,jpj,16) :: ztmp 68 REAL(wp), DIMENSION(16) :: zbg 72 69 !!--------------------------------------------------------------------------- 73 70 IF( ln_timing ) CALL timing_start('ice_dia') … … 83 80 ENDIF 84 81 85 ! ----------------------- ! 86 ! 1 - Contents ! 87 ! ----------------------- ! 88 IF( iom_use('ibgvol_tot' ) .OR. iom_use('sbgvol_tot' ) .OR. iom_use('ibgarea_tot') .OR. & 89 & iom_use('ibgsalt_tot') .OR. iom_use('ibgheat_tot') .OR. iom_use('sbgheat_tot') ) THEN 90 91 zbg_ivol = glob_sum( 'icedia', vt_i(:,:) * e1e2t(:,:) ) * 1.e-9 ! ice volume (km3) 92 zbg_svol = glob_sum( 'icedia', vt_s(:,:) * e1e2t(:,:) ) * 1.e-9 ! snow volume (km3) 93 zbg_area = glob_sum( 'icedia', at_i(:,:) * e1e2t(:,:) ) * 1.e-6 ! area (km2) 94 zbg_isal = glob_sum( 'icedia', st_i(:,:) * e1e2t(:,:) ) * 1.e-9 ! salt content (pss*km3) 95 zbg_item = glob_sum( 'icedia', et_i(:,:) * e1e2t(:,:) ) * 1.e-20 ! heat content (1.e20 J) 96 zbg_stem = glob_sum( 'icedia', et_s(:,:) * e1e2t(:,:) ) * 1.e-20 ! heat content (1.e20 J) 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 105 ENDIF 106 82 ztmp(:,:,:) = 0._wp ! should be better coded 83 107 84 ! ---------------------------! 108 ! 2- Trends due to forcing !85 ! 1 - Trends due to forcing ! 109 86 ! ---------------------------! 110 87 ! 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 112 z_frc_voltop = r1_rho0 * glob_sum( 'icedia', -( wfx_sub(:,:) + wfx_spr(:,:) ) * e1e2t(:,:) ) * 1.e-9 ! freshwater flux ice/snow-atm 113 z_frc_sal = r1_rho0 * glob_sum( 'icedia', - sfx(:,:) * e1e2t(:,:) ) * 1.e-9 ! salt fluxes ice/snow-ocean 114 z_frc_tembot = glob_sum( 'icedia', qt_oce_ai(:,:) * e1e2t(:,:) ) * 1.e-20 ! heat on top of ocean (and below ice) 115 z_frc_temtop = glob_sum( 'icedia', qt_atm_oi(:,:) * e1e2t(:,:) ) * 1.e-20 ! heat on top of ice-coean 116 ! 117 frc_voltop = frc_voltop + z_frc_voltop * rDt_ice ! km3 118 frc_volbot = frc_volbot + z_frc_volbot * rDt_ice ! km3 119 frc_sal = frc_sal + z_frc_sal * rDt_ice ! km3*pss 120 frc_temtop = frc_temtop + z_frc_temtop * rDt_ice ! 1.e20 J 121 frc_tembot = frc_tembot + z_frc_tembot * rDt_ice ! 1.e20 J 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) 128 129 IF( iom_use('ibgfrchfxtop') .OR. iom_use('ibgfrchfxbot') ) THEN 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 88 ztmp(:,:,1) = - ( wfx_ice(:,:) + wfx_snw(:,:) + wfx_err_sub(:,:) ) * e1e2t(:,:) ! freshwater flux ice/snow-ocean 89 ztmp(:,:,2) = - ( wfx_sub(:,:) + wfx_spr(:,:) ) * e1e2t(:,:) ! freshwater flux ice/snow-atm 90 ztmp(:,:,3) = - sfx (:,:) * e1e2t(:,:) ! salt fluxes ice/snow-ocean 91 ztmp(:,:,4) = qt_atm_oi(:,:) * e1e2t(:,:) ! heat on top of ice-ocean 92 ztmp(:,:,5) = qt_oce_ai(:,:) * e1e2t(:,:) ! heat on top of ocean (and below ice) 93 94 ! ----------------------- ! 95 ! 2 - Contents ! 96 ! ----------------------- ! 97 IF( iom_use('ibgvol_tot' ) ) ztmp(:,:,6 ) = vt_i (:,:) * e1e2t(:,:) ! ice volume 98 IF( iom_use('sbgvol_tot' ) ) ztmp(:,:,7 ) = vt_s (:,:) * e1e2t(:,:) ! snow volume 99 IF( iom_use('ibgarea_tot') ) ztmp(:,:,8 ) = at_i (:,:) * e1e2t(:,:) ! area 100 IF( iom_use('ibgsalt_tot') ) ztmp(:,:,9 ) = st_i (:,:) * e1e2t(:,:) ! salt content 101 IF( iom_use('ibgheat_tot') ) ztmp(:,:,10) = et_i (:,:) * e1e2t(:,:) ! heat content 102 IF( iom_use('sbgheat_tot') ) ztmp(:,:,11) = et_s (:,:) * e1e2t(:,:) ! heat content 103 IF( iom_use('ipbgvol_tot') ) ztmp(:,:,12) = vt_ip(:,:) * e1e2t(:,:) ! ice pond volume 104 IF( iom_use('ilbgvol_tot') ) ztmp(:,:,13) = vt_il(:,:) * e1e2t(:,:) ! ice pond lid volume 133 105 134 106 ! ---------------------------------- ! 135 107 ! 3 - Content variations and drifts ! 136 108 ! ---------------------------------- ! 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) 140 zdiff_sal = r1_rho0 * glob_sum( 'icedia', ( rhoi*st_i(:,:) - sal_loc_ini(:,:) ) * e1e2t(:,:) ) * 1.e-9 ! salt content trend (km3*pss) 141 zdiff_tem = glob_sum( 'icedia', ( et_i(:,:) + et_s(:,:) - tem_loc_ini(:,:) ) * e1e2t(:,:) ) * 1.e-20 ! heat content trend (1.e20 J) 142 ! + SUM( qevap_ice * a_i_b, dim=3 ) !! clem: I think this term should not be there (but needs a check) 143 144 zdiff_vol = zdiff_vol - ( frc_voltop + frc_volbot ) 145 zdiff_sal = zdiff_sal - frc_sal 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) 149 CALL iom_put( 'ibgsaltco' , zdiff_sal ) ! ice salt content drift (psu*km3 equivalent ocean water) 150 CALL iom_put( 'ibgheatco' , zdiff_tem ) ! ice/snow heat content drift (1.e20 J) 151 ! 152 ENDIF 153 109 IF( iom_use('ibgvolume') ) ztmp(:,:,14) = ( rhoi*vt_i(:,:) + rhos*vt_s(:,:) - vol_loc_ini(:,:) ) * e1e2t(:,:) ! freshwater trend 110 IF( iom_use('ibgsaltco') ) ztmp(:,:,15) = ( rhoi*st_i(:,:) - sal_loc_ini(:,:) ) * e1e2t(:,:) ! salt content trend 111 IF( iom_use('ibgheatco') .OR. iom_use('ibgheatfx') ) & 112 & ztmp(:,:,16) = ( et_i(:,:) + et_s(:,:) - tem_loc_ini(:,:) ) * e1e2t(:,:) ! heat content trend 113 114 ! global sum 115 zbg(1:16) = glob_sum_vec( 'icedia', ztmp(:,:,1:16) ) 116 117 ! change units for trends 118 zbg(1) = zbg(1) * r1_rho0 * 1.e-9 * rDt_ice ! freshwater flux ice/snow-ocean (km3) 119 zbg(2) = zbg(2) * r1_rho0 * 1.e-9 * rDt_ice ! freshwater flux ice/snow-atm (km3) 120 zbg(3) = zbg(3) * r1_rho0 * 1.e-9 * rDt_ice ! salt fluxes ice/snow-ocean (km3*pss) 121 zbg(4) = zbg(4) * 1.e-20 * rDt_ice ! heat on top of ice-ocean (1.e20 J) 122 zbg(5) = zbg(5) * 1.e-20 * rDt_ice ! heat on top of ocean (and below ice) (1.e20 J) 123 ! cumulative sum 124 frc_voltop = frc_voltop + zbg(1) 125 frc_volbot = frc_volbot + zbg(2) 126 frc_sal = frc_sal + zbg(3) 127 frc_temtop = frc_temtop + zbg(4) 128 frc_tembot = frc_tembot + zbg(5) 129 130 ! change units for contents 131 zbg(6) = zbg(6) * 1.e-9 ! ice volume (km3) 132 zbg(7) = zbg(7) * 1.e-9 ! snw volume (km3) 133 zbg(8) = zbg(8) * 1.e-6 ! ice area (km2) 134 zbg(9) = zbg(9) * 1.e-9 ! salt content (km3*pss) 135 zbg(10) = zbg(10) * 1.e-20 ! ice heat content (1.e20 J) 136 zbg(11) = zbg(11) * 1.e-20 ! snw heat content (1.e20 J) 137 zbg(12) = zbg(12) * 1.e-9 ! pnd volume (km3) 138 zbg(13) = zbg(13) * 1.e-9 ! pnd lid volume (km3) 139 140 ! change units for trends 141 zbg(14) = zbg(14) * r1_rho0 * 1.e-9 ! freshwater trend (km3) 142 zbg(15) = zbg(15) * r1_rho0 * 1.e-9 ! salt content trend (km3*pss) 143 zbg(16) = zbg(16) * 1.e-20 ! heat content trend (1.e20 J) 144 ! difference 145 zbg(14) = zbg(14) - ( frc_voltop + frc_volbot ) 146 zbg(15) = zbg(15) - frc_sal 147 zbg(16) = zbg(16) - ( frc_tembot - frc_temtop ) 148 149 ! outputs 150 CALL iom_put( 'ibgfrcvoltop' , frc_voltop ) ! vol forcing ice/snw-atm (km3 equivalent ocean water) 151 CALL iom_put( 'ibgfrcvolbot' , frc_volbot ) ! vol forcing ice/snw-ocean (km3 equivalent ocean water) 152 CALL iom_put( 'ibgfrcsal' , frc_sal ) ! sal forcing (psu*km3 equivalent ocean water) 153 CALL iom_put( 'ibgfrctemtop' , frc_temtop ) ! heat on top of ice/snw/ocean (1.e20 J) 154 CALL iom_put( 'ibgfrctembot' , frc_tembot ) ! heat on top of ocean(below ice) (1.e20 J) 155 CALL iom_put( 'ibgfrchfxtop' , frc_temtop * z1_e1e2 * 1.e-20 * kt*rn_Dt ) ! heat on top of ice/snw/ocean (W/m2) 156 CALL iom_put( 'ibgfrchfxbot' , frc_tembot * z1_e1e2 * 1.e-20 * kt*rn_Dt ) ! heat on top of ocean(below ice) (W/m2) 157 158 CALL iom_put( 'ibgvol_tot' , zbg(6) ) 159 CALL iom_put( 'sbgvol_tot' , zbg(7) ) 160 CALL iom_put( 'ibgarea_tot' , zbg(8) ) 161 CALL iom_put( 'ibgsalt_tot' , zbg(9) ) 162 CALL iom_put( 'ibgheat_tot' , zbg(10) ) 163 CALL iom_put( 'sbgheat_tot' , zbg(11) ) 164 CALL iom_put( 'ipbgvol_tot' , zbg(12) ) 165 CALL iom_put( 'ilbgvol_tot' , zbg(13) ) 166 167 CALL iom_put( 'ibgvolume' , zbg(14) ) ! ice/snow volume drift (km3 equivalent ocean water) 168 CALL iom_put( 'ibgsaltco' , zbg(15) ) ! ice salt content drift (psu*km3 equivalent ocean water) 169 CALL iom_put( 'ibgheatco' , zbg(16) ) ! ice/snow heat content drift (1.e20 J) 170 ! 171 ! restarts 154 172 IF( lrst_ice ) CALL ice_dia_rst( 'WRITE', kt_ice ) 155 173 ! -
NEMO/branches/2021/ticket2632_r14588_theta_sbcblk/src/ICE/icedyn.F90
r14072 r15548 135 135 ! CFL = 0.5 at a distance from the bound of 1/6 of the basin length 136 136 ! Then for dx = 2m and dt = 1s => rn_uice = u (1/6th) = 1m/s 137 DO_2D( 1, 1, 1, 1)137 DO_2D( nn_hls, nn_hls, nn_hls, nn_hls ) 138 138 zcoefu = ( REAL(jpiglo+1)*0.5_wp - REAL(ji+nimpp-1) ) / ( REAL(jpiglo+1)*0.5_wp - 1._wp ) 139 139 zcoefv = ( REAL(jpjglo+1)*0.5_wp - REAL(jj+njmpp-1) ) / ( REAL(jpjglo+1)*0.5_wp - 1._wp ) -
NEMO/branches/2021/ticket2632_r14588_theta_sbcblk/src/ICE/icedyn_adv_pra.F90
r14433 r15548 268 268 & , sxxice, 'T', 1._wp, syyice, 'T', 1._wp, sxyice, 'T', 1._wp & 269 269 & , z0snw , 'T', 1._wp, sxsn , 'T', -1._wp, sysn , 'T', -1._wp & ! snw volume 270 & , sxxsn , 'T', 1._wp, syysn , 'T', 1._wp, sxysn , 'T', 1._wp )271 CALL lbc_lnk( 'icedyn_adv_pra', z0smi , 'T', 1._wp, sxsal , 'T', -1._wp, sysal , 'T', -1._wp & ! ice salinity270 & , sxxsn , 'T', 1._wp, syysn , 'T', 1._wp, sxysn , 'T', 1._wp & 271 & , z0smi , 'T', 1._wp, sxsal , 'T', -1._wp, sysal , 'T', -1._wp & ! ice salinity 272 272 & , sxxsal, 'T', 1._wp, syysal, 'T', 1._wp, sxysal, 'T', 1._wp & 273 273 & , z0ai , 'T', 1._wp, sxa , 'T', -1._wp, sya , 'T', -1._wp & ! ice concentration 274 & , sxxa , 'T', 1._wp, syya , 'T', 1._wp, sxya , 'T', 1._wp )275 CALL lbc_lnk( 'icedyn_adv_pra', z0oi , 'T', 1._wp, sxage , 'T', -1._wp, syage , 'T', -1._wp & ! ice age274 & , sxxa , 'T', 1._wp, syya , 'T', 1._wp, sxya , 'T', 1._wp & 275 & , z0oi , 'T', 1._wp, sxage , 'T', -1._wp, syage , 'T', -1._wp & ! ice age 276 276 & , sxxage, 'T', 1._wp, syyage, 'T', 1._wp, sxyage, 'T', 1._wp ) 277 277 CALL lbc_lnk( 'icedyn_adv_pra', z0es , 'T', 1._wp, sxc0 , 'T', -1._wp, syc0 , 'T', -1._wp & ! snw enthalpy … … 280 280 & , sxxe , 'T', 1._wp, syye , 'T', 1._wp, sxye , 'T', 1._wp ) 281 281 IF ( ln_pnd_LEV .OR. ln_pnd_TOPO ) THEN 282 CALL lbc_lnk( 'icedyn_adv_pra', z0ap , 'T', 1._wp, sxap , 'T', -1._wp, syap , 'T', -1._wp & ! melt pond fraction 283 & , sxxap, 'T', 1._wp, syyap, 'T', 1._wp, sxyap, 'T', 1._wp & 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 ) 286 IF ( ln_pnd_lids ) THEN 287 CALL lbc_lnk( '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 ) 282 IF( ln_pnd_lids ) THEN 283 CALL lbc_lnk( 'icedyn_adv_pra', z0ap , 'T', 1._wp, sxap , 'T', -1._wp, syap , 'T', -1._wp & ! melt pond fraction 284 & , sxxap, 'T', 1._wp, syyap, 'T', 1._wp, sxyap, 'T', 1._wp & 285 & , z0vp , 'T', 1._wp, sxvp , 'T', -1._wp, syvp , 'T', -1._wp & ! melt pond volume 286 & , sxxvp, 'T', 1._wp, syyvp, 'T', 1._wp, sxyvp, 'T', 1._wp & 287 & , 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 ) 289 ELSE 290 CALL lbc_lnk( 'icedyn_adv_pra', z0ap , 'T', 1._wp, sxap , 'T', -1._wp, syap , 'T', -1._wp & ! melt pond fraction 291 & , sxxap, 'T', 1._wp, syyap, 'T', 1._wp, sxyap, 'T', 1._wp & 292 & , z0vp , 'T', 1._wp, sxvp , 'T', -1._wp, syvp , 'T', -1._wp & ! melt pond volume 293 & , sxxvp, 'T', 1._wp, syyvp, 'T', 1._wp, sxyvp, 'T', 1._wp ) 289 294 ENDIF 290 295 ENDIF … … 766 771 ! 767 772 DO jl = 1, jpl 768 DO_2D( 1, 1, 1, 1)773 DO_2D( nn_hls, nn_hls, nn_hls, nn_hls ) 769 774 IF ( pv_i(ji,jj,jl) > 0._wp ) THEN 770 775 ! … … 813 818 ! ! -- check e_i/v_i -- ! 814 819 DO jl = 1, jpl 815 DO_3D( 1, 1, 1, 1, 1, nlay_i )820 DO_3D( nn_hls, nn_hls, nn_hls, nn_hls, 1, nlay_i ) 816 821 IF ( pv_i(ji,jj,jl) > 0._wp ) THEN 817 822 ! if e_i/v_i is larger than the surrounding 9 pts => put the heat excess in the ocean … … 827 832 ! ! -- check e_s/v_s -- ! 828 833 DO jl = 1, jpl 829 DO_3D( 1, 1, 1, 1, 1, nlay_s )834 DO_3D( nn_hls, nn_hls, nn_hls, nn_hls, 1, nlay_s ) 830 835 IF ( pv_s(ji,jj,jl) > 0._wp ) THEN 831 836 ! if e_s/v_s is larger than the surrounding 9 pts => put the heat excess in the ocean … … 870 875 ! -- check snow load -- ! 871 876 DO jl = 1, jpl 872 DO_2D( 1, 1, 1, 1)877 DO_2D( nn_hls, nn_hls, nn_hls, nn_hls ) 873 878 IF ( pv_i(ji,jj,jl) > 0._wp ) THEN 874 879 ! … … 1168 1173 !! ** Purpose : compute the max of the 9 points around 1169 1174 !!---------------------------------------------------------------------- 1170 REAL(wp), DIMENSION(:,:,:) , INTENT(in ) :: pice ! input 1171 REAL(wp), DIMENSION(:,:,:) , INTENT(out) :: pmax ! output 1172 REAL(wp), DIMENSION(2:jpim1,jpj) :: zmax ! temporary array 1175 REAL(wp), DIMENSION(:,:,:), INTENT(in ) :: pice ! input 1176 REAL(wp), DIMENSION(:,:,:), INTENT(out) :: pmax ! output 1177 ! 1178 REAL(wp), DIMENSION(Nis0:Nie0) :: zmax1, zmax2 1179 REAL(wp) :: zmax3 1173 1180 INTEGER :: ji, jj, jl ! dummy loop indices 1174 1181 !!---------------------------------------------------------------------- 1182 ! basic version: get the max of epsi20 + 9 neighbours 1183 !!$ DO jl = 1, jpl 1184 !!$ DO_2D( 0, 0, 0, 0 ) 1185 !!$ pmax(ji,jj,jl) = MAX( epsi20, pice(ji-1,jj-1,jl), pice(ji,jj-1,jl), pice(ji+1,jj-1,jl), & 1186 !!$ & pice(ji-1,jj ,jl), pice(ji,jj ,jl), pice(ji+1,jj ,jl), & 1187 !!$ & pice(ji-1,jj+1,jl), pice(ji,jj+1,jl), pice(ji+1,jj+1,jl) ) 1188 !!$ END_2D 1189 !!$ END DO 1190 ! optimized version : does a little bit more than 2 max of epsi20 + 3 neighbours 1175 1191 DO jl = 1, jpl 1176 DO jj = Njs0-1, Nje0+1 1177 DO ji = Nis0, Nie0 1178 zmax(ji,jj) = MAX( epsi20, pice(ji,jj,jl), pice(ji-1,jj,jl), pice(ji+1,jj,jl) ) 1179 END DO 1192 DO ji = Nis0, Nie0 1193 zmax1(ji) = MAX( epsi20, pice(ji,Njs0-1,jl), pice(ji-1,Njs0-1,jl), pice(ji+1,Njs0-1,jl) ) 1194 zmax2(ji) = MAX( epsi20, pice(ji,Njs0 ,jl), pice(ji-1,Njs0 ,jl), pice(ji+1,Njs0 ,jl) ) 1180 1195 END DO 1181 DO jj = Njs0, Nje0 1182 DO ji = Nis0, Nie0 1183 pmax(ji,jj,jl) = MAX( epsi20, zmax(ji,jj), zmax(ji,jj-1), zmax(ji,jj+1) ) 1184 END DO 1185 END DO 1196 DO_2D( 0, 0, 0, 0 ) 1197 zmax3 = MAX( epsi20, pice(ji,jj+1,jl), pice(ji-1,jj+1,jl), pice(ji+1,jj+1,jl) ) 1198 pmax(ji,jj,jl) = MAX( epsi20, zmax1(ji), zmax2(ji), zmax3 ) 1199 zmax1(ji) = zmax2(ji) 1200 zmax2(ji) = zmax3 1201 END_2D 1186 1202 END DO 1187 1203 END SUBROUTINE icemax3D … … 1192 1208 !! ** Purpose : compute the max of the 9 points around 1193 1209 !!---------------------------------------------------------------------- 1194 REAL(wp), DIMENSION(:,:,:,:) , INTENT(in ) :: pice ! input 1195 REAL(wp), DIMENSION(:,:,:,:) , INTENT(out) :: pmax ! output 1196 REAL(wp), DIMENSION(2:jpim1,jpj) :: zmax ! temporary array 1210 REAL(wp), DIMENSION(:,:,:,:), INTENT(in ) :: pice ! input 1211 REAL(wp), DIMENSION(:,:,:,:), INTENT(out) :: pmax ! output 1212 ! 1213 REAL(wp), DIMENSION(Nis0:Nie0) :: zmax1, zmax2 1214 REAL(wp) :: zmax3 1197 1215 INTEGER :: jlay, ji, jj, jk, jl ! dummy loop indices 1198 1216 !!---------------------------------------------------------------------- 1199 1217 jlay = SIZE( pice , 3 ) ! size of input arrays 1218 ! basic version: get the max of epsi20 + 9 neighbours 1219 !!$ DO jl = 1, jpl 1220 !!$ DO jk = 1, jlay 1221 !!$ DO_2D( 0, 0, 0, 0 ) 1222 !!$ pmax(ji,jj,jk,jl) = MAX( epsi20, pice(ji-1,jj-1,jk,jl), pice(ji,jj-1,jk,jl), pice(ji+1,jj-1,jk,jl), & 1223 !!$ & pice(ji-1,jj ,jk,jl), pice(ji,jj ,jk,jl), pice(ji+1,jj ,jk,jl), & 1224 !!$ & pice(ji-1,jj+1,jk,jl), pice(ji,jj+1,jk,jl), pice(ji+1,jj+1,jk,jl) ) 1225 !!$ END_2D 1226 !!$ END DO 1227 !!$ END DO 1228 ! optimized version : does a little bit more than 2 max of epsi20 + 3 neighbours 1200 1229 DO jl = 1, jpl 1201 1230 DO jk = 1, jlay 1202 DO j j = Njs0-1, Nje0+11203 DO ji = Nis0, Nie01204 zmax(ji,jj) = MAX( epsi20, pice(ji,jj,jk,jl), pice(ji-1,jj,jk,jl), pice(ji+1,jj,jk,jl) )1205 1206 END DO1207 DO jj = Njs0, Nje01208 DO ji = Nis0, Nie01209 pmax(ji,jj,jk,jl) = MAX( epsi20, zmax(ji,jj), zmax(ji,jj-1), zmax(ji,jj+1))1210 END DO1211 END DO1231 DO ji = Nis0, Nie0 1232 zmax1(ji) = MAX( epsi20, pice(ji,Njs0-1,jk,jl), pice(ji-1,Njs0-1,jk,jl), pice(ji+1,Njs0-1,jk,jl) ) 1233 zmax2(ji) = MAX( epsi20, pice(ji,Njs0 ,jk,jl), pice(ji-1,Njs0 ,jk,jl), pice(ji+1,Njs0 ,jk,jl) ) 1234 END DO 1235 DO_2D( 0, 0, 0, 0 ) 1236 zmax3 = MAX( epsi20, pice(ji,jj+1,jk,jl), pice(ji-1,jj+1,jk,jl), pice(ji+1,jj+1,jk,jl) ) 1237 pmax(ji,jj,jk,jl) = MAX( epsi20, zmax1(ji), zmax2(ji), zmax3 ) 1238 zmax1(ji) = zmax2(ji) 1239 zmax2(ji) = zmax3 1240 END_2D 1212 1241 END DO 1213 1242 END DO -
NEMO/branches/2021/ticket2632_r14588_theta_sbcblk/src/ICE/icedyn_adv_umx.F90
r14433 r15548 164 164 ! 165 165 ! --- define velocity for advection: u*grad(H) --- ! 166 DO_2D( 0, 0, 0, 0)166 DO_2D( nn_hls-1, nn_hls, nn_hls, nn_hls ) 167 167 IF ( pu_ice(ji,jj) * pu_ice(ji-1,jj) <= 0._wp ) THEN ; zcu_box(ji,jj) = 0._wp 168 168 ELSEIF( pu_ice(ji,jj) > 0._wp ) THEN ; zcu_box(ji,jj) = pu_ice(ji-1,jj) 169 169 ELSE ; zcu_box(ji,jj) = pu_ice(ji ,jj) 170 170 ENDIF 171 171 END_2D 172 DO_2D( nn_hls, nn_hls, nn_hls-1, nn_hls ) 172 173 IF ( pv_ice(ji,jj) * pv_ice(ji,jj-1) <= 0._wp ) THEN ; zcv_box(ji,jj) = 0._wp 173 174 ELSEIF( pv_ice(ji,jj) > 0._wp ) THEN ; zcv_box(ji,jj) = pv_ice(ji,jj-1) … … 204 205 IF( .NOT. ALLOCATED(jmsk_small) ) ALLOCATE( jmsk_small(jpi,jpj,jpl) ) 205 206 DO jl = 1, jpl 206 DO_2D( 1, 0, 1, 0)207 DO_2D( 1, 0, nn_hls, nn_hls ) 207 208 zvi_cen = 0.5_wp * ( pv_i(ji+1,jj,jl) + pv_i(ji,jj,jl) ) 208 209 IF( zvi_cen < epsi06) THEN ; imsk_small(ji,jj,jl) = 0 209 210 ELSE ; imsk_small(ji,jj,jl) = 1 ; ENDIF 211 END_2D 212 DO_2D( nn_hls, nn_hls, 1, 0 ) 210 213 zvi_cen = 0.5_wp * ( pv_i(ji,jj+1,jl) + pv_i(ji,jj,jl) ) 211 214 IF( zvi_cen < epsi06) THEN ; jmsk_small(ji,jj,jl) = 0 … … 583 586 ! 584 587 DO jl = 1, jpl 585 DO_2D( 1, 0, 1, 0)588 DO_2D( nn_hls, nn_hls-1, nn_hls, nn_hls-1 ) 586 589 pfu_ups(ji,jj,jl) = MAX( pu(ji,jj), 0._wp ) * pt(ji,jj,jl) + MIN( pu(ji,jj), 0._wp ) * pt(ji+1,jj,jl) 587 590 pfv_ups(ji,jj,jl) = MAX( pv(ji,jj), 0._wp ) * pt(ji,jj,jl) + MIN( pv(ji,jj), 0._wp ) * pt(ji,jj+1,jl) … … 594 597 ! 595 598 DO jl = 1, jpl !-- flux in x-direction 596 DO_2D( 1, 0, 1, 1)599 DO_2D( nn_hls, nn_hls-1, nn_hls, nn_hls ) 597 600 pfu_ups(ji,jj,jl) = MAX( pu(ji,jj), 0._wp ) * pt(ji,jj,jl) + MIN( pu(ji,jj), 0._wp ) * pt(ji+1,jj,jl) 598 601 END_2D … … 600 603 ! 601 604 DO jl = 1, jpl !-- first guess of tracer from u-flux 602 DO_2D( 0, 0, 1, 1)605 DO_2D( nn_hls-1, nn_hls-1, nn_hls, nn_hls ) 603 606 ztra = - ( pfu_ups(ji,jj,jl) - pfu_ups(ji-1,jj,jl) ) & 604 607 & + ( pu (ji,jj ) - pu (ji-1,jj ) ) * pt(ji,jj,jl) * (1.-pamsk) … … 609 612 ! 610 613 DO jl = 1, jpl !-- flux in y-direction 611 DO_2D( 0, 0, 1, 0)614 DO_2D( nn_hls-1, nn_hls-1, nn_hls, nn_hls-1 ) 612 615 pfv_ups(ji,jj,jl) = MAX( pv(ji,jj), 0._wp ) * zpt(ji,jj,jl) + MIN( pv(ji,jj), 0._wp ) * zpt(ji,jj+1,jl) 613 616 END_2D … … 617 620 ! 618 621 DO jl = 1, jpl !-- flux in y-direction 619 DO_2D( 1, 1, 1, 0)622 DO_2D( nn_hls, nn_hls, nn_hls, nn_hls-1 ) 620 623 pfv_ups(ji,jj,jl) = MAX( pv(ji,jj), 0._wp ) * pt(ji,jj,jl) + MIN( pv(ji,jj), 0._wp ) * pt(ji,jj+1,jl) 621 624 END_2D … … 623 626 ! 624 627 DO jl = 1, jpl !-- first guess of tracer from v-flux 625 DO_2D( 1, 1, 0, 0)628 DO_2D( nn_hls, nn_hls, nn_hls-1, nn_hls-1 ) 626 629 ztra = - ( pfv_ups(ji,jj,jl) - pfv_ups(ji,jj-1,jl) ) & 627 630 & + ( pv (ji,jj ) - pv (ji,jj-1 ) ) * pt(ji,jj,jl) * (1.-pamsk) … … 632 635 ! 633 636 DO jl = 1, jpl !-- flux in x-direction 634 DO_2D( 1, 0, 0, 0)637 DO_2D( nn_hls, nn_hls-1, nn_hls-1, nn_hls-1 ) 635 638 pfu_ups(ji,jj,jl) = MAX( pu(ji,jj), 0._wp ) * zpt(ji,jj,jl) + MIN( pu(ji,jj), 0._wp ) * zpt(ji+1,jj,jl) 636 639 END_2D … … 642 645 ! 643 646 DO jl = 1, jpl !-- after tracer with upstream scheme 644 DO_2D( 0, 0, 0, 0)647 DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 ) 645 648 ztra = - ( pfu_ups(ji,jj,jl) - pfu_ups(ji-1,jj ,jl) & 646 649 & + pfv_ups(ji,jj,jl) - pfv_ups(ji ,jj-1,jl) ) & … … 651 654 END_2D 652 655 END DO 653 CALL lbc_lnk( 'icedyn_adv_umx', pt_ups, 'T', 1.0_wp )656 IF( nn_hls == 1 ) CALL lbc_lnk( 'icedyn_adv_umx', pt_ups, 'T', 1.0_wp ) 654 657 655 658 END SUBROUTINE upstream … … 681 684 ! 682 685 DO jl = 1, jpl 683 DO_2D( 1, 0, 1, 1)686 DO_2D( nn_hls, nn_hls-1, nn_hls, nn_hls ) 684 687 pfu_ho(ji,jj,jl) = 0.5_wp * pu(ji,jj) * ( pt(ji,jj,jl) + pt(ji+1,jj ,jl) ) 685 688 END_2D 686 DO_2D( 1, 1, 1, 0)689 DO_2D( nn_hls, nn_hls, nn_hls, nn_hls-1 ) 687 690 pfv_ho(ji,jj,jl) = 0.5_wp * pv(ji,jj) * ( pt(ji,jj,jl) + pt(ji ,jj+1,jl) ) 688 691 END_2D … … 701 704 ! 702 705 DO jl = 1, jpl !-- flux in x-direction 703 DO_2D( 1, 0, 1, 1)706 DO_2D( nn_hls, nn_hls-1, nn_hls, nn_hls ) 704 707 pfu_ho(ji,jj,jl) = 0.5_wp * pu(ji,jj) * ( pt(ji,jj,jl) + pt(ji+1,jj,jl) ) 705 708 END_2D … … 708 711 709 712 DO jl = 1, jpl !-- first guess of tracer from u-flux 710 DO_2D( 0, 0, 1, 1)713 DO_2D( nn_hls-1, nn_hls-1, nn_hls, nn_hls ) 711 714 ztra = - ( pfu_ho(ji,jj,jl) - pfu_ho(ji-1,jj,jl) ) & 712 715 & + ( pu (ji,jj ) - pu (ji-1,jj ) ) * pt(ji,jj,jl) * (1.-pamsk) … … 717 720 718 721 DO jl = 1, jpl !-- flux in y-direction 719 DO_2D( 0, 0, 1, 0)722 DO_2D( nn_hls-1, nn_hls-1, nn_hls, nn_hls-1 ) 720 723 pfv_ho(ji,jj,jl) = 0.5_wp * pv(ji,jj) * ( zpt(ji,jj,jl) + zpt(ji,jj+1,jl) ) 721 724 END_2D … … 726 729 ! 727 730 DO jl = 1, jpl !-- flux in y-direction 728 DO_2D( 1, 1, 1, 0)731 DO_2D( nn_hls, nn_hls, nn_hls, nn_hls-1 ) 729 732 pfv_ho(ji,jj,jl) = 0.5_wp * pv(ji,jj) * ( pt(ji,jj,jl) + pt(ji,jj+1,jl) ) 730 733 END_2D … … 733 736 ! 734 737 DO jl = 1, jpl !-- first guess of tracer from v-flux 735 DO_2D( 1, 1, 0, 0)738 DO_2D( nn_hls, nn_hls, nn_hls-1, nn_hls-1 ) 736 739 ztra = - ( pfv_ho(ji,jj,jl) - pfv_ho(ji,jj-1,jl) ) & 737 740 & + ( pv (ji,jj ) - pv (ji,jj-1 ) ) * pt(ji,jj,jl) * (1.-pamsk) … … 742 745 ! 743 746 DO jl = 1, jpl !-- flux in x-direction 744 DO_2D( 1, 0, 0, 0)747 DO_2D( nn_hls, nn_hls-1, nn_hls-1, nn_hls-1 ) 745 748 pfu_ho(ji,jj,jl) = 0.5_wp * pu(ji,jj) * ( zpt(ji,jj,jl) + zpt(ji+1,jj,jl) ) 746 749 END_2D … … 785 788 ! 786 789 ! !-- ultimate interpolation of pt at u-point --! 787 CALL ultimate_x( pamsk, kn_umx, pdt, pt, pu, zt_u, pfu_ho )790 CALL ultimate_x( nn_hls, pamsk, kn_umx, pdt, pt, pu, zt_u, pfu_ho ) 788 791 ! !-- limiter in x --! 789 792 IF( np_limiter == 2 .OR. np_limiter == 3 ) CALL limiter_x( pdt, pu, pt, pfu_ups, pfu_ho ) 790 793 ! !-- advective form update in zpt --! 791 794 DO jl = 1, jpl 792 DO_2D( 0, 0, 0, 0)795 DO_2D( 0, 0, nn_hls, nn_hls ) 793 796 zpt(ji,jj,jl) = ( pt(ji,jj,jl) - ( pubox(ji,jj ) * ( zt_u(ji,jj,jl) - zt_u(ji-1,jj,jl) ) * r1_e1t (ji,jj) & 794 797 & + pt (ji,jj,jl) * ( pu (ji,jj ) - pu (ji-1,jj ) ) * r1_e1e2t(ji,jj) & … … 797 800 END_2D 798 801 END DO 799 CALL lbc_lnk( 'icedyn_adv_umx', zpt, 'T', 1.0_wp )800 802 ! 801 803 ! !-- ultimate interpolation of pt at v-point --! 802 804 IF( ll_hoxy ) THEN 803 CALL ultimate_y( pamsk, kn_umx, pdt, zpt, pv, zt_v, pfv_ho )805 CALL ultimate_y( 0, pamsk, kn_umx, pdt, zpt, pv, zt_v, pfv_ho ) 804 806 ELSE 805 CALL ultimate_y( pamsk, kn_umx, pdt, pt , pv, zt_v, pfv_ho )807 CALL ultimate_y( 0, pamsk, kn_umx, pdt, pt , pv, zt_v, pfv_ho ) 806 808 ENDIF 807 809 ! !-- limiter in y --! … … 812 814 ! 813 815 ! !-- ultimate interpolation of pt at v-point --! 814 CALL ultimate_y( pamsk, kn_umx, pdt, pt, pv, zt_v, pfv_ho )816 CALL ultimate_y( nn_hls, pamsk, kn_umx, pdt, pt, pv, zt_v, pfv_ho ) 815 817 ! !-- limiter in y --! 816 818 IF( np_limiter == 2 .OR. np_limiter == 3 ) CALL limiter_y( pdt, pv, pt, pfv_ups, pfv_ho ) 817 819 ! !-- advective form update in zpt --! 818 820 DO jl = 1, jpl 819 DO_2D( 0, 0, 0, 0 )821 DO_2D( nn_hls, nn_hls, 0, 0 ) 820 822 zpt(ji,jj,jl) = ( pt(ji,jj,jl) - ( pvbox(ji,jj ) * ( zt_v(ji,jj,jl) - zt_v(ji,jj-1,jl) ) * r1_e2t (ji,jj) & 821 823 & + pt (ji,jj,jl) * ( pv (ji,jj ) - pv (ji,jj-1 ) ) * r1_e1e2t(ji,jj) & … … 824 826 END_2D 825 827 END DO 826 CALL lbc_lnk( 'icedyn_adv_umx', zpt, 'T', 1.0_wp )827 828 ! 828 829 ! !-- ultimate interpolation of pt at u-point --! 829 830 IF( ll_hoxy ) THEN 830 CALL ultimate_x( pamsk, kn_umx, pdt, zpt, pu, zt_u, pfu_ho )831 CALL ultimate_x( 0, pamsk, kn_umx, pdt, zpt, pu, zt_u, pfu_ho ) 831 832 ELSE 832 CALL ultimate_x( pamsk, kn_umx, pdt, pt , pu, zt_u, pfu_ho )833 CALL ultimate_x( 0, pamsk, kn_umx, pdt, pt , pu, zt_u, pfu_ho ) 833 834 ENDIF 834 835 ! !-- limiter in x --! … … 842 843 843 844 844 SUBROUTINE ultimate_x( pamsk, kn_umx, pdt, pt, pu, pt_u, pfu_ho )845 SUBROUTINE ultimate_x( kloop, pamsk, kn_umx, pdt, pt, pu, pt_u, pfu_ho ) 845 846 !!--------------------------------------------------------------------- 846 847 !! *** ROUTINE ultimate_x *** … … 852 853 !! Reference : Leonard, B.P., 1991, Comput. Methods Appl. Mech. Eng., 88, 17-74. 853 854 !!---------------------------------------------------------------------- 855 INTEGER , INTENT(in ) :: kloop ! either 0 or nn_hls depending on the order of the call 854 856 REAL(wp) , INTENT(in ) :: pamsk ! advection of concentration (1) or other tracers (0) 855 857 INTEGER , INTENT(in ) :: kn_umx ! order of the scheme (1-5=UM or 20=CEN2) … … 867 869 ! !-- Laplacian in i-direction --! 868 870 DO jl = 1, jpl 869 DO jj = 2, jpjm1 ! First derivative (gradient) 870 DO ji = 1, jpim1 871 ztu1(ji,jj,jl) = ( pt(ji+1,jj,jl) - pt(ji,jj,jl) ) * r1_e1u(ji,jj) * umask(ji,jj,1) 872 END DO 873 ! ! Second derivative (Laplacian) 874 DO ji = 2, jpim1 875 ztu2(ji,jj,jl) = ( ztu1(ji,jj,jl) - ztu1(ji-1,jj,jl) ) * r1_e1t(ji,jj) 876 END DO 877 END DO 878 END DO 879 CALL lbc_lnk( 'icedyn_adv_umx', ztu2, 'T', 1.0_wp ) 871 DO_2D( nn_hls, nn_hls-1, kloop, kloop ) ! First derivative (gradient) 872 ztu1(ji,jj,jl) = ( pt(ji+1,jj,jl) - pt(ji,jj,jl) ) * r1_e1u(ji,jj) * umask(ji,jj,1) 873 END_2D 874 DO_2D( nn_hls-1, nn_hls-1, kloop, kloop ) ! Second derivative (Laplacian) 875 ztu2(ji,jj,jl) = ( ztu1(ji,jj,jl) - ztu1(ji-1,jj,jl) ) * r1_e1t(ji,jj) 876 END_2D 877 !!$ DO jj = 2, jpjm1 ! First derivative (gradient) 878 !!$ DO ji = 1, jpim1 879 !!$ ztu1(ji,jj,jl) = ( pt(ji+1,jj,jl) - pt(ji,jj,jl) ) * r1_e1u(ji,jj) * umask(ji,jj,1) 880 !!$ END DO 881 !!$ ! ! Second derivative (Laplacian) 882 !!$ DO ji = 2, jpim1 883 !!$ ztu2(ji,jj,jl) = ( ztu1(ji,jj,jl) - ztu1(ji-1,jj,jl) ) * r1_e1t(ji,jj) 884 !!$ END DO 885 !!$ END DO 886 END DO 887 IF( nn_hls == 1 ) CALL lbc_lnk( 'icedyn_adv_umx', ztu2, 'T', 1.0_wp ) 880 888 ! 881 889 ! !-- BiLaplacian in i-direction --! 882 890 DO jl = 1, jpl 883 DO jj = 2, jpjm1 ! Third derivative 884 DO ji = 1, jpim1 885 ztu3(ji,jj,jl) = ( ztu2(ji+1,jj,jl) - ztu2(ji,jj,jl) ) * r1_e1u(ji,jj) * umask(ji,jj,1) 886 END DO 887 ! ! Fourth derivative 888 DO ji = 2, jpim1 889 ztu4(ji,jj,jl) = ( ztu3(ji,jj,jl) - ztu3(ji-1,jj,jl) ) * r1_e1t(ji,jj) 890 END DO 891 END DO 892 END DO 893 CALL lbc_lnk( 'icedyn_adv_umx', ztu4, 'T', 1.0_wp ) 891 DO_2D( 1, 0, kloop, kloop ) ! Third derivative 892 ztu3(ji,jj,jl) = ( ztu2(ji+1,jj,jl) - ztu2(ji,jj,jl) ) * r1_e1u(ji,jj) * umask(ji,jj,1) 893 END_2D 894 DO_2D( 0, 0, kloop, kloop ) ! Fourth derivative 895 ztu4(ji,jj,jl) = ( ztu3(ji,jj,jl) - ztu3(ji-1,jj,jl) ) * r1_e1t(ji,jj) 896 END_2D 897 !!$ DO jj = 2, jpjm1 ! Third derivative 898 !!$ DO ji = 1, jpim1 899 !!$ ztu3(ji,jj,jl) = ( ztu2(ji+1,jj,jl) - ztu2(ji,jj,jl) ) * r1_e1u(ji,jj) * umask(ji,jj,1) 900 !!$ END DO 901 !!$ ! ! Fourth derivative 902 !!$ DO ji = 2, jpim1 903 !!$ ztu4(ji,jj,jl) = ( ztu3(ji,jj,jl) - ztu3(ji-1,jj,jl) ) * r1_e1t(ji,jj) 904 !!$ END DO 905 !!$ END DO 906 END DO 894 907 ! 895 908 ! … … 899 912 ! 900 913 DO jl = 1, jpl 901 DO_2D( 1, 0, 0, 0)914 DO_2D( 1, 0, kloop, kloop ) 902 915 pt_u(ji,jj,jl) = 0.5_wp * umask(ji,jj,1) * ( pt(ji+1,jj,jl) + pt(ji,jj,jl) & 903 916 & - SIGN( 1._wp, pu(ji,jj) ) * ( pt(ji+1,jj,jl) - pt(ji,jj,jl) ) ) … … 908 921 ! 909 922 DO jl = 1, jpl 910 DO_2D( 1, 0, 0, 0)923 DO_2D( 1, 0, kloop, kloop ) 911 924 zcu = pu(ji,jj) * r1_e2u(ji,jj) * pdt * r1_e1u(ji,jj) 912 925 pt_u(ji,jj,jl) = 0.5_wp * umask(ji,jj,1) * ( pt(ji+1,jj,jl) + pt(ji,jj,jl) & … … 918 931 ! 919 932 DO jl = 1, jpl 920 DO_2D( 1, 0, 0, 0)933 DO_2D( 1, 0, kloop, kloop ) 921 934 zcu = pu(ji,jj) * r1_e2u(ji,jj) * pdt * r1_e1u(ji,jj) 922 935 zdx2 = e1u(ji,jj) * e1u(ji,jj) … … 932 945 ! 933 946 DO jl = 1, jpl 934 DO_2D( 1, 0, 0, 0)947 DO_2D( 1, 0, kloop, kloop ) 935 948 zcu = pu(ji,jj) * r1_e2u(ji,jj) * pdt * r1_e1u(ji,jj) 936 949 zdx2 = e1u(ji,jj) * e1u(ji,jj) … … 945 958 CASE( 5 ) !== 5th order central TIM ==! (Eq. 29) 946 959 ! 947 DO jl = 1, jpl 948 DO_2D( 1, 0, 0, 0 ) 960 CALL lbc_lnk( 'icedyn_adv_umx', ztu4, 'T', 1.0_wp ) 961 ! 962 DO jl = 1, jpl 963 DO_2D( 1, 0, kloop, kloop ) 949 964 zcu = pu(ji,jj) * r1_e2u(ji,jj) * pdt * r1_e1u(ji,jj) 950 965 zdx2 = e1u(ji,jj) * e1u(ji,jj) … … 967 982 IF( ll_neg ) THEN 968 983 DO jl = 1, jpl 969 DO_2D( 1, 0, 0, 0)984 DO_2D( 1, 0, kloop, kloop ) 970 985 IF( pt_u(ji,jj,jl) < 0._wp .OR. ( imsk_small(ji,jj,jl) == 0 .AND. pamsk == 0. ) ) THEN 971 986 pt_u(ji,jj,jl) = 0.5_wp * umask(ji,jj,1) * ( pt(ji+1,jj,jl) + pt(ji,jj,jl) & … … 985 1000 986 1001 987 SUBROUTINE ultimate_y( pamsk, kn_umx, pdt, pt, pv, pt_v, pfv_ho )1002 SUBROUTINE ultimate_y( kloop, pamsk, kn_umx, pdt, pt, pv, pt_v, pfv_ho ) 988 1003 !!--------------------------------------------------------------------- 989 1004 !! *** ROUTINE ultimate_y *** … … 995 1010 !! Reference : Leonard, B.P., 1991, Comput. Methods Appl. Mech. Eng., 88, 17-74. 996 1011 !!---------------------------------------------------------------------- 1012 INTEGER , INTENT(in ) :: kloop ! either 0 or nn_hls depending on the order of the call 997 1013 REAL(wp) , INTENT(in ) :: pamsk ! advection of concentration (1) or other tracers (0) 998 1014 INTEGER , INTENT(in ) :: kn_umx ! order of the scheme (1-5=UM or 20=CEN2) … … 1010 1026 ! !-- Laplacian in j-direction --! 1011 1027 DO jl = 1, jpl 1012 DO_2D( 0, 0, 1, 0 )! First derivative (gradient)1028 DO_2D( kloop, kloop, nn_hls, nn_hls-1 ) ! First derivative (gradient) 1013 1029 ztv1(ji,jj,jl) = ( pt(ji,jj+1,jl) - pt(ji,jj,jl) ) * r1_e2v(ji,jj) * vmask(ji,jj,1) 1014 1030 END_2D 1015 DO_2D( 0, 0, 0, 0 )! Second derivative (Laplacian)1031 DO_2D( kloop, kloop, nn_hls-1, nn_hls-1 ) ! Second derivative (Laplacian) 1016 1032 ztv2(ji,jj,jl) = ( ztv1(ji,jj,jl) - ztv1(ji,jj-1,jl) ) * r1_e2t(ji,jj) 1017 1033 END_2D 1018 1034 END DO 1019 CALL lbc_lnk( 'icedyn_adv_umx', ztv2, 'T', 1.0_wp )1035 IF( nn_hls == 1 ) CALL lbc_lnk( 'icedyn_adv_umx', ztv2, 'T', 1.0_wp ) 1020 1036 ! 1021 1037 ! !-- BiLaplacian in j-direction --! 1022 1038 DO jl = 1, jpl 1023 DO_2D( 0, 0, 1, 0 ) ! Firstderivative1039 DO_2D( kloop, kloop, 1, 0 ) ! Third derivative 1024 1040 ztv3(ji,jj,jl) = ( ztv2(ji,jj+1,jl) - ztv2(ji,jj,jl) ) * r1_e2v(ji,jj) * vmask(ji,jj,1) 1025 1041 END_2D 1026 DO_2D( 0, 0, 0, 0 ) ! Secondderivative1042 DO_2D( kloop, kloop, 0, 0 ) ! Fourth derivative 1027 1043 ztv4(ji,jj,jl) = ( ztv3(ji,jj,jl) - ztv3(ji,jj-1,jl) ) * r1_e2t(ji,jj) 1028 1044 END_2D 1029 1045 END DO 1030 CALL lbc_lnk( 'icedyn_adv_umx', ztv4, 'T', 1.0_wp )1031 1046 ! 1032 1047 ! … … 1035 1050 CASE( 1 ) !== 1st order central TIM ==! (Eq. 21) 1036 1051 DO jl = 1, jpl 1037 DO_2D( 0, 0, 1, 0 )1052 DO_2D( kloop, kloop, 1, 0 ) 1038 1053 pt_v(ji,jj,jl) = 0.5_wp * vmask(ji,jj,1) * ( pt(ji,jj+1,jl) + pt(ji,jj,jl) & 1039 1054 & - SIGN( 1._wp, pv(ji,jj) ) * ( pt(ji,jj+1,jl) - pt(ji,jj,jl) ) ) … … 1043 1058 CASE( 2 ) !== 2nd order central TIM ==! (Eq. 23) 1044 1059 DO jl = 1, jpl 1045 DO_2D( 0, 0, 1, 0 )1060 DO_2D( kloop, kloop, 1, 0 ) 1046 1061 zcv = pv(ji,jj) * r1_e1v(ji,jj) * pdt * r1_e2v(ji,jj) 1047 1062 pt_v(ji,jj,jl) = 0.5_wp * vmask(ji,jj,1) * ( pt(ji,jj+1,jl) + pt(ji,jj,jl) & … … 1052 1067 CASE( 3 ) !== 3rd order central TIM ==! (Eq. 24) 1053 1068 DO jl = 1, jpl 1054 DO_2D( 0, 0, 1, 0 )1069 DO_2D( kloop, kloop, 1, 0 ) 1055 1070 zcv = pv(ji,jj) * r1_e1v(ji,jj) * pdt * r1_e2v(ji,jj) 1056 1071 zdy2 = e2v(ji,jj) * e2v(ji,jj) … … 1065 1080 CASE( 4 ) !== 4th order central TIM ==! (Eq. 27) 1066 1081 DO jl = 1, jpl 1067 DO_2D( 0, 0, 1, 0 )1082 DO_2D( kloop, kloop, 1, 0 ) 1068 1083 zcv = pv(ji,jj) * r1_e1v(ji,jj) * pdt * r1_e2v(ji,jj) 1069 1084 zdy2 = e2v(ji,jj) * e2v(ji,jj) … … 1077 1092 ! 1078 1093 CASE( 5 ) !== 5th order central TIM ==! (Eq. 29) 1079 DO jl = 1, jpl 1080 DO_2D( 0, 0, 1, 0 ) 1094 ! 1095 CALL lbc_lnk( 'icedyn_adv_umx', ztv4, 'T', 1.0_wp ) 1096 ! 1097 DO jl = 1, jpl 1098 DO_2D( kloop, kloop, 1, 0 ) 1081 1099 zcv = pv(ji,jj) * r1_e1v(ji,jj) * pdt * r1_e2v(ji,jj) 1082 1100 zdy2 = e2v(ji,jj) * e2v(ji,jj) … … 1099 1117 IF( ll_neg ) THEN 1100 1118 DO jl = 1, jpl 1101 DO_2D( 0, 0, 1, 0 )1119 DO_2D( kloop, kloop, 1, 0 ) 1102 1120 IF( pt_v(ji,jj,jl) < 0._wp .OR. ( jmsk_small(ji,jj,jl) == 0 .AND. pamsk == 0. ) ) THEN 1103 1121 pt_v(ji,jj,jl) = 0.5_wp * vmask(ji,jj,1) * ( ( pt(ji,jj+1,jl) + pt(ji,jj,jl) ) & … … 1299 1317 ! 1300 1318 DO jl = 1, jpl 1301 DO_2D( 0, 0, 0, 0 )1319 DO_2D( nn_hls, nn_hls-1, 0, 0 ) 1302 1320 zslpx(ji,jj,jl) = ( pt(ji+1,jj,jl) - pt(ji,jj,jl) ) * umask(ji,jj,1) 1303 1321 END_2D 1304 1322 END DO 1305 CALL lbc_lnk( 'icedyn_adv_umx', zslpx, 'U', -1.0_wp) ! lateral boundary cond.1306 1307 DO jl = 1, jpl 1308 DO_2D( 0, 0, 0, 0 )1323 IF( nn_hls == 1 ) CALL lbc_lnk( 'icedyn_adv_umx', zslpx, 'U', -1.0_wp) ! lateral boundary cond. 1324 1325 DO jl = 1, jpl 1326 DO_2D( nn_hls-1, 0, 0, 0 ) 1309 1327 uCFL = pdt * ABS( pu(ji,jj) ) * r1_e1e2t(ji,jj) 1310 1328 … … 1367 1385 END_2D 1368 1386 END DO 1369 CALL lbc_lnk( 'icedyn_adv_umx', pfu_ho, 'U', -1.0_wp) ! lateral boundary cond.1387 IF( nn_hls == 1 ) CALL lbc_lnk( 'icedyn_adv_umx', pfu_ho, 'U', -1.0_wp) ! lateral boundary cond. 1370 1388 ! 1371 1389 END SUBROUTINE limiter_x … … 1390 1408 ! 1391 1409 DO jl = 1, jpl 1392 DO_2D( 0, 0, 0, 0)1410 DO_2D( 0, 0, nn_hls, nn_hls-1 ) 1393 1411 zslpy(ji,jj,jl) = ( pt(ji,jj+1,jl) - pt(ji,jj,jl) ) * vmask(ji,jj,1) 1394 1412 END_2D 1395 1413 END DO 1396 CALL lbc_lnk( 'icedyn_adv_umx', zslpy, 'V', -1.0_wp) ! lateral boundary cond.1397 1398 DO jl = 1, jpl 1399 DO_2D( 0, 0, 0, 0 )1414 IF( nn_hls == 1 ) CALL lbc_lnk( 'icedyn_adv_umx', zslpy, 'V', -1.0_wp) ! lateral boundary cond. 1415 1416 DO jl = 1, jpl 1417 DO_2D( 0, 0, nn_hls-1, 0 ) 1400 1418 vCFL = pdt * ABS( pv(ji,jj) ) * r1_e1e2t(ji,jj) 1401 1419 … … 1459 1477 END_2D 1460 1478 END DO 1461 CALL lbc_lnk( 'icedyn_adv_umx', pfv_ho, 'V', -1.0_wp) ! lateral boundary cond.1479 IF( nn_hls == 1 ) CALL lbc_lnk( 'icedyn_adv_umx', pfv_ho, 'V', -1.0_wp) ! lateral boundary cond. 1462 1480 ! 1463 1481 END SUBROUTINE limiter_y … … 1494 1512 ! 1495 1513 DO jl = 1, jpl 1496 DO_2D( 1, 1, 1, 1)1514 DO_2D( nn_hls, nn_hls, nn_hls, nn_hls ) 1497 1515 IF ( pv_i(ji,jj,jl) > 0._wp ) THEN 1498 1516 ! … … 1541 1559 ! ! -- check e_i/v_i -- ! 1542 1560 DO jl = 1, jpl 1543 DO_3D( 1, 1, 1, 1, 1, nlay_i )1561 DO_3D( nn_hls, nn_hls, nn_hls, nn_hls, 1, nlay_i ) 1544 1562 IF ( pv_i(ji,jj,jl) > 0._wp ) THEN 1545 1563 ! if e_i/v_i is larger than the surrounding 9 pts => put the heat excess in the ocean … … 1555 1573 ! ! -- check e_s/v_s -- ! 1556 1574 DO jl = 1, jpl 1557 DO_3D( 1, 1, 1, 1, 1, nlay_s )1575 DO_3D( nn_hls, nn_hls, nn_hls, nn_hls, 1, nlay_s ) 1558 1576 IF ( pv_s(ji,jj,jl) > 0._wp ) THEN 1559 1577 ! if e_s/v_s is larger than the surrounding 9 pts => put the heat excess in the ocean … … 1598 1616 ! -- check snow load -- ! 1599 1617 DO jl = 1, jpl 1600 DO_2D( 1, 1, 1, 1)1618 DO_2D( nn_hls, nn_hls, nn_hls, nn_hls ) 1601 1619 IF ( pv_i(ji,jj,jl) > 0._wp ) THEN 1602 1620 ! … … 1627 1645 !! ** Purpose : compute the max of the 9 points around 1628 1646 !!---------------------------------------------------------------------- 1629 REAL(wp), DIMENSION(:,:,:) , INTENT(in ) :: pice ! input 1630 REAL(wp), DIMENSION(:,:,:) , INTENT(out) :: pmax ! output 1631 REAL(wp), DIMENSION(2:jpim1,jpj) :: zmax ! temporary array 1647 REAL(wp), DIMENSION(:,:,:), INTENT(in ) :: pice ! input 1648 REAL(wp), DIMENSION(:,:,:), INTENT(out) :: pmax ! output 1649 ! 1650 REAL(wp), DIMENSION(Nis0:Nie0) :: zmax1, zmax2 1651 REAL(wp) :: zmax3 1632 1652 INTEGER :: ji, jj, jl ! dummy loop indices 1633 1653 !!---------------------------------------------------------------------- 1634 DO jl = 1, jpl 1635 DO jj = Njs0-1, Nje0+1 1636 DO ji = Nis0, Nie0 1637 zmax(ji,jj) = MAX( epsi20, pice(ji,jj,jl), pice(ji-1,jj,jl), pice(ji+1,jj,jl) ) 1638 END DO 1639 END DO 1640 DO jj = Njs0, Nje0 1641 DO ji = Nis0, Nie0 1642 pmax(ji,jj,jl) = MAX( epsi20, zmax(ji,jj), zmax(ji,jj-1), zmax(ji,jj+1) ) 1643 END DO 1644 END DO 1654 ! basic version: get the max of epsi20 + 9 neighbours 1655 !!$ DO jl = 1, jpl 1656 !!$ DO_2D( 0, 0, 0, 0 ) 1657 !!$ pmax(ji,jj,jl) = MAX( epsi20, pice(ji-1,jj-1,jl), pice(ji,jj-1,jl), pice(ji+1,jj-1,jl), & 1658 !!$ & pice(ji-1,jj ,jl), pice(ji,jj ,jl), pice(ji+1,jj ,jl), & 1659 !!$ & pice(ji-1,jj+1,jl), pice(ji,jj+1,jl), pice(ji+1,jj+1,jl) ) 1660 !!$ END_2D 1661 !!$ END DO 1662 ! optimized version : does a little bit more than 2 max of epsi20 + 3 neighbours 1663 DO jl = 1, jpl 1664 DO ji = Nis0, Nie0 1665 zmax1(ji) = MAX( epsi20, pice(ji,Njs0-1,jl), pice(ji-1,Njs0-1,jl), pice(ji+1,Njs0-1,jl) ) 1666 zmax2(ji) = MAX( epsi20, pice(ji,Njs0 ,jl), pice(ji-1,Njs0 ,jl), pice(ji+1,Njs0 ,jl) ) 1667 END DO 1668 DO_2D( 0, 0, 0, 0 ) 1669 zmax3 = MAX( epsi20, pice(ji,jj+1,jl), pice(ji-1,jj+1,jl), pice(ji+1,jj+1,jl) ) 1670 pmax(ji,jj,jl) = MAX( epsi20, zmax1(ji), zmax2(ji), zmax3 ) 1671 zmax1(ji) = zmax2(ji) 1672 zmax2(ji) = zmax3 1673 END_2D 1645 1674 END DO 1646 1675 END SUBROUTINE icemax3D … … 1651 1680 !! ** Purpose : compute the max of the 9 points around 1652 1681 !!---------------------------------------------------------------------- 1653 REAL(wp), DIMENSION(:,:,:,:) , INTENT(in ) :: pice ! input 1654 REAL(wp), DIMENSION(:,:,:,:) , INTENT(out) :: pmax ! output 1655 REAL(wp), DIMENSION(2:jpim1,jpj) :: zmax ! temporary array 1682 REAL(wp), DIMENSION(:,:,:,:), INTENT(in ) :: pice ! input 1683 REAL(wp), DIMENSION(:,:,:,:), INTENT(out) :: pmax ! output 1684 ! 1685 REAL(wp), DIMENSION(Nis0:Nie0) :: zmax1, zmax2 1686 REAL(wp) :: zmax3 1656 1687 INTEGER :: jlay, ji, jj, jk, jl ! dummy loop indices 1657 1688 !!---------------------------------------------------------------------- 1658 1689 jlay = SIZE( pice , 3 ) ! size of input arrays 1690 ! basic version: get the max of epsi20 + 9 neighbours 1691 !!$ DO jl = 1, jpl 1692 !!$ DO jk = 1, jlay 1693 !!$ DO_2D( 0, 0, 0, 0 ) 1694 !!$ pmax(ji,jj,jk,jl) = MAX( epsi20, pice(ji-1,jj-1,jk,jl), pice(ji,jj-1,jk,jl), pice(ji+1,jj-1,jk,jl), & 1695 !!$ & pice(ji-1,jj ,jk,jl), pice(ji,jj ,jk,jl), pice(ji+1,jj ,jk,jl), & 1696 !!$ & pice(ji-1,jj+1,jk,jl), pice(ji,jj+1,jk,jl), pice(ji+1,jj+1,jk,jl) ) 1697 !!$ END_2D 1698 !!$ END DO 1699 !!$ END DO 1700 ! optimized version : does a little bit more than 2 max of epsi20 + 3 neighbours 1659 1701 DO jl = 1, jpl 1660 1702 DO jk = 1, jlay 1661 DO j j = Njs0-1, Nje0+11662 DO ji = Nis0, Nie01663 zmax(ji,jj) = MAX( epsi20, pice(ji,jj,jk,jl), pice(ji-1,jj,jk,jl), pice(ji+1,jj,jk,jl) )1664 1665 END DO1666 DO jj = Njs0, Nje01667 DO ji = Nis0, Nie01668 pmax(ji,jj,jk,jl) = MAX( epsi20, zmax(ji,jj), zmax(ji,jj-1), zmax(ji,jj+1))1669 END DO1670 END DO1703 DO ji = Nis0, Nie0 1704 zmax1(ji) = MAX( epsi20, pice(ji,Njs0-1,jk,jl), pice(ji-1,Njs0-1,jk,jl), pice(ji+1,Njs0-1,jk,jl) ) 1705 zmax2(ji) = MAX( epsi20, pice(ji,Njs0 ,jk,jl), pice(ji-1,Njs0 ,jk,jl), pice(ji+1,Njs0 ,jk,jl) ) 1706 END DO 1707 DO_2D( 0, 0, 0, 0 ) 1708 zmax3 = MAX( epsi20, pice(ji,jj+1,jk,jl), pice(ji-1,jj+1,jk,jl), pice(ji+1,jj+1,jk,jl) ) 1709 pmax(ji,jj,jk,jl) = MAX( epsi20, zmax1(ji), zmax2(ji), zmax3 ) 1710 zmax1(ji) = zmax2(ji) 1711 zmax2(ji) = zmax3 1712 END_2D 1671 1713 END DO 1672 1714 END DO -
NEMO/branches/2021/ticket2632_r14588_theta_sbcblk/src/ICE/icedyn_rdgrft.F90
r14072 r15548 57 57 ! 58 58 ! ** namelist (namdyn_rdgrft) ** 59 LOGICAL :: ln_str_H79 ! ice strength parameterization (Hibler79)60 REAL(wp) :: rn_pstar ! determines ice strength, Hibler JPO7961 59 REAL(wp) :: rn_csrdg ! fraction of shearing energy contributing to ridging 62 60 LOGICAL :: ln_partf_lin ! participation function linear (Thorndike et al. (1975)) … … 162 160 npti = 0 ; nptidx(:) = 0 163 161 ipti = 0 ; iptidx(:) = 0 164 DO_2D( 1, 1, 1, 1)162 DO_2D( nn_hls, nn_hls, nn_hls, nn_hls ) 165 163 IF ( at_i(ji,jj) > epsi10 ) THEN 166 164 npti = npti + 1 … … 272 270 273 271 ! controls 274 IF( sn_cfctl%l_prtctl ) CALL ice_prt3D ('icedyn_rdgrft')! prints272 IF( sn_cfctl%l_prtctl ) CALL ice_prt3D('icedyn_rdgrft') ! prints 275 273 IF( ln_icectl ) CALL ice_prt (kt, iiceprt, jiceprt,-1, ' - ice dyn rdgrft - ') ! prints 276 274 IF( ln_icediachk ) CALL ice_cons_hsm(1, 'icedyn_rdgrft', rdiag_v, rdiag_s, rdiag_t, rdiag_fv, rdiag_fs, rdiag_ft) ! conservation … … 520 518 ! 521 519 INTEGER , DIMENSION(jpij) :: itest_rdg, itest_rft ! test for conservation 520 LOGICAL , DIMENSION(jpij) :: ll_shift ! logical for doing calculation or not 522 521 !!------------------------------------------------------------------- 523 522 ! … … 540 539 DO ji = 1, npti 541 540 542 IF( apartf(ji,jl1) > 0._wp .AND. closing_gross(ji) > 0._wp ) THEN ! only if ice is ridging 541 ! set logical to true when ridging 542 IF( apartf(ji,jl1) > 0._wp .AND. closing_gross(ji) > 0._wp ) THEN ; ll_shift(ji) = .TRUE. 543 ELSE ; ll_shift(ji) = .FALSE. 544 ENDIF 545 546 IF( ll_shift(ji) ) THEN ! only if ice is ridging 543 547 544 548 IF( a_i_2d(ji,jl1) > epsi10 ) THEN ; z1_ai(ji) = 1._wp / a_i_2d(ji,jl1) … … 630 634 DO jk = 1, nlay_s 631 635 DO ji = 1, npti 632 IF( apartf(ji,jl1) > 0._wp .AND. closing_gross(ji) > 0._wp) THEN636 IF( ll_shift(ji) ) THEN 633 637 ! Compute ridging /rafting fractions 634 638 afrdg = aridge(ji,jl1) * closing_gross(ji) * rDt_ice * z1_ai(ji) … … 651 655 DO jk = 1, nlay_i 652 656 DO ji = 1, npti 653 IF( apartf(ji,jl1) > 0._wp .AND. closing_gross(ji) > 0._wp) THEN657 IF( ll_shift(ji) ) THEN 654 658 ! Compute ridging /rafting fractions 655 659 afrdg = aridge(ji,jl1) * closing_gross(ji) * rDt_ice * z1_ai(ji) … … 674 678 DO ji = 1, npti 675 679 676 IF( apartf(ji,jl1) > 0._wp .AND. closing_gross(ji) > 0._wp) THEN680 IF( ll_shift(ji) ) THEN 677 681 678 682 ! Compute the fraction of ridged ice area and volume going to thickness category jl2 … … 731 735 DO jk = 1, nlay_s 732 736 DO ji = 1, npti 733 IF( apartf(ji,jl1) > 0._wp .AND. closing_gross(ji) > 0._wp) &737 IF( ll_shift(ji) ) & 734 738 & ze_s_2d(ji,jk,jl2) = ze_s_2d(ji,jk,jl2) + ( esrdg(ji,jk) * rn_fsnwrdg * fvol(ji) + & 735 739 & esrft(ji,jk) * rn_fsnwrft * zswitch(ji) ) … … 740 744 DO jk = 1, nlay_i 741 745 DO ji = 1, npti 742 IF( apartf(ji,jl1) > 0._wp .AND. closing_gross(ji) > 0._wp) &746 IF( ll_shift(ji) ) & 743 747 & ze_i_2d(ji,jk,jl2) = ze_i_2d(ji,jk,jl2) + eirdg(ji,jk) * fvol(ji) + eirft(ji,jk) * zswitch(ji) 744 748 END DO -
NEMO/branches/2021/ticket2632_r14588_theta_sbcblk/src/ICE/icedyn_rhg_eap.F90
r14433 r15548 58 58 59 59 REAL(wp), DIMENSION(nx_yield, ny_yield, na_yield) :: s11r, s12r, s22r, s11s, s12s, s22s 60 REAL(wp), DIMENSION(:,:), ALLOCATABLE :: fimask ! mask at F points for the ice 61 62 !! for convergence tests 63 INTEGER :: ncvgid ! netcdf file id 64 INTEGER :: nvarid ! netcdf variable id 60 65 61 66 !! * Substitutions 62 67 # include "do_loop_substitute.h90" 63 68 # include "domzgr_substitute.h90" 64 65 !! for convergence tests66 INTEGER :: ncvgid ! netcdf file id67 INTEGER :: nvarid ! netcdf variable id68 REAL(wp), ALLOCATABLE, DIMENSION(:,:) :: aimsk0069 REAL(wp), ALLOCATABLE, DIMENSION(:,:) :: eap_res , aimsk1570 69 !!---------------------------------------------------------------------- 71 70 !! NEMO/ICE 4.0 , NEMO Consortium (2018) … … 180 179 REAL(wp), DIMENSION(jpi,jpj) :: ztaux_base, ztauy_base ! ice-bottom stress at U-V points (landfast) 181 180 ! 181 REAL(wp), DIMENSION(jpi,jpj) :: zmsk00, zmsk15 182 182 REAL(wp), DIMENSION(jpi,jpj) :: zmsk01x, zmsk01y ! dummy arrays 183 183 REAL(wp), DIMENSION(jpi,jpj) :: zmsk00x, zmsk00y ! mask for ice presence 184 REAL(wp), DIMENSION(jpi,jpj) :: zfmask ! mask at F points for the ice185 184 186 185 REAL(wp), PARAMETER :: zepsi = 1.0e-20_wp ! tolerance parameter … … 203 202 IF( kt == nit000 .AND. lwp ) WRITE(numout,*) '-- ice_dyn_rhg_eap: EAP sea-ice rheology' 204 203 ! 205 IF( kt == nit000 ) THEN 206 ! 207 ! for diagnostics 208 ALLOCATE( aimsk00(jpi,jpj) ) 209 ! for convergence tests 210 IF( nn_rhg_chkcvg > 0 ) ALLOCATE( eap_res(jpi,jpj), aimsk15(jpi,jpj) ) 211 ENDIF 212 ! 204 ! for diagnostics and convergence tests 213 205 DO_2D( 1, 1, 1, 1 ) 214 aimsk00(ji,jj) = MAX( 0._wp , SIGN( 1._wp , at_i(ji,jj) - epsi06 ) ) ! 1 if ice , 0 if no ice206 zmsk00(ji,jj) = MAX( 0._wp , SIGN( 1._wp , at_i(ji,jj) - epsi06 ) ) ! 1 if ice , 0 if no ice 215 207 END_2D 216 208 IF( nn_rhg_chkcvg > 0 ) THEN 217 209 DO_2D( 1, 1, 1, 1 ) 218 aimsk15(ji,jj) = MAX( 0._wp , SIGN( 1._wp , at_i(ji,jj) - 0.15_wp ) ) ! 1 if 15% ice, 0 if less210 zmsk15(ji,jj) = MAX( 0._wp , SIGN( 1._wp , at_i(ji,jj) - 0.15_wp ) ) ! 1 if 15% ice, 0 if less 219 211 END_2D 220 212 ENDIF 221 213 ! 222 !!gm for Clem: OPTIMIZATION: I think zfmask can be computed one for all at the initialization....223 214 !------------------------------------------------------------------------------! 224 215 ! 0) mask at F points for the ice 225 216 !------------------------------------------------------------------------------! 226 ! ocean/land mask 227 DO_2D( 1, 0, 1, 0 ) 228 zfmask(ji,jj) = tmask(ji,jj,1) * tmask(ji+1,jj,1) * tmask(ji,jj+1,1) * tmask(ji+1,jj+1,1) 229 END_2D 230 CALL lbc_lnk( 'icedyn_rhg_eap', zfmask, 'F', 1._wp ) 231 232 ! Lateral boundary conditions on velocity (modify zfmask) 233 DO_2D( 0, 0, 0, 0 ) 234 IF( zfmask(ji,jj) == 0._wp ) THEN 235 zfmask(ji,jj) = rn_ishlat * MIN( 1._wp , MAX( umask(ji,jj,1), umask(ji,jj+1,1), & 236 & vmask(ji,jj,1), vmask(ji+1,jj,1) ) ) 217 IF( kt == nit000 ) THEN 218 ! ocean/land mask 219 ALLOCATE( fimask(jpi,jpj) ) 220 IF( rn_ishlat == 0._wp ) THEN 221 DO_2D( 0, 0, 0, 0 ) 222 fimask(ji,jj) = tmask(ji,jj,1) * tmask(ji+1,jj,1) * tmask(ji,jj+1,1) * tmask(ji+1,jj+1,1) 223 END_2D 224 ELSE 225 DO_2D( 0, 0, 0, 0 ) 226 fimask(ji,jj) = tmask(ji,jj,1) * tmask(ji+1,jj,1) * tmask(ji,jj+1,1) * tmask(ji+1,jj+1,1) 227 ! Lateral boundary conditions on velocity (modify fimask) 228 IF( fimask(ji,jj) == 0._wp ) THEN 229 fimask(ji,jj) = rn_ishlat * MIN( 1._wp , MAX( umask(ji,jj,1), umask(ji,jj+1,1), & 230 & vmask(ji,jj,1), vmask(ji+1,jj,1) ) ) 231 ENDIF 232 END_2D 237 233 ENDIF 238 END_2D 239 DO jj = 2, jpjm1 240 IF( zfmask(1,jj) == 0._wp ) THEN 241 zfmask(1 ,jj) = rn_ishlat * MIN( 1._wp , MAX( vmask(2,jj,1), umask(1,jj+1,1), umask(1,jj,1) ) ) 242 ENDIF 243 IF( zfmask(jpi,jj) == 0._wp ) THEN 244 zfmask(jpi,jj) = rn_ishlat * MIN( 1._wp , MAX( umask(jpi,jj+1,1), vmask(jpim1,jj,1), umask(jpi,jj-1,1) ) ) 245 ENDIF 246 END DO 247 DO ji = 2, jpim1 248 IF( zfmask(ji,1) == 0._wp ) THEN 249 zfmask(ji, 1 ) = rn_ishlat * MIN( 1._wp , MAX( vmask(ji+1,1,1), umask(ji,2,1), vmask(ji,1,1) ) ) 250 ENDIF 251 IF( zfmask(ji,jpj) == 0._wp ) THEN 252 zfmask(ji,jpj) = rn_ishlat * MIN( 1._wp , MAX( vmask(ji+1,jpj,1), vmask(ji-1,jpj,1), umask(ji,jpjm1,1) ) ) 253 ENDIF 254 END DO 255 CALL lbc_lnk( 'icedyn_rhg_eap', zfmask, 'F', 1.0_wp ) 234 CALL lbc_lnk( 'icedyn_rhg_eap', fimask, 'F', 1.0_wp ) 235 ENDIF 256 236 257 237 !------------------------------------------------------------------------------! … … 401 381 zds(ji,jj) = ( ( u_ice(ji,jj+1) * r1_e1u(ji,jj+1) - u_ice(ji,jj) * r1_e1u(ji,jj) ) * e1f(ji,jj) * e1f(ji,jj) & 402 382 & + ( v_ice(ji+1,jj) * r1_e2v(ji+1,jj) - v_ice(ji,jj) * r1_e2v(ji,jj) ) * e2f(ji,jj) * e2f(ji,jj) & 403 & ) * r1_e1e2f(ji,jj) * zfmask(ji,jj)383 & ) * r1_e1e2f(ji,jj) * fimask(ji,jj) 404 384 405 385 END_2D … … 760 740 761 741 ! convergence test 762 IF( nn_rhg_chkcvg == 2 ) CALL rhg_cvg_eap( kt, jter, nn_nevp, u_ice, v_ice, zu_ice, zv_ice )742 IF( nn_rhg_chkcvg == 2 ) CALL rhg_cvg_eap( kt, jter, nn_nevp, u_ice, v_ice, zu_ice, zv_ice, zmsk15 ) 763 743 ! 764 744 ! ! ==================== ! … … 777 757 zds(ji,jj) = ( ( u_ice(ji,jj+1) * r1_e1u(ji,jj+1) - u_ice(ji,jj) * r1_e1u(ji,jj) ) * e1f(ji,jj) * e1f(ji,jj) & 778 758 & + ( v_ice(ji+1,jj) * r1_e2v(ji+1,jj) - v_ice(ji,jj) * r1_e2v(ji,jj) ) * e2f(ji,jj) * e2f(ji,jj) & 779 & ) * r1_e1e2f(ji,jj) * zfmask(ji,jj)759 & ) * r1_e1e2f(ji,jj) * fimask(ji,jj) 780 760 781 761 END_2D … … 830 810 & ztauy_ai, 'V', -1.0_wp, ztaux_bi, 'U', -1.0_wp, ztauy_bi, 'V', -1.0_wp ) 831 811 ! 832 CALL iom_put( 'utau_oi' , ztaux_oi * aimsk00 )833 CALL iom_put( 'vtau_oi' , ztauy_oi * aimsk00 )834 CALL iom_put( 'utau_ai' , ztaux_ai * aimsk00 )835 CALL iom_put( 'vtau_ai' , ztauy_ai * aimsk00 )836 CALL iom_put( 'utau_bi' , ztaux_bi * aimsk00 )837 CALL iom_put( 'vtau_bi' , ztauy_bi * aimsk00 )812 CALL iom_put( 'utau_oi' , ztaux_oi * zmsk00 ) 813 CALL iom_put( 'vtau_oi' , ztauy_oi * zmsk00 ) 814 CALL iom_put( 'utau_ai' , ztaux_ai * zmsk00 ) 815 CALL iom_put( 'vtau_ai' , ztauy_ai * zmsk00 ) 816 CALL iom_put( 'utau_bi' , ztaux_bi * zmsk00 ) 817 CALL iom_put( 'vtau_bi' , ztauy_bi * zmsk00 ) 838 818 ENDIF 839 819 840 820 ! --- divergence, shear and strength --- ! 841 IF( iom_use('icediv') ) CALL iom_put( 'icediv' , pdivu_i * aimsk00 ) ! divergence842 IF( iom_use('iceshe') ) CALL iom_put( 'iceshe' , pshear_i * aimsk00 ) ! shear843 IF( iom_use('icedlt') ) CALL iom_put( 'icedlt' , pdelta_i * aimsk00 ) ! delta844 IF( iom_use('icestr') ) CALL iom_put( 'icestr' , strength * aimsk00 ) ! strength821 IF( iom_use('icediv') ) CALL iom_put( 'icediv' , pdivu_i * zmsk00 ) ! divergence 822 IF( iom_use('iceshe') ) CALL iom_put( 'iceshe' , pshear_i * zmsk00 ) ! shear 823 IF( iom_use('icedlt') ) CALL iom_put( 'icedlt' , pdelta_i * zmsk00 ) ! delta 824 IF( iom_use('icestr') ) CALL iom_put( 'icestr' , strength * zmsk00 ) ! strength 845 825 846 826 ! --- Stress tensor invariants (SIMIP diags) --- ! … … 861 841 862 842 ! Stress invariants (sigma_I, sigma_II, Coon 1974, Feltham 2008) 863 zsig_I (ji,jj) = zsig1 * 0.5_wp 864 zsig_II(ji,jj) = SQRT ( MAX( 0._wp, zsig2 * zsig2 * 0.25_wp + zsig12 ) ) ! 2nd '' '', aka maximum shear stress843 zsig_I (ji,jj) = zsig1 * 0.5_wp ! 1st stress invariant, aka average normal stress, aka negative pressure 844 zsig_II(ji,jj) = SQRT ( zsig2 * zsig2 * 0.25_wp + zsig12 * zsig12 ) ! 2nd '' '' , aka maximum shear stress 865 845 866 846 END_2D 867 847 ! 868 848 ! Stress tensor invariants (normal and shear stress N/m) - SIMIP diags - definitions following Coon (1974) and Feltham (2008) 869 IF( iom_use('normstr') ) CALL iom_put( 'normstr', zsig_I (:,:) * aimsk00(:,:) ) ! Normal stress870 IF( iom_use('sheastr') ) CALL iom_put( 'sheastr', zsig_II(:,:) * aimsk00(:,:) ) ! Maximum shear stress849 IF( iom_use('normstr') ) CALL iom_put( 'normstr', zsig_I (:,:) * zmsk00(:,:) ) ! Normal stress 850 IF( iom_use('sheastr') ) CALL iom_put( 'sheastr', zsig_II(:,:) * zmsk00(:,:) ) ! Maximum shear stress 871 851 872 852 DEALLOCATE ( zsig_I, zsig_II ) … … 893 873 894 874 ! Stress invariants (sigma_I, sigma_II, Coon 1974, Feltham 2008), T-point 895 zsig_I(ji,jj) = zsig1 * 0.5_wp 896 zsig_II(ji,jj) = SQRT ( MAX( 0._wp, zsig2 * zsig2 * 0.25_wp + zsig12 ) ) ! 2nd '' '', aka maximum shear stress875 zsig_I(ji,jj) = zsig1 * 0.5_wp ! 1st stress invariant, aka average normal stress, aka negative pressure 876 zsig_II(ji,jj) = SQRT ( zsig2 * zsig2 * 0.25_wp + zsig12 * zsig12 ) ! 2nd '' '' , aka maximum shear stress 897 877 898 878 ! Normalized principal stresses (used to display the ellipse) … … 914 894 CALL lbc_lnk( 'icedyn_rhg_eap', zyield11, 'T', 1.0_wp, zyield22, 'T', 1.0_wp, zyield12, 'T', 1.0_wp ) 915 895 916 CALL iom_put( 'yield11', zyield11 * aimsk00 )917 CALL iom_put( 'yield22', zyield22 * aimsk00 )918 CALL iom_put( 'yield12', zyield12 * aimsk00 )896 CALL iom_put( 'yield11', zyield11 * zmsk00 ) 897 CALL iom_put( 'yield22', zyield22 * zmsk00 ) 898 CALL iom_put( 'yield12', zyield12 * zmsk00 ) 919 899 ENDIF 920 900 … … 922 902 IF( iom_use('aniso') ) THEN 923 903 CALL lbc_lnk( 'icedyn_rhg_eap', paniso_11, 'T', 1.0_wp ) 924 CALL iom_put( 'aniso' , paniso_11 * aimsk00 )904 CALL iom_put( 'aniso' , paniso_11 * zmsk00 ) 925 905 ENDIF 926 906 … … 933 913 & zfU, 'U', -1.0_wp, zfV, 'V', -1.0_wp ) 934 914 935 CALL iom_put( 'dssh_dx' , zspgU * aimsk00 ) ! Sea-surface tilt term in force balance (x)936 CALL iom_put( 'dssh_dy' , zspgV * aimsk00 ) ! Sea-surface tilt term in force balance (y)937 CALL iom_put( 'corstrx' , zCorU * aimsk00 ) ! Coriolis force term in force balance (x)938 CALL iom_put( 'corstry' , zCorV * aimsk00 ) ! Coriolis force term in force balance (y)939 CALL iom_put( 'intstrx' , zfU * aimsk00 ) ! Internal force term in force balance (x)940 CALL iom_put( 'intstry' , zfV * aimsk00 ) ! Internal force term in force balance (y)915 CALL iom_put( 'dssh_dx' , zspgU * zmsk00 ) ! Sea-surface tilt term in force balance (x) 916 CALL iom_put( 'dssh_dy' , zspgV * zmsk00 ) ! Sea-surface tilt term in force balance (y) 917 CALL iom_put( 'corstrx' , zCorU * zmsk00 ) ! Coriolis force term in force balance (x) 918 CALL iom_put( 'corstry' , zCorV * zmsk00 ) ! Coriolis force term in force balance (y) 919 CALL iom_put( 'intstrx' , zfU * zmsk00 ) ! Internal force term in force balance (x) 920 CALL iom_put( 'intstry' , zfV * zmsk00 ) ! Internal force term in force balance (y) 941 921 ENDIF 942 922 … … 949 929 DO_2D( 0, 0, 0, 0 ) 950 930 ! 2D ice mass, snow mass, area transport arrays (X, Y) 951 zfac_x = 0.5 * u_ice(ji,jj) * e2u(ji,jj) * aimsk00(ji,jj)952 zfac_y = 0.5 * v_ice(ji,jj) * e1v(ji,jj) * aimsk00(ji,jj)931 zfac_x = 0.5 * u_ice(ji,jj) * e2u(ji,jj) * zmsk00(ji,jj) 932 zfac_y = 0.5 * v_ice(ji,jj) * e1v(ji,jj) * zmsk00(ji,jj) 953 933 954 934 zdiag_xmtrp_ice(ji,jj) = rhoi * zfac_x * ( vt_i(ji+1,jj) + vt_i(ji,jj) ) ! ice mass transport, X-component … … 984 964 IF( ln_aEVP ) THEN ! output: beta * ( u(t=nn_nevp) - u(t=nn_nevp-1) ) 985 965 CALL iom_put( 'uice_cvg', MAX( ABS( u_ice(:,:) - zu_ice(:,:) ) * zbeta(:,:) * umask(:,:,1) , & 986 & ABS( v_ice(:,:) - zv_ice(:,:) ) * zbeta(:,:) * vmask(:,:,1) ) * aimsk15(:,:) )966 & ABS( v_ice(:,:) - zv_ice(:,:) ) * zbeta(:,:) * vmask(:,:,1) ) * zmsk15(:,:) ) 987 967 ELSE ! output: nn_nevp * ( u(t=nn_nevp) - u(t=nn_nevp-1) ) 988 968 CALL iom_put( 'uice_cvg', REAL( nn_nevp ) * MAX( ABS( u_ice(:,:) - zu_ice(:,:) ) * umask(:,:,1) , & 989 & ABS( v_ice(:,:) - zv_ice(:,:) ) * vmask(:,:,1) ) * aimsk15(:,:) )969 & ABS( v_ice(:,:) - zv_ice(:,:) ) * vmask(:,:,1) ) * zmsk15(:,:) ) 990 970 ENDIF 991 971 ENDIF … … 995 975 996 976 997 SUBROUTINE rhg_cvg_eap( kt, kiter, kitermax, pu, pv, pub, pvb )977 SUBROUTINE rhg_cvg_eap( kt, kiter, kitermax, pu, pv, pub, pvb, pmsk15 ) 998 978 !!---------------------------------------------------------------------- 999 979 !! *** ROUTINE rhg_cvg_eap *** … … 1010 990 INTEGER , INTENT(in) :: kt, kiter, kitermax ! ocean time-step index 1011 991 REAL(wp), DIMENSION(:,:), INTENT(in) :: pu, pv, pub, pvb ! now and before velocities 992 REAL(wp), DIMENSION(:,:), INTENT(in) :: pmsk15 1012 993 !! 1013 994 INTEGER :: it, idtime, istatus … … 1038 1019 1039 1020 ! time 1040 it = ( kt - 1) * kitermax + kiter1021 it = ( kt - nit000 ) * kitermax + kiter 1041 1022 1042 1023 ! convergence … … 1044 1025 zresm = 0._wp 1045 1026 ELSE 1046 DO_2D( 1, 1, 1, 1 ) 1047 eap_res(ji,jj) = MAX( ABS( pu(ji,jj) - pub(ji,jj) ) * umask(ji,jj,1), & 1048 & ABS( pv(ji,jj) - pvb(ji,jj) ) * vmask(ji,jj,1) ) * aimsk15(ji,jj) 1027 zresm = 0._wp 1028 DO_2D( 0, 0, 0, 0 ) 1029 zresm = MAX( zresm, MAX( ABS( pu(ji,jj) - pub(ji,jj) ) * umask(ji,jj,1), & 1030 & ABS( pv(ji,jj) - pvb(ji,jj) ) * vmask(ji,jj,1) ) * pmsk15(ji,jj) ) 1049 1031 END_2D 1050 1051 zresm = MAXVAL( eap_res )1052 1032 CALL mpp_max( 'icedyn_rhg_evp', zresm ) ! max over the global domain 1053 1033 ENDIF … … 1057 1037 istatus = NF90_PUT_VAR( ncvgid, nvarid, (/zresm/), (/it/), (/1/) ) 1058 1038 ! close file 1059 IF( kt == nitend ) istatus = NF90_CLOSE(ncvgid)1039 IF( kt == nitend - nn_fsbc + 1 .AND. kiter == kitermax ) istatus = NF90_CLOSE(ncvgid) 1060 1040 ENDIF 1061 1041 -
NEMO/branches/2021/ticket2632_r14588_theta_sbcblk/src/ICE/icedyn_rhg_evp.F90
r14433 r15548 48 48 PUBLIC rhg_evp_rst ! called by icedyn_rhg.F90 49 49 50 !! for convergence tests 51 INTEGER :: ncvgid ! netcdf file id 52 INTEGER :: nvarid ! netcdf variable id 53 REAL(wp), DIMENSION(:,:), ALLOCATABLE :: fimask ! mask at F points for the ice 54 50 55 !! * Substitutions 51 56 # include "do_loop_substitute.h90" 52 57 # include "domzgr_substitute.h90" 53 54 !! for convergence tests55 INTEGER :: ncvgid ! netcdf file id56 INTEGER :: nvarid ! netcdf variable id57 REAL(wp), ALLOCATABLE, DIMENSION(:,:) :: zmsk00, zmsk1558 58 !!---------------------------------------------------------------------- 59 59 !! NEMO/ICE 4.0 , NEMO Consortium (2018) … … 134 134 REAL(wp) :: zvCr ! critical ice volume above which ice is landfast 135 135 ! 136 REAL(wp) :: zintb, zintn ! dummy argument137 136 REAL(wp) :: zfac_x, zfac_y 138 REAL(wp) :: zshear, zdum1, zdum2139 137 ! 140 138 REAL(wp), DIMENSION(jpi,jpj) :: zdelta, zp_delt ! delta and P/delta at T points … … 161 159 REAL(wp), DIMENSION(jpi,jpj) :: ztaux_base, ztauy_base ! ice-bottom stress at U-V points (landfast) 162 160 ! 161 REAL(wp), DIMENSION(jpi,jpj) :: zmsk00, zmsk15 163 162 REAL(wp), DIMENSION(jpi,jpj) :: zmsk01x, zmsk01y ! dummy arrays 164 163 REAL(wp), DIMENSION(jpi,jpj) :: zmsk00x, zmsk00y ! mask for ice presence 165 REAL(wp), DIMENSION(jpi,jpj) :: zfmask ! mask at F points for the ice166 164 167 165 REAL(wp), PARAMETER :: zepsi = 1.0e-20_wp ! tolerance parameter … … 180 178 REAL(wp), ALLOCATABLE, DIMENSION(:,:) :: zdiag_xatrp ! X-component of area transport (m2/s) 181 179 REAL(wp), ALLOCATABLE, DIMENSION(:,:) :: zdiag_yatrp ! Y-component of area transport (m2/s) 180 !! -- advect fields at the rheology time step for the calculation of strength 181 !! it seems that convergence is worse when ll_advups=true. So it not really a good idea 182 LOGICAL :: ll_advups = .FALSE. 183 REAL(wp) :: zdt_ups 184 REAL(wp), ALLOCATABLE, DIMENSION(:,:) :: ztmp 185 REAL(wp), ALLOCATABLE, DIMENSION(:,:,:) :: za_i_ups, zv_i_ups ! tracers advected upstream 182 186 !!------------------------------------------------------------------- 183 187 … … 185 189 ! 186 190 ! for diagnostics and convergence tests 187 ALLOCATE( zmsk00(jpi,jpj), zmsk15(jpi,jpj) ) 188 DO_2D( 1, 1, 1, 1 ) 191 DO_2D( nn_hls, nn_hls, nn_hls, nn_hls ) 189 192 zmsk00(ji,jj) = MAX( 0._wp , SIGN( 1._wp , at_i(ji,jj) - epsi06 ) ) ! 1 if ice , 0 if no ice 190 zmsk15(ji,jj) = MAX( 0._wp , SIGN( 1._wp , at_i(ji,jj) - 0.15_wp ) ) ! 1 if 15% ice, 0 if less191 193 END_2D 192 ! 193 !!gm for Clem: OPTIMIZATION: I think zfmask can be computed one for all at the initialization.... 194 IF( nn_rhg_chkcvg > 0 ) THEN 195 DO_2D( nn_hls, nn_hls, nn_hls, nn_hls ) 196 zmsk15(ji,jj) = MAX( 0._wp , SIGN( 1._wp , at_i(ji,jj) - 0.15_wp ) ) ! 1 if 15% ice, 0 if less 197 END_2D 198 ENDIF 199 ! 194 200 !------------------------------------------------------------------------------! 195 201 ! 0) mask at F points for the ice 196 202 !------------------------------------------------------------------------------! 197 ! ocean/land mask 198 DO_2D( 1, 0, 1, 0 ) 199 zfmask(ji,jj) = tmask(ji,jj,1) * tmask(ji+1,jj,1) * tmask(ji,jj+1,1) * tmask(ji+1,jj+1,1) 200 END_2D 201 CALL lbc_lnk( 'icedyn_rhg_evp', zfmask, 'F', 1._wp) 202 203 ! Lateral boundary conditions on velocity (modify zfmask) 204 DO_2D( 0, 0, 0, 0 ) 205 IF( zfmask(ji,jj) == 0._wp ) THEN 206 zfmask(ji,jj) = rn_ishlat * MIN( 1._wp , MAX( umask(ji,jj,1), umask(ji,jj+1,1), & 207 & vmask(ji,jj,1), vmask(ji+1,jj,1) ) ) 203 IF( kt == nit000 ) THEN 204 ! ocean/land mask 205 ALLOCATE( fimask(jpi,jpj) ) 206 IF( rn_ishlat == 0._wp ) THEN 207 DO_2D( 0, 0, 0, 0 ) 208 fimask(ji,jj) = tmask(ji,jj,1) * tmask(ji+1,jj,1) * tmask(ji,jj+1,1) * tmask(ji+1,jj+1,1) 209 END_2D 210 ELSE 211 DO_2D( 0, 0, 0, 0 ) 212 fimask(ji,jj) = tmask(ji,jj,1) * tmask(ji+1,jj,1) * tmask(ji,jj+1,1) * tmask(ji+1,jj+1,1) 213 ! Lateral boundary conditions on velocity (modify fimask) 214 IF( fimask(ji,jj) == 0._wp ) THEN 215 fimask(ji,jj) = rn_ishlat * MIN( 1._wp , MAX( umask(ji,jj,1), umask(ji,jj+1,1), & 216 & vmask(ji,jj,1), vmask(ji+1,jj,1) ) ) 217 ENDIF 218 END_2D 208 219 ENDIF 209 END_2D 210 DO jj = 2, jpjm1 211 IF( zfmask(1,jj) == 0._wp ) THEN 212 zfmask(1 ,jj) = rn_ishlat * MIN( 1._wp , MAX( vmask(2,jj,1), umask(1,jj+1,1), umask(1,jj,1) ) ) 213 ENDIF 214 IF( zfmask(jpi,jj) == 0._wp ) THEN 215 zfmask(jpi,jj) = rn_ishlat * MIN( 1._wp , MAX( umask(jpi,jj+1,1), vmask(jpim1,jj,1), umask(jpi,jj-1,1) ) ) 216 ENDIF 217 END DO 218 DO ji = 2, jpim1 219 IF( zfmask(ji,1) == 0._wp ) THEN 220 zfmask(ji, 1 ) = rn_ishlat * MIN( 1._wp , MAX( vmask(ji+1,1,1), umask(ji,2,1), vmask(ji,1,1) ) ) 221 ENDIF 222 IF( zfmask(ji,jpj) == 0._wp ) THEN 223 zfmask(ji,jpj) = rn_ishlat * MIN( 1._wp , MAX( vmask(ji+1,jpj,1), vmask(ji-1,jpj,1), umask(ji,jpjm1,1) ) ) 224 ENDIF 225 END DO 226 CALL lbc_lnk( 'icedyn_rhg_evp', zfmask, 'F', 1._wp ) 227 220 CALL lbc_lnk( 'icedyn_rhg_evp', fimask, 'F', 1._wp ) 221 ENDIF 228 222 !------------------------------------------------------------------------------! 229 223 ! 1) define some variables and initialize arrays … … 244 238 z1_alph2 = 1._wp / ( zalph2 + 1._wp ) 245 239 ELSE 246 zdtevp = r dt_ice240 zdtevp = rDt_ice 247 241 ! zalpha parameters set later on adaptatively 248 242 ENDIF … … 270 264 zsshdyn(:,:) = ice_var_sshdyn( ssh_m, snwice_mass, snwice_mass_b) 271 265 272 DO_2D( 0, 0, 0, 0 ) 266 DO_2D( nn_hls, nn_hls, nn_hls, nn_hls ) 267 zm1 = ( rhos * vt_s(ji,jj) + rhoi * vt_i(ji,jj) ) ! Ice/snow mass at U-V points 268 zmf (ji,jj) = zm1 * ff_t(ji,jj) ! Coriolis at T points (m*f) 269 zdt_m(ji,jj) = zdtevp / MAX( zm1, zmmin ) ! dt/m at T points (for alpha and beta coefficients) 270 END_2D 271 272 DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 ) 273 273 274 274 ! ice fraction at U-V points … … 284 284 285 285 ! Ocean currents at U-V points 286 v_oceU(ji,jj) = 0.25_wp * ( v_oce(ji,jj) + v_oce(ji,jj-1) + v_oce(ji+1,jj) + v_oce(ji+1,jj-1) ) * umask(ji,jj,1) 287 u_oceV(ji,jj) = 0.25_wp * ( u_oce(ji,jj) + u_oce(ji-1,jj) + u_oce(ji,jj+1) + u_oce(ji-1,jj+1) ) * vmask(ji,jj,1) 288 289 ! Coriolis at T points (m*f) 290 zmf(ji,jj) = zm1 * ff_t(ji,jj) 291 292 ! dt/m at T points (for alpha and beta coefficients) 293 zdt_m(ji,jj) = zdtevp / MAX( zm1, zmmin ) 286 ! (brackets added to fix the order of floating point operations for halo 1 - halo 2 compatibility) 287 v_oceU(ji,jj) = 0.25_wp * ( (v_oce(ji,jj) + v_oce(ji,jj-1)) + (v_oce(ji+1,jj) + v_oce(ji+1,jj-1)) ) * umask(ji,jj,1) 288 u_oceV(ji,jj) = 0.25_wp * ( (u_oce(ji,jj) + u_oce(ji-1,jj)) + (u_oce(ji,jj+1) + u_oce(ji-1,jj+1)) ) * vmask(ji,jj,1) 294 289 295 290 ! m/dt … … 316 311 317 312 END_2D 318 CALL lbc_lnk( 'icedyn_rhg_evp', zmf, 'T', 1.0_wp, zdt_m, 'T', 1.0_wp )319 313 ! 320 314 ! !== Landfast ice parameterization ==! 321 315 ! 322 316 IF( ln_landfast_L16 ) THEN !-- Lemieux 2016 323 DO_2D( 0, 0, 0, 0)317 DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 ) 324 318 ! ice thickness at U-V points 325 319 zvU = 0.5_wp * ( vt_i(ji,jj) * e1e2t(ji,jj) + vt_i(ji+1,jj) * e1e2t(ji+1,jj) ) * r1_e1e2u(ji,jj) * umask(ji,jj,1) … … 338 332 ! 339 333 ELSE !-- no landfast 340 DO_2D( 0, 0, 0, 0)334 DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 ) 341 335 ztaux_base(ji,jj) = 0._wp 342 336 ztauy_base(ji,jj) = 0._wp … … 362 356 363 357 ! --- divergence, tension & shear (Appendix B of Hunke & Dukowicz, 2002) --- ! 364 DO_2D( 1, 0, 1, 0)358 DO_2D( nn_hls, nn_hls-1, nn_hls, nn_hls-1 ) 365 359 366 360 ! shear at F points 367 361 zds(ji,jj) = ( ( u_ice(ji,jj+1) * r1_e1u(ji,jj+1) - u_ice(ji,jj) * r1_e1u(ji,jj) ) * e1f(ji,jj) * e1f(ji,jj) & 368 362 & + ( v_ice(ji+1,jj) * r1_e2v(ji+1,jj) - v_ice(ji,jj) * r1_e2v(ji,jj) ) * e2f(ji,jj) * e2f(ji,jj) & 369 & ) * r1_e1e2f(ji,jj) * zfmask(ji,jj)363 & ) * r1_e1e2f(ji,jj) * fimask(ji,jj) 370 364 371 365 END_2D … … 393 387 zdelta(ji,jj) = SQRT( zdiv2 + ( zdt2 + zds2 ) * z1_ecc2 ) 394 388 389 ! P/delta at T points 390 zp_delt(ji,jj) = strength(ji,jj) / ( zdelta(ji,jj) + rn_creepl ) 391 395 392 END_2D 396 CALL lbc_lnk( 'icedyn_rhg_evp', zdelta, 'T', 1.0_wp ) 397 398 ! P/delta at T points 399 DO_2D( 1, 1, 1, 1 ) 400 zp_delt(ji,jj) = strength(ji,jj) / ( zdelta(ji,jj) + rn_creepl ) 401 END_2D 402 403 DO_2D( 0, 1, 0, 1 ) ! loop ends at jpi,jpj so that no lbc_lnk are needed for zs1 and zs2 393 CALL lbc_lnk( 'icedyn_rhg_evp', zdelta, 'T', 1.0_wp, zp_delt, 'T', 1.0_wp ) 394 395 ! 396 DO_2D( nn_hls-1, nn_hls, nn_hls-1, nn_hls ) ! loop ends at jpi,jpj so that no lbc_lnk are needed for zs1 and zs2 404 397 405 398 ! divergence at T points (duplication to avoid communications) 406 zdiv = ( e2u(ji,jj) * u_ice(ji,jj) - e2u(ji-1,jj) * u_ice(ji-1,jj) & 407 & + e1v(ji,jj) * v_ice(ji,jj) - e1v(ji,jj-1) * v_ice(ji,jj-1) & 399 ! (brackets added to fix the order of floating point operations for halo 1 - halo 2 compatibility) 400 zdiv = ( (e2u(ji,jj) * u_ice(ji,jj) - e2u(ji-1,jj) * u_ice(ji-1,jj)) & 401 & + (e1v(ji,jj) * v_ice(ji,jj) - e1v(ji,jj-1) * v_ice(ji,jj-1)) & 408 402 & ) * r1_e1e2t(ji,jj) 409 403 … … 436 430 ! Save beta at T-points for further computations 437 431 IF( ln_aEVP ) THEN 438 DO_2D( 1, 1, 1, 1)432 DO_2D( nn_hls, nn_hls, nn_hls, nn_hls ) 439 433 zbeta(ji,jj) = MAX( 50._wp, rpi * SQRT( 0.5_wp * zp_delt(ji,jj) * r1_e1e2t(ji,jj) * zdt_m(ji,jj) ) ) 440 434 END_2D 441 435 ENDIF 442 436 443 DO_2D( 1, 0, 1, 0)437 DO_2D( nn_hls, nn_hls-1, nn_hls, nn_hls-1 ) 444 438 445 439 ! alpha for aEVP … … 453 447 454 448 ! P/delta at F points 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) ) 449 ! (brackets added to fix the order of floating point operations for halo 1 - halo 2 compatibility) 450 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 451 457 452 ! stress at F points (zkt/=0 if landfast) … … 461 456 462 457 ! --- Ice internal stresses (Appendix C of Hunke and Dukowicz, 2002) --- ! 463 DO_2D( 0, 0, 0, 0 ) 458 ! (brackets added to fix the order of floating point operations for halo 1 - halo 2 compatibility) 459 DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 ) 464 460 ! !--- U points 465 zfU(ji,jj) = 0.5_wp * ( ( zs1(ji+1,jj) - zs1(ji,jj) ) * e2u(ji,jj) &461 zfU(ji,jj) = 0.5_wp * ( (( zs1(ji+1,jj) - zs1(ji,jj) ) * e2u(ji,jj) & 466 462 & + ( zs2(ji+1,jj) * e2t(ji+1,jj) * e2t(ji+1,jj) - zs2(ji,jj) * e2t(ji,jj) * e2t(ji,jj) & 467 & ) * r1_e2u(ji,jj) &463 & ) * r1_e2u(ji,jj)) & 468 464 & + ( zs12(ji,jj) * e1f(ji,jj) * e1f(ji,jj) - zs12(ji,jj-1) * e1f(ji,jj-1) * e1f(ji,jj-1) & 469 465 & ) * 2._wp * r1_e1u(ji,jj) & … … 471 467 ! 472 468 ! !--- V points 473 zfV(ji,jj) = 0.5_wp * ( ( zs1(ji,jj+1) - zs1(ji,jj) ) * e1v(ji,jj) &469 zfV(ji,jj) = 0.5_wp * ( (( zs1(ji,jj+1) - zs1(ji,jj) ) * e1v(ji,jj) & 474 470 & - ( zs2(ji,jj+1) * e1t(ji,jj+1) * e1t(ji,jj+1) - zs2(ji,jj) * e1t(ji,jj) * e1t(ji,jj) & 475 & ) * r1_e1v(ji,jj) &471 & ) * r1_e1v(ji,jj)) & 476 472 & + ( zs12(ji,jj) * e2f(ji,jj) * e2f(ji,jj) - zs12(ji-1,jj) * e2f(ji-1,jj) * e2f(ji-1,jj) & 477 473 & ) * 2._wp * r1_e2v(ji,jj) & … … 479 475 ! 480 476 ! !--- ice currents at U-V point 481 v_iceU(ji,jj) = 0.25_wp * ( v_ice(ji,jj) + v_ice(ji,jj-1) + v_ice(ji+1,jj) + v_ice(ji+1,jj-1) ) * umask(ji,jj,1)482 u_iceV(ji,jj) = 0.25_wp * ( u_ice(ji,jj) + u_ice(ji-1,jj) + u_ice(ji,jj+1) + u_ice(ji-1,jj+1) ) * vmask(ji,jj,1)477 v_iceU(ji,jj) = 0.25_wp * ( (v_ice(ji,jj) + v_ice(ji,jj-1)) + (v_ice(ji+1,jj) + v_ice(ji+1,jj-1)) ) * umask(ji,jj,1) 478 u_iceV(ji,jj) = 0.25_wp * ( (u_ice(ji,jj) + u_ice(ji-1,jj)) + (u_ice(ji,jj+1) + u_ice(ji-1,jj+1)) ) * vmask(ji,jj,1) 483 479 ! 484 480 END_2D … … 489 485 IF( MOD(jter,2) == 0 ) THEN ! even iterations 490 486 ! 491 DO_2D( 0, 0, 0, 0)487 DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 ) 492 488 ! !--- tau_io/(v_oce - v_ice) 493 489 zTauO = zaV(ji,jj) * zrhoco * SQRT( ( v_ice (ji,jj) - v_oce (ji,jj) ) * ( v_ice (ji,jj) - v_oce (ji,jj) ) & … … 533 529 ENDIF 534 530 END_2D 535 CALL lbc_lnk( 'icedyn_rhg_evp', v_ice, 'V', -1.0_wp ) 536 ! 537 #if defined key_agrif 538 !! CALL agrif_interp_ice( 'V', jter, nn_nevp ) 539 CALL agrif_interp_ice( 'V' ) 540 #endif 541 IF( ln_bdy ) CALL bdy_ice_dyn( 'V' ) 531 IF( nn_hls == 1 ) CALL lbc_lnk( 'icedyn_rhg_evp', v_ice, 'V', -1.0_wp ) 542 532 ! 543 533 DO_2D( 0, 0, 0, 0 ) … … 585 575 ENDIF 586 576 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' ) 577 IF( nn_hls == 1 ) THEN ; CALL lbc_lnk( 'icedyn_rhg_evp', u_ice, 'U', -1.0_wp ) 578 ELSE ; CALL lbc_lnk( 'icedyn_rhg_evp', u_ice, 'U', -1.0_wp, v_ice, 'V', -1.0_wp ) 579 ENDIF 594 580 ! 595 581 ELSE ! odd iterations 596 582 ! 597 DO_2D( 0, 0, 0, 0)583 DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 ) 598 584 ! !--- tau_io/(u_oce - u_ice) 599 585 zTauO = zaU(ji,jj) * zrhoco * SQRT( ( u_ice (ji,jj) - u_oce (ji,jj) ) * ( u_ice (ji,jj) - u_oce (ji,jj) ) & … … 639 625 ENDIF 640 626 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' ) 627 IF( nn_hls == 1 ) CALL lbc_lnk( 'icedyn_rhg_evp', u_ice, 'U', -1.0_wp ) 648 628 ! 649 629 DO_2D( 0, 0, 0, 0 ) … … 691 671 ENDIF 692 672 END_2D 693 CALL lbc_lnk( 'icedyn_rhg_evp', v_ice, 'V', -1.0_wp ) 694 ! 673 IF( nn_hls == 1 ) THEN ; CALL lbc_lnk( 'icedyn_rhg_evp', v_ice, 'V', -1.0_wp ) 674 ELSE ; CALL lbc_lnk( 'icedyn_rhg_evp', u_ice, 'U', -1.0_wp, v_ice, 'V', -1.0_wp ) 675 ENDIF 676 ! 677 ENDIF 678 ! 695 679 #if defined key_agrif 696 !! CALL agrif_interp_ice( 'V', jter, nn_nevp ) 697 CALL agrif_interp_ice( 'V' ) 680 !! CALL agrif_interp_ice( 'U', jter, nn_nevp ) 681 !! CALL agrif_interp_ice( 'V', jter, nn_nevp ) 682 CALL agrif_interp_ice( 'U' ) 683 CALL agrif_interp_ice( 'V' ) 698 684 #endif 699 IF( ln_bdy ) CALL bdy_ice_dyn( 'V' ) 700 ! 685 IF( ln_bdy ) CALL bdy_ice_dyn( 'U' ) 686 IF( ln_bdy ) CALL bdy_ice_dyn( 'V' ) 687 ! 688 ! convergence test 689 IF( nn_rhg_chkcvg == 2 ) CALL rhg_cvg( kt, jter, nn_nevp, u_ice, v_ice, zu_ice, zv_ice, zmsk15 ) 690 ! 691 ! 692 ! --- change strength according to advected a_i and v_i (upstream for now) --- ! 693 IF( ll_advups .AND. ln_str_H79 ) THEN 694 ! 695 IF( jter == 1 ) THEN ! init 696 ALLOCATE( za_i_ups(jpi,jpj,jpl), zv_i_ups(jpi,jpj,jpl) ) 697 ALLOCATE( ztmp(jpi,jpj) ) 698 zdt_ups = rDt_ice / REAL( nn_nevp ) 699 za_i_ups(:,:,:) = a_i(:,:,:) 700 zv_i_ups(:,:,:) = v_i(:,:,:) 701 ELSE 702 CALL lbc_lnk( 'icedyn_rhg_evp', za_i_ups, 'T', 1.0_wp, zv_i_ups, 'T', 1.0_wp ) 703 ENDIF 704 ! 705 CALL rhg_upstream( jter, zdt_ups, u_ice, v_ice, za_i_ups ) ! upstream advection: a_i 706 CALL rhg_upstream( jter, zdt_ups, u_ice, v_ice, zv_i_ups ) ! upstream advection: v_i 707 ! 708 DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 ) ! strength 709 strength(ji,jj) = rn_pstar * SUM( zv_i_ups(ji,jj,:) ) * EXP( -rn_crhg * ( 1._wp - SUM( za_i_ups(ji,jj,:) ) ) ) 710 END_2D 711 IF( nn_hls == 1 ) CALL lbc_lnk( 'icedyn_rhg_evp', strength, 'T', 1.0_wp ) 712 ! 713 DO_2D( 0, 0, 0, 0 ) ! strength smoothing 714 IF( SUM( za_i_ups(ji,jj,:) ) > 0._wp ) THEN 715 ztmp(ji,jj) = ( 4._wp * strength(ji,jj) + strength(ji-1,jj ) + strength(ji+1,jj ) & 716 & + strength(ji ,jj-1) + strength(ji ,jj+1) & 717 & ) / ( 4._wp + tmask(ji-1,jj,1) + tmask(ji+1,jj,1) + tmask(ji,jj-1,1) + tmask(ji,jj+1,1) ) 718 ELSE 719 ztmp(ji,jj) = 0._wp 720 ENDIF 721 END_2D 722 DO_2D( 0, 0, 0, 0 ) 723 strength(ji,jj) = ztmp(ji,jj) 724 END_2D 725 ! 726 IF( jter == nn_nevp ) THEN 727 DEALLOCATE( za_i_ups, zv_i_ups ) 728 DEALLOCATE( ztmp ) 729 ENDIF 701 730 ENDIF 702 703 ! convergence test704 IF( nn_rhg_chkcvg == 2 ) CALL rhg_cvg( kt, jter, nn_nevp, u_ice, v_ice, zu_ice, zv_ice )705 !706 731 ! ! ==================== ! 707 732 END DO ! end loop over jter ! … … 709 734 IF( ln_aEVP ) CALL iom_put( 'beta_evp' , zbeta ) 710 735 ! 736 IF( ll_advups .AND. ln_str_H79 ) CALL lbc_lnk( 'icedyn_rhg_evp', strength, 'T', 1.0_wp ) 737 ! 711 738 !------------------------------------------------------------------------------! 712 739 ! 4) Recompute delta, shear and div (inputs for mechanical redistribution) 713 740 !------------------------------------------------------------------------------! 714 DO_2D( 1, 0, 1, 0)741 DO_2D( nn_hls, nn_hls-1, nn_hls, nn_hls-1 ) 715 742 716 743 ! shear at F points 717 744 zds(ji,jj) = ( ( u_ice(ji,jj+1) * r1_e1u(ji,jj+1) - u_ice(ji,jj) * r1_e1u(ji,jj) ) * e1f(ji,jj) * e1f(ji,jj) & 718 745 & + ( v_ice(ji+1,jj) * r1_e2v(ji+1,jj) - v_ice(ji,jj) * r1_e2v(ji,jj) ) * e2f(ji,jj) * e2f(ji,jj) & 719 & ) * r1_e1e2f(ji,jj) * zfmask(ji,jj)746 & ) * r1_e1e2f(ji,jj) * fimask(ji,jj) 720 747 721 748 END_2D … … 782 809 IF( iom_use('iceshe') ) CALL iom_put( 'iceshe' , pshear_i * zmsk00 ) ! shear 783 810 IF( iom_use('icestr') ) CALL iom_put( 'icestr' , strength * zmsk00 ) ! strength 811 IF( iom_use('icedlt') ) CALL iom_put( 'icedlt' , pdelta_i * zmsk00 ) ! delta 784 812 785 813 ! --- Stress tensor invariants (SIMIP diags) --- ! … … 788 816 ALLOCATE( zsig_I(jpi,jpj) , zsig_II(jpi,jpj) ) 789 817 ! 790 DO_2D( 1, 1, 1, 1)818 DO_2D( nn_hls, nn_hls, nn_hls, nn_hls ) 791 819 792 820 ! Ice stresses … … 800 828 801 829 ! Stress invariants (sigma_I, sigma_II, Coon 1974, Feltham 2008) 802 zsig_I (ji,jj) = zsig1 * 0.5_wp 803 zsig_II(ji,jj) = SQRT ( MAX( 0._wp, zsig2 * zsig2 * 0.25_wp + zsig12 ) ) ! 2nd '' '', aka maximum shear stress830 zsig_I (ji,jj) = zsig1 * 0.5_wp ! 1st stress invariant, aka average normal stress, aka negative pressure 831 zsig_II(ji,jj) = SQRT ( zsig2 * zsig2 * 0.25_wp + zsig12 * zsig12 ) ! 2nd '' '' , aka maximum shear stress 804 832 805 833 END_2D … … 821 849 ALLOCATE( zsig1_p(jpi,jpj) , zsig2_p(jpi,jpj) , zsig_I(jpi,jpj) , zsig_II(jpi,jpj) ) 822 850 ! 823 DO_2D( 1, 1, 1, 1)851 DO_2D( nn_hls, nn_hls, nn_hls, nn_hls ) 824 852 825 853 ! Ice stresses computed with **viscosities** (delta, p/delta) at **previous** iterates … … 832 860 833 861 ! Stress invariants (sigma_I, sigma_II, Coon 1974, Feltham 2008), T-point 834 zsig_I(ji,jj) = zsig1 * 0.5_wp 835 zsig_II(ji,jj) = SQRT ( MAX( 0._wp, zsig2 * zsig2 * 0.25_wp + zsig12 ) ) ! 2nd '' '', aka maximum shear stress862 zsig_I(ji,jj) = zsig1 * 0.5_wp ! 1st stress invariant, aka average normal stress, aka negative pressure 863 zsig_II(ji,jj) = SQRT ( zsig2 * zsig2 * 0.25_wp + zsig12 * zsig12 ) ! 2nd '' '' , aka maximum shear stress 836 864 837 865 ! Normalized principal stresses (used to display the ellipse) … … 914 942 ENDIF 915 943 ! 916 DEALLOCATE( zmsk00, zmsk15 )917 !918 944 END SUBROUTINE ice_dyn_rhg_evp 919 945 920 946 921 SUBROUTINE rhg_cvg( kt, kiter, kitermax, pu, pv, pub, pvb )947 SUBROUTINE rhg_cvg( kt, kiter, kitermax, pu, pv, pub, pvb, pmsk15 ) 922 948 !!---------------------------------------------------------------------- 923 949 !! *** ROUTINE rhg_cvg *** … … 934 960 INTEGER , INTENT(in) :: kt, kiter, kitermax ! ocean time-step index 935 961 REAL(wp), DIMENSION(:,:), INTENT(in) :: pu, pv, pub, pvb ! now and before velocities 962 REAL(wp), DIMENSION(:,:), INTENT(in) :: pmsk15 936 963 !! 937 964 INTEGER :: it, idtime, istatus … … 939 966 REAL(wp) :: zresm ! local real 940 967 CHARACTER(len=20) :: clname 941 REAL(wp), DIMENSION(jpi,jpj) :: zres ! check convergence 968 LOGICAL :: ll_maxcvg 969 REAL(wp), DIMENSION(jpi,jpj,2) :: zres 970 REAL(wp), DIMENSION(2) :: ztmp 942 971 !!---------------------------------------------------------------------- 943 972 ll_maxcvg = .FALSE. 973 ! 944 974 ! create file 945 975 IF( kt == nit000 .AND. kiter == 1 ) THEN … … 956 986 istatus = NF90_CREATE( TRIM(clname), NF90_CLOBBER, ncvgid ) 957 987 istatus = NF90_DEF_DIM( ncvgid, 'time' , NF90_UNLIMITED, idtime ) 958 istatus = NF90_DEF_VAR( ncvgid, 'uice_cvg', NF90_DOUBLE 988 istatus = NF90_DEF_VAR( ncvgid, 'uice_cvg', NF90_DOUBLE , (/ idtime /), nvarid ) 959 989 istatus = NF90_ENDDEF(ncvgid) 960 990 ENDIF … … 963 993 964 994 ! time 965 it = ( kt - 1) * kitermax + kiter995 it = ( kt - nit000 ) * kitermax + kiter 966 996 967 997 ! convergence … … 969 999 zresm = 0._wp 970 1000 ELSE 971 DO_2D( 1, 1, 1, 1 ) 972 zres(ji,jj) = MAX( ABS( pu(ji,jj) - pub(ji,jj) ) * umask(ji,jj,1), & 973 & ABS( pv(ji,jj) - pvb(ji,jj) ) * vmask(ji,jj,1) ) * zmsk15(ji,jj) 974 END_2D 975 zresm = MAXVAL( zres ) 976 CALL mpp_max( 'icedyn_rhg_evp', zresm ) ! max over the global domain 1001 zresm = 0._wp 1002 IF( ll_maxcvg ) THEN ! error max over the domain 1003 DO_2D( 0, 0, 0, 0 ) 1004 zresm = MAX( zresm, MAX( ABS( pu(ji,jj) - pub(ji,jj) ) * umask(ji,jj,1), & 1005 & ABS( pv(ji,jj) - pvb(ji,jj) ) * vmask(ji,jj,1) ) * pmsk15(ji,jj) ) 1006 END_2D 1007 CALL mpp_max( 'icedyn_rhg_evp', zresm ) 1008 ELSE ! error averaged over the domain 1009 DO_2D( 0, 0, 0, 0 ) 1010 zres(ji,jj,1) = MAX( ABS( pu(ji,jj) - pub(ji,jj) ) * umask(ji,jj,1), & 1011 & ABS( pv(ji,jj) - pvb(ji,jj) ) * vmask(ji,jj,1) ) * pmsk15(ji,jj) 1012 zres(ji,jj,2) = pmsk15(ji,jj) 1013 END_2D 1014 ztmp(:) = glob_sum_vec( 'icedyn_rhg_evp', zres ) 1015 IF( ztmp(2) /= 0._wp ) zresm = ztmp(1) / ztmp(2) 1016 ENDIF 977 1017 ENDIF 978 1018 … … 981 1021 istatus = NF90_PUT_VAR( ncvgid, nvarid, (/zresm/), (/it/), (/1/) ) 982 1022 ! close file 983 IF( kt == nitend - nn_fsbc + 1 ) istatus = NF90_CLOSE(ncvgid)1023 IF( kt == nitend - nn_fsbc + 1 .AND. kiter == kitermax ) istatus = NF90_CLOSE(ncvgid) 984 1024 ENDIF 985 1025 … … 1042 1082 END SUBROUTINE rhg_evp_rst 1043 1083 1084 SUBROUTINE rhg_upstream( jter, pdt, pu, pv, pt ) 1085 !!--------------------------------------------------------------------- 1086 !! *** ROUTINE rhg_upstream *** 1087 !! 1088 !! ** Purpose : compute the upstream fluxes and upstream guess of tracer 1089 !!---------------------------------------------------------------------- 1090 INTEGER , INTENT(in ) :: jter 1091 REAL(wp) , INTENT(in ) :: pdt ! tracer time-step 1092 REAL(wp), DIMENSION(:,: ) , INTENT(in ) :: pu, pv ! 2 ice velocity components 1093 REAL(wp), DIMENSION(:,:,:) , INTENT(inout) :: pt ! tracer fields 1094 ! 1095 INTEGER :: ji, jj, jl ! dummy loop indices 1096 REAL(wp) :: ztra ! local scalar 1097 LOGICAL :: ll_upsxy = .TRUE. 1098 REAL(wp), DIMENSION(jpi,jpj) :: zfu_ups, zfv_ups, zpt ! upstream fluxes and tracer guess 1099 !!---------------------------------------------------------------------- 1100 DO jl = 1, jpl 1101 IF( .NOT. ll_upsxy ) THEN !** no alternate directions **! 1102 ! 1103 DO_2D( nn_hls, nn_hls-1, nn_hls, nn_hls-1 ) 1104 zfu_ups(ji,jj) = MAX(pu(ji,jj)*e2u(ji,jj), 0._wp) * pt(ji,jj,jl) + MIN(pu(ji,jj)*e2u(ji,jj), 0._wp) * pt(ji+1,jj,jl) 1105 zfv_ups(ji,jj) = MAX(pv(ji,jj)*e1v(ji,jj), 0._wp) * pt(ji,jj,jl) + MIN(pv(ji,jj)*e1v(ji,jj), 0._wp) * pt(ji,jj+1,jl) 1106 END_2D 1107 ! 1108 ELSE !** alternate directions **! 1109 ! 1110 IF( MOD(jter,2) == 1 ) THEN !== odd ice time step: adv_x then adv_y ==! 1111 ! 1112 DO_2D( nn_hls, nn_hls-1, nn_hls, nn_hls ) !-- flux in x-direction 1113 zfu_ups(ji,jj) = MAX( pu(ji,jj)*e2u(ji,jj), 0._wp ) * pt(ji ,jj,jl) + & 1114 & MIN( pu(ji,jj)*e2u(ji,jj), 0._wp ) * pt(ji+1,jj,jl) 1115 END_2D 1116 ! 1117 DO_2D( nn_hls-1, nn_hls-1, nn_hls, nn_hls ) !-- first guess of tracer from u-flux 1118 ztra = - ( zfu_ups(ji,jj) - zfu_ups(ji-1,jj) ) 1119 zpt(ji,jj) = ( pt(ji,jj,jl) + ztra * pdt * r1_e1e2t(ji,jj) ) * tmask(ji,jj,1) 1120 END_2D 1121 ! 1122 DO_2D( nn_hls-1, nn_hls-1, nn_hls, nn_hls-1 ) !-- flux in y-direction 1123 zfv_ups(ji,jj) = MAX( pv(ji,jj)*e1v(ji,jj), 0._wp ) * zpt(ji,jj ) + & 1124 & MIN( pv(ji,jj)*e1v(ji,jj), 0._wp ) * zpt(ji,jj+1) 1125 END_2D 1126 ! 1127 ELSE !== even ice time step: adv_y then adv_x ==! 1128 ! 1129 DO_2D( nn_hls, nn_hls, nn_hls, nn_hls-1 ) !-- flux in y-direction 1130 zfv_ups(ji,jj) = MAX( pv(ji,jj)*e1v(ji,jj), 0._wp ) * pt(ji,jj ,jl) + & 1131 & MIN( pv(ji,jj)*e1v(ji,jj), 0._wp ) * pt(ji,jj+1,jl) 1132 END_2D 1133 ! 1134 DO_2D( nn_hls, nn_hls, nn_hls-1, nn_hls-1 ) !-- first guess of tracer from v-flux 1135 ztra = - ( zfv_ups(ji,jj) - zfv_ups(ji,jj-1) ) 1136 zpt(ji,jj) = ( pt(ji,jj,jl) + ztra * pdt * r1_e1e2t(ji,jj) ) * tmask(ji,jj,1) 1137 END_2D 1138 ! 1139 DO_2D( nn_hls, nn_hls-1, nn_hls-1, nn_hls-1 ) !-- flux in x-direction 1140 zfu_ups(ji,jj) = MAX( pu(ji,jj)*e2u(ji,jj), 0._wp ) * zpt(ji ,jj) + & 1141 & MIN( pu(ji,jj)*e2u(ji,jj), 0._wp ) * zpt(ji+1,jj) 1142 END_2D 1143 ! 1144 ENDIF 1145 ! 1146 ENDIF 1147 ! 1148 DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 ) 1149 ztra = - ( zfu_ups(ji,jj) - zfu_ups(ji-1,jj) + zfv_ups(ji,jj) - zfv_ups(ji,jj-1) ) 1150 pt(ji,jj,jl) = ( pt(ji,jj,jl) + ztra * pdt * r1_e1e2t(ji,jj) ) * tmask(ji,jj,1) 1151 END_2D 1152 END DO 1153 ! 1154 END SUBROUTINE rhg_upstream 1044 1155 1045 1156 #else -
NEMO/branches/2021/ticket2632_r14588_theta_sbcblk/src/ICE/icedyn_rhg_vp.F90
r14433 r15548 41 41 PUBLIC ice_dyn_rhg_vp ! called by icedyn_rhg.F90 42 42 43 44 LOGICAL :: lp_zebra_vp =.TRUE. 43 INTEGER :: nn_nvp ! total number of VP iterations (n_out_vp*n_inn_vp) 44 LOGICAL :: lp_zebra_vp =.TRUE. ! activate zebra (solve the linear system problem every odd j-band, then one every even one) 45 45 REAL(wp) :: zrelaxu_vp=0.95 ! U-relaxation factor (MV: can probably be merged with V-factor once ok) 46 46 REAL(wp) :: zrelaxv_vp=0.95 ! V-relaxation factor 47 47 REAL(wp) :: zuerr_max_vp=0.80 ! maximum velocity error, above which a forcing error is considered and solver is stopped 48 REAL(wp) :: zuerr_min_vp=1.e-04 48 REAL(wp) :: zuerr_min_vp=1.e-04 ! minimum velocity error, beyond which convergence is assumed 49 49 50 50 !! for convergence tests 51 51 INTEGER :: ncvgid ! netcdf file id 52 INTEGER :: nvarid_ures 53 INTEGER :: nvarid_vres 54 INTEGER :: nvarid_velres 55 INTEGER :: nvarid_udif 56 INTEGER :: nvarid_vdif 57 INTEGER :: nvarid_veldif 52 INTEGER :: nvarid_ures, nvarid_vres, nvarid_velres 53 INTEGER :: nvarid_uerr_max, nvarid_verr_max, nvarid_velerr_max 54 INTEGER :: nvarid_umad, nvarid_vmad, nvarid_velmad 55 INTEGER :: nvarid_umad_outer, nvarid_vmad_outer, nvarid_velmad_outer 58 56 INTEGER :: nvarid_mke 59 INTEGER :: nvarid_ures_xy, nvarid_vres_xy 60 61 REAL(wp), ALLOCATABLE, DIMENSION(:,:) :: zmsk00, zmsk15 62 57 58 REAL(wp), DIMENSION(:,:), ALLOCATABLE :: fimask ! mask at F points for the ice 59 60 !! * Substitutions 61 # include "do_loop_substitute.h90" 63 62 !!---------------------------------------------------------------------- 64 63 !! NEMO/ICE 4.0 , NEMO Consortium (2018) … … 86 85 !! 87 86 !! f1(u) = g1(v) 88 !! f2(v) = g2( v)87 !! f2(v) = g2(u) 89 88 !! 90 89 !! The right-hand side (RHS) is explicit … … 139 138 ! 140 139 INTEGER :: ji, ji2, jj, jj2, jn ! dummy loop indices 141 INTEGER :: jter, i_out, i_inn!140 INTEGER :: i_out, i_inn, i_inn_tot ! 142 141 INTEGER :: ji_min, jj_min ! 143 142 INTEGER :: nn_zebra_vp ! number of zebra steps 144 143 145 INTEGER :: nn_nvp ! total number of VP iterations (n_out_vp*n_inn_vp)146 144 ! 147 145 REAL(wp) :: zrhoco ! rho0 * rn_cio … … 150 148 REAL(wp) :: zkt ! isotropic tensile strength for landfast ice 151 149 REAL(wp) :: zm1, zm2, zm3, zmassU, zmassV ! ice/snow mass and volume 152 REAL(wp) :: zd eltat, zds2, zdt, zdt2, zdiv, zdiv2! temporary scalars153 REAL(wp) :: zp_del tastar_f!150 REAL(wp) :: zds2, zdt, zdt2, zdiv, zdiv2 ! temporary scalars 151 REAL(wp) :: zp_delstar_f ! 154 152 REAL(wp) :: zu_cV, zv_cU ! 155 153 REAL(wp) :: zfac, zfac1, zfac2, zfac3 … … 158 156 REAL(wp) :: zAA3, zw, ztau, zuerr_max, zverr_max 159 157 ! 160 REAL(wp), DIMENSION(jpi,jpj) :: zfmask ! mask at F points for the ice161 158 REAL(wp), DIMENSION(jpi,jpj) :: za_iU , za_iV ! ice fraction on U/V points 162 159 REAL(wp), DIMENSION(jpi,jpj) :: zmU_t, zmV_t ! Acceleration term contribution to RHS 163 160 REAL(wp), DIMENSION(jpi,jpj) :: zmassU_t, zmassV_t ! Mass per unit area divided by time step 164 161 ! 165 REAL(wp), DIMENSION(jpi,jpj) :: zdelta star_t !Delta* at T-points166 REAL(wp), DIMENSION(jpi,jpj) :: zten _i ! Tension167 REAL(wp), DIMENSION(jpi,jpj) :: zp_del tastar_t! P/delta* at T points162 REAL(wp), DIMENSION(jpi,jpj) :: zdeltat, zdelstar_t ! Delta & Delta* at T-points 163 REAL(wp), DIMENSION(jpi,jpj) :: ztens, zshear ! Tension, shear 164 REAL(wp), DIMENSION(jpi,jpj) :: zp_delstar_t ! P/delta* at T points 168 165 REAL(wp), DIMENSION(jpi,jpj) :: zzt, zet ! Viscosity pre-factors at T points 169 166 REAL(wp), DIMENSION(jpi,jpj) :: zef ! Viscosity pre-factor at F point … … 193 190 REAL(wp), DIMENSION(jpi,jpj) :: zFU, zFU_prime, zBU_prime ! Rearranged linear system coefficients, U equation 194 191 REAL(wp), DIMENSION(jpi,jpj) :: zFV, zFV_prime, zBV_prime ! Rearranged linear system coefficients, V equation 195 REAL(wp), DIMENSION(jpi,jpj) :: zCU_prime, zCV_prime ! Rearranged linear system coefficients, V equation196 192 !!! REAL(wp), DIMENSION(jpi,jpj) :: ztaux_bi, ztauy_bi ! ice-OceanBottom stress at U-V points (landfast) 197 193 !!! REAL(wp), DIMENSION(jpi,jpj) :: ztaux_base, ztauy_base ! ice-bottom stress at U-V points (landfast) 198 194 ! 195 REAL(wp), DIMENSION(jpi,jpj) :: zmsk00 199 196 REAL(wp), DIMENSION(jpi,jpj) :: zmsk01x, zmsk01y ! mask for lots of ice (1), little ice (0) 200 197 REAL(wp), DIMENSION(jpi,jpj) :: zmsk00x, zmsk00y ! mask for ice presence (1), no ice (0) … … 204 201 REAL(wp), PARAMETER :: zamin = 0.001_wp ! ice concentration below which ice velocity becomes very small 205 202 !! --- diags 206 REAL(wp) :: zsig1, zsig2, zsig12, zdelta, z1_strength, zfac_x, zfac_y203 REAL(wp) :: zsig1, zsig2, zsig12, zdelta, z1_strength, zfac_x, zfac_y 207 204 REAL(wp), DIMENSION(jpi,jpj) :: zs1, zs2, zs12, zs12f ! stress tensor components 208 205 REAL(wp), ALLOCATABLE, DIMENSION(:,:) :: zsig_I, zsig_II, zsig1_p, zsig2_p … … 212 209 REAL(wp), ALLOCATABLE, DIMENSION(:,:) :: zdiag_xatrp, zdiag_yatrp ! X/Y-component of area transport (m2/s, SIMIP) 213 210 214 215 CALL ctl_stop( 'STOP', 'icedyn_rhg_vp: stop because vp rheology is an ongoing work and should not be used' ) 211 REAL(wp), ALLOCATABLE, DIMENSION(:,:) :: zvel_res ! Residual of the linear system at last iteration 212 REAL(wp), ALLOCATABLE, DIMENSION(:,:) :: zvel_diff ! Absolute velocity difference @last outer iteration 213 216 214 217 215 !!---------------------------------------------------------------------------------------------------------------------- 218 ! DEBUG put all forcing terms to zero219 ! air-ice drag220 utau_ice(:,:) = 0._wp221 vtau_ice(:,:) = 0._wp222 ! coriolis223 ff_t(:,:) = 0._wp224 ! ice-ocean drag225 rn_cio = 0._wp226 ! ssh227 ! done line 330 !!! dont forget to act there228 ! END DEBUG229 216 230 217 IF( kt == nit000 .AND. lwp ) WRITE(numout,*) '-- ice_dyn_rhg_vp: VP sea-ice rheology (LSR solver)' … … 238 225 239 226 ! for diagnostics and convergence tests 240 ALLOCATE( zmsk00(jpi,jpj), zmsk15(jpi,jpj) ) 241 DO jj = 1, jpj 242 DO ji = 1, jpi 243 zmsk00(ji,jj) = MAX( 0._wp , SIGN( 1._wp , at_i(ji,jj) - epsi06 ) ) ! 1 if ice , 0 if no ice 244 zmsk15(ji,jj) = MAX( 0._wp , SIGN( 1._wp , at_i(ji,jj) - 0.15_wp ) ) ! 1 if 15% ice, 0 if less 245 END DO 246 END DO 227 DO_2D( nn_hls, nn_hls, nn_hls, nn_hls ) 228 zmsk00(ji,jj) = MAX( 0._wp , SIGN( 1._wp , at_i(ji,jj) - epsi06 ) ) ! 1 if ice , 0 if no ice 229 END_2D 247 230 248 231 IF ( lp_zebra_vp ) THEN; nn_zebra_vp = 2 … … 264 247 IF( nn_rhg_chkcvg /= 0 ) THEN 265 248 266 ! ice area for global mean kinetic energy 267 zglob_area = glob_sum( 'ice_rhg_vp', at_i(:,:) * e1e2t(:,:) ) ! global ice area (km2)249 ! ice area for global mean kinetic energy (m2) 250 zglob_area = glob_sum( 'ice_rhg_vp', at_i(:,:) * e1e2t(:,:) * tmask(:,:,1) ) 268 251 269 252 ENDIF … … 276 259 277 260 zs1_rhsu(:,:) = 0._wp; zs2_rhsu(:,:) = 0._wp; zs1_rhsv(:,:) = 0._wp; zs2_rhsv(:,:) = 0._wp 278 zAU(:,:) = 0._wp; zBU(:,:) = 0._wp; zCU(:,:) = 0._wp; zDU(:,:) = 0._wp; zEU(:,:) = 0._wp; 279 zAV(:,:) = 0._wp; zBV(:,:) = 0._wp; zCV(:,:) = 0._wp; zDV(:,:) = 0._wp; zEV(:,:) = 0._wp; 280 zrhsu(:,:) = 0._wp; zrhsv(:,:) = 0._wp 281 zf_rhsu(:,:) = 0._wp; zf_rhsv(:,:) = 0._wp 261 zrhsu (:,:) = 0._wp; zrhsv (:,:) = 0._wp; zf_rhsu(:,:) = 0._wp; zf_rhsv(:,:) = 0._wp 262 zAU(:,:) = 0._wp; zBU(:,:) = 0._wp; zCU(:,:) = 0._wp; zDU(:,:) = 0._wp; zEU(:,:) = 0._wp 263 zAV(:,:) = 0._wp; zBV(:,:) = 0._wp; zCV(:,:) = 0._wp; zDV(:,:) = 0._wp; zEV(:,:) = 0._wp 282 264 283 265 !------------------------------------------------------------------------------! … … 289 271 CALL ice_strength ! strength at T points 290 272 291 !------------------------------ 292 ! -- F-mask (code from EVP) 293 !------------------------------ 294 ! MartinV: 295 ! In EVP routine, zfmask is applied on shear at F-points, in order to enforce the lateral boundary condition (no-slip, ..., free-slip) 296 ! I am not sure the same recipe applies here 297 298 ! - ocean/land mask 299 DO jj = 1, jpj - 1 300 DO ji = 1, jpi - 1 301 zfmask(ji,jj) = tmask(ji,jj,1) * tmask(ji+1,jj,1) * tmask(ji,jj+1,1) * tmask(ji+1,jj+1,1) 302 END DO 303 END DO 304 305 ! Lateral boundary conditions on velocity (modify zfmask) 306 ! Can be computed once for all, at first time step, for all rheologies 307 DO jj = 2, jpj - 1 308 DO ji = 2, jpi - 1 ! vector opt. 309 IF( zfmask(ji,jj) == 0._wp ) THEN 310 zfmask(ji,jj) = rn_ishlat * MIN( 1._wp , MAX( umask(ji,jj,1), umask(ji,jj+1,1), & 311 & vmask(ji,jj,1), vmask(ji+1,jj,1) ) ) 312 ENDIF 313 END DO 314 END DO 315 DO jj = 2, jpj - 1 316 IF( zfmask(1,jj) == 0._wp ) THEN 317 zfmask(1 ,jj) = rn_ishlat * MIN( 1._wp , MAX( vmask(2,jj,1), umask(1,jj+1,1), umask(1,jj,1) ) ) 273 !--------------------------- 274 ! -- F-mask (code from EVP) 275 !--------------------------- 276 IF( kt == nit000 ) THEN 277 ! MartinV: 278 ! In EVP routine, fimask is applied on shear at F-points, in order to enforce the lateral boundary condition (no-slip, ..., free-slip) 279 ! I am not sure the same recipe applies here 280 281 ! - ocean/land mask 282 ALLOCATE( fimask(jpi,jpj) ) 283 IF( rn_ishlat == 0._wp ) THEN 284 DO_2D( 0, 0, 0, 0 ) 285 fimask(ji,jj) = tmask(ji,jj,1) * tmask(ji+1,jj,1) * tmask(ji,jj+1,1) * tmask(ji+1,jj+1,1) 286 END_2D 287 ELSE 288 DO_2D( 0, 0, 0, 0 ) 289 fimask(ji,jj) = tmask(ji,jj,1) * tmask(ji+1,jj,1) * tmask(ji,jj+1,1) * tmask(ji+1,jj+1,1) 290 ! Lateral boundary conditions on velocity (modify fimask) 291 IF( fimask(ji,jj) == 0._wp ) THEN 292 fimask(ji,jj) = rn_ishlat * MIN( 1._wp , MAX( umask(ji,jj,1), umask(ji,jj+1,1), & 293 & vmask(ji,jj,1), vmask(ji+1,jj,1) ) ) 294 ENDIF 295 END_2D 318 296 ENDIF 319 IF( zfmask(jpi,jj) == 0._wp ) THEN 320 zfmask(jpi,jj) = rn_ishlat * MIN( 1._wp , MAX( umask(jpi,jj+1,1), vmask(jpi - 1,jj,1), umask(jpi,jj-1,1) ) ) 321 ENDIF 322 END DO 323 DO ji = 2, jpi - 1 324 IF( zfmask(ji,1) == 0._wp ) THEN 325 zfmask(ji, 1 ) = rn_ishlat * MIN( 1._wp , MAX( vmask(ji+1,1,1), umask(ji,2,1), vmask(ji,1,1) ) ) 326 ENDIF 327 IF( zfmask(ji,jpj) == 0._wp ) THEN 328 zfmask(ji,jpj) = rn_ishlat * MIN( 1._wp , MAX( vmask(ji+1,jpj,1), vmask(ji-1,jpj,1), umask(ji,jpj - 1,1) ) ) 329 ENDIF 330 END DO 331 332 CALL lbc_lnk( 'icedyn_rhg_vp', zfmask, 'F', 1._wp ) 297 298 CALL lbc_lnk( 'icedyn_rhg_vp', fimask, 'F', 1._wp ) 299 ENDIF 333 300 334 301 !---------------------------------------------------------------------------------------------------------- … … 340 307 ! embedded sea ice: compute representative ice top surface 341 308 ! non-embedded sea ice: use ocean surface for slope calculation 342 zsshdyn(:,:) = ice_var_sshdyn( ssh_m, snwice_mass, snwice_mass_b) 343 zsshdyn(:,:) = 0._wp ! DEBUG CAREFUL !!! 344 345 zmt(:,:) = rhos * vt_s(:,:) + rhoi * vt_i(:,:) ! Snow and ice mass at T-point 346 zmf(:,:) = zmt(:,:) * ff_t(:,:) ! Coriolis factor at T points (m*f) 347 348 DO jj = 2, jpj - 1 349 DO ji = 2, jpi - 1 350 351 ! Ice fraction at U-V points 352 za_iU(ji,jj) = 0.5_wp * ( at_i(ji,jj) * e1e2t(ji,jj) + at_i(ji+1,jj) * e1e2t(ji+1,jj) ) * r1_e1e2u(ji,jj) * umask(ji,jj,1) 353 za_iV(ji,jj) = 0.5_wp * ( at_i(ji,jj) * e1e2t(ji,jj) + at_i(ji,jj+1) * e1e2t(ji,jj+1) ) * r1_e1e2v(ji,jj) * vmask(ji,jj,1) 354 355 ! Snow and ice mass at U-V points 356 zm1 = zmt(ji,jj) 357 zm2 = zmt(ji+1,jj) 358 zm3 = zmt(ji,jj+1) 359 360 zmassU = 0.5_wp * ( zm1 * e1e2t(ji,jj) + zm2 * e1e2t(ji+1,jj) ) * r1_e1e2u(ji,jj) * umask(ji,jj,1) 361 zmassV = 0.5_wp * ( zm1 * e1e2t(ji,jj) + zm3 * e1e2t(ji,jj+1) ) * r1_e1e2v(ji,jj) * vmask(ji,jj,1) 362 363 ! Mass per unit area divided by time step 364 zmassU_t(ji,jj) = zmassU * r1_Dt_ice 365 zmassV_t(ji,jj) = zmassV * r1_Dt_ice 366 367 ! Acceleration term contribution to RHS (depends on velocity at previous time step) 368 zmU_t(ji,jj) = zmassU_t(ji,jj) * u_ice(ji,jj) 369 zmV_t(ji,jj) = zmassV_t(ji,jj) * v_ice(ji,jj) 370 371 ! Ocean currents at U-V points 372 v_oceU(ji,jj) = 0.25_wp * ( v_oce(ji,jj) + v_oce(ji,jj-1) + v_oce(ji+1,jj) + v_oce(ji+1,jj-1) ) * umask(ji,jj,1) 373 u_oceV(ji,jj) = 0.25_wp * ( u_oce(ji,jj) + u_oce(ji-1,jj) + u_oce(ji,jj+1) + u_oce(ji-1,jj+1) ) * vmask(ji,jj,1) 374 375 ! Wind stress 376 ztaux_ai(ji,jj) = za_iU(ji,jj) * utau_ice(ji,jj) 377 ztauy_ai(ji,jj) = za_iV(ji,jj) * vtau_ice(ji,jj) 378 379 ! Force due to sea surface tilt(- m*g*GRAD(ssh)) 380 zspgU(ji,jj) = - zmassU * grav * ( zsshdyn(ji+1,jj) - zsshdyn(ji,jj) ) * r1_e1u(ji,jj) 381 zspgV(ji,jj) = - zmassV * grav * ( zsshdyn(ji,jj+1) - zsshdyn(ji,jj) ) * r1_e2v(ji,jj) 382 383 ! Mask for ice presence (1) or absence (0) 384 zmsk00x(ji,jj) = 1._wp - MAX( 0._wp, SIGN( 1._wp, -zmassU ) ) ! 0 if no ice 385 zmsk00y(ji,jj) = 1._wp - MAX( 0._wp, SIGN( 1._wp, -zmassV ) ) ! 0 if no ice 386 387 ! Mask for lots of ice (1) or little ice (0) 388 IF ( zmassU <= zmmin .AND. za_iU(ji,jj) <= zamin ) THEN ; zmsk01x(ji,jj) = 0._wp 389 ELSE ; zmsk01x(ji,jj) = 1._wp ; ENDIF 390 IF ( zmassV <= zmmin .AND. za_iV(ji,jj) <= zamin ) THEN ; zmsk01y(ji,jj) = 0._wp 391 ELSE ; zmsk01y(ji,jj) = 1._wp ; ENDIF 392 393 ! MV TEST DEBUG 394 IF ( ( zmt(ji,jj) <= zmmin .OR. zmt(ji+1,jj) <= zmmin ) .AND. & 395 & ( at_i(ji,jj) <= zamin .OR. at_i(ji+1,jj) <= zamin ) ) THEN ; zmsk01x(ji,jj) = 0._wp 396 ELSE ; zmsk01x(ji,jj) = 1._wp ; ENDIF 397 398 IF ( ( zmt(ji,jj) <= zmmin .OR. zmt(ji,jj+1) <= zmmin ) .AND. & 399 & ( at_i(ji,jj) <= zamin .OR. at_i(ji,jj+1) <= zamin ) ) THEN ; zmsk01y(ji,jj) = 0._wp 400 ELSE ; zmsk01y(ji,jj) = 1._wp ; ENDIF 401 ! END MV TEST DEBUG 402 403 END DO 404 END DO 405 406 CALL iom_put( 'zmsk00x' , zmsk00x ) ! MV DEBUG 407 CALL iom_put( 'zmsk00y' , zmsk00y ) ! MV DEBUG 408 CALL iom_put( 'zmsk01x' , zmsk01x ) ! MV DEBUG 409 CALL iom_put( 'zmsk01y' , zmsk01y ) ! MV DEBUG 410 CALL iom_put( 'ztaux_ai' , ztaux_ai ) ! MV DEBUG 411 CALL iom_put( 'ztauy_ai' , ztauy_ai ) ! MV DEBUG 412 CALL iom_put( 'zspgU' , zspgU ) ! MV DEBUG 413 CALL iom_put( 'zspgV' , zspgV ) ! MV DEBUG 309 zsshdyn(:,:) = ice_var_sshdyn( ssh_m, snwice_mass, snwice_mass_b) 310 311 DO_2D( nn_hls, nn_hls, nn_hls, nn_hls ) 312 zmt(ji,jj) = rhos * vt_s(ji,jj) + rhoi * vt_i(ji,jj) ! Snow and ice mass at T-point 313 zmf(ji,jj) = zmt(ji,jj) * ff_t(ji,jj) ! Coriolis factor at T points (m*f) 314 END_2D 315 316 DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 ) ! 2->jpj-1; 2->jpi-1 317 318 ! Ice fraction at U-V points 319 za_iU(ji,jj) = 0.5_wp * ( at_i(ji,jj) * e1e2t(ji,jj) + at_i(ji+1,jj) * e1e2t(ji+1,jj) ) * r1_e1e2u(ji,jj) * umask(ji,jj,1) 320 za_iV(ji,jj) = 0.5_wp * ( at_i(ji,jj) * e1e2t(ji,jj) + at_i(ji,jj+1) * e1e2t(ji,jj+1) ) * r1_e1e2v(ji,jj) * vmask(ji,jj,1) 321 322 ! Snow and ice mass at U-V points 323 zm1 = zmt(ji,jj) 324 zm2 = zmt(ji+1,jj) 325 zm3 = zmt(ji,jj+1) 326 zmassU = 0.5_wp * ( zm1 * e1e2t(ji,jj) + zm2 * e1e2t(ji+1,jj) ) * r1_e1e2u(ji,jj) * umask(ji,jj,1) 327 zmassV = 0.5_wp * ( zm1 * e1e2t(ji,jj) + zm3 * e1e2t(ji,jj+1) ) * r1_e1e2v(ji,jj) * vmask(ji,jj,1) 328 329 ! Mass per unit area divided by time step 330 zmassU_t(ji,jj) = zmassU * r1_Dt_ice 331 zmassV_t(ji,jj) = zmassV * r1_Dt_ice 332 333 ! Acceleration term contribution to RHS (depends on velocity at previous time step) 334 zmU_t(ji,jj) = zmassU_t(ji,jj) * u_ice(ji,jj) 335 zmV_t(ji,jj) = zmassV_t(ji,jj) * v_ice(ji,jj) 336 337 ! Ocean currents at U-V points 338 v_oceU(ji,jj) = 0.25_wp * ( v_oce(ji,jj) + v_oce(ji,jj-1) + v_oce(ji+1,jj) + v_oce(ji+1,jj-1) ) * umask(ji,jj,1) 339 u_oceV(ji,jj) = 0.25_wp * ( u_oce(ji,jj) + u_oce(ji-1,jj) + u_oce(ji,jj+1) + u_oce(ji-1,jj+1) ) * vmask(ji,jj,1) 340 341 ! Wind stress 342 ztaux_ai(ji,jj) = za_iU(ji,jj) * utau_ice(ji,jj) 343 ztauy_ai(ji,jj) = za_iV(ji,jj) * vtau_ice(ji,jj) 344 345 ! Force due to sea surface tilt(- m*g*GRAD(ssh)) 346 zspgU(ji,jj) = - zmassU * grav * ( zsshdyn(ji+1,jj) - zsshdyn(ji,jj) ) * r1_e1u(ji,jj) 347 zspgV(ji,jj) = - zmassV * grav * ( zsshdyn(ji,jj+1) - zsshdyn(ji,jj) ) * r1_e2v(ji,jj) 348 349 ! Mask for ice presence (1) or absence (0) 350 zmsk00x(ji,jj) = 1._wp - MAX( 0._wp, SIGN( 1._wp, -zmassU ) ) ! 0 if no ice 351 zmsk00y(ji,jj) = 1._wp - MAX( 0._wp, SIGN( 1._wp, -zmassV ) ) ! 0 if no ice 352 353 ! Mask for lots of ice (1) or little ice (0) 354 IF ( zmassU <= zmmin .AND. za_iU(ji,jj) <= zamin ) THEN ; zmsk01x(ji,jj) = 0._wp 355 ELSE ; zmsk01x(ji,jj) = 1._wp ; ENDIF 356 IF ( zmassV <= zmmin .AND. za_iV(ji,jj) <= zamin ) THEN ; zmsk01y(ji,jj) = 0._wp 357 ELSE ; zmsk01y(ji,jj) = 1._wp ; ENDIF 358 359 END_2D 414 360 415 361 !------------------------------------------------------------------------------! … … 422 368 zv_c(:,:) = v_ice(:,:) 423 369 424 jter= 0370 i_inn_tot = 0 425 371 426 372 DO i_out = 1, nn_vp_nout 427 373 428 IF( lwp ) WRITE(numout,*) ' outer loop i_out : ', i_out429 430 374 ! Velocities used in the non linear terms are the average of the past two iterates 431 ! u_it = 0.5 * ( u_{it-1} + u_{it-2} )375 ! u_it = 0.5 * ( u_{it-1} + u_{it-2} ) 432 376 ! Also used in Hibler and Ackley (1983); Zhang and Hibler (1997); Lemieux and Tremblay (2009) 433 377 zu_c(:,:) = 0.5_wp * ( u_ice(:,:) + zu_c(:,:) ) … … 441 385 ! In the outer loop, one needs to update all RHS terms 442 386 ! with explicit velocity dependencies (viscosities, coriolis, ocean stress) 443 ! as a function of uc 444 ! 387 ! as a function of "current" velocities (uc, vc) 445 388 446 389 !------------------------------------------ … … 449 392 450 393 ! --- divergence, tension & shear (Appendix B of Hunke & Dukowicz, 2002) --- ! 451 DO jj = 1, jpj - 1 ! loops start at 1 since there is no boundary condition (lbc_lnk) at i=1 and j=1 for F points 452 DO ji = 1, jpi - 1 453 454 ! shear at F points 455 zds(ji,jj) = ( ( zu_c(ji,jj+1) * r1_e1u(ji,jj+1) - zu_c(ji,jj) * r1_e1u(ji,jj) ) * e1f(ji,jj) * e1f(ji,jj) & 456 & + ( zv_c(ji+1,jj) * r1_e2v(ji+1,jj) - zv_c(ji,jj) * r1_e2v(ji,jj) ) * e2f(ji,jj) * e2f(ji,jj) & 457 & ) * r1_e1e2f(ji,jj) * zfmask(ji,jj) 458 459 END DO 460 END DO 461 462 CALL lbc_lnk( 'icedyn_rhg_vp', zds, 'F', 1. ) ! MV TEST could be un-necessary according to Gurvan 463 CALL iom_put( 'zds' , zds ) ! MV DEBUG 464 465 IF( lwp ) WRITE(numout,*) ' outer loop 1a i_out : ', i_out 466 467 !DO jj = 2, jpj - 1 ! loop to jpi,jpj to avoid making a communication for zs1,zs2,zs12 468 ! DO ji = 2, jpi - 1 ! 469 470 ! MV DEBUG 471 DO jj = 2, jpj ! loop to jpi,jpj to avoid making a communication for zs1,zs2,zs12 472 DO ji = 2, jpi ! 473 ! END MV DEBUG 474 475 ! shear**2 at T points (doc eq. A16) 476 zds2 = ( zds(ji,jj ) * zds(ji,jj ) * e1e2f(ji,jj ) + zds(ji-1,jj ) * zds(ji-1,jj ) * e1e2f(ji-1,jj ) & 477 & + 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) & 478 & ) * 0.25_wp * r1_e1e2t(ji,jj) 394 DO_2D( nn_hls, nn_hls-1, nn_hls, nn_hls-1 ) ! 1->jpi-1 395 396 ! loops start at 1 since there is no boundary condition (lbc_lnk) at i=1 and j=1 for F points 397 ! shear at F points 398 zds(ji,jj) = ( ( zu_c(ji,jj+1) * r1_e1u(ji,jj+1) - zu_c(ji,jj) * r1_e1u(ji,jj) ) * e1f(ji,jj) * e1f(ji,jj) & 399 & + ( zv_c(ji+1,jj) * r1_e2v(ji+1,jj) - zv_c(ji,jj) * r1_e2v(ji,jj) ) * e2f(ji,jj) * e2f(ji,jj) & 400 & ) * r1_e1e2f(ji,jj) * fimask(ji,jj) 401 402 END_2D 403 404 CALL lbc_lnk( 'icedyn_rhg_vp', zds, 'F', 1. ) ! necessary, zds2 uses jpi/jpj values for zds 405 406 DO_2D( nn_hls-1, nn_hls, nn_hls-1, nn_hls ) ! 2 -> jpj; 2,jpi !!! CHECK !!! 407 ! loop to jpi,jpj to avoid making a communication for zs1,zs2,zs12 408 409 ! shear**2 at T points (doc eq. A16) 410 zds2 = ( zds(ji,jj ) * zds(ji,jj ) * e1e2f(ji,jj ) + zds(ji-1,jj ) * zds(ji-1,jj ) * e1e2f(ji-1,jj ) & 411 & + 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) & 412 & ) * 0.25_wp * r1_e1e2t(ji,jj) 479 413 480 481 482 483 484 414 ! divergence at T points 415 zdiv = ( e2u(ji,jj) * zu_c(ji,jj) - e2u(ji-1,jj) * zu_c(ji-1,jj) & 416 & + e1v(ji,jj) * zv_c(ji,jj) - e1v(ji,jj-1) * zv_c(ji,jj-1) & 417 & ) * r1_e1e2t(ji,jj) 418 zdiv2 = zdiv * zdiv 485 419 486 487 zdt= ( ( zu_c(ji,jj) * r1_e2u(ji,jj) - zu_c(ji-1,jj) * r1_e2u(ji-1,jj) ) * e2t(ji,jj) * e2t(ji,jj) &488 &- ( zv_c(ji,jj) * r1_e1v(ji,jj) - zv_c(ji,jj-1) * r1_e1v(ji,jj-1) ) * e1t(ji,jj) * e1t(ji,jj) &489 &) * r1_e1e2t(ji,jj)490 zdt2= zdt * zdt420 ! tension at T points 421 zdt = ( ( zu_c(ji,jj) * r1_e2u(ji,jj) - zu_c(ji-1,jj) * r1_e2u(ji-1,jj) ) * e2t(ji,jj) * e2t(ji,jj) & 422 & - ( zv_c(ji,jj) * r1_e1v(ji,jj) - zv_c(ji,jj-1) * r1_e1v(ji,jj-1) ) * e1t(ji,jj) * e1t(ji,jj) & 423 & ) * r1_e1e2t(ji,jj) 424 zdt2 = zdt * zdt 491 425 492 493 zdeltat= SQRT( zdiv2 + ( zdt2 + zds2 ) * z1_ecc2 )426 ! delta at T points 427 zdeltat(ji,jj) = SQRT( zdiv2 + ( zdt2 + zds2 ) * z1_ecc2 ) 494 428 495 496 zdeltastar_t(ji,jj) = zdeltat + rn_creepl429 ! delta* at T points (following Lemieux and Dupont, GMD 2020) 430 zdelstar_t(ji,jj) = zdeltat(ji,jj) + rn_creepl ! OPT zdelstar_t can be totally removed and put into next line directly. Could change results 497 431 498 ! P/deltaat T-points499 zp_deltastar_t(ji,jj) = strength(ji,jj) / zdeltastar_t(ji,jj)432 ! P/delta* at T-points 433 zp_delstar_t(ji,jj) = strength(ji,jj) / zdelstar_t(ji,jj) 500 434 501 502 zzt(ji,jj) = zp_deltastar_t(ji,jj) * r1_e1e2t(ji,jj)503 zet(ji,jj)= zzt(ji,jj) * z1_ecc2435 ! Temporary zzt and zet factors at T-points 436 zzt(ji,jj) = zp_delstar_t(ji,jj) * r1_e1e2t(ji,jj) 437 zet(ji,jj) = zzt(ji,jj) * z1_ecc2 504 438 505 END DO 506 END DO 507 508 CALL lbc_lnk( 'icedyn_rhg_vp', zp_deltastar_t , 'T', 1. , zzt , 'T', 1., zet, 'T', 1. ) 509 510 CALL iom_put( 'zzt' , zzt ) ! MV DEBUG 511 CALL iom_put( 'zet' , zet ) ! MV DEBUG 512 CALL iom_put( 'zp_deltastar_t', zp_deltastar_t ) ! MV DEBUG 513 514 IF( lwp ) WRITE(numout,*) ' outer loop 1b i_out : ', i_out 515 516 DO jj = 1, jpj - 1 517 DO ji = 1, jpi - 1 518 439 END_2D 440 441 CALL lbc_lnk( 'icedyn_rhg_vp', zp_delstar_t , 'T', 1. ) ! necessary, used for ji = 1 and jj = 1 442 443 DO_2D( nn_hls, nn_hls-1, nn_hls, nn_hls-1 )! 1-> jpj-1; 1->jpi-1 444 519 445 ! P/delta* at F points 520 zp_del tastar_f = 0.25_wp * ( zp_deltastar_t(ji,jj) + zp_deltastar_t(ji+1,jj) + zp_deltastar_t(ji,jj+1) + zp_deltastar_t(ji+1,jj+1) )446 zp_delstar_f = 0.25_wp * ( zp_delstar_t(ji,jj) + zp_delstar_t(ji+1,jj) + zp_delstar_t(ji,jj+1) + zp_delstar_t(ji+1,jj+1) ) 521 447 522 448 ! Temporary zef factor at F-point 523 zef(ji,jj) = zp_deltastar_f * r1_e1e2f(ji,jj) * z1_ecc2 * zfmask(ji,jj) 524 525 END DO 526 END DO 527 528 CALL lbc_lnk( 'icedyn_rhg_vp', zef, 'F', 1. ) 529 CALL iom_put( 'zef' , zef ) ! MV DEBUG 530 IF( lwp ) WRITE(numout,*) ' outer loop 1c i_out : ', i_out 531 449 zef(ji,jj) = zp_delstar_f * r1_e1e2f(ji,jj) * z1_ecc2 * fimask(ji,jj) * 0.5_wp 450 451 END_2D 452 532 453 !--------------------------------------------------- 533 454 ! -- Ocean-ice drag and Coriolis RHS contributions 534 455 !--------------------------------------------------- 535 456 536 DO jj = 2, jpj - 1 537 DO ji = 2, jpi - 1 457 DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 ) ! 2->jpj-1; 2->jpi-1 458 459 !--- ice u-velocity @V points, v-velocity @U points (for non-linear drag computation) 460 zu_cV = 0.25_wp * ( zu_c(ji,jj) + zu_c(ji-1,jj) + zu_c(ji,jj+1) + zu_c(ji-1,jj+1) ) * vmask(ji,jj,1) 461 zv_cU = 0.25_wp * ( zv_c(ji,jj) + zv_c(ji,jj-1) + zv_c(ji+1,jj) + zv_c(ji+1,jj-1) ) * umask(ji,jj,1) 538 462 539 !--- ice u-velocity @V points, v-velocity @U points (for non-linear drag computation) 540 zu_cV = 0.25_wp * ( zu_c(ji,jj) + zu_c(ji-1,jj) + zu_c(ji,jj+1) + zu_c(ji-1,jj+1) ) * vmask(ji,jj,1) 541 zv_cU = 0.25_wp * ( zv_c(ji,jj) + zv_c(ji,jj-1) + zv_c(ji+1,jj) + zv_c(ji+1,jj-1) ) * umask(ji,jj,1) 463 !--- non-linear drag coefficients (need to be updated at each outer loop, see Lemieux and Tremblay JGR09, p.3, beginning of Section 3) 464 zCwU(ji,jj) = za_iU(ji,jj) * zrhoco * SQRT( ( zu_c (ji,jj) - u_oce (ji,jj) ) * ( zu_c (ji,jj) - u_oce (ji,jj) ) & 465 & + ( zv_cU - v_oceU(ji,jj) ) * ( zv_cU - v_oceU(ji,jj) ) ) 466 zCwV(ji,jj) = za_iV(ji,jj) * zrhoco * SQRT( ( zv_c (ji,jj) - v_oce (ji,jj) ) * ( zv_c (ji,jj) - v_oce (ji,jj) ) & 467 & + ( zu_cV - u_oceV(ji,jj) ) * ( zu_cV - u_oceV(ji,jj) ) ) 468 469 !--- Ocean-ice drag contributions to RHS 470 ztaux_oi_rhsu(ji,jj) = zCwU(ji,jj) * u_oce(ji,jj) 471 ztauy_oi_rhsv(ji,jj) = zCwV(ji,jj) * v_oce(ji,jj) 542 472 543 !--- non-linear drag coefficients (need to be updated at each outer loop, see Lemieux and Tremblay JGR09, p.3, beginning of Section 3) 544 zCwU(ji,jj) = za_iU(ji,jj) * zrhoco * SQRT( ( zu_c (ji,jj) - u_oce (ji,jj) ) * ( zu_c (ji,jj) - u_oce (ji,jj) ) & 545 & + ( zv_cU - v_oceU(ji,jj) ) * ( zv_cU - v_oceU(ji,jj) ) ) 546 zCwV(ji,jj) = za_iV(ji,jj) * zrhoco * SQRT( ( zv_c (ji,jj) - v_oce (ji,jj) ) * ( zv_c (ji,jj) - v_oce (ji,jj) ) & 547 & + ( zu_cV - u_oceV(ji,jj) ) * ( zu_cV - u_oceV(ji,jj) ) ) 548 549 !--- Ocean-ice drag contributions to RHS 550 ztaux_oi_rhsu(ji,jj) = zCwU(ji,jj) * u_oce(ji,jj) 551 ztauy_oi_rhsv(ji,jj) = zCwV(ji,jj) * v_oce(ji,jj) 552 553 ! --- U-component of Coriolis Force (energy conserving formulation) 554 ! Note Lemieux et al 2008 recommend to do that implicitly, but I don't really see how this could be done 555 zCorU(ji,jj) = 0.25_wp * r1_e1u(ji,jj) * & 556 & ( zmf(ji ,jj) * ( e1v(ji ,jj) * zv_c(ji ,jj) + e1v(ji ,jj-1) * zv_c(ji ,jj-1) ) & 557 & + zmf(ji+1,jj) * ( e1v(ji+1,jj) * zv_c(ji+1,jj) + e1v(ji+1,jj-1) * zv_c(ji+1,jj-1) ) ) 473 !--- U-component of Coriolis Force (energy conserving formulation) 474 zCorU(ji,jj) = 0.25_wp * r1_e1u(ji,jj) * & 475 & ( zmf(ji ,jj) * ( e1v(ji ,jj) * zv_c(ji ,jj) + e1v(ji ,jj-1) * zv_c(ji ,jj-1) ) & 476 & + zmf(ji+1,jj) * ( e1v(ji+1,jj) * zv_c(ji+1,jj) + e1v(ji+1,jj-1) * zv_c(ji+1,jj-1) ) ) 558 477 559 ! --- V-component of Coriolis Force (energy conserving formulation) 560 zCorV(ji,jj) = - 0.25_wp * r1_e2v(ji,jj) * & 561 & ( zmf(ji,jj ) * ( e2u(ji,jj ) * zu_c(ji,jj ) + e2u(ji-1,jj ) * zu_c(ji-1,jj ) ) & 562 & + zmf(ji,jj+1) * ( e2u(ji,jj+1) * zu_c(ji,jj+1) + e2u(ji-1,jj+1) * zu_c(ji-1,jj+1) ) ) 563 564 END DO 565 END DO 566 567 IF( lwp ) WRITE(numout,*) ' outer loop 1d i_out : ', i_out 568 569 CALL lbc_lnk( 'icedyn_rhg_vp', zCwU , 'U', -1., zCwV, 'V', -1. ) 570 CALL lbc_lnk( 'icedyn_rhg_vp', zCorU, 'U', -1., zCorV, 'V', -1. ) 571 572 CALL iom_put( 'zCwU' , zCwU ) ! MV DEBUG 573 CALL iom_put( 'zCwV' , zCwV ) ! MV DEBUG 574 CALL iom_put( 'zCorU' , zCorU ) ! MV DEBUG 575 CALL iom_put( 'zCorV' , zCorV ) ! MV DEBUG 576 577 IF( lwp ) WRITE(numout,*) ' outer loop 1f i_out : ', i_out 578 579 ! a priori, Coriolis and drag terms only affect diagonal or independent term of the linear system, 580 ! so there is no need for lbclnk on drag and coriolis 581 478 !--- V-component of Coriolis Force (energy conserving formulation) 479 zCorV(ji,jj) = - 0.25_wp * r1_e2v(ji,jj) * & 480 & ( zmf(ji,jj ) * ( e2u(ji,jj ) * zu_c(ji,jj ) + e2u(ji-1,jj ) * zu_c(ji-1,jj ) ) & 481 & + zmf(ji,jj+1) * ( e2u(ji,jj+1) * zu_c(ji,jj+1) + e2u(ji-1,jj+1) * zu_c(ji-1,jj+1) ) ) 482 483 END_2D 484 582 485 !------------------------------------- 583 486 ! -- Internal stress RHS contribution 584 487 !------------------------------------- 585 488 586 ! --- Stress contributions at T-points 587 DO jj = 2, jpj ! loop to jpi,jpj to avoid making a communication for zs1,zs2,zs12 588 DO ji = 2, jpi ! 489 ! --- Stress contributions at T-points 490 DO_2D( nn_hls-1, nn_hls, nn_hls-1, nn_hls ) ! 2 -> jpj; 2,jpi !!! CHECK !!! 491 492 ! loop to jpi,jpj to avoid making a communication for zs1 & zs2 589 493 590 ! sig1 contribution to RHS of U-equation at T-points 591 zs1_rhsu(ji,jj) = zzt(ji,jj) * ( e1v(ji,jj) * zv_c(ji,jj) - e1v(ji,jj-1) * zv_c(ji,jj-1) - 1.0_wp ) 494 ! sig1 contribution to RHS of U-equation at T-points 495 zs1_rhsu(ji,jj) = zzt(ji,jj) * ( e1v(ji,jj) * zv_c(ji,jj) - e1v(ji,jj-1) * zv_c(ji,jj-1) ) & 496 & - zp_delstar_t(ji,jj) * zdeltat(ji,jj) 592 497 593 ! sig2 contribution to RHS of U-equation at T-points 594 zs2_rhsu(ji,jj) = - zet(ji,jj) * ( r1_e1v(ji,jj) * zv_c(ji,jj) - r1_e1v(ji,jj-1) * zv_c(ji,jj-1) ) * e1t(ji,jj) * e1t(ji,jj) 595 596 ! sig1 contribution to RHS of V-equation at T-points 597 zs1_rhsv(ji,jj) = zzt(ji,jj) * ( e2u(ji,jj) * zu_c(ji,jj) - e2u(ji-1,jj) * zu_c(ji-1,jj) - 1.0_wp ) 598 599 ! sig2 contribution to RHS of V-equation at T-points 600 zs2_rhsv(ji,jj) = zet(ji,jj) * ( r1_e2u(ji,jj) * zu_c(ji,jj) - r1_e2u(ji-1,jj) * zu_c(ji-1,jj) ) * e2t(ji,jj) * e2t(ji,jj) 601 602 END DO 603 END DO 604 605 CALL iom_put( 'zs1_rhsu' , zs1_rhsu ) ! MV DEBUG 606 CALL iom_put( 'zs2_rhsu' , zs2_rhsu ) ! MV DEBUG 607 CALL iom_put( 'zs1_rhsv' , zs1_rhsv ) ! MV DEBUG 608 CALL iom_put( 'zs2_rhsv' , zs2_rhsv ) ! MV DEBUG 609 610 ! a priori, no lbclnk, because rhsu is only used in the inner domain 611 612 ! --- Stress contributions at f-points 613 ! MV NOTE: I applied zfmask on zds, by mimetism on EVP, but without deep understanding of what I was doing 498 ! sig2 contribution to RHS of U-equation at T-points 499 zs2_rhsu(ji,jj) = - zet(ji,jj) * ( r1_e1v(ji,jj) * zv_c(ji,jj) - r1_e1v(ji,jj-1) * zv_c(ji,jj-1) ) * e1t(ji,jj) * e1t(ji,jj) 500 501 ! sig1 contribution to RHS of V-equation at T-points 502 zs1_rhsv(ji,jj) = zzt(ji,jj) * ( e2u(ji,jj) * zu_c(ji,jj) - e2u(ji-1,jj) * zu_c(ji-1,jj) ) & 503 & - zp_delstar_t(ji,jj) * zdeltat(ji,jj) 504 505 ! sig2 contribution to RHS of V-equation at T-points 506 zs2_rhsv(ji,jj) = zet(ji,jj) * ( r1_e2u(ji,jj) * zu_c(ji,jj) - r1_e2u(ji-1,jj) * zu_c(ji-1,jj) ) * e2t(ji,jj) * e2t(ji,jj) 507 508 END_2D 509 510 ! --- Stress contributions at F-points 511 ! MV NOTE: I applied fimask on zds, by mimetism on EVP, but without deep understanding of what I was doing 614 512 ! My guess is that this is the way to enforce boundary conditions on strain rate tensor 615 513 616 IF( lwp ) WRITE(numout,*) ' outer loop 2 i_out : ', i_out 617 618 DO jj = 1, jpj - 1 619 DO ji = 1, jpi - 1 620 621 ! sig12 contribution to RHS of U equation at F-points 622 zs12_rhsu(ji,jj) = - zef(ji,jj) * ( r1_e2v(ji+1,jj) * zv_c(ji+1,jj) - r1_e2v(ji,jj) * zv_c(ji,jj) ) * e2f(ji,jj) * e2f(ji,jj) * zfmask(ji,jj) 623 624 ! sig12 contribution to RHS of V equation at F-points 625 zs12_rhsv(ji,jj) = zef(ji,jj) * ( r1_e1u(ji,jj+1) * zu_c(ji,jj+1) - r1_e1u(ji,jj) * zu_c(ji,jj) ) * e1f(ji,jj) * e1f(ji,jj) * zfmask(ji,jj) 626 627 END DO 628 END DO 629 630 CALL lbc_lnk( 'icedyn_rhg_vp', zs12_rhsu, 'F', 1. ) 631 CALL lbc_lnk( 'icedyn_rhg_vp', zs12_rhsv, 'F', 1. ) 632 633 CALL iom_put( 'zs12_rhsu' , zs12_rhsu ) ! MV DEBUG 634 CALL iom_put( 'zs12_rhsv' , zs12_rhsv ) ! MV DEBUG 635 636 ! a priori, no lbclnk, because rhsu are only used in the inner domain 637 514 DO_2D( nn_hls, nn_hls-1, nn_hls, nn_hls-1 ) ! 1->jpi-1 515 516 ! sig12 contribution to RHS of U equation at F-points 517 zs12_rhsu(ji,jj) = zef(ji,jj) * ( r1_e2v(ji+1,jj) * zv_c(ji+1,jj) + r1_e2v(ji,jj) * zv_c(ji,jj) ) * e2f(ji,jj) * e2f(ji,jj) * fimask(ji,jj) 518 519 ! sig12 contribution to RHS of V equation at F-points 520 zs12_rhsv(ji,jj) = zef(ji,jj) * ( r1_e1u(ji,jj+1) * zu_c(ji,jj+1) + r1_e1u(ji,jj) * zu_c(ji,jj) ) * e1f(ji,jj) * e1f(ji,jj) * fimask(ji,jj) 521 522 END_2D 523 638 524 ! --- Internal force contributions to RHS, taken as divergence of stresses (Appendix C of Hunke and Dukowicz, 2002) 639 525 ! OPT: merge with next loop and use intermediate scalars for zf_rhsu 640 641 DO jj = 2, jpj - 1 642 DO ji = 2, jpi - 1 526 DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 ) ! 2->jpj-1; 2->jpi-1 527 643 528 ! --- U component of internal force contribution to RHS at U points 644 529 zf_rhsu(ji,jj) = 0.5_wp * r1_e1e2u(ji,jj) * & … … 650 535 zf_rhsv(ji,jj) = 0.5_wp * r1_e1e2v(ji,jj) * & 651 536 & ( e1v(ji,jj) * ( zs1_rhsv(ji,jj+1) - zs1_rhsv(ji,jj) ) & 652 & + r1_e1v(ji,jj) * ( e1t(ji,jj+1) * e1t(ji,jj+1) * zs2_rhsv(ji,jj+1) - e1t(ji,jj) * e1t(ji,jj)* zs2_rhsv(ji,jj) ) &537 & - r1_e1v(ji,jj) * ( e1t(ji,jj+1) * e1t(ji,jj+1) * zs2_rhsv(ji,jj+1) - e1t(ji,jj) * e1t(ji,jj) * zs2_rhsv(ji,jj) ) & 653 538 & + 2._wp * r1_e2v(ji,jj) * ( e2f(ji,jj) * e2f(ji,jj) * zs12_rhsv(ji,jj) - e2f(ji-1,jj) * e2f(ji-1,jj) * zs12_rhsv(ji-1,jj) ) ) 654 655 END DO 656 END DO 657 658 CALL iom_put( 'zf_rhsu' , zf_rhsu ) ! MV DEBUG 659 CALL iom_put( 'zf_rhsv' , zf_rhsv ) ! MV DEBUG 539 540 END_2D 660 541 661 542 !--------------------------- … … 664 545 ! 665 546 ! OPT: could use intermediate scalars to reduce memory access 666 DO jj = 2, jpj - 1 667 DO ji = 2, jpi - 1 668 669 ! still miss ice ocean stress and acceleration contribution 670 zrhsu(ji,jj) = zmU_t(ji,jj) + ztaux_ai(ji,jj) + ztaux_oi_rhsu(ji,jj) + zspgU(ji,jj) + zCorU(ji,jj) + zf_rhsu(ji,jj) 671 zrhsv(ji,jj) = zmV_t(ji,jj) + ztauy_ai(ji,jj) + ztauy_oi_rhsv(ji,jj) + zspgV(ji,jj) + zCorV(ji,jj) + zf_rhsu(ji,jj) 672 673 END DO 674 END DO 675 676 CALL lbc_lnk( 'icedyn_rhg_vp', zrhsu, 'U', -1., zrhsv, 'V', -1.) 677 CALL lbc_lnk( 'icedyn_rhg_vp', zmU_t, 'U', -1., zmV_t, 'V', -1.) 678 CALL lbc_lnk( 'icedyn_rhg_vp', ztaux_oi_rhsu, 'U', -1., ztauy_oi_rhsv, 'V', -1.) 679 680 CALL iom_put( 'zmU_t' , zmU_t ) ! MV DEBUG 681 CALL iom_put( 'zmV_t' , zmV_t ) ! MV DEBUG 682 CALL iom_put( 'ztaux_oi_rhsu' , ztaux_oi_rhsu ) ! MV DEBUG 683 CALL iom_put( 'ztauy_oi_rhsv' , ztauy_oi_rhsv ) ! MV DEBUG 684 CALL iom_put( 'zrhsu' , zrhsu ) ! MV DEBUG 685 CALL iom_put( 'zrhsv' , zrhsv ) ! MV DEBUG 686 687 ! inner domain calculations -> no lbclnk 688 689 IF( lwp ) WRITE(numout,*) ' outer loop 4 i_out : ', i_out 690 547 DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 ) ! 2->jpj-1; 2->jpi-1 548 549 zrhsu(ji,jj) = zmU_t(ji,jj) + ztaux_ai(ji,jj) + ztaux_oi_rhsu(ji,jj) + zspgU(ji,jj) + zCorU(ji,jj) + zf_rhsu(ji,jj) 550 zrhsv(ji,jj) = zmV_t(ji,jj) + ztauy_ai(ji,jj) + ztauy_oi_rhsv(ji,jj) + zspgV(ji,jj) + zCorV(ji,jj) + zf_rhsv(ji,jj) 551 552 END_2D 553 691 554 !---------------------------------------------------------------------------------------! 692 555 ! … … 706 569 ! only zzt and zet are iteration-dependent, other only depend on scale factors 707 570 708 DO ji = 2, jpi - 1 ! internal domain do loop 709 DO jj = 2, jpj - 1 710 711 !------------------------------------- 712 ! -- Internal forces LHS contribution 713 !------------------------------------- 714 ! 715 ! --- U-component 716 ! 717 ! "T" factors (intermediate results) 718 ! 719 zfac = 0.5_wp * r1_e1e2u(ji,jj) 720 zfac1 = zfac * e2u(ji,jj) 721 zfac2 = zfac * r1_e2u(ji,jj) 722 zfac3 = 2._wp * zfac * r1_e1u(ji,jj) 723 724 zt12U = - zfac1 * zzt(ji+1,jj) 725 zt11U = zfac1 * zzt(ji,jj) 726 727 zt22U = - zfac2 * zet(ji+1,jj) * e2t(ji+1,jj) * e2t(ji+1,jj) * e2t(ji+1,jj) * e2t(ji+1,jj) 728 zt21U = zfac2 * zet(ji,jj) * e2t(ji,jj) * e2t(ji,jj) * e2t(ji,jj) * e2t(ji,jj) 729 730 zt122U = - zfac3 * zef(ji,jj) * e1f(ji,jj) * e1f(ji,jj) * e1f(ji,jj) * e1f(ji,jj) 731 zt121U = zfac3 * zef(ji,jj-1) * e1f(ji,jj-1) * e1f(ji,jj-1) * e1f(ji,jj-1) * e1f(ji,jj-1) 571 DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 ) ! 2->jpj-1; 2->jpi-1 572 573 !------------------------------------- 574 ! -- Internal forces LHS contribution 575 !------------------------------------- 576 ! 577 ! --- U-component 578 ! 579 ! "T" factors (intermediate results) 580 ! 581 zfac = 0.5_wp * r1_e1e2u(ji,jj) 582 zfac1 = zfac * e2u(ji,jj) 583 zfac2 = zfac * r1_e2u(ji,jj) 584 zfac3 = 2._wp * zfac * r1_e1u(ji,jj) 585 586 zt11U = zfac1 * zzt(ji,jj) 587 zt12U = zfac1 * zzt(ji+1,jj) 588 589 zt21U = zfac2 * zet(ji,jj) * e2t(ji,jj) * e2t(ji,jj) * e2t(ji,jj) * e2t(ji,jj) 590 zt22U = zfac2 * zet(ji+1,jj) * e2t(ji+1,jj) * e2t(ji+1,jj) * e2t(ji+1,jj) * e2t(ji+1,jj) 591 592 zt121U = zfac3 * zef(ji,jj-1) * e1f(ji,jj-1) * e1f(ji,jj-1) * e1f(ji,jj-1) * e1f(ji,jj-1) 593 zt122U = zfac3 * zef(ji,jj) * e1f(ji,jj) * e1f(ji,jj) * e1f(ji,jj) * e1f(ji,jj) 732 594 733 734 735 736 zAU(ji,jj) = - zt11U * e2u(ji-1,jj) - zt21U* r1_e2u(ji-1,jj)737 zBU(ji,jj) = ( zt12U + zt11U ) * e2u(ji,jj) + ( zt22U + zt21U ) * r1_e2u(ji,jj) + ( zt122U + zt121U ) * r1_e1u(ji,jj)738 zCU(ji,jj) = - zt12U * e2u(ji+1,jj) - zt22U* r1_e2u(ji+1,jj)739 740 zDU(ji,jj) =zt121U * r1_e1u(ji,jj-1)741 zEU(ji,jj) =zt122U * r1_e1u(ji,jj+1)595 ! 596 ! Linear system coefficients 597 ! 598 zAU(ji,jj) = - zt11U * e2u(ji-1,jj) - zt21U * r1_e2u(ji-1,jj) 599 zBU(ji,jj) = ( zt11U + zt12U ) * e2u(ji,jj) + ( zt21U + zt22U ) * r1_e2u(ji,jj) + ( zt121U + zt122U ) * r1_e1u(ji,jj) 600 zCU(ji,jj) = - zt12U * e2u(ji+1,jj) - zt22U * r1_e2u(ji+1,jj) 601 602 zDU(ji,jj) = zt121U * r1_e1u(ji,jj-1) 603 zEU(ji,jj) = zt122U * r1_e1u(ji,jj+1) 742 604 743 744 745 746 747 748 749 zfac1 = zfac * e2v(ji,jj)750 751 752 753 zt12V = - zfac1 * zzt(ji,jj+1)754 zt11V = zfac1 * zzt(ji,jj)755 756 zt22V = zfac2 * zet(ji,jj+1) * e1t(ji,jj+1) * e1t(ji,jj+1) * e1t(ji,jj+1) * e1t(ji,jj+1)757 zt21V = - zfac2 * zet(ji,jj) * e1t(ji,jj) * e1t(ji,jj) * e1t(ji,jj) * e1t(ji,jj)758 759 zt122V = zfac3 * zef(ji,jj) * e2f(ji,jj) * e2f(ji,jj) * e2f(ji,jj) * e2f(ji,jj)760 zt121V = - zfac3 * zef(ji-1,jj) * e2f(ji-1,jj) * e2f(ji-1,jj) * e2f(ji-1,jj) * e2f(ji-1,jj)761 762 763 764 765 zAV(ji,jj) = - zt11V * e1v(ji,jj-1) + zt21V* r1_e1v(ji,jj-1)766 zBV(ji,jj) = ( zt12V + zt11V ) * e1v(ji,jj) - ( zt22V + zt21V ) * r1_e1v(ji,jj) -( zt122V + zt121V ) * r1_e2v(ji,jj)767 zCV(ji,jj) = - zt12V * e1v(ji,jj+1) + zt22V* r1_e1v(ji,jj+1)768 769 zDV(ji,jj) = - zt121V * r1_e2v(ji-1,jj) ! mistake is in the pdf notes not here770 zEV(ji,jj) = -zt122V * r1_e2v(ji+1,jj)605 ! 606 ! --- V-component 607 ! 608 ! "T" factors (intermediate results) 609 ! 610 zfac = 0.5_wp * r1_e1e2v(ji,jj) 611 zfac1 = zfac * e1v(ji,jj) 612 zfac2 = zfac * r1_e1v(ji,jj) 613 zfac3 = 2._wp * zfac * r1_e2v(ji,jj) 614 615 zt11V = zfac1 * zzt(ji,jj) 616 zt12V = zfac1 * zzt(ji,jj+1) 617 618 zt21V = zfac2 * zet(ji,jj) * e1t(ji,jj) * e1t(ji,jj) * e1t(ji,jj) * e1t(ji,jj) 619 zt22V = zfac2 * zet(ji,jj+1) * e1t(ji,jj+1) * e1t(ji,jj+1) * e1t(ji,jj+1) * e1t(ji,jj+1) 620 621 zt121V = zfac3 * zef(ji-1,jj) * e2f(ji-1,jj) * e2f(ji-1,jj) * e2f(ji-1,jj) * e2f(ji-1,jj) 622 zt122V = zfac3 * zef(ji,jj) * e2f(ji,jj) * e2f(ji,jj) * e2f(ji,jj) * e2f(ji,jj) 623 624 ! 625 ! Linear system coefficients 626 ! 627 zAV(ji,jj) = - zt11V * e1v(ji,jj-1) - zt21V * r1_e1v(ji,jj-1) 628 zBV(ji,jj) = ( zt11V + zt12V ) * e1v(ji,jj) + ( zt21V + zt22V ) * r1_e1v(ji,jj) + ( zt122V + zt121V ) * r1_e2v(ji,jj) 629 zCV(ji,jj) = - zt12V * e1v(ji,jj+1) - zt22V * r1_e1v(ji,jj+1) 630 631 zDV(ji,jj) = zt121V * r1_e2v(ji-1,jj) 632 zEV(ji,jj) = zt122V * r1_e2v(ji+1,jj) 771 633 772 !----------------------------------------------------- 773 ! -- Ocean-ice drag and acceleration LHS contribution 774 !----------------------------------------------------- 775 zBU(ji,jj) = zBU(ji,jj) + zCwU(ji,jj) + zmassU_t(ji,jj) 776 zBV(ji,jj) = ZBV(ji,jj) + zCwV(ji,jj) + zmassV_t(ji,jj) 777 778 END DO 779 END DO 780 781 CALL lbc_lnk( 'icedyn_rhg_vp', zAU , 'U', 1., zAV , 'V', 1. ) 782 CALL lbc_lnk( 'icedyn_rhg_vp', zBU , 'U', 1., zBV , 'V', 1. ) 783 CALL lbc_lnk( 'icedyn_rhg_vp', zCU , 'U', 1., zCV , 'V', 1. ) 784 CALL lbc_lnk( 'icedyn_rhg_vp', zDU , 'U', 1., zDV , 'V', 1. ) 785 CALL lbc_lnk( 'icedyn_rhg_vp', zEU , 'U', 1., zEV , 'V', 1. ) 786 787 CALL iom_put( 'zAU' , zAU ) ! MV DEBUG 788 CALL iom_put( 'zBU' , zBU ) ! MV DEBUG 789 CALL iom_put( 'zCU' , zCU ) ! MV DEBUG 790 CALL iom_put( 'zDU' , zDU ) ! MV DEBUG 791 CALL iom_put( 'zEU' , zEU ) ! MV DEBUG 792 CALL iom_put( 'zAV' , zAV ) ! MV DEBUG 793 CALL iom_put( 'zBV' , zBV ) ! MV DEBUG 794 CALL iom_put( 'zCV' , zCV ) ! MV DEBUG 795 CALL iom_put( 'zDV' , zDV ) ! MV DEBUG 796 CALL iom_put( 'zEV' , zEV ) ! MV DEBUG 797 634 !----------------------------------------------------- 635 ! -- Ocean-ice drag and acceleration LHS contribution 636 !----------------------------------------------------- 637 zBU(ji,jj) = zBU(ji,jj) + zCwU(ji,jj) + zmassU_t(ji,jj) 638 zBV(ji,jj) = zBV(ji,jj) + zCwV(ji,jj) + zmassV_t(ji,jj) 639 640 END_2D 641 798 642 !------------------------------------------------------------------------------! 799 643 ! … … 808 652 DO i_inn = 1, nn_vp_ninn ! inner loop iterations 809 653 810 IF( lwp ) WRITE(numout,*) ' inner loop 1 i_inn : ', i_inn811 812 654 !--- mitgcm computes initial value of residual here... 813 655 814 jter = jter + 1 815 ! l_full_nf_update = jter == nn_nvp ! false: disable full North fold update (performances) for iter = 1 to nn_nevp-1 816 817 zu_b(:,:) = u_ice(:,:) ! velocity at previous sub-iterate 818 zv_b(:,:) = v_ice(:,:) 819 820 ! zAU(:,:) = 0._wp; zBU(:,:) = 0._wp; zCU(:,:) = 0._wp; zDU(:,:) = 0._wp; zEU(:,:) = 0._wp 821 ! zAV(:,:) = 0._wp; zBV(:,:) = 0._wp; zCV(:,:) = 0._wp; zDV(:,:) = 0._wp; zEV(:,:) = 0._wp 656 i_inn_tot = i_inn_tot + 1 657 ! l_full_nf_update = i_inn_tot == nn_nvp ! false: disable full North fold update (performances) for iter = 1 to nn_nevp-1 658 659 zu_b(:,:) = u_ice(:,:) ! velocity at previous inner-iterate 660 zv_b(:,:) = v_ice(:,:) 822 661 823 662 IF ( ll_u_iterate .OR. ll_v_iterate ) THEN … … 832 671 ! A*u(i-1,j)+B*u(i,j)+C*u(i+1,j) = F 833 672 834 zFU(:,:) = 0._wp ; zFU_prime(:,:) = 0._wp ; zBU_prime(:,:) = 0._wp; zCU_prime(:,:) = 0._wp673 zFU(:,:) = 0._wp ; zFU_prime(:,:) = 0._wp ; zBU_prime(:,:) = 0._wp; 835 674 836 675 DO jn = 1, nn_zebra_vp ! "zebra" loop (! red-black-sor!!! ) … … 841 680 ELSE ; jj_min = 3 842 681 ENDIF 843 844 IF ( lwp ) WRITE(numout,*) ' Into the U-zebra loop at step jn = ', jn, ', with jj_min = ', jj_min845 682 846 683 DO jj = jj_min, jpj - 1, nn_zebra_vp … … 850 687 !------------------------ 851 688 DO ji = 2, jpi - 1 852 853 ! boundary condition substitution 689 ! note: these are key lines linking information between processors 690 ! u_ice/v_ice need to be lbc_linked 691 692 ! sub-domain boundary condition substitution 854 693 ! see Zhang and Hibler, 1997, Appendix B 855 694 zAA3 = 0._wp … … 867 706 END DO 868 707 869 CALL lbc_lnk( 'icedyn_rhg_vp', zFU, 'U', 1. )870 871 708 !--------------- 872 709 ! Forward sweep … … 874 711 DO jj = jj_min, jpj - 1, nn_zebra_vp 875 712 713 zBU_prime(2,jj) = zBU(2,jj) 714 zFU_prime(2,jj) = zFU(2,jj) 715 876 716 DO ji = 3, jpi - 1 877 717 … … 884 724 885 725 END DO 886 887 CALL lbc_lnk( 'icedyn_rhg_vp', zFU_prime, 'U', 1., zBU_prime, 'U', 1. ) 888 726 889 727 !----------------------------- 890 728 ! Backward sweep & relaxation … … 894 732 895 733 ! --- Backward sweep 734 896 735 ! last row 897 736 zfac = SIGN( 1._wp , zBU_prime(jpi-1,jj) ) * MAX( 0._wp , SIGN( 1._wp , ABS( zBU_prime(jpi-1,jj) ) - epsi20 ) ) 898 737 u_ice(jpi-1,jj) = zfac * zFU_prime(jpi-1,jj) / MAX( ABS ( zBU_prime(jpi-1,jj) ) , epsi20 ) & 899 738 & * umask(jpi-1,jj,1) 900 DO ji = jpi-2 , 2, -1 ! all other rows ! ---> original backward loop 739 740 DO ji = jpi - 2 , 2, -1 ! all other rows ! ---> original backward loop 901 741 zfac = SIGN( 1._wp , zBU_prime(ji,jj) ) * MAX( 0._wp , SIGN( 1._wp , ABS( zBU_prime(ji,jj) ) - epsi20 ) ) 902 742 u_ice(ji,jj) = zfac * ( zFU_prime(ji,jj) - zCU(ji,jj) * u_ice(ji+1,jj) ) * umask(ji,jj,1) & … … 904 744 END DO 905 745 906 !--- Relaxation 907 ! and velocity masking for little-ice and no-ice cases 746 !--- Relaxation and masking (for low-ice/no-ice cases) 908 747 DO ji = 2, jpi - 1 909 748 … … 917 756 918 757 END DO ! jj 758 759 CALL lbc_lnk( 'icedyn_rhg_vp', u_ice, 'U', -1. ) 919 760 920 761 END DO ! zebra loop … … 932 773 !!! ZH97 explain it is critical for convergence speed 933 774 934 zFV(:,:) = 0._wp ; zFV_prime(:,:) = 0._wp ; zBV_prime(:,:) = 0._wp; zCV_prime(:,:) = 0._wp775 zFV(:,:) = 0._wp ; zFV_prime(:,:) = 0._wp ; zBV_prime(:,:) = 0._wp; 935 776 936 777 DO jn = 1, nn_zebra_vp ! "zebra" loop … … 940 781 ENDIF 941 782 942 IF ( lwp ) WRITE(numout,*) ' Into the V-zebra loop at step jn = ', jn, ', with ji_min = ', ji_min943 944 783 DO ji = ji_min, jpi - 1, nn_zebra_vp 945 784 … … 949 788 DO jj = 2, jpj - 1 950 789 951 ! boundary condition substitution (check it is correctly applied !!!)790 ! subdomain boundary condition substitution (check it is correctly applied !!!) 952 791 ! see Zhang and Hibler, 1997, Appendix B 953 792 zAA3 = 0._wp … … 965 804 END DO 966 805 967 CALL lbc_lnk( 'icedyn_rhg_vp', zFV, 'V', 1.)968 969 806 !--------------- 970 807 ! Forward sweep … … 972 809 DO ji = ji_min, jpi - 1, nn_zebra_vp 973 810 974 DO jj = 3, jpj - 1 811 zBV_prime(ji,2) = zBV(ji,2) 812 zFV_prime(ji,2) = zFV(ji,2) 813 814 DO jj = 3, jpj - 1 975 815 976 816 zfac = SIGN( 1._wp , zBV(ji,jj-1) ) * MAX( 0._wp , SIGN( 1._wp , ABS( zBV(ji,jj-1) ) - epsi20 ) ) … … 983 823 END DO 984 824 985 CALL lbc_lnk( 'icedyn_rhg_vp', zFV_prime, 'V', 1., zBV_prime, 'V', 1. )986 987 825 !----------------------------- 988 826 ! Backward sweep & relaxation … … 1003 841 END DO 1004 842 1005 ! --- Relaxation & masking (should it be now or later)843 ! --- Relaxation & masking 1006 844 DO jj = 2, jpj - 1 1007 845 … … 1015 853 1016 854 END DO ! ji 855 856 CALL lbc_lnk( 'icedyn_rhg_vp', v_ice, 'V', -1. ) 1017 857 1018 858 END DO ! zebra loop … … 1020 860 ENDIF ! ll_v_iterate 1021 861 1022 CALL lbc_lnk( 'icedyn_rhg_vp', u_ice, 'U', -1., v_ice, 'V', -1. )862 ! I suspect the communication should go into the zebra loop if we want reproducibility 1023 863 1024 864 !-------------------------------------------------------------------------------------- … … 1031 871 ! MV OPT: if the number of iterations to convergence is really variable, and keep the convergence check 1032 872 ! then we must optimize the use of the mpp_max, which is prohibitive 1033 zuerr_max = 0._wp873 zuerr_max = 0._wp 1034 874 1035 875 IF ( ll_u_iterate .AND. MOD ( i_inn, nn_vp_chkcvg ) == 0 ) THEN … … 1037 877 ! - Maximum U-velocity difference 1038 878 zuerr(:,:) = 0._wp 1039 DO jj = 2, jpj - 1 1040 DO ji = 2, jpi - 1 1041 zuerr(ji,jj) = ABS ( ( u_ice(ji,jj) - zu_b(ji,jj) ) ) * umask(ji,jj,1) 1042 END DO 1043 END DO 879 DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 ) ! 2->jpj-1; 2->jpi-1 880 881 zuerr(ji,jj) = ABS ( ( u_ice(ji,jj) - zu_b(ji,jj) ) ) * umask(ji,jj,1) 882 883 END_2D 884 1044 885 zuerr_max = MAXVAL( zuerr ) 1045 886 CALL mpp_max( 'icedyn_rhg_evp', zuerr_max ) ! max over the global domain - damned! 1046 1047 ! - Stop if error is too large ("safeguard against bad forcing" of original Zhang routine)887 888 ! - Stop if max error is too large ("safeguard against bad forcing" of original Zhang routine) 1048 889 IF ( i_inn > 1 .AND. zuerr_max > zuerr_max_vp ) THEN 1049 890 IF ( lwp ) WRITE(numout,*) " VP rheology error was too large : ", zuerr_max, " in outer U-iteration ", i_out, " after ", i_inn, " iterations, we stopped " … … 1068 909 ! - Maximum V-velocity difference 1069 910 zverr(:,:) = 0._wp 1070 DO jj = 2, jpj -11071 DO ji = 2, jpi - 1911 DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 ) ! 2->jpj-1; 2->jpi-1 912 1072 913 zverr(ji,jj) = ABS ( ( v_ice(ji,jj) - zv_b(ji,jj) ) ) * vmask(ji,jj,1) 1073 END DO1074 END DO1075 914 915 END_2D 916 1076 917 zverr_max = MAXVAL( zverr ) 1077 918 CALL mpp_max( 'icedyn_rhg_evp', zverr_max ) ! max over the global domain - damned! … … 1098 939 ! 1099 940 !--------------------------------------------------------------------------------------- 1100 1101 IF( nn_rhg_chkcvg/=0 .AND. MOD ( i_inn - 1, nn_vp_chkcvg ) == 0 ) CALL rhg_cvg_vp( kt, jter, nn_nvp, u_ice, v_ice, zmt, zuerr_max, zverr_max, zglob_area, & 1102 & zrhsu, zAU, zBU, zCU, zDU, zEU, zrhsv, zAV, zBV, zCV, zDV, zEV ) 1103 1104 IF ( lwp ) WRITE(numout,*) ' Done convergence tests ' 941 IF( nn_rhg_chkcvg/=0 .AND. MOD ( i_inn - 1, nn_vp_chkcvg ) == 0 ) THEN 942 943 CALL rhg_cvg_vp( kt, i_out, i_inn, i_inn_tot, nn_vp_nout, nn_vp_ninn, nn_nvp, & 944 & u_ice, v_ice, zu_b, zv_b, zu_c, zv_c, & 945 & zmt, za_iU, za_iV, zuerr_max, zverr_max, zglob_area, & 946 & zrhsu, zAU, zBU, zCU, zDU, zEU, zFU, & 947 & zrhsv, zAV, zBV, zCV, zDV, zEV, zFV, & 948 zvel_res, zvel_diff ) 949 950 ENDIF 1105 951 1106 952 END DO ! i_inn, end of inner loop … … 1108 954 END DO ! End of outer loop (i_out) ============================================================================================= 1109 955 1110 IF ( lwp ) WRITE(numout,*) ' We are out of outer loop ' 1111 1112 CALL lbc_lnk( 'icedyn_rhg_vp', zFU , 'U', 1., zFV , 'V', 1. ) 1113 CALL lbc_lnk( 'icedyn_rhg_vp', zBU_prime , 'U', 1., zBV_prime , 'V', 1. ) 1114 CALL lbc_lnk( 'icedyn_rhg_vp', zFU_prime , 'U', 1., zFV_prime , 'V', 1. ) 1115 CALL lbc_lnk( 'icedyn_rhg_vp', zCU_prime , 'U', 1., zCV_prime , 'V', 1. ) 1116 1117 CALL iom_put( 'zFU' , zFU ) ! MV DEBUG 1118 CALL iom_put( 'zBU_prime' , zBU_prime ) ! MV DEBUG 1119 CALL iom_put( 'zCU_prime' , zCU_prime ) ! MV DEBUG 1120 CALL iom_put( 'zFU_prime' , zFU_prime ) ! MV DEBUG 1121 1122 CALL iom_put( 'zFV' , zFV ) ! MV DEBUG 1123 CALL iom_put( 'zBV_prime' , zBV_prime ) ! MV DEBUG 1124 CALL iom_put( 'zCV_prime' , zCV_prime ) ! MV DEBUG 1125 CALL iom_put( 'zFV_prime' , zFV_prime ) ! MV DEBUG 1126 1127 CALL lbc_lnk( 'icedyn_rhg_vp', u_ice, 'U', -1., v_ice, 'V', -1. ) 1128 1129 IF ( lwp ) WRITE(numout,*) ' We are about to output uice_dbg ' 1130 IF( iom_use('uice_dbg' ) ) CALL iom_put( 'uice_dbg' , u_ice ) ! ice velocity u after solver 1131 IF( iom_use('vice_dbg' ) ) CALL iom_put( 'vice_dbg' , v_ice ) ! ice velocity v after solver 1132 956 IF( nn_rhg_chkcvg/=0 ) THEN 957 958 IF( iom_use('velo_res') ) CALL iom_put( 'velo_res', zvel_res ) ! linear system residual @last inner&outer iteration 959 IF( iom_use('velo_ero') ) CALL iom_put( 'velo_ero', zvel_diff ) ! abs velocity difference @last outer iteration 960 IF( iom_use('uice_eri') ) CALL iom_put( 'uice_eri', zuerr ) ! abs velocity difference @last inner iteration 961 IF( iom_use('vice_eri') ) CALL iom_put( 'vice_eri', zverr ) ! abs velocity difference @last inner iteration 962 963 DEALLOCATE( zvel_res , zvel_diff ) 964 965 ENDIF ! nn_rhg_chkcvg 966 1133 967 !------------------------------------------------------------------------------! 1134 968 ! 1135 ! --- Convergence diagnostics969 ! --- Recompute delta, shear and div (inputs for mechanical redistribution) 1136 970 ! 1137 971 !------------------------------------------------------------------------------! 1138 1139 IF( nn_rhg_chkcvg /= 0 ) THEN1140 1141 IF( iom_use('uice_cvg') ) THEN1142 CALL iom_put( 'uice_cvg', MAX( ABS( u_ice(:,:) - zu_b(:,:) ) * umask(:,:,1) , & ! ice velocity difference at last iteration1143 & ABS( v_ice(:,:) - zv_b(:,:) ) * vmask(:,:,1) ) * zmsk15(:,:) )1144 ENDIF1145 1146 ENDIF1147 1148 ! MV DEBUG test - replace ice velocity by ocean current to give the model the means to go ahead1149 DO jj = 2, jpj - 11150 DO ji = 2, jpi - 11151 1152 u_ice(ji,jj) = zmsk00x(ji,jj) &1153 & * ( zmsk01x(ji,jj) * u_oce(ji,jj) * 0.01_wp &1154 + ( 1._wp - zmsk01x(ji,jj) ) * u_oce(ji,jj) * 0.01_wp )1155 1156 v_ice(ji,jj) = zmsk00y(ji,jj) &1157 & * ( zmsk01y(ji,jj) * v_oce(ji,jj) * 0.01_wp &1158 + ( 1._wp - zmsk01y(ji,jj) ) * v_oce(ji,jj) * 0.01_wp )1159 1160 END DO1161 END DO1162 1163 CALL lbc_lnk( 'icedyn_rhg_vp', u_ice, 'U', -1., v_ice, 'V', -1. )1164 1165 IF ( lwp ) WRITE(numout,*) ' Velocity replaced '1166 1167 ! END DEBUG1168 1169 !------------------------------------------------------------------------------!1170 !1171 ! --- Recompute delta, shear and div (inputs for mechanical redistribution)1172 !1173 !------------------------------------------------------------------------------!1174 972 ! 1175 973 ! MV OPT: subroutinize ? 1176 1177 DO jj = 1, jpj - 1 1178 DO ji = 1, jpi - 1 974 DO_2D( nn_hls, nn_hls, nn_hls-1, nn_hls-1 ) ! 1->jpj-1; 1->jpi-1 1179 975 1180 976 ! shear at F points 1181 977 zds(ji,jj) = ( ( u_ice(ji,jj+1) * r1_e1u(ji,jj+1) - u_ice(ji,jj) * r1_e1u(ji,jj) ) * e1f(ji,jj) * e1f(ji,jj) & 1182 978 & + ( v_ice(ji+1,jj) * r1_e2v(ji+1,jj) - v_ice(ji,jj) * r1_e2v(ji,jj) ) * e2f(ji,jj) * e2f(ji,jj) & 1183 & ) * r1_e1e2f(ji,jj) * zfmask(ji,jj) 1184 1185 END DO 1186 END DO 1187 1188 DO jj = 2, jpj - 1 1189 DO ji = 2, jpi - 1 ! 979 & ) * r1_e1e2f(ji,jj) * fimask(ji,jj) 980 981 END_2D 982 983 DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 ) ! 2->jpj-1; 2->jpi-1 1190 984 1191 985 ! tension**2 at T points … … 1195 989 zdt2 = zdt * zdt 1196 990 1197 zten _i(ji,jj)= zdt991 ztens(ji,jj) = zdt 1198 992 1199 993 ! shear**2 at T points (doc eq. A16) … … 1202 996 & ) * 0.25_wp * r1_e1e2t(ji,jj) 1203 997 1204 ! shear at T points 1205 pshear_i(ji,jj) = SQRT( zdt2 + zds2 ) 998 ! maximum shear rate at T points (includees tension, output only) 999 pshear_i(ji,jj) = SQRT( zdt2 + zds2 ) ! i think this is maximum shear rate and not actual shear --- i'm not totally sure here 1000 1001 ! shear at T-points 1002 zshear(ji,jj) = SQRT( zds2 ) 1206 1003 1207 1004 ! divergence at T points … … 1209 1006 & + e1v(ji,jj) * v_ice(ji,jj) - e1v(ji,jj-1) * v_ice(ji,jj-1) & 1210 1007 & ) * r1_e1e2t(ji,jj) 1008 1009 zdiv2 = pdivu_i(ji,jj) * pdivu_i(ji,jj) 1211 1010 1212 1011 ! delta at T points 1213 zdelta = SQRT( pdivu_i(ji,jj) * pdivu_i(ji,jj) + ( zdt2 + zds2 ) * z1_ecc2 )1012 zdelta = SQRT( zdiv2 + ( zdt2 + zds2 ) * z1_ecc2 ) 1214 1013 rswitch = 1._wp - MAX( 0._wp, SIGN( 1._wp, -zdelta ) ) ! 0 if delta=0 1215 1216 !pdelta_i(ji,jj) = zdelta + rn_creepl * rswitch 1217 pdelta_i(ji,jj) = zdelta + rn_creepl 1218 1219 END DO 1220 END DO 1221 1222 IF ( lwp ) WRITE(numout,*) ' Deformation recalculated ' 1014 1015 pdelta_i(ji,jj) = zdelta + rn_creepl ! * rswitch 1016 1017 END_2D 1223 1018 1224 1019 CALL lbc_lnk( 'icedyn_rhg_vp', pshear_i, 'T', 1., pdivu_i, 'T', 1., pdelta_i, 'T', 1. ) … … 1237 1032 ! 1238 1033 ! ---- Sea ice stresses at T-points 1239 IF ( iom_use('normstr') .OR. iom_use('sheastr') .OR. iom_use('intstrx') .OR. iom_use('intstry') ) THEN 1240 1241 DO jj = 2, jpj - 1 1242 DO ji = 2, jpi - 1 1243 zp_deltastar_t(ji,jj) = strength(ji,jj) / pdelta_i(ji,jj) 1244 zfac = zp_deltastar_t(ji,jj) 1034 IF ( iom_use('normstr') .OR. iom_use('sheastr') .OR. & 1035 & iom_use('intstrx') .OR. iom_use('intstry') .OR. & 1036 & iom_use('sig1_pnorm') .OR. iom_use('sig2_pnorm') ) THEN 1037 1038 DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 ) ! 2->jpj-1; 2->jpi-1 1039 1040 zp_delstar_t(ji,jj) = strength(ji,jj) / pdelta_i(ji,jj) 1041 zfac = zp_delstar_t(ji,jj) 1245 1042 zs1(ji,jj) = zfac * ( pdivu_i(ji,jj) - pdelta_i(ji,jj) ) 1246 zs2(ji,jj) = zfac * z1_ecc2 * zten _i(ji,jj)1247 zs12(ji,jj) = zfac * z1_ecc2 * pshear_i(ji,jj)1248 END DO 1249 END DO1043 zs2(ji,jj) = zfac * z1_ecc2 * ztens(ji,jj) 1044 zs12(ji,jj) = zfac * z1_ecc2 * zshear(ji,jj) * 0.5_wp ! Bug 12 nov 1045 1046 END_2D 1250 1047 1251 1048 CALL lbc_lnk( 'icedyn_rhg_vp', zs1, 'T', 1., zs2, 'T', 1., zs12, 'T', 1. ) … … 1256 1053 IF ( iom_use('intstrx') .OR. iom_use('intstry') ) THEN 1257 1054 1258 DO jj = 1, jpj - 1 1259 DO ji = 1, jpi - 1 1055 DO_2D( nn_hls, nn_hls, nn_hls-1, nn_hls-1 ) ! 1->jpj-1; 1->jpi-1 1260 1056 1261 1057 ! P/delta* at F points 1262 zp_del tastar_f = 0.25_wp * ( zp_deltastar_t(ji,jj) + zp_deltastar_t(ji+1,jj) + zp_deltastar_t(ji,jj+1) + zp_deltastar_t(ji+1,jj+1) )1058 zp_delstar_f = 0.25_wp * ( zp_delstar_t(ji,jj) + zp_delstar_t(ji+1,jj) + zp_delstar_t(ji,jj+1) + zp_delstar_t(ji+1,jj+1) ) 1263 1059 1264 1060 ! s12 at F-points 1265 zs12f(ji,jj) = zp_del tastar_f * z1_ecc2 * zds(ji,jj)1061 zs12f(ji,jj) = zp_delstar_f * z1_ecc2 * zds(ji,jj) 1266 1062 1267 END DO 1268 END DO 1063 END_2D 1269 1064 1270 1065 CALL lbc_lnk( 'icedyn_rhg_vp', zs12f, 'F', 1. ) 1271 1066 1272 1067 ENDIF 1273 1274 IF ( lwp ) WRITE(numout,*) ' zs12f recalculated '1275 1068 1276 1069 ! … … 1286 1079 1287 1080 !--- Recalculate oceanic stress at last inner iteration 1288 DO jj = 2, jpj - 1 1289 DO ji = 2, jpi - 1 1081 DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 ) ! 2->jpj-1; 2->jpi-1 1290 1082 1291 1083 !--- ice u-velocity @V points, v-velocity @U points (for non-linear drag computation) … … 1303 1095 ztauy_oi(ji,jj) = zCwV(ji,jj) * ( v_oce(ji,jj) - v_ice(ji,jj) ) 1304 1096 1305 END DO 1306 END DO 1097 END_2D 1307 1098 1308 1099 ! 1309 1100 CALL lbc_lnk( 'icedyn_rhg_vp', ztaux_oi, 'U', -1., ztauy_oi, 'V', -1., ztaux_ai, 'U', -1., ztauy_ai, 'V', -1. ) !, & 1310 ! & 1101 ! & ztaux_bi, 'U', -1., ztauy_bi, 'V', -1. ) 1311 1102 ! 1312 1103 CALL iom_put( 'utau_oi' , ztaux_oi * zmsk00 ) … … 1323 1114 ! --- Divergence, shear and strength --- ! 1324 1115 IF( iom_use('icediv') ) CALL iom_put( 'icediv' , pdivu_i * zmsk00 ) ! divergence 1325 IF( iom_use('iceshe') ) CALL iom_put( 'iceshe' , pshear_i * zmsk00 ) ! shear1116 IF( iom_use('iceshe') ) CALL iom_put( 'iceshe' , pshear_i * zmsk00 ) ! maximum shear rate 1326 1117 IF( iom_use('icedlt') ) CALL iom_put( 'icedlt' , pdelta_i * zmsk00 ) ! delta 1327 1118 IF( iom_use('icestr') ) CALL iom_put( 'icestr' , strength * zmsk00 ) ! strength 1328 1119 1329 IF ( lwp ) WRITE(numout,*) 'Some terms recalculated '1330 1331 1120 ! --- Stress tensor invariants (SIMIP diags) --- ! 1332 1121 IF( iom_use('normstr') .OR. iom_use('sheastr') ) THEN … … 1340 1129 ALLOCATE( zsig_I(jpi,jpj) , zsig_II(jpi,jpj) ) 1341 1130 ! 1342 DO jj = 2, jpj - 1 1343 DO ji = 2, jpi - 1 1131 DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 ) ! 2->jpj-1; 2->jpi-1 1344 1132 ! Stress invariants 1345 zsig_I(ji,jj) = zs1(ji,jj) * 0.5_wp ! 1st invariant, aka average normal stress aka negative pressure 1346 zsig_II(ji,jj) = SQRT ( zs2(ji,jj) * zs2(ji,jj) * 0.25_wp + zs12(ji,jj) ) ! 2nd invariant, aka maximum shear stress 1347 END DO 1348 END DO 1133 zsig_I(ji,jj) = zs1(ji,jj) * 0.5_wp ! 1st invariant, aka average normal stress aka negative pressure 1134 zsig_II(ji,jj) = 0.5_wp * SQRT ( zs2(ji,jj) * zs2(ji,jj) + 4. * zs12(ji,jj) * zs12(ji,jj) ) ! 2nd invariant, aka maximum shear stress 1135 END_2D 1349 1136 1350 1137 CALL lbc_lnk( 'icedyn_rhg_vp', zsig_I, 'T', 1., zsig_II, 'T', 1.) … … 1356 1143 1357 1144 ENDIF 1358 1359 IF ( lwp ) WRITE(numout,*) 'SIMIP work done'1360 1145 1361 1146 ! --- Normalized stress tensor principal components --- ! … … 1370 1155 ALLOCATE( zsig1_p(jpi,jpj) , zsig2_p(jpi,jpj) , zsig_I(jpi,jpj) , zsig_II(jpi,jpj) ) 1371 1156 ! 1372 DO jj = 2, jpj -11373 DO ji = 2, jpi - 11157 DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 ) ! 2->jpj-1; 2->jpi-1 1158 1374 1159 ! Ice stresses computed with **viscosities** (delta, p/delta) at **previous** iterates 1375 1160 ! and **deformations** at current iterates 1376 1161 ! following Lemieux & Dupont (2020) 1377 zfac = zp_deltastar_t(ji,jj) 1378 zsig1 = zfac * ( pdivu_i(ji,jj) - zdeltastar_t(ji,jj) ) 1379 zsig1 = 0._wp !!! FUCKING DEBUG TEST !!! 1380 zsig2 = zfac * z1_ecc2 * zten_i(ji,jj) 1381 zsig12 = zfac * z1_ecc2 * pshear_i(ji,jj) 1162 zfac = zp_delstar_t(ji,jj) 1163 zsig1 = zfac * ( pdivu_i(ji,jj) - zdeltat(ji,jj) ) 1164 zsig2 = zfac * z1_ecc2 * ztens(ji,jj) 1165 zsig12 = zfac * z1_ecc2 * zshear(ji,jj) * 0.5_wp ! Bugfix 12 Nov 1382 1166 1383 1167 ! Stress invariants (sigma_I, sigma_II, Coon 1974, Feltham 2008), T-point 1384 zsig_I(ji,jj) = zsig1 * 0.5_wp ! 1st invariant1385 zsig_II(ji,jj) = SQRT ( zsig2 * zsig2 * 0.25_wp +zsig12 ) ! 2nd invariant1168 zsig_I(ji,jj) = zsig1 * 0.5_wp ! 1st invariant 1169 zsig_II(ji,jj) = 0.5_wp * SQRT ( zsig2 * zsig2 + 4. *zsig12 * zsig12 ) ! 2nd invariant 1386 1170 1387 1171 ! Normalized principal stresses (used to display the ellipse) … … 1389 1173 zsig1_p(ji,jj) = ( zsig_I(ji,jj) + zsig_II(ji,jj) ) * z1_strength 1390 1174 zsig2_p(ji,jj) = ( zsig_I(ji,jj) - zsig_II(ji,jj) ) * z1_strength 1391 END DO 1392 END DO 1393 IF ( lwp ) WRITE(numout,*) 'Some shitty stress work done' 1175 1176 END_2D 1394 1177 ! 1395 1178 CALL lbc_lnk( 'icedyn_rhg_vp', zsig1_p, 'T', 1., zsig2_p, 'T', 1.) 1396 !1397 IF ( lwp ) WRITE(numout,*) ' Beauaaaarflblbllll '1398 1179 ! 1399 1180 CALL iom_put( 'sig1_pnorm' , zsig1_p ) … … 1401 1182 1402 1183 DEALLOCATE( zsig1_p , zsig2_p , zsig_I , zsig_II ) 1403 1404 IF ( lwp ) WRITE(numout,*) ' So what ??? '1405 1184 1406 1185 ENDIF … … 1411 1190 1412 1191 ! --- Recalculate Coriolis stress at last inner iteration 1413 DO jj = 2, jpj - 1 1414 DO ji = 2, jpi - 1 1192 DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 ) ! 2->jpj-1; 2->jpi-1 1415 1193 ! --- U-component 1416 1194 zCorU(ji,jj) = 0.25_wp * r1_e1u(ji,jj) * & … … 1420 1198 & ( zmf(ji,jj ) * ( e2u(ji,jj ) * u_ice(ji,jj ) + e2u(ji-1,jj ) * u_ice(ji-1,jj ) ) & 1421 1199 & + zmf(ji,jj+1) * ( e2u(ji,jj+1) * u_ice(ji,jj+1) + e2u(ji-1,jj+1) * u_ice(ji-1,jj+1) ) ) 1422 END DO 1423 END DO 1200 END_2D 1424 1201 ! 1425 1202 CALL lbc_lnk( 'icedyn_rhg_vp', zspgU, 'U', -1., zspgV, 'V', -1., & … … 1436 1213 1437 1214 ! Recalculate internal forces (divergence of stress tensor) at last inner iteration 1438 DO jj = 2, jpj -11439 DO ji = 2, jpi - 1 1215 DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 ) ! 2->jpj-1; 2->jpi-1 1216 1440 1217 zfU(ji,jj) = 0.5_wp * ( ( zs1(ji+1,jj) - zs1(ji,jj) ) * e2u(ji,jj) & 1441 1218 & + ( zs2(ji+1,jj) * e2t(ji+1,jj) * e2t(ji+1,jj) - zs2(ji,jj) * e2t(ji,jj) * e2t(ji,jj) & … … 1444 1221 & ) * 2._wp * r1_e1u(ji,jj) & 1445 1222 & ) * r1_e1e2u(ji,jj) 1223 1446 1224 zfV(ji,jj) = 0.5_wp * ( ( zs1(ji,jj+1) - zs1(ji,jj) ) * e1v(ji,jj) & 1447 1225 & - ( zs2(ji,jj+1) * e1t(ji,jj+1) * e1t(ji,jj+1) - zs2(ji,jj) * e1t(ji,jj) * e1t(ji,jj) & … … 1450 1228 & ) * 2._wp * r1_e2v(ji,jj) & 1451 1229 & ) * r1_e1e2v(ji,jj) 1452 END DO 1453 END DO1230 1231 END_2D 1454 1232 1455 1233 CALL lbc_lnk( 'icedyn_rhg_vp', zfU, 'U', -1., zfV, 'V', -1. ) … … 1467 1245 & zdiag_xmtrp_snw(jpi,jpj) , zdiag_ymtrp_snw(jpi,jpj) , zdiag_xatrp(jpi,jpj) , zdiag_yatrp(jpi,jpj) ) 1468 1246 ! 1469 DO jj = 2, jpj - 1 1470 DO ji = 2, jpi - 1 1471 ! 2D ice mass, snow mass, area transport arrays (X, Y) 1247 DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 ) ! 2->jpj-1; 2->jpi-1 ! 2D ice mass, snow mass, area transport arrays (X, Y) 1248 1472 1249 zfac_x = 0.5 * u_ice(ji,jj) * e2u(ji,jj) * zmsk00(ji,jj) 1473 1250 zfac_y = 0.5 * v_ice(ji,jj) * e1v(ji,jj) * zmsk00(ji,jj) … … 1482 1259 zdiag_yatrp(ji,jj) = zfac_y * ( at_i(ji,jj+1) + at_i(ji,jj) ) ! '' Y- '' 1483 1260 1484 END DO 1485 END DO 1486 1261 END_2D 1262 1487 1263 CALL lbc_lnk( 'icedyn_rhg_vp', zdiag_xmtrp_ice, 'U', -1., zdiag_ymtrp_ice, 'V', -1., & 1488 1264 & zdiag_xmtrp_snw, 'U', -1., zdiag_ymtrp_snw, 'V', -1., & … … 1501 1277 ENDIF 1502 1278 1503 DEALLOCATE( zmsk00, zmsk15 )1504 1505 1279 END SUBROUTINE ice_dyn_rhg_vp 1506 1280 1507 1281 1508 1509 SUBROUTINE rhg_cvg_vp( kt, kiter, kitermax, pu, pv, pmt, puerr_max, pverr_max, pglob_area, & 1510 & prhsu, pAU, pBU, pCU, pDU, pEU, prhsv, pAV, pBV, pCV, pDV, pEV ) 1511 1282 SUBROUTINE rhg_cvg_vp( kt, kitout, kitinn, kitinntot, kitoutmax, kitinnmax, kitinntotmax , & 1283 & pu, pv, pub, pvb, pub_outer, pvb_outer , & 1284 & pmt, pat_iu, pat_iv, puerr_max, pverr_max, pglob_area , & 1285 & prhsu, pAU, pBU, pCU, pDU, pEU, pFU , & 1286 & prhsv, pAV, pBV, pCV, pDV, pEV, pFV , & 1287 & pvel_res, pvel_diff ) 1288 !! 1512 1289 !!---------------------------------------------------------------------- 1513 1290 !! *** ROUTINE rhg_cvg_vp *** … … 1524 1301 !! 1525 1302 !! ** Note : for the first sub-iteration, uice_cvg is set to 0 (too large otherwise) 1303 !! 1526 1304 !!---------------------------------------------------------------------- 1527 INTEGER , INTENT(in) :: kt, kiter, kitermax ! ocean time-step index 1528 REAL(wp), DIMENSION(:,:), INTENT(in) :: pu, pv, pmt ! now velocity and mass per unit area 1529 REAL(wp), INTENT(in) :: puerr_max, pverr_max ! absolute mean velocity difference 1530 REAL(wp), INTENT(in) :: pglob_area ! global ice area 1531 REAL(wp), DIMENSION(:,:), INTENT(in) :: prhsu, pAU, pBU, pCU, pDU, pEU ! linear system coefficients 1532 REAL(wp), DIMENSION(:,:), INTENT(in) :: prhsv, pAV, pBV, pCV, pDV, pEV 1533 !! 1534 INTEGER :: it, idtime, istatus, ix_dim, iy_dim 1305 !! 1306 INTEGER , INTENT(in) :: kt, kitout, kitinn, kitinntot ! ocean model iterate, outer, inner and total n-iterations 1307 INTEGER , INTENT(in) :: kitoutmax, kitinnmax ! max number of outer & inner iterations 1308 INTEGER , INTENT(in) :: kitinntotmax ! max number of total sub-iterations 1309 REAL(wp), DIMENSION(:,:), INTENT(in) :: pu, pv, pub, pvb ! now & sub-iter-before velocities 1310 REAL(wp), DIMENSION(:,:), INTENT(in) :: pub_outer, pvb_outer ! velocities @before outer iterations 1311 REAL(wp), DIMENSION(:,:), INTENT(in) :: pmt, pat_iu, pat_iv ! mass at T-point, ice concentration at U&V 1312 REAL(wp), INTENT(in) :: puerr_max, pverr_max ! absolute mean velocity difference 1313 REAL(wp), INTENT(in) :: pglob_area ! global ice area 1314 REAL(wp), DIMENSION(:,:), INTENT(in) :: prhsu, pAU, pBU, pCU, pDU, pEU, pFU ! linear system coefficients 1315 REAL(wp), DIMENSION(:,:), INTENT(in) :: prhsv, pAV, pBV, pCV, pDV, pEV, pFV 1316 REAL(wp), DIMENSION(:,:), INTENT(inout) :: pvel_res ! velocity residual @last inner iteration 1317 REAL(wp), DIMENSION(:,:), INTENT(inout) :: pvel_diff ! velocity difference @last outer iteration 1318 !! 1319 1320 INTEGER :: idtime, istatus, ix_dim, iy_dim 1535 1321 INTEGER :: ji, jj ! dummy loop indices 1536 REAL(wp) :: zveldif, zu_res_mean, zv_res_mean, zvelres, zmke, zu, zv ! local scalars 1537 REAL(wp) :: z1_pglob_area 1322 INTEGER :: it_inn_file, it_out_file 1323 REAL(wp) :: zu_res_mean, zv_res_mean, zvel_res_mean ! mean residuals of the linear system 1324 REAL(wp) :: zu_mad, zv_mad, zvel_mad ! mean absolute deviation, sub-iterates 1325 REAL(wp) :: zu_mad_outer, zv_mad_outer, zvel_mad_outer ! mean absolute deviation, outer-iterates 1326 REAL(wp) :: zvel_err_max, zmke, zu, zv ! local scalars 1327 REAL(wp) :: z1_pglob_area ! inverse global ice area 1328 1538 1329 REAL(wp), DIMENSION(jpi,jpj) :: zu_res, zv_res, zvel2 ! local arrays 1330 REAL(wp), DIMENSION(jpi,jpj) :: zu_diff, zv_diff ! local arrays 1539 1331 1540 1332 CHARACTER(len=20) :: clname 1541 1333 !!---------------------------------------------------------------------- 1542 1334 1335 1543 1336 IF( lwp ) THEN 1337 1544 1338 WRITE(numout,*) 1545 1339 WRITE(numout,*) 'rhg_cvg_vp : ice rheology convergence control' 1546 1340 WRITE(numout,*) '~~~~~~~~~~~' 1547 WRITE(numout,*) ' kiter = : ', kiter 1548 WRITE(numout,*) ' kitermax = : ', kitermax 1341 WRITE(numout,*) ' kt = : ', kt 1342 WRITE(numout,*) ' kitout = : ', kitout 1343 WRITE(numout,*) ' kitinn = : ', kitinn 1344 WRITE(numout,*) ' kitinntot = : ', kitinntot 1345 WRITE(numout,*) ' kitoutmax (nn_vp_nout) = ', kitoutmax 1346 WRITE(numout,*) ' kitinnmax (nn_vp_ninn) = ', kitinnmax 1347 WRITE(numout,*) ' kitinntotmax (nn_nvp) = ', kitinntotmax 1348 WRITE(numout,*) 1349 1549 1350 ENDIF 1550 1351 1352 z1_pglob_area = 1._wp / pglob_area ! inverse global ice area 1353 1551 1354 ! create file 1552 IF( kt == nit000 .AND. kit er== 1 ) THEN1355 IF( kt == nit000 .AND. kitinntot == 1 ) THEN 1553 1356 ! 1554 1357 IF( lwm ) THEN … … 1562 1365 istatus = NF90_DEF_DIM( ncvgid, 'y' , jpj, iy_dim ) 1563 1366 1564 ! i suggest vel_dif instead 1565 istatus = NF90_DEF_VAR( ncvgid, 'u_res' , NF90_DOUBLE , (/ idtime /), nvarid_ures ) 1566 istatus = NF90_DEF_VAR( ncvgid, 'v_res' , NF90_DOUBLE , (/ idtime /), nvarid_vres ) 1567 istatus = NF90_DEF_VAR( ncvgid, 'vel_res', NF90_DOUBLE , (/ idtime /), nvarid_velres ) 1568 istatus = NF90_DEF_VAR( ncvgid, 'u_dif' , NF90_DOUBLE , (/ idtime /), nvarid_udif ) 1569 istatus = NF90_DEF_VAR( ncvgid, 'v_dif' , NF90_DOUBLE , (/ idtime /), nvarid_vdif ) 1570 istatus = NF90_DEF_VAR( ncvgid, 'vel_dif', NF90_DOUBLE , (/ idtime /), nvarid_veldif ) 1367 istatus = NF90_DEF_VAR( ncvgid, 'u_res' , NF90_DOUBLE , (/ idtime /), nvarid_ures ) 1368 istatus = NF90_DEF_VAR( ncvgid, 'v_res' , NF90_DOUBLE , (/ idtime /), nvarid_vres ) 1369 istatus = NF90_DEF_VAR( ncvgid, 'vel_res' , NF90_DOUBLE , (/ idtime /), nvarid_velres ) 1370 1371 istatus = NF90_DEF_VAR( ncvgid, 'uerr_max_sub' , NF90_DOUBLE , (/ idtime /), nvarid_uerr_max ) 1372 istatus = NF90_DEF_VAR( ncvgid, 'verr_max_sub' , NF90_DOUBLE , (/ idtime /), nvarid_verr_max ) 1373 istatus = NF90_DEF_VAR( ncvgid, 'velerr_max_sub', NF90_DOUBLE , (/ idtime /), nvarid_velerr_max ) 1374 1375 istatus = NF90_DEF_VAR( ncvgid, 'umad_sub' , NF90_DOUBLE , (/ idtime /), nvarid_umad ) 1376 istatus = NF90_DEF_VAR( ncvgid, 'vmad_sub' , NF90_DOUBLE , (/ idtime /), nvarid_vmad ) 1377 istatus = NF90_DEF_VAR( ncvgid, 'velmad_sub' , NF90_DOUBLE , (/ idtime /), nvarid_velmad ) 1378 1379 istatus = NF90_DEF_VAR( ncvgid, 'umad_outer' , NF90_DOUBLE , (/ idtime /), nvarid_umad_outer ) 1380 istatus = NF90_DEF_VAR( ncvgid, 'vmad_outer' , NF90_DOUBLE , (/ idtime /), nvarid_vmad_outer ) 1381 istatus = NF90_DEF_VAR( ncvgid, 'velmad_outer' , NF90_DOUBLE , (/ idtime /), nvarid_velmad_outer ) 1382 1571 1383 istatus = NF90_DEF_VAR( ncvgid, 'mke_ice', NF90_DOUBLE , (/ idtime /), nvarid_mke ) 1572 1384 1573 istatus = NF90_DEF_VAR( ncvgid, 'u_res_xy', NF90_DOUBLE, (/ ix_dim, iy_dim /), nvarid_ures_xy)1574 istatus = NF90_DEF_VAR( ncvgid, 'v_res_xy', NF90_DOUBLE, (/ ix_dim, iy_dim /), nvarid_vres_xy)1575 1576 1385 istatus = NF90_ENDDEF(ncvgid) 1577 1386 … … 1580 1389 ENDIF 1581 1390 1582 IF ( lwp ) WRITE(numout,*) ' File created ' 1583 1584 ! --- Max absolute velocity difference with previous iterate (zveldif) 1585 zveldif = MAX( puerr_max, pverr_max ) ! velocity difference with previous iterate, should nearly be equivalent to evp code 1586 ! if puerrmask and pverrmax are masked at 15% (TEST) 1587 1588 ! --- Mean residual and kinetic energy 1589 IF ( kiter == 1 ) THEN 1590 1591 zu_res_mean = 0._wp 1592 zv_res_mean = 0._wp 1593 zvelres = 0._wp 1594 zmke = 0._wp 1391 !------------------------------------------------------------ 1392 ! 1393 ! Max absolute velocity difference with previous sub-iterate 1394 ! ( zvel_err_max ) 1395 ! 1396 !------------------------------------------------------------ 1397 ! 1398 ! This comes from the criterion used to stop the iterative procedure 1399 zvel_err_max = 0.5_wp * ( puerr_max + pverr_max ) ! average of U- and V- maximum error over the whole domain 1400 1401 !---------------------------------------------- 1402 ! 1403 ! Mean-absolute-deviation (sub-iterates) 1404 ! ( zu_mad, zv_mad, zvel_mad) 1405 ! 1406 !---------------------------------------------- 1407 ! 1408 ! U 1409 zu_diff(:,:) = 0._wp 1410 1411 DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 ) ! 2->jpj-1; 2->jpi-1 1412 1413 zu_diff(ji,jj) = ABS ( ( pu(ji,jj) - pub(ji,jj) ) ) * e1e2u(ji,jj) * pat_iu(ji,jj) * umask(ji,jj,1) * z1_pglob_area 1414 1415 END_2D 1416 1417 ! V 1418 zv_diff(:,:) = 0._wp 1419 1420 DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 ) ! 2->jpj-1; 2->jpi-1 1421 1422 zv_diff(ji,jj) = ABS ( ( pv(ji,jj) - pvb(ji,jj) ) ) * e1e2v(ji,jj) * pat_iv(ji,jj) * vmask(ji,jj,1) * z1_pglob_area 1423 1424 END_2D 1425 1426 ! global sum & U-V average 1427 CALL lbc_lnk( 'icedyn_rhg_cvg_vp', zu_diff, 'U', 1., zv_diff , 'V', 1. ) 1428 zu_mad = glob_sum( 'icedyn_rhg_vp : ', zu_diff ) 1429 zv_mad = glob_sum( 'icedyn_rhg_vp : ', zv_diff ) 1430 1431 zvel_mad = 0.5_wp * ( zu_mad + zv_mad ) 1432 1433 !----------------------------------------------- 1434 ! 1435 ! Mean-absolute-deviation (outer-iterates) 1436 ! ( zu_mad_outer, zv_mad_outer, zvel_mad_outer) 1437 ! 1438 !----------------------------------------------- 1439 ! 1440 IF ( kitinn == kitinnmax ) THEN ! only work at the end of outer iterates 1441 1442 ! * U 1443 zu_diff(:,:) = 0._wp 1444 1445 DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 ) ! 2->jpj-1; 2->jpi-1 1446 1447 zu_diff(ji,jj) = ABS ( ( pu(ji,jj) - pub_outer(ji,jj) ) ) * e1e2u(ji,jj) * pat_iu(ji,jj) * umask(ji,jj,1) * & 1448 & z1_pglob_area 1449 1450 END_2D 1451 1452 ! * V 1453 zv_diff(:,:) = 0._wp 1454 1455 DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 ) ! 2->jpj-1; 2->jpi-1 1456 1457 zv_diff(ji,jj) = ABS ( ( pv(ji,jj) - pvb_outer(ji,jj) ) ) * e1e2v(ji,jj) * pat_iv(ji,jj) * vmask(ji,jj,1) * & 1458 & z1_pglob_area 1459 1460 END_2D 1461 1462 ! Global ice-concentration, grid-cell-area weighted mean 1463 CALL lbc_lnk( 'icedyn_rhg_cvg_vp', zu_diff, 'U', 1., zv_diff , 'V', 1. ) ! abs behaves as a scalar no ? 1464 1465 zu_mad_outer = glob_sum( 'icedyn_rhg_vp : ', zu_diff ) 1466 zv_mad_outer = glob_sum( 'icedyn_rhg_vp : ', zv_diff ) 1467 1468 ! Average of both U & V 1469 zvel_mad_outer = 0.5_wp * ( zu_mad_outer + zv_mad_outer ) 1470 1471 ENDIF 1472 1473 ! --- Spatially-resolved absolute difference to send back to main routine 1474 ! (last iteration only, T-point) 1475 1476 IF ( kitinntot == kitinntotmax) THEN 1477 1478 zu_diff(:,:) = 0._wp 1479 zv_diff(:,:) = 0._wp 1480 1481 DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 ) ! 2->jpj-1; 2->jpi-1 1482 1483 zu_diff(ji,jj) = ( ABS ( ( pu(ji-1,jj) - pub_outer(ji-1,jj) ) ) * umask(ji-1,jj,1) & 1484 & + ABS ( ( pu(ji,jj ) - pub_outer(ji,jj) ) ) * umask(ji,jj,1) ) & 1485 & / ( umask(ji-1,jj,1) + umask(ji,jj,1) ) 1486 1487 zv_diff(ji,jj) = ( ABS ( ( pv(ji,jj-1) - pvb_outer(ji,jj-1) ) ) * vmask(ji,jj-1,1) & 1488 & + ABS ( ( pv(ji,jj ) - pvb_outer(ji,jj) ) ) * vmask(ji,jj,1) & 1489 & / ( vmask(ji,jj-1,1) + vmask(ji,jj,1) ) ) 1490 1491 1492 END_2D 1493 1494 CALL lbc_lnk( 'icedyn_rhg_cvg_vp', zu_diff, 'T', 1., zv_diff , 'T', 1. ) 1495 pvel_diff(:,:) = 0.5_wp * ( zu_diff(:,:) + zv_diff(:,:) ) 1595 1496 1596 1497 ELSE 1597 1498 1598 ! -- Mean residual (N/m^2), zu_res_mean 1599 ! Here we take the residual of the linear system (N/m^2), 1600 ! We define it as in mitgcm: square-root of area-weighted mean square residual 1601 ! Local residual r = Ax - B expresses to which extent the momentum balance is verified 1602 ! i.e., how close we are to a solution 1603 1604 IF ( lwp ) WRITE(numout,*) ' TEST 1 ' 1605 1606 z1_pglob_area = 1._wp / pglob_area 1607 1608 zu_res(:,:) = 0._wp; zv_res(:,:) = 0._wp 1609 1610 DO jj = 2, jpj - 1 1611 DO ji = 2, jpi - 1 1612 zu_res(ji,jj) = ( prhsu(ji,jj) + pDU(ji,jj) * pu(ji,jj-1) + pEU(ji,jj) * pu(ji,jj+1) & 1613 & - pAU(ji,jj) * pu(ji-1,jj) - pBU(ji,jj) * pu(ji,jj) - pCU(ji,jj) * pu(ji+1,jj) ) 1614 1615 zv_res(ji,jj) = ( prhsv(ji,jj) + pDV(ji,jj) * pv(ji-1,jj) + pEV(ji,jj) * pv(ji+1,jj) & 1616 & - pAV(ji,jj) * pv(ji,jj-1) - pBV(ji,jj) * pv(ji,jj) - pCV(ji,jj) * pv(ji,jj+1) ) 1617 1618 zu_res(ji,jj) = SQRT( zu_res(ji,jj) * zu_res(ji,jj) ) * umask(ji,jj,1) * e1e2u(ji,jj) * z1_pglob_area 1619 zv_res(ji,jj) = SQRT( zv_res(ji,jj) * zv_res(ji,jj) ) * vmask(ji,jj,1) * e1e2v(ji,jj) * z1_pglob_area 1620 1621 END DO 1622 END DO 1623 1624 IF ( lwp ) WRITE(numout,*) ' TEST 2 ' 1625 zu_res_mean = glob_sum( 'ice_rhg_vp', zu_res(:,:) ) 1626 zv_res_mean = glob_sum( 'ice_rhg_vp', zv_res(:,:) ) 1627 IF ( lwp ) WRITE(numout,*) ' TEST 3 ' 1628 zvelres = 0.5_wp * ( zu_res_mean + zv_res_mean ) 1629 1630 IF ( lwp ) WRITE(numout,*) ' TEST 4 ' 1631 1632 ! -- Global mean kinetic energy per unit area (J/m2) 1633 zvel2(:,:) = 0._wp 1634 DO jj = 2, jpj - 1 1635 DO ji = 2, jpi - 1 1636 zu = 0.5_wp * ( pu(ji-1,jj) + pu(ji,jj) ) ! u-vel at T-point 1637 zv = 0.5_wp * ( pv(ji,jj-1) + pv(ji,jj) ) 1638 zvel2(ji,jj) = zu*zu + zv*zv ! square of ice velocity at T-point 1639 END DO 1640 END DO 1641 1642 IF ( lwp ) WRITE(numout,*) ' TEST 5 ' 1643 1644 zmke = 0.5_wp * glob_sum( 'ice_rhg_vp', pmt(:,:) * e1e2t(:,:) * zvel2(:,:) ) / pglob_area 1645 1646 IF ( lwp ) WRITE(numout,*) ' TEST 6 ' 1647 1648 ENDIF ! kiter 1499 pvel_diff(:,:) = 0._wp 1500 1501 ENDIF 1502 1503 !--------------------------------------- 1504 ! 1505 ! --- Mean residual & kinetic energy 1506 ! 1507 !--------------------------------------- 1508 1509 IF ( kitinntot == 1 ) THEN 1510 1511 zu_res_mean = 0._wp 1512 zv_res_mean = 0._wp 1513 zvel_res_mean = 0._wp 1514 zmke = 0._wp 1515 1516 ELSE 1517 1518 ! * Mean residual (N/m2) 1519 ! Here we take the residual of the linear system (N/m2), 1520 ! We define it as in mitgcm: global area-weighted mean of square-root residual 1521 ! Local residual r = Ax - B expresses to which extent the momentum balance is verified 1522 ! i.e., how close we are to a solution 1523 zu_res(:,:) = 0._wp; zv_res(:,:) = 0._wp 1524 1525 DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 ) ! 2->jpj-1; 2->jpi-1 1526 1527 zu_res(ji,jj) = ( prhsu(ji,jj) + pDU(ji,jj) * pu(ji,jj-1) + pEU(ji,jj) * pu(ji,jj+1) & 1528 & - pAU(ji,jj) * pu(ji-1,jj) - pBU(ji,jj) * pu(ji,jj) - pCU(ji,jj) * pu(ji+1,jj) ) 1529 zv_res(ji,jj) = ( prhsv(ji,jj) + pDV(ji,jj) * pv(ji-1,jj) + pEV(ji,jj) * pv(ji+1,jj) & 1530 & - pAV(ji,jj) * pv(ji,jj-1) - pBV(ji,jj) * pv(ji,jj) - pCV(ji,jj) * pv(ji,jj+1) ) 1531 1532 ! zu_res(ji,jj) = pFU(ji,jj) - pAU(ji,jj) * pu(ji-1,jj) - pBU(ji,jj) * pu(ji,jj) - pCU(ji,jj) * pu(ji+1,jj) 1533 ! zv_res(ji,jj) = pFV(ji,jj) - pAV(ji,jj) * pv(ji,jj-1) - pBV(ji,jj) * pv(ji,jj) - pCV(ji,jj) * pv(ji,jj+1) 1534 1535 zu_res(ji,jj) = SQRT( zu_res(ji,jj) * zu_res(ji,jj) ) * umask(ji,jj,1) * pat_iu(ji,jj) * e1e2u(ji,jj) * z1_pglob_area 1536 zv_res(ji,jj) = SQRT( zv_res(ji,jj) * zv_res(ji,jj) ) * vmask(ji,jj,1) * pat_iv(ji,jj) * e1e2v(ji,jj) * z1_pglob_area 1537 1538 END_2D 1539 1540 ! Global ice-concentration, grid-cell-area weighted mean 1541 CALL lbc_lnk( 'icedyn_rhg_cvg_vp', zu_res, 'U', 1., zv_res , 'V', 1. ) 1542 1543 zu_res_mean = glob_sum( 'ice_rhg_vp', zu_res(:,:) ) 1544 zv_res_mean = glob_sum( 'ice_rhg_vp', zv_res(:,:) ) 1545 zvel_res_mean = 0.5_wp * ( zu_res_mean + zv_res_mean ) 1546 1547 ! --- Global mean kinetic energy per unit area (J/m2) 1548 zvel2(:,:) = 0._wp 1549 1550 DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 ) ! 2->jpj-1; 2->jpi-1 1649 1551 1650 ! ! ==================== ! 1651 1652 ! time 1653 it = ( kt - 1 ) * kitermax + kiter 1654 1655 1552 zu = 0.5_wp * ( pu(ji-1,jj) + pu(ji,jj) ) ! u-vel at T-point 1553 zv = 0.5_wp * ( pv(ji,jj-1) + pv(ji,jj) ) 1554 zvel2(ji,jj) = zu*zu + zv*zv ! square of ice velocity at T-point 1555 1556 END_2D 1557 1558 zmke = 0.5_wp * glob_sum( 'ice_rhg_vp', pmt(:,:) * e1e2t(:,:) * zvel2(:,:) ) / pglob_area 1559 1560 ENDIF ! kitinntot 1561 1562 !--- Spatially-resolved residual at last iteration to send back to main routine (last iteration only) 1563 !--- Calculation @T-point 1564 1565 IF ( kitinntot == kitinntotmax) THEN 1566 1567 DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 ) ! 2->jpj-1; 2->jpi-1 1568 1569 zu_res(ji,jj) = ( prhsu(ji,jj) + pDU(ji,jj) * pu(ji,jj-1) + pEU(ji,jj) * pu(ji,jj+1) & 1570 & - pAU(ji,jj) * pu(ji-1,jj) - pBU(ji,jj) * pu(ji,jj) - pCU(ji,jj) * pu(ji+1,jj) ) 1571 zv_res(ji,jj) = ( prhsv(ji,jj) + pDV(ji,jj) * pv(ji-1,jj) + pEV(ji,jj) * pv(ji+1,jj) & 1572 & - pAV(ji,jj) * pv(ji,jj-1) - pBV(ji,jj) * pv(ji,jj) - pCV(ji,jj) * pv(ji,jj+1) ) 1573 1574 zu_res(ji,jj) = SQRT( zu_res(ji,jj) * zu_res(ji,jj) ) * umask(ji,jj,1) 1575 zv_res(ji,jj) = SQRT( zv_res(ji,jj) * zv_res(ji,jj) ) * vmask(ji,jj,1) 1576 1577 END_2D 1578 1579 CALL lbc_lnk( 'icedyn_rhg_cvg_vp', zu_res, 'U', 1., zv_res , 'V', 1. ) 1580 1581 DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 ) ! 2->jpj-1; 2->jpi-1 1582 1583 pvel_res(ji,jj) = 0.25_wp * ( zu_res(ji-1,jj) + zu_res(ji,jj) + zv_res(ji,jj-1) + zv_res(ji,jj) ) 1584 1585 END_2D 1586 CALL lbc_lnk( 'icedyn_rhg_cvg_vp', pvel_res, 'T', 1. ) 1587 1588 ELSE 1589 1590 pvel_res(:,:) = 0._wp 1591 1592 ENDIF 1593 1594 ! ! ==================== ! 1595 1596 it_inn_file = ( kt - nit000 ) * kitinntotmax + kitinntot ! time step in the file 1597 it_out_file = ( kt - nit000 ) * kitoutmax + kitout 1598 1599 ! write variables 1656 1600 IF( lwm ) THEN 1657 ! write variables 1658 istatus = NF90_PUT_VAR( ncvgid, nvarid_ures, (/zu_res_mean/), (/it/), (/1/) ) ! U-residual of the linear system 1659 istatus = NF90_PUT_VAR( ncvgid, nvarid_vres, (/zv_res_mean/), (/it/), (/1/) ) ! V-residual of the linear system 1660 istatus = NF90_PUT_VAR( ncvgid, nvarid_velres, (/zvelres/), (/it/), (/1/) ) ! average of u- and v- residuals 1661 istatus = NF90_PUT_VAR( ncvgid, nvarid_udif, (/puerr_max/), (/it/), (/1/) ) ! max U velocity difference, inner iterations 1662 istatus = NF90_PUT_VAR( ncvgid, nvarid_vdif, (/pverr_max/), (/it/), (/1/) ) ! max V velocity difference, inner iterations 1663 istatus = NF90_PUT_VAR( ncvgid, nvarid_veldif, (/zveldif/), (/it/), (/1/) ) ! max U or V velocity diff between subiterations 1664 istatus = NF90_PUT_VAR( ncvgid, nvarid_mke, (/zmke/), (/it/), (/1/) ) ! mean kinetic energy 1665 1666 ! 1667 IF ( kiter == kitermax ) THEN 1668 WRITE(numout,*) ' Should plot the spatially dependent residual ' 1669 istatus = NF90_PUT_VAR( ncvgid, nvarid_ures_xy, (/zu_res/) ) ! U-residual, spatially dependent 1670 istatus = NF90_PUT_VAR( ncvgid, nvarid_vres_xy, (/zv_res/) ) ! V-residual, spatially dependent 1601 1602 istatus = NF90_PUT_VAR( ncvgid, nvarid_ures , (/zu_res_mean/), (/it_inn_file/), (/1/) ) ! Residuals of the linear system, area weighted mean 1603 istatus = NF90_PUT_VAR( ncvgid, nvarid_vres , (/zv_res_mean/), (/it_inn_file/), (/1/) ) ! 1604 istatus = NF90_PUT_VAR( ncvgid, nvarid_velres, (/zvel_res_mean/), (/it_inn_file/), (/1/) ) ! 1605 1606 istatus = NF90_PUT_VAR( ncvgid, nvarid_uerr_max , (/puerr_max/), (/it_inn_file/), (/1/) ) ! Max velocit_inn_filey error, sub-it_inn_fileerates 1607 istatus = NF90_PUT_VAR( ncvgid, nvarid_verr_max , (/pverr_max/), (/it_inn_file/), (/1/) ) ! 1608 istatus = NF90_PUT_VAR( ncvgid, nvarid_velerr_max, (/zvel_err_max/), (/it_inn_file/), (/1/) ) ! 1609 1610 istatus = NF90_PUT_VAR( ncvgid, nvarid_umad , (/zu_mad/) , (/it_inn_file/), (/1/) ) ! velocit_inn_filey MAD, area/sic-weighted, sub-it_inn_fileerates 1611 istatus = NF90_PUT_VAR( ncvgid, nvarid_vmad , (/zv_mad/) , (/it_inn_file/), (/1/) ) ! 1612 istatus = NF90_PUT_VAR( ncvgid, nvarid_velmad , (/zvel_mad/), (/it_inn_file/), (/1/) ) ! 1613 1614 istatus = NF90_PUT_VAR( ncvgid, nvarid_mke, (/zmke/), (/kitinntot/), (/1/) ) ! mean kinetic energy 1615 1616 IF ( kitinn == kitinnmax ) THEN ! only print outer mad at the end of inner loop 1617 1618 istatus = NF90_PUT_VAR( ncvgid, nvarid_umad_outer , (/zu_mad_outer/) , (/it_out_file/), (/1/) ) ! velocity MAD, area/sic-weighted, outer-iterates 1619 istatus = NF90_PUT_VAR( ncvgid, nvarid_vmad_outer , (/zv_mad_outer/) , (/it_out_file/), (/1/) ) ! 1620 istatus = NF90_PUT_VAR( ncvgid, nvarid_velmad_outer , (/zvel_mad_outer/), (/it_out_file/), (/1/) ) ! 1621 1671 1622 ENDIF 1672 1623 1673 ! close file 1674 IF( kt == nitend ) istatus = NF90_CLOSE( ncvgid ) 1624 IF( kt == nitend - nn_fsbc + 1 .AND. kitinntot == kitinntotmax ) istatus = NF90_CLOSE( ncvgid ) 1675 1625 ENDIF 1676 1626 -
NEMO/branches/2021/ticket2632_r14588_theta_sbcblk/src/ICE/iceistate.F90
r14143 r15548 75 75 INTEGER , PARAMETER :: jp_hld = 10 ! index of pnd lid depth (m) 76 76 TYPE(FLD), ALLOCATABLE, DIMENSION(:) :: si ! structure of input fields (file informations, fields read) 77 77 ! 78 #if defined key_agrif 79 REAL(wp), PUBLIC :: rsshadj !: initial mean ssh adjustment due to initial ice+snow mass 80 #endif 81 ! 78 82 !! * Substitutions 79 83 # include "do_loop_substitute.h90" … … 108 112 ! 109 113 INTEGER :: ji, jj, jk, jl ! dummy loop indices 110 REAL(wp) :: ztmelts 114 REAL(wp) :: ztmelts, zsshadj, area 111 115 INTEGER , DIMENSION(4) :: itest 112 116 REAL(wp), DIMENSION(jpi,jpj) :: z2d … … 308 312 ! select ice covered grid points 309 313 npti = 0 ; nptidx(:) = 0 310 DO_2D( 1, 1, 1, 1)314 DO_2D( nn_hls, nn_hls, nn_hls, nn_hls ) 311 315 IF ( zht_i_ini(ji,jj) > 0._wp ) THEN 312 316 npti = npti + 1 … … 363 367 CALL ice_var_salprof ! for sz_i 364 368 DO jl = 1, jpl 365 DO_2D( 1, 1, 1, 1)369 DO_2D( nn_hls, nn_hls, nn_hls, nn_hls ) 366 370 v_i (ji,jj,jl) = h_i(ji,jj,jl) * a_i(ji,jj,jl) 367 371 v_s (ji,jj,jl) = h_s(ji,jj,jl) * a_i(ji,jj,jl) … … 371 375 ! 372 376 DO jl = 1, jpl 373 DO_3D( 1, 1, 1, 1, 1, nlay_s )377 DO_3D( nn_hls, nn_hls, nn_hls, nn_hls, 1, nlay_s ) 374 378 t_s(ji,jj,jk,jl) = zts_3d(ji,jj,jl) 375 379 e_s(ji,jj,jk,jl) = zswitch(ji,jj) * v_s(ji,jj,jl) * r1_nlay_s * & … … 379 383 ! 380 384 DO jl = 1, jpl 381 DO_3D( 1, 1, 1, 1, 1, nlay_i )385 DO_3D( nn_hls, nn_hls, nn_hls, nn_hls, 1, nlay_i ) 382 386 t_i (ji,jj,jk,jl) = zti_3d(ji,jj,jl) 383 387 ztmelts = - rTmlt * sz_i(ji,jj,jk,jl) + rt0 ! melting temperature in K … … 414 418 ENDIF ! ln_iceini 415 419 ! 416 !---------------------------------------------- 417 ! 4) Snow-ice mass (case ice is fully embedded)418 !---------------------------------------------- 420 !---------------------------------------------------------- 421 ! 4) Adjust ssh and vertical scale factors to snow-ice mass 422 !---------------------------------------------------------- 419 423 snwice_mass (:,:) = tmask(:,:,1) * SUM( rhos * v_s + rhoi * v_i + rhow * ( v_ip + v_il ), dim=3 ) ! snow+ice mass 420 424 snwice_mass_b(:,:) = snwice_mass(:,:) 421 425 ! 422 426 IF( ln_ice_embd ) THEN ! embedded sea-ice: deplete the initial ssh below sea-ice area 423 ! 427 ! ! ---------------- 424 428 ssh(:,:,Kmm) = ssh(:,:,Kmm) - snwice_mass(:,:) * r1_rho0 425 429 ssh(:,:,Kbb) = ssh(:,:,Kbb) - snwice_mass(:,:) * r1_rho0 426 430 ! 431 ELSE ! levitating sea-ice: deplete the initial ssh over the whole domain 432 ! ! ------------------ 433 area = glob_sum( 'iceistate', e1e2t(:,:) * ssmask(:,:) ) 434 zsshadj = glob_sum( 'iceistate', snwice_mass(:,:) * r1_rho0 * e1e2t(:,:) ) / area 435 #if defined key_agrif 436 ! Override ssh adjustment in nested domains by the root-domain ssh adjustment; 437 ! store the adjustment value in a global module variable to make it retrievable in nested domains 438 IF( .NOT.Agrif_Root() ) THEN 439 IF (.NOT.ln_init_chfrpar ) THEN ! child is not initialized from the parent 440 zsshadj = Agrif_Parent(rsshadj) 441 ELSE ! child is initialized from the parent 442 zsshadj = 0._wp ! => 0 since ssh adjustement is already done 443 ENDIF 444 ELSE 445 rsshadj = zsshadj 446 ENDIF 447 #endif 448 IF(lwp) WRITE(numout,'(A23,F10.6,A20)') ' sea level adjusted by ', -zsshadj, ' m to compensate for' 449 IF(lwp) WRITE(numout,*) ' the initial snow+ice mass' 450 ! 451 WHERE( ssmask(:,:) == 1._wp ) 452 ssh(:,:,Kmm) = ssh(:,:,Kmm) - zsshadj 453 ssh(:,:,Kbb) = ssh(:,:,Kbb) - zsshadj 454 ENDWHERE 455 ! 456 ENDIF 457 ! 458 IF( .NOT.ln_linssh ) THEN 427 459 #if defined key_qco 428 IF( .NOT.ln_linssh )CALL dom_qco_zgr( Kbb, Kmm ) ! upadte of r3=ssh/h0 ratios460 CALL dom_qco_zgr( Kbb, Kmm ) ! upadte of r3=ssh/h0 ratios 429 461 #elif defined key_linssh 430 ! ! fix in time coord. : no update of vertical coord.462 ! ! Fix in time : key_linssh case, set through domzgr_substitute.h90 431 463 #else 432 IF( .NOT.ln_linssh ) CALL dom_vvl_zgr( Kbb, Kmm, Kaa ) ! interpolation scale factor, depth and water column 464 DO jk = 1, jpk 465 DO_2D( nn_hls, nn_hls, nn_hls, nn_hls) 466 IF( snwice_mass(ji,jj) /= 0._wp ) THEN 467 e3t(ji,jj,jk,Kmm) = e3t_0(ji,jj,jk) * ( 1._wp + ssh(ji,jj,Kmm) * r1_ht_0(ji,jj) * tmask(ji,jj,jk) ) 468 e3t(ji,jj,jk,Kbb) = e3t_0(ji,jj,jk) * ( 1._wp + ssh(ji,jj,Kbb) * r1_ht_0(ji,jj) * tmask(ji,jj,jk) ) 469 ENDIF 470 END_2D 471 END DO 472 ! 473 CALL dom_vvl_zgr( Kbb, Kmm, Kaa ) ! interpolation of scale factor, depth and water column 433 474 #endif 434 435 475 ENDIF 436 476 ! 437 477 !!clem: output of initial state should be written here but it is impossible because 438 478 !! the ocean and ice are in the same file -
NEMO/branches/2021/ticket2632_r14588_theta_sbcblk/src/ICE/iceitd.F90
r14072 r15548 101 101 ! 102 102 npti = 0 ; nptidx(:) = 0 103 DO_2D( 1, 1, 1, 1)103 DO_2D( nn_hls, nn_hls, nn_hls, nn_hls ) 104 104 IF ( at_i(ji,jj) > epsi10 ) THEN 105 105 npti = npti + 1 … … 378 378 ! 379 379 ! Compute coefficients of g(eta) = g0 + g1*eta 380 zdhr = 1._wp / (phR(ji) - phL(ji)) 380 IF( phR(ji) > phL(ji) ) THEN ; zdhr = 1._wp / (phR(ji) - phL(ji)) 381 ELSE ; zdhr = 0._wp ! if hR=hL=hice => no remapping 382 ENDIF 383 !!zdhr = 1._wp / (phR(ji) - phL(ji)) 381 384 zwk1 = 6._wp * paice(ji) * zdhr 382 385 zwk2 = ( phice(ji) - phL(ji) ) * zdhr … … 624 627 ! !--------------------------------------- 625 628 npti = 0 ; nptidx(:) = 0 626 DO_2D( 1, 1, 1, 1)629 DO_2D( nn_hls, nn_hls, nn_hls, nn_hls ) 627 630 IF( a_i(ji,jj,jl) > 0._wp .AND. v_i(ji,jj,jl) > (a_i(ji,jj,jl) * hi_max(jl)) ) THEN 628 631 npti = npti + 1 … … 660 663 ! !----------------------------------------- 661 664 npti = 0 ; nptidx(:) = 0 662 DO_2D( 1, 1, 1, 1)665 DO_2D( nn_hls, nn_hls, nn_hls, nn_hls ) 663 666 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 667 npti = npti + 1 -
NEMO/branches/2021/ticket2632_r14588_theta_sbcblk/src/ICE/icesbc.F90
r14433 r15548 109 109 !! dqns_ice = non solar heat sensistivity [W/m2] 110 110 !! qemp_oce, qemp_ice, qprec_ice, qevap_ice = sensible heat (associated with evap & precip) [W/m2] 111 !! + these fields 112 !! qsb_ice_bot = sensible heat at the ice bottom [W/m2] 113 !! fhld, qlead = heat budget in the leads [W/m2] 111 114 !! + some fields that are not used outside this module: 112 115 !! qla_ice = latent heat flux over ice [W/m2] … … 117 120 INTEGER, INTENT(in) :: kt ! ocean time step 118 121 INTEGER, INTENT(in) :: ksbc ! flux formulation (user defined, bulk or Pure Coupled) 119 !120 INTEGER :: ji, jj, jl ! dummy loop index121 REAL(wp) :: zmiss_val ! missing value retrieved from xios122 REAL(wp), DIMENSION(:,:), ALLOCATABLE :: zalb, zmsk00 ! 2D workspace123 122 !!-------------------------------------------------------------------- 124 123 ! … … 130 129 WRITE(numout,*)'~~~~~~~~~~~~~~~' 131 130 ENDIF 132 133 ! get missing value from xml 134 CALL iom_miss_val( "icetemp", zmiss_val ) 135 136 ! --- ice albedo --- ! 131 ! !== ice albedo ==! 137 132 CALL ice_alb( t_su, h_i, h_s, ln_pnd_alb, a_ip_eff, h_ip, cloud_fra, alb_ice ) 138 139 133 ! 140 134 SELECT CASE( ksbc ) !== fluxes over sea ice ==! … … 142 136 CASE( jp_usr ) !--- user defined formulation 143 137 CALL usrdef_sbc_ice_flx( kt, h_s, h_i ) 144 CASE( jp_blk, jp_abl ) !--- bulk formulation & ABL formulation138 CASE( jp_blk, jp_abl ) !--- bulk formulation & ABL formulation 145 139 CALL blk_ice_2 ( t_su, h_s, h_i, alb_ice, & 146 140 & theta_air_zt(:,:), q_air_zt(:,:), & ! #LB: known from "sbc_oce" module... 147 141 & sf(jp_slp)%fnow(:,:,1), sf(jp_qlw)%fnow(:,:,1), & 148 142 & sf(jp_prec)%fnow(:,:,1), sf(jp_snow)%fnow(:,:,1) ) 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 )143 IF( ln_mixcpl ) CALL sbc_cpl_ice_flx( kt, picefr=at_i_b, palbi=alb_ice, psst=sst_m, pist=t_su, phs=h_s, phi=h_i ) 150 144 IF( nn_flxdist /= -1 ) CALL ice_flx_dist ( t_su, alb_ice, qns_ice, qsr_ice, dqns_ice, evap_ice, devap_ice, nn_flxdist ) 151 145 ! ! compute conduction flux and surface temperature (as in Jules surface module) … … 153 147 & CALL blk_ice_qcn ( ln_virtual_itd, t_su, t_bo, h_s, h_i ) 154 148 CASE ( jp_purecpl ) !--- coupled formulation 155 CALL sbc_cpl_ice_flx( picefr=at_i_b, palbi=alb_ice, psst=sst_m, pist=t_su, phs=h_s, phi=h_i )149 CALL sbc_cpl_ice_flx( kt, picefr=at_i_b, palbi=alb_ice, psst=sst_m, pist=t_su, phs=h_s, phi=h_i ) 156 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 ) 157 151 END SELECT 158 159 !--- output ice albedo and surface albedo ---! 160 IF( iom_use('icealb') .OR. iom_use('albedo') ) THEN 161 162 ALLOCATE( zalb(jpi,jpj), zmsk00(jpi,jpj) ) 163 164 WHERE( at_i_b < 1.e-03 ) 165 zmsk00(:,:) = 0._wp 166 zalb (:,:) = rn_alb_oce 167 ELSEWHERE 168 zmsk00(:,:) = 1._wp 169 zalb (:,:) = SUM( alb_ice * a_i_b, dim=3 ) / at_i_b 170 END WHERE 171 ! ice albedo 172 CALL iom_put( 'icealb' , zalb * zmsk00 + zmiss_val * ( 1._wp - zmsk00 ) ) 173 ! ice+ocean albedo 174 zalb(:,:) = SUM( alb_ice * a_i_b, dim=3 ) + rn_alb_oce * ( 1._wp - at_i_b ) 175 CALL iom_put( 'albedo' , zalb ) 176 177 DEALLOCATE( zalb, zmsk00 ) 178 179 ENDIF 152 ! !== some fluxes at the ice-ocean interface and in the leads 153 CALL ice_flx_other 180 154 ! 181 155 IF( ln_timing ) CALL timing_stop('icesbc') … … 270 244 271 245 246 SUBROUTINE ice_flx_other 247 !!----------------------------------------------------------------------- 248 !! *** ROUTINE ice_flx_other *** 249 !! 250 !! ** Purpose : prepare necessary fields for thermo calculations 251 !! 252 !! ** Inputs : u_ice, v_ice, ssu_m, ssv_m, utau, vtau 253 !! frq_m, qsr_oce, qns_oce, qemp_oce, e3t_m, sst_m 254 !! ** Outputs : qsb_ice_bot, fhld, qlead 255 !!----------------------------------------------------------------------- 256 INTEGER :: ji, jj ! dummy loop indices 257 REAL(wp) :: zfric_u, zqld, zqfr, zqfr_neg, zqfr_pos, zu_io, zv_io, zu_iom1, zv_iom1 258 REAL(wp), PARAMETER :: zfric_umin = 0._wp ! lower bound for the friction velocity (cice value=5.e-04) 259 REAL(wp), PARAMETER :: zch = 0.0057_wp ! heat transfer coefficient 260 REAL(wp), DIMENSION(jpi,jpj) :: zfric, zvel ! ice-ocean velocity (m/s) and frictional velocity (m2/s2) 261 !!----------------------------------------------------------------------- 262 ! 263 ! computation of friction velocity at T points 264 IF( ln_icedyn ) THEN 265 DO_2D( 0, 0, 0, 0 ) 266 zu_io = u_ice(ji ,jj ) - ssu_m(ji ,jj ) 267 zu_iom1 = u_ice(ji-1,jj ) - ssu_m(ji-1,jj ) 268 zv_io = v_ice(ji ,jj ) - ssv_m(ji ,jj ) 269 zv_iom1 = v_ice(ji ,jj-1) - ssv_m(ji ,jj-1) 270 ! 271 zfric(ji,jj) = rn_cio * ( 0.5_wp * ( zu_io*zu_io + zu_iom1*zu_iom1 + zv_io*zv_io + zv_iom1*zv_iom1 ) ) * tmask(ji,jj,1) 272 zvel (ji,jj) = 0.5_wp * SQRT( ( u_ice(ji-1,jj ) + u_ice(ji,jj) ) * ( u_ice(ji-1,jj ) + u_ice(ji,jj) ) + & 273 & ( v_ice(ji ,jj-1) + v_ice(ji,jj) ) * ( v_ice(ji ,jj-1) + v_ice(ji,jj) ) ) 274 END_2D 275 ELSE ! if no ice dynamics => transfer directly the atmospheric stress to the ocean 276 DO_2D( 0, 0, 0, 0 ) 277 zfric(ji,jj) = r1_rho0 * SQRT( 0.5_wp * & 278 & ( utau(ji,jj) * utau(ji,jj) + utau(ji-1,jj) * utau(ji-1,jj) & 279 & + vtau(ji,jj) * vtau(ji,jj) + vtau(ji,jj-1) * vtau(ji,jj-1) ) ) * tmask(ji,jj,1) 280 zvel(ji,jj) = 0._wp 281 END_2D 282 ENDIF 283 CALL lbc_lnk( 'icesbc', zfric, 'T', 1.0_wp, zvel, 'T', 1.0_wp ) 284 ! 285 !--------------------------------------------------------------------! 286 ! Partial computation of forcing for the thermodynamic sea ice model 287 !--------------------------------------------------------------------! 288 DO_2D( nn_hls, nn_hls, nn_hls, nn_hls ) ! needed for qlead 289 rswitch = tmask(ji,jj,1) * MAX( 0._wp , SIGN( 1._wp , at_i(ji,jj) - epsi10 ) ) ! 0 if no ice 290 ! 291 ! --- Energy received in the lead from atm-oce exchanges, zqld is defined everywhere (J.m-2) --- ! 292 zqld = tmask(ji,jj,1) * rDt_ice * & 293 & ( ( 1._wp - at_i_b(ji,jj) ) * qsr_oce(ji,jj) * frq_m(ji,jj) + & 294 & ( 1._wp - at_i_b(ji,jj) ) * qns_oce(ji,jj) + qemp_oce(ji,jj) ) 295 296 ! --- Energy needed to bring ocean surface layer until its freezing, zqfr is defined everywhere (J.m-2) --- ! 297 ! (mostly<0 but >0 if supercooling) 298 zqfr = rho0 * rcp * e3t_m(ji,jj) * ( t_bo(ji,jj) - ( sst_m(ji,jj) + rt0 ) ) * tmask(ji,jj,1) ! both < 0 (t_bo < sst) and > 0 (t_bo > sst) 299 zqfr_neg = MIN( zqfr , 0._wp ) ! only < 0 300 zqfr_pos = MAX( zqfr , 0._wp ) ! only > 0 301 302 ! --- Sensible ocean-to-ice heat flux (W/m2) --- ! 303 ! (mostly>0 but <0 if supercooling) 304 zfric_u = MAX( SQRT( zfric(ji,jj) ), zfric_umin ) 305 qsb_ice_bot(ji,jj) = rswitch * rho0 * rcp * zch * zfric_u * ( ( sst_m(ji,jj) + rt0 ) - t_bo(ji,jj) ) 306 307 ! upper bound for qsb_ice_bot: the heat retrieved from the ocean must be smaller than the heat necessary to reach 308 ! the freezing point, so that we do not have SST < T_freeze 309 ! This implies: qsb_ice_bot(ji,jj) * at_i(ji,jj) * rtdice <= - zqfr_neg 310 ! The following formulation is ok for both normal conditions and supercooling 311 qsb_ice_bot(ji,jj) = rswitch * MIN( qsb_ice_bot(ji,jj), - zqfr_neg * r1_Dt_ice / MAX( at_i(ji,jj), epsi10 ) ) 312 313 ! If conditions are always supercooled (such as at the mouth of ice-shelves), then ice grows continuously 314 ! ==> stop ice formation by artificially setting up the turbulent fluxes to 0 when volume > 20m (arbitrary) 315 IF( ( t_bo(ji,jj) - ( sst_m(ji,jj) + rt0 ) ) > 0._wp .AND. vt_i(ji,jj) >= 20._wp ) THEN 316 zqfr = 0._wp 317 zqfr_pos = 0._wp 318 qsb_ice_bot(ji,jj) = 0._wp 319 ENDIF 320 ! 321 ! --- Energy Budget of the leads (qlead, J.m-2) --- ! 322 ! qlead is the energy received from the atm. in the leads. 323 ! If warming (zqld >= 0), then the energy in the leads is used to melt ice (bottom melting) => fhld (W/m2) 324 ! If cooling (zqld < 0), then the energy in the leads is used to grow ice in open water => qlead (J.m-2) 325 IF( zqld >= 0._wp .AND. at_i(ji,jj) > 0._wp ) THEN 326 ! upper bound for fhld: fhld should be equal to zqld 327 ! but we have to make sure that this heat will not make the sst drop below the freezing point 328 ! so the max heat that can be pulled out of the ocean is zqld - qsb - zqfr_pos 329 ! The following formulation is ok for both normal conditions and supercooling 330 fhld (ji,jj) = rswitch * MAX( 0._wp, ( zqld - zqfr_pos ) * r1_Dt_ice / MAX( at_i(ji,jj), epsi10 ) & ! divided by at_i since this is (re)multiplied by a_i in icethd_dh.F90 331 & - qsb_ice_bot(ji,jj) ) 332 qlead(ji,jj) = 0._wp 333 ELSE 334 fhld (ji,jj) = 0._wp 335 ! upper bound for qlead: qlead should be equal to zqld 336 ! but before using this heat for ice formation, we suppose that the ocean cools down till the freezing point. 337 ! The energy for this cooling down is zqfr. Also some heat will be removed from the ocean from turbulent fluxes (qsb) 338 ! and freezing point is reached if zqfr = zqld - qsb*a/dt 339 ! so the max heat that can be pulled out of the ocean is zqld - qsb - zqfr 340 ! The following formulation is ok for both normal conditions and supercooling 341 qlead(ji,jj) = MIN( 0._wp , zqld - ( qsb_ice_bot(ji,jj) * at_i(ji,jj) * rDt_ice ) - zqfr ) 342 ENDIF 343 ! 344 ! If ice is landfast and ice concentration reaches its max 345 ! => stop ice formation in open water 346 IF( zvel(ji,jj) <= 5.e-04_wp .AND. at_i(ji,jj) >= rn_amax_2d(ji,jj)-epsi06 ) qlead(ji,jj) = 0._wp 347 ! 348 ! If the grid cell is almost fully covered by ice (no leads) 349 ! => stop ice formation in open water 350 IF( at_i(ji,jj) >= (1._wp - epsi10) ) qlead(ji,jj) = 0._wp 351 ! 352 ! If ln_leadhfx is false 353 ! => do not use energy of the leads to melt sea-ice 354 IF( .NOT.ln_leadhfx ) fhld(ji,jj) = 0._wp 355 ! 356 END_2D 357 358 ! In case we bypass open-water ice formation 359 IF( .NOT. ln_icedO ) qlead(:,:) = 0._wp 360 ! In case we bypass growing/melting from top and bottom 361 IF( .NOT. ln_icedH ) THEN 362 qsb_ice_bot(:,:) = 0._wp 363 fhld (:,:) = 0._wp 364 ENDIF 365 366 END SUBROUTINE ice_flx_other 367 368 272 369 SUBROUTINE ice_sbc_init 273 370 !!------------------------------------------------------------------- -
NEMO/branches/2021/ticket2632_r14588_theta_sbcblk/src/ICE/icestp.F90
r14072 r15548 159 159 CALL ice_rst_opn( kt ) ! Open Ice restart file (if necessary) 160 160 ! 161 IF( ln_icedyn .AND. .NOT.l k_c1d ) &161 IF( ln_icedyn .AND. .NOT.ln_c1d ) & 162 162 & CALL ice_dyn( kt, Kmm ) ! -- Ice dynamics 163 163 ! … … 404 404 !!---------------------------------------------------------------------- 405 405 406 DO_2D( 1, 1, 1, 1 )406 DO_2D( nn_hls, nn_hls, nn_hls, nn_hls ) ! needed for (at least) diag_adv_mass -> to be removed 407 407 sfx (ji,jj) = 0._wp ; 408 408 sfx_bri(ji,jj) = 0._wp ; sfx_lam(ji,jj) = 0._wp … … 452 452 453 453 DO jl = 1, jpl 454 DO_2D( 1, 1, 1, 1)454 DO_2D( nn_hls, nn_hls, nn_hls, nn_hls ) 455 455 ! SIMIP diagnostics 456 456 t_si (ji,jj,jl) = rt0 ! temp at the ice-snow interface … … 460 460 qcn_ice (ji,jj,jl) = 0._wp ! conductive flux (ln_cndflx=T & ln_cndemule=T) 461 461 qtr_ice_bot(ji,jj,jl) = 0._wp ! part of solar radiation transmitted through the ice needed at least for outputs 462 qml_ice (ji,jj,jl) = 0._wp ! surface melt heat flux 462 463 ! Melt pond surface melt diagnostics (mv - more efficient: grouped into one water volume flux) 463 464 dh_i_sum_2d(ji,jj,jl) = 0._wp -
NEMO/branches/2021/ticket2632_r14588_theta_sbcblk/src/ICE/icethd.F90
r14433 r15548 48 48 PUBLIC ice_thd_init ! called by ice_init 49 49 50 !!** namelist (namthd) **51 LOGICAL :: ln_icedH ! activate ice thickness change from growing/melting (T) or not (F)52 LOGICAL :: ln_icedA ! activate lateral melting param. (T) or not (F)53 LOGICAL :: ln_icedO ! activate ice growth in open-water (T) or not (F)54 LOGICAL :: ln_icedS ! activate gravity drainage and flushing (T) or not (F)55 LOGICAL :: ln_leadhfx ! heat in the leads is used to melt sea-ice before warming the ocean56 57 50 !! for convergence tests 58 51 REAL(wp), ALLOCATABLE, DIMENSION(:,:,:) :: ztice_cvgerr, ztice_cvgstp … … 92 85 ! 93 86 INTEGER :: ji, jj, jk, jl ! dummy loop indices 94 REAL(wp) :: zfric_u, zqld, zqfr, zqfr_neg, zqfr_pos95 REAL(wp), PARAMETER :: zfric_umin = 0._wp ! lower bound for the friction velocity (cice value=5.e-04)96 REAL(wp), PARAMETER :: zch = 0.0057_wp ! heat transfer coefficient97 REAL(wp), DIMENSION(jpi,jpj) :: zu_io, zv_io, zfric, zvel ! ice-ocean velocity (m/s) and frictional velocity (m2/s2)98 !99 87 !!------------------------------------------------------------------- 100 88 ! controls … … 114 102 ztice_cvgerr = 0._wp ; ztice_cvgstp = 0._wp 115 103 ENDIF 116 117 !---------------------------------------------! 118 ! computation of friction velocity at T points 119 !---------------------------------------------! 120 IF( ln_icedyn ) THEN 121 zu_io(:,:) = u_ice(:,:) - ssu_m(:,:) 122 zv_io(:,:) = v_ice(:,:) - ssv_m(:,:) 123 DO_2D( 0, 0, 0, 0 ) 124 zfric(ji,jj) = rn_cio * ( 0.5_wp * & 125 & ( zu_io(ji,jj) * zu_io(ji,jj) + zu_io(ji-1,jj) * zu_io(ji-1,jj) & 126 & + zv_io(ji,jj) * zv_io(ji,jj) + zv_io(ji,jj-1) * zv_io(ji,jj-1) ) ) * tmask(ji,jj,1) 127 zvel(ji,jj) = 0.5_wp * SQRT( ( u_ice(ji-1,jj) + u_ice(ji,jj) ) * ( u_ice(ji-1,jj) + u_ice(ji,jj) ) + & 128 & ( v_ice(ji,jj-1) + v_ice(ji,jj) ) * ( v_ice(ji,jj-1) + v_ice(ji,jj) ) ) 129 END_2D 130 ELSE ! if no ice dynamics => transmit directly the atmospheric stress to the ocean 131 DO_2D( 0, 0, 0, 0 ) 132 zfric(ji,jj) = r1_rho0 * SQRT( 0.5_wp * & 133 & ( utau(ji,jj) * utau(ji,jj) + utau(ji-1,jj) * utau(ji-1,jj) & 134 & + vtau(ji,jj) * vtau(ji,jj) + vtau(ji,jj-1) * vtau(ji,jj-1) ) ) * tmask(ji,jj,1) 135 zvel(ji,jj) = 0._wp 136 END_2D 137 ENDIF 138 CALL lbc_lnk( 'icethd', zfric, 'T', 1.0_wp, zvel, 'T', 1.0_wp ) 139 ! 140 !--------------------------------------------------------------------! 141 ! Partial computation of forcing for the thermodynamic sea ice model 142 !--------------------------------------------------------------------! 143 DO_2D( 1, 1, 1, 1 ) 144 rswitch = tmask(ji,jj,1) * MAX( 0._wp , SIGN( 1._wp , at_i(ji,jj) - epsi10 ) ) ! 0 if no ice 145 ! 146 ! --- Energy received in the lead from atm-oce exchanges, zqld is defined everywhere (J.m-2) --- ! 147 zqld = tmask(ji,jj,1) * rDt_ice * & 148 & ( ( 1._wp - at_i_b(ji,jj) ) * qsr_oce(ji,jj) * frq_m(ji,jj) + & 149 & ( 1._wp - at_i_b(ji,jj) ) * qns_oce(ji,jj) + qemp_oce(ji,jj) ) 150 151 ! --- Energy needed to bring ocean surface layer until its freezing, zqfr is defined everywhere (J.m-2) --- ! 152 ! (mostly<0 but >0 if supercooling) 153 zqfr = rho0 * rcp * e3t_m(ji,jj) * ( t_bo(ji,jj) - ( sst_m(ji,jj) + rt0 ) ) * tmask(ji,jj,1) ! both < 0 (t_bo < sst) and > 0 (t_bo > sst) 154 zqfr_neg = MIN( zqfr , 0._wp ) ! only < 0 155 zqfr_pos = MAX( zqfr , 0._wp ) ! only > 0 156 157 ! --- Sensible ocean-to-ice heat flux (W/m2) --- ! 158 ! (mostly>0 but <0 if supercooling) 159 zfric_u = MAX( SQRT( zfric(ji,jj) ), zfric_umin ) 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 163 ! the freezing point, so that we do not have SST < T_freeze 164 ! This implies: qsb_ice_bot(ji,jj) * at_i(ji,jj) * rtdice <= - zqfr_neg 165 ! The following formulation is ok for both normal conditions and supercooling 166 qsb_ice_bot(ji,jj) = rswitch * MIN( qsb_ice_bot(ji,jj), - zqfr_neg * r1_Dt_ice / MAX( at_i(ji,jj), epsi10 ) ) 167 168 ! If conditions are always supercooled (such as at the mouth of ice-shelves), then ice grows continuously 169 ! ==> stop ice formation by artificially setting up the turbulent fluxes to 0 when volume > 20m (arbitrary) 170 IF( ( t_bo(ji,jj) - ( sst_m(ji,jj) + rt0 ) ) > 0._wp .AND. vt_i(ji,jj) >= 20._wp ) THEN 171 zqfr = 0._wp 172 zqfr_pos = 0._wp 173 qsb_ice_bot(ji,jj) = 0._wp 174 ENDIF 175 ! 176 ! --- Energy Budget of the leads (qlead, J.m-2) --- ! 177 ! qlead is the energy received from the atm. in the leads. 178 ! If warming (zqld >= 0), then the energy in the leads is used to melt ice (bottom melting) => fhld (W/m2) 179 ! If cooling (zqld < 0), then the energy in the leads is used to grow ice in open water => qlead (J.m-2) 180 IF( zqld >= 0._wp .AND. at_i(ji,jj) > 0._wp ) THEN 181 ! upper bound for fhld: fhld should be equal to zqld 182 ! but we have to make sure that this heat will not make the sst drop below the freezing point 183 ! so the max heat that can be pulled out of the ocean is zqld - qsb - zqfr_pos 184 ! The following formulation is ok for both normal conditions and supercooling 185 fhld (ji,jj) = rswitch * MAX( 0._wp, ( zqld - zqfr_pos ) * r1_Dt_ice / MAX( at_i(ji,jj), epsi10 ) & ! divided by at_i since this is (re)multiplied by a_i in icethd_dh.F90 186 & - qsb_ice_bot(ji,jj) ) 187 qlead(ji,jj) = 0._wp 188 ELSE 189 fhld (ji,jj) = 0._wp 190 ! upper bound for qlead: qlead should be equal to zqld 191 ! but before using this heat for ice formation, we suppose that the ocean cools down till the freezing point. 192 ! The energy for this cooling down is zqfr. Also some heat will be removed from the ocean from turbulent fluxes (qsb) 193 ! and freezing point is reached if zqfr = zqld - qsb*a/dt 194 ! so the max heat that can be pulled out of the ocean is zqld - qsb - zqfr 195 ! The following formulation is ok for both normal conditions and supercooling 196 qlead(ji,jj) = MIN( 0._wp , zqld - ( qsb_ice_bot(ji,jj) * at_i(ji,jj) * rDt_ice ) - zqfr ) 197 ENDIF 198 ! 199 ! If ice is landfast and ice concentration reaches its max 200 ! => stop ice formation in open water 201 IF( zvel(ji,jj) <= 5.e-04_wp .AND. at_i(ji,jj) >= rn_amax_2d(ji,jj)-epsi06 ) qlead(ji,jj) = 0._wp 202 ! 203 ! If the grid cell is almost fully covered by ice (no leads) 204 ! => stop ice formation in open water 205 IF( at_i(ji,jj) >= (1._wp - epsi10) ) qlead(ji,jj) = 0._wp 206 ! 207 ! If ln_leadhfx is false 208 ! => do not use energy of the leads to melt sea-ice 209 IF( .NOT.ln_leadhfx ) fhld(ji,jj) = 0._wp 210 ! 211 END_2D 212 213 ! In case we bypass open-water ice formation 214 IF( .NOT. ln_icedO ) qlead(:,:) = 0._wp 215 ! In case we bypass growing/melting from top and bottom 216 IF( .NOT. ln_icedH ) THEN 217 qsb_ice_bot(:,:) = 0._wp 218 fhld (:,:) = 0._wp 219 ENDIF 220 104 ! 105 CALL ice_thd_frazil !--- frazil ice: collection thickness (ht_i_new) & fraction of frazil (fraz_frac) 106 ! 221 107 !-------------------------------------------------------------------------------------------! 222 108 ! Thermodynamic computation (only on grid points covered by ice) => loop over ice categories … … 226 112 ! select ice covered grid points 227 113 npti = 0 ; nptidx(:) = 0 228 DO_2D( 1, 1, 1, 1)114 DO_2D( nn_hls, nn_hls, nn_hls, nn_hls ) 229 115 IF ( a_i(ji,jj,jl) > epsi10 ) THEN 230 116 npti = npti + 1 … … 268 154 ! 269 155 IF ( ln_pnd .AND. ln_icedH ) & 270 & CALL ice_thd_pnd ! --- Melt ponds 156 & CALL ice_thd_pnd ! --- Melt ponds --- ! 271 157 ! 272 158 IF( jpl > 1 ) CALL ice_itd_rem( kt ) ! --- Transport ice between thickness categories --- ! … … 276 162 CALL ice_cor( kt , 2 ) ! --- Corrections --- ! 277 163 ! 278 oa_i(:,:,:) = oa_i(:,:,:) + a_i(:,:,:) * rDt_ice ! ice natural aging incrementation 164 oa_i(:,:,:) = oa_i(:,:,:) + a_i(:,:,:) * rDt_ice ! --- Ice natural aging incrementation 165 ! 166 DO_2D( 0, 0, 0, 0 ) ! --- Ice velocity corrections 167 IF( at_i(ji,jj) == 0._wp ) THEN ! if ice has melted 168 IF( at_i(ji+1,jj) == 0._wp ) u_ice(ji ,jj) = 0._wp ! right side 169 IF( at_i(ji-1,jj) == 0._wp ) u_ice(ji-1,jj) = 0._wp ! left side 170 IF( at_i(ji,jj+1) == 0._wp ) v_ice(ji,jj ) = 0._wp ! upper side 171 IF( at_i(ji,jj-1) == 0._wp ) v_ice(ji,jj-1) = 0._wp ! bottom side 172 ENDIF 173 END_2D 174 CALL lbc_lnk( 'icethd', u_ice, 'U', -1.0_wp, v_ice, 'V', -1.0_wp ) 279 175 ! 280 176 ! convergence tests … … 355 251 END SUBROUTINE ice_thd_mono 356 252 357 358 253 SUBROUTINE ice_thd_1d2d( kl, kn ) 359 254 !!----------------------------------------------------------------------- … … 536 431 CALL tab_1d_2d( npti, nptidx(1:npti), qcn_ice_bot_1d(1:npti), qcn_ice_bot(:,:,kl) ) 537 432 CALL tab_1d_2d( npti, nptidx(1:npti), qcn_ice_top_1d(1:npti), qcn_ice_top(:,:,kl) ) 433 CALL tab_1d_2d( npti, nptidx(1:npti), qml_ice_1d (1:npti), qml_ice (:,:,kl) ) 538 434 ! extensive variables 539 435 CALL tab_1d_2d( npti, nptidx(1:npti), v_i_1d (1:npti), v_i (:,:,kl) ) -
NEMO/branches/2021/ticket2632_r14588_theta_sbcblk/src/ICE/icethd_da.F90
r12489 r15548 109 109 !!--------------------------------------------------------------------- 110 110 INTEGER :: ji ! dummy loop indices 111 REAL(wp) :: zastar, zdfloe, zperi, zwlat, zda 111 REAL(wp) :: zastar, zdfloe, zperi, zwlat, zda, zda_tot 112 112 REAL(wp), PARAMETER :: zdmax = 300._wp 113 113 REAL(wp), PARAMETER :: zcs = 0.66_wp 114 114 REAL(wp), PARAMETER :: zm1 = 3.e-6_wp 115 115 REAL(wp), PARAMETER :: zm2 = 1.36_wp 116 !117 REAL(wp), DIMENSION(jpij) :: zda_tot118 116 !!--------------------------------------------------------------------- 119 117 ! … … 128 126 zwlat = zm1 * ( MAX( 0._wp, sst_1d(ji) - ( t_bo_1d(ji) - rt0 ) ) )**zm2 ! Melt speed rate [m/s] 129 127 ! 130 zda_tot (ji) = MIN( zwlat * zperi * rDt_ice, at_i_1d(ji) )! sea ice concentration decrease (>0)128 zda_tot = MIN( zwlat * zperi * rDt_ice, at_i_1d(ji) ) ! sea ice concentration decrease (>0) 131 129 132 130 ! --- Distribute reduction among ice categories and calculate associated ice-ocean fluxes --- ! … … 134 132 ! decrease of concentration for the category jl 135 133 ! each category contributes to melting in proportion to its concentration 136 zda = MIN( a_i_1d(ji), zda_tot (ji)* a_i_1d(ji) / at_i_1d(ji) )134 zda = MIN( a_i_1d(ji), zda_tot * a_i_1d(ji) / at_i_1d(ji) ) 137 135 138 136 ! Contribution to salt flux -
NEMO/branches/2021/ticket2632_r14588_theta_sbcblk/src/ICE/icethd_dh.F90
r14072 r15548 224 224 zevap_rema(1:npti) = 0._wp 225 225 DO ji = 1, npti 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 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 ENDIF 226 zdeltah (ji) = MAX( - evap_ice_1d(ji) * r1_rhos * rDt_ice, - h_s_1d(ji) ) ! amount of snw that sublimates, < 0 227 zevap_rema(ji) = evap_ice_1d(ji) * rDt_ice + zdeltah(ji) * rhos ! remaining evap in kg.m-2 (used for ice sublimation later on) 230 228 END DO 231 229 -
NEMO/branches/2021/ticket2632_r14588_theta_sbcblk/src/ICE/icethd_do.F90
r14433 r15548 35 35 36 36 PUBLIC ice_thd_do ! called by ice_thd 37 PUBLIC ice_thd_frazil ! called by ice_thd 37 38 PUBLIC ice_thd_do_init ! called by ice_stp 38 39 ! !!** namelist (namthd_do) **40 REAL(wp) :: rn_hinew ! thickness for new ice formation (m)41 LOGICAL :: ln_frazil ! use of frazil ice collection as function of wind (T) or not (F)42 REAL(wp) :: rn_maxfraz ! maximum portion of frazil ice collecting at the ice bottom43 REAL(wp) :: rn_vfraz ! threshold drift speed for collection of bottom frazil ice44 REAL(wp) :: rn_Cfraz ! squeezing coefficient for collection of bottom frazil ice45 39 46 40 !! * Substitutions … … 78 72 !!------------------------------------------------------------------------ 79 73 INTEGER :: ji, jj, jk, jl ! dummy loop indices 80 INTEGER :: iter ! - - 81 REAL(wp) :: ztmelts, zfrazb, zweight, zde ! local scalars 82 REAL(wp) :: zgamafr, zvfrx, zvgx, ztaux, ztwogp, zf ! - - 83 REAL(wp) :: ztenagm, zvfry, zvgy, ztauy, zvrel2, zfp, zsqcd , zhicrit ! - - 84 ! 74 ! 75 REAL(wp) :: ztmelts 76 REAL(wp) :: zdE 85 77 REAL(wp) :: zQm ! enthalpy exchanged with the ocean (J/m2, >0 towards ocean) 86 78 REAL(wp) :: zEi ! sea ice specific enthalpy (J/kg) … … 102 94 REAL(wp), DIMENSION(jpij) :: zda_res ! residual area in case of excessive heat budget 103 95 REAL(wp), DIMENSION(jpij) :: zv_frazb ! accretion of frazil ice at the ice bottom 104 REAL(wp), DIMENSION(jpij) :: z vrel_1d! relative ice / frazil velocity (1D vector)96 REAL(wp), DIMENSION(jpij) :: zfraz_frac_1d ! relative ice / frazil velocity (1D vector) 105 97 ! 106 98 REAL(wp), DIMENSION(jpij,jpl) :: zv_b ! old volume of ice in category jl … … 109 101 REAL(wp), DIMENSION(jpij,nlay_i,jpl) :: ze_i_2d !: 1-D version of e_i 110 102 ! 111 REAL(wp), DIMENSION(jpi,jpj) :: zvrel ! relative ice / frazil velocity112 !113 REAL(wp) :: zcai = 1.4e-3_wp ! ice-air drag (clem: should be dependent on coupling/forcing used)114 103 !!-----------------------------------------------------------------------! 115 104 … … 119 108 at_i(:,:) = SUM( a_i, dim=3 ) 120 109 !------------------------------------------------------------------------------! 121 ! 1) Collection thickness of ice formed in leads and polynyas 122 !------------------------------------------------------------------------------! 123 ! ht_i_new is the thickness of new ice formed in open water 124 ! ht_i_new can be either prescribed (ln_frazil=F) or computed (ln_frazil=T) 125 ! Frazil ice forms in open water, is transported by wind 126 ! accumulates at the edge of the consolidated ice edge 127 ! where it forms aggregates of a specific thickness called 128 ! collection thickness. 129 130 zvrel(:,:) = 0._wp 131 132 ! Default new ice thickness 133 WHERE( qlead(:,:) < 0._wp ) ! cooling 134 ht_i_new(:,:) = rn_hinew 135 ELSEWHERE 136 ht_i_new(:,:) = 0._wp 137 END WHERE 138 139 IF( ln_frazil ) THEN 140 ! 141 ht_i_new(:,:) = 0._wp 142 ! 143 ! Physical constants 144 zhicrit = 0.04 ! frazil ice thickness 145 ztwogp = 2. * rho0 / ( grav * 0.3 * ( rho0 - rhoi ) ) ! reduced grav 146 zsqcd = 1.0 / SQRT( 1.3 * zcai ) ! 1/SQRT(airdensity*drag) 147 zgamafr = 0.03 148 ! 149 DO_2D( 0, 0, 0, 0 ) 150 IF ( qlead(ji,jj) < 0._wp ) THEN ! cooling 151 ! -- Wind stress -- ! 152 ztaux = ( utau_ice(ji-1,jj ) * umask(ji-1,jj ,1) & 153 & + utau_ice(ji ,jj ) * umask(ji ,jj ,1) ) * 0.5_wp 154 ztauy = ( vtau_ice(ji ,jj-1) * vmask(ji ,jj-1,1) & 155 & + vtau_ice(ji ,jj ) * vmask(ji ,jj ,1) ) * 0.5_wp 156 ! Square root of wind stress 157 ztenagm = SQRT( SQRT( ztaux * ztaux + ztauy * ztauy ) ) 158 159 ! -- Frazil ice velocity -- ! 160 rswitch = MAX( 0._wp, SIGN( 1._wp , ztenagm - epsi10 ) ) 161 zvfrx = rswitch * zgamafr * zsqcd * ztaux / MAX( ztenagm, epsi10 ) 162 zvfry = rswitch * zgamafr * zsqcd * ztauy / MAX( ztenagm, epsi10 ) 163 164 ! -- Pack ice velocity -- ! 165 zvgx = ( u_ice(ji-1,jj ) * umask(ji-1,jj ,1) + u_ice(ji,jj) * umask(ji,jj,1) ) * 0.5_wp 166 zvgy = ( v_ice(ji ,jj-1) * vmask(ji ,jj-1,1) + v_ice(ji,jj) * vmask(ji,jj,1) ) * 0.5_wp 167 168 ! -- Relative frazil/pack ice velocity -- ! 169 rswitch = MAX( 0._wp, SIGN( 1._wp , at_i(ji,jj) - epsi10 ) ) 170 zvrel2 = MAX( ( zvfrx - zvgx ) * ( zvfrx - zvgx ) & 171 & + ( zvfry - zvgy ) * ( zvfry - zvgy ) , 0.15 * 0.15 ) * rswitch 172 zvrel(ji,jj) = SQRT( zvrel2 ) 173 174 ! -- new ice thickness (iterative loop) -- ! 175 ht_i_new(ji,jj) = zhicrit + ( zhicrit + 0.1 ) & 176 & / ( ( zhicrit + 0.1 ) * ( zhicrit + 0.1 ) - zhicrit * zhicrit ) * ztwogp * zvrel2 177 178 iter = 1 179 DO WHILE ( iter < 20 ) 180 zf = ( ht_i_new(ji,jj) - zhicrit ) * ( ht_i_new(ji,jj) * ht_i_new(ji,jj) - zhicrit * zhicrit ) - & 181 & ht_i_new(ji,jj) * zhicrit * ztwogp * zvrel2 182 zfp = ( ht_i_new(ji,jj) - zhicrit ) * ( 3.0 * ht_i_new(ji,jj) + zhicrit ) - zhicrit * ztwogp * zvrel2 183 184 ht_i_new(ji,jj) = ht_i_new(ji,jj) - zf / MAX( zfp, epsi20 ) 185 iter = iter + 1 186 END DO 187 ! 188 ! bound ht_i_new (though I don't see why it should be necessary) 189 ht_i_new(ji,jj) = MAX( 0.01_wp, MIN( ht_i_new(ji,jj), hi_max(jpl) ) ) 190 ! 191 ENDIF 192 ! 193 END_2D 194 ! 195 CALL lbc_lnk( 'icethd_do', zvrel, 'T', 1.0_wp, ht_i_new, 'T', 1.0_wp ) 196 197 ENDIF 198 199 !------------------------------------------------------------------------------! 200 ! 2) Compute thickness, salinity, enthalpy, age, area and volume of new ice 110 ! 1) Compute thickness, salinity, enthalpy, age, area and volume of new ice 201 111 !------------------------------------------------------------------------------! 202 112 ! it occurs if cooling … … 204 114 ! Identify grid points where new ice forms 205 115 npti = 0 ; nptidx(:) = 0 206 DO_2D( 1, 1, 1, 1)116 DO_2D( nn_hls, nn_hls, nn_hls, nn_hls ) 207 117 IF ( qlead(ji,jj) < 0._wp ) THEN 208 118 npti = npti + 1 … … 223 133 END DO 224 134 END DO 225 CALL tab_2d_1d( npti, nptidx(1:npti), qlead_1d (1:npti) , qlead )226 CALL tab_2d_1d( npti, nptidx(1:npti), t_bo_1d (1:npti) , t_bo )227 CALL tab_2d_1d( npti, nptidx(1:npti), sfx_opw_1d (1:npti) , sfx_opw )228 CALL tab_2d_1d( npti, nptidx(1:npti), wfx_opw_1d (1:npti) , wfx_opw )229 CALL tab_2d_1d( npti, nptidx(1:npti), zh_newice (1:npti) , ht_i_new )230 CALL tab_2d_1d( npti, nptidx(1:npti), z vrel_1d (1:npti) , zvrel)135 CALL tab_2d_1d( npti, nptidx(1:npti), qlead_1d (1:npti) , qlead ) 136 CALL tab_2d_1d( npti, nptidx(1:npti), t_bo_1d (1:npti) , t_bo ) 137 CALL tab_2d_1d( npti, nptidx(1:npti), sfx_opw_1d (1:npti) , sfx_opw ) 138 CALL tab_2d_1d( npti, nptidx(1:npti), wfx_opw_1d (1:npti) , wfx_opw ) 139 CALL tab_2d_1d( npti, nptidx(1:npti), zh_newice (1:npti) , ht_i_new ) 140 CALL tab_2d_1d( npti, nptidx(1:npti), zfraz_frac_1d(1:npti) , fraz_frac ) 231 141 232 142 CALL tab_2d_1d( npti, nptidx(1:npti), hfx_thd_1d(1:npti) , hfx_thd ) … … 300 210 END DO 301 211 302 zv_frazb(1:npti) = 0._wp 303 IF( ln_frazil ) THEN 304 ! A fraction zfrazb of frazil ice is accreted at the ice bottom 305 DO ji = 1, npti 306 rswitch = 1._wp - MAX( 0._wp, SIGN( 1._wp , - at_i_1d(ji) ) ) 307 zfrazb = rswitch * ( TANH( rn_Cfraz * ( zvrel_1d(ji) - rn_vfraz ) ) + 1.0 ) * 0.5 * rn_maxfraz 308 zv_frazb(ji) = zfrazb * zv_newice(ji) 309 zv_newice(ji) = ( 1.0 - zfrazb ) * zv_newice(ji) 310 END DO 311 END IF 212 ! A fraction fraz_frac of frazil ice is accreted at the ice bottom 213 DO ji = 1, npti 214 rswitch = 1._wp - MAX( 0._wp, SIGN( 1._wp , - at_i_1d(ji) ) ) 215 zv_frazb(ji) = zfraz_frac_1d(ji) * rswitch * zv_newice(ji) 216 zv_newice(ji) = ( 1._wp - zfraz_frac_1d(ji) * rswitch ) * zv_newice(ji) 217 END DO 312 218 313 219 ! --- Area of new ice --- ! … … 317 223 318 224 !------------------------------------------------------------------------------! 319 ! 3) Redistribute new ice area and volume into ice categories !225 ! 2) Redistribute new ice area and volume into ice categories ! 320 226 !------------------------------------------------------------------------------! 321 227 … … 426 332 427 333 334 SUBROUTINE ice_thd_frazil 335 !!----------------------------------------------------------------------- 336 !! *** ROUTINE ice_thd_frazil *** 337 !! 338 !! ** Purpose : frazil ice collection thickness and fraction 339 !! 340 !! ** Inputs : u_ice, v_ice, utau_ice, vtau_ice 341 !! ** Ouputs : ht_i_new, fraz_frac 342 !!----------------------------------------------------------------------- 343 INTEGER :: ji, jj ! dummy loop indices 344 INTEGER :: iter 345 REAL(wp) :: zvfrx, zvgx, ztaux, zf, ztenagm, zvfry, zvgy, ztauy, zvrel2, zfp, ztwogp 346 REAL(wp), PARAMETER :: zcai = 1.4e-3_wp ! ice-air drag (clem: should be dependent on coupling/forcing used) 347 REAL(wp), PARAMETER :: zhicrit = 0.04_wp ! frazil ice thickness 348 REAL(wp), PARAMETER :: zsqcd = 1.0_wp / SQRT( 1.3_wp * zcai ) ! 1/SQRT(airdensity*drag) 349 REAL(wp), PARAMETER :: zgamafr = 0.03_wp 350 !!----------------------------------------------------------------------- 351 ! 352 !---------------------------------------------------------! 353 ! Collection thickness of ice formed in leads and polynyas 354 !---------------------------------------------------------! 355 ! ht_i_new is the thickness of new ice formed in open water 356 ! ht_i_new can be either prescribed (ln_frazil=F) or computed (ln_frazil=T) 357 ! Frazil ice forms in open water, is transported by wind, accumulates at the edge of the consolidated ice edge 358 ! where it forms aggregates of a specific thickness called collection thickness. 359 ! 360 fraz_frac(:,:) = 0._wp 361 ! 362 ! Default new ice thickness 363 WHERE( qlead(:,:) < 0._wp ) ! cooling 364 ht_i_new(:,:) = rn_hinew 365 ELSEWHERE 366 ht_i_new(:,:) = 0._wp 367 END WHERE 368 369 IF( ln_frazil ) THEN 370 ztwogp = 2._wp * rho0 / ( grav * 0.3_wp * ( rho0 - rhoi ) ) ! reduced grav 371 ! 372 DO_2D( 0, 0, 0, 0 ) 373 IF ( qlead(ji,jj) < 0._wp ) THEN ! cooling 374 ! -- Wind stress -- ! 375 ztaux = ( utau_ice(ji-1,jj ) * umask(ji-1,jj ,1) + utau_ice(ji,jj) * umask(ji,jj,1) ) * 0.5_wp 376 ztauy = ( vtau_ice(ji ,jj-1) * vmask(ji ,jj-1,1) + vtau_ice(ji,jj) * vmask(ji,jj,1) ) * 0.5_wp 377 ! Square root of wind stress 378 ztenagm = SQRT( SQRT( ztaux * ztaux + ztauy * ztauy ) ) 379 380 ! -- Frazil ice velocity -- ! 381 rswitch = MAX( 0._wp, SIGN( 1._wp , ztenagm - epsi10 ) ) 382 zvfrx = rswitch * zgamafr * zsqcd * ztaux / MAX( ztenagm, epsi10 ) 383 zvfry = rswitch * zgamafr * zsqcd * ztauy / MAX( ztenagm, epsi10 ) 384 385 ! -- Pack ice velocity -- ! 386 zvgx = ( u_ice(ji-1,jj ) * umask(ji-1,jj ,1) + u_ice(ji,jj) * umask(ji,jj,1) ) * 0.5_wp 387 zvgy = ( v_ice(ji ,jj-1) * vmask(ji ,jj-1,1) + v_ice(ji,jj) * vmask(ji,jj,1) ) * 0.5_wp 388 389 ! -- Relative frazil/pack ice velocity -- ! 390 rswitch = MAX( 0._wp, SIGN( 1._wp , at_i(ji,jj) - epsi10 ) ) 391 zvrel2 = MAX( (zvfrx - zvgx)*(zvfrx - zvgx) + (zvfry - zvgy)*(zvfry - zvgy), 0.15_wp*0.15_wp ) * rswitch 392 393 ! -- fraction of frazil ice -- ! 394 fraz_frac(ji,jj) = rswitch * ( TANH( rn_Cfraz * ( SQRT(zvrel2) - rn_vfraz ) ) + 1._wp ) * 0.5_wp * rn_maxfraz 395 396 ! -- new ice thickness (iterative loop) -- ! 397 ht_i_new(ji,jj) = zhicrit + ( zhicrit + 0.1_wp ) & 398 & / ( ( zhicrit + 0.1_wp ) * ( zhicrit + 0.1_wp ) - zhicrit * zhicrit ) * ztwogp * zvrel2 399 iter = 1 400 DO WHILE ( iter < 20 ) 401 zf = ( ht_i_new(ji,jj) - zhicrit ) * ( ht_i_new(ji,jj) * ht_i_new(ji,jj) - zhicrit * zhicrit ) - & 402 & ht_i_new(ji,jj) * zhicrit * ztwogp * zvrel2 403 zfp = ( ht_i_new(ji,jj) - zhicrit ) * ( 3.0_wp * ht_i_new(ji,jj) + zhicrit ) - zhicrit * ztwogp * zvrel2 404 405 ht_i_new(ji,jj) = ht_i_new(ji,jj) - zf / MAX( zfp, epsi20 ) 406 iter = iter + 1 407 END DO 408 ! 409 ! bound ht_i_new (though I don't see why it should be necessary) 410 ht_i_new(ji,jj) = MAX( 0.01_wp, MIN( ht_i_new(ji,jj), hi_max(jpl) ) ) 411 ! 412 ELSE 413 ht_i_new(ji,jj) = 0._wp 414 ENDIF 415 ! 416 END_2D 417 ! 418 CALL lbc_lnk( 'icethd_frazil', fraz_frac, 'T', 1.0_wp, ht_i_new, 'T', 1.0_wp ) 419 420 ENDIF 421 END SUBROUTINE ice_thd_frazil 422 423 428 424 SUBROUTINE ice_thd_do_init 429 425 !!----------------------------------------------------------------------- -
NEMO/branches/2021/ticket2632_r14588_theta_sbcblk/src/ICE/icethd_ent.F90
r13547 r15548 121 121 DO ji = 1, npti 122 122 rswitch = MAX( 0._wp , SIGN( 1._wp , zhnew(ji) - epsi20 ) ) 123 qnew(ji,jk1) = rswitch * ( zeh_cum1(ji,jk1) - zeh_cum1(ji,jk1-1) ) / MAX( zhnew(ji), epsi20 )123 qnew(ji,jk1) = rswitch * MAX( 0._wp, zeh_cum1(ji,jk1) - zeh_cum1(ji,jk1-1) ) / MAX( zhnew(ji), epsi20 ) ! max for roundoff error 124 124 END DO 125 125 END DO -
NEMO/branches/2021/ticket2632_r14588_theta_sbcblk/src/ICE/icethd_pnd.F90
r14252 r15548 99 99 ! 100 100 DO jl = 1, jpl 101 DO_2D( 1, 1, 1, 1)101 DO_2D( nn_hls, nn_hls, nn_hls, nn_hls ) 102 102 IF( v_i(ji,jj,jl) < epsi10 .OR. at_i(ji,jj) < epsi10 ) THEN 103 103 wfx_pnd (ji,jj) = wfx_pnd(ji,jj) + ( v_ip(ji,jj,jl) + v_il(ji,jj,jl) ) * rhow * r1_Dt_ice … … 116 116 !------------------------------ 117 117 npti = 0 ; nptidx(:) = 0 118 DO_2D( 1, 1, 1, 1)118 DO_2D( nn_hls, nn_hls, nn_hls, nn_hls ) 119 119 IF( at_i(ji,jj) >= epsi10 ) THEN 120 120 npti = npti + 1 … … 590 590 591 591 DO jl = 1, jpl 592 DO_2D( 1, 1, 1, 1)592 DO_2D( nn_hls, nn_hls, nn_hls, nn_hls ) 593 593 594 594 IF ( a_i(ji,jj,jl) > epsi10 ) THEN … … 638 638 IF( ln_pnd_lids ) THEN 639 639 640 DO_2D( 1, 1, 1, 1)640 DO_2D( nn_hls, nn_hls, nn_hls, nn_hls ) 641 641 642 642 IF ( at_i(ji,jj) > 0.01 .AND. hm_i(ji,jj) > rn_himin .AND. zvolp_ini(ji,jj) > zvp_min * at_i(ji,jj) ) THEN … … 662 662 IF ( t_su(ji,jj,jl) > zTp ) THEN 663 663 664 zdvice = MIN( dh_i_sum_2d(ji,jj,jl)*a_ip(ji,jj,jl), v_il(ji,jj,jl) )664 zdvice = MIN( -dh_i_sum_2d(ji,jj,jl)*a_ip(ji,jj,jl), v_il(ji,jj,jl) ) 665 665 666 666 IF ( zdvice > epsi10 ) THEN … … 765 765 DO jl = 1, jpl 766 766 767 DO_2D( 1, 1, 1, 1)767 DO_2D( nn_hls, nn_hls, nn_hls, nn_hls ) 768 768 769 769 ! ! zap lids on small ponds … … 775 775 ! recalculate equivalent pond variables 776 776 IF ( a_ip(ji,jj,jl) > epsi10) THEN 777 h_ip(ji,jj,jl) = v_ip(ji,jj,jl) / a_i (ji,jj,jl)777 h_ip(ji,jj,jl) = v_ip(ji,jj,jl) / a_ip(ji,jj,jl) 778 778 a_ip_frac(ji,jj,jl) = a_ip(ji,jj,jl) / a_i(ji,jj,jl) ! MV in principle, useless as computed in icevar 779 779 h_il(ji,jj,jl) = v_il(ji,jj,jl) / a_ip(ji,jj,jl) ! MV in principle, useless as computed in icevar … … 869 869 h_ip(:,:,:) = 0._wp 870 870 871 DO_2D( 1, 1, 1, 1)871 DO_2D( nn_hls, nn_hls, nn_hls, nn_hls ) 872 872 873 873 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 -
NEMO/branches/2021/ticket2632_r14588_theta_sbcblk/src/ICE/iceupdate.F90
r14581 r15548 92 92 INTEGER :: ji, jj, jl, jk ! dummy loop indices 93 93 REAL(wp) :: zqsr ! New solar flux received by the ocean 94 REAL(wp), DIMENSION(jpi,jpj) :: z2d ! 2D workspace94 REAL(wp), ALLOCATABLE, DIMENSION(:,:) :: z2d ! 2D workspace 95 95 !!--------------------------------------------------------------------- 96 96 IF( ln_timing ) CALL timing_start('iceupdate') … … 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 IF( ln_cndflx ) THEN ! ice-atm interface = conduction (and melting) fluxes 107 qt_atm_oi(:,:) = ( 1._wp - at_i_b(:,:) ) * ( qns_oce(:,:) + qsr_oce(:,:) ) + qemp_oce(:,:) + & 108 & SUM( a_i_b * ( qcn_ice + qml_ice + qtr_ice_top ), dim=3 ) + qemp_ice(:,:) 109 ELSE ! ice-atm interface = solar and non-solar fluxes 110 qt_atm_oi(:,:) = qns_tot(:,:) + qsr_tot(:,:) 111 ENDIF 107 112 108 113 ! --- case we bypass ice thermodynamics --- ! … … 115 120 ENDIF 116 121 117 DO_2D( 1, 1, 1, 1)122 DO_2D( nn_hls, nn_hls, nn_hls, nn_hls ) 118 123 119 124 ! Solar heat flux reaching the ocean (max) = zqsr (W.m-2) 120 125 !--------------------------------------------------- 121 zqsr = qsr_tot(ji,jj) - SUM( a_i_b(ji,jj,:) * ( qsr_ice(ji,jj,:) - qtr_ice_bot(ji,jj,:) ) ) 126 IF( ln_cndflx ) THEN ! ice-atm interface = conduction (and melting) fluxes 127 zqsr = ( 1._wp - at_i_b(ji,jj) ) * qsr_oce(ji,jj) + SUM( a_i_b (ji,jj,:) * qtr_ice_bot(ji,jj,:) ) 128 ELSE ! ice-atm interface = solar and non-solar fluxes 129 zqsr = qsr_tot(ji,jj) - SUM( a_i_b(ji,jj,:) * ( qsr_ice(ji,jj,:) - qtr_ice_bot(ji,jj,:) ) ) 130 ENDIF 122 131 123 132 ! Total heat flux reaching the ocean = qt_oce_ai (W.m-2) 124 133 !--------------------------------------------------- 125 qt_oce_ai(ji,jj) = qt_atm_oi(ji,jj) - hfx_sum(ji,jj) - hfx_bom(ji,jj) - hfx_bog(ji,jj) & 126 & - hfx_dif(ji,jj) - hfx_opw(ji,jj) - hfx_snw(ji,jj) & 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 134 IF( ln_icethd ) THEN 135 qt_oce_ai(ji,jj) = qt_atm_oi(ji,jj) - hfx_sum(ji,jj) - hfx_bom(ji,jj) - hfx_bog(ji,jj) & 136 & - hfx_dif(ji,jj) - hfx_opw(ji,jj) - hfx_snw(ji,jj) & 137 & + hfx_thd(ji,jj) + hfx_dyn(ji,jj) + hfx_res(ji,jj) & 138 & + hfx_sub(ji,jj) - SUM( qevap_ice(ji,jj,:) * a_i_b(ji,jj,:) ) + hfx_spr(ji,jj) 139 ENDIF 140 130 141 ! New qsr and qns used to compute the oceanic heat flux at the next time step 131 142 !---------------------------------------------------------------------------- … … 228 239 229 240 IF ( iom_use( 'vfxthin' ) ) THEN ! mass flux from ice growth in open water + thin ice (<20cm) => comparable to observations 241 ALLOCATE( z2d(jpi,jpj) ) 230 242 WHERE( hm_i(:,:) < 0.2 .AND. hm_i(:,:) > 0. ) ; z2d = wfx_bog 231 243 ELSEWHERE ; z2d = 0._wp 232 244 END WHERE 233 245 CALL iom_put( 'vfxthin', wfx_opw + z2d ) 246 DEALLOCATE( z2d ) 234 247 ENDIF 235 248 … … 278 291 IF( iom_use('hfxcndbot' ) ) CALL iom_put( 'hfxcndbot' , SUM( qcn_ice_bot * a_i_b, dim=3 ) ) ! Bottom conduction flux 279 292 IF( iom_use('hfxcndtop' ) ) CALL iom_put( 'hfxcndtop' , SUM( qcn_ice_top * a_i_b, dim=3 ) ) ! Surface conduction flux 280 !!IF( iom_use('hfxmelt' ) ) CALL iom_put( 'hfxmelt' , SUM( qml_ice * a_i_b, dim=3 ) ) ! Surface melt flux281 !!IF( iom_use('hfxldmelt' ) ) CALL iom_put( 'hfxldmelt' , fhld * at_i_b ) ! Heat in lead for ice melting282 !!IF( iom_use('hfxldgrow' ) ) CALL iom_put( 'hfxldgrow' , qlead * r1_Dt_ice ) ! Heat in lead for ice growth293 IF( iom_use('hfxmelt' ) ) CALL iom_put( 'hfxmelt' , SUM( qml_ice * a_i_b, dim=3 ) ) ! Surface melt flux 294 IF( iom_use('hfxldmelt' ) ) CALL iom_put( 'hfxldmelt' , fhld * at_i_b ) ! Heat in lead for ice melting 295 IF( iom_use('hfxldgrow' ) ) CALL iom_put( 'hfxldgrow' , qlead * r1_Dt_ice ) ! Heat in lead for ice growth 283 296 284 297 ! controls -
NEMO/branches/2021/ticket2632_r14588_theta_sbcblk/src/ICE/icevar.F90
r14072 r15548 271 271 zlay_i = REAL( nlay_i , wp ) ! number of layers 272 272 DO jl = 1, jpl 273 DO_3D( 1, 1, 1, 1, 1, nlay_i )273 DO_3D( nn_hls, nn_hls, nn_hls, nn_hls, 1, nlay_i ) 274 274 IF ( v_i(ji,jj,jl) > epsi20 ) THEN !--- icy area 275 275 ! … … 341 341 !!------------------------------------------------------------------- 342 342 INTEGER :: ji, jj, jk, jl ! dummy loop index 343 REAL(wp) :: z sal, z1_dS344 REAL(wp) :: z argtemp, zs0, zs345 REAL(wp), ALLOCATABLE, DIMENSION(:,: ,:) :: z_slope_s, zalpha ! case 2 only343 REAL(wp) :: z1_dS 344 REAL(wp) :: ztmp1, ztmp2, zs0, zs 345 REAL(wp), ALLOCATABLE, DIMENSION(:,:) :: z_slope_s, zalpha ! case 2 only 346 346 REAL(wp), PARAMETER :: zsi0 = 3.5_wp 347 347 REAL(wp), PARAMETER :: zsi1 = 4.5_wp … … 361 361 CASE( 2 ) ! time varying salinity with linear profile ! 362 362 ! !---------------------------------------------! 363 ! 364 ALLOCATE( z_slope_s(jpi,jpj,jpl) , zalpha(jpi,jpj,jpl) ) 363 z1_dS = 1._wp / ( zsi1 - zsi0 ) 364 ! 365 ALLOCATE( z_slope_s(jpi,jpj) , zalpha(jpi,jpj) ) 365 366 ! 366 367 DO jl = 1, jpl 367 DO jk = 1, nlay_i 368 sz_i(:,:,jk,jl) = s_i(:,:,jl) 369 END DO 370 END DO 371 ! ! Slope of the linear profile 372 WHERE( h_i(:,:,:) > epsi20 ) ; z_slope_s(:,:,:) = 2._wp * s_i(:,:,:) / h_i(:,:,:) 373 ELSEWHERE ; z_slope_s(:,:,:) = 0._wp 374 END WHERE 375 ! 376 z1_dS = 1._wp / ( zsi1 - zsi0 ) 377 DO jl = 1, jpl 378 DO_2D( 1, 1, 1, 1 ) 379 zalpha(ji,jj,jl) = MAX( 0._wp , MIN( ( zsi1 - s_i(ji,jj,jl) ) * z1_dS , 1._wp ) ) 368 369 DO_2D( nn_hls, nn_hls, nn_hls, nn_hls ) 370 ! ! Slope of the linear profile 371 IF( h_i(ji,jj,jl) > epsi20 ) THEN 372 z_slope_s(ji,jj) = 2._wp * s_i(ji,jj,jl) / h_i(ji,jj,jl) 373 ELSE 374 z_slope_s(ji,jj) = 0._wp 375 ENDIF 376 ! 377 zalpha(ji,jj) = MAX( 0._wp , MIN( ( zsi1 - s_i(ji,jj,jl) ) * z1_dS , 1._wp ) ) 380 378 ! ! 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._wp379 IF( 2._wp * s_i(ji,jj,jl) >= sss_m(ji,jj) ) zalpha(ji,jj) = 0._wp 382 380 END_2D 383 END DO 384 ! 385 ! Computation of the profile 386 DO jl = 1, jpl 387 DO_3D( 1, 1, 1, 1, 1, nlay_i ) 381 ! 382 ! Computation of the profile 383 DO_3D( nn_hls, nn_hls, nn_hls, nn_hls, 1, nlay_i ) 388 384 ! ! linear profile with 0 surface value 389 zs0 = z_slope_s(ji,jj ,jl) * ( REAL(jk,wp) - 0.5_wp ) * h_i(ji,jj,jl) * r1_nlay_i390 zs = zalpha(ji,jj ,jl) * zs0 + ( 1._wp - zalpha(ji,jj,jl) ) * s_i(ji,jj,jl) ! weighting the profile385 zs0 = z_slope_s(ji,jj) * ( REAL(jk,wp) - 0.5_wp ) * h_i(ji,jj,jl) * r1_nlay_i 386 zs = zalpha(ji,jj) * zs0 + ( 1._wp - zalpha(ji,jj) ) * s_i(ji,jj,jl) ! weighting the profile 391 387 sz_i(ji,jj,jk,jl) = MIN( rn_simax, MAX( zs, rn_simin ) ) 392 388 END_3D … … 409 405 DO jl = 1, jpl 410 406 DO jk = 1, nlay_i 411 zargtemp = ( REAL(jk,wp) - 0.5_wp ) * r1_nlay_i 412 sz_i(:,:,jk,jl) = 1.6_wp * ( 1._wp - COS( rpi * zargtemp**(0.407_wp/(0.573_wp+zargtemp)) ) ) 407 ztmp1 = ( REAL(jk,wp) - 0.5_wp ) * r1_nlay_i 408 ztmp2 = 1.6_wp * ( 1._wp - COS( rpi * ztmp1**(0.407_wp/(0.573_wp+ztmp1)) ) ) 409 DO_2D( nn_hls, nn_hls, nn_hls, nn_hls ) 410 sz_i(ji,jj,jk,jl) = ztmp2 411 END_2D 413 412 END DO 414 413 END DO … … 427 426 !!------------------------------------------------------------------- 428 427 INTEGER :: ji, jk ! dummy loop indices 429 REAL(wp) :: z argtemp, zsal, z1_dS ! local scalars428 REAL(wp) :: ztmp1, ztmp2, z1_dS ! local scalars 430 429 REAL(wp) :: zs, zs0 ! - - 431 430 ! … … 445 444 CASE( 2 ) ! time varying salinity with linear profile ! 446 445 ! !---------------------------------------------! 446 z1_dS = 1._wp / ( zsi1 - zsi0 ) 447 447 ! 448 448 ALLOCATE( z_slope_s(jpij), zalpha(jpij) ) 449 449 ! 450 ! ! Slope of the linear profile451 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 ELSEWHERE ; z_slope_s(1:npti) = 0._wp453 END WHERE454 455 z1_dS = 1._wp / ( zsi1 - zsi0 )456 450 DO ji = 1, npti 451 ! ! Slope of the linear profile 452 IF( h_i_1d(ji) > epsi20 ) THEN 453 z_slope_s(ji) = 2._wp * s_i_1d(ji) / h_i_1d(ji) 454 ELSE 455 z_slope_s(ji) = 0._wp 456 ENDIF 457 ! 457 458 zalpha(ji) = MAX( 0._wp , MIN( ( zsi1 - s_i_1d(ji) ) * z1_dS , 1._wp ) ) 458 459 ! ! force a constant profile when SSS too low (Baltic Sea) 459 460 IF( 2._wp * s_i_1d(ji) >= sss_1d(ji) ) zalpha(ji) = 0._wp 461 ! 460 462 END DO 461 463 ! … … 480 482 !!gm cf remark in ice_var_salprof routine, CASE( 3 ) 481 483 DO jk = 1, nlay_i 482 z argtemp= ( REAL(jk,wp) - 0.5_wp ) * r1_nlay_i483 z sal = 1.6_wp * ( 1._wp - COS( rpi * zargtemp**( 0.407_wp / ( 0.573_wp + zargtemp) ) ) )484 ztmp1 = ( REAL(jk,wp) - 0.5_wp ) * r1_nlay_i 485 ztmp2 = 1.6_wp * ( 1._wp - COS( rpi * ztmp1**( 0.407_wp / ( 0.573_wp + ztmp1 ) ) ) ) 484 486 DO ji = 1, npti 485 sz_i_1d(ji,jk) = z sal487 sz_i_1d(ji,jk) = ztmp2 486 488 END DO 487 489 END DO … … 515 517 ! Zap ice energy and use ocean heat to melt ice 516 518 !----------------------------------------------------------------- 517 DO_3D( 1, 1, 1, 1, 1, nlay_i )519 DO_3D( nn_hls, nn_hls, nn_hls, nn_hls, 1, nlay_i ) 518 520 ! update exchanges with ocean 519 521 hfx_res(ji,jj) = hfx_res(ji,jj) - (1._wp - zswitch(ji,jj) ) * e_i(ji,jj,jk,jl) * r1_Dt_ice ! W.m-2 <0 … … 522 524 END_3D 523 525 ! 524 DO_3D( 1, 1, 1, 1, 1, nlay_s )526 DO_3D( nn_hls, nn_hls, nn_hls, nn_hls, 1, nlay_s ) 525 527 ! update exchanges with ocean 526 528 hfx_res(ji,jj) = hfx_res(ji,jj) - (1._wp - zswitch(ji,jj) ) * e_s(ji,jj,jk,jl) * r1_Dt_ice ! W.m-2 <0 … … 532 534 ! zap ice and snow volume, add water and salt to ocean 533 535 !----------------------------------------------------------------- 534 DO_2D( 1, 1, 1, 1)536 DO_2D( nn_hls, nn_hls, nn_hls, nn_hls ) 535 537 ! update exchanges with ocean 536 538 sfx_res(ji,jj) = sfx_res(ji,jj) + ( 1._wp - zswitch(ji,jj) ) * sv_i(ji,jj,jl) * rhoi * r1_Dt_ice … … 608 610 ! zap ice energy and send it to the ocean 609 611 !---------------------------------------- 610 DO_3D( 1, 1, 1, 1, 1, nlay_i )612 DO_3D( nn_hls, nn_hls, nn_hls, nn_hls, 1, nlay_i ) 611 613 IF( pe_i(ji,jj,jk,jl) < 0._wp .OR. pa_i(ji,jj,jl) <= 0._wp ) THEN 612 614 hfx_res(ji,jj) = hfx_res(ji,jj) - pe_i(ji,jj,jk,jl) * z1_dt ! W.m-2 >0 … … 615 617 END_3D 616 618 ! 617 DO_3D( 1, 1, 1, 1, 1, nlay_s )619 DO_3D( nn_hls, nn_hls, nn_hls, nn_hls, 1, nlay_s ) 618 620 IF( pe_s(ji,jj,jk,jl) < 0._wp .OR. pa_i(ji,jj,jl) <= 0._wp ) THEN 619 621 hfx_res(ji,jj) = hfx_res(ji,jj) - pe_s(ji,jj,jk,jl) * z1_dt ! W.m-2 <0 … … 625 627 ! zap ice and snow volume, add water and salt to ocean 626 628 !----------------------------------------------------- 627 DO_2D( 1, 1, 1, 1)629 DO_2D( nn_hls, nn_hls, nn_hls, nn_hls ) 628 630 IF( pv_i(ji,jj,jl) < 0._wp .OR. pa_i(ji,jj,jl) <= 0._wp ) THEN 629 631 wfx_res(ji,jj) = wfx_res(ji,jj) + pv_i (ji,jj,jl) * rhoi * z1_dt … … 712 714 bv_i (:,:,:) = 0._wp 713 715 DO jl = 1, jpl 714 DO jk = 1, nlay_i715 WHERE( t_i(:,:,jk,jl) < rt0 - epsi10 )716 bv_i( :,:,jl) = bv_i(:,:,jl) - rTmlt * sz_i(:,:,jk,jl) * r1_nlay_i / ( t_i(:,:,jk,jl) - rt0 )717 END WHERE718 END DO716 DO_3D( nn_hls, nn_hls, nn_hls, nn_hls, 1, nlay_i ) 717 IF( t_i(ji,jj,jk,jl) < rt0 - epsi10 ) THEN 718 bv_i(ji,jj,jl) = bv_i(ji,jj,jl) - rTmlt * sz_i(ji,jj,jk,jl) * r1_nlay_i / ( t_i(ji,jj,jk,jl) - rt0 ) 719 ENDIF 720 END_3D 719 721 END DO 720 722 WHERE( vt_i(:,:) > epsi20 ) ; bvm_i(:,:) = SUM( bv_i(:,:,:) * v_i(:,:,:) , dim=3 ) / vt_i(:,:) … … 779 781 ! temporary 780 782 REAL(wp) :: zintn, zintb ! time interpolation weights [] 781 REAL(wp), DIMENSION(jpi,jpj) :: zsnwiceload ! snow and ice load [m]782 783 ! 783 784 ! compute ice load used to define the equivalent ssh in lead … … 792 793 zintb = REAL( nn_fsbc + 1 ) / REAL( nn_fsbc ) * 0.5_wp 793 794 ! 794 zsnwiceload(:,:) = ( zintn * psnwice_mass(:,:) + zintb * psnwice_mass_b(:,:) ) * r1_rho0 795 ! compute equivalent ssh in lead 796 ice_var_sshdyn(:,:) = pssh(:,:) + ( zintn * psnwice_mass(:,:) + zintb * psnwice_mass_b(:,:) ) * r1_rho0 795 797 ! 796 798 ELSE 797 zsnwiceload(:,:) = 0.0_wp 799 ! compute equivalent ssh in lead 800 ice_var_sshdyn(:,:) = pssh(:,:) 798 801 ENDIF 799 ! compute equivalent ssh in lead800 ice_var_sshdyn(:,:) = pssh(:,:) + zsnwiceload(:,:)801 802 ! 802 803 END FUNCTION ice_var_sshdyn -
NEMO/branches/2021/ticket2632_r14588_theta_sbcblk/src/ICE/icewri.F90
r14072 r15548 20 20 USE ice ! sea-ice: variables 21 21 USE icevar ! sea-ice: operations 22 USE icealb , ONLY : rn_alb_oce 22 23 ! 23 24 USE ioipsl ! … … 53 54 REAL(wp) :: z2da, z2db, zrho1, zrho2 54 55 REAL(wp) :: zmiss_val ! missing value retrieved from xios 55 REAL(wp), DIMENSION(jpi,jpj) :: z2d , zfast! 2D workspace56 REAL(wp), DIMENSION(jpi,jpj) :: z2d ! 2D workspace 56 57 REAL(wp), DIMENSION(jpi,jpj) :: zmsk00, zmsk05, zmsk15, zmsksn ! O%, 5% and 15% concentration mask and snow mask 57 58 REAL(wp), DIMENSION(jpi,jpj,jpl) :: zmsk00l, zmsksnl ! cat masks 59 REAL(wp), DIMENSION(:,:), ALLOCATABLE :: zfast, zalb, zmskalb ! 2D workspace 58 60 ! 59 61 ! Global ice diagnostics (SIMIP) … … 71 73 72 74 ! tresholds for outputs 73 DO_2D( 1, 1, 1, 1)75 DO_2D( nn_hls, nn_hls, nn_hls, nn_hls ) 74 76 zmsk00(ji,jj) = MAX( 0._wp , SIGN( 1._wp , at_i(ji,jj) - epsi06 ) ) ! 1 if ice , 0 if no ice 75 77 zmsk05(ji,jj) = MAX( 0._wp , SIGN( 1._wp , at_i(ji,jj) - 0.05_wp ) ) ! 1 if 5% ice , 0 if less … … 78 80 END_2D 79 81 DO jl = 1, jpl 80 DO_2D( 1, 1, 1, 1)82 DO_2D( nn_hls, nn_hls, nn_hls, nn_hls ) 81 83 zmsk00l(ji,jj,jl) = MAX( 0._wp , SIGN( 1._wp , a_i(ji,jj,jl) - epsi06 ) ) 82 84 zmsksnl(ji,jj,jl) = MAX( 0._wp , SIGN( 1._wp , v_s(ji,jj,jl) - epsi06 ) ) … … 131 133 IF( iom_use('vice' ) ) CALL iom_put( 'vice' , v_ice ) ! ice velocity v 132 134 ! 133 IF( iom_use('icevel') .OR. iom_use('fasticepres') ) THEN ! module of ice velocity 135 IF( iom_use('icevel') .OR. iom_use('fasticepres') ) THEN ! module of ice velocity & fast ice 136 ALLOCATE( zfast(jpi,jpj) ) 134 137 DO_2D( 0, 0, 0, 0 ) 135 138 z2da = u_ice(ji,jj) + u_ice(ji-1,jj) … … 144 147 END WHERE 145 148 CALL iom_put( 'fasticepres', zfast ) 146 ENDIF 147 149 DEALLOCATE( zfast ) 150 ENDIF 151 ! 152 IF( iom_use('icealb') .OR. iom_use('albedo') ) THEN ! ice albedo and surface albedo 153 ALLOCATE( zalb(jpi,jpj), zmskalb(jpi,jpj) ) 154 ! ice albedo 155 WHERE( at_i_b < 1.e-03 ) 156 zmskalb(:,:) = 0._wp 157 zalb (:,:) = rn_alb_oce 158 ELSEWHERE 159 zmskalb(:,:) = 1._wp 160 zalb (:,:) = SUM( alb_ice * a_i_b, dim=3 ) / at_i_b 161 END WHERE 162 CALL iom_put( 'icealb' , zalb * zmskalb + zmiss_val * ( 1._wp - zmskalb ) ) 163 ! ice+ocean albedo 164 zalb(:,:) = SUM( alb_ice * a_i_b, dim=3 ) + rn_alb_oce * ( 1._wp - at_i_b ) 165 CALL iom_put( 'albedo' , zalb ) 166 DEALLOCATE( zalb, zmskalb ) 167 ENDIF 168 ! 148 169 ! --- category-dependent fields --- ! 149 170 IF( iom_use('icemask_cat' ) ) CALL iom_put( 'icemask_cat' , zmsk00l ) ! ice mask 0%
Note: See TracChangeset
for help on using the changeset viewer.