subroutine rain(ptimestep,pplev,pplay,t,pdt,pq,pdq,d_t,dqrain,dqsrain,dqssnow,rneb) ! to use 'getin' use ioipsl_getincom use watercommon_h, only: T_h2O_ice_liq,T_h2O_ice_clouds, RLVTT, RCPD, RCPV, RV, RVTMP2,Psat_water,Tsat_water,rhowater use radii_mod, only: h2o_cloudrad implicit none !================================================================== ! ! Purpose ! ------- ! Calculates H2O precipitation using simplified microphysics. ! ! Authors ! ------- ! Adapted from the LMDTERRE code by R. Wordsworth (2009) ! Added rain vaporization in case of T>Tsat ! Original author Z. X. Li (1993) ! !================================================================== #include "dimensions.h" #include "dimphys.h" #include "tracer.h" #include "comcstfi.h" #include "callkeys.h" ! Pre-arguments (for universal model) real pq(ngridmx,nlayermx,nqmx) ! tracer (kg/kg) real qsurf(ngridmx,nqmx) ! tracer at the surface (kg.m-2) REAL pdt(ngridmx,nlayermx),pdq(ngridmx,nlayermx,nqmx) real dqrain(ngridmx,nlayermx,nqmx) ! tendency of H2O precipitation (kg/kg.s-1) real dqsrain(ngridmx) ! rain flux at the surface (kg.m-2.s-1) real dqssnow(ngridmx) ! snow flux at the surface (kg.m-2.s-1) REAL d_t(ngridmx,nlayermx) ! temperature increment ! Arguments REAL ptimestep ! time interval REAL pplev(ngridmx,nlayermx+1) ! inter-layer pressure REAL pplay(ngridmx,nlayermx) ! mid-layer pressure REAL t(ngridmx,nlayermx) ! input temperature (K) REAL zt(ngridmx,nlayermx) ! working temperature (K) REAL ql(ngridmx,nlayermx) ! liquid water (Kg/Kg) REAL q(ngridmx,nlayermx) ! specific humidity (Kg/Kg) REAL rneb(ngridmx,nlayermx) ! cloud fraction REAL d_q(ngridmx,nlayermx) ! water vapor increment REAL d_ql(ngridmx,nlayermx) ! liquid water / ice increment ! Subroutine options REAL seuil_neb ! Nebulosity threshold PARAMETER (seuil_neb=0.001) INTEGER,save :: precip_scheme ! id number for precipitaion scheme ! for simple scheme (precip_scheme=1) REAL,SAVE :: rainthreshold ! Precipitation threshold in simple scheme ! for sundquist scheme (precip_scheme=2-3) REAL,SAVE :: cloud_sat ! Precipitation threshold in non simple scheme REAL,SAVE :: precip_timescale ! Precipitation timescale ! for Boucher scheme (precip_scheme=4) REAL,SAVE :: Cboucher ! Precipitation constant in Boucher 95 scheme REAL,PARAMETER :: Kboucher=1.19E8 REAL,SAVE :: c1 INTEGER ninter PARAMETER (ninter=5) logical evap_prec ! Does the rain evaporate? parameter(evap_prec=.true.) ! for simple scheme real t_crit PARAMETER (t_crit=218.0) real lconvert ! Local variables INTEGER i, k, n REAL zqs(ngridmx,nlayermx),Tsat(ngridmx,nlayermx), zdelta, zcor REAL zrfl(ngridmx), zrfln(ngridmx), zqev, zqevt REAL zoliq(ngridmx) REAL zdz(ngridmx),zrho(ngridmx),ztot(ngridmx), zrhol(ngridmx) REAL zchau(ngridmx),zfroi(ngridmx),zfrac(ngridmx),zneb(ngridmx) real reffh2oliq(ngridmx,nlayermx),reffh2oice(ngridmx,nlayermx) real ttemp, ptemp, psat_tmp real tnext(ngridmx,nlayermx) real l2c(ngridmx,nlayermx) real dWtot ! Indices of water vapour and water ice tracers INTEGER, SAVE :: i_vap=0 ! water vapour INTEGER, SAVE :: i_ice=0 ! water ice LOGICAL firstcall SAVE firstcall ! Online functions REAL fallv, fall2v, zzz ! falling speed of ice crystals fallv (zzz) = 3.29 * ((zzz)**0.16) fall2v (zzz) =10.6 * ((zzz)**0.31) !for use with radii DATA firstcall /.true./ IF (firstcall) THEN i_vap=igcm_h2o_vap i_ice=igcm_h2o_ice write(*,*) "rain: i_ice=",i_ice write(*,*) " i_vap=",i_vap PRINT*, 'in rain.F, ninter=', ninter PRINT*, 'in rain.F, evap_prec=', evap_prec write(*,*) "Precipitation scheme to use?" precip_scheme=1 ! default value call getin("precip_scheme",precip_scheme) write(*,*) " precip_scheme = ",precip_scheme if (precip_scheme.eq.1) then write(*,*) "rainthreshold in simple scheme?" rainthreshold=0. ! default value call getin("rainthreshold",rainthreshold) write(*,*) " rainthreshold = ",rainthreshold else if (precip_scheme.eq.2.or.precip_scheme.eq.3) then write(*,*) "cloud water saturation level in non simple scheme?" cloud_sat=2.6e-4 ! default value call getin("cloud_sat",cloud_sat) write(*,*) " cloud_sat = ",cloud_sat write(*,*) "precipitation timescale in non simple scheme?" precip_timescale=3600. ! default value call getin("precip_timescale",precip_timescale) write(*,*) " precip_timescale = ",precip_timescale else if (precip_scheme.eq.4) then write(*,*) "multiplicative constant in Boucher 95 precip scheme" Cboucher=1. ! default value call getin("Cboucher",Cboucher) write(*,*) " Cboucher = ",Cboucher c1=1.00*1.097/rhowater*Cboucher*Kboucher endif firstcall = .false. ENDIF ! GCM -----> subroutine variables DO k = 1, nlayermx DO i = 1, ngridmx zt(i,k) = t(i,k)+pdt(i,k)*ptimestep ! a big fat bug was here q(i,k) = pq(i,k,i_vap)+pdq(i,k,i_vap)*ptimestep ql(i,k) = pq(i,k,i_ice)+pdq(i,k,i_ice)*ptimestep !q(i,k) = pq(i,k,i_vap)!+pdq(i,k,i_vap) !ql(i,k) = pq(i,k,i_ice)!+pdq(i,k,i_ice) if(q(i,k).lt.0.)then ! if this is not done, we don't conserve water q(i,k)=0. endif if(ql(i,k).lt.0.)then ql(i,k)=0. endif ENDDO ENDDO ! Initialise the outputs DO k = 1, nlayermx DO i = 1, ngridmx d_t(i,k) = 0.0 d_q(i,k) = 0.0 d_ql(i,k) = 0.0 ENDDO ENDDO DO i = 1, ngridmx zrfl(i) = 0.0 zrfln(i) = 0.0 ENDDO ! calculate saturation mixing ratio DO k = 1, nlayermx DO i = 1, ngridmx ttemp = zt(i,k) ptemp = pplay(i,k) ! call watersat(ttemp,ptemp,zqs(i,k)) call Psat_water(ttemp,ptemp,psat_tmp,zqs(i,k)) call Tsat_water(ptemp,Tsat(i,k)) ENDDO ENDDO ! get column / layer conversion factor DO k = 1, nlayermx DO i = 1, ngridmx l2c(i,k)=(pplev(i,k)-pplev(i,k+1))/g ENDDO ENDDO ! Vertical loop (from top to bottom) ! We carry the rain with us and calculate that added by warm/cold precipitation ! processes and that subtracted by evaporation at each level. DO 9999 k = nlayermx, 1, -1 IF (evap_prec) THEN ! note no rneb dependence! DO i = 1, ngridmx IF (zrfl(i) .GT.0.) THEN if(zt(i,k).gt.Tsat(i,k))then ! treat the case where all liquid water should boil zqev=MIN((zt(i,k)-Tsat(i,k))*RCPD*l2c(i,k)/RLVTT,zrfl(i)) zrfl(i)=MAX(zrfl(i)-zqev,0.) d_q(i,k)=zqev/l2c(i,k) d_t(i,k) = - d_q(i,k) * RLVTT/RCPD else zqev = MAX (0.0, (zqs(i,k)-q(i,k)))*l2c(i,k)/ptimestep !there was a bug here zqevt= 2.0e-5*(1.0-q(i,k)/zqs(i,k)) & !default was 2.e-5 *sqrt(zrfl(i))*l2c(i,k)/pplay(i,k)*zt(i,k)*R ! BC modif here zqevt = MAX (zqevt, 0.0) zqev = MIN (zqev, zqevt) zqev = MAX (zqev, 0.0) zrfln(i)= zrfl(i) - zqev zrfln(i)= max(zrfln(i),0.0) d_q(i,k) = - (zrfln(i)-zrfl(i))/l2c(i,k)*ptimestep !d_t(i,k) = d_q(i,k) * RLVTT/RCPD!/(1.0+RVTMP2*q(i,k)) ! double BC modif here d_t(i,k) = - d_q(i,k) * RLVTT/RCPD ! was bugged! zrfl(i) = zrfln(i) end if ENDIF ENDDO ENDIF DO i = 1, ngridmx zoliq(i) = 0.0 ENDDO if(precip_scheme.eq.1)then DO i = 1, ngridmx ttemp = zt(i,k) IF (ttemp .ge. T_h2O_ice_liq) THEN lconvert=rainthreshold ELSEIF (ttemp .gt. t_crit) THEN lconvert=rainthreshold*(1.- t_crit/ttemp) lconvert=MAX(0.0,lconvert) ELSE lconvert=0. ENDIF IF (ql(i,k).gt.1.e-9) then zneb(i) = MAX(rneb(i,k), seuil_neb) IF ((ql(i,k)/zneb(i)).gt.lconvert)THEN ! precipitate! d_ql(i,k) = -MAX((ql(i,k)-lconvert*zneb(i)),0.0) zrfl(i) = zrfl(i) - d_ql(i,k)*l2c(i,k)/ptimestep ENDIF ENDIF ENDDO elseif (precip_scheme.ge.2) then DO i = 1, ngridmx IF (rneb(i,k).GT.0.0) THEN zoliq(i) = ql(i,k) zrho(i) = pplay(i,k) / ( zt(i,k) * R ) zdz(i) = (pplev(i,k)-pplev(i,k+1)) / (zrho(i)*g) zfrac(i) = (zt(i,k)-T_h2O_ice_clouds) / (T_h2O_ice_liq-T_h2O_ice_clouds) zfrac(i) = MAX(zfrac(i), 0.0) zfrac(i) = MIN(zfrac(i), 1.0) zneb(i) = MAX(rneb(i,k), seuil_neb) ENDIF ENDDO !recalculate liquid water particle radii call h2o_cloudrad(ql,reffh2oliq,reffh2oice) SELECT CASE(precip_scheme) !precip scheme from Sundquist 78 CASE(2) DO n = 1, ninter DO i = 1, ngridmx IF (rneb(i,k).GT.0.0) THEN ! this is the ONLY place where zneb, precip_timescale and cloud_sat are used zchau(i) = (ptimestep/(FLOAT(ninter)*precip_timescale)) * zoliq(i) & * (1.0-EXP(-(zoliq(i)/zneb(i)/cloud_sat)**2)) * zfrac(i) zrhol(i) = zrho(i) * zoliq(i) / zneb(i) zfroi(i) = ptimestep/FLOAT(ninter)/zdz(i)*zoliq(i) & *fall2v(reffh2oice(i,k)) * (1.0-zfrac(i)) ! zfroi behaves oddly... ztot(i) = zchau(i) + zfroi(i) IF (zneb(i).EQ.seuil_neb) ztot(i) = 0.0 ztot(i) = MIN(MAX(ztot(i),0.0),zoliq(i)) zoliq(i) = MAX(zoliq(i)-ztot(i), 0.0) ENDIF ENDDO ENDDO !precip scheme modified from Sundquist 78 (in q**3) CASE(3) DO n = 1, ninter DO i = 1, ngridmx IF (rneb(i,k).GT.0.0) THEN ! this is the ONLY place where zneb, precip_timescale and cloud_sat are used zchau(i) = (ptimestep/(FLOAT(ninter)*precip_timescale*cloud_sat**2)) * (zoliq(i)/zneb(i))**3 zrhol(i) = zrho(i) * zoliq(i) / zneb(i) zfroi(i) = ptimestep/FLOAT(ninter)/zdz(i)*zoliq(i) & *fall2v(reffh2oice(i,k)) * (1.0-zfrac(i)) ! zfroi behaves oddly... ztot(i) = zchau(i) + zfroi(i) IF (zneb(i).EQ.seuil_neb) ztot(i) = 0.0 ztot(i) = MIN(MAX(ztot(i),0.0),zoliq(i)) zoliq(i) = MAX(zoliq(i)-ztot(i), 0.0) ENDIF ENDDO ENDDO !precip scheme modified from Boucher 95 CASE(4) DO n = 1, ninter DO i = 1, ngridmx IF (rneb(i,k).GT.0.0) THEN ! this is the ONLY place where zneb and c1 are used zchau(i) = ptimestep/FLOAT(ninter) *c1* zrho(i) & *(zoliq(i)/zneb(i))**2*reffh2oliq(i,k)*zneb(i)* zfrac(i) zrhol(i) = zrho(i) * zoliq(i) / zneb(i) zfroi(i) = ptimestep/FLOAT(ninter)/zdz(i)*zoliq(i) & *fall2v(reffh2oice(i,k)) * (1.0-zfrac(i)) ! zfroi behaves oddly... ztot(i) = zchau(i) + zfroi(i) IF (zneb(i).EQ.seuil_neb) ztot(i) = 0.0 ztot(i) = MIN(MAX(ztot(i),0.0),zoliq(i)) zoliq(i) = MAX(zoliq(i)-ztot(i), 0.0) ENDIF ENDDO ENDDO END SELECT ! precip_scheme ! Change in cloud density and surface H2O values DO i = 1, ngridmx IF (rneb(i,k).GT.0.0) THEN d_ql(i,k) = (zoliq(i) - ql(i,k))!/ptimestep zrfl(i) = zrfl(i)+ MAX(ql(i,k)-zoliq(i),0.0)*l2c(i,k)/ptimestep ENDIF ENDDO endif ! if precip_scheme=1 9999 continue ! Rain or snow on the ground DO i = 1, ngridmx if(zrfl(i).lt.0.0)then print*,'Droplets of negative rain are falling...' call abort endif IF (t(i,1) .LT. T_h2O_ice_liq) THEN dqssnow(i) = zrfl(i) dqsrain(i) = 0.0 ELSE dqssnow(i) = 0.0 dqsrain(i) = zrfl(i) ! liquid water = ice for now ENDIF ENDDO ! now subroutine -----> GCM variables DO k = 1, nlayermx DO i = 1, ngridmx if(evap_prec)then dqrain(i,k,i_vap) = d_q(i,k)/ptimestep d_t(i,k) = d_t(i,k)/ptimestep else dqrain(i,k,i_vap) = 0.0 d_t(i,k) = 0.0 endif dqrain(i,k,i_ice) = d_ql(i,k)/ptimestep ENDDO ENDDO RETURN end subroutine rain