MODULE rocketduststorm_mod IMPLICIT NONE REAL, SAVE, ALLOCATABLE :: dustliftday(:) ! dust lifting rate (s-1) CONTAINS !======================================================================= ! ROCKET DUST STORM - vertical transport and detrainment !======================================================================= ! calculation of the vertical flux ! call of vl_storm : Van Leer transport scheme of the dust tracers ! detrainement of stormdust in the background dust ! ----------------------------------------------------------------------- ! Authors: M. Vals; C. Wang; F. Forget; T. Bertrand ! Institution: Laboratoire de Meteorologie Dynamique (LMD) Paris, France ! ----------------------------------------------------------------------- SUBROUTINE rocketduststorm(ngrid,nlayer,nq,ptime,ptimestep, & pq,pdqfi,pt,pdtfi,pplev,pplay,pzlev, & pzlay,pdtsw,pdtlw, & ! input for radiative transfer clearatm,icount,zday,zls, & tsurf,igout,totstormfract, & ! input sub-grid scale cloud clearsky,totcloudfrac, & ! output pdqrds,wrad,dsodust,dsords) USE tracer_mod, only: igcm_stormdust_mass,igcm_stormdust_number & ,igcm_dust_mass,igcm_dust_number & ,rho_dust USE comcstfi_h, only: r,g,cpp,rcp USE dimradmars_mod, only: albedo,naerkind USE comsaison_h, only: dist_sol,mu0,fract USE surfdat_h, only: emis,co2ice,zmea, zstd, zsig, hmons USE callradite_mod IMPLICIT NONE !-------------------------------------------------------- ! Input Variables !-------------------------------------------------------- INTEGER, INTENT(IN) :: ngrid ! number of horizontal grid points INTEGER, INTENT(IN) :: nlayer ! number of vertical grid points INTEGER, INTENT(IN) :: nq ! number of tracer species REAL, INTENT(IN) :: ptime REAL, INTENT(IN) :: ptimestep REAL, INTENT(IN) :: pq(ngrid,nlayer,nq) ! advected field nq REAL, INTENT(IN) :: pdqfi(ngrid,nlayer,nq)! tendancy field pq REAL, INTENT(IN) :: pt(ngrid,nlayer) ! temperature at mid-layer (K) REAL, INTENT(IN) :: pdtfi(ngrid,nlayer) ! tendancy temperature at mid-layer (K) REAL, INTENT(IN) :: pplay(ngrid,nlayer) ! pressure at middle of the layers REAL, INTENT(IN) :: pplev(ngrid,nlayer+1) ! pressure at intermediate levels REAL, INTENT(IN) :: pzlay(ngrid,nlayer) ! altitude at the middle of the layers REAL, INTENT(IN) :: pzlev(ngrid,nlayer+1) ! altitude at layer boundaries REAL, INTENT(IN) :: pdtsw(ngrid,nlayer) ! (K/s) env REAL, INTENT(IN) :: pdtlw(ngrid,nlayer) ! (K/s) env ! input for second radiative transfer LOGICAL, INTENT(IN) :: clearatm INTEGER, INTENT(INOUT) :: icount REAL, INTENT(IN) :: zday REAL, INTENT(IN) :: zls REAL, INTENT(IN) :: tsurf(ngrid) INTEGER, INTENT(IN) :: igout REAL, INTENT(IN) :: totstormfract(ngrid) ! sbgrid scale water ice clouds logical, intent(in) :: clearsky real, intent(in) :: totcloudfrac(ngrid) !-------------------------------------------------------- ! Output Variables !-------------------------------------------------------- REAL, INTENT(OUT) :: pdqrds(ngrid,nlayer,nq) ! tendancy field for dust when detraining REAL, INTENT(OUT) :: wrad(ngrid,nlayer+1) ! vertical speed within the rocket dust storm REAL, INTENT(OUT) :: dsodust(ngrid,nlayer) ! density scaled opacity of env. dust REAL, INTENT(OUT) :: dsords(ngrid,nlayer) ! density scaled opacity of storm dust !-------------------------------------------------------- ! Local variables !-------------------------------------------------------- INTEGER l,ig,tsub,iq,ll ! local variables from callradite.F REAL zdtlw1(ngrid,nlayer) ! (K/s) storm REAL zdtsw1(ngrid,nlayer) ! (K/s) storm REAL zt(ngrid,nlayer) ! actual temperature at mid-layer (K) REAL zdtvert(ngrid,nlayer) ! dT/dz , lapse rate REAL ztlev(ngrid,nlayer) ! temperature at intermediate levels l+1/2 without last level REAL zdtlw1_lev(nlayer),zdtsw1_lev(nlayer) ! rad. heating rate at intermediate levels l+1/2 for stormdust REAL zdtlw_lev(nlayer),zdtsw_lev(nlayer) ! rad. heating rate at intermediate levels l+1/2 for background dust REAL zq_stormdust_mass(ngrid,nlayer) ! intermediate tracer stormdust mass REAL zq_stormdust_number(ngrid,nlayer) ! intermediate tracer stormdust number REAL zq_dust_mass(ngrid,nlayer) ! intermediate tracer dust mass REAL zq_dust_number(ngrid,nlayer) ! intermediate tracer dust number REAL mr_stormdust_mass(ngrid,nlayer) ! intermediate mixing ratio to calculate van leer transport with the "real" concentration (stormdust mass) REAL mr_stormdust_number(ngrid,nlayer) ! intermediate mixing ratio to calculate van leer transport with the "real" concentration (stormdust number) REAL mr_dust_mass(ngrid,nlayer) ! intermediate mixing ratio to calculate van leer transport with the "real" concentration (dust mass) REAL mr_dust_number(ngrid,nlayer) ! intermediate mixing ratio to calculate van leer transport with the "real" concentration (sdust number) REAL zq_vl_col(nlayer) ! column intermediate tracer used by Van Leer (number) REAL zn_vl_col(nlayer) ! column intermediate tracer used by Van Leer (mass) REAL dqvl_stormdust_mass(ngrid,nlayer) ! tendancy of vertical transport (stormdust mass) REAL dqvl_stormdust_number(ngrid,nlayer) ! tendancy of vertical transport (stormdust number) REAL dqvl_dust_mass(ngrid,nlayer) ! tendancy of vertical transport (dust mass) REAL dqvl_dust_number(ngrid,nlayer) ! tendancy of vertical transport (dust number) REAL dqdet_stormdust_mass(ngrid,nlayer) ! tendancy of detrainement (stormdust mass) REAL dqdet_stormdust_number(ngrid,nlayer) ! tendancy of detrainement (stormdust number) REAL masse_col(nlayer) ! mass of atmosphere (kg/m2) REAL zq(ngrid,nlayer,nq) ! updated tracers REAL w(ngrid,nlayer) ! air mass flux (calculated with the vertical wind velocity profile) used as input in Van Leer (kgair/m2) REAL wqmass(ngrid,nlayer+1) ! tracer (dust_mass) mass flux in Van Leer (kg/m2) REAL wqnumber(ngrid,nlayer+1) ! tracer (dust_number) mass flux in Van Leer (kg/m2) LOGICAL storm(ngrid) ! true when there is a dust storm (if the opacity is high): trigger the rocket dust storm scheme REAL coefdetrain(ngrid,nlayer) ! coefficient for detrainment : % of stormdust detrained INTEGER scheme(ngrid) ! triggered scheme REAL,PARAMETER:: coefmin =0.025 ! 00 if(w(l+1).le.0)then ! Regular scheme (transfered mass < 1 layer) ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if(-w(l+1).le.masse(l))then sigw=w(l+1)/masse(l) wq(l+1)=w(l+1)*(q(l)-0.5*(1.+sigw)*dzq(l)) ! Extended scheme (transfered mass > 1 layer) ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ else m = l-1 Mtot = masse(m+1) MQtot = masse(m+1)*q(m+1) if (m.le.0)goto 77 do while(-w(l+1).gt.(Mtot+masse(m))) ! do while(-w(l+1).gt.Mtot) m=m-1 Mtot = Mtot + masse(m+1) MQtot = MQtot + masse(m+1)*q(m+1) if (m.le.0)goto 77 end do 77 continue if (m.gt.0) then sigw=(w(l+1)+Mtot)/masse(m) wq(l+1)= -(MQtot + (-w(l+1)-Mtot)* & (q(m)-0.5*(1.+sigw)*dzq(m)) ) else w(l+1) = -Mtot wq(l+1) = -MQtot end if if ( masse(l)*q(l) .lt. -(wq(l+1)-wq(l)) ) then ! particular case when the vertical velocity is very strong in the layer and null below (wq(l)=0) wq(l+1) = wq(l)-masse(l)*q(l) end if endif endif ! w<0 (up) enddo do l = 1,nlay-1 ! loop different than when w>0 q(l)=q(l) + (wq(l+1)-wq(l))/masse(l) enddo ! 2) Compute wq where w > 0 (down) (ALWAYS FOR SEDIMENTATION) ! =============================== ! Initialisation wq = 0 to consider now only downward flux wq(:)=0. ! do l = 1,nlay ! loop different than when w<0 if(w(l).gt.0.)then ! Regular scheme (transfered mass < 1 layer) ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if(w(l).le.masse(l))then sigw=w(l)/masse(l) wq(l)=w(l)*(q(l)+0.5*(1.-sigw)*dzq(l)) ! write(*,*),'TB14 wq after up',wq(1,:) ! Extended scheme (transfered mass > 1 layer) ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ else m=l Mtot = masse(m) MQtot = masse(m)*q(m) if(m.ge.nlay)goto 88 do while(w(l).gt.(Mtot+masse(m+1))) m=m+1 Mtot = Mtot + masse(m) MQtot = MQtot + masse(m)*q(m) if(m.ge.nlay)goto 88 end do 88 continue if (m.lt.nlay) then sigw=(w(l)-Mtot)/masse(m+1) wq(l)=(MQtot + (w(l)-Mtot)* & (q(m+1)+0.5*(1.-sigw)*dzq(m+1)) ) else w(l) = Mtot wq(l) = MQtot end if if ( masse(l)*q(l) .lt. -(wq(l+1)-wq(l)) ) then ! particular case when the vertical velocity is very strong in the layer and null above (wq(l+1)=0) wq(l) = wq(l+1)+masse(l)*q(l) end if end if end if ! w>0 (down) enddo do l = 1,nlay ! loop different than when w<0 q(l)=q(l) + (wq(l+1)-wq(l))/masse(l) enddo END SUBROUTINE vl_storm !======================================================================= ! Initialization of the module variables subroutine ini_rocketduststorm_mod(ngrid) implicit none integer, intent(in) :: ngrid allocate(dustliftday(ngrid)) end subroutine ini_rocketduststorm_mod subroutine end_rocketduststorm_mod implicit none if (allocated(dustliftday)) deallocate(dustliftday) end subroutine end_rocketduststorm_mod END MODULE rocketduststorm_mod