| 1 | module lmdz_blowing_snow_sublim_sedim |
|---|
| 2 | |
|---|
| 3 | contains |
|---|
| 4 | |
|---|
| 5 | !============================================================================== |
|---|
| 6 | subroutine blowing_snow_sublim_sedim(ngrid,nlay,dtime,ustar,temp,qv,qb,pplay,paprs,dtemp_bs,dqv_bs,dqb_bs,bsfl,precip_bs) |
|---|
| 7 | |
|---|
| 8 | !============================================================================== |
|---|
| 9 | ! Routine that calculates the sublimation, melting and sedimentation |
|---|
| 10 | ! of blowing snow |
|---|
| 11 | ! Reference: Vignon et al 2025, GMD, https://doi.org/10.5194/egusphere-2025-2871 |
|---|
| 12 | ! |
|---|
| 13 | ! Etienne Vignon, October 2022 |
|---|
| 14 | !============================================================================== |
|---|
| 15 | |
|---|
| 16 | |
|---|
| 17 | use lmdz_blowing_snow_ini, only : iflag_sublim_bs, iflag_sedim_bs, coef_sub_bs,RTT,RD,RG,fallv_bs |
|---|
| 18 | use lmdz_blowing_snow_ini, only : qbmin, RCPD, RLSTT, RLMLT, RLVTT, RVTMP2, RV, RPI |
|---|
| 19 | use lmdz_blowing_snow_ini, only : tbsmelt, taumeltbs0, rhobs, r_bs |
|---|
| 20 | USE lmdz_lscp_tools, only : calc_qsat_ecmwf |
|---|
| 21 | |
|---|
| 22 | implicit none |
|---|
| 23 | |
|---|
| 24 | |
|---|
| 25 | !++++++++++++++++++++++++++++++++++++++++++++++++++++ |
|---|
| 26 | ! Declarations |
|---|
| 27 | !++++++++++++++++++++++++++++++++++++++++++++++++++++ |
|---|
| 28 | |
|---|
| 29 | !INPUT |
|---|
| 30 | !===== |
|---|
| 31 | |
|---|
| 32 | integer, intent(in) :: ngrid ! number of horizontal grid points |
|---|
| 33 | integer, intent(in) :: nlay ! number of vertical layers |
|---|
| 34 | real, intent(in) :: dtime ! physics time step [s] |
|---|
| 35 | real, intent(in), dimension(ngrid) :: ustar ! surface friction velocity [m/s] |
|---|
| 36 | real, intent(in), dimension(ngrid,nlay) :: temp ! temperature of the air [K] |
|---|
| 37 | real, intent(in), dimension(ngrid,nlay) :: qv ! specific content of water [kg/kg] |
|---|
| 38 | real, intent(in), dimension(ngrid,nlay) :: qb ! specific content of blowing snow [kg/kg] |
|---|
| 39 | real, intent(in), dimension(ngrid,nlay) :: pplay ! pressure at the middle of layers [Pa] |
|---|
| 40 | real, intent(in), dimension(ngrid,nlay+1) :: paprs ! pressure at the layer bottom interface [Pa] |
|---|
| 41 | |
|---|
| 42 | |
|---|
| 43 | |
|---|
| 44 | ! OUTPUT |
|---|
| 45 | !======== |
|---|
| 46 | |
|---|
| 47 | |
|---|
| 48 | real, intent(out), dimension(ngrid,nlay) :: dtemp_bs ! temperature tendency [K/s] |
|---|
| 49 | real, intent(out), dimension(ngrid,nlay) :: dqv_bs ! water vapor tendency [kg/kg/s] |
|---|
| 50 | real, intent(out), dimension(ngrid,nlay) :: dqb_bs ! blowing snow mass tendancy [kg/kg/s] |
|---|
| 51 | real, intent(out), dimension(ngrid,nlay+1) :: bsfl ! vertical profile of blowing snow vertical flux [kg/m2/s] |
|---|
| 52 | real, intent(out), dimension(ngrid) :: precip_bs ! surface sedimentation flux of blowing snow [kg/s/m2] |
|---|
| 53 | |
|---|
| 54 | ! LOCAL |
|---|
| 55 | !====== |
|---|
| 56 | |
|---|
| 57 | |
|---|
| 58 | integer :: k,i,n |
|---|
| 59 | real :: cpd, cpw, dqbsub, maxdqbsub, dqbmelt, zmair |
|---|
| 60 | real :: dqsedim,precbs, dqvmelt, zmelt, taumeltbs |
|---|
| 61 | real :: maxdqvmelt, rhoair, dz, dqbsedim |
|---|
| 62 | real :: delta_p, b_p, a_p, c_p, c_sub, qvsub |
|---|
| 63 | real :: p0, T0, Dv, Aprime, Bprime, Ka, radius0, radius |
|---|
| 64 | real, dimension(ngrid) :: ztemp,zqv,zqb,zpres,qsi,dqsi,qsl,dqsl,qzero,sedim |
|---|
| 65 | real, dimension(ngrid) :: zpaprsup, zpaprsdn, ztemp_up, zqb_up, zvelo |
|---|
| 66 | real, dimension(ngrid,nlay) :: temp_seri, qb_seri, qv_seri, zz |
|---|
| 67 | |
|---|
| 68 | !++++++++++++++++++++++++++++++++++++++++++++++++++ |
|---|
| 69 | ! Initialisation |
|---|
| 70 | !++++++++++++++++++++++++++++++++++++++++++++++++++ |
|---|
| 71 | |
|---|
| 72 | qzero(:)=0. |
|---|
| 73 | dtemp_bs(:,:)=0. |
|---|
| 74 | dqv_bs(:,:)=0. |
|---|
| 75 | dqb_bs(:,:)=0. |
|---|
| 76 | zvelo(:)=0. |
|---|
| 77 | sedim(:)=0. |
|---|
| 78 | precip_bs(:)=0. |
|---|
| 79 | bsfl(:,:)=0. |
|---|
| 80 | zz(:,:)=0. |
|---|
| 81 | |
|---|
| 82 | |
|---|
| 83 | p0=101325.0 ! ref pressure |
|---|
| 84 | |
|---|
| 85 | |
|---|
| 86 | DO k=1,nlay |
|---|
| 87 | DO i=1,ngrid |
|---|
| 88 | temp_seri(i,k)=temp(i,k) |
|---|
| 89 | qv_seri(i,k)=qv(i,k) |
|---|
| 90 | qb_seri(i,k)=qb(i,k) |
|---|
| 91 | zz(i,k)=zz(i,k)+(paprs(i,k)-paprs(i,k+1)) / (pplay(i,k)/RD/temp(i,k)*RG) |
|---|
| 92 | ENDDO |
|---|
| 93 | ENDDO |
|---|
| 94 | |
|---|
| 95 | |
|---|
| 96 | ! Sedimentation scheme |
|---|
| 97 | !---------------------- |
|---|
| 98 | |
|---|
| 99 | IF (iflag_sedim_bs .GT. 0) THEN |
|---|
| 100 | ! begin of top-down loop |
|---|
| 101 | DO k = nlay, 1, -1 |
|---|
| 102 | |
|---|
| 103 | DO i=1,ngrid |
|---|
| 104 | ztemp(i)=temp_seri(i,k) |
|---|
| 105 | zqv(i)=qv_seri(i,k) |
|---|
| 106 | zqb(i)=qb_seri(i,k) |
|---|
| 107 | zpres(i)=pplay(i,k) |
|---|
| 108 | zpaprsup(i)=paprs(i,k+1) |
|---|
| 109 | zpaprsdn(i)=paprs(i,k) |
|---|
| 110 | ENDDO |
|---|
| 111 | |
|---|
| 112 | ! thermalization of blowing snow precip coming from above |
|---|
| 113 | IF (k.LE.nlay-1) THEN |
|---|
| 114 | |
|---|
| 115 | DO i = 1, ngrid |
|---|
| 116 | zmair=(zpaprsdn(i)-zpaprsup(i))/RG |
|---|
| 117 | ! RVTMP2=rcpv/rcpd-1 |
|---|
| 118 | cpd=RCPD*(1.0+RVTMP2*zqv(i)) |
|---|
| 119 | cpw=RCPD*RVTMP2 |
|---|
| 120 | ! zqb_up: blowing snow mass that has to be thermalized with |
|---|
| 121 | ! layer's air so that precipitation at the ground has the |
|---|
| 122 | ! same temperature as the lowermost layer |
|---|
| 123 | zqb_up(i) = sedim(i)*dtime/zmair |
|---|
| 124 | ztemp_up(i)=temp_seri(i,k+1) |
|---|
| 125 | |
|---|
| 126 | ! t(i,k+1)+d_t(i,k+1): new temperature of the overlying layer |
|---|
| 127 | ztemp(i) = ( ztemp_up(i)*zqb_up(i)*cpw + cpd*ztemp(i) ) & |
|---|
| 128 | / (cpd + zqb_up(i)*cpw) |
|---|
| 129 | ENDDO |
|---|
| 130 | |
|---|
| 131 | ENDIF |
|---|
| 132 | |
|---|
| 133 | DO i = 1, ngrid |
|---|
| 134 | |
|---|
| 135 | rhoair = zpres(i) / ztemp(i) / RD |
|---|
| 136 | dz = (zpaprsdn(i)-zpaprsup(i)) / (rhoair*RG) |
|---|
| 137 | ! BS fall velocity assumed to be constant for now |
|---|
| 138 | zvelo(i) = fallv_bs |
|---|
| 139 | ! dqb/dt_sedim=1/rho(sedim/dz - rho w qb/dz) |
|---|
| 140 | ! implicit resolution |
|---|
| 141 | dqbsedim = (sedim(i)/rhoair/dz*dtime+zqb(i))/(1.+zvelo(i)*dtime/dz) - zqb(i) |
|---|
| 142 | ! flux and dqb update |
|---|
| 143 | zqb(i)=zqb(i)+dqbsedim |
|---|
| 144 | !sedim(i) = sedim(i)-dqbsedim/dtime*rhoair*dz |
|---|
| 145 | sedim(i)=rhoair*zvelo(i)*zqb(i) |
|---|
| 146 | |
|---|
| 147 | |
|---|
| 148 | ! variables update: |
|---|
| 149 | bsfl(i,k)=sedim(i) |
|---|
| 150 | |
|---|
| 151 | qb_seri(i,k) = zqb(i) |
|---|
| 152 | qv_seri(i,k) = zqv(i) |
|---|
| 153 | temp_seri(i,k) = ztemp(i) |
|---|
| 154 | |
|---|
| 155 | ENDDO ! Loop on ngrid |
|---|
| 156 | |
|---|
| 157 | |
|---|
| 158 | ENDDO ! vertical loop |
|---|
| 159 | |
|---|
| 160 | |
|---|
| 161 | !surface bs flux |
|---|
| 162 | DO i = 1, ngrid |
|---|
| 163 | precip_bs(i) = sedim(i) |
|---|
| 164 | ENDDO |
|---|
| 165 | |
|---|
| 166 | ENDIF |
|---|
| 167 | |
|---|
| 168 | |
|---|
| 169 | |
|---|
| 170 | |
|---|
| 171 | !+++++++++++++++++++++++++++++++++++++++++++++++ |
|---|
| 172 | ! Sublimation and melting |
|---|
| 173 | !++++++++++++++++++++++++++++++++++++++++++++++ |
|---|
| 174 | IF (iflag_sublim_bs .GT. 0) THEN |
|---|
| 175 | |
|---|
| 176 | DO k = 1, nlay |
|---|
| 177 | |
|---|
| 178 | DO i=1,ngrid |
|---|
| 179 | ztemp(i)=temp_seri(i,k) |
|---|
| 180 | zqv(i)=qv_seri(i,k) |
|---|
| 181 | zqb(i)=qb_seri(i,k) |
|---|
| 182 | zpres(i)=pplay(i,k) |
|---|
| 183 | zpaprsup(i)=paprs(i,k+1) |
|---|
| 184 | zpaprsdn(i)=paprs(i,k) |
|---|
| 185 | |
|---|
| 186 | ! computation of blowing snow mean radius. Either constant value = r_bs if >0 |
|---|
| 187 | ! or use of the height-dependent formulation from Sauter et al. 2013 and Saigger et al. 2024 |
|---|
| 188 | IF (r_bs .GT. 0.) THEN |
|---|
| 189 | radius=r_bs |
|---|
| 190 | ELSE |
|---|
| 191 | radius0=0.5*(ustar(i)*(7.8e-6)/0.036+31.e-6) |
|---|
| 192 | radius=radius0*zz(i,k)**(-0.258) |
|---|
| 193 | ENDIF |
|---|
| 194 | |
|---|
| 195 | ENDDO |
|---|
| 196 | |
|---|
| 197 | ! calulation saturation specific humidity |
|---|
| 198 | CALL CALC_QSAT_ECMWF(ngrid,ztemp(:),qzero(:),zpres(:),RTT,2,.false.,qsi(:),dqsi(:)) |
|---|
| 199 | |
|---|
| 200 | |
|---|
| 201 | DO i = 1, ngrid |
|---|
| 202 | |
|---|
| 203 | rhoair = zpres(i) / ztemp(i) / RD |
|---|
| 204 | dz = (zpaprsdn(i)-zpaprsup(i)) / (rhoair*RG) |
|---|
| 205 | ! BS fall velocity assumed to be constant for now |
|---|
| 206 | zvelo(i) = fallv_bs |
|---|
| 207 | |
|---|
| 208 | |
|---|
| 209 | IF (ztemp(i) .GT. RTT) THEN |
|---|
| 210 | |
|---|
| 211 | ! if temperature is positive, we assume that part of the blowing snow |
|---|
| 212 | ! already present melts and evaporates with a typical time |
|---|
| 213 | ! constant taumeltbs |
|---|
| 214 | |
|---|
| 215 | taumeltbs=taumeltbs0*exp(-max(0.,(ztemp(i)-RTT)/(tbsmelt-RTT))) |
|---|
| 216 | dqvmelt=min(zqb(i),-1.*zqb(i)*(exp(-dtime/taumeltbs)-1.)) |
|---|
| 217 | maxdqvmelt= max(RCPD*(1.0+RVTMP2*(zqv(i)+zqb(i)))*(ztemp(i)-RTT)/(RLMLT+RLVTT),0.) |
|---|
| 218 | dqvmelt=min(dqvmelt,maxdqvmelt) |
|---|
| 219 | ! qv update, melting + evaporation |
|---|
| 220 | zqv(i) = zqv(i) + dqvmelt |
|---|
| 221 | ! temp update melting + evaporation |
|---|
| 222 | ztemp(i) = ztemp(i) - dqvmelt * (RLMLT+RLVTT)/RCPD/(1.0+RVTMP2*(zqv(i)+zqb(i))) |
|---|
| 223 | ! qb update melting + evaporation |
|---|
| 224 | zqb(i)=zqb(i)-dqvmelt |
|---|
| 225 | |
|---|
| 226 | ELSE |
|---|
| 227 | ! negative celcius temperature |
|---|
| 228 | ! Sublimation scheme |
|---|
| 229 | |
|---|
| 230 | |
|---|
| 231 | ! Sublimation formulation for ice crystals from Pruppacher & Klett, Rutledge & Hobbs 1983 |
|---|
| 232 | ! assuming monodispered crystal distrib |
|---|
| 233 | ! dqb/dt_sub=-coef_sub_bs*(1-qv/qsi)*nc*8*radius/(Aprime+Bprime) |
|---|
| 234 | ! assuming Mi=rhobs*4/3*pi*radius**3 |
|---|
| 235 | ! qb=nc*Mi -> nc=qb/Mi |
|---|
| 236 | ! dqb/dt_sub=-coef_sub_bs*(1-qv/qsi)*6*qb/(rhobs*pi*radius**2)/(Aprime+Bprime) |
|---|
| 237 | ! dqb/dt_sub=-c_sub(1-qv/qsi)*qb |
|---|
| 238 | ! c_sub=coef_sub_bs*6/(rhobs*pi*radius**2)/(Aprime+Bprime) |
|---|
| 239 | ! |
|---|
| 240 | ! Note the strong coupling between specific contents of water vapor and blowing snow during sublimation |
|---|
| 241 | ! equations dqv/dt_sub and dqb/dt_sub must be solved jointly to prevent irrealistic increase of water vapor |
|---|
| 242 | ! at typical physics time steps |
|---|
| 243 | ! we thus solve the differential equation using an implicit scheme for both qb and qv |
|---|
| 244 | |
|---|
| 245 | ! we do not consider deposition, only sublimation |
|---|
| 246 | IF (zqv(i) .LT. qsi(i)) THEN |
|---|
| 247 | rhoair=zpres(i)/ztemp(i)/RD |
|---|
| 248 | Dv=0.0001*0.211*(p0/zpres(i))*((ztemp(i)/RTT)**1.94) ! water vapor diffusivity in air, SI |
|---|
| 249 | Ka=(5.69+0.017*(ztemp(i)-RTT))*1.e-5*100.*4.184 ! thermal conductivity of the air, SI |
|---|
| 250 | Aprime=RLSTT/Ka/ztemp(i)*(RLSTT/RV/ztemp(i) -1.) |
|---|
| 251 | Bprime=1./(rhoair*Dv*qsi(i)) |
|---|
| 252 | c_sub=coef_sub_bs*3./(rhobs*radius**2)/(Aprime+Bprime) |
|---|
| 253 | c_p=-zqb(i) |
|---|
| 254 | b_p=1.+c_sub*dtime-c_sub*dtime/qsi(i)*zqb(i)-c_sub*dtime/qsi(i)*zqv(i) |
|---|
| 255 | a_p=c_sub*dtime/qsi(i) |
|---|
| 256 | delta_p=(b_p**2)-4.*a_p*c_p |
|---|
| 257 | dqbsub=(-b_p+sqrt(delta_p))/(2.*a_p) - zqb(i) |
|---|
| 258 | dqbsub = MIN(0.0,MAX(dqbsub,-zqb(i))) |
|---|
| 259 | ! Sublimation limit: we ensure that the whole mesh does not exceed saturation wrt ice |
|---|
| 260 | maxdqbsub = MAX(0.0, qsi(i)-zqv(i)) |
|---|
| 261 | dqbsub = MAX(dqbsub,-maxdqbsub) |
|---|
| 262 | ELSE |
|---|
| 263 | dqbsub=0. |
|---|
| 264 | ENDIF |
|---|
| 265 | |
|---|
| 266 | ! vapor, temperature, precip fluxes update following sublimation |
|---|
| 267 | zqv(i) = zqv(i) - dqbsub |
|---|
| 268 | zqb(i) = zqb(i) + dqbsub |
|---|
| 269 | ztemp(i) = ztemp(i) + dqbsub*RLSTT/RCPD/(1.0+RVTMP2*(zqv(i)+zqb(i))) |
|---|
| 270 | |
|---|
| 271 | ENDIF |
|---|
| 272 | |
|---|
| 273 | ! if qb<qbmin, sublimate or melt and evaporate qb |
|---|
| 274 | ! see Gerber et al. 2023, JGR Atmos for the choice of qbmin |
|---|
| 275 | |
|---|
| 276 | IF (zqb(i) .LT. qbmin) THEN |
|---|
| 277 | zqv(i) = zqv(i)+zqb(i) |
|---|
| 278 | IF (ztemp(i) .LT. RTT) THEN |
|---|
| 279 | ztemp(i) = ztemp(i) - zqb(i) * RLSTT/RCPD/(1.0+RVTMP2*(zqv(i))) |
|---|
| 280 | ELSE |
|---|
| 281 | ztemp(i) = ztemp(i) - zqb(i) * (RLVTT+RLMLT)/RCPD/(1.0+RVTMP2*(zqv(i))) |
|---|
| 282 | ENDIF |
|---|
| 283 | zqb(i)=0. |
|---|
| 284 | ENDIF |
|---|
| 285 | |
|---|
| 286 | ! variables update |
|---|
| 287 | temp_seri(i,k)=ztemp(i) |
|---|
| 288 | qv_seri(i,k)=zqv(i) |
|---|
| 289 | qb_seri(i,k)=zqb(i) |
|---|
| 290 | ENDDO |
|---|
| 291 | ENDDO |
|---|
| 292 | |
|---|
| 293 | ENDIF |
|---|
| 294 | |
|---|
| 295 | |
|---|
| 296 | ! OUTPUTS |
|---|
| 297 | !++++++++++ |
|---|
| 298 | |
|---|
| 299 | ! 3D variables |
|---|
| 300 | DO k=1,nlay |
|---|
| 301 | DO i=1,ngrid |
|---|
| 302 | dqb_bs(i,k) = qb_seri(i,k) - qb(i,k) |
|---|
| 303 | dqv_bs(i,k) = qv_seri(i,k) - qv(i,k) |
|---|
| 304 | dtemp_bs(i,k) = temp_seri(i,k) - temp(i,k) |
|---|
| 305 | ENDDO |
|---|
| 306 | ENDDO |
|---|
| 307 | |
|---|
| 308 | |
|---|
| 309 | |
|---|
| 310 | return |
|---|
| 311 | |
|---|
| 312 | end subroutine blowing_snow_sublim_sedim |
|---|
| 313 | !============================================================================== |
|---|
| 314 | |
|---|
| 315 | |
|---|
| 316 | |
|---|
| 317 | end module lmdz_blowing_snow_sublim_sedim |
|---|