Changeset 15440
- Timestamp:
- 2021-10-23T12:18:24+02:00 (2 years ago)
- Location:
- NEMO/branches/2021/dev_r14383_PISCES_NEWDEV_PISCO
- Files:
-
- 38 edited
Legend:
- Unmodified
- Added
- Removed
-
NEMO/branches/2021/dev_r14383_PISCES_NEWDEV_PISCO/cfgs/ORCA2_OFF_PISCES/EXPREF/namelist_cfg
r15127 r15440 325 325 sn_sal = 'dyna_grid_T' , 120. , 'vosaline' , .true. , .true. , 'yearly' , '' , '' , '' 326 326 sn_mld = 'dyna_grid_T' , 120. , 'somixhgt' , .true. , .true. , 'yearly' , '' , '' , '' 327 sn_emp = 'dyna_grid_T' , 120. , 'sowafl up' , .true. , .true. , 'yearly' , '' , '' , ''327 sn_emp = 'dyna_grid_T' , 120. , 'sowaflcd' , .true. , .true. , 'yearly' , '' , '' , '' 328 328 sn_fmf = 'dyna_grid_T' , 120. , 'iowaflup' , .true. , .true. , 'yearly' , '' , '' , '' 329 329 sn_ice = 'dyna_grid_T' , 120. , 'soicecov' , .true. , .true. , 'yearly' , '' , '' , '' -
NEMO/branches/2021/dev_r14383_PISCES_NEWDEV_PISCO/src/ICE/ice.F90
r15349 r15440 196 196 ! ! = 0 Grenfell and Maykut 1977 (depends on cloudiness and is 0 when there is snow) 197 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 198 212 ! 199 213 ! !!** ice-vertical diffusion namelist (namthd_zdf) ** -
NEMO/branches/2021/dev_r14383_PISCES_NEWDEV_PISCO/src/ICE/icectl.F90
r15127 r15440 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 ! … … 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( nn_hls, nn_hls, nn_hls, nn_hls ) 778 zdiag_mass2D(ji,jj) = wfx_ice(ji,jj) + wfx_snw(ji,jj) + wfx_spr(ji,jj) + wfx_sub(ji,jj) + wfx_pnd(ji,jj) & 779 & + diag_vice(ji,jj) + diag_vsnw(ji,jj) + diag_vpnd(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 + wfx_pnd & 792 & + diag_vice + diag_vsnw + diag_vpnd - 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/dev_r14383_PISCES_NEWDEV_PISCO/src/ICE/icedyn_rhg_evp.F90
r15349 r15440 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 … … 181 179 REAL(wp), ALLOCATABLE, DIMENSION(:,:) :: zdiag_yatrp ! Y-component of area transport (m2/s) 182 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 183 182 LOGICAL :: ll_advups = .FALSE. 184 183 REAL(wp) :: zdt_ups … … 704 703 ENDIF 705 704 ! 706 CALL rhg_upstream( zdt_ups, u_ice, v_ice, za_i_ups ) ! upstream advection: a_i707 CALL rhg_upstream( zdt_ups, u_ice, v_ice, zv_i_ups ) ! upstream advection: v_i705 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 708 707 ! 709 708 DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 ) ! strength … … 967 966 REAL(wp) :: zresm ! local real 968 967 CHARACTER(len=20) :: clname 968 LOGICAL :: ll_maxcvg 969 REAL(wp), DIMENSION(jpi,jpj,2) :: zres 970 REAL(wp), DIMENSION(2) :: ztmp 969 971 !!---------------------------------------------------------------------- 970 972 ll_maxcvg = .FALSE. 973 ! 971 974 ! create file 972 975 IF( kt == nit000 .AND. kiter == 1 ) THEN … … 983 986 istatus = NF90_CREATE( TRIM(clname), NF90_CLOBBER, ncvgid ) 984 987 istatus = NF90_DEF_DIM( ncvgid, 'time' , NF90_UNLIMITED, idtime ) 985 istatus = NF90_DEF_VAR( ncvgid, 'uice_cvg', NF90_DOUBLE 988 istatus = NF90_DEF_VAR( ncvgid, 'uice_cvg', NF90_DOUBLE , (/ idtime /), nvarid ) 986 989 istatus = NF90_ENDDEF(ncvgid) 987 990 ENDIF … … 997 1000 ELSE 998 1001 zresm = 0._wp 999 DO_2D( 0, 0, 0, 0 ) 1000 zresm = MAX( zresm, MAX( ABS( pu(ji,jj) - pub(ji,jj) ) * umask(ji,jj,1), & 1001 & ABS( pv(ji,jj) - pvb(ji,jj) ) * vmask(ji,jj,1) ) * pmsk15(ji,jj) ) 1002 END_2D 1003 CALL mpp_max( 'icedyn_rhg_evp', zresm ) ! max over the global domain 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 1004 1017 ENDIF 1005 1018 … … 1069 1082 END SUBROUTINE rhg_evp_rst 1070 1083 1071 SUBROUTINE rhg_upstream( pdt, pu, pv, pt )1084 SUBROUTINE rhg_upstream( jter, pdt, pu, pv, pt ) 1072 1085 !!--------------------------------------------------------------------- 1073 1086 !! *** ROUTINE rhg_upstream *** … … 1075 1088 !! ** Purpose : compute the upstream fluxes and upstream guess of tracer 1076 1089 !!---------------------------------------------------------------------- 1090 INTEGER , INTENT(in ) :: jter 1077 1091 REAL(wp) , INTENT(in ) :: pdt ! tracer time-step 1078 1092 REAL(wp), DIMENSION(:,: ) , INTENT(in ) :: pu, pv ! 2 ice velocity components … … 1081 1095 INTEGER :: ji, jj, jl ! dummy loop indices 1082 1096 REAL(wp) :: ztra ! local scalar 1083 REAL(wp), DIMENSION(jpi,jpj) :: zfu_ups, zfv_ups ! upstream fluxes 1097 LOGICAL :: ll_upsxy = .TRUE. 1098 REAL(wp), DIMENSION(jpi,jpj) :: zfu_ups, zfv_ups, zpt ! upstream fluxes and tracer guess 1084 1099 !!---------------------------------------------------------------------- 1085 1100 DO jl = 1, jpl 1086 DO_2D( nn_hls, nn_hls-1, nn_hls, nn_hls-1 ) 1087 zfu_ups(ji,jj) = MAX( pu(ji,jj)*e2u(ji,jj), 0._wp ) * pt(ji ,jj ,jl) + & 1088 & MIN( pu(ji,jj)*e2u(ji,jj), 0._wp ) * pt(ji+1,jj ,jl) 1089 zfv_ups(ji,jj) = MAX( pv(ji,jj)*e1v(ji,jj), 0._wp ) * pt(ji ,jj ,jl) + & 1090 & MIN( pv(ji,jj)*e1v(ji,jj), 0._wp ) * pt(ji ,jj+1,jl) 1091 END_2D 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 ! 1092 1148 DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 ) 1093 ztra = - ( zfu_ups(ji,jj) - zfu_ups(ji-1,jj) + zfv_ups(ji,jj) - zfv_ups(ji,jj-1) ) 1094 ! 1095 pt(ji,jj,jl) = ( pt(ji,jj,jl) + ztra * pdt * r1_e1e2t(ji,jj) ) * tmask(ji,jj,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) 1096 1151 END_2D 1097 1152 END DO -
NEMO/branches/2021/dev_r14383_PISCES_NEWDEV_PISCO/src/ICE/icesbc.F90
r15127 r15440 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... … … 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/dev_r14383_PISCES_NEWDEV_PISCO/src/ICE/icethd.F90
r15349 r15440 20 20 USE sbc_oce , ONLY : sss_m, sst_m, e3t_m, utau, vtau, ssu_m, ssv_m, frq_m, sprecip, ln_cpl 21 21 USE sbc_ice , ONLY : qsr_oce, qns_oce, qemp_oce, qsr_ice, qns_ice, dqns_ice, evap_ice, qprec_ice, qevap_ice, & 22 & qml_ice, qcn_ice, qtr_ice_top , utau_ice, vtau_ice22 & qml_ice, qcn_ice, qtr_ice_top 23 23 USE ice1D ! sea-ice: thermodynamics variables 24 24 USE icethd_zdf ! sea-ice: vertical heat diffusion … … 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 ! for collection thickness100 INTEGER :: iter ! - -101 REAL(wp) :: zvfrx, zvgx, ztaux, zf ! - -102 REAL(wp) :: ztenagm, zvfry, zvgy, ztauy, zvrel2, zfp, ztwogp ! - -103 REAL(wp), PARAMETER :: zcai = 1.4e-3_wp ! ice-air drag (clem: should be dependent on coupling/forcing used)104 REAL(wp), PARAMETER :: zhicrit = 0.04_wp ! frazil ice thickness105 REAL(wp), PARAMETER :: zsqcd = 1.0_wp / SQRT( 1.3_wp * zcai ) ! 1/SQRT(airdensity*drag)106 REAL(wp), PARAMETER :: zgamafr = 0.03_wp107 87 !!------------------------------------------------------------------- 108 88 ! controls … … 122 102 ztice_cvgerr = 0._wp ; ztice_cvgstp = 0._wp 123 103 ENDIF 124 125 !---------------------------------------------! 126 ! computation of friction velocity at T points 127 !---------------------------------------------! 128 IF( ln_icedyn ) THEN 129 zu_io(:,:) = u_ice(:,:) - ssu_m(:,:) 130 zv_io(:,:) = v_ice(:,:) - ssv_m(:,:) 131 DO_2D( 0, 0, 0, 0 ) 132 zfric(ji,jj) = rn_cio * ( 0.5_wp * & 133 & ( zu_io(ji,jj) * zu_io(ji,jj) + zu_io(ji-1,jj) * zu_io(ji-1,jj) & 134 & + zv_io(ji,jj) * zv_io(ji,jj) + zv_io(ji,jj-1) * zv_io(ji,jj-1) ) ) * tmask(ji,jj,1) 135 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) ) + & 136 & ( v_ice(ji,jj-1) + v_ice(ji,jj) ) * ( v_ice(ji,jj-1) + v_ice(ji,jj) ) ) 137 END_2D 138 ELSE ! if no ice dynamics => transfer directly the atmospheric stress to the ocean 139 DO_2D( 0, 0, 0, 0 ) 140 zfric(ji,jj) = r1_rho0 * SQRT( 0.5_wp * & 141 & ( utau(ji,jj) * utau(ji,jj) + utau(ji-1,jj) * utau(ji-1,jj) & 142 & + vtau(ji,jj) * vtau(ji,jj) + vtau(ji,jj-1) * vtau(ji,jj-1) ) ) * tmask(ji,jj,1) 143 zvel(ji,jj) = 0._wp 144 END_2D 145 ENDIF 146 CALL lbc_lnk( 'icethd', zfric, 'T', 1.0_wp, zvel, 'T', 1.0_wp ) 147 ! 148 !--------------------------------------------------------------------! 149 ! Partial computation of forcing for the thermodynamic sea ice model 150 !--------------------------------------------------------------------! 151 DO_2D( nn_hls, nn_hls, nn_hls, nn_hls ) ! needed for qlead 152 rswitch = tmask(ji,jj,1) * MAX( 0._wp , SIGN( 1._wp , at_i(ji,jj) - epsi10 ) ) ! 0 if no ice 153 ! 154 ! --- Energy received in the lead from atm-oce exchanges, zqld is defined everywhere (J.m-2) --- ! 155 zqld = tmask(ji,jj,1) * rDt_ice * & 156 & ( ( 1._wp - at_i_b(ji,jj) ) * qsr_oce(ji,jj) * frq_m(ji,jj) + & 157 & ( 1._wp - at_i_b(ji,jj) ) * qns_oce(ji,jj) + qemp_oce(ji,jj) ) 158 159 ! --- Energy needed to bring ocean surface layer until its freezing, zqfr is defined everywhere (J.m-2) --- ! 160 ! (mostly<0 but >0 if supercooling) 161 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) 162 zqfr_neg = MIN( zqfr , 0._wp ) ! only < 0 163 zqfr_pos = MAX( zqfr , 0._wp ) ! only > 0 164 165 ! --- Sensible ocean-to-ice heat flux (W/m2) --- ! 166 ! (mostly>0 but <0 if supercooling) 167 zfric_u = MAX( SQRT( zfric(ji,jj) ), zfric_umin ) 168 qsb_ice_bot(ji,jj) = rswitch * rho0 * rcp * zch * zfric_u * ( ( sst_m(ji,jj) + rt0 ) - t_bo(ji,jj) ) 169 170 ! upper bound for qsb_ice_bot: the heat retrieved from the ocean must be smaller than the heat necessary to reach 171 ! the freezing point, so that we do not have SST < T_freeze 172 ! This implies: qsb_ice_bot(ji,jj) * at_i(ji,jj) * rtdice <= - zqfr_neg 173 ! The following formulation is ok for both normal conditions and supercooling 174 qsb_ice_bot(ji,jj) = rswitch * MIN( qsb_ice_bot(ji,jj), - zqfr_neg * r1_Dt_ice / MAX( at_i(ji,jj), epsi10 ) ) 175 176 ! If conditions are always supercooled (such as at the mouth of ice-shelves), then ice grows continuously 177 ! ==> stop ice formation by artificially setting up the turbulent fluxes to 0 when volume > 20m (arbitrary) 178 IF( ( t_bo(ji,jj) - ( sst_m(ji,jj) + rt0 ) ) > 0._wp .AND. vt_i(ji,jj) >= 20._wp ) THEN 179 zqfr = 0._wp 180 zqfr_pos = 0._wp 181 qsb_ice_bot(ji,jj) = 0._wp 182 ENDIF 183 ! 184 ! --- Energy Budget of the leads (qlead, J.m-2) --- ! 185 ! qlead is the energy received from the atm. in the leads. 186 ! If warming (zqld >= 0), then the energy in the leads is used to melt ice (bottom melting) => fhld (W/m2) 187 ! If cooling (zqld < 0), then the energy in the leads is used to grow ice in open water => qlead (J.m-2) 188 IF( zqld >= 0._wp .AND. at_i(ji,jj) > 0._wp ) THEN 189 ! upper bound for fhld: fhld should be equal to zqld 190 ! but we have to make sure that this heat will not make the sst drop below the freezing point 191 ! so the max heat that can be pulled out of the ocean is zqld - qsb - zqfr_pos 192 ! The following formulation is ok for both normal conditions and supercooling 193 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 194 & - qsb_ice_bot(ji,jj) ) 195 qlead(ji,jj) = 0._wp 196 ELSE 197 fhld (ji,jj) = 0._wp 198 ! upper bound for qlead: qlead should be equal to zqld 199 ! but before using this heat for ice formation, we suppose that the ocean cools down till the freezing point. 200 ! The energy for this cooling down is zqfr. Also some heat will be removed from the ocean from turbulent fluxes (qsb) 201 ! and freezing point is reached if zqfr = zqld - qsb*a/dt 202 ! so the max heat that can be pulled out of the ocean is zqld - qsb - zqfr 203 ! The following formulation is ok for both normal conditions and supercooling 204 qlead(ji,jj) = MIN( 0._wp , zqld - ( qsb_ice_bot(ji,jj) * at_i(ji,jj) * rDt_ice ) - zqfr ) 205 ENDIF 206 ! 207 ! If ice is landfast and ice concentration reaches its max 208 ! => stop ice formation in open water 209 IF( zvel(ji,jj) <= 5.e-04_wp .AND. at_i(ji,jj) >= rn_amax_2d(ji,jj)-epsi06 ) qlead(ji,jj) = 0._wp 210 ! 211 ! If the grid cell is almost fully covered by ice (no leads) 212 ! => stop ice formation in open water 213 IF( at_i(ji,jj) >= (1._wp - epsi10) ) qlead(ji,jj) = 0._wp 214 ! 215 ! If ln_leadhfx is false 216 ! => do not use energy of the leads to melt sea-ice 217 IF( .NOT.ln_leadhfx ) fhld(ji,jj) = 0._wp 218 ! 219 END_2D 220 221 ! In case we bypass open-water ice formation 222 IF( .NOT. ln_icedO ) qlead(:,:) = 0._wp 223 ! In case we bypass growing/melting from top and bottom 224 IF( .NOT. ln_icedH ) THEN 225 qsb_ice_bot(:,:) = 0._wp 226 fhld (:,:) = 0._wp 227 ENDIF 228 229 230 !---------------------------------------------------------! 231 ! Collection thickness of ice formed in leads and polynyas 232 !---------------------------------------------------------! 233 ! ht_i_new is the thickness of new ice formed in open water 234 ! ht_i_new can be either prescribed (ln_frazil=F) or computed (ln_frazil=T) 235 ! Frazil ice forms in open water, is transported by wind, accumulates at the edge of the consolidated ice edge 236 ! where it forms aggregates of a specific thickness called collection thickness. 237 ! 238 fraz_frac(:,:) = 0._wp 239 ! 240 ! Default new ice thickness 241 WHERE( qlead(:,:) < 0._wp ) ! cooling 242 ht_i_new(:,:) = rn_hinew 243 ELSEWHERE 244 ht_i_new(:,:) = 0._wp 245 END WHERE 246 247 IF( ln_frazil ) THEN 248 ztwogp = 2._wp * rho0 / ( grav * 0.3_wp * ( rho0 - rhoi ) ) ! reduced grav 249 ! 250 DO_2D( 0, 0, 0, 0 ) 251 IF ( qlead(ji,jj) < 0._wp ) THEN ! cooling 252 ! -- Wind stress -- ! 253 ztaux = ( utau_ice(ji-1,jj ) * umask(ji-1,jj ,1) & 254 & + utau_ice(ji ,jj ) * umask(ji ,jj ,1) ) * 0.5_wp 255 ztauy = ( vtau_ice(ji ,jj-1) * vmask(ji ,jj-1,1) & 256 & + vtau_ice(ji ,jj ) * vmask(ji ,jj ,1) ) * 0.5_wp 257 ! Square root of wind stress 258 ztenagm = SQRT( SQRT( ztaux * ztaux + ztauy * ztauy ) ) 259 260 ! -- Frazil ice velocity -- ! 261 rswitch = MAX( 0._wp, SIGN( 1._wp , ztenagm - epsi10 ) ) 262 zvfrx = rswitch * zgamafr * zsqcd * ztaux / MAX( ztenagm, epsi10 ) 263 zvfry = rswitch * zgamafr * zsqcd * ztauy / MAX( ztenagm, epsi10 ) 264 265 ! -- Pack ice velocity -- ! 266 zvgx = ( u_ice(ji-1,jj ) * umask(ji-1,jj ,1) + u_ice(ji,jj) * umask(ji,jj,1) ) * 0.5_wp 267 zvgy = ( v_ice(ji ,jj-1) * vmask(ji ,jj-1,1) + v_ice(ji,jj) * vmask(ji,jj,1) ) * 0.5_wp 268 269 ! -- Relative frazil/pack ice velocity -- ! 270 rswitch = MAX( 0._wp, SIGN( 1._wp , at_i(ji,jj) - epsi10 ) ) 271 zvrel2 = MAX( ( zvfrx - zvgx ) * ( zvfrx - zvgx ) & 272 & + ( zvfry - zvgy ) * ( zvfry - zvgy ) , 0.15_wp * 0.15_wp ) * rswitch 273 274 !!clem 275 fraz_frac(ji,jj) = rswitch * ( TANH( rn_Cfraz * ( SQRT(zvrel2) - rn_vfraz ) ) + 1._wp ) * 0.5_wp * rn_maxfraz 276 !!clem 277 278 ! -- new ice thickness (iterative loop) -- ! 279 ht_i_new(ji,jj) = zhicrit + ( zhicrit + 0.1_wp ) & 280 & / ( ( zhicrit + 0.1_wp ) * ( zhicrit + 0.1_wp ) - zhicrit * zhicrit ) * ztwogp * zvrel2 281 iter = 1 282 DO WHILE ( iter < 20 ) 283 zf = ( ht_i_new(ji,jj) - zhicrit ) * ( ht_i_new(ji,jj) * ht_i_new(ji,jj) - zhicrit * zhicrit ) - & 284 & ht_i_new(ji,jj) * zhicrit * ztwogp * zvrel2 285 zfp = ( ht_i_new(ji,jj) - zhicrit ) * ( 3.0_wp * ht_i_new(ji,jj) + zhicrit ) - zhicrit * ztwogp * zvrel2 286 287 ht_i_new(ji,jj) = ht_i_new(ji,jj) - zf / MAX( zfp, epsi20 ) 288 iter = iter + 1 289 END DO 290 ! 291 ! bound ht_i_new (though I don't see why it should be necessary) 292 ht_i_new(ji,jj) = MAX( 0.01_wp, MIN( ht_i_new(ji,jj), hi_max(jpl) ) ) 293 ! 294 ELSE 295 ht_i_new(ji,jj) = 0._wp 296 ENDIF 297 ! 298 END_2D 299 ! 300 CALL lbc_lnk( 'icethd', fraz_frac, 'T', 1.0_wp, ht_i_new, 'T', 1.0_wp ) 301 302 ENDIF 303 104 ! 105 CALL ice_thd_frazil !--- frazil ice: collection thickness (ht_i_new) & fraction of frazil (fraz_frac) 106 ! 304 107 !-------------------------------------------------------------------------------------------! 305 108 ! Thermodynamic computation (only on grid points covered by ice) => loop over ice categories … … 369 172 ENDIF 370 173 END_2D 371 CALL lbc_lnk( 'ice cor', u_ice, 'U', -1.0_wp, v_ice, 'V', -1.0_wp )174 CALL lbc_lnk( 'icethd', u_ice, 'U', -1.0_wp, v_ice, 'V', -1.0_wp ) 372 175 ! 373 176 ! convergence tests … … 447 250 ! 448 251 END SUBROUTINE ice_thd_mono 449 450 252 451 253 SUBROUTINE ice_thd_1d2d( kl, kn ) -
NEMO/branches/2021/dev_r14383_PISCES_NEWDEV_PISCO/src/ICE/icethd_da.F90
r12489 r15440 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/dev_r14383_PISCES_NEWDEV_PISCO/src/ICE/icethd_do.F90
r15349 r15440 17 17 USE phycst ! physical constants 18 18 USE sbc_oce , ONLY : sss_m 19 USE sbc_ice , ONLY : utau_ice, vtau_ice 19 20 USE ice1D ! sea-ice: thermodynamics variables 20 21 USE ice ! sea-ice: variables … … 34 35 35 36 PUBLIC ice_thd_do ! called by ice_thd 37 PUBLIC ice_thd_frazil ! called by ice_thd 36 38 PUBLIC ice_thd_do_init ! called by ice_stp 37 38 ! !!** namelist (namthd_do) **39 REAL(wp), PUBLIC :: rn_hinew ! thickness for new ice formation (m)40 LOGICAL , PUBLIC :: ln_frazil ! use of frazil ice collection as function of wind (T) or not (F)41 REAL(wp), PUBLIC :: rn_maxfraz ! maximum portion of frazil ice collecting at the ice bottom42 REAL(wp), PUBLIC :: rn_vfraz ! threshold drift speed for collection of bottom frazil ice43 REAL(wp), PUBLIC :: rn_Cfraz ! squeezing coefficient for collection of bottom frazil ice44 39 45 40 !! * Substitutions … … 337 332 338 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 339 424 SUBROUTINE ice_thd_do_init 340 425 !!----------------------------------------------------------------------- -
NEMO/branches/2021/dev_r14383_PISCES_NEWDEV_PISCO/src/ICE/iceupdate.F90
r15127 r15440 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') … … 239 239 240 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) ) 241 242 WHERE( hm_i(:,:) < 0.2 .AND. hm_i(:,:) > 0. ) ; z2d = wfx_bog 242 243 ELSEWHERE ; z2d = 0._wp 243 244 END WHERE 244 245 CALL iom_put( 'vfxthin', wfx_opw + z2d ) 246 DEALLOCATE( z2d ) 245 247 ENDIF 246 248 -
NEMO/branches/2021/dev_r14383_PISCES_NEWDEV_PISCO/src/ICE/icevar.F90
r15127 r15440 343 343 REAL(wp) :: z1_dS 344 344 REAL(wp) :: ztmp1, ztmp2, zs0, zs 345 REAL(wp), ALLOCATABLE, DIMENSION(:,: ,:) :: z_slope_s, zalpha ! case 2 only345 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 368 378 369 DO_2D( nn_hls, nn_hls, nn_hls, nn_hls ) 379 zalpha(ji,jj,jl) = MAX( 0._wp , MIN( ( zsi1 - s_i(ji,jj,jl) ) * z1_dS , 1._wp ) ) 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 381 ! 382 ! Computation of the profile 387 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 … … 448 444 CASE( 2 ) ! time varying salinity with linear profile ! 449 445 ! !---------------------------------------------! 446 z1_dS = 1._wp / ( zsi1 - zsi0 ) 450 447 ! 451 448 ALLOCATE( z_slope_s(jpij), zalpha(jpij) ) 452 449 ! 453 ! ! Slope of the linear profile454 WHERE( h_i_1d(1:npti) > epsi20 ) ; z_slope_s(1:npti) = 2._wp * s_i_1d(1:npti) / h_i_1d(1:npti)455 ELSEWHERE ; z_slope_s(1:npti) = 0._wp456 END WHERE457 458 z1_dS = 1._wp / ( zsi1 - zsi0 )459 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 ! 460 458 zalpha(ji) = MAX( 0._wp , MIN( ( zsi1 - s_i_1d(ji) ) * z1_dS , 1._wp ) ) 461 459 ! ! force a constant profile when SSS too low (Baltic Sea) 462 460 IF( 2._wp * s_i_1d(ji) >= sss_1d(ji) ) zalpha(ji) = 0._wp 461 ! 463 462 END DO 464 463 ! … … 715 714 bv_i (:,:,:) = 0._wp 716 715 DO jl = 1, jpl 717 DO jk = 1, nlay_i718 WHERE( t_i(:,:,jk,jl) < rt0 - epsi10 )719 bv_i( :,:,jl) = bv_i(:,:,jl) - rTmlt * sz_i(:,:,jk,jl) * r1_nlay_i / ( t_i(:,:,jk,jl) - rt0 )720 END WHERE721 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 722 721 END DO 723 722 WHERE( vt_i(:,:) > epsi20 ) ; bvm_i(:,:) = SUM( bv_i(:,:,:) * v_i(:,:,:) , dim=3 ) / vt_i(:,:) … … 782 781 ! temporary 783 782 REAL(wp) :: zintn, zintb ! time interpolation weights [] 784 REAL(wp), DIMENSION(jpi,jpj) :: zsnwiceload ! snow and ice load [m]785 783 ! 786 784 ! compute ice load used to define the equivalent ssh in lead … … 795 793 zintb = REAL( nn_fsbc + 1 ) / REAL( nn_fsbc ) * 0.5_wp 796 794 ! 797 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 798 797 ! 799 798 ELSE 800 zsnwiceload(:,:) = 0.0_wp 799 ! compute equivalent ssh in lead 800 ice_var_sshdyn(:,:) = pssh(:,:) 801 801 ENDIF 802 ! compute equivalent ssh in lead803 ice_var_sshdyn(:,:) = pssh(:,:) + zsnwiceload(:,:)804 802 ! 805 803 END FUNCTION ice_var_sshdyn -
NEMO/branches/2021/dev_r14383_PISCES_NEWDEV_PISCO/src/ICE/icewri.F90
r15127 r15440 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) … … 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% -
NEMO/branches/2021/dev_r14383_PISCES_NEWDEV_PISCO/src/NST/agrif_oce_interp.F90
r15127 r15440 1578 1578 DO jj = j1, j2 1579 1579 DO ji = i1, i2 1580 zh = 0._wp 1581 DO jk = 1, mbkt_parent(ji, jj)-1 1582 zh = zh + e3t0_parent(ji,jj,jk) 1583 END DO 1584 e3t0_parent(ji,jj,mbkt_parent(ji,jj)) = ht0_parent(ji, jj) - zh 1580 IF ( mbkt_parent(ji,jj) > 1 ) THEN 1581 zh = 0._wp 1582 DO jk = 1, mbkt_parent(ji, jj)-1 1583 zh = zh + e3t0_parent(ji,jj,jk) 1584 END DO 1585 e3t0_parent(ji,jj,mbkt_parent(ji,jj)) = ht0_parent(ji, jj) - zh 1586 ENDIF 1585 1587 END DO 1586 1588 END DO -
NEMO/branches/2021/dev_r14383_PISCES_NEWDEV_PISCO/src/NST/agrif_oce_sponge.F90
r15349 r15440 386 386 INTEGER :: iku, ikv 387 387 REAL(wp) :: ztsa, zabe1, zabe2, zbtr, zhtot 388 REAl(wp) :: zflag, zdmod, zdtot 388 389 REAL(wp), DIMENSION(i1-1:i2,j1-1:j2,jpk) :: ztu, ztv 389 390 REAL(wp), DIMENSION(i1:i2,j1:j2,jpk,n1:n2) ::tsbdiff … … 401 402 DO jj=j1,j2 402 403 DO ji=i1,i2 403 tabres(ji,jj,jk,jn) = ts(ji,jj,jk,jn,Kbb_a) 404 ! JC: masking is mandatory here: before tracer field seems 405 ! to hold non zero values where tmask=0 406 tabres(ji,jj,jk,jn) = ts(ji,jj,jk,jn,Kbb_a) * tmask(ji,jj,jk) 404 407 END DO 405 408 END DO … … 536 539 DO ji = i1,i2-1 537 540 zabe1 = rn_sponge_tra * r1_Dt * umask(ji,jj,jk) * e1e2u(ji,jj) * e3u(ji,jj,jk,Kmm_a) 538 ztu(ji,jj,jk) = zabe1 * fspu(ji,jj) * ( tsbdiff(ji+1,jj ,jk,jn) - tsbdiff(ji,jj,jk,jn) ) 541 zdtot = tsbdiff(ji+1,jj,jk,jn) - tsbdiff(ji,jj,jk,jn) 542 zdmod = ts(ji+1,jj,jk,jn,Kbb_a) - ts(ji,jj,jk,jn,Kbb_a) 543 zflag = 0.5_wp + SIGN(0.5_wp, zdtot*zdmod) 544 ztu(ji,jj,jk) = zabe1 * fspu(ji,jj) * ( zflag * zdtot + (1._wp - zflag) * zdmod ) 539 545 END DO 540 546 END DO … … 544 550 zabe2 = rn_sponge_tra * r1_Dt * vmask(ji,jj,jk) * e1e2v(ji,jj) * e3v(ji,jj,jk,Kmm_a) 545 551 ztv(ji,jj,jk) = zabe2 * fspv(ji,jj) * ( tsbdiff(ji ,jj+1,jk,jn) - tsbdiff(ji,jj,jk,jn) ) 552 zdtot = tsbdiff(ji,jj+1,jk,jn) - tsbdiff(ji,jj,jk,jn) 553 zdmod = ts(ji,jj+1,jk,jn,Kbb_a) - ts(ji,jj,jk,jn,Kbb_a) 554 zflag = 0.5_wp + SIGN(0.5_wp, zdtot*zdmod) 555 ztv(ji,jj,jk) = zabe2 * fspv(ji,jj) * ( zflag * zdtot + (1._wp - zflag) * zdmod ) 546 556 END DO 547 557 END DO … … 612 622 DO jj=j1,j2 613 623 DO ji=i1,i2 614 tabres(ji,jj,jk,m1) = uu(ji,jj,jk,Kbb_a) 624 tabres(ji,jj,jk,m1) = uu(ji,jj,jk,Kbb_a) * umask(ji,jj,jk) 615 625 END DO 616 626 END DO … … 797 807 DO jj=j1,j2 798 808 DO ji=i1,i2 799 tabres(ji,jj,jk,m1) = vv(ji,jj,jk,Kbb_a) 809 tabres(ji,jj,jk,m1) = vv(ji,jj,jk,Kbb_a) * vmask(ji,jj,jk) 800 810 END DO 801 811 END DO -
NEMO/branches/2021/dev_r14383_PISCES_NEWDEV_PISCO/src/NST/agrif_top_sponge.F90
r14170 r15440 90 90 DO jj=j1,j2 91 91 DO ji=i1,i2 92 tabres(ji,jj,jk,jn) = tr(ji,jj,jk,jn,Kbb_a) 92 tabres(ji,jj,jk,jn) = tr(ji,jj,jk,jn,Kbb_a) * tmask(ji,jj,jk) 93 93 END DO 94 94 END DO -
NEMO/branches/2021/dev_r14383_PISCES_NEWDEV_PISCO/src/OCE/ASM/asmbkg.F90
r12377 r15440 31 31 USE eosbn2 ! Equation of state (eos_bn2 routine) 32 32 USE zdfmxl ! Mixed layer depth 33 USE dom_oce , ONLY : ndastp33 USE dom_oce , ONLY : ndastp, l_istiled 34 34 USE in_out_manager ! I/O manager 35 35 USE iom ! I/O module … … 74 74 !!----------------------------------------------------------------------- 75 75 76 ! !-------------------------------------------77 IF( kt == nitbkg_r ) THEN ! Write out background at time step nitbkg_r78 ! !-----------------------------------========79 !80 WRITE(cl_asmbkg, FMT='(A,".nc")' ) TRIM( c_asmbkg )81 cl_asmbkg = TRIM( cl_asmbkg )82 INQUIRE( FILE = cl_asmbkg, EXIST = llok )83 !84 IF( .NOT. llok ) THEN85 IF(lwp) WRITE(numout,*) ' Setting up assimilation background file '// TRIM( c_asmbkg )86 !87 ! ! Define the output file88 CALL iom_open( c_asmbkg, inum, ldwrt = .TRUE. )89 !90 IF( nitbkg_r == nit000 - 1 ) THEN ! Treat special case when nitbkg = 091 zdate = REAL( ndastp )92 IF( ln_zdftke ) THEN ! read turbulent kinetic energy ( en )93 IF(lwp) WRITE(numout,*) ' Reading TKE (en) from restart...'94 CALL tke_rst( nit000, 'READ' )95 ENDIF96 ELSE97 zdate = REAL( ndastp )98 ENDIF99 !100 ! ! Write the information101 CALL iom_rstput( kt, nitbkg_r, inum, 'rdastp' , zdate )102 CALL iom_rstput( kt, nitbkg_r, inum, 'un' , uu(:,:,:,Kmm) )103 CALL iom_rstput( kt, nitbkg_r, inum, 'vn' , vv(:,:,:,Kmm) )104 CALL iom_rstput( kt, nitbkg_r, inum, 'tn' , ts(:,:,:,jp_tem,Kmm) )105 CALL iom_rstput( kt, nitbkg_r, inum, 'sn' , ts(:,:,:,jp_sal,Kmm) )106 CALL iom_rstput( kt, nitbkg_r, inum, 'sshn' , ssh(:,:,Kmm) )107 IF( ln_zdftke ) CALL iom_rstput( kt, nitbkg_r, inum, 'en' , en )108 !109 CALL iom_close( inum )110 ENDIF111 !112 ENDIF113 76 114 ! !------------------------------------------- 115 IF( kt == nitdin_r ) THEN ! Write out background at time step nitdin_r 116 ! !-----------------------------------======== 117 ! 118 WRITE(cl_asmdin, FMT='(A,".nc")' ) TRIM( c_asmdin ) 119 cl_asmdin = TRIM( cl_asmdin ) 120 INQUIRE( FILE = cl_asmdin, EXIST = llok ) 121 ! 122 IF( .NOT. llok ) THEN 123 IF(lwp) WRITE(numout,*) ' Setting up assimilation background file '// TRIM( c_asmdin ) 124 ! 125 ! ! Define the output file 126 CALL iom_open( c_asmdin, inum, ldwrt = .TRUE. ) 127 ! 128 IF( nitdin_r == nit000 - 1 ) THEN ! Treat special case when nitbkg = 0 129 130 zdate = REAL( ndastp ) 131 ELSE 132 zdate = REAL( ndastp ) 133 ENDIF 134 ! 135 ! ! Write the information 136 CALL iom_rstput( kt, nitdin_r, inum, 'rdastp' , zdate ) 137 CALL iom_rstput( kt, nitdin_r, inum, 'un' , uu(:,:,:,Kmm) ) 138 CALL iom_rstput( kt, nitdin_r, inum, 'vn' , vv(:,:,:,Kmm) ) 139 CALL iom_rstput( kt, nitdin_r, inum, 'tn' , ts(:,:,:,jp_tem,Kmm) ) 140 CALL iom_rstput( kt, nitdin_r, inum, 'sn' , ts(:,:,:,jp_sal,Kmm) ) 141 CALL iom_rstput( kt, nitdin_r, inum, 'sshn' , ssh(:,:,Kmm) ) 77 IF( .NOT. l_istiled .OR. ntile == nijtile ) THEN ! Do only on the last tile 78 ! !------------------------------------------- 79 IF( kt == nitbkg_r ) THEN ! Write out background at time step nitbkg_r 80 ! !-----------------------------------======== 81 ! 82 WRITE(cl_asmbkg, FMT='(A,".nc")' ) TRIM( c_asmbkg ) 83 cl_asmbkg = TRIM( cl_asmbkg ) 84 INQUIRE( FILE = cl_asmbkg, EXIST = llok ) 85 ! 86 IF( .NOT. llok ) THEN 87 IF(lwp) WRITE(numout,*) ' Setting up assimilation background file '// TRIM( c_asmbkg ) 88 ! 89 ! ! Define the output file 90 CALL iom_open( c_asmbkg, inum, ldwrt = .TRUE. ) 91 ! 92 IF( nitbkg_r == nit000 - 1 ) THEN ! Treat special case when nitbkg = 0 93 zdate = REAL( ndastp ) 94 IF( ln_zdftke ) THEN ! read turbulent kinetic energy ( en ) 95 IF(lwp) WRITE(numout,*) ' Reading TKE (en) from restart...' 96 CALL tke_rst( nit000, 'READ' ) 97 ENDIF 98 ELSE 99 zdate = REAL( ndastp ) 100 ENDIF 101 ! 102 ! ! Write the information 103 CALL iom_rstput( kt, nitbkg_r, inum, 'rdastp' , zdate ) 104 CALL iom_rstput( kt, nitbkg_r, inum, 'un' , uu(:,:,:,Kmm) ) 105 CALL iom_rstput( kt, nitbkg_r, inum, 'vn' , vv(:,:,:,Kmm) ) 106 CALL iom_rstput( kt, nitbkg_r, inum, 'tn' , ts(:,:,:,jp_tem,Kmm) ) 107 CALL iom_rstput( kt, nitbkg_r, inum, 'sn' , ts(:,:,:,jp_sal,Kmm) ) 108 CALL iom_rstput( kt, nitbkg_r, inum, 'sshn' , ssh(:,:,Kmm) ) 109 IF( ln_zdftke ) CALL iom_rstput( kt, nitbkg_r, inum, 'en' , en ) 110 ! 111 CALL iom_close( inum ) 112 ENDIF 113 ! 114 ENDIF 115 116 ! !------------------------------------------- 117 IF( kt == nitdin_r ) THEN ! Write out background at time step nitdin_r 118 ! !-----------------------------------======== 119 ! 120 WRITE(cl_asmdin, FMT='(A,".nc")' ) TRIM( c_asmdin ) 121 cl_asmdin = TRIM( cl_asmdin ) 122 INQUIRE( FILE = cl_asmdin, EXIST = llok ) 123 ! 124 IF( .NOT. llok ) THEN 125 IF(lwp) WRITE(numout,*) ' Setting up assimilation background file '// TRIM( c_asmdin ) 126 ! 127 ! ! Define the output file 128 CALL iom_open( c_asmdin, inum, ldwrt = .TRUE. ) 129 ! 130 IF( nitdin_r == nit000 - 1 ) THEN ! Treat special case when nitbkg = 0 131 132 zdate = REAL( ndastp ) 133 ELSE 134 zdate = REAL( ndastp ) 135 ENDIF 136 ! 137 ! ! Write the information 138 CALL iom_rstput( kt, nitdin_r, inum, 'rdastp' , zdate ) 139 CALL iom_rstput( kt, nitdin_r, inum, 'un' , uu(:,:,:,Kmm) ) 140 CALL iom_rstput( kt, nitdin_r, inum, 'vn' , vv(:,:,:,Kmm) ) 141 CALL iom_rstput( kt, nitdin_r, inum, 'tn' , ts(:,:,:,jp_tem,Kmm) ) 142 CALL iom_rstput( kt, nitdin_r, inum, 'sn' , ts(:,:,:,jp_sal,Kmm) ) 143 CALL iom_rstput( kt, nitdin_r, inum, 'sshn' , ssh(:,:,Kmm) ) 142 144 #if defined key_si3 143 IF( nn_ice == 2 ) THEN144 IF( ALLOCATED(at_i) ) THEN145 CALL iom_rstput( kt, nitdin_r, inum, 'iceconc', at_i(:,:) )146 ELSE147 CALL ctl_warn('asm_bkg_wri: Ice concentration not written to background ', &148 & 'as ice variable at_i not allocated on this timestep')149 ENDIF150 ENDIF145 IF( nn_ice == 2 ) THEN 146 IF( ALLOCATED(at_i) ) THEN 147 CALL iom_rstput( kt, nitdin_r, inum, 'iceconc', at_i(:,:) ) 148 ELSE 149 CALL ctl_warn('asm_bkg_wri: Ice concentration not written to background ', & 150 & 'as ice variable at_i not allocated on this timestep') 151 ENDIF 152 ENDIF 151 153 #endif 152 ! 153 CALL iom_close( inum ) 154 ENDIF 155 ! 156 ENDIF 154 ! 155 CALL iom_close( inum ) 156 ENDIF 157 ! 158 ENDIF 159 ENDIF ! check for last tile 157 160 ! 158 161 END SUBROUTINE asm_bkg_wri -
NEMO/branches/2021/dev_r14383_PISCES_NEWDEV_PISCO/src/OCE/BDY/bdy_oce.F90
r13472 r15440 137 137 TYPE(OBC_DATA) , DIMENSION(jp_bdy), TARGET :: dta_bdy !: bdy external data (local process) 138 138 !$AGRIF_END_DO_NOT_TREAT 139 LOGICAL, ALLOCATABLE, DIMENSION(:,:,:,:) :: lsend_bdy 140 LOGICAL, ALLOCATABLE, DIMENSION(:,:,:,:) :: lrecv_bdy !: when searching in any direction139 LOGICAL, ALLOCATABLE, DIMENSION(:,:,:,:) :: lsend_bdyolr !: mark needed communication for given boundary, grid and neighbour 140 LOGICAL, ALLOCATABLE, DIMENSION(:,:,:,:) :: lrecv_bdyolr !: when searching in any direction (only for orlansky) 141 141 LOGICAL, ALLOCATABLE, DIMENSION(:,:,:,:) :: lsend_bdyint !: mark needed communication for given boundary, grid and neighbour 142 142 LOGICAL, ALLOCATABLE, DIMENSION(:,:,:,:) :: lrecv_bdyint !: when searching towards the interior of the computational domain -
NEMO/branches/2021/dev_r14383_PISCES_NEWDEV_PISCO/src/OCE/BDY/bdydta.F90
r13472 r15440 243 243 ! If full velocities in boundary data, then split it into barotropic and baroclinic component 244 244 IF( bf_alias(jp_bdyu3d)%ltotvel ) THEN ! if we read 3D total velocity (can be true only if u3d was read) 245 !246 245 igrd = 2 ! zonal velocity 247 246 DO ib = 1, idx_bdy(jbdy)%nblen(igrd) … … 258 257 END DO 259 258 END DO 259 ENDIF ! ltotvel 260 IF( bf_alias(jp_bdyv3d)%ltotvel ) THEN ! if we read 3D total velocity (can be true only if v3d was read) 260 261 igrd = 3 ! meridional velocity 261 262 DO ib = 1, idx_bdy(jbdy)%nblen(igrd) -
NEMO/branches/2021/dev_r14383_PISCES_NEWDEV_PISCO/src/OCE/BDY/bdydyn2d.F90
r15349 r15440 18 18 USE bdylib ! BDY library routines 19 19 USE phycst ! physical constants 20 USE lib_mpp , ONLY: jpfillnothing20 USE lib_mpp 21 21 USE lbclnk ! ocean lateral boundary conditions (or mpp link) 22 22 USE wet_dry ! Use wet dry to get reference ssh level 23 23 USE in_out_manager ! 24 USE lib_mpp, ONLY: ctl_stop25 24 26 25 IMPLICIT NONE … … 50 49 REAL(wp), DIMENSION(jpi,jpj), INTENT(in ) :: pssh 51 50 !! 52 INTEGER :: ib_bdy, ir ! BDY set index, rim index 53 LOGICAL :: llrim0 ! indicate if rim 0 is treated 54 LOGICAL, DIMENSION(4) :: llsend2, llrecv2, llsend3, llrecv3 ! indicate how communications are to be carried out 51 INTEGER :: ib_bdy, ir ! BDY set index, rim index 52 INTEGER, DIMENSION(3) :: idir3 53 INTEGER, DIMENSION(6) :: idir6 54 LOGICAL :: llrim0 ! indicate if rim 0 is treated 55 LOGICAL, DIMENSION(8) :: llsend2, llrecv2, llsend3, llrecv3 ! indicate how communications are to be carried out 56 !!---------------------------------------------------------------------- 55 57 56 58 llsend2(:) = .false. ; llrecv2(:) = .false. … … 87 89 SELECT CASE( cn_dyn2d(ib_bdy) ) 88 90 CASE('flather') 89 llsend2(1:2) = llsend2(1:2) .OR. lsend_bdyint(ib_bdy,2,1:2,ir) ! west/east, U points 90 llsend2(1) = llsend2(1) .OR. lsend_bdyext(ib_bdy,2,1,ir) ! neighbour might search point towards its east bdy 91 llrecv2(1:2) = llrecv2(1:2) .OR. lrecv_bdyint(ib_bdy,2,1:2,ir) ! west/east, U points 92 llrecv2(2) = llrecv2(2) .OR. lrecv_bdyext(ib_bdy,2,2,ir) ! might search point towards bdy on the east 93 llsend3(3:4) = llsend3(3:4) .OR. lsend_bdyint(ib_bdy,3,3:4,ir) ! north/south, V points 94 llsend3(3) = llsend3(3) .OR. lsend_bdyext(ib_bdy,3,3,ir) ! neighbour might search point towards its north bdy 95 llrecv3(3:4) = llrecv3(3:4) .OR. lrecv_bdyint(ib_bdy,3,3:4,ir) ! north/south, V points 96 llrecv3(4) = llrecv3(4) .OR. lrecv_bdyext(ib_bdy,3,4,ir) ! might search point towards bdy on the north 91 idir6 = (/ jpwe, jpea, jpsw, jpse, jpnw, jpne /) 92 llsend2(idir6) = llsend2(idir6) .OR. lsend_bdyint(ib_bdy,2,idir6,ir) ! west/east, U points 93 idir3 = (/ jpwe, jpsw, jpnw /) 94 llsend2(idir3) = llsend2(idir3) .OR. lsend_bdyext(ib_bdy,2,idir3,ir) ! nei might search point towards its east bdy 95 llrecv2(idir6) = llrecv2(idir6) .OR. lrecv_bdyint(ib_bdy,2,idir6,ir) ! west/east, U points 96 idir3 = (/ jpea, jpse, jpne /) 97 llrecv2(idir3) = llrecv2(idir3) .OR. lrecv_bdyext(ib_bdy,2,idir3,ir) ! might search point towards bdy on the east 98 idir6 = (/ jpso, jpno, jpsw, jpse, jpnw, jpne /) 99 llsend3(idir6) = llsend3(idir6) .OR. lsend_bdyint(ib_bdy,3,idir6,ir) ! north/south, V points 100 idir3 = (/ jpso, jpsw, jpse /) 101 llsend3(idir3) = llsend3(idir3) .OR. lsend_bdyext(ib_bdy,3,idir3,ir) ! nei might search point towards its north bdy 102 llrecv3(idir6) = llrecv3(idir6) .OR. lrecv_bdyint(ib_bdy,3,idir6,ir) ! north/south, V points 103 idir3 = (/ jpno, jpnw, jpne /) 104 llrecv3(idir3) = llrecv3(idir3) .OR. lrecv_bdyext(ib_bdy,3,idir3,ir) ! might search point towards bdy on the north 97 105 CASE('orlanski', 'orlanski_npo') 98 llsend2(:) = llsend2(:) .OR. lsend_bdy (ib_bdy,2,:,ir) ! possibly every direction, U points99 llrecv2(:) = llrecv2(:) .OR. lrecv_bdy (ib_bdy,2,:,ir) ! possibly every direction, U points100 llsend3(:) = llsend3(:) .OR. lsend_bdy (ib_bdy,3,:,ir) ! possibly every direction, V points101 llrecv3(:) = llrecv3(:) .OR. lrecv_bdy (ib_bdy,3,:,ir) ! possibly every direction, V points106 llsend2(:) = llsend2(:) .OR. lsend_bdyolr(ib_bdy,2,:,ir) ! possibly every direction, U points 107 llrecv2(:) = llrecv2(:) .OR. lrecv_bdyolr(ib_bdy,2,:,ir) ! possibly every direction, U points 108 llsend3(:) = llsend3(:) .OR. lsend_bdyolr(ib_bdy,3,:,ir) ! possibly every direction, V points 109 llrecv3(:) = llrecv3(:) .OR. lrecv_bdyolr(ib_bdy,3,:,ir) ! possibly every direction, V points 102 110 END SELECT 103 111 END DO … … 310 318 INTEGER :: ibeg, iend ! length of rim to be treated (rim 0 or rim 1) 311 319 LOGICAL :: llrim0 ! indicate if rim 0 is treated 312 LOGICAL, DIMENSION( 4) :: llsend1, llrecv1 ! indicate how communications are to be carried out320 LOGICAL, DIMENSION(8) :: llsend1, llrecv1 ! indicate how communications are to be carried out 313 321 !!---------------------------------------------------------------------- 314 322 llsend1(:) = .false. ; llrecv1(:) = .false. -
NEMO/branches/2021/dev_r14383_PISCES_NEWDEV_PISCO/src/OCE/BDY/bdydyn3d.F90
r15127 r15440 15 15 USE bdy_oce ! ocean open boundary conditions 16 16 USE bdylib ! for orlanski library routines 17 USE lib_mpp , ONLY: jpfillnothing17 USE lib_mpp 18 18 USE lbclnk ! ocean lateral boundary conditions (or mpp link) 19 19 USE in_out_manager ! 20 USE lib_mpp, ONLY: ctl_stop21 20 Use phycst 22 21 … … 45 44 REAL(wp), DIMENSION(jpi,jpj,jpk,jpt), INTENT( inout ) :: puu, pvv ! Ocean velocities (to be updated at open boundaries) 46 45 ! 47 INTEGER :: ib_bdy, ir ! BDY set index, rim index 48 LOGICAL :: llrim0 ! indicate if rim 0 is treated 49 LOGICAL, DIMENSION(4) :: llsend2, llrecv2, llsend3, llrecv3 ! indicate how communications are to be carried out 50 51 !!---------------------------------------------------------------------- 46 INTEGER :: ib_bdy, ir ! BDY set index, rim index 47 INTEGER, DIMENSION(6) :: idir6 48 LOGICAL :: llrim0 ! indicate if rim 0 is treated 49 LOGICAL, DIMENSION(8) :: llsend2, llrecv2, llsend3, llrecv3 ! indicate how communications are to be carried out 50 !!---------------------------------------------------------------------- 51 52 52 llsend2(:) = .false. ; llrecv2(:) = .false. 53 53 llsend3(:) = .false. ; llrecv3(:) = .false. … … 82 82 SELECT CASE( cn_dyn3d(ib_bdy) ) 83 83 CASE('orlanski', 'orlanski_npo') 84 llsend2(:) = llsend2(:) .OR. lsend_bdy (ib_bdy,2,:,ir) ! possibly every direction, U points85 llrecv2(:) = llrecv2(:) .OR. lrecv_bdy (ib_bdy,2,:,ir) ! possibly every direction, U points86 llsend3(:) = llsend3(:) .OR. lsend_bdy (ib_bdy,3,:,ir) ! possibly every direction, V points87 llrecv3(:) = llrecv3(:) .OR. lrecv_bdy (ib_bdy,3,:,ir) ! possibly every direction, V points84 llsend2(:) = llsend2(:) .OR. lsend_bdyolr(ib_bdy,2,:,ir) ! possibly every direction, U points 85 llrecv2(:) = llrecv2(:) .OR. lrecv_bdyolr(ib_bdy,2,:,ir) ! possibly every direction, U points 86 llsend3(:) = llsend3(:) .OR. lsend_bdyolr(ib_bdy,3,:,ir) ! possibly every direction, V points 87 llrecv3(:) = llrecv3(:) .OR. lrecv_bdyolr(ib_bdy,3,:,ir) ! possibly every direction, V points 88 88 CASE('zerograd') 89 llsend2(3:4) = llsend2(3:4) .OR. lsend_bdyint(ib_bdy,2,3:4,ir) ! north/south, U points 90 llrecv2(3:4) = llrecv2(3:4) .OR. lrecv_bdyint(ib_bdy,2,3:4,ir) ! north/south, U points 91 llsend3(1:2) = llsend3(1:2) .OR. lsend_bdyint(ib_bdy,3,1:2,ir) ! west/east, V points 92 llrecv3(1:2) = llrecv3(1:2) .OR. lrecv_bdyint(ib_bdy,3,1:2,ir) ! west/east, V points 89 idir6 = (/ jpso, jpno, jpsw, jpse, jpnw, jpne /) 90 llsend2(idir6) = llsend2(idir6) .OR. lsend_bdyint(ib_bdy,2,idir6,ir) ! north/south, U points 91 llrecv2(idir6) = llrecv2(idir6) .OR. lrecv_bdyint(ib_bdy,2,idir6,ir) ! north/south, U points 92 idir6 = (/ jpwe, jpea, jpsw, jpse, jpnw, jpne /) 93 llsend3(idir6) = llsend3(idir6) .OR. lsend_bdyint(ib_bdy,3,idir6,ir) ! west/east, V points 94 llrecv3(idir6) = llrecv3(idir6) .OR. lrecv_bdyint(ib_bdy,3,idir6,ir) ! west/east, V points 93 95 CASE('neumann') 94 96 llsend2(:) = llsend2(:) .OR. lsend_bdyint(ib_bdy,2,:,ir) ! possibly every direction, U points -
NEMO/branches/2021/dev_r14383_PISCES_NEWDEV_PISCO/src/OCE/BDY/bdyice.F90
r15127 r15440 58 58 INTEGER :: ibeg, iend ! length of rim to be treated (rim 0 or rim 1) 59 59 LOGICAL :: llrim0 ! indicate if rim 0 is treated 60 LOGICAL, DIMENSION( 4) :: llsend1, llrecv1 ! indicate how communications are to be carried out60 LOGICAL, DIMENSION(8) :: llsend1, llrecv1 ! indicate how communications are to be carried out 61 61 !!---------------------------------------------------------------------- 62 62 ! controls … … 327 327 CHARACTER(len=1), INTENT(in) :: cd_type ! nature of velocity grid-points 328 328 ! 329 INTEGER :: i_bdy, jgrd ! dummy loop indices 330 INTEGER :: ji, jj ! local scalar 331 INTEGER :: jbdy, ir ! BDY set index, rim index 332 INTEGER :: ibeg, iend ! length of rim to be treated (rim 0 or rim 1) 333 REAL(wp) :: zmsk1, zmsk2, zflag 334 LOGICAL, DIMENSION(4) :: llsend2, llrecv2, llsend3, llrecv3 ! indicate how communications are to be carried out 329 INTEGER :: i_bdy, jgrd ! dummy loop indices 330 INTEGER :: ji, jj ! local scalar 331 INTEGER :: jbdy, ir ! BDY set index, rim index 332 INTEGER :: ibeg, iend ! length of rim to be treated (rim 0 or rim 1) 333 INTEGER, DIMENSION(3) :: idir3 334 REAL(wp) :: zmsk1, zmsk2, zflag 335 LOGICAL, DIMENSION(8) :: llsend2, llrecv2, llsend3, llrecv3 ! indicate how communications are to be carried out 335 336 !!------------------------------------------------------------------------------ 336 337 IF( ln_timing ) CALL timing_start('bdy_ice_dyn') … … 430 431 DO jbdy = 1, nb_bdy 431 432 IF( cn_ice(jbdy) == 'frs' .AND. nn_ice_dta(jbdy) /= 0 ) THEN 432 llsend2(:) = llsend2(:) .OR. lsend_bdyint(jbdy,2,:,ir) ! possibly every direction, U points 433 llsend2(1) = llsend2(1) .OR. lsend_bdyext(jbdy,2,1,ir) ! neighbour might search point towards its west bdy 434 llrecv2(:) = llrecv2(:) .OR. lrecv_bdyint(jbdy,2,:,ir) ! possibly every direction, U points 435 llrecv2(2) = llrecv2(2) .OR. lrecv_bdyext(jbdy,2,2,ir) ! might search point towards east bdy 433 llsend2( : ) = llsend2( : ) .OR. lsend_bdyint(jbdy,2, : ,ir) ! possibly every direction, U points 434 idir3 = (/ jpwe, jpsw, jpnw /) 435 llsend2(idir3) = llsend2(idir3) .OR. lsend_bdyext(jbdy,2,idir3,ir) ! nei might search point towards its ea bdy 436 llrecv2( : ) = llrecv2( : ) .OR. lrecv_bdyint(jbdy,2, : ,ir) ! possibly every direction, U points 437 idir3 = (/ jpea, jpse, jpne /) 438 llrecv2(idir3) = llrecv2(idir3) .OR. lrecv_bdyext(jbdy,2,idir3,ir) ! might search point towards east bdy 436 439 END IF 437 440 END DO … … 444 447 DO jbdy = 1, nb_bdy 445 448 IF( cn_ice(jbdy) == 'frs' .AND. nn_ice_dta(jbdy) /= 0 ) THEN 446 llsend3(:) = llsend3(:) .OR. lsend_bdyint(jbdy,3,:,ir) ! possibly every direction, V points 447 llsend3(3) = llsend3(3) .OR. lsend_bdyext(jbdy,3,3,ir) ! neighbour might search point towards its south bdy 448 llrecv3(:) = llrecv3(:) .OR. lrecv_bdyint(jbdy,3,:,ir) ! possibly every direction, V points 449 llrecv3(4) = llrecv3(4) .OR. lrecv_bdyext(jbdy,3,4,ir) ! might search point towards north bdy 449 llsend3( : ) = llsend3( : ) .OR. lsend_bdyint(jbdy,3, : ,ir) ! possibly every direction, V points 450 idir3 = (/ jpso, jpsw, jpse /) 451 llsend3(idir3) = llsend3(idir3) .OR. lsend_bdyext(jbdy,3,idir3,ir) ! nei might search point towards its no bdy 452 llrecv3( : ) = llrecv3( : ) .OR. lrecv_bdyint(jbdy,3, : ,ir) ! possibly every direction, V points 453 idir3 = (/ jpno, jpnw, jpne /) 454 llrecv3(idir3) = llrecv3(idir3) .OR. lrecv_bdyext(jbdy,3,idir3,ir) ! might search point towards north bdy 450 455 END IF 451 456 END DO -
NEMO/branches/2021/dev_r14383_PISCES_NEWDEV_PISCO/src/OCE/BDY/bdyini.F90
r15349 r15440 146 146 INTEGER :: ib_bdy, ii, ij, igrd, ib, ir, iseg ! dummy loop indices 147 147 INTEGER :: icount, icountr, icountr0, ibr_max ! local integers 148 INTEGER :: ilen1 ! - - 148 INTEGER :: ilen1 ! - - 149 INTEGER :: iiRst, iiRnd, iiSst, iiSnd, iiSstdiag, iiSnddiag, iiSstsono, iiSndsono 150 INTEGER :: ijRst, ijRnd, ijSst, ijSnd, ijSstdiag, ijSnddiag, ijSstsono, ijSndsono 151 INTEGER :: iiout, ijout, iioutdir, ijoutdir, icnt 152 INTEGER :: iRnei, iRdiag, iRsono 153 INTEGER :: iSnei, iSdiag, iSsono ! - - 149 154 INTEGER :: iwe, ies, iso, ino, inum, id_dummy ! - - 150 155 INTEGER :: jpbdta ! - - … … 163 168 REAL(wp) , DIMENSION(jpi,jpj) :: zfmask ! temporary fmask array excluding coastal boundary condition (shlat) 164 169 REAL(wp) , DIMENSION(jpi,jpj) :: ztmask, zumask, zvmask ! temporary u/v mask array 170 REAL(wp) , DIMENSION(jpi,jpj) :: zzbdy 165 171 !!---------------------------------------------------------------------- 166 172 ! … … 562 568 ! Initialize array indicating communications in bdy 563 569 ! ------------------------------------------------- 564 ALLOCATE( lsend_bdy (nb_bdy,jpbgrd,4,0:1), lrecv_bdy(nb_bdy,jpbgrd,4,0:1) )565 lsend_bdy (:,:,:,:) = .false.566 lrecv_bdy (:,:,:,:) = .false.570 ALLOCATE( lsend_bdyolr(nb_bdy,jpbgrd,8,0:1), lrecv_bdyolr(nb_bdy,jpbgrd,8,0:1) ) 571 lsend_bdyolr(:,:,:,:) = .false. 572 lrecv_bdyolr(:,:,:,:) = .false. 567 573 568 574 DO ib_bdy = 1, nb_bdy … … 576 582 ! 577 583 ! check if point has to be sent to a neighbour 578 ! W neighbour and on the inner left side 579 IF( ii >= Nis0 .AND. ii < Nis0 + nn_hls .AND. mpiSnei(nn_hls,jpwe) > -1 ) lsend_bdy(ib_bdy,igrd,jpwe,ir) = .TRUE. 580 ! E neighbour and on the inner right side 581 IF( ii <= Nie0 .AND. ii > Nie0 - nn_hls .AND. mpiSnei(nn_hls,jpea) > -1 ) lsend_bdy(ib_bdy,igrd,jpea,ir) = .TRUE. 582 ! S neighbour and on the inner down side 583 IF( ij >= Njs0 .AND. ij < Njs0 + nn_hls .AND. mpiSnei(nn_hls,jpso) > -1 ) lsend_bdy(ib_bdy,igrd,jpso,ir) = .TRUE. 584 ! N neighbour and on the inner up side 585 IF( ij <= Nje0 .AND. ij > Nje0 - nn_hls .AND. mpiSnei(nn_hls,jpno) > -1 ) lsend_bdy(ib_bdy,igrd,jpno,ir) = .TRUE. 584 IF( ii >= Nis0 .AND. ii < Nis0 + nn_hls .AND. ij >= Njs0 .AND. ij <= Nje0 ) THEN ! we inner side 585 IF( mpiSnei(nn_hls,jpwe) > -1 ) lsend_bdyolr(ib_bdy,igrd,jpwe,ir) = .TRUE. 586 ENDIF 587 IF( ii <= Nie0 .AND. ii > Nie0 - nn_hls .AND. ij >= Njs0 .AND. ij <= Nje0 ) THEN ! ea inner side 588 IF( mpiSnei(nn_hls,jpea) > -1 ) lsend_bdyolr(ib_bdy,igrd,jpea,ir) = .TRUE. 589 ENDIF 590 IF( ii >= Nis0 .AND. ii <= Nie0 .AND. ij >= Njs0 .AND. ij < Njs0 + nn_hls ) THEN ! so inner side 591 IF( mpiSnei(nn_hls,jpso) > -1 ) lsend_bdyolr(ib_bdy,igrd,jpso,ir) = .TRUE. 592 ENDIF 593 IF( ii < Nis0 .AND. ij >= Njs0 .AND. ij < Njs0 + nn_hls ) THEN ! so side we-halo 594 IF( mpiSnei(nn_hls,jpso) > -1 .AND. nn_comm == 1 ) lsend_bdyolr(ib_bdy,igrd,jpso,ir) = .TRUE. 595 ENDIF 596 IF( ii > Nie0 .AND. ij >= Njs0 .AND. ij < Njs0 + nn_hls ) THEN ! so side ea-halo 597 IF( mpiSnei(nn_hls,jpso) > -1 .AND. nn_comm == 1 ) lsend_bdyolr(ib_bdy,igrd,jpso,ir) = .TRUE. 598 ENDIF 599 IF( ii >= Nis0 .AND. ii <= Nie0 .AND. ij <= Nje0 .AND. ij > Nje0 - nn_hls ) THEN ! no inner side 600 IF( mpiSnei(nn_hls,jpno) > -1 ) lsend_bdyolr(ib_bdy,igrd,jpno,ir) = .TRUE. 601 ENDIF 602 IF( ii < Nis0 .AND. ij <= Nje0 .AND. ij > Nje0 - nn_hls ) THEN ! no side we-halo 603 IF( mpiSnei(nn_hls,jpno) > -1 .AND. nn_comm == 1 ) lsend_bdyolr(ib_bdy,igrd,jpno,ir) = .TRUE. 604 ENDIF 605 IF( ii > Nie0 .AND. ij <= Nje0 .AND. ij > Nje0 - nn_hls ) THEN ! no side ea-halo 606 IF( mpiSnei(nn_hls,jpno) > -1 .AND. nn_comm == 1 ) lsend_bdyolr(ib_bdy,igrd,jpno,ir) = .TRUE. 607 ENDIF 608 IF( ii >= Nis0 .AND. ii < Nis0 + nn_hls .AND. ij >= Njs0 .AND. ij < Njs0 + nn_hls ) THEN ! sw inner corner 609 IF( mpiSnei(nn_hls,jpsw) > -1 ) lsend_bdyolr(ib_bdy,igrd,jpsw,ir) = .TRUE. 610 ENDIF 611 IF( ii <= Nie0 .AND. ii > Nie0 - nn_hls .AND. ij >= Njs0 .AND. ij < Njs0 + nn_hls ) THEN ! se inner corner 612 IF( mpiSnei(nn_hls,jpse) > -1 ) lsend_bdyolr(ib_bdy,igrd,jpse,ir) = .TRUE. 613 ENDIF 614 IF( ii >= Nis0 .AND. ii < Nis0 + nn_hls .AND. ij <= Nje0 .AND. ij > Nje0 - nn_hls ) THEN ! nw inner corner 615 IF( mpiSnei(nn_hls,jpnw) > -1 ) lsend_bdyolr(ib_bdy,igrd,jpnw,ir) = .TRUE. 616 ENDIF 617 IF( ii <= Nie0 .AND. ii > Nie0 - nn_hls .AND. ij <= Nje0 .AND. ij > Nje0 - nn_hls ) THEN ! ne inner corner 618 IF( mpiSnei(nn_hls,jpne) > -1 ) lsend_bdyolr(ib_bdy,igrd,jpne,ir) = .TRUE. 619 ENDIF 586 620 ! 587 621 ! check if point has to be received from a neighbour 588 ! W neighbour and on the outter left side 589 IF( ii < Nis0 .AND. mpiRnei(nn_hls,jpwe) > -1 ) lrecv_bdy(ib_bdy,igrd,jpwe,ir) = .TRUE. 590 ! E neighbour and on the outter right side 591 IF( ii > Nie0 .AND. mpiRnei(nn_hls,jpea) > -1 ) lrecv_bdy(ib_bdy,igrd,jpea,ir) = .TRUE. 592 ! S neighbour and on the outter down side 593 IF( ij < Njs0 .AND. mpiRnei(nn_hls,jpso) > -1 ) lrecv_bdy(ib_bdy,igrd,jpso,ir) = .TRUE. 594 ! N neighbour and on the outter up side 595 IF( ij > Nje0 .AND. mpiRnei(nn_hls,jpno) > -1 ) lrecv_bdy(ib_bdy,igrd,jpno,ir) = .TRUE. 622 IF( ii < Nis0 .AND. ij >= Njs0 .AND. ij <= Nje0 ) THEN ! we side 623 IF( mpiRnei(nn_hls,jpwe) > -1 ) lrecv_bdyolr(ib_bdy,igrd,jpwe,ir) = .TRUE. 624 ENDIF 625 IF( ii > Nie0 .AND. ij >= Njs0 .AND. ij <= Nje0 ) THEN ! ea side 626 IF( mpiRnei(nn_hls,jpea) > -1 ) lrecv_bdyolr(ib_bdy,igrd,jpea,ir) = .TRUE. 627 ENDIF 628 IF( ii >= Nis0 .AND. ii <= Nie0 .AND. ij < Njs0 ) THEN ! so side 629 IF( mpiRnei(nn_hls,jpso) > -1 ) lrecv_bdyolr(ib_bdy,igrd,jpso,ir) = .TRUE. 630 ENDIF 631 IF( ii >= Nis0 .AND. ii <= Nie0 .AND. ij > Nje0 ) THEN ! no side 632 IF( mpiRnei(nn_hls,jpno) > -1 ) lrecv_bdyolr(ib_bdy,igrd,jpno,ir) = .TRUE. 633 ENDIF 634 IF( ii < Nis0 .AND. ij < Njs0 ) THEN ! sw corner 635 IF( mpiRnei(nn_hls,jpsw) > -1 ) lrecv_bdyolr(ib_bdy,igrd,jpsw,ir) = .TRUE. 636 IF( mpiRnei(nn_hls,jpso) > -1 .AND. nn_comm == 1 ) lrecv_bdyolr(ib_bdy,igrd,jpso,ir) = .TRUE. 637 ENDIF 638 IF( ii > Nie0 .AND. ij < Njs0 ) THEN ! se corner 639 IF( mpiRnei(nn_hls,jpse) > -1 ) lrecv_bdyolr(ib_bdy,igrd,jpse,ir) = .TRUE. 640 IF( mpiRnei(nn_hls,jpso) > -1 .AND. nn_comm == 1 ) lrecv_bdyolr(ib_bdy,igrd,jpso,ir) = .TRUE. 641 ENDIF 642 IF( ii < Nis0 .AND. ij > Nje0 ) THEN ! nw corner 643 IF( mpiRnei(nn_hls,jpnw) > -1 ) lrecv_bdyolr(ib_bdy,igrd,jpnw,ir) = .TRUE. 644 IF( mpiRnei(nn_hls,jpno) > -1 .AND. nn_comm == 1 ) lrecv_bdyolr(ib_bdy,igrd,jpno,ir) = .TRUE. 645 ENDIF 646 IF( ii > Nie0 .AND. ij > Nje0 ) THEN ! ne corner 647 IF( mpiRnei(nn_hls,jpne) > -1 ) lrecv_bdyolr(ib_bdy,igrd,jpne,ir) = .TRUE. 648 IF( mpiRnei(nn_hls,jpno) > -1 .AND. nn_comm == 1 ) lrecv_bdyolr(ib_bdy,igrd,jpno,ir) = .TRUE. 649 ENDIF 596 650 ! 597 651 END DO 598 END DO ! igrd 599 652 END DO ! igrd 653 654 ! Comment out for debug 655 !!$ DO ir = 0,1 656 !!$ zzbdy(:,:) = narea ; CALL lbc_lnk('bdy debug', zzbdy, 'T', 1._wp, kfillmode = jpfillnothing, & 657 !!$ & lsend = lsend_bdyolr(ib_bdy,1,:,ir), lrecv = lrecv_bdyolr(ib_bdy,1,:,ir) ) 658 !!$ IF(lwp) WRITE(numout,*) ' seb bdy debug olr T', ir ; CALL FLUSH(numout) 659 !!$ zzbdy(:,:) = narea ; CALL lbc_lnk('bdy debug', zzbdy, 'U', 1._wp, kfillmode = jpfillnothing, & 660 !!$ & lsend = lsend_bdyolr(ib_bdy,2,:,ir), lrecv = lrecv_bdyolr(ib_bdy,2,:,ir) ) 661 !!$ IF(lwp) WRITE(numout,*) ' seb bdy debug olr U', ir ; CALL FLUSH(numout) 662 !!$ zzbdy(:,:) = narea ; CALL lbc_lnk('bdy debug', zzbdy, 'V', 1._wp, kfillmode = jpfillnothing, & 663 !!$ & lsend = lsend_bdyolr(ib_bdy,3,:,ir), lrecv = lrecv_bdyolr(ib_bdy,3,:,ir) ) 664 !!$ IF(lwp) WRITE(numout,*) ' seb bdy debug olr V', ir ; CALL FLUSH(numout) 665 !!$ END DO 666 600 667 ! Compute rim weights for FRS scheme 601 668 ! ---------------------------------- … … 709 776 ! 710 777 ! Check which boundaries might need communication 711 ALLOCATE( lsend_bdyint(nb_bdy,jpbgrd, 4,0:1), lrecv_bdyint(nb_bdy,jpbgrd,4,0:1) )778 ALLOCATE( lsend_bdyint(nb_bdy,jpbgrd,8,0:1), lrecv_bdyint(nb_bdy,jpbgrd,8,0:1) ) 712 779 lsend_bdyint(:,:,:,:) = .false. 713 780 lrecv_bdyint(:,:,:,:) = .false. 714 ALLOCATE( lsend_bdyext(nb_bdy,jpbgrd, 4,0:1), lrecv_bdyext(nb_bdy,jpbgrd,4,0:1) )781 ALLOCATE( lsend_bdyext(nb_bdy,jpbgrd,8,0:1), lrecv_bdyext(nb_bdy,jpbgrd,8,0:1) ) 715 782 lsend_bdyext(:,:,:,:) = .false. 716 783 lrecv_bdyext(:,:,:,:) = .false. 717 784 ! 718 DO i grd = 1, jpbgrd719 DO i b_bdy = 1, nb_bdy785 DO ib_bdy = 1, nb_bdy 786 DO igrd = 1, jpbgrd 720 787 DO ib = 1, idx_bdy(ib_bdy)%nblenrim(igrd) 721 788 IF( idx_bdy(ib_bdy)%ntreat(ib,igrd) == -1 ) CYCLE … … 731 798 CALL find_neib( ii, ij, idx_bdy(ib_bdy)%ntreat(ib,igrd), ii1, ij1, ii2, ij2, ii3, ij3 ) ! free ocean neighbours 732 799 ! 733 ! search neighbour in the west/east direction800 ! take care of the 4 sides 734 801 ! 735 ! Rim is on the halo and computed ocean is towards exterior of mpi domain : 736 ! <-- (o exterior) --> 737 ! (1) o|x OR (2) x|o 738 ! |___ ___| 739 ! ==> cannot compute the point x -> need to receive it 740 IF( iibi==0 .OR. ii1==0 .OR. ii2==0 .OR. ii3==0 ) lrecv_bdyint(ib_bdy,igrd,jpwe,ir) = .TRUE. 741 IF( iibe==0 ) lrecv_bdyext(ib_bdy,igrd,jpwe,ir) = .TRUE. 742 IF( iibi==jpi+1 .OR. ii1==jpi+1 .OR. ii2==jpi+1 .OR. ii3==jpi+1 ) lrecv_bdyint(ib_bdy,igrd,jpea,ir) = .TRUE. 743 IF( iibe==jpi+1 ) lrecv_bdyext(ib_bdy,igrd,jpea,ir) = .TRUE. 744 ! Check if neighbour has its rim parallel to its mpi subdomain border and located next to its halo. 745 ! :¨¨¨¨¨|¨¨--> | | <--¨¨|¨¨¨¨¨: 746 ! : | x:o | neighbour limited by ... would need o | o:x | : 747 ! :.....|_._:_____| (1) W neighbour E neighbour (2) |_____:_._|.....: 748 ! ==> the neighbour cannot compute the point x -> need to send it 749 IF( ii == 2*nn_hls .AND. mpiSnei(nn_hls,jpwe) > -1 ) THEN ! 2*nn_hls -> ji=jpi of western neighbour 750 IF( iibi==ii+1 .OR. ii1==ii+1 .OR. ii2==ii+1 .OR. ii3==ii+1 ) lsend_bdyint(ib_bdy,igrd,jpwe,ir) = .TRUE. 751 IF( iibe==ii+1 ) lsend_bdyext(ib_bdy,igrd,jpwe,ir) = .TRUE. 752 ENDIF 753 IF( ii == jpi-2*nn_hls+1 .AND. mpiSnei(nn_hls,jpea) > -1 ) THEN ! jpi-2*nn_hls+1-> ji=1 of eastern neighbour 754 IF( iibi==ii-1 .OR. ii1==ii-1 .OR. ii2==ii-1 .OR. ii3==ii-1 ) lsend_bdyint(ib_bdy,igrd,jpea,ir) = .TRUE. 755 IF( iibe==ii-1 ) lsend_bdyext(ib_bdy,igrd,jpea,ir) = .TRUE. 756 ENDIF 802 DO icnt = 1, 4 803 SELECT CASE( icnt ) 804 ! ... _____ 805 CASE( 1 ) ! x: rim on rcvwe/sndea-side o| : 806 ! o: potential neighbour(s) o|x : 807 ! outside of the MPI domain ..o|__:__ 808 iRnei = jpwe ; iSnei = jpea 809 iiRst = 1 ; ijRst = Njs0 ! Rcv we-side starting point, excluding sw-corner 810 iiRnd = nn_hls ; ijRnd = Nje0 ! Rcv we-side ending point, excluding nw-corner 811 iiSst = Nie0-nn_hls+1 ; ijSst = Njs0 ! Snd ea-side starting point, excluding se-corner 812 iiSnd = Nie0 ; ijSnd = Nje0 ! Snd ea-side ending point, excluding ne-corner 813 iioutdir = -1 ; ijoutdir = -999 ! outside MPI domain: westward 814 ! ______.... 815 CASE( 2 ) ! x: rim on rcvea/sndwe-side : |o 816 ! o: potential neighbour(s) : x|o 817 ! outside of the MPI domain ___:__|o.. 818 iRnei = jpea ; iSnei = jpwe 819 iiRst = Nie0+1 ; ijRst = Njs0 ! Rcv ea-side starting point, excluding se-corner 820 iiRnd = jpi ; ijRnd = Nje0 ! Rcv ea-side ending point, excluding ne-corner 821 iiSst = Nis0 ; ijSst = Njs0 ! Snd we-side starting point, excluding sw-corner 822 iiSnd = Nis0+nn_hls-1 ; ijSnd = Nje0 ! Snd we-side ending point, excluding nw-corner 823 iioutdir = 1 ; ijoutdir = -999 ! outside MPI domain: eastward 824 ! 825 CASE( 3 ) ! x: rim on rcvso/sndno-side | | 826 ! o: potential neighbour(s) |¨¨¨¨¨¨¨| 827 ! outside of the MPI domain |___x___| 828 ! : o o o : 829 ! : : 830 iRnei = jpso ; iSnei = jpno 831 iiRst = Nis0 ; ijRst = 1 ! Rcv so-side starting point, excluding sw-corner 832 iiRnd = Nie0 ; ijRnd = nn_hls ! Rcv so-side ending point, excluding se-corner 833 iiSst = Nis0 ; ijSst = Nje0-nn_hls+1 ! Snd no-side starting point, excluding nw-corner 834 iiSnd = Nie0 ; ijSnd = Nje0 ! Snd no-side ending point, excluding ne-corner 835 iioutdir = -999 ; ijoutdir = -1 ! outside MPI domain: southward 836 ! : : 837 CASE( 4 ) ! x: rim on rcvno/sndso-side :_o_o_o_: 838 ! o: potential neighbour(s) | x | 839 ! outside of the MPI domain | | 840 ! |¨¨¨¨¨¨¨| 841 iRnei = jpno ; iSnei = jpso 842 iiRst = Nis0 ; ijRst = Nje0+1 ! Rcv no-side starting point, excluding nw-corner 843 iiRnd = Nie0 ; ijRnd = jpj ! Rcv no-side ending point, excluding ne-corner 844 iiSst = Nis0 ; ijSst = Njs0 ! Snd so-side starting point, excluding sw-corner 845 iiSnd = Nie0 ; ijSnd = Njs0+nn_hls-1 ! Snd so-side ending point, excluding se-corner 846 iioutdir = -999 ; ijoutdir = 1 ! outside MPI domain: northward 847 END SELECT 848 ! 849 IF( ii >= iiRst .AND. ii <= iiRnd .AND. ij >= ijRst .AND. ij <= ijRnd ) THEN ! rim point in recv side 850 iiout = ii+iioutdir ; ijout = ij+ijoutdir ! in which direction do we go outside of the MPI domain? 851 ! take care of neighbourg(s) in the interior of the computational domain 852 IF( iibi==iiout .OR. ii1==iiout .OR. ii2==iiout .OR. ii3==iiout .OR. & ! Neib outside of the MPI domain 853 & ijbi==ijout .OR. ij1==ijout .OR. ij2==ijout .OR. ij3==ijout ) THEN ! -> I cannot compute it -> recv it 854 IF( mpiRnei(nn_hls,iRnei) > -1 ) lrecv_bdyint(ib_bdy,igrd,iRnei,ir) = .TRUE. 855 ENDIF 856 ! take care of neighbourg in the exterior of the computational domain 857 IF( iibe==iiout .OR. ijbe==ijout ) THEN ! Neib outside of the MPI domain -> I cannot compute it -> recv it 858 IF( mpiRnei(nn_hls,iRnei) > -1 ) lrecv_bdyext(ib_bdy,igrd,iRnei,ir) = .TRUE. 859 ENDIF 860 ENDIF 861 862 IF( ii >= iiSst .AND. ii <= iiSnd .AND. ij >= ijSst .AND. ij <= ijSnd ) THEN ! rim point in send side 863 iiout = ii+iioutdir ; ijout = ij+ijoutdir ! in which direction do we go outside of the nei MPI domain? 864 ! take care of neighbourg(s) in the interior of the computational domain 865 IF( iibi==iiout .OR. ii1==iiout .OR. ii2==iiout .OR. ii3==iiout .OR. & ! Neib outside of nei MPI domain 866 & ijbi==ijout .OR. ij1==ijout .OR. ij2==ijout .OR. ij3==ijout ) THEN ! -> nei cannot compute it 867 IF( mpiSnei(nn_hls,iSnei) > -1 ) lsend_bdyint(ib_bdy,igrd,iSnei,ir) = .TRUE. ! -> send to nei 868 ENDIF 869 ! take care of neighbourg in the exterior of the computational domain 870 IF( iibe == iiout .OR. ijbe == ijout ) THEN ! Neib outside of the nei MPI domain -> nei cannot compute it 871 IF( mpiSnei(nn_hls,iSnei) > -1 ) lsend_bdyext(ib_bdy,igrd,iSnei,ir) = .TRUE. ! -> send to nei 872 ENDIF 873 END IF 874 875 END DO ! 4 sides 757 876 ! 758 ! s earch neighbour in the north/south direction877 ! specific treatment for the corners 759 878 ! 760 ! Rim is on the halo and computed ocean is towards exterior of mpi domain 761 ! ==> cannot compute the point x -> need to receive it 762 !(3) | | ^ ___o___ 763 ! | |___x___| OR | | x | 764 ! v o (4) | | 765 IF( ijbi==0 .OR. ij1==0 .OR. ij2==0 .OR. ij3==0 ) lrecv_bdyint(ib_bdy,igrd,jpso,ir) = .TRUE. 766 IF( ijbe==0 ) lrecv_bdyext(ib_bdy,igrd,jpso,ir) = .TRUE. 767 IF( ijbi==jpj+1 .OR. ij1==jpj+1 .OR. ij2==jpj+1 .OR. ij3==jpj+1 ) lrecv_bdyint(ib_bdy,igrd,jpno,ir) = .TRUE. 768 IF( ijbe==jpj+1 ) lrecv_bdyext(ib_bdy,igrd,jpno,ir) = .TRUE. 769 ! Check if neighbour has its rim parallel to its mpi subdomain _________ border and next to its halo 770 ! ^ | o | : : 771 ! | |¨¨¨¨x¨¨¨¨| neighbour limited by ... would need o | |....x....| 772 ! :_________: (3) S neighbour N neighbour (4) v | o | 773 ! ==> the neighbour cannot compute the point x -> need to send it 774 IF( ij == 2*nn_hls .AND. mpiSnei(nn_hls,jpso) > -1 ) THEN ! 2*nn_hls -> jj=jpj of southern neighbour 775 IF( ijbi==ij+1 .OR. ij1==ij+1 .OR. ij2==ij+1 .OR. ij3==ij+1 ) lsend_bdyint(ib_bdy,igrd,jpso,ir) = .TRUE. 776 IF( ijbe==ij+1 ) lsend_bdyext(ib_bdy,igrd,jpso,ir) = .TRUE. 777 ENDIF 778 IF( ij == jpj-2*nn_hls+1 .AND. mpiSnei(nn_hls,jpno) > -1 ) THEN ! jpj-2*nn_hls+1-> jj=1 of northern neighbour 779 IF( ijbi==ij-1 .OR. ij1==ij-1 .OR. ij2==ij-1 .OR. ij3==ij-1 ) lsend_bdyint(ib_bdy,igrd,jpno,ir) = .TRUE. 780 IF( ijbe==ij-1 ) lsend_bdyext(ib_bdy,igrd,jpno,ir) = .TRUE. 781 ENDIF 782 END DO 783 END DO 784 END DO 879 DO icnt = 1, 4 880 SELECT CASE( icnt ) 881 ! ...|.... 882 CASE( 1 ) ! x: rim on sw-corner o| : 883 ! o: potential neighbour(s) o|x__:__ 884 ! outside of the MPI domain o o o: 885 ! : 886 iRdiag = jpsw ; iRsono = jpso ! Recv: for sw or so 887 iSdiag = jpne ; iSsono = jpno ! Send: to ne or no 888 iiRst = 1 ; ijRst = 1 ! Rcv sw-corner starting point 889 iiRnd = nn_hls ; ijRnd = nn_hls ! Rcv sw-corner ending point 890 iiSstdiag = Nie0-nn_hls+1 ; ijSstdiag = Nje0-nn_hls+1 ! send to sw-corner of ne neighbourg 891 iiSnddiag = Nie0 ; ijSnddiag = Nje0 ! send to sw-corner of ne neighbourg 892 iiSstsono = 1 ; ijSstsono = Nje0-nn_hls+1 ! send to sw-corner of no neighbourg 893 iiSndsono = nn_hls ; ijSndsono = Nje0 ! send to sw-corner of no neighbourg 894 iioutdir = -1 ; ijoutdir = -1 ! outside MPI domain: westward or southward 895 ! ....|... 896 CASE( 2 ) ! x: rim on se-corner : |o 897 ! o: potential neighbour(s) __:__x|o 898 ! outside of the MPI domain :o o o 899 ! : 900 iRdiag = jpse ; iRsono = jpso ! Recv: for se or so 901 iSdiag = jpnw ; iSsono = jpno ! Send: to nw or no 902 iiRst = Nie0+1 ; ijRst = 1 ! Rcv se-corner starting point 903 iiRnd = jpi ; ijRnd = nn_hls ! Rcv se-corner ending point 904 iiSstdiag = Nis0 ; ijSstdiag = Nje0-nn_hls+1 ! send to se-corner of nw neighbourg 905 iiSnddiag = Nis0+nn_hls-1 ; ijSnddiag = Nje0 ! send to se-corner of nw neighbourg 906 iiSstsono = Nie0+1 ; ijSstsono = Nje0-nn_hls+1 ! send to se-corner of no neighbourg 907 iiSndsono = jpi ; ijSndsono = Nje0 ! send to se-corner of no neighbourg 908 iioutdir = 1 ; ijoutdir = -1 ! outside MPI domain: eastward or southward 909 ! : 910 ! o o_o:___ 911 CASE( 3 ) ! x: rim on nw-corner o|x : 912 ! o: potential neighbour(s) ..o|...: 913 ! outside of the MPI domain | 914 iRdiag = jpnw ; iRsono = jpno ! Recv: for nw or no 915 iSdiag = jpse ; iSsono = jpso ! Send: to se or so 916 iiRst = 1 ; ijRst = Nje0+1 ! Rcv nw-corner starting point 917 iiRnd = nn_hls ; ijRnd = jpj ! Rcv nw-corner ending point 918 iiSstdiag = Nie0-nn_hls+1 ; ijSstdiag = Njs0 ! send to nw-corner of se neighbourg 919 iiSnddiag = Nie0 ; ijSnddiag = Njs0+nn_hls-1 ! send to nw-corner of se neighbourg 920 iiSstsono = 1 ; ijSstsono = Njs0 ! send to nw-corner of so neighbourg 921 iiSndsono = nn_hls ; ijSndsono = Njs0+nn_hls-1 ! send to nw-corner of so neighbourg 922 iioutdir = -1 ; ijoutdir = 1 ! outside MPI domain: westward or northward 923 ! : 924 ! ___:o_o o 925 CASE( 4 ) ! x: rim on ne-corner : x|o 926 ! o: potential neighbour(s) :...|o... 927 ! outside of the MPI domain | 928 iRdiag = jpne ; iRsono = jpno ! Recv: for ne or no 929 iSdiag = jpsw ; iSsono = jpso ! Send: to sw or so 930 iiRst = Nie0+1 ; ijRst = Nje0+1 ! Rcv ne-corner starting point 931 iiRnd = jpi ; ijRnd = jpj ! Rcv ne-corner ending point 932 iiSstdiag = Nis0 ; ijSstdiag = Njs0 ! send to ne-corner of sw neighbourg 933 iiSnddiag = Nis0+nn_hls-1 ; ijSnddiag = Njs0+nn_hls-1 ! send to ne-corner of sw neighbourg 934 iiSstsono = Nie0+1 ; ijSstsono = Njs0 ! send to ne-corner of so neighbourg 935 iiSndsono = jpi ; ijSndsono = Njs0+nn_hls-1 ! send to ne-corner of so neighbourg 936 iioutdir = 1 ; ijoutdir = 1 ! outside MPI domain: eastward or southward 937 END SELECT 938 ! 939 ! Check if we need to receive data for this rim point 940 IF( ii >= iiRst .AND. ii <= iiRnd .AND. ij >= ijRst .AND. ij <= ijRnd ) THEN ! rim point on the corner 941 iiout = ii+iioutdir ; ijout = ij+ijoutdir ! in which direction do we go outside of the MPI domain? 942 ! take care of neighbourg(s) in the interior of the computational domain 943 IF( iibi==iiout .OR. ii1==iiout .OR. ii2==iiout .OR. ii3==iiout .OR. & ! Neib outside of the MPI domain 944 & ijbi==ijout .OR. ij1==ijout .OR. ij2==ijout .OR. ij3==ijout ) THEN ! -> I cannot compute it -> recv it 945 IF( mpiRnei(nn_hls,iRdiag) > -1 ) lrecv_bdyint(ib_bdy,igrd,iRdiag,ir) = .TRUE. ! Receive directly from diagonal neighbourg 946 IF( mpiRnei(nn_hls,iRsono) > -1 .AND. nn_comm == 1 ) lrecv_bdyint(ib_bdy,igrd,iRsono,ir) = .TRUE. ! Receive through the South/North neighbourg 947 ENDIF 948 ! take care of neighbourg in the exterior of the computational domain 949 IF( iibe==iiout .OR. ijbe==ijout ) THEN ! Neib outside of the MPI domain -> I cannot compute it -> recv it 950 IF( mpiRnei(nn_hls,iRdiag) > -1 ) lrecv_bdyext(ib_bdy,igrd,iRdiag,ir) = .TRUE. ! Receive directly from diagonal neighbourg 951 IF( mpiRnei(nn_hls,iRsono) > -1 .AND. nn_comm == 1 ) lrecv_bdyext(ib_bdy,igrd,iRsono,ir) = .TRUE. ! Receive through the South/North neighbourg 952 ENDIF 953 ENDIF 954 ! 955 ! Check if this rim point corresponds to the corner of one neighbourg. if yes, do we need to send data? 956 ! Direct send to diag: Is this rim point the corner point of a diag neighbour with which we communicate? 957 IF( ii >= iiSstdiag .AND. ii <= iiSnddiag .AND. ij >= ijSstdiag .AND. ij <= ijSnddiag & 958 & .AND. mpiSnei(nn_hls,iSdiag) > -1 ) THEN 959 iiout = ii+iioutdir ; ijout = ij+ijoutdir ! in which direction do we go outside of the nei MPI domain? 960 ! take care of neighbourg(s) in the interior of the computational domain 961 IF( iibi==iiout .OR. ii1==iiout .OR. ii2==iiout .OR. ii3==iiout .OR. & ! Neib outside of diag nei MPI 962 & ijbi==ijout .OR. ij1==ijout .OR. ij2==ijout .OR. ij3==ijout ) & ! domain -> nei cannot compute it 963 & lsend_bdyint(ib_bdy,igrd,iSdiag,ir) = .TRUE. ! send rim point data to diag nei 964 ! take care of neighbourg in the exterior of the computational domain 965 IF( iibe==iiout .OR. ijbe==ijout ) & 966 & lsend_bdyext(ib_bdy,igrd,iSdiag,ir) = .TRUE. 967 ENDIF 968 ! Indirect send to diag (through so/no): rim point is the corner point of a so/no nei with which we communicate 969 IF( ii >= iiSstsono .AND. ii <= iiSndsono .AND. ij >= ijSstsono .AND. ij <= ijSndsono & 970 & .AND. mpiSnei(nn_hls,iSsono) > -1 .AND. nn_comm == 1 ) THEN 971 iiout = ii+iioutdir ; ijout = ij+ijoutdir ! in which direction do we go outside of the nei MPI domain? 972 ! take care of neighbourg(s) in the interior of the computational domain 973 IF( iibi==iiout .OR. ii1==iiout .OR. ii2==iiout .OR. ii3==iiout .OR. & ! Neib outside of so/no nei MPI 974 & ijbi==ijout .OR. ij1==ijout .OR. ij2==ijout .OR. ij3==ijout ) & ! domain -> nei cannot compute it 975 & lsend_bdyint(ib_bdy,igrd,iSsono,ir) = .TRUE. ! send rim point data to so/no nei 976 ! take care of neighbourg in the exterior of the computational domain 977 IF( iibe==iiout .OR. ijbe==ijout ) & 978 & lsend_bdyext(ib_bdy,igrd,iSsono,ir) = .TRUE. 979 ENDIF 980 ! 981 END DO ! 4 corners 982 END DO ! ib 983 END DO ! igrd 984 985 ! Comment out for debug 986 !!$ DO ir = 0,1 987 !!$ zzbdy(:,:) = narea ; CALL lbc_lnk('bdy debug', zzbdy, 'T', 1._wp, kfillmode = jpfillnothing, & 988 !!$ & lsend = lsend_bdyint(ib_bdy,1,:,ir), lrecv = lrecv_bdyint(ib_bdy,1,:,ir) ) 989 !!$ IF(lwp) WRITE(numout,*) ' bdy debug int T', ir ; CALL FLUSH(numout) 990 !!$ zzbdy(:,:) = narea ; CALL lbc_lnk('bdy debug', zzbdy, 'U', 1._wp, kfillmode = jpfillnothing, & 991 !!$ & lsend = lsend_bdyint(ib_bdy,2,:,ir), lrecv = lrecv_bdyint(ib_bdy,2,:,ir) ) 992 !!$ IF(lwp) WRITE(numout,*) ' bdy debug int U', ir ; CALL FLUSH(numout) 993 !!$ zzbdy(:,:) = narea ; CALL lbc_lnk('bdy debug', zzbdy, 'V', 1._wp, kfillmode = jpfillnothing, & 994 !!$ & lsend = lsend_bdyint(ib_bdy,3,:,ir), lrecv = lrecv_bdyint(ib_bdy,3,:,ir) ) 995 !!$ IF(lwp) WRITE(numout,*) ' bdy debug int V', ir ; CALL FLUSH(numout) 996 !!$ zzbdy(:,:) = narea ; CALL lbc_lnk('bdy debug', zzbdy, 'T', 1._wp, kfillmode = jpfillnothing, & 997 !!$ & lsend = lsend_bdyext(ib_bdy,1,:,ir), lrecv = lrecv_bdyext(ib_bdy,1,:,ir) ) 998 !!$ IF(lwp) WRITE(numout,*) ' bdy debug ext T', ir ; CALL FLUSH(numout) 999 !!$ zzbdy(:,:) = narea ; CALL lbc_lnk('bdy debug', zzbdy, 'U', 1._wp, kfillmode = jpfillnothing, & 1000 !!$ & lsend = lsend_bdyext(ib_bdy,2,:,ir), lrecv = lrecv_bdyext(ib_bdy,2,:,ir) ) 1001 !!$ IF(lwp) WRITE(numout,*) ' bdy debug ext U', ir ; CALL FLUSH(numout) 1002 !!$ zzbdy(:,:) = narea ; CALL lbc_lnk('bdy debug', zzbdy, 'V', 1._wp, kfillmode = jpfillnothing, & 1003 !!$ & lsend = lsend_bdyext(ib_bdy,3,:,ir), lrecv = lrecv_bdyext(ib_bdy,3,:,ir) ) 1004 !!$ IF(lwp) WRITE(numout,*) ' bdy debug ext V', ir ; CALL FLUSH(numout) 1005 !!$ END DO 1006 1007 END DO ! ib_bdy 785 1008 786 1009 DO ib_bdy = 1,nb_bdy -
NEMO/branches/2021/dev_r14383_PISCES_NEWDEV_PISCO/src/OCE/BDY/bdytra.F90
r15127 r15440 55 55 TYPE(ztrabdy), DIMENSION(jpts) :: zdta ! Temporary data structure 56 56 LOGICAL :: llrim0 ! indicate if rim 0 is treated 57 LOGICAL, DIMENSION( 4) :: llsend1, llrecv1 ! indicate how communications are to be carried out57 LOGICAL, DIMENSION(8) :: llsend1, llrecv1 ! indicate how communications are to be carried out 58 58 !!---------------------------------------------------------------------- 59 59 igrd = 1 … … 96 96 llrecv1(:) = llrecv1(:) .OR. lrecv_bdyint(ib_bdy,1,:,ir) ! possibly every direction, T points 97 97 CASE('orlanski', 'orlanski_npo') 98 llsend1(:) = llsend1(:) .OR. lsend_bdy (ib_bdy,1,:,ir) ! possibly every direction, T points99 llrecv1(:) = llrecv1(:) .OR. lrecv_bdy (ib_bdy,1,:,ir) ! possibly every direction, T points98 llsend1(:) = llsend1(:) .OR. lsend_bdyolr(ib_bdy,1,:,ir) ! possibly every direction, T points 99 llrecv1(:) = llrecv1(:) .OR. lrecv_bdyolr(ib_bdy,1,:,ir) ! possibly every direction, T points 100 100 END SELECT 101 101 END DO -
NEMO/branches/2021/dev_r14383_PISCES_NEWDEV_PISCO/src/OCE/DYN/dynspg_ts.F90
r15127 r15440 1051 1051 #if defined key_agrif 1052 1052 ! Restrict the use of Agrif to the forward case only 1053 !!!IF( .NOT.ln_bt_fw .AND. .NOT.Agrif_Root() ) CALL ctl_stop( 'AGRIF not implemented if ln_bt_fw=.FALSE.' )1053 IF( .NOT.ln_bt_fw .AND. .NOT.Agrif_Root() ) CALL ctl_stop( 'AGRIF not implemented if ln_bt_fw=.FALSE.' ) 1054 1054 #endif 1055 1055 ! -
NEMO/branches/2021/dev_r14383_PISCES_NEWDEV_PISCO/src/OCE/ICB/icbini.F90
r15127 r15440 73 73 ! 74 74 IF( .NOT. ln_icebergs ) RETURN 75 ! 76 ALLOCATE( utau_icb(jpi,jpj), vtau_icb(jpi,jpj) ) 75 77 ! 76 78 ! ! allocate gridded fields -
NEMO/branches/2021/dev_r14383_PISCES_NEWDEV_PISCO/src/OCE/ICB/icbutl.F90
r15127 r15440 93 93 sss_e(1:jpi,1:jpj) = sss_m(:,:) 94 94 fr_e (1:jpi,1:jpj) = fr_i (:,:) 95 ua_e (1:jpi,1:jpj) = utau (:,:) * umask(:,:,1) ! maybe mask useless because mask applied in sbcblk96 va_e (1:jpi,1:jpj) = vtau (:,:) * vmask(:,:,1) ! maybe mask useless because mask applied in sbcblk95 ua_e (1:jpi,1:jpj) = utau_icb (:,:) * umask(:,:,1) ! maybe mask useless because mask applied in sbcblk 96 va_e (1:jpi,1:jpj) = vtau_icb (:,:) * vmask(:,:,1) ! maybe mask useless because mask applied in sbcblk 97 97 ff_e(1:jpi,1:jpj) = ff_f (:,:) 98 98 ! -
NEMO/branches/2021/dev_r14383_PISCES_NEWDEV_PISCO/src/OCE/LBC/lbc_lnk_call_generic.h90
r15127 r15440 52 52 REAL(PRECISION) , OPTIONAL , INTENT(in ) :: pfillval ! background value (used at closed boundaries) 53 53 INTEGER , OPTIONAL , INTENT(in ) :: khls ! halo size, default = nn_hls 54 LOGICAL, DIMENSION( 4), OPTIONAL , INTENT(in ) :: lsend, lrecv ! indicate how communications are to be carried out54 LOGICAL, DIMENSION(8), OPTIONAL , INTENT(in ) :: lsend, lrecv ! indicate how communications are to be carried out 55 55 LOGICAL , OPTIONAL , INTENT(in ) :: ld4only ! if .T., do only 4-neighbour comm (ignore corners) 56 56 !! -
NEMO/branches/2021/dev_r14383_PISCES_NEWDEV_PISCO/src/OCE/LBC/lbc_lnk_neicoll_generic.h90
r15349 r15440 9 9 REAL(PRECISION), OPTIONAL, INTENT(in ) :: pfillval ! background value (used at closed boundaries) 10 10 INTEGER , OPTIONAL, INTENT(in ) :: khls ! halo size, default = nn_hls 11 LOGICAL, DIMENSION( 4),OPTIONAL, INTENT(in ) :: lsend, lrecv ! communication with other 4 proc11 LOGICAL, DIMENSION(8),OPTIONAL, INTENT(in ) :: lsend, lrecv ! communication with other 4 proc 12 12 LOGICAL, OPTIONAL, INTENT(in ) :: ld4only ! if .T., do only 4-neighbour comm (ignore corners) 13 13 ! … … 74 74 ! define llsend and llrecv: logicals which say if mpi-neibourgs for send or receive exist or not. 75 75 IF ( PRESENT(lsend) .AND. PRESENT(lrecv) ) THEN ! localy defined neighbourgs 76 CALL ctl_stop( 'STOP', 'mpp_nc_generic+BDY not yet implemented') 77 !!$ ---> llsend(:) = lsend(:) ; llrecv(:) = lrecv(:) ??? 76 CALL ctl_stop( 'STOP', 'mpp_nc_generic+lsend and lrecv not yet implemented') 78 77 ELSE IF( PRESENT(lsend) .OR. PRESENT(lrecv) ) THEN 79 78 WRITE(ctmp1,*) TRIM(cdname), ' is calling lbc_lnk with only one of the two arguments lsend or lrecv' -
NEMO/branches/2021/dev_r14383_PISCES_NEWDEV_PISCO/src/OCE/LBC/lbc_lnk_pt2pt_generic.h90
r15349 r15440 10 10 REAL(PRECISION), OPTIONAL, INTENT(in ) :: pfillval ! background value (used at closed boundaries) 11 11 INTEGER , OPTIONAL, INTENT(in ) :: khls ! halo size, default = nn_hls 12 LOGICAL, DIMENSION( 4),OPTIONAL, INTENT(in ) :: lsend, lrecv ! communication with other 4 proc12 LOGICAL, DIMENSION(8),OPTIONAL, INTENT(in ) :: lsend, lrecv ! communication with other 4 proc 13 13 LOGICAL, OPTIONAL, INTENT(in ) :: ld4only ! if .T., do only 4-neighbour comm (ignore corners) 14 14 ! … … 72 72 ! define llsend and llrecv: logicals which say if mpi-neibourgs for send or receive exist or not. 73 73 IF ( PRESENT(lsend) .AND. PRESENT(lrecv) ) THEN ! localy defined neighbourgs 74 llsend( 1:4) = lsend(1:4) ; llrecv(1:4) = lrecv(1:4)74 llsend(:) = lsend(:) ; llrecv(:) = lrecv(:) 75 75 ELSE IF( PRESENT(lsend) .OR. PRESENT(lrecv) ) THEN 76 76 WRITE(ctmp1,*) TRIM(cdname), ' is calling lbc_lnk with only one of the two arguments lsend or lrecv' -
NEMO/branches/2021/dev_r14383_PISCES_NEWDEV_PISCO/src/OCE/SBC/sbc_oce.F90
r14227 r15440 106 106 REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) :: utau , utau_b !: sea surface i-stress (ocean referential) [N/m2] 107 107 REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) :: vtau , vtau_b !: sea surface j-stress (ocean referential) [N/m2] 108 REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) :: utau_icb, vtau_icb !: sea surface (i,j)-stress used by icebergs [N/m2] 108 109 REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) :: taum !: module of sea surface stress (at T-point) [N/m2] 109 110 !! wndm is used compute surface gases exchanges in ice-free ocean or leads -
NEMO/branches/2021/dev_r14383_PISCES_NEWDEV_PISCO/src/OCE/SBC/sbcblk_algo_ecmwf.F90
r14072 r15440 31 31 USE sbc_phy ! Catalog of functions for physical/meteorological parameters in the marine boundary layer 32 32 USE sbcblk_skin_ecmwf ! cool-skin/warm layer scheme !LB 33 USE sbcwave, ONLY : charn 34 USE sbc_oce, ONLY : ln_charn ! wave module 33 35 34 36 IMPLICIT NONE … … 229 231 u_star = 0.035_wp*Ubzu*ztmp1/ztmp0 ! (u* = 0.035*Un10) 230 232 231 z0 = charn0_ecmwf*u_star*u_star/grav + 0.11_wp*znu_a/u_star 233 IF (ln_charn) THEN ! Charnock value if wave coupling 234 z0 = charn*u_star*u_star/grav + 0.11_wp*znu_a/u_star 235 ELSE 236 z0 = charn0_ecmwf*u_star*u_star/grav + 0.11_wp*znu_a/u_star 237 ENDIF 232 238 z0 = MIN( MAX(ABS(z0), 1.E-9) , 1._wp ) ! (prevents FPE from stupid values from masked region later on) 233 239 … … 296 302 ztmp2 = u_star*u_star 297 303 ztmp1 = znu_a/u_star 304 IF (ln_charn) THEN ! Charnock value if wave coupling 305 z0 = MIN( ABS( alpha_M*ztmp1 + charn*ztmp2/grav ) , 0.001_wp) 306 ELSE 307 z0 = MIN( ABS( alpha_M*ztmp1 + charn0_ecmwf*ztmp2/grav ) , 0.001_wp) 308 ENDIF 298 309 z0 = MIN( ABS( alpha_M*ztmp1 + charn0_ecmwf*ztmp2/grav ) , 0.001_wp) 299 310 z0t = MIN( ABS( alpha_H*ztmp1 ) , 0.001_wp) ! eq.3.26, Chap.3, p.34, IFS doc - Cy31r1 -
NEMO/branches/2021/dev_r14383_PISCES_NEWDEV_PISCO/src/OCE/SBC/sbcfwb.F90
r15127 r15440 36 36 37 37 REAL(wp) :: rn_fwb0 ! initial freshwater adjustment flux [kg/m2/s] (nn_fwb = 2 only) 38 REAL(wp) :: a_fwb ! annual domain averaged freshwater budget from the 39 ! previous year 38 REAL(wp) :: a_fwb ! annual domain averaged freshwater budget from the previous year 39 REAL(wp) :: a_fwb_b ! annual domain averaged freshwater budget from the year before or at initial state 40 REAL(wp) :: a_fwb_ini ! initial domain averaged freshwater budget 40 41 REAL(wp) :: area ! global mean ocean surface (interior domain) 41 42 … … 129 130 ! 130 131 CASE ( 2 ) !== fw adjustment based on fw budget at the end of the previous year ==! 131 ! 132 IF( kt == nit000 ) THEN ! initialisation 133 ! ! set the fw adjustment (a_fwb) 134 IF ( ln_rstart .AND. iom_varid( numror, 'a_fwb', ldstop = .FALSE. ) > 0 ) THEN ! as read from restart file 135 IF(lwp) WRITE(numout,*) 'sbc_fwb : reading FW-budget adjustment from restart file' 136 CALL iom_get( numror, 'a_fwb', a_fwb ) 137 ELSE ! as specified in namelist 138 a_fwb = rn_fwb0 132 ! simulation is supposed to start 1st of January 133 IF( kt == nit000 ) THEN ! initialisation 134 ! ! set the fw adjustment (a_fwb) 135 IF ( ln_rstart .AND. iom_varid( numror, 'a_fwb_b', ldstop = .FALSE. ) > 0 & ! as read from restart file 136 & .AND. iom_varid( numror, 'a_fwb', ldstop = .FALSE. ) > 0 ) THEN 137 IF(lwp) WRITE(numout,*) 'sbc_fwb : reading freshwater-budget from restart file' 138 CALL iom_get( numror, 'a_fwb_b', a_fwb_b ) 139 CALL iom_get( numror, 'a_fwb' , a_fwb ) 140 ! 141 a_fwb_ini = a_fwb_b 142 ELSE ! as specified in namelist 143 IF(lwp) WRITE(numout,*) 'sbc_fwb : setting freshwater-budget from namelist rn_fwb0' 144 a_fwb = rn_fwb0 145 a_fwb_b = 0._wp ! used only the first year then it is replaced by a_fwb_ini 146 ! 147 a_fwb_ini = glob_sum( 'sbcfwb', e1e2t(:,:) * ( ssh(:,:,Kmm) + snwice_mass(:,:) * r1_rho0 ) ) & 148 & * rho0 / ( area * rday * REAL(nyear_len(1), wp) ) 139 149 END IF 140 150 ! 141 IF(lwp)WRITE(numout,*) 142 IF(lwp)WRITE(numout,*)'sbc_fwb : initial freshwater-budget adjustment = ', a_fwb, 'kg/m2/s' 143 ! 144 ENDIF 145 ! ! Update a_fwb if new year start 146 ikty = 365 * 86400 / rn_Dt !!bug use of 365 days leap year or 360d year !!!!!!! 147 IF( MOD( kt, ikty ) == 0 ) THEN 148 ! mean sea level taking into account the ice+snow 149 ! sum over the global domain 150 a_fwb = glob_sum( 'sbcfwb', e1e2t(:,:) * ( ssh(:,:,Kmm) + snwice_mass(:,:) * r1_rho0 ) ) 151 a_fwb = a_fwb * 1.e+3 / ( area * rday * 365. ) ! convert in Kg/m3/s = mm/s 152 !!gm ! !!bug 365d year 153 ENDIF 154 ! 155 IF( MOD( kt-1, kn_fsbc ) == 0 ) THEN ! correct the freshwater fluxes 156 zcoef = a_fwb * rcp 157 emp(:,:) = emp(:,:) + a_fwb * tmask(:,:,1) 158 qns(:,:) = qns(:,:) - zcoef * sst_m(:,:) * tmask(:,:,1) ! account for change to the heat budget due to fw correction 151 IF(lwp) WRITE(numout,*) 152 IF(lwp) WRITE(numout,*)'sbc_fwb : freshwater-budget at the end of previous year = ', a_fwb , 'kg/m2/s' 153 IF(lwp) WRITE(numout,*)' freshwater-budget at initial state = ', a_fwb_ini, 'kg/m2/s' 154 ! 155 ELSE 156 ! at the end of year n: 157 ikty = nyear_len(1) * 86400 / NINT(rn_Dt) 158 IF( MOD( kt, ikty ) == 0 ) THEN ! Update a_fwb at the last time step of a year 159 ! It should be the first time step of a year MOD(kt-1,ikty) but then the restart would be wrong 160 ! Hence, we make a small error here but the code is restartable 161 a_fwb_b = a_fwb_ini 162 ! mean sea level taking into account ice+snow 163 a_fwb = glob_sum( 'sbcfwb', e1e2t(:,:) * ( ssh(:,:,Kmm) + snwice_mass(:,:) * r1_rho0 ) ) 164 a_fwb = a_fwb * rho0 / ( area * rday * REAL(nyear_len(1), wp) ) ! convert in kg/m2/s 165 ENDIF 166 ! 167 ENDIF 168 ! 169 IF( MOD( kt-1, kn_fsbc ) == 0 ) THEN ! correct the freshwater fluxes using previous year budget minus initial state 170 zcoef = ( a_fwb - a_fwb_b ) 171 emp(:,:) = emp(:,:) + zcoef * tmask(:,:,1) 172 qns(:,:) = qns(:,:) - zcoef * rcp * sst_m(:,:) * tmask(:,:,1) ! account for change to the heat budget due to fw correction 159 173 ! outputs 160 IF( iom_use('hflx_fwb_cea') ) CALL iom_put( 'hflx_fwb_cea', -zcoef * sst_m(:,:) * tmask(:,:,1) )161 IF( iom_use('vflx_fwb_cea') ) CALL iom_put( 'vflx_fwb_cea', - a_fwb* tmask(:,:,1) )174 IF( iom_use('hflx_fwb_cea') ) CALL iom_put( 'hflx_fwb_cea', -zcoef * rcp * sst_m(:,:) * tmask(:,:,1) ) 175 IF( iom_use('vflx_fwb_cea') ) CALL iom_put( 'vflx_fwb_cea', -zcoef * tmask(:,:,1) ) 162 176 ENDIF 163 177 ! Output restart information … … 166 180 IF(lwp) WRITE(numout,*) 'sbc_fwb : writing FW-budget adjustment to ocean restart file at it = ', kt 167 181 IF(lwp) WRITE(numout,*) '~~~~' 168 CALL iom_rstput( kt, nitrst, numrow, 'a_fwb', a_fwb ) 182 CALL iom_rstput( kt, nitrst, numrow, 'a_fwb_b', a_fwb_b ) 183 CALL iom_rstput( kt, nitrst, numrow, 'a_fwb', a_fwb ) 169 184 END IF 170 185 ! 171 IF( kt == nitend .AND. lwp ) WRITE(numout,*) 'sbc_fwb : final freshwater-budget adjustment = ', a_fwb, 'kg/m2/s' 186 IF( kt == nitend .AND. lwp ) THEN 187 WRITE(numout,*) 'sbc_fwb : freshwater-budget at the end of simulation (year now) = ', a_fwb , 'kg/m2/s' 188 WRITE(numout,*) ' freshwater-budget at initial state = ', a_fwb_b, 'kg/m2/s' 189 ENDIF 172 190 ! 173 191 CASE ( 3 ) !== global fwf set to zero and spread out over erp area ==! -
NEMO/branches/2021/dev_r14383_PISCES_NEWDEV_PISCO/src/OCE/SBC/sbcmod.F90
r15349 r15440 466 466 CALL lbc_lnk( 'sbcmod', taum(:,:), 'T', 1. ) 467 467 ! 468 IF( ln_icebergs ) THEN ! save pure stresses (with no ice-ocean stress) for use by icebergs 469 utau_icb(:,:) = utau(:,:) ; vtau_icb(:,:) = vtau(:,:) 470 ENDIF 471 ! 468 472 ! !== Misc. Options ==! 469 473 ! -
NEMO/branches/2021/dev_r14383_PISCES_NEWDEV_PISCO/src/OCE/lib_fortran.F90
r15349 r15440 34 34 PUBLIC glob_sum_vec 35 35 PUBLIC glob_sum_full_vec 36 PUBLIC glob_min_vec, glob_max_vec 36 37 #if defined key_nosignedzero 37 38 PUBLIC SIGN … … 61 62 INTERFACE glob_sum_full_vec 62 63 MODULE PROCEDURE glob_sum_full_vec_3d, glob_sum_full_vec_4d 64 END INTERFACE 65 INTERFACE glob_min_vec 66 MODULE PROCEDURE glob_min_vec_3d, glob_min_vec_4d 67 END INTERFACE 68 INTERFACE glob_max_vec 69 MODULE PROCEDURE glob_max_vec_3d, glob_max_vec_4d 63 70 END INTERFACE 64 71 … … 503 510 END FUNCTION glob_sum_full_vec_4d 504 511 512 FUNCTION glob_min_vec_3d( cdname, ptab ) RESULT( ptmp ) 513 !!---------------------------------------------------------------------- 514 CHARACTER(len=*), INTENT(in) :: cdname ! name of the calling subroutine 515 REAL(wp), INTENT(in) :: ptab(:,:,:) ! array on which operation is applied 516 REAL(wp), DIMENSION(SIZE(ptab,3)) :: ptmp 517 ! 518 INTEGER :: jk ! dummy loop indice & dimension 519 INTEGER :: ipk ! dimension 520 !!----------------------------------------------------------------------- 521 ! 522 ipk = SIZE(ptab,3) 523 DO jk = 1, ipk 524 ptmp(jk) = MINVAL( ptab(:,:,jk) * tmask_i(:,:) ) 525 ENDDO 526 ! 527 CALL mpp_min( cdname, ptmp (:) ) 528 ! 529 END FUNCTION glob_min_vec_3d 530 531 FUNCTION glob_min_vec_4d( cdname, ptab ) RESULT( ptmp ) 532 !!---------------------------------------------------------------------- 533 CHARACTER(len=*), INTENT(in) :: cdname ! name of the calling subroutine 534 REAL(wp), INTENT(in) :: ptab(:,:,:,:) ! array on which operation is applied 535 REAL(wp), DIMENSION(SIZE(ptab,4)) :: ptmp 536 ! 537 INTEGER :: jk , jl ! dummy loop indice & dimension 538 INTEGER :: ipk, ipl ! dimension 539 !!----------------------------------------------------------------------- 540 ! 541 ipk = SIZE(ptab,3) 542 ipl = SIZE(ptab,4) 543 DO jl = 1, ipl 544 ptmp(jl) = MINVAL( ptab(:,:,1,jl) * tmask_i(:,:) ) 545 DO jk = 2, ipk 546 ptmp(jl) = MIN( ptmp(jl), MINVAL( ptab(:,:,jk,jl) * tmask_i(:,:) ) ) 547 ENDDO 548 ENDDO 549 ! 550 CALL mpp_min( cdname, ptmp (:) ) 551 ! 552 END FUNCTION glob_min_vec_4d 553 554 FUNCTION glob_max_vec_3d( cdname, ptab ) RESULT( ptmp ) 555 !!---------------------------------------------------------------------- 556 CHARACTER(len=*), INTENT(in) :: cdname ! name of the calling subroutine 557 REAL(wp), INTENT(in) :: ptab(:,:,:) ! array on which operation is applied 558 REAL(wp), DIMENSION(SIZE(ptab,3)) :: ptmp 559 ! 560 INTEGER :: jk ! dummy loop indice & dimension 561 INTEGER :: ipk ! dimension 562 !!----------------------------------------------------------------------- 563 ! 564 ipk = SIZE(ptab,3) 565 DO jk = 1, ipk 566 ptmp(jk) = MAXVAL( ptab(:,:,jk) * tmask_i(:,:) ) 567 ENDDO 568 ! 569 CALL mpp_max( cdname, ptmp (:) ) 570 ! 571 END FUNCTION glob_max_vec_3d 572 573 FUNCTION glob_max_vec_4d( cdname, ptab ) RESULT( ptmp ) 574 !!---------------------------------------------------------------------- 575 CHARACTER(len=*), INTENT(in) :: cdname ! name of the calling subroutine 576 REAL(wp), INTENT(in) :: ptab(:,:,:,:) ! array on which operation is applied 577 REAL(wp), DIMENSION(SIZE(ptab,4)) :: ptmp 578 ! 579 INTEGER :: jk , jl ! dummy loop indice & dimension 580 INTEGER :: ipk, ipl ! dimension 581 !!----------------------------------------------------------------------- 582 ! 583 ipk = SIZE(ptab,3) 584 ipl = SIZE(ptab,4) 585 DO jl = 1, ipl 586 ptmp(jl) = MAXVAL( ptab(:,:,1,jl) * tmask_i(:,:) ) 587 DO jk = 2, ipk 588 ptmp(jl) = MAX( ptmp(jl), MAXVAL( ptab(:,:,jk,jl) * tmask_i(:,:) ) ) 589 ENDDO 590 ENDDO 591 ! 592 CALL mpp_max( cdname, ptmp (:) ) 593 ! 594 END FUNCTION glob_max_vec_4d 595 505 596 SUBROUTINE DDPDD( ydda, yddb ) 506 597 !!---------------------------------------------------------------------- -
NEMO/branches/2021/dev_r14383_PISCES_NEWDEV_PISCO/src/OCE/step.F90
r15127 r15440 229 229 IF( lk_asminc .AND. ln_asmiau .AND. ln_dyninc ) & 230 230 & CALL dyn_asm_inc ( kstp, Nbb, Nnn, uu, vv, Nrhs ) ! apply dynamics assimilation increment 231 IF( ln_bkgwri ) CALL asm_bkg_wri( kstp, Nnn ) ! output background fields 231 232 IF( ln_bdy ) CALL bdy_dyn3d_dmp ( kstp, Nbb, uu, vv, Nrhs ) ! bdy damping trends 232 233 #if defined key_agrif -
NEMO/branches/2021/dev_r14383_PISCES_NEWDEV_PISCO/src/OCE/stpmlf.F90
r15127 r15440 241 241 IF( lk_asminc .AND. ln_asmiau .AND. ln_dyninc ) & 242 242 & CALL dyn_asm_inc ( kstp, Nbb, Nnn, uu, vv, Nrhs ) ! apply dynamics assimilation increment 243 IF( ln_bkgwri ) CALL asm_bkg_wri( kstp, Nnn ) ! output background fields 243 244 IF( ln_bdy ) CALL bdy_dyn3d_dmp ( kstp, Nbb, uu, vv, Nrhs ) ! bdy damping trends 244 245 #if defined key_agrif … … 507 508 ! so that asselin contribution is removed at the same time 508 509 DO jk = 1, jpkm1 509 DO_2D( 0, 0, 0, 0 ) 510 puu(ji,jj,jk,Kmm) = ( puu(ji,jj,jk,Kmm) - un_adv(ji,jj)*r1_hu(ji,jj,Kmm) + uu_b(ji,jj,Kmm) )*umask(ji,jj,jk) 511 pvv(ji,jj,jk,Kmm) = ( pvv(ji,jj,jk,Kmm) - vn_adv(ji,jj)*r1_hv(ji,jj,Kmm) + vv_b(ji,jj,Kmm) )*vmask(ji,jj,jk) 512 END_2D 510 puu(:,:,jk,Kmm) = ( puu(:,:,jk,Kmm) - un_adv(:,:)*r1_hu(:,:,Kmm) + uu_b(:,:,Kmm) )*umask(:,:,jk) 511 pvv(:,:,jk,Kmm) = ( pvv(:,:,jk,Kmm) - vn_adv(:,:)*r1_hv(:,:,Kmm) + vv_b(:,:,Kmm) )*vmask(:,:,jk) 513 512 END DO 514 513 ENDIF -
NEMO/branches/2021/dev_r14383_PISCES_NEWDEV_PISCO/src/TOP/TRP/trcsbc.F90
r14215 r15440 51 51 !! The surface freshwater flux modify the ocean volume 52 52 !! and thus the concentration of a tracer as : 53 !! tr(Krhs) = tr(Krhs) + emp * tr(Kmm) / e3t_ for k=1 54 !! where emp, the surface freshwater budget (evaporation minus 55 !! precipitation ) given in kg/m2/s is divided 56 !! by 1035 kg/m3 (density of ocean water) to obtain m/s. 53 !! tr(Krhs) = tr(Krhs) + emp * tr(Kmm) / e3t_ + fmmflx * tri / e3t for k=1 54 !! - tr(Kmm) , the concentration of tracer in the ocean 55 !! - tri, the concentration of tracer in the sea-ice 56 !! - emp, the surface freshwater budget (evaporation minus precipitation + fmmflx) 57 !! given in kg/m2/s is divided by 1035 kg/m3 (density of ocean water) to obtain m/s. 58 !! - fmmflx, the flux asscociated to freezing-melting of sea-ice 59 !! In linear free surface case (ln_linssh=T), the volume of the 60 !! ocean does not change with the water exchanges at the (air+ice)-sea 57 61 !! 58 62 !! ** Action : - Update the 1st level of tr(:,:,:,:,Krhs) with the trend associated … … 66 70 INTEGER :: ji, jj, jn ! dummy loop indices 67 71 REAL(wp) :: zse3t, zrtrn, zfact ! local scalars 68 REAL(wp) :: z ftra, zdtra, ztfx, ztra! - -72 REAL(wp) :: zdtra ! - - 69 73 CHARACTER (len=22) :: charout 70 REAL(wp), DIMENSION(jpi,jpj) :: zsfx71 74 REAL(wp), ALLOCATABLE, DIMENSION(:,:,:) :: ztrtrd 72 75 !!--------------------------------------------------------------------- … … 106 109 ENDIF 107 110 108 ! Coupling online : river runoff is added to the horizontal divergence (hdiv) in the subroutine sbc_rnf_div109 ! one only consider the concentration/dilution effect due to evaporation minus precipitation + freezing/melting of sea-ice110 ! Coupling offline : runoff are in emp which contains E-P-R111 !112 IF( .NOT.ln_linssh ) THEN ! online coupling with vvl113 zsfx(:,:) = 0._wp114 ELSE ! online coupling free surface or offline with free surface115 zsfx(:,:) = emp(:,:)116 ENDIF117 118 111 ! 0. initialization 119 112 SELECT CASE ( nn_ice_tr ) 120 113 121 CASE ( -1 ) ! No tracers in sea ice (null concentration in sea ice) 122 ! 123 DO jn = 1, jptra 124 DO_2D( 0, 0, 0, 1 ) 125 sbc_trc(ji,jj,jn) = zsfx(ji,jj) * r1_rho0 * ptr(ji,jj,1,jn,Kmm) 126 END_2D 127 END DO 128 ! 129 CASE ( 0 ) ! Same concentration in sea ice and in the ocean 130 ! 131 DO jn = 1, jptra 132 DO_2D( 0, 0, 0, 1 ) 133 sbc_trc(ji,jj,jn) = ( zsfx(ji,jj) + fmmflx(ji,jj) ) * r1_rho0 * ptr(ji,jj,1,jn,Kmm) 134 END_2D 135 END DO 114 CASE ( -1 ) ! ! No tracers in sea ice ( trc_i = 0 ) 115 ! 116 DO jn = 1, jptra 117 DO_2D( 0, 0, 0, 1 ) 118 sbc_trc(ji,jj,jn) = 0._wp 119 END_2D 120 END DO 121 ! 122 IF( ln_linssh ) THEN !* linear free surface 123 DO jn = 1, jptra 124 DO_2D( 0, 0, 0, 1 ) 125 sbc_trc(ji,jj,jn) = sbc_trc(ji,jj,jn) + r1_rho0 * emp(ji,jj) * ptr(ji,jj,1,jn,Kmm) !==>> add concentration/dilution effect due to constant volume cell 126 END_2D 127 END DO 128 ENDIF 129 ! 130 CASE ( 0 ) ! Same concentration in sea ice and in the ocean ( trc_i = ptr(...,Kmm) ) 131 ! 132 DO jn = 1, jptra 133 DO_2D( 0, 0, 0, 1 ) 134 sbc_trc(ji,jj,jn) = - fmmflx(ji,jj) * r1_rho0 * ptr(ji,jj,1,jn,Kmm) 135 END_2D 136 END DO 137 ! 138 IF( ln_linssh ) THEN !* linear free surface 139 DO jn = 1, jptra 140 DO_2D( 0, 0, 0, 1 ) 141 sbc_trc(ji,jj,jn) = sbc_trc(ji,jj,jn) + r1_rho0 * emp(ji,jj) * ptr(ji,jj,1,jn,Kmm) !==>> add concentration/dilution effect due to constant volume cell 142 END_2D 143 END DO 144 ENDIF 136 145 ! 137 146 CASE ( 1 ) ! Specific treatment of sea ice fluxes with an imposed concentration in sea ice … … 139 148 DO jn = 1, jptra 140 149 DO_2D( 0, 0, 0, 1 ) 141 zse3t = 1. / e3t(ji,jj,1,Kmm) 142 ! tracer flux at the ice/ocean interface (tracer/m2/s) 143 zftra = - trc_i(ji,jj,jn) * fmmflx(ji,jj) ! uptake of tracer in the sea ice 144 ! ! only used in the levitating sea ice case 145 ! tracer flux only : add concentration dilution term in net tracer flux, no F-M in volume flux 146 ! tracer and mass fluxes : no concentration dilution term in net tracer flux, F-M term in volume flux 147 ztfx = zftra ! net tracer flux 148 ! 149 zdtra = r1_rho0 * ( ztfx + ( zsfx(ji,jj) + fmmflx(ji,jj) ) * ptr(ji,jj,1,jn,Kmm) ) 150 IF ( zdtra < 0. ) THEN 151 zdtra = MAX(zdtra, -ptr(ji,jj,1,jn,Kmm) * e3t(ji,jj,1,Kmm) / rDt_trc ) ! avoid negative concentrations to arise 152 ENDIF 153 sbc_trc(ji,jj,jn) = zdtra 154 END_2D 155 END DO 150 sbc_trc(ji,jj,jn) = - fmmflx(ji,jj) * r1_rho0 * trc_i(ji,jj,jn) 151 END_2D 152 END DO 153 ! 154 IF( ln_linssh ) THEN !* linear free surface 155 DO jn = 1, jptra 156 DO_2D( 0, 0, 0, 1 ) 157 sbc_trc(ji,jj,jn) = sbc_trc(ji,jj,jn) + r1_rho0 * emp(ji,jj) * ptr(ji,jj,1,jn,Kmm) !==>> add concentration/dilution effect due to constant volume cell 158 END_2D 159 END DO 160 ENDIF 161 ! 162 DO jn = 1, jptra 163 DO_2D( 0, 0, 0, 1 ) 164 zse3t = rDt_trc / e3t(ji,jj,1,Kmm) 165 zdtra = ptr(ji,jj,1,jn,Kmm) + sbc_trc(ji,jj,jn) * zse3t 166 IF( zdtra < 0. ) sbc_trc(ji,jj,jn) = MAX( zdtra, -ptr(ji,jj,1,jn,Kmm) / zse3t ) ! avoid negative concentration that can occurs if trc_i > ptr 167 END_2D 168 END DO 169 ! 156 170 END SELECT 157 171 ! -
NEMO/branches/2021/dev_r14383_PISCES_NEWDEV_PISCO/src/TOP/trc.F90
r15127 r15440 116 116 ! 117 117 REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:,:) :: trc3d !: 3D diagnostics for tracers 118 REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,: ,:):: trc2d !: 2D diagnostics for tracers118 REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) :: trc2d !: 2D diagnostics for tracers 119 119 120 120 !! information for inputs … … 179 179 IF (jp_dia3d > 0 ) ALLOCATE( trc3d(jpi,jpj,jpk,jp_dia3d), STAT = ierr(3) ) 180 180 ! 181 IF (jp_dia2d > 0 ) ALLOCATE( trc2d(jpi,jpj,jp k,jp_dia2d), STAT = ierr(4) )181 IF (jp_dia2d > 0 ) ALLOCATE( trc2d(jpi,jpj,jp_dia2d) , STAT = ierr(4) ) 182 182 ! 183 183 trc_alloc = MAXVAL( ierr ) -
NEMO/branches/2021/dev_r14383_PISCES_NEWDEV_PISCO/src/TOP/trcbdy.F90
r13527 r15440 50 50 REAL(wp), POINTER, DIMENSION(:,:) :: ztrc 51 51 LOGICAL :: llrim0 ! indicate if rim 0 is treated 52 LOGICAL, DIMENSION( 4) :: llsend1, llrecv1 ! indicate how communications are to be carried out52 LOGICAL, DIMENSION(8) :: llsend1, llrecv1 ! indicate how communications are to be carried out 53 53 !!---------------------------------------------------------------------- 54 54 ! … … 98 98 llrecv1(:) = llrecv1(:) .OR. lrecv_bdyint(ib_bdy,1,:,ir) ! possibly every direction, T points 99 99 CASE('orlanski','orlanski_npo') 100 llsend1(:) = llsend1(:) .OR. lsend_bdy (ib_bdy,1,:,ir) ! possibly every direction, T points101 llrecv1(:) = llrecv1(:) .OR. lrecv_bdy (ib_bdy,1,:,ir) ! possibly every direction, T points100 llsend1(:) = llsend1(:) .OR. lsend_bdyolr(ib_bdy,1,:,ir) ! possibly every direction, T points 101 llrecv1(:) = llrecv1(:) .OR. lrecv_bdyolr(ib_bdy,1,:,ir) ! possibly every direction, T points 102 102 END SELECT 103 103 END DO
Note: See TracChangeset
for help on using the changeset viewer.